]>
git.saurik.com Git - apple/icu.git/blob - icuSources/test/cintltst/tracetst.c
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 2003-2013, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
14 #include "unicode/utypes.h"
15 #include "unicode/utrace.h"
16 #include "unicode/uclean.h"
17 #include "unicode/uchar.h"
18 #include "unicode/ures.h"
19 #include "unicode/ucnv.h"
25 /* We define the following to always test tracing, even when it's off in the library. */
27 #define ENABLE_TRACING_ORIG_VAL 1
29 #define ENABLE_TRACING_ORIG_VAL 0
31 #undef U_ENABLE_TRACING
32 #define U_ENABLE_TRACING 1
36 static void TestTraceAPI(void);
40 addUTraceTest(TestNode
** root
);
43 addUTraceTest(TestNode
** root
)
45 addTest(root
, &TestTraceAPI
, "tsutil/TraceTest/TestTraceAPI" );
50 * Macro for assert style tests.
52 #define TEST_ASSERT(expr) UPRV_BLOCK_MACRO_BEGIN { \
54 log_err("FAILED Assertion \"" #expr "\" at %s:%d.\n", __FILE__, __LINE__); \
56 } UPRV_BLOCK_MACRO_END
60 * test_format. Helper function for checking the results of a formatting
61 * operation. Executes the format op and compares actual
62 * results with the expected results.
64 * params: format: the format to be applied.
65 * bufCap buffer size to pass to formatter.
66 * indent: indent value to give to formatter
67 * result expected result. Do not truncate for short bufCap -
68 * this function will do it.
69 * line __LINE__, so we can report where failure happened.
70 * ... variable args to pass to formatter
73 static void test_format(const char *format
, int32_t bufCap
, int32_t indent
,
74 const char *result
, int32_t line
, ...) {
78 char expectedResult
[300];
80 /* check that local buffers are big enough for the test case */
81 if ((int32_t)sizeof(buf
) <= bufCap
) {
82 log_err("At file:line %s:%d, requested bufCap too large.\n");
85 if (strlen(result
) >= sizeof(expectedResult
)) {
86 log_err("At file:line %s:%d, expected result too large.\n");
90 /* Guarantee a nul term if buffer is smaller than output */
91 strcpy(expectedResult
, result
);
92 expectedResult
[bufCap
] = 0;
94 /* run the formatter */
96 memset(buf
, 0, sizeof(buf
));
97 len
= utrace_vformat(buf
, bufCap
, indent
, format
, args
);
98 (void)len
; /* Suppress set but not used warning. */
101 if (strcmp(expectedResult
, buf
) != 0) {
102 log_err("At file:line %s:%d Expected \"%s\", got \"%s\" \n",
103 __FILE__
, line
, expectedResult
, buf
);
110 * define trace functions for use in this test.
112 static int gTraceEntryCount
;
113 static int gTraceExitCount
;
114 static int gTraceDataCount
;
115 static UBool gFnNameError
= FALSE
;
116 static UBool gFnFormatError
= FALSE
;
118 static void U_CALLCONV
testTraceEntry(const void *context
, int32_t fnNumber
) {
119 (void)context
; // suppress compiler warnings about unused variable
121 const char *bogusFnName
;
125 /* Verify that a name is available for the fnNumber passed to us */
126 bogusFnName
= utrace_functionName(-1);
127 fnName
= utrace_functionName(fnNumber
);
128 if (strcmp(fnName
, bogusFnName
) == 0) {
131 /* printf("%s() Enter\n", fnName); */
135 static void U_CALLCONV
testTraceExit(const void *context
, int32_t fnNumber
,
136 const char *fmt
, va_list args
) {
137 (void)context
; // suppress compiler warnings about unused variable
140 const char *bogusFnName
;
144 /* Verify that a name is available for the fnNumber passed to us */
145 bogusFnName
= utrace_functionName(-1);
146 fnName
= utrace_functionName(fnNumber
);
147 if (strcmp(fnName
, bogusFnName
) == 0) {
151 /* Verify that the format can be used. */
153 utrace_vformat(buf
, sizeof(buf
), 0, fmt
, args
);
154 if (strlen(buf
) == 0) {
155 gFnFormatError
= TRUE
;
158 /* printf("%s() %s\n", fnName, buf); */
162 static void U_CALLCONV
testTraceData(const void *context
, int32_t fnNumber
, int32_t level
,
163 const char *fmt
, va_list args
) {
164 // suppress compiler warnings about unused variables
169 const char *bogusFnName
;
173 /* Verify that a name is available for the fnNumber passed to us */
174 bogusFnName
= utrace_functionName(-1);
175 fnName
= utrace_functionName(fnNumber
);
176 if (strcmp(fnName
, bogusFnName
) == 0) {
180 /* Verify that the format can be used. */
182 utrace_vformat(buf
, sizeof(buf
), 0, fmt
, args
);
183 if (strlen(buf
) == 0) {
184 gFnFormatError
= TRUE
;
187 /* printf(" %s() %s\n", fnName, buf); */
190 #if !ENABLE_TRACING_ORIG_VAL
191 static UConverter
* pseudo_ucnv_open(const char *name
, UErrorCode
* err
)
193 UTRACE_ENTRY_OC(UTRACE_UCNV_LOAD
);
195 UTRACE_DATA2(UTRACE_OPEN_CLOSE
, "error code is %s for %s", u_errorName(*err
), name
);
197 UTRACE_EXIT_PTR_STATUS(NULL
, *err
);
200 static void pseudo_ucnv_close(UConverter
* cnv
)
202 UTRACE_ENTRY_OC(UTRACE_UCNV_UNLOAD
);
203 UTRACE_DATA1(UTRACE_OPEN_CLOSE
, "unload converter %p", cnv
);
204 UTRACE_EXIT_VALUE((int32_t)TRUE
);
211 static void TestTraceAPI() {
214 UTraceEntry
*originalTEntryFunc
;
215 UTraceExit
*originalTExitFunc
;
216 UTraceData
*originalTDataFunc
;
217 const void *originalTContext
;
218 int32_t originalLevel
;
221 * Save the original tracing state so that we can restore it after the test.
223 utrace_getFunctions(&originalTContext
, &originalTEntryFunc
, &originalTExitFunc
,
225 originalLevel
= utrace_getLevel();
228 /* verify that set/get of tracing functions returns what was set. */
234 const void *newContext
= (const char *)originalTContext
+ 1;
236 TEST_ASSERT(originalTEntryFunc
!= testTraceEntry
);
237 TEST_ASSERT(originalTExitFunc
!= testTraceExit
);
238 TEST_ASSERT(originalTDataFunc
!= testTraceData
);
240 utrace_setFunctions(newContext
, testTraceEntry
, testTraceExit
, testTraceData
);
241 utrace_getFunctions(&context
, &e
, &x
, &d
);
242 TEST_ASSERT(e
== testTraceEntry
);
243 TEST_ASSERT(x
== testTraceExit
);
244 TEST_ASSERT(d
== testTraceData
);
245 TEST_ASSERT(context
== newContext
);
248 /* verify that set/get level work as a pair, and that the level
249 * identifiers all exist.
255 utrace_setLevel(UTRACE_OFF
);
256 level
= utrace_getLevel();
257 TEST_ASSERT(level
==UTRACE_OFF
);
258 utrace_setLevel(UTRACE_VERBOSE
);
259 level
= utrace_getLevel();
260 TEST_ASSERT(level
==UTRACE_VERBOSE
);
261 utrace_setLevel(UTRACE_ERROR
);
262 utrace_setLevel(UTRACE_WARNING
);
263 utrace_setLevel(UTRACE_OPEN_CLOSE
);
264 utrace_setLevel(UTRACE_INFO
);
268 * Open and close a converter with tracing enabled.
269 * Verify that our tracing callback functions get called.
272 UErrorCode status
= U_ZERO_ERROR
;
275 gTraceEntryCount
= 0;
278 gFnNameError
= FALSE
;
279 gFnFormatError
= FALSE
;
280 utrace_setLevel(UTRACE_OPEN_CLOSE
);
281 #if ENABLE_TRACING_ORIG_VAL
282 cnv
= ucnv_open(NULL
, &status
);
283 TEST_ASSERT(U_SUCCESS(status
));
286 cnv
= pseudo_ucnv_open(NULL
, &status
);
287 TEST_ASSERT(U_SUCCESS(status
));
288 pseudo_ucnv_close(cnv
);
290 TEST_ASSERT(gTraceEntryCount
> 0);
291 TEST_ASSERT(gTraceExitCount
> 0);
292 TEST_ASSERT(gTraceDataCount
> 0);
293 TEST_ASSERT(gFnNameError
== FALSE
);
294 TEST_ASSERT(gFnFormatError
== FALSE
);
300 * trace data formatter operation.
303 UChar s1
[] = {0x41fe, 0x42, 0x43, 00};
304 const char *a1
[] = {"s1", "s2", "s3"};
307 test_format("hello, world", 50, 0, "hello, world", __LINE__
);
308 test_format("hello, world", 50, 4, " hello, world", __LINE__
);
309 test_format("hello, world", 3, 0, "hello, world", __LINE__
);
311 test_format("a character %c", 50, 0, "a character x", __LINE__
, 'x');
312 test_format("a string %s ", 50, 0, "a string hello ", __LINE__
, "hello");
313 test_format("uchars %S ", 50, 0, "uchars 41fe 0042 0043 0000 ", __LINE__
, s1
, -1);
314 test_format("uchars %S ", 50, 0, "uchars 41fe 0042 ", __LINE__
, s1
, 2);
316 test_format("a byte %b--", 50, 0, "a byte dd--", __LINE__
, 0xdd);
317 test_format("a 16 bit val %h", 50, 0, "a 16 bit val 1234", __LINE__
, 0x1234);
318 test_format("a 32 bit val %d...", 50, 0, "a 32 bit val 6789abcd...", __LINE__
, 0x6789abcd);
319 test_format("a 64 bit val %l", 50, 0, "a 64 bit val 123456780abcdef0"
320 , __LINE__
, INT64_C(0x123456780abcdef0));
322 if (sizeof(void *) == 4) {
323 ptr
= (void *)0xdeadbeef;
324 test_format("a 32 bit ptr %p", 50, 0, "a 32 bit ptr deadbeef", __LINE__
, ptr
);
325 } else if (sizeof(void *) == 8) {
326 ptr
= (void *) INT64_C(0x1000200030004000);
327 test_format("a 64 bit ptr %p", 50, 0, "a 64 bit ptr 1000200030004000", __LINE__
, ptr
);
328 } else if (sizeof(void *) == 16) {
333 } massiveBigEndianPtr
= {{ 0x10002000, 0x30004000, 0x50006000, 0x70008000 }};
334 ptr
= massiveBigEndianPtr
.ptr
;
335 test_format("a 128 bit ptr %p", 50, 0, "a 128 bit ptr 10002000300040005000600070008000", __LINE__
, ptr
);
341 test_format("%vc", 100, 0, "abc[ffffffff]", __LINE__
, "abc", -1);
342 test_format("%vs", 100, 0, "s1\ns2\n[00000002]", __LINE__
, a1
, 2);
343 test_format("%vs", 100, 4, " s1\n s2\n [00000002]", __LINE__
, a1
, 2);
345 test_format("%vb", 100, 0, "41 42 43 [00000003]", __LINE__
, "\x41\x42\x43", 3);
347 /* Null ptrs for strings, vectors */
348 test_format("Null string - %s", 50, 0, "Null string - *NULL*", __LINE__
, NULL
);
349 test_format("Null string - %S", 50, 0, "Null string - *NULL*", __LINE__
, NULL
, -1);
350 test_format("Null vector - %vc", 50, 0, "Null vector - *NULL* [00000002]", __LINE__
, NULL
, 2);
351 test_format("Null vector - %vC", 50, 0, "Null vector - *NULL* [00000002]", __LINE__
, NULL
, 2);
352 test_format("Null vector - %vd", 50, 0, "Null vector - *NULL* [00000002]", __LINE__
, NULL
, 2);
357 * utrace_format. Only need a minimal test to see that the function works at all.
358 * Full functionality is tested via utrace_vformat.
363 x
= utrace_format(buf
, 100, 0, "%s", "Hello, World.");
364 TEST_ASSERT(strcmp(buf
, "Hello, World.") == 0);
365 TEST_ASSERT(x
== 14);
369 * utrace_functionName. Just spot-check a couple of them.
373 name
= utrace_functionName(UTRACE_U_INIT
);
374 TEST_ASSERT(strcmp(name
, "u_init") == 0);
375 name
= utrace_functionName(UTRACE_UCNV_OPEN
);
376 TEST_ASSERT(strcmp(name
, "ucnv_open") == 0);
377 name
= utrace_functionName(UTRACE_UCOL_GET_SORTKEY
);
378 TEST_ASSERT(strcmp(name
, "ucol_getSortKey") == 0);
383 /* Restore the trace function settings to their original values. */
384 utrace_setFunctions(originalTContext
, originalTEntryFunc
, originalTExitFunc
, originalTDataFunc
);
385 utrace_setLevel(originalLevel
);