/**
* Copyright 2015 StreamSets Inc.
*
* Licensed under the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.streamsets.datacollector.execution.runner;
import com.codahale.metrics.MetricRegistry;
import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.GreenMailUtil;
import com.streamsets.datacollector.execution.Manager;
import com.streamsets.datacollector.execution.PipelineState;
import com.streamsets.datacollector.execution.PipelineStateStore;
import com.streamsets.datacollector.execution.PipelineStatus;
import com.streamsets.datacollector.execution.Runner;
import com.streamsets.datacollector.execution.Snapshot;
import com.streamsets.datacollector.execution.SnapshotInfo;
import com.streamsets.datacollector.execution.StateListener;
import com.streamsets.datacollector.execution.common.ExecutorConstants;
import com.streamsets.datacollector.execution.manager.standalone.StandaloneAndClusterPipelineManager;
import com.streamsets.datacollector.execution.runner.common.AsyncRunner;
import com.streamsets.datacollector.execution.runner.common.PipelineRunnerException;
import com.streamsets.datacollector.execution.runner.common.ProductionPipeline;
import com.streamsets.datacollector.main.RuntimeInfo;
import com.streamsets.datacollector.main.RuntimeModule;
import com.streamsets.datacollector.main.StandaloneRuntimeInfo;
import com.streamsets.datacollector.runner.production.OffsetFileUtil;
import com.streamsets.datacollector.util.Configuration;
import com.streamsets.datacollector.util.ContainerError;
import com.streamsets.datacollector.util.TestUtil;
import com.streamsets.dc.execution.manager.standalone.ResourceManager;
import com.streamsets.pipeline.api.ExecutionMode;
import com.streamsets.pipeline.api.Source;
import com.streamsets.pipeline.lib.util.ThreadUtil;
import dagger.Module;
import dagger.ObjectGraph;
import dagger.Provides;
import org.apache.commons.io.FileUtils;
import org.awaitility.Duration;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import javax.inject.Singleton;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import static com.streamsets.datacollector.util.AwaitConditionUtil.desiredPipelineState;
import static org.awaitility.Awaitility.await;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class TestStandaloneRunner {
private static final String DATA_DIR_KEY = RuntimeModule.SDC_PROPERTY_PREFIX + RuntimeInfo.DATA_DIR;
private File dataDir;
private Manager pipelineManager;
private PipelineStateStore pipelineStateStore;
@Before
public void setUp() throws IOException {
dataDir = new File("target", UUID.randomUUID().toString()).getAbsoluteFile();
dataDir.mkdirs();
Assert.assertTrue("Could not create: " + dataDir, dataDir.isDirectory());
System.setProperty(DATA_DIR_KEY, dataDir.getAbsolutePath());
TestUtil.captureStagesForProductionRun();
TestUtil.EMPTY_OFFSET = false;
RuntimeInfo info = new StandaloneRuntimeInfo(RuntimeModule.SDC_PROPERTY_PREFIX, new MetricRegistry(),
Arrays.asList(getClass().getClassLoader()));
OffsetFileUtil.saveOffsets(info, TestUtil.MY_PIPELINE, "0", Collections.singletonMap(Source.POLL_SOURCE_OFFSET_KEY, "dummy"));
ObjectGraph objectGraph = ObjectGraph.create(new TestUtil.TestPipelineManagerModule());
pipelineStateStore = objectGraph.get(PipelineStateStore.class);
pipelineManager = new StandaloneAndClusterPipelineManager(objectGraph);
pipelineManager.init();
pipelineManager.run();
}
@After
public void tearDown() throws Exception {
TestUtil.EMPTY_OFFSET = false;
if (pipelineManager != null) {
pipelineManager.stop();
}
TestUtil.EMPTY_OFFSET = false;
System.getProperties().remove(DATA_DIR_KEY);
await().atMost(Duration.ONE_MINUTE).until(() -> FileUtils.deleteQuietly(dataDir));
}
@Test(timeout = 20000)
public void testPipelineStart() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
runner.start("admin");
waitForState(runner, PipelineStatus.RUNNING);
((AsyncRunner)runner).getRunner().prepareForStop("admin");
((AsyncRunner)runner).getRunner().stop("admin");
waitForState(runner, PipelineStatus.STOPPED);
}
@Test(timeout = 20000)
public void testPipelineStartWithParameters() throws Exception {
Runner runner = pipelineManager.getRunner(TestUtil.MY_PIPELINE, "0");
Map<String, Object> runtimeParameters = new HashMap<>();
runtimeParameters.put("param1", "Param1 Value");
runner.start("admin", runtimeParameters);
waitForState(runner, PipelineStatus.RUNNING);
PipelineState pipelineState = runner.getState();
Map<String, Object> runtimeConstantsInState = (Map<String, Object>) pipelineState.getAttributes()
.get(ProductionPipeline.RUNTIME_PARAMETERS_ATTR);
assertNotNull(runtimeConstantsInState);
assertEquals(runtimeParameters.get("param1"), runtimeConstantsInState.get("param1"));
((AsyncRunner)runner).getRunner().prepareForStop("admin");
((AsyncRunner)runner).getRunner().stop("admin");
waitForState(runner, PipelineStatus.STOPPED);
}
@Test(timeout = 50000)
public void testPipelinePrepare() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.FINISHING, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
runner.prepareForDataCollectorStart("admin");
assertEquals(PipelineStatus.FINISHED, runner.getState().getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.STOPPING, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
runner.prepareForDataCollectorStart("admin");
assertEquals(PipelineStatus.STOPPED, runner.getState().getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.DISCONNECTING, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
runner.prepareForDataCollectorStart("admin");
assertEquals(PipelineStatus.DISCONNECTED, runner.getState().getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.CONNECTING, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
runner.prepareForDataCollectorStart("admin");
assertEquals(PipelineStatus.DISCONNECTED, runner.getState().getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.STARTING, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
runner.prepareForDataCollectorStart("admin");
assertEquals(PipelineStatus.DISCONNECTED, runner.getState().getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.RUNNING, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
runner.prepareForDataCollectorStart("admin");
assertEquals(PipelineStatus.DISCONNECTED, runner.getState().getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.DISCONNECTED, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
runner.prepareForDataCollectorStart("admin");
assertEquals(PipelineStatus.DISCONNECTED, runner.getState().getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.STOPPED, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
runner.start("admin");
assertEquals(PipelineStatus.STARTING, runner.getState().getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.STOPPED, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
assertNull(runner.getState().getMetrics());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.RETRY, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
runner.start("admin");
assertEquals(PipelineStatus.STARTING, runner.getState().getStatus());
}
@Test
public void testPipelineRetry() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
runner.start("admin");
waitForState(runner, PipelineStatus.RUNNING);
TestUtil.EMPTY_OFFSET = true;
waitForState(runner, PipelineStatus.FINISHED);
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.RUNNING_ERROR, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
runner = ((AsyncRunner)runner).getRunner();
((StateListener)runner).stateChanged(PipelineStatus.RETRY, null, null);
assertEquals(1, pipelineStateStore.getState(TestUtil.MY_PIPELINE, "0").getRetryAttempt());
assertEquals(PipelineStatus.RETRY, pipelineStateStore.getState(TestUtil.MY_PIPELINE, "0").getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.RUNNING_ERROR, null, null,
ExecutionMode.STANDALONE, null, 1, 0);
((StateListener)runner).stateChanged(PipelineStatus.RETRY, null, null);
assertEquals(2, pipelineStateStore.getState(TestUtil.MY_PIPELINE, "0").getRetryAttempt());
assertEquals(PipelineStatus.RETRY, pipelineStateStore.getState(TestUtil.MY_PIPELINE, "0").getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.RUNNING_ERROR, null, null,
ExecutionMode.STANDALONE, null, 2, 0);
((StateListener)runner).stateChanged(PipelineStatus.RETRY, null, null);
assertEquals(3, pipelineStateStore.getState(TestUtil.MY_PIPELINE, "0").getRetryAttempt());
assertEquals(PipelineStatus.RETRY, pipelineStateStore.getState(TestUtil.MY_PIPELINE, "0").getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.RUNNING_ERROR, null, null,
ExecutionMode.STANDALONE, null, 3, 0);
((StateListener)runner).stateChanged(PipelineStatus.RETRY, null, null);
assertEquals(0, pipelineStateStore.getState(TestUtil.MY_PIPELINE, "0").getRetryAttempt());
assertEquals(PipelineStatus.RUN_ERROR, pipelineStateStore.getState(TestUtil.MY_PIPELINE, "0").getStatus());
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.STOPPED, null, null,
ExecutionMode.STANDALONE, null, 0, 0);
}
@Test(timeout = 20000)
public void testPipelineStartMultipleTimes() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
runner.start("admin");
waitForState(runner, PipelineStatus.RUNNING);
// call start on the already running pipeline and make sure it doesn't request new resource each time
for (int counter =0; counter < 10; counter++) {
try {
runner.start("admin");
Assert.fail("Expected exception but didn't get any");
} catch (PipelineRunnerException ex) {
Assert.assertTrue(ex.getMessage().contains("CONTAINER_0102"));
}
}
((AsyncRunner)runner).getRunner().prepareForStop("admin");
((AsyncRunner)runner).getRunner().stop("admin");
waitForState(runner, PipelineStatus.STOPPED);
}
@Test(timeout = 20000)
public void testPipelineFinish() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
runner.start("admin");
waitForState(runner, PipelineStatus.RUNNING);
assertNull(runner.getState().getMetrics());
TestUtil.EMPTY_OFFSET = true;
waitForState(runner, PipelineStatus.FINISHED);
assertNotNull(runner.getState().getMetrics());
}
@Test(timeout = 20000)
public void testLoadingUnsupportedPipeline() throws Exception {
Runner runner = pipelineManager.getRunner(TestUtil.HIGHER_VERSION_PIPELINE, "0");
runner.start("user2");
waitForState(runner, PipelineStatus.START_ERROR);
PipelineState state = pipelineManager.getRunner(TestUtil.HIGHER_VERSION_PIPELINE, "0").getState();
Assert.assertTrue(state.getStatus() == PipelineStatus.START_ERROR);
Assert.assertTrue(state.getMessage().contains("CONTAINER_0158"));
assertNull(runner.getState().getMetrics());
}
@Test(timeout = 20000)
public void testDisconnectedPipelineStartedAgain() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
runner.start("admin");
waitForState(runner, PipelineStatus.RUNNING);
// sdc going down
pipelineManager.stop();
waitForState(runner, PipelineStatus.DISCONNECTED);
ObjectGraph objectGraph = ObjectGraph.create(new TestUtil.TestPipelineManagerModule());
pipelineStateStore = objectGraph.get(PipelineStateStore.class);
pipelineManager = new StandaloneAndClusterPipelineManager(objectGraph);
pipelineManager.init();
pipelineManager.run();
runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
waitForState(runner, PipelineStatus.RUNNING);
((AsyncRunner)runner).getRunner().prepareForStop("admin");
((AsyncRunner)runner).getRunner().stop("admin");
Assert.assertTrue(runner.getState().getStatus() == PipelineStatus.STOPPED);
assertNotNull(runner.getState().getMetrics());
}
@Test(timeout = 20000)
public void testFinishedPipelineNotStartingAgain() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
runner.start("admin");
waitForState(runner, PipelineStatus.RUNNING);
TestUtil.EMPTY_OFFSET = true;
waitForState(runner, PipelineStatus.FINISHED);
// sdc going down
pipelineManager.stop();
assertNotNull(runner.getState().getMetrics());
// Simulate finishing, the runner shouldn't restart on finishing
pipelineStateStore.saveState("admin", TestUtil.MY_PIPELINE, "0", PipelineStatus.FINISHING, null, null,
ExecutionMode.STANDALONE, runner.getState().getMetrics(), 0, 0);
ObjectGraph objectGraph = ObjectGraph.create(new TestUtil.TestPipelineManagerModule());
pipelineStateStore = objectGraph.get(PipelineStateStore.class);
pipelineManager = new StandaloneAndClusterPipelineManager(objectGraph);
pipelineManager.init();
pipelineManager.run();
//Since SDC went down we need to get the runner again
runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
waitForState(runner, PipelineStatus.FINISHED);
assertNotNull(runner.getState().getMetrics());
}
@Test(timeout = 20000)
public void testMultiplePipelineStartStop() throws Exception {
Runner runner1 = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
Runner runner2 = pipelineManager.getRunner( TestUtil.MY_SECOND_PIPELINE, "0");
runner1.start("admin");
runner2.start("admin2");
waitForState(runner1, PipelineStatus.RUNNING);
waitForState(runner2, PipelineStatus.RUNNING);
((AsyncRunner)runner1).getRunner().prepareForStop("admin");
((AsyncRunner)runner1).getRunner().stop("admin");
waitForState(runner1, PipelineStatus.STOPPED);
((AsyncRunner)runner2).getRunner().prepareForStop("admin2");
((AsyncRunner)runner2).getRunner().stop("admin2");
Assert.assertTrue(runner2.getState().getStatus() == PipelineStatus.STOPPED);
assertNotNull(runner1.getState().getMetrics());
assertNotNull(runner2.getState().getMetrics());
}
@Test(timeout = 20000)
public void testMultiplePipelineFinish() throws Exception {
Runner runner1 = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
Runner runner2 = pipelineManager.getRunner( TestUtil.MY_SECOND_PIPELINE, "0");
runner1.start("admin");
runner2.start("admin2");
waitForState(runner1, PipelineStatus.RUNNING);
waitForState(runner2, PipelineStatus.RUNNING);
TestUtil.EMPTY_OFFSET = true;
waitForState(runner1, PipelineStatus.FINISHED);
waitForState(runner2, PipelineStatus.FINISHED);
assertNotNull(runner1.getState().getMetrics());
assertNotNull(runner2.getState().getMetrics());
}
@Test(timeout = 20000)
public void testDisconnectedPipelinesStartedAgain() throws Exception {
Runner runner1 = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
Runner runner2 = pipelineManager.getRunner( TestUtil.MY_SECOND_PIPELINE, "0");
runner1.start("admin");
runner2.start("admin2");
waitForState(runner1, PipelineStatus.RUNNING);
waitForState(runner2, PipelineStatus.RUNNING);
// sdc going down
pipelineManager.stop();
waitForState(runner1, PipelineStatus.DISCONNECTED);
waitForState(runner2, PipelineStatus.DISCONNECTED);
ObjectGraph objectGraph = ObjectGraph.create(new TestUtil.TestPipelineManagerModule());
pipelineStateStore = objectGraph.get(PipelineStateStore.class);
pipelineManager = new StandaloneAndClusterPipelineManager(objectGraph);
pipelineManager.init();
pipelineManager.run();
runner1 = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
runner2 = pipelineManager.getRunner( TestUtil.MY_SECOND_PIPELINE, "0");
waitForState(runner1, PipelineStatus.RUNNING);
waitForState(runner2, PipelineStatus.RUNNING);
((AsyncRunner)runner1).getRunner().prepareForStop("admin");
((AsyncRunner)runner1).getRunner().stop("admin");
((AsyncRunner)runner2).getRunner().prepareForStop("admin2");
((AsyncRunner)runner2).getRunner().stop("admin2");
waitForState(runner1, PipelineStatus.STOPPED);
waitForState(runner2, PipelineStatus.STOPPED);
assertNotNull(runner1.getState().getMetrics());
assertNotNull(runner2.getState().getMetrics());
}
private void waitForState(Runner runner, PipelineStatus pipelineStatus) {
await().until(desiredPipelineState(runner, pipelineStatus));
}
@Test(timeout = 20000)
public void testPipelineStopTimeout() throws Exception {
TestUtil.captureMockStagesLongWait();
Runner runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
runner.start("admin");
waitForState(runner, PipelineStatus.RUNNING);
((AsyncRunner)runner).getRunner().prepareForStop("admin");
((AsyncRunner)runner).getRunner().stop("admin");
((AsyncRunner)runner).getRunner().forceQuit("admin");
waitForState(runner, PipelineStatus.STOPPED);
}
@Test
public void testSnapshot() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
runner.start("admin");
waitForState(runner, PipelineStatus.RUNNING);
//request to capture snapshot and check the status
final String snapshotName = UUID.randomUUID().toString();
String snapshotId = runner.captureSnapshot("admin", snapshotName, "snapshot label", 5, 10);
assertNotNull(snapshotId);
Snapshot snapshot = runner.getSnapshot(snapshotId);
assertNotNull(snapshot);
SnapshotInfo info = snapshot.getInfo();
assertNotNull(info);
assertNull(snapshot.getOutput());
assertTrue(info.isInProgress());
assertEquals(snapshotId, info.getId());
assertEquals(TestUtil.MY_PIPELINE, info.getName());
assertEquals("0", info.getRev());
//update label
snapshotId = runner.updateSnapshotLabel(snapshotName, "updated snapshot label");
assertNotNull(snapshotId);
snapshot = runner.getSnapshot(snapshotId);
assertNotNull(snapshot);
info = snapshot.getInfo();
assertNotNull(info);
assertEquals(snapshotName, info.getId());
assertEquals("updated snapshot label", info.getLabel());
//request cancel snapshot
runner.deleteSnapshot(snapshotId);
snapshot = runner.getSnapshot(snapshotId);
assertNotNull(snapshot);
assertNull(snapshot.getInfo());
assertNull(snapshot.getOutput());
//call cancel again - no op
runner.deleteSnapshot(snapshotName);
snapshot = runner.getSnapshot(snapshotId);
assertNotNull(snapshot);
assertNull(snapshot.getInfo());
assertNull(snapshot.getOutput());
//call cancel on some other snapshot which does not exist - no op
runner.deleteSnapshot("mySnapshot1");
snapshot = runner.getSnapshot(snapshotId);
assertNotNull(snapshot);
assertNull(snapshot.getInfo());
assertNull(snapshot.getOutput());
((AsyncRunner)runner).getRunner().prepareForStop("admin");
((AsyncRunner)runner).getRunner().stop("admin");
waitForState(runner, PipelineStatus.STOPPED);
}
@Test (timeout = 60000)
public void testStartAndCaptureSnapshot() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
String snapshotId = UUID.randomUUID().toString();
runner.startAndCaptureSnapshot("admin", null, snapshotId, "snapshot label", 1, 10);
waitForState(runner, PipelineStatus.RUNNING);
Snapshot snapshot = runner.getSnapshot(snapshotId);
assertNotNull(snapshot);
SnapshotInfo info = snapshot.getInfo();
assertNotNull(info);
assertNotNull(snapshot.getOutput());
assertFalse(info.isInProgress());
assertEquals(snapshotId, info.getId());
assertEquals(TestUtil.MY_PIPELINE, info.getName());
assertEquals("0", info.getRev());
assertEquals(1, info.getBatchNumber());
((AsyncRunner)runner).getRunner().prepareForStop("admin");
((AsyncRunner)runner).getRunner().stop("admin");
waitForState(runner, PipelineStatus.STOPPED);
// try with batch size less than 0
snapshotId = UUID.randomUUID().toString();
try {
runner.startAndCaptureSnapshot("admin",null, snapshotId, "snapshot label", 1, 0);
Assert.fail("Expected PipelineRunnerException");
} catch (PipelineRunnerException e) {
Assert.assertEquals(ContainerError.CONTAINER_0107, e.getErrorCode());
}
}
@Test (timeout = 60000)
public void testRunningMaxPipelines() throws Exception {
ObjectGraph objectGraph = ObjectGraph.create(new TestUtil.TestPipelineManagerModule(), ConfigModule.class);
pipelineManager = new StandaloneAndClusterPipelineManager(objectGraph);
pipelineManager.init();
pipelineManager.run();
//Only one runner can start pipeline at the max since the runner thread pool size is 3
Runner runner1 = pipelineManager.getRunner( TestUtil.MY_PIPELINE, "0");
runner1.start("admin");
waitForState(runner1, PipelineStatus.RUNNING);
Runner runner2 = pipelineManager.getRunner( TestUtil.MY_SECOND_PIPELINE, "0");
try {
runner2.start("admin2");
Assert.fail("Expected PipelineRunnerException");
} catch (PipelineRunnerException e) {
Assert.assertEquals(ContainerError.CONTAINER_0166, e.getErrorCode());
}
((AsyncRunner)runner1).getRunner().prepareForStop("admin");
((AsyncRunner)runner1).getRunner().stop("admin");
waitForState(runner1, PipelineStatus.STOPPED);
runner2.start("admin2");
waitForState(runner2, PipelineStatus.RUNNING);
try {
runner1.start("admin");
Assert.fail("Expected PipelineRunnerException");
} catch (PipelineRunnerException e) {
Assert.assertEquals(ContainerError.CONTAINER_0166, e.getErrorCode());
}
((AsyncRunner)runner2).getRunner().prepareForStop("admin");
((AsyncRunner)runner2).getRunner().stop("admin2");
waitForState(runner2, PipelineStatus.STOPPED);
}
@Test(timeout = 20000)
public void testPipelineStoppedWithMail() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.PIPELINE_WITH_EMAIL, "0");
runner.start("admin");
waitForState(runner, PipelineStatus.RUNNING);
((AsyncRunner)runner).getRunner().prepareForStop("admin");
((AsyncRunner)runner).getRunner().stop("admin");
waitForState(runner, PipelineStatus.STOPPED);
//wait for email
GreenMail mailServer = TestUtil.TestRuntimeModule.getMailServer();
while(mailServer.getReceivedMessages().length < 1) {
ThreadUtil.sleep(100);
}
String headers = GreenMailUtil.getHeaders(mailServer.getReceivedMessages()[0]);
Assert.assertTrue(headers.contains("To: foo, bar"));
Assert.assertTrue(headers.contains("Subject: StreamsSets Data Collector Alert - " +
TestUtil.PIPELINE_TITLE_WITH_EMAIL + " - STOPPED"));
Assert.assertTrue(headers.contains("From: sdc@localhost"));
Assert.assertNotNull(GreenMailUtil.getBody(mailServer.getReceivedMessages()[0]));
mailServer.reset();
}
@Test(timeout = 20000)
public void testPipelineFinishWithMail() throws Exception {
Runner runner = pipelineManager.getRunner( TestUtil.PIPELINE_WITH_EMAIL, "0");
runner.start("admin");
waitForState(runner, PipelineStatus.RUNNING);
assertNull(runner.getState().getMetrics());
TestUtil.EMPTY_OFFSET = true;
waitForState(runner, PipelineStatus.FINISHED);
assertNotNull(runner.getState().getMetrics());
//wait for email
GreenMail mailServer = TestUtil.TestRuntimeModule.getMailServer();
while(mailServer.getReceivedMessages().length < 1) {
ThreadUtil.sleep(100);
}
String headers = GreenMailUtil.getHeaders(mailServer.getReceivedMessages()[0]);
Assert.assertTrue(headers.contains("To: foo, bar"));
Assert.assertTrue(headers.contains("Subject: StreamsSets Data Collector Alert - " +
TestUtil.PIPELINE_TITLE_WITH_EMAIL + " - FINISHED"));
Assert.assertTrue(headers.contains("From: sdc@localhost"));
Assert.assertNotNull(GreenMailUtil.getBody(mailServer.getReceivedMessages()[0]));
mailServer.reset();
}
@Module(overrides = true, library = true)
static class ConfigModule {
@Provides
@Singleton
public Configuration provideConfiguration() {
Configuration configuration = new Configuration();
configuration.set(ExecutorConstants.RUNNER_THREAD_POOL_SIZE_KEY, 3);
return configuration;
}
@Provides
@Singleton
public ResourceManager provideResourceManager(Configuration configuration) {
return new ResourceManager(configuration);
}
}
}