ndt5

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 21, 2022 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package ndt5 contains an ndt5 client.

Example

This shows how to run a ndt5 test.

ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
client := ndt5.NewClient("ndt5-client-go-example", "0.1.0", "https://locate.measurementlab.net")
ch, err := client.Start(ctx)
if err != nil {
	log.Fatal(err)
}
for ev := range ch {
	log.Printf("%+v", ev)
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrExpectedNonEmptyMessage indicates we expected a message
	// with no body and we received one with body.
	ErrExpectedNonEmptyMessage = errors.New("expected non-empty message")

	// ErrInvalidKickoff indicates that the kickoff message we did
	// receive from the server isn't what we expected
	ErrInvalidKickoff = errors.New("ReceiveKickoff: get invalid kickoff bytes")

	// ErrServerBusy indicates that the server is busy
	ErrServerBusy = errors.New("WaitInQueue: server is busy")

	// ErrUnexpectedMessage indicates we received a message that
	// we were not expecting at this stage.
	ErrUnexpectedMessage = errors.New("unexpected message type")
)
View Source
var ErrMessageSize = errors.New("message too large for ndt5 frame")

ErrMessageSize indicates that a message is larger than the maximum message size than a ndt5 frame can transport.

Functions

This section is empty.

Types

type Client

type Client struct {
	// ClientName is the name of the software running ndt7 tests. It's set by
	// NewClient; you may want to change this value.
	ClientName string

	// ClientVersion is the version of the software running ndt7 tests. It's
	// set by NewClient; you may want to change this value.
	ClientVersion string

	// ProtocolFactory creates a ControlManager. It's set to its
	// default value by NewClient; you may override it.
	//
	// This is generally only required for testing.
	ProtocolFactory ProtocolFactory

	// FQDN is the optional server FQDN. We will discover the FQDN of
	// a nearby M-Lab server for you if this field is empty.
	//
	// Setting this field allows you test use a specific server.
	FQDN string

	// MLabNSClient is the mlabns client. We'll configure it with
	// defaults in NewClient and you may override it.
	MLabNSClient MlabNSClient

	// Results is the result of the test. It contains the bytes sent/received
	// for each test and web100 data sent by the server at the end of an
	// S2C test.
	Result TestResult
}

Client is an ndt5 client.

func NewClient

func NewClient(clientName, clientVersion, nsURL string) *Client

NewClient creates a new ndt5 client instance.

func (*Client) Start

func (c *Client) Start(ctx context.Context) (<-chan *Output, error)

Start discovers a ndt5 server (if needed) and starts the whole ndt5 test. On success it returns a channel where measurements are posted. This channel is closed when the test ends. On failure, the error is non nil and you should not attempt using the channel. A side effect of starting the test is that, if you did not specify a server FQDN, we will discover a server for you and store that value into the c.FQDN field. This is done without locking.

type ConnectionsFactory

type ConnectionsFactory interface {
	// DialControlConn dials a control connection. The code shall check
	// whether the address contain a port and use the default port for
	// the specific transport otherwise. The userAgent string may be used
	// to construct a User-Agent header when using WebSocket.
	DialControlConn(ctx context.Context, address, userAgent string) (ControlConn, error)

	// DialMeasurementConn dials a measurement connection with the
	// specified address. The caller is supposed to compose such address
	// by joining together the FQDN currently being used with the port
	// that has been indicated by the ndt5 server. The userAgent string
	// may be used to construct a User-Agent header when using WebSocket.
	DialMeasurementConn(
		ctx context.Context, address, userAgent string) (MeasurementConn, error)
}

ConnectionsFactory creates connections. There are several ndt5 transports (e.g. raw TCP, WebSocket) and, for each of them, there is a specific ConnectionFactory that you can use.

type ControlConn

