1/*
2 * Copyright (C) 2007 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 tests.api.java.lang;
18
19import dalvik.annotation.BrokenTest;
20
21import junit.framework.TestCase;
22
23import java.io.BufferedReader;
24import java.io.File;
25import java.io.FileInputStream;
26import java.io.IOException;
27import java.io.InputStream;
28import java.io.InputStreamReader;
29import java.io.OutputStream;
30
31public class ProcessManagerTest extends TestCase {
32
33    Thread thread = null;
34    Process process = null;
35    boolean isThrown = false;
36
37    public void testCat() throws IOException, InterruptedException {
38        String[] commands = { "cat" };
39        Process process = Runtime.getRuntime().exec(commands, null, null);
40
41        OutputStream out = process.getOutputStream();
42        String greeting = "Hello, World!";
43        out.write(greeting.getBytes());
44        out.write('\n');
45        out.close();
46
47        assertEquals(greeting, readLine(process));
48    }
49
50    @BrokenTest("Sporadic failures in CTS, but not in CoreTestRunner")
51    public void testSleep() throws IOException {
52        String[] commands = { "sleep", "1" };
53        process = Runtime.getRuntime().exec(commands, null, null);
54        try {
55            assertEquals(0, process.waitFor());
56
57        } catch(InterruptedException ie) {
58            fail("InterruptedException was thrown.");
59        }
60
61        isThrown = false;
62        thread = new Thread() {
63            public void run() {
64                String[] commands = { "sleep", "1000"};
65                try {
66                    process = Runtime.getRuntime().exec(commands, null, null);
67                } catch (IOException e1) {
68                    fail("IOException was thrown.");
69                }
70                try {
71                    process.waitFor();
72                    fail("InterruptedException was not thrown.");
73                } catch(InterruptedException ie) {
74                    isThrown = true;
75                }
76            }
77        };
78
79        Thread interruptThread = new Thread() {
80            public void run() {
81                try {
82                    sleep(10);
83                } catch(InterruptedException ie) {
84                    fail("InterruptedException was thrown in " +
85                            "the interruptThread.");
86                }
87                thread.interrupt();
88            }
89        };
90        thread.start();
91        interruptThread.start();
92        try {
93            interruptThread.join();
94        } catch (InterruptedException e) {
95            fail("InterruptedException was thrown.");
96        }
97        try {
98            Thread.sleep(100);
99        } catch(InterruptedException ie) {
100
101        }
102
103        thread.interrupt();
104        //process.destroy();
105        try {
106            Thread.sleep(100);
107        } catch(InterruptedException ie) {
108
109        }
110
111        assertTrue(isThrown);
112    }
113
114    public void testPwd() throws IOException, InterruptedException {
115        String[] commands = { "sh", "-c", "pwd" };
116        Process process = Runtime.getRuntime().exec(
117                commands, null, new File("/"));
118        logErrors(process);
119        assertEquals("/", readLine(process));
120    }
121
122    public void testEnvironment() throws IOException, InterruptedException {
123        String[] commands = { "sh", "-c", "echo $FOO" };
124
125        // Remember to set the path so we can find sh.
126        String[] environment = { "FOO=foo", "PATH=" + System.getenv("PATH") };
127        Process process = Runtime.getRuntime().exec(
128                commands, environment, null);
129        logErrors(process);
130        assertEquals("foo", readLine(process));
131    }
132
133    String readLine(Process process) throws IOException {
134        InputStream in = process.getInputStream();
135        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
136        return reader.readLine();
137    }
138
139    void logErrors(final Process process) throws IOException {
140        Thread thread = new Thread() {
141            public void run() {
142                InputStream in = process.getErrorStream();
143                BufferedReader reader
144                        = new BufferedReader(new InputStreamReader(in));
145                String line;
146                try {
147                    while ((line = reader.readLine()) != null) {
148                        System.err.println(line);
149                    }
150                } catch (IOException e) {
151                    e.printStackTrace();
152                }
153            }
154        };
155        thread.setDaemon(true);
156        thread.start();
157    }
158
159    public void testHeavyLoad() {
160        int i;
161        for (i = 0; i < 100; i++)
162            stuff();
163    }
164
165    private static void stuff() {
166        Runtime rt = Runtime.getRuntime();
167        try {
168            Process proc = rt.exec("ls");
169            proc.waitFor();
170            proc = null;
171        } catch (Exception ex) {
172            System.err.println("Failure: " + ex);
173            throw new RuntimeException(ex);
174        }
175        rt.gc();
176        rt = null;
177    }
178
179    InputStream in;
180
181    public void testCloseNonStandardFds()
182            throws IOException, InterruptedException {
183        String[] commands = { "ls", "/proc/self/fd" };
184
185        Process process = Runtime.getRuntime().exec(commands, null, null);
186        int before = countLines(process);
187
188        // Open a new fd.
189        this.in = new FileInputStream("/proc/version");
190
191        try {
192            process = Runtime.getRuntime().exec(commands, null, null);
193            int after = countLines(process);
194
195            // Assert that the new fd wasn't open in the second run.
196            assertEquals(before, after);
197        } finally {
198            this.in = null;
199        }
200    }
201
202    /**
203     * Counts lines of input from the given process. Equivalent to "wc -l".
204     */
205    private int countLines(Process process) throws IOException {
206        logErrors(process);
207        InputStream in = process.getInputStream();
208        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
209        int count = 0;
210        while (reader.readLine() != null) {
211            count++;
212        }
213        return count;
214    }
215
216    public void testInvalidCommand()
217            throws IOException, InterruptedException {
218        try {
219            String[] commands = { "doesnotexist" };
220            Runtime.getRuntime().exec(commands, null, null);
221        } catch (IOException e) { /* expected */ }
222    }
223}
224