Home | History | Annotate | Download | only in lang
      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 
     18 package org.apache.harmony.tests.java.lang;
     19 
     20 import java.io.File;
     21 import java.io.IOException;
     22 import java.io.InputStream;
     23 import java.io.OutputStream;
     24 import java.util.ArrayList;
     25 import libcore.io.Libcore;
     26 import java.util.concurrent.TimeUnit;
     27 
     28 public class ProcessTest extends junit.framework.TestCase {
     29   // Test that failures to exec don't leave zombies lying around.
     30   public void test_55017() throws Exception {
     31     ArrayList<Process> children = new ArrayList<Process>();
     32     for (int i = 0; i < 256; ++i) {
     33       try {
     34         children.add(Runtime.getRuntime().exec(new String[] { "/system/bin/does-not-exist" }, null, null));
     35         System.gc();
     36       } catch (IOException expected) {
     37       }
     38     }
     39     assertEquals(0, children.size());
     40 
     41     String pid = Integer.toString(Libcore.os.getpid());
     42     boolean onDevice = new File("/system/bin").exists();
     43     String[] psCommand = onDevice ? new String[] { "ps", "--ppid", pid }
     44                                   : new String[] { "ps", "S", "--ppid", pid };
     45     Process ps = Runtime.getRuntime().exec(psCommand, null, null);
     46     int zombieCount = 0;
     47     for (String line : readAndCloseStream(ps.getInputStream()).split("\n")) {
     48       if (line.contains(" Z ") || line.contains(" Z+ ")) {
     49         ++zombieCount;
     50       }
     51     }
     52     assertEquals(0, zombieCount);
     53   }
     54 
     55   public void test_getOutputStream() throws Exception {
     56     String[] commands = { "cat", "-"};
     57     Process p = Runtime.getRuntime().exec(commands, null, null);
     58     OutputStream os = p.getOutputStream();
     59     // send data, and check if it is echoed back correctly
     60     String str1 = "Some data for testing communication between processes\n";
     61     String str2 = "More data that serves the same purpose.\n";
     62     String str3 = "Here is some more data.\n";
     63     os.write(str1.getBytes());
     64     try {
     65       Thread.sleep(1000);
     66     } catch (InterruptedException e) {
     67       e.printStackTrace();
     68     }
     69     os.write(str2.getBytes());
     70     os.write(str3.getBytes());
     71     os.close();
     72 
     73     String received = readAndCloseStream(p.getInputStream());
     74     assertEquals(str1 + str2 + str3, received);
     75 
     76     String stderr = readAndCloseStream(p.getErrorStream());
     77     assertEquals("", stderr);
     78 
     79     p.waitFor();
     80     p.destroy();
     81   }
     82 
     83   public void test_getErrorStream() throws Exception {
     84     String[] commands = { "cat", "--no-such-option"};
     85     Process p = Runtime.getRuntime().exec(commands, null, null);
     86 
     87     p.getOutputStream().close();
     88 
     89     String received = readAndCloseStream(p.getInputStream());
     90     assertEquals("", received);
     91 
     92     String stderr = readAndCloseStream(p.getErrorStream());
     93     assertTrue(stderr, stderr.contains("no-such-option"));
     94 
     95     p.waitFor();
     96     p.destroy();
     97   }
     98 
     99   private String readAndCloseStream(InputStream is) throws IOException {
    100     StringBuffer result = new StringBuffer();
    101     while (true) {
    102       int c = is.read();
    103       if (c == -1) {
    104         break;
    105       }
    106       result.append((char) c);
    107     }
    108     is.close();
    109     return result.toString();
    110   }
    111 
    112   public void test_exitValue() throws Exception {
    113     String[] commands = { "sh", "-c", "exit 0" };
    114     Process process = Runtime.getRuntime().exec(commands, null, null);
    115     process.waitFor();
    116     assertEquals(0, process.exitValue());
    117 
    118     String[] commandsNonZeroExit = { "sh", "-c", "exit 34" };
    119     process = Runtime.getRuntime().exec(commandsNonZeroExit, null, null);
    120     process.waitFor();
    121     assertEquals(34, process.exitValue());
    122 
    123     String[] commandsSleep = { "sleep", "3000" };
    124     process = Runtime.getRuntime().exec(commandsSleep, null, null);
    125     process.destroy();
    126     process.waitFor(); // destroy is asynchronous.
    127     assertTrue(process.exitValue() != 0);
    128 
    129     process = Runtime.getRuntime().exec(new String[] { "sleep", "3000" }, null, null);
    130     try {
    131       process.exitValue();
    132       fail();
    133     } catch(IllegalThreadStateException expected) {
    134     }
    135   }
    136 
    137   public void test_destroy() throws Exception {
    138     String[] commands = { "sh", "-c", "exit 0"};
    139     Process process = Runtime.getRuntime().exec(commands, null, null);
    140     process.destroy();
    141     process.destroy();
    142     process.destroy();
    143   }
    144 
    145   public void test_destroyForcibly() throws Exception {
    146     String[] commands = { "sh", "-c", "sleep 3000"};
    147     Process process = Runtime.getRuntime().exec(commands, null, null);
    148     assertNotNull(process.destroyForcibly());
    149     process.waitFor(); // destroy is asynchronous.
    150     assertTrue(process.exitValue() != 0);
    151   }
    152 
    153   public void test_isAlive() throws Exception {
    154     String[] commands = { "sh", "-c", "sleep 3000"};
    155     Process process = Runtime.getRuntime().exec(commands, null, null);
    156     assertTrue(process.isAlive());
    157     assertNotNull(process.destroyForcibly());
    158     process.waitFor(); // destroy is asynchronous.
    159     assertFalse(process.isAlive());
    160   }
    161 
    162   public void test_waitForTimeout() throws Exception {
    163     String[] commands = { "sh", "-c", "sleep 3000"};
    164     Process process = Runtime.getRuntime().exec(commands, null, null);
    165     assertFalse(process.waitFor(0, TimeUnit.MICROSECONDS));
    166     assertTrue(process.isAlive());
    167     assertFalse(process.waitFor(500, TimeUnit.MICROSECONDS));
    168     assertTrue(process.isAlive());
    169     assertNotNull(process.destroyForcibly());
    170     assertTrue(process.waitFor(2, TimeUnit.SECONDS));
    171     assertFalse(process.isAlive());
    172   }
    173 
    174   public void test_waitForTimeout_NPE() throws Exception {
    175     String[] commands = { "sh", "-c", "sleep 3000"};
    176     Process process = Runtime.getRuntime().exec(commands, null, null);
    177     try {
    178       process.waitFor(500, null);
    179       fail();
    180     } catch(NullPointerException expected) {}
    181     assertNotNull(process.destroyForcibly());
    182     process.waitFor();
    183   }
    184 
    185 }
    186