type ControlConn interface {
	// SetFrameReadWriteObserver sets the observer for the
	// events where a ndt5 frame is read or written
	SetFrameReadWriteObserver(observer FrameReadWriteObserver)

	// SetDeadline sets the read and write dealines for the conn.
	SetDeadline(deadline time.Time) error

	// WriteLogin writes the login message using the proper convention
	// required by the current transport.
	WriteLogin(versionCompat string, testSuite byte) error

	// ReadKickoffMessage reads the kickoff message into b. Depending
	// on the transport we may not read an actual message from the network
	// rather we'd just pretend doing so.
	ReadKickoffMessage(b []byte) error

	// ReadFrame reads the next ndt5 frame.
	ReadFrame() (*Frame, error)

	// WriteMessage writes a ndt5 frame containing the specified ndt5
	// message type and message data as body.
	WriteMessage(mtype uint8, data []byte) error

	// WriteFrame writes the specified frame.
	WriteFrame(frame *Frame) error

	// Close closes the connection.
	Close() error
}

ControlConn is a control connection.

type Failure

type Failure struct {
	Error error
}

Failure contains an error

type Frame

type Frame struct {
	Message []byte // message body
	Raw     []byte // the whole raw message
	Type    uint8  // type of message
}

Frame is an ndt5 frame

func NewFrame

func NewFrame(mtype uint8, message []byte) (*Frame, error)

NewFrame creates a new frame

type FrameReadWriteObserver

type FrameReadWriteObserver interface {
	OnRead(frame *Frame)
	OnWrite(frame *Frame)
}

FrameReadWriteObserver observes when ndt5 frames are read or written on the control conn. You MUST NOT change the frames that you see, but you can log them.

type FrameReadWriteObserverFactory

type FrameReadWriteObserverFactory interface {
	New(out chan<- *Output) FrameReadWriteObserver
}

FrameReadWriteObserverFactory creates a new instance of FrameReadWriteObserver.

type LogMessage

type LogMessage struct {
	Message string
}

LogMessage contains a log message

type MeasurementConn

type MeasurementConn interface {
	// SetDeadline sets the read and write deadlines.
	SetDeadline(deadline time.Time) error

	// AllocReadBuffer configures the buffer to be used
	// by ReadDiscard. You MUST call this method before you
	// call ReadDiscard, or the code will crash.
	AllocReadBuffer(size int)

	// ReadDiscard reads and discard bytes. Returns the
	// number of discarded bytes or an error.
	ReadDiscard() (int64, error)

	// SetPreparedMessage sets the message that you want to
	// send in WritePreparedMessage. You MUST call this method
	// before you call WritePreparedMessage, or we'll crash.
	SetPreparedMessage(b []byte)

	// WritePreparedMessage writes the previously prepared
	// message. Returns number of bytes written or error.
	WritePreparedMessage() (int, error)

	// Close closes the measurement connection.
	Close() error
}

MeasurementConn is a measurement connection.

type MlabNSClient

type MlabNSClient interface {
	Query(ctx context.Context) (fqdn string, err error)
}

MlabNSClient is an mlab-ns client.

type NetDialer

type NetDialer interface {
	Dial(network, address string) (net.Conn, error)
	DialContext(ctx context.Context, network, address string) (net.Conn, error)
}

NetDialer is a network dialer.

type Output

type Output struct {
	CurDownloadSpeed *Speed      `json:",omitempty"`
	CurUploadSpeed   *Speed      `json:",omitempty"`
	DebugMessage     *LogMessage `json:",omitempty"`
	ErrorMessage     *Failure    `json:",omitempty"`
	InfoMessage      *LogMessage `json:",omitempty"`
	WarningMessage   *Failure    `json:",omitempty"`
}

Output is the output emitted by ndt5

type Protocol

type Protocol interface {
	SendLogin() error
	ReceiveKickoff() error
	WaitInQueue() error
	ReceiveVersion() (version string, err error)
	ReceiveTestIDs() (ids []uint8, err error)
	ExpectTestPrepare() (portnum string, err error)
	DialDownloadConn(ctx context.Context, address, userAgent string) (MeasurementConn, error)
	DialUploadConn(ctx context.Context, address, userAgent string) (MeasurementConn, error)
	ExpectTestStart() error
	ExpectTestMsg() (info string, err error)
	ExpectTestFinalize() error
	SendTestMsg(data []byte) error
	ReceiveTestFinalizeOrTestMsg() (mtype uint8, mdata []byte, err error)
	ReceiveLogoutOrResults() (mtype uint8, mdata []byte, err error)
	Close() error
}

Protocol manages a ControlConn. We currently only support the ndt5 control protocol. You may still want to override the protocol instance used by the client for testing purposes.

