Files
nmon/internal/simagent/simagent_test.go

123 lines
3.5 KiB
Go

package simagent
import (
"context"
"strings"
"testing"
"time"
"github.com/gosnmp/gosnmp"
"github.com/v10networks/nmon/internal/snmprec"
)
const sample = `# comment
1.3.6.1.2.1.1.1.0|4|Linux box
1.3.6.1.2.1.1.2.0|6|1.3.6.1.4.1.8072.3.2.10
1.3.6.1.2.1.1.3.0|67|123456
1.3.6.1.2.1.1.4.0|4x|00ff7c
1.3.6.1.2.1.1.5.0|5|
1.3.6.1.2.1.4.20.1.1.10.0.0.1|64|10.0.0.1
1.3.6.1.2.1.2.2.1.5.1|66|1000000000
1.3.6.1.2.1.2.2.1.10.1|65|42
1.3.6.1.2.1.2.1.0|2|-3
1.3.6.1.2.1.31.1.1.1.6.1|70|18446744073709551615
1.3.6.1.2.1.1.9.0|68x|0102
1.3.6.1.2.1.1.9.0|68x|0304
.1.3.6.1.2.1.31.1.1.1.10.1|70:numeric|rate=125000,initial=7,wrap=999
`
func TestGetNextAndBulkSemantics(t *testing.T) {
rec, err := snmprec.Parse(strings.NewReader(sample))
if err != nil {
t.Fatal(err)
}
a, err := Start(context.Background(), Config{Recording: rec})
if err != nil {
t.Fatal(err)
}
defer func() { _ = a.Close() }() // test cleanup
g := &gosnmp.GoSNMP{
Target: a.Addr().Addr().String(), Port: a.Addr().Port(), Version: gosnmp.Version2c, Community: "public",
Timeout: time.Second, Retries: 0,
}
if err := g.Connect(); err != nil {
t.Fatal(err)
}
defer func() { _ = g.Close() }() // test cleanup
p, err := g.GetNext([]string{"1.3.6.1.2.1.31.1.1.1.10.1"})
if err != nil || len(p.Variables) != 1 || p.Variables[0].Type != gosnmp.EndOfMibView {
t.Fatalf("past the end: %v %+v", err, p)
}
// 2 repeaters from the start, one non-repeater: non-repeater first, then rows interleaved.
p, err = g.GetBulk([]string{"1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.3.0", "1.3.6.1.2.1.2.2.1.5"}, 1, 3)
if err != nil {
t.Fatal(err)
}
var names []string
for _, v := range p.Variables {
names = append(names, v.Name)
}
want := []string{
".1.3.6.1.2.1.1.2.0",
".1.3.6.1.2.1.1.4.0", ".1.3.6.1.2.1.2.2.1.5.1",
".1.3.6.1.2.1.1.5.0", ".1.3.6.1.2.1.2.2.1.10.1",
".1.3.6.1.2.1.1.9.0", ".1.3.6.1.2.1.4.20.1.1.10.0.0.1",
}
if strings.Join(names, ",") != strings.Join(want, ",") {
t.Fatalf("bulk order:\n got %v\nwant %v", names, want)
}
// Bulk off the end stops once every repeater is exhausted.
p, err = g.GetBulk([]string{"1.3.6.1.2.1.31.1.1.1.6.1"}, 0, 50)
if err != nil || len(p.Variables) != 2 || p.Variables[1].Type != gosnmp.EndOfMibView {
t.Fatalf("bulk tail: %v %+v", err, p.Variables)
}
// Set is refused.
if p, err = g.Set([]gosnmp.SnmpPDU{{Name: "1.3.6.1.2.1.1.5.0", Type: gosnmp.OctetString, Value: "x"}}); err != nil || p.Error == gosnmp.NoError {
t.Fatalf("set: %v %+v", err, p)
}
}
func TestPool(t *testing.T) {
rec, _ := snmprec.Parse(strings.NewReader(sample))
cfgs := make([]Config, 100)
for i := range cfgs {
cfgs[i] = Config{Recording: rec}
}
var p Pool
if err := p.Start(context.Background(), cfgs); err != nil {
t.Fatal(err)
}
seen := map[uint16]bool{}
for _, a := range p.Agents() {
seen[a.Addr().Port()] = true
}
if len(seen) != 100 {
t.Fatalf("%d distinct ports", len(seen))
}
if err := p.Close(); err != nil {
t.Fatal(err)
}
if err := p.Start(context.Background(), []Config{{Recording: rec}, {}}); err == nil || len(p.Agents()) != 0 {
t.Fatal("a failing config must leave the pool empty")
}
}
func TestContextCancelStopsAgent(t *testing.T) {
rec, _ := snmprec.Parse(strings.NewReader(sample))
ctx, cancel := context.WithCancel(context.Background())
a, err := Start(ctx, Config{Recording: rec})
if err != nil {
t.Fatal(err)
}
cancel()
done := make(chan struct{})
go func() { _ = a.Close(); close(done) }()
select {
case <-done:
case <-time.After(5 * time.Second):
t.Fatal("Close hung after cancel")
}
}