fixture

package
v0.0.0-...-15a9a0c Latest Latest
Warning

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

Go to latest
Published: May 19, 2023 License: BSD-3-Clause Imports: 18 Imported by: 0

Documentation

Overview

Package fixture provides fixture stack data structure.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewHandler

func NewHandler(server *StackServer) processor.Handler

NewHandler creates a handler which handles stack operation.

Types

type CombinedStack

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

CombinedStack combines two stacks and show them as a single stack.

func NewCombinedStack

func NewCombinedStack(parent *ExternalStack, child *InternalStack) *CombinedStack

NewCombinedStack creates a new CombinedStack.

func (*CombinedStack) Errors

func (s *CombinedStack) Errors() []*protocol.Error

Errors returns errors to be reported for tests depending on this fixture stack. See InternalStack.Errors for details.

func (*CombinedStack) Pop

func (s *CombinedStack) Pop(ctx context.Context) error

Pop removes the top-most fixture from the fixture stack. See InternalStack.Pop for details.

func (*CombinedStack) PreTest

func (s *CombinedStack) PreTest(ctx context.Context, test *protocol.Entity, outDir string, out testing.OutputStream, condition *testing.EntityCondition) (func(context.Context) error, error)

PreTest runs PreTests on the fixtures. It returns a post test hook that runs PostTests on the fixtures.

func (*CombinedStack) Push

Push adds a new fixture to the top of the fixture stack. See InternalStack.Push for details.

func (*CombinedStack) Reset

func (s *CombinedStack) Reset(ctx context.Context) error

Reset resets all fixtures on the stack if the stack is green. Reset clears the dirty flag of the stack. See InternalStack.Reset for details.

func (*CombinedStack) SerializedVal

func (s *CombinedStack) SerializedVal(ctx context.Context) ([]byte, error)

SerializedVal returns the serialized fixture value obtained on setup.

func (*CombinedStack) SetDirty

func (s *CombinedStack) SetDirty(ctx context.Context, dirty bool) error

SetDirty marks the fixture stack dirty. It returns an error if dirty is true and the stack is already dirty. The dirty flag can be cleared by calling Reset. SetDirty(true) can be called before running a test to make sure Reset is called for sure between tests.

func (*CombinedStack) Status

func (s *CombinedStack) Status() Status

Status returns the current status of the fixture stack.

func (*CombinedStack) Top

Top returns the state of the top fixture. If the child stack is empty, it returns zero value.

func (*CombinedStack) Val

func (s *CombinedStack) Val() interface{}

Val returns the fixture value obtained on setup.

type Config

type Config struct {
	// DataDir and other fields are subset of the fields in planner.Config.
	// See its description for details.
	DataDir           string
	OutDir            string
	Vars              map[string]string
	Service           *protocol.ServiceConfig
	BuildArtifactsURL string
	RemoteData        *testing.RemoteData
	StartFixtureName  string
	// Features contains software/hardware features each DUT has, and runtime variables.
	// Its key for the map is the role of the DUT such as "cd1".
	// The role for primary DUT should be "".
	Features map[string]*frameworkprotocol.DUTFeatures
	// GracePeriod specifies the grace period after fixture timeout.
	GracePeriod time.Duration
}

Config contains details about how to run fixtures.

type ExternalStack

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

ExternalStack operates fixtures in a remote bundle.

func NewExternalStack

func NewExternalStack(ctx context.Context, out output.Stream) (*ExternalStack, error)

NewExternalStack creates a new ExternalStack.

func (*ExternalStack) Errors

func (s *ExternalStack) Errors() []*protocol.Error

Errors returns errors of the underlying stack.

func (*ExternalStack) PreTest

func (s *ExternalStack) PreTest(ctx context.Context, test *protocol.Entity, condition *testing.EntityCondition) (func(context.Context) error, error)

PreTest runs PreTest on the underlying stack.

func (*ExternalStack) Reset

func (s *ExternalStack) Reset(ctx context.Context) error

Reset runs Reset on the underlying stack.

func (*ExternalStack) SerializedVal

func (s *ExternalStack) SerializedVal(ctx context.Context) ([]byte, error)

SerializedVal returns the serialized value

