Skip to content

Commit

Permalink
Project import generated by Copybara.
Browse files Browse the repository at this point in the history
FolderOrigin-RevId: /usr/local/google/home/gdennis/copybara/temp/folder-destination7553968756789479621/.
  • Loading branch information
GGN Engprod Team authored and greg-dennis committed Oct 4, 2023
1 parent 14f1361 commit 6aee4ce
Show file tree
Hide file tree
Showing 19 changed files with 47,187 additions and 46,696 deletions.
60 changes: 32 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,34 @@ abstract topology and criteria specified in the testbed file.

Ondatra provides a set of
[fluent interfaces](https://en.wikipedia.org/wiki/Fluent_interface) for
configuring and interacting with network devices. See the
[full API reference documentation](https://pkg.go.dev/github.com/openconfig/ondatra#section-documentation).
configuring and interacting with network devices. The interfaces are divided
into several API packages:

* [Config](https://pkg.go.dev/github.com/openconfig/ondatra/config) provides
an API to set native config on devices via vendor-specific (non-gNMI)
protocols.
* [Console](https://pkg.go.dev/github.com/openconfig/ondatra/console) provides
an API to interact with the serial console of a device.
* [Debug](https://pkg.go.dev/github.com/openconfig/ondatra/debug) provides an
API to add breakpoints to the test to debug its execution.
* [Event Listener](https://pkg.go.dev/github.com/openconfig/ondatra/eventlis)
provides an API to attach listeners that are called at events during the
test execution.
* [gNMI](https://pkg.go.dev/github.com/openconfig/ondatra/gnmi) provides an
API for querying telemetry and setting the state of the device via gNMI.
* [Netutil](https://pkg.go.dev/github.com/openconfig/ondatra/netutil) provides
a collection of network-related helper methods for testing.
* [OTG](https://pkg.go.dev/github.com/openconfig/ondatra/otg) provides an API
to generate traffic using Open Traffic Generator.
* [Raw](https://pkg.go.dev/github.com/openconfig/ondatra/raw) provides
low-level access to the raw device APIs, to be used when the other
higher-level APIs are not sufficient.
* [Report](https://pkg.go.dev/github.com/openconfig/ondatra/report) provides
an API to add properties to, and extract properties from, the JUnit XML test
report.

The Ondatra gNMI API plays a particularly central role in Ondatra tests. It
provide a set of test helpers for querying telemetry and setting the state of
the device via gNMI. [Read more about the Ondatra gNMI API](gnmi/README.md).
See the
[full API reference documentation](https://pkg.go.dev/github.com/openconfig/ondatra).

## Running an Ondatra Test

Expand Down Expand Up @@ -89,19 +111,8 @@ for more details on matching subtests with the `-run` flag.
## Debugging an Ondatra Test

To run an Ondatra test in debug mode, pass the `-debug` flag to `go test`. Debug
mode allows you to insert breakpoints in your code with one simple line:

```go
ondatra.Debug().Breakpoint(t)
```

The `Breakpoint` and `Breakpointf` functions allow you to include custom text in
the breakpoint message, too. For example:

```go
ondatra.Debug().Breakpoint(t, "this should be unreachable")
ondatra.Debug().Breakpointf(t, "myVar has value %v", myVar)
```
mode allows you to insert breakpoints in your code using the
[Debug API](https://pkg.go.dev/github.com/openconfig/ondatra/debug).

Debug mode also offers a menu option to pause the test immediately after the
testbed is reserved. This is useful if you want to manually inspect the testbed
Expand Down Expand Up @@ -159,16 +170,9 @@ for more information on all the glog flags.
Ondatra has the ability to output test results in JUnit XML format. If you pass
`-xml=[path]` to your `go test` invocation, Ondatra will use
[go-junit-report](https://github.com/jstemmer/go-junit-report) to translate the
Go test log to an XML file at the provided path.

To attach properties to the test or individual test cases in the XML report, use
the `ondatra.Report()` API. For example, `ondatra.Report().AddTestProperty()`
attaches a key-value property to the currently running test case.

The help with the development of external tooling that makes use of the XML
output, the `report` package also provides the utility functions `ReadXML` and
`ExtractProperties` for decoding the XML and extracting a properties map,
respectively.
Go test log to an XML file at the provided path. To attach properties to the XML
report and to programmatically parse the XML file use the Ondatra
[Report API](https://pkg.go.dev/github.com/openconfig/ondatra/report).

## Testing on KNE

Expand Down
27 changes: 14 additions & 13 deletions binding/as.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,31 +40,32 @@ func ATEAs(ate ATE, target any) error {
func as[T Device](src T, target any, field string, assert func(any) (T, bool)) error {
targetPtrVal, ok := nonNilPtr(target)
if !ok {
return fmt.Errorf("target must be non-nil pointer, got %v (%T)", target, target)
return fmt.Errorf("target must be non-nil pointer, got %v (type: %T)", target, target)
}
targetVal := targetPtrVal.Elem()
srcVal, ok := nonNilPtr(src)
if !ok {
return fmt.Errorf("src must be non-nil pointer, got %v (type: %T)", src, src)
}

for {
srcVal, ok := nonNilPtr(src)
if !ok {
return fmt.Errorf("src must be non-nil pointer, got %v (%T)", src, src)
}
if srcVal.Type().AssignableTo(targetVal.Type()) {
targetVal.Set(srcVal)
for curr, currVal := src, srcVal; ; {
if currVal.Type().AssignableTo(targetVal.Type()) {
targetVal.Set(currVal)
return nil
}
embedField := srcVal.Elem().FieldByName(field)
embedField := currVal.Elem().FieldByName(field)
if !embedField.IsValid() {
return fmt.Errorf("no match found")
return fmt.Errorf("no match found in %v (type: %T)", src, src)
}
intf := embedField.Interface()
if intf == nil {
return fmt.Errorf("no match found")
return fmt.Errorf("no match found in %v (type: %T)", src, src)
}
src, ok = assert(intf)
curr, ok = assert(intf)
if !ok {
return fmt.Errorf("embedded field %v must be a %v", embedField, field)
return fmt.Errorf("embedded field %v must be of type binding.%v, got %T", field, field, intf)
}
currVal = reflect.ValueOf(curr)
}
}

Expand Down
54 changes: 53 additions & 1 deletion config/vendor.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,59 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package config contains APIs for configuring DUTs.
// Package config provides an API for setting native config on DUTs via
// vendor-specific (non-gNMI) protocols.
//
// We use the following example snippet to understand various aspects of the
// Config API.
//
// dut.Config().New().
// WithAristaText(`
// interface {{ port "port1" }}
// no switchport
// ip address 192.0.2.1/30
// ip address {{ var "ipv4addr" }}
// ipv6 address 2001:DB8::1/126
// load-interval 30`).
// WithCiscoText(`
// interface {{ port "port1" }}
// ipv4 address {{ var "ipv4addr" }}
// ipv6 address 2001:DB8::1/126
// load-interval 30`).
// WithJuniperFile(`path/to/juniper.config`).
// WithVarValue("ipv4addr", computeV4Address()).
// Push(t)
//
// # Per-Vendor Configs
//
// In the example above, one of three possible native configs are pushed to the
// device depending upon the vendor of the device at runtime. If the vendor is
// not one of those three, the [VendorConfig.Push] function fails fatally. The
// `With<Vendor>Text` methods will push a vendor-specific text string and the
// `With<Vendor>File` methods will push the text in a vendor-specific file.
//
// If the test has already pre-computed the native config in a way that has
// taken the vendor into account, perhaps by calling an external
// config-generation service, the test can push that config without regard to
// the vendor using the functions [VendorConfig.WithText] or
// [VendorConfig.WithFile].
//
// # Templated Variables
//
// As shown, the syntax for the config allows templated port names like `{{ port
// "port1" }}`. That placeholder will be replaced at runtime with the name given
// to `port1`, where `port1` is the ID of a port in the testbed file. The syntax
// may also contain instances of `{{ var "<key>" }}`, which will be replaced at
// runtime by calling `WithVarValue` or `WithVarMap` on the config object.
//
// # Push vs Append
//
// The effect of Push is to reset the device back to its original config (the
// config the device had when it was reserved) and then to append the specified
// config. As a result, test cases that use native config don't usually need to
// reset the device config to be hermetic; it suffices to just start the test
// case with a call to Push. If a test wants only to append config and skip
// the reset behavior, it should call [VendorConfig.Append] instead.
package config

import (
Expand Down
33 changes: 30 additions & 3 deletions console/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,28 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package console provides the DUT Console API.
// Package console provides an API to interact with the serial console of a DUT.
//
// To capture the contents of the serial console to a file, use the
// [Console.StartCapture] method:
//
// stdoutFile, err := os.Create("stdout.log")
// if err != nil {
// return err
// }
// stderrFile, err := os.Create("stderr.log")
// if err != nil {
// return err
// }
// dut.Console().StartCapture(t, stdoutFile, stderrFile)
//
// StartCapture automatically registers a test cleanup function to stop the
// capture, but if a test needs fine-grained control over when precisely it is
// stopped, it can call the [StopCaptureFunc] function returned by StartCapture:
//
// stopFn := dut.Console().StartCapture(t, stdoutFile, stderrFile)
// doStuffToTriggerConsoleOutput()
// stopFn(t)
package console

import (
Expand Down Expand Up @@ -40,15 +61,21 @@ type Console struct {
dut binding.DUT
}

// StartCapture starts copying console stdout and stderr to out and err,
// and returns a function that stops copying console stdout and stderr.
// StartCapture starts copying console stdout and stderr to outw and errw,
// respectively. It registers a cleanup function to stop the capture but also
// returns that same function, in case the user wants to stop it earlier.
func (c *Console) StartCapture(t testing.TB, outw, errw io.Writer) StopCaptureFunc {
t.Helper()
t = events.ActionStarted(t, "Starting console capture on %s", c.dut)
cap, err := c.startCapture(context.Background(), outw, errw)
if err != nil {
t.Fatalf("StartCapture(t, out, err) on %s: %v", c.dut, err)
}
t.Cleanup(func() {
if err := cap.stop(); err != nil {
log.Errorf("StopCapture(t) on %s: %v", c.dut, err)
}
})
return func(t testing.TB) {
t.Helper()
if err := cap.stop(); err != nil {
Expand Down
21 changes: 20 additions & 1 deletion debug/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package debug contains the Ondatra debug API.
// Package debug provides an API to add breakpoints to the test to debug its
// execution.
//
// The functions defined in this package must only be used for local debugging
// and require that the test be run in [Debug Mode]. If a breakpoint is reached
// when not in debug mode, the test will fail there and then. Therefore, no
// tests with breakpoints should be committed to any persistent repository
//
// To insert a simple breakpoint in your code, use:
//
// ondatra.Debug().Breakpoint(t)
//
// For more informative breakpoints, the [Debug.Breakpoint] and
// [Debug.Breakpoint] functions allow you to include custom text in the
// breakpoint message:
//
// ondatra.Debug().Breakpoint(t, "this should be unreachable")
// ondatra.Debug().Breakpointf(t, "myVar has value %v", myVar)
//
// [Debug Mode]: https://github.com/openconfig/ondatra#debugging-an-ondatra-test
package debug

import (
Expand Down
22 changes: 21 additions & 1 deletion eventlis/eventlis.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,27 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package eventlis provides an event listener API.
// Package eventlis provides an API to attach listeners that are called at
// events during the test execution.
//
// Code can register a callback to be invoked after the reservation is complete
// but before any tests are executed by calling
// [EventListener.AddBeforeTestsCallback]:
//
// ondatra.EventListener().AddBeforeTestsCallback(func (e *eventlis.BeforeTestsEvent) {
// handleBeforeTestsEvent(e)
// })
//
// Code can register a callback to be invoked after all the tests are complete
// but before the reservation is released by calling
// [EventListener.AddAfterTestsCallback]:
//
// ondatra.EventListener().AddAfterTestsCallback(func (e *eventlis.AfterTestsEvent) {
// handleAfterTestsEvent(e)
// })
//
// These calls can be made from the test itself, from the binding, or from a
// helper library that the test imports.
package eventlis

import (
Expand Down
Loading

0 comments on commit 6aee4ce

Please sign in to comment.