@Test
 public void testTriggerKWArg() throws FlumeSpecException {
   FlumeBuilder.buildSink(
       LogicalNodeContext.testingContext(), "roll(1000, trigger=time) { null }");
   FlumeBuilder.buildSink(
       LogicalNodeContext.testingContext(), "roll(1000, trigger=size(1000)) { null }");
 }
  @Test
  public void testSizeTriggerFunctional()
      throws FlumeSpecException, IOException, InterruptedException {
    // a ridiculous amount of time trigger time to forces size trigger
    EventSink snk =
        FlumeBuilder.buildSink(
            LogicalNodeContext.testingContext(), "roll(1000000, trigger=size(10)) { console }");
    snk.open();

    // Events from this loop:
    // 0, 1, trigger, 2, 3, trigger, 4, 5, trigger, 6, 7, trigger, 8 ,9,
    for (int i = 0; i < 10; i++) {
      snk.append(new EventImpl("6chars".getBytes()));
    }
    snk.close();

    ReportEvent rpt = snk.getMetrics();
    // See above for why there are 4 triggers:
    assertEquals(4, (long) rpt.getLongMetric(RollSink.A_ROLLS));
  }
 @Test(expected = FlumeSpecException.class)
 public void testBadTriggerKWArgArg() throws FlumeSpecException {
   FlumeBuilder.buildSink(
       LogicalNodeContext.testingContext(), "roll(1000, trigger=size(\"badarg\")) { null }");
 }
 @Test(expected = FlumeSpecException.class)
 public void testBadMissingTimeTriggerKWArg() throws FlumeSpecException {
   FlumeBuilder.buildSink(LogicalNodeContext.testingContext(), "roll(trigger=size(100)) { null }");
 }
  /**
   * This test has an append that is blocked because a sink inside of a roll always throws an
   * exception. (ex: a down network connection). This test attempts to guarantee that the rotate
   * succeeds in a reasoanble amoutn of time.
   *
   * @throws IOException
   * @throws InterruptedException
   */
  @Test
  public void testRollAppendBlockedDeadlock() throws IOException, InterruptedException {
    final EventSink mock = mock(EventSink.Base.class);
    doNothing().doThrow(new IOException()).when(mock).close();
    final Event e1 = new EventImpl("foo1".getBytes());
    final Event e2 = new EventImpl("foo2".getBytes());
    doThrow(new IOException()).when(mock).append(e1);
    doThrow(new IOException()).when(mock).append(e2);

    SinkFactoryImpl sfi = new SinkFactoryImpl();
    sfi.setSink(
        "rollLock",
        new SinkBuilder() {
          @Override
          public EventSink build(Context context, String... argv) {
            return mock;
          }
        });
    FlumeBuilder.setSinkFactory(sfi);

    final RollSink roll =
        new RollSink(
            LogicalNodeContext.testingContext(),
            "insistentOpen stubbornAppend insistentAppend rollLock",
            1000000,
            1000000);
    final CountDownLatch latch = new CountDownLatch(1);
    // excessively long roll and check times which allow test to force checks.
    Thread t =
        new Thread("blocked append thread") {
          public void run() {
            try {
              roll.open();
              roll.append(e1); // append blocks.
            } catch (InterruptedException e) {
              latch.countDown();
              LOG.error("Exited with expected Exception");
              return;
            } catch (IOException e) {
              LOG.info("Got the unexpected IOException exit", e);
              e.printStackTrace();
            }
            LOG.info("Got the unexpected clean exit");
          }
        };
    t.start();
    // have another thread timeout.
    final CountDownLatch latch2 = new CountDownLatch(1);
    Thread t2 =
        new Thread("roll rotate thread") {
          public void run() {
            try {
              Clock.sleep(1000); // this is imperfect, but wait for append to block.
              roll.rotate();
              roll.close();
            } catch (IOException e) {
              e.printStackTrace();
            } catch (InterruptedException e) {
              e.printStackTrace();
            } finally {
              latch2.countDown();
            }
          }
        };
    t2.start();
    boolean success = latch.await(5, TimeUnit.SECONDS);
    assertTrue(success);

    success = latch2.await(5, TimeUnit.SECONDS);
    assertTrue(success);
  }