binding

package
v0.1.5 Latest Latest
Warning

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

Go to latest
Published: Feb 9, 2023 License: Apache-2.0 Imports: 27 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

This section is empty.

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.
	// Implementations must append transport security options necessary to reach the server.
	// 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.
	// Implementations must append transport security options necessary to reach the server.
	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.

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) CustomData added in v0.1.1

func (a *AbstractATE) CustomData() map[string]any

CustomData returns custom data for the ATE.

func (*AbstractATE) DialGNMI

DialGNMI returns an unimplemented error.

func (*AbstractATE) DialIxNetwork

func (a *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 AbstractDUT

type AbstractDUT struct {
	*Dims
}

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

func (*AbstractDUT) CustomData added in v0.1.1

func (d *AbstractDUT) CustomData() map[string]any

CustomData returns custom data for the DUT.

func (*AbstractDUT) DialCLI

func (d *AbstractDUT) DialCLI(context.Context) (StreamClient, error)

DialCLI returns an unimplemented error.

func (*AbstractDUT) DialConsole

func (d *AbstractDUT) DialConsole(context.Context) (StreamClient, error)

DialConsole returns an unimplemented error.

func (*AbstractDUT) DialGNMI

func (d *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) 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 (d *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 AbstractGNOIClients

type AbstractGNOIClients struct{}

AbstractGNOIClients is implementation support for the GNOIClients interface.

func (*AbstractGNOIClients) BGP

BGP logs a fatal unimplemented error.

func (*AbstractGNOIClients) CertificateManagement

func (g *AbstractGNOIClients) CertificateManagement() cpb.CertificateManagementClient

CertificateManagement logs a fatal unimplemented error.

func (*AbstractGNOIClients) Diag

Diag logs a fatal unimplemented error.

func (*AbstractGNOIClients) FactoryReset

func (g *AbstractGNOIClients) FactoryReset() frpb.FactoryResetClient

FactoryReset logs a fatal unimplemented error.

func (*AbstractGNOIClients) File

File logs a fatal unimplemented error.

func (*AbstractGNOIClients) Healthz

func (g *AbstractGNOIClients) Healthz() hpb.HealthzClient

Healthz logs a fatal unimplemented error.

func (*AbstractGNOIClients) Interface

func (g *AbstractGNOIClients) Interface() ipb.InterfaceClient

Interface logs a fatal unimplemented error.

func (*AbstractGNOIClients) Layer2

func (g *AbstractGNOIClients) Layer2() lpb.Layer2Client

Layer2 logs a fatal unimplemented error.

func (*AbstractGNOIClients) LinkQualification

func (g *AbstractGNOIClients) LinkQualification() plqpb.LinkQualificationClient

LinkQualification logs a fatal unimplemented error.

func (*AbstractGNOIClients) MPLS

MPLS logs a fatal unimplemented error.

func (*AbstractGNOIClients) OS

OS logs a fatal unimplemented error.

func (*AbstractGNOIClients) OTDR

OTDR logs a fatal unimplemented error.

func (*AbstractGNOIClients) System

func (g *AbstractGNOIClients) System() spb.SystemClient

System logs a fatal unimplemented error.

func (*AbstractGNOIClients) WavelengthRouter

func (g *AbstractGNOIClients) WavelengthRouter() wpb.WavelengthRouterClient

WavelengthRouter logs a fatal unimplemented error.

type AbstractStreamClient

type AbstractStreamClient struct{}

AbstractStreamClient is implementation support for the StreamClient interface.

func (*AbstractStreamClient) Close

func (s *AbstractStreamClient) Close() error

Close returns an unimplemented error.

func (*AbstractStreamClient) SendCommand

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

SendCommand returns an unimplemented error.

func (*AbstractStreamClient) Stderr

func (s *AbstractStreamClient) Stderr() io.ReadCloser

Stderr logs a fatal unimplemented error.

func (*AbstractStreamClient) Stdin

func (s *AbstractStreamClient) Stdin() io.WriteCloser

Stdin logs a fatal unimplemented error.

func (*AbstractStreamClient) Stdout

func (s *AbstractStreamClient) Stdout() io.ReadCloser

Stdout 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 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) (StreamClient, error)

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

	// DialGNMI creates a client connection to the DUT's gNMI endpoint.
	// Implementations must append transport security options necessary to reach the server.
	DialGNMI(context.Context, ...grpc.DialOption) (gpb.GNMIClient, error)

	// DialGNOI creates a client connection to the DUT's gNOI endpoint.
	// Implementations must append transport security options necessary to reach the server.
	DialGNOI(context.Context, ...grpc.DialOption) (GNOIClients, error)

	// DialGRIBI creates a client connection to the DUT's gRIBI endpoint.
	// Implementations must append transport security options necessary to reach the server.
	DialGRIBI(context.Context, ...grpc.DialOption) (grpb.GRIBIClient, error)

	// DialP4RT creates a client connection to the DUT's P4RT endpoint.
	// Implementations must append transport security options necessary to reach the server.
	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.

type Device

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

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
	CustomData      map[string]any
}

Dims contains the dimensions of reserved DUT or ATE.

func (*Dims) String

func (d *Dims) String() string

type GNOIClients

type GNOIClients interface {
	BGP() bpb.BGPClient
	CertificateManagement() cpb.CertificateManagementClient
	Diag() dpb.DiagClient
	FactoryReset() frpb.FactoryResetClient
	File() fpb.FileClient
	Healthz() hpb.HealthzClient
	Interface() ipb.InterfaceClient
	Layer2() lpb.Layer2Client
	LinkQualification() plqpb.LinkQualificationClient
	MPLS() mpb.MPLSClient
	OS() ospb.OSClient
	OTDR() otpb.OTDRClient
	System() spb.SystemClient
	WavelengthRouter() wpb.WavelengthRouterClient
	// contains filtered or unexported methods
}

GNOIClients stores APIs to GNOI services. All implementations of this interface must embed AbstractGNOIClients.

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.

type StreamClient

type StreamClient interface {
	// SendCommand always expects a clean "prompt" on the underlying
	// device. If the device is interleaving Stdin writes with SendCommand
	// the underlying channel must be at a clean prompt to allow SendCommand
	// to complete the operation. Additionaly, the result buffer will be fully
	// consumed by SendCommand, ensuring it leaves a clean prompt behind.
	SendCommand(context.Context, string) (string, error)
	Stdin() io.WriteCloser
	Stdout() io.ReadCloser
	Stderr() io.ReadCloser
	Close() error
	// contains filtered or unexported methods
}

StreamClient provides the interface for streaming IO to DUT. All implementations of this interface must embed AbstractStreamClient.

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