changeset 1318:247cd7edff41

Agent Proxy client tests This patch includes all of the test cases for the previous Agent Proxy client patch. Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-November/008705.html PR1460
author Elliott Baron <ebaron@redhat.com>
date Thu, 14 Nov 2013 11:30:53 -0500
parents b8b5934f7977
children 2bfdbd5a77f6
files agent/core/src/test/java/com/redhat/thermostat/agent/internal/ActivatorTest.java agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/AgentProxyClientTest.java agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectorTest.java agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/RMIRegistryTest.java
diffstat 5 files changed, 462 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/internal/ActivatorTest.java	Thu Nov 14 11:30:11 2013 -0500
+++ b/agent/core/src/test/java/com/redhat/thermostat/agent/internal/ActivatorTest.java	Thu Nov 14 11:30:53 2013 -0500
@@ -37,6 +37,8 @@
 package com.redhat.thermostat.agent.internal;
 
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 
 import org.junit.Test;
 
@@ -44,6 +46,7 @@
 import com.redhat.thermostat.testutils.StubBundleContext;
 import com.redhat.thermostat.utils.management.MXBeanConnectionPool;
 import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl;
+import com.redhat.thermostat.utils.management.internal.RMIRegistry;
 import com.redhat.thermostat.utils.username.UserNameUtil;
 import com.redhat.thermostat.utils.username.internal.UserNameUtilImpl;
 
@@ -53,7 +56,9 @@
 
         StubBundleContext context = new StubBundleContext();
 
-        Activator activator = new Activator();
+        RMIRegistry registry = mock(RMIRegistry.class);
+        MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(registry);
+        Activator activator = new Activator(pool);
 
         activator.start(context);
 
@@ -61,4 +66,17 @@
         assertTrue(context.isServiceRegistered(UserNameUtil.class.getName(), UserNameUtilImpl.class));
         assertTrue(context.isServiceRegistered(VmBlacklist.class.getName(), VmBlacklistImpl.class));
     }
