| /* |
| * Copyright (C) 2009 The Android Open Source Project |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
| * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
| * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| */ |
| |
| |
| #ifndef SYSTEM_EXTRAS_TESTS_SDCARD_TESTCASE_H_ |
| #define SYSTEM_EXTRAS_TESTS_SDCARD_TESTCASE_H_ |
| |
| #include <stdlib.h> |
| #include "stopwatch.h" |
| #include "sysutil.h" |
| |
| namespace android_test { |
| |
| // Class to group test parameters and implementation. |
| // Takes care of forking child processes and wait for them. |
| |
| class TestCase { |
| public: |
| enum Type {UNKNOWN_TEST, WRITE, READ, OPEN_CREATE, READ_WRITE, TRAVERSE}; |
| enum Pipe {READ_FROM_CHILD = 0, WRITE_TO_PARENT, READ_FROM_PARENT, WRITE_TO_CHILD}; |
| enum Sync {NO_SYNC, FSYNC, SYNC}; |
| |
| // Reads takes less time than writes. This is a basic |
| // approximation of how much longer the read tasks must run to |
| // terminate roughly at the same time as the write tasks. |
| const static int kReadWriteFactor = 5; |
| |
| TestCase(const char *appName); |
| |
| ~TestCase(); |
| |
| size_t iter() const { return mIter; } |
| void setIter(size_t iter); |
| |
| size_t nproc() const { return mNproc; } |
| void setNproc(size_t val) { mNproc = val; } |
| |
| size_t dataSize() const { return mDataSize; } |
| void setDataSize(size_t val) { mDataSize = val; } |
| |
| size_t chunkSize() const { return mChunkSize; } |
| void setChunkSize(size_t val) { mChunkSize = val; } |
| |
| size_t treeDepth() const { return mTreeDepth; } |
| void setTreeDepth(size_t val) { mTreeDepth = val; } |
| |
| bool newFairSleepers() const { return mNewFairSleepers; } |
| void setNewFairSleepers(bool val) { |
| mNewFairSleepers = val; |
| android::setNewFairSleepers(val); |
| } |
| |
| bool normalizedSleepers() const { return mNormalizedSleepers; } |
| void setNormalizedSleepers(bool val) { |
| mNormalizedSleepers = val; |
| android::setNormalizedSleepers(val); |
| } |
| |
| Sync sync() const { return mSync; } |
| void setSync(Sync s); |
| const char *syncAsStr() const; |
| |
| bool cpuScaling() const { return mCpuScaling; } |
| void setCpuScaling() { mCpuScaling = true; } |
| |
| bool truncateToSize() const { return mTruncateToSize; } |
| void setTruncateToSize() { mTruncateToSize = true; } |
| |
| int fadvise() { return mFadvice; } |
| void setFadvise(const char *advice); |
| const char *fadviseAsStr() const; |
| |
| // Print the samples. |
| void setDump() { StopWatch::setPrintRawMode(true); } |
| |
| StopWatch *testTimer() { return mTestTimer; } |
| StopWatch *openTimer() { return mOpenTimer; } |
| StopWatch *readTimer() { return mReadTimer; } |
| StopWatch *writeTimer() { return mWriteTimer; } |
| StopWatch *syncTimer() { return mSyncTimer; } |
| StopWatch *truncateTimer() { return mTruncateTimer; } |
| StopWatch *traverseTimer() { return mTraverseTimer; } |
| |
| // Fork the children, run the test and wait for them to complete. |
| bool runTest(); |
| |
| void signalParentAndWait() { |
| if (!android::writePidAndWaitForReply(mIpc[WRITE_TO_PARENT], mIpc[READ_FROM_PARENT])) { |
| exit(1); |
| } |
| } |
| |
| void createTimers(); |
| bool setTypeFromName(const char *test_name); |
| Type type() const { return mType; } |
| pid_t pid() const { return mPid; } |
| const char *name() const { return mName; } |
| |
| // This is set to the function that will actually do the test when |
| // the command line arguments have been parsed. The function will |
| // be run in one or more child(ren) process(es). |
| bool (*mTestBody)(TestCase *); |
| private: |
| const char *mAppName; |
| size_t mDataSize; |
| size_t mChunkSize; |
| size_t mTreeDepth; |
| size_t mIter; |
| size_t mNproc; |
| pid_t mPid; |
| char mName[80]; |
| Type mType; |
| |
| bool mDump; // print the raw values instead of a human friendly report. |
| bool mCpuScaling; // true, do not turn off cpu scaling. |
| Sync mSync; |
| int mFadvice; |
| // When new files are created, truncate them to the final size. |
| bool mTruncateToSize; |
| |
| bool mNewFairSleepers; |
| bool mNormalizedSleepers; |
| |
| // IPC |
| // Parent Child(ren) |
| // --------------------------------------- |
| // 0: read from child closed |
| // 1: closed write to parent |
| // 2: closed read from parent |
| // 3: write to child closed |
| int mIpc[4]; |
| |
| StopWatch *mTestTimer; // Used to time the test overall. |
| StopWatch *mOpenTimer; // Used to time the open calls. |
| StopWatch *mReadTimer; // Used to time the read calls. |
| StopWatch *mWriteTimer; // Used to time the write calls. |
| StopWatch *mSyncTimer; // Used to time the sync/fsync calls. |
| StopWatch *mTruncateTimer; // Used to time the ftruncate calls. |
| StopWatch *mTraverseTimer; // Used to time each traversal. |
| }; |
| |
| } // namespace android_test |
| |
| #endif // SYSTEM_EXTRAS_TESTS_SDCARD_TESTCASE_H_ |