xref: /netbsd-src/tests/lib/libutil/t_pidfile.c (revision 255271589f90bf5a4990d46ab152a8930793cf64)
1*25527158Sjmmv /* $NetBSD: t_pidfile.c,v 1.3 2011/03/29 13:55:37 jmmv Exp $ */
2f8d6f5f3Sjmmv 
3f8d6f5f3Sjmmv /*
4f8d6f5f3Sjmmv  * Copyright (c) 2011 The NetBSD Foundation, Inc.
5f8d6f5f3Sjmmv  * All rights reserved.
6f8d6f5f3Sjmmv  *
7f8d6f5f3Sjmmv  * Redistribution and use in source and binary forms, with or without
8f8d6f5f3Sjmmv  * modification, are permitted provided that the following conditions
9f8d6f5f3Sjmmv  * are met:
10f8d6f5f3Sjmmv  * 1. Redistributions of source code must retain the above copyright
11f8d6f5f3Sjmmv  *    notice, this list of conditions and the following disclaimer.
12f8d6f5f3Sjmmv  * 2. Redistributions in binary form must reproduce the above copyright
13f8d6f5f3Sjmmv  *    notice, this list of conditions and the following disclaimer in the
14f8d6f5f3Sjmmv  *    documentation and/or other materials provided with the distribution.
15f8d6f5f3Sjmmv  *
16f8d6f5f3Sjmmv  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17f8d6f5f3Sjmmv  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18f8d6f5f3Sjmmv  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19f8d6f5f3Sjmmv  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20f8d6f5f3Sjmmv  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21f8d6f5f3Sjmmv  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22f8d6f5f3Sjmmv  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23f8d6f5f3Sjmmv  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24f8d6f5f3Sjmmv  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25f8d6f5f3Sjmmv  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26f8d6f5f3Sjmmv  * POSSIBILITY OF SUCH DAMAGE.
27f8d6f5f3Sjmmv  */
28f8d6f5f3Sjmmv 
29f8d6f5f3Sjmmv /*
30f8d6f5f3Sjmmv  * This file implements tests for the pidfile(3) functions.
31f8d6f5f3Sjmmv  *
32f8d6f5f3Sjmmv  * The tests here are tricky because we need to validate that the atexit(3)
33f8d6f5f3Sjmmv  * handler registered by pidfile(3) correctly deletes the generated pidfile.
34f8d6f5f3Sjmmv  * To do so:
35f8d6f5f3Sjmmv  * 1) We spawn a subprocess in every test case,
36f8d6f5f3Sjmmv  * 2) Run our test code in such subprocesses.  We cannot call any of the ATF
37f8d6f5f3Sjmmv  *    primitives from inside these.
38f8d6f5f3Sjmmv  * 3) Wait for the subprocess to terminate and ensure it exited successfully.
39f8d6f5f3Sjmmv  * 4) Check that the pidfile(s) created in the subprocess are gone.
40f8d6f5f3Sjmmv  *
41f8d6f5f3Sjmmv  * Additionally, pidfile(3) hardcodes a path to a directory writable only by
42f8d6f5f3Sjmmv  * root (/var/run).  This makes us require root privileges to execute these
43f8d6f5f3Sjmmv  * tests.
44f8d6f5f3Sjmmv  */
45f8d6f5f3Sjmmv 
46f8d6f5f3Sjmmv #include <sys/cdefs.h>
47f8d6f5f3Sjmmv __COPYRIGHT("@(#) Copyright (c) 2011\
48f8d6f5f3Sjmmv  The NetBSD Foundation, inc. All rights reserved.");
49*25527158Sjmmv __RCSID("$NetBSD: t_pidfile.c,v 1.3 2011/03/29 13:55:37 jmmv Exp $");
50f8d6f5f3Sjmmv 
51*25527158Sjmmv #include <sys/stat.h>
52f8d6f5f3Sjmmv #include <sys/wait.h>
53f8d6f5f3Sjmmv 
54f8d6f5f3Sjmmv #include <assert.h>
55f8d6f5f3Sjmmv #include <err.h>
56f8d6f5f3Sjmmv #include <stdbool.h>
57f8d6f5f3Sjmmv #include <stdio.h>
58f8d6f5f3Sjmmv #include <stdlib.h>
59f8d6f5f3Sjmmv #include <paths.h>
60f8d6f5f3Sjmmv #include <unistd.h>
61f8d6f5f3Sjmmv #include <util.h>
62f8d6f5f3Sjmmv 
63f8d6f5f3Sjmmv #include <atf-c.h>
64f8d6f5f3Sjmmv 
65f8d6f5f3Sjmmv /* Used by routines that can be called both from the parent and the child
66f8d6f5f3Sjmmv  * code to implement proper error reporting. */
67f8d6f5f3Sjmmv static bool in_child = false;
68f8d6f5f3Sjmmv 
69f8d6f5f3Sjmmv /* Callable from the test case child code. */
70f8d6f5f3Sjmmv static void
check_pidfile(const char * path)71f8d6f5f3Sjmmv check_pidfile(const char *path)
72f8d6f5f3Sjmmv {
73f8d6f5f3Sjmmv 	FILE *file;
74f8d6f5f3Sjmmv 	int pid;
75f8d6f5f3Sjmmv 
76f8d6f5f3Sjmmv 	printf("Validating contents of pidfile '%s'\n", path);
77f8d6f5f3Sjmmv 
78f8d6f5f3Sjmmv 	if ((file = fopen(path, "r")) == NULL)
79f8d6f5f3Sjmmv 		errx(EXIT_FAILURE, "Cannot open expected pidfile '%s'", path);
80f8d6f5f3Sjmmv 
81f8d6f5f3Sjmmv 	if (fscanf(file, "%d", &pid) == -1)
82f8d6f5f3Sjmmv 		errx(EXIT_FAILURE, "Failed to read pid from pidfile '%s'",
83f8d6f5f3Sjmmv 		    path);
84f8d6f5f3Sjmmv 
85f8d6f5f3Sjmmv 	printf("Read pid %d, current pid %d\n", pid, getpid());
86f8d6f5f3Sjmmv 	if (pid != getpid())
87f8d6f5f3Sjmmv 		errx(EXIT_FAILURE, "Pid in pidfile (%d) does not match "
88f8d6f5f3Sjmmv 		    "current pid (%d)", pid, getpid());
89f8d6f5f3Sjmmv }
90f8d6f5f3Sjmmv 
91f8d6f5f3Sjmmv /* Callable from the test case parent/child code. */
92f8d6f5f3Sjmmv static void
ensure_deleted(const char * path)93f8d6f5f3Sjmmv ensure_deleted(const char *path)
94f8d6f5f3Sjmmv {
95f8d6f5f3Sjmmv 	printf("Ensuring pidfile %s does not exist any more\n", path);
96f8d6f5f3Sjmmv 	if (access(path, R_OK) != -1) {
97f8d6f5f3Sjmmv 		unlink(path);
98f8d6f5f3Sjmmv 		if (in_child)
99f8d6f5f3Sjmmv 			errx(EXIT_FAILURE, "The pidfile %s was not deleted",
100f8d6f5f3Sjmmv 			    path);
101f8d6f5f3Sjmmv 		else
102f8d6f5f3Sjmmv 			atf_tc_fail("The pidfile %s was not deleted", path);
103f8d6f5f3Sjmmv 	}
104f8d6f5f3Sjmmv }
105f8d6f5f3Sjmmv 
106f8d6f5f3Sjmmv /* Callable from the test case parent code. */
107f8d6f5f3Sjmmv static void
run_child(void (* child)(const char *),const char * cookie)108f8d6f5f3Sjmmv run_child(void (*child)(const char *), const char *cookie)
109f8d6f5f3Sjmmv {
110f8d6f5f3Sjmmv 	pid_t pid;
111f8d6f5f3Sjmmv 
112f8d6f5f3Sjmmv 	pid = fork();
113f8d6f5f3Sjmmv 	ATF_REQUIRE(pid != -1);
114f8d6f5f3Sjmmv 	if (pid == 0) {
115f8d6f5f3Sjmmv 		in_child = true;
116f8d6f5f3Sjmmv 		child(cookie);
117f8d6f5f3Sjmmv 		assert(false);
118f8d6f5f3Sjmmv 		/* UNREACHABLE */
119f8d6f5f3Sjmmv 	} else {
120f8d6f5f3Sjmmv 		int status;
121f8d6f5f3Sjmmv 
122f8d6f5f3Sjmmv 		ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
123f8d6f5f3Sjmmv 		if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS)
124f8d6f5f3Sjmmv 			atf_tc_fail("See stderr for details");
125f8d6f5f3Sjmmv 	}
126f8d6f5f3Sjmmv }
127f8d6f5f3Sjmmv 
128f8d6f5f3Sjmmv /* Callable from the test case parent/child code. */
129a6fb334dSjmmv static char *
generate_varrun_pidfile(const char * basename)130a6fb334dSjmmv generate_varrun_pidfile(const char *basename)
131f8d6f5f3Sjmmv {
132a6fb334dSjmmv 	char *path;
133a6fb334dSjmmv 
134a6fb334dSjmmv 	if (asprintf(&path, "%s%s.pid", _PATH_VARRUN,
135a6fb334dSjmmv 	    basename == NULL ? getprogname() : basename) == -1) {
136f8d6f5f3Sjmmv 		if (in_child)
137f8d6f5f3Sjmmv 			errx(EXIT_FAILURE, "Cannot allocate memory for path");
138f8d6f5f3Sjmmv 		else
139f8d6f5f3Sjmmv 			atf_tc_fail("Cannot allocate memory for path");
140f8d6f5f3Sjmmv 	}
141f8d6f5f3Sjmmv 
142a6fb334dSjmmv 	return path;
143f8d6f5f3Sjmmv }
144f8d6f5f3Sjmmv 
145f8d6f5f3Sjmmv static void
helper_default_path(const char * path)146*25527158Sjmmv helper_default_path(const char *path)
147f8d6f5f3Sjmmv {
148f8d6f5f3Sjmmv 
149f8d6f5f3Sjmmv 	if (pidfile(NULL) == -1)
150f8d6f5f3Sjmmv 		errx(EXIT_FAILURE, "Failed to create pidfile with default "
151f8d6f5f3Sjmmv 		    "basename");
152f8d6f5f3Sjmmv 
153f8d6f5f3Sjmmv 	check_pidfile(path);
154f8d6f5f3Sjmmv 	exit(EXIT_SUCCESS);
155f8d6f5f3Sjmmv }
156f8d6f5f3Sjmmv 
157*25527158Sjmmv ATF_TC(default_path);
ATF_TC_HEAD(default_path,tc)158*25527158Sjmmv ATF_TC_HEAD(default_path, tc)
159f8d6f5f3Sjmmv {
160f8d6f5f3Sjmmv 	atf_tc_set_md_var(tc, "require.user", "root");
161f8d6f5f3Sjmmv }
ATF_TC_BODY(default_path,tc)162*25527158Sjmmv ATF_TC_BODY(default_path, tc)
163f8d6f5f3Sjmmv {
164f8d6f5f3Sjmmv 	char *path;
165f8d6f5f3Sjmmv 
166a6fb334dSjmmv 	path = generate_varrun_pidfile(NULL);
167*25527158Sjmmv 	run_child(helper_default_path, path);
168f8d6f5f3Sjmmv 	ensure_deleted(path);
169a6fb334dSjmmv 	free(path);
170f8d6f5f3Sjmmv }
171f8d6f5f3Sjmmv 
172f8d6f5f3Sjmmv static void
helper_custom_basename(const char * path)173f8d6f5f3Sjmmv helper_custom_basename(const char *path)
174f8d6f5f3Sjmmv {
175f8d6f5f3Sjmmv 
176f8d6f5f3Sjmmv 	if (pidfile("custom-basename") == -1)
177f8d6f5f3Sjmmv 		errx(EXIT_FAILURE, "Failed to create pidfile with custom "
178f8d6f5f3Sjmmv 		    "basename");
179f8d6f5f3Sjmmv 
180f8d6f5f3Sjmmv 	check_pidfile(path);
181f8d6f5f3Sjmmv 	exit(EXIT_SUCCESS);
182f8d6f5f3Sjmmv }
183f8d6f5f3Sjmmv 
184a6fb334dSjmmv ATF_TC(custom_basename);
ATF_TC_HEAD(custom_basename,tc)185a6fb334dSjmmv ATF_TC_HEAD(custom_basename, tc)
186f8d6f5f3Sjmmv {
187f8d6f5f3Sjmmv 	atf_tc_set_md_var(tc, "require.user", "root");
188f8d6f5f3Sjmmv }
ATF_TC_BODY(custom_basename,tc)189a6fb334dSjmmv ATF_TC_BODY(custom_basename, tc)
190f8d6f5f3Sjmmv {
191f8d6f5f3Sjmmv 	char *path;
192f8d6f5f3Sjmmv 
193a6fb334dSjmmv 	path = generate_varrun_pidfile("custom-basename");
194f8d6f5f3Sjmmv 	run_child(helper_custom_basename, path);
195f8d6f5f3Sjmmv 	ensure_deleted(path);
196a6fb334dSjmmv 	free(path);
197f8d6f5f3Sjmmv }
198f8d6f5f3Sjmmv 
199f8d6f5f3Sjmmv static void
helper_custom_path(const char * path)200*25527158Sjmmv helper_custom_path(const char *path)
201*25527158Sjmmv {
202*25527158Sjmmv 
203*25527158Sjmmv 	if (pidfile(path) == -1)
204*25527158Sjmmv 		errx(EXIT_FAILURE, "Failed to create pidfile '%s'", path);
205*25527158Sjmmv 	check_pidfile(path);
206*25527158Sjmmv 	exit(EXIT_SUCCESS);
207*25527158Sjmmv }
208*25527158Sjmmv 
209*25527158Sjmmv ATF_TC_WITHOUT_HEAD(custom_path);
ATF_TC_BODY(custom_path,tc)210*25527158Sjmmv ATF_TC_BODY(custom_path, tc)
211*25527158Sjmmv {
212*25527158Sjmmv 
213*25527158Sjmmv 	ATF_REQUIRE(mkdir("var", 0777) != -1);
214*25527158Sjmmv 	ATF_REQUIRE(mkdir("var/run", 0777) != -1);
215*25527158Sjmmv 
216*25527158Sjmmv 	run_child(helper_custom_path, "./var/run/my-pidfile.pid");
217*25527158Sjmmv 
218*25527158Sjmmv 	ensure_deleted("./var/run/my-pidfile.pid");
219*25527158Sjmmv }
220*25527158Sjmmv 
221*25527158Sjmmv static void
helper_change_basenames(const char * unused_cookie)222f8d6f5f3Sjmmv helper_change_basenames(const char *unused_cookie)
223f8d6f5f3Sjmmv {
224f8d6f5f3Sjmmv 	char *default_path;
225f8d6f5f3Sjmmv 	char *custom_path;
226f8d6f5f3Sjmmv 
227a6fb334dSjmmv 	default_path = generate_varrun_pidfile(NULL);
228f8d6f5f3Sjmmv 	if (pidfile(NULL) == -1)
229f8d6f5f3Sjmmv 		errx(EXIT_FAILURE, "Failed to create pidfile with default "
230f8d6f5f3Sjmmv 		    "basename");
231f8d6f5f3Sjmmv 	check_pidfile(default_path);
232f8d6f5f3Sjmmv 	if (pidfile(NULL) == -1)
233f8d6f5f3Sjmmv 		errx(EXIT_FAILURE, "Failed to recreate pidfile with default "
234f8d6f5f3Sjmmv 		    "basename");
235f8d6f5f3Sjmmv 	check_pidfile(default_path);
236f8d6f5f3Sjmmv 
237a6fb334dSjmmv 	custom_path = generate_varrun_pidfile("custom-basename");
238f8d6f5f3Sjmmv 	if (pidfile("custom-basename") == -1)
239f8d6f5f3Sjmmv 		errx(EXIT_FAILURE, "Failed to create pidfile with custom "
240f8d6f5f3Sjmmv 		    "basename");
241f8d6f5f3Sjmmv 	ensure_deleted(default_path);
242f8d6f5f3Sjmmv 	check_pidfile(custom_path);
243f8d6f5f3Sjmmv 	if (pidfile("custom-basename") == -1)
244f8d6f5f3Sjmmv 		errx(EXIT_FAILURE, "Failed to recreate pidfile with custom "
245f8d6f5f3Sjmmv 		    "basename");
246f8d6f5f3Sjmmv 	check_pidfile(custom_path);
247f8d6f5f3Sjmmv 
248a6fb334dSjmmv 	free(custom_path);
249a6fb334dSjmmv 	free(default_path);
250f8d6f5f3Sjmmv 	exit(EXIT_SUCCESS);
251f8d6f5f3Sjmmv }
252f8d6f5f3Sjmmv 
253a6fb334dSjmmv ATF_TC(change_basenames);
ATF_TC_HEAD(change_basenames,tc)254a6fb334dSjmmv ATF_TC_HEAD(change_basenames, tc)
255f8d6f5f3Sjmmv {
256f8d6f5f3Sjmmv 	atf_tc_set_md_var(tc, "require.user", "root");
257f8d6f5f3Sjmmv }
ATF_TC_BODY(change_basenames,tc)258a6fb334dSjmmv ATF_TC_BODY(change_basenames, tc)
259f8d6f5f3Sjmmv {
260f8d6f5f3Sjmmv 	char *default_path;
261f8d6f5f3Sjmmv 	char *custom_path;
262f8d6f5f3Sjmmv 
263f8d6f5f3Sjmmv 	run_child(helper_change_basenames, NULL);
264f8d6f5f3Sjmmv 
265a6fb334dSjmmv 	default_path = generate_varrun_pidfile(NULL);
266a6fb334dSjmmv 	custom_path = generate_varrun_pidfile("custom-basename");
267f8d6f5f3Sjmmv 
268f8d6f5f3Sjmmv 	ensure_deleted(default_path);
269f8d6f5f3Sjmmv 	ensure_deleted(custom_path);
270a6fb334dSjmmv 
271a6fb334dSjmmv 	free(custom_path);
272a6fb334dSjmmv 	free(default_path);
273f8d6f5f3Sjmmv }
274f8d6f5f3Sjmmv 
275*25527158Sjmmv static void
helper_change_paths(const char * unused_cookie)276*25527158Sjmmv helper_change_paths(const char *unused_cookie)
277*25527158Sjmmv {
278*25527158Sjmmv 
279*25527158Sjmmv 	if (pidfile("./var/run/first.pid") == -1)
280*25527158Sjmmv 		errx(EXIT_FAILURE, "Failed to create pidfile "
281*25527158Sjmmv 		    "'./var/run/first.pid'");
282*25527158Sjmmv 	check_pidfile("./var/run/first.pid");
283*25527158Sjmmv 
284*25527158Sjmmv 	if (pidfile("./second.pid") == -1)
285*25527158Sjmmv 		errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'");
286*25527158Sjmmv 	ensure_deleted("./var/run/first.pid");
287*25527158Sjmmv 	check_pidfile("./second.pid");
288*25527158Sjmmv 
289*25527158Sjmmv 	exit(EXIT_SUCCESS);
290*25527158Sjmmv }
291*25527158Sjmmv 
292*25527158Sjmmv ATF_TC_WITHOUT_HEAD(change_paths);
ATF_TC_BODY(change_paths,tc)293*25527158Sjmmv ATF_TC_BODY(change_paths, tc)
294*25527158Sjmmv {
295*25527158Sjmmv 
296*25527158Sjmmv 	ATF_REQUIRE(mkdir("var", 0777) != -1);
297*25527158Sjmmv 	ATF_REQUIRE(mkdir("var/run", 0777) != -1);
298*25527158Sjmmv 
299*25527158Sjmmv 	run_child(helper_change_paths, NULL);
300*25527158Sjmmv 
301*25527158Sjmmv 	ensure_deleted("./var/run/my-pidfile.pid");
302*25527158Sjmmv 	ensure_deleted("second.pid");
303*25527158Sjmmv }
304*25527158Sjmmv 
305*25527158Sjmmv static void
helper_mix(const char * unused_cookie)306*25527158Sjmmv helper_mix(const char *unused_cookie)
307*25527158Sjmmv {
308*25527158Sjmmv 	char *default_path;
309*25527158Sjmmv 	char *custom_path;
310*25527158Sjmmv 
311*25527158Sjmmv 	default_path = generate_varrun_pidfile(NULL);
312*25527158Sjmmv 	custom_path = generate_varrun_pidfile("custom-basename");
313*25527158Sjmmv 
314*25527158Sjmmv 	if (pidfile(NULL) == -1)
315*25527158Sjmmv 		errx(EXIT_FAILURE, "Failed to create default pidfile");
316*25527158Sjmmv 	check_pidfile(default_path);
317*25527158Sjmmv 
318*25527158Sjmmv 	if (pidfile("./second.pid") == -1)
319*25527158Sjmmv 		errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'");
320*25527158Sjmmv 	ensure_deleted(default_path);
321*25527158Sjmmv 	check_pidfile("./second.pid");
322*25527158Sjmmv 
323*25527158Sjmmv 	if (pidfile("custom-basename") == -1)
324*25527158Sjmmv 		errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'");
325*25527158Sjmmv 	ensure_deleted(default_path);
326*25527158Sjmmv 	ensure_deleted("./second.pid");
327*25527158Sjmmv 	ensure_deleted("./custom-basename");
328*25527158Sjmmv 	check_pidfile(custom_path);
329*25527158Sjmmv 
330*25527158Sjmmv 	free(custom_path);
331*25527158Sjmmv 	free(default_path);
332*25527158Sjmmv 	exit(EXIT_SUCCESS);
333*25527158Sjmmv }
334*25527158Sjmmv 
335*25527158Sjmmv ATF_TC(change_mix);
ATF_TC_HEAD(change_mix,tc)336*25527158Sjmmv ATF_TC_HEAD(change_mix, tc)
337*25527158Sjmmv {
338*25527158Sjmmv 	atf_tc_set_md_var(tc, "require.user", "root");
339*25527158Sjmmv }
ATF_TC_BODY(change_mix,tc)340*25527158Sjmmv ATF_TC_BODY(change_mix, tc)
341*25527158Sjmmv {
342*25527158Sjmmv 	char *default_path;
343*25527158Sjmmv 
344*25527158Sjmmv 	run_child(helper_mix, NULL);
345*25527158Sjmmv 
346*25527158Sjmmv 	default_path = generate_varrun_pidfile(NULL);
347*25527158Sjmmv 	ensure_deleted(default_path);
348*25527158Sjmmv 	ensure_deleted("second.pid");
349*25527158Sjmmv 	free(default_path);
350*25527158Sjmmv }
351*25527158Sjmmv 
ATF_TP_ADD_TCS(tp)352f8d6f5f3Sjmmv ATF_TP_ADD_TCS(tp)
353f8d6f5f3Sjmmv {
354f8d6f5f3Sjmmv 
355*25527158Sjmmv 	ATF_TP_ADD_TC(tp, default_path);
356a6fb334dSjmmv 	ATF_TP_ADD_TC(tp, custom_basename);
357*25527158Sjmmv 	ATF_TP_ADD_TC(tp, custom_path);
358a6fb334dSjmmv 	ATF_TP_ADD_TC(tp, change_basenames);
359*25527158Sjmmv 	ATF_TP_ADD_TC(tp, change_paths);
360*25527158Sjmmv 	ATF_TP_ADD_TC(tp, change_mix);
361f8d6f5f3Sjmmv 
362f8d6f5f3Sjmmv 	return atf_no_error();
363f8d6f5f3Sjmmv }
364