View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.commons.exec.issues;
21  
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  
26  import java.io.File;
27  
28  import org.apache.commons.exec.CommandLine;
29  import org.apache.commons.exec.DefaultExecuteResultHandler;
30  import org.apache.commons.exec.DefaultExecutor;
31  import org.apache.commons.exec.ExecuteWatchdog;
32  import org.apache.commons.exec.Executor;
33  import org.apache.commons.exec.TestUtil;
34  import org.junit.jupiter.api.Test;
35  
36  /**
37   * EXEC-34 https://issues.apache.org/jira/browse/EXEC-34
38   */
39  class Exec34Test {
40  
41      private final Executor exec = DefaultExecutor.builder().get();
42      private final File testDir = new File("src/test/scripts");
43      private final File pingScript = TestUtil.resolveScriptFileForOS(testDir + "/ping");
44  
45      /**
46       *
47       * Race condition prevent watchdog working using ExecuteStreamHandler. The test fails because when watchdog.destroyProcess() is invoked the external process
48       * is not bound to the watchdog yet.
49       *
50       * @throws Exception the test failed
51       */
52      @Test
53      void testExec34Part1() throws Exception {
54  
55          final CommandLine cmdLine = new CommandLine(pingScript);
56          cmdLine.addArgument("10"); // sleep 10 seconds
57  
58          final ExecuteWatchdog watchdog = new ExecuteWatchdog(Integer.MAX_VALUE);
59          final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
60          exec.setWatchdog(watchdog);
61          exec.execute(cmdLine, handler);
62          assertTrue(watchdog.isWatching());
63          watchdog.destroyProcess();
64          assertTrue(watchdog.killedProcess(), "Watchdog should have killed the process");
65          assertFalse(watchdog.isWatching(), "Watchdog is no longer watching the process");
66      }
67  
68      /**
69       * Some user waited for an asynchronous process using watchdog.isWatching() which is now properly implemented using {@code DefaultExecuteResultHandler}.
70       *
71       * @throws Exception the test failed
72       */
73      @Test
74      void testExec34Part2() throws Exception {
75  
76          final CommandLine cmdLine = new CommandLine(pingScript);
77          cmdLine.addArgument("10"); // sleep 10 seconds
78  
79          final ExecuteWatchdog watchdog = new ExecuteWatchdog(5000);
80          final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
81          exec.setWatchdog(watchdog);
82          exec.execute(cmdLine, handler);
83          handler.waitFor();
84          assertTrue(handler.hasResult(), "Process has exited");
85          assertNotNull(handler.getException(), "Process was aborted");
86          assertTrue(watchdog.killedProcess(), "Watchdog should have killed the process");
87          assertFalse(watchdog.isWatching(), "Watchdog is no longer watching the process");
88      }
89  }