139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania/*
239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * Copyright (C) 2009 The Android Open Source Project
339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * All rights reserved.
439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *
539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * Redistribution and use in source and binary forms, with or without
639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * modification, are permitted provided that the following conditions
739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * are met:
839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *  * Redistributions of source code must retain the above copyright
939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *    notice, this list of conditions and the following disclaimer.
1039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *  * Redistributions in binary form must reproduce the above copyright
1139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *    notice, this list of conditions and the following disclaimer in
1239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *    the documentation and/or other materials provided with the
1339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *    distribution.
1439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania *
1539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
2239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * SUCH DAMAGE.
2739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania */
2839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
2939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <cstdio>
3039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <cstdlib>
3139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <ctime>
3239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <errno.h>
3339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <fcntl.h>
3439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <getopt.h>
3539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <limits.h>
3639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <string.h>
3739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <sys/stat.h>
3839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <linux/fadvise.h>
3939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <unistd.h>
40e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey#include <fts.h>
4139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
4239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include "stopwatch.h"
4339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include "sysutil.h"
4439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include "testcase.h"
4539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
4639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Stress test for the sdcard. Use this to generate some load on the
47e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey// sdcard and collect performance statistics. The output is either a
4839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// human readable report or the raw timing samples that can be
4939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// processed using another tool.
5039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
5139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Needs debugfs:
5239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//   adb root;
5339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//   adb shell mount -t debugfs none /sys/kernel/debug
5439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
5539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// The following tests are defined (value of the --test flag):
5639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//  write:       Open a file write some random data and close.
5739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//  read:        Open a file read it and close.
5839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//  read_write:  Combine readers and writers.
5939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//  open_create: Open|create an non existing file.
6039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
6139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// For each run you can control how many processes will run the test in
6239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// parallel to simulate a real load (--procnb flag)
6339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
6439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// For each process, the test selected will be executed many time to
6539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// get a meaningful average/min/max (--iterations flag)
6639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
6739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Use --dump to also get the raw data.
6839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
6939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// For read/write tests, size is the number of Kbytes to use.
7039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
7139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// To build: mmm system/extras/tests/sdcard/Android.mk SDCARD_TESTS=1
7239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
7339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Examples:
7439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// adb shell /system/bin/sdcard_perf_test --test=read --size=1000 --chunk-size=100 --procnb=1 --iterations=10 --dump > /tmp/data.txt
7539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// adb shell /system/bin/sdcard_perf_test --test=write --size=1000 --chunk-size=100 --procnb=1 --iterations=100 --dump > /tmp/data.txt
7639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
7739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// To watch the memory: cat /proc/meminfo
7839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// If the phone crashes, look at /proc/last_kmsg on reboot.
7939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
8039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// TODO: It would be cool if we could play with various fadvise()
8139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// strategies in here to see how tweaking read-ahead changes things.
8239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania//
8339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
8439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaextern char *optarg;
8539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaextern int optind, opterr, optopt;
8639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
8739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// TODO: No clue where fadvise is. Disabled for now.
8839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#define FADVISE(fd, off, len, advice) (void)0
8939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
9039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#ifndef min
9139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#define min(a,b) (((a)>(b))?(b):(a))
9239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#endif
9339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
9439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catanianamespace  {
9539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniausing android::kernelVersion;
9639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniausing android::kMinKernelVersionBufferSize;
9739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniausing android::schedFeatures;
9839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniausing android::kMinSchedFeaturesBufferSize;
9939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniausing android_test::StopWatch;
10039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniausing android::writePidAndWaitForReply;
10139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniausing android::waitForChildrenAndSignal;
10239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniausing android::waitForChildrenOrExit;
10339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniausing android_test::TestCase;
10439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
10539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kAppName = "sdcard_perf_test";
10639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst char *kTestDir = "/sdcard/perf";
10739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaconst bool kVerbose = false;
10839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
10939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Used by getopt to parse the command line.
11039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniastruct option long_options[] = {
11139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"size", required_argument, 0, 's'},
11239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"chunk-size", required_argument, 0, 'S'},
113e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    {"depth", required_argument, 0, 'D'},
11439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"iterations",  required_argument, 0, 'i'},
11539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"procnb",  required_argument, 0, 'p'},
11639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"test",  required_argument, 0, 't'},
11739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"dump",  no_argument, 0, 'd'},
11839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"cpu-scaling",  no_argument, 0, 'c'},
11939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"sync",  required_argument, 0, 'f'},
12039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"truncate", no_argument, 0, 'e'},
12139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"no-new-fair-sleepers", no_argument, 0, 'z'},
12239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"no-normalized-sleepers", no_argument, 0, 'Z'},
12339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"fadvise", required_argument, 0, 'a'},
12439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {"help", no_argument, 0, 'h'},
12539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {0, 0, 0, 0},
12639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania};
12739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
12839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid usage()
12939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
130e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    printf("sdcard_perf_test --test=write|read|read_write|open_create|traverse [options]\n\n"
13139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -t --test:        Select the test.\n"
13239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -s --size:        Size in kbytes of the data.\n"
13339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -S --chunk-size:  Size of a chunk. Default to size ie 1 chunk.\n"
13439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "                    Data will be written/read using that chunk size.\n"
135e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey           "  -D --depth:       Depth of directory tree to create for traversal.\n",
13639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -i --iterations:  Number of time a process should carry its task.\n"
13739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -p --procnb:      Number of processes to use.\n"
13839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -d --dump:        Print the raw timing on stdout.\n"
13939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -c --cpu-scaling: Enable cpu scaling.\n"
14039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -s --sync: fsync|sync Use fsync or sync in write test. Default: no sync call.\n"
14139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -e --truncate:    Truncate to size the file on creation.\n"
14239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -z --no-new-fair-sleepers: Turn them off. You need to mount debugfs.\n"
14339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -Z --no-normalized-sleepers: Turn them off. You need to mount debugfs.\n"
14439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           "  -a --fadvise:     Specify an fadvise policy (not supported).\n"
14539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania           );
14639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
14739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
14839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Print command line, pid, kernel version, OOM adj and scheduler.
14939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid printHeader(int argc, char **argv, const TestCase& testCase)
15039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
15139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    printf("# Command: ");
15239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    for (int i = 0; i < argc; ++i)
15339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
15439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        printf("%s ", argv[i]);
15539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
15639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    printf("\n");
15739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
15839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    printf("# Pid: %d\n", getpid());
15939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
16039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
16139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        char buffer[kMinKernelVersionBufferSize] = {0, };
16239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (kernelVersion(buffer, sizeof(buffer)) > 0)
16339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
16439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            printf("# Kernel: %s", buffer);
16539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
16639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
16739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
16839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // Earlier on, running this test was crashing the phone. It turned
16939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // out that it was using too much memory but its oom_adj value was
17039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // -17 which means disabled. -16 is the system_server and 0 is
17139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // typically what applications run at. The issue is that adb runs
17239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // at -17 and so is this test. We force oom_adj to 0 unless the
17339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // oom_adj option has been used.
17439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // TODO: We talked about adding an option to control oom_adj, not
17539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // sure if we still need that.
17639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int oomAdj = android::pidOutOfMemoryAdj();
17739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
17839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    printf("# Oom_adj: %d ", oomAdj);
17939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (oomAdj < 0)
18039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
18139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        android::setPidOutOfMemoryAdj(0);
18239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        printf("adjuted to %d", android::pidOutOfMemoryAdj());
18339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
18439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    printf("\n");
18539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
18639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
18739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        char buffer[kMinSchedFeaturesBufferSize] = {0, };
18839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (schedFeatures(buffer, sizeof(buffer)) > 0)
18939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
19039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            printf("# Sched features: %s", buffer);
19139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
19239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
19339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    printf("# Fadvise: %s\n", testCase.fadviseAsStr());
19439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
19539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
19639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Remove all the files under kTestDir and clear the caches.
19739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid cleanup() {
19839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    android::resetDirectory(kTestDir);
19939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    android::syncAndDropCaches();  // don't pollute runs.
20039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
20139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
20239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// @param argc, argv have a wild guess.
20339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// @param[out] testCase Structure built from the cmd line args.
20439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniavoid parseCmdLine(int argc, char **argv, TestCase *testCase)\
20539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
20639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int c;
20739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
20839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    while(true)
20939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
21039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        // getopt_long stores the option index here.
21139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        int option_index = 0;
21239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
21339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        c = getopt_long (argc, argv,
214e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey                         "hS:s:D:i:p:t:dcf:ezZa:",
21539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                         long_options,
21639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                         &option_index);
21739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        // Detect the end of the options.
21839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (c == -1) break;
21939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
22039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        switch (c)
22139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
22239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 's':
22339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setDataSize(atoi(optarg) * 1024);
22439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
22539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'S':
22639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setChunkSize(atoi(optarg) * 1024);
22739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
228e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            case 'D': // tree depth
229e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey                testCase->setTreeDepth(atoi(optarg));
230e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey                break;
23139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'i':
23239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setIter(atoi(optarg));
23339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                printf("# Iterations: %d\n", testCase->iter());
23439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
23539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'p':
23639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setNproc(atoi(optarg));
23739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                printf("# Proc nb: %d\n", testCase->nproc());
23839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
23939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 't':
24039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setTypeFromName(optarg);
24139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                printf("# Test name %s\n", testCase->name());
24239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
24339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'd':
24439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setDump();
24539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
24639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'c':
24739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                printf("# Cpu scaling is on\n");
24839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setCpuScaling();
24939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
25039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'f':
25139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                if (strcmp("sync", optarg) == 0) {
25239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                    testCase->setSync(TestCase::SYNC);
25339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                } else if (strcmp("fsync", optarg) == 0) {
25439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                    testCase->setSync(TestCase::FSYNC);
25539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                }
25639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
25739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'e':  // e for empty
25839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                printf("# Will truncate to size\n");
25939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setTruncateToSize();
26039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
26139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'z':  // no new fair sleepers
26239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setNewFairSleepers(false);
26339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
26439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'Z':  // no normalized sleepers
26539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setNormalizedSleepers(false);
26639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
26739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'a':  // fadvise
26839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                testCase->setFadvise(optarg);
26939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                break;
27039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            case 'h':
27139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                usage();
27239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                exit(0);
27339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            default:
27439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                fprintf(stderr, "Unknown option %s\n", optarg);
27539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                exit(EXIT_FAILURE);
27639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
27739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
27839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
27939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
28039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// ----------------------------------------------------------------------
28139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// READ TEST
28239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
28339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Read a file.  We use a new file each time to avoid any caching
28439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// effect that would happen if we were reading the same file each
28539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// time.
28639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// @param chunk buffer large enough where the chunk read are written.
28739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// @param idx iteration number.
28839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// @param testCase has all the timers and paramters to run the test.
28939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
29039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniabool readData(char *const chunk, const int idx, TestCase *testCase)
29139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
29239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char filename[80] = {'\0',};
29339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
29439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    sprintf(filename, "%s/file-%d-%d", kTestDir, idx, getpid());
29539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
29639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->openTimer()->start();
29739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    int fd = open(filename, O_RDONLY);
29839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->openTimer()->stop();
29939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
30039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (fd < 0)
30139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
30239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        fprintf(stderr, "Open read only failed.");
30339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return false;
30439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
30539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    FADVISE(fd, 0, 0, testCase->fadvise());
30639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
30739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    size_t left = testCase->dataSize();
30839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    pid_t *pid = (pid_t*)chunk;
30939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    while (left > 0)
31039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
31139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        char *dest = chunk;
31239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        size_t chunk_size = testCase->chunkSize();
31339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
31439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (chunk_size > left)
31539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
31639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            chunk_size = left;
31739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            left = 0;
31839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
31939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        else
32039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
32139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            left -= chunk_size;
32239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
32339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
32439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        testCase->readTimer()->start();
32539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        while (chunk_size > 0)
32639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
32739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            ssize_t s = read(fd, dest, chunk_size);
32839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (s < 0)
32939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
33039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                fprintf(stderr, "Failed to read.\n");
33139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                close(fd);
33239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                return false;
33339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
33439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            chunk_size -= s;
33539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            dest += s;
33639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
33739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        testCase->readTimer()->stop();
33839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
33939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    close(fd);
34039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (testCase->pid() != *pid)
34139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
34239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        fprintf(stderr, "Wrong pid found @ read block %x != %x\n", testCase->pid(), *pid);
34339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return false;
34439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
34539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    else
34639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
34739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return true;
34839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
34939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
35039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
35139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
35239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniabool testRead(TestCase *testCase) {
35339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // Setup the testcase by writting some dummy files.
35439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    const size_t size = testCase->dataSize();
35539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    size_t chunk_size = testCase->chunkSize();
35639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char *const chunk = new char[chunk_size];
35739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
35839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    memset(chunk, 0xaa, chunk_size);
35939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    *((pid_t *)chunk) = testCase->pid(); // write our pid at the beginning of each chunk
36039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
36139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    size_t iter = testCase->iter();
36239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
36339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // since readers are much faster we increase the number of
36439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // iteration to last longer and have concurrent read/write
36539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // thoughout the whole test.
36639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (testCase->type() == TestCase::READ_WRITE)
36739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
36839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        iter *= TestCase::kReadWriteFactor;
36939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
37039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
37139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    for (size_t i = 0; i < iter; ++i)
37239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
37339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        char filename[80] = {'\0',};
37439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
37539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        sprintf(filename, "%s/file-%d-%d", kTestDir, i, testCase->pid());
376e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        int fd = open(filename, O_RDWR | O_CREAT, S_IRWXU);
37739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
37839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        size_t left = size;
37939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        while (left > 0)
38039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
38139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (chunk_size > left)
38239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
38339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                chunk_size = left;
38439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
38539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            ssize_t written = write(fd, chunk, chunk_size);
38639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (written < 0)
38739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
38839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                fprintf(stderr, "Write failed %d %s.", errno, strerror(errno));
38939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                return false;
39039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
39139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            left -= written;
39239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
39339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        close(fd);
39439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
39539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (kVerbose) printf("Child %d all chunk written\n", testCase->pid());
39639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
39739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    android::syncAndDropCaches();
39839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->signalParentAndWait();
39939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
40039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // Start the read test.
40139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->testTimer()->start();
40239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    for (size_t i = 0; i < iter; ++i)
40339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
40439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (!readData(chunk, i, testCase))
40539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
40639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            return false;
40739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
40839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
40939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->testTimer()->stop();
41039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
41139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    delete [] chunk;
41239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return true;
41339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
41439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
41539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// ----------------------------------------------------------------------
41639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// WRITE TEST
41739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
41839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniabool writeData(const char *const chunk, const int idx, TestCase *testCase) {
41939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char filename[80] = {'\0',};
42039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
42139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    sprintf(filename, "%s/file-%d-%d", kTestDir, idx, getpid());
42239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->openTimer()->start();
423e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    int fd = open(filename, O_RDWR | O_CREAT, S_IRWXU);  // no O_TRUNC, see header comment
42439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->openTimer()->stop();
42539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
42639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (fd < 0)
42739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
42839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        fprintf(stderr, "Open write failed.");
42939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return false;
43039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
43139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    FADVISE(fd, 0, 0, testCase->fadvise());
43239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
43339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (testCase->truncateToSize())
43439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
43539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        testCase->truncateTimer()->start();
43639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        ftruncate(fd, testCase->dataSize());
43739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        testCase->truncateTimer()->stop();
43839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
43939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
44039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    size_t left = testCase->dataSize();
44139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    while (left > 0)
44239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
44339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        const char *dest = chunk;
44439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        size_t chunk_size = testCase->chunkSize();
44539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
44639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (chunk_size > left)
44739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
44839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            chunk_size = left;
44939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            left = 0;
45039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
45139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        else
45239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
45339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            left -= chunk_size;
45439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
45539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
45639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
45739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        testCase->writeTimer()->start();
45839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        while (chunk_size > 0)
45939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
46039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            ssize_t s = write(fd, dest, chunk_size);
46139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            if (s < 0)
46239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            {
46339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                fprintf(stderr, "Failed to write.\n");
46439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                close(fd);
46539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania                return false;
46639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            }
46739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            chunk_size -= s;
46839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            dest += s;
46939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
47039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        testCase->writeTimer()->stop();
47139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
47239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
47339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (TestCase::FSYNC == testCase->sync())
47439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
47539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        testCase->syncTimer()->start();
47639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        fsync(fd);
47739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        testCase->syncTimer()->stop();
47839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
47939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    else if (TestCase::SYNC == testCase->sync())
48039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
48139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        testCase->syncTimer()->start();
48239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        sync();
48339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        testCase->syncTimer()->stop();
48439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
48539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    close(fd);
48639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return true;
48739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
48839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
48939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniabool testWrite(TestCase *testCase)
49039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
49139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    const size_t size = testCase->dataSize();
49239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    size_t chunk_size = testCase->chunkSize();
49339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char *data = new char[chunk_size];
49439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
49539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    memset(data, 0xaa, chunk_size);
49639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // TODO: write the pid at the beginning like in the write
49739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    // test. Have a mode where we check the write was correct.
49839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->signalParentAndWait();
49939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
50039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->testTimer()->start();
50139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    for (size_t i = 0; i < testCase->iter(); ++i)
50239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
50339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (!writeData(data, i, testCase))
50439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
50539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            return false;
50639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
50739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
50839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->testTimer()->stop();
50939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    delete [] data;
51039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return true;
51139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
51239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
51339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
51439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// ----------------------------------------------------------------------
51539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// READ WRITE
51639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
51739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Mix of read and write test. Even PID run the write test. Odd PID
51839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// the read test. Not fool proof but work most of the time.
51939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniabool testReadWrite(TestCase *testCase)
52039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
52139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (getpid() & 0x1) {
52239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return testRead(testCase);
52339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    } else {
52439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        return testWrite(testCase);
52539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
52639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
52739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
52839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// ----------------------------------------------------------------------
52939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// OPEN CREATE TEST
53039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
53139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniabool testOpenCreate(TestCase *testCase)
53239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
53339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    char filename[80] = {'\0',};
53439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
53539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->signalParentAndWait();
53639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->testTimer()->start();
53739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
53839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    for (size_t i = 0; i < testCase->iter(); ++i)
53939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
54039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        sprintf(filename, "%s/file-%d-%d", kTestDir, i, testCase->pid());
54139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
542e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        int fd = open(filename, O_RDWR | O_CREAT, S_IRWXU);
54339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        FADVISE(fd, 0, 0, testCase->fadvise());
54439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
54539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (testCase->truncateToSize())
54639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
54739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            ftruncate(fd, testCase->dataSize());
54839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
54939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        if (fd < 0)
55039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        {
55139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            return false;
55239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        }
55339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        close(fd);
55439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
55539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase->testTimer()->stop();
55639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    return true;
55739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
55839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
559e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkeybool writeTestFile(TestCase *testCase, const char* filename) {
560e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    int fd = open(filename, O_RDWR | O_CREAT, S_IRWXU);
561e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    if (fd < 0) {
562e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        fprintf(stderr, "open() failed: %s\n", strerror(errno));
563e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        return false;
564e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    }
565e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
566e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    bool res = false;
567e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
568e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    char * const chunk = new char[testCase->chunkSize()];
569e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    memset(chunk, 0xaa, testCase->chunkSize());
570e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
571e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    size_t left = testCase->dataSize();
572e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    while (left > 0) {
573e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        char *dest = chunk;
574e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        size_t chunk_size = testCase->chunkSize();
575e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
576e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        if (chunk_size > left) {
577e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            chunk_size = left;
578e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            left = 0;
579e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        } else {
580e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            left -= chunk_size;
581e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        }
582e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
583e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        while (chunk_size > 0) {
584e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            ssize_t s = write(fd, dest, chunk_size);
585e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            if (s < 0) {
586e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey                fprintf(stderr, "write() failed: %s\n", strerror(errno));
587e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey                goto fail;
588e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            }
589e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            chunk_size -= s;
590e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            dest += s;
591e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        }
592e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    }
593e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
594e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    res = true;
595e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkeyfail:
596e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    close(fd);
597e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    delete[] chunk;
598e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    return res;
599e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey}
600e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
601e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey// ----------------------------------------------------------------------
602e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey// TRAVERSE
603e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
604e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey#define MAX_PATH 512
605e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
606e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey// Creates a directory tree that is both deep and wide, and times
607e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey// traversal using fts_open().
608e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkeybool testTraverse(TestCase *testCase) {
609e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    char path[MAX_PATH];
610e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    char filepath[MAX_PATH];
611e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    strcpy(path, kTestDir);
612e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
613e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    // Generate a deep directory hierarchy
614e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    size_t depth = testCase->treeDepth();
615e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    for (size_t i = 0; i < depth; i++) {
616e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        // Go deeper by appending onto current path
617e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        snprintf(path + strlen(path), MAX_PATH - strlen(path), "/dir%d", i);
618e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        mkdir(path, S_IRWXU);
619e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
620e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        // Create some files at this depth
621e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        strcpy(filepath, path);
622e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        int pathlen = strlen(path);
623e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        char* nameStart = filepath + pathlen;
624e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        for (size_t j = 0; j < depth; j++) {
625e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            snprintf(nameStart, MAX_PATH - pathlen, "/file%d", j);
626e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            writeTestFile(testCase, filepath);
627e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        }
628e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    }
629e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
630e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    testCase->signalParentAndWait();
631e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    testCase->testTimer()->start();
632e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
633e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    // Now traverse structure
634e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    size_t iter = testCase->iter();
635e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    for (size_t i = 0; i < iter; i++) {
636e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        testCase->traverseTimer()->start();
637e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
638e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        FTS *ftsp;
639e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        if ((ftsp = fts_open((char **) &kTestDir, FTS_LOGICAL | FTS_XDEV, NULL)) == NULL) {
640e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            fprintf(stderr, "fts_open() failed: %s\n", strerror(errno));
641e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            return false;
642e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        }
643e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
644e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        // Count discovered files
645e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        int dirs = 0, files = 0;
646e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
647e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        FTSENT *curr;
648e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        while ((curr = fts_read(ftsp)) != NULL) {
649e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            switch (curr->fts_info) {
650e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            case FTS_D:
651e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey                dirs++;
652e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey                break;
653e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            case FTS_F:
654e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey                files++;
655e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey                break;
656e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            }
657e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        }
658e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
659e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        fts_close(ftsp);
660e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
661e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        testCase->traverseTimer()->stop();
662e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
663e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        int expectedDirs = depth + 1;
664e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        if (expectedDirs != dirs) {
665e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            fprintf(stderr, "expected %d dirs, but found %d\n", expectedDirs, dirs);
666e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            return false;
667e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        }
668e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
669e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        int expectedFiles = depth * depth;
670e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        if (expectedFiles != files) {
671e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            fprintf(stderr, "expected %d files, but found %d\n", expectedFiles, files);
672e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            return false;
673e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        }
674e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    }
675e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
676e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    testCase->testTimer()->stop();
677e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey    return true;
678e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey}
679e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey
68039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}  // anonymous namespace
68139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
68239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaint main(int argc, char **argv)
68339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania{
68439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    android_test::TestCase testCase(kAppName);
68539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
68639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    cleanup();
68739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
68839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    parseCmdLine(argc, argv, &testCase);
68939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    printHeader(argc, argv, testCase);
69039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
69139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    printf("# File size %d kbytes\n", testCase.dataSize() / 1024);
69239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    printf("# Chunk size %d kbytes\n", testCase.chunkSize() / 1024);
69339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    printf("# Sync: %s\n", testCase.syncAsStr());
69439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
69539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (!testCase.cpuScaling())
69639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
69739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        android::disableCpuScaling();
69839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
69939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
70039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    switch(testCase.type()) {
70139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        case TestCase::WRITE:
70239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            testCase.mTestBody = testWrite;
70339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            break;
70439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        case TestCase::READ:
70539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            testCase.mTestBody = testRead;
70639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            break;
70739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        case TestCase::OPEN_CREATE:
70839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            testCase.mTestBody = testOpenCreate;
70939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            break;
71039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        case TestCase::READ_WRITE:
71139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            testCase.mTestBody = testReadWrite;
71239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            break;
713e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey        case TestCase::TRAVERSE:
714e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            testCase.mTestBody = testTraverse;
715e1b480b11c19f014a2a6ceddd28883275a4ba0e3Jeff Sharkey            break;
71639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        default:
71739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            fprintf(stderr, "Unknown test type %s", testCase.name());
71839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania            exit(EXIT_FAILURE);
71939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
72039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
72139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    testCase.createTimers();
72239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
72339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    bool ok;
72439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
72539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    ok = testCase.runTest();
72639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania
72739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    cleanup();
72839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    if (!ok)
72939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
73039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        printf("error %d %s", errno, strerror(errno));
73139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        exit(EXIT_FAILURE);
73239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
73339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    else
73439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    {
73539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania        exit(EXIT_SUCCESS);
73639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania    }
73739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}
738