1 #include <test.h>
2
3 #include <compiler.h>
4 #include <process_lib.h>
5 #include <process_unix_priv.h>
6
7 /*
8 * procfs.h is not 64-bit off_t clean, but the only affected structure is
9 * priovec, which we don't use. Hence we may work around #error in sys/procfs.h
10 * by lying that we are not compiling with large file support (while we do).
11 */
12 #define _FILE_OFFSET_BITS 32
13
14 #include <procfs.h>
15
open(const char * filename,int flags,...)16 int open(const char *filename, int flags, ...)
17 {
18 if (!strcmp(filename, "/proc/1/psinfo"))
19 {
20 return 1;
21 }
22
23 if (!strcmp(filename, "/proc/1/status"))
24 {
25 return 101;
26 }
27
28 if (!strcmp(filename, "/proc/2/status"))
29 {
30 return 102;
31 }
32
33 if (!strcmp(filename, "/proc/3/status"))
34 {
35 return 103;
36 }
37
38 errno = ENOENT;
39 return -1;
40 }
41
42 int fdpos[4];
43
read(int fd,void * buf,size_t bufsize)44 ssize_t read(int fd, void *buf, size_t bufsize)
45 {
46 if (fd == 1)
47 {
48 if (fdpos[0] == 0)
49 {
50 psinfo_t psinfo;
51 psinfo.pr_start.tv_sec = 100;
52 memcpy(buf, &psinfo, sizeof(psinfo));
53 fdpos[0] = sizeof(psinfo);
54 return sizeof(psinfo);
55 }
56 else
57 {
58 return 0;
59 }
60 }
61
62 if (fd == 101)
63 {
64 if (fdpos[1] == 0)
65 {
66 pstatus_t pstatus;
67 pstatus.pr_nlwp = 1;
68 pstatus.pr_lwp.pr_flags = PR_STOPPED;
69 pstatus.pr_lwp.pr_why = PR_SIGNALLED;
70 memcpy(buf, &pstatus, sizeof(pstatus));
71 fdpos[1] = sizeof(pstatus);
72 return sizeof(pstatus);
73 }
74 else
75 {
76 return 0;
77 }
78 }
79
80 if (fd == 102)
81 {
82 if (fdpos[2] == 0)
83 {
84 pstatus_t pstatus;
85 pstatus.pr_nlwp = 1;
86 pstatus.pr_lwp.pr_flags = 0;
87 pstatus.pr_lwp.pr_why = 0;
88 memcpy(buf, &pstatus, sizeof(pstatus));
89 fdpos[2] = sizeof(pstatus);
90 return sizeof(pstatus);
91 }
92 else
93 {
94 return 0;
95 }
96 }
97
98 if (fd == 103)
99 {
100 if (fdpos[3] == 0)
101 {
102 /* Currently this is unused, the test is switched off. */
103
104 pstatus_t pstatus;
105 pstatus.pr_nlwp = 0; /* zombie */
106 memcpy(buf, &pstatus, sizeof(pstatus));
107 fdpos[3] = sizeof(pstatus);
108 return sizeof(pstatus);
109 }
110 else
111 {
112 return 0;
113 }
114 }
115
116 errno = EIO;
117 return -1;
118 }
119
close(int fd)120 int close(int fd)
121 {
122 return 0;
123 }
124
test_get_start_time_process1(void)125 static void test_get_start_time_process1(void)
126 {
127 time_t t = GetProcessStartTime(1);
128 assert_int_equal(t, 100);
129 }
130
test_get_start_time_process2(void)131 static void test_get_start_time_process2(void)
132 {
133 time_t t = GetProcessStartTime(2);
134 assert_int_equal(t, PROCESS_START_TIME_UNKNOWN);
135 }
136
test_get_state_process1(void)137 static void test_get_state_process1(void)
138 {
139 ProcessState s = GetProcessState(1);
140 assert_int_equal(s, PROCESS_STATE_STOPPED);
141 }
142
test_get_state_process2(void)143 static void test_get_state_process2(void)
144 {
145 ProcessState s = GetProcessState(2);
146 assert_int_equal(s, PROCESS_STATE_RUNNING);
147 }
148
test_get_state_process3(void)149 static void test_get_state_process3(void)
150 {
151 ProcessState s = GetProcessState(3);
152 assert_int_equal(s, PROCESS_STATE_ZOMBIE);
153 }
154
test_get_state_process4(void)155 static void test_get_state_process4(void)
156 {
157 ProcessState s = GetProcessState(4);
158 assert_int_equal(s, PROCESS_STATE_DOES_NOT_EXIST);
159 }
160
main()161 int main()
162 {
163 PRINT_TEST_BANNER();
164
165 const UnitTest tests[] =
166 {
167 unit_test(test_get_start_time_process1),
168 unit_test(test_get_start_time_process2),
169 unit_test(test_get_state_process1),
170 unit_test(test_get_state_process2),
171 /* TODO zombie process unit test for solaris is not currently working
172 * because of the huge amount of hacks needed to actually figure out
173 * if a process is zombie, see libpromises/process_solaris.c. */
174 // unit_test(test_get_state_process3),
175 };
176
177 return run_tests(tests);
178 }
179