func (*ExternalStack) SetDirty

func (s *ExternalStack) SetDirty(ctx context.Context, dirty bool) error

SetDirty runs SetDirty on the underlying stack.

func (*ExternalStack) Status

func (s *ExternalStack) Status() Status

Status returns status of the underlying stack.

func (*ExternalStack) Val

func (s *ExternalStack) Val() (val interface{})

Val returns nil. TODO(oka): support remote fixture value.

type InternalStack

type InternalStack struct {
	ParentFixtSerializedValue func() ([]byte, error) // ParentFixtSerializedValue is needed its parent is an external stack.
	// contains filtered or unexported fields
}

InternalStack maintains a stack of fixtures in the current bundle and their states.

A fixture stack corresponds to a path from the root of a fixture tree. As we traverse a fixture tree, a new child fixture is pushed to the stack by Push, or a fixture of the lowest level is popped from the stack by Pop, calling their SetUp/TearDown methods as needed.

A fixture is in exactly one of three statuses: green, yellow, and red.

  • A fixture is green if it has been successfully set up and never failed to reset so far.
  • A fixture is yellow if it has been successfully set up but failed to reset.
  • A fixture is red if it has been torn down.

The following diagram illustrates the status transition of a fixture:

                                 OK
                           +-------------+
                           v             |
+-----+  SetUp     OK  +-------+  Reset  |  Fail  +--------+
| red |---------+----->| green |---------+--name----->| yellow |
+-----+         |      +-------+                  +--------+
 ^ ^ ^          | Fail     |                          |
 | | +----------+          | TearDown                 | TearDown
 | +-----------------------+                          |
 +----------------------------------------------------+

InternalStack maintains the following invariants about fixture statuses:

  1. When there is a yellow fixture in the stack, no other fixtures are red.
  2. When there is no yellow fixture in the stack, there is an integer k (0 <= k <= n; n is the number of fixtures in the stack) where the first k fixtures from the bottom of the stack are green and the remaining fixtures are red.

A fixture stack can be also in exactly one of three statuses: green, yellow, and red.

  • A fixture stack is green if all fixtures in the stack are green.
  • A fixture stack is yellow if any fixture in the stack is yellow.
  • A fixture stack is red if any fixture in the stack is red.

An empty fixture stack is green. When SetUp fails on pushing a new fixture to an green stack, the stack becomes red until the failed fixture is popped from the stack. It is still possible to push more fixtures to the stack, but SetUp is not called for those fixtures, and the stack remains red. This behavior allows continuing to traverse a fixture tree despite SetUp failures. When Reset fails between tests, the stack becomes yellow until the bottom-most yellow fixture is popped from the stack. It is not allowed to push more fixtures to the stack in this case.

The following diagram illustrates the status transition of a fixture stack:

                                         OK
                                   +------------+          +-+ Push
                                   v            |          v |
   +--------+  Fail     Reset  +-------+  Push  |  Fail  +-----+
+->| yellow |<-------+---------| green |--------+------->| red |<-+
|  +--------+        |         +-------+                 +-----+  |
|       |            | OK        ^ ^ ^                      |     |
|       | Pop        |           | | |                      | Pop |
|       |            +-----------+ | |                      |     |
+-------+--------------------------+ +----------------------+-----+

A fixture stack is clean or dirty. A stack is initially clean. A clean stack can be marked dirty with MarkDirty. It is an error to call MarkDirty on a dirty stack. The dirty flag can be cleared by Reset. MarkDirty can be called before running a test to make sure Reset is called for sure between tests.

func NewInternalStack

func NewInternalStack(cfg *Config, out output.Stream) *InternalStack

NewInternalStack creates a new empty fixture stack.

func (*InternalStack) Errors

func (st *InternalStack) Errors() []*protocol.Error

Errors returns errors to be reported for tests depending on this fixture stack.

If there is no red fixture in the stack, an empty slice is returned. Otherwise, this function returns a slice of error messages to be reported for tests depending on the fixture stack. An error message is formatted in the following way:

[Fixture failure] (fixture name): (original error message)

func (*InternalStack) MarkDirty

func (st *InternalStack) MarkDirty() error

