1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.tests.java.lang;
19
20import java.io.File;
21import java.io.IOException;
22import java.io.InputStream;
23import java.io.OutputStream;
24import java.util.ArrayList;
25
26public class ProcessTest extends junit.framework.TestCase {
27
28  public void test_55017() throws Exception {
29    ArrayList<Process> children = new ArrayList<Process>();
30    for (int i = 0; i < 256; ++i) {
31      try {
32        children.add(Runtime.getRuntime().exec(new String[] { "/system/bin/does-not-exist" }, null, null));
33        System.gc();
34      } catch (IOException expected) {
35      }
36    }
37    assertEquals(0, children.size());
38
39    boolean onDevice = new File("/system/bin").exists();
40    String[] psCommand = onDevice ? new String[] { "ps" } : new String[] { "ps", "s" };
41    Process ps = Runtime.getRuntime().exec(psCommand, null, null);
42    int zombieCount = 0;
43    for (String line : readAndCloseStream(ps.getInputStream()).split("\n")) {
44      if (line.contains(" Z ") || line.contains(" Z+ ")) {
45          ++zombieCount;
46      }
47    }
48    assertEquals(0, zombieCount);
49  }
50
51  public void test_getOutputStream() throws Exception {
52    String[] commands = { "cat", "-"};
53    Process p = Runtime.getRuntime().exec(commands, null, null);
54    OutputStream os = p.getOutputStream();
55    // send data, and check if it is echoed back correctly
56    String str1 = "Some data for testing communication between processes\n";
57    String str2 = "More data that serves the same purpose.\n";
58    String str3 = "Here is some more data.\n";
59    os.write(str1.getBytes());
60    try {
61      Thread.sleep(1000);
62    } catch (InterruptedException e) {
63      e.printStackTrace();
64    }
65    os.write(str2.getBytes());
66    os.write(str3.getBytes());
67    os.close();
68
69    String received = readAndCloseStream(p.getInputStream());
70    assertEquals(str1 + str2 + str3, received);
71
72    String stderr = readAndCloseStream(p.getErrorStream());
73    assertEquals("", stderr);
74
75    p.waitFor();
76    p.destroy();
77  }
78
79  public void test_getErrorStream() throws Exception {
80    String[] commands = { "cat", "--no-such-option"};
81    Process p = Runtime.getRuntime().exec(commands, null, null);
82
83    p.getOutputStream().close();
84
85    String received = readAndCloseStream(p.getInputStream());
86    assertEquals("", received);
87
88    String stderr = readAndCloseStream(p.getErrorStream());
89    assertTrue(stderr, stderr.contains("unrecognized option") || stderr.contains("invalid option"));
90
91    p.waitFor();
92    p.destroy();
93  }
94
95  private String readAndCloseStream(InputStream is) throws IOException {
96    StringBuffer result = new StringBuffer();
97    while (true) {
98      int c = is.read();
99      if (c == -1) {
100        break;
101      }
102      result.append((char) c);
103    }
104    is.close();
105    return result.toString();
106  }
107
108  public void test_exitValue() throws Exception {
109    String[] commands = { "ls" };
110    Process process = Runtime.getRuntime().exec(commands, null, null);
111    process.waitFor();
112    assertEquals(0, process.exitValue());
113
114    String[] commandsSleep = { "sleep", "3000" };
115    process = Runtime.getRuntime().exec(commandsSleep, null, null);
116    process.destroy();
117    process.waitFor(); // destroy is asynchronous.
118    assertTrue(process.exitValue() != 0);
119
120    process = Runtime.getRuntime().exec(new String[] { "sleep", "3000" }, null, null);
121    try {
122      process.exitValue();
123      fail();
124    } catch(IllegalThreadStateException expected) {
125    }
126  }
127
128  public void test_destroy() throws Exception {
129    String[] commands = { "ls"};
130    Process process = Runtime.getRuntime().exec(commands, null, null);
131    process.destroy();
132    process.destroy();
133    process.destroy();
134  }
135}
136