# HG changeset patch # User Mario Torre # Date 1506431431 -7200 # Node ID 845c5af7b42ff863f98512b410f5f3650e9abf9a # Parent 8a51183ffad8ed61fc3b268266c26fa700ca2dee Add VM Mapper service review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-September/025088.html reviwed-by: jerboaa diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/VmListenerBackend.java --- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/VmListenerBackend.java Tue Sep 26 15:10:28 2017 +0200 +++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/VmListenerBackend.java Tue Sep 26 15:10:31 2017 +0200 @@ -42,6 +42,7 @@ import com.redhat.thermostat.backend.BaseBackend; import com.redhat.thermostat.backend.BackendException; import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.jvm.overview.agent.internal.VmMonitor; import com.redhat.thermostat.storage.core.WriterID; /** diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/VmMonitor.java --- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/VmMonitor.java Tue Sep 26 15:10:28 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +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 - * . - * - * 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; - -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.backend.BackendException; -import com.redhat.thermostat.jvm.overview.agent.internal.VmListenerWrapper; -import sun.jvmstat.monitor.HostIdentifier; -import sun.jvmstat.monitor.MonitorException; -import sun.jvmstat.monitor.MonitoredHost; -import sun.jvmstat.monitor.MonitoredVm; -import sun.jvmstat.monitor.VmIdentifier; - -import com.redhat.thermostat.common.portability.ProcessChecker; -import com.redhat.thermostat.common.Pair; -import com.redhat.thermostat.common.utils.LoggingUtils; - -public class VmMonitor { - - private final Logger logger = LoggingUtils.getLogger(VmMonitor.class); - - private final ProcessChecker processChecker; - private MonitoredHost host; - private Map> pidToData = new HashMap<>(); - - public VmMonitor() throws BackendException { - this(new ProcessChecker()); - } - - public VmMonitor(ProcessChecker processChecker) throws BackendException { - this.processChecker = processChecker; - try { - HostIdentifier hostId = new HostIdentifier((String) null); - host = MonitoredHost.getMonitoredHost(hostId); - } catch (MonitorException me) { - throw new BackendException("Problems with connecting jvmstat to local machine", me); - } catch (URISyntaxException use) { - throw new BackendException("Failed to create host identifier", use); - } - } - - public void handleNewVm(VmUpdateListener listener, int pid) { - try { - MonitoredVm vm = host.getMonitoredVm(host.getHostIdentifier().resolve(new VmIdentifier(String.valueOf(pid)))); - VmListenerWrapper wrapper = new VmListenerWrapper(listener, vm); - vm.addVmListener(wrapper); - - pidToData.put(pid, new Pair<>(vm, wrapper)); - logger.finer("Attached " + listener.getClass().getName() + " for VM: " + pid); - } catch (MonitorException e) { - logMsg(pid, e); - } catch (URISyntaxException e) { - logger.log(Level.WARNING, "unable to attach to vm " + pid, e); - } - } - - private void logMsg(int pid, MonitorException e) { - Throwable cause = e.getCause(); - if (cause != null && cause instanceof IllegalArgumentException && !processChecker.exists(pid)) { - logger.log(Level.FINEST, "Tried to attach to a process which no longer exists. Pid was " + pid, e); - } else { - logger.log(Level.WARNING, "unable to attach to vm" + pid, e); - } - } - - public void handleStoppedVm(int pid) { - Pair data = pidToData.remove(pid); - // we were not monitoring pid at all, so nothing to do - if (data == null) { - return; - } - - MonitoredVm vm = data.getFirst(); - VmListenerWrapper listener = data.getSecond(); - try { - vm.removeVmListener(listener); - } catch (MonitorException e) { - logger.log(Level.WARNING, "can't remove vm listener", e); - } - vm.detach(); - } - - public void removeVmListeners() { - for (Pair data : pidToData.values()) { - MonitoredVm vm = data.getFirst(); - VmListenerWrapper listener = data.getSecond(); - try { - vm.removeVmListener(listener); - } catch (MonitorException e) { - logger.log(Level.WARNING, "can't remove vm listener", e); - } - } - pidToData.clear(); - } - - /* - * For testing purposes only. - */ - void setHost(MonitoredHost host) { - this.host = host; - } - - /* - * For testing purposes only. - */ - Map> getPidToDataMap() { - return pidToData; - } - -} - diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/VmPollingBackend.java --- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/VmPollingBackend.java Tue Sep 26 15:10:28 2017 +0200 +++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/VmPollingBackend.java Tue Sep 26 15:10:31 2017 +0200 @@ -50,6 +50,8 @@ import com.redhat.thermostat.common.Pair; import com.redhat.thermostat.common.Version; import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.jvm.overview.agent.internal.model.VmMapperServiceImpl; +import com.redhat.thermostat.jvm.overview.agent.model.VmMapperService; /** * Convenience {@link com.redhat.thermostat.backend.Backend} class for implementations that will take some diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/VMMonitorBackend.java --- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/VMMonitorBackend.java Tue Sep 26 15:10:28 2017 +0200 +++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/VMMonitorBackend.java Tue Sep 26 15:10:31 2017 +0200 @@ -43,6 +43,8 @@ import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.jvm.overview.agent.VmBlacklist; import com.redhat.thermostat.jvm.overview.agent.internal.model.VmInfoDAO; +import com.redhat.thermostat.jvm.overview.agent.internal.model.VmMapperServiceImpl; +import com.redhat.thermostat.jvm.overview.agent.model.VmMapperService; import com.redhat.thermostat.storage.core.WriterID; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; @@ -50,6 +52,7 @@ import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; import sun.jvmstat.monitor.HostIdentifier; import sun.jvmstat.monitor.MonitorException; import sun.jvmstat.monitor.MonitoredHost; @@ -80,6 +83,8 @@ private MonitoredHost host; private JvmStatHostListener hostListener; + private VmMapperServiceImpl vmMapperService; + private ServiceRegistration mapperRegistration; public VMMonitorBackend() { super("VM Basic Monitor Backend", @@ -90,13 +95,18 @@ @Activate private void _activate_(BundleContext context) { - notifier = new VmStatusChangeNotifier(context); + + vmMapperService = new VmMapperServiceImpl(); + mapperRegistration = context.registerService(VmMapperService.class, vmMapperService, null); + + notifier = new VmStatusChangeNotifier(context, vmMapperService); notifier.start(); } @Deactivate private void _deactivate_() { notifier.stop(); + mapperRegistration.unregister(); } @Override diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/VmMonitor.java --- /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/VmMonitor.java Tue Sep 26 15:10:31 2017 +0200 @@ -0,0 +1,150 @@ +/* + * 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 + * . + * + * 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; + +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.backend.BackendException; +import com.redhat.thermostat.jvm.overview.agent.VmUpdateListener; +import sun.jvmstat.monitor.HostIdentifier; +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredHost; +import sun.jvmstat.monitor.MonitoredVm; +import sun.jvmstat.monitor.VmIdentifier; + +import com.redhat.thermostat.common.portability.ProcessChecker; +import com.redhat.thermostat.common.Pair; +import com.redhat.thermostat.common.utils.LoggingUtils; + +public class VmMonitor { + + private final Logger logger = LoggingUtils.getLogger(VmMonitor.class); + + private final ProcessChecker processChecker; + private MonitoredHost host; + private Map> pidToData = new HashMap<>(); + + public VmMonitor() throws BackendException { + this(new ProcessChecker()); + } + + public VmMonitor(ProcessChecker processChecker) throws BackendException { + this.processChecker = processChecker; + try { + HostIdentifier hostId = new HostIdentifier((String) null); + host = MonitoredHost.getMonitoredHost(hostId); + } catch (MonitorException me) { + throw new BackendException("Problems with connecting jvmstat to local machine", me); + } catch (URISyntaxException use) { + throw new BackendException("Failed to create host identifier", use); + } + } + + public void handleNewVm(VmUpdateListener listener, int pid) { + try { + MonitoredVm vm = host.getMonitoredVm(host.getHostIdentifier().resolve(new VmIdentifier(String.valueOf(pid)))); + VmListenerWrapper wrapper = new VmListenerWrapper(listener, vm); + vm.addVmListener(wrapper); + + pidToData.put(pid, new Pair<>(vm, wrapper)); + logger.finer("Attached " + listener.getClass().getName() + " for VM: " + pid); + } catch (MonitorException e) { + logMsg(pid, e); + } catch (URISyntaxException e) { + logger.log(Level.WARNING, "unable to attach to vm " + pid, e); + } + } + + private void logMsg(int pid, MonitorException e) { + Throwable cause = e.getCause(); + if (cause != null && cause instanceof IllegalArgumentException && !processChecker.exists(pid)) { + logger.log(Level.FINEST, "Tried to attach to a process which no longer exists. Pid was " + pid, e); + } else { + logger.log(Level.WARNING, "unable to attach to vm" + pid, e); + } + } + + public void handleStoppedVm(int pid) { + Pair data = pidToData.remove(pid); + // we were not monitoring pid at all, so nothing to do + if (data == null) { + return; + } + + MonitoredVm vm = data.getFirst(); + VmListenerWrapper listener = data.getSecond(); + try { + vm.removeVmListener(listener); + } catch (MonitorException e) { + logger.log(Level.WARNING, "can't remove vm listener", e); + } + vm.detach(); + } + + public void removeVmListeners() { + for (Pair data : pidToData.values()) { + MonitoredVm vm = data.getFirst(); + VmListenerWrapper listener = data.getSecond(); + try { + vm.removeVmListener(listener); + } catch (MonitorException e) { + logger.log(Level.WARNING, "can't remove vm listener", e); + } + } + pidToData.clear(); + } + + /* + * For testing purposes only. + */ + void setHost(MonitoredHost host) { + this.host = host; + } + + /* + * For testing purposes only. + */ + Map> getPidToDataMap() { + return pidToData; + } + +} + diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/VmStatusChangeNotifier.java --- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/VmStatusChangeNotifier.java Tue Sep 26 15:10:28 2017 +0200 +++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/VmStatusChangeNotifier.java Tue Sep 26 15:10:31 2017 +0200 @@ -45,6 +45,7 @@ import com.redhat.thermostat.jvm.overview.agent.VmStatusListener; import com.redhat.thermostat.jvm.overview.agent.VmStatusListener.Status; +import com.redhat.thermostat.jvm.overview.agent.internal.model.VmMapperServiceImpl; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; @@ -66,8 +67,12 @@ private final Map> listeners = new ConcurrentHashMap<>(); private final ServiceTracker tracker; + private VmMapperServiceImpl vmMapperService; - public VmStatusChangeNotifier(BundleContext bundleContext) { + public VmStatusChangeNotifier(BundleContext bundleContext, VmMapperServiceImpl vmMapperService) { + + this.vmMapperService = vmMapperService; + this.activePids = new HashMap<>(); tracker = new ServiceTracker(bundleContext, VmStatusListener.class, null) { @@ -128,6 +133,7 @@ if (newStatus == Status.VM_STARTED) { activePids.put(pid, vmId); + vmMapperService.cache(vmId, pid); } else { activePids.remove(pid); } diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmMapperServiceImpl.java --- /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/VmMapperServiceImpl.java Tue Sep 26 15:10:31 2017 +0200 @@ -0,0 +1,71 @@ +/* + * 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 + * . + * + * 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.jvm.overview.agent.model.VmId; +import com.redhat.thermostat.jvm.overview.agent.model.VmMapperService; +import com.redhat.thermostat.lang.schema.models.Pid; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class VmMapperServiceImpl implements VmMapperService { + + private Map cache; + + public VmMapperServiceImpl() { + this(new ConcurrentHashMap()); + } + + VmMapperServiceImpl(Map cache) { + this.cache = cache; + } + + @Override + public Pid getPid(VmId vmId) { + return getPid(vmId.get()); + } + + @Override + public Pid getPid(String vmId) { + return cache.get(vmId); + } + + public void cache(String vmId, int pid) { + cache.put(vmId, new Pid(pid)); + } +} diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/model/HostsVMsLoader.java --- a/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/model/HostsVMsLoader.java Tue Sep 26 15:10:28 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +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 - * . - * - * 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.model; - -import com.redhat.thermostat.storage.core.HostRef; - -import java.util.Collection; - - -/** - * Provides a way to load the current hosts and VMs. - */ -public interface HostsVMsLoader { - - Collection getHosts(); - Collection getVMs(HostRef host); -} - diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/model/VmMapperService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/jvm-overview/agent/src/main/java/com/redhat/thermostat/jvm/overview/agent/model/VmMapperService.java Tue Sep 26 15:10:31 2017 +0200 @@ -0,0 +1,46 @@ +/* + * 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 + * . + * + * 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.model; + +import com.redhat.thermostat.annotations.Service; +import com.redhat.thermostat.lang.schema.models.Pid; + +@Service +public interface VmMapperService { + Pid getPid(VmId vmId); + Pid getPid(String vmId); +} diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/VmListenerBackendTest.java --- a/plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/VmListenerBackendTest.java Tue Sep 26 15:10:28 2017 +0200 +++ b/plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/VmListenerBackendTest.java Tue Sep 26 15:10:31 2017 +0200 @@ -48,6 +48,7 @@ import java.net.URISyntaxException; import com.redhat.thermostat.jvm.overview.agent.VmStatusListener.Status; +import com.redhat.thermostat.jvm.overview.agent.internal.VmMonitor; import org.junit.Before; import org.junit.Test; diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/VmMonitorTest.java --- a/plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/VmMonitorTest.java Tue Sep 26 15:10:28 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,286 +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 - * . - * - * 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; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.isA; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import java.net.URISyntaxException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.redhat.thermostat.jvm.overview.agent.internal.TestLogHandler; -import com.redhat.thermostat.jvm.overview.agent.internal.VmListenerWrapper; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import com.redhat.thermostat.common.portability.ProcessChecker; - -import sun.jvmstat.monitor.HostIdentifier; -import sun.jvmstat.monitor.MonitorException; -import sun.jvmstat.monitor.MonitoredHost; -import sun.jvmstat.monitor.MonitoredVm; -import sun.jvmstat.monitor.VmIdentifier; -import sun.jvmstat.monitor.event.VmListener; - -public class VmMonitorTest { - - private static final String PROCESS_NOT_FOUND = "Process not found"; - private static final int MONITOR_EXCEPTION_THROWING_PID = 999; - private VmMonitor monitor; - private HostIdentifier hostIdentifier; - private MonitoredHost host; - private MonitoredVm monitoredVm; - private ProcessChecker checker; - private TestLogHandler handler; - private Logger logger; - private Level savedLoggingLevel; - - @After - public void tearDown() { - if (handler != null) { - logger.removeHandler(handler); - handler = null; - } - logger.setLevel(savedLoggingLevel); - } - - @Before - public void setUp() throws Exception { - savedLoggingLevel = setupTestLoggerAndReturnOriginalLevel(); - - hostIdentifier = mock(HostIdentifier.class); - when(hostIdentifier.resolve(isA(VmIdentifier.class))).then(new Answer() { - @Override - public VmIdentifier answer(InvocationOnMock invocation) throws Throwable { - return (VmIdentifier) invocation.getArguments()[0]; - } - }); - host = mock(MonitoredHost.class); - when(host.getHostIdentifier()).thenReturn(hostIdentifier); - - checker = mock(ProcessChecker.class); - when(checker.exists(isA(Integer.class))).thenReturn(false); - - monitoredVm = mock(MonitoredVm.class); - - monitor = new VmMonitor(checker); - monitor.setHost(host); - } - - private Level setupTestLoggerAndReturnOriginalLevel() { - logger = Logger.getLogger("com.redhat.thermostat"); - Level originalLevel = logger.getLevel(); - logger.setLevel(Level.FINEST); - handler = new TestLogHandler(MONITOR_EXCEPTION_THROWING_PID); - logger.addHandler(handler); - return originalLevel; - } - - @Test - public void testNewVM() throws MonitorException, URISyntaxException { - final int VM_PID = 1; - VmIdentifier VM_ID = new VmIdentifier(String.valueOf(VM_PID)); - when(host.getMonitoredVm(VM_ID)).thenReturn(monitoredVm); - - VmUpdateListener listener = mock(VmUpdateListener.class); - monitor.handleNewVm(listener, VM_PID); - - // Check listener registered - ArgumentCaptor captor = ArgumentCaptor.forClass(VmListenerWrapper.class); - verify(monitoredVm).addVmListener(captor.capture()); - VmListenerWrapper wrapper = captor.getValue(); - assertEquals(listener, wrapper.getVmUpdateListener()); - - // Check pid map - assertTrue(monitor.getPidToDataMap().containsKey(VM_PID)); - assertEquals(wrapper, monitor.getPidToDataMap().get(VM_PID).getSecond()); - } - - /* - * English locale "Process not found". It must not matter really for this - * test. See the next test which verifies this. - */ - @Test - public void testNewVMWithProcessNotFoundDoesNotLogWarning() throws Exception { - String exceptionMsg = PROCESS_NOT_FOUND; - basicProcNotFoundTest(exceptionMsg); - } - - /* - * Random exception message as the exact message will be locale dependent. - */ - @Test - public void testNewVMWithProcessNotFoundDoesNotLogWarning2() throws Exception { - String exceptionMsg = "foo but not bar"; - basicProcNotFoundTest(exceptionMsg); - } - - private void basicProcNotFoundTest(String exceptionMsg) throws Exception { - IllegalArgumentException iae = new IllegalArgumentException(exceptionMsg); - MonitorException procNotFound = new MonitorException(iae); - assertEquals(iae, procNotFound.getCause()); - - VmIdentifier vmID = new VmIdentifier(String.valueOf(MONITOR_EXCEPTION_THROWING_PID)); - when(host.getMonitoredVm(vmID)).thenThrow(procNotFound); - VmUpdateListener listener = mock(VmUpdateListener.class); - - monitor.handleNewVm(listener, MONITOR_EXCEPTION_THROWING_PID); - assertFalse(handler.isUnableToAttachLoggedAsWarning()); - assertTrue(handler.isUnableToAttachLoggedAsFinest()); - assertFalse(handler.isUnableToAttachLoggedAsWarningUnrelated()); - } - - @Test - public void testNewVMUnrelatedCausedMonitorExceptionLogWarning() throws Exception { - MonitorException procNotFound = new MonitorException("unknown"); - - VmIdentifier vmID = new VmIdentifier(String.valueOf(MONITOR_EXCEPTION_THROWING_PID)); - when(host.getMonitoredVm(vmID)).thenThrow(procNotFound); - VmUpdateListener listener = mock(VmUpdateListener.class); - - monitor.handleNewVm(listener, MONITOR_EXCEPTION_THROWING_PID); - assertFalse(handler.isUnableToAttachLoggedAsWarning()); - assertFalse(handler.isUnableToAttachLoggedAsFinest()); - assertTrue(handler.isUnableToAttachLoggedAsWarningUnrelated()); - } - - @Test - public void testStatVMGetMonitoredVmFails() throws MonitorException { - final int VM_PID = 1; - MonitorException monitorException = new MonitorException(); - when(host.getMonitoredVm(isA(VmIdentifier.class))).thenThrow(monitorException); - - VmUpdateListener listener = mock(VmUpdateListener.class); - monitor.handleNewVm(listener, VM_PID); - - assertFalse(monitor.getPidToDataMap().containsKey(VM_PID)); - } - - @Test - public void testStoppedVM() throws MonitorException, URISyntaxException { - final int VM_PID = 1; - VmIdentifier VM_ID = new VmIdentifier(String.valueOf(VM_PID)); - when(host.getMonitoredVm(VM_ID)).thenReturn(monitoredVm); - - VmUpdateListener listener = mock(VmUpdateListener.class); - - monitor.handleNewVm(listener, VM_PID); - monitor.handleStoppedVm(VM_PID); - - // Check listener unregistered - ArgumentCaptor captor = ArgumentCaptor.forClass(VmListenerWrapper.class); - verify(monitoredVm).removeVmListener(captor.capture()); - VmListenerWrapper wrapper = captor.getValue(); - assertEquals(listener, wrapper.getVmUpdateListener()); - - assertFalse(monitor.getPidToDataMap().containsKey(VM_PID)); - } - - @Test - public void testUnknownVMStopped() throws URISyntaxException, MonitorException { - final int VM_PID = 1; - VmIdentifier VM_ID = new VmIdentifier(String.valueOf(VM_PID)); - when(host.getMonitoredVm(VM_ID)).thenReturn(monitoredVm); - - monitor.handleStoppedVm(VM_PID); - - verifyNoMoreInteractions(monitoredVm); - } - - @Test - public void testErrorRemovingVmListener() throws URISyntaxException, MonitorException { - final int VM_PID = 1; - VmIdentifier VM_ID = new VmIdentifier(String.valueOf(VM_PID)); - when(host.getMonitoredVm(VM_ID)).thenReturn(monitoredVm); - - MonitorException monitorException = new MonitorException(); - doThrow(monitorException).when(monitoredVm).removeVmListener(any(VmListener.class)); - - VmUpdateListener listener = mock(VmUpdateListener.class); - monitor.handleNewVm(listener, VM_PID); - monitor.handleStoppedVm(VM_PID); - - verify(monitoredVm).detach(); - } - - @Test - public void testRemoveAllListeners() throws URISyntaxException, MonitorException { - final int VM_PID1 = 1; - final int VM_PID2 = 2; - - VmIdentifier VM_ID1 = new VmIdentifier(String.valueOf(VM_PID1)); - when(host.getMonitoredVm(VM_ID1)).thenReturn(monitoredVm); - - MonitoredVm monitoredVm2 = mock(MonitoredVm.class); - VmIdentifier VM_ID2 = new VmIdentifier(String.valueOf(VM_PID2)); - when(host.getMonitoredVm(VM_ID2)).thenReturn(monitoredVm2); - - VmUpdateListener listener1 = mock(VmUpdateListener.class); - VmUpdateListener listener2 = mock(VmUpdateListener.class); - monitor.handleNewVm(listener1, VM_PID1); - monitor.handleNewVm(listener2, VM_PID2); - - monitor.removeVmListeners(); - - ArgumentCaptor captor1 = ArgumentCaptor.forClass(VmListenerWrapper.class); - verify(monitoredVm).removeVmListener(captor1.capture()); - VmListenerWrapper wrapper1 = captor1.getValue(); - assertEquals(listener1, wrapper1.getVmUpdateListener()); - - ArgumentCaptor captor2 = ArgumentCaptor.forClass(VmListenerWrapper.class); - verify(monitoredVm2).removeVmListener(captor2.capture()); - VmListenerWrapper wrapper2 = captor2.getValue(); - assertEquals(listener2, wrapper2.getVmUpdateListener()); - - assertEquals(0, monitor.getPidToDataMap().size()); - } - -} - diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/VmMonitorTest.java --- /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/VmMonitorTest.java Tue Sep 26 15:10:31 2017 +0200 @@ -0,0 +1,287 @@ +/* + * 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 + * . + * + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import java.net.URISyntaxException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.jvm.overview.agent.VmUpdateListener; +import com.redhat.thermostat.jvm.overview.agent.internal.TestLogHandler; +import com.redhat.thermostat.jvm.overview.agent.internal.VmListenerWrapper; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.redhat.thermostat.common.portability.ProcessChecker; + +import sun.jvmstat.monitor.HostIdentifier; +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredHost; +import sun.jvmstat.monitor.MonitoredVm; +import sun.jvmstat.monitor.VmIdentifier; +import sun.jvmstat.monitor.event.VmListener; + +public class VmMonitorTest { + + private static final String PROCESS_NOT_FOUND = "Process not found"; + private static final int MONITOR_EXCEPTION_THROWING_PID = 999; + private VmMonitor monitor; + private HostIdentifier hostIdentifier; + private MonitoredHost host; + private MonitoredVm monitoredVm; + private ProcessChecker checker; + private TestLogHandler handler; + private Logger logger; + private Level savedLoggingLevel; + + @After + public void tearDown() { + if (handler != null) { + logger.removeHandler(handler); + handler = null; + } + logger.setLevel(savedLoggingLevel); + } + + @Before + public void setUp() throws Exception { + savedLoggingLevel = setupTestLoggerAndReturnOriginalLevel(); + + hostIdentifier = mock(HostIdentifier.class); + when(hostIdentifier.resolve(isA(VmIdentifier.class))).then(new Answer() { + @Override + public VmIdentifier answer(InvocationOnMock invocation) throws Throwable { + return (VmIdentifier) invocation.getArguments()[0]; + } + }); + host = mock(MonitoredHost.class); + when(host.getHostIdentifier()).thenReturn(hostIdentifier); + + checker = mock(ProcessChecker.class); + when(checker.exists(isA(Integer.class))).thenReturn(false); + + monitoredVm = mock(MonitoredVm.class); + + monitor = new VmMonitor(checker); + monitor.setHost(host); + } + + private Level setupTestLoggerAndReturnOriginalLevel() { + logger = Logger.getLogger("com.redhat.thermostat"); + Level originalLevel = logger.getLevel(); + logger.setLevel(Level.FINEST); + handler = new TestLogHandler(MONITOR_EXCEPTION_THROWING_PID); + logger.addHandler(handler); + return originalLevel; + } + + @Test + public void testNewVM() throws MonitorException, URISyntaxException { + final int VM_PID = 1; + VmIdentifier VM_ID = new VmIdentifier(String.valueOf(VM_PID)); + when(host.getMonitoredVm(VM_ID)).thenReturn(monitoredVm); + + VmUpdateListener listener = mock(VmUpdateListener.class); + monitor.handleNewVm(listener, VM_PID); + + // Check listener registered + ArgumentCaptor captor = ArgumentCaptor.forClass(VmListenerWrapper.class); + verify(monitoredVm).addVmListener(captor.capture()); + VmListenerWrapper wrapper = captor.getValue(); + assertEquals(listener, wrapper.getVmUpdateListener()); + + // Check pid map + assertTrue(monitor.getPidToDataMap().containsKey(VM_PID)); + assertEquals(wrapper, monitor.getPidToDataMap().get(VM_PID).getSecond()); + } + + /* + * English locale "Process not found". It must not matter really for this + * test. See the next test which verifies this. + */ + @Test + public void testNewVMWithProcessNotFoundDoesNotLogWarning() throws Exception { + String exceptionMsg = PROCESS_NOT_FOUND; + basicProcNotFoundTest(exceptionMsg); + } + + /* + * Random exception message as the exact message will be locale dependent. + */ + @Test + public void testNewVMWithProcessNotFoundDoesNotLogWarning2() throws Exception { + String exceptionMsg = "foo but not bar"; + basicProcNotFoundTest(exceptionMsg); + } + + private void basicProcNotFoundTest(String exceptionMsg) throws Exception { + IllegalArgumentException iae = new IllegalArgumentException(exceptionMsg); + MonitorException procNotFound = new MonitorException(iae); + assertEquals(iae, procNotFound.getCause()); + + VmIdentifier vmID = new VmIdentifier(String.valueOf(MONITOR_EXCEPTION_THROWING_PID)); + when(host.getMonitoredVm(vmID)).thenThrow(procNotFound); + VmUpdateListener listener = mock(VmUpdateListener.class); + + monitor.handleNewVm(listener, MONITOR_EXCEPTION_THROWING_PID); + assertFalse(handler.isUnableToAttachLoggedAsWarning()); + assertTrue(handler.isUnableToAttachLoggedAsFinest()); + assertFalse(handler.isUnableToAttachLoggedAsWarningUnrelated()); + } + + @Test + public void testNewVMUnrelatedCausedMonitorExceptionLogWarning() throws Exception { + MonitorException procNotFound = new MonitorException("unknown"); + + VmIdentifier vmID = new VmIdentifier(String.valueOf(MONITOR_EXCEPTION_THROWING_PID)); + when(host.getMonitoredVm(vmID)).thenThrow(procNotFound); + VmUpdateListener listener = mock(VmUpdateListener.class); + + monitor.handleNewVm(listener, MONITOR_EXCEPTION_THROWING_PID); + assertFalse(handler.isUnableToAttachLoggedAsWarning()); + assertFalse(handler.isUnableToAttachLoggedAsFinest()); + assertTrue(handler.isUnableToAttachLoggedAsWarningUnrelated()); + } + + @Test + public void testStatVMGetMonitoredVmFails() throws MonitorException { + final int VM_PID = 1; + MonitorException monitorException = new MonitorException(); + when(host.getMonitoredVm(isA(VmIdentifier.class))).thenThrow(monitorException); + + VmUpdateListener listener = mock(VmUpdateListener.class); + monitor.handleNewVm(listener, VM_PID); + + assertFalse(monitor.getPidToDataMap().containsKey(VM_PID)); + } + + @Test + public void testStoppedVM() throws MonitorException, URISyntaxException { + final int VM_PID = 1; + VmIdentifier VM_ID = new VmIdentifier(String.valueOf(VM_PID)); + when(host.getMonitoredVm(VM_ID)).thenReturn(monitoredVm); + + VmUpdateListener listener = mock(VmUpdateListener.class); + + monitor.handleNewVm(listener, VM_PID); + monitor.handleStoppedVm(VM_PID); + + // Check listener unregistered + ArgumentCaptor captor = ArgumentCaptor.forClass(VmListenerWrapper.class); + verify(monitoredVm).removeVmListener(captor.capture()); + VmListenerWrapper wrapper = captor.getValue(); + assertEquals(listener, wrapper.getVmUpdateListener()); + + assertFalse(monitor.getPidToDataMap().containsKey(VM_PID)); + } + + @Test + public void testUnknownVMStopped() throws URISyntaxException, MonitorException { + final int VM_PID = 1; + VmIdentifier VM_ID = new VmIdentifier(String.valueOf(VM_PID)); + when(host.getMonitoredVm(VM_ID)).thenReturn(monitoredVm); + + monitor.handleStoppedVm(VM_PID); + + verifyNoMoreInteractions(monitoredVm); + } + + @Test + public void testErrorRemovingVmListener() throws URISyntaxException, MonitorException { + final int VM_PID = 1; + VmIdentifier VM_ID = new VmIdentifier(String.valueOf(VM_PID)); + when(host.getMonitoredVm(VM_ID)).thenReturn(monitoredVm); + + MonitorException monitorException = new MonitorException(); + doThrow(monitorException).when(monitoredVm).removeVmListener(any(VmListener.class)); + + VmUpdateListener listener = mock(VmUpdateListener.class); + monitor.handleNewVm(listener, VM_PID); + monitor.handleStoppedVm(VM_PID); + + verify(monitoredVm).detach(); + } + + @Test + public void testRemoveAllListeners() throws URISyntaxException, MonitorException { + final int VM_PID1 = 1; + final int VM_PID2 = 2; + + VmIdentifier VM_ID1 = new VmIdentifier(String.valueOf(VM_PID1)); + when(host.getMonitoredVm(VM_ID1)).thenReturn(monitoredVm); + + MonitoredVm monitoredVm2 = mock(MonitoredVm.class); + VmIdentifier VM_ID2 = new VmIdentifier(String.valueOf(VM_PID2)); + when(host.getMonitoredVm(VM_ID2)).thenReturn(monitoredVm2); + + VmUpdateListener listener1 = mock(VmUpdateListener.class); + VmUpdateListener listener2 = mock(VmUpdateListener.class); + monitor.handleNewVm(listener1, VM_PID1); + monitor.handleNewVm(listener2, VM_PID2); + + monitor.removeVmListeners(); + + ArgumentCaptor captor1 = ArgumentCaptor.forClass(VmListenerWrapper.class); + verify(monitoredVm).removeVmListener(captor1.capture()); + VmListenerWrapper wrapper1 = captor1.getValue(); + assertEquals(listener1, wrapper1.getVmUpdateListener()); + + ArgumentCaptor captor2 = ArgumentCaptor.forClass(VmListenerWrapper.class); + verify(monitoredVm2).removeVmListener(captor2.capture()); + VmListenerWrapper wrapper2 = captor2.getValue(); + assertEquals(listener2, wrapper2.getVmUpdateListener()); + + assertEquals(0, monitor.getPidToDataMap().size()); + } + +} + diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/VmStatusChangeNotifierTest.java --- a/plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/VmStatusChangeNotifierTest.java Tue Sep 26 15:10:28 2017 +0200 +++ b/plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/VmStatusChangeNotifierTest.java Tue Sep 26 15:10:31 2017 +0200 @@ -44,6 +44,8 @@ import com.redhat.thermostat.jvm.overview.agent.VmStatusListener; import com.redhat.thermostat.jvm.overview.agent.VmStatusListener.Status; +import com.redhat.thermostat.jvm.overview.agent.internal.model.VmMapperServiceImpl; +import org.junit.Before; import org.junit.Test; import org.osgi.framework.BundleContext; @@ -51,13 +53,20 @@ public class VmStatusChangeNotifierTest { + private VmMapperServiceImpl vmMapperService; + + @Before + public void setUp() { + vmMapperService = mock(VmMapperServiceImpl.class); + } + @Test public void verifyWorksWithoutAnyListeners() { final String VM_ID = "vmId"; final int VM_PID = 2; StubBundleContext bundleContext = new StubBundleContext(); - VmStatusChangeNotifier notifier = new VmStatusChangeNotifier(bundleContext); + VmStatusChangeNotifier notifier = new VmStatusChangeNotifier(bundleContext, vmMapperService); notifier.start(); notifier.notifyVmStatusChange(Status.VM_STARTED, VM_ID, VM_PID); @@ -73,11 +82,12 @@ VmStatusListener listener = mock(VmStatusListener.class); bundleContext.registerService(VmStatusListener.class, listener, null); - VmStatusChangeNotifier notifier = new VmStatusChangeNotifier(bundleContext); + VmStatusChangeNotifier notifier = new VmStatusChangeNotifier(bundleContext, vmMapperService); notifier.start(); notifier.notifyVmStatusChange(Status.VM_STARTED, VM_ID, VM_PID); verify(listener).vmStatusChanged(Status.VM_STARTED, VM_ID, VM_PID); + verify(vmMapperService).cache(VM_ID, VM_PID); notifier.notifyVmStatusChange(Status.VM_STOPPED, VM_ID, VM_PID); @@ -90,7 +100,7 @@ final int VM_PID = 2; StubBundleContext bundleContext = new StubBundleContext(); - VmStatusChangeNotifier notifier = new VmStatusChangeNotifier(bundleContext); + VmStatusChangeNotifier notifier = new VmStatusChangeNotifier(bundleContext, vmMapperService); notifier.start(); notifier.notifyVmStatusChange(Status.VM_STARTED, VM_ID, VM_PID); @@ -109,7 +119,7 @@ @Test public void canAddListenersWhileFiringEvent() throws InterruptedException { StubBundleContext bundleContext = new StubBundleContext(); - VmStatusChangeNotifier notifier = new VmStatusChangeNotifier(bundleContext); + VmStatusChangeNotifier notifier = new VmStatusChangeNotifier(bundleContext, vmMapperService); // Add > 2 listeners. One of them registers another listener in vmStatusChanged() // Thus provoking ConcurrentModificationException. diff -r 8a51183ffad8 -r 845c5af7b42f plugins/jvm-overview/agent/src/test/java/com/redhat/thermostat/jvm/overview/agent/internal/model/VmMapperServiceImplTest.java --- /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/VmMapperServiceImplTest.java Tue Sep 26 15:10:31 2017 +0200 @@ -0,0 +1,72 @@ +/* + * 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 + * . + * + * 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.jvm.overview.agent.model.VmId; +import com.redhat.thermostat.lang.schema.models.Pid; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class VmMapperServiceImplTest { + @Test + public void cacheNewVm() throws Exception { + Map cache = new HashMap<>(); + VmMapperServiceImpl service = new VmMapperServiceImpl(cache); + assertTrue(cache.isEmpty()); + + service.cache("42", 4242); + assertTrue(cache.containsKey("42")); + assertEquals(new Pid(4242), cache.get("42")); + + assertEquals(new Pid(4242), service.getPid("42")); + assertEquals(new Pid(4242), service.getPid(new VmId("42"))); + } + + @Test + public void requestingNonExistingVmsReturnsSimplyNullNotExceptions() throws Exception { + Map cache = new HashMap<>(); + VmMapperServiceImpl service = new VmMapperServiceImpl(cache); + + assertEquals(null, service.getPid("42")); + assertEquals(null, service.getPid(new VmId("42"))); + } +}