lib/bench/src/metadata.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

  1 const std = @import("std");
  2 const builtin = @import("builtin");
  3 const pretty_json = @import("pretty").json;
  4 const stabilizer = @import("stabilizer");
  5 
  6 pub const BuildMetadata = struct {
  7     git_sha: []const u8,
  8     git_dirty: bool,
  9     optimize: []const u8,
 10     target: []const u8,
 11     zig_version: []const u8,
 12     host_os: []const u8,
 13     host_arch: []const u8,
 14 };
 15 
 16 const FakeBuildOptions = struct {
 17     const git_sha = "abc123";
 18     const git_dirty = true;
 19     const optimize = "ReleaseFast";
 20     const target = "x86_64-linux-gnu";
 21     const host_os = "linux";
 22     const host_arch = "x86_64";
 23 };
 24 
 25 pub fn currentBuildMetadata(comptime build_options: type) BuildMetadata {
 26     return .{
 27         .git_sha = build_options.git_sha,
 28         .git_dirty = build_options.git_dirty,
 29         .optimize = build_options.optimize,
 30         .target = build_options.target,
 31         .zig_version = builtin.zig_version_string,
 32         .host_os = build_options.host_os,
 33         .host_arch = build_options.host_arch,
 34     };
 35 }
 36 
 37 pub fn compiledBuildMetadata() BuildMetadata {
 38     return .{
 39         .git_sha = "",
 40         .git_dirty = false,
 41         .optimize = @tagName(builtin.mode),
 42         .target = @tagName(builtin.cpu.arch) ++ "-" ++ @tagName(builtin.os.tag) ++ "-" ++ @tagName(builtin.abi),
 43         .zig_version = builtin.zig_version_string,
 44         .host_os = @tagName(builtin.os.tag),
 45         .host_arch = @tagName(builtin.cpu.arch),
 46     };
 47 }
 48 
 49 pub fn writeBuildMetadata(object: pretty_json.Object, metadata: BuildMetadata) !void {
 50     try object.field("git_sha", metadata.git_sha);
 51     try object.field("git_dirty", metadata.git_dirty);
 52     try object.field("optimize", metadata.optimize);
 53     try object.field("target", metadata.target);
 54     try object.field("zig_version", metadata.zig_version);
 55     try object.field("host_os", metadata.host_os);
 56     try object.field("host_arch", metadata.host_arch);
 57     try object.end();
 58 }
 59 
 60 pub fn writeStabilizerConfig(object: pretty_json.Object, layout_config: stabilizer.Config) !void {
 61     try object.field("seed", layout_config.seed);
 62     const heap = try object.object("heap");
 63     try heap.field("enabled", layout_config.heap.enabled);
 64     try heap.field("pointer_validation", layout_config.heap.pointer_validation);
 65     try heap.field("shuffle_slots", layout_config.heap.shuffle_slots);
 66     try heap.field("min_class_size", layout_config.heap.min_class_size);
 67     try heap.field("max_shuffled_size", layout_config.heap.max_shuffled_size);
 68     try heap.end();
 69     const stack = try object.object("stack");
 70     try stack.field("enabled", layout_config.stack.enabled);
 71     try stack.field("entries", layout_config.stack.entries);
 72     try stack.field("alignment", layout_config.stack.alignment);
 73     try stack.end();
 74     const code = try object.object("code");
 75     try code.field("enabled", layout_config.code.enabled);
 76     try code.field("shuffle_slots", layout_config.code.shuffle_slots);
 77     try code.field("alignment", layout_config.code.alignment);
 78     try code.field("interval_ms", layout_config.code.interval_ms);
 79     try code.end();
 80     try object.end();
 81 }
 82 
 83 test "stabilizer config metadata records heap stack and code fields" {
 84     const allocator = std.testing.allocator;
 85     var out = std.Io.Writer.Allocating.init(allocator);
 86     defer out.deinit();
 87 
 88     var stream = pretty_json.Writer.init(&out.writer, .minified);
 89     try writeStabilizerConfig(try stream.object(), .{
 90         .seed = 77,
 91         .heap = .{
 92             .pointer_validation = false,
 93             .shuffle_slots = 5,
 94             .max_shuffled_size = 4096,
 95         },
 96         .stack = .{
 97             .entries = 9,
 98         },
 99         .code = .{
100             .enabled = false,
101         },
102     });
103 
104     const json = out.written();
105     try std.testing.expect(std.mem.indexOf(u8, json, "\"seed\":77") != null);
106     try std.testing.expect(std.mem.indexOf(u8, json, "\"pointer_validation\":false") != null);
107     try std.testing.expect(std.mem.indexOf(u8, json, "\"shuffle_slots\":5") != null);
108     try std.testing.expect(std.mem.indexOf(u8, json, "\"max_shuffled_size\":4096") != null);
109     try std.testing.expect(std.mem.indexOf(u8, json, "\"stack\":{\"enabled\":true,\"entries\":9") != null);
110     try std.testing.expect(std.mem.indexOf(u8, json, "\"code\":{\"enabled\":false") != null);
111 }
112 
113 test "build metadata helper records profile build options" {
114     const value = currentBuildMetadata(FakeBuildOptions);
115     try std.testing.expectEqualStrings("abc123", value.git_sha);
116     try std.testing.expect(value.git_dirty);
117     try std.testing.expectEqualStrings("ReleaseFast", value.optimize);
118     try std.testing.expectEqualStrings("x86_64-linux-gnu", value.target);
119     try std.testing.expectEqualStrings(builtin.zig_version_string, value.zig_version);
120     try std.testing.expectEqualStrings("linux", value.host_os);
121     try std.testing.expectEqualStrings("x86_64", value.host_arch);
122 }
123 
124 test "build metadata writes benchmark environment" {
125     var out = std.Io.Writer.Allocating.init(std.testing.allocator);
126     defer out.deinit();
127 
128     var stream = pretty_json.Writer.init(&out.writer, .minified);
129     const root = try stream.object();
130     try writeBuildMetadata(try root.object("metadata"), .{
131         .git_sha = "abc123",
132         .git_dirty = true,
133         .optimize = "ReleaseFast",
134         .target = "x86_64-linux-gnu",
135         .zig_version = "0.16.0",
136         .host_os = "linux",
137         .host_arch = "x86_64",
138     });
139     try root.end();
140 
141     const json = out.written();
142     try std.testing.expect(std.mem.indexOf(u8, json, "\"metadata\":{") != null);
143     try std.testing.expect(std.mem.indexOf(u8, json, "\"git_sha\":\"abc123\"") != null);
144     try std.testing.expect(std.mem.indexOf(u8, json, "\"git_dirty\":true") != null);
145     try std.testing.expect(std.mem.indexOf(u8, json, "\"host_os\":\"linux\"") != null);
146 }