type ProtocolFactory

type ProtocolFactory interface {
	NewProtocol(
		ctx context.Context, fqdn, userAgent string, ch chan<- *Output) (Protocol, error)
}

ProtocolFactory creates a Protocol.

type ProtocolFactory5

type ProtocolFactory5 struct {
	// ConnectionsFactory creates connections. It's set to its
	// default value by NewClient; you may override it.
	//
	// By changing this field before starting the experiment
	// you can choose the specific transport you want.
	//
	// The default transport is the raw TCP transport that was
	// initially introduced with the NDT codebase.
	ConnectionsFactory ConnectionsFactory

	// ObserverFactory allows you to observe frame events. It's set to its
	// default value by NewClient; you may override it.
	ObserverFactory FrameReadWriteObserverFactory
}

ProtocolFactory5 is a factory that creates the ndt5 protocol

func NewProtocolFactory5

func NewProtocolFactory5() *ProtocolFactory5

NewProtocolFactory5 creates a new ProtocolFactory5 instance

func (*ProtocolFactory5) NewProtocol

func (p *ProtocolFactory5) NewProtocol(
	ctx context.Context, fqdn, userAgent string, ch chan<- *Output) (Protocol, error)

NewProtocol implements ProtocolFactory.NewProtocol

type RawConnectionsFactory

type RawConnectionsFactory struct {
	// contains filtered or unexported fields
}

RawConnectionsFactory creates ndt5 connections

func NewRawConnectionsFactory

func NewRawConnectionsFactory(dialer NetDialer) *RawConnectionsFactory

NewRawConnectionsFactory creates a factory for ndt5 connections

func (*RawConnectionsFactory) DialControlConn

func (cf *RawConnectionsFactory) DialControlConn(
	ctx context.Context, address, userAgent string) (ControlConn, error)

DialControlConn implements ConnectionsFactory.DialControlConn

func (*RawConnectionsFactory) DialMeasurementConn

func (cf *RawConnectionsFactory) DialMeasurementConn(
	ctx context.Context, address, userAgent string) (MeasurementConn, error)

DialMeasurementConn implements ConnectionsFactory.DialMeasurementConn.

type Speed

type Speed struct {
	Count   int64         // number of bytes transferred
	Elapsed time.Duration // nanoseconds since beginning
}

Speed contains a speed measurement

type TestResult

type TestResult struct {
	ClientMeasuredDownload Speed
	ServerMeasuredUpload   float64
	Web100                 map[string]string
}

TestResult is a struct storing the results of the NDT5 test.

type WSConnectionsFactory

type WSConnectionsFactory struct {
	Dialer *websocket.Dialer
	URL    *url.URL
}

WSConnectionsFactory creates ndt5+wss connections

func NewWSConnectionsFactory

func NewWSConnectionsFactory(dialer NetDialer, u *url.URL) *WSConnectionsFactory

NewWSConnectionsFactory returns a factory for ndt5+wss connections

func (*WSConnectionsFactory) DialControlConn

func (cf *WSConnectionsFactory) DialControlConn(
	ctx context.Context, address, userAgent string) (ControlConn, error)

DialControlConn implements ConnectionsFactory.DialControlConn

func (*WSConnectionsFactory) DialEx

func (cf *WSConnectionsFactory) DialEx(
	ctx context.Context, u url.URL, wsProtocol, userAgent string,
) (*websocket.Conn, error)

DialEx is the extended WebSocket dial function

func (*WSConnectionsFactory) DialMeasurementConn

func (cf *WSConnectionsFactory) DialMeasurementConn(
	ctx context.Context, address, userAgent string) (MeasurementConn, error)

DialMeasurementConn implements ConnectionsFactory.DialMeasurementConn.

Directories

Path Synopsis
cmd
ndt5-client/internal/emitter
Package emitter contains the ndt5-client emitter.
Package emitter contains the ndt5-client emitter.
ndt5-client/internal/mocks
Package mocks contains mocks
Package mocks contains mocks
internal
trafficshaping
Package trafficshaping contains code to perform traffic shaping.
Package trafficshaping contains code to perform traffic shaping.
Package mlabns implements a simple mlab-ns client.
Package mlabns implements a simple mlab-ns client.

Jump to

Keyboard shortcuts

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