+    
+    @Test
+    public void verifyPoolShutdown() throws Exception {
+
+        StubBundleContext context = new StubBundleContext();
+
+        MXBeanConnectionPoolImpl pool = mock(MXBeanConnectionPoolImpl.class);
+        Activator activator = new Activator(pool);
+
+        activator.stop(context);
+
+        verify(pool).shutdown();
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/AgentProxyClientTest.java	Thu Nov 14 11:30:53 2013 -0500
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2012, 2013 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.utils.management.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.io.IOException;
+import java.rmi.RemoteException;
+import java.rmi.registry.Registry;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import com.redhat.thermostat.agent.proxy.common.AgentProxyControl;
+import com.redhat.thermostat.agent.proxy.common.AgentProxyListener;
+import com.redhat.thermostat.agent.proxy.common.AgentProxyLogin;
+import com.redhat.thermostat.common.tools.ApplicationException;
+import com.redhat.thermostat.shared.config.Configuration;
+import com.redhat.thermostat.utils.management.internal.AgentProxyClient.ProcessCreator;
+
+public class AgentProxyClientTest {
+    
+    private AgentProxyClient client;
+    private RMIRegistry rmi;
+    private Registry registry;
+    private ProcessCreator procCreator;
+    private Configuration config;
+    private CountDownLatch latch;
+    private AgentProxyListener listenerStub;
+    private AgentProxyLogin proxyLogin;
+    private AgentProxyControl proxyControl;
+    
+    @Before
+    public void setup() throws Exception {
+        rmi = mock(RMIRegistry.class);
+        listenerStub = mock(AgentProxyListener.class);
+        when(rmi.export(any(AgentProxyListener.class))).thenReturn(listenerStub);
+        registry = mock(Registry.class);
+        when(rmi.getRegistry()).thenReturn(registry);
+        proxyLogin = mock(AgentProxyLogin.class);
+        when(registry.lookup(AgentProxyLogin.REMOTE_PREFIX + "0")).thenReturn(proxyLogin);
+        proxyControl = mock(AgentProxyControl.class);
+        when(proxyLogin.login()).thenReturn(proxyControl);
+        
+        procCreator = mock(ProcessCreator.class);
+        config = mock(Configuration.class);
+        String binPath = "/path/to/thermostat/bin";
+        when(config.getSystemBinRoot()).thenReturn(new File(binPath));
+        latch = mock(CountDownLatch.class);
+    }
+    
+    @Test
+    public void testCreateProxy() throws Exception {
+        createClient();
+        
+        // Verify listener exported and bound
+        verify(rmi).export(client);
+        verify(registry).rebind(AgentProxyListener.REMOTE_PREFIX + "0", listenerStub);
+        
+        // Verify server created
+        String progName = "/path/to/thermostat/bin" + File.separator + "thermostat-agent-proxy";
+        verify(procCreator).createAndRunProcess(new String[] { progName, "0" });
+        verify(latch).countDown();
+        
+        // Verify listener removed
+        verify(registry).unbind(AgentProxyListener.REMOTE_PREFIX + "0");
+        verify(rmi).unexport(client);
+        
+        // Verify login
+        verify(registry).lookup(AgentProxyLogin.REMOTE_PREFIX + "0");
+        verify(proxyLogin).login();
+        
+        // Check returned proxy control
+        assertEquals(proxyControl, client.getProxy());
+    }
+
+    private void createClient() throws InterruptedException, IOException,
+            ApplicationException {
+        client = new AgentProxyClient(rmi, 0, config, latch, procCreator);
+        
+        doAnswer(new Answer<Boolean>() {
+            @Override
+            public Boolean answer(InvocationOnMock invocation) throws Throwable {
+                // Trigger server started
+                client.serverStarted();
+                return true;
+            }
+        }).when(latch).await(any(Long.class), any(TimeUnit.class));
+        
+        client.createProxy();
+    }
+    
+    @Test
+    public void testCreateProxyFailed() throws Exception {
+        client = new AgentProxyClient(rmi, 0, config, latch, procCreator);
+        
+        final Exception error = mock(Exception.class);
+        doAnswer(new Answer<Boolean>() {
+            @Override
+            public Boolean answer(InvocationOnMock invocation) throws Throwable {
+                // Trigger server started
+                client.serverFailedToStart(error);
+                return true;
+            }
+        }).when(latch).await(any(Long.class), any(TimeUnit.class));
+        
+        try {
+            client.createProxy();
+            fail("Expected RemoteException");
+        } catch (RemoteException e) {
+            assertEquals(error, e.getCause());
+        }
+        
+        // Verify listener exported and bound
+        verify(rmi).export(client);
+        verify(registry).rebind(AgentProxyListener.REMOTE_PREFIX + "0", listenerStub);
+        
+        // Verify server created
+        String progName = "/path/to/thermostat/bin" + File.separator + "thermostat-agent-proxy";
+        verify(procCreator).createAndRunProcess(new String[] { progName, "0" });
+        verify(latch).countDown();
+        
+        // Verify listener removed
+        verify(registry).unbind(AgentProxyListener.REMOTE_PREFIX + "0");
+        verify(rmi).unexport(client);
+    }
+    
+    @Test
+    public void testCreateProxyTimeout() throws Exception {
+        when(latch.await(any(Long.class), any(TimeUnit.class))).thenReturn(false);
+        client = new AgentProxyClient(rmi, 0, config, latch, procCreator);
+        
+        try {
+            client.createProxy();
+            fail("Expected RemoteException");
+        } catch (RemoteException e) {
+            // Verify listener exported and bound
+            verify(rmi).export(client);
+            verify(registry).rebind(AgentProxyListener.REMOTE_PREFIX + "0", listenerStub);
+            
+            // Verify server created
+            String progName = "/path/to/thermostat/bin" + File.separator + "thermostat-agent-proxy";
+            verify(procCreator).createAndRunProcess(new String[] { progName, "0" });
+            
+            // Verify listener removed
+            verify(registry).unbind(AgentProxyListener.REMOTE_PREFIX + "0");
+            verify(rmi).unexport(client);
+        }
+    }
+    
+    @Test
+    public void testAttach() throws Exception {
+        createClient();
+        
+        client.attach();
+        verify(proxyControl).attach();
+    }
+    
+    @Test
+    public void testIsAttached() throws Exception {
+        createClient();
+        when(proxyControl.isAttached()).thenReturn(true);
+        
+        boolean result = client.isAttached();
+        verify(proxyControl).isAttached();
+        assertTrue(result);
+    }
+    
+    @Test
+    public void testDetach() throws Exception {
+        createClient();
+        
+        client.detach();
+        verify(proxyControl).detach();
+    }
+    
+}
--- a/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java	Thu Nov 14 11:30:11 2013 -0500
+++ b/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java	Thu Nov 14 11:30:53 2013 -0500
@@ -38,6 +38,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -45,12 +46,10 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
-import org.junit.Before;
 import org.junit.Test;
 
 import com.redhat.thermostat.utils.management.MXBeanConnection;
 import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl.ConnectorCreator;
-import com.redhat.thermostat.utils.management.internal.MXBeanConnector;
 
 public class MXBeanConnectionPoolImplTest {
 
@@ -60,10 +59,11 @@
         MXBeanConnector connector = mock(MXBeanConnector.class);
         ConnectorCreator creator = mock(ConnectorCreator.class);
 
-        when(creator.create(anyInt())).thenReturn(connector);
+        when(creator.create(any(RMIRegistry.class), anyInt())).thenReturn(connector);
         when(connector.connect()).thenReturn(toReturn);
 
-        MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator);
+        RMIRegistry registry = mock(RMIRegistry.class);
+        MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry);
 
         MXBeanConnection connection = pool.acquire(0);
 
