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
|
// Copyright 2026 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package aflow
import (
"testing"
)
func TestDoWhile(t *testing.T) {
type inputs struct {
Bug string
}
type outputs struct {
Diff string
}
type patchArgs struct {
Bug string
Diff string
TestError string
}
type patchResults struct {
Patch string
}
type testArgs struct {
Patch string
}
type testResults struct {
Diff string
TestError string
}
iter := 0
testFlow[inputs, outputs](t, map[string]any{"Bug": "bug"}, map[string]any{"Diff": "diff"},
&DoWhile{
Do: Pipeline(
NewFuncAction("patch-generator", func(ctx *Context, args patchArgs) (patchResults, error) {
iter++
if iter <= 2 {
return patchResults{"bad"}, nil
}
return patchResults{"good"}, nil
}),
NewFuncAction("patch-tester", func(ctx *Context, args testArgs) (testResults, error) {
if args.Patch == "bad" {
return testResults{TestError: "error"}, nil
}
return testResults{Diff: "diff"}, nil
}),
),
While: "TestError",
MaxIterations: 10,
},
nil,
nil,
)
}
func TestDoWhileErrors(t *testing.T) {
testRegistrationError[struct{}, struct{}](t,
"flow test: action body: no input Missing, available inputs: []",
&Flow{Root: &DoWhile{
Do: NewFuncAction("body", func(ctx *Context, args struct {
Missing string
}) (struct{}, error) {
return struct{}{}, nil
}),
While: "Condition",
MaxIterations: 10,
}})
testRegistrationError[struct{ Input string }, struct{}](t,
"flow test: action DoWhile: While must not be empty",
&Flow{Root: &DoWhile{
Do: NewFuncAction("body", func(ctx *Context, args struct {
Input string
}) (struct{}, error) {
return struct{}{}, nil
}),
MaxIterations: 10,
}})
type output struct {
Output1 string
Output2 string
}
testRegistrationError[struct{}, struct{}](t,
"flow test: action body: output Output2 is unused",
&Flow{Root: &DoWhile{
Do: NewFuncAction("body", func(ctx *Context, args struct{}) (output, error) {
return output{}, nil
}),
While: "Output1",
MaxIterations: 10,
}})
testRegistrationError[struct{}, struct{}](t,
"flow test: action DoWhile: bad MaxIterations value 0, should be within [1, 1000]",
&Flow{Root: &DoWhile{
Do: NewFuncAction("body", func(ctx *Context, args struct{}) (output, error) {
return output{}, nil
}),
While: "Output1",
}})
}
func TestDoWhileMaxIters(t *testing.T) {
type actionResults struct {
Error string
}
testFlow[struct{}, struct{}](t, nil, "DoWhile loop is going in cycles for 3 iterations",
&DoWhile{
Do: NewFuncAction("nop", func(ctx *Context, args struct{}) (actionResults, error) {
return actionResults{"failed"}, nil
}),
While: "Error",
MaxIterations: 3,
},
nil,
nil,
)
}
|