/**
* Licensed to Cloudera, Inc. under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Cloudera, Inc. licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cloudera.flume.agent.diskfailover;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import com.cloudera.flume.agent.FlumeNode;
import com.cloudera.flume.conf.Context;
import com.cloudera.flume.core.Event;
import com.cloudera.flume.core.EventImpl;
import com.cloudera.flume.core.EventSink;
import com.cloudera.flume.core.EventSource;
import com.cloudera.flume.core.EventUtil;
import com.cloudera.flume.handlers.rolling.ProcessTagger;
import com.cloudera.flume.handlers.rolling.TimeTrigger;
import com.cloudera.flume.reporter.ReportEvent;
import com.cloudera.util.BenchmarkHarness;
public class TestDiskFailoverDeco {
@Before
public void setup() {
BenchmarkHarness.setupLocalWriteDir();
}
@After
public void cleanup() {
BenchmarkHarness.setupLocalWriteDir();
}
/**
* Semantically, if an exception is thrown by an internal thread, the
* exception should get percolated up to the appender.
*/
@Test
public void testHandleExns() throws IOException {
EventSink msnk = mock(EventSink.class);
doNothing().when(msnk).open();
doNothing().when(msnk).close();
doNothing().doThrow(new IOException("foo")).doNothing().when(msnk).append(
Mockito.<Event> anyObject());
doReturn(new ReportEvent("blah")).when(msnk).getReport();
// cannot write to the same instance.
Event e1 = new EventImpl(new byte[0]);
Event e2 = new EventImpl(new byte[0]);
Event e3 = new EventImpl(new byte[0]);
EventSource msrc = mock(EventSource.class);
doNothing().when(msrc).open();
doNothing().when(msrc).close();
when(msrc.next()).thenReturn(e1).thenReturn(e2).thenReturn(e3).thenReturn(
null);
DiskFailoverDeco<EventSink> snk = new DiskFailoverDeco<EventSink>(msnk,
FlumeNode.getInstance().getDFOManager(), new TimeTrigger(
new ProcessTagger(), 60000), 300000);
snk.open();
try {
EventUtil.dumpAll(msrc, snk);
snk.close();
} catch (IOException ioe) {
// expected the IO exception from the underlying sink to percolate up to
// this append.
return;
}
fail("Expected IO exception to percolate to this thread");
// TODO (jon) sometimes a IllegalStateException is thrown, sometimes not.
// Inconsistency is bad.
}
/**
* These should be successful
*/
@Test
public void testBuilder() {
DiskFailoverDeco.builder().build(new Context());
DiskFailoverDeco.builder().build(new Context(), "1000");
}
/**
* Fail (expected at most 1 arg
*/
@Test(expected = IllegalArgumentException.class)
public void testBuilderFail1() {
DiskFailoverDeco.builder().build(new Context(), "12341", "foo");
}
/**
* Fail (expected number)
*/
@Test(expected = IllegalArgumentException.class)
public void testBuilderFail2() {
DiskFailoverDeco.builder().build(new Context(), "foo");
}
}