Skip to content

Commit abc3ac3

Browse files
committed
Support labels: section in runbooks
1 parent b812055 commit abc3ac3

12 files changed

+78
-38
lines changed

book.go

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const noDesc = "[No Description]"
2222
// book - Aggregated settings. runbook settings and run settings are aggregated.
2323
type book struct {
2424
desc string
25+
labels []string
2526
runners map[string]any
2627
vars map[string]any
2728
rawSteps []map[string]any
@@ -508,6 +509,7 @@ func (bk *book) generateOperatorRoot() (string, error) {
508509
func (bk *book) merge(loaded *book) error {
509510
bk.path = loaded.path
510511
bk.desc = loaded.desc
512+
bk.labels = loaded.labels
511513
bk.ifCond = loaded.ifCond
512514
bk.useMap = loaded.useMap
513515
for k, r := range loaded.runners {

capture/runbook.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,19 @@ type cRunbook struct {
2727
runbooks sync.Map
2828
loadDesc bool
2929
desc string
30+
labels []string
3031
runners map[string]any
3132
}
3233

34+
type runbookMeta struct {
35+
Desc string `yaml:"desc"`
36+
Labels []string `yaml:"labels,omitempty"`
37+
Runners yaml.MapSlice `yaml:"runners,omitempty"`
38+
}
39+
3340
type runbook struct {
3441
Desc string `yaml:"desc"`
42+
Labels []string `yaml:"labels,omitempty"`
3543
Runners yaml.MapSlice `yaml:"runners,omitempty"`
3644
Steps []yaml.MapSlice `yaml:"steps"`
3745

@@ -71,14 +79,15 @@ func (c *cRunbook) CaptureStart(trs runn.Trails, bookPath, desc string) {
7179
c.errs = multierr.Append(c.errs, err)
7280
return
7381
}
74-
rb := runbook{}
82+
rb := runbookMeta{}
7583
if err := yaml.Unmarshal(b, &rb); err != nil {
7684
c.errs = multierr.Append(c.errs, err)
7785
return
7886
}
7987
if c.loadDesc {
8088
c.desc = rb.Desc
8189
}
90+
c.labels = rb.Labels
8291
for _, r := range rb.Runners {
8392
k, ok := r.Key.(string)
8493
if !ok {
@@ -544,6 +553,7 @@ func (c *cRunbook) writeRunbook(trs runn.Trails, bookPath string) {
544553
} else {
545554
r.Desc = fmt.Sprintf("Captured of %s run", filepath.Base(bookPath))
546555
}
556+
r.Labels = c.labels
547557
b, err := yaml.Marshal(r)
548558
if err != nil {
549559
c.errs = multierr.Append(c.errs, fmt.Errorf("failed to yaml.Marshal: %w", err))

operator.go

+19-13
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"testing"
1919
"time"
2020

21+
"github.com/goccy/go-json"
2122
"github.com/k1LoW/concgroup"
2223
"github.com/k1LoW/stopw"
2324
"github.com/ryo-yamaoka/otchkiss"
@@ -39,6 +40,7 @@ type operator struct {
3940
steps []*step
4041
store store
4142
desc string
43+
labels []string
4244
useMap bool // Use map syntax in `steps:`.
4345
debug bool
4446
disableProfile bool
@@ -420,6 +422,7 @@ func New(opts ...Option) (*operator, error) {
420422
},
421423
useMap: bk.useMap,
422424
desc: bk.desc,
425+
labels: bk.labels,
423426
debug: bk.debug,
424427
disableProfile: bk.disableProfile,
425428
interval: bk.interval,
@@ -441,7 +444,7 @@ func New(opts ...Option) (*operator, error) {
441444
afterFuncs: bk.afterFuncs,
442445
sw: stopw.New(),
443446
capturers: bk.capturers,
444-
runResult: newRunResult(bk.desc, bk.path),
447+
runResult: newRunResult(bk.desc, bk.labels, bk.path),
445448
}
446449

447450
if o.debug {
@@ -776,7 +779,7 @@ func (o *operator) Result() *RunResult {
776779
}
777780

778781
func (o *operator) clearResult() {
779-
o.runResult = newRunResult(o.desc, o.bookPathOrID())
782+
o.runResult = newRunResult(o.desc, o.labels, o.bookPathOrID())
780783
o.runResult.ID = o.runbookID()
781784
for _, s := range o.steps {
782785
s.clearResult()
@@ -1511,20 +1514,23 @@ func setElasped(r *RunResult, result *stopw.Span) error {
15111514

15121515
// collectStepElaspedByRunbookIDFull collects the elapsed time of each step by runbook ID.
15131516
func collectStepElaspedByRunbookIDFull(r *stopw.Span, trs Trails, m map[string]time.Duration) map[string]time.Duration {
1514-
t, ok := r.ID.(Trail)
1517+
var t Trail
1518+
s, ok := r.ID.(string)
15151519
if ok {
1516-
trs = append(trs, t)
1517-
switch t.Type {
1518-
case TrailTypeRunbook:
1519-
id := trs.runbookID()
1520-
if !strings.Contains(id, "?step=") {
1521-
// Collect root runbook only
1520+
if err := json.Unmarshal([]byte(s), &t); err != nil {
1521+
trs = append(trs, t)
1522+
switch t.Type {
1523+
case TrailTypeRunbook:
1524+
id := trs.runbookID()
1525+
if !strings.Contains(id, "?step=") {
1526+
// Collect root runbook only
1527+
m[id] += r.Elapsed
1528+
}
1529+
case TrailTypeStep:
1530+
// Collect steps
1531+
id := trs.runbookID()
15221532
m[id] += r.Elapsed
15231533
}
1524-
case TrailTypeStep:
1525-
// Collect steps
1526-
id := trs.runbookID()
1527-
m[id] += r.Elapsed
15281534
}
15291535
}
15301536
for _, b := range r.Breakdown {

result.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type RunResult struct {
2222
// runbook ID
2323
ID string
2424
Desc string
25+
Labels []string
2526
Path string
2627
Skipped bool
2728
Err error
@@ -58,7 +59,8 @@ type runNResultSimplified struct {
5859
}
5960

6061
type runResultSimplified struct {
61-
ID string `json:"id,omitempty"`
62+
ID string `json:"id"`
63+
Labels []string `json:"labels,omitempty"`
6264
Path string `json:"path"`
6365
Result result `json:"result"`
6466
Steps []*stepResultSimplified `json:"steps"`
@@ -73,10 +75,11 @@ type stepResultSimplified struct {
7375
Elapsed time.Duration `json:"elapsed,omitempty"`
7476
}
7577

76-
func newRunResult(desc, path string) *RunResult {
78+
func newRunResult(desc string, labels []string, path string) *RunResult {
7779
return &RunResult{
78-
Desc: desc,
79-
Path: path,
80+
Desc: desc,
81+
Labels: labels,
82+
Path: path,
8083
}
8184
}
8285

runbook.go

+5
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type areas struct {
3939

4040
type runbook struct {
4141
Desc string `yaml:"desc"`
42+
Labels []string `yaml:"labels,omitempty"`
4243
Runners map[string]any `yaml:"runners,omitempty"`
4344
Vars map[string]any `yaml:"vars,omitempty"`
4445
Steps []yaml.MapSlice `yaml:"steps"`
@@ -57,6 +58,7 @@ type runbook struct {
5758

5859
type runbookMapped struct {
5960
Desc string `yaml:"desc,omitempty"`
61+
Labels []string `yaml:"labels,omitempty"`
6062
Runners map[string]any `yaml:"runners,omitempty"`
6163
Vars map[string]any `yaml:"vars,omitempty"`
6264
Steps yaml.MapSlice `yaml:"steps,omitempty"`
@@ -117,6 +119,7 @@ func parseRunbookMapped(b []byte, rb *runbook) error {
117119
}
118120
rb.useMap = true
119121
rb.Desc = m.Desc
122+
rb.Labels = m.Labels
120123
rb.Runners = m.Runners
121124
rb.Vars = m.Vars
122125
rb.Debug = m.Debug
@@ -179,6 +182,7 @@ func (rb *runbook) MarshalYAML() (any, error) {
179182
}
180183
m := &runbookMapped{}
181184
m.Desc = rb.Desc
185+
m.Labels = rb.Labels
182186
m.Runners = rb.Runners
183187
m.Vars = rb.Vars
184188
m.Debug = rb.Debug
@@ -355,6 +359,7 @@ func (rb *runbook) toBook() (*book, error) {
355359
)
356360
bk := newBook()
357361
bk.desc = rb.Desc
362+
bk.labels = rb.Labels
358363
bk.runners, ok = normalize(rb.Runners).(map[string]any)
359364
if !ok {
360365
return nil, fmt.Errorf("failed to normalize runners: %v", rb.Runners)

testdata/book/http.yml

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
desc: Test using HTTP
2+
labels:
3+
- http
4+
- openapi3
25
runners:
36
req:
47
endpoint: ${TEST_HTTP_END_POINT:-https:example.com}

testdata/grpc.yml.runbook.golden

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
-- -testdata-book-grpc.yml --
22
desc: Captured of grpc.yml run
33
runners:
4-
greq: '[THIS IS gRPC RUNNER]'
4+
greq:
5+
addr: grpc://grpc.example.com:443
6+
protos:
7+
- ../grpctest.proto
58
steps:
69
- greq:
710
grpctest.GrpcTestService/Hello:

testdata/http.yml.runbook.golden

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
-- -testdata-book-http.yml --
22
desc: Captured of http.yml run
3+
labels:
4+
- http
5+
- openapi3
36
runners:
4-
req: '[THIS IS HTTP RUNNER]'
7+
req:
8+
endpoint: ${TEST_HTTP_END_POINT:-https:example.com}
9+
openapi3: ../openapi3.yml
510
steps:
611
- req:
712
/users:

testdata/http_multipart.yml.runbook.golden

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
-- -testdata-book-http_multipart.yml --
22
desc: Captured of http_multipart.yml run
33
runners:
4-
req: '[THIS IS HTTP RUNNER]'
4+
req:
5+
endpoint: ${TEST_HTTP_END_POINT:-https:example.com}
6+
openapi3: ../openapi3.yml
57
steps:
68
- req:
79
/upload:

testdata/pick_step.http.yml.0.golden

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
7 getusers:
2-
8 req:
3-
9 /users:
4-
10 get:
5-
11 body: null
6-
12 test: |
7-
13 'bob' in map(current.res.body, {#.username})
1+
10 getusers:
2+
11 req:
3+
12 /users:
4+
13 get:
5+
14 body: null
6+
15 test: |
7+
16 'bob' in map(current.res.body, {#.username})

testdata/pick_step.http.yml.8.golden

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
91 fileupload:
2-
92 desc: Post /upload with single file
3-
93 req:
4-
94 /upload:
5-
95 post:
6-
96 body:
7-
97 multipart/form-data:
8-
98 upload0: ../dummy.png
9-
99 test: |
10-
100 current.res.status == 201
1+
94 fileupload:
2+
95 desc: Post /upload with single file
3+
96 req:
4+
97 /upload:
5+
98 post:
6+
99 body:
7+
100 multipart/form-data:
8+
101 upload0: ../dummy.png
9+
102 test: |
10+
103 current.res.status == 201

trail.go

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const (
3131
)
3232

3333
// Trail - The trail of elements in the runbook at runtime.
34+
// Trail does not use slices to copy values.
3435
type Trail struct {
3536
Type TrailType `json:"type"`
3637
Desc string `json:"desc,omitempty"`

0 commit comments

Comments
 (0)