Skip to content

Commit

Permalink
Merge branch 'main' into RT-1.32
Browse files Browse the repository at this point in the history
  • Loading branch information
cprabha authored Nov 21, 2024
2 parents bc4635f + b3d9c73 commit 762d2bd
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 63 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

# /feature folders each have owners who are auto requested for review and may merge PR's
/feature/acl/ @alokmtri-g
/feature/aft/ @sudhinj
/feature/aft/ @sudhinj @yunjie-lu
/feature/bgp/ @dplore
/feature/dhcp/ @alokmtri-g
/feature/ethernet/ @ram-mac
Expand Down
4 changes: 2 additions & 2 deletions feature/gribi/otg_tests/encap_decap_scale/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ network-instances {
* Add 1 VRF for decapsulation, `DECAP_TE_VRF`.
* Add 2 Tunnel VRFs, `TE_VRF_111` and `TE_VRF_222`.
* Inject 5000 IPv4Entry-ies and 5000 IPv6Entry-ies to each of the 4 encap VRFs.
* The entries in the encap VRFs should point to NextHopGroups in the `DEFAULT` VRF. Inject 200 such NextHopGroups in the DEFAULT VRF.
* The entries in the encap VRFs should point to NextHopGroups in the `DEFAULT` VRF. Inject 800 such NextHopGroups in the DEFAULT VRF.
* Each NextHopGroup should have 8 NextHops where each NextHop points to a tunnel in the `TE_VRF_111`. In addition, the weights specified in the NextHopGroup should be co-prime and the sum of the weights should be 16.
* Inject `48` entries in the DECAP_TE_VRF where the entries have a mix of prefix lengths /22, /24, /26, and /28.

Expand Down Expand Up @@ -395,7 +395,7 @@ network-instances {
* outer_src: `ipv4_outer_src_111`
* outer_dst: `ipv4_outer_decap_match`
* dscp: `dscp_encap_d`
* proto: `41`
* proto: `41`
```
3. Send traffic to DUT-1, covering all the installed v4 and v6 entries in the decap and encap VRFs. Validate that all traffic are all decapped per the DECAP VRFs and then encapsulated per the ENCAP VRFs and received as encapsulated packet by ATE.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ const (
teVrf111TunnelCount = 1600
teVrf222TunnelCount = 1600
encapNhCount = 1600
encapNhgcount = 200
encapNhgcount = 800
encapIPv4Count = 5000
encapIPv6Count = 5000
decapIPv4Count = 48
Expand Down Expand Up @@ -368,7 +368,7 @@ func createIPv6Entries(startIP string, count uint64) []string {

// pushEncapEntries pushes IP entries in a specified Encap VRFs and tunnel VRFs.
// The entries in the encap VRFs should point to NextHopGroups in the DEFAULT VRF.
// Inject 200 such NextHopGroups in the DEFAULT VRF. Each NextHopGroup should have
// Inject 800 such NextHopGroups in the DEFAULT VRF. Each NextHopGroup should have
// 8 NextHops where each NextHop points to a tunnel in the TE_VRF_111.
// In addition, the weights specified in the NextHopGroup should be co-prime and the
// sum of the weights should be 16.
Expand Down
11 changes: 11 additions & 0 deletions feature/platform/transceiver/tests/zr_pm_test/metadata.textproto
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,14 @@ platform_exceptions: {
default_network_instance: "default"
}
}
platform_exceptions: {
platform: {
vendor: CISCO
}
deviations: {
otn_channel_trib_unsupported: true
eth_channel_ingress_parameters_unsupported: true
eth_channel_assignment_cisco_numbering: true
cisco_pre_fec_ber_inactive_value: true
}
}
26 changes: 18 additions & 8 deletions feature/platform/transceiver/tests/zr_pm_test/zr_pm_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package zr_pm_test

import (
"flag"
"testing"
"time"

"github.com/openconfig/featureprofiles/internal/cfgplugins"
"github.com/openconfig/featureprofiles/internal/deviations"
"github.com/openconfig/featureprofiles/internal/fptest"
"github.com/openconfig/featureprofiles/internal/samplestream"
"github.com/openconfig/ondatra"
Expand All @@ -14,7 +16,6 @@ import (
)

const (
dp16QAM = uint16(1)
samplingInterval = 10 * time.Second
minAllowedQValue = 7.0
maxAllowedQValue = 14.0
Expand All @@ -26,14 +27,15 @@ const (
inactivePreFECBER = 0.0
inactiveESNR = 0.0
timeout = 10 * time.Minute
flapInterval = 30 * time.Second
otnIndexBase = uint32(4000)
ethernetIndexBase = uint32(40000)
)

var (
frequencies = []uint64{191400000, 196100000}
targetOpticalPowers = []float64{-9, -13}
operationalModeFlag = flag.Int("operational_mode", 1, "vendor-specific operational-mode for the channel")
operationalMode uint16
)

func TestMain(m *testing.M) {
Expand All @@ -42,7 +44,11 @@ func TestMain(m *testing.M) {

func TestPM(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")
}
fptest.ConfigureDefaultNetworkInstance(t, dut)

var (
Expand Down Expand Up @@ -71,7 +77,7 @@ func TestPM(t *testing.T) {
for _, targetOpticalPower := range targetOpticalPowers {
// Configure OCH component and OTN and ETH logical channels.
for _, p := range dut.Ports() {
cfgplugins.ConfigOpticalChannel(t, dut, ochs[p.Name()], frequency, targetOpticalPower, dp16QAM)
cfgplugins.ConfigOpticalChannel(t, dut, ochs[p.Name()], frequency, targetOpticalPower, operationalMode)
cfgplugins.ConfigOTNChannel(t, dut, ochs[p.Name()], otnIndexes[p.Name()], ethIndexes[p.Name()])
cfgplugins.ConfigETHChannel(t, dut, p.Name(), trs[p.Name()], otnIndexes[p.Name()], ethIndexes[p.Name()])
}
Expand Down Expand Up @@ -135,7 +141,7 @@ func validateAllSamples(t *testing.T, dut *ondatra.DUTDevice, isEnabled bool, in
if valIndex >= len(otnStreams[p.Name()].All()) {
break
}
operStatus := validateSampleStream(t, interfaceStreams[p.Name()].All()[valIndex], otnStreams[p.Name()].All()[valIndex], p.Name())
operStatus := validateSampleStream(t, dut, interfaceStreams[p.Name()].All()[valIndex], otnStreams[p.Name()].All()[valIndex], p.Name())
switch operStatus {
case oc.Interface_OperStatus_UP:
if !isEnabled {
Expand All @@ -151,7 +157,7 @@ func validateAllSamples(t *testing.T, dut *ondatra.DUTDevice, isEnabled bool, in
}

// validateSampleStream validates the stream data.
func validateSampleStream(t *testing.T, interfaceData *ygnmi.Value[*oc.Interface], terminalDeviceData *ygnmi.Value[*oc.TerminalDevice_Channel], portName string) oc.E_Interface_OperStatus {
func validateSampleStream(t *testing.T, dut *ondatra.DUTDevice, interfaceData *ygnmi.Value[*oc.Interface], terminalDeviceData *ygnmi.Value[*oc.TerminalDevice_Channel], portName string) oc.E_Interface_OperStatus {
if interfaceData == nil {
t.Errorf("Data not received for port %v.", portName)
return oc.Interface_OperStatus_UNSET
Expand Down Expand Up @@ -179,7 +185,11 @@ func validateSampleStream(t *testing.T, interfaceData *ygnmi.Value[*oc.Interface
if b := otn.GetPreFecBer(); b == nil {
t.Errorf("PreFECBER data is empty for port %v", portName)
} else {
validatePMValue(t, portName, "PreFECBER", b.GetInstant(), b.GetMin(), b.GetMax(), b.GetAvg(), minAllowedPreFECBER, maxAllowedPreFECBER, inactivePreFECBER, operStatus)
if deviations.CiscoPreFECBERInactiveValue(dut) {
validatePMValue(t, portName, "PreFECBER", b.GetInstant(), b.GetMin(), b.GetMax(), b.GetAvg(), minAllowedPreFECBER, maxAllowedPreFECBER, 0.5, operStatus)
} else {
validatePMValue(t, portName, "PreFECBER", b.GetInstant(), b.GetMin(), b.GetMax(), b.GetAvg(), minAllowedPreFECBER, maxAllowedPreFECBER, inactivePreFECBER, operStatus)
}
}
if e := otn.GetEsnr(); e == nil {
t.Errorf("ESNR data is empty for port %v", portName)
Expand All @@ -203,7 +213,7 @@ func validatePMValue(t *testing.T, portName, pm string, instant, min, max, avg,
return
}
case oc.Interface_OperStatus_DOWN:
if instant != inactiveValue {
if instant > inactiveValue {
t.Errorf("Invalid %v sample when %v is DOWN --> min : %v, max : %v, avg : %v, instant : %v", pm, portName, min, max, avg, instant)
return
}
Expand Down
192 changes: 144 additions & 48 deletions internal/deviations/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,57 @@
## Guidelines to add deviations to FNT tests
# Guidelines to add deviations to FNT tests

### Adding Deviations
## When to use deviations

* Add the deviation to the `Deviations` message in the [proto/metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto) file.
1. Deviations may be created to use alternate OC or use CLI instead of OC to
achieve the operational intent described in the README.
2. Deviations should not be created which change the operational intent. See
below for guidance on changing operational intent.
3. Deviations may be created to change which OC path is used for telemetry or
use an implementation's native yang path.  Deviations for telemetry
should not introduce a depedency on CLI output.
4. As with any pull request (PR), the CODEOWNERs must review and approve (or
delegate if appropriate).
5. The CODEOWNERs must ensure the README and code reflects the agreed to
operational support goal.  This may be done via offline discussions or
directly via approvals in the github PR.

```
See [Deviation Examples](#deviation-examples) for more information.

## When not to use a deviation

Deviations should not be used to skip configuration or skip validations. If the
feature is not supported and there is no workaround to achieve
the functionality, then the test should fail for that platform.

If the README is in error, the README can be updated and code can be changed
(without introducing deviation) with approval from the CODEOWNERs.

If the intent of the README needs to be changed (not due to an error, but a
change in the feature request), the CODEOWNER must ensure all parties are
notified. The CODEOWNER must determine if the change is late or early in the
development cycle. If late (development is underway and/or nearly complete), it
is recommended to create a new test which represents the change. If early in
the feature request (development has not started or is very early stage), then
the existing README and code may be updated.

## Adding Deviations

* Add the deviation to the `Deviations` message in the
[proto/metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto)
file.

```go
message Deviations {
...
// Device does not support fragmentation bit for traceroute.
bool traceroute_fragmentation = 2;
...
}
```
```

* Run `make proto/metadata_go_proto/metadata.pb.go` from your featureprofiles root directory to generate the Go code for the added proto fields.

```
```shell
$ make proto/metadata_go_proto/metadata.pb.go
mkdir -p proto/metadata_go_proto
# Set directory to hold symlink
Expand All @@ -30,36 +66,57 @@
go list -f '{{ .Dir }} protobuf-import/{{ .Path }}' -m github.com/openconfig/ondatra | xargs -L1 -- ln -s
protoc -I='protobuf-import' --proto_path=proto --go_out=./ --go_opt=Mmetadata.proto=proto/metadata_go_proto metadata.proto
goimports -w proto/metadata_go_proto/metadata.pb.go
```

* Add the accessor function for this deviation to the [internal/deviations/deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go) file. This function will need to accept a parameter `dut` of type `*ondatra.DUTDevice` to lookup the deviation value for a specific dut. This accessor function must call `lookupDUTDeviations` and return the deviation value. Test code will use this function to access deviations.
* If the default value of the deviation is the same as the default value for the proto field, the accessor method can directly call the `Get*()` function for the deviation field. For example, the boolean `traceroute_fragmentation` deviation, which has a default value of `false`, will have an accessor method with the single line `return lookupDUTDeviations(dut).GetTracerouteFragmentation()`.

```
// TraceRouteFragmentation returns if the device does not support fragmentation bit for traceroute.
// Default value is false.
func TraceRouteFragmentation(dut *ondatra.DUTDevice) bool {
return lookupDUTDeviations(dut).GetTracerouteFragmentation()
}
```

* If the default value of deviation is not the same as the default value of the proto field, the accessor method can add a check and return the required default value. For example, the accessor method for the float `hierarchical_weight_resolution_tolerance` deviation, which has a default value of `0`, will call the `GetHierarchicalWeightResolutionTolerance()` to check the value set in `metadata.textproto` and return the default value `0.2` if applicable.

```
// HierarchicalWeightResolutionTolerance returns the allowed tolerance for BGP traffic flow while comparing for pass or fail conditions.
// Default minimum value is 0.2. Anything less than 0.2 will be set to 0.2.
func HierarchicalWeightResolutionTolerance(dut *ondatra.DUTDevice) float64 {
hwrt := lookupDUTDeviations(dut).GetHierarchicalWeightResolutionTolerance()
if minHWRT := 0.2; hwrt < minHWRT {
```

* Add the accessor function for this deviation to the
[internal/deviations/deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go)
file. This function will need to accept a parameter `dut` of type
`*ondatra.DUTDevice` to lookup the deviation value for a specific dut. This
accessor function must call `lookupDUTDeviations` and return the deviation
value. Test code will use this function to access deviations.
* If the default value of the deviation is the same as the default value for
the proto field, the accessor method can directly call the `Get*()` function
for the deviation field. For example, the boolean `traceroute_fragmentation`
deviation, which has a default value of `false`, will have an accessor
method with the single line `return
lookupDUTDeviations(dut).GetTracerouteFragmentation()`.

```go
// TraceRouteFragmentation returns if the device does not support fragmentation bit for traceroute.
// Default value is false.
func TraceRouteFragmentation(dut *ondatra.DUTDevice) bool {
return lookupDUTDeviations(dut).GetTracerouteFragmentation()
}
```

* If the default value of deviation is not the same as the default value of
the proto field, the accessor method can add a check and return the required
default value. For example, the accessor method for the float
`hierarchical_weight_resolution_tolerance` deviation, which has a default
value of `0`, will call the `GetHierarchicalWeightResolutionTolerance()` to
check the value set in `metadata.textproto` and return the default value
`0.2` if applicable.

```go
// HierarchicalWeightResolutionTolerance returns the allowed tolerance for BGP traffic flow while comparing for pass or fail conditions.
// Default minimum value is 0.2. Anything less than 0.2 will be set to 0.2.
func HierarchicalWeightResolutionTolerance(dut *ondatra.DUTDevice) float64 {
hwrt := lookupDUTDeviations(dut).GetHierarchicalWeightResolutionTolerance()
if minHWRT := 0.2; hwrt < minHWRT {
return minHWRT
}
return hwrt
}
```

* Set the deviation value in the `metadata.textproto` file in the same folder as the test. For example, the deviations used in the test `feature/gnoi/system/tests/traceroute_test/traceroute_test.go` will be set in the file `feature/gnoi/system/tests/traceroute_test/metadata.textproto`. List all the vendor and optionally also hardware model regex that this deviation is applicable for.

```
}
return hwrt
}
```

* Set the deviation value in the `metadata.textproto` file in the same folder as
the test. For example, the deviations used in the test
`feature/gnoi/system/tests/traceroute_test/traceroute_test.go` will be set in
the file `feature/gnoi/system/tests/traceroute_test/metadata.textproto`. List
all the vendor and optionally also hardware model regex that this deviation is
applicable for.

```go
...
platform_exceptions: {
platform: {
Expand All @@ -73,30 +130,69 @@
...
```

* To access the deviation from the test call the accessor function for the deviation. Pass the dut to this accessor.
* To access the deviation from the test call the accessor function for the
deviation. Pass the dut to this accessor.

```
```go
if deviations.TraceRouteFragmentation(dut) {
...
}
```

* Example PRs - https://github.com/openconfig/featureprofiles/pull/1649 and
https://github.com/openconfig/featureprofiles/pull/1668
* Example PRs - <https://github.com/openconfig/featureprofiles/pull/1649> and
<https://github.com/openconfig/featureprofiles/pull/1668>

## Removing Deviations

### Removing Deviations
* Once a deviation is no longer required and removed from all tests, delete the
deviation by removing them from the following files:

* Once a deviation is no longer required and removed from all tests, delete the deviation by removing them from the following files:
* metadata.textproto - Remove the deviation field from all metadata.textproto
in all tests.

* metadata.textproto - Remove the deviation field from all metadata.textproto in all tests.
* Remove the accessor method from
[deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go)

* [deviations.go](https://github.com/openconfig/featureprofiles/blob/main/internal/deviations/deviations.go) - Remove the accessor method for this deviation.
* Remove the field number from
[metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto)
by adding the `reserved n` to the `Deviations` message. Ref:
<https://protobuf.dev/programming-guides/proto3/#deleting>

* [metadata.proto](https://github.com/openconfig/featureprofiles/blob/main/proto/metadata.proto) - Remove the deviation field from the `Deviations` message and reserve the deleted field number by adding the `reserved n` to the `Deviations` message.
Ref: https://protobuf.dev/programming-guides/proto3/#deleting
* Run `make proto/metadata_go_proto/metadata.pb.go` from your featureprofiles
root directory to update the Go code for the removed proto fields.

* Run `make proto/metadata_go_proto/metadata.pb.go` from your featureprofiles root directory to update the Go code for the removed proto fields.
## Deviation examples

```go
conf := configureDUT(dut) // returns *oc.Root

if deviations.AlternateOCEnabled(t, dut) {
switch dut.Vendor() {
case ondatra.VENDOR_X:
conf.SetAlternateOC(val)
}
} else {
conf.SetRequiredOC(val)
}
```

```go
conf := configureDUT(dut) // returns *oc.Root

if deviations.RequiredOCNotSupported(t, dut) {
switch dut.Vendor() {
case ondatra.VENDOR_X:
configureDeviceUsingCli(t, dut, vendorXConfig)
}
}
```

## Notes
* If you run into issues with the `make proto/metadata_go_proto/metadata.pb.go` you may need to check if the `protoc` module is installed in your environment. Also depending on your Go version you may need to update your PATH and GOPATH.
* After running the `make proto/metadata_go_proto/metadata.pb.go` script, a `protobuf-import/` folder will be added in your current directory. Keep an eye out for this in case you use `git add .` to add modified files since this folder should not be part of your PR.

* If you run into issues with the `make proto/metadata_go_proto/metadata.pb.go`
you may need to check if the `protoc` module is installed in your environment.
Also depending on your Go version you may need to update your PATH and GOPATH.
* After running the `make proto/metadata_go_proto/metadata.pb.go` script, a
`protobuf-import/` folder will be added in your current directory. Keep an eye
out for this in case you use `git add .` to add modified files since this
folder should not be part of your PR.
Loading

0 comments on commit 762d2bd

Please sign in to comment.