binding

package
v0.4.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 10, 2023 License: Apache-2.0 Imports: 20 Imported by: 1

README

Binding Interface

The Binding interface abstracts Ondatra from the particulars of how to access the devices under test. Those particulars include the inventory of devices and their properties, how to reserve them, and how to reach their various protocol endpoints.

An implementation of the Reserve method of Binding returns a Reservation struct, which in turn contains implementations of the DUT and ATE interfaces. Substantial care was taken in writing the godoc comments on Binding, DUT, ATE, and all other interfaces in the binding package, so please read those carefully to ensure each method of an implementation adheres to the stated contract.

Abstract Structs

Ondatra provides a set of "abstract" structs that must be embedded in any implementation of the binding interfaces. For example, any implementation of the DUT interface must embed AbstractDUT and any implementation of ATE must embed AbstractATE. This is enforced by the presence of a mustEmbedAbstractDUT method in DUT and a mustEmbedAbstactATE method in ATE, un-exported methods that are only implemented in AbstractDUT and Abstract ATE, respectively.

The primary purpose of the abstract structs is to enable binding implementations to be partial. It is perfectly acceptable for a binding leave some interface methods unimplemented, and embedding the abstract structs gives them an easy way to do that. It also allows Ondatra developers to add new binding methods in the future without breaking existing implementations. A similar effect could have been obtained by embedding the interface itself, but then calls to unimplemented methods would produce cryptic panics rather than the prescriptive error messages produced by the abstract implementations.

Dialing gRPC

The binding includes many methods that dial gRPC endpoints, like DialGNMI, DialGNOI, etc. Each of these methods accepts a context and a variadic number of DialOption arguments. The implementation of these methods must include a call to grpc.DialContext with the specified context (or perhaps a context derived for the specified context) is the first argument.

Ondatra calls these Dial* functions with some options that it believes all gRPC dial calls should include, but it is then up to the implementation to append any additional necessary or desirable options for connecting to the gRPC endpoint. Every such Dial* implementation must append a dial option that specifies the transport credentials necessary to reach the endpoint; otherwise the call to DialContext will fail. For example:

opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
grpc.DialContext(ctx, addr, opts...)

Here are some other options you might consider adding, depending on your lab and network environment:

  • grpc.WithDefaultCallOptions(grpc.WaitForReady(true))
    Try this option if you are experiencing transient failures in the RPC channel. Such failures normally manifest as "connection refused" RPC errors. One downside of this option is that it can cause the RPC to hang indefinitely if the channel never returns to a ready state. For that reason, we recommend only using this option in combination with the "default timeout" options documented below. To read more about the semantics of WaitForReady https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md.

  • grpcutil.WithUnaryDefaultTimeout(defaultTimeout) and grpcutil.WithStreamDefaultTimeout(defaultTimeout)
    Try these options if you want to ensure all RPCs have timeouts configured. If the context passed to any RPC does not already have a timeout or deadline, these options cause the RPC to be issued with a new context that has the specified defaultTimeout. These options are provided by the Ondatra grpcutil package.

Documentation

Overview

Package binding holds the Ondatra binding interface.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ATEAs added in v0.3.1

func ATEAs(ate ATE, target any) error

ATEAs tests if the specified ATE or any ATE it transitively embeds fulfills the interface pointed to by target, and if so, sets target to that ATE.

func DUTAs added in v0.3.1

func DUTAs(dut DUT, target any) error

DUTAs tests if the specified DUT or any DUT it transitively embeds fulfills the interface pointed to by target, and if so, sets target to that DUT.

func SendCommandUsingRun added in v0.4.2

func SendCommandUsingRun(ctx context.Context, cmd string, c CLIClient) (string, error)

SendCommandUsingRun implements SendCommand using the client's RunCommand.

Types

type ATE

type ATE interface {
	Device

	// DialIxNetwork creates a client connection to the ATE's IxNetwork endpoint.
	DialIxNetwork(context.Context) (*IxNetwork, error)

	// DialGNMI creates a client connection to the ATE's gNMI endpoint.
	// See the interface comment for proper handling of dial options.
	// This method must be implemented to receive gNMI from OTG but not from IxNetwork;
	// Implementing DialIxNetwork is sufficient for gNMI support for IxNetwork.
	DialGNMI(context.Context, ...grpc.DialOption) (gpb.GNMIClient, error)

	// DialOTG creates a client connection to the ATE's OTG endpoint.
	// See the interface comment for proper handling of dial options.
	DialOTG(context.Context, ...grpc.DialOption) (gosnappi.GosnappiApi, error)
	// contains filtered or unexported methods
}

