]>
Commit | Line | Data |
---|---|---|
1 | #include <stdlib.h> | |
2 | #include <unistd.h> | |
3 | #include <dirstat.h> | |
4 | #include <darwintest.h> | |
5 | #include <darwintest_utils.h> | |
6 | #include <sys/stat.h> | |
7 | ||
8 | #include <TargetConditionals.h> | |
9 | ||
10 | #if !TARGET_OS_SIMULATOR | |
11 | #define HAS_APFS | |
12 | #endif | |
13 | ||
14 | #ifdef HAS_APFS | |
15 | #include <apfs/apfs_fsctl.h> | |
16 | #endif | |
17 | ||
18 | T_DECL(dirstat, "Runs dirstat(3)") | |
19 | { | |
20 | bool fast_only = false; | |
21 | bool force_fallback = false; | |
22 | char *path = "/System/Library/Frameworks"; | |
23 | ||
24 | // <rdar://problem/26400444> Libdarwintest passes argv without progname and flags starting in argv[0] | |
25 | optind = 0; | |
26 | ||
27 | int ch; | |
28 | while ((ch = getopt(argc, argv, "fup:")) != -1){ | |
29 | switch (ch){ | |
30 | case 'f': | |
31 | fast_only = true; | |
32 | break; | |
33 | case 'u': | |
34 | force_fallback = true; | |
35 | break; | |
36 | case 'p': | |
37 | path = optarg; | |
38 | break; | |
39 | case '?': | |
40 | T_ASSERT_FAIL("Usage: [-f] [-p <path>]"); | |
41 | } | |
42 | } | |
43 | ||
44 | T_LOG("Path: %s", path); | |
45 | ||
46 | int flags = 0; | |
47 | if (fast_only) { | |
48 | T_LOG("Using DIRSTAT_FAST_ONLY"); | |
49 | flags |= DIRSTAT_FAST_ONLY; | |
50 | } | |
51 | if (force_fallback) { | |
52 | T_LOG("Using DIRSTAT_FORCE_FALLBACK"); | |
53 | flags |= DIRSTAT_FORCE_FALLBACK; | |
54 | } | |
55 | ||
56 | struct dirstat ds = {0}; | |
57 | ||
58 | T_ASSERT_POSIX_SUCCESS(dirstat_np(path, flags, &ds, sizeof(ds)), NULL); | |
59 | ||
60 | T_LOG("Size: %zd bytes", ds.total_size); | |
61 | T_LOG("Descendants: %llu objects", ds.descendants); | |
62 | } | |
63 | ||
64 | T_DECL(dirstat_fallback, "Tests dirstat(3) fallback") | |
65 | { | |
66 | char *path = "/System/Library/Frameworks"; | |
67 | ||
68 | struct dirstat ds = {0}; | |
69 | ||
70 | off_t native_size = 0; | |
71 | off_t fallback_size = 0; | |
72 | ||
73 | T_LOG("dirstat_np(\"%s\", 0, ...)", path); | |
74 | T_EXPECT_POSIX_SUCCESS(dirstat_np(path, 0, &ds, sizeof(ds)), NULL); | |
75 | T_LOG("Size: %zd bytes", ds.total_size); | |
76 | T_LOG("Descendants: %llu objects", ds.descendants); | |
77 | native_size = ds.total_size; | |
78 | ||
79 | T_LOG("dirstat_np(\"%s\", DIRSTAT_FORCE_FALLBACK, ...)", path); | |
80 | T_EXPECT_POSIX_SUCCESS(dirstat_np(path, DIRSTAT_FORCE_FALLBACK, &ds, sizeof(ds)), NULL); | |
81 | T_LOG("Size: %zd bytes", ds.total_size); | |
82 | T_LOG("Descendants: %llu objects", ds.descendants); | |
83 | fallback_size = ds.total_size; | |
84 | ||
85 | T_EXPECT_EQ(native_size, fallback_size, "Native and fallback sizes match"); | |
86 | } | |
87 | ||
88 | T_DECL(dirstat_flags, "Tests dirstat(3)'s behavior flags") | |
89 | { | |
90 | int err; | |
91 | struct dirstat ds = {0}; | |
92 | ||
93 | char *not_fast = "/System/Library/Frameworks"; | |
94 | ||
95 | T_LOG("dirstat_np(\"%s\", DIRSTAT_FAST_ONLY, ...)", not_fast); | |
96 | T_EXPECT_EQ(dirstat_np(not_fast, DIRSTAT_FAST_ONLY, &ds, sizeof(ds)), -1, "Fast-only fails on non-fast-enabled directory"); | |
97 | ||
98 | #ifdef HAS_APFS | |
99 | char *fast_tmpdir; | |
100 | uint64_t flags = 0; | |
101 | ||
102 | T_SETUPBEGIN; | |
103 | T_ASSERT_NE(asprintf(&fast_tmpdir, "%s/%s", dt_tmpdir(), "fast-XXXXXX"), -1, "Generate fast dir stats directory name"); | |
104 | T_ASSERT_EQ((void *)mkdtemp(fast_tmpdir), (void *)fast_tmpdir, "Make fast dir stats directory"); | |
105 | err = fsctl(fast_tmpdir, APFSIOC_MAINTAIN_DIR_STATS, &flags, 0); | |
106 | if (err != 0) { | |
107 | rmdir(fast_tmpdir); | |
108 | free(fast_tmpdir); | |
109 | T_SKIP("Couldn't enable fast dir stats for directory (not on APFS?)"); | |
110 | } | |
111 | T_SETUPEND; | |
112 | ||
113 | T_LOG("dirstat_np(\"%s\", DIRSTAT_FAST_ONLY, ...)", fast_tmpdir); | |
114 | T_EXPECTFAIL; | |
115 | T_EXPECT_POSIX_SUCCESS(dirstat_np(fast_tmpdir, DIRSTAT_FAST_ONLY, &ds, sizeof(ds)), "Fast-only works on fast-enabled directory"); | |
116 | ||
117 | T_ASSERT_POSIX_SUCCESS(rmdir(fast_tmpdir), NULL); | |
118 | free(fast_tmpdir); | |
119 | #endif | |
120 | } |