/* * RHQ Management Platform * Copyright 2013, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.core.system; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import java.util.ArrayList; import java.util.List; import org.hyperic.sigar.OperatingSystem; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; /** * @author Thomas Segismont */ public class DeadProcessInfoRefreshTest { private static final class SampleProgram { @SuppressWarnings("unused") public static void main(String[] args) { while (true) { try { Thread.sleep(5000); } catch (Exception ignore) { } } } } private static final String SAMPLE_PROGRAM_NAME = SampleProgram.class.getName(); private Process testProcess; private ProcessInfo testProcessInfo; @BeforeTest(alwaysRun = true) public void setup() throws Exception { testProcess = createTestProcess(); if (!isAlive(testProcess)) { throw new RuntimeException("Test process is not alive"); } NativeSystemInfo systemInfo = new NativeSystemInfo(); List<ProcessInfo> foundProcesses = systemInfo.getProcesses("arg|" + SAMPLE_PROGRAM_NAME + "|match=.*"); if (foundProcesses.size() != 1) { throw new RuntimeException("Found " + foundProcesses.size() + " processes with arg [" + SampleProgram.class.getName() + "]"); } testProcessInfo = foundProcesses.iterator().next(); } private Process createTestProcess() throws Exception { String javaHome = System.getProperty("java.home"); String javaCmd = javaHome + "/bin/java"; List<String> args = new ArrayList<String>(); args.add(javaCmd); args.add("-cp"); args.add("target/test-classes"); args.add(SampleProgram.class.getName()); ProcessBuilder processBuilder = new ProcessBuilder(args); processBuilder.inheritIO(); Process process = processBuilder.start(); return process; } @AfterTest(alwaysRun = true) public void tearDown() { if (testProcess != null) { testProcess.destroy(); testProcess = null; } testProcessInfo = null; } /** * We want to be sure that once the process has been reported down, subsequent calls to refresh will not report it * up. See this thread on VMWare forum: http://communities.vmware.com/message/2187972#2187972 * * Unfortunately there is no work around for this failure on Mac OSX so the test will silently return on this * platform. * * @throws Exception */ @Test(timeOut = 1000 * 10) public void testRefreshInterval() throws Exception { if (OperatingSystem.getInstance().getName().equals(OperatingSystem.NAME_MACOSX)) { return; } // Sigar should see the process running assertTrue(testProcessInfo.freshSnapshot().isRunning()); // Send kill testProcess.destroy(); // Wait for death while (isAlive(testProcess)) { Thread.sleep(100); } // Wait at least two seconds to by-pass Sigar cache Thread.sleep(2000); assertFalse(testProcessInfo.freshSnapshot().isRunning()); // It should no longer be necessary to wait two seconds for (int i = 0; i < 100; i++) { assertFalse(testProcessInfo.freshSnapshot().isRunning()); } } private boolean isAlive(Process process) { if (process == null) { return false; } try { process.exitValue(); return false; } catch (IllegalThreadStateException e) { return true; } } }