Documentation
¶
Index ¶
- Constants
- Variables
- func NewReportStore() *reportStore
- type Action
- type Condition
- func IsEventOf(replica types.ReplicaID) Condition
- func IsEventOfF(replicaFunc func(*types.Event, *Context) (types.ReplicaID, bool)) Condition
- func IsEventType(t string) Condition
- func IsMessageFrom(from types.ReplicaID) Condition
- func IsMessageFromF(replicaF func(*types.Event, *Context) (types.ReplicaID, bool)) Condition
- func IsMessageFromPart(partLabel string) Condition
- func IsMessageReceive() Condition
- func IsMessageSend() Condition
- func IsMessageTo(to types.ReplicaID) Condition
- func IsMessageToF(replicaF func(*types.Event, *Context) (types.ReplicaID, bool)) Condition
- func IsMessageType(t string) Condition
- func OnceCondition(c Condition) Condition
- type Context
- func (c *Context) Abort()
- func (c *Context) CreatePartition(sizes []int, labels []string)
- func (c *Context) EndTestCase()
- func (c *Context) GetMessage(e *types.Event) (*types.Message, bool)
- func (c *Context) Log(keyvals map[string]string)
- func (c *Context) Logger() *log.Logger
- func (c *Context) NewMessage(cur *types.Message, data []byte) *types.Message
- type CountWrapper
- func (c *CountWrapper) Eq(val int) Condition
- func (c *CountWrapper) EqF(val func(*types.Event, *Context) (int, bool)) Condition
- func (c *CountWrapper) Geq(val int) Condition
- func (c *CountWrapper) GeqF(val func(*types.Event, *Context) (int, bool)) Condition
- func (c *CountWrapper) Gt(val int) Condition
- func (c *CountWrapper) GtF(val func(*types.Event, *Context) (int, bool)) Condition
- func (c *CountWrapper) Incr() Action
- func (c *CountWrapper) Leq(val int) Condition
- func (c *CountWrapper) LeqF(val func(*types.Event, *Context) (int, bool)) Condition
- func (c *CountWrapper) Lt(val int) Condition
- func (c *CountWrapper) LtF(valF func(*types.Event, *Context) (int, bool)) Condition
- type Counter
- type FilterFunc
- type FilterSet
- type FilterSetOption
- type IfThenHandler
- type ReplicaPartition
- type SetWrapper
- type State
- type StateMachine
- type StateMachineBuilder
- type TestCase
- type TestCaseDriver
- type TestingServer
- type VarSet
- func (v *VarSet) Exists(label string) bool
- func (v *VarSet) Get(label string) (interface{}, bool)
- func (v *VarSet) GetBool(label string) (bool, bool)
- func (v *VarSet) GetCounter(label string) (*Counter, bool)
- func (v *VarSet) GetInt(label string) (int, bool)
- func (v *VarSet) GetMessageSet(label string) (*types.Map[types.MessageID, *types.Message], bool)
- func (v *VarSet) GetString(label string) (string, bool)
- func (v *VarSet) NewMessageSet(label string)
- func (v *VarSet) Set(label string, value interface{})
- func (v *VarSet) SetCounter(label string)
Constants ¶
const ( // StartStateLabel is the start state label of a state machine StartStateLabel = "startState" // FailStateLabel is the failure state label FailStateLabel = "failState" // SuccessStateLabel is the state label of the success state SuccessStateLabel = "successState" )
Variables ¶
var ( ErrNotEnoughReplicas = errors.New("not enough replicas") ErrSizeLabelsMismatch = errors.New("sizes and labels are not of the same length") )
Functions ¶
func NewReportStore ¶
func NewReportStore() *reportStore
Types ¶
type Action ¶
Action is used to specify the consequence in the `If().Then()` handler
func DeliverMessage ¶
func DeliverMessage() Action
DeliverMessage returns the message if the event is a message send event
func OnceAction ¶ added in v0.1.1
func RecordMessageAs ¶
RecordMessageAs returns an action. If the event is a message send or receive, the message is recorded in context with the label as reference
type Condition ¶
Condition type to define predicates over the current event or the history of events
func IsEventOfF ¶ added in v0.1.1
func IsEventType ¶
IsEventType condition returns true if the event is GenericEventType with T == t
func IsMessageFrom ¶
IsMessageFrom condition returns true if the event is a message send or receive with message.From == from
func IsMessageFromF ¶
IsMessageFromF works the same as IsMessageFrom but the replica is fetched from the event and context
func IsMessageFromPart ¶ added in v0.1.1
func IsMessageReceive ¶
func IsMessageReceive() Condition
IsMessageReceive condition returns true if the event is a message receive event
func IsMessageSend ¶
func IsMessageSend() Condition
IsMessageSend condition returns true if the event is a message send event
func IsMessageTo ¶
IsMessageTo condition returns true if the event is a message send or receive with message.To == to
func IsMessageToF ¶
IsMessageToF works the same as IsMessageTo but the replica is fetched from the event and context
func IsMessageType ¶
IsMessageType condition returns true if the event is a message send or receive and the type of message is `t`
func OnceCondition ¶ added in v0.1.1
Once is a meta condition that allows the inner condition to be true only once
type Context ¶
type Context struct {
// MessagePool reference to an instance of the MessageStore
MessagePool *types.Map[types.MessageID, *types.Message]
// Replicas reference to the replica store
Replicas *types.ReplicaStore
// EventDAG is the directed acyclic graph all prior events
EventDAG *types.EventDAG
// Vars is a generic key value store to facilitate maintaining auxiliary information
// during the execution of a testcase
Vars *VarSet
// contains filtered or unexported fields
}
Context struct is passed to the calls of StateAction and Condition encapsulates all information needed by the StateAction and Condition to function
func (*Context) CreatePartition ¶ added in v0.1.1
func (*Context) EndTestCase ¶
func (c *Context) EndTestCase()
Ends the testcase without failing. The assertion will determine the success of the testcase
func (*Context) GetMessage ¶
GetMessage returns the `Message` struct from the Message pool if the event provided is a message send ot receive event
type CountWrapper ¶
CountWrapper encapsulates the function to fetch counter (CounterFunc) from state dynamically. CountWrapper is used to define actions and condition based on the counter.
func Count ¶
func Count(label string) *CountWrapper
Count returns a CountWrapper where the CounterFunc fetches the counter based on the label
func CountF ¶
CountF returns a CountWrapper where the label is also fetched based on the event and context
func CountTo ¶
func CountTo(label string) *CountWrapper
CountTo returns a CountWrapper where the counter label is `label` appended with message.To, if the event is a message send or receive
func (*CountWrapper) Eq ¶
func (c *CountWrapper) Eq(val int) Condition
Eq condition that returns true if the counter value is equal to the specified value.
func (*CountWrapper) EqF ¶
EqF condition that returns true if the counter value is equal to the specified value. The input is a function that obtains the value dynamically based on the event and context.
func (*CountWrapper) Geq ¶
func (c *CountWrapper) Geq(val int) Condition
Geq condition that returns true if the counter value is greater than or equal to the specified value.
func (*CountWrapper) GeqF ¶
GeqF condition that returns true if the counter value is greather than or equal to the specified value. The input is a function that obtains the value dynamically based on the event and context.
func (*CountWrapper) Gt ¶
func (c *CountWrapper) Gt(val int) Condition
Gt condition that returns true if the counter value is greater than the specified value.
func (*CountWrapper) GtF ¶
GtF condition that returns true if the counter value is greater than the specified value. The input is a function that obtains the value dynamically based on the event and context.
func (*CountWrapper) Incr ¶
func (c *CountWrapper) Incr() Action
Incr returns an action which increments the counter value
func (*CountWrapper) Leq ¶
func (c *CountWrapper) Leq(val int) Condition
Leq condition that returns true if the counter value is less than or equal to the specified value.
func (*CountWrapper) LeqF ¶
LeqF condition that returns true if the counter value is less than or equal to the specified value. The input is a function that obtains the value dynamically based on the event and context.
func (*CountWrapper) Lt ¶
func (c *CountWrapper) Lt(val int) Condition
Lt condition that returns true if the counter value is less than the specified value.
type Counter ¶
type Counter struct {
// contains filtered or unexported fields
}
Counter threadsafe counter
type FilterFunc ¶
FilterFunc type to define a conditional handler returns false in the second return value if the handler is not concerned about the event
func NewStateMachineHandler ¶
func NewStateMachineHandler(stateMachine *StateMachine) FilterFunc
NewStateMachineHandler returns a HandlerFunc that encodes the execution logic of the StateMachine For every invocation of the handler, internall a state machine step is executed which may or may not transition. If the StateMachine transitions to FailureState, the handler aborts the testcase
type FilterSet ¶
type FilterSet struct {
Filters []FilterFunc
DefaultFilter FilterFunc
}
FilterSet implements Handler Executes handlers in the specified order until the event is handled If no handler handles the event then the default handler is called
func NewFilterSet ¶
func NewFilterSet(opts ...FilterSetOption) *FilterSet
NewFilterSet creates a new cascade handler with the specified state machine and options
func (*FilterSet) AddFilter ¶
func (c *FilterSet) AddFilter(h FilterFunc)
AddFilter adds a handler to the cascade
type FilterSetOption ¶
type FilterSetOption func(*FilterSet)
FilterSetOption changes the parameters of the HandlerCascade
func WithDefault ¶
func WithDefault(d FilterFunc) FilterSetOption
WithDefault changes the HandlerCascade default handler
type IfThenHandler ¶
type IfThenHandler struct {
// contains filtered or unexported fields
}
IfThenHandler struct is used to wrap the attributes of the `If().Then()` handler
func If ¶
func If(cond Condition) *IfThenHandler
If creates a IfThenHandler with the specified condition
func (*IfThenHandler) Then ¶
func (i *IfThenHandler) Then(action Action, rest ...Action) FilterFunc
Then returns a HandlerFunc which encodes the `If().Then()` semantics. Accepts actions as arguments
type ReplicaPartition ¶ added in v0.1.1
type ReplicaPartition struct {
// contains filtered or unexported fields
}
func NewPartition ¶ added in v0.1.1
func NewPartition(replicas *types.ReplicaStore, sizes []int, labels []string) (*ReplicaPartition, error)
type SetWrapper ¶
type SetWrapper struct {
SetFunc func(*types.Event, *Context) (*types.Map[types.MessageID, *types.Message], bool)
}
SetWrapper encapsulates the mechanism to fetch a message set from the state. SetFunc should return a message set given the current event and context.
func Set ¶
func Set(label string) *SetWrapper
Set returns a SetWrapper where the set is fetched based on the label
func SetF ¶
SetF returns a SetWrapper where the label is determined dynamically by the event and context
func (*SetWrapper) Contains ¶
func (s *SetWrapper) Contains() Condition
Contains condition returns true if the event is a message send or receive and the message is apart of the message set.
func (*SetWrapper) Count ¶
func (s *SetWrapper) Count() *CountWrapper
Count returns a counter where the value is size of the message set
func (*SetWrapper) DeliverAll ¶
func (s *SetWrapper) DeliverAll() Action
DeliverAll returns an action which inturn returns all the messages in the message set and removes the messages from the set.
func (*SetWrapper) Store ¶
func (s *SetWrapper) Store() Action
Store returns an action. If the event is a message send or receive, the action adds the message to the message set
type State ¶
type State struct {
Label string `json:"label"`
Transitions map[string]Condition `json:"-"`
Success bool `json:"success"`
// contains filtered or unexported fields
}
State of the testcase state machine
func (*State) MarshalJSON ¶
type StateMachine ¶
type StateMachine struct {
// contains filtered or unexported fields
}
StateMachine is a deterministic transition system where the transitions are labelled by conditions
func NewStateMachine ¶
func NewStateMachine() *StateMachine
NewStateMachine instantiate a StateMachine
func (*StateMachine) Builder ¶
func (s *StateMachine) Builder() StateMachineBuilder
Builder retruns a StateMachineBuilder instance which provides a builder patter to construct the state machine
func (*StateMachine) CurState ¶
func (s *StateMachine) CurState() *State
CurState return the State that the StateMachine is currently in
func (*StateMachine) InState ¶
func (s *StateMachine) InState(state string) Condition
InState returns a condition which is true if the StateMachine is in a specific state. This can be used to define handler that access the state
func (*StateMachine) InSuccessState ¶
func (s *StateMachine) InSuccessState() bool
InSuccessState returns true if the current state of the state machine is a success state
func (*StateMachine) Transition ¶
func (s *StateMachine) Transition(to string)
Transition moves the current stat eof the StateMachine to the specified state
type StateMachineBuilder ¶
type StateMachineBuilder struct {
// contains filtered or unexported fields
}
StateMachineBuilder struct defines a builder pattern to create a state machine
func (StateMachineBuilder) MarkSuccess ¶
func (s StateMachineBuilder) MarkSuccess() StateMachineBuilder
MarkSuccess marks the current state of the builder as a success state
func (StateMachineBuilder) On ¶
func (s StateMachineBuilder) On(cond Condition, stateLabel string) StateMachineBuilder
On can be used to create a transition relation between states based on the specified condition
type TestCase ¶
type TestCase struct {
// Name name of the testcase
Name string
// Timeout maximum duration of the testcase execution
Timeout time.Duration
// Cascade instance of *HandlerCascade
Cascade *FilterSet
// StateMachine instance of *StateMachine to assert a property
StateMachine *StateMachine
// Logger to log information
Logger *log.Logger
// contains filtered or unexported fields
}
TestCase represents a unit test case
func NewTestCase ¶
func NewTestCase(name string, timeout time.Duration, sm *StateMachine, cascade *FilterSet) *TestCase
NewTestCase instantiates a TestCase based on the parameters specified The new testcase has three states by default. - Start state where the execution starts from - Fail state that can be used to fail the testcase - Success state that can be used to indicate a success of the testcase
type TestCaseDriver ¶ added in v0.1.1
type TestCaseDriver struct {
TestCase *TestCase
// contains filtered or unexported fields
}
func NewTestDriver ¶ added in v0.1.1
func NewTestDriver(ctx *context.RootContext, testcase *TestCase) *TestCaseDriver
type TestingServer ¶
type TestingServer struct {
*types.BaseService
// contains filtered or unexported fields
}
TestingServer is used to run the scheduler tool for unit testing
func NewTestingServer ¶
func NewTestingServer(config *config.Config, messageParser types.MessageParser, testcases []*TestCase) (*TestingServer, error)
NewTestingServer instantiates TestingServer testcases are passed as arguments
func (*TestingServer) Done ¶
func (srv *TestingServer) Done() chan string
Done returns the channel which will be closed once all testcases are run
func (*TestingServer) Name ¶
func (srv *TestingServer) Name() string
Name implements DashboardRouter
func (*TestingServer) SetupRouter ¶
func (srv *TestingServer) SetupRouter(router *gin.RouterGroup)
SetupRouter for setting up the dashboard routes implements DashboardRouter
func (*TestingServer) Start ¶
func (srv *TestingServer) Start()
Start starts the TestingServer and implements Service
func (*TestingServer) Stop ¶
func (srv *TestingServer) Stop()
Stop stops the TestingServer and implements Service
type VarSet ¶
type VarSet struct {
// contains filtered or unexported fields
}
VarSet is a dictionary for storing auxiliary state during the execution of the testcase VarSet is stored in the context passed to actions and conditions
func (*VarSet) Get ¶
Get returns the value stored of the specified label the second return argument is false if the label does not exist
func (*VarSet) GetBool ¶
GetBool casts the value at label (if it exists) into boolean and returns it
func (*VarSet) GetCounter ¶
GetCounter returns the counter at the label if it exists (nil, false) otherwise
func (*VarSet) GetMessageSet ¶
GetMessageSet returns the message set at label if one exists (nil, false) otherwise
func (*VarSet) GetString ¶
GetString casts the value at label (if it exists) into string and returns it
func (*VarSet) NewMessageSet ¶
NewMessageSet creates a message set at the specified label
func (*VarSet) SetCounter ¶
SetCounter sets a counter instance at the specified label with initial value 1