Documentation
¶
Index ¶
- Constants
- func NewReportStore() *reportStore
- type Action
- type Condition
- func IsEventOf(replica types.ReplicaID) Condition
- func IsEventType(t string) Condition
- func IsMessageFrom(from types.ReplicaID) Condition
- func IsMessageFromF(replicaF func(*types.Event, *Context) (types.ReplicaID, bool)) 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 Once(c Condition) Condition
- type Context
- 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 HandlerCascade
- type HandlerCascadeOption
- type HandlerFunc
- type IfThenHandler
- type ReplicaFunc
- type SetWrapper
- type State
- type StateMachine
- type StateMachineBuilder
- type TestCase
- type TestingServer
- type TimeoutDriver
- 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.MessageStore, 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 ¶
This section is empty.
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 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
func RestartReplica ¶ added in v0.1.4
func RestartReplica(replicaFunc ReplicaFunc) Action
RestartReplica is the action to restart a replica. The replica details are fetched dynamically through the specified function
func StartReplica ¶ added in v0.1.4
func StartReplica(replicaFunc ReplicaFunc) Action
StartReplica is the action to start a replica. The replica details are fetched dynamically through the specified function
func StopReplica ¶ added in v0.1.4
func StopReplica(replicaFunc ReplicaFunc) Action
StopReplica is the action to stop a replica. The replica details are fetched dynamically through the specified function
type Condition ¶
Condition type to define predicates over the current event or the history of events
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 ¶ added in v0.1.3
IsMessageFromF works the same as IsMessageFrom but the replica is fetched from the event and context
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 ¶ added in v0.1.3
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 Once ¶ added in v0.1.4
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.MessageStore // 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 facilate maintaining auxilliary 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) 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 HandlerCascade ¶
type HandlerCascade struct { Handlers []HandlerFunc DefaultHandler HandlerFunc }
HandlerCascade 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 NewHandlerCascade ¶
func NewHandlerCascade(opts ...HandlerCascadeOption) *HandlerCascade
NewHandlerCascade creates a new cascade handler with the specified state machine and options
func (*HandlerCascade) AddHandler ¶
func (c *HandlerCascade) AddHandler(h HandlerFunc)
AddHandler adds a handler to the cascade
type HandlerCascadeOption ¶
type HandlerCascadeOption func(*HandlerCascade)
HandlerCascadeOption changes the parameters of the HandlerCascade
func WithDefault ¶
func WithDefault(d HandlerFunc) HandlerCascadeOption
WithDefault changes the HandlerCascade default handler
type HandlerFunc ¶
HandlerFunc 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) HandlerFunc
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 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) HandlerFunc
Then returns a HandlerFunc which encodes the `If().Then()` semantics. Accepts actions as arguments
type ReplicaFunc ¶ added in v0.1.4
func EventReplica ¶ added in v0.1.4
func EventReplica() ReplicaFunc
EventReplica ReplicaFunc returns the replica of the current event.
func MessageFrom ¶ added in v0.1.4
func MessageFrom() ReplicaFunc
MessageFrom ReplicaFunc returns the message from replica, if the event is a message send/receive
func MessageTo ¶ added in v0.1.4
func MessageTo() ReplicaFunc
MessageTo ReplicaFunc returns the message to replica, if the event is a message send/receive
type SetWrapper ¶
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 *HandlerCascade // 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 *HandlerCascade) *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 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 TimeoutDriver ¶
type TimeoutDriver struct {
// contains filtered or unexported fields
}
Flow of execution
- Update the timeout context with the current event that is observed a. Keep track of pending timeouts b. Keep track of messages that have been delivered but not acknowledged
- Check delivery of messages that are currently intended to be delivered a. Easy to modify graph (mark nodes as clean and dirty) b. Check spuriousness (this can be configured explicitly) c. Easy algorithm to check spuriousness d. algorithm to order the timeouts that need to be fired.
- Update with additional timers that need to be fired a. Parameterized strategy to pick timeouts b. Ability for filters to mark certain timeouts to be fired earlier
func NewTimeoutDriver ¶
func NewTimeoutDriver(store *types.TimeoutStore) *TimeoutDriver
func (*TimeoutDriver) NewEvent ¶
func (t *TimeoutDriver) NewEvent(e *types.Event)
func (*TimeoutDriver) ToDispatch ¶
func (t *TimeoutDriver) ToDispatch() []*types.ReplicaTimeout
type VarSet ¶
type VarSet struct {
// contains filtered or unexported fields
}
VarSet is a dictionary for storing auxilliary 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 ¶
func (v *VarSet) GetMessageSet(label string) (*types.MessageStore, bool)
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