changeset 1156:2932f90a008f

PR1451: Blocked console after "service" command error message Reviewed-by: omajid, vanaltj Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-July/007241.html
author Andriy Petrus <apetrus@redhat.com>
date Tue, 09 Jul 2013 11:03:56 -0400
parents c70ab9ec00f5
children 8cd620e9a658
files agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/ServiceCommand.java agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/locale/LocaleResources.java agent/cli/src/main/resources/com/redhat/thermostat/agent/cli/impl/strings.properties agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/ServiceCommandTest.java
diffstat 4 files changed, 178 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/ServiceCommand.java	Tue Jul 09 15:10:03 2013 +0200
+++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/ServiceCommand.java	Tue Jul 09 11:03:56 2013 -0400
@@ -68,6 +68,7 @@
     private Semaphore agentBarrier = new Semaphore(0);
     private BundleContext context;
     private Launcher launcher;
+    private boolean storageFailed = false;
 
     public ServiceCommand(BundleContext context) {
         this.context = context;
@@ -86,6 +87,12 @@
         launcher.run(storageStartArgs, listeners, false);
         agentBarrier.acquireUninterruptibly();
         
+        if (storageFailed) {
+            storageFailed = false;
+            context.ungetService(launcherRef);
+            throw new CommandException(translator.localize(LocaleResources.SERVICE_FAILED_TO_START_DB));
+        }
+        
         String[] storageStopArgs = new String[] { "storage", "--stop" };
         launcher.run(storageStopArgs, false);
         
@@ -106,16 +113,16 @@
                 String[] agentArgs =  new String[] {"agent", "-d", dbUrl};
                 System.err.println(translator.localize(LocaleResources.STARTING_AGENT).getContents());
                 launcher.run(agentArgs, false);
-                agentBarrier.release();
                 break;
             case FAIL:
-                System.err.println(translator.localize(LocaleResources.ERROR_STARTING_DB).getContents());
+                storageFailed = true;
                 Object payload = actionEvent.getPayload();
                 if (payload instanceof StorageAlreadyRunningException) {
                     System.err.println(translator.localize(LocaleResources.STORAGE_ALREADY_RUNNING).getContents());
                 }
                 break;
             }
+            agentBarrier.release();
         }
     }
 
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/locale/LocaleResources.java	Tue Jul 09 15:10:03 2013 +0200
+++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/locale/LocaleResources.java	Tue Jul 09 11:03:56 2013 -0400
@@ -46,7 +46,7 @@
 
     STORAGE_ALREADY_RUNNING,
     STORAGE_ALREADY_RUNNING_WITH_PID,
-    ERROR_STARTING_DB,
+    SERVICE_FAILED_TO_START_DB,
     SERVER_SHUTDOWN_COMPLETE,
     LOG_FILE_AT,
     CANNOT_START_SERVER,
--- a/agent/cli/src/main/resources/com/redhat/thermostat/agent/cli/impl/strings.properties	Tue Jul 09 15:10:03 2013 +0200
+++ b/agent/cli/src/main/resources/com/redhat/thermostat/agent/cli/impl/strings.properties	Tue Jul 09 11:03:56 2013 -0400
@@ -2,7 +2,7 @@
 
 COMMAND_STORAGE_ARGUMENT_REQUIRED = either --start or --stop must be given
 
-ERROR_STARTING_DB = error starting db
+SERVICE_FAILED_TO_START_DB = Service failed to start due to error starting storage.
 STORAGE_ALREADY_RUNNING = Storage is already running. Please use "agent --start" to start the agent
 STORAGE_ALREADY_RUNNING_WITH_PID = Storage is already running with pid {0}
 SERVER_SHUTDOWN_COMPLETE = server shutdown complete: {0}
--- a/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/ServiceCommandTest.java	Tue Jul 09 15:10:03 2013 +0200
+++ b/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/ServiceCommandTest.java	Tue Jul 09 11:03:56 2013 -0400
@@ -36,26 +36,188 @@
 
 package com.redhat.thermostat.agent.cli.impl;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.isA;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.never;
+
+import java.util.Collection;
+
+import junit.framework.Assert;
+
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.osgi.framework.ServiceReference;
 
