summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2018-05-10 14:02:45 -0700
committerandroid-build-merger <android-build-merger@google.com>2018-05-10 14:02:45 -0700
commit9cff3fe4adc2ac3ff782453bf4c567f750a4c209 (patch)
tree2d404a496dc5e432358e036840af676239433d69 /tests
parented1e7d48f4fafe107f40df78100e29bcd1e3f75b (diff)
parent02c5bd86da69527c24be7e87106ef70f193280c6 (diff)
downloadextras-9cff3fe4adc2ac3ff782453bf4c567f750a4c209.tar.gz
Merge "Remove sdcard_perf_test" am: 68d1cc59e9
am: 02c5bd86da Change-Id: I4d049be663ae2d66fcb76244e45b0d904afa6ffb
Diffstat (limited to 'tests')
-rw-r--r--tests/sdcard/Android.mk37
-rw-r--r--tests/sdcard/README63
-rwxr-xr-xtests/sdcard/plot_sdcard.py334
-rwxr-xr-xtests/sdcard/profile_sdcard.sh64
-rw-r--r--tests/sdcard/sdcard_perf_test.cpp737
-rw-r--r--tests/sdcard/stopwatch.cpp236
-rw-r--r--tests/sdcard/stopwatch.h156
-rw-r--r--tests/sdcard/sysutil.cpp604
-rw-r--r--tests/sdcard/sysutil.h146
-rw-r--r--tests/sdcard/testcase.cpp232
-rw-r--r--tests/sdcard/testcase.h169
11 files changed, 0 insertions, 2778 deletions
diff --git a/tests/sdcard/Android.mk b/tests/sdcard/Android.mk
deleted file mode 100644
index d1e06f25..00000000
--- a/tests/sdcard/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Build control file for Bionic's test programs
-# define the BIONIC_TESTS environment variable to build the test programs
-#
-
-ifdef SDCARD_TESTS
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES = \
- stopwatch.cpp \
- sysutil.cpp \
- sdcard_perf_test.cpp \
- testcase.cpp
-
-LOCAL_MODULE := sdcard_perf_test
-LOCAL_MODULE_TAGS := eng tests
-LOCAL_SHARED_LIBRARIES := libutils libhardware_legacy
-
-include $(BUILD_EXECUTABLE)
-
-endif # SDCARD_TESTS
diff --git a/tests/sdcard/README b/tests/sdcard/README
deleted file mode 100644
index 210bb43f..00000000
--- a/tests/sdcard/README
+++ /dev/null
@@ -1,63 +0,0 @@
-This directory contains tools to profile the sdcard performance.
-
-There are 2 parts to the tool:
-* A binary that runs on the device, exercises the sdcard and send
- measurment data back to the host (sdcard_perf_test).
-* A host python script to plot the data.
-
-Additionally, there is script 'profile_sdcard.sh' that allows you
-to check how the sdcard scale with the number of processes.
-
-INSTALLATION
-============
-Build, install and mount debugfs. In this directory with a properly
-configured enviroment:
-
- mm SDCARD_TESTS=1
- adb remount
- adb push $ANDROID_PRODUCT_OUT/system/bin/sdcard_perf_test /system/bin/sdcard_perf_test
- adb shell mount -t debugfs none /sys/kernel/debug
-
-If you want to graph the results you need gnuplot and numpy:
-
- sudo apt-get install gnuplot python-numpy python-numeric
-
-You need Gnuplot.py version 1.8 (not the one coming with ubuntu).
-Download it from the Gnuplot.py web site. Extract to a temp
-directory, chdir and run:
-
- sudo python setup.py install
-
-
-INVOCATION
-==========
-
-Run a simple test:
-
- adb shell sdcard_perf_test --test=write --size=1000 --chunk-size=100 --procnb=1 --iterations=100
-
-This test will write 1000kbyte (1M) files using writes of 100kbytes (so 10 writes per file) using
-only 1 process for 100 times (100 files will be written on the sdcard).
-The test will not call sync to flush the writes.
-At the end of the test, some stats for the 'open' and 'write' system calls are written.
-
-If you want to plot the data, you need to use the --dump option and provide a file:
-
- adb shell sdcard_perf_test --test=write --size=1000 --chunk-size=100 --procnb=1 --iterations=100 --dump >/tmp/data.txt
-
-PLOTTING
-========
-
-To plot the result using the iter number of the x axis:
-
- plot_sdcard.py -i /tmp/data.txt
-
-To plot the result using time for the x axis:
-
- plot_sdcard.py -t /tmp/data.txt
-
-To plot the result from the profiler:
-
- profile_sdcard.sh
- plot_sdcard.py -p
-
diff --git a/tests/sdcard/plot_sdcard.py b/tests/sdcard/plot_sdcard.py
deleted file mode 100755
index 0959465c..00000000
--- a/tests/sdcard/plot_sdcard.py
+++ /dev/null
@@ -1,334 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2009, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-"""plot_sdcard: A module to plot the results of an sdcard perf test.
-
-Requires Gnuplot python v 1.8
-
-Typical usage:
- -t x axis is time
- -i x axis is iteration
- -p profile data generated by profile_sdcard.sh
-
-./plot_sdcard.py -t /tmp/data.txt
-./plot_sdcard.py -i /tmp/data.txt
-./plot_sdcard.py -p
-
-python interpreter
->>> import plot_sdcard as p
->>> (metadata, data) = p.Parse('/tmp/data.txt')
->>> p.PlotIterations(metadata, data)
->>> p.PlotTimes(metadata, data)
-
-"""
-
-import getopt
-from itertools import izip
-import re
-import sys
-import Gnuplot
-import numpy
-
-
-class DataSet(object):
- """Dataset holds the summary and data (time,value pairs)."""
-
- def __init__(self, line):
- res = re.search(('# StopWatch ([\w]+) total/cumulative '
- 'duration ([0-9.]+). Samples: ([0-9]+)'), line)
- self.time = []
- self.data = []
- self.name = res.group(1)
- self.duration = float(res.group(2))
- self.iteration = int(res.group(3))
- self.summary = re.match('([a-z_]+)_total', self.name)
-
- def __repr__(self):
- return str(zip(self.time, self.data))
-
- def Add(self, time, value):
- self.time.append(time)
- self.data.append(value)
-
- def RescaleTo(self, length):
- factor = len(self.data) / length
-
- if factor > 1:
- new_time = []
- new_data = []
- accum = 0.0
- idx = 1
- for t, d in izip(self.time, self.data):
- accum += d
- if idx % factor == 0:
- new_time.append(t)
- new_data.append(accum / factor)
- accum = 0
- idx += 1
- self.time = new_time
- self.data = new_data
-
-
-class Metadata(object):
- def __init__(self):
- self.kernel = ''
- self.command_line = ''
- self.sched = ''
- self.name = ''
- self.fadvise = ''
- self.iterations = 0
- self.duration = 0.0
- self.complete = False
-
- def Parse(self, line):
- if line.startswith('# Kernel:'):
- self.kernel = re.search('Linux version ([0-9.]+-[^ ]+)', line).group(1)
- elif line.startswith('# Command:'):
- self.command_line = re.search('# Command: [/\w_]+ (.*)', line).group(1)
- self.command_line = self.command_line.replace(' --', '-')
- self.command_line = self.command_line.replace(' -d', '')
- self.command_line = self.command_line.replace('--test=', '')
- elif line.startswith('# Iterations'):
- self.iterations = int(re.search('# Iterations: ([0-9]+)', line).group(1))
- elif line.startswith('# Fadvise'):
- self.fadvise = re.search('# Fadvise: ([\w]+)', line).group(1)
- elif line.startswith('# Sched'):
- self.sched = re.search('# Sched features: ([\w]+)', line).group(1)
- self.complete = True
-
- def AsTitle(self):
- return '%s-duration:%f\\n-%s\\n%s' % (
- self.kernel, self.duration, self.command_line, self.sched)
-
- def UpdateWith(self, dataset):
- self.duration = max(self.duration, dataset.duration)
- self.name = dataset.name
-
-
-def Parse(filename):
- """Parse a file with the collected data.
-
- The data must be in 2 rows (x,y).
-
- Args:
- filename: Full path to the file.
- """
-
- f = open(filename, 'r')
-
- metadata = Metadata()
- data = [] # array of dataset
- dataset = None
-
- for num, line in enumerate(f):
- try:
- line = line.strip()
- if not line: continue
-
- if not metadata.complete:
- metadata.Parse(line)
- continue
-
- if re.match('[a-z_]', line):
- continue
-
- if line.startswith('# StopWatch'): # Start of a new dataset
- if dataset:
- if dataset.summary:
- metadata.UpdateWith(dataset)
- else:
- data.append(dataset)
-
- dataset = DataSet(line)
- continue
-
- if line.startswith('#'):
- continue
-
- # must be data at this stage
- try:
- (time, value) = line.split(None, 1)
- except ValueError:
- print 'skipping line %d: %s' % (num, line)
- continue
-
- if dataset and not dataset.summary:
- dataset.Add(float(time), float(value))
-
- except Exception:
- print 'Error parsing line %d' % num, sys.exc_info()[0]
- raise
- data.append(dataset)
- if not metadata.complete:
- print """Error missing metadata. Did you mount debugfs?
- [adb shell mount -t debugfs none /sys/kernel/debug]"""
- sys.exit(1)
- return (metadata, data)
-
-
-def PlotIterations(metadata, data):
- """Plot the duration of the ops against iteration.
-
- If you are plotting data with widely different runtimes you probably want to
- use PlotTimes instead.
-
- For instance when readers and writers are in the same mix, the
- readers will go thru 100 iterations much faster than the
- writers. The load test tries to be smart about that but the final
- iterations of the writers will likely be done w/o any influence from
- the readers.
-
- Args:
- metadata: For the graph's title.
- data: pair of to be plotted.
- """
-
- gp = Gnuplot.Gnuplot(persist=1)
- gp('set data style lines')
- gp.clear()
- gp.xlabel('iterations')
- gp.ylabel('duration in second')
- gp.title(metadata.AsTitle())
- styles = {}
- line_style = 1
-
- for dataset in data:
- dataset.RescaleTo(metadata.iterations)
- x = numpy.arange(len(dataset.data), dtype='int_')
- if not dataset.name in styles:
- styles[dataset.name] = line_style
- line_style += 1
- d = Gnuplot.Data(x, dataset.data,
- title=dataset.name,
- with_='lines ls %d' % styles[dataset.name])
- else: # no need to repeat a title that exists already.
- d = Gnuplot.Data(x, dataset.data,
- with_='lines ls %d' % styles[dataset.name])
-
- gp.replot(d)
- gp.hardcopy('/tmp/%s-%s-%f.png' %
- (metadata.name, metadata.kernel, metadata.duration),
- terminal='png')
-
-
-def PlotTimes(metadata, data):
- """Plot the duration of the ops against time elapsed.
-
- Args:
- metadata: For the graph's title.
- data: pair of to be plotted.
- """
-
- gp = Gnuplot.Gnuplot(persist=1)
- gp('set data style impulses')
- gp('set xtics 1')
- gp.clear()
- gp.xlabel('seconds')
- gp.ylabel('duration in second')
- gp.title(metadata.AsTitle())
- styles = {}
- line_style = 1
-
- for dataset in data:
- x = numpy.array(dataset.time, dtype='float_')
- if not dataset.name in styles:
- styles[dataset.name] = line_style
- line_style += 1
- d = Gnuplot.Data(x, dataset.data,
- title=dataset.name,
- with_='impulses ls %d' % styles[dataset.name])
- else: # no need to repeat a title that exists already.
- d = Gnuplot.Data(x, dataset.data,
- with_='impulses ls %d' % styles[dataset.name])
-
- gp.replot(d)
- gp.hardcopy('/tmp/%s-%s-%f.png' %
- (metadata.name, metadata.kernel, metadata.duration),
- terminal='png')
-
-
-def PlotProfile():
- """Plot the time of a run against the number of processes."""
- (metadata, data) = Parse('/tmp/sdcard-scalability.txt')
- gp = Gnuplot.Gnuplot(persist=1)
- gp('set data style impulses')
- gp('set xtics 1')
- gp('set pointsize 2')
- gp.clear()
- gp.xlabel('writer process')
- gp.ylabel('duration in second')
- gp.title(metadata.AsTitle())
-
- dataset = data[0]
- x = numpy.array(dataset.time, dtype='int_')
- d = Gnuplot.Data(x, dataset.data,
- title=dataset.name,
- with_='linespoints')
- gp.replot(d)
- gp.hardcopy('/tmp/%s-%s-%f.png' %
- (metadata.name, metadata.kernel, metadata.duration),
- terminal='png')
-
-
-def Usage():
- """Print this module's usage."""
- print """
- To plot the result using the iter number of the x axis:
-
- plot_sdcard.py -i /tmp/data.txt
-
- To plot the result using time for the x axis:
-
- plot_sdcard.py -t /tmp/data.txt
-
- To plot the result from the profiler:
-
- profile_sdcard.sh
- plot_sdcard.py -p
-
- """
- sys.exit(2)
-
-
-def main(argv):
- try:
- (optlist, args) = getopt.getopt(argv[1:],
- 'itp', ['iteration', 'time', 'profile'])
- except getopt.GetoptError, err:
- print str(err)
- Usage()
-
- for flag, val in optlist:
- if flag in ('-i', '--iteration'):
- (metadata, data) = Parse(args[0])
- PlotIterations(metadata, data)
- sys.exit(0)
- elif flag in ('-t', '--time'):
- (metadata, data) = Parse(args[0])
- PlotTimes(metadata, data)
- sys.exit(0)
- elif flag in ('-p', '--profile'):
- PlotProfile()
- sys.exit(0)
- Usage()
-
-
-if __name__ == '__main__':
- if Gnuplot.__version__ != "1.8":
- print "Gnuplot should be 1.8. See REAME file"
- sys.exit(2)
- main(sys.argv)
diff --git a/tests/sdcard/profile_sdcard.sh b/tests/sdcard/profile_sdcard.sh
deleted file mode 100755
index 4629c910..00000000
--- a/tests/sdcard/profile_sdcard.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/bash
-# Copyright 2009, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Run a bunch of test on the sdcard to establish a performance profile.
-
-print_kernel() {
- adb shell cat /proc/version
-}
-print_sched_features() {
- adb shell cat /sys/kernel/debug/sched_features
-}
-
-# Use dd to get the raw speed of the card
-block_level() {
- true
-}
-
-# Time to run a test vs number of processes
-scalability() {
- local file="/tmp/sdcard-scalability.txt"
- rm -f ${file}
- echo "# Scalability tests" | tee -a ${file}
- echo "# Kernel: $(print_kernel)" | tee -a ${file}
- echo "# Sched features: $(print_sched_features)" | tee -a ${file}
- echo "# StopWatch scalability total/cumulative duration 0.0 Samples: 1" | tee -a ${file}
- echo "# Process Time" | tee -a ${file}
- for p in $(seq 1 8); do
- adb shell sdcard_perf_test --test=write --procnb=${p} --size=1000 --chunk-size=100 --iterations=50 >/tmp/tmp-sdcard.txt
- local t=$(grep 'write_total' /tmp/tmp-sdcard.txt | tail -n 1 | cut -f 6 -d ' ')
- echo "$p $t" | tee -a ${file}
- done
-
-}
-
-# Readers and writers should not starve each others.
-fairness() {
- # Check readers finished before writers.
- # Find the time of the last read op.
- # Count how many writes and how many read happend
- # during that period, do the ratio.
- true
-}
-
-#######################################################################
-# MAIN
-
-echo "Make sure debugfs is mounted on the device."
-block_level
-scalability
-fairness
-
-
diff --git a/tests/sdcard/sdcard_perf_test.cpp b/tests/sdcard/sdcard_perf_test.cpp
deleted file mode 100644
index 7efa6508..00000000
--- a/tests/sdcard/sdcard_perf_test.cpp
+++ /dev/null
@@ -1,737 +0,0 @@
-/*
- * 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.
- */
-
-#include <cstdio>
-#include <cstdlib>
-#include <ctime>
-#include <errno.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <limits.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <linux/fadvise.h>
-#include <unistd.h>
-#include <fts.h>
-
-#include "stopwatch.h"
-#include "sysutil.h"
-#include "testcase.h"
-
-// Stress test for the sdcard. Use this to generate some load on the
-// sdcard and collect performance statistics. The output is either a
-// human readable report or the raw timing samples that can be
-// processed using another tool.
-//
-// Needs debugfs:
-// adb root;
-// adb shell mount -t debugfs none /sys/kernel/debug
-//
-// The following tests are defined (value of the --test flag):
-// write: Open a file write some random data and close.
-// read: Open a file read it and close.
-// read_write: Combine readers and writers.
-// open_create: Open|create an non existing file.
-//
-// For each run you can control how many processes will run the test in
-// parallel to simulate a real load (--procnb flag)
-//
-// For each process, the test selected will be executed many time to
-// get a meaningful average/min/max (--iterations flag)
-//
-// Use --dump to also get the raw data.
-//
-// For read/write tests, size is the number of Kbytes to use.
-//
-// To build: mmm system/extras/tests/sdcard/Android.mk SDCARD_TESTS=1
-//
-// Examples:
-// adb shell /system/bin/sdcard_perf_test --test=read --size=1000 --chunk-size=100 --procnb=1 --iterations=10 --dump > /tmp/data.txt
-// adb shell /system/bin/sdcard_perf_test --test=write --size=1000 --chunk-size=100 --procnb=1 --iterations=100 --dump > /tmp/data.txt
-//
-// To watch the memory: cat /proc/meminfo
-// If the phone crashes, look at /proc/last_kmsg on reboot.
-//
-// TODO: It would be cool if we could play with various fadvise()
-// strategies in here to see how tweaking read-ahead changes things.
-//
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-
-// TODO: No clue where fadvise is. Disabled for now.
-#define FADVISE(fd, off, len, advice) (void)0
-
-#ifndef min
-#define min(a,b) (((a)>(b))?(b):(a))
-#endif
-
-namespace {
-using android::kernelVersion;
-using android::kMinKernelVersionBufferSize;
-using android::schedFeatures;
-using android::kMinSchedFeaturesBufferSize;
-using android_test::StopWatch;
-using android::writePidAndWaitForReply;
-using android::waitForChildrenAndSignal;
-using android::waitForChildrenOrExit;
-using android_test::TestCase;
-
-const char *kAppName = "sdcard_perf_test";
-const char *kTestDir = "/sdcard/perf";
-const bool kVerbose = false;
-
-// Used by getopt to parse the command line.
-struct option long_options[] = {
- {"size", required_argument, 0, 's'},
- {"chunk-size", required_argument, 0, 'S'},
- {"depth", required_argument, 0, 'D'},
- {"iterations", required_argument, 0, 'i'},
- {"procnb", required_argument, 0, 'p'},
- {"test", required_argument, 0, 't'},
- {"dump", no_argument, 0, 'd'},
- {"cpu-scaling", no_argument, 0, 'c'},
- {"sync", required_argument, 0, 'f'},
- {"truncate", no_argument, 0, 'e'},
- {"no-new-fair-sleepers", no_argument, 0, 'z'},
- {"no-normalized-sleepers", no_argument, 0, 'Z'},
- {"fadvise", required_argument, 0, 'a'},
- {"help", no_argument, 0, 'h'},
- {0, 0, 0, 0},
-};
-
-void usage()
-{
- printf("sdcard_perf_test --test=write|read|read_write|open_create|traverse [options]\n\n"
- " -t --test: Select the test.\n"
- " -s --size: Size in kbytes of the data.\n"
- " -S --chunk-size: Size of a chunk. Default to size ie 1 chunk.\n"
- " Data will be written/read using that chunk size.\n"
- " -D --depth: Depth of directory tree to create for traversal.\n"
- " -i --iterations: Number of time a process should carry its task.\n"
- " -p --procnb: Number of processes to use.\n"
- " -d --dump: Print the raw timing on stdout.\n"
- " -c --cpu-scaling: Enable cpu scaling.\n"
- " -s --sync: fsync|sync Use fsync or sync in write test. Default: no sync call.\n"
- " -e --truncate: Truncate to size the file on creation.\n"
- " -z --no-new-fair-sleepers: Turn them off. You need to mount debugfs.\n"
- " -Z --no-normalized-sleepers: Turn them off. You need to mount debugfs.\n"
- " -a --fadvise: Specify an fadvise policy (not supported).\n"
- );
-}
-
-// Print command line, pid, kernel version, OOM adj and scheduler.
-void printHeader(int argc, char **argv, const TestCase& testCase)
-{
- printf("# Command: ");
- for (int i = 0; i < argc; ++i)
- {
- printf("%s ", argv[i]);
- }
- printf("\n");
-
- printf("# Pid: %d\n", getpid());
-
- {
- char buffer[kMinKernelVersionBufferSize] = {0, };
- if (kernelVersion(buffer, sizeof(buffer)) > 0)
- {
- printf("# Kernel: %s", buffer);
- }
- }
-
- // Earlier on, running this test was crashing the phone. It turned
- // out that it was using too much memory but its oom_adj value was
- // -17 which means disabled. -16 is the system_server and 0 is
- // typically what applications run at. The issue is that adb runs
- // at -17 and so is this test. We force oom_adj to 0 unless the
- // oom_adj option has been used.
- // TODO: We talked about adding an option to control oom_adj, not
- // sure if we still need that.
- int oomAdj = android::pidOutOfMemoryAdj();
-
- printf("# Oom_adj: %d ", oomAdj);
- if (oomAdj < 0)
- {
- android::setPidOutOfMemoryAdj(0);
- printf("adjuted to %d", android::pidOutOfMemoryAdj());
- }
- printf("\n");
-
- {
- char buffer[kMinSchedFeaturesBufferSize] = {0, };
- if (schedFeatures(buffer, sizeof(buffer)) > 0)
- {
- printf("# Sched features: %s", buffer);
- }
- }
- printf("# Fadvise: %s\n", testCase.fadviseAsStr());
-}
-
-// Remove all the files under kTestDir and clear the caches.
-void cleanup() {
- android::resetDirectory(kTestDir);
- android::syncAndDropCaches(); // don't pollute runs.
-}
-
-// @param argc, argv have a wild guess.
-// @param[out] testCase Structure built from the cmd line args.
-void parseCmdLine(int argc, char **argv, TestCase *testCase)\
-{
- int c;
-
- while(true)
- {
- // getopt_long stores the option index here.
- int option_index = 0;
-
- c = getopt_long (argc, argv,
- "hS:s:D:i:p:t:dcf:ezZa:",
- long_options,
- &option_index);
- // Detect the end of the options.
- if (c == -1) break;
-
- switch (c)
- {
- case 's':
- testCase->setDataSize(atoi(optarg) * 1024);
- break;
- case 'S':
- testCase->setChunkSize(atoi(optarg) * 1024);
- break;
- case 'D': // tree depth
- testCase->setTreeDepth(atoi(optarg));
- break;
- case 'i':
- testCase->setIter(atoi(optarg));
- printf("# Iterations: %d\n", testCase->iter());
- break;
- case 'p':
- testCase->setNproc(atoi(optarg));
- printf("# Proc nb: %d\n", testCase->nproc());
- break;
- case 't':
- testCase->setTypeFromName(optarg);
- printf("# Test name %s\n", testCase->name());
- break;
- case 'd':
- testCase->setDump();
- break;
- case 'c':
- printf("# Cpu scaling is on\n");
- testCase->setCpuScaling();
- break;
- case 'f':
- if (strcmp("sync", optarg) == 0) {
- testCase->setSync(TestCase::SYNC);
- } else if (strcmp("fsync", optarg) == 0) {
- testCase->setSync(TestCase::FSYNC);
- }
- break;
- case 'e': // e for empty
- printf("# Will truncate to size\n");
- testCase->setTruncateToSize();
- break;
- case 'z': // no new fair sleepers
- testCase->setNewFairSleepers(false);
- break;
- case 'Z': // no normalized sleepers
- testCase->setNormalizedSleepers(false);
- break;
- case 'a': // fadvise
- testCase->setFadvise(optarg);
- break;
- case 'h':
- usage();
- exit(0);
- default:
- fprintf(stderr, "Unknown option %s\n", optarg);
- exit(EXIT_FAILURE);
- }
- }
-}
-
-// ----------------------------------------------------------------------
-// READ TEST
-
-// Read a file. We use a new file each time to avoid any caching
-// effect that would happen if we were reading the same file each
-// time.
-// @param chunk buffer large enough where the chunk read are written.
-// @param idx iteration number.
-// @param testCase has all the timers and paramters to run the test.
-
-bool readData(char *const chunk, const int idx, TestCase *testCase)
-{
- char filename[80] = {'\0',};
-
- sprintf(filename, "%s/file-%d-%d", kTestDir, idx, getpid());
-
- testCase->openTimer()->start();
- int fd = open(filename, O_RDONLY);
- testCase->openTimer()->stop();
-
- if (fd < 0)
- {
- fprintf(stderr, "Open read only failed.");
- return false;
- }
- FADVISE(fd, 0, 0, testCase->fadvise());
-
- size_t left = testCase->dataSize();
- pid_t *pid = (pid_t*)chunk;
- while (left > 0)
- {
- char *dest = chunk;
- size_t chunk_size = testCase->chunkSize();
-
- if (chunk_size > left)
- {
- chunk_size = left;
- left = 0;
- }
- else
- {
- left -= chunk_size;
- }
-
- testCase->readTimer()->start();
- while (chunk_size > 0)
- {
- ssize_t s = read(fd, dest, chunk_size);
- if (s < 0)
- {
- fprintf(stderr, "Failed to read.\n");
- close(fd);
- return false;
- }
- chunk_size -= s;
- dest += s;
- }
- testCase->readTimer()->stop();
- }
- close(fd);
- if (testCase->pid() != *pid)
- {
- fprintf(stderr, "Wrong pid found @ read block %x != %x\n", testCase->pid(), *pid);
- return false;
- }
- else
- {
- return true;
- }
-}
-
-
-bool testRead(TestCase *testCase) {
- // Setup the testcase by writting some dummy files.
- const size_t size = testCase->dataSize();
- size_t chunk_size = testCase->chunkSize();
- char *const chunk = new char[chunk_size];
-
- memset(chunk, 0xaa, chunk_size);
- *((pid_t *)chunk) = testCase->pid(); // write our pid at the beginning of each chunk
-
- size_t iter = testCase->iter();
-
- // since readers are much faster we increase the number of
- // iteration to last longer and have concurrent read/write
- // thoughout the whole test.
- if (testCase->type() == TestCase::READ_WRITE)
- {
- iter *= TestCase::kReadWriteFactor;
- }
-
- for (size_t i = 0; i < iter; ++i)
- {
- char filename[80] = {'\0',};
-
- sprintf(filename, "%s/file-%d-%d", kTestDir, i, testCase->pid());
- int fd = open(filename, O_RDWR | O_CREAT, S_IRWXU);
-
- size_t left = size;
- while (left > 0)
- {
- if (chunk_size > left)
- {
- chunk_size = left;
- }
- ssize_t written = write(fd, chunk, chunk_size);
- if (written < 0)
- {
- fprintf(stderr, "Write failed %d %s.", errno, strerror(errno));
- return false;
- }
- left -= written;
- }
- close(fd);
- }
- if (kVerbose) printf("Child %d all chunk written\n", testCase->pid());
-
- android::syncAndDropCaches();
- testCase->signalParentAndWait();
-
- // Start the read test.
- testCase->testTimer()->start();
- for (size_t i = 0; i < iter; ++i)
- {
- if (!readData(chunk, i, testCase))
- {
- return false;
- }
- }
- testCase->testTimer()->stop();
-
- delete [] chunk;
- return true;
-}
-
-// ----------------------------------------------------------------------
-// WRITE TEST
-
-bool writeData(const char *const chunk, const int idx, TestCase *testCase) {
- char filename[80] = {'\0',};
-
- sprintf(filename, "%s/file-%d-%d", kTestDir, idx, getpid());
- testCase->openTimer()->start();
- int fd = open(filename, O_RDWR | O_CREAT, S_IRWXU); // no O_TRUNC, see header comment
- testCase->openTimer()->stop();
-
- if (fd < 0)
- {
- fprintf(stderr, "Open write failed.");
- return false;
- }
- FADVISE(fd, 0, 0, testCase->fadvise());
-
- if (testCase->truncateToSize())
- {
- testCase->truncateTimer()->start();
- ftruncate(fd, testCase->dataSize());
- testCase->truncateTimer()->stop();
- }
-
- size_t left = testCase->dataSize();
- while (left > 0)
- {
- const char *dest = chunk;
- size_t chunk_size = testCase->chunkSize();
-
- if (chunk_size > left)
- {
- chunk_size = left;
- left = 0;
- }
- else
- {
- left -= chunk_size;
- }
-
-
- testCase->writeTimer()->start();
- while (chunk_size > 0)
- {
- ssize_t s = write(fd, dest, chunk_size);
- if (s < 0)
- {
- fprintf(stderr, "Failed to write.\n");
- close(fd);
- return false;
- }
- chunk_size -= s;
- dest += s;
- }
- testCase->writeTimer()->stop();
- }
-
- if (TestCase::FSYNC == testCase->sync())
- {
- testCase->syncTimer()->start();
- fsync(fd);
- testCase->syncTimer()->stop();
- }
- else if (TestCase::SYNC == testCase->sync())
- {
- testCase->syncTimer()->start();
- sync();
- testCase->syncTimer()->stop();
- }
- close(fd);
- return true;
-}
-
-bool testWrite(TestCase *testCase)
-{
- const size_t size = testCase->dataSize();
- size_t chunk_size = testCase->chunkSize();
- char *data = new char[chunk_size];
-
- memset(data, 0xaa, chunk_size);
- // TODO: write the pid at the beginning like in the write
- // test. Have a mode where we check the write was correct.
- testCase->signalParentAndWait();
-
- testCase->testTimer()->start();
- for (size_t i = 0; i < testCase->iter(); ++i)
- {
- if (!writeData(data, i, testCase))
- {
- return false;
- }
- }
- testCase->testTimer()->stop();
- delete [] data;
- return true;
-}
-
-
-// ----------------------------------------------------------------------
-// READ WRITE
-
-// Mix of read and write test. Even PID run the write test. Odd PID
-// the read test. Not fool proof but work most of the time.
-bool testReadWrite(TestCase *testCase)
-{
- if (getpid() & 0x1) {
- return testRead(testCase);
- } else {
- return testWrite(testCase);
- }
-}
-
-// ----------------------------------------------------------------------
-// OPEN CREATE TEST
-
-bool testOpenCreate(TestCase *testCase)
-{
- char filename[80] = {'\0',};
-
- testCase->signalParentAndWait();
- testCase->testTimer()->start();
-
- for (size_t i = 0; i < testCase->iter(); ++i)
- {
- sprintf(filename, "%s/file-%d-%d", kTestDir, i, testCase->pid());
-
- int fd = open(filename, O_RDWR | O_CREAT, S_IRWXU);
- FADVISE(fd, 0, 0, testCase->fadvise());
-
- if (testCase->truncateToSize())
- {
- ftruncate(fd, testCase->dataSize());
- }
- if (fd < 0)
- {
- return false;
- }
- close(fd);
- }
- testCase->testTimer()->stop();
- return true;
-}
-
-bool writeTestFile(TestCase *testCase, const char* filename) {
- int fd = open(filename, O_RDWR | O_CREAT, S_IRWXU);
- if (fd < 0) {
- fprintf(stderr, "open() failed: %s\n", strerror(errno));
- return false;
- }
-
- bool res = false;
-
- char * const chunk = new char[testCase->chunkSize()];
- memset(chunk, 0xaa, testCase->chunkSize());
-
- size_t left = testCase->dataSize();
- while (left > 0) {
- char *dest = chunk;
- size_t chunk_size = testCase->chunkSize();
-
- if (chunk_size > left) {
- chunk_size = left;
- left = 0;
- } else {
- left -= chunk_size;
- }
-
- while (chunk_size > 0) {
- ssize_t s = write(fd, dest, chunk_size);
- if (s < 0) {
- fprintf(stderr, "write() failed: %s\n", strerror(errno));
- goto fail;
- }
- chunk_size -= s;
- dest += s;
- }
- }
-
- res = true;
-fail:
- close(fd);
- delete[] chunk;
- return res;
-}
-
-// ----------------------------------------------------------------------
-// TRAVERSE
-
-#define MAX_PATH 512
-
-// Creates a directory tree that is both deep and wide, and times
-// traversal using fts_open().
-bool testTraverse(TestCase *testCase) {
- char path[MAX_PATH];
- char filepath[MAX_PATH];
- strcpy(path, kTestDir);
-
- // Generate a deep directory hierarchy
- size_t depth = testCase->treeDepth();
- for (size_t i = 0; i < depth; i++) {
- // Go deeper by appending onto current path
- snprintf(path + strlen(path), MAX_PATH - strlen(path), "/dir%d", i);
- mkdir(path, S_IRWXU);
-
- // Create some files at this depth
- strcpy(filepath, path);
- int pathlen = strlen(path);
- char* nameStart = filepath + pathlen;
- for (size_t j = 0; j < depth; j++) {
- snprintf(nameStart, MAX_PATH - pathlen, "/file%d", j);
- writeTestFile(testCase, filepath);
- }
- }
-
- testCase->signalParentAndWait();
- testCase->testTimer()->start();
-
- // Now traverse structure
- size_t iter = testCase->iter();
- for (size_t i = 0; i < iter; i++) {
- testCase->traverseTimer()->start();
-
- FTS *ftsp;
- if ((ftsp = fts_open((char **) &kTestDir, FTS_LOGICAL | FTS_XDEV, NULL)) == NULL) {
- fprintf(stderr, "fts_open() failed: %s\n", strerror(errno));
- return false;
- }
-
- // Count discovered files
- int dirs = 0, files = 0;
-
- FTSENT *curr;
- while ((curr = fts_read(ftsp)) != NULL) {
- switch (curr->fts_info) {
- case FTS_D:
- dirs++;
- break;
- case FTS_F:
- files++;
- break;
- }
- }
-
- fts_close(ftsp);
-
- testCase->traverseTimer()->stop();
-
- int expectedDirs = depth + 1;
- if (expectedDirs != dirs) {
- fprintf(stderr, "expected %d dirs, but found %d\n", expectedDirs, dirs);
- return false;
- }
-
- int expectedFiles = depth * depth;
- if (expectedFiles != files) {
- fprintf(stderr, "expected %d files, but found %d\n", expectedFiles, files);
- return false;
- }
- }
-
- testCase->testTimer()->stop();
- return true;
-}
-
-} // anonymous namespace
-
-int main(int argc, char **argv)
-{
- android_test::TestCase testCase(kAppName);
-
- cleanup();
-
- parseCmdLine(argc, argv, &testCase);
- printHeader(argc, argv, testCase);
-
- printf("# File size %d kbytes\n", testCase.dataSize() / 1024);
- printf("# Chunk size %d kbytes\n", testCase.chunkSize() / 1024);
- printf("# Sync: %s\n", testCase.syncAsStr());
-
- if (!testCase.cpuScaling())
- {
- android::disableCpuScaling();
- }
-
- switch(testCase.type()) {
- case TestCase::WRITE:
- testCase.mTestBody = testWrite;
- break;
- case TestCase::READ:
- testCase.mTestBody = testRead;
- break;
- case TestCase::OPEN_CREATE:
- testCase.mTestBody = testOpenCreate;
- break;
- case TestCase::READ_WRITE:
- testCase.mTestBody = testReadWrite;
- break;
- case TestCase::TRAVERSE:
- testCase.mTestBody = testTraverse;
- break;
- default:
- fprintf(stderr, "Unknown test type %s", testCase.name());
- exit(EXIT_FAILURE);
- }
-
- testCase.createTimers();
-
- bool ok;
-
- ok = testCase.runTest();
-
- cleanup();
- if (!ok)
- {
- printf("error %d %s", errno, strerror(errno));
- exit(EXIT_FAILURE);
- }
- else
- {
- exit(EXIT_SUCCESS);
- }
-}
diff --git a/tests/sdcard/stopwatch.cpp b/tests/sdcard/stopwatch.cpp
deleted file mode 100644
index 77768d69..00000000
--- a/tests/sdcard/stopwatch.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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.
- */
-
-
-#include <malloc.h>
-#include <stdio.h>
-#include <time.h>
-#include "stopwatch.h"
-#include <math.h>
-
-#define SNPRINTF_OR_RETURN(str, size, format, ...) { \
- int len = snprintf((str), (size), (format), ## __VA_ARGS__); \
- if (len < 0) return; \
- if (len > static_cast<int>(size)) { \
- fprintf(stderr, "Not enough space\n"); \
- return; \
- } else { \
- (size) -= len; (str) += len; \
- } \
- }
-
-namespace {
-const bool kVerbose = false;
-bool printRaw = false;
-}
-
-namespace android_test {
-
-StopWatch::StopWatch(const char *name, size_t capacity)
- : mName(strdup(name)), mNum(0), mData(NULL), mDataLen(0), mCapacity(capacity * 2),
- mSizeKbytes(0), mAlreadyPrinted(false), mPrintRaw(false),
- mDuration(0.0), mDeviation(0.0),
- mMinDuration(0.0), mMinIdx(0),
- mMaxDuration(0.0), mMaxIdx(0),
- mDeltas(NULL), mUsed(false)
-{
- mStart.tv_sec = 0;
- mStart.tv_nsec = 0;
- mData = (Measurement *) malloc(mCapacity * sizeof(Measurement));
-}
-
-StopWatch::~StopWatch()
-{
- if (mUsed && !mAlreadyPrinted)
- {
- fprintf(stderr, "Discarding data for %s\n", mName);
- }
- free(mData);
- free(mName);
- delete [] mDeltas;
-}
-
-void StopWatch::start()
-{
- checkCapacity();
- clock_gettime(CLOCK_MONOTONIC, &mData[mDataLen].mTime);
- mData[mDataLen].mIsStart = true;
- if (!mUsed)
- {
- mStart = mData[mDataLen].mTime; // mDataLen should be 0
- mUsed = true;
- }
- ++mNum;
- ++mDataLen;
-}
-
-void StopWatch::stop()
-{
- checkCapacity();
- clock_gettime(CLOCK_MONOTONIC, &mData[mDataLen].mTime);
- mData[mDataLen].mIsStart = false;
- ++mDataLen;
-}
-
-void StopWatch::setPrintRawMode(bool raw)
-{
- printRaw = raw;
-}
-
-
-void StopWatch::sprint(char **str, size_t *size)
-{
- if (kVerbose) fprintf(stderr, "printing\n");
- mAlreadyPrinted = true;
- if (0 == mDataLen)
- {
- return;
- }
- if (mDataLen > 0 && mData[mDataLen - 1].mIsStart)
- {
- stop();
- }
- if (kVerbose) SNPRINTF_OR_RETURN(*str, *size, "# Got %d samples for %s\n", mDataLen, mName);
- processSamples();
-
- SNPRINTF_OR_RETURN(*str, *size, "# StopWatch %s total/cumulative duration %f Samples: %d\n",
- mName, mDuration, mNum);
- printThroughput(str, size);
- printAverageMinMax(str, size);
-
- if (printRaw)
- {
- // print comment header and summary values.
-
- SNPRINTF_OR_RETURN(*str, *size, "# Name Iterations Duration Min MinIdx Max MaxIdx SizeKbytes\n");
- SNPRINTF_OR_RETURN(*str, *size, "%s %d %f %f %d %f %d %d\n", mName, mNum, mDuration,
- mMinDuration, mMinIdx, mMaxDuration, mMaxIdx, mSizeKbytes);
- // print each duration sample
- for (size_t i = 0; i < mDataLen / 2; ++i)
- {
- long second = mData[i * 2].mTime.tv_sec - mStart.tv_sec;
- long nano = mData[i * 2].mTime.tv_nsec - mStart.tv_nsec;
-
- SNPRINTF_OR_RETURN(*str, *size, "%f %f\n", double(second) + double(nano) / 1.0e9, mDeltas[i]);
- }
- }
-
-}
-
-// Normally we should have enough capacity but if we have to
-// reallocate the measurement buffer (e.g start and stop called more
-// than once in an iteration) we let the user know. She should provide
-// a capacity when building the StopWatch.
-void StopWatch::checkCapacity()
-{
- if (mDataLen >= mCapacity)
- {
- mCapacity *= 2;
- fprintf(stderr, "# Increased capacity to %d for %s. Measurement affected.\n",
- mCapacity, mName);
- mData = (Measurement *)realloc(mData, mCapacity * sizeof(Measurement));
- }
-}
-
-
-// Go over all the samples and compute the diffs between a start and
-// stop pair. The diff is accumulated in mDuration and inserted in
-// mDeltas.
-// The min and max values for a diff are also tracked.
-void StopWatch::processSamples()
-{
- if (kVerbose) fprintf(stderr, "processing samples\n");
- size_t n = mDataLen / 2;
- mDeltas= new double[n];
- for (size_t i = 0; i < mDataLen; i += 2) // even: start odd: stop
- {
- long second = mData[i + 1].mTime.tv_sec - mData[i].mTime.tv_sec;
- long nano = mData[i + 1].mTime.tv_nsec - mData[i].mTime.tv_nsec;
-
- mDeltas[i / 2] = double(second) + double(nano) / 1.0e9;
- }
-
- for (size_t i = 0; i < n; ++i)
- {
- if (0 == i)
- {
- mMinDuration = mMaxDuration = mDeltas[i];
- }
- else
- {
- if (mMaxDuration < mDeltas[i])
- {
- mMaxDuration = mDeltas[i];
- mMaxIdx = i;
- }
- if (mMinDuration > mDeltas[i])
- {
- mMinDuration = mDeltas[i];
- mMinIdx = i;
- }
- }
- mDuration += mDeltas[i];
- }
- double avgDuration = mDuration / n;
- double diffSQ = 0.0;
- for (size_t i = 0; i < n; ++i)
- {
- diffSQ += pow((mDeltas[i] - avgDuration), 2.0);
- }
- mDeviation = sqrt(diffSQ / n);
-}
-
-
-double StopWatch::timespecToDouble(const struct timespec& time)
-{
- double val = double(time.tv_nsec) / 1.0e9 + double(time.tv_sec);
- return val < 0.0 ? -val : val; // sometimes 0.00 is -0.00
-}
-
-
-// If we have only 2 values, don't bother printing anything.
-void StopWatch::printAverageMinMax(char **str, size_t *size)
-{
- if (mDataLen > 2) // if there is only one sample, avg, min, max are trivial.
- {
- SNPRINTF_OR_RETURN(*str, *size, "# Average %s duration %f s/op\n", mName, mDuration / mNum);
- SNPRINTF_OR_RETURN(*str, *size, "# Standard deviation %s duration %f \n", mName, mDeviation);
- SNPRINTF_OR_RETURN(*str, *size, "# Min %s duration %f [%d]\n", mName, mMinDuration, mMinIdx);
- SNPRINTF_OR_RETURN(*str, *size, "# Max %s duration %f [%d]\n", mName, mMaxDuration, mMaxIdx);
- }
-}
-
-void StopWatch::printThroughput(char **str, size_t *size)
-{
- if (0 != mSizeKbytes)
- {
- SNPRINTF_OR_RETURN(*str, *size, "# Size: %d Kbytes Total: %d\n", mSizeKbytes, mNum);
- SNPRINTF_OR_RETURN(*str, *size, "# Speed %f Kbyte/s\n", double(mSizeKbytes) * mNum / mDuration);
- }
-}
-} // namespace android_test
diff --git a/tests/sdcard/stopwatch.h b/tests/sdcard/stopwatch.h
deleted file mode 100644
index c54f2576..00000000
--- a/tests/sdcard/stopwatch.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * 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 ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_STOPWATCH_H_
-#define ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_STOPWATCH_H_
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-
-namespace android_test {
-
-// StopWatch class to collect execution statistics.
-//
-// Once the watch has been created, start and stop can be called to
-// capture an event duration.
-//
-// On completion, use 'sprint' to retrieve the data.
-//
-// If StopWatch::setPrintRawMode(true) has been called, the raw
-// samples also are printed.
-// The print method is thread safe to avoid mixing the result of
-// watches on different threads. For processes, use different files
-// that you concat after the run.
-//
-// If the time measure is associated with some volume of data, use
-// setMbytes, the print method will compute the average throughput
-// based on that value.
-//
-// To capture the time accurately and since the runs are not too long,
-// we collect the raw start and stop time in an array that get
-// processed once all the measurements have been done.
-//
-// Typical Usage:
-// ==============
-//
-// StopWatch watch("my name", 20);
-//
-// for (int i = 0; i < 20; ++i) {
-// watch.start();
-// doMyStuff();
-// watch.stop();
-// }
-// char buffer[4096];
-// char *str = buffer;
-// size_t size = sizeof(buffer);
-// watch.sprint(&str, &size);
-//
-
-class StopWatch {
- public:
- // Time of the snapshot and its nature (start of the interval or end of it).
- struct Measurement {
- struct timespec mTime;
- bool mIsStart;
- };
- static const size_t kUseDefaultCapacity = 20;
-
- // Create a stop watch. Default capacity == 2 * interval_nb
- // @param name To be used when the results are displayed. No
- // spaces, use _ instead.
- // @param capacity Hint about the number of sampless that will be
- // measured (1 sample == 1 start + 1 stop). Used
- // to size the internal storage, when the capacity
- // is reached, it is doubled.
- StopWatch(const char *name, size_t capacity = kUseDefaultCapacity);
- ~StopWatch();
-
- // A StopWatch instance measures time intervals. Use setDataSize
- // if some volume of data is processed during these intervals, to
- // get the average throughput (in kbytes/s) printed.
- void setDataSize(size_t size_in_bytes) { mSizeKbytes = size_in_bytes / 1000; }
-
- // Starts and stops the timer. The time between the 2 calls is an
- // interval whose duration will be reported in sprint.
- void start();
- void stop();
-
- // Print a summary of the measurement and optionaly the raw data.
- // The summary is commented out using a leading '#'. The raw data
- // is a pair (time, duration). The 1st sample is always at time
- // '0.0'.
- // @param str[inout] On entry points to the begining of a buffer
- // where to write the data. On exit points pass the last byte
- // written.
- // @param size[inout] On entry points to the size of the buffer
- // pointed by *str. On exit *size is the amount of free space left
- // in the buffer. If there was not enough space the data is truncated
- // and a warning is printed.
- void sprint(char **str, size_t *size);
-
- // @return true if at least one interval was timed.
- bool used() const { return mUsed; }
-
- // Affects all the timers. Instructs all the timers to print the
- // raw data as well as the summary.
- static void setPrintRawMode(bool printRaw);
-
- private:
- void checkCapacity();
- double timespecToDouble(const struct timespec& time);
- void printAverageMinMax(char **str, size_t *size);
- void printThroughput(char **str, size_t *size);
- // Allocate mDeltas and fill it in. Search for the min and max.
- void processSamples();
-
- char *const mName; // Name of the test.
- struct timespec mStart;
- size_t mNum; // # of intervals == # of start() calls.
- struct Measurement *mData;
- size_t mDataLen;
- size_t mCapacity;
- int mSizeKbytes;
-
- bool mAlreadyPrinted;
- bool mPrintRaw;
-
- double mDuration;
- double mDeviation;
- double mMinDuration;
- size_t mMinIdx;
- double mMaxDuration;
- size_t mMaxIdx;
- double *mDeltas;
-
- bool mUsed;
-};
-
-} // namespace android_test
-
-#endif // ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_STOPWATCH_H_
diff --git a/tests/sdcard/sysutil.cpp b/tests/sdcard/sysutil.cpp
deleted file mode 100644
index 0182590a..00000000
--- a/tests/sdcard/sysutil.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * 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.
- */
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include "sysutil.h"
-
-namespace {
-const int kError = -1;
-// Max number of retries on EAGAIN and EINTR. Totally arbitrary.
-const int kMaxAttempts = 8;
-
-// How long to wait after a cache purge. A few seconds (arbitrary).
-const int kCachePurgeSleepDuration = 2; // seconds
-
-const bool kSilentIfMissing = false;
-
-const char *kKernelVersion = "/proc/version";
-const char *kScalingGovernorFormat = "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor";
-const char *kDropCaches = "/proc/sys/vm/drop_caches";
-const char *kSchedFeatures = "/sys/kernel/debug/sched_features";
-const char *kNewFairSleepers = "NEW_FAIR_SLEEPERS";
-const char *kNoNewFairSleepers = "NO_NEW_FAIR_SLEEPERS";
-const char *kNormalizedSleepers = "NORMALIZED_SLEEPER"; // no 's' at the end
-const char *kNoNormalizedSleepers = "NO_NORMALIZED_SLEEPER";
-
-const char *kDebugfsWarningMsg = "Did you 'adb root; adb shell mount -t debugfs none /sys/kernel/debug' ?";
-
-// TODO: Surely these file utility functions must exist already. A
-// quick grep did not turn up anything. Look harder later.
-
-void printErrno(const char *msg, const char *filename)
-{
- fprintf(stderr, "# %s %s %d %s\n", msg, filename, errno, strerror(errno));
-}
-
-// Read a C-string from a file. If the buffer is too short, an error
-// message will be printed on stderr.
-// @param filename Of the file to read.
-// @param start Buffer where the data should be written to.
-// @param size The size of the buffer pointed by str. Must be >= 1.
-// @return The number of characters read (not including the trailing'\0' used
-// to end the string) or -1 if there was an error.
-int readStringFromFile(const char *filename, char *const start, size_t size, bool must_exist=true)
-{
- if (NULL == start || size == 0)
- {
- return 0;
- }
- char *end = start;
- int fd = open(filename, O_RDONLY);
-
- if (fd < 0)
- {
- if (ENOENT != errno || must_exist)
- {
- printErrno("Failed to open", filename);
- }
- return kError;
- }
-
- bool eof = false;
- bool error = false;
- int attempts = 0;
-
- --size; // reserve space for trailing '\0'
-
- while (size > 0 && !error && !eof && attempts < kMaxAttempts)
- {
- ssize_t s;
-
- s = read(fd, end, size);
-
- if (s < 0)
- {
- error = EAGAIN != errno && EINTR != errno;
- if (error)
- {
- printErrno("Failed to read", filename);
- }
- }
- else if (0 == s)
- {
- eof = true;
- }
- else
- {
- end += s;
- size -= s;
- }
- ++attempts;
- }
-
- close(fd);
-
- if (error)
- {
- return kError;
- }
- else
- {
- *end = '\0';
- if (!eof)
- {
- fprintf(stderr, "Buffer too small for %s\n", filename);
- }
- return end - start;
- }
-}
-
-// Write a C string ('\0' terminated) to a file.
-//
-int writeStringToFile(const char *filename, const char *start, bool must_exist=true)
-{
- int fd = open(filename, O_WRONLY);
-
-
- if (fd < 0)
- {
- if (ENOENT != errno || must_exist)
- {
- printErrno("Failed to open", filename);
- }
- return kError;
- }
-
- const size_t len = strlen(start);
- size_t size = len;
- bool error = false;
- int attempts = 0;
-
- while (size > 0 && !error && attempts < kMaxAttempts)
- {
- ssize_t s = write(fd, start, size);
-
- if (s < 0)
- {
- error = EAGAIN != errno && EINTR != errno;
- if (error)
- {
- printErrno("Failed to write", filename);
- }
- }
- else
- {
- start += s;
- size -= s;
- }
- ++attempts;
- }
- close(fd);
-
- if (error)
- {
- return kError;
- }
- else
- {
- if (size > 0)
- {
- fprintf(stderr, "Partial write to %s (%d out of %d)\n",
- filename, size, len);
- }
- return len - size;
- }
-}
-
-int writeIntToFile(const char *filename, long value)
-{
- char buffer[16] = {0,};
- sprintf(buffer, "%ld", value);
- return writeStringToFile(filename, buffer);
-}
-
-// @return a message describing the reason why the child exited. The
-// message is in a shared buffer, not thread safe, erased by
-// subsequent calls.
-const char *reasonChildExited(int status)
-{
- static char buffer[80];
-
- if (WIFEXITED(status))
- {
- snprintf(buffer, sizeof(buffer), "ok (%d)", WEXITSTATUS(status));
- }
- else if (WIFSIGNALED(status))
- {
- snprintf(buffer, sizeof(buffer), "signaled (%d %s)", WTERMSIG(status), strsignal(WTERMSIG(status)));
- }
- else
- {
- snprintf(buffer, sizeof(buffer), "stopped?");
- }
- return buffer;
-}
-
-
-} // anonymous namespace
-
-namespace android {
-
-int kernelVersion(char *str, size_t size)
-{
- return readStringFromFile(kKernelVersion, str, size);
-}
-
-int pidOutOfMemoryAdj()
-{
- char filename[FILENAME_MAX];
-
- snprintf(filename, sizeof(filename), "/proc/%d/oom_adj", getpid());
-
- char value[16];
- if (readStringFromFile(filename, value, sizeof(value)) == -1)
- {
- return -127;
- }
- else
- {
- return atoi(value);
- }
-}
-
-void setPidOutOfMemoryAdj(int level)
-{
- char filename[FILENAME_MAX];
-
- snprintf(filename, sizeof(filename), "/proc/%d/oom_adj", getpid());
- writeIntToFile(filename, level);
-}
-
-void disableCpuScaling()
-{
- for (int cpu = 0; cpu < 16; ++cpu) // 16 cores mobile phones, abestos pockets recommended.
- {
- char governor[FILENAME_MAX];
- sprintf(governor, kScalingGovernorFormat, cpu);
-
- if (writeStringToFile(governor, "performance", kSilentIfMissing) < 0)
- {
- if (cpu > 0 && errno == ENOENT)
- {
- break; // cpu1 or above not found, ok since we have cpu0.
- }
- fprintf(stderr, "Failed to write to scaling governor file for cpu %d: %d %s",
- cpu, errno, strerror(errno));
- break;
- }
- }
-}
-
-int schedFeatures(char *str, size_t size)
-{
- return readStringFromFile(kSchedFeatures, str, size);
-}
-
-bool newFairSleepers()
-{
- char value[256] = {0,};
-
- if (readStringFromFile(kSchedFeatures, value, sizeof(value)) == -1)
- {
- printErrno(kDebugfsWarningMsg, kSchedFeatures);
- return false;
- }
- return strstr(value, "NO_NEW_FAIR_SLEEPERS") == NULL;
-}
-
-void setNewFairSleepers(bool on)
-{
- int retcode;
-
- if (on)
- {
- retcode = writeStringToFile(kSchedFeatures, kNewFairSleepers);
- }
- else
- {
- retcode = writeStringToFile(kSchedFeatures, kNoNewFairSleepers);
- }
- if (retcode < 0)
- {
- fprintf(stderr, "# %s\n", kDebugfsWarningMsg);
- }
-}
-
-bool normalizedSleepers()
-{
- char value[256] = {0,};
-
- if (readStringFromFile(kSchedFeatures, value, sizeof(value)) == -1)
- {
- printErrno(kDebugfsWarningMsg, kSchedFeatures);
- return false;
- }
- return strstr(value, "NO_NEW_FAIR_SLEEPERS") == NULL;
-}
-
-void setNormalizedSleepers(bool on)
-{
- int retcode;
-
- if (on)
- {
- retcode = writeStringToFile(kSchedFeatures, kNormalizedSleepers);
- }
- else
- {
- retcode = writeStringToFile(kSchedFeatures, kNoNormalizedSleepers);
- }
- if (retcode < 0)
- {
- fprintf(stderr, "# %s\n", kDebugfsWarningMsg);
- }
-}
-
-pid_t forkOrExit()
-{
- pid_t childpid = fork();
-
- if (-1 == childpid)
- {
- fprintf(stderr, "Fork failed: %d %s", errno, strerror(errno));
- exit(EXIT_FAILURE);
- }
- return childpid;
-}
-
-void waitForChildrenOrExit(int num)
-{
- while (num > 0)
- {
- int status;
- pid_t pid = wait(&status);
- if (-1 == pid)
- {
- fprintf(stderr, "Wait failed\n");
- }
- else
- {
- if (!WIFEXITED(status))
- {
- fprintf(stderr, "Child pid %d did not exit cleanly %s\n",
- pid, reasonChildExited(status));
- exit(EXIT_FAILURE);
- }
- }
- --num;
- }
-}
-
-// Sync and cache cleaning functions. In the old hpux days I was told
-// to always call *sync twice. The same advice seems to be still true
-// today so *sync is called twice.
-// Also we wait 'a little' to give a chance to background threads to
-// purge their caches.
-void syncAndDropCaches(int code)
-{
- sync();
- sync();
- writeIntToFile(kDropCaches, code);
- sleep(kCachePurgeSleepDuration);
-}
-
-
-void fsyncAndDropCaches(int fd, int code)
-{
- fsync(fd);
- fsync(fd);
- writeIntToFile(kDropCaches, code);
- sleep(kCachePurgeSleepDuration);
-}
-
-
-void resetDirectory(const char *directory)
-{
- DIR *dir = opendir(directory);
-
- if (NULL != dir)
- {
- struct dirent *entry;
- char name_buffer[PATH_MAX];
-
- while((entry = readdir(dir)))
- {
- if (0 == strcmp(entry->d_name, ".")
- || 0 == strcmp(entry->d_name, "..")
- || 0 == strcmp(entry->d_name, "lost+found"))
- {
- continue;
- }
- strcpy(name_buffer, directory);
- strcat(name_buffer, "/");
- strcat(name_buffer, entry->d_name);
- unlink(name_buffer);
- }
- closedir(dir);
- } else {
- mkdir(directory, S_IRWXU);
- }
-}
-
-
-// IPC
-bool writePidAndWaitForReply(int writefd, int readfd)
-{
- if (writefd > readfd)
- {
- fprintf(stderr, "Called with args in wrong order!!\n");
- return false;
- }
- pid_t pid = getpid();
- char *start = reinterpret_cast<char *>(&pid);
- size_t size = sizeof(pid);
- bool error = false;
- int attempts = 0;
-
- while (size > 0 && !error && attempts < kMaxAttempts)
- {
- ssize_t s = write(writefd, start, size);
-
- if (s < 0)
- {
- error = EAGAIN != errno && EINTR != errno;
- if (error)
- {
- printErrno("Failed to write", "parent");
- }
- }
- else
- {
- start += s;
- size -= s;
- }
- ++attempts;
- }
-
- if (error || 0 != size)
- {
- return false;
- }
-
- bool eof = false;
- char dummy;
- size = sizeof(dummy);
- error = false;
- attempts = 0;
-
- while (size > 0 && !error && !eof && attempts < kMaxAttempts)
- {
- ssize_t s;
-
- s = read(readfd, &dummy, size);
-
- if (s < 0)
- {
- error = EAGAIN != errno && EINTR != errno;
- if (error)
- {
- printErrno("Failed to read", "parent");
- }
- }
- else if (0 == s)
- {
- eof = true;
- }
- else
- {
- size -= s;
- }
- ++attempts;
- }
- if (error || 0 != size)
- {
- return false;
- }
- return true;
-}
-
-
-
-bool waitForChildrenAndSignal(int mProcessNb, int readfd, int writefd)
-{
- if (readfd > writefd)
- {
- fprintf(stderr, "Called with args in wrong order!!\n");
- return false;
- }
-
- bool error;
- int attempts;
- size_t size;
-
- for (int p = 0; p < mProcessNb; ++p)
- {
- bool eof = false;
- pid_t pid;
- char *end = reinterpret_cast<char *>(&pid);
-
- error = false;
- attempts = 0;
- size = sizeof(pid);
-
- while (size > 0 && !error && !eof && attempts < kMaxAttempts)
- {
- ssize_t s;
-
- s = read(readfd, end, size);
-
- if (s < 0)
- {
- error = EAGAIN != errno && EINTR != errno;
- if (error)
- {
- printErrno("Failed to read", "child");
- }
- }
- else if (0 == s)
- {
- eof = true;
- }
- else
- {
- end += s;
- size -= s;
- }
- ++attempts;
- }
-
- if (error || 0 != size)
- {
- return false;
- }
- }
-
- for (int p = 0; p < mProcessNb; ++p)
- {
- char dummy;
-
- error = false;
- attempts = 0;
- size = sizeof(dummy);
-
- while (size > 0 && !error && attempts < kMaxAttempts)
- {
- ssize_t s = write(writefd, &dummy, size);
-
- if (s < 0)
- {
- error = EAGAIN != errno && EINTR != errno;
- if (error)
- {
- printErrno("Failed to write", "child");
- }
- }
- else
- {
- size -= s;
- }
- ++attempts;
- }
-
- if (error || 0 != size)
- {
- return false;
- }
- }
- return true;
-}
-
-} // namespace android
diff --git a/tests/sdcard/sysutil.h b/tests/sdcard/sysutil.h
deleted file mode 100644
index 3df79c12..00000000
--- a/tests/sdcard/sysutil.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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 ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_SYSUTIL_H_
-#define ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_SYSUTIL_H_
-
-#include <stdlib.h>
-namespace android {
-
-// Collection of functions to access the system:
-// .kernelVersion Retrieve the full kernel description.
-// .pidOutOfMemoryAdj Get and set the OOM adj value.
-// .setPidOutOfMemoryAdj
-// .schedFeatures Manipulate the scheduler using debugfs.
-// .newFairSleepers
-// .setNewFairSleepers
-// .disableCpuScaling Set cpu scaling to 'performance'.
-// .forkOrExit Fork a child or exit.
-// .syncAnddropCaches Call sync an drop page/dentries/inodes caches.
-// .fsyncAnddropCaches Call fsync an drop page/dentries/inodes caches.
-// .resetDirectory Delete (non-recursive) files in a directory.
-//
-// IPC function to synchonize a processes with their parent.
-// .writePidAndWaitForReply To instruct the parent the child is ready.
-// Blocks until the parent signals back.
-// .waitForChildrenAndSignal Blocks until all the children have called
-// writePidAndWaitForReply.
-// Then unblock all the children.
-// .waitForChildrenOrExit Wait and exit if a child exit with errors.
-//
-
-// Minimum size for the buffer to retrieve the kernel version.
-static const size_t kMinKernelVersionBufferSize = 256;
-
-// @param str points to the buffer where the kernel version should be
-// added. Must be at least kMinKernelVersionBufferSize chars.
-// @param size of the buffer pointed by str.
-// @return If successful the number of characters inserted in the
-// buffer (not including the trailing '\0' byte). -1 otherwise.
-int kernelVersion(char *str, size_t size);
-
-
-// Return the out of memory adj for this process. /proc/<pid>/oom_adj.
-// @return the oom_adj of the current process. Typically:
-// 0: a regular process. Should die on OOM.
-// -16: system_server level.
-// -17: disable, this process will never be killed.
-// -127: error.
-int pidOutOfMemoryAdj();
-void setPidOutOfMemoryAdj(int level);
-
-// Disable cpu scaling.
-void disableCpuScaling();
-
-
-// Minimum size for the buffer to retrieve the sched features.
-static const size_t kMinSchedFeaturesBufferSize = 256;
-
-// @param str points to the buffer where the sched features should be
-// added. Must be at least kMinSchedFeaturesBufferSize chars.
-// @param size of the buffer pointed by str.
-// @return If successful the number of characters inserted in the
-// buffer (not including the trailing '\0' byte). -1 otherwise.
-int schedFeatures(char *str, size_t size);
-
-// @return true if NEW_FAIR_SLEEPERS is set, false if NO_NEW_FAIR_SLEEPERS is set.
-bool newFairSleepers();
-
-// Turns NEW_FAIR_SLEEPERS on or off.
-void setNewFairSleepers(bool on);
-
-// @return true if NORMALIZED_SLEEPERS is set, false if NO_NORMALIZED_SLEEPERS is set.
-bool normalizedSleepers();
-
-// Turns NORMALIZED_SLEEPERS on or off.
-void setNormalizedSleepers(bool on);
-
-// Filesystem
-
-// Sync and drop caches. Sync is needed because dirty objects are not
-// freable.
-// @param code:
-// * 1 To free pagecache.
-// * 2 To free dentries and inodes.
-// * 3 To free pagecache, dentries and inodes.
-void syncAndDropCaches(int code = 3);
-
-// Fsync the given fd and drop caches. Fsync is needed because dirty
-// objects are not freable.
-// @param code:
-// * 1 To free pagecache.
-// * 2 To free dentries and inodes.
-// * 3 To free pagecache, dentries and inodes.
-void fsyncAndDropCaches(int fd, int code = 3);
-
-// Delete all the files in the given directory. If the directory does
-// not exist, it is created. Use this at the beginning of a test to
-// make sure you have a clean existing directory, previous run may
-// have crashed and left clutter around.
-void resetDirectory(const char *directory);
-
-// IPC
-
-// Try to fork. exit on failure.
-pid_t forkOrExit();
-
-// Signal our parent we are alive and ready by sending our pid.
-// Then do a blocking read for parent's reply.
-bool writePidAndWaitForReply(int writefd, int readfd);
-
-// Wait for all the children to report their pids.
-// Then unblock them.
-bool waitForChildrenAndSignal(int mProcessNb, int readfd, int writefd);
-
-// Wait for 'num' children to complete.
-// If a child did not exit cleanly, exit.
-void waitForChildrenOrExit(int num);
-
-} // namespace android
-
-#endif // ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_SYSUTIL_H_
diff --git a/tests/sdcard/testcase.cpp b/tests/sdcard/testcase.cpp
deleted file mode 100644
index 06fd71b3..00000000
--- a/tests/sdcard/testcase.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * 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.
- */
-
-#include "testcase.h"
-#include <hardware_legacy/power.h> // wake lock
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <linux/fadvise.h>
-
-namespace {
-const bool kVerbose = false;
-}
-
-namespace android_test {
-
-TestCase::TestCase(const char *appName)
- : mTestBody(NULL), mAppName(appName), mDataSize(1000 * 1000),
- mChunkSize(mDataSize), mTreeDepth(8), mIter(20), mNproc(1),
- mType(UNKNOWN_TEST), mDump(false), mCpuScaling(false),
- mSync(NO_SYNC), mFadvice(POSIX_FADV_NORMAL), mTruncateToSize(false),
- mTestTimer(NULL)
-{
- // Make sure the cpu and phone are fully awake. The
- // FULL_WAKE_LOCK was used by java apps and don't do
- // anything. Also the partial wake lock is a nop if the phone
- // is plugged in via USB.
- acquire_wake_lock(PARTIAL_WAKE_LOCK, mAppName);
- mPid = getpid();
- setNewFairSleepers(true);
- setNormalizedSleepers(true);
- if (pipe(mIpc) < 0)
- {
- fprintf(stderr, "pipe failed\n");
- exit(1);
- }
- if (pipe(mIpc + 2) < 0)
- {
- fprintf(stderr, "pipe failed\n");
- exit(1);
- }
-}
-
-TestCase::~TestCase()
-{
- release_wake_lock(mAppName);
- for (int i = 0; i < 4; ++i) close(mIpc[i]);
- delete mTestTimer;
- delete mOpenTimer;
-}
-
-
-bool TestCase::runTest()
-{
- if (UNKNOWN_TEST == mType)
- {
- fprintf(stderr, "No test set.");
- return false;
- }
- for (size_t p = 0; p < mNproc; ++p)
- {
- pid_t childpid = android::forkOrExit();
-
- if (0 == childpid) { // I am a child, run the test.
- mPid = getpid();
- close(mIpc[READ_FROM_CHILD]);
- close(mIpc[WRITE_TO_CHILD]);
-
- if (kVerbose) printf("Child pid: %d\n", mPid);
- if (!mTestBody(this)) {
- printf("Test failed\n");
- }
- char buffer[32000] = {0,};
- char *str = buffer;
- size_t size_left = sizeof(buffer);
-
- testTimer()->sprint(&str, &size_left);
- if(openTimer()->used()) openTimer()->sprint(&str, &size_left);
- if(readTimer()->used()) readTimer()->sprint(&str, &size_left);
- if(writeTimer()->used()) writeTimer()->sprint(&str, &size_left);
- if(syncTimer()->used()) syncTimer()->sprint(&str, &size_left);
- if(truncateTimer()->used()) truncateTimer()->sprint(&str, &size_left);
- if(traverseTimer()->used()) traverseTimer()->sprint(&str, &size_left);
-
- write(mIpc[TestCase::WRITE_TO_PARENT], buffer, str - buffer);
-
-
- close(mIpc[WRITE_TO_PARENT]);
- close(mIpc[READ_FROM_PARENT]);
- exit(EXIT_SUCCESS);
- }
- }
- // I am the parent process
- close(mIpc[WRITE_TO_PARENT]);
- close(mIpc[READ_FROM_PARENT]);
-
- // Block until all the children have reported for
- // duty. Unblock them so they start the work.
- if (!android::waitForChildrenAndSignal(mNproc, mIpc[READ_FROM_CHILD], mIpc[WRITE_TO_CHILD]))
- {
- exit(1);
- }
-
- // Process the output of each child.
- // TODO: handle EINTR
- char buffer[32000] = {0,};
- while(read(mIpc[READ_FROM_CHILD], buffer, sizeof(buffer)) != 0)
- {
- printf("%s", buffer);
- fflush(stdout);
- memset(buffer, 0, sizeof(buffer));
- }
- // Parent is waiting for children to exit.
- android::waitForChildrenOrExit(mNproc);
- return true;
-}
-
-void TestCase::setIter(size_t iter)
-{
- mIter = iter;
-}
-
-void TestCase::createTimers()
-{
- char total_time[80];
-
- snprintf(total_time, sizeof(total_time), "%s_total", mName);
- mTestTimer = new StopWatch(total_time, 1);
- mTestTimer->setDataSize(dataSize());
-
- mOpenTimer = new StopWatch("open", iter() * kReadWriteFactor);
-
- mReadTimer = new StopWatch("read", iter() * dataSize() / chunkSize() * kReadWriteFactor);
- mReadTimer->setDataSize(dataSize());
-
- mWriteTimer = new StopWatch("write", iter() * dataSize() / chunkSize());
- mWriteTimer->setDataSize(dataSize());
-
- mSyncTimer = new StopWatch("sync", iter());
-
- mTruncateTimer = new StopWatch("truncate", iter());
-
- mTraverseTimer = new StopWatch("traversal", iter());
-}
-
-bool TestCase::setTypeFromName(const char *test_name)
-{
- strcpy(mName, test_name);
- if (strcmp(mName, "write") == 0) mType = WRITE;
- if (strcmp(mName, "read") == 0) mType = READ;
- if (strcmp(mName, "read_write") == 0) mType = READ_WRITE;
- if (strcmp(mName, "open_create") == 0) mType = OPEN_CREATE;
- if (strcmp(mName, "traverse") == 0) mType = TRAVERSE;
-
- return UNKNOWN_TEST != mType;
-}
-
-void TestCase::setSync(Sync s)
-{
- mSync = s;
-}
-
-const char *TestCase::syncAsStr() const
-{
- return mSync == NO_SYNC ? "disabled" : (mSync == FSYNC ? "fsync" : "sync");
-}
-
-void TestCase::setFadvise(const char *advice)
-{
- mFadvice = POSIX_FADV_NORMAL;
- if (strcmp(advice, "sequential") == 0)
- {
- mFadvice = POSIX_FADV_SEQUENTIAL;
- }
- else if (strcmp(advice, "random") == 0)
- {
- mFadvice = POSIX_FADV_RANDOM;
- }
- else if (strcmp(advice, "noreuse") == 0)
- {
- mFadvice = POSIX_FADV_NOREUSE;
- }
- else if (strcmp(advice, "willneed") == 0)
- {
- mFadvice = POSIX_FADV_WILLNEED;
- }
- else if (strcmp(advice, "dontneed") == 0)
- {
- mFadvice = POSIX_FADV_DONTNEED;
- }
-}
-
-const char *TestCase::fadviseAsStr() const
-{
- switch (mFadvice) {
- case POSIX_FADV_NORMAL: return "fadv_normal";
- case POSIX_FADV_SEQUENTIAL: return "fadv_sequential";
- case POSIX_FADV_RANDOM: return "fadv_random";
- case POSIX_FADV_NOREUSE: return "fadv_noreuse";
- case POSIX_FADV_WILLNEED: return "fadv_willneed";
- case POSIX_FADV_DONTNEED: return "fadv_dontneed";
- default: return "fadvice_unknown";
- }
-}
-
-
-} // namespace android_test
diff --git a/tests/sdcard/testcase.h b/tests/sdcard/testcase.h
deleted file mode 100644
index e973d9a7..00000000
--- a/tests/sdcard/testcase.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * 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_