Skip to content

Commit

Permalink
Adding test files for 400G ZR++ logical channel test and tunable para…
Browse files Browse the repository at this point in the history
…meter test (#3712)

* adding test files for 400G ZR++ logical channel test and tunable parameter test

* modified the cisco deviation part
  • Loading branch information
jianchen-g authored Jan 27, 2025
1 parent 0fce440 commit 79aa0be
Show file tree
Hide file tree
Showing 6 changed files with 639 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# TRANSCEIVER-11: Telemetry: 400ZR_PLUS Optics logical channels provisioning and related telemetry.
# TRANSCEIVER-11 (400ZR_PLUS): Telemetry: 400ZR_PLUS Optics logical channels provisioning and related telemetry.

## Summary

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto
# proto-message: Metadata
uuid: "e5b469c9-f765-4f95-b3dc-af4c926309f5"
plan_id: "TRANSCEIVER-11 (400ZR_PLUS)"
description: "Telemetry: 400ZR_PLUS Optics logical channels provisioning and related telemetry."
testbed: TESTBED_DUT_400ZR_PLUS
platform_exceptions: {
platform: {
vendor: ARISTA
}
deviations: {
interface_enabled: true
default_network_instance: "default"
missing_port_to_optical_channel_component_mapping: true
channel_assignment_rate_class_parameters_unsupported: 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
@@ -0,0 +1,280 @@
package zrp_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"
"github.com/openconfig/ondatra/gnmi"
"github.com/openconfig/ondatra/gnmi/oc"
)

const (
targetOutputPower = -3
frequency = 193100000
samplingInterval = 10 * time.Second
timeout = 10 * time.Minute
otnIndex1 = uint32(4001)
otnIndex2 = uint32(4002)
ethernetIndex1 = uint32(40001)
ethernetIndex2 = uint32(40002)
)

var (
dutPort1 = attrs.Attributes{
Desc: "dutPort1",
IPv4: "192.0.2.1",
IPv4Len: 30,
}
dutPort2 = attrs.Attributes{
Desc: "dutPort2",
IPv4: "192.0.2.5",
IPv4Len: 30,
}
operationalModeFlag = flag.Int("operational_mode", 5, "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")

fptest.ConfigureDefaultNetworkInstance(t, dut)

gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut))
gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut))

oc1 := components.OpticalChannelComponentFromPort(t, dut, p1)
oc2 := components.OpticalChannelComponentFromPort(t, dut, p2)
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, operationalMode)
cfgplugins.ConfigOTNChannel(t, dut, oc1, otnIndex1, ethernetIndex1)
cfgplugins.ConfigETHChannel(t, dut, p1.Name(), tr1, otnIndex1, ethernetIndex1)
cfgplugins.ConfigOpticalChannel(t, dut, oc2, frequency, targetOutputPower, operationalMode)
cfgplugins.ConfigOTNChannel(t, dut, oc2, otnIndex2, ethernetIndex2)
cfgplugins.ConfigETHChannel(t, dut, p2.Name(), tr2, otnIndex2, ethernetIndex2)

ethChan1 := samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(ethernetIndex1).State(), samplingInterval)
defer ethChan1.Close()
ethChan2 := samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(ethernetIndex2).State(), samplingInterval)
defer ethChan2.Close()
otnChan1 := samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(otnIndex1).State(), samplingInterval)
defer otnChan1.Close()
otnChan2 := samplestream.New(t, dut, gnmi.OC().TerminalDevice().Channel(otnIndex2).State(), samplingInterval)
defer otnChan2.Close()

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, 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, 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")
}
ec, ok := val.Val()
if !ok {
t.Fatalf("Ethernet Channel telemetry stream empty in last 10 seconds")
}
tcs := []testcase{
{
desc: "Index",
got: ec.GetIndex(),
want: ethernetChIdx,
},
{
desc: "Description",
got: ec.GetDescription(),
want: "ETH Logical Channel",
},
{
desc: "Logical Channel Type",
got: ec.GetLogicalChannelType().String(),
want: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_ETHERNET.String(),
},
{
desc: "Trib Protocol",
got: ec.GetTribProtocol().String(),
want: oc.TransportTypes_TRIBUTARY_PROTOCOL_TYPE_PROT_400GE.String(),
},
}
var assignmentIndexTestcases []testcase

