1/*
2 * Copyright (C) 2009 The Android Open Source Project
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
7 * are met:
8 *  * Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in
12 *    the documentation and/or other materials provided with the
13 *    distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29
30#ifndef SYSTEM_EXTRAS_TESTS_SDCARD_TESTCASE_H_
31#define SYSTEM_EXTRAS_TESTS_SDCARD_TESTCASE_H_
32
33#include <stdlib.h>
34#include "stopwatch.h"
35#include "sysutil.h"
36
37namespace android_test {
38
39// Class to group test parameters and implementation.
40// Takes care of forking child processes and wait for them.
41
42class TestCase {
43  public:
44    enum Type {UNKNOWN_TEST, WRITE, READ, OPEN_CREATE, READ_WRITE, TRAVERSE};
45    enum Pipe {READ_FROM_CHILD = 0, WRITE_TO_PARENT, READ_FROM_PARENT, WRITE_TO_CHILD};
46    enum Sync {NO_SYNC, FSYNC, SYNC};
47
48    // Reads takes less time than writes. This is a basic
49    // approximation of how much longer the read tasks must run to
50    // terminate roughly at the same time as the write tasks.
51    const static int kReadWriteFactor = 5;
52
53    TestCase(const char *appName);
54
55    ~TestCase();
56
57    size_t iter() const { return mIter; }
58    void setIter(size_t iter);
59
60    size_t nproc() const { return mNproc; }
61    void setNproc(size_t val) { mNproc = val; }
62
63    size_t dataSize() const { return mDataSize; }
64    void setDataSize(size_t val) { mDataSize = val; }
65
66    size_t chunkSize() const { return mChunkSize; }
67    void setChunkSize(size_t val) { mChunkSize = val; }
68
69    size_t treeDepth() const { return mTreeDepth; }
70    void setTreeDepth(size_t val) { mTreeDepth = val; }
71
72    bool newFairSleepers() const { return mNewFairSleepers; }
73    void setNewFairSleepers(bool val) {
74        mNewFairSleepers = val;
75        android::setNewFairSleepers(val);
76    }
77
78    bool normalizedSleepers() const { return mNormalizedSleepers; }
79    void setNormalizedSleepers(bool val) {
80        mNormalizedSleepers = val;
81        android::setNormalizedSleepers(val);
82    }
83
84    Sync sync() const { return mSync; }
85    void setSync(Sync s);
86    const char *syncAsStr() const;
87
88    bool cpuScaling() const { return mCpuScaling; }
89    void setCpuScaling() { mCpuScaling = true; }
90
91    bool truncateToSize() const { return mTruncateToSize; }
92    void setTruncateToSize() { mTruncateToSize = true; }
93
94    int fadvise() { return mFadvice; }
95    void setFadvise(const char *advice);
96    const char *fadviseAsStr() const;
97
98    // Print the samples.
99    void setDump() { StopWatch::setPrintRawMode(true); }
100
101    StopWatch *testTimer() { return mTestTimer; }
102    StopWatch *openTimer() { return mOpenTimer; }
103    StopWatch *readTimer() { return mReadTimer; }
104    StopWatch *writeTimer() { return mWriteTimer; }
105    StopWatch *syncTimer() { return mSyncTimer; }
106    StopWatch *truncateTimer() { return mTruncateTimer; }
107    StopWatch *traverseTimer() { return mTraverseTimer; }
108
109    // Fork the children, run the test and wait for them to complete.
110    bool runTest();
111
112    void signalParentAndWait() {
113        if (!android::writePidAndWaitForReply(mIpc[WRITE_TO_PARENT], mIpc[READ_FROM_PARENT])) {
114            exit(1);
115        }
116    }
117
118    void createTimers();
119    bool setTypeFromName(const char *test_name);
120    Type type() const { return mType; }
121    pid_t pid() const { return mPid; }
122    const char *name() const { return mName; }
123
124    // This is set to the function that will actually do the test when
125    // the command line arguments have been parsed. The function will
126    // be run in one or more child(ren) process(es).
127    bool (*mTestBody)(TestCase *);
128private:
129    const char *mAppName;
130    size_t mDataSize;
131    size_t mChunkSize;
132    size_t mTreeDepth;
133    size_t mIter;
134    size_t mNproc;
135    pid_t mPid;
136    char mName[80];
137    Type mType;
138
139    bool mDump;  // print the raw values instead of a human friendly report.
140    bool mCpuScaling;  // true, do not turn off cpu scaling.
141    Sync mSync;
142    int mFadvice;
143    // When new files are created, truncate them to the final size.
144    bool mTruncateToSize;
145
146    bool mNewFairSleepers;
147    bool mNormalizedSleepers;
148
149    // IPC
150    //        Parent               Child(ren)
151    // ---------------------------------------
152    // 0: read from child          closed
153    // 1: closed                   write to parent
154    // 2: closed                   read from parent
155    // 3: write to child           closed
156    int mIpc[4];
157
158    StopWatch *mTestTimer;  // Used to time the test overall.
159    StopWatch *mOpenTimer;  // Used to time the open calls.
160    StopWatch *mReadTimer;  // Used to time the read calls.
161    StopWatch *mWriteTimer;  // Used to time the write calls.
162    StopWatch *mSyncTimer;  // Used to time the sync/fsync calls.
163    StopWatch *mTruncateTimer;  // Used to time the ftruncate calls.
164    StopWatch *mTraverseTimer;  // Used to time each traversal.
165};
166
167}  // namespace android_test
168
169#endif  // SYSTEM_EXTRAS_TESTS_SDCARD_TESTCASE_H_
170