authorgravatar for matu3ba@users.noreply.github.commatu3ba <matu3ba@users.noreply.github.com> 2022-03-27 10:43:40+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-27 11:43:40+03:00
logdbbda0f41a7c5e214801925f8447a15193c3c731
tree41fb278c8b58afe3b74d1723af12a99be54e88b2
parentf9a2c0fc6c51be929640fbff39809bd1371eedc2
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

std.testing: add methods tmpDirPath, getTestArgs, buildExe

continuation of #11093 to simplify testing IPC * use cases - get path to temporary directory - get the test arguments inside test block for reusage - build executables from text within test blocks, ie to test IPC * missing conventions - how to name and debug test cases - where do simple+repititve build commands for testing belong

2 files changed, 70 insertions(+), 36 deletions(-)

lib/std/child_process.zig+20-36
......@@ -1348,46 +1348,30 @@ const childstr =
13481348test "build and call child_process" {
13491349 if (builtin.os.tag == .wasi) return error.SkipZigTest;
13501350 const testing = std.testing;
1351 var it = try std.process.argsWithAllocator(std.testing.allocator);
1351 const allocator = testing.allocator;
1352
1353 var it = try std.process.argsWithAllocator(allocator);
13521354 defer it.deinit(); // no-op unless WASI or Windows
1355 const testargs = try testing.getTestArgs(&it);
13531356
1354 _ = it.next() orelse unreachable;
1355 const zigexec = it.next() orelse unreachable;
1356 try testing.expect(it.next() == null);
1357 try testing.expect(!it.skip());
1358 const cwd_str = try process.getCwdAlloc(testing.allocator);
1359 defer testing.allocator.free(cwd_str);
13601357 var tmp = testing.tmpDir(.{ .no_follow = true }); // ie zig-cache/tmp/8DLgoSEqz593PAEE
13611358 defer tmp.cleanup();
1362 const cache = "zig-cache";
1363 const tmpdir = "tmp";
1359 const tmpdirpath = try tmp.getFullPath(allocator);
1360 defer allocator.free(tmpdirpath);
13641361 const child_name = "child"; // no need for suffixes (.exe, .wasm) due to '-femit-bin'
13651362 const suffix_zig = ".zig";
1366 const child_path = try fs.path.join(testing.allocator, &[_][]const u8{ cwd_str, std.fs.path.sep_str, cache, tmpdir, &tmp.sub_path, child_name });
1367 defer testing.allocator.free(child_path);
1368
1369 const child_zig = try mem.concat(testing.allocator, u8, &[_][]const u8{ child_path, suffix_zig });
1370 defer testing.allocator.free(child_zig);
1371 const emit_flag = "-femit-bin=";
1372 const emit_bin = try mem.concat(testing.allocator, u8, &[_][]const u8{ emit_flag, child_path });
1373 defer testing.allocator.free(emit_bin);
1374 {
1375 // 'zigexec build-exe path/to/child.zig -femit-bin=path/to/child' expect success
1376 try tmp.dir.writeFile("child.zig", childstr);
1377 const args = [_][]const u8{ zigexec, "build-exe", child_zig, emit_bin };
1378 var procCompileChild = try ChildProcess.init(&args, testing.allocator);
1379 defer procCompileChild.deinit();
1380 try procCompileChild.spawn();
1381 const ret_val = try procCompileChild.wait();
1382 try testing.expectEqual(ret_val, .{ .Exited = 0 });
1383 }
1384 {
1385 // spawn compiled file as child_process with argument 'hello world' + expect success
1386 const args = [_][]const u8{ child_path, "hello world" };
1387 var child_proc = try ChildProcess.init(&args, testing.allocator);
1388 defer child_proc.deinit();
1389 try child_proc.spawn();
1390 const ret_val = try child_proc.wait();
1391 try testing.expectEqual(ret_val, .{ .Exited = 0 });
1392 }
1363 const child_path = try fs.path.join(allocator, &[_][]const u8{ tmpdirpath, child_name });
1364 defer allocator.free(child_path);
1365 const child_zig = try mem.concat(allocator, u8, &[_][]const u8{ child_path, suffix_zig });
1366 defer allocator.free(child_zig);
1367
1368 try tmp.dir.writeFile("child.zig", childstr);
1369 try testing.buildExe(testargs.zigexec, child_zig, child_path);
1370
1371 // spawn compiled file as child_process with argument 'hello world' + expect success
1372 const args = [_][]const u8{ child_path, "hello world" };
1373 var child_proc = try ChildProcess.init(&args, allocator);
1374 defer child_proc.deinit();
1375 const ret_val = try child_proc.spawnAndWait();
1376 try testing.expectEqual(ret_val, .{ .Exited = 0 });
13931377}
lib/std/testing.zig+50
......@@ -355,6 +355,19 @@ pub const TmpDir = struct {
355355 const random_bytes_count = 12;
356356 const sub_path_len = std.fs.base64_encoder.calcSize(random_bytes_count);
357357
358 /// caller owns memory
359 pub fn getFullPath(self: *TmpDir, alloc: std.mem.Allocator) ![]u8 {
360 const cwd_str = try std.process.getCwdAlloc(alloc);
361 defer alloc.free(cwd_str);
362 const path = try std.fs.path.join(alloc, &[_][]const u8{
363 cwd_str,
364 "zig-cache",
365 "tmp",
366 &self.sub_path,
367 });
368 return path;
369 }
370
358371 pub fn cleanup(self: *TmpDir) void {
359372 self.dir.close();
360373 self.parent_dir.deleteTree(&self.sub_path) catch {};
......@@ -400,6 +413,43 @@ pub fn tmpDir(opts: std.fs.Dir.OpenDirOptions) TmpDir {
400413 };
401414}
402415
416const TestArgs = struct {
417 testexec: [:0]const u8 = undefined,
418 zigexec: [:0]const u8 = undefined,
419};
420
421/// Get test arguments inside test block by regular test runner ('zig test file.zig')
422/// Caller must provide backing ArgIterator
423pub fn getTestArgs(it: *std.process.ArgIterator) !TestArgs {
424 var testargs = TestArgs{};
425 testargs.testexec = it.next() orelse unreachable;
426 testargs.zigexec = it.next() orelse unreachable;
427 try expect(!it.skip());
428 return testargs;
429}
430
431test "getTestArgs" {
432 var it = try std.process.argsWithAllocator(allocator);
433 const testargs = try getTestArgs(&it);
434 defer it.deinit(); // no-op unless WASI or Windows
435 try expect(testargs.testexec.len > 0); // zig compiler executable path
436 try expect(testargs.zigexec.len > 0); // test runner executable path
437}
438
439/// Spawns child process with 'zigexec build-exe zigfile -femit-bin=binfile'
440/// and expects success
441pub fn buildExe(zigexec: []const u8, zigfile: []const u8, binfile: []const u8) !void {
442 const flag_emit = "-femit-bin=";
443 const cmd_emit = try std.mem.concat(allocator, u8, &[_][]const u8{ flag_emit, binfile });
444 defer allocator.free(cmd_emit);
445 const args = [_][]const u8{ zigexec, "build-exe", zigfile, cmd_emit };
446 var procCompileChild = try std.ChildProcess.init(&args, allocator);
447 defer procCompileChild.deinit();
448 try procCompileChild.spawn();
449 const ret_val = try procCompileChild.wait();
450 try expectEqual(ret_val, .{ .Exited = 0 });
451}
452
403453test "expectEqual nested array" {
404454 const a = [2][2]f32{
405455 [_]f32{ 1.0, 0.0 },