From 55a4296bd1fe1c873e4de2d099ab561e5fca592e Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 23 Jan 2026 15:25:16 +0100 Subject: pkg/aflow: add DoWhile loop action DoWhile represents "do { body } while (cond)" loop. See added test for an example. --- pkg/aflow/loop_test.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 pkg/aflow/loop_test.go (limited to 'pkg/aflow/loop_test.go') diff --git a/pkg/aflow/loop_test.go b/pkg/aflow/loop_test.go new file mode 100644 index 000000000..e68191c2b --- /dev/null +++ b/pkg/aflow/loop_test.go @@ -0,0 +1,96 @@ +// 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", + }, + nil, + ) +} + +func TestDoWhileErrors(t *testing.T) { + testRegistrationError[struct{}, struct{}](t, + "flow test: action body: no input Missing, available inputs: []", + Pipeline( + &DoWhile{ + Do: NewFuncAction("body", func(ctx *Context, args struct { + Missing string + }) (struct{}, error) { + return struct{}{}, nil + }), + While: "Condition", + }, + )) + + testRegistrationError[struct{ Input string }, struct{}](t, + "flow test: action DoWhile: While must not be empty", + Pipeline( + &DoWhile{ + Do: NewFuncAction("body", func(ctx *Context, args struct { + Input string + }) (struct{}, error) { + return struct{}{}, nil + }), + }, + )) + + type output struct { + Output1 string + Output2 string + } + testRegistrationError[struct{}, struct{}](t, + "flow test: action body: output Output2 is unused", + Pipeline( + &DoWhile{ + Do: NewFuncAction("body", func(ctx *Context, args struct{}) (output, error) { + return output{}, nil + }), + While: "Output1", + }, + )) +} -- cgit mrf-deployment