blob: b55cf409bf737b4ca99d27b92e76e7cad1022db3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ace.processlauncher.test.impl;
import static org.apache.ace.processlauncher.test.impl.TestUtil.createTempDir;
import static org.apache.ace.processlauncher.test.impl.TestUtil.getOSName;
import static org.apache.ace.processlauncher.test.impl.TestUtil.sleep;
import static org.apache.ace.test.utils.TestUtils.UNIT;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.io.File;
import org.apache.ace.processlauncher.LaunchConfiguration;
import org.apache.ace.processlauncher.impl.LaunchConfigurationImpl;
import org.apache.ace.processlauncher.impl.ProcessManager;
import org.apache.ace.processlauncher.impl.ProcessManagerImpl;
import org.apache.ace.test.utils.TestUtils;
import org.osgi.service.log.LogService;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
/**
* Test cases for {@link ProcessManager}.
*/
public class ProcessManagerImplTest {
private ProcessManagerImpl m_processManager;
/**
* Tests that launching a simple process works for a UNIX-derived operating system.
*
* @throws Exception not part of this test case.
*/
@Test(groups = { UNIT })
public void testLaunchProcessOnUnixDerivativeOk() throws Exception {
// This test will not work on Windows!
if (getOSName().contains("windows")) {
return;
}
LaunchConfiguration launchConfig = createLaunchConfiguration("/bin/sh", "-c", "sleep 1 && exit 1");
int processCountBefore = m_processManager.getRunningProcessesCount();
m_processManager.launch("myPid", launchConfig);
// make sure we sleep a little to ensure the process is started
sleep(100);
int processCountAfter = m_processManager.getRunningProcessesCount();
assertTrue(processCountAfter > processCountBefore);
assertEquals(processCountAfter, m_processManager.getRunningProcessesCount());
// make sure we sleep a little longer to allow the process to finish...
sleep(1000);
assertEquals(processCountBefore, m_processManager.getRunningProcessesCount());
}
/**
* Tests that launching a simple process works for a Windows operating system.
*
* @throws Exception not part of this test case.
*/
@Test(groups = { UNIT })
public void testLaunchProcessOnWindowsOk() throws Exception {
// This test will only work on Windows!
if (!getOSName().contains("windows")) {
return;
}
LaunchConfiguration launchConfig = createLaunchConfiguration("PING", "-n", "2", "127.0.0.1");
int processCountBefore = m_processManager.getRunningProcessesCount();
m_processManager.launch("myPid", launchConfig);
// make sure we sleep a little to ensure the process is started
sleep(100);
int processCountAfter = m_processManager.getRunningProcessesCount();
assertTrue(processCountAfter > processCountBefore);
assertEquals(processCountAfter, m_processManager.getRunningProcessesCount());
// make sure we sleep a little longer to allow the process to finish...
sleep(1000);
assertEquals(processCountBefore, m_processManager.getRunningProcessesCount());
}
/**
* Tests that respawning a simple process works for a UNIX-derived operating system.
*
* @throws Exception not part of this test case.
*/
@Test(groups = { UNIT })
public void testRespawnProcessOnUnixDerivativeOk() throws Exception {
// This test will not work on Windows!
if (getOSName().contains("windows")) {
return;
}
int count = 2;
File tmpFile = File.createTempFile("ace", null);
String tmpFilename = tmpFile.getAbsolutePath();
// Seems daunting, but what this command does is simply count the number
// of lines in a given file (= tmpFile), and append this to that same
// file; it uses this number to create an exit value, which counts from
// <count> back to 0. This way, we can test whether the respawn
// functionality works, as this currently checks for certain exit
// values...
String script =
String.format("L=$(cat %1$s | wc -l)" + "&& echo $L >> %1$s && exit $((%2$d-$L))", tmpFilename, count);
LaunchConfiguration launchConfig =
createLaunchConfiguration(true /* respawnAutomatically */, "/bin/bash", "-c", script);
int processCountBefore = m_processManager.getRunningProcessesCount();
m_processManager.launch("myPid", launchConfig);
// sleep a little to ensure the process is started...
sleep(10);
assertEquals(processCountBefore + 1, m_processManager.getRunningProcessesCount());
// make sure we sleep a little longer to allow the process to finish...
sleep(500);
assertEquals(processCountBefore, m_processManager.getRunningProcessesCount());
String testResult = TestUtil.slurpFile(tmpFile);
assertTrue(testResult.matches("(?s)^0\n1\n2\n$"), testResult);
}
/**
* Tests that terminating all running processes works.
*
* @throws Exception not part of this test case.
*/
@Test(groups = { UNIT })
public void testShutdownOnUnixDerivativeOk() throws Exception {
// This test will not work on Windows!
if (getOSName().contains("windows")) {
return;
}
LaunchConfiguration launchConfig = createLaunchConfiguration("/bin/sh", "-c", "sleep 10");
int processCountBefore = m_processManager.getRunningProcessesCount();
for (int i = 0; i < 5; i++) {
m_processManager.launch(String.format("myPid%d", i), launchConfig);
}
// make sure we sleep a little to ensure the processes are started
sleep(100);
int processCountAfter = m_processManager.getRunningProcessesCount();
assertTrue(processCountAfter > processCountBefore);
// Shut down the process manager; should terminate all running
// processes...
m_processManager.shutdown();
assertEquals(processCountBefore, m_processManager.getRunningProcessesCount());
}
/**
* Tests that terminating all running processes works.
*
* @throws Exception not part of this test case.
*/
@Test(groups = { UNIT })
public void testShutdownOnWindowsOk() throws Exception {
// This test will only work on Windows!
if (!getOSName().contains("windows")) {
return;
}
LaunchConfiguration launchConfig = createLaunchConfiguration("PING", "-n", "11", "127.0.0.1");
int processCountBefore = m_processManager.getRunningProcessesCount();
for (int i = 0; i < 5; i++) {
m_processManager.launch(String.format("myPid%d", i), launchConfig);
}
// make sure we sleep a little to ensure the processes are started
sleep(100);
int processCountAfter = m_processManager.getRunningProcessesCount();
assertTrue(processCountAfter > processCountBefore);
// Shut down the process manager; should terminate all running
// processes...
m_processManager.shutdown();
assertEquals(processCountBefore, m_processManager.getRunningProcessesCount());
}
/**
* Tests that terminating a single process works.
*
* @throws Exception not part of this test case.
*/
@Test(groups = { UNIT })
public void testTerminateProcessOnUnixDerivativeOk() throws Exception {
// This test will not work on Windows!
if (getOSName().contains("windows")) {
return;
}
LaunchConfiguration launchConfig = createLaunchConfiguration("/bin/sh", "-c", "sleep 10");
int processCountBefore = m_processManager.getRunningProcessesCount();
final String pid = "myPid";
m_processManager.launch(pid, launchConfig);
// make sure we sleep a little to ensure the process is started
sleep(100);
int processCountAfterLaunch = m_processManager.getRunningProcessesCount();
assertTrue(processCountAfterLaunch > processCountBefore);
m_processManager.terminate(pid);
int processCountAfterTerminate = m_processManager.getRunningProcessesCount();
assertTrue(processCountAfterTerminate == processCountBefore);
}
/**
* Tests that terminating a single process works.
*
* @throws Exception not part of this test case.
*/
@Test(groups = { UNIT })
public void testTerminateProcessOnWindowsOk() throws Exception {
// This test will not work on Windows!
if (!getOSName().contains("windows")) {
return;
}
LaunchConfiguration launchConfig = createLaunchConfiguration("PING", "-n", "11", "127.0.0.1");
int processCountBefore = m_processManager.getRunningProcessesCount();
final String pid = "myPid";
m_processManager.launch(pid, launchConfig);
// make sure we sleep a little to ensure the process is started
sleep(100);
int processCountAfterLaunch = m_processManager.getRunningProcessesCount();
assertTrue(processCountAfterLaunch > processCountBefore);
m_processManager.terminate(pid);
int processCountAfterTerminate = m_processManager.getRunningProcessesCount();
assertTrue(processCountAfterTerminate == processCountBefore);
}
/**
* Set up for this test case.
*/
@BeforeTest
protected void setUp() {
m_processManager = new ProcessManagerImpl();
TestUtils.configureObject(m_processManager, LogService.class);
}
/**
* Creates a new launch configuration for the given executable and arguments.
*
* @param respawnAutomatically <code>true</code> if the process should be respawned
* automatically upon a non-zero exit value;
* @param execName the name of the executable;
* @param execArgs the (optional) arguments.
*
* @return a {@link LaunchConfigurationImpl} instance, never <code>null</code>.
*/
private LaunchConfiguration createLaunchConfiguration(boolean respawnAutomatically, String execName,
String... execArgs) throws Exception {
return new LaunchConfigurationImpl(1, createTempDir().getAbsolutePath(), execName, execArgs, 0, null /* processStreamListenerFilter */,
null /* processLifecycleListenerFilter */, respawnAutomatically);
}
/**
* Creates a new launch configuration for the given executable and arguments.
*
* @param execName the name of the executable;
* @param execArgs the (optional) arguments.
*
* @return a {@link LaunchConfigurationImpl} instance, never <code>null</code>.
*/
private LaunchConfiguration createLaunchConfiguration(String execName, String... execArgs) throws Exception {
return createLaunchConfiguration(false /* respawnAutomatically */, execName, execArgs);
}
}