@@ -81,10 +81,11 @@
         MXBeanConnector connector = mock(MXBeanConnector.class);
         ConnectorCreator creator = mock(ConnectorCreator.class);
 
-        when(creator.create(anyInt())).thenReturn(connector);
+        when(creator.create(any(RMIRegistry.class), anyInt())).thenReturn(connector);
         when(connector.connect()).thenReturn(toReturn);
 
-        MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator);
+        RMIRegistry registry = mock(RMIRegistry.class);
+        MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry);
 
         MXBeanConnection connection1 = pool.acquire(0);
 
@@ -106,10 +107,11 @@
         MXBeanConnector connector = mock(MXBeanConnector.class);
         ConnectorCreator creator = mock(ConnectorCreator.class);
 
-        when(creator.create(anyInt())).thenReturn(connector);
+        when(creator.create(any(RMIRegistry.class), anyInt())).thenReturn(connector);
         when(connector.connect()).thenReturn(actualConnection);
 
-        MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator);
+        RMIRegistry registry = mock(RMIRegistry.class);
+        MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry);
 
         MXBeanConnection connection = pool.acquire(0);
 
@@ -126,10 +128,11 @@
         MXBeanConnector connector = mock(MXBeanConnector.class);
         ConnectorCreator creator = mock(ConnectorCreator.class);
 
-        when(creator.create(anyInt())).thenReturn(connector);
+        when(creator.create(any(RMIRegistry.class), anyInt())).thenReturn(connector);
         when(connector.connect()).thenReturn(actualConnection);
 
-        MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator);
+        RMIRegistry registry = mock(RMIRegistry.class);
+        MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry);
 
         // connection1 == connection1 == actualConnection
         MXBeanConnection connection1 = pool.acquire(0);
@@ -144,4 +147,15 @@
         verify(actualConnection).close();
 
     }