ATE is a reserved ATE.

All implementations of this interface must embed AbstractATE.

For methods that dial gRPC endpoints, implementations must use a default set of dial options necessary to reach the endpoint, so that the dial succeeds when no options are provided by the caller. When the caller does specify options, implementations are encouraged to append those options to the default set, so the call can both inherit and override the default behavior.

type AbstractATE

type AbstractATE struct {
	Dims *Dims
}

AbstractATE is implementation support for the ATE interface. All implementations of the ATE interface must embed this type.

func (*AbstractATE) DialGNMI

DialGNMI returns an unimplemented error.

func (*AbstractATE) DialIxNetwork

func (*AbstractATE) DialIxNetwork(context.Context) (*IxNetwork, error)

DialIxNetwork returns an unimplemented error.

func (*AbstractATE) DialOTG

DialOTG returns an unimplemented error.

func (*AbstractATE) HardwareModel

func (a *AbstractATE) HardwareModel() string

HardwareModel returns the hardware model of the ATE.

func (*AbstractATE) Name

func (a *AbstractATE) Name() string

Name returns the name of the ATE.

func (*AbstractATE) Ports

func (a *AbstractATE) Ports() map[string]*Port

Ports returns the reserved ports on the ATE.

func (*AbstractATE) SoftwareVersion

func (a *AbstractATE) SoftwareVersion() string

SoftwareVersion returns the software version of the ATE.

func (*AbstractATE) String

func (a *AbstractATE) String() string

func (*AbstractATE) Vendor

func (a *AbstractATE) Vendor() opb.Device_Vendor

Vendor returns the vendor of the ATE.

type AbstractCLIClient added in v0.2.8

type AbstractCLIClient struct{}

AbstractCLIClient is implementation support for the CLIClient interface.

func (*AbstractCLIClient) RunCommand added in v0.4.2

func (*AbstractCLIClient) RunCommand(ctx context.Context, cmd string) (CommandResult, error)

RunCommand returns an unimplemented error.

func (*AbstractCLIClient) SendCommand added in v0.2.8

func (*AbstractCLIClient) SendCommand(ctx context.Context, cmd string) (string, error)

SendCommand returns an unimplemented error. Deprecated: Use RunCommand() instead. TODO(team): Remove when all clients using RunCommand.

type AbstractCommandResult added in v0.4.2

type AbstractCommandResult struct{}

AbstractCommandResult is implementation support for the CommandResult interface.

func (*AbstractCommandResult) Error added in v0.4.2

func (*AbstractCommandResult) Error() string

Error logs a fatal unimplemented error.

func (*AbstractCommandResult) Output added in v0.4.2

func (*AbstractCommandResult) Output() string

Output logs a fatal unimplemented error.

type AbstractConsoleClient added in v0.2.8

type AbstractConsoleClient struct{}

AbstractConsoleClient is implementation support for the ConsoleClient interface.

func (*AbstractConsoleClient) Close added in v0.2.8

func (*AbstractConsoleClient) Close() error

Close returns an unimplemented error.

func (*AbstractConsoleClient) Stderr added in v0.2.8

Stderr logs a fatal unimplemented error.

func (*AbstractConsoleClient) Stdin added in v0.2.8

Stdin logs a fatal unimplemented error.

func (*AbstractConsoleClient) Stdout added in v0.2.8

Stdout logs a fatal unimplemented error.

type AbstractDUT

type AbstractDUT struct {
	*Dims
}

AbstractDUT is a reserved DUT. All implementations of the DUT interface must embed this type.

func (*AbstractDUT) DialCLI

func (*AbstractDUT) DialCLI(context.Context) (CLIClient, error)

DialCLI returns an unimplemented error.

func (*AbstractDUT) DialConsole

func (*AbstractDUT) DialConsole(context.Context) (ConsoleClient, error)

DialConsole returns an unimplemented error.

func (*AbstractDUT) DialGNMI

func (*AbstractDUT) DialGNMI(ctx context.Context, opts ...grpc.DialOption) (gpb.GNMIClient, error)

DialGNMI returns an unimplemented error.

func (*AbstractDUT) DialGNOI

DialGNOI returns an unimplemented error.

func (*AbstractDUT) DialGNSI added in v0.2.1

DialGNSI returns an unimplemented error.

func (*AbstractDUT) DialGRIBI

DialGRIBI returns an unimplemented error.

func (*AbstractDUT) DialP4RT

DialP4RT returns an unimplemented error.

func (*AbstractDUT) HardwareModel

