Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | // // nanov2_tests.c // libmalloc // // Tests that are specific to the implementation details of Nanov2. // #include <TargetConditionals.h> #include <darwintest.h> #include <darwintest_utils.h> #include <spawn.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <malloc/malloc.h> #include <../src/internal.h> #if CONFIG_NANOZONE && !TARGET_OS_BRIDGE static void run_replay_tool(char *replay_file, const char *out_dir, char *test_name, char **envp) { int rc; char *replay_tool = "/usr/local/bin/libmalloc_replay"; char replay_arg[256]; rc = snprintf(replay_arg, 256, "%s", replay_file); char output_arg[256]; rc |= snprintf(output_arg, 256, "%s/libmalloc.replay.%s", out_dir, test_name); char *args[] = {replay_tool, "-r", replay_arg, "-j", output_arg, "-t", test_name, "-s", NULL}; T_QUIET; T_ASSERT_POSIX_SUCCESS(rc, "Failed to generate libmalloc_replay command"); pid_t pid; rc = posix_spawn(&pid, replay_tool, NULL, NULL, args, envp); T_QUIET; T_ASSERT_POSIX_SUCCESS(rc, "posix_spawn failed: %d", rc); int exit_status = 0; rc = waitpid(pid, &exit_status, 0); if (rc == -1 || !WIFEXITED(exit_status) || WEXITSTATUS(exit_status)) { T_ASSERT_FAIL("Replay tool exited abnormally: %d", WEXITSTATUS(exit_status)); } } static void run_nano_replay(char *replay_file_path, char *test_name, char *version) { T_QUIET; T_ASSERT_POSIX_SUCCESS(access(replay_file_path, F_OK), "Test cannot access replay file: %s", replay_file_path); const char *tmp_dir = dt_tmpdir(); T_QUIET; T_ASSERT_NOTNULL(tmp_dir, "Couldn't fetch dt_tmpdir"); char full_test_name[256]; char env_var[32]; int rc = snprintf(full_test_name, sizeof(full_test_name), "%s_%s", test_name, version); T_QUIET; T_ASSERT_POSIX_SUCCESS(rc, "Failed to generate full test name"); rc = snprintf(env_var, sizeof(env_var), "MallocNanoZone=%s", version); T_QUIET; T_ASSERT_POSIX_SUCCESS(rc, "Failed to generate env vars"); char *envp[] = {env_var, NULL}; run_replay_tool(replay_file_path, tmp_dir, full_test_name, envp); } #ifndef TEST_TIMEOUT #define TEST_TIMEOUT 1200 #endif #define NANO_FRAG_TEST_VERSION(trace_name, nano_version, timeout) \ T_DECL(nano_frag_## trace_name ## _ ## nano_version, "track Nano"#nano_version" fragmentation in "#trace_name, \ T_META_TAG_PERF, T_META_NAMESPACE("libmalloc"), \ T_META_GIT_ASSET_URL("ssh://git@stash.sd.apple.com/coreos/libmalloc.git"), \ T_META_TIMEOUT(timeout), \ T_META_GIT_ASSET("../traces/"#trace_name".mtrace")) \ { \ const char *dt_assets = getenv("DT_ASSETS"); \ T_QUIET; T_ASSERT_NOTNULL(dt_assets, "$DT_ASSETS not set"); \ char *replay_file = NULL; \ asprintf(&replay_file, "%s/%s", dt_assets, "../traces/"#trace_name".mtrace"); \ run_nano_replay(replay_file, #trace_name, #nano_version); \ T_PASS("Successfully ran libmalloc_replay under Nano"#nano_version); \ free(replay_file); \ } #elif CONFIG_NANOZONE && TARGET_OS_BRIDGE #define NANO_FRAG_TEST_VERSION(trace_name, nano_version, timeout) \ T_DECL(nano_frag_## trace_name ## _ ## nano_version, "track Nano"#nano_version" fragmentation in "#trace_name, \ T_META_NAMESPACE("libmalloc")) \ { \ T_SKIP("skipping trace replay on BridgeOS"); \ } #else // !CONFIG_NANOZONE && !TARGET_OS_BRIDGE #define NANO_FRAG_TEST_VERSION(trace_name, nano_version, timeout) \ T_DECL(nano_frag_## trace_name ## _ ## nano_version, "track Nano"#nano_version" fragmentation in "#trace_name, \ T_META_NAMESPACE("libmalloc")) \ { \ T_SKIP("nanozone configured off; trace replay skipped"); \ } #endif // !CONFIG_NANOZONE && !TARGET_OS_BRIDGE #define NANO_FRAG_TEST(trace_name) \ NANO_FRAG_TEST_VERSION(trace_name, V1, TEST_TIMEOUT) \ NANO_FRAG_TEST_VERSION(trace_name, V2, TEST_TIMEOUT) NANO_FRAG_TEST(TRACE_NAME) |