Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lx9FNLG2CqeBbVGGd9bFsP
123 lines
3.5 KiB
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")
|
|
}
|
|
}
|