func (d *AbstractDUT) HardwareModel() string

HardwareModel returns the hardware model of the DUT.

func (*AbstractDUT) Name

func (d *AbstractDUT) Name() string

Name returns the name of the DUT.

func (*AbstractDUT) Ports

func (d *AbstractDUT) Ports() map[string]*Port

Ports returns the reserved ports on the DUT.

func (*AbstractDUT) PushConfig

func (*AbstractDUT) PushConfig(ctx context.Context, config string, reset bool) error

PushConfig returns an unimplemented error.

func (*AbstractDUT) SoftwareVersion

func (d *AbstractDUT) SoftwareVersion() string

SoftwareVersion returns the software version of the DUT.

func (*AbstractDUT) String

func (d *AbstractDUT) String() string

func (*AbstractDUT) Vendor

func (d *AbstractDUT) Vendor() opb.Device_Vendor

Vendor returns the vendor of the DUT.

type AbstractGNSIClients added in v0.2.1

type AbstractGNSIClients struct{}

AbstractGNSIClients is implementation support for the GNSIClients interface.

func (*AbstractGNSIClients) Acctz added in v0.2.8

Acctz logs a fatal unimplemented error.

func (*AbstractGNSIClients) Authz added in v0.2.1

Authz logs a fatal unimplemented error.

func (*AbstractGNSIClients) Certz added in v0.2.1

Certz logs a fatal unimplemented error.

func (*AbstractGNSIClients) Credentialz added in v0.2.1

Credentialz logs a fatal unimplemented error.

func (*AbstractGNSIClients) Pathz added in v0.2.1

Pathz logs a fatal unimplemented error.

type Binding

type Binding interface {

	// Reserve reserves resources matching the criteria in the specified testbed.
	// The framework has already verified that the testbed is valid, and will
	// validate that the returned reservation matches the testbed criteria.
	//
	// The testbed resources must be reserved for the specified runTime, or
	// until Release is called. A runTime of zero means the caller requested an
	// unlimited runTime. The implementation is free to impose a maximum limit on
	// the runTime and return an error if it exceeds that limit. The framework has
	// already checked that the runTime is not negative.
	//
	// This method may block for up to the specified waitTime for all testbed
	// resources to become available. Given a zero waitTime, the implementation
	// must choose a reasonable duration. The framework has already checked that
	// the waitTime is not negative.
	//
	// The 'partial' map gives a partial mapping of device and port IDs in the
	// testbed to concrete names to constrain the topology that is reserved.
	//
	// Devices in the returned reservation should be initialiazed with a fixed
	// base configuration. Implementations are encouraged to make this base
	// configuration "minimal," meaning a configuration that ensures the device
	// is reachable and capable of being configured further, but little else,
	// so that tests make as few assumptions about the devices as possible.
	Reserve(ctx context.Context, tb *opb.Testbed, runTime, waitTime time.Duration, partial map[string]string) (*Reservation, error)

	// Release releases the reserved testbed.
	// It is not called if the reservation was fetched.
	Release(ctx context.Context) error

	// FetchReservation looks up and returns the pre-existing reservation with
	// the specified ID.
	FetchReservation(ctx context.Context, id string) (*Reservation, error)
}

Binding is a strategy interface for Ondatra vendor implementations.

The framework enforces that at most testbed is reserved at a time, so implementations can assume that these methods are never called out of order, e.g. Release() is never be called without a prior Reserve().

type CLIClient added in v0.2.8

type CLIClient interface {
	// TODO(team): Remove when all clients using RunCommand.
	SendCommand(context.Context, string) (string, error)
	RunCommand(context.Context, string) (CommandResult, error)
	// contains filtered or unexported methods
}

CLIClient provides the interface for sending CLI commands to the DUT. All implementations of this interface must embed AbstractCLIClient.

type CommandResult added in v0.4.2

type CommandResult interface {
	// Output returns the output of the command.
	// The return value may be non-empty even when the command fails.
	Output() string
	// Error returns an error message that occurred when running the command.
	// The return value is the empty string if and only if the command succeeds.
	Error() string
	// contains filtered or unexported methods
}

CommandResult provides the interface for the result of a CLI command. All implementations of this interface must embed AbstractCommandResult.

type ConsoleClient added in v0.2.8

type ConsoleClient interface {
	Stdin() io.WriteCloser
	Stdout() io.ReadCloser
	Stderr() io.ReadCloser
	Close() error
	// contains filtered or unexported methods
}

ConsoleClient provides the interface for console access to the DUT. All implementations of this interface must embed AbstractConsoleClient.

