Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions gnmi_server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,26 @@ func initFullCountersDb(t *testing.T, namespace string) {
aclRule1Counter := loadConfig(t, "COUNTERS:oid:0x9000000000711", aclRule1CounterByte)
loadDB(t, rclient, aclRule1Counter)

// Load PORT_PHY_ATTR data for Ethernet68 -> oid:0x1000000000039
fileName = "../testdata/PORT_PHY_ATTR:oid:0x1000000000039.txt"
phyAttrEth68Byte, err := os.ReadFile(fileName)
if err != nil {
t.Fatalf("failed to open %s, err: %v", fileName, err)
}

phyAttrEth68 := loadConfig(t, "PORT_PHY_ATTR:oid:0x1000000000039", phyAttrEth68Byte)
loadDB(t, rclient, phyAttrEth68)

// Load PORT_PHY_ATTR data for Ethernet1 -> oid:0x1000000000003
fileName = "../testdata/PORT_PHY_ATTR:oid:0x1000000000003.txt"
phyAttrEth1Byte, err := os.ReadFile(fileName)
if err != nil {
t.Fatalf("failed to open %s, err: %v", fileName, err)
}

phyAttrEth1 := loadConfig(t, "PORT_PHY_ATTR:oid:0x1000000000003", phyAttrEth1Byte)
loadDB(t, rclient, phyAttrEth1)

fileName = "../testdata/COUNTERS_DEBUG_NAME_SWITCH_STAT_MAP.txt"
countersDebugNameSwitchStatMapByte, err := ioutil.ReadFile(fileName)
if err != nil {
Expand Down Expand Up @@ -1067,6 +1087,26 @@ func prepareDb(t *testing.T, namespace string) {
aclRule1Counter := loadConfig(t, "COUNTERS:oid:0x9000000000711", aclRule1CounterByte)
loadDB(t, rclient, aclRule1Counter)

// Load PORT_PHY_ATTR data for Ethernet68 -> oid:0x1000000000039
fileName = "../testdata/PORT_PHY_ATTR:oid:0x1000000000039.txt"
phyAttrEth68Byte, err := os.ReadFile(fileName)
if err != nil {
t.Fatalf("failed to open %s, err: %v", fileName, err)
}

phyAttrEth68 := loadConfig(t, "PORT_PHY_ATTR:oid:0x1000000000039", phyAttrEth68Byte)
loadDB(t, rclient, phyAttrEth68)

// Load PORT_PHY_ATTR data for Ethernet1 -> oid:0x1000000000003
fileName = "../testdata/PORT_PHY_ATTR:oid:0x1000000000003.txt"
phyAttrEth1Byte, err := os.ReadFile(fileName)
if err != nil {
t.Fatalf("failed to open %s, err: %v", fileName, err)
}

phyAttrEth1 := loadConfig(t, "PORT_PHY_ATTR:oid:0x1000000000003", phyAttrEth1Byte)
loadDB(t, rclient, phyAttrEth1)

fileName = "../testdata/COUNTERS:oid:0x54000000004f63.txt"
sid1_byte, err := os.ReadFile(fileName)
if err != nil {
Expand Down Expand Up @@ -1693,6 +1733,19 @@ func runGnmiTestGet(t *testing.T, namespace string) {
t.Fatalf("failed to open %s, err: %v", fileName, err)
}

// PORT_PHY_ATTR test vectors
fileName = "../testdata/PORT_PHY_ATTR:Ethernet_wildcard.json"
phyAttrWildcardByte, err := os.ReadFile(fileName)
if err != nil {
t.Fatalf("failed to open %s, err: %v", fileName, err)
}

fileName = "../testdata/PORT_PHY_ATTR:Ethernet_single_entry.json"
phyAttrSingleEntryByte, err := os.ReadFile(fileName)
if err != nil {
t.Fatalf("failed to open %s, err: %v", fileName, err)
}

stateDBPath := "STATE_DB"

ns, _ := sdcfg.GetDbDefaultNamespace()
Expand Down Expand Up @@ -1998,6 +2051,34 @@ func runGnmiTestGet(t *testing.T, namespace string) {
wantRetCode: codes.OK,
wantRespVal: countersAclSingleEntryByte,
valTest: true,
}, {
desc: "get PORT_PHY_ATTR:Ethernet*",
pathTarget: "COUNTERS_DB",
textPbPath: `
elem: <
name: "PORT_PHY_ATTR"
>
elem: <
name: "Ethernet*"
>
`,
wantRetCode: codes.OK,
wantRespVal: phyAttrWildcardByte,
valTest: true,
}, {
desc: "get PORT_PHY_ATTR:Ethernet68",
pathTarget: "COUNTERS_DB",
textPbPath: `
elem: <
name: "PORT_PHY_ATTR"
>
elem: <
name: "Ethernet68"
>
`,
wantRetCode: codes.OK,
wantRespVal: phyAttrSingleEntryByte,
valTest: true,
}, {
desc: "get COUNTERS:fcbb:bbbb:2::/48 -- malformed",
pathTarget: "COUNTERS_DB",
Expand Down Expand Up @@ -2492,6 +2573,26 @@ func runTestSubscribe(t *testing.T, namespace string) {
singleAclCounterJsonUpdate := make(map[string]interface{})
singleAclCounterJsonUpdate["DATAACL:RULE_1"] = tmp

// PORT_PHY_ATTR wildcard + single entry update for subscriptions
var phyAttrWildcardJson interface{}
fileName = "../testdata/PORT_PHY_ATTR:Ethernet_wildcard.json"
phyAttrWildcardJsonByte, err := ioutil.ReadFile(fileName)
if err != nil {
t.Fatalf("failed to open %s, err: %v", fileName, err)
}
err = json.Unmarshal(phyAttrWildcardJsonByte, &phyAttrWildcardJson)
if err != nil {
t.Fatalf("failed to unmarshal %s, err: %v", fileName, err)
}

tmp = map[string]interface{}{
"phy_rx_signal_detect": "{\"0\":\"T*\", \"1\":\"T*\", \"2\":\"F*\"}",
"pcs_fec_lane_alignment_lock": "{\"0\":\"F*\", \"1\":\"F*\", \"2\":\"F*\"}",
"rx_snr": "{\"0\":5385, \"1\":5385, \"2\":5385}",
}
singlePhyAttrJsonUpdate := make(map[string]interface{})
singlePhyAttrJsonUpdate["Ethernet68"] = tmp

fileName = "../testdata/COUNTERS:Ethernet_wildcard_Queues_alias.txt"
countersEthernetWildQueuesByte, err := ioutil.ReadFile(fileName)
if err != nil {
Expand Down Expand Up @@ -3748,6 +3849,75 @@ func runTestSubscribe(t *testing.T, namespace string) {
client.Update{Path: []string{"COUNTERS_DB", "COUNTERS", "ACL_RULE*"}, TS: time.Unix(0, 200), Val: mergeStrMaps(countersAclCountersWildcardJson, singleAclCounterJsonUpdate)},
},
},
{
desc: "poll query for PORT_PHY_ATTR/Ethernet*",
poll: 3,
q: client.Query{
Target: "COUNTERS_DB",
Type: client.Poll,
Queries: []client.Path{{"PORT_PHY_ATTR", "Ethernet*"}},
TLS: &tls.Config{InsecureSkipVerify: true},
},
updates: []tablePathValue{
// simulate phy_rx_signal_detect change on Ethernet68
{
dbName: "COUNTERS_DB",
tableName: "PORT_PHY_ATTR",
tableKey: "oid:0x1000000000039",
delimitor: ":",
field: "phy_rx_signal_detect",
value: "{\"0\":\"T*\", \"1\":\"T*\", \"2\":\"F*\"}",
},
},
wantNoti: []client.Notification{
client.Connected{},
client.Update{
Path: []string{"COUNTERS_DB", "PORT_PHY_ATTR", "Ethernet*"},
TS: time.Unix(0, 200),
Val: phyAttrWildcardJson,
},
client.Sync{},
client.Update{
Path: []string{"COUNTERS_DB", "PORT_PHY_ATTR", "Ethernet*"},
TS: time.Unix(0, 200),
Val: mergeStrMaps(phyAttrWildcardJson, singlePhyAttrJsonUpdate),
},
client.Sync{},
client.Update{
Path: []string{"COUNTERS_DB", "PORT_PHY_ATTR", "Ethernet*"},
TS: time.Unix(0, 200),
Val: mergeStrMaps(phyAttrWildcardJson, singlePhyAttrJsonUpdate),
},
client.Sync{},
client.Update{
Path: []string{"COUNTERS_DB", "PORT_PHY_ATTR", "Ethernet*"},
TS: time.Unix(0, 200),
Val: mergeStrMaps(phyAttrWildcardJson, singlePhyAttrJsonUpdate),
},
client.Sync{},
},
},
{
desc: "sample stream query for PORT_PHY_ATTR/Ethernet* with field value update",
q: createCountersDbQuerySampleMode(t, 0, false, "PORT_PHY_ATTR", "Ethernet*"),
generateIntervals: true,
updates: []tablePathValue{
{
dbName: "COUNTERS_DB",
tableName: "PORT_PHY_ATTR",
tableKey: "oid:0x1000000000039",
delimitor: ":",
field: "phy_rx_signal_detect",
value: "{\"0\":\"T*\", \"1\":\"T*\", \"2\":\"F*\"}",
},
},
wantNoti: []client.Notification{
client.Connected{},
client.Update{Path: []string{"COUNTERS_DB", "PORT_PHY_ATTR", "Ethernet*"}, TS: time.Unix(0, 200), Val: phyAttrWildcardJson},
client.Sync{},
client.Update{Path: []string{"COUNTERS_DB", "PORT_PHY_ATTR", "Ethernet*"}, TS: time.Unix(0, 200), Val: mergeStrMaps(phyAttrWildcardJson, singlePhyAttrJsonUpdate)},
},
},
}

sdc.NeedMock = true
Expand Down
23 changes: 17 additions & 6 deletions sonic_data_client/db_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,13 @@ func ValToResp(val Value) (*gnmipb.SubscribeResponse, error) {
}
}

// countersDbHasTableKeys returns true if the given COUNTERS_DB table stores
// data under per-object keys (e.g. COUNTERS, PORT_PHY_ATTR). Tables that are
// stored as a single hash without sub-keys return false.
func countersDbHasTableKeys(tableName string) bool {
return tableName == "COUNTERS" || tableName == "PORT_PHY_ATTR"
}

func GetTableKeySeparator(target string, ns string) (string, error) {
_, ok := spb.Target_value[target]
if !ok {
Expand All @@ -507,11 +514,15 @@ func GetRedisClientsForDb(target string) (redis_client_map map[string]*redis.Cli
return redis_client_map, err
}
for _, ns := range ns_list {
redis_client_map[ns] = Target2RedisDb[ns][target]
if client := Target2RedisDb[ns][target]; client != nil {
redis_client_map[ns] = client
}
}
} else {
ns, _ := sdcfg.GetDbDefaultNamespace()
redis_client_map[ns] = Target2RedisDb[ns][target]
if client := Target2RedisDb[ns][target]; client != nil {
redis_client_map[ns] = client
}
}
return redis_client_map, nil
}
Expand Down Expand Up @@ -887,8 +898,8 @@ func TableData2Msi(tblPath *tablePath, useKey bool, op *string, msi *map[string]

//Only table name provided
if tblPath.tableKey == "" {
// tables in COUNTERS_DB other than COUNTERS table doesn't have keys
if tblPath.dbName == "COUNTERS_DB" && tblPath.tableName != "COUNTERS" {
// tables in COUNTERS_DB other than COUNTERS/PORT_PHY_ATTR don't have keys
if tblPath.dbName == "COUNTERS_DB" && !countersDbHasTableKeys(tblPath.tableName) {
pattern = tblPath.tableName
} else {
pattern = tblPath.tableName + tblPath.delimitor + "*"
Expand Down Expand Up @@ -1458,8 +1469,8 @@ func dbTableKeySubscribe(c *DbClient, gnmiPath *gnmipb.Path, interval time.Durat
// Subscribe to keyspace notification
pattern := "__keyspace@" + strconv.Itoa(int(spb.Target_value[tblPath.dbName])) + "__:"
pattern += tblPath.tableName
if tblPath.dbName == "COUNTERS_DB" && tblPath.tableName != "COUNTERS" {
// tables in COUNTERS_DB other than COUNTERS don't have keys, skip delimitor
if tblPath.dbName == "COUNTERS_DB" && !countersDbHasTableKeys(tblPath.tableName) {
// tables in COUNTERS_DB without per-object keys, skip delimitor
} else {
pattern += tblPath.delimitor
}
Expand Down
16 changes: 8 additions & 8 deletions sonic_data_client/mixed_db_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -686,9 +686,9 @@ func (c *MixedDbClient) getDbtablePath(path *gnmipb.Path, value *gnmipb.TypedVal
tblPath.tableName = ""
if len(stringSlice) > 1 {
tblPath.tableName = stringSlice[1]
// tables in COUNTERS_DB other than COUNTERS table doesn't have keys
// tables in COUNTERS_DB other than COUNTERS/PORT_PHY_ATTR don't have keys
// Insert a dummy table key
if tblPath.dbName == "COUNTERS_DB" && tblPath.tableName != "COUNTERS" {
if tblPath.dbName == "COUNTERS_DB" && !countersDbHasTableKeys(tblPath.tableName) {
if len(stringSlice) == 2 {
stringSlice = append(stringSlice, "")
} else {
Expand Down Expand Up @@ -864,8 +864,8 @@ func (c *MixedDbClient) tableData2Msi(tblPath *tablePath, useKey bool, op *strin
}
} else if tblPath.tableKey == "" {
// Only table name provided
// tables in COUNTERS_DB other than COUNTERS table doesn't have keys
if tblPath.dbName == "COUNTERS_DB" && tblPath.tableName != "COUNTERS" {
// tables in COUNTERS_DB other than COUNTERS/PORT_PHY_ATTR don't have keys
if tblPath.dbName == "COUNTERS_DB" && !countersDbHasTableKeys(tblPath.tableName) {
pattern = tblPath.tableName
} else {
pattern = tblPath.tableName + tblPath.delimitor + "*"
Expand Down Expand Up @@ -1086,8 +1086,8 @@ func (c *MixedDbClient) handleTableData(tblPaths []tablePath) error {
if tblPath.operation == opRemove {
//Only table name provided
if tblPath.tableKey == "" {
// tables in COUNTERS_DB other than COUNTERS table doesn't have keys
if tblPath.dbName == "COUNTERS_DB" && tblPath.tableName != "COUNTERS" {
// tables in COUNTERS_DB other than COUNTERS/PORT_PHY_ATTR don't have keys
if tblPath.dbName == "COUNTERS_DB" && !countersDbHasTableKeys(tblPath.tableName) {
pattern = tblPath.tableName
} else {
pattern = tblPath.tableName + tblPath.delimitor + "*"
Expand Down Expand Up @@ -2049,8 +2049,8 @@ func (c *MixedDbClient) dbTableKeySubscribe(gnmiPath *gnmipb.Path, interval time
// Subscribe to keyspace notification
pattern := "__keyspace@" + strconv.Itoa(int(spb.Target_value[tblPath.dbName])) + "__:"
pattern += tblPath.tableName
if tblPath.dbName == "COUNTERS_DB" && tblPath.tableName != "COUNTERS" {
// tables in COUNTERS_DB other than COUNTERS don't have keys, skip delimitor
if tblPath.dbName == "COUNTERS_DB" && !countersDbHasTableKeys(tblPath.tableName) {
// tables in COUNTERS_DB without per-object keys, skip delimitor
} else {
pattern += tblPath.delimitor
}
Expand Down
Loading