Skip to content

Commit

Permalink
Cisco logical channels (#3470)
Browse files Browse the repository at this point in the history
* uncorrectable_frames deviation

* uncorrectable_frames deviation

* pm + logical-channels deviations

* fec blocks

* revert

* firmware version

* deviation for tunable params test

* error fix

* error fix

* error fix

* error fix

* PR suggestions

* PR changes

* metadata changes

* logical channels changes

* cisco channel changes

* cleanup redundant code

* fix errors

---------

Co-authored-by: ahsaanyousaf <[email protected]>
  • Loading branch information
karthikeya-remilla and ahsaanyousaf authored Nov 18, 2024
1 parent 61ba135 commit fd12118
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,14 @@ platform_exceptions: {
missing_port_to_optical_channel_component_mapping: true
}
}
platform_exceptions: {
platform: {
vendor: CISCO
}
deviations: {
otn_channel_trib_unsupported: true
eth_channel_ingress_parameters_unsupported: true
eth_channel_assignment_cisco_numbering: true
otn_channel_assignment_cisco_numbering: true
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package zr_logical_channels_test

import (
"flag"
"strings"
"testing"
"time"

"github.com/google/go-cmp/cmp"
"github.com/openconfig/featureprofiles/internal/attrs"
"github.com/openconfig/featureprofiles/internal/cfgplugins"
"github.com/openconfig/featureprofiles/internal/components"
"github.com/openconfig/featureprofiles/internal/deviations"
"github.com/openconfig/featureprofiles/internal/fptest"
"github.com/openconfig/featureprofiles/internal/samplestream"
"github.com/openconfig/ondatra"
Expand All @@ -18,7 +21,6 @@ import (
const (
targetOutputPower = -9
frequency = 193100000
dp16QAM = 1
samplingInterval = 10 * time.Second
timeout = 10 * time.Minute
otnIndex1 = uint32(4001)
Expand All @@ -33,21 +35,32 @@ var (
IPv4: "192.0.2.1",
IPv4Len: 30,
}

dutPort2 = attrs.Attributes{
Desc: "dutPort2",
IPv4: "192.0.2.5",
IPv4Len: 30,
}
operationalModeFlag = flag.Int("operational_mode", 1, "vendor-specific operational-mode for the channel")
operationalMode uint16
)

type testcase struct {
desc string
got any
want any
}

func TestMain(m *testing.M) {
fptest.RunTests(m)
}

func Test400ZRLogicalChannels(t *testing.T) {
dut := ondatra.DUT(t, "dut")

if operationalModeFlag != nil {
operationalMode = uint16(*operationalModeFlag)
} else {
t.Fatalf("Please specify the vendor-specific operational-mode flag")
}
p1 := dut.Port(t, "port1")
p2 := dut.Port(t, "port2")

Expand All @@ -61,10 +74,10 @@ func Test400ZRLogicalChannels(t *testing.T) {
tr1 := gnmi.Get(t, dut, gnmi.OC().Interface(p1.Name()).Transceiver().State())
tr2 := gnmi.Get(t, dut, gnmi.OC().Interface(p2.Name()).Transceiver().State())

cfgplugins.ConfigOpticalChannel(t, dut, oc1, frequency, targetOutputPower, dp16QAM)
cfgplugins.ConfigOpticalChannel(t, dut, oc1, frequency, targetOutputPower, operationalMode)
cfgplugins.ConfigOTNChannel(t, dut, oc1, otnIndex1, ethernetIndex1)
cfgplugins.ConfigETHChannel(t, dut, p1.Name(), tr1, otnIndex1, ethernetIndex1)
cfgplugins.ConfigOpticalChannel(t, dut, oc2, frequency, targetOutputPower, dp16QAM)
cfgplugins.ConfigOpticalChannel(t, dut, oc2, frequency, targetOutputPower, operationalMode)
cfgplugins.ConfigOTNChannel(t, dut, oc2, otnIndex2, ethernetIndex2)
cfgplugins.ConfigETHChannel(t, dut, p2.Name(), tr2, otnIndex2, ethernetIndex2)

Expand All @@ -80,13 +93,13 @@ func Test400ZRLogicalChannels(t *testing.T) {
gnmi.Await(t, dut, gnmi.OC().Interface(p1.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP)
gnmi.Await(t, dut, gnmi.OC().Interface(p2.Name()).OperStatus().State(), timeout, oc.Interface_OperStatus_UP)

validateEthernetChannelTelemetry(t, otnIndex1, ethernetIndex1, ethChan1)
validateEthernetChannelTelemetry(t, otnIndex2, ethernetIndex2, ethChan2)
validateOTNChannelTelemetry(t, otnIndex1, ethernetIndex1, oc1, otnChan1)
validateOTNChannelTelemetry(t, otnIndex2, ethernetIndex2, oc2, otnChan2)
validateEthernetChannelTelemetry(t, dut, otnIndex1, ethernetIndex1, ethChan1)
validateEthernetChannelTelemetry(t, dut, otnIndex2, ethernetIndex2, ethChan2)
validateOTNChannelTelemetry(t, dut, otnIndex1, ethernetIndex1, oc1, otnChan1)
validateOTNChannelTelemetry(t, dut, otnIndex2, ethernetIndex2, oc2, otnChan2)
}

func validateEthernetChannelTelemetry(t *testing.T, otnChIdx, ethernetChIdx uint32, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) {
func validateEthernetChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnChIdx, ethernetChIdx uint32, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) {
val := stream.Next() // value received in the gnmi subscription within 10 seconds
if val == nil {
t.Fatalf("Ethernet Channel telemetry stream not received in last 10 seconds")
Expand All @@ -95,11 +108,7 @@ func validateEthernetChannelTelemetry(t *testing.T, otnChIdx, ethernetChIdx uint
if !ok {
t.Fatalf("Ethernet Channel telemetry stream empty in last 10 seconds")
}
tcs := []struct {
desc string
got any
want any
}{
tcs := []testcase{
{
desc: "Index",
got: ec.GetIndex(),
Expand All @@ -120,32 +129,64 @@ func validateEthernetChannelTelemetry(t *testing.T, otnChIdx, ethernetChIdx uint
got: ec.GetTribProtocol().String(),
want: oc.TransportTypes_TRIBUTARY_PROTOCOL_TYPE_PROT_400GE.String(),
},
{
desc: "Assignment: Index",
got: ec.GetAssignment(0).GetIndex(),
want: uint32(0),
},
{
desc: "Assignment: Logical Channel",
got: ec.GetAssignment(0).GetLogicalChannel(),
want: otnChIdx,
},
{
desc: "Assignment: Description",
got: ec.GetAssignment(0).GetDescription(),
want: "ETH to OTN",
},
{
desc: "Assignment: Allocation",
got: ec.GetAssignment(0).GetAllocation(),
want: float64(400),
},
{
desc: "Assignment: Type",
got: ec.GetAssignment(0).GetAssignmentType().String(),
want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(),
},
}
var assignmentIndexTestcases []testcase

if deviations.EthChannelAssignmentCiscoNumbering(dut) {
assignmentIndexTestcases = []testcase{
{
desc: "Assignment: Index",
got: ec.GetAssignment(1).GetIndex(),
want: uint32(1)},
{
desc: "Assignment: Logical Channel",
got: ec.GetAssignment(1).GetLogicalChannel(),
want: otnChIdx,
},
{
desc: "Assignment: Description",
got: ec.GetAssignment(1).GetDescription(),
want: "ETH to OTN",
},
{
desc: "Assignment: Allocation",
got: ec.GetAssignment(1).GetAllocation(),
want: float64(400),
},
{
desc: "Assignment: Type",
got: ec.GetAssignment(1).GetAssignmentType().String(),
want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(),
}}
} else {
assignmentIndexTestcases = []testcase{
{
desc: "Assignment: Index",
got: ec.GetAssignment(0).GetIndex(),
want: uint32(0),
},
{
desc: "Assignment: Logical Channel",
got: ec.GetAssignment(0).GetLogicalChannel(),
want: otnChIdx,
},
{
desc: "Assignment: Description",
got: ec.GetAssignment(0).GetDescription(),
want: "ETH to OTN",
},
{
desc: "Assignment: Allocation",
got: ec.GetAssignment(0).GetAllocation(),
want: float64(400),
},
{
desc: "Assignment: Type",
got: ec.GetAssignment(0).GetAssignmentType().String(),
want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(),
}}
}
tcs = append(tcs, assignmentIndexTestcases...)
for _, tc := range tcs {
t.Run(tc.desc, func(t *testing.T) {
if diff := cmp.Diff(tc.got, tc.want); diff != "" {
Expand All @@ -155,7 +196,7 @@ func validateEthernetChannelTelemetry(t *testing.T, otnChIdx, ethernetChIdx uint
}
}

func validateOTNChannelTelemetry(t *testing.T, otnChIdx uint32, ethChIdx uint32, opticalChannel string, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) {
func validateOTNChannelTelemetry(t *testing.T, dut *ondatra.DUTDevice, otnChIdx uint32, ethChIdx uint32, opticalChannel string, stream *samplestream.SampleStream[*oc.TerminalDevice_Channel]) {
val := stream.Next() // value received in the gnmi subscription within 10 seconds
if val == nil {
t.Fatalf("OTN Channel telemetry stream not received in last 10 seconds")
Expand All @@ -164,11 +205,7 @@ func validateOTNChannelTelemetry(t *testing.T, otnChIdx uint32, ethChIdx uint32,
if !ok {
t.Fatalf("OTN Channel telemetry stream empty in last 10 seconds")
}
tcs := []struct {
desc string
got any
want any
}{
tcs := []testcase{
{
desc: "Description",
got: cc.GetDescription(),
Expand All @@ -184,56 +221,97 @@ func validateOTNChannelTelemetry(t *testing.T, otnChIdx uint32, ethChIdx uint32,
got: cc.GetLogicalChannelType().String(),
want: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_OTN.String(),
},
{
desc: "Optical Channel Assignment: Index",
got: cc.GetAssignment(0).GetIndex(),
want: uint32(0),
},
{
desc: "Optical Channel Assignment: Optical Channel",
got: cc.GetAssignment(0).GetOpticalChannel(),
want: opticalChannel,
},
{
desc: "Optical Channel Assignment: Description",
got: cc.GetAssignment(0).GetDescription(),
want: "OTN to Optical Channel",
},
{
desc: "Optical Channel Assignment: Allocation",
got: cc.GetAssignment(0).GetAllocation(),
want: float64(400),
},
{
desc: "Optical Channel Assignment: Type",
got: cc.GetAssignment(0).GetAssignmentType().String(),
want: oc.Assignment_AssignmentType_OPTICAL_CHANNEL.String(),
},
{
desc: "Ethernet Assignment: Index",
got: cc.GetAssignment(1).GetIndex(),
want: uint32(1),
},
{
desc: "Ethernet Assignment: Logical Channel",
got: cc.GetAssignment(1).GetLogicalChannel(),
want: ethChIdx,
},
{
desc: "Ethernet Assignment: Description",
got: cc.GetAssignment(1).GetDescription(),
want: "OTN to ETH",
},
{
desc: "Ethernet Assignment: Allocation",
got: cc.GetAssignment(1).GetAllocation(),
want: float64(400),
},
{
desc: "Ethernet Assignment: Type",
got: cc.GetAssignment(1).GetAssignmentType().String(),
want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(),
},
}
var opticalChannelAssignmentIndexTestcases []testcase

if deviations.OTNChannelAssignmentCiscoNumbering(dut) {
ciscoOpticalChannelFormat := strings.ReplaceAll(opticalChannel, "/", "_") // Ex: OpticalChannel0_0_0_18
opticalChannelAssignmentIndexTestcases = []testcase{
{
desc: "Assignment: Index",
got: cc.GetAssignment(1).GetIndex(),
want: uint32(1),
},
{
desc: "Optical Channel Assignment: Optical Channel",
got: cc.GetAssignment(1).GetOpticalChannel(),
want: ciscoOpticalChannelFormat,
},
{
desc: "Optical Channel Assignment: Description",
got: cc.GetAssignment(1).GetDescription(),
want: "OTN to Optical Channel",
},
{
desc: "Optical Channel Assignment: Allocation",
got: cc.GetAssignment(1).GetAllocation(),
want: float64(400),
},
{
desc: "Optical Channel Assignment: Type",
got: cc.GetAssignment(1).GetAssignmentType().String(),
want: oc.Assignment_AssignmentType_OPTICAL_CHANNEL.String(),
},
}
} else {
opticalChannelAssignmentIndexTestcases = []testcase{
{
desc: "Assignment: Index",
got: cc.GetAssignment(0).GetIndex(),
want: uint32(0)},
{
desc: "Optical Channel Assignment: Optical Channel",
got: cc.GetAssignment(0).GetOpticalChannel(),
want: opticalChannel,
},
{
desc: "Optical Channel Assignment: Description",
got: cc.GetAssignment(0).GetDescription(),
want: "OTN to Optical Channel",
},
{
desc: "Optical Channel Assignment: Allocation",
got: cc.GetAssignment(0).GetAllocation(),
want: float64(400),
},
{
desc: "Optical Channel Assignment: Type",
got: cc.GetAssignment(0).GetAssignmentType().String(),
want: oc.Assignment_AssignmentType_OPTICAL_CHANNEL.String(),
},
}
}
tcs = append(tcs, opticalChannelAssignmentIndexTestcases...)

if !deviations.OTNChannelTribUnsupported(dut) {
logicalChannelAssignmentTestcases := []testcase{
{
desc: "Ethernet Assignment: Index",
got: cc.GetAssignment(1).GetIndex(),
want: uint32(1),
},
{
desc: "Ethernet Assignment: Logical Channel",
got: cc.GetAssignment(1).GetLogicalChannel(),
want: ethChIdx,
},
{
desc: "Ethernet Assignment: Description",
got: cc.GetAssignment(1).GetDescription(),
want: "OTN to ETH",
},
{
desc: "Ethernet Assignment: Allocation",
got: cc.GetAssignment(1).GetAllocation(),
want: float64(400),
},
{
desc: "Ethernet Assignment: Type",
got: cc.GetAssignment(1).GetAssignmentType().String(),
want: oc.Assignment_AssignmentType_LOGICAL_CHANNEL.String(),
},
}
tcs = append(tcs, logicalChannelAssignmentTestcases...)
}

for _, tc := range tcs {
Expand Down
5 changes: 5 additions & 0 deletions internal/deviations/deviations.go
Original file line number Diff line number Diff line change
Expand Up @@ -1207,3 +1207,8 @@ func EnableMultipathUnderAfiSafi(dut *ondatra.DUTDevice) bool {
func BgpAllowownasDiffDefaultValue(dut *ondatra.DUTDevice) bool {
return lookupDUTDeviations(dut).GetBgpAllowownasDiffDefaultValue()
}

// OTNChannelAssignmentCiscoNumbering returns true if OTN channel assignment index starts from 1 instead of 0
func OTNChannelAssignmentCiscoNumbering(dut *ondatra.DUTDevice) bool {
return lookupDUTDeviations(dut).GetOtnChannelAssignmentCiscoNumbering()
}
3 changes: 2 additions & 1 deletion proto/metadata.proto
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,8 @@ message Metadata {
// Device have different default value for allow own as.
// Juniper : b/373559004
bool bgp_allowownas_diff_default_value = 231;

// Cisco numbering for OTN channel assignment starts from 1 instead of 0
bool otn_channel_assignment_cisco_numbering = 232;
// Reserved field numbers and identifiers.
reserved 84, 9, 28, 20, 90, 97, 55, 89, 19, 36, 35, 40, 173;
}
Expand Down
Loading

0 comments on commit fd12118

Please sign in to comment.