+    
+    @Test
+    public void testShutdown() throws Exception {
+        RMIRegistry registry = mock(RMIRegistry.class);
+        ConnectorCreator creator = mock(ConnectorCreator.class);
+        MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry);
+        verify(registry).start();
+        
+        pool.shutdown();
+        verify(registry).stop();
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectorTest.java	Thu Nov 14 11:30:53 2013 -0500
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2012, 2013 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.utils.management.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXServiceURL;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.redhat.thermostat.utils.management.internal.MXBeanConnector.JMXConnectionCreator;
+
+public class MXBeanConnectorTest {
+    
+    private MXBeanConnector connector;
+    private JMXConnectionCreator jmxCreator;
+    private AgentProxyClient client;
+    
+    @Before
+    public void setup() throws Exception {
+        jmxCreator = mock(JMXConnectionCreator.class);
+        client = mock(AgentProxyClient.class);
+        connector = new MXBeanConnector(client, jmxCreator);
+    }
+    
+    @Test
+    public void testInit() throws Exception {
+        // MXBeanConnector constructor calls createProxy
+        verify(client).createProxy();
+    }
+    
+    @Test
+    public void testAttach() throws Exception {
+        connector.attach();
+        verify(client).attach();
+    }
+    
+    @Test
+    public void testIsAttached() throws Exception {
+        when(client.isAttached()).thenReturn(true);
+        boolean result = connector.isAttached();
+        verify(client).isAttached();
+        assertTrue(result);
+    }
+    
+    @Test
+    public void testClose() throws Exception {
+        connector.close();
+        verify(client).detach();
+    }
+    
+    @Test
+    public void testConnect() throws Exception {
+        String jmxUrl = "service:jmx:rmi://myHost:1099/blah";
+        when(client.getConnectorAddress()).thenReturn(jmxUrl);
+        
+        JMXConnector jmxConnector = mock(JMXConnector.class);
+        when(jmxCreator.create(new JMXServiceURL(jmxUrl))).thenReturn(jmxConnector);
+        MBeanServerConnection connection = mock(MBeanServerConnection.class);
+        when(jmxConnector.getMBeanServerConnection()).thenReturn(connection);
+        
+        MXBeanConnectionImpl result = connector.connect();
+        verify(client).getConnectorAddress();
+        assertEquals(connection, result.get());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/RMIRegistryTest.java	Thu Nov 14 11:30:53 2013 -0500
@@ -0,0 +1,88 @@
+package com.redhat.thermostat.utils.management.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.rmi.registry.Registry;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RMISocketFactory;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.redhat.thermostat.utils.management.internal.RMIRegistry.RegistryCreator;
+import com.redhat.thermostat.utils.management.internal.RMIRegistry.ServerSocketCreator;
+
+public class RMIRegistryTest {
+    
+    @Test
+    public void testRegistryStart() throws IOException {
+        RegistryCreator creator = mock(RegistryCreator.class);
+        Registry reg = mock(Registry.class);
+        when(creator.createRegistry(anyInt(), any(RMIClientSocketFactory.class), 
+                any(RMIServerSocketFactory.class))).thenReturn(reg);
+        ServerSocketCreator sockCreator = mock(ServerSocketCreator.class);
+        
+        RMIRegistry registry = new RMIRegistry(creator, sockCreator);
+        registry.start();
+        
+        ArgumentCaptor<Integer> portCaptor = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<RMIClientSocketFactory> csfCaptor = ArgumentCaptor.forClass(RMIClientSocketFactory.class);
+        ArgumentCaptor<RMIServerSocketFactory> ssfCaptor = ArgumentCaptor.forClass(RMIServerSocketFactory.class);
+        verify(creator).createRegistry(portCaptor.capture(), csfCaptor.capture(), ssfCaptor.capture());
+        
+        // Ensure defaults used for port and client socket factory
+        int port = portCaptor.getValue();
+        assertEquals(Registry.REGISTRY_PORT, port);
+        
+        RMIClientSocketFactory csf = csfCaptor.getValue();
+        assertEquals(RMISocketFactory.getDefaultSocketFactory(), csf);
+        
+        // Ensure bound to loopback address
+        RMIServerSocketFactory ssf = ssfCaptor.getValue();
+        ssf.createServerSocket(port);
+        verify(sockCreator).createSocket(port, 0, InetAddress.getLoopbackAddress());
+    }
+    
+    @Test
+    public void testRegistryStop() throws IOException {
+        RegistryCreator creator = mock(RegistryCreator.class);
+        Registry reg = mock(Registry.class);
+        when(creator.createRegistry(anyInt(), any(RMIClientSocketFactory.class), 
+                any(RMIServerSocketFactory.class))).thenReturn(reg);
+        ServerSocketCreator sockCreator = mock(ServerSocketCreator.class);
+        
+        RMIRegistry registry = new RMIRegistry(creator, sockCreator);
+        registry.start();
+        
+        registry.stop();
+        
+        verify(creator).destroyRegistry(reg);
+        assertNull(registry.getRegistryImpl());
+    }
+    
+    @Test
+    public void testRegistryStopNotStarted() throws IOException {
+        RegistryCreator creator = mock(RegistryCreator.class);
+        Registry reg = mock(Registry.class);
+        when(creator.createRegistry(anyInt(), any(RMIClientSocketFactory.class), 
+                any(RMIServerSocketFactory.class))).thenReturn(reg);
+        ServerSocketCreator sockCreator = mock(ServerSocketCreator.class);
+        
+        RMIRegistry registry = new RMIRegistry(creator, sockCreator);
+        
+        registry.stop();
+        
+        verify(creator, never()).destroyRegistry(reg);
+    }
+    
+}