+import com.redhat.thermostat.agent.cli.impl.db.DBStartupConfiguration;
+import com.redhat.thermostat.agent.cli.impl.db.StorageCommand;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ActionNotifier;
+import com.redhat.thermostat.common.Launcher;
+import com.redhat.thermostat.common.cli.CommandContext;
+import com.redhat.thermostat.common.cli.CommandException;
+import com.redhat.thermostat.common.tools.ApplicationState;
 import com.redhat.thermostat.testutils.StubBundleContext;
 
 public class ServiceCommandTest {
 
-    private ServiceCommand thermostatService;
+    private Launcher mockLauncher;
+    private ServiceCommand serviceCommand;
+    private CommandContext mockCommandContext;
+
+    private static ActionEvent<ApplicationState> mockActionEvent;
+    private static Collection<ActionListener<ApplicationState>> listeners;
 
+    private static final String[] STORAGE_START_ARGS = { "storage", "--start" };
+    private static final String[] STORAGE_STOP_ARGS = { "storage", "--stop" };
+    private static final String[] AGENT_ARGS = {"agent", "-d", "Test String"};
+    
+    private static int count = 0;
+
+    @SuppressWarnings("unchecked")
     @Before
     public void setUp() {
-        StubBundleContext context = new StubBundleContext();
-        thermostatService = new ServiceCommand(context);
+        StubBundleContext bundleContext = new StubBundleContext();
+        mockLauncher = mock(Launcher.class);
+        bundleContext.registerService(Launcher.class, mockLauncher, null);
+        serviceCommand = new ServiceCommand(bundleContext);
+        
+        StorageCommand mockStorageCommand = mock(StorageCommand.class);
+        mockActionEvent = mock(ActionEvent.class);
+        when(mockActionEvent.getSource()).thenReturn(mockStorageCommand);
+        mockCommandContext = mock(CommandContext.class);
+        
+        ActionNotifier<ApplicationState> mockNotifier = mock(ActionNotifier.class);
+        DBStartupConfiguration mockDbsConfiguration = mock(DBStartupConfiguration.class);
+        when(mockStorageCommand.getNotifier()).thenReturn(mockNotifier);
+        when(mockStorageCommand.getConfiguration()).thenReturn(mockDbsConfiguration);
+        when(mockDbsConfiguration.getDBConnectionString()).thenReturn(new String("Test String"));
     }
 
     @After
     public void tearDown() {
-        thermostatService = null;
+        count = 0;
+        listeners = null;
+        mockLauncher = null;
+        serviceCommand = null;
+        mockActionEvent = null;
+        mockCommandContext = null;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test(timeout=1000)
+    public void testRunOnce() throws CommandException {
+        doAnswer(new Answer<Void>() {
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                listeners = (Collection<ActionListener<ApplicationState>>)args[1];
+                
+                when(mockActionEvent.getActionId()).thenReturn(ApplicationState.START);
+                
+                for(ActionListener<ApplicationState> listener : listeners) {
+                    listener.actionPerformed(mockActionEvent);
+                }
+                return null;
+            }
+        }).when(mockLauncher).run(eq(STORAGE_START_ARGS), isA(Collection.class), anyBoolean());
+        
+        boolean exTriggered = false;
+        try {
+            serviceCommand.run(mockCommandContext);
+        } catch (CommandException e) { 
+            exTriggered = true;
+        }
+        Assert.assertFalse(exTriggered);
+        
+        verify(mockLauncher, times(1)).run(eq(STORAGE_START_ARGS), isA(Collection.class), anyBoolean());
+        verify(mockLauncher, times(1)).run(eq(STORAGE_STOP_ARGS), anyBoolean());
+        verify(mockLauncher, times(1)).run(eq(AGENT_ARGS), anyBoolean());
+        verify(mockActionEvent, times(1)).getActionId();
     }
 
-    // TODO really need to add more tests for service
+    @SuppressWarnings("unchecked")
+    @Test(timeout=1000)
+    public void testMultipleRun() throws CommandException {
+        doAnswer(new Answer<Void>() {
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                listeners = (Collection<ActionListener<ApplicationState>>)args[1];
+                
+                if (count == 0) {
+                    when(mockActionEvent.getActionId()).thenReturn(ApplicationState.START);
+                } else {
+                    when(mockActionEvent.getActionId()).thenReturn(ApplicationState.FAIL);
+                }
+                ++count;
+                
+                for(ActionListener<ApplicationState> listener : listeners) {
+                    listener.actionPerformed(mockActionEvent);
+                }
+                return null;
+            }
+        }).when(mockLauncher).run(eq(STORAGE_START_ARGS), isA(Collection.class), anyBoolean());
+        
+        boolean exTriggered = false;
+        try {
+            serviceCommand.run(mockCommandContext);
+        } catch (CommandException e) { 
+            exTriggered = true;
+        }
+        Assert.assertFalse(exTriggered);
+        
+        try {
+            serviceCommand.run(mockCommandContext);
+        } catch (CommandException e) {
+            exTriggered = true;
+            Assert.assertEquals(e.getLocalizedMessage(), "Service failed to start due to error starting storage.");
+        }
+        Assert.assertTrue(exTriggered);
+        
+        verify(mockLauncher, times(2)).run(eq(STORAGE_START_ARGS), isA(Collection.class), anyBoolean());
+        verify(mockLauncher, times(1)).run(eq(STORAGE_STOP_ARGS), anyBoolean());
+        verify(mockLauncher, times(1)).run(eq(AGENT_ARGS), anyBoolean());
+        verify(mockActionEvent, times(2)).getActionId();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test(timeout=1000)
+    public void testStorageFailStart()  throws CommandException {
+        doAnswer(new Answer<Void>() {
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                listeners = (Collection<ActionListener<ApplicationState>>)args[1];
+                
+                when(mockActionEvent.getActionId()).thenReturn(ApplicationState.FAIL);
+                
+                for(ActionListener<ApplicationState> listener : listeners) {
+                    listener.actionPerformed(mockActionEvent);
+                }
+                return null;
+            }
+        }).when(mockLauncher).run(eq(STORAGE_START_ARGS), isA(Collection.class), anyBoolean());
+        
+        boolean exTriggered = false;
+        try {
+            serviceCommand.run(mockCommandContext);
+        } catch (CommandException e) {
+            exTriggered = true;
+        }
+        Assert.assertTrue(exTriggered);
+        
+        verify(mockLauncher, times(1)).run(eq(STORAGE_START_ARGS), isA(Collection.class), anyBoolean());
+        verify(mockLauncher, never()).run(eq(STORAGE_STOP_ARGS), anyBoolean());
+        verify(mockLauncher, never()).run(eq(AGENT_ARGS), anyBoolean());
+        verify(mockActionEvent, times(1)).getActionId();
+    }
+
 }