/* * Copyright 2017 Nokia Solutions and Networks * Licensed under the Apache License, Version 2.0, * see license.txt file for details. */ package org.rf.ide.core.execution.server; import static com.google.common.collect.Lists.newArrayList; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.atLeast; 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.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.StringReader; import java.util.Map; import org.codehaus.jackson.map.ObjectMapper; import org.junit.Test; import org.rf.ide.core.execution.LogLevel; import org.rf.ide.core.execution.RobotAgentEventListener; import org.rf.ide.core.execution.Status; import com.google.common.collect.ImmutableMap; public class RobotAgentEventDispatcherTest { @Test(expected = IOException.class) public void exceptionIsRethrown_whenReaderThrowsIOException() throws Exception { final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null); final BufferedReader reader = mock(BufferedReader.class); when(reader.readLine()).thenThrow(IOException.class); dispatcher.runEventsLoop(reader); } @Test public void listenerIsNotNotified_whenThereAreNoEvents() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); dispatcher.runEventsLoop(readerFor("")); verify(listener).setClient(nullable(AgentClient.class)); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotNotified_whenUnknownEventComes() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final String json = toJson(ImmutableMap.of("some_event", "val")); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotNotified_whenValidEventComesButListenerDoesNotHandleEventsAnymore() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(false); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final String json = toJson(ImmutableMap.of("pid", 1)); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verifyNoMoreInteractions(listener); } @Test public void whenAtLeastOneListenerIsHandlingEvents_allAreNotifiedAboutIt() throws Exception { final RobotAgentEventListener listener1 = mock(RobotAgentEventListener.class); final RobotAgentEventListener listener2 = mock(RobotAgentEventListener.class); final RobotAgentEventListener listener3 = mock(RobotAgentEventListener.class); when(listener1.isHandlingEvents()).thenReturn(false); when(listener2.isHandlingEvents()).thenReturn(true); when(listener3.isHandlingEvents()).thenReturn(false); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener1, listener2, listener3); final String json = toJson(ImmutableMap.of("ready_to_start", 1)); dispatcher.runEventsLoop(readerFor(json)); verify(listener1).setClient(nullable(AgentClient.class)); verify(listener1, atLeast(0)).isHandlingEvents(); verify(listener1).handleAgentIsReadyToStart(); verifyNoMoreInteractions(listener1); verify(listener2).setClient(nullable(AgentClient.class)); verify(listener2, atLeast(1)).isHandlingEvents(); verify(listener2).handleAgentIsReadyToStart(); verifyNoMoreInteractions(listener2); verify(listener3).setClient(nullable(AgentClient.class)); verify(listener3, atLeast(0)).isHandlingEvents(); verify(listener3).handleAgentIsReadyToStart(); verifyNoMoreInteractions(listener3); } @Test public void listenerIsNotifiedAboutReadyToStartEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final String json = toJson(ImmutableMap.of("ready_to_start", 0)); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleAgentIsReadyToStart(); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutAgentInitializingEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Map<String, String> attributes = ImmutableMap.of("agent_mode", "debug"); final String json = toJson(ImmutableMap.of("agent_initializing", newArrayList(attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleAgentInitializing(); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutVersionEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(mock(AgentClient.class), listener); final Map<String, Object> attributes = ImmutableMap.of("python", "py3", "robot", "1.2.3", "protocol", 1); final String json = toJson(ImmutableMap.of("version", newArrayList(attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleVersions("py3", "1.2.3", 1); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutResourceImportEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Map<String, String> attributes = ImmutableMap.of("source", "/a/b/file.robot"); final String json = toJson(ImmutableMap.of("resource_import", newArrayList("file", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleResourceImport(new File("/a/b/file.robot")); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutSuiteStartEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Map<String, String> attributes = ImmutableMap.of("source", "/a/b/suite.robot"); final String json = toJson(ImmutableMap.of("start_suite", newArrayList("suite", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleSuiteStarted("suite", new File("/a/b/suite.robot")); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutSuiteEndEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Map<String, Object> attributes = ImmutableMap.<String, Object> of("elapsedtime", 10, "message", "msg", "status", "PASS"); final String json = toJson(ImmutableMap.of("end_suite", newArrayList("suite", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleSuiteEnded("suite", 10, Status.PASS, "msg"); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutTestStartEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Map<String, String> attributes = ImmutableMap.of("longname", "suite-a-b-test"); final String json = toJson(ImmutableMap.of("start_test", newArrayList("test", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleTestStarted("test", "suite-a-b-test"); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutTestEndEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Map<String, Object> attributes = ImmutableMap.<String, Object> of("longname", "suite-a-b-test", "elapsedtime", 10, "message", "msg", "status", "FAIL"); final String json = toJson(ImmutableMap.of("end_test", newArrayList("test", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleTestEnded("test", "suite-a-b-test", 10, Status.FAIL, "msg"); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutKeywordStartEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Map<String, Object> attributes = ImmutableMap.<String, Object> of("type", "Keyword", "args", newArrayList("1", "2")); final String json = toJson(ImmutableMap.of("start_keyword", newArrayList("kw", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleKeywordStarted("kw", "Keyword", newArrayList("1", "2")); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutKeywordEndEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Map<String, Object> attributes = ImmutableMap.<String, Object> of("type", "Setup"); final String json = toJson(ImmutableMap.of("end_keyword", newArrayList("kw", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleKeywordEnded("kw", "Setup"); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutVariablesEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Map<String, Object> attributes = ImmutableMap.<String, Object> of("a", "value", "b", newArrayList("1", "2")); final String json = toJson(ImmutableMap.of("vars", newArrayList("_", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleVariables(ImmutableMap.<String, Object> of("a", "value", "b", newArrayList("1", "2"))); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutGlobalVariablesEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Map<String, String> attributes = ImmutableMap.of("a", "value", "b", "other_value"); final String json = toJson(ImmutableMap.of("global_vars", newArrayList("_", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleGlobalVariables(ImmutableMap.of("a", "value", "b", "other_value")); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutCheckConditionEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final String json = toJson(ImmutableMap.of("check_condition", 0)); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleCheckCondition(); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutConditionResultEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final String json = toJson(ImmutableMap.of("condition_result", newArrayList(true))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleConditionResult(true); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutConditionErrorEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final String json = toJson(ImmutableMap.of("condition_error", newArrayList("error message"))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleConditionError("error message"); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutCheckedConditionEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final String json = toJson(ImmutableMap.of("condition_checked", 0)); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleConditionChecked(); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutPausedEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final String json = toJson(ImmutableMap.of("paused", 0)); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handlePaused(); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutClosedEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final String json = toJson(ImmutableMap.of("close", 0)); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleClosed(); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutLogMessageEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Object attributes = ImmutableMap.of("message", "msg", "timestamp", "time", "level", "INFO"); final String json = toJson(ImmutableMap.of("log_message", newArrayList(attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleLogMessage("msg", LogLevel.INFO, "time"); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutOutputFileEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final String json = toJson(ImmutableMap.of("output_file", newArrayList("/a/b/file.xml"))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleOutputFile(new File("/a/b/file.xml")); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutLibraryImportEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Object attributes = ImmutableMap.of("importer", "importerPath", "source", "sourcePath", "args", newArrayList("arg1", "arg2")); final String json = toJson(ImmutableMap.of("library_import", newArrayList("lib1", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleLibraryImport("lib1", "importerPath", "sourcePath", newArrayList("arg1", "arg2")); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutLibraryImportEvent_whenOriginalNameExists() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Object attributes = ImmutableMap.of("importer", "importerPath", "source", "sourcePath", "args", newArrayList("arg1", "arg2"), "originalname", "lib2"); final String json = toJson(ImmutableMap.of("library_import", newArrayList("lib1", attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleLibraryImport("lib2", "importerPath", "sourcePath", newArrayList("arg1", "arg2")); verifyNoMoreInteractions(listener); } @Test public void listenerIsNotifiedAboutMessageEvent() throws Exception { final RobotAgentEventListener listener = mock(RobotAgentEventListener.class); when(listener.isHandlingEvents()).thenReturn(true); final RobotAgentEventDispatcher dispatcher = new RobotAgentEventDispatcher(null, listener); final Object attributes = ImmutableMap.of("message", "abc", "level", "ERROR"); final String json = toJson(ImmutableMap.of("message", newArrayList(attributes))); dispatcher.runEventsLoop(readerFor(json)); verify(listener).setClient(nullable(AgentClient.class)); verify(listener, atLeast(1)).isHandlingEvents(); verify(listener).handleMessage("abc", LogLevel.ERROR); verifyNoMoreInteractions(listener); } private static String toJson(final Object object) throws Exception { return new ObjectMapper().writeValueAsString(object); } private static BufferedReader readerFor(final String content) { return new BufferedReader(new StringReader(content)); } }