2 * Copyright (C) 2010 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
32 #include <android/log.h>
34 #define ALEN(a) (sizeof(a) / sizeof((a)[0])) // Array length
35 typedef unsigned int bool_t;
41 static const char *logCatTag;
42 static const unsigned int uSecsPerSec = 1000000;
43 static const unsigned int nSecsPerSec = 1000000000;
45 // struct timespec to double
46 double ts2double(const struct timespec *val)
51 rv += (double) val->tv_nsec / nSecsPerSec;
56 // struct timeval to double
57 double tv2double(const struct timeval *val)
62 rv += (double) val->tv_usec / uSecsPerSec;
67 // double to struct timespec
68 struct timespec double2ts(double amt)
72 rv.tv_sec = floor(amt);
73 rv.tv_nsec = (amt - rv.tv_sec) * nSecsPerSec;
74 // TODO: Handle cases where amt is negative
75 while ((unsigned) rv.tv_nsec >= nSecsPerSec) {
76 rv.tv_nsec -= nSecsPerSec;
83 // double to struct timeval
84 struct timeval double2tv(double amt)
88 rv.tv_sec = floor(amt);
89 rv.tv_usec = (amt - rv.tv_sec) * uSecsPerSec;
90 // TODO: Handle cases where amt is negative
91 while ((unsigned) rv.tv_usec >= uSecsPerSec) {
92 rv.tv_usec -= uSecsPerSec;
99 // Delta (difference) between two struct timespec.
100 // It is expected that the time given by the structure pointed to by
101 // second, is later than the time pointed to by first.
102 struct timespec tsDelta(const struct timespec *first,
103 const struct timespec *second)
107 assert(first != NULL);
108 assert(second != NULL);
109 assert(first->tv_nsec >= 0 && first->tv_nsec < nSecsPerSec);
110 assert(second->tv_nsec >= 0 && second->tv_nsec < nSecsPerSec);
111 rv.tv_sec = second->tv_sec - first->tv_sec;
112 if (second->tv_nsec >= first->tv_nsec) {
113 rv.tv_nsec = second->tv_nsec - first->tv_nsec;
115 rv.tv_nsec = (second->tv_nsec + nSecsPerSec) - first->tv_nsec;
122 // Delta (difference) between two struct timeval.
123 // It is expected that the time given by the structure pointed to by
124 // second, is later than the time pointed to by first.
125 struct timeval tvDelta(const struct timeval *first,
126 const struct timeval *second)
130 assert(first != NULL);
131 assert(second != NULL);
132 assert(first->tv_usec >= 0 && first->tv_usec < uSecsPerSec);
133 assert(second->tv_usec >= 0 && second->tv_usec < uSecsPerSec);
134 rv.tv_sec = second->tv_sec - first->tv_sec;
135 if (second->tv_usec >= first->tv_usec) {
136 rv.tv_usec = second->tv_usec - first->tv_usec;
138 rv.tv_usec = (second->tv_usec + uSecsPerSec) - first->tv_usec;
145 void testPrint(FILE *stream, const char *fmt, ...)
151 vsnprintf(line, sizeof(line), fmt, args);
152 if (stream == stderr) {
153 ALOG(LOG_ERROR, logCatTag, "%s", line);
155 ALOG(LOG_INFO, logCatTag, "%s", line);
157 vfprintf(stream, fmt, args);
161 // Set tag used while logging to the logcat error interface
162 void testSetLogCatTag(const char *tag)
167 // Obtain pointer to current log to logcat error interface tag
168 const char * testGetLogCatTag(void)
176 * Returns a pseudo random number in the range [0:2^32-1].
178 * Precondition: srand48() called to set the seed of
179 * the pseudo random number generator.
181 uint32_t testRand(void)
185 // Use lrand48() to obtain 31 bits worth
189 // Make an additional lrand48() call and merge
190 // the randomness into the most significant bits.
191 val ^= lrand48() << 1;
199 * Pseudo randomly returns unsigned integer in the range [0, mod).
201 * Precondition: srand48() called to set the seed of
202 * the pseudo random number generator.
204 uint32_t testRandMod(uint32_t mod)
206 // Obtain the random value
207 // Use lrand48() when it would produce a sufficient
208 // number of random bits, otherwise use testRand().
209 const uint32_t lrand48maxVal = ((uint32_t) 1 << 31) - 1;
210 uint32_t val = (mod <= lrand48maxVal) ? (uint32_t) lrand48() : testRand();
213 * The contents of individual bytes tend to be less than random
214 * across different seeds. For example, srand48(x) and
215 * srand48(x + n * 4) cause lrand48() to return the same sequence of
216 * least significant bits. For small mod values this can produce
217 * noticably non-random sequnces. For mod values of less than 2
218 * bytes, will use the randomness from all the bytes.
220 if (mod <= 0x10000) {
221 val = (val & 0xffff) ^ (val >> 16);
223 // If mod less than a byte, can further combine down to
226 val = (val & 0xff) ^ (val >> 8);
236 * Pseudo randomly returns 0 (false) or 1 (true).
238 * Precondition: srand48() called to set the seed of
239 * the pseudo random number generator.
241 int testRandBool(void)
243 return (testRandMod(2));
249 * Pseudo randomly return a value in the range [0.0, 1.0).
251 * Precondition: srand48() called to set the seed of
252 * the pseudo random number generator.
254 double testRandFract(void)
259 // Delays for the number of seconds specified by amt or a greater amount.
260 // The amt variable is of type float and thus non-integer amounts
261 // of time can be specified. This function automatically handles cases
262 // where nanosleep(2) returns early due to reception of a signal.
263 void testDelay(float amt)
265 struct timespec start, current, delta;
266 struct timespec remaining;
268 // Get the time at which we started
269 clock_gettime(CLOCK_MONOTONIC, &start);
273 clock_gettime(CLOCK_MONOTONIC, ¤t);
275 // How much time is left
276 delta = tsDelta(&start, ¤t);
277 if (ts2double(&delta) > amt) { break; }
279 // Request to sleep for the remaining time
280 remaining = double2ts(amt - ts2double(&delta));
281 (void) nanosleep(&remaining, NULL);
285 // Delay spins for the number of seconds specified by amt or a greater
286 // amount. The amt variable is of type float and thus non-integer amounts
287 // of time can be specified. Differs from testDelay() in that
288 // testDelaySpin() performs a spin loop, instead of using nanosleep().
289 void testDelaySpin(float amt)
291 struct timespec start, current, delta;
293 // Get the time at which we started
294 clock_gettime(CLOCK_MONOTONIC, &start);
298 clock_gettime(CLOCK_MONOTONIC, ¤t);
300 // How much time is left
301 delta = tsDelta(&start, ¤t);
302 if (ts2double(&delta) > amt) { break; }
309 * Displays in hex the contents of the memory starting at the location
310 * pointed to by buf, for the number of bytes given by size.
311 * Each line of output is indented by a number of spaces that
312 * can be set by calling xDumpSetIndent(). It is also possible
313 * to offset the displayed address by an amount set by calling
316 static uint8_t xDumpIndent;
317 static uint64_t xDumpOffset;
319 testXDump(const void *buf, size_t size)
321 const unsigned int bytesPerLine = 16;
324 const unsigned char *ptr = buf, *start = buf;
329 if (((ptr - start) % bytesPerLine) == 0) {
331 testPrintE("%s", line);
334 rv = snprintf(linep, ALEN(line) - (linep - line),
335 "%*s%06llx:", xDumpIndent, "",
336 (long long) (ptr - start) + xDumpOffset);
340 // Check that there is at least room for 4
341 // more characters. The 4 characters being
342 // a space, 2 hex digits and the terminating
344 assert((ALEN(line) - 4) >= (linep - line));
345 rv = snprintf(linep, ALEN(line) - (linep - line),
351 testPrintE("%s", line);
355 // Set an indent of spaces for each line of hex dump output
357 testXDumpSetIndent(uint8_t indent)
359 xDumpIndent = indent;
362 // Obtain the current hex dump indent amount
364 testXDumpGetIndent(void)
369 // Set the hex dump address offset amount
371 testXDumpSetOffset(uint64_t offset)
373 xDumpOffset = offset;
376 // Get the current hex dump address offset amount
378 testXDumpGetOffset(void)
386 * Executes the command pointed to by cmd. Output from the
387 * executed command is captured and sent to LogCat Info. Once
388 * the command has finished execution, it's exit status is captured
389 * and checked for an exit status of zero. Any other exit status
390 * causes diagnostic information to be printed and an immediate
393 void testExecCmd(const char *cmd)
400 // Display command to be executed
401 testPrintI("cmd: %s", cmd);
403 // Execute the command
405 if ((fp = popen(cmd, "r")) == NULL) {
406 testPrintE("execCmd popen failed, errno: %i", errno);
410 // Obtain and display each line of output from the executed command
411 while (fgets(str, sizeof(str), fp) != NULL) {
412 if ((strlen(str) > 1) && (str[strlen(str) - 1] == '\n')) {
413 str[strlen(str) - 1] = '\0';
415 testPrintI(" out: %s", str);
418 // Obtain and check return status of executed command.
419 // Fail on non-zero exit status
421 if (!(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) {
422 testPrintE("Unexpected command failure");
423 testPrintE(" status: %#x", status);
424 if (WIFEXITED(status)) {
425 testPrintE("WEXITSTATUS: %i", WEXITSTATUS(status));
427 if (WIFSIGNALED(status)) {
428 testPrintE("WTERMSIG: %i", WTERMSIG(status));