]> git.saurik.com Git - apple/xnu.git/blob - tests/xnu_quick_test.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tests / xnu_quick_test.c
1 #include <darwintest.h>
2 #include "xnu_quick_test_helpers.h"
3
4 #include <fcntl.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <mach/mach.h>
8 #include <sys/stat.h>
9 #include <sys/syscall.h>
10 #include <sys/sysctl.h>
11 #include <sys/wait.h>
12
13 T_GLOBAL_META(
14 T_META_NAMESPACE("xnu.quicktest"),
15 T_META_CHECK_LEAKS(false),
16 T_META_RUN_CONCURRENTLY(true)
17 );
18
19 char g_target_path[PATH_MAX];
20
21 T_DECL(syscall, "xnu_quick_test for syscall")
22 {
23 int my_fd = -1;
24 char * my_pathp;
25 kern_return_t my_kr;
26
27 T_SETUPBEGIN;
28
29 create_target_directory(TEST_DIRECTORY);
30
31 T_SETUPEND;
32
33 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp,
34 PATH_MAX, VM_FLAGS_ANYWHERE);
35 T_ASSERT_MACH_SUCCESS(my_kr, "Allocating vm to path %s", my_pathp);
36
37 *my_pathp = 0x00;
38 strcpy( my_pathp, &g_target_path[0] );
39 strcat( my_pathp, "/" );
40
41 /* create a test file */
42
43 T_ASSERT_MACH_SUCCESS( create_random_name( my_pathp, 1), "Create random test file" );
44 /* use an indirect system call to open our test file.
45 * I picked open since it uses a path pointer which grows to 64 bits in an LP64 environment.
46 */
47 T_EXPECT_NE(my_fd = syscall( SYS_open, my_pathp, (O_RDWR | O_EXCL), 0 ),
48 -1, "Attempt to open file using indirect syscall %s", my_pathp);
49
50 if (my_fd != -1) {
51 close(my_fd);
52 }
53
54 if (my_pathp != NULL) {
55 remove(my_pathp);
56 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
57 }
58
59 T_ATEND(remove_target_directory);
60 }
61
62 T_DECL(fork_wait4_exit,
63 "Tests forking off a process and waiting for the child to exit")
64 {
65 int my_err, my_status;
66 pid_t my_pid, my_wait_pid;
67 struct rusage my_usage;
68
69 strncpy(g_target_path, "/", 2);
70
71 /* spin off another process */
72 T_ASSERT_NE(my_pid = fork(), -1, "Fork off a process");
73
74 if (my_pid == 0) {
75 struct stat my_sb;
76
77 /* child process does very little then exits */
78 my_err = stat( &g_target_path[0], &my_sb );
79 T_WITH_ERRNO;
80 T_ASSERT_TRUE(my_err == 0, "stat call with path: \"%s\" returned \"%d\"", &g_target_path[0], errno);
81 exit( 44 );
82 }
83
84 /* parent process waits for child to exit */
85 T_ASSERT_NE(my_wait_pid = wait4( my_pid, &my_status, 0, &my_usage ), -1,
86 "Wait for child to exit\n");
87
88 /* wait4 should return our child's pid when it exits */
89 T_ASSERT_EQ(my_wait_pid, my_pid,
90 "wait4 should return our child's pid when it exits");
91
92 /* kind of just guessing on these values so if this fails we should take a closer
93 * look at the returned rusage structure.
94 */
95 T_ASSERT_FALSE((my_usage.ru_utime.tv_sec > 1 ||
96 my_usage.ru_stime.tv_sec > 1 || my_usage.ru_majflt > 1000 ||
97 my_usage.ru_msgsnd > 100), "wait4 returned rusage structure");
98
99 T_ASSERT_TRUE((WIFEXITED( my_status ) && WEXITSTATUS( my_status ) == 44),
100 "check if wait4 returns right exit status");
101 }
102
103 T_DECL(getrusage, "check getrusage works")
104 {
105 struct rusage rubuf;
106
107 int ret = getrusage(RUSAGE_SELF, &rubuf);
108 T_ASSERT_POSIX_SUCCESS(ret, "getrusage for self");
109
110 T_EXPECT_LT(rubuf.ru_msgrcv, 1000, "upper bound on messages received");
111 T_EXPECT_GE(rubuf.ru_msgrcv, 0, "lower bound on messages reseived");
112 T_EXPECT_LT(rubuf.ru_nsignals, 1000, "upper bound on signals");
113 T_EXPECT_GE(rubuf.ru_nsignals, 0, "lower bound on signals");
114 }