gbm: factor out gbm_window_{init,teardown}
[mesa-waffle.git] / src / waffle / core / wcore_error_unittest.c
blob8f0d8df572e6c46c8765c38e1be5e29216ffb605
1 // Copyright 2012-2013 Intel Corporation
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // - Redistributions of source code must retain the above copyright notice, this
9 // list of conditions and the following disclaimer.
11 // - Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include <setjmp.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include "c99_compat.h"
32 #include "threads.h"
34 #include <cmocka.h>
36 #include "wcore_error.h"
38 static void
39 test_wcore_error_code_unknown_error(void **state) {
40 wcore_error_reset();
41 wcore_error(WAFFLE_ERROR_UNKNOWN);
42 assert_int_equal(wcore_error_get_code(), WAFFLE_ERROR_UNKNOWN);
43 assert_string_equal(wcore_error_get_info()->message, "");
47 static void
48 test_wcore_error_code_bad_attribute(void **state) {
49 wcore_error_reset();
50 wcore_error(WAFFLE_ERROR_BAD_ATTRIBUTE);
51 assert_int_equal(wcore_error_get_code(), WAFFLE_ERROR_BAD_ATTRIBUTE);
52 assert_string_equal(wcore_error_get_info()->message, "");
55 static void
56 test_wcore_error_with_message(void **state) {
57 wcore_error_reset();
58 wcore_errorf(WAFFLE_ERROR_BAD_PARAMETER, "bad %s (0x%x)", "gl_api", 0x17);
59 assert_int_equal(wcore_error_get_code(), WAFFLE_ERROR_BAD_PARAMETER);
60 assert_string_equal(wcore_error_get_info()->message, "bad gl_api (0x17)");
63 static void
64 test_wcore_error_internal_error(void **state) {
65 char error_location[1024];
66 snprintf(error_location, 1024, "%s:%d:", __FILE__, __LINE__ + 3);
68 wcore_error_reset();
69 wcore_error_internal("%s zoroaster %d", "hello", 5);
70 assert_int_equal(wcore_error_get_code(), WAFFLE_ERROR_INTERNAL);
71 assert_true(strstr(wcore_error_get_info()->message, "hello zoroaster 5"));
72 assert_true(strstr(wcore_error_get_info()->message, error_location));
75 static void
76 test_wcore_error_first_call_without_message_wins(void **state) {
77 wcore_error_reset();
78 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "cookies");
79 wcore_error(WAFFLE_ERROR_BAD_ATTRIBUTE);
80 assert_int_equal(wcore_error_get_code(), WAFFLE_ERROR_UNKNOWN);
81 assert_string_equal(wcore_error_get_info()->message, "cookies");
84 static void
85 test_wcore_error_first_call_with_message_wins(void **state) {
86 wcore_error_reset();
87 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "cookies");
88 wcore_errorf(WAFFLE_NO_ERROR, "all is well");
89 assert_int_equal(wcore_error_get_code(), WAFFLE_ERROR_UNKNOWN);
90 assert_string_equal(wcore_error_get_info()->message, "cookies");
93 static void
94 test_wcore_error_disable_then_error(void **state) {
95 wcore_error_reset();
96 wcore_error(WAFFLE_ERROR_NOT_INITIALIZED);
97 WCORE_ERROR_DISABLED(
98 wcore_error(WAFFLE_ERROR_BAD_ATTRIBUTE);
100 assert_int_equal(wcore_error_get_code(), WAFFLE_ERROR_NOT_INITIALIZED);
103 static void
104 test_wcore_error_disable_then_errorf(void **state) {
105 wcore_error_reset();
106 wcore_error(WAFFLE_ERROR_NOT_INITIALIZED);
107 WCORE_ERROR_DISABLED(
108 wcore_errorf(WAFFLE_ERROR_BAD_ATTRIBUTE, "i'm not here");
110 assert_int_equal(wcore_error_get_code(), WAFFLE_ERROR_NOT_INITIALIZED);
113 static void
114 test_wcore_error_disable_then_error_internal(void **state) {
115 wcore_error_reset();
116 wcore_error(WAFFLE_ERROR_NOT_INITIALIZED);
117 WCORE_ERROR_DISABLED({
118 // Compilation fails with gcc when wcore_error_internal() appears
119 // here. So directly the macro's implementing function.
120 _wcore_error_internal(__FILE__, __LINE__, "this isn't happening");
122 assert_int_equal(wcore_error_get_code(), WAFFLE_ERROR_NOT_INITIALIZED);
125 /// Number of threads in test wcore_error.thread_local.
126 enum {
127 NUM_THREADS = 3,
130 /// Given to thrd_create() in test wcore_error.thread_local.
132 /// A sub-thread, after calling wcore_error(), locks the mutex, increments
133 /// `num_threads_waiting`, and waits on `cond`. When all sub-threads are
134 /// waiting (that is, `num_threads_waiting == TOTAL_THREADS`), then the main
135 /// thread broadcasts on `cond`.
136 struct thread_arg {
137 /// Has value in range `[0, TOTAL_THREADS)`.
138 int thread_id;
140 /// Protects `num_threads_waiting` and `cond`.
141 mtx_t *mutex;
143 /// Satisfied when `num_threads_waiting == TOTAL_THREADS`.
144 cnd_t *cond;
146 /// Number of threads waiting on `cond`.
147 volatile int *num_threads_waiting;
150 /// The start routine given to threads in test wcore_error.thread_local.
151 static bool
152 thread_start(struct thread_arg *a)
154 static const enum waffle_error error_codes[NUM_THREADS] = {
155 WAFFLE_ERROR_BAD_ATTRIBUTE,
156 WAFFLE_ERROR_UNKNOWN,
157 WAFFLE_ERROR_ALREADY_INITIALIZED,
160 bool ok = true;
161 enum waffle_error error_code = error_codes[a->thread_id];
163 // Each thread begins in an error-free state.
164 ok &= wcore_error_get_code() == WAFFLE_NO_ERROR;
166 // Each thread sets its error code.
167 wcore_error(error_code);
169 // Wait for all threads to set their error codes, thus giving
170 // the threads opportunity to clobber each other's codes.
171 mtx_lock(a->mutex); {
172 *a->num_threads_waiting += 1;
173 cnd_wait(a->cond, a->mutex);
174 mtx_unlock(a->mutex);
177 // Verify that the threads did not clobber each other's
178 // error codes.
179 ok &= wcore_error_get_code() == error_code;
181 return ok;
184 // Test that threads do not clobber each other's error codes.
185 static void
186 test_wcore_error_thread_local(void **state) {
187 mtx_t mutex;
188 cnd_t cond;
189 volatile int num_threads_waiting = 0;
191 thrd_t threads[NUM_THREADS];
192 struct thread_arg thread_args[NUM_THREADS];
193 int exit_codes[NUM_THREADS];
195 mtx_init(&mutex, mtx_plain);
196 cnd_init(&cond);
198 for (int i = 0; i < NUM_THREADS; ++i) {
199 struct thread_arg *a = &thread_args[i];
200 a->thread_id = i;
201 a->mutex = &mutex;
202 a->cond = &cond;
203 a->num_threads_waiting = &num_threads_waiting;
205 thrd_create(&threads[i],
206 (thrd_start_t) thread_start,
207 (void*) a);
210 // Wait for all threads to set their error codes, thus giving
211 // the threads opportunity to clobber each other's codes.
212 while (num_threads_waiting < NUM_THREADS)
214 mtx_lock(&mutex); {
215 cnd_broadcast(&cond);
216 mtx_unlock(&mutex);
219 for (int i = 0; i < NUM_THREADS; ++i) {
220 thrd_join(threads[i], &exit_codes[i]);
221 assert_true(exit_codes[i]);
224 cnd_destroy(&cond);
225 mtx_destroy(&mutex);
229 main(void) {
230 const struct CMUnitTest tests[] = {
231 cmocka_unit_test(test_wcore_error_code_unknown_error),
232 cmocka_unit_test(test_wcore_error_code_bad_attribute),
233 cmocka_unit_test(test_wcore_error_code_unknown_error),
234 cmocka_unit_test(test_wcore_error_with_message),
235 cmocka_unit_test(test_wcore_error_internal_error),
236 cmocka_unit_test(test_wcore_error_first_call_without_message_wins),
237 cmocka_unit_test(test_wcore_error_first_call_with_message_wins),
238 cmocka_unit_test(test_wcore_error_disable_then_error),
239 cmocka_unit_test(test_wcore_error_disable_then_errorf),
240 cmocka_unit_test(test_wcore_error_disable_then_error_internal),
241 cmocka_unit_test(test_wcore_error_thread_local),
244 return cmocka_run_group_tests(tests, NULL, NULL);