Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cfo: simplify process spawning #1934

Merged
merged 2 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ pub fn build(b: *std.Build) !void {
run_step.dependOn(&run_cmd.step);
}

{ // Fuzzers: zig build fuzz -- lsm_tree --seed=92 --events-max=100
{ // Fuzzers: zig build fuzz -- --events-max=100 lsm_tree 123
const fuzz_exe = b.addExecutable(.{
.name = "fuzz",
.root_source_file = .{ .path = "src/fuzz_tests.zig" },
Expand Down
6 changes: 3 additions & 3 deletions src/fuzz_tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ const Fuzzers = .{
const FuzzersEnum = std.meta.FieldEnum(@TypeOf(Fuzzers));

const CliArgs = struct {
seed: ?u64 = null,
events_max: ?usize = null,
positional: struct {
fuzzer: FuzzersEnum,
seed: ?u64 = null,
},
};

Expand All @@ -58,7 +58,7 @@ pub fn main() !void {

switch (cli_args.positional.fuzzer) {
.smoke => {
assert(cli_args.seed == null);
assert(cli_args.positional.seed == null);
assert(cli_args.events_max == null);
try main_smoke();
},
Expand Down Expand Up @@ -104,7 +104,7 @@ fn main_smoke() !void {
fn main_single(cli_args: CliArgs) !void {
assert(cli_args.positional.fuzzer != .smoke);

const seed: usize = cli_args.seed orelse seed: {
const seed: usize = cli_args.positional.seed orelse seed: {
// If no seed was given, use a random seed instead.
var seed_random: u64 = undefined;
try std.os.getrandom(std.mem.asBytes(&seed_random));
Expand Down
89 changes: 32 additions & 57 deletions src/scripts/cfo.zig
Original file line number Diff line number Diff line change
Expand Up @@ -78,61 +78,19 @@ const Fuzzer = enum {
vopr_lite,
vopr_testing_lite,

fn print_command(fuzzer: Fuzzer, shell: *Shell, seed: u64) ![]const u8 {
if (fuzzer == .vopr or fuzzer == .vopr_testing or
fuzzer == .vopr_lite or fuzzer == .vopr_testing_lite)
{
const state_machine: []const u8 = if (fuzzer == .vopr or fuzzer == .vopr_lite)
""
else
" -Dsimulator-state-machine=testing";
const lite: []const u8 = if (fuzzer == .vopr or fuzzer == .vopr_testing)
""
else
" --lite";
return try shell.fmt(
"./zig/zig build -Drelease{s} simulator_run --{s} {d}",
.{ state_machine, lite, seed },
);
}
return try shell.fmt(
"./zig/zig build -Drelease fuzz -- --seed={d} {s}",
.{ seed, @tagName(fuzzer) },
);
}

fn spawn_command(fuzzer: Fuzzer, shell: *Shell, seed: u64) !std.ChildProcess {
if (fuzzer == .vopr or fuzzer == .vopr_testing or
fuzzer == .vopr_lite or fuzzer == .vopr_testing_lite)
{
const state_machine: []const []const u8 = if (fuzzer == .vopr or fuzzer == .vopr_lite)
&.{}
else
&.{"-Dsimulator-state-machine=testing"};
const lite: []const []const u8 = if (fuzzer == .vopr or fuzzer == .vopr_testing)
&.{}
else
&.{"--lite"};
return try shell.spawn(
.{ .stdin_behavior = .Pipe },
"{zig} build -Drelease {state_machine} simulator_run -- {lite} {seed}",
.{
.zig = shell.zig_exe.?,
.state_machine = state_machine,
.lite = lite,
.seed = seed,
},
);
}
return try shell.spawn(
.{ .stdin_behavior = .Pipe },
"{zig} build -Drelease fuzz -- --seed={seed} {fuzzer}",
.{
.zig = shell.zig_exe.?,
.seed = seed,
.fuzzer = @tagName(fuzzer),
fn fill_args(fuzzer: Fuzzer, accumulator: *std.ArrayList([]const u8)) !void {
switch (fuzzer) {
.vopr, .vopr_testing, .vopr_lite, .vopr_testing_lite => |f| {
if (f == .vopr_testing or f == .vopr_testing_lite) {
try accumulator.append("-Dsimulator-state-machine=testing");
}
try accumulator.appendSlice(&.{ "simulator_run", "--" });
if (f == .vopr_lite or f == .vopr_testing_lite) {
try accumulator.append("--lite");
}
},
);
else => |f| try accumulator.appendSlice(&.{ "fuzz", "--", @tagName(f) }),
}
}
};

Expand Down Expand Up @@ -206,6 +164,7 @@ fn run_fuzzers(
}
};

var args = std.ArrayList([]const u8).init(shell.arena.allocator());
const total_budget_seconds = options.budget_seconds + options.hang_seconds;
for (0..total_budget_seconds) |second| {
const last_iteration = second == total_budget_seconds - 1;
Expand All @@ -225,14 +184,30 @@ fn run_fuzzers(

seed_record.seed = random.int(u64);
seed_record.seed_timestamp_start = @intCast(std.time.timestamp());
seed_record.command =
try seed_record.fuzzer.print_command(shell, seed_record.seed);

args.clearRetainingCapacity();
try args.appendSlice(&.{ "build", "-Drelease" });
try seed_record.fuzzer.fill_args(&args);
try args.append(try shell.fmt("{d}", .{seed_record.seed}));

var command = std.ArrayList(u8).init(shell.arena.allocator());
try command.appendSlice("./zig/zig");
for (args.items) |arg| {
try command.append(' ');
try command.appendSlice(arg);
}

seed_record.command = command.items;

log.debug("will start '{s}'", .{seed_record.command});
// Zig doesn't have non-blocking version of child.wait, so we use `BrokenPipe`
// on writing to child's stdin to detect if a child is dead in a non-blocking
// manner.
const child = try seed_record.fuzzer.spawn_command(shell, seed_record.seed);
const child = try shell.spawn(
.{ .stdin_behavior = .Pipe },
"{zig} {args}",
.{ .zig = shell.zig_exe.?, .args = args.items },
);
_ = try std.os.fcntl(
child.stdin.?.handle,
std.os.F.SETFL,
Expand Down
Loading