]>
Commit | Line | Data |
---|---|---|
7b463f34 MT |
1 | /*############################################################################# |
2 | # # | |
3 | # Pakfire - The IPFire package management system # | |
4 | # Copyright (C) 2017 Pakfire development team # | |
5 | # # | |
6 | # This program is free software: you can redistribute it and/or modify # | |
7 | # it under the terms of the GNU General Public License as published by # | |
8 | # the Free Software Foundation, either version 3 of the License, or # | |
9 | # (at your option) any later version. # | |
10 | # # | |
11 | # This program is distributed in the hope that it will be useful, # | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
14 | # GNU General Public License for more details. # | |
15 | # # | |
16 | # You should have received a copy of the GNU General Public License # | |
17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
18 | # # | |
19 | #############################################################################*/ | |
20 | ||
51bc8c08 | 21 | #include <errno.h> |
6dbda957 MT |
22 | #include <linux/limits.h> |
23 | #include <stdlib.h> | |
24 | ||
7b463f34 MT |
25 | #include "testsuite.h" |
26 | ||
c348901e | 27 | #include <pakfire/logging.h> |
97ddb354 | 28 | #include <pakfire/mount.h> |
c348901e | 29 | #include <pakfire/pakfire.h> |
95946a55 | 30 | #include <pakfire/util.h> |
c348901e | 31 | |
79a0a5cd MT |
32 | #define TMP_TEMPLATE "/tmp/pakfire-test.XXXXXX" |
33 | ||
35bb0e8f | 34 | struct testsuite ts; |
1413be07 | 35 | |
68d81d63 | 36 | static int test_run(int i, struct test* t) { |
e126402c | 37 | struct pakfire_ctx* ctx = NULL; |
0cb40254 | 38 | struct pakfire* p = NULL; |
509aaad2 | 39 | FILE* c = NULL; |
0cb40254 | 40 | |
788da09a | 41 | char root[PATH_MAX] = TEST_ROOTFS "/pakfire-test-XXXXXX"; |
6dbda957 MT |
42 | int r; |
43 | ||
44 | // Create test root directory | |
95946a55 MT |
45 | char* tmp = pakfire_mkdtemp(root); |
46 | if (!tmp) { | |
47 | LOG("Could not create temporary directory %s: %m\n", root); | |
48 | exit(1); | |
49 | } | |
6dbda957 MT |
50 | |
51 | LOG("running %s (%s)\n", t->name, root); | |
52 | ||
f2a8f4f2 | 53 | // Create a new context |
e5941810 | 54 | r = pakfire_ctx_create(&t->ctx, TEST_CONFIG_FILE); |
f2a8f4f2 MT |
55 | if (r) { |
56 | LOG("Could not create context: %m\n"); | |
57 | goto ERROR; | |
58 | } | |
59 | ||
273ce4d5 | 60 | // Set the log level to DEBUG |
ab11cb4c | 61 | pakfire_ctx_set_log_level(t->ctx, LOG_DEBUG); |
273ce4d5 | 62 | |
6641e780 | 63 | // Log everything to the console |
ab11cb4c | 64 | pakfire_ctx_set_log_callback(t->ctx, pakfire_log_stderr, NULL); |
6641e780 | 65 | |
509aaad2 MT |
66 | // Open the configuration file |
67 | c = fopen(TEST_SRC_PATH "/pakfire.conf", "r"); | |
68 | if (!c) { | |
69 | LOG("Could not open configuration file: %m\n"); | |
70 | r = 1; | |
71 | goto ERROR; | |
72 | } | |
73 | ||
f96ed3ac MT |
74 | // Create a pakfire instance (if requested) |
75 | if (t->flags & TEST_WANTS_PAKFIRE) { | |
76 | r = pakfire_create(&t->pakfire, t->ctx, root, NULL, c, 0); | |
77 | if (r) { | |
78 | LOG("ERROR: Could not initialize pakfire: %m\n"); | |
79 | goto ERROR; | |
80 | } | |
81 | ||
82 | // Check if the instance was created properly | |
83 | if (r == 0 && !t->pakfire) { | |
84 | LOG("ERROR: Pakfire was not initialized, but no error was raised: %m\n"); | |
85 | goto ERROR; | |
86 | } | |
87 | ||
88 | // Copy command into environment | |
89 | r = pakfire_bind(t->pakfire, TEST_STUB_COMMAND, "/command", 0); | |
90 | if (r) { | |
91 | LOG("ERROR: Could not copy command: %m\n"); | |
92 | goto ERROR; | |
93 | } | |
6dbda957 | 94 | } |
7b463f34 | 95 | |
a2ab26e0 MT |
96 | // Create a HTTP client (if requested) |
97 | if (t->flags & TEST_WANTS_HTTPCLIENT) { | |
98 | r = pakfire_httpclient_create(&t->httpclient, t->ctx); | |
99 | if (r) { | |
100 | LOG("ERROR: Could not initialize the HTTP client: %s\n", strerror(-r)); | |
101 | goto ERROR; | |
102 | } | |
103 | } | |
104 | ||
0cb40254 | 105 | // Run test |
6dbda957 | 106 | r = t->func(t); |
8e43fe98 MT |
107 | if (r) |
108 | LOG("Test failed with error code: %d\n", r); | |
7b463f34 | 109 | |
0cb40254 | 110 | ERROR: |
a2ab26e0 MT |
111 | // Release HTTP client |
112 | if (t->httpclient) | |
113 | pakfire_httpclient_unref(t->httpclient); | |
114 | ||
f907e1a2 | 115 | // Release pakfire |
84e59679 MT |
116 | if (t->pakfire) { |
117 | p = pakfire_unref(t->pakfire); | |
0f9411f7 | 118 | |
84e59679 MT |
119 | // Check if Pakfire was actually released |
120 | if (p) { | |
121 | LOG("Error: Pakfire instance was not released in test %d\n", i); | |
117b70ab | 122 | r = 1; |
84e59679 | 123 | } |
f907e1a2 | 124 | |
84e59679 MT |
125 | // Reset pointer (just in case) |
126 | t->pakfire = NULL; | |
127 | } | |
0cb40254 | 128 | |
e126402c MT |
129 | // Release context |
130 | if (t->ctx) { | |
131 | ctx = pakfire_ctx_unref(t->ctx); | |
132 | ||
133 | // Check if the context was actually released | |
134 | if (ctx) { | |
135 | LOG("Error: Context was not released in test %s\n", t->name); | |
136 | r = 1; | |
137 | } | |
138 | ||
139 | // Reset pointer (just in case) | |
140 | t->ctx = NULL; | |
141 | } | |
f2a8f4f2 | 142 | |
509aaad2 MT |
143 | // Close the configuration file |
144 | if (c) | |
145 | fclose(c); | |
146 | ||
6dbda957 | 147 | // Cleanup root |
788da09a | 148 | pakfire_rmtree(root, 0); |
6dbda957 | 149 | |
7b463f34 MT |
150 | return r; |
151 | } | |
152 | ||
c296431f | 153 | int __testsuite_add_test(const char* name, int (*func)(const struct test* t), int flags) { |
1413be07 MT |
154 | // Check if any space is left |
155 | if (ts.num >= MAX_TESTS) { | |
156 | LOG("ERROR: We are out of space for tests\n"); | |
7b463f34 | 157 | exit(EXIT_FAILURE); |
7b463f34 MT |
158 | } |
159 | ||
1413be07 MT |
160 | struct test* test = &ts.tests[ts.num++]; |
161 | ||
162 | // Set parameters | |
163 | test->name = name; | |
164 | test->func = func; | |
c296431f | 165 | test->flags = flags; |
7b463f34 MT |
166 | |
167 | return 0; | |
168 | } | |
169 | ||
b0ead88b MT |
170 | static int check_whether_to_run(const struct test* t, const int argc, const char* argv[]) { |
171 | // Run all tests when nothing has been selected | |
172 | if (argc < 2) | |
2e764d33 | 173 | return 1; |
b0ead88b MT |
174 | |
175 | // Check if this test has been listed | |
176 | for (unsigned int i = 1; i < argc; i++) { | |
177 | if (strcmp(t->name, argv[i]) == 0) | |
178 | return 1; | |
179 | } | |
180 | ||
181 | return 0; | |
182 | } | |
183 | ||
184 | int testsuite_run(int argc, const char* argv[]) { | |
1413be07 | 185 | for (unsigned int i = 0; i < ts.num; i++) { |
b0ead88b MT |
186 | struct test* test = &ts.tests[i]; |
187 | ||
188 | // Skip any tests that should not be run | |
189 | if (!check_whether_to_run(test, argc, argv)) | |
190 | continue; | |
191 | ||
192 | // Run the test | |
193 | int r = test_run(i, test); | |
7b463f34 MT |
194 | if (r) |
195 | exit(r); | |
196 | } | |
197 | ||
198 | return EXIT_SUCCESS; | |
199 | } | |
436677a3 | 200 | |
79a0a5cd MT |
201 | FILE* test_mktemp(char** path) { |
202 | char* p = NULL; | |
203 | ||
204 | // Reset path | |
205 | if (path) | |
206 | *path = NULL; | |
207 | ||
208 | int r = asprintf(&p, "%s", TMP_TEMPLATE); | |
209 | if (r < 0) | |
210 | return NULL; | |
436677a3 | 211 | |
79a0a5cd | 212 | int fd = mkstemp(p); |
436677a3 MT |
213 | if (fd < 0) |
214 | return NULL; | |
215 | ||
79a0a5cd MT |
216 | // If we want a named temporary file, we set path |
217 | if (path) { | |
218 | *path = p; | |
219 | ||
220 | // Otherwise we unlink the path and free p | |
221 | } else { | |
222 | unlink(p); | |
223 | free(p); | |
224 | } | |
292f8013 | 225 | |
a8c8f799 | 226 | return fdopen(fd, "w+"); |
436677a3 | 227 | } |
67849b24 MT |
228 | |
229 | char* test_mkdtemp() { | |
79a0a5cd | 230 | char path[] = TMP_TEMPLATE; |
67849b24 MT |
231 | |
232 | char* p = mkdtemp(path); | |
233 | if (!p) | |
234 | return NULL; | |
235 | ||
236 | return strdup(path); | |
237 | } |