File: network_x_test.go

package info (click to toggle)
golang-collectd 0.5.0%2Bgit20240104.26404de-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 468 kB
  • sloc: ansic: 324; sh: 7; makefile: 3
file content (119 lines) | stat: -rw-r--r-- 2,410 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package network_test

import (
	"context"
	"errors"
	"fmt"
	"net"
	"testing"
	"time"

	"collectd.org/api"
	"collectd.org/network"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"golang.org/x/net/nettest"
)

type testPasswordLookup map[string]string

func (l testPasswordLookup) Password(user string) (string, error) {
	pw, ok := l[user]
	if !ok {
		return "", fmt.Errorf("user %q not found", user)
	}
	return pw, nil
}

func TestNetwork(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	const (
		username = "TestNetwork"
		password = `oi5aGh7oLo0mai5oaG8zei8a`
	)

	conn, err := nettest.NewLocalPacketListener("udp")
	if err != nil {
		t.Fatal(err)
	}
	defer conn.Close()

	ch := make(chan *api.ValueList)
	go func() {
		srv := &network.Server{
			Conn: conn.(*net.UDPConn),
			Writer: api.WriterFunc(func(_ context.Context, vl *api.ValueList) error {
				ch <- vl
				return nil
			}),
			PasswordLookup: testPasswordLookup{
				username: password,
			},
		}

		err := srv.ListenAndWrite(ctx)
		if !errors.Is(err, context.Canceled) {
			t.Errorf("Server.ListenAndWrite() = %v, want %v", err, context.Canceled)
		}
		close(ch)
	}()

	var want []*api.ValueList
	go func() {
		client, err := network.Dial(conn.LocalAddr().String(),
			network.ClientOptions{
				SecurityLevel: network.Encrypt,
				Username:      username,
				Password:      password,
			})
		if err != nil {
			t.Fatal(err)
		}

		vl := &api.ValueList{
			Identifier: api.Identifier{
				Host:   "example.com",
				Plugin: "TestNetwork",
				Type:   "gauge",
			},
			Time:     time.Unix(1588164686, 0),
			Interval: 10 * time.Second,
			Values:   []api.Value{api.Gauge(42)},
		}

		for i := 0; i < 30; i++ {
			if err := client.Write(ctx, vl); err != nil {
				t.Errorf("client.Write() = %v", err)
				break
			}
			want = append(want, vl.Clone())

			vl.Time = vl.Time.Add(vl.Interval)
		}

		if err := client.Close(); err != nil {
			t.Errorf("client.Close() = %v", err)
		}
	}()

	var got []*api.ValueList
loop:
	for {
		select {
		case vl, ok := <-ch:
			if !ok {
				break loop
			}
			got = append(got, vl)
		case <-time.After(100 * time.Millisecond):
			// cancel the context so the server returns.
			cancel()
		}
	}

	if diff := cmp.Diff(want, got, cmpopts.EquateEmpty()); diff != "" {
		t.Errorf("sent and received value lists differ (+got/-want):\n%s", diff)
	}
}