1/*
2 * Copyright (C) 2009 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
19import android.app.Activity;
20import android.content.Intent;
21import android.os.Handler;
22import android.os.Message;
23import android.test.ActivityInstrumentationTestCase2;
24import android.util.Log;
25
26import java.io.BufferedOutputStream;
27import java.io.BufferedReader;
28import java.io.File;
29import java.io.FileNotFoundException;
30import java.io.FileOutputStream;
31import java.io.FileReader;
32import java.io.IOException;
33import java.io.InputStream;
34import java.io.OutputStream;
35
36public class ReliabilityTest extends ActivityInstrumentationTestCase2<ReliabilityTestActivity> {
37
38    private static final String LOGTAG = "ReliabilityTest";
39    private static final String PKG_NAME = "com.android.dumprendertree";
40    private static final String TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt";
41    private static final String TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt";
42    private static final String TEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt";
43    private static final String TEST_LOAD_TIME_FILE = "/sdcard/android/reliability_load_time.txt";
44    private static final String TEST_DONE = "#DONE";
45    static final String RELIABILITY_TEST_RUNNER_FILES[] = {
46        "run_reliability_tests.py"
47    };
48
49    public ReliabilityTest() {
50        super(PKG_NAME, ReliabilityTestActivity.class);
51    }
52
53    public void runReliabilityTest() throws Throwable {
54//        ReliabilityTestActivity activity = getActivity();
55        LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner)getInstrumentation();
56
57        File testListFile = new File(TEST_LIST_FILE);
58        if(!testListFile.exists())
59            throw new FileNotFoundException("test list file not found.");
60
61        BufferedReader listReader = new BufferedReader(
62                new FileReader(testListFile));
63
64        //always try to resume first, hence cleaning up status will be the
65        //responsibility of driver scripts
66        String lastUrl = FsUtils.readTestStatus(TEST_STATUS_FILE);
67        if(lastUrl != null && !TEST_DONE.equals(lastUrl))
68            fastForward(listReader, lastUrl);
69
70        String url = null;
71        Handler handler = null;
72        boolean timeoutFlag = false;
73        long start, elapsed;
74
75        Intent intent = new Intent(runner.getContext(), ReliabilityTestActivity.class);
76        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
77        ReliabilityTestActivity activity = (ReliabilityTestActivity)runner.startActivitySync(
78            intent);
79        //read from BufferedReader instead of populating a list in advance,
80        //this will avoid excessive memory usage in case of a large list
81        while((url = listReader.readLine()) != null) {
82            url = url.trim();
83            if(url.length() == 0)
84                continue;
85            start = System.currentTimeMillis();
86            Log.v(LOGTAG, "Testing URL: " + url);
87            FsUtils.updateTestStatus(TEST_STATUS_FILE, url);
88            activity.reset();
89            //use message to send new URL to avoid interacting with
90            //WebView in non-UI thread
91            handler = activity.getHandler();
92            Message msg = handler.obtainMessage(
93                    ReliabilityTestActivity.MSG_NAVIGATE,
94                    runner.mTimeoutInMillis, runner.mDelay);
95            msg.getData().putString(ReliabilityTestActivity.MSG_NAV_URL, url);
96            msg.getData().putBoolean(ReliabilityTestActivity.MSG_NAV_LOGTIME,
97                    runner.mLogtime);
98            handler.sendMessage(msg);
99            timeoutFlag = activity.waitUntilDone();
100            elapsed = System.currentTimeMillis() - start;
101            if(elapsed < 1000) {
102                Log.w(LOGTAG, "Page load finished in " + elapsed
103                        + "ms, too soon?");
104            } else {
105                Log.v(LOGTAG, "Page load finished in " + elapsed + "ms");
106            }
107            if(timeoutFlag) {
108                writeTimeoutFile(url);
109            }
110            if(runner.mLogtime) {
111                writeLoadTime(url, activity.getPageLoadTime());
112            }
113            System.runFinalization();
114            System.gc();
115            System.gc();
116        }
117        activity.finish();
118        FsUtils.updateTestStatus(TEST_STATUS_FILE, TEST_DONE);
119//        activity.finish();
120        listReader.close();
121    }
122
123    public void copyRunnerAssetsToCache() {
124        try {
125            String out_dir = getActivity().getApplicationContext()
126            .getCacheDir().getPath() + "/";
127
128            for( int i=0; i< RELIABILITY_TEST_RUNNER_FILES.length; i++) {
129                InputStream in = getActivity().getAssets().open(
130                        RELIABILITY_TEST_RUNNER_FILES[i]);
131                OutputStream out = new FileOutputStream(
132                        out_dir + RELIABILITY_TEST_RUNNER_FILES[i]);
133
134                byte[] buf = new byte[2048];
135                int len;
136
137                while ((len = in.read(buf)) >= 0 ) {
138                    out.write(buf, 0, len);
139                }
140                out.close();
141                in.close();
142            }
143        }catch (IOException e) {
144            Log.e(LOGTAG, "Cannot extract scripts for testing.", e);
145        }
146    }
147
148    private void fastForward(BufferedReader testListReader, String lastUrl) {
149        //fastforward the BufferedReader to the position right after last url
150        if(lastUrl == null)
151            return;
152
153        String line = null;
154        try {
155            while((line = testListReader.readLine()) != null) {
156                if(lastUrl.equals(line))
157                    return;
158            }
159        } catch (IOException ioe) {
160            Log.e(LOGTAG, "Error while reading test list.", ioe);
161            return;
162        }
163    }
164
165    private void writeTimeoutFile(String s) {
166        //append to the file containing the list of timeout urls
167        try {
168            BufferedOutputStream bos = new BufferedOutputStream(
169                    new FileOutputStream(TEST_TIMEOUT_FILE, true));
170            bos.write(s.getBytes());
171            bos.write('\n');
172            bos.close();
173        } catch (Exception e) {
174            Log.e(LOGTAG, "Cannot update file " + TEST_TIMEOUT_FILE, e);
175        }
176    }
177
178    private void writeLoadTime(String s, long time) {
179        //append to the file containing the list of timeout urls
180        try {
181            BufferedOutputStream bos = new BufferedOutputStream(
182                    new FileOutputStream(TEST_LOAD_TIME_FILE, true));
183            bos.write((s + '|' + time + '\n').getBytes());
184            bos.close();
185        } catch (Exception e) {
186            Log.e(LOGTAG, "Cannot update file " + TEST_LOAD_TIME_FILE, e);
187        }
188    }
189}
190