Mercurial > hg > thermostat-ng > agent
changeset 2753:2f33764996f8
Port native library plugin to Windows
This patch adds Windows compatibility for the native library plugin code, and moves the Linux code to common-portability module.
Reviewed-by: sgehwolf
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-September/024893.html
line wrap: on
line diff
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcess.java Mon Sep 11 15:58:32 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcess.java Tue Sep 12 08:41:11 2017 -0400 @@ -61,4 +61,6 @@ boolean terminateProcess(int pid, int exitcode, int waitMillis); int getCurrentProcessPid(); + + String[] getNativeLibs(int pid); }
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/PosixHelperImpl.java Mon Sep 11 15:58:32 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/PosixHelperImpl.java Tue Sep 12 08:41:11 2017 -0400 @@ -36,7 +36,7 @@ package com.redhat.thermostat.common.portability.internal; -public class PosixHelperImpl { +public class PosixHelperImpl extends PortableNativeLibraryLoader{ public int getCurrentProcessPid() { return getCurrentProcessID0();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxNativeLibsExtractor.java Tue Sep 12 08:41:11 2017 -0400 @@ -0,0 +1,84 @@ +/* + * 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 Mon Sep 11 15:58:32 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessImpl.java Tue Sep 12 08:41:11 2017 -0400 @@ -119,4 +119,9 @@ public int getCurrentProcessPid() { return posixHelper.getCurrentProcessPid(); } + + @Override + public String[] getNativeLibs(int pid) { + return LinuxNativeLibsExtractor.getNativeLibs(pid); + } }
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSProcessImpl.java Mon Sep 11 15:58:32 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSProcessImpl.java Tue Sep 12 08:41:11 2017 -0400 @@ -41,6 +41,7 @@ import com.redhat.thermostat.common.portability.PortableProcessStat; import com.redhat.thermostat.common.portability.PortableVmIoStat; import com.redhat.thermostat.common.portability.internal.PosixHelperImpl; +import com.redhat.thermostat.common.portability.internal.UnimplementedError; import java.util.Map; @@ -102,4 +103,9 @@ public int getCurrentProcessPid() { return posixHelper.getCurrentProcessPid(); } + + @Override + public String[] getNativeLibs(int pid) { + throw new UnimplementedError("getNativeLibs() is unsupported on macOS"); + } }
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java Mon Sep 11 15:58:32 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java Tue Sep 12 08:41:11 2017 -0400 @@ -45,7 +45,6 @@ import java.util.HashMap; import java.util.Map; - /** * Utility class to access Windows native code */ @@ -307,6 +306,15 @@ return terminateProcess0(pid, exitcode, waitMillis); } + /** + * returns a list ofprocess modules. + * @param pid process id (input) if 0, use current process + * @return array of process moudles (DLLs and executable), module 0 is executable binary. NULL if there was an error. + */ + public String[] getProcessModules(int pid) { + return getModules0(pid); + } + private static native String getHostName0(boolean prependDomain); private static native void getOSVersion0(long[] versionAndBuild); private static native boolean getGlobalMemoryStatus0(long[] info); @@ -321,11 +329,15 @@ private static native String getProcessSID0(int pid); private static native String getUserName0(int pid, boolean prependDomain); - private static native Object getEnvironment0(long hProcess, int mode); // mode = 0 returns DirectByteBuffer, 1 = String cwd, 2 = String execuatable, 3 = String command line private static native boolean getProcessInfo0(int pid, long[] info); private static native boolean getProcessIOInfo0(int pid, long[] info); private static native int exists0(int pid); + // mode = 0 returns DirectByteBuffer, 1 = String cwd, 2 = String executable, 3 = String command line + private static native Object getEnvironment0(long hProcess, int mode); + + private static native String[] getModules0(int pid); + private static native int getCurrentProcessID0(); private static native long getCurrentProcessHandle0(); private static native long getProcessHandle0(int pid);
--- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableProcessImpl.java Mon Sep 11 15:58:32 2017 +0200 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableProcessImpl.java Tue Sep 12 08:41:11 2017 -0400 @@ -106,4 +106,9 @@ public int getCurrentProcessPid() { return helper.getCurrentProcessPid(); } + + @Override + public String[] getNativeLibs(int pid) { + return helper.getProcessModules(pid); + } }
--- a/common/portability/src/main/native/WindowsHelperImpl.c Mon Sep 11 15:58:32 2017 +0200 +++ b/common/portability/src/main/native/WindowsHelperImpl.c Tue Sep 12 08:41:11 2017 -0400 @@ -1007,3 +1007,48 @@ void *buffer = (*env)->GetDirectBufferAddress(env, bytebuffer); free(buffer); } + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: getModules0 + * Signature: (J)[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getModules0 + (JNIEnv *env, jclass klass, jint pid) { + + // Get a handle to the process (current process if pid = 0) + HANDLE hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); + if (NULL == hProcess) { + return NULL; + } + + jobjectArray ret = NULL; + + // Get a list of all the modules in this process. + DWORD cbNeeded = 0; + if (EnumProcessModules(hProcess, NULL, 0, &cbNeeded)) { + HMODULE* hMods = malloc(cbNeeded); + DWORD retBytes = 0; + // potential chase here: the library list can change size between these two calls. + if (EnumProcessModules(hProcess, hMods, cbNeeded, &retBytes)) { + int nModules = (retBytes / sizeof(HMODULE)); + ret = (jobjectArray) (*env)->NewObjectArray(env, nModules, (*env)->FindClass(env, "java/lang/String"), NULL); + for (int i = 0; i < nModules; i++) { + TCHAR szModName[MAX_PATH]; + // Get the full path to the module's file. + int nchar = GetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)); + if (nchar > 0) { + // Print the module name and handle value. + jstring s = (*env)->NewString(env, (const jchar *)szModName, (jsize)wcslen(szModName)); + s = (*env)->NewStringUTF(env, szModName); + (*env)->SetObjectArrayElement(env, ret, i, s); + } + } + } + free(hMods); + } + + // Release the handle to the process. + CloseHandle( hProcess ); + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxNativeLibsExtractorTest.java Tue Sep 12 08:41:11 2017 -0400 @@ -0,0 +1,100 @@ +/* + * 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/resources/native_lib_empty Tue Sep 12 08:41:11 2017 -0400 @@ -0,0 +1,1 @@ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/resources/native_lib_no_libs Tue Sep 12 08:41:11 2017 -0400 @@ -0,0 +1,3 @@ +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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/test/resources/native_lib_three_libs Tue Sep 12 08:41:11 2017 -0400 @@ -0,0 +1,4 @@ +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/VmLinuxNativeLibsExtractor.java Mon Sep 11 15:58:32 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +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.jvm.overview.agent.internal.model; - -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.Objects; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class VmLinuxNativeLibsExtractor implements VmNativeLibsExtractor { - - private static final Logger LOGGER - = LoggingUtils.getLogger(VmInfoDAOImpl.class); - - private final Integer pid; - - public VmLinuxNativeLibsExtractor(Integer pid) { - Objects.requireNonNull(pid); - this.pid = pid; - } - - private 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]; - } - } - - @Override - public String[] getNativeLibs() { - return getNativeLibsFromReader(new File(String.format("/proc/%d/maps", pid))); - } - - // for testing purposes only - String[] getNativeLibs(File testFile) { - return getNativeLibsFromReader(testFile); - } -}
--- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmNativeLibsExtractorFactory.java Mon Sep 11 15:58:32 2017 +0200 +++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmNativeLibsExtractorFactory.java Tue Sep 12 08:41:11 2017 -0400 @@ -41,10 +41,6 @@ public final class VmNativeLibsExtractorFactory { public static VmNativeLibsExtractor getInstance(Integer pid) { - if (OS.IS_LINUX) { - return new VmLinuxNativeLibsExtractor(pid); - } else { - throw new UnsupportedOperationException("Extractor for the given OS not supported yet."); - } + return new VmNativeLibsExtractorImpl(pid); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmNativeLibsExtractorImpl.java Tue Sep 12 08:41:11 2017 -0400 @@ -0,0 +1,58 @@ +/* + * 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.jvm.overview.agent.internal.model; + +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.portability.PortableProcessFactory; + +import java.util.Objects; + +public class VmNativeLibsExtractorImpl implements VmNativeLibsExtractor { + + private final Integer pid; + private final PortableProcess helper = PortableProcessFactory.getInstance(); + + public VmNativeLibsExtractorImpl(Integer pid) { + Objects.requireNonNull(pid); + this.pid = pid; + } + + @Override + public String[] getNativeLibs() { + return helper.getNativeLibs(pid); + } +}
--- a/plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmLinuxNativeLibsExtractorTest.java Mon Sep 11 15:58:32 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +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.jvm.overview.agent.internal.model; - -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.Before; -import org.junit.Test; - -public class VmLinuxNativeLibsExtractorTest { - - private VmLinuxNativeLibsExtractor extractor; - - private static final Integer VM_PID = 0; - - 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); - } - } - - @Before - public void setup() { - extractor = new VmLinuxNativeLibsExtractor(VM_PID); - } - - @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(extractor.getNativeLibs(THREE_LIBS)))); - } - - @Test - public void noLibs() { - String[] result = extractor.getNativeLibs(NO_LIBS); - int numExpectedLibs = 0; - - assertNotNull(result); - assertEquals(result.length, numExpectedLibs); - - } - - @Test - public void empty() { - String[] result = extractor.getNativeLibs(EMPTY); - int numExpectedLibs = 0; - - assertNotNull(result); - assertEquals(result.length, numExpectedLibs); - - } - -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmNativeLibsExtractorImplTest.java Tue Sep 12 08:41:11 2017 -0400 @@ -0,0 +1,83 @@ +/* + * 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.jvm.overview.agent.internal.model; + +import com.redhat.thermostat.common.portability.PortableProcess; +import com.redhat.thermostat.common.portability.PortableProcessFactory; +import com.redhat.thermostat.shared.config.OS; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class VmNativeLibsExtractorImplTest { + + private PortableProcess procHelper = PortableProcessFactory.getInstance(); + + @Before + public void setup() { + procHelper = PortableProcessFactory.getInstance(); + } + + @Test + public void currentProcessTest() { + final int pid = procHelper.getCurrentProcessPid(); + VmNativeLibsExtractorImpl extractor = new VmNativeLibsExtractorImpl(pid); + checkLibs(extractor.getNativeLibs()); + } + + private void checkLibs(final String[] libArray) { + assertNotNull(libArray); + Set<String> libs = new HashSet<String>(); + for (String s : libArray) { + File f = new File(s); + libs.add(f.getName().toLowerCase()); + } + if (OS.IS_WINDOWS) { + assertTrue(libs.contains("jvm.dll")); + } else if (OS.IS_MACOS) { + assertTrue(libs.contains("libjvm.dylib")); + } else { + assertTrue(libs.contains("libjvm.so")); + } + } +}
--- a/plugins/jvm-overview/agent/src/test/resources/native_lib_empty Mon Sep 11 15:58:32 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -
--- a/plugins/jvm-overview/agent/src/test/resources/native_lib_no_libs Mon Sep 11 15:58:32 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/plugins/jvm-overview/agent/src/test/resources/native_lib_three_libs Mon Sep 11 15:58:32 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 -