Mercurial > hg > release > thermostat-0.11
changeset 151:c55999f78af9
Merge
author | Roman Kennke <rkennke@redhat.com> |
---|---|
date | Wed, 28 Mar 2012 17:44:33 +0200 |
parents | 64ccdd315b31 (current diff) 95349a1edfdd (diff) |
children | c1fed4f2c975 955bd3f31075 |
files | |
diffstat | 10 files changed, 599 insertions(+), 122 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java Wed Mar 28 17:43:13 2012 +0200 +++ b/agent/src/main/java/com/redhat/thermostat/backend/system/JvmStatHostListener.java Wed Mar 28 17:44:33 2012 +0200 @@ -120,7 +120,8 @@ long stopTime = Long.MIN_VALUE; JvmStatDataExtractor extractor = new JvmStatDataExtractor(vm); Map<String, String> properties = new HashMap<String, String>(); - Map<String, String> environment = ProcessEnvironmentBuilder.build(vmId); + ProcDataSource dataSource = new ProcDataSource(); + Map<String, String> environment = new ProcessEnvironmentBuilder(dataSource).build(vmId); // TODO actually figure out the loaded libraries. List<String> loadedNativeLibraries = new ArrayList<String>(); info = new VmInfo(vmId, startTime, stopTime,
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/ProcDataSource.java Wed Mar 28 17:43:13 2012 +0200 +++ b/agent/src/main/java/com/redhat/thermostat/backend/system/ProcDataSource.java Wed Mar 28 17:44:33 2012 +0200 @@ -46,6 +46,9 @@ private static final String MEMINFO_FILE = "/proc/meminfo"; private static final String CPUINFO_FILE = "/proc/cpuinfo"; + private static final String PID_STAT_FILE = "/proc/${pid}/stat"; + private static final String PID_ENVIRON_FILE = "/proc/${pid}/environ"; + /** * Returns a reader for /proc/cpuinfo */ @@ -67,4 +70,22 @@ return new FileReader(MEMINFO_FILE); } + /** + * Returns a reader for /proc/$PID/stat + */ + public Reader getStatReader(int pid) throws IOException { + return new FileReader(getPidFile(PID_STAT_FILE, pid)); + } + + /** + * Returns a reader for /proc/$PID/environ + */ + public Reader getEnvironReader(int pid) throws IOException { + return new FileReader(getPidFile(PID_ENVIRON_FILE, pid)); + } + + private String getPidFile(String fileName, int pid) { + return fileName.replace("${pid}", Integer.toString(pid)); + } + }
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/ProcessEnvironmentBuilder.java Wed Mar 28 17:43:13 2012 +0200 +++ b/agent/src/main/java/com/redhat/thermostat/backend/system/ProcessEnvironmentBuilder.java Wed Mar 28 17:44:33 2012 +0200 @@ -36,11 +36,10 @@ package com.redhat.thermostat.backend.system; -import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -53,56 +52,51 @@ private static final Logger logger = LoggingUtils.getLogger(ProcessEnvironmentBuilder.class); - private ProcessEnvironmentBuilder() { - /* should not be instantiated */ + private final ProcDataSource dataSource; + + public ProcessEnvironmentBuilder(ProcDataSource dataSource) { + this.dataSource = dataSource; } - public static Map<String, String> build(int pid) { + public Map<String, String> build(int pid) { + try (Reader reader = dataSource.getEnvironReader(pid)) { + return build(reader); + } catch (IOException ioe) { + logger.log(Level.WARNING, "error reading env", ioe); + } + + return Collections.emptyMap(); + } + + private Map<String,String> build(Reader reader) throws IOException { + Map<String, String> env = new HashMap<String, String>(); - String filename = "/proc/" + pid + "/environ"; - try { - Reader reader = new FileReader(filename); - try { - char[] fileBuffer = new char[1024]; - int fileBufferIndex = 0; - char[] buffer = new char[1024]; - int read = 0; - while (true) { - read = reader.read(buffer); - if (read == -1) { - break; - } - - if (read + fileBufferIndex > fileBuffer.length) { - char[] newFileBuffer = new char[fileBuffer.length * 2]; - System.arraycopy(fileBuffer, 0, newFileBuffer, 0, fileBufferIndex); - fileBuffer = newFileBuffer; - } - System.arraycopy(buffer, 0, fileBuffer, fileBufferIndex, read); - fileBufferIndex = fileBufferIndex + read; + char[] fileBuffer = new char[1024]; + int fileBufferIndex = 0; + char[] buffer = new char[1024]; + int read = 0; + while (true) { + read = reader.read(buffer); + if (read == -1) { + break; + } - } - List<String> parts = getParts(fileBuffer, fileBufferIndex); - for (String part : parts) { - int splitterPos = part.indexOf("="); - String key = part.substring(0, splitterPos); - String value = part.substring(splitterPos + 1); - env.put(key, value); - } - } catch (IOException e) { - logger.log(Level.WARNING, "error reading " + filename, e); - } finally { - try { - reader.close(); - } catch (IOException e) { - e.printStackTrace(); - logger.log(Level.WARNING, "error closing " + filename); - } + if (read + fileBufferIndex > fileBuffer.length) { + char[] newFileBuffer = new char[fileBuffer.length * 2]; + System.arraycopy(fileBuffer, 0, newFileBuffer, 0, fileBufferIndex); + fileBuffer = newFileBuffer; } - } catch (FileNotFoundException e) { - e.printStackTrace(); - logger.log(Level.WARNING, "file " + filename + " not found"); + System.arraycopy(buffer, 0, fileBuffer, fileBufferIndex, read); + fileBufferIndex = fileBufferIndex + read; + + } + List<String> parts = getParts(fileBuffer, fileBufferIndex); + for (String part : parts) { + int splitterPos = part.indexOf("="); + String key = part.substring(0, splitterPos); + String value = part.substring(splitterPos + 1); + env.put(key, value); } return env; @@ -112,7 +106,7 @@ * Split a char array, where items are separated by a null into into a list * of strings */ - private static List<String> getParts(char[] nullSeparatedBuffer, int bufferLength) { + private List<String> getParts(char[] nullSeparatedBuffer, int bufferLength) { int maxLength = Math.min(nullSeparatedBuffer.length, bufferLength); List<String> parts = new ArrayList<String>();
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/ProcessStatusInfo.java Wed Mar 28 17:43:13 2012 +0200 +++ b/agent/src/main/java/com/redhat/thermostat/backend/system/ProcessStatusInfo.java Wed Mar 28 17:44:33 2012 +0200 @@ -36,82 +36,18 @@ package com.redhat.thermostat.backend.system; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.Scanner; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.common.utils.LoggingUtils; - -/** - * Extract status information about the process from /proc/. This is what tools - * like {@code ps} and {@code top} use. - * - * @see {@code proc(5)} - */ public class ProcessStatusInfo { - private static final Logger logger = LoggingUtils.getLogger(ProcessStatusInfo.class); - /* All times are measured in clock ticks */ - /* TODO map these (effectively c) data types to java types more sanely */ - - private int pid; - private long utime; - private long stime; - - public static ProcessStatusInfo getFor(int pid) { - return new ProcessStatusInfo(pid); - } - - private ProcessStatusInfo(int pid) { - Scanner scanner = null; - String fileName = "/proc/" + pid + "/stat"; - BufferedReader reader = null; - try { - reader = new BufferedReader(new FileReader(fileName)); - String statusLine = reader.readLine(); - - /* be prepared for process names like '1 ) 2 3 4 foo 5' */ - - scanner = new Scanner(statusLine); - this.pid = scanner.nextInt(); - scanner.close(); - - int execEndNamePos = statusLine.lastIndexOf(')'); - - String cleanStatusLine = statusLine.substring(execEndNamePos + 1); + private final int pid; + private final long userTime; + private final long kernelTime; - scanner = new Scanner(cleanStatusLine); - /* state = */scanner.next(); - /* ppid = */scanner.nextInt(); - /* pgrp = */scanner.nextInt(); - /* session = */scanner.nextInt(); - /* tty_nr = */scanner.nextInt(); - /* tpgid = */scanner.nextInt(); - /* flags = */scanner.nextInt(); - /* minflt = */scanner.nextLong(); - /* cminflt = */scanner.nextLong(); - /* majflt = */scanner.nextLong(); - /* cmajflt = */scanner.nextLong(); - utime = scanner.nextLong(); - stime = scanner.nextLong(); - scanner.close(); - - } catch (IOException e) { - logger.log(Level.WARNING, "unable to read " + fileName); - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - logger.log(Level.WARNING, "unable to close " + fileName); - } - } - } + public ProcessStatusInfo(int pid, long userTime, long kernelTime) { + this.pid = pid; + this.userTime = userTime; + this.kernelTime = kernelTime; } public int getPid() { @@ -123,7 +59,7 @@ * kernel ticks */ public long getUserTime() { - return utime; + return userTime; } /** @@ -131,7 +67,7 @@ * ticks */ public long getKernelTime() { - return stime; + return kernelTime; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/main/java/com/redhat/thermostat/backend/system/ProcessStatusInfoBuilder.java Wed Mar 28 17:44:33 2012 +0200 @@ -0,0 +1,118 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.common.utils.LoggingUtils; + +/** + * Extract status information about the process from /proc/. This is what tools + * like {@code ps} and {@code top} use. + * + * @see {@code proc(5)} + */ +public class ProcessStatusInfoBuilder { + + private static final Logger logger = LoggingUtils.getLogger(ProcessStatusInfoBuilder.class); + + private final ProcDataSource dataSource; + + public ProcessStatusInfoBuilder(ProcDataSource dataSource) { + this.dataSource = dataSource; + } + + public ProcessStatusInfo build(int pid) { + try (BufferedReader reader = new BufferedReader(dataSource.getStatReader(pid))) { + return build(reader); + } catch (IOException e) { + logger.log(Level.WARNING, "unable to read stat info for " + pid); + } + + return new ProcessStatusInfo(-1, -1, -1); + } + + private ProcessStatusInfo build(Reader r) throws IOException { + + int pid = -1; + long utime = -1; + long stime = -1; + + Scanner scanner = null; + + /* TODO map these (effectively c) data types to java types more sanely */ + + try (BufferedReader reader = new BufferedReader(r)) { + String statusLine = reader.readLine(); + + /* be prepared for process names like '1 ) 2 3 4 foo 5' */ + + scanner = new Scanner(statusLine); + pid = scanner.nextInt(); + scanner.close(); + + int execEndNamePos = statusLine.lastIndexOf(')'); + + String cleanStatusLine = statusLine.substring(execEndNamePos + 1); + + scanner = new Scanner(cleanStatusLine); + /* state = */scanner.next(); + /* ppid = */scanner.nextInt(); + /* pgrp = */scanner.nextInt(); + /* session = */scanner.nextInt(); + /* tty_nr = */scanner.nextInt(); + /* tpgid = */scanner.nextInt(); + /* flags = */scanner.nextInt(); + /* minflt = */scanner.nextLong(); + /* cminflt = */scanner.nextLong(); + /* majflt = */scanner.nextLong(); + /* cmajflt = */scanner.nextLong(); + utime = scanner.nextLong(); + stime = scanner.nextLong(); + scanner.close(); + } + + return new ProcessStatusInfo(pid, utime, stime); + + } + +}
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/VmCpuStatBuilder.java Wed Mar 28 17:43:13 2012 +0200 +++ b/agent/src/main/java/com/redhat/thermostat/backend/system/VmCpuStatBuilder.java Wed Mar 28 17:44:33 2012 +0200 @@ -60,7 +60,8 @@ */ public static synchronized VmCpuStat build(Integer pid) { - ProcessStatusInfo info = ProcessStatusInfo.getFor(pid); + ProcDataSource dataSource = new ProcDataSource(); + ProcessStatusInfo info = new ProcessStatusInfoBuilder(dataSource).build(pid); long miliTime = System.currentTimeMillis(); long time = System.nanoTime(); long programTicks = (info.getKernelTime() + info.getUserTime());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/test/java/com/redhat/thermostat/backend/system/ProcDataSourceTest.java Wed Mar 28 17:44:33 2012 +0200 @@ -0,0 +1,83 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system; + +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.io.Reader; + +import org.junit.Test; + +import com.redhat.thermostat.TestUtils; + +public class ProcDataSourceTest { + + @Test + public void testGetCpuInfoReader() throws IOException { + Reader r = new ProcDataSource().getCpuInfoReader(); + assertNotNull(r); + } + + @Test + public void testGetCpuLoadReader() throws IOException { + Reader r = new ProcDataSource().getCpuLoadReader(); + assertNotNull(r); + } + + @Test + public void testGetMemInfoReader() throws IOException { + Reader r = new ProcDataSource().getMemInfoReader(); + assertNotNull(r); + } + + @Test + public void testGetStatReader() throws IOException { + int pid = TestUtils.getProcessId(); + Reader r = new ProcDataSource().getStatReader(pid); + assertNotNull(r); + } + + + @Test + public void testGetEnvironReader() throws IOException { + int pid = TestUtils.getProcessId(); + Reader r = new ProcDataSource().getEnvironReader(pid); + assertNotNull(r); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/test/java/com/redhat/thermostat/backend/system/ProcessEnvironmentBuilderTest.java Wed Mar 28 17:44:33 2012 +0200 @@ -0,0 +1,133 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Map; +import java.util.Random; + +import org.junit.Test; + +import com.redhat.thermostat.TestUtils; + +public class ProcessEnvironmentBuilderTest { + + private final Random r = new Random(); + + @Test + public void test() { + ProcDataSource dataSource = new ProcDataSource(); + Map<String, String> result = new ProcessEnvironmentBuilder(dataSource).build(TestUtils.getProcessId()); + assertNotNull(result); + assertFalse(result.isEmpty()); + assertTrue(result.containsKey("USER")); + } + + @Test + public void testCustomEnvironment() throws IOException { + byte[] data = ("USER=test\000HOME=house\000").getBytes(); + + Reader r = new InputStreamReader(new ByteArrayInputStream(data)); + ProcDataSource dataSource = mock(ProcDataSource.class); + when(dataSource.getEnvironReader(any(Integer.class))).thenReturn(r); + + Map<String, String> result = new ProcessEnvironmentBuilder(dataSource).build(0); + + verify(dataSource).getEnvironReader(eq(0)); + assertEquals("test", result.get("USER")); + assertEquals("house", result.get("HOME")); + } + + @Test + public void testLargeRandomEnvironment() throws IOException { + int TEST_ENV_SIZE = 1024 * 1024; + byte[] data = new byte[TEST_ENV_SIZE]; + int currentPosition = 0; + do { + byte[] key = generateRandomBytes(); + byte[] value = generateRandomBytes(); + if (currentPosition + key.length + value.length + 2 >= data.length) { + break; + } + System.arraycopy(key, 0, data, currentPosition, key.length); + currentPosition += key.length; + data[currentPosition] = (byte) '='; + currentPosition++; + System.arraycopy(value, 0, data, currentPosition, value.length); + currentPosition += value.length; + data[currentPosition] = 0x00; + currentPosition++; + } while (true); + Reader r = new InputStreamReader(new ByteArrayInputStream(data, 0, currentPosition)); + ProcDataSource dataSource = mock(ProcDataSource.class); + when(dataSource.getEnvironReader(any(Integer.class))).thenReturn(r); + + Map<String, String> result = new ProcessEnvironmentBuilder(dataSource).build(0); + + verify(dataSource).getEnvironReader(eq(0)); + assertNotNull(result); + } + + private byte[] generateRandomBytes() { + byte start = (byte) 'a'; + byte end = (byte) 'z' + 1; + + byte[] alphabet = new byte[end - start]; + for (int i = 0; i < (end-start); i++) { + alphabet[i] = (byte) (i + start); + } + int size = r.nextInt(15) + 10; + byte[] result = new byte[size]; + for (int i = 0; i < result.length; i++) { + result[i] = alphabet[r.nextInt(alphabet.length)]; + } + return result; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/test/java/com/redhat/thermostat/backend/system/ProcessStatusInfoBuilderTest.java Wed Mar 28 17:44:33 2012 +0200 @@ -0,0 +1,140 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.io.StringReader; + +import org.junit.Test; + +public class ProcessStatusInfoBuilderTest { + + @Test + public void testSimpleProcessStatus() { + ProcDataSource dataSource = new ProcDataSource(); + ProcessStatusInfo stat = new ProcessStatusInfoBuilder(dataSource).build(1); + assertNotNull(stat); + } + + @Test + public void testKnownProcessStatus() throws IOException { + final int PID = 10363; + String PROCESS_NAME = "(bash)"; + String STATE = "S"; + String PPID = "1737"; + String PROCESS_GROUP_ID = "10363"; + String SESSION_ID = "10363"; + String TTY_NUMBER = "34817"; + String TTY_PROCESS_GROUP_ID = "11404"; + String FLAGS_WORD = "4202496"; + String MINOR_FAULTS = "8093"; + String MINOR_FAULTS_CHILDREN = "607263"; + String MAJOR_FAULTS = "1"; + String MAJOR_FAULTS_CHILDREN = "251"; + final long USER_TIME_TICKS = 21; + final long KERNEL_TIME_TICKS = 7; + final long USER_TIME_CHILDREN = 10; + String KERNEL_TIME_CHILDREN = "1000"; + String PRIORITY = "20"; + String statString = "" + + PID + " " + PROCESS_NAME + " " + STATE + " " + PPID + " " + + PROCESS_GROUP_ID + " " + SESSION_ID + " " + TTY_NUMBER + " " + + TTY_PROCESS_GROUP_ID + " " + FLAGS_WORD + " " + MINOR_FAULTS + " " + + MINOR_FAULTS_CHILDREN + " " + MAJOR_FAULTS + " " + MAJOR_FAULTS_CHILDREN + " " + + USER_TIME_TICKS + " " + KERNEL_TIME_TICKS + " " + USER_TIME_CHILDREN + " " + + KERNEL_TIME_CHILDREN + " " + PRIORITY; + + ProcDataSource dataSource = mock(ProcDataSource.class); + when(dataSource.getStatReader(any(Integer.class))).thenReturn(new StringReader(statString)); + ProcessStatusInfoBuilder builder = new ProcessStatusInfoBuilder(dataSource); + ProcessStatusInfo stat = builder.build(PID); + + verify(dataSource).getStatReader(PID); + assertNotNull(stat); + assertEquals(PID, stat.getPid()); + assertEquals(USER_TIME_TICKS, stat.getUserTime()); + assertEquals(KERNEL_TIME_TICKS, stat.getKernelTime()); + } + + @Test + public void testBadProcessName() throws IOException { + final int PID = 10363; + String PROCESS_NAME = "(secretly-bad process sleep 10 20 ) 6)"; + String STATE = "S"; + String PPID = "1737"; + String PROCESS_GROUP_ID = "10363"; + String SESSION_ID = "10363"; + String TTY_NUMBER = "34817"; + String TTY_PROCESS_GROUP_ID = "11404"; + String FLAGS_WORD = "4202496"; + String MINOR_FAULTS = "8093"; + String MINOR_FAULTS_CHILDREN = "607263"; + String MAJOR_FAULTS = "1"; + String MAJOR_FAULTS_CHILDREN = "251"; + final long USER_TIME_TICKS = 21; + final long KERNEL_TIME_TICKS = 7; + final long USER_TIME_CHILDREN = 10; + String KERNEL_TIME_CHILDREN = "1000"; + String PRIORITY = "20"; + String statString = "" + + PID + " " + PROCESS_NAME + " " + STATE + " " + PPID + " " + + PROCESS_GROUP_ID + " " + SESSION_ID + " " + TTY_NUMBER + " " + + TTY_PROCESS_GROUP_ID + " " + FLAGS_WORD + " " + MINOR_FAULTS + " " + + MINOR_FAULTS_CHILDREN + " " + MAJOR_FAULTS + " " + MAJOR_FAULTS_CHILDREN + " " + + USER_TIME_TICKS + " " + KERNEL_TIME_TICKS + " " + USER_TIME_CHILDREN + " " + + KERNEL_TIME_CHILDREN + " " + PRIORITY; + + ProcDataSource dataSource = mock(ProcDataSource.class); + when(dataSource.getStatReader(any(Integer.class))).thenReturn(new StringReader(statString)); + ProcessStatusInfoBuilder builder = new ProcessStatusInfoBuilder(dataSource); + ProcessStatusInfo stat = builder.build(PID); + + verify(dataSource).getStatReader(PID); + assertNotNull(stat); + assertEquals(PID, stat.getPid()); + assertEquals(USER_TIME_TICKS, stat.getUserTime()); + assertEquals(KERNEL_TIME_TICKS, stat.getKernelTime()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/test/java/com/redhat/thermostat/backend/system/SysConfTest.java Wed Mar 28 17:44:33 2012 +0200 @@ -0,0 +1,50 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.backend.system; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class SysConfTest { + + @Test + public void test() { + long ticksPerSecond = SysConf.getClockTicksPerSecond(); + assertTrue(ticksPerSecond >= 1); + } +}