MarkDirty marks the fixture stack dirty. It returns an error if the stack is already dirty.

The dirty flag can be cleared by calling Reset. MarkDirty can be called before running a test to make sure Reset is called for sure between tests.

func (*InternalStack) Pop

func (st *InternalStack) Pop(ctx context.Context) error

Pop removes the top-most fixture from the fixture stack.

If the top-most fixture is green or yellow, its TearDown method is called.

func (*InternalStack) PreTest

func (st *InternalStack) PreTest(ctx context.Context, outDir string, out testing.OutputStream, condition *testing.EntityCondition, testEntity *protocol.Entity) (func(ctx context.Context) error, error)

PreTest runs PreTests on the fixtures. It returns a post test hook that runs PostTests on the fixtures.

func (*InternalStack) Push

Push adds a new fixture to the top of the fixture stack.

If the current fixture stack is green, the new fixture's SetUp is called, and the resulting fixture stack is either green or red.

If the current fixture stack is red, the new fixture's SetUp is not called and the resulting fixture stack is red.

It is an error to call Push for a yellow fixture stack.

func (*InternalStack) Reset

func (st *InternalStack) Reset(ctx context.Context) error

Reset resets all fixtures on the stack if the stack is green.

Reset clears the dirty flag of the stack.

Reset is called in bottom-to-top order. If any fixture fails to reset, the fixture and fixture stack becomes yellow.

Unless the fixture execution is abandoned, this method returns success even if Reset returns an error and the fixture becomes yellow. Callers should check Status after calling Reset to see if they can proceed to pushing more fixtures on the stack.

If the stack is red, Reset does nothing. If the stack is yellow, it is an error to call this method.

func (*InternalStack) SerializedVal

func (st *InternalStack) SerializedVal(ctx context.Context) ([]byte, error)

SerializedVal returns the serialized fixture value of the top fixture.

If the fixture stack is empty or red, it returns nil.

func (*InternalStack) Status

func (st *InternalStack) Status() Status

Status returns the current status of the fixture stack.

func (*InternalStack) Val

func (st *InternalStack) Val() interface{}

Val returns the fixture value of the top fixture.

If the fixture stack is empty or red, it returns nil.

type StackServer

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

StackServer provides handling of stack operation requests from local bundles.

func NewStackServer

func NewStackServer(cfg *StackServerConfig) *StackServer

NewStackServer creates a new StackServer.

func (*StackServer) Errors

Errors runs Errors on stack.

func (*StackServer) FixtValue

FixtValue returns a serialized value on Errors on stack.

func (*StackServer) Handle

Handle handles a stack operation request. If a framework error happens during the handling, FatalError field in the response will be populated with the error message. If FatalError is empty, it means the operation has been successful.

func (*StackServer) PostTest

PostTest runs PostTest on stack.

func (*StackServer) PreTest

PreTest constructs a TestEntityRoot, and calls PreTest on the stack. It stores a callback function for PostTest, so to invoke it on the next PostTest request. It's an error to call PreTest before PostTest is called after a successful PreTest.

func (*StackServer) Reset

Reset runs Reset on stack.

func (*StackServer) SetDirty

SetDirty runs SetDirty on stack. TODO(oka): Consider removing SetDirty as it's only for debugging and adds round-trips between bundles.

func (*StackServer) Status

Status runs Status on stack.

type StackServerConfig

type StackServerConfig struct {
	// Out is the output stream.
	Out output.Stream
	// Stack is the stack to operate.
	Stack *CombinedStack
	// OutDir is the common output directory.
	OutDir string

	CloudStorage *testing.CloudStorage
	RemoteData   *testing.RemoteData
}

StackServerConfig contains static information the server should have to run stack methods.

type Status

type Status int

Status represents a status of a fixture, as well as that of a fixture stack. See comments around InternalStack for details.

const (
	// StatusRed means fixture is not set up or torn down.
	StatusRed Status = iota
	// StatusGreen means fixture is set up.
	StatusGreen
	// StatusYellow means fixture is set up but last reset failed
	StatusYellow
)

func (Status) String

func (s Status) String() string

String converts fixtureStatus to a string for debugging.

Jump to

Keyboard shortcuts

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