diff --git a/dialout/dialout_client/dialout_client_test.go b/dialout/dialout_client/dialout_client_test.go index 1a8b76ebd..6ab03f04e 100644 --- a/dialout/dialout_client/dialout_client_test.go +++ b/dialout/dialout_client/dialout_client_test.go @@ -194,6 +194,14 @@ func prepareDb(t *testing.T) { mpi_name_map := loadConfig(t, "COUNTERS_PORT_NAME_MAP", countersPortNameMapByte) loadDB(t, rclient, mpi_name_map) + fileName = "../../testdata/COUNTERS_QUEUE_NAME_MAP.txt" + countersQueueNameMapByte, err := ioutil.ReadFile(fileName) + if err != nil { + t.Fatalf("read file %v err: %v", fileName, err) + } + mpi_qname_map := loadConfig(t, "COUNTERS_QUEUE_NAME_MAP", countersQueueNameMapByte) + loadDB(t, rclient, mpi_qname_map) + fileName = "../../testdata/COUNTERS:Ethernet68.txt" countersEthernet68Byte, err := ioutil.ReadFile(fileName) if err != nil { @@ -221,6 +229,33 @@ func prepareDb(t *testing.T) { mpi_counter = loadConfig(t, "COUNTERS:oid:0x1500000000092a", counters92aByte) loadDB(t, rclient, mpi_counter) + // "Ethernet68:1": "oid:0x1500000000091c" : queue counter, for COUNTERS/Ethernet68/Queue vpath test + fileName = "../../testdata/COUNTERS:oid:0x1500000000091c.txt" + countersEeth68_1Byte, err := ioutil.ReadFile(fileName) + if err != nil { + t.Fatalf("read file %v err: %v", fileName, err) + } + mpi_counter = loadConfig(t, "COUNTERS:oid:0x1500000000091c", countersEeth68_1Byte) + loadDB(t, rclient, mpi_counter) + + // "Ethernet68:3": "oid:0x1500000000091e" : lossless queue counter, for COUNTERS/Ethernet68/Pfcwd vpath test + fileName = "../../testdata/COUNTERS:oid:0x1500000000091e.txt" + countersEeth68_3Byte, err := ioutil.ReadFile(fileName) + if err != nil { + t.Fatalf("read file %v err: %v", fileName, err) + } + mpi_counter = loadConfig(t, "COUNTERS:oid:0x1500000000091e", countersEeth68_3Byte) + loadDB(t, rclient, mpi_counter) + + // "Ethernet68:4": "oid:0x1500000000091f" : lossless queue counter, for COUNTERS/Ethernet68/Pfcwd vpath test + fileName = "../../testdata/COUNTERS:oid:0x1500000000091f.txt" + countersEeth68_4Byte, err := ioutil.ReadFile(fileName) + if err != nil { + t.Fatalf("read file %v err: %v", fileName, err) + } + mpi_counter = loadConfig(t, "COUNTERS:oid:0x1500000000091f", countersEeth68_4Byte) + loadDB(t, rclient, mpi_counter) + // Load CONFIG_DB for alias translation prepareConfigDb(t) } @@ -275,6 +310,37 @@ func compareUpdateValue(t *testing.T, want *pb.Notification, got *pb.Notificatio } +func compareUpdatePath(t *testing.T, want *pb.Notification, got *pb.Notification) { + gotUpdates := got.GetUpdate() + if len(gotUpdates) != 1 { + t.Fatalf("got %d updates in the notification, want 1", len(gotUpdates)) + } + + wantUpdates := want.GetUpdate() + if len(wantUpdates) != 1 { + t.Fatalf("got %d updates in the notification, want 1", len(wantUpdates)) + } + + gotPath := gotUpdates[0].GetPath().GetElem() + wantPath := wantUpdates[0].GetPath().GetElem() + + if len(gotPath) != len(wantPath) { + t.Errorf("got path: %v,\nwant path %v", gotPath, wantPath) + return + } + for i := range gotPath { + if gotPath[i].GetName() != wantPath[i].GetName() { + t.Errorf("got path: %v,\nwant path %v", gotPath, wantPath) + return + } + if !reflect.DeepEqual(gotPath[i].GetKey(), wantPath[i].GetKey()) { + t.Errorf("got path: %v,\nwant path %v", gotPath, wantPath) + return + } + } + +} + // Type defines the type of ServerOp. type ServerOp int @@ -341,6 +407,14 @@ func TestGNMIDialOutPublish(t *testing.T) { _ = countersEthernetWildcardPfcByte + fileName = "../../testdata/COUNTERS:Ethernet68:Queues.txt" + countersEthernet68QueuesByte, err := ioutil.ReadFile(fileName) + if err != nil { + t.Fatalf("read file %v err: %v", fileName, err) + } + + _ = countersEthernet68QueuesByte + clientCfg := ClientConfig{ SrcIp: "", RetryInterval: 5 * time.Second, @@ -368,6 +442,8 @@ func TestGNMIDialOutPublish(t *testing.T) { wantErr bool collector string wantRespVal interface{} + + comparePath bool }{{ desc: "DialOut to first collector in stream mode and synced", cmds: []string{ @@ -442,6 +518,174 @@ func TestGNMIDialOutPublish(t *testing.T) { }, }, }, + }, { + desc: "DialOut to first collector in periodic mode (COUNTERS_PORT_NAME_MAP)", + cmds: []string{ + "redis-cli -n 4 hset TELEMETRY_CLIENT|DestinationGroup_HS dst_addr 127.0.0.1:8080,127.0.0.1:8081", + "redis-cli -n 4 hmset TELEMETRY_CLIENT|Subscription_HS_RDMA path_target COUNTERS_DB dst_group HS report_type periodic report_interval 1000 paths COUNTERS_PORT_NAME_MAP", + }, + collector: "s1", + waitTime: time.Second*2, + wantRespVal: []*pb.SubscribeResponse{ + &pb.SubscribeResponse{ + Response: &pb.SubscribeResponse_Update{ + Update: &pb.Notification{ + Update: []*pb.Update{ + {Val: &pb.TypedValue{ + Value: &pb.TypedValue_JsonIetfVal{ + JsonIetfVal: countersPortNameMapByte, + }}, + }, + }, + }, + }, + }, + &pb.SubscribeResponse{ + Response: &pb.SubscribeResponse_Update{ + Update: &pb.Notification{ + Update: []*pb.Update{ + {Val: &pb.TypedValue{ + Value: &pb.TypedValue_JsonIetfVal{ + JsonIetfVal: countersPortNameMapByte, + }}, + }, + }, + }, + }, + }, + }, + }, { + desc: "DialOut to first collector in periodic mode (COUNTERS/Ethernet*)", + cmds: []string{ + "redis-cli -n 4 hset TELEMETRY_CLIENT|DestinationGroup_HS dst_addr 127.0.0.1:8080,127.0.0.1:8081", + "redis-cli -n 4 hmset TELEMETRY_CLIENT|Subscription_HS_RDMA path_target COUNTERS_DB dst_group HS report_type periodic report_interval 1000 paths COUNTERS/Ethernet*", + }, + collector: "s1", + waitTime: time.Second*2, + wantRespVal: []*pb.SubscribeResponse{ + &pb.SubscribeResponse{ + Response: &pb.SubscribeResponse_Update{ + Update: &pb.Notification{ + Update: []*pb.Update{ + {Val: &pb.TypedValue{ + Value: &pb.TypedValue_JsonIetfVal{ + JsonIetfVal: countersEthernetWildcardByte, + }}, + }, + }, + }, + }, + }, + &pb.SubscribeResponse{ + Response: &pb.SubscribeResponse_Update{ + Update: &pb.Notification{ + Update: []*pb.Update{ + {Val: &pb.TypedValue{ + Value: &pb.TypedValue_JsonIetfVal{ + JsonIetfVal: countersEthernetWildcardByte, + }}, + }, + }, + }, + }, + }, + }, + }, { + desc: "DialOut to second collector in periodic mode upon failure of first collector (COUNTERS/Ethernet68/Queues)", + cmds: []string{ + "redis-cli -n 4 hset TELEMETRY_CLIENT|DestinationGroup_HS dst_addr 127.0.0.1:8080,127.0.0.1:8081", + "redis-cli -n 4 hmset TELEMETRY_CLIENT|Subscription_HS_RDMA path_target COUNTERS_DB dst_group HS report_type periodic report_interval 1000 paths COUNTERS/Ethernet68/Queues", + }, + collector: "s2", + sop: S1Stop, + waitTime: clientCfg.RetryInterval + time.Second*2, + wantRespVal: []*pb.SubscribeResponse{ + &pb.SubscribeResponse{ + Response: &pb.SubscribeResponse_Update{ + Update: &pb.Notification{ + Update: []*pb.Update{ + {Val: &pb.TypedValue{ + Value: &pb.TypedValue_JsonIetfVal{ + JsonIetfVal: countersEthernet68QueuesByte, + }}, + }, + }, + }, + }, + }, + &pb.SubscribeResponse{ + Response: &pb.SubscribeResponse_Update{ + Update: &pb.Notification{ + Update: []*pb.Update{ + {Val: &pb.TypedValue{ + Value: &pb.TypedValue_JsonIetfVal{ + JsonIetfVal: countersEthernet68QueuesByte, + }}, + }, + }, + }, + }, + }, + }, + }, { + desc: "DialOut to second collector in periodic mode upon failure of first collector (platform/cpu)", + cmds: []string{ + "redis-cli -n 4 hset TELEMETRY_CLIENT|DestinationGroup_HS dst_addr 127.0.0.1:8080,127.0.0.1:8081", + "redis-cli -n 4 hmset TELEMETRY_CLIENT|Subscription_HS_RDMA path_target OTHERS dst_group HS report_type periodic report_interval 1000 paths platform/cpu", + }, + collector: "s2", + sop: S1Stop, + waitTime: clientCfg.RetryInterval + time.Second*2, + wantRespVal: []*pb.SubscribeResponse{ + &pb.SubscribeResponse{ + Response: &pb.SubscribeResponse_Update{ + Update: &pb.Notification{ + Update: []*pb.Update{ + {Val: &pb.TypedValue{ + Value: &pb.TypedValue_JsonIetfVal{ + JsonIetfVal: make([]uint8, 0), + }}, + Path: &pb.Path{ + Elem: []*pb.PathElem{ + &pb.PathElem{ + Name: "platform", + }, + &pb.PathElem{ + Name: "cpu", + }, + }, + }, + }, + }, + }, + }, + }, + &pb.SubscribeResponse{ + Response: &pb.SubscribeResponse_Update{ + Update: &pb.Notification{ + Update: []*pb.Update{ + { + Val: &pb.TypedValue{ + Value: &pb.TypedValue_JsonIetfVal{ + JsonIetfVal: make([]uint8, 0), + }}, + Path: &pb.Path{ + Elem: []*pb.PathElem{ + &pb.PathElem{ + Name: "platform", + }, + &pb.PathElem{ + Name: "cpu", + }, + }, + }, + }, + }, + }, + }, + }, + }, + comparePath: true, }} rclient := getRedisClient(t) @@ -490,8 +734,11 @@ func TestGNMIDialOutPublish(t *testing.T) { t.Fatalf("Expecting %v, got SyncResponse", resp.GetResponse()) } case *pb.SubscribeResponse_Update: - compareUpdateValue(t, resp.GetUpdate(), store[idx].GetUpdate()) - + if tt.comparePath{ + compareUpdatePath(t, resp.GetUpdate(), store[slen-wlen+idx].GetUpdate()) + } else { + compareUpdateValue(t, resp.GetUpdate(), store[slen-wlen+idx].GetUpdate()) + } } } }) diff --git a/gnmi_server/server_test.go b/gnmi_server/server_test.go index 040859b6f..3a3e5488d 100644 --- a/gnmi_server/server_test.go +++ b/gnmi_server/server_test.go @@ -558,6 +558,18 @@ func TestGnmiGet(t *testing.T) { t.Fatalf("read file %v err: %v", fileName, err) } + fileName = "../testdata/COUNTERS:Ethernet68:Queues.txt" + countersEthernet68QueuesByte, err := ioutil.ReadFile(fileName) + if err != nil { + t.Fatalf("read file %v err: %v", fileName, err) + } + + fileName = "../testdata/COUNTERS:Ethernet68:Queues_alias.txt" + countersEthernet68QueuesAliasByte, err := ioutil.ReadFile(fileName) + if err != nil { + t.Fatalf("read file %v err: %v", fileName, err) + } + fileName = "../testdata/COUNTERS:Ethernet_wildcard_alias.txt" countersEthernetWildcardByte, err := ioutil.ReadFile(fileName) if err != nil { @@ -576,6 +588,12 @@ func TestGnmiGet(t *testing.T) { t.Fatalf("read file %v err: %v", fileName, err) } + fileName = "../testdata/COUNTERS:Ethernet_wildcard_Queues_alias.txt" + countersEthernetWildcardQueuesByte, err := ioutil.ReadFile(fileName) + if err != nil { + t.Fatalf("read file %v err: %v", fileName, err) + } + tds := []struct { desc string pathTarget string @@ -612,6 +630,7 @@ func TestGnmiGet(t *testing.T) { `, wantRetCode: codes.OK, wantRespVal: countersPortNameMapByte, + valTest: true, }, { desc: "get COUNTERS:Ethernet68", pathTarget: "COUNTERS_DB", @@ -621,6 +640,7 @@ func TestGnmiGet(t *testing.T) { `, wantRetCode: codes.OK, wantRespVal: countersEthernet68Byte, + valTest: true, }, { desc: "get COUNTERS:Ethernet68 SAI_PORT_STAT_PFC_7_RX_PKTS", pathTarget: "COUNTERS_DB", @@ -631,6 +651,7 @@ func TestGnmiGet(t *testing.T) { `, wantRetCode: codes.OK, wantRespVal: "2", + valTest: true, }, { desc: "get COUNTERS:Ethernet68 Pfcwd", pathTarget: "COUNTERS_DB", @@ -641,6 +662,18 @@ func TestGnmiGet(t *testing.T) { `, wantRetCode: codes.OK, wantRespVal: countersEthernet68PfcwdByte, + valTest: true, + }, { + desc: "Get COUNTERS:Ethernet68 Queues", + pathTarget: "COUNTERS_DB", + textPbPath: ` + elem: + elem: + elem: + `, + wantRetCode: codes.OK, + wantRespVal: countersEthernet68QueuesByte, + valTest: true, }, { desc: "get COUNTERS (use vendor alias):Ethernet68/1", pathTarget: "COUNTERS_DB", @@ -650,6 +683,7 @@ func TestGnmiGet(t *testing.T) { `, wantRetCode: codes.OK, wantRespVal: countersEthernet68Byte, + valTest: true, }, { desc: "get COUNTERS (use vendor alias):Ethernet68/1 SAI_PORT_STAT_PFC_7_RX_PKTS", pathTarget: "COUNTERS_DB", @@ -660,6 +694,7 @@ func TestGnmiGet(t *testing.T) { `, wantRetCode: codes.OK, wantRespVal: "2", + valTest: true, }, { desc: "get COUNTERS (use vendor alias):Ethernet68/1 Pfcwd", pathTarget: "COUNTERS_DB", @@ -670,6 +705,18 @@ func TestGnmiGet(t *testing.T) { `, wantRetCode: codes.OK, wantRespVal: countersEthernet68PfcwdAliasByte, + valTest: true, + }, { + desc: "Get COUNTERS (use vendor alias):Ethernet68/1 Queues", + pathTarget: "COUNTERS_DB", + textPbPath: ` + elem: + elem: + elem: + `, + wantRetCode: codes.OK, + wantRespVal: countersEthernet68QueuesAliasByte, + valTest: true, }, { desc: "get COUNTERS:Ethernet*", pathTarget: "COUNTERS_DB", @@ -679,6 +726,7 @@ func TestGnmiGet(t *testing.T) { `, wantRetCode: codes.OK, wantRespVal: countersEthernetWildcardByte, + valTest: true, }, { desc: "get COUNTERS:Ethernet* SAI_PORT_STAT_PFC_7_RX_PKTS", pathTarget: "COUNTERS_DB", @@ -689,6 +737,7 @@ func TestGnmiGet(t *testing.T) { `, wantRetCode: codes.OK, wantRespVal: countersEthernetWildcardPfcByte, + valTest: true, }, { desc: "get COUNTERS:Ethernet* Pfcwd", pathTarget: "COUNTERS_DB", @@ -699,6 +748,26 @@ func TestGnmiGet(t *testing.T) { `, wantRetCode: codes.OK, wantRespVal: countersEthernetWildcardPfcwdByte, + valTest: true, + }, { + desc: "Get COUNTERS:Ethernet* Queues", + pathTarget: "COUNTERS_DB", + textPbPath: ` + elem: + elem: + elem: + `, + wantRetCode: codes.OK, + wantRespVal: countersEthernetWildcardQueuesByte, + valTest: true, + }, { + desc: "get non-db platform cpu", + pathTarget: "OTHERS", + textPbPath: ` + elem: + elem: + `, + wantRetCode: codes.OK, }, } @@ -1020,6 +1089,8 @@ func runTestSubscribe(t *testing.T) { json.Unmarshal(countersEthernet68QueuesAliasByte, &countersEthernet68QueuesAliasJsonUpdate) countersEthernet68QueuesAliasJsonUpdate["Ethernet68/1:1"] = eth68_1 + var emptyVal = make(map[string]string) + tests := []struct { desc string q client.Query @@ -1030,6 +1101,8 @@ func runTestSubscribe(t *testing.T) { poll int wantPollErr string + + comparePath bool }{{ desc: "stream query for table COUNTERS_PORT_NAME_MAP with new test_field field", q: client.Query{ @@ -1658,6 +1731,31 @@ func runTestSubscribe(t *testing.T) { TS: time.Unix(0, 200), Val: countersEthernet68QueuesAliasJsonUpdate}, client.Sync{}, }, + }, { + desc: "poll query for platform/cpu", + poll: 3, + q: client.Query{ + Target: "OTHERS", + Type: client.Poll, + Queries: []client.Path{{"platform", "cpu"}}, + TLS: &tls.Config{InsecureSkipVerify: true}, + }, + wantNoti: []client.Notification{ + client.Connected{}, + client.Update{Path: []string{"platform", "cpu"}, + TS: time.Unix(0, 200), Val: emptyVal}, + client.Sync{}, + client.Update{Path: []string{"platform", "cpu"}, + TS: time.Unix(0, 200), Val: emptyVal}, + client.Sync{}, + client.Update{Path: []string{"platform", "cpu"}, + TS: time.Unix(0, 200), Val: emptyVal}, + client.Sync{}, + client.Update{Path: []string{"platform", "cpu"}, + TS: time.Unix(0, 200), Val: emptyVal}, + client.Sync{}, + }, + comparePath: true, }} rclient := getRedisClient(t) @@ -1684,6 +1782,9 @@ func runTestSubscribe(t *testing.T) { //t.Logf("reflect.TypeOf(n) %v : %v", reflect.TypeOf(n), n) if nn, ok := n.(client.Update); ok { nn.TS = time.Unix(0, 200) + if tt.comparePath { + nn.Val = emptyVal + } gotNoti = append(gotNoti, nn) } else { gotNoti = append(gotNoti, n)