Mercurial > hg > thermostat-ng > agent
changeset 2764:d624d92d95ca
jvm-memory should also collect resident memory
Reviewed-by: stooke
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-September/025132.html
line wrap: on
line diff
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcess.java Tue Sep 26 15:10:31 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcess.java Wed Sep 20 12:23:54 2017 +0200 @@ -63,4 +63,11 @@ int getCurrentProcessPid(); String[] getNativeLibs(int pid); + + /** + * Returns resident memory size of the process with PID {@code pid}. If no + * such information is available or cannot be retrieved, null is + * returned. + */ + Long getResidentMemorySize(int pid); }
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxNativeLibsExtractor.java Tue Sep 26 15:10:31 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright 2012-2017 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.common.portability.internal.linux; - -import com.redhat.thermostat.common.utils.LoggingUtils; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.HashSet; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class LinuxNativeLibsExtractor { - - private static final Logger LOGGER - = LoggingUtils.getLogger(LinuxNativeLibsExtractor.class); - - public static String[] getNativeLibs(int pid) { - return getNativeLibsFromReader(new File(String.format("/proc/%d/maps", pid))); - } - - // for testing purposes only - static String[] getNativeLibs(File testFile) { - return getNativeLibsFromReader(testFile); - } - - private static String[] getNativeLibsFromReader(File nativeLibFile) { - final String soGrep = ".+\\.so.*"; - Set<String> result = new HashSet<>(); - try (BufferedReader br - = new BufferedReader(new FileReader(nativeLibFile))) { - String next = br.readLine(); - while (next != null) { - next = next.trim(); - if (next.matches(soGrep)) { - String candidate = next.substring(next.lastIndexOf(' ') + 1); - result.add(candidate); - } - next = br.readLine(); - } - return result.toArray(new String[0]); - } catch (IOException ex) { - LOGGER.log(Level.WARNING, "Unable to retrieve native libraries."); - LOGGER.log(Level.INFO, ex.getMessage()); - return new String[0]; - } - } -}
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessImpl.java Tue Sep 26 15:10:31 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessImpl.java Wed Sep 20 12:23:54 2017 +0200 @@ -122,6 +122,11 @@ @Override public String[] getNativeLibs(int pid) { - return LinuxNativeLibsExtractor.getNativeLibs(pid); + return LinuxProcfsDataExtractor.getNativeLibs(pid); + } + + @Override + public Long getResidentMemorySize(int pid) { + return LinuxProcfsDataExtractor.getResidentMemorySize(pid); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcfsDataExtractor.java Wed Sep 20 12:23:54 2017 +0200 @@ -0,0 +1,134 @@ +/* +/* + * Copyright 2012-2017 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.common.portability.internal.linux; + +import com.redhat.thermostat.common.portability.linux.ProcDataSource; +import com.redhat.thermostat.common.utils.LoggingUtils; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class LinuxProcfsDataExtractor { + + private static final Logger LOGGER + = LoggingUtils.getLogger(LinuxProcfsDataExtractor.class); + private static final ProcDataSource PROC_DATA_HELPER = new ProcDataSource(); + + /** + * Returns String array consisting of loaded native libraries using + * /proc/$PID/maps. Should an error occur or such file does not exist, empty + * array is returned. + */ + public static String[] getNativeLibs(int pid) { + try { + return getNativeLibsFromFile(PROC_DATA_HELPER.getMapsFile(pid)); + } catch (IOException ex) { + LOGGER.log(Level.WARNING, "Failed reading procfs maps file."); + LOGGER.log(Level.INFO, ex.getMessage()); + return new String[0]; + } + } + + // for testing purposes only + static String[] getNativeLibs(StringReader testReader) { + return getNativeLibsFromFile(testReader); + } + + private static String[] getNativeLibsFromFile(Reader reader) { + final String soGrep = ".+\\.so.*"; + Set<String> result = new HashSet<>(); + try (BufferedReader br + = new BufferedReader(reader)) { + String next = br.readLine(); + while (next != null) { + next = next.trim(); + if (next.matches(soGrep)) { + String candidate = next.substring(next.lastIndexOf(' ') + 1); + result.add(candidate); + } + next = br.readLine(); + } + return result.toArray(new String[0]); + } catch (IOException ex) { + LOGGER.log(Level.WARNING, "Unable to retrieve native libraries."); + LOGGER.log(Level.INFO, ex.getMessage()); + return new String[0]; + } + } + + public static Long getResidentMemorySize(int pid) { + try { + return getResidentMemorySizeFromFile(PROC_DATA_HELPER.getStatusReader(pid)); + } catch (IOException ex) { + LOGGER.log(Level.WARNING, "Failed reading procfs status file."); + LOGGER.log(Level.INFO, ex.getMessage()); + return null; + } + } + + // for testing purposes only + static Long getResidentMemorySize(StringReader file) { + return getResidentMemorySizeFromFile(file); + } + + private static Long getResidentMemorySizeFromFile(Reader reader) { + final String vmRssRegex = "VmRSS:\\s+.*"; + try (BufferedReader br = new BufferedReader(reader)) { + String next = br.readLine(); + while (next != null) { + next = next.trim(); + if (next.matches(vmRssRegex)) { + String residentMem = next.split("\\s+")[1]; + return Long.parseLong(residentMem); + } + next = br.readLine(); + } + return null; + } catch (IOException ex) { + LOGGER.log(Level.WARNING, "Unable to retrieve resident memory size."); + LOGGER.log(Level.INFO, ex.getMessage()); + return null; + } + } +} +
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSProcessImpl.java Tue Sep 26 15:10:31 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSProcessImpl.java Wed Sep 20 12:23:54 2017 +0200 @@ -42,11 +42,16 @@ import com.redhat.thermostat.common.portability.PortableVmIoStat; import com.redhat.thermostat.common.portability.internal.PosixHelperImpl; import com.redhat.thermostat.common.portability.internal.UnimplementedError; +import com.redhat.thermostat.common.utils.LoggingUtils; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; public class MacOSProcessImpl implements PortableProcess { + private static final Logger LOGGER = LoggingUtils.getLogger(MacOSProcessImpl.class); + public static final MacOSProcessImpl INSTANCE = new MacOSProcessImpl(); private static final MacOSHelperImpl helper = MacOSHelperImpl.INSTANCE; private PosixHelperImpl posixHelper = new PosixHelperImpl(); @@ -106,6 +111,16 @@ @Override public String[] getNativeLibs(int pid) { - throw new UnimplementedError("getNativeLibs() is unsupported on macOS"); + throw new UnimplementedError("getNativeLibs() is unsupported on macOS"); + } + + @Override + public Long getResidentMemorySize(int pid) { + try { + throw new UnimplementedError("getResidentMemorySize()"); + } catch (UnimplementedError e) { + LOGGER.log(Level.WARNING, "getResidentMemorySize() is not available for MacOS at this moment"); + return null; + } } }
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableProcessImpl.java Tue Sep 26 15:10:31 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableProcessImpl.java Wed Sep 20 12:23:54 2017 +0200 @@ -40,12 +40,18 @@ import com.redhat.thermostat.common.portability.PortableProcess; import com.redhat.thermostat.common.portability.PortableProcessStat; import com.redhat.thermostat.common.portability.PortableVmIoStat; +import com.redhat.thermostat.common.portability.internal.UnimplementedError; +import com.redhat.thermostat.common.utils.LoggingUtils; import java.util.Collections; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; public class WindowsPortableProcessImpl implements PortableProcess { + private static final Logger LOGGER = LoggingUtils.getLogger(WindowsPortableProcessImpl.class); + public static final WindowsPortableProcessImpl INSTANCE = new WindowsPortableProcessImpl(); private static final WindowsHelperImpl helper = WindowsHelperImpl.INSTANCE; @@ -111,4 +117,14 @@ public String[] getNativeLibs(int pid) { return helper.getProcessModules(pid); } + + @Override + public Long getResidentMemorySize(int pid) { + try { + throw new UnimplementedError("getResidentMemorySize()"); + } catch (UnimplementedError e) { + LOGGER.log(Level.WARNING, "getResidentMemorySize() is not available for Windows at this moment"); + return null; + } + } }
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/linux/ProcDataSource.java Tue Sep 26 15:10:31 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/linux/ProcDataSource.java Wed Sep 20 12:23:54 2017 +0200 @@ -40,12 +40,11 @@ import java.io.FileReader; import java.io.IOException; import java.io.Reader; - /** * Wrapper for files under {@code /proc/}. See proc(5) for details about this. * * This class is inherently unportable, but a _lot_ of Linux code needs refactoring - * before it can be make package private + * before it can be made package private * * Note that different Unix-like OSs may or may not have a /proc (and the format may be different) * for example Darwin/OSX doesn't have /proc @@ -56,12 +55,15 @@ private static final String STAT_FILE = "/proc/stat"; private static final String MEMINFO_FILE = "/proc/meminfo"; private static final String CPUINFO_FILE = "/proc/cpuinfo"; - - private static final String PID_ENVIRON_FILE = "/proc/${pid}/environ"; - private static final String PID_IO_FILE = "/proc/${pid}/io"; - private static final String PID_STAT_FILE = "/proc/${pid}/stat"; - private static final String PID_STATUS_FILE = "/proc/${pid}/status"; - private static final String PID_NUMA_MAPS_FILE = "/proc/${pid}/numa_maps"; + + private static final String PROC_PREFIX = "/proc/"; + private static final String PID_FORMAT = "%d"; + private static final String PID_ENVIRON_FILE = getPidFileFormatter("/environ"); + private static final String PID_IO_FILE = getPidFileFormatter("/io"); + private static final String PID_STAT_FILE = getPidFileFormatter("/stat"); + private static final String PID_STATUS_FILE = getPidFileFormatter("/status"); + private static final String PID_NUMA_MAPS_FILE = getPidFileFormatter("/numa_maps"); + private static final String PID_MAPS_FILE = getPidFileFormatter("/maps"); private final ReaderCreator readerCreator; @@ -74,6 +76,13 @@ } /** + * @param file proc file beginning with a forward slash + */ + private static String getPidFileFormatter(String file) { + return PROC_PREFIX + PID_FORMAT + file; + } + + /** * Returns a reader for /proc/cpuinfo */ public Reader getCpuInfoReader() throws IOException { @@ -135,17 +144,22 @@ public Reader getNumaMapsReader(int pid) throws IOException { return readerCreator.createFileReader(getPidFile(PID_NUMA_MAPS_FILE, pid)); } + + /** + * Returns a reader for /proc/$PID/maps + */ + public Reader getMapsFile(int pid) throws IOException { + return readerCreator.createFileReader(getPidFile(PID_MAPS_FILE, pid)); + } - private String getPidFile(String fileName, int pid) { - return fileName.replace("${pid}", Integer.toString(pid)); + private String getPidFile(String fileNameFormatter, int pid) { + return String.format(fileNameFormatter, pid); } - // For testing purposes static class ReaderCreator { FileReader createFileReader(String fileName) throws FileNotFoundException { return new FileReader(fileName); } } - }
--- a/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxNativeLibsExtractorTest.java Tue Sep 26 15:10:31 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright 2012-2017 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.common.portability.internal.linux; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.File; -import java.io.UnsupportedEncodingException; -import java.net.URL; -import java.net.URLDecoder; -import java.util.Arrays; -import java.util.HashSet; - -import org.junit.Test; - -public class LinuxNativeLibsExtractorTest { - - private final File THREE_LIBS = getFileFromTestSources("native_lib_three_libs"); - private final File NO_LIBS = getFileFromTestSources("native_lib_no_libs"); - private final File EMPTY = getFileFromTestSources("native_lib_empty"); - - private File getFileFromTestSources(String path) { - path = '/' + path; - return new File(decodeFilePath(this.getClass().getResource(path))); - } - - private String decodeFilePath(URL url) { - try { - return URLDecoder.decode(url.getFile(), "UTF-8"); - } catch (UnsupportedEncodingException ex) { - throw new AssertionError(ex); - } - } - - @Test - public void threeLibs() { - HashSet<String> expectedLibs = new HashSet<>(Arrays.asList("/usr/foo/libhello.so", - "/usr/bar/libworld.so.0.18.0", "/tmp/libnew.so.so")); - - // Cannot compare arrays directly since the implementation internally gathers libs - // to a Set, which might yield a different ordering of items in the collection in the end - assertEquals(expectedLibs, new HashSet<>(Arrays.asList(LinuxNativeLibsExtractor.getNativeLibs(THREE_LIBS)))); - } - - @Test - public void noLibs() { - String[] result = LinuxNativeLibsExtractor.getNativeLibs(NO_LIBS); - int numExpectedLibs = 0; - - assertNotNull(result); - assertEquals(result.length, numExpectedLibs); - - } - - @Test - public void empty() { - String[] result = LinuxNativeLibsExtractor.getNativeLibs(EMPTY); - int numExpectedLibs = 0; - - assertNotNull(result); - assertEquals(result.length, numExpectedLibs); - - } - -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcfsDataExtractorTest.java Wed Sep 20 12:23:54 2017 +0200 @@ -0,0 +1,162 @@ +/* + * Copyright 2012-2017 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.common.portability.internal.linux; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.io.StringReader; +import java.util.Arrays; +import java.util.HashSet; + +import org.junit.Test; + +public class LinuxProcfsDataExtractorTest { + + @Test + public void threeLibs() { + HashSet<String> expectedLibs = new HashSet<>(Arrays.asList("/usr/foo/libhello.so", + "/usr/bar/libworld.so.0.18.0", "/tmp/libnew.so.so")); + StringReader threeLibs = new StringReader( + "000000000000-00000000f000 r-xp 00000000 fd:01 1234567 /usr/foo/libhello.so\n" + + "00000000f000-000000050000 ---p 00085000 fd:02 1234567 /usr/bar/libworld.so.0.18.0\n" + + "000000050000-000000e00000 r--p 00085000 fd:03 1234567 /tmp/libnew.so.so"); + // Cannot compare arrays directly since the implementation internally gathers libs + // to a Set, which might yield a different ordering of items in the collection in the end + assertEquals(expectedLibs, new HashSet<>(Arrays.asList(LinuxProcfsDataExtractor.getNativeLibs(threeLibs)))); + } + + @Test + public void noLibs() { + StringReader noLibs = new StringReader( + "000000000000-00000000f000 r-xp 00000000 fd:01 1234567 /usr/foo/libhello\n" + + "00000000f000-000000050000 ---p 00085000 fd:02 1234567 /usr/bar/libworld\n" + + "000000050000-000000e00000 r--p 00085000 fd:03 1234567 /tmp/libnew"); + String[] result = LinuxProcfsDataExtractor.getNativeLibs(noLibs); + int numExpectedLibs = 0; + + assertNotNull(result); + assertEquals(result.length, numExpectedLibs); + + } + + @Test + public void emptyFileNativeLibs() { + StringReader empty = new StringReader(""); + String[] result = LinuxProcfsDataExtractor.getNativeLibs(empty); + int numExpectedLibs = 0; + + assertNotNull(result); + assertEquals(result.length, numExpectedLibs); + + } + + @Test + public void emptyFileResidentMemory() { + StringReader empty = new StringReader(""); + Long result = LinuxProcfsDataExtractor.getResidentMemorySize(empty); + + assertNull(result); + } + + @Test + public void missingResidentMemoryStat() { + StringReader resMemMissing = new StringReader( + "Uid: 1000 1000 1000 1000\n" + + "Gid: 100 100 100 100\n" + + "FDSize: 256\n" + + "Groups: 16 33 100\n" + + "NStgid: 17248\n" + + "NSpid: 17248\n" + + "NSpgid: 17248\n" + + "NSsid: 17200\n" + + "VmPeak: 131168 kB\n" + + "VmSize: 131168 kB\n" + + "VmLck: 0 kB\n" + + "VmPin: 0 kB\n" + + "VmHWM: 13484 kB\n" + + "RssAnon: 10264 kB\n" + + "RssFile: 3220 kB\n" + + "RssShmem: 0 kB\n" + + "VmData: 10332 kB\n" + + "VmStk: 136 kB\n" + + "VmExe: 992 kB\n" + + "VmLib: 2104 kB\n" + + "VmPTE: 76 kB\n" + + "VmPMD: 12 kB\n" + + "VmSwap: 0 kB"); + Long result = LinuxProcfsDataExtractor.getResidentMemorySize(resMemMissing); + + assertNull(result); + } + + @Test + public void residentMemoryStatPresent() { + StringReader resMemPresent = new StringReader( + "Uid: 1000 1000 1000 1000\n" + + "Gid: 100 100 100 100\n" + + "FDSize: 256\n" + + "Groups: 16 33 100\n" + + "NStgid: 17248\n" + + "NSpid: 17248\n" + + "NSpgid: 17248\n" + + "NSsid: 17200\n" + + "VmPeak: 131168 kB\n" + + "VmSize: 131168 kB\n" + + "VmLck: 0 kB\n" + + "VmPin: 0 kB\n" + + "VmHWM: 13484 kB\n" + + "VmRSS: 13484 kB\n" + + "RssAnon: 10264 kB\n" + + "RssFile: 3220 kB\n" + + "RssShmem: 0 kB\n" + + "VmData: 10332 kB\n" + + "VmStk: 136 kB\n" + + "VmExe: 992 kB\n" + + "VmLib: 2104 kB\n" + + "VmPTE: 76 kB\n" + + "VmPMD: 12 kB\n" + + "VmSwap: 0 kB"); + Long result = LinuxProcfsDataExtractor.getResidentMemorySize(resMemPresent); + + long expected = 13484; + + assertEquals(result.longValue(), expected); + } + +}
--- a/common/portability/src/test/resources/native_lib_empty Tue Sep 26 15:10:31 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -
--- a/common/portability/src/test/resources/native_lib_no_libs Tue Sep 26 15:10:31 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -000000000000-00000000f000 r-xp 00000000 fd:01 1234567 /usr/foo/libhello -00000000f000-000000050000 ---p 00085000 fd:02 1234567 /usr/bar/libworld -000000050000-000000e00000 r--p 00085000 fd:03 1234567 /tmp/libnew
--- a/common/portability/src/test/resources/native_lib_three_libs Tue Sep 26 15:10:31 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -000000000000-00000000f000 r-xp 00000000 fd:01 1234567 /usr/foo/libhello.so -00000000f000-000000050000 ---p 00085000 fd:02 1234567 /usr/bar/libworld.so.0.18.0 -000000050000-000000e00000 r--p 00085000 fd:03 1234567 /tmp/libnew.so.so -
--- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmNativeLibsExtractorFactory.java Tue Sep 26 15:10:31 2017 +0200 +++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmNativeLibsExtractorFactory.java Wed Sep 20 12:23:54 2017 +0200 @@ -36,8 +36,6 @@ package com.redhat.thermostat.jvm.overview.agent.internal.model; -import com.redhat.thermostat.shared.config.OS; - public final class VmNativeLibsExtractorFactory { public static VmNativeLibsExtractor getInstance(Integer pid) {
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackend.java Tue Sep 26 15:10:31 2017 +0200 +++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackend.java Wed Sep 20 12:23:54 2017 +0200 @@ -55,7 +55,7 @@ @Component @Service(value = Backend.class) public class VmMemoryBackend extends VmListenerBackend { - + private final ListenerCreator listenerCreator; @Reference @@ -107,12 +107,12 @@ @Override protected VmUpdateListener createVmListener(String writerId, String vmId, int pid) { - return listenerCreator.create(writerId, vmMemoryStatDAO, vmTlabStatDAO, vmId); + return listenerCreator.create(writerId, vmMemoryStatDAO, vmTlabStatDAO, vmId, pid); } static class ListenerCreator { - VmMemoryVmListener create(String writerId, VmMemoryStatDAO dao, VmTlabStatDAO tlabDao, String vmId) { - return new VmMemoryVmListener(writerId, dao, tlabDao, vmId); + VmMemoryVmListener create(String writerId, VmMemoryStatDAO dao, VmTlabStatDAO tlabDao, String vmId, int pid) { + return new VmMemoryVmListener(writerId, dao, tlabDao, vmId, pid); } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryResidentSizeExtractor.java Wed Sep 20 12:23:54 2017 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright 2012-2017 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.vm.memory.agent.internal; + + +public interface VmMemoryResidentSizeExtractor { + + Long getResidentMemorySize(int pid); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryResidentSizeExtractorImpl.java Wed Sep 20 12:23:54 2017 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright 2012-2017 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.vm.memory.agent.internal; + +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.portability.PortableProcessFactory; +import com.redhat.thermostat.vm.memory.agent.model.VmMemoryStat; + +public class VmMemoryResidentSizeExtractorImpl implements VmMemoryResidentSizeExtractor { + + private final PortableProcess helper; + private static final VmMemoryResidentSizeExtractor INSTANCE = new VmMemoryResidentSizeExtractorImpl(); + + public static VmMemoryResidentSizeExtractor getInstance() { + return INSTANCE; + } + + public VmMemoryResidentSizeExtractorImpl() { + helper = PortableProcessFactory.getInstance(); + } + + VmMemoryResidentSizeExtractorImpl(PortableProcess helper) { + this.helper = helper; + } + + @Override + public Long getResidentMemorySize(int pid) { + Long result = helper.getResidentMemorySize(pid); + return result == null ? VmMemoryStat.UNKNOWN : result; + } + +}
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListener.java Tue Sep 26 15:10:31 2017 +0200 +++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListener.java Wed Sep 20 12:23:54 2017 +0200 @@ -55,27 +55,29 @@ import com.redhat.thermostat.vm.memory.agent.model.VmTlabStat; public class VmMemoryVmListener implements VmUpdateListener { - + private static final Logger logger = LoggingUtils.getLogger(VmMemoryVmListener.class); private final String vmId; + private final int pid; private final VmMemoryStatDAO memDAO; private final VmTlabStatDAO tlabDAO; private final String writerId; private final Clock clock; - + private boolean error; - public VmMemoryVmListener(String writerId, VmMemoryStatDAO vmMemoryStatDao, VmTlabStatDAO vmTlabStatDao, String vmId) { - this(writerId, vmMemoryStatDao, vmTlabStatDao, new SystemClock(), vmId); + public VmMemoryVmListener(String writerId, VmMemoryStatDAO vmMemoryStatDao, VmTlabStatDAO vmTlabStatDao, String vmId, int pid) { + this(writerId, vmMemoryStatDao, vmTlabStatDao, new SystemClock(), vmId, pid); } - public VmMemoryVmListener(String writerId, VmMemoryStatDAO vmMemoryStatDao, VmTlabStatDAO vmTlabStatDao, Clock clock, String vmId) { + public VmMemoryVmListener(String writerId, VmMemoryStatDAO vmMemoryStatDao, VmTlabStatDAO vmTlabStatDao, Clock clock, String vmId, int pid) { this.memDAO = vmMemoryStatDao; this.tlabDAO = vmTlabStatDao; this.clock = clock; this.vmId = vmId; this.writerId = writerId; + this.pid = pid; } @Override @@ -85,10 +87,19 @@ recordTlabStat(extractor); } + void countersUpdated(VmUpdate update, VmMemoryResidentSizeExtractor residentMemoryExtractor) { + VmMemoryDataExtractor extractor = new VmMemoryDataExtractor(update); + recordMemoryStat(extractor, residentMemoryExtractor); + recordTlabStat(extractor); + } + void recordMemoryStat(VmMemoryDataExtractor extractor) { + recordMemoryStat(extractor, VmMemoryResidentSizeExtractorImpl.getInstance()); + } + + void recordMemoryStat(VmMemoryDataExtractor extractor, VmMemoryResidentSizeExtractor residentSizeExtractor) { try { long timestamp = clock.getRealTimeMillis(); - long metaspaceMaxCapacity = extractor.getMetaspaceMaxCapacity(VmMemoryStat.UNKNOWN); long metaspaceMinCapacity = extractor.getMetaspaceMinCapacity(VmMemoryStat.UNKNOWN); long metaspaceCapacity = extractor.getMetaspaceCapacity(VmMemoryStat.UNKNOWN); @@ -119,9 +130,11 @@ } } } - VmMemoryStat stat = new VmMemoryStat(writerId, timestamp, vmId, + Long residentMemory = residentSizeExtractor.getResidentMemorySize(pid); + VmMemoryStat stat = new VmMemoryStat(writerId, timestamp, vmId, generations.toArray(new Generation[generations.size()]), - metaspaceMaxCapacity, metaspaceMinCapacity, metaspaceCapacity, metaspaceUsed); + metaspaceMaxCapacity, metaspaceMinCapacity, metaspaceCapacity, + metaspaceUsed, residentMemory); memDAO.putVmMemoryStat(stat); } else { @@ -136,29 +149,29 @@ int generation) throws VmUpdateException { String name = extractor.getGenerationName(generation); if (name == null) { - logWarningOnce("Unable to determine name of generation " + logWarningOnce("Unable to determine name of generation " + generation + " for VM " + vmId); return null; } Long capacity = extractor.getGenerationCapacity(generation); if (capacity == null) { - logWarningOnce("Unable to determine capacity of generation " + logWarningOnce("Unable to determine capacity of generation " + generation + " for VM " + vmId); return null; } Long maxCapacity = extractor.getGenerationMaxCapacity(generation); if (maxCapacity == null) { - logWarningOnce("Unable to determine max capacity of generation " + logWarningOnce("Unable to determine max capacity of generation " + generation + " for VM " + vmId); return null; } String collector = extractor.getGenerationCollector(generation); if (collector == null) { - logWarningOnce("Unable to determine collector of generation " + logWarningOnce("Unable to determine collector of generation " + generation + " for VM " + vmId); return null; } - + Generation g = new Generation(); g.setName(name); g.setCapacity(capacity); @@ -171,29 +184,29 @@ int space) throws VmUpdateException { String name = extractor.getSpaceName(generation, space); if (name == null) { - logWarningOnce("Unable to determine name of space " + space + logWarningOnce("Unable to determine name of space " + space + " in generation " + generation + " for VM " + vmId); return null; } Long capacity = extractor.getSpaceCapacity(generation, space); if (capacity == null) { - logWarningOnce("Unable to determine capacity of space " + space + logWarningOnce("Unable to determine capacity of space " + space + " in generation " + generation + " for VM " + vmId); return null; } Long maxCapacity = extractor.getSpaceMaxCapacity(generation, space); if (maxCapacity == null) { - logWarningOnce("Unable to determine max capacity of space " + space + logWarningOnce("Unable to determine max capacity of space " + space + " in generation " + generation + " for VM " + vmId); return null; } Long used = extractor.getSpaceUsed(generation, space); if (used == null) { - logWarningOnce("Unable to determine used memory of space " + space + logWarningOnce("Unable to determine used memory of space " + space + " in generation " + generation + " for VM " + vmId); return null; } - + Space s = new Space(); s.setIndex(space); s.setName(name);
--- a/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/model/VmMemoryStat.java Tue Sep 26 15:10:31 2017 +0200 +++ b/plugins/vm-memory/agent/src/main/java/com/redhat/thermostat/vm/memory/agent/model/VmMemoryStat.java Wed Sep 20 12:23:54 2017 +0200 @@ -186,13 +186,15 @@ private long metaspaceMinCapacity; private long metaspaceCapacity; private long metaspaceUsed; + private long residentMemory; public VmMemoryStat() { - this(null, UNKNOWN, null, null, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN); + this(null, UNKNOWN, null, null, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN); } public VmMemoryStat(String writerId, long timestamp, String jvmId, Generation[] generations, - long metaspaceMaxCapacity, long metaspaceMinCapacity, long metaspaceCapacity, long metaspaceUsed) { + long metaspaceMaxCapacity, long metaspaceMinCapacity, + long metaspaceCapacity, long metaspaceUsed, long residentMemory) { super(writerId); this.timeStamp = timestamp; this.jvmId = jvmId; @@ -203,6 +205,7 @@ this.metaspaceMinCapacity = metaspaceMinCapacity; this.metaspaceCapacity = metaspaceCapacity; this.metaspaceUsed = metaspaceUsed; + this.residentMemory = residentMemory; checkSaneValuesForMetaspace(); } @@ -286,6 +289,16 @@ this.metaspaceUsed = used; } + @Persist + public long getResidentMemory() { + return residentMemory; + } + + @Persist + public void setResidentMemory(long residentMemory) { + this.residentMemory = residentMemory; + } + public boolean isMetaspacePresent() { checkSaneValuesForMetaspace(); if (metaspaceCapacity == UNKNOWN) {
--- a/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackendTest.java Tue Sep 26 15:10:31 2017 +0200 +++ b/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryBackendTest.java Wed Sep 20 12:23:54 2017 +0200 @@ -123,7 +123,7 @@ backend.bindVmTlabStatDAO(tlabDao); backend.createVmListener(writerId, vmId, pid); - verify(listenerCreator).create(writerId, dao, tlabDao, vmId); + verify(listenerCreator).create(writerId, dao, tlabDao, vmId, pid); } static class TestVmMemoryBackend extends VmMemoryBackend {
--- a/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListenerTest.java Tue Sep 26 15:10:31 2017 +0200 +++ b/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/VmMemoryVmListenerTest.java Wed Sep 20 12:23:54 2017 +0200 @@ -65,7 +65,7 @@ private static final Long[] GEN_MAX_CAPS = new Long[] { 5000L, 10000L }; private static final String[] GEN_GCS = new String[] { "GC1", "GC2" }; private static final Long[] GEN_SPACES = new Long[] { 2L, 1L }; - private static final String[][] SPACE_NAME = new String[][] { + private static final String[][] SPACE_NAME = new String[][] { { "Space1", "Space2" }, { "Space3" } }; @@ -86,19 +86,29 @@ private static final long METASPACE_MIN_CAPACITY = 0; private static final long METASPACE_CAPACITY = 10; private static final long METASPACE_USED = 5; - + private static final long RESIDENT_MEMORY_SIZE = 1024L; + private VmMemoryVmListener vmListener; private VmMemoryDataExtractor extractor; private VmMemoryStatDAO vmMemoryStatDAO; private VmTlabStatDAO vmTlabStatDAO; - + private VmMemoryResidentSizeExtractor vmResidentSizeExtractor; + @Before public void setup() throws VmUpdateException { final int numGens = 2; vmMemoryStatDAO = mock(VmMemoryStatDAO.class); vmTlabStatDAO = mock(VmTlabStatDAO.class); - vmListener = new VmMemoryVmListener("foo-agent", vmMemoryStatDAO, vmTlabStatDAO, "jvmId"); + //We can use arbitrary pid as this will not be used + //in the used VmMemoryResidentSizeExtractor anyway + vmListener = new VmMemoryVmListener("foo-agent", vmMemoryStatDAO, vmTlabStatDAO, "jvmId", 0); extractor = mock(VmMemoryDataExtractor.class); + vmResidentSizeExtractor = new VmMemoryResidentSizeExtractor() { + @Override + public Long getResidentMemorySize(int pid) { + return RESIDENT_MEMORY_SIZE; + } + }; mockTotalGenerations(numGens); @@ -128,7 +138,7 @@ private void mockGenerationName(int gen) throws VmUpdateException { when(extractor.getGenerationName(gen)).thenReturn(GEN_NAMES[gen]); } - + private void mockGenerationCapacity(int gen) throws VmUpdateException { when(extractor.getGenerationCapacity(gen)).thenReturn(GEN_CAPS[gen]); } @@ -136,27 +146,27 @@ private void mockGenerationMaxCapacity(int gen) throws VmUpdateException { when(extractor.getGenerationMaxCapacity(gen)).thenReturn(GEN_MAX_CAPS[gen]); } - + private void mockGenerationGC(int gen) throws VmUpdateException { when(extractor.getGenerationCollector(gen)).thenReturn(GEN_GCS[gen]); } - + private void mockTotalSpaces(int gen) throws VmUpdateException { when(extractor.getTotalSpaces(gen)).thenReturn(GEN_SPACES[gen]); } - + private void mockSpaceName(int gen, int space) throws VmUpdateException { when(extractor.getSpaceName(gen, space)).thenReturn(SPACE_NAME[gen][space]); } - + private void mockSpaceCapacity(int gen, int space) throws VmUpdateException { when(extractor.getSpaceCapacity(gen, space)).thenReturn(SPACE_CAPS[gen][space]); } - + private void mockSpaceMaxCapacity(int gen, int space) throws VmUpdateException { when(extractor.getSpaceMaxCapacity(gen, space)).thenReturn(SPACE_MAX_CAPS[gen][space]); } - + private void mockSpaceUsed(int gen, int space) throws VmUpdateException { when(extractor.getSpaceUsed(gen, space)).thenReturn(SPACE_USED[gen][space]); } @@ -175,7 +185,7 @@ @Test public void testMonitorsUpdated() throws VmUpdateException { VmUpdate update = mock(VmUpdate.class); - vmListener.countersUpdated(update); + vmListener.countersUpdated(update, vmResidentSizeExtractor); verify(vmMemoryStatDAO).putVmMemoryStat(isA(VmMemoryStat.class)); verify(vmTlabStatDAO).putStat(isA(VmTlabStat.class)); @@ -183,11 +193,11 @@ @Test public void testRecordMemoryStat() { - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class); verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); VmMemoryStat memoryStat = captor.getValue(); - + Generation[] gens = memoryStat.getGenerations(); assertEquals(2, gens.length); for (int i = 0; i < gens.length; i++) { @@ -206,7 +216,7 @@ assertEquals(SPACE_USED[i][j], (Long) space.getUsed()); } } - + assertEquals(RESIDENT_MEMORY_SIZE, memoryStat.getResidentMemory()); assertEquals(METASPACE_MAX_CAPACITY, memoryStat.getMetaspaceMaxCapacity()); assertEquals(METASPACE_MIN_CAPACITY, memoryStat.getMetaspaceMinCapacity()); assertEquals(METASPACE_CAPACITY, memoryStat.getMetaspaceCapacity()); @@ -216,26 +226,26 @@ @Test public void testRecordingMemoryInPresenseOfExtrationErrors() throws VmUpdateException { when(extractor.getTotalGcGenerations()).thenThrow(new VmUpdateException()); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); verifyNoMoreInteractions(vmMemoryStatDAO); } - + @Test public void testRecordMemoryStatNoTotal() throws VmUpdateException { when(extractor.getTotalGcGenerations()).thenReturn(null); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); verify(vmMemoryStatDAO, never()).putVmMemoryStat(any(VmMemoryStat.class)); } @Test public void testRecordMemoryStatNoName() throws VmUpdateException { when(extractor.getGenerationName(0)).thenReturn(null); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class); verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); VmMemoryStat memoryStat = captor.getValue(); - + Generation[] gens = memoryStat.getGenerations(); assertEquals(1, gens.length); Generation gen = gens[0]; @@ -253,15 +263,15 @@ assertEquals(SPACE_USED[1][j], (Long) space.getUsed()); } } - + @Test public void testRecordMemoryStatNoCapacity() throws VmUpdateException { when(extractor.getGenerationCapacity(0)).thenReturn(null); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class); verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); VmMemoryStat memoryStat = captor.getValue(); - + Generation[] gens = memoryStat.getGenerations(); assertEquals(1, gens.length); Generation gen = gens[0]; @@ -279,15 +289,15 @@ assertEquals(SPACE_USED[1][j], (Long) space.getUsed()); } } - + @Test public void testRecordMemoryStatNoMaxCapacity() throws VmUpdateException { when(extractor.getGenerationMaxCapacity(0)).thenReturn(null); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class); verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); VmMemoryStat memoryStat = captor.getValue(); - + Generation[] gens = memoryStat.getGenerations(); assertEquals(1, gens.length); Generation gen = gens[0]; @@ -305,15 +315,15 @@ assertEquals(SPACE_USED[1][j], (Long) space.getUsed()); } } - + @Test public void testRecordMemoryStatNoCollector() throws VmUpdateException { when(extractor.getGenerationCollector(0)).thenReturn(null); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor,vmResidentSizeExtractor); ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class); verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); VmMemoryStat memoryStat = captor.getValue(); - + Generation[] gens = memoryStat.getGenerations(); assertEquals(1, gens.length); Generation gen = gens[0]; @@ -331,15 +341,15 @@ assertEquals(SPACE_USED[1][j], (Long) space.getUsed()); } } - + @Test public void testRecordMemoryStatNoTotalSpaces() throws VmUpdateException { when(extractor.getTotalSpaces(0)).thenReturn(null); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class); verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); VmMemoryStat memoryStat = captor.getValue(); - + Generation[] gens = memoryStat.getGenerations(); assertEquals(1, gens.length); Generation gen = gens[0]; @@ -357,15 +367,15 @@ assertEquals(SPACE_USED[1][j], (Long) space.getUsed()); } } - + @Test public void testRecordMemoryStatNoSpaceName() throws VmUpdateException { when(extractor.getSpaceName(0, 1)).thenReturn(null); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class); verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); VmMemoryStat memoryStat = captor.getValue(); - + Generation[] gens = memoryStat.getGenerations(); assertEquals(2, gens.length); for (int i = 0; i < gens.length; i++) { @@ -391,15 +401,15 @@ } } } - + @Test public void testRecordMemoryStatNoSpaceCapacity() throws VmUpdateException { when(extractor.getSpaceCapacity(0, 1)).thenReturn(null); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class); verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); VmMemoryStat memoryStat = captor.getValue(); - + Generation[] gens = memoryStat.getGenerations(); assertEquals(2, gens.length); for (int i = 0; i < gens.length; i++) { @@ -425,15 +435,15 @@ } } } - + @Test public void testRecordMemoryStatNoSpaceMaxCapacity() throws VmUpdateException { when(extractor.getSpaceMaxCapacity(0, 1)).thenReturn(null); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class); verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); VmMemoryStat memoryStat = captor.getValue(); - + Generation[] gens = memoryStat.getGenerations(); assertEquals(2, gens.length); for (int i = 0; i < gens.length; i++) { @@ -459,15 +469,15 @@ } } } - + @Test public void testRecordMemoryStatNoSpaceUsed() throws VmUpdateException { when(extractor.getSpaceUsed(0, 1)).thenReturn(null); - vmListener.recordMemoryStat(extractor); + vmListener.recordMemoryStat(extractor, vmResidentSizeExtractor); ArgumentCaptor<VmMemoryStat> captor = ArgumentCaptor.forClass(VmMemoryStat.class); verify(vmMemoryStatDAO).putVmMemoryStat(captor.capture()); VmMemoryStat memoryStat = captor.getValue(); - + Generation[] gens = memoryStat.getGenerations(); assertEquals(2, gens.length); for (int i = 0; i < gens.length; i++) {
--- a/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAOImplTest.java Tue Sep 26 15:10:31 2017 +0200 +++ b/plugins/vm-memory/agent/src/test/java/com/redhat/thermostat/vm/memory/agent/internal/models/VmMemoryStatDAOImplTest.java Wed Sep 20 12:23:54 2017 +0200 @@ -62,7 +62,7 @@ private static final String JSON = "{\"this\":\"is\",\"test\":\"JSON\"}"; private static final URI GATEWAY_URI = URI.create("http://example.com/jvm-memory/0.0.2/"); - + private JsonHelper jsonHelper; private PluginConfiguration config; VmMemoryStatDAOImpl.ConfigurationCreator creator; @@ -73,7 +73,7 @@ public void setUp() throws Exception { jsonHelper = mock(JsonHelper.class); when(jsonHelper.toJson(anyListOf(VmMemoryStat.class))).thenReturn(JSON); - + config = mock(PluginConfiguration.class); when(config.getGatewayURL()).thenReturn(GATEWAY_URI); @@ -115,7 +115,7 @@ gen.setSpaces(spaces.toArray(new Space[spaces.size()])); } VmMemoryStat stat = new VmMemoryStat("foo-agent", 1, "jvmId", generations.toArray(new Generation[generations.size()]), - 2, 3, 4, 5); + 2, 3, 4, 5, 0); VmMemoryStatDAOImpl dao = new VmMemoryStatDAOImpl(jsonHelper, creator, source); dao.bindHttpRequestService(httpRequestService); @@ -123,12 +123,12 @@ when(id.getSystemID()).thenReturn("systemid"); dao.bindSystemID(id); dao.activate(); - + dao.putVmMemoryStat(stat); verify(jsonHelper).toJson(Arrays.asList(stat)); verify(httpRequestService).sendHttpRequest(JSON, GATEWAY_URI.resolve("systems/systemid/jvms/jvmId"), HttpRequestService.Method.POST); } - + }