private void runLogging() {
   final Thread currentThread = Thread.currentThread();
   final ConsoleRowFormatter consoleRowFormatter = new ConsoleRowFormatter();
   anythingLogged = false;
   try {
     while (!currentThread.isInterrupted()) {
       ConsoleRow row = outputQueue.take();
       // subtract length of contained test string
       modifyCharacterCount(-row.getPayload().length());
       try {
         // TODO add an explicit flush mechanism to ensure rows are on disk after a
         // given time?
         writer.append(consoleRowFormatter.toCombinedLogFileFormat(row));
         anythingLogged = true;
       } catch (IOException e) {
         log.error(e);
         break;
       }
     }
   } catch (InterruptedException e) {
     log.debug("Background log writer interrupted");
   }
   try {
     writer.close();
     // TODO bad encapsulation; improve when reworking this class
     if (!anythingLogged) {
       logFile.delete();
     }
   } catch (IOException e) {
     log.error(e);
   }
 }
  /** Tests if a log message is sent as expected. */
  @Test
  public void testSendLogMessageAsConsoleRow() {
    Capture<ConsoleRow> consoleRowCapture = new Capture<>();
    ComponentExecutionRelatedInstances compExeRelatedInstances =
        createComponentExecutionRelatedInstances(consoleRowCapture);
    ConsoleRowsSender consoleRowsSender = new ConsoleRowsSender(compExeRelatedInstances);

    String payload = "some message";
    consoleRowsSender.sendLogMessageAsConsoleRow(ConsoleRow.Type.TOOL_ERROR, payload);

    ConsoleRow capturedConsoleRow =
        verifyAfterConsoleRowSent(consoleRowCapture, ConsoleRow.Type.TOOL_ERROR);
    assertEquals(payload, capturedConsoleRow.getPayload());
  }
 /**
  * Enqueues {@link ConsoleRow} entries to log. This method is thread-safe, although there is no
  * guarantee that lists of {@link ConsoleRow}s passed by concurrent calls are appended as
  * uninterrupted sequences.
  *
  * @param rows the {@link ConsoleRow}s to log
  */
 @Override
 public void processConsoleRows(List<ConsoleRow> rows) {
   if (!enabled) {
     return;
   }
   // add total string length to counter
   int charCount = 0;
   for (ConsoleRow row : rows) {
     charCount += row.getPayload().length();
   }
   modifyCharacterCount(charCount);
   // add to buffer
   outputQueue.addAll(rows);
 }
  /** Tests if a log message is sent as expected. */
  @Test
  public void testSendTimelineEventAsConsoleRow() {
    Capture<ConsoleRow> consoleRowCapture = new Capture<>();
    ComponentExecutionRelatedInstances compExeRelatedInstances =
        createComponentExecutionRelatedInstances(consoleRowCapture);
    ConsoleRowsSender consoleRowsSender = new ConsoleRowsSender(compExeRelatedInstances);

    consoleRowsSender.sendTimelineEventAsConsoleRow(
        ConsoleRow.Type.LIFE_CYCLE_EVENT, WorkflowLifecyleEventType.TOOL_STARTING.name());

    ConsoleRow capturedConsoleRow =
        verifyAfterConsoleRowSent(consoleRowCapture, ConsoleRow.Type.LIFE_CYCLE_EVENT);
    String[] payload = StringUtils.splitAndUnescape(capturedConsoleRow.getPayload());
    assertEquals(payload[0], WorkflowLifecyleEventType.TOOL_STARTING.name());
    assertEquals(payload[1], String.valueOf(DM_ID));
  }
  /** Tests if a {@link ComponentState} is sent as expected. */
  @Test
  public void testSendStateAsConsoleRow() {
    Capture<ConsoleRow> consoleRowCapture = new Capture<>();
    ComponentExecutionRelatedInstances compExeRelatedInstances =
        createComponentExecutionRelatedInstances(consoleRowCapture);
    ConsoleRowsSender consoleRowsSender = new ConsoleRowsSender(compExeRelatedInstances);

    consoleRowsSender.sendStateAsConsoleRow(
        ConsoleRow.WorkflowLifecyleEventType.COMPONENT_TERMINATED);

    ConsoleRow capturedConsoleRow =
        verifyAfterConsoleRowSent(consoleRowCapture, ConsoleRow.Type.LIFE_CYCLE_EVENT);
    assertEquals(
        ConsoleRow.WorkflowLifecyleEventType.COMPONENT_TERMINATED.name(),
        capturedConsoleRow.getPayload());
  }
  /**
   * Tests if the trigger for writing log files to the data management is done properly. That
   * includes that certain flags are set properly afterwards.
   */
  @Test
  public void testSendLogFileWriteTriggerAsConsoleRow() {

    Capture<ConsoleRow> consoleRowCapture = new Capture<>();
    ComponentExecutionRelatedInstances compExeRelatedInstances =
        createComponentExecutionRelatedInstances(consoleRowCapture);
    ConsoleRowsSender consoleRowsSender = new ConsoleRowsSender(compExeRelatedInstances);

    consoleRowsSender.sendLogFileWriteTriggerAsConsoleRow();

    ConsoleRow capturedConsoleRow =
        verifyAfterConsoleRowSent(consoleRowCapture, ConsoleRow.Type.LIFE_CYCLE_EVENT);

    String[] payload = StringUtils.splitAndUnescape(capturedConsoleRow.getPayload());
    assertEquals(ConsoleRow.WorkflowLifecyleEventType.COMPONENT_LOG_FINISHED.name(), payload[0]);
    assertEquals(String.valueOf(DM_ID), payload[1]);
    assertEquals(String.valueOf(EXE_COUNT), payload[2]);

    assertEquals(0, compExeRelatedInstances.compExeRelatedStates.consoleRowSequenceNumber.get());
    assertFalse(
        compExeRelatedInstances.compExeRelatedStates.compHasSentConsoleRowLogMessages.get());
  }
  private ConsoleRow verifyAfterConsoleRowSent(
      Capture<ConsoleRow> consoleRowCapture, ConsoleRow.Type expectedType) {
    EasyMock.verify(batchingConsoleRowForwarderMock);
    assertTrue(consoleRowCapture.hasCaptured());
    assertEquals(1, consoleRowCapture.getValues().size());

    ConsoleRow capturedConsoleRow = consoleRowCapture.getValue();
    assertEquals(
        ComponentExecutionContextDefaultStub.COMP_EXE_ID,
        capturedConsoleRow.getComponentIdentifier());
    assertEquals(
        ComponentExecutionContextDefaultStub.WF_EXE_ID, capturedConsoleRow.getWorkflowIdentifier());
    assertEquals(
        ComponentExecutionContextDefaultStub.COMP_INSTANCE_NAME,
        capturedConsoleRow.getComponentName());
    assertEquals(
        ComponentExecutionContextDefaultStub.WF_INSTANCE_NAME,
        capturedConsoleRow.getWorkflowName());
    assertEquals(expectedType, capturedConsoleRow.getType());

    return capturedConsoleRow;
  }
 /**
  * Enqueues a {@link ConsoleRow} to log. This method is thread-safe.
  *
  * @param row the {@link ConsoleRow} to log
  */
 public void append(ConsoleRow row) {
   // add the length of contained payload; note that this is not an exact measure of log output to
   // write
   modifyCharacterCount(row.getPayload().length());
   outputQueue.add(row);
 }