/
scenario.go
123 lines (111 loc) · 3.65 KB
/
scenario.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package spec
import "fmt"
// ScenarioDoc is a scenario document as part of a simulation.
type ScenarioDoc struct {
Schema string `json:"schema" yaml:"schema"`
Name string `json:"name" yaml:"name"`
Source string `json:"source" yaml:"source"`
Description string `json:"description" yaml:"description"`
Version string `json:"version" yaml:"version"`
Interfaces []*InterfaceEntry `json:"interfaces" yaml:"interfaces"`
Sequences []*SequenceEntry `json:"sequences" yaml:"sequences"`
}
func (d *ScenarioDoc) Validate() error {
if d.Interfaces == nil {
d.Interfaces = make([]*InterfaceEntry, 0)
}
if d.Sequences == nil {
d.Sequences = make([]*SequenceEntry, 0)
}
for _, iface := range d.Interfaces {
if err := iface.Validate(); err != nil {
return err
}
}
for _, sequence := range d.Sequences {
if err := sequence.Validate(); err != nil {
return err
}
}
return nil
}
// GetInterface returns the interface entry with the given name.
func (s *ScenarioDoc) GetInterface(name string) *InterfaceEntry {
for _, iface := range s.Interfaces {
if iface.Name == name {
return iface
}
}
return nil
}
// GetSequence returns the sequence entry with the given name.
func (s *ScenarioDoc) GetSequence(name string) *SequenceEntry {
for _, sequence := range s.Sequences {
if sequence.Name == name {
return sequence
}
}
return nil
}
// InterfaceEntry represents an interface in a scenario.
type InterfaceEntry struct {
Name string `json:"name" yaml:"name"`
Description string `json:"description" yaml:"description"`
Properties map[string]any `json:"properties" yaml:"properties"`
Operations []*ActionListEntry `json:"operations" yaml:"operations"`
}
func (e *InterfaceEntry) Validate() error {
if e.Properties == nil {
e.Properties = make(map[string]any)
}
if e.Operations == nil {
e.Operations = make([]*ActionListEntry, 0)
}
return nil
}
// GetOperation returns the operation entry with the given name.
func (e InterfaceEntry) GetOperation(name string) *ActionListEntry {
for _, o := range e.Operations {
if o.Name == name {
return o
}
}
return nil
}
// SequenceEntry represents a sequence in a scenario.
type SequenceEntry struct {
// Name is the name of the sequence.
Name string `json:"name" yaml:"name"`
// Description is the description of the sequence.
Description string `json:"description" yaml:"description"`
// Interface is the name of the default interface used.
Interface string `json:"interface" yaml:"interface"`
// Interval is the interval in milliseconds between runs.
Interval int `json:"interval" yaml:"interval"`
// Loops is the number of times the sequence should be run.
Loops int `json:"loops" yaml:"loops"`
// Forever is true if the sequence should be run forever.
Forever bool `json:"forever" yaml:"forever"`
// Steps is the list of steps in the sequence.
Steps []*ActionListEntry `json:"steps" yaml:"steps"`
}
func (e *SequenceEntry) Validate() error {
if e.Interface == "" {
return fmt.Errorf("sequence %s: interface is required", e.Name)
}
if e.Steps == nil {
e.Steps = make([]*ActionListEntry, 0)
}
return nil
}
// ActionListEntry represents a list of actions
type ActionListEntry struct {
// Name is the name of the action list.
Name string `json:"name" yaml:"name"`
// Description is the description of the action list.
Description string `json:"description" yaml:"description"`
// Actions is the list of actions in the action list.
Actions []ActionEntry `json:"actions" yaml:"actions"`
}
// ActionEntry represents an action in an operation or sequence.
type ActionEntry map[string]map[string]any