sm

package
v0.3.5 Latest Latest
Warning

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

Go to latest
Published: Jan 24, 2023 License: MIT Imports: 6 Imported by: 12

Documentation

Overview

Package sm defines the state machine used to specify properties to test for.

The package also defines a builder interface that can be used to construct the state machine in an intuitive manner.

Index

Constants

View Source
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

This section is empty.

Types

type Action added in v0.2.1

type Action func(*types.Event, *Context)

Action is a generic function that can be used to define side effects in the context

type Condition

type Condition func(e *types.Event, c *Context) bool

Condition a generic function that used to transition the StateMachine from one state to the next.

func ConditionWithAction added in v0.2.1

func ConditionWithAction(cond Condition, action Action) Condition

ConditionWithAction creates a condition with the side effect given by Action

func IsEventOf

func IsEventOf(replica types.ReplicaID) Condition

IsEventOf returns true if the event if of the specified replica

func IsEventOfF

func IsEventOfF(replicaFunc func(*types.Event, *Context) (types.ReplicaID, bool)) Condition

IsEventOfF accepts a function to specify the replica and returns true if the event is of that corresponding replica.

func IsEventType

func IsEventType(t string) Condition

IsEventType condition returns true if the event is of type types.GenericEventType with T == t

func IsMessageBetween added in v0.2.2

func IsMessageBetween(one, two types.ReplicaID) Condition

IsMessage between condition is true when the underlying event is a message between the two specified processes.

func IsMessageFrom

func IsMessageFrom(from types.ReplicaID) Condition

IsMessageFrom condition returns true if the event is a message send or receive with message.From == from

func IsMessageFromF

func IsMessageFromF(replicaF func(*types.Event, *Context) (types.ReplicaID, bool)) Condition

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

func IsMessageTo(to types.ReplicaID) Condition

IsMessageTo condition returns true if the event is a message send or receive with message.To == to

func IsMessageToF

func IsMessageToF(replicaF func(*types.Event, *Context) (types.ReplicaID, bool)) Condition

IsMessageToF works the same as IsMessageTo but the replica is fetched from the event and context

func IsMessageType

func IsMessageType(t string) Condition

IsMessageType condition returns true if the event is a message send or receive and the type of message is `t`

func OnceCondition

func OnceCondition(name string, c Condition) Condition

Once is a meta condition that allows the inner condition to be true only once

func (Condition) And

func (c Condition) And(other Condition) Condition

And to create boolean conditional expressions

func (Condition) Not

func (c Condition) Not() Condition

Not to create boolean conditional expressions

func (Condition) Or

func (c Condition) Or(other Condition) Condition

Or to create boolean conditional expressions

type Context

type Context struct {
	MessagePool  *types.Map[types.MessageID, *types.Message]
	ReplicaStore *types.ReplicaStore
	EventDAG     *types.EventDAG
	Vars         *types.VarSet
	Logger       *log.Logger
}

Context used to step the state machine. The Context is passed to the Condition.

func NewContext

func NewContext(ctx *context.RootContext, logger *log.Logger) *Context

NewContext creates a new context from the global context object.

func (*Context) GetMessage

func (c *Context) GetMessage(e *types.Event) (*types.Message, bool)

GetMessage helper function used to fetch the message for the corresponding event This returns the message only when the event is a send or a receive.

type CountWrapper

type CountWrapper struct {
	CounterFunc func(*types.Event, *Context) (*types.Counter, bool)
}

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

func CountF(labelFunc func(*types.Event, *Context) (string, bool)) *CountWrapper

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

func (c *CountWrapper) EqF(val func(*types.Event, *Context) (int, bool)) Condition

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

func (c *CountWrapper) GeqF(val func(*types.Event, *Context) (int, bool)) Condition

GeqF condition that returns true if the counter value is greater 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

func (c *CountWrapper) GtF(val func(*types.Event, *Context) (int, bool)) Condition

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 added in v0.2.1

func (c *CountWrapper) Incr() Action

Incr is an action that increments the counter

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

func (c *CountWrapper) LeqF(val func(*types.Event, *Context) (int, bool)) Condition

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.

func (*CountWrapper) LtF

func (c *CountWrapper) LtF(valF func(*types.Event, *Context) (int, bool)) Condition

LtF condition that returns true if the counter value is less than the specified value. The input is a function that obtains the value dynamically based on the event and context.

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

func SetF(labelFunc func(*types.Event, *Context) (string, bool)) *SetWrapper

SetF returns a SetWrapper where the label is determined dynamically by the event and context

func (*SetWrapper) Add added in v0.2.1

func (s *SetWrapper) Add() Action

Add is an action that adds the corresponding message (if any) to the 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

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) Eq

func (s *State) Eq(other *State) bool

Eq returns true if the two state labels are the same

func (*State) Is

func (s *State) Is(l string) bool

Is returns true if the label matches with the current state label

func (*State) MarshalJSON

func (s *State) MarshalJSON() ([]byte, error)

For serializing the

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) Reset

func (s *StateMachine) Reset()

Reset the state machine to its initial state

func (*StateMachine) Step

func (s *StateMachine) Step(e *types.Event, c *Context)

Step runs the next step of the state machine for the current event.

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

On can be used to create a transition relation between states based on the specified condition

Jump to

Keyboard shortcuts

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