]> git.saurik.com Git - apple/libc.git/blob - tests/dirstat.c
Libc-1439.100.3.tar.gz
[apple/libc.git] / tests / dirstat.c
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 }