authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-26 16:22:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-26 16:22:47-07:00
log67d5bfefba48d28c02e2841f1a47a213d28d4693
tree6b1fa9ebcdc207782cbe85997fc7070fb6ca22b0
parentba426f0a54d1c80ae9a4c73e06c5dc1265f0568b

std.testing: remove tight coupling with executing zig as child process

This tight coupling causes problems for various targets, requires hacky "get args" functionality, and bungles relative file system paths, making invalid assumptions about the zig-cache directory. In short, these are not unit tests; these should be standalone tests instead. Reverts e5d4a694ea7dd251e10d6434c9321b5e0a548d4b Reverts d976456ef665bf0aba3a83a8e7fccb4a92b2d3b2 Reverts dbbda0f41a7c5e214801925f8447a15193c3c731 Closes #11542

2 files changed, 0 insertions(+), 139 deletions(-)

lib/std/child_process.zig-88
...@@ -1323,91 +1323,3 @@ test "createNullDelimitedEnvMap" {...@@ -1323,91 +1323,3 @@ test "createNullDelimitedEnvMap" {
1323 }1323 }
1324 }1324 }
1325}1325}
1326
1327const childstr =
1328 \\ const std = @import("std");
1329 \\ const builtin = @import("builtin");
1330 \\ pub fn main() !void {
1331 \\ var it = try std.process.argsWithAllocator(std.testing.allocator);
1332 \\ defer it.deinit(); // no-op unless WASI or Windows
1333 \\ _ = it.next() orelse unreachable; // skip binary name
1334 \\ const input = it.next() orelse unreachable;
1335 \\ var expect_helloworld = "hello world".*;
1336 \\ try std.testing.expect(std.mem.eql(u8, &expect_helloworld, input));
1337 \\ try std.testing.expect(it.next() == null);
1338 \\ try std.testing.expect(!it.skip());
1339 \\ }
1340;
1341
1342test "build and call child_process" {
1343 if (builtin.os.tag == .wasi) return error.SkipZigTest;
1344 const testing = std.testing;
1345 const allocator = testing.allocator;
1346
1347 var it = try std.process.argsWithAllocator(allocator);
1348 defer it.deinit(); // no-op unless WASI or Windows
1349 const testargs = try testing.getTestArgs(&it);
1350
1351 var tmp = testing.tmpDir(.{ .no_follow = true }); // ie zig-cache/tmp/8DLgoSEqz593PAEE
1352 defer tmp.cleanup();
1353 const tmpdirpath = try tmp.getFullPath(allocator);
1354 defer allocator.free(tmpdirpath);
1355 const child_name = "child"; // no need for suffixes (.exe, .wasm) due to '-femit-bin'
1356 const suffix_zig = ".zig";
1357 const child_path = try fs.path.join(allocator, &[_][]const u8{ tmpdirpath, child_name });
1358 defer allocator.free(child_path);
1359 const child_zig = try mem.concat(allocator, u8, &[_][]const u8{ child_path, suffix_zig });
1360 defer allocator.free(child_zig);
1361
1362 try tmp.dir.writeFile("child.zig", childstr);
1363 try testing.buildExe(testargs.zigexec, child_zig, child_path);
1364
1365 // spawn compiled file as child_process with argument 'hello world' + expect success
1366 const args = [_][]const u8{ child_path, "hello world" };
1367 var child_proc = ChildProcess.init(&args, allocator);
1368 const ret_val = try child_proc.spawnAndWait();
1369 try testing.expectEqual(ret_val, .{ .Exited = 0 });
1370}
1371
1372test "creating a child process with stdin and stdout behavior set to StdIo.Pipe" {
1373 if (builtin.os.tag == .wasi) return error.SkipZigTest;
1374 const testing = std.testing;
1375 const allocator = testing.allocator;
1376
1377 var child_process = std.ChildProcess.init(
1378 &[_][]const u8{ testing.zig_exe_path, "fmt", "--stdin" },
1379 allocator,
1380 );
1381 child_process.stdin_behavior = .Pipe;
1382 child_process.stdout_behavior = .Pipe;
1383
1384 try child_process.spawn();
1385
1386 const input_program =
1387 \\ const std = @import("std");
1388 \\ pub fn main() void {
1389 \\ std.debug.print("Hello World", .{});
1390 \\ }
1391 ;
1392
1393 try child_process.stdin.?.writer().writeAll(input_program);
1394 child_process.stdin.?.close();
1395 child_process.stdin = null;
1396
1397 const out_bytes = try child_process.stdout.?.reader().readAllAlloc(allocator, std.math.maxInt(usize));
1398 defer allocator.free(out_bytes);
1399
1400 switch (try child_process.wait()) {
1401 .Exited => |code| if (code == 0) {
1402 const expected_program =
1403 \\const std = @import("std");
1404 \\pub fn main() void {
1405 \\ std.debug.print("Hello World", .{});
1406 \\}
1407 \\
1408 ;
1409 try testing.expectEqualStrings(expected_program, out_bytes);
1410 },
1411 else => unreachable,
1412 }
1413}
lib/std/testing.zig-51
...@@ -355,19 +355,6 @@ pub const TmpDir = struct {...@@ -355,19 +355,6 @@ pub const TmpDir = struct {
355 const random_bytes_count = 12;355 const random_bytes_count = 12;
356 const sub_path_len = std.fs.base64_encoder.calcSize(random_bytes_count);356 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
371 pub fn cleanup(self: *TmpDir) void {358 pub fn cleanup(self: *TmpDir) void {
372 self.dir.close();359 self.dir.close();
373 self.parent_dir.deleteTree(&self.sub_path) catch {};360 self.parent_dir.deleteTree(&self.sub_path) catch {};
...@@ -413,44 +400,6 @@ pub fn tmpDir(opts: std.fs.Dir.OpenDirOptions) TmpDir {...@@ -413,44 +400,6 @@ pub fn tmpDir(opts: std.fs.Dir.OpenDirOptions) TmpDir {
413 };400 };
414}401}
415402
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
446 const args = [_][]const u8{ zigexec, "build-exe", zigfile, cmd_emit };
447 var procCompileChild = std.ChildProcess.init(&args, allocator);
448 try procCompileChild.spawn();
449
450 const ret_val = try procCompileChild.wait();
451 try expectEqual(ret_val, .{ .Exited = 0 });
452}
453
454test "expectEqual nested array" {403test "expectEqual nested array" {
455 const a = [2][2]f32{404 const a = [2][2]f32{
456 [_]f32{ 1.0, 0.0 },405 [_]f32{ 1.0, 0.0 },