/*
* 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.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.hyperic.sigar.ProcCpu;
import org.hyperic.sigar.ProcCred;
import org.hyperic.sigar.ProcCredName;
import org.hyperic.sigar.ProcExe;
import org.hyperic.sigar.ProcFd;
import org.hyperic.sigar.ProcMem;
import org.hyperic.sigar.ProcState;
import org.hyperic.sigar.ProcTime;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.SigarProxy;
import org.mockito.Mockito;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* A {@link ProcessInfo} unit test class (mocked SIGAR)
*
* @author Thomas Segismont
*/
public class ProcessInfoTest {
private static final int PID = 15;
private SigarProxy sigarProxy;
private ProcExe procExe;
private ProcState procState;
private ProcTime procTime;
private ProcMem procMem;
private ProcCpu procCpu;
private ProcFd procFd;
private ProcCred procCred;
private ProcCredName procCredName;
private ProcessInfo processInfo;
@BeforeMethod(alwaysRun = true)
protected void setUp() throws Exception {
sigarProxy = Mockito.mock(SigarProxy.class);
procExe = Mockito.mock(ProcExe.class);
when(sigarProxy.getProcExe(PID)).thenReturn(procExe);
procState = Mockito.mock(ProcState.class);
// Calls to refresh won't succeed if the process is reported down
when(procState.getState()).thenReturn(ProcState.RUN);
when(sigarProxy.getProcState(PID)).thenReturn(procState);
procTime = Mockito.mock(ProcTime.class);
when(sigarProxy.getProcTime(PID)).thenReturn(procTime);
procMem = Mockito.mock(ProcMem.class);
when(sigarProxy.getProcMem(PID)).thenReturn(procMem);
procCpu = Mockito.mock(ProcCpu.class);
when(sigarProxy.getProcCpu(PID)).thenReturn(procCpu);
procFd = Mockito.mock(ProcFd.class);
when(sigarProxy.getProcFd(PID)).thenReturn(procFd);
procCred = Mockito.mock(ProcCred.class);
when(sigarProxy.getProcCred(PID)).thenReturn(procCred);
procCredName = Mockito.mock(ProcCredName.class);
when(sigarProxy.getProcCredName(PID)).thenReturn(procCredName);
processInfo = new ProcessInfo(PID, sigarProxy);
}
@Test
public void testGetPid() {
assertEquals(processInfo.getPid(), PID);
}
@Test
public void testGetNameDefault() {
assertEquals(processInfo.getName(), "?");
}
@Test
public void testGetNameFromArgs() throws Exception {
// Force new test instance because this test case work with data
// which is initialized at instance creation
when(sigarProxy.getProcArgs(PID)).thenReturn(new String[] { "onearg", "somearg", "otherarg" });
processInfo = new ProcessInfo(PID, sigarProxy);
assertEquals(processInfo.getName(), "onearg");
}
@Test
public void testGetNameFromExe() throws Exception {
// Force new test instance because this test case work with data
// which is initialized at instance creation
procExe = Mockito.mock(ProcExe.class);
when(procExe.getName()).thenReturn("aprocname");
when(sigarProxy.getProcExe(PID)).thenReturn(procExe);
processInfo = new ProcessInfo(PID, sigarProxy);
assertEquals(processInfo.getName(), "aprocname");
}
@Test
public void testGetNameFromStateWithFileNotExists() throws Exception {
// Force new test instance because this test case work with data
// which is initialized at instance creation
procState = Mockito.mock(ProcState.class);
when(procState.getName()).thenReturn("/this/file/should/not/exists");
when(sigarProxy.getProcState(PID)).thenReturn(procState);
processInfo = new ProcessInfo(PID, sigarProxy);
assertEquals(processInfo.getName(), "/this/file/should/not/exists");
}
@Test
public void testGetNameFromStateWithFileExists() throws Exception {
// Force new test instance because this test case work with data
// which is initialized at instance creation
File tmpFile = File.createTempFile("ProcessInfoTest-", ".tmp");
tmpFile.deleteOnExit();
procState = Mockito.mock(ProcState.class);
when(procState.getName()).thenReturn(tmpFile.getAbsolutePath());
when(sigarProxy.getProcState(PID)).thenReturn(procState);
processInfo = new ProcessInfo(PID, sigarProxy);
assertEquals(processInfo.getName(), tmpFile.getAbsolutePath());
}
@Test
public void testGetBaseName() throws Exception {
// Force new test instance because this test case work with data
// which is initialized at instance creation
File tmpFile = File.createTempFile("ProcessInfoTest-", ".tmp");
tmpFile.deleteOnExit();
procState = Mockito.mock(ProcState.class);
when(procState.getName()).thenReturn(tmpFile.getAbsolutePath());
when(sigarProxy.getProcState(PID)).thenReturn(procState);
processInfo = new ProcessInfo(PID, sigarProxy);
assertEquals(processInfo.getBaseName(), tmpFile.getName());
}
@Test
public void testGetEmptyCommandLine() throws Exception {
assertEquals(processInfo.getCommandLine(), new String[] {});
}
@Test
public void testGetCommandLine() throws Exception {
// Force new proxy and test instance because this test case work on process static data
// which is initialized at instance creation
sigarProxy = Mockito.mock(SigarProxy.class);
String[] array = new String[] { "one", "two", "three" };
when(sigarProxy.getProcArgs(PID)).thenReturn(array);
processInfo = new ProcessInfo(PID, sigarProxy);
assertEquals(processInfo.getCommandLine(), array);
}
@Test
public void testGetEmptyEnvironmentVariables() throws Exception {
assertEquals(processInfo.getEnvironmentVariables(), Collections.EMPTY_MAP);
}
@Test
public void testGetEnvironmentVariables() throws Exception {
// Force new test instance because this test case work with data
// which is initialized at instance creation
Map<String, String> env = new HashMap<String, String>();
env.put("one", "1");
env.put("two", "2");
env.put("three", "3");
when(sigarProxy.getProcEnv(PID)).thenReturn(env);
processInfo = new ProcessInfo(PID, sigarProxy);
assertEquals(processInfo.getEnvironmentVariables(), env);
}
@Test
public void testGetEnvironmentVariableWithNullEnv() throws Exception {
assertEquals(processInfo.getEnvironmentVariable("anyvar"), null);
}
@Test
public void testGetEnvironmentVariable() throws Exception {
// Force new test instance because this test case work with data
// which is initialized at instance creation
Map<String, String> env = new HashMap<String, String>();
env.put("one", "1");
env.put("two", "2");
env.put("three", "3");
when(sigarProxy.getProcEnv(PID)).thenReturn(env);
processInfo = new ProcessInfo(PID, sigarProxy);
assertEquals(processInfo.getEnvironmentVariable("two"), "2");
}
@Test
public void testGetParentPidWithNullState() throws Exception {
// Force new test instance because this test case work with data
// which is initialized at instance creation
when(sigarProxy.getProcState(PID)).thenThrow(new SigarException());
// This is to avoid NPE in test instance error checking code
when(sigarProxy.getProcList()).thenReturn(new long[] { PID });
processInfo = new ProcessInfo(PID, sigarProxy);
assertEquals(processInfo.getParentPid(), 0);
}
@Test
public void testGetParentPid() {
when(procState.getPpid()).thenReturn(Long.valueOf(10));
assertEquals(processInfo.getParentPid(), 10);
}
@Test
public void testGetState() throws Exception {
assertTrue(procState == processInfo.getState());
// Change procState
procState = Mockito.mock(ProcState.class);
when(sigarProxy.getProcState(PID)).thenReturn(procState);
// Should not be same until refresh is called
assertFalse(procState == processInfo.getState());
processInfo.refresh();
assertTrue(procState == processInfo.getState());
}
@Test
public void testGetExecutable() throws Exception {
assertTrue(procExe == processInfo.getExecutable());
// Change procExe
procExe = Mockito.mock(ProcExe.class);
when(sigarProxy.getProcExe(PID)).thenReturn(procExe);
// Should not be same until refresh is called
assertFalse(procExe == processInfo.getExecutable());
processInfo.refresh();
assertTrue(procExe == processInfo.getExecutable());
}
@Test
public void testGetTime() throws Exception {
assertTrue(procTime == processInfo.getTime());
// Change procTime
procTime = Mockito.mock(ProcTime.class);
when(sigarProxy.getProcTime(PID)).thenReturn(procTime);
// Should not be same until refresh is called
assertFalse(procTime == processInfo.getTime());
processInfo.refresh();
assertTrue(procTime == processInfo.getTime());
}
@Test
public void testGetMemory() throws Exception {
assertTrue(procMem == processInfo.getMemory());
// Change procMem
procMem = Mockito.mock(ProcMem.class);
when(sigarProxy.getProcMem(PID)).thenReturn(procMem);
// Should not be same until refresh is called
assertFalse(procMem == processInfo.getMemory());
processInfo.refresh();
assertTrue(procMem == processInfo.getMemory());
}
@Test
public void testGetCpu() throws Exception {
assertTrue(procCpu == processInfo.getCpu());
// Change procCpu
procCpu = Mockito.mock(ProcCpu.class);
when(sigarProxy.getProcCpu(PID)).thenReturn(procCpu);
// Should not be same until refresh is called
assertFalse(procCpu == processInfo.getCpu());
processInfo.refresh();
assertTrue(procCpu == processInfo.getCpu());
}
@Test
public void testGetFileDescriptor() throws Exception {
assertTrue(procFd == processInfo.getFileDescriptor());
// Change procFd
procFd = Mockito.mock(ProcFd.class);
when(sigarProxy.getProcFd(PID)).thenReturn(procFd);
// Should not be same until refresh is called
assertFalse(procFd == processInfo.getFileDescriptor());
processInfo.refresh();
assertTrue(procFd == processInfo.getFileDescriptor());
}
@Test
public void testGetCredentials() throws Exception {
assertTrue(procCred == processInfo.getCredentials());
// Change procCred
procCred = Mockito.mock(ProcCred.class);
when(sigarProxy.getProcCred(PID)).thenReturn(procCred);
// Should not be same until refresh is called
assertFalse(procCred == processInfo.getCredentials());
processInfo.refresh();
assertTrue(procCred == processInfo.getCredentials());
}
@Test
public void testGetCredentialsName() throws Exception {
assertTrue(procCredName == processInfo.getCredentialsName());
// Change procCred
procCredName = Mockito.mock(ProcCredName.class);
when(sigarProxy.getProcCredName(PID)).thenReturn(procCredName);
// Should not be same until refresh is called
assertFalse(procCredName == processInfo.getCredentialsName());
processInfo.refresh();
assertTrue(procCredName == processInfo.getCredentialsName());
}
@Test
public void testGetCurrentWorkingDirectoryFailure() throws Exception {
when(procExe.getCwd()).thenThrow(new RuntimeException());
// This is to avoid NPE in test instance error checking code
when(sigarProxy.getProcList()).thenReturn(new long[] { PID });
assertNull(processInfo.getCurrentWorkingDirectory());
}
@Test
public void testGetCurrentWorkingDirectory() throws Exception {
when(procExe.getCwd()).thenReturn("adir");
assertEquals(processInfo.getCurrentWorkingDirectory(), "adir");
}
@Test
public void testIsRunning() {
for (char state : new char[] { ProcState.RUN, ProcState.SLEEP, ProcState.IDLE }) {
when(procState.getState()).thenReturn(state);
assertTrue(processInfo.isRunning());
}
for (char state : new char[] { ProcState.ZOMBIE, ProcState.STOP }) {
when(procState.getState()).thenReturn(state);
assertFalse(processInfo.isRunning());
}
}
@Test
public void testGetParentProcess() {
when(procState.getPpid()).thenReturn(Long.valueOf(10));
assertEquals(processInfo.getParentProcess().getPid(), 10);
when(procState.getPpid()).thenReturn(Long.valueOf(11));
assertEquals(processInfo.getParentProcess().getPid(), 10, "Parent process should be cached");
}
}