tigerbeetle-node 0.11.12 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +212 -196
- package/dist/bin/aarch64-linux-gnu/client.node +0 -0
- package/dist/bin/aarch64-linux-musl/client.node +0 -0
- package/dist/bin/aarch64-macos/client.node +0 -0
- package/dist/bin/x86_64-linux-gnu/client.node +0 -0
- package/dist/bin/x86_64-linux-musl/client.node +0 -0
- package/dist/bin/x86_64-macos/client.node +0 -0
- package/dist/index.js +33 -1
- package/dist/index.js.map +1 -1
- package/package-lock.json +66 -0
- package/package.json +8 -17
- package/src/index.ts +56 -1
- package/src/node.zig +10 -9
- package/dist/.client.node.sha256 +0 -1
- package/scripts/build_lib.sh +0 -61
- package/scripts/download_node_headers.sh +0 -32
- package/src/tigerbeetle/scripts/benchmark.bat +0 -48
- package/src/tigerbeetle/scripts/benchmark.sh +0 -66
- package/src/tigerbeetle/scripts/confirm_image.sh +0 -44
- package/src/tigerbeetle/scripts/fuzz_loop.sh +0 -15
- package/src/tigerbeetle/scripts/fuzz_unique_errors.sh +0 -7
- package/src/tigerbeetle/scripts/install.bat +0 -7
- package/src/tigerbeetle/scripts/install.sh +0 -21
- package/src/tigerbeetle/scripts/install_zig.bat +0 -113
- package/src/tigerbeetle/scripts/install_zig.sh +0 -90
- package/src/tigerbeetle/scripts/lint.zig +0 -199
- package/src/tigerbeetle/scripts/pre-commit.sh +0 -9
- package/src/tigerbeetle/scripts/scripts/benchmark.bat +0 -48
- package/src/tigerbeetle/scripts/scripts/benchmark.sh +0 -66
- package/src/tigerbeetle/scripts/scripts/confirm_image.sh +0 -44
- package/src/tigerbeetle/scripts/scripts/fuzz_loop.sh +0 -15
- package/src/tigerbeetle/scripts/scripts/fuzz_unique_errors.sh +0 -7
- package/src/tigerbeetle/scripts/scripts/install.bat +0 -7
- package/src/tigerbeetle/scripts/scripts/install.sh +0 -21
- package/src/tigerbeetle/scripts/scripts/install_zig.bat +0 -113
- package/src/tigerbeetle/scripts/scripts/install_zig.sh +0 -90
- package/src/tigerbeetle/scripts/scripts/lint.zig +0 -199
- package/src/tigerbeetle/scripts/scripts/pre-commit.sh +0 -9
- package/src/tigerbeetle/scripts/scripts/shellcheck.sh +0 -5
- package/src/tigerbeetle/scripts/scripts/tests_on_alpine.sh +0 -10
- package/src/tigerbeetle/scripts/scripts/tests_on_ubuntu.sh +0 -14
- package/src/tigerbeetle/scripts/scripts/upgrade_ubuntu_kernel.sh +0 -48
- package/src/tigerbeetle/scripts/scripts/validate_docs.sh +0 -23
- package/src/tigerbeetle/scripts/scripts/vr_state_enumerate +0 -46
- package/src/tigerbeetle/scripts/shellcheck.sh +0 -5
- package/src/tigerbeetle/scripts/tests_on_alpine.sh +0 -10
- package/src/tigerbeetle/scripts/tests_on_ubuntu.sh +0 -14
- package/src/tigerbeetle/scripts/upgrade_ubuntu_kernel.sh +0 -48
- package/src/tigerbeetle/scripts/validate_docs.sh +0 -23
- package/src/tigerbeetle/scripts/vr_state_enumerate +0 -46
- package/src/tigerbeetle/src/benchmark.zig +0 -314
- package/src/tigerbeetle/src/config.zig +0 -234
- package/src/tigerbeetle/src/constants.zig +0 -436
- package/src/tigerbeetle/src/ewah.zig +0 -286
- package/src/tigerbeetle/src/ewah_benchmark.zig +0 -120
- package/src/tigerbeetle/src/ewah_fuzz.zig +0 -130
- package/src/tigerbeetle/src/fifo.zig +0 -120
- package/src/tigerbeetle/src/io/benchmark.zig +0 -213
- package/src/tigerbeetle/src/io/darwin.zig +0 -814
- package/src/tigerbeetle/src/io/linux.zig +0 -1062
- package/src/tigerbeetle/src/io/test.zig +0 -643
- package/src/tigerbeetle/src/io/windows.zig +0 -1183
- package/src/tigerbeetle/src/io.zig +0 -34
- package/src/tigerbeetle/src/iops.zig +0 -107
- package/src/tigerbeetle/src/lsm/README.md +0 -308
- package/src/tigerbeetle/src/lsm/binary_search.zig +0 -341
- package/src/tigerbeetle/src/lsm/bloom_filter.zig +0 -125
- package/src/tigerbeetle/src/lsm/compaction.zig +0 -603
- package/src/tigerbeetle/src/lsm/composite_key.zig +0 -77
- package/src/tigerbeetle/src/lsm/direction.zig +0 -11
- package/src/tigerbeetle/src/lsm/eytzinger.zig +0 -587
- package/src/tigerbeetle/src/lsm/eytzinger_benchmark.zig +0 -330
- package/src/tigerbeetle/src/lsm/forest.zig +0 -204
- package/src/tigerbeetle/src/lsm/forest_fuzz.zig +0 -401
- package/src/tigerbeetle/src/lsm/grid.zig +0 -573
- package/src/tigerbeetle/src/lsm/groove.zig +0 -972
- package/src/tigerbeetle/src/lsm/k_way_merge.zig +0 -474
- package/src/tigerbeetle/src/lsm/level_iterator.zig +0 -332
- package/src/tigerbeetle/src/lsm/manifest.zig +0 -617
- package/src/tigerbeetle/src/lsm/manifest_level.zig +0 -877
- package/src/tigerbeetle/src/lsm/manifest_log.zig +0 -789
- package/src/tigerbeetle/src/lsm/manifest_log_fuzz.zig +0 -691
- package/src/tigerbeetle/src/lsm/merge_iterator.zig +0 -106
- package/src/tigerbeetle/src/lsm/node_pool.zig +0 -235
- package/src/tigerbeetle/src/lsm/posted_groove.zig +0 -378
- package/src/tigerbeetle/src/lsm/segmented_array.zig +0 -1328
- package/src/tigerbeetle/src/lsm/segmented_array_benchmark.zig +0 -148
- package/src/tigerbeetle/src/lsm/segmented_array_fuzz.zig +0 -9
- package/src/tigerbeetle/src/lsm/set_associative_cache.zig +0 -850
- package/src/tigerbeetle/src/lsm/table.zig +0 -1031
- package/src/tigerbeetle/src/lsm/table_immutable.zig +0 -203
- package/src/tigerbeetle/src/lsm/table_iterator.zig +0 -340
- package/src/tigerbeetle/src/lsm/table_mutable.zig +0 -220
- package/src/tigerbeetle/src/lsm/test.zig +0 -438
- package/src/tigerbeetle/src/lsm/tree.zig +0 -1193
- package/src/tigerbeetle/src/lsm/tree_fuzz.zig +0 -474
- package/src/tigerbeetle/src/message_bus.zig +0 -1012
- package/src/tigerbeetle/src/message_pool.zig +0 -156
- package/src/tigerbeetle/src/ring_buffer.zig +0 -399
- package/src/tigerbeetle/src/simulator.zig +0 -569
- package/src/tigerbeetle/src/state_machine/auditor.zig +0 -577
- package/src/tigerbeetle/src/state_machine/workload.zig +0 -883
- package/src/tigerbeetle/src/state_machine.zig +0 -1881
- package/src/tigerbeetle/src/static_allocator.zig +0 -65
- package/src/tigerbeetle/src/stdx.zig +0 -162
- package/src/tigerbeetle/src/storage.zig +0 -393
- package/src/tigerbeetle/src/testing/cluster/message_bus.zig +0 -82
- package/src/tigerbeetle/src/testing/cluster/network.zig +0 -237
- package/src/tigerbeetle/src/testing/cluster/state_checker.zig +0 -169
- package/src/tigerbeetle/src/testing/cluster/storage_checker.zig +0 -202
- package/src/tigerbeetle/src/testing/cluster.zig +0 -443
- package/src/tigerbeetle/src/testing/fuzz.zig +0 -140
- package/src/tigerbeetle/src/testing/hash_log.zig +0 -66
- package/src/tigerbeetle/src/testing/id.zig +0 -99
- package/src/tigerbeetle/src/testing/packet_simulator.zig +0 -364
- package/src/tigerbeetle/src/testing/priority_queue.zig +0 -645
- package/src/tigerbeetle/src/testing/reply_sequence.zig +0 -139
- package/src/tigerbeetle/src/testing/state_machine.zig +0 -249
- package/src/tigerbeetle/src/testing/storage.zig +0 -757
- package/src/tigerbeetle/src/testing/table.zig +0 -247
- package/src/tigerbeetle/src/testing/time.zig +0 -84
- package/src/tigerbeetle/src/tigerbeetle.zig +0 -227
- package/src/tigerbeetle/src/time.zig +0 -112
- package/src/tigerbeetle/src/tracer.zig +0 -529
- package/src/tigerbeetle/src/unit_tests.zig +0 -42
- package/src/tigerbeetle/src/vopr.zig +0 -495
- package/src/tigerbeetle/src/vsr/README.md +0 -209
- package/src/tigerbeetle/src/vsr/client.zig +0 -544
- package/src/tigerbeetle/src/vsr/clock.zig +0 -853
- package/src/tigerbeetle/src/vsr/journal.zig +0 -2413
- package/src/tigerbeetle/src/vsr/journal_format_fuzz.zig +0 -111
- package/src/tigerbeetle/src/vsr/marzullo.zig +0 -309
- package/src/tigerbeetle/src/vsr/replica.zig +0 -6381
- package/src/tigerbeetle/src/vsr/replica_format.zig +0 -219
- package/src/tigerbeetle/src/vsr/superblock.zig +0 -1631
- package/src/tigerbeetle/src/vsr/superblock_client_table.zig +0 -256
- package/src/tigerbeetle/src/vsr/superblock_free_set.zig +0 -929
- package/src/tigerbeetle/src/vsr/superblock_free_set_fuzz.zig +0 -334
- package/src/tigerbeetle/src/vsr/superblock_fuzz.zig +0 -390
- package/src/tigerbeetle/src/vsr/superblock_manifest.zig +0 -615
- package/src/tigerbeetle/src/vsr/superblock_quorums.zig +0 -394
- package/src/tigerbeetle/src/vsr/superblock_quorums_fuzz.zig +0 -314
- package/src/tigerbeetle/src/vsr.zig +0 -1352
|
@@ -1,495 +0,0 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
|
-
const fmt = std.fmt;
|
|
3
|
-
const mem = std.mem;
|
|
4
|
-
const net = std.net;
|
|
5
|
-
const os = std.os;
|
|
6
|
-
const assert = std.debug.assert;
|
|
7
|
-
const log = std.log;
|
|
8
|
-
|
|
9
|
-
const simulator = @import("simulator.zig");
|
|
10
|
-
const vsr = @import("vsr.zig");
|
|
11
|
-
const stdx = @import("stdx.zig");
|
|
12
|
-
|
|
13
|
-
// TODO use DNS instead since hard-coding an IP address isn't ideal.
|
|
14
|
-
const default_send_address = net.Address.initIp4([4]u8{ 65, 21, 207, 251 }, 5555);
|
|
15
|
-
|
|
16
|
-
const usage = fmt.comptimePrint(
|
|
17
|
-
\\Usage:
|
|
18
|
-
\\
|
|
19
|
-
\\ vopr [-h | --help]
|
|
20
|
-
\\
|
|
21
|
-
\\ vopr [--send] [--simulations=<count>]
|
|
22
|
-
\\
|
|
23
|
-
\\ vopr [--send] --seed=<int> [--build-mode=<mode>]
|
|
24
|
-
\\
|
|
25
|
-
\\Options:
|
|
26
|
-
\\
|
|
27
|
-
\\ -h, --help
|
|
28
|
-
\\ Print this help message and exit.
|
|
29
|
-
\\
|
|
30
|
-
\\ --seed=<integer>
|
|
31
|
-
\\ Set the seed to a provided 64-bit unsigned integer.
|
|
32
|
-
\\ By default the VOPR will run a specified seed in debug mode.
|
|
33
|
-
\\ If this option is omitted, a series of random seeds will be generated.
|
|
34
|
-
\\
|
|
35
|
-
\\ --send[=<address>]
|
|
36
|
-
\\ When set, the send option opts in to send any bugs found by the VOPR to the VOPR Hub.
|
|
37
|
-
\\ The VOPR Hub will then automatically create a GitHub issue if it can verify the bug.
|
|
38
|
-
\\ The VOPR Hub's address is already present as the default address.
|
|
39
|
-
\\ You can optionally supply an IPv4 address for the VOPR Hub if needed.
|
|
40
|
-
\\ If this option is omitted, any bugs that are found will replay locally in Debug mode.
|
|
41
|
-
\\
|
|
42
|
-
\\ --build-mode=<mode>
|
|
43
|
-
\\ Set the build mode for the VOPR. Accepts either ReleaseSafe or Debug.
|
|
44
|
-
\\ By default when no seed is provided the VOPR will run in ReleaseSafe mode.
|
|
45
|
-
\\ By default when a seed is provided the VOPR will run in Debug mode.
|
|
46
|
-
\\ Debug mode is only a valid build mode if a seed is also provided.
|
|
47
|
-
\\
|
|
48
|
-
\\ --simulations=<integer>
|
|
49
|
-
\\ Set the number of times for the simulator to run when using randomly generated seeds.
|
|
50
|
-
\\ By default 1000 random seeds will be generated.
|
|
51
|
-
\\ This flag can only be used with ReleaseSafe mode and when no seed has been specified.
|
|
52
|
-
\\
|
|
53
|
-
\\Example:
|
|
54
|
-
\\
|
|
55
|
-
\\ vopr --seed=123 --send=127.0.0.1:5555 --build-mode=ReleaseSafe
|
|
56
|
-
\\ vopr --simulations=10 --send --build-mode=Debug
|
|
57
|
-
\\
|
|
58
|
-
, .{});
|
|
59
|
-
|
|
60
|
-
// The Report struct contains all the information to be sent to the VOPR Hub.
|
|
61
|
-
const Report = struct {
|
|
62
|
-
checksum: [16]u8,
|
|
63
|
-
bug: u8,
|
|
64
|
-
seed: [8]u8,
|
|
65
|
-
commit: [20]u8,
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const Flags = struct {
|
|
69
|
-
seed: ?u64,
|
|
70
|
-
send_address: ?net.Address, // A null value indicates that the "send" flag is not set.
|
|
71
|
-
build_mode: std.builtin.Mode,
|
|
72
|
-
simulations: u32,
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const Bug = enum(u8) {
|
|
76
|
-
crash = 127, // Any assertion crash will be given an exit code of 127 by default.
|
|
77
|
-
liveness = 128,
|
|
78
|
-
correctness = 129,
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
pub fn main() void {
|
|
82
|
-
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
|
83
|
-
defer arena.deinit();
|
|
84
|
-
|
|
85
|
-
const allocator = arena.allocator();
|
|
86
|
-
|
|
87
|
-
const args = parse_args(allocator) catch |err| {
|
|
88
|
-
fatal("unable to parse the VOPR's arguments: {}", .{err});
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
if (args.send_address != null) {
|
|
92
|
-
check_git_status(allocator);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// If a seed is provided as an argument then replay the seed, otherwise test a 1,000 seeds:
|
|
96
|
-
if (args.seed) |seed| {
|
|
97
|
-
// Build in fast ReleaseSafe mode if required, useful where you don't need debug logging:
|
|
98
|
-
if (args.build_mode != .Debug) {
|
|
99
|
-
// Build the simulator binary
|
|
100
|
-
build_simulator(allocator, .ReleaseSafe);
|
|
101
|
-
log.debug("Replaying seed {} in ReleaseSafe mode...\n", .{seed});
|
|
102
|
-
_ = run_simulator(allocator, seed, .ReleaseSafe, args.send_address);
|
|
103
|
-
} else {
|
|
104
|
-
// Build the simulator binary
|
|
105
|
-
build_simulator(allocator, .Debug);
|
|
106
|
-
log.debug(
|
|
107
|
-
"Replaying seed {} in Debug mode with full debug logging enabled...\n",
|
|
108
|
-
.{seed},
|
|
109
|
-
);
|
|
110
|
-
_ = run_simulator(allocator, seed, .Debug, args.send_address);
|
|
111
|
-
}
|
|
112
|
-
} else if (args.build_mode == .Debug) {
|
|
113
|
-
fatal("no seed provided: the VOPR must be run with --mode=ReleaseSafe", .{});
|
|
114
|
-
} else {
|
|
115
|
-
// Build the simulator binary
|
|
116
|
-
build_simulator(allocator, .ReleaseSafe);
|
|
117
|
-
// Run the simulator with randomly generated seeds.
|
|
118
|
-
var i: u32 = 0;
|
|
119
|
-
while (i < args.simulations) : (i += 1) {
|
|
120
|
-
const seed_random = std.crypto.random.int(u64);
|
|
121
|
-
const exit_code = run_simulator(
|
|
122
|
-
allocator,
|
|
123
|
-
seed_random,
|
|
124
|
-
.ReleaseSafe,
|
|
125
|
-
args.send_address,
|
|
126
|
-
);
|
|
127
|
-
if (exit_code != null) {
|
|
128
|
-
// If a seed fails exit the loop.
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Builds the simulator binary.
|
|
136
|
-
fn build_simulator(
|
|
137
|
-
allocator: mem.Allocator,
|
|
138
|
-
mode: std.builtin.Mode,
|
|
139
|
-
) void {
|
|
140
|
-
const mode_str = switch (mode) {
|
|
141
|
-
.Debug => "-Ddebug",
|
|
142
|
-
.ReleaseSafe => "-Drelease-safe",
|
|
143
|
-
else => unreachable,
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
const exec_result = std.ChildProcess.exec(.{
|
|
147
|
-
.allocator = allocator,
|
|
148
|
-
.argv = &.{ "zig/zig", "build", "simulator", mode_str },
|
|
149
|
-
}) catch |err| {
|
|
150
|
-
fatal("unable to build the simulator binary. Error: {}", .{err});
|
|
151
|
-
};
|
|
152
|
-
defer allocator.free(exec_result.stdout);
|
|
153
|
-
defer allocator.free(exec_result.stderr);
|
|
154
|
-
|
|
155
|
-
switch (exec_result.term) {
|
|
156
|
-
.Exited => |code| {
|
|
157
|
-
if (code != 0) {
|
|
158
|
-
fatal("unable to build the simulator binary. Term: {}\n", .{exec_result.term});
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
else => {
|
|
162
|
-
fatal("unable to build the simulator binary. Term: {}\n", .{exec_result.term});
|
|
163
|
-
},
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Runs the simulator as a child process.
|
|
168
|
-
// Reruns the simulator in Debug mode if a seed fails in ReleaseSafe mode.
|
|
169
|
-
fn run_simulator(
|
|
170
|
-
allocator: mem.Allocator,
|
|
171
|
-
seed: u64,
|
|
172
|
-
mode: std.builtin.Mode,
|
|
173
|
-
send_address: ?net.Address,
|
|
174
|
-
) ?Bug {
|
|
175
|
-
var seed_str = std.ArrayList(u8).init(allocator);
|
|
176
|
-
defer seed_str.deinit();
|
|
177
|
-
|
|
178
|
-
fmt.formatInt(seed, 10, .lower, .{}, seed_str.writer()) catch |err| switch (err) {
|
|
179
|
-
error.OutOfMemory => fatal("unable to format seed as an int. Error: {}", .{err}),
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
// The child process executes zig run instead of zig build. Otherwise the build process is
|
|
183
|
-
// interposed between the VOPR and the simulator and its exit code is returned instead of the
|
|
184
|
-
// simulator's exit code.
|
|
185
|
-
const exit_code = run_child_process(
|
|
186
|
-
allocator,
|
|
187
|
-
&.{ "./zig-out/bin/simulator", seed_str.items },
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
const result = switch (exit_code) {
|
|
191
|
-
0 => null,
|
|
192
|
-
127 => Bug.crash,
|
|
193
|
-
128 => Bug.liveness,
|
|
194
|
-
129 => Bug.correctness,
|
|
195
|
-
else => {
|
|
196
|
-
log.debug("unexpected simulator exit code: {}\n", .{exit_code});
|
|
197
|
-
@panic("unexpected simulator exit code.");
|
|
198
|
-
},
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
if (result) |bug| {
|
|
202
|
-
if (send_address) |hub_address| {
|
|
203
|
-
var report: Report = create_report(allocator, bug, seed);
|
|
204
|
-
send_report(report, hub_address);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (mode == .ReleaseSafe) {
|
|
208
|
-
log.debug("simulator exited with exit code {}.\n", .{@enumToInt(bug)});
|
|
209
|
-
log.debug("rerunning seed {} in Debug mode.\n", .{seed});
|
|
210
|
-
// Build the simulator binary in Debug mode instead.
|
|
211
|
-
build_simulator(allocator, .Debug);
|
|
212
|
-
assert(bug == run_simulator(allocator, seed, .Debug, null).?);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return result;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Initializes and executes the simulator as a child process.
|
|
219
|
-
// Terminates the VOPR if the simulator fails to run or exits without an exit code.
|
|
220
|
-
fn run_child_process(allocator: mem.Allocator, argv: []const []const u8) u8 {
|
|
221
|
-
const child_process = std.ChildProcess.init(argv, allocator) catch |err| {
|
|
222
|
-
fatal("unable to initialize simulator as a child process. Error: {}", .{err});
|
|
223
|
-
};
|
|
224
|
-
defer child_process.deinit();
|
|
225
|
-
|
|
226
|
-
child_process.stdout = std.io.getStdOut();
|
|
227
|
-
child_process.stderr = std.io.getStdErr();
|
|
228
|
-
|
|
229
|
-
// Using spawn instead of exec because spawn allows output to be streamed instead of buffered.
|
|
230
|
-
const term = child_process.spawnAndWait() catch |err| {
|
|
231
|
-
fatal("unable to run the simulator as a child process. Error: {}", .{err});
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
switch (term) {
|
|
235
|
-
.Exited => |code| {
|
|
236
|
-
log.debug("exit with code: {}\n", .{code});
|
|
237
|
-
return code;
|
|
238
|
-
},
|
|
239
|
-
.Signal => |code| {
|
|
240
|
-
switch (code) {
|
|
241
|
-
6 => {
|
|
242
|
-
log.debug("exit with signal: {}. Indicates a crash bug.\n", .{code});
|
|
243
|
-
return @enumToInt(Bug.crash);
|
|
244
|
-
},
|
|
245
|
-
else => {
|
|
246
|
-
fatal("the simulator exited with an unexpected signal. Term: {}\n", .{term});
|
|
247
|
-
},
|
|
248
|
-
}
|
|
249
|
-
},
|
|
250
|
-
else => {
|
|
251
|
-
fatal("the simulator exited without an exit code. Term: {}\n", .{term});
|
|
252
|
-
},
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
fn check_git_status(allocator: mem.Allocator) void {
|
|
257
|
-
// Running git status to determine whether there is any uncommitted code or local changes.
|
|
258
|
-
var args = [2][]const u8{ "git", "status" };
|
|
259
|
-
var exec_result = std.ChildProcess.exec(.{
|
|
260
|
-
.allocator = allocator,
|
|
261
|
-
.argv = &args,
|
|
262
|
-
}) catch |err| {
|
|
263
|
-
fatal("unable to determine TigerBeetle's git status. Error: {}", .{err});
|
|
264
|
-
};
|
|
265
|
-
defer allocator.free(exec_result.stdout);
|
|
266
|
-
defer allocator.free(exec_result.stderr);
|
|
267
|
-
|
|
268
|
-
var git_status = exec_result.stdout;
|
|
269
|
-
var code_committed = mem.containsAtLeast(
|
|
270
|
-
u8,
|
|
271
|
-
git_status,
|
|
272
|
-
1,
|
|
273
|
-
"nothing to commit, working tree clean",
|
|
274
|
-
);
|
|
275
|
-
var code_up_to_date = (mem.containsAtLeast(
|
|
276
|
-
u8,
|
|
277
|
-
git_status,
|
|
278
|
-
1,
|
|
279
|
-
"Your branch is up to date",
|
|
280
|
-
) or
|
|
281
|
-
mem.containsAtLeast(
|
|
282
|
-
u8,
|
|
283
|
-
git_status,
|
|
284
|
-
1,
|
|
285
|
-
"HEAD detached at",
|
|
286
|
-
));
|
|
287
|
-
if (code_committed and code_up_to_date) {
|
|
288
|
-
log.debug("All code has been committed and pushed.\n", .{});
|
|
289
|
-
} else {
|
|
290
|
-
fatal(
|
|
291
|
-
"the VOPR cannot run with --send when your branch is ahead or there's uncommited code",
|
|
292
|
-
.{},
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Sends a bug report to the VOPR Hub.
|
|
298
|
-
// The VOPR Hub will attempt to verify the bug and automatically create a GitHub issue.
|
|
299
|
-
fn send_report(report: Report, address: net.Address) void {
|
|
300
|
-
// Bug type
|
|
301
|
-
assert(report.bug == 1 or report.bug == 2 or report.bug == 3);
|
|
302
|
-
|
|
303
|
-
const vopr_message_size = 45;
|
|
304
|
-
var message: [vopr_message_size]u8 = undefined;
|
|
305
|
-
message[0..16].* = report.checksum;
|
|
306
|
-
message[16] = report.bug;
|
|
307
|
-
message[17..25].* = report.seed;
|
|
308
|
-
message[25..vopr_message_size].* = report.commit;
|
|
309
|
-
|
|
310
|
-
const stream = net.tcpConnectToAddress(address) catch |err| {
|
|
311
|
-
fatal("unable to create a connection to the VOPR Hub. Error: {}", .{err});
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
log.debug("Connected to VOPR Hub.\n", .{});
|
|
315
|
-
|
|
316
|
-
var writer = stream.writer();
|
|
317
|
-
writer.writeAll(&message) catch |err| {
|
|
318
|
-
fatal("unable to send the report to the VOPR Hub. Error: {}", .{err});
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
// Receive reply
|
|
322
|
-
var reply: [1]u8 = undefined;
|
|
323
|
-
var reader = stream.reader();
|
|
324
|
-
var bytes_read = reader.readAll(&reply) catch |err| {
|
|
325
|
-
fatal("unable to read a reply from the VOPR Hub. Error: {}", .{err});
|
|
326
|
-
};
|
|
327
|
-
if (bytes_read > 0) {
|
|
328
|
-
log.debug("Confirmation received from VOPR Hub: {s}.\n", .{reply});
|
|
329
|
-
} else {
|
|
330
|
-
log.debug("No reply received from VOPR Hub.\n", .{});
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// Creating a single report struct that contains all information required for the VOPR Hub.
|
|
335
|
-
fn create_report(allocator: mem.Allocator, bug: Bug, seed: u64) Report {
|
|
336
|
-
log.debug("Collecting VOPR bug and seed, and the current git commit hash.\n", .{});
|
|
337
|
-
|
|
338
|
-
// Setting the bug type.
|
|
339
|
-
var bug_type: u8 = undefined;
|
|
340
|
-
switch (bug) {
|
|
341
|
-
.correctness => bug_type = 1,
|
|
342
|
-
.liveness => bug_type = 2,
|
|
343
|
-
.crash => bug_type = 3,
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// Running git log to extract the current TigerBeetle git commit hash from stdout.
|
|
347
|
-
var args = [3][]const u8{ "git", "log", "-1" };
|
|
348
|
-
var exec_result = std.ChildProcess.exec(.{
|
|
349
|
-
.allocator = allocator,
|
|
350
|
-
.argv = &args,
|
|
351
|
-
}) catch |err| {
|
|
352
|
-
fatal("unable to extract TigerBeetle's git commit hash. Error: {}", .{err});
|
|
353
|
-
};
|
|
354
|
-
defer allocator.free(exec_result.stdout);
|
|
355
|
-
defer allocator.free(exec_result.stderr);
|
|
356
|
-
|
|
357
|
-
var git_log = exec_result.stdout;
|
|
358
|
-
log.debug("git commit that was retrieved: {s}\n", .{git_log[7..47].*});
|
|
359
|
-
|
|
360
|
-
var commit_string = git_log[7..47].*;
|
|
361
|
-
var commit_byte_array: [20]u8 = undefined;
|
|
362
|
-
_ = fmt.hexToBytes(&commit_byte_array, &commit_string) catch |err| {
|
|
363
|
-
fatal("unable to cast the git commit hash to hex. Error: {}", .{err});
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
// Zig stores value as Little Endian when VOPR Hub is expecting Big Endian.
|
|
367
|
-
assert(@import("builtin").target.cpu.arch.endian() == .Little);
|
|
368
|
-
|
|
369
|
-
var message = Report{
|
|
370
|
-
.checksum = undefined,
|
|
371
|
-
.bug = bug_type,
|
|
372
|
-
.seed = @bitCast([8]u8, @byteSwap(u64, seed)),
|
|
373
|
-
.commit = commit_byte_array,
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
var hash: [32]u8 = undefined;
|
|
377
|
-
std.crypto.hash.sha2.Sha256.hash(std.mem.asBytes(&message)[@sizeOf(u128)..45], hash[0..], .{});
|
|
378
|
-
stdx.copy_disjoint(.exact, u8, message.checksum[0..], hash[0..message.checksum.len]);
|
|
379
|
-
|
|
380
|
-
return message;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/// Format and print an error message followed by the usage string to stderr,
|
|
384
|
-
/// then exit with an exit code of 1.
|
|
385
|
-
fn fatal(comptime fmt_string: []const u8, args: anytype) noreturn {
|
|
386
|
-
const stderr = std.io.getStdErr().writer();
|
|
387
|
-
stderr.print("error: " ++ fmt_string ++ "\n", args) catch {};
|
|
388
|
-
os.exit(1);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/// Parse e.g. `--seed=123` into 123 with error handling.
|
|
392
|
-
fn parse_flag(comptime flag: []const u8, arg: [:0]const u8) [:0]const u8 {
|
|
393
|
-
const value = arg[flag.len..];
|
|
394
|
-
if (value.len < 2) {
|
|
395
|
-
fatal("{s} argument requires a value", .{flag});
|
|
396
|
-
}
|
|
397
|
-
if (value[0] != '=') {
|
|
398
|
-
fatal("expected '=' after {s} but found '{c}'", .{ flag, value[0] });
|
|
399
|
-
}
|
|
400
|
-
return value[1..];
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// Parses the VOPR arguments to set flag values, otherwise uses default flag values.
|
|
404
|
-
fn parse_args(allocator: mem.Allocator) !Flags {
|
|
405
|
-
// Set default values
|
|
406
|
-
var seed: ?u64 = null;
|
|
407
|
-
var send_address: ?net.Address = null;
|
|
408
|
-
var build_mode: ?std.builtin.Mode = null;
|
|
409
|
-
var simulations: u32 = 1000;
|
|
410
|
-
|
|
411
|
-
var args = try std.process.argsWithAllocator(allocator);
|
|
412
|
-
defer args.deinit();
|
|
413
|
-
|
|
414
|
-
// Keep track of the args from the ArgIterator above that were allocated
|
|
415
|
-
// then free them all at the end of the scope.
|
|
416
|
-
var args_allocated = std.ArrayList([:0]const u8).init(allocator);
|
|
417
|
-
defer {
|
|
418
|
-
for (args_allocated.items) |arg| allocator.free(arg);
|
|
419
|
-
args_allocated.deinit();
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// Skip argv[0] which is the name of this executable
|
|
423
|
-
assert(args.skip());
|
|
424
|
-
|
|
425
|
-
while (args.next(allocator)) |arg_next| {
|
|
426
|
-
const arg = try arg_next;
|
|
427
|
-
try args_allocated.append(arg);
|
|
428
|
-
|
|
429
|
-
if (mem.startsWith(u8, arg, "--seed")) {
|
|
430
|
-
const seed_string = parse_flag("--seed", arg);
|
|
431
|
-
seed = simulator.parse_seed(seed_string);
|
|
432
|
-
// If a seed is supplied Debug becomes the default mode.
|
|
433
|
-
if (build_mode == null) {
|
|
434
|
-
build_mode = .Debug;
|
|
435
|
-
}
|
|
436
|
-
} else if (mem.startsWith(u8, arg, "--send")) {
|
|
437
|
-
if (mem.eql(u8, arg, "--send")) {
|
|
438
|
-
// If --send is set and no address is supplied then use default address.
|
|
439
|
-
send_address = default_send_address;
|
|
440
|
-
} else {
|
|
441
|
-
const str_address = parse_flag("--send", arg);
|
|
442
|
-
send_address = try vsr.parse_address(str_address);
|
|
443
|
-
}
|
|
444
|
-
} else if (mem.startsWith(u8, arg, "--build-mode")) {
|
|
445
|
-
if (mem.eql(u8, parse_flag("--build-mode", arg), "ReleaseSafe")) {
|
|
446
|
-
build_mode = .ReleaseSafe;
|
|
447
|
-
} else if (mem.eql(u8, parse_flag("--build-mode", arg), "Debug")) {
|
|
448
|
-
build_mode = .Debug;
|
|
449
|
-
} else {
|
|
450
|
-
fatal(
|
|
451
|
-
"unsupported build mode: {s}. Use either ReleaseSafe or Debug mode.",
|
|
452
|
-
.{arg},
|
|
453
|
-
);
|
|
454
|
-
}
|
|
455
|
-
} else if (mem.startsWith(u8, arg, "--simulations")) {
|
|
456
|
-
const num_simulations_string = parse_flag("--simulations", arg);
|
|
457
|
-
simulations = std.fmt.parseUnsigned(
|
|
458
|
-
u32,
|
|
459
|
-
num_simulations_string,
|
|
460
|
-
10,
|
|
461
|
-
) catch |err| switch (err) {
|
|
462
|
-
error.Overflow => @panic(
|
|
463
|
-
"the number of simulations exceeds a 16-bit unsigned integer",
|
|
464
|
-
),
|
|
465
|
-
error.InvalidCharacter => @panic(
|
|
466
|
-
"the number of simulations contains an invalid character",
|
|
467
|
-
),
|
|
468
|
-
};
|
|
469
|
-
} else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
|
|
470
|
-
std.io.getStdOut().writeAll(usage) catch os.exit(1);
|
|
471
|
-
os.exit(0);
|
|
472
|
-
} else if (mem.startsWith(u8, arg, "--")) {
|
|
473
|
-
fatal("unexpected argument: '{s}'", .{arg});
|
|
474
|
-
} else {
|
|
475
|
-
fatal("unexpected argument: '{s}' (must start with '--')", .{arg});
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// Build mode is set last to ensure that if a seed is passed to the VOPR the Debug default
|
|
480
|
-
// doesn't override a user specified mode.
|
|
481
|
-
if (build_mode == null) {
|
|
482
|
-
build_mode = .ReleaseSafe;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
if (seed == null and build_mode.? != .ReleaseSafe) {
|
|
486
|
-
fatal("random seeds must be run in ReleaseSafe mode", .{});
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
return Flags{
|
|
490
|
-
.seed = seed,
|
|
491
|
-
.send_address = send_address,
|
|
492
|
-
.build_mode = build_mode.?,
|
|
493
|
-
.simulations = simulations,
|
|
494
|
-
};
|
|
495
|
-
}
|