blob: ee5bb5df29303fc5951aea0e5f3c0bff9262059b [file] [log] [blame]
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dumprendertree;
18
Guang Zhuf6d1b3f2011-04-26 16:41:13 -070019import com.android.dumprendertree.forwarder.AdbUtils;
20import com.android.dumprendertree.forwarder.ForwardServer;
21
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070022import android.app.Instrumentation;
Guang Zhu00069522010-12-06 11:17:38 -080023import android.content.Context;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070024import android.content.Intent;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070025import android.os.Bundle;
Guang Zhub933f6692009-05-05 01:02:14 -070026import android.os.Debug;
Christian Mehlmauer8b85dce2010-07-19 20:11:27 +020027import android.os.Environment;
Guang Zhu40656be2009-06-30 11:56:13 -070028import android.os.Process;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070029import android.test.ActivityInstrumentationTestCase2;
Guang Zhu40656be2009-06-30 11:56:13 -070030import android.util.Log;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070031
Guang Zhu00069522010-12-06 11:17:38 -080032import java.io.File;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070033import java.io.FileOutputStream;
34import java.io.IOException;
Guang Zhub933f6692009-05-05 01:02:14 -070035import java.io.InputStream;
36import java.io.OutputStream;
37import java.io.PrintStream;
Guang Zhu5794f232011-01-25 15:43:57 -080038import java.util.concurrent.CountDownLatch;
39import java.util.concurrent.TimeUnit;
Guang Zhuf6d1b3f2011-04-26 16:41:13 -070040import java.util.regex.Matcher;
41import java.util.regex.Pattern;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070042
43public class LoadTestsAutoTest extends ActivityInstrumentationTestCase2<TestShellActivity> {
44
45 private final static String LOGTAG = "LoadTest";
Christian Mehlmauer8b85dce2010-07-19 20:11:27 +020046 private final static String LOAD_TEST_RESULT =
47 Environment.getExternalStorageDirectory() + "/load_test_result.txt";
Guang Zhu5794f232011-01-25 15:43:57 -080048 private final static int MAX_GC_WAIT_SEC = 10;
Guang Zhuf6d1b3f2011-04-26 16:41:13 -070049 private final static int LOCAL_PORT = 17171;
Guang Zhub933f6692009-05-05 01:02:14 -070050 private boolean mFinished;
51 static final String LOAD_TEST_RUNNER_FILES[] = {
52 "run_page_cycler.py"
Guang Zhu4010ac32009-04-29 14:49:03 -070053 };
Guang Zhuf6d1b3f2011-04-26 16:41:13 -070054 private ForwardServer mForwardServer;
Guang Zhub933f6692009-05-05 01:02:14 -070055
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070056 public LoadTestsAutoTest() {
Guang Zhuf6d1b3f2011-04-26 16:41:13 -070057 super(TestShellActivity.class);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070058 }
59
60 // This function writes the result of the layout test to
61 // Am status so that it can be picked up from a script.
62 public void passOrFailCallback(String file, boolean result) {
63 Instrumentation inst = getInstrumentation();
64 Bundle bundle = new Bundle();
65 bundle.putBoolean(file, result);
66 inst.sendStatus(0, bundle);
67 }
Guang Zhub933f6692009-05-05 01:02:14 -070068
Guang Zhuf6d1b3f2011-04-26 16:41:13 -070069 private String setUpForwarding(String forwardInfo, String suite, String iteration) throws IOException {
70 // read forwarding information first
71 Pattern forwardPattern = Pattern.compile("(.*):(\\d+)/(.*)/");
72 Matcher matcher = forwardPattern.matcher(forwardInfo);
73 if (!matcher.matches()) {
74 throw new RuntimeException("Invalid forward information");
75 }
76 String host = matcher.group(1);
77 int port = Integer.parseInt(matcher.group(2));
78 mForwardServer = new ForwardServer(LOCAL_PORT, AdbUtils.resolve(host), port);
79 mForwardServer.start();
80 return String.format("http://127.0.0.1:%d/%s/%s/start.html?auto=1&iterations=%s",
81 LOCAL_PORT, matcher.group(3), suite, iteration);
82 }
83
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070084 // Invokes running of layout tests
85 // and waits till it has finished running.
Guang Zhuf6d1b3f2011-04-26 16:41:13 -070086 public void runPageCyclerTest() throws IOException {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070087 LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner) getInstrumentation();
88
Guang Zhuf6d1b3f2011-04-26 16:41:13 -070089 if (runner.mPageCyclerSuite != null) {
90 // start forwarder to use page cycler suites hosted on external web server
91 if (runner.mPageCyclerForwardHost == null) {
92 throw new RuntimeException("no forwarder information provided");
93 }
94 runner.mTestPath = setUpForwarding(runner.mPageCyclerForwardHost,
95 runner.mPageCyclerSuite, runner.mPageCyclerIteration);
96 Log.d(LOGTAG, "using path: " + runner.mTestPath);
97 }
98
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070099 if (runner.mTestPath == null) {
Guang Zhuf6d1b3f2011-04-26 16:41:13 -0700100 throw new RuntimeException("No test specified");
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700101 }
Guang Zhub933f6692009-05-05 01:02:14 -0700102
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700103 TestShellActivity activity = (TestShellActivity) getActivity();
104
Guang Zhu2a197b12009-05-18 14:37:23 -0700105 Log.v(LOGTAG, "About to run tests, calling gc first...");
Guang Zhu40656be2009-06-30 11:56:13 -0700106 freeMem();
Guang Zhu2a197b12009-05-18 14:37:23 -0700107
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700108 // Run tests
Guang Zhu5dc4f212009-10-29 18:24:54 -0700109 runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis,
110 runner.mGetDrawTime, runner.mSaveImagePath);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700111
Guang Zhu889181d2009-07-09 12:55:15 -0700112 activity.clearCache();
Guang Zhuf6d1b3f2011-04-26 16:41:13 -0700113 if (mForwardServer != null) {
114 mForwardServer.stop();
115 mForwardServer = null;
116 }
Guang Zhu1f6c72b2009-07-17 14:22:24 -0700117 try {
118 Thread.sleep(5000);
119 } catch (InterruptedException e) {
120 }
Guang Zhub933f6692009-05-05 01:02:14 -0700121 dumpMemoryInfo();
122
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700123 // Kill activity
124 activity.finish();
125 }
126
Guang Zhu40656be2009-06-30 11:56:13 -0700127 private void freeMem() {
Guang Zhu3974be62011-01-18 18:04:34 -0800128 Log.v(LOGTAG, "freeMem: calling gc...");
Guang Zhu5794f232011-01-25 15:43:57 -0800129 final CountDownLatch latch = new CountDownLatch(1);
Guang Zhuf6d1b3f2011-04-26 16:41:13 -0700130 @SuppressWarnings("unused")
Guang Zhu5794f232011-01-25 15:43:57 -0800131 Object dummy = new Object() {
Guang Zhuf6d1b3f2011-04-26 16:41:13 -0700132 // this object instance is used to track gc
Guang Zhu5794f232011-01-25 15:43:57 -0800133 @Override
134 protected void finalize() throws Throwable {
135 latch.countDown();
136 super.finalize();
137 }
138 };
139 dummy = null;
140 System.gc();
141 try {
142 if (!latch.await(MAX_GC_WAIT_SEC, TimeUnit.SECONDS)) {
143 Log.w(LOGTAG, "gc did not happen in 10s");
144 }
145 } catch (InterruptedException e) {
146 //ignore
147 }
Guang Zhu40656be2009-06-30 11:56:13 -0700148 }
149
150 private void printRow(PrintStream ps, String format, Object...objs) {
151 ps.println(String.format(format, objs));
152 }
153
Guang Zhub933f6692009-05-05 01:02:14 -0700154 private void dumpMemoryInfo() {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700155 try {
Guang Zhu40656be2009-06-30 11:56:13 -0700156 freeMem();
Guang Zhub933f6692009-05-05 01:02:14 -0700157 Log.v(LOGTAG, "Dumping memory information.");
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700158
Guang Zhub933f6692009-05-05 01:02:14 -0700159 FileOutputStream out = new FileOutputStream(LOAD_TEST_RESULT, true);
160 PrintStream ps = new PrintStream(out);
161
Guang Zhub933f6692009-05-05 01:02:14 -0700162 ps.print("\n\n\n");
Guang Zhu40656be2009-06-30 11:56:13 -0700163 ps.println("** MEMINFO in pid " + Process.myPid()
164 + " [com.android.dumprendertree] **");
165 String formatString = "%17s %8s %8s %8s %8s";
166
167 long nativeMax = Debug.getNativeHeapSize() / 1024;
168 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
169 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
170 Runtime runtime = Runtime.getRuntime();
171 long dalvikMax = runtime.totalMemory() / 1024;
172 long dalvikFree = runtime.freeMemory() / 1024;
173 long dalvikAllocated = dalvikMax - dalvikFree;
174
175
176 Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
177 Debug.getMemoryInfo(memInfo);
178
179 final int nativeShared = memInfo.nativeSharedDirty;
180 final int dalvikShared = memInfo.dalvikSharedDirty;
181 final int otherShared = memInfo.otherSharedDirty;
182
183 final int nativePrivate = memInfo.nativePrivateDirty;
184 final int dalvikPrivate = memInfo.dalvikPrivateDirty;
185 final int otherPrivate = memInfo.otherPrivateDirty;
186
187 printRow(ps, formatString, "", "native", "dalvik", "other", "total");
188 printRow(ps, formatString, "size:", nativeMax, dalvikMax, "N/A", nativeMax + dalvikMax);
189 printRow(ps, formatString, "allocated:", nativeAllocated, dalvikAllocated, "N/A",
190 nativeAllocated + dalvikAllocated);
191 printRow(ps, formatString, "free:", nativeFree, dalvikFree, "N/A",
192 nativeFree + dalvikFree);
193
194 printRow(ps, formatString, "(Pss):", memInfo.nativePss, memInfo.dalvikPss,
195 memInfo.otherPss, memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss);
196
197 printRow(ps, formatString, "(shared dirty):", nativeShared, dalvikShared, otherShared,
198 nativeShared + dalvikShared + otherShared);
199 printRow(ps, formatString, "(priv dirty):", nativePrivate, dalvikPrivate, otherPrivate,
200 nativePrivate + dalvikPrivate + otherPrivate);
Guang Zhub933f6692009-05-05 01:02:14 -0700201 ps.print("\n\n\n");
202 ps.flush();
203 ps.close();
204 out.flush();
205 out.close();
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700206 } catch (IOException e) {
207 Log.e(LOGTAG, e.getMessage());
Guang Zhub933f6692009-05-05 01:02:14 -0700208 }
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700209 }
Guang Zhub933f6692009-05-05 01:02:14 -0700210
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700211 // A convenient method to be called by another activity.
Guang Zhu5dc4f212009-10-29 18:24:54 -0700212 private void runTestAndWaitUntilDone(TestShellActivity activity, String url, int timeout,
213 boolean getDrawTime, String saveImagePath) {
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700214 activity.setCallback(new TestShellCallback() {
215 public void finished() {
216 synchronized (LoadTestsAutoTest.this) {
Guang Zhub933f6692009-05-05 01:02:14 -0700217 mFinished = true;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700218 LoadTestsAutoTest.this.notifyAll();
219 }
Guang Zhub933f6692009-05-05 01:02:14 -0700220 }
Guang Zhu40656be2009-06-30 11:56:13 -0700221
Guang Zhu4010ac32009-04-29 14:49:03 -0700222 public void timedOut(String url) {
223 }
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700224 });
Guang Zhub933f6692009-05-05 01:02:14 -0700225
226 mFinished = false;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700227 Intent intent = new Intent(Intent.ACTION_VIEW);
228 intent.setClass(activity, TestShellActivity.class);
229 intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
230 intent.putExtra(TestShellActivity.TEST_URL, url);
231 intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout);
232 intent.putExtra(TestShellActivity.RESULT_FILE, LOAD_TEST_RESULT);
Guang Zhu5dc4f212009-10-29 18:24:54 -0700233 intent.putExtra(TestShellActivity.GET_DRAW_TIME, getDrawTime);
234 if (saveImagePath != null)
235 intent.putExtra(TestShellActivity.SAVE_IMAGE, saveImagePath);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700236 activity.startActivity(intent);
Guang Zhub933f6692009-05-05 01:02:14 -0700237
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700238 // Wait until done.
239 synchronized (this) {
Guang Zhub933f6692009-05-05 01:02:14 -0700240 while(!mFinished) {
241 try {
242 this.wait();
243 } catch (InterruptedException e) { }
244 }
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700245 }
Guang Zhub933f6692009-05-05 01:02:14 -0700246 }
247
248 public void copyRunnerAssetsToCache() {
249 try {
Guang Zhu00069522010-12-06 11:17:38 -0800250 Context targetContext = getInstrumentation().getTargetContext();
251 File cacheDir = targetContext.getCacheDir();
Guang Zhub933f6692009-05-05 01:02:14 -0700252
253 for( int i=0; i< LOAD_TEST_RUNNER_FILES.length; i++) {
Guang Zhu00069522010-12-06 11:17:38 -0800254 InputStream in = targetContext.getAssets().open(
Guang Zhub933f6692009-05-05 01:02:14 -0700255 LOAD_TEST_RUNNER_FILES[i]);
256 OutputStream out = new FileOutputStream(
Guang Zhu00069522010-12-06 11:17:38 -0800257 new File(cacheDir, LOAD_TEST_RUNNER_FILES[i]));
Guang Zhub933f6692009-05-05 01:02:14 -0700258
259 byte[] buf = new byte[2048];
260 int len;
261
262 while ((len = in.read(buf)) >= 0 ) {
263 out.write(buf, 0, len);
264 }
265 out.close();
266 in.close();
267 }
268 }catch (IOException e) {
269 e.printStackTrace();
270 }
271
272 }
273
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700274}