index := 0
if deviations.EthChannelAssignmentCiscoNumbering(dut) {
index = 1
}

assignment := ec.GetAssignment(uint32(index))
assignmentIndexTestcases = []testcase{
{
desc: "Assignment: Index",
got: assignment.GetIndex(),
want: uint32(index),
},
{
desc: "Assignment: Logical Channel",
got: assignment.GetLogicalChannel(),
want: otnChIdx,
},
{
desc: "Assignment: Description",
got: assignment.GetDescription(),
want: "ETH to OTN",
},
{
desc: "Assignment: Allocation",
got: assignment.GetAllocation(),
want: float64(400),
},
{
desc: "Assignment: Type",
got: assignment.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 != "" {
t.Errorf("Ethernet Logical Channel: %s, diff (-got +want):\n%s", tc.desc, diff)
}
})
}
}

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")
}
cc, ok := val.Val()
if !ok {
t.Fatalf("OTN Channel telemetry stream empty in last 10 seconds")
}
tcs := []testcase{
{
desc: "Description",
got: cc.GetDescription(),
want: "OTN Logical Channel",
},
{
desc: "Index",
got: cc.GetIndex(),
want: otnChIdx,
},
{
desc: "Logical Channel Type",
got: cc.GetLogicalChannelType().String(),
want: oc.TransportTypes_LOGICAL_ELEMENT_PROTOCOL_TYPE_PROT_OTN.String(),
},
}
var opticalChannelAssignmentIndexTestcases []testcase

index := 0
if deviations.OTNChannelAssignmentCiscoNumbering(dut) {
opticalChannel = strings.ReplaceAll(opticalChannel, "/", "_") // Ex: ciscoOpticalChannelFormat is OpticalChannel0_0_0_18
index = 1
}

assignment := cc.GetAssignment(uint32(index))
opticalChannelAssignmentIndexTestcases = []testcase{
{
desc: "Assignment: Index",
got: assignment.GetIndex(),
want: uint32(index),
},
{
desc: "Optical Channel Assignment: Optical Channel",
got: assignment.GetOpticalChannel(),
want: opticalChannel,
},
{
desc: "Optical Channel Assignment: Description",
got: assignment.GetDescription(),
want: "OTN to Optical Channel",
},
{
desc: "Optical Channel Assignment: Allocation",
got: assignment.GetAllocation(),
want: float64(400),
},
{
desc: "Optical Channel Assignment: Type",
got: assignment.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 {
t.Run(tc.desc, func(t *testing.T) {
if diff := cmp.Diff(tc.got, tc.want); diff != "" {
t.Errorf("OTN Logical Channel: %s, diff (-got +want):\n%s", tc.desc, diff)
}
})
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# TRANSCEIVER-5: Configuration: 400ZR_PLUS channel frequency, output TX launch power and operational mode setting.
# TRANSCEIVER-5 (400ZR_PLUS): Configuration: 400ZR_PLUS channel frequency, output TX launch power and operational mode setting.

## Summary

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto
# proto-message: Metadata
uuid: "0ff18ddb-5333-4fc3-a2fb-5ac6d372a88f"
plan_id: "TRANSCEIVER-5 (400ZR_PLUS)"
description: "Configuration: 400ZR_PLUS channel frequency, output TX launch power and operational mode setting."
testbed: TESTBED_DUT_400ZR_PLUS
platform_exceptions: {
platform: {
vendor: ARISTA
}
deviations: {
interface_enabled: true
default_network_instance: "default"
missing_zr_optical_channel_tunable_parameters_telemetry: true
}
}
platform_exceptions: {
platform: {
vendor: JUNIPER
}
deviations: {
operational_mode_unsupported: true
}
}
Loading

0 comments on commit 79aa0be

Please sign in to comment.