type DUT

type DUT interface {
	Device

	// PushConfig adds config to the device. If reset is true, the device
	// is reset to its base config before the specified config is added.
	// The following Go template functions are allowed in config:
	// - {{ port "<portID>" }}: replaced with the physical port name
	// - {{ secrets "<arg1>" "<arg2>" }}: left untouched, returned as-is
	PushConfig(ctx context.Context, config string, reset bool) error

	// DialCLI creates a client connection to the DUT's CLI endpoint.
	DialCLI(context.Context) (CLIClient, error)

	// DialConsole creates a client connection to the DUT's Console endpoint.
	DialConsole(context.Context) (ConsoleClient, error)

	// DialGNMI creates a client connection to the DUT's gNMI endpoint.
	// See the interface comment for proper handling of dial options.
	DialGNMI(context.Context, ...grpc.DialOption) (gpb.GNMIClient, error)

	// DialGNOI creates a client connection to the DUT's gNOI endpoint.
	// See the interface comment for proper handling of dial options.
	DialGNOI(context.Context, ...grpc.DialOption) (gnoigo.Clients, error)

	// DialGNSI creates a client connection to the DUT's gNSI endpoint.
	// See the interface comment for proper handling of dial options.
	DialGNSI(context.Context, ...grpc.DialOption) (GNSIClients, error)

	// DialGRIBI creates a client connection to the DUT's gRIBI endpoint.
	// See the interface comment for proper handling of dial options.
	DialGRIBI(context.Context, ...grpc.DialOption) (grpb.GRIBIClient, error)

	// DialP4RT creates a client connection to the DUT's P4RT endpoint.
	// See the interface comment for proper handling of dial options.
	DialP4RT(context.Context, ...grpc.DialOption) (p4pb.P4RuntimeClient, error)
	// contains filtered or unexported methods
}

DUT is a reserved DUT.

All implementations of this interface must embed AbstractDUT.

For methods that dial gRPC endpoints, implementations must use a default set of dial options necessary to reach the endpoint, so that the dial succeeds when no options are provided by the caller. When the caller does specify options, implementations are encouraged to append those options to the default set, so the call can both inherit and override the default behavior.

type Device

type Device interface {
	Name() string
	Vendor() opb.Device_Vendor
	HardwareModel() string
	SoftwareVersion() string
	Ports() map[string]*Port
}

Device is a reserved DUT or ATE.

type Dims

type Dims struct {
	Name            string
	Vendor          opb.Device_Vendor
	HardwareModel   string
	SoftwareVersion string
	Ports           map[string]*Port
}

Dims contains the dimensions of reserved DUT or ATE.

func (*Dims) String

func (d *Dims) String() string

type GNSIClients added in v0.2.1

type GNSIClients interface {
	Authz() authzpb.AuthzClient
	Pathz() pathzpb.PathzClient
	Certz() certzpb.CertzClient
	Credentialz() credzpb.CredentialzClient
	Acctz() acctzpb.AcctzClient
	// contains filtered or unexported methods
}

GNSIClients stores APIs to GNSI services. All implementations of this interface must embed AbstractGNSIClients.

type IxNetwork

type IxNetwork struct {
	// Session is an IxNetwork session for an ATE.
	Session *ixweb.Session
	// ChassisHost is an optional hostname or IP address to use when assigning
	// Ixia VPorts. If empty, defaults to the name of the reserved ATE.
	ChassisHost string
	// SyslogHost is an optional hostname or IP address to which IxNetwork should
	// stream logs. If empty, syslog streaming is not enabled.
	SyslogHost string
}

IxNetwork provides information for an IxNetwork session.

type Port

type Port struct {
	Name      string
	Speed     opb.Port_Speed
	CardModel string
	PMD       opb.Port_Pmd
}

Port is a reserved Port.

func (*Port) String

func (p *Port) String() string

type Reservation

type Reservation struct {
	ID   string
	DUTs map[string]DUT
	ATEs map[string]ATE
}

Reservation holds the reserved DUTs and ATEs as an id map.

Directories

Path Synopsis
Package grpcutil contains gRPC utilities useful to binding implementations.
Package grpcutil contains gRPC utilities useful to binding implementations.
testservice
Package testservice provides an interface for testing with the Test service.
Package testservice provides an interface for testing with the Test service.
Package ixweb provides a connection to the Ixia Web Platform.
Package ixweb provides a connection to the Ixia Web Platform.
Package portgraph searches for a graph that satisfies a set of constraints.
Package portgraph searches for a graph that satisfies a set of constraints.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL