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