xref: /aosp_15_r20/system/extras/tests/lib/testUtil/testUtil.c (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2010 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  *
16*288bf522SAndroid Build Coastguard Worker  */
17*288bf522SAndroid Build Coastguard Worker 
18*288bf522SAndroid Build Coastguard Worker #include <testUtil.h>
19*288bf522SAndroid Build Coastguard Worker 
20*288bf522SAndroid Build Coastguard Worker #include <assert.h>
21*288bf522SAndroid Build Coastguard Worker #include <errno.h>
22*288bf522SAndroid Build Coastguard Worker #include <math.h>
23*288bf522SAndroid Build Coastguard Worker #include <stdarg.h>
24*288bf522SAndroid Build Coastguard Worker #include <stdbool.h>
25*288bf522SAndroid Build Coastguard Worker #include <stdint.h>
26*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
27*288bf522SAndroid Build Coastguard Worker #include <stdlib.h>
28*288bf522SAndroid Build Coastguard Worker #include <string.h>
29*288bf522SAndroid Build Coastguard Worker #include <sys/time.h>
30*288bf522SAndroid Build Coastguard Worker #include <sys/wait.h>
31*288bf522SAndroid Build Coastguard Worker #include <time.h>
32*288bf522SAndroid Build Coastguard Worker 
33*288bf522SAndroid Build Coastguard Worker #include <log/log.h>
34*288bf522SAndroid Build Coastguard Worker 
35*288bf522SAndroid Build Coastguard Worker #define ALEN(a) (sizeof(a) / sizeof((a)[0]))  // Array length
36*288bf522SAndroid Build Coastguard Worker 
37*288bf522SAndroid Build Coastguard Worker #define MAXSTR 200
38*288bf522SAndroid Build Coastguard Worker 
39*288bf522SAndroid Build Coastguard Worker static const char *logCatTag;
40*288bf522SAndroid Build Coastguard Worker static const unsigned int uSecsPerSec = 1000000;
41*288bf522SAndroid Build Coastguard Worker static const unsigned int nSecsPerSec = 1000000000;
42*288bf522SAndroid Build Coastguard Worker 
43*288bf522SAndroid Build Coastguard Worker // struct timespec to double
ts2double(const struct timespec * val)44*288bf522SAndroid Build Coastguard Worker double ts2double(const struct timespec *val)
45*288bf522SAndroid Build Coastguard Worker {
46*288bf522SAndroid Build Coastguard Worker     double rv;
47*288bf522SAndroid Build Coastguard Worker 
48*288bf522SAndroid Build Coastguard Worker     rv = val->tv_sec;
49*288bf522SAndroid Build Coastguard Worker     rv += (double) val->tv_nsec / nSecsPerSec;
50*288bf522SAndroid Build Coastguard Worker 
51*288bf522SAndroid Build Coastguard Worker     return rv;
52*288bf522SAndroid Build Coastguard Worker }
53*288bf522SAndroid Build Coastguard Worker 
54*288bf522SAndroid Build Coastguard Worker // struct timeval to double
tv2double(const struct timeval * val)55*288bf522SAndroid Build Coastguard Worker double tv2double(const struct timeval *val)
56*288bf522SAndroid Build Coastguard Worker {
57*288bf522SAndroid Build Coastguard Worker     double rv;
58*288bf522SAndroid Build Coastguard Worker 
59*288bf522SAndroid Build Coastguard Worker     rv = val->tv_sec;
60*288bf522SAndroid Build Coastguard Worker     rv += (double) val->tv_usec / uSecsPerSec;
61*288bf522SAndroid Build Coastguard Worker 
62*288bf522SAndroid Build Coastguard Worker     return rv;
63*288bf522SAndroid Build Coastguard Worker }
64*288bf522SAndroid Build Coastguard Worker 
65*288bf522SAndroid Build Coastguard Worker // double to struct timespec
double2ts(double amt)66*288bf522SAndroid Build Coastguard Worker struct timespec double2ts(double amt)
67*288bf522SAndroid Build Coastguard Worker {
68*288bf522SAndroid Build Coastguard Worker     struct timespec rv;
69*288bf522SAndroid Build Coastguard Worker 
70*288bf522SAndroid Build Coastguard Worker     rv.tv_sec = floor(amt);
71*288bf522SAndroid Build Coastguard Worker     rv.tv_nsec = (amt - rv.tv_sec) * nSecsPerSec;
72*288bf522SAndroid Build Coastguard Worker     // TODO: Handle cases where amt is negative
73*288bf522SAndroid Build Coastguard Worker     while ((unsigned) rv.tv_nsec >= nSecsPerSec) {
74*288bf522SAndroid Build Coastguard Worker         rv.tv_nsec -= nSecsPerSec;
75*288bf522SAndroid Build Coastguard Worker         rv.tv_sec++;
76*288bf522SAndroid Build Coastguard Worker     }
77*288bf522SAndroid Build Coastguard Worker 
78*288bf522SAndroid Build Coastguard Worker     return rv;
79*288bf522SAndroid Build Coastguard Worker }
80*288bf522SAndroid Build Coastguard Worker 
81*288bf522SAndroid Build Coastguard Worker // double to struct timeval
double2tv(double amt)82*288bf522SAndroid Build Coastguard Worker struct timeval double2tv(double amt)
83*288bf522SAndroid Build Coastguard Worker {
84*288bf522SAndroid Build Coastguard Worker     struct timeval rv;
85*288bf522SAndroid Build Coastguard Worker 
86*288bf522SAndroid Build Coastguard Worker     rv.tv_sec = floor(amt);
87*288bf522SAndroid Build Coastguard Worker     rv.tv_usec = (amt - rv.tv_sec) * uSecsPerSec;
88*288bf522SAndroid Build Coastguard Worker     // TODO: Handle cases where amt is negative
89*288bf522SAndroid Build Coastguard Worker     while ((unsigned) rv.tv_usec >= uSecsPerSec) {
90*288bf522SAndroid Build Coastguard Worker         rv.tv_usec -= uSecsPerSec;
91*288bf522SAndroid Build Coastguard Worker         rv.tv_sec++;
92*288bf522SAndroid Build Coastguard Worker     }
93*288bf522SAndroid Build Coastguard Worker 
94*288bf522SAndroid Build Coastguard Worker     return rv;
95*288bf522SAndroid Build Coastguard Worker }
96*288bf522SAndroid Build Coastguard Worker 
97*288bf522SAndroid Build Coastguard Worker // Delta (difference) between two struct timespec.
98*288bf522SAndroid Build Coastguard Worker // It is expected that the time given by the structure pointed to by
99*288bf522SAndroid Build Coastguard Worker // second, is later than the time pointed to by first.
tsDelta(const struct timespec * first,const struct timespec * second)100*288bf522SAndroid Build Coastguard Worker struct timespec tsDelta(const struct timespec *first,
101*288bf522SAndroid Build Coastguard Worker                         const struct timespec *second)
102*288bf522SAndroid Build Coastguard Worker {
103*288bf522SAndroid Build Coastguard Worker     struct timespec rv;
104*288bf522SAndroid Build Coastguard Worker 
105*288bf522SAndroid Build Coastguard Worker     assert(first != NULL);
106*288bf522SAndroid Build Coastguard Worker     assert(second != NULL);
107*288bf522SAndroid Build Coastguard Worker     assert(first->tv_nsec >= 0 && first->tv_nsec < nSecsPerSec);
108*288bf522SAndroid Build Coastguard Worker     assert(second->tv_nsec >= 0 && second->tv_nsec < nSecsPerSec);
109*288bf522SAndroid Build Coastguard Worker     rv.tv_sec = second->tv_sec - first->tv_sec;
110*288bf522SAndroid Build Coastguard Worker     if (second->tv_nsec >= first->tv_nsec) {
111*288bf522SAndroid Build Coastguard Worker         rv.tv_nsec = second->tv_nsec - first->tv_nsec;
112*288bf522SAndroid Build Coastguard Worker     } else {
113*288bf522SAndroid Build Coastguard Worker         rv.tv_nsec = (second->tv_nsec + nSecsPerSec) - first->tv_nsec;
114*288bf522SAndroid Build Coastguard Worker         rv.tv_sec--;
115*288bf522SAndroid Build Coastguard Worker     }
116*288bf522SAndroid Build Coastguard Worker 
117*288bf522SAndroid Build Coastguard Worker     return rv;
118*288bf522SAndroid Build Coastguard Worker }
119*288bf522SAndroid Build Coastguard Worker 
120*288bf522SAndroid Build Coastguard Worker // Delta (difference) between two struct timeval.
121*288bf522SAndroid Build Coastguard Worker // It is expected that the time given by the structure pointed to by
122*288bf522SAndroid Build Coastguard Worker // second, is later than the time pointed to by first.
tvDelta(const struct timeval * first,const struct timeval * second)123*288bf522SAndroid Build Coastguard Worker struct timeval tvDelta(const struct timeval *first,
124*288bf522SAndroid Build Coastguard Worker                        const struct timeval *second)
125*288bf522SAndroid Build Coastguard Worker {
126*288bf522SAndroid Build Coastguard Worker     struct timeval rv;
127*288bf522SAndroid Build Coastguard Worker 
128*288bf522SAndroid Build Coastguard Worker     assert(first != NULL);
129*288bf522SAndroid Build Coastguard Worker     assert(second != NULL);
130*288bf522SAndroid Build Coastguard Worker     assert(first->tv_usec >= 0 && first->tv_usec < uSecsPerSec);
131*288bf522SAndroid Build Coastguard Worker     assert(second->tv_usec >= 0 && second->tv_usec < uSecsPerSec);
132*288bf522SAndroid Build Coastguard Worker     rv.tv_sec = second->tv_sec - first->tv_sec;
133*288bf522SAndroid Build Coastguard Worker     if (second->tv_usec >= first->tv_usec) {
134*288bf522SAndroid Build Coastguard Worker         rv.tv_usec = second->tv_usec - first->tv_usec;
135*288bf522SAndroid Build Coastguard Worker     } else {
136*288bf522SAndroid Build Coastguard Worker         rv.tv_usec = (second->tv_usec + uSecsPerSec) - first->tv_usec;
137*288bf522SAndroid Build Coastguard Worker         rv.tv_sec--;
138*288bf522SAndroid Build Coastguard Worker     }
139*288bf522SAndroid Build Coastguard Worker 
140*288bf522SAndroid Build Coastguard Worker     return rv;
141*288bf522SAndroid Build Coastguard Worker }
142*288bf522SAndroid Build Coastguard Worker 
testPrint(FILE * stream,const char * fmt,...)143*288bf522SAndroid Build Coastguard Worker void testPrint(FILE *stream, const char *fmt, ...)
144*288bf522SAndroid Build Coastguard Worker {
145*288bf522SAndroid Build Coastguard Worker     char line[MAXSTR];
146*288bf522SAndroid Build Coastguard Worker     va_list args;
147*288bf522SAndroid Build Coastguard Worker 
148*288bf522SAndroid Build Coastguard Worker     va_start(args, fmt);
149*288bf522SAndroid Build Coastguard Worker     vsnprintf(line, sizeof(line), fmt, args);
150*288bf522SAndroid Build Coastguard Worker     if (stream == stderr) {
151*288bf522SAndroid Build Coastguard Worker         ALOG(LOG_ERROR, logCatTag, "%s", line);
152*288bf522SAndroid Build Coastguard Worker     } else {
153*288bf522SAndroid Build Coastguard Worker         ALOG(LOG_INFO, logCatTag, "%s", line);
154*288bf522SAndroid Build Coastguard Worker     }
155*288bf522SAndroid Build Coastguard Worker     vfprintf(stream, fmt, args);
156*288bf522SAndroid Build Coastguard Worker     va_end(args);
157*288bf522SAndroid Build Coastguard Worker     fputc('\n', stream);
158*288bf522SAndroid Build Coastguard Worker }
159*288bf522SAndroid Build Coastguard Worker 
160*288bf522SAndroid Build Coastguard Worker // Set tag used while logging to the logcat error interface
testSetLogCatTag(const char * tag)161*288bf522SAndroid Build Coastguard Worker void testSetLogCatTag(const char *tag)
162*288bf522SAndroid Build Coastguard Worker {
163*288bf522SAndroid Build Coastguard Worker     logCatTag = tag;
164*288bf522SAndroid Build Coastguard Worker }
165*288bf522SAndroid Build Coastguard Worker 
166*288bf522SAndroid Build Coastguard Worker // Obtain pointer to current log to logcat error interface tag
testGetLogCatTag(void)167*288bf522SAndroid Build Coastguard Worker const char * testGetLogCatTag(void)
168*288bf522SAndroid Build Coastguard Worker {
169*288bf522SAndroid Build Coastguard Worker     return logCatTag;
170*288bf522SAndroid Build Coastguard Worker }
171*288bf522SAndroid Build Coastguard Worker 
172*288bf522SAndroid Build Coastguard Worker /*
173*288bf522SAndroid Build Coastguard Worker  * Random
174*288bf522SAndroid Build Coastguard Worker  *
175*288bf522SAndroid Build Coastguard Worker  * Returns a pseudo random number in the range [0:2^32-1].
176*288bf522SAndroid Build Coastguard Worker  *
177*288bf522SAndroid Build Coastguard Worker  * Precondition: srand48() called to set the seed of
178*288bf522SAndroid Build Coastguard Worker  *   the pseudo random number generator.
179*288bf522SAndroid Build Coastguard Worker  */
testRand(void)180*288bf522SAndroid Build Coastguard Worker uint32_t testRand(void)
181*288bf522SAndroid Build Coastguard Worker {
182*288bf522SAndroid Build Coastguard Worker     uint32_t val;
183*288bf522SAndroid Build Coastguard Worker 
184*288bf522SAndroid Build Coastguard Worker     // Use lrand48() to obtain 31 bits worth
185*288bf522SAndroid Build Coastguard Worker     // of randomness.
186*288bf522SAndroid Build Coastguard Worker     val = lrand48();
187*288bf522SAndroid Build Coastguard Worker 
188*288bf522SAndroid Build Coastguard Worker     // Make an additional lrand48() call and merge
189*288bf522SAndroid Build Coastguard Worker     // the randomness into the most significant bits.
190*288bf522SAndroid Build Coastguard Worker     val ^= lrand48() << 1;
191*288bf522SAndroid Build Coastguard Worker 
192*288bf522SAndroid Build Coastguard Worker     return val;
193*288bf522SAndroid Build Coastguard Worker }
194*288bf522SAndroid Build Coastguard Worker 
195*288bf522SAndroid Build Coastguard Worker /*
196*288bf522SAndroid Build Coastguard Worker  * Random Modulus
197*288bf522SAndroid Build Coastguard Worker  *
198*288bf522SAndroid Build Coastguard Worker  * Pseudo randomly returns unsigned integer in the range [0, mod).
199*288bf522SAndroid Build Coastguard Worker  *
200*288bf522SAndroid Build Coastguard Worker  * Precondition: srand48() called to set the seed of
201*288bf522SAndroid Build Coastguard Worker  *   the pseudo random number generator.
202*288bf522SAndroid Build Coastguard Worker  */
testRandMod(uint32_t mod)203*288bf522SAndroid Build Coastguard Worker uint32_t testRandMod(uint32_t mod)
204*288bf522SAndroid Build Coastguard Worker {
205*288bf522SAndroid Build Coastguard Worker     // Obtain the random value
206*288bf522SAndroid Build Coastguard Worker     // Use lrand48() when it would produce a sufficient
207*288bf522SAndroid Build Coastguard Worker     // number of random bits, otherwise use testRand().
208*288bf522SAndroid Build Coastguard Worker     const uint32_t lrand48maxVal = ((uint32_t) 1 << 31) - 1;
209*288bf522SAndroid Build Coastguard Worker     uint32_t val = (mod <= lrand48maxVal) ? (uint32_t) lrand48() : testRand();
210*288bf522SAndroid Build Coastguard Worker 
211*288bf522SAndroid Build Coastguard Worker     /*
212*288bf522SAndroid Build Coastguard Worker      * The contents of individual bytes tend to be less than random
213*288bf522SAndroid Build Coastguard Worker      * across different seeds.  For example, srand48(x) and
214*288bf522SAndroid Build Coastguard Worker      * srand48(x + n * 4) cause lrand48() to return the same sequence of
215*288bf522SAndroid Build Coastguard Worker      * least significant bits.  For small mod values this can produce
216*288bf522SAndroid Build Coastguard Worker      * noticably non-random sequnces.  For mod values of less than 2
217*288bf522SAndroid Build Coastguard Worker      * bytes, will use the randomness from all the bytes.
218*288bf522SAndroid Build Coastguard Worker      */
219*288bf522SAndroid Build Coastguard Worker     if (mod <= 0x10000) {
220*288bf522SAndroid Build Coastguard Worker         val = (val & 0xffff) ^ (val >> 16);
221*288bf522SAndroid Build Coastguard Worker 
222*288bf522SAndroid Build Coastguard Worker         // If mod less than a byte, can further combine down to
223*288bf522SAndroid Build Coastguard Worker         // a single byte.
224*288bf522SAndroid Build Coastguard Worker         if (mod <= 0x100) {
225*288bf522SAndroid Build Coastguard Worker             val = (val & 0xff) ^ (val >> 8);
226*288bf522SAndroid Build Coastguard Worker         }
227*288bf522SAndroid Build Coastguard Worker     }
228*288bf522SAndroid Build Coastguard Worker 
229*288bf522SAndroid Build Coastguard Worker     return val % mod;
230*288bf522SAndroid Build Coastguard Worker }
231*288bf522SAndroid Build Coastguard Worker 
232*288bf522SAndroid Build Coastguard Worker /*
233*288bf522SAndroid Build Coastguard Worker  * Random Boolean
234*288bf522SAndroid Build Coastguard Worker  *
235*288bf522SAndroid Build Coastguard Worker  * Pseudo randomly returns 0 (false) or 1 (true).
236*288bf522SAndroid Build Coastguard Worker  *
237*288bf522SAndroid Build Coastguard Worker  * Precondition: srand48() called to set the seed of
238*288bf522SAndroid Build Coastguard Worker  *   the pseudo random number generator.
239*288bf522SAndroid Build Coastguard Worker  */
testRandBool(void)240*288bf522SAndroid Build Coastguard Worker int testRandBool(void)
241*288bf522SAndroid Build Coastguard Worker {
242*288bf522SAndroid Build Coastguard Worker     return (testRandMod(2));
243*288bf522SAndroid Build Coastguard Worker }
244*288bf522SAndroid Build Coastguard Worker 
245*288bf522SAndroid Build Coastguard Worker /*
246*288bf522SAndroid Build Coastguard Worker  * Random Fraction
247*288bf522SAndroid Build Coastguard Worker  *
248*288bf522SAndroid Build Coastguard Worker  * Pseudo randomly return a value in the range [0.0, 1.0).
249*288bf522SAndroid Build Coastguard Worker  *
250*288bf522SAndroid Build Coastguard Worker  * Precondition: srand48() called to set the seed of
251*288bf522SAndroid Build Coastguard Worker  *   the pseudo random number generator.
252*288bf522SAndroid Build Coastguard Worker  */
testRandFract(void)253*288bf522SAndroid Build Coastguard Worker double testRandFract(void)
254*288bf522SAndroid Build Coastguard Worker {
255*288bf522SAndroid Build Coastguard Worker     return drand48();
256*288bf522SAndroid Build Coastguard Worker }
257*288bf522SAndroid Build Coastguard Worker 
258*288bf522SAndroid Build Coastguard Worker // Delays for the number of seconds specified by amt or a greater amount.
259*288bf522SAndroid Build Coastguard Worker // The amt variable is of type float and thus non-integer amounts
260*288bf522SAndroid Build Coastguard Worker // of time can be specified.  This function automatically handles cases
261*288bf522SAndroid Build Coastguard Worker // where nanosleep(2) returns early due to reception of a signal.
testDelay(float amt)262*288bf522SAndroid Build Coastguard Worker void testDelay(float amt)
263*288bf522SAndroid Build Coastguard Worker {
264*288bf522SAndroid Build Coastguard Worker     struct timespec   start, current, delta;
265*288bf522SAndroid Build Coastguard Worker     struct timespec   remaining;
266*288bf522SAndroid Build Coastguard Worker 
267*288bf522SAndroid Build Coastguard Worker     // Get the time at which we started
268*288bf522SAndroid Build Coastguard Worker     clock_gettime(CLOCK_MONOTONIC, &start);
269*288bf522SAndroid Build Coastguard Worker 
270*288bf522SAndroid Build Coastguard Worker     do {
271*288bf522SAndroid Build Coastguard Worker         // Get current time
272*288bf522SAndroid Build Coastguard Worker         clock_gettime(CLOCK_MONOTONIC, &current);
273*288bf522SAndroid Build Coastguard Worker 
274*288bf522SAndroid Build Coastguard Worker         // How much time is left
275*288bf522SAndroid Build Coastguard Worker         delta = tsDelta(&start, &current);
276*288bf522SAndroid Build Coastguard Worker         if (ts2double(&delta) > amt) { break; }
277*288bf522SAndroid Build Coastguard Worker 
278*288bf522SAndroid Build Coastguard Worker         // Request to sleep for the remaining time
279*288bf522SAndroid Build Coastguard Worker         remaining = double2ts(amt - ts2double(&delta));
280*288bf522SAndroid Build Coastguard Worker         (void) nanosleep(&remaining, NULL);
281*288bf522SAndroid Build Coastguard Worker     } while (true);
282*288bf522SAndroid Build Coastguard Worker }
283*288bf522SAndroid Build Coastguard Worker 
284*288bf522SAndroid Build Coastguard Worker // Delay spins for the number of seconds specified by amt or a greater
285*288bf522SAndroid Build Coastguard Worker // amount.  The amt variable is of type float and thus non-integer amounts
286*288bf522SAndroid Build Coastguard Worker // of time can be specified.  Differs from testDelay() in that
287*288bf522SAndroid Build Coastguard Worker // testDelaySpin() performs a spin loop, instead of using nanosleep().
testDelaySpin(float amt)288*288bf522SAndroid Build Coastguard Worker void testDelaySpin(float amt)
289*288bf522SAndroid Build Coastguard Worker {
290*288bf522SAndroid Build Coastguard Worker     struct timespec   start, current, delta;
291*288bf522SAndroid Build Coastguard Worker 
292*288bf522SAndroid Build Coastguard Worker     // Get the time at which we started
293*288bf522SAndroid Build Coastguard Worker     clock_gettime(CLOCK_MONOTONIC, &start);
294*288bf522SAndroid Build Coastguard Worker 
295*288bf522SAndroid Build Coastguard Worker     do {
296*288bf522SAndroid Build Coastguard Worker         // Get current time
297*288bf522SAndroid Build Coastguard Worker         clock_gettime(CLOCK_MONOTONIC, &current);
298*288bf522SAndroid Build Coastguard Worker 
299*288bf522SAndroid Build Coastguard Worker         // How much time is left
300*288bf522SAndroid Build Coastguard Worker         delta = tsDelta(&start, &current);
301*288bf522SAndroid Build Coastguard Worker         if (ts2double(&delta) > amt) { break; }
302*288bf522SAndroid Build Coastguard Worker     } while (true);
303*288bf522SAndroid Build Coastguard Worker }
304*288bf522SAndroid Build Coastguard Worker 
305*288bf522SAndroid Build Coastguard Worker /*
306*288bf522SAndroid Build Coastguard Worker  * Hex Dump
307*288bf522SAndroid Build Coastguard Worker  *
308*288bf522SAndroid Build Coastguard Worker  * Displays in hex the contents of the memory starting at the location
309*288bf522SAndroid Build Coastguard Worker  * pointed to by buf, for the number of bytes given by size.
310*288bf522SAndroid Build Coastguard Worker  * Each line of output is indented by a number of spaces that
311*288bf522SAndroid Build Coastguard Worker  * can be set by calling xDumpSetIndent().  It is also possible
312*288bf522SAndroid Build Coastguard Worker  * to offset the displayed address by an amount set by calling
313*288bf522SAndroid Build Coastguard Worker  * xDumpSetOffset.
314*288bf522SAndroid Build Coastguard Worker  */
315*288bf522SAndroid Build Coastguard Worker static uint8_t     xDumpIndent;
316*288bf522SAndroid Build Coastguard Worker static uint64_t    xDumpOffset;
317*288bf522SAndroid Build Coastguard Worker void
testXDump(const void * buf,size_t size)318*288bf522SAndroid Build Coastguard Worker testXDump(const void *buf, size_t size)
319*288bf522SAndroid Build Coastguard Worker {
320*288bf522SAndroid Build Coastguard Worker     const unsigned int bytesPerLine = 16;
321*288bf522SAndroid Build Coastguard Worker     int rv;
322*288bf522SAndroid Build Coastguard Worker     char line[MAXSTR];
323*288bf522SAndroid Build Coastguard Worker     const unsigned char *ptr = buf, *start = buf;
324*288bf522SAndroid Build Coastguard Worker     size_t num = size;
325*288bf522SAndroid Build Coastguard Worker     char *linep = line;
326*288bf522SAndroid Build Coastguard Worker 
327*288bf522SAndroid Build Coastguard Worker     while (num) {
328*288bf522SAndroid Build Coastguard Worker         if (((ptr - start) % bytesPerLine) == 0) {
329*288bf522SAndroid Build Coastguard Worker             if (linep != line) {
330*288bf522SAndroid Build Coastguard Worker                 testPrintE("%s", line);
331*288bf522SAndroid Build Coastguard Worker             }
332*288bf522SAndroid Build Coastguard Worker             linep = line;
333*288bf522SAndroid Build Coastguard Worker             rv = snprintf(linep, ALEN(line) - (linep - line),
334*288bf522SAndroid Build Coastguard Worker                 "%*s%06llx:", xDumpIndent, "",
335*288bf522SAndroid Build Coastguard Worker                 (long long) (ptr - start) + xDumpOffset);
336*288bf522SAndroid Build Coastguard Worker             linep += rv;
337*288bf522SAndroid Build Coastguard Worker         }
338*288bf522SAndroid Build Coastguard Worker 
339*288bf522SAndroid Build Coastguard Worker         // Check that there is at least room for 4
340*288bf522SAndroid Build Coastguard Worker         // more characters.  The 4 characters being
341*288bf522SAndroid Build Coastguard Worker         // a space, 2 hex digits and the terminating
342*288bf522SAndroid Build Coastguard Worker         // '\0'.
343*288bf522SAndroid Build Coastguard Worker         assert((ALEN(line) - 4) >= (linep - line));
344*288bf522SAndroid Build Coastguard Worker         rv = snprintf(linep, ALEN(line) - (linep - line),
345*288bf522SAndroid Build Coastguard Worker             " %02x", *ptr++);
346*288bf522SAndroid Build Coastguard Worker         linep += rv;
347*288bf522SAndroid Build Coastguard Worker         num--;
348*288bf522SAndroid Build Coastguard Worker     }
349*288bf522SAndroid Build Coastguard Worker     if (linep != line) {
350*288bf522SAndroid Build Coastguard Worker         testPrintE("%s", line);
351*288bf522SAndroid Build Coastguard Worker     }
352*288bf522SAndroid Build Coastguard Worker }
353*288bf522SAndroid Build Coastguard Worker 
354*288bf522SAndroid Build Coastguard Worker // Set an indent of spaces for each line of hex dump output
355*288bf522SAndroid Build Coastguard Worker void
testXDumpSetIndent(uint8_t indent)356*288bf522SAndroid Build Coastguard Worker testXDumpSetIndent(uint8_t indent)
357*288bf522SAndroid Build Coastguard Worker {
358*288bf522SAndroid Build Coastguard Worker     xDumpIndent = indent;
359*288bf522SAndroid Build Coastguard Worker }
360*288bf522SAndroid Build Coastguard Worker 
361*288bf522SAndroid Build Coastguard Worker // Obtain the current hex dump indent amount
362*288bf522SAndroid Build Coastguard Worker uint8_t
testXDumpGetIndent(void)363*288bf522SAndroid Build Coastguard Worker testXDumpGetIndent(void)
364*288bf522SAndroid Build Coastguard Worker {
365*288bf522SAndroid Build Coastguard Worker     return xDumpIndent;
366*288bf522SAndroid Build Coastguard Worker }
367*288bf522SAndroid Build Coastguard Worker 
368*288bf522SAndroid Build Coastguard Worker // Set the hex dump address offset amount
369*288bf522SAndroid Build Coastguard Worker void
testXDumpSetOffset(uint64_t offset)370*288bf522SAndroid Build Coastguard Worker testXDumpSetOffset(uint64_t offset)
371*288bf522SAndroid Build Coastguard Worker {
372*288bf522SAndroid Build Coastguard Worker     xDumpOffset = offset;
373*288bf522SAndroid Build Coastguard Worker }
374*288bf522SAndroid Build Coastguard Worker 
375*288bf522SAndroid Build Coastguard Worker // Get the current hex dump address offset amount
376*288bf522SAndroid Build Coastguard Worker uint64_t
testXDumpGetOffset(void)377*288bf522SAndroid Build Coastguard Worker testXDumpGetOffset(void)
378*288bf522SAndroid Build Coastguard Worker {
379*288bf522SAndroid Build Coastguard Worker     return xDumpOffset;
380*288bf522SAndroid Build Coastguard Worker }
381*288bf522SAndroid Build Coastguard Worker 
382*288bf522SAndroid Build Coastguard Worker /*
383*288bf522SAndroid Build Coastguard Worker  * Execute Command
384*288bf522SAndroid Build Coastguard Worker  *
385*288bf522SAndroid Build Coastguard Worker  * Executes the command pointed to by cmd.  Output from the
386*288bf522SAndroid Build Coastguard Worker  * executed command is captured and sent to LogCat Info.  Once
387*288bf522SAndroid Build Coastguard Worker  * the command has finished execution, it's exit status is captured
388*288bf522SAndroid Build Coastguard Worker  * and checked for an exit status of zero.  Any other exit status
389*288bf522SAndroid Build Coastguard Worker  * causes diagnostic information to be printed and an immediate
390*288bf522SAndroid Build Coastguard Worker  * testcase failure.
391*288bf522SAndroid Build Coastguard Worker  */
testExecCmd(const char * cmd)392*288bf522SAndroid Build Coastguard Worker void testExecCmd(const char *cmd)
393*288bf522SAndroid Build Coastguard Worker {
394*288bf522SAndroid Build Coastguard Worker     FILE *fp;
395*288bf522SAndroid Build Coastguard Worker     int status;
396*288bf522SAndroid Build Coastguard Worker     char str[MAXSTR];
397*288bf522SAndroid Build Coastguard Worker 
398*288bf522SAndroid Build Coastguard Worker     // Display command to be executed
399*288bf522SAndroid Build Coastguard Worker     testPrintI("cmd: %s", cmd);
400*288bf522SAndroid Build Coastguard Worker 
401*288bf522SAndroid Build Coastguard Worker     // Execute the command
402*288bf522SAndroid Build Coastguard Worker     fflush(stdout);
403*288bf522SAndroid Build Coastguard Worker     if ((fp = popen(cmd, "r")) == NULL) {
404*288bf522SAndroid Build Coastguard Worker         testPrintE("execCmd popen failed, errno: %i", errno);
405*288bf522SAndroid Build Coastguard Worker         exit(100);
406*288bf522SAndroid Build Coastguard Worker     }
407*288bf522SAndroid Build Coastguard Worker 
408*288bf522SAndroid Build Coastguard Worker     // Obtain and display each line of output from the executed command
409*288bf522SAndroid Build Coastguard Worker     while (fgets(str, sizeof(str), fp) != NULL) {
410*288bf522SAndroid Build Coastguard Worker         if ((strlen(str) > 1) && (str[strlen(str) - 1] == '\n')) {
411*288bf522SAndroid Build Coastguard Worker             str[strlen(str) - 1] = '\0';
412*288bf522SAndroid Build Coastguard Worker         }
413*288bf522SAndroid Build Coastguard Worker         testPrintI(" out: %s", str);
414*288bf522SAndroid Build Coastguard Worker     }
415*288bf522SAndroid Build Coastguard Worker 
416*288bf522SAndroid Build Coastguard Worker     // Obtain and check return status of executed command.
417*288bf522SAndroid Build Coastguard Worker     // Fail on non-zero exit status
418*288bf522SAndroid Build Coastguard Worker     status = pclose(fp);
419*288bf522SAndroid Build Coastguard Worker     if (!(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) {
420*288bf522SAndroid Build Coastguard Worker         testPrintE("Unexpected command failure");
421*288bf522SAndroid Build Coastguard Worker         testPrintE("  status: %#x", status);
422*288bf522SAndroid Build Coastguard Worker         if (WIFEXITED(status)) {
423*288bf522SAndroid Build Coastguard Worker             testPrintE("WEXITSTATUS: %i", WEXITSTATUS(status));
424*288bf522SAndroid Build Coastguard Worker         }
425*288bf522SAndroid Build Coastguard Worker         if (WIFSIGNALED(status)) {
426*288bf522SAndroid Build Coastguard Worker             testPrintE("WTERMSIG: %i", WTERMSIG(status));
427*288bf522SAndroid Build Coastguard Worker         }
428*288bf522SAndroid Build Coastguard Worker         exit(101);
429*288bf522SAndroid Build Coastguard Worker     }
430*288bf522SAndroid Build Coastguard Worker }
431