summaryrefslogtreecommitdiff
path: root/test/src/unit_test_run.c
blob: 6a07e4c6eab495ef2169b3755f61a5a19a7b0ffd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * oma-ds-agent
 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "unit_test_common.h"
#include "unit_test_run.h"
#include "unit_test_suites.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

/* introduction to unit test using check by yangsuh
  * SRunner : runner of all test which belong to added suites
  *	Suite : container of test cases(TCase)
  *		TCase : container of tests
  *			test : container of many asserts
  *
  * SRunner has fork_status option. I will set this option to CK_FORK which means
  * not stopping until all test finished.
  * (Of course, when error like SIGSEGV occurs or test failed, current test will be stopped
  * and goes to next test)
  */

typedef enum fork_status fork_status_t;
int unit_test_main(fork_status_t fork_status)
{
	SRunner *sr = NULL;

	/* srunner build up by defined test suites */
	int suite_count = sizeof(suiteFunctions) / sizeof(SUITE_FUNCTION);
	fprintf(stderr, "total test suites number = %d\n", suite_count);

	if (suite_count == 0) {
		return 0;	/* nothing to do */
	} else {		/* suite_count > 0 */
		SUITE_FUNCTION suite_func = NULL;

		int i = 0;
		for (i = 0; i < suite_count; i++) {
			suite_func = suiteFunctions[i];
			Suite *s = suite_func();
			if (s != NULL) {
				if (i == 0) {
					sr = srunner_create(s);
				} else if (i > 0 && i < suite_count) {
					srunner_add_suite(sr, s);
				}
			} else {
				fprintf(stderr, "%s\n", "invalid suite function");
			}
		}
	}

	/* srunner setting */
	srunner_set_log(sr, "/tmp/test.log");	/* set log file */
	srunner_set_fork_status(sr, fork_status);	/* set fork status of Runner */

	srunner_run_all(sr, CK_VERBOSE);	/* set print mode to verbose */
	srunner_free(sr);

	return 0;
}

/* TODO : return handling */
static inline int unit_test_run_fork_mode()
{
	pid_t pid_w;
	pid_t pid;
	int status = 0;

	pid = fork();
	if (pid == -1)
		fprintf(stderr, "%s\n", "Error in call to fork");
	if (pid == 0) {
		/* child process : run unit_test_main */
		unit_test_main(CK_FORK);
		exit(EXIT_SUCCESS);
	} else {
		/* parent process */
		fprintf(stderr, "test process pid = %d", pid);
		pid_w = waitpid(pid, &status, 0);

		if (pid_w == pid) {
			fprintf(stderr, "%s\n", "test finished successfully");
			return 1;	/* test finished */
		} else {
			fprintf(stderr, "%s\n", "test failed");
			return 0;	/* test error */
		}
	}

	return status;
}

/* running as main function will be need during debugging */
/* TODO : return handling */
static inline int unit_test_run_function_mode()
{
	return unit_test_main(CK_NOFORK);
}

int unit_test_run(run_unit_test_mode_t mode)
{
	int success = 1;	/* success */

	switch (mode) {
	case FORK_MODE:
		success = unit_test_run_fork_mode();
		break;
	case FUNCTION_MODE:
		success = unit_test_run_function_mode();
		break;
	default:
		break;
	}

	return success;
}