187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller/*
287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Copyright (C) 2010 The Android Open Source Project
387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Licensed under the Apache License, Version 2.0 (the "License");
587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * you may not use this file except in compliance with the License.
687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * You may obtain a copy of the License at
787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *      http://www.apache.org/licenses/LICENSE-2.0
987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
1087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Unless required by applicable law or agreed to in writing, software
1187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * distributed under the License is distributed on an "AS IS" BASIS,
1287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * See the License for the specific language governing permissions and
1487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * limitations under the License.
1587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
1687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller */
1787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
1887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <testUtil.h>
1987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
2087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <assert.h>
218eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller#include <errno.h>
2287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <math.h>
2387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <stdarg.h>
2487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <stdint.h>
2587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <stdio.h>
2687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <stdlib.h>
278678c6fc0a7c2f29f1843cc3d0be23cc5908fa85Elliott Hughes#include <string.h>
2887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#include <sys/time.h>
298eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller#include <sys/wait.h>
303d66aa307eed9ed622a70df0814e6c398bac40f9Mark Salyzyn#include <time.h>
318eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller
328d73846876905ab0fbbb0d15bcda472f87d3aab2Mark Salyzyn#include <log/log.h>
3387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
34d312cdbf041b2b5c47f5c18c1697ec7ed8e3414dChih-Hung Hsieh#define ALEN(a) (sizeof(a) / sizeof((a)[0]))  // Array length
3587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillertypedef unsigned int bool_t;
3687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define true (0 == 0)
3787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define false (!true)
3887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
3987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller#define MAXSTR 200
40d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
4187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemillerstatic const char *logCatTag;
42d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic const unsigned int uSecsPerSec = 1000000;
43d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstatic const unsigned int nSecsPerSec = 1000000000;
44d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
45d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller// struct timespec to double
46d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerdouble ts2double(const struct timespec *val)
47d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{
48d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    double rv;
49d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
50d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    rv = val->tv_sec;
51d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    rv += (double) val->tv_nsec / nSecsPerSec;
52d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
53d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    return rv;
54d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}
5587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
5687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// struct timeval to double
57d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerdouble tv2double(const struct timeval *val)
5887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
5987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    double rv;
6087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
6187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv = val->tv_sec;
6287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv += (double) val->tv_usec / uSecsPerSec;
6387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
6487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    return rv;
6587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
6687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
6787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// double to struct timespec
68d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstruct timespec double2ts(double amt)
6987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
7087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    struct timespec rv;
7187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
7287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv.tv_sec = floor(amt);
7387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv.tv_nsec = (amt - rv.tv_sec) * nSecsPerSec;
7487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // TODO: Handle cases where amt is negative
7587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    while ((unsigned) rv.tv_nsec >= nSecsPerSec) {
7687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        rv.tv_nsec -= nSecsPerSec;
7787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        rv.tv_sec++;
7887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
7987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
8087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    return rv;
8187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
8287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
83d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller// double to struct timeval
84d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstruct timeval double2tv(double amt)
85d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{
86d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    struct timeval rv;
87d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
88d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    rv.tv_sec = floor(amt);
89d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    rv.tv_usec = (amt - rv.tv_sec) * uSecsPerSec;
90d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    // TODO: Handle cases where amt is negative
91d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    while ((unsigned) rv.tv_usec >= uSecsPerSec) {
92d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        rv.tv_usec -= uSecsPerSec;
93d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        rv.tv_sec++;
94d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
95d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
96d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    return rv;
97d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}
98d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
99d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller// Delta (difference) between two struct timespec.
100d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller// It is expected that the time given by the structure pointed to by
101d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller// second, is later than the time pointed to by first.
102d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstruct timespec tsDelta(const struct timespec *first,
103d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                        const struct timespec *second)
104d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller{
105d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    struct timespec rv;
106d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
107d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    assert(first != NULL);
108d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    assert(second != NULL);
109d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    assert(first->tv_nsec >= 0 && first->tv_nsec < nSecsPerSec);
110d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    assert(second->tv_nsec >= 0 && second->tv_nsec < nSecsPerSec);
111d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    rv.tv_sec = second->tv_sec - first->tv_sec;
112d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    if (second->tv_nsec >= first->tv_nsec) {
113d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        rv.tv_nsec = second->tv_nsec - first->tv_nsec;
114d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    } else {
115d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        rv.tv_nsec = (second->tv_nsec + nSecsPerSec) - first->tv_nsec;
116d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        rv.tv_sec--;
117d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    }
118d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
119d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    return rv;
120d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller}
121d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller
12287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// Delta (difference) between two struct timeval.
12387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// It is expected that the time given by the structure pointed to by
12487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// second, is later than the time pointed to by first.
125d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerstruct timeval tvDelta(const struct timeval *first,
126d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller                       const struct timeval *second)
12787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
12887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    struct timeval rv;
12987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
13087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    assert(first != NULL);
13187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    assert(second != NULL);
13287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    assert(first->tv_usec >= 0 && first->tv_usec < uSecsPerSec);
13387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    assert(second->tv_usec >= 0 && second->tv_usec < uSecsPerSec);
13487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    rv.tv_sec = second->tv_sec - first->tv_sec;
13587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (second->tv_usec >= first->tv_usec) {
13687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        rv.tv_usec = second->tv_usec - first->tv_usec;
13787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    } else {
13887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        rv.tv_usec = (second->tv_usec + uSecsPerSec) - first->tv_usec;
13987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        rv.tv_sec--;
14087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
14187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
14287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    return rv;
14387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
14487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
145d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillervoid testPrint(FILE *stream, const char *fmt, ...)
14687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
14787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    char line[MAXSTR];
14887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    va_list args;
14987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
15087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    va_start(args, fmt);
15187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    vsnprintf(line, sizeof(line), fmt, args);
15287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    if (stream == stderr) {
1536ca3a62a0d193b272d668f9ad24dc26cea1d3e27Steve Block        ALOG(LOG_ERROR, logCatTag, "%s", line);
15487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    } else {
1556ca3a62a0d193b272d668f9ad24dc26cea1d3e27Steve Block        ALOG(LOG_INFO, logCatTag, "%s", line);
15687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    }
15787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    vfprintf(stream, fmt, args);
15887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    fputc('\n', stream);
15987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
16087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
16187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// Set tag used while logging to the logcat error interface
162d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillervoid testSetLogCatTag(const char *tag)
16387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
16487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    logCatTag = tag;
16587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
16687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
16787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// Obtain pointer to current log to logcat error interface tag
168d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerconst char * testGetLogCatTag(void)
16987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
17087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    return logCatTag;
17187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
17287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
17387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller/*
1748eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller * Random
1758eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller *
1768eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller * Returns a pseudo random number in the range [0:2^32-1].
1778eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller *
1788eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller * Precondition: srand48() called to set the seed of
1798eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller *   the pseudo random number generator.
1808eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller */
1818eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemilleruint32_t testRand(void)
1828eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller{
1838eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    uint32_t val;
1848eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller
1858eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // Use lrand48() to obtain 31 bits worth
1868eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // of randomness.
1878eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    val = lrand48();
1888eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller
1898eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // Make an additional lrand48() call and merge
1908eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // the randomness into the most significant bits.
1918eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    val ^= lrand48() << 1;
1928eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller
1938eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    return val;
1948eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller}
1958eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller
1968eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller/*
197a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * Random Modulus
198a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller *
199a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * Pseudo randomly returns unsigned integer in the range [0, mod).
200a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller *
201a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * Precondition: srand48() called to set the seed of
202a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller *   the pseudo random number generator.
203a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller */
2048eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemilleruint32_t testRandMod(uint32_t mod)
205a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller{
206a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    // Obtain the random value
2078eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // Use lrand48() when it would produce a sufficient
2088eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // number of random bits, otherwise use testRand().
2098eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    const uint32_t lrand48maxVal = ((uint32_t) 1 << 31) - 1;
2108eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    uint32_t val = (mod <= lrand48maxVal) ? (uint32_t) lrand48() : testRand();
211a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
212a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    /*
213a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller     * The contents of individual bytes tend to be less than random
214a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller     * across different seeds.  For example, srand48(x) and
215a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller     * srand48(x + n * 4) cause lrand48() to return the same sequence of
216a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller     * least significant bits.  For small mod values this can produce
217a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller     * noticably non-random sequnces.  For mod values of less than 2
2188eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller     * bytes, will use the randomness from all the bytes.
219a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller     */
220a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    if (mod <= 0x10000) {
221a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        val = (val & 0xffff) ^ (val >> 16);
222a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
223a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        // If mod less than a byte, can further combine down to
224a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        // a single byte.
225a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        if (mod <= 0x100) {
226a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller            val = (val & 0xff) ^ (val >> 8);
227a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        }
228a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    }
229a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
230a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    return val % mod;
231a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller}
232a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
233a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller/*
23487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Random Boolean
23587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
23687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Pseudo randomly returns 0 (false) or 1 (true).
23787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *
23887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller * Precondition: srand48() called to set the seed of
23987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller *   the pseudo random number generator.
24087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller */
241d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemillerint testRandBool(void)
24287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
243a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    return (testRandMod(2));
244a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller}
245a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
246a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller/*
247a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * Random Fraction
248a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller *
249a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * Pseudo randomly return a value in the range [0.0, 1.0).
250a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller *
251a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * Precondition: srand48() called to set the seed of
252a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller *   the pseudo random number generator.
253a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller */
254a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemillerdouble testRandFract(void)
255a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller{
256b5f6c6605b02945070a5de0987b6d50c0d3841d8Louis Huemiller    return drand48();
25787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
25887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
25987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// Delays for the number of seconds specified by amt or a greater amount.
26087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// The amt variable is of type float and thus non-integer amounts
26187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// of time can be specified.  This function automatically handles cases
26287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller// where nanosleep(2) returns early due to reception of a signal.
263a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemillervoid testDelay(float amt)
26487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller{
265d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    struct timespec   start, current, delta;
26687dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    struct timespec   remaining;
26787dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
26887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    // Get the time at which we started
269d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller    clock_gettime(CLOCK_MONOTONIC, &start);
27087dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
27187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    do {
27287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Get current time
273d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        clock_gettime(CLOCK_MONOTONIC, &current);
27487dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
27587dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // How much time is left
276d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        delta = tsDelta(&start, &current);
277d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        if (ts2double(&delta) > amt) { break; }
27887dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller
27987dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        // Request to sleep for the remaining time
280d2447fd2505466a8c30cdca247325f79ba95be34Louis Huemiller        remaining = double2ts(amt - ts2double(&delta));
28187dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller        (void) nanosleep(&remaining, NULL);
28287dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller    } while (true);
28387dd9e92610d5e7552f5cdb6ab2578035e2210f5Louis Huemiller}
284a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
285f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller// Delay spins for the number of seconds specified by amt or a greater
286f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller// amount.  The amt variable is of type float and thus non-integer amounts
287f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller// of time can be specified.  Differs from testDelay() in that
288f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller// testDelaySpin() performs a spin loop, instead of using nanosleep().
289f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemillervoid testDelaySpin(float amt)
290f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller{
291f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller    struct timespec   start, current, delta;
292f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller
293f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller    // Get the time at which we started
294f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller    clock_gettime(CLOCK_MONOTONIC, &start);
295f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller
296f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller    do {
297f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller        // Get current time
298f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller        clock_gettime(CLOCK_MONOTONIC, &current);
299f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller
300f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller        // How much time is left
301f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller        delta = tsDelta(&start, &current);
302f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller        if (ts2double(&delta) > amt) { break; }
303f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller    } while (true);
304f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller}
305f3df372c18c3baf9c0c9c93bce7622818ae6a8a1Louis Huemiller
306a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller/*
307a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * Hex Dump
308a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller *
309a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * Displays in hex the contents of the memory starting at the location
310a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * pointed to by buf, for the number of bytes given by size.
311a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * Each line of output is indented by a number of spaces that
312a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * can be set by calling xDumpSetIndent().  It is also possible
313a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * to offset the displayed address by an amount set by calling
314a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller * xDumpSetOffset.
315a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller */
316a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemillerstatic uint8_t     xDumpIndent;
317a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemillerstatic uint64_t    xDumpOffset;
318a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemillervoid
319a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis HuemillertestXDump(const void *buf, size_t size)
320a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller{
321a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    const unsigned int bytesPerLine = 16;
322a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    int rv;
323a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    char line[MAXSTR];
324a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    const unsigned char *ptr = buf, *start = buf;
325a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    size_t num = size;
326a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    char *linep = line;
327a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
328a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    while (num) {
329a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        if (((ptr - start) % bytesPerLine) == 0) {
330a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller            if (linep != line) {
331a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller                testPrintE("%s", line);
332a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller            }
333a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller            linep = line;
334a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller            rv = snprintf(linep, ALEN(line) - (linep - line),
335a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller                "%*s%06llx:", xDumpIndent, "",
336a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller                (long long) (ptr - start) + xDumpOffset);
337a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller            linep += rv;
338a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        }
339a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
340a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        // Check that there is at least room for 4
341a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        // more characters.  The 4 characters being
342a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        // a space, 2 hex digits and the terminating
343a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        // '\0'.
344a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        assert((ALEN(line) - 4) >= (linep - line));
345a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        rv = snprintf(linep, ALEN(line) - (linep - line),
346a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller            " %02x", *ptr++);
347a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        linep += rv;
348a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        num--;
349a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    }
350a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    if (linep != line) {
351a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller        testPrintE("%s", line);
352a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    }
353a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller}
354a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
355a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller// Set an indent of spaces for each line of hex dump output
356a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemillervoid
357a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis HuemillertestXDumpSetIndent(uint8_t indent)
358a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller{
359a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    xDumpIndent = indent;
360a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller}
361a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
362a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller// Obtain the current hex dump indent amount
363a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemilleruint8_t
364a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis HuemillertestXDumpGetIndent(void)
365a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller{
366a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    return xDumpIndent;
367a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller}
368a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
369a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller// Set the hex dump address offset amount
370a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemillervoid
371a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis HuemillertestXDumpSetOffset(uint64_t offset)
372a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller{
373a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    xDumpOffset = offset;
374a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller}
375a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller
376a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller// Get the current hex dump address offset amount
377a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemilleruint64_t
378a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis HuemillertestXDumpGetOffset(void)
379a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller{
380a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller    return xDumpOffset;
381a31faf1b7edb5c20d3a8949ba3ca767b4f0a4a7dLouis Huemiller}
3828eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller
3838eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller/*
3848eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller * Execute Command
3858eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller *
3868eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller * Executes the command pointed to by cmd.  Output from the
3878eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller * executed command is captured and sent to LogCat Info.  Once
3888eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller * the command has finished execution, it's exit status is captured
3898eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller * and checked for an exit status of zero.  Any other exit status
3908eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller * causes diagnostic information to be printed and an immediate
3918eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller * testcase failure.
3928eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller */
3938eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemillervoid testExecCmd(const char *cmd)
3948eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller{
3958eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    FILE *fp;
3968eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    int rv;
3978eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    int status;
3988eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    char str[MAXSTR];
3998eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller
4008eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // Display command to be executed
4018eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    testPrintI("cmd: %s", cmd);
4028eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller
4038eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // Execute the command
4048eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    fflush(stdout);
4058eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    if ((fp = popen(cmd, "r")) == NULL) {
4068eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        testPrintE("execCmd popen failed, errno: %i", errno);
4078eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        exit(100);
4088eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    }
4098eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller
4108eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // Obtain and display each line of output from the executed command
4118eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    while (fgets(str, sizeof(str), fp) != NULL) {
4128eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        if ((strlen(str) > 1) && (str[strlen(str) - 1] == '\n')) {
4138eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller            str[strlen(str) - 1] = '\0';
4148eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        }
4158eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        testPrintI(" out: %s", str);
4168eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    }
4178eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller
4188eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // Obtain and check return status of executed command.
4198eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    // Fail on non-zero exit status
4208eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    status = pclose(fp);
4218eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    if (!(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) {
4228eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        testPrintE("Unexpected command failure");
4238eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        testPrintE("  status: %#x", status);
4248eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        if (WIFEXITED(status)) {
4258eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller            testPrintE("WEXITSTATUS: %i", WEXITSTATUS(status));
4268eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        }
4278eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        if (WIFSIGNALED(status)) {
4288eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller            testPrintE("WTERMSIG: %i", WTERMSIG(status));
4298eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        }
4308eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller        exit(101);
4318eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller    }
4328eea4fcdf2a829e01e8114a9572573cae98f2a6eLouis Huemiller}
433