feat(cmd): add --generator llm|seeded flag

This commit is contained in:
pj committed 2026-07-13 07:07:06 +05:30
1 parent c7402e8f7d
commit 5b7a71358c
3 files changed
+11

No files matched your search

+7
View File
@@ -30,6 +30,7 @@ type testOptions struct {
seed int64 seed int64
output string output string
clearData bool clearData bool
generator string
} }
const topUsage = `sanderling is a property-based UI fuzzer for mobile apps. const topUsage = `sanderling is a property-based UI fuzzer for mobile apps.
@@ -62,6 +63,7 @@ func parseTestArgs(args []string, stderr io.Writer) (testOptions, error) {
flagSet.Int64Var(&options.seed, "seed", 0, "RNG seed (0 = random)") flagSet.Int64Var(&options.seed, "seed", 0, "RNG seed (0 = random)")
flagSet.StringVar(&options.output, "output", "./runs", "output directory for traces") flagSet.StringVar(&options.output, "output", "./runs", "output directory for traces")
flagSet.BoolVar(&options.clearData, "clear-data", true, "clear app data before launching so each run starts from a fresh install; pass --clear-data=false to resume prior state") flagSet.BoolVar(&options.clearData, "clear-data", true, "clear app data before launching so each run starts from a fresh install; pass --clear-data=false to resume prior state")
flagSet.StringVar(&options.generator, "generator", "seeded", "action generator: seeded (weighted random) or llm (model picks from the same candidate set; requires generator = llm() in the spec)")
if err := flagSet.Parse(args); err != nil { if err := flagSet.Parse(args); err != nil {
return testOptions{}, err return testOptions{}, err
} }
@@ -76,6 +78,11 @@ func parseTestArgs(args []string, stderr io.Writer) (testOptions, error) {
default: default:
return testOptions{}, fmt.Errorf("unsupported platform: %q (android, ios, web)", options.platform) return testOptions{}, fmt.Errorf("unsupported platform: %q (android, ios, web)", options.platform)
} }
switch options.generator {
case "seeded", "llm":
default:
return testOptions{}, fmt.Errorf("unsupported generator: %q (seeded, llm)", options.generator)
}
return options, nil return options, nil
} }
+1
View File
@@ -21,5 +21,6 @@ func runTestPipeline(ctx context.Context, options testOptions, stdout io.Writer)
Seed: options.seed, Seed: options.seed,
Output: options.output, Output: options.output,
ClearData: options.clearData, ClearData: options.clearData,
Generator: options.generator,
}, stdout) }, stdout)
} }
+3
View File
@@ -34,6 +34,8 @@ type Options struct {
Seed int64 Seed int64
Output string Output string
ClearData bool ClearData bool
// Generator selects the action picker: "llm" or the default seeded picker.
Generator string
// iosUDID, iosIsSimulator, and iosCoreDeviceID are filled by Execute after // iosUDID, iosIsSimulator, and iosCoreDeviceID are filled by Execute after
// resolving the iOS target, then read by buildDriver to choose the simulator // resolving the iOS target, then read by buildDriver to choose the simulator
@@ -166,6 +168,7 @@ func Execute(ctx context.Context, options Options, stdout io.Writer) error {
Verifier: verifierInstance, Verifier: verifierInstance,
TraceWriter: traceWriter, TraceWriter: traceWriter,
Logger: newProgressLogger(stdout), Logger: newProgressLogger(stdout),
Generator: options.Generator,
}) })
terminateCtx, terminateCancel := context.WithTimeout(context.Background(), 5*time.Second) terminateCtx, terminateCancel := context.WithTimeout(context.Background(), 5*time.Second)