/* * 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_