/*
* Copyright 2013 Netflix, Inc.
*
* Licensed 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.netflix.governator.lifecycle.warmup;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.netflix.governator.LifecycleInjectorBuilderProvider;
import com.netflix.governator.guice.LifecycleInjector;
import com.netflix.governator.lifecycle.LifecycleManager;
public class TestWarmUpManager extends LifecycleInjectorBuilderProvider {
private static final Logger LOG = LoggerFactory.getLogger(TestWarmUpManager.class);
@Test
public void testPostStart() throws Exception {
Injector injector = LifecycleInjector.builder().build().createInjector();
injector.getInstance(LifecycleManager.class).start();
injector.getInstance(Dag1.A.class);
Recorder recorder = injector.getInstance(Recorder.class);
LOG.info("" + recorder.getRecordings());
LOG.info("" + recorder.getConcurrents());
assertSingleExecution(recorder);
assertNotConcurrent(recorder, "A", "B");
assertNotConcurrent(recorder, "A", "C");
Assert.assertEquals(recorder.getInterruptions().size(), 0);
assertOrdering(recorder, "A", "B");
assertOrdering(recorder, "A", "C");
}
@Test(expected = Error.class)
public void testErrors() throws Exception {
AbstractModule module = new AbstractModule() {
@Override
protected void configure() {
binder().bind(WarmUpWithException.class).asEagerSingleton();
}
};
LifecycleInjector.builder().withModules(module).build().createInjector().getInstance(LifecycleManager.class)
.start();
}
@Test
public void testDag1MultiModule() throws Exception {
final List<AbstractModule> modules = Arrays.asList(new AbstractModule() {
@Override
protected void configure() {
bind(Dag1.A.class);
}
}, new AbstractModule() {
@Override
protected void configure() {
bind(Dag1.B.class);
}
}, new AbstractModule() {
@Override
protected void configure() {
bind(Dag1.C.class);
}
});
Injector injector = LifecycleInjector.builder().withModules(modules).build().createInjector();
injector.getInstance(LifecycleManager.class).start();
Recorder recorder = injector.getInstance(Recorder.class);
LOG.info("" + recorder.getRecordings());
LOG.info("" + recorder.getConcurrents());
assertSingleExecution(recorder);
assertNotConcurrent(recorder, "A", "B");
assertNotConcurrent(recorder, "A", "C");
Assert.assertEquals(recorder.getInterruptions().size(), 0);
assertOrdering(recorder, "A", "B");
assertOrdering(recorder, "A", "C");
}
@Test
public void testDagInterfaceModule() throws Exception {
final Module dag1Module = new AbstractModule() {
@Override
protected void configure() {
bind(DagInterface.A.class).to(DagInterface.AImpl.class);
bind(DagInterface.B.class).to(DagInterface.BImpl.class);
bind(DagInterface.C.class).to(DagInterface.CImpl.class);
}
};
Injector injector = LifecycleInjector.builder().withModules(dag1Module).build().createInjector();
injector.getInstance(LifecycleManager.class).start();
Recorder recorder = injector.getInstance(Recorder.class);
LOG.info("" + recorder.getRecordings());
LOG.info("" + recorder.getConcurrents());
assertSingleExecution(recorder);
assertNotConcurrent(recorder, "A", "B");
assertNotConcurrent(recorder, "A", "C");
Assert.assertEquals(recorder.getInterruptions().size(), 0);
assertOrdering(recorder, "A", "B");
assertOrdering(recorder, "A", "C");
}
@Test
public void testDag1() throws Exception {
Injector injector = LifecycleInjector.builder().build().createInjector();
injector.getInstance(Dag1.A.class);
injector.getInstance(LifecycleManager.class).start();
Recorder recorder = injector.getInstance(Recorder.class);
LOG.info("" + recorder.getRecordings());
LOG.info("" + recorder.getConcurrents());
assertSingleExecution(recorder);
assertNotConcurrent(recorder, "A", "B");
assertNotConcurrent(recorder, "A", "C");
Assert.assertEquals(recorder.getInterruptions().size(), 0);
assertOrdering(recorder, "A", "B");
assertOrdering(recorder, "A", "C");
}
@Test
public void testDag2() throws Exception {
Injector injector = LifecycleInjector.builder().build().createInjector();
injector.getInstance(Dag2.A1.class);
injector.getInstance(Dag2.A2.class);
injector.getInstance(Dag2.A3.class);
injector.getInstance(LifecycleManager.class).start();
Recorder recorder = injector.getInstance(Recorder.class);
LOG.info("" + recorder.getRecordings());
LOG.info("" + recorder.getConcurrents());
assertSingleExecution(recorder);
assertNotConcurrent(recorder, "A1", "B1");
assertNotConcurrent(recorder, "A1", "B2");
assertNotConcurrent(recorder, "B1", "C1");
assertNotConcurrent(recorder, "B2", "C1");
assertNotConcurrent(recorder, "A2", "B2");
assertNotConcurrent(recorder, "A2", "B3");
assertNotConcurrent(recorder, "B2", "C2");
assertNotConcurrent(recorder, "B3", "C2");
assertNotConcurrent(recorder, "A3", "B3");
assertNotConcurrent(recorder, "A3", "B4");
assertNotConcurrent(recorder, "B3", "C3");
assertNotConcurrent(recorder, "B4", "C3");
Assert.assertEquals(recorder.getInterruptions().size(), 0);
assertOrdering(recorder, "A1", "B1");
assertOrdering(recorder, "B1", "C1");
assertOrdering(recorder, "A1", "B2");
assertOrdering(recorder, "B2", "C1");
assertOrdering(recorder, "A2", "B2");
assertOrdering(recorder, "B2", "C2");
assertOrdering(recorder, "A2", "B3");
assertOrdering(recorder, "B3", "C2");
assertOrdering(recorder, "A3", "B3");
assertOrdering(recorder, "B3", "C3");
assertOrdering(recorder, "A3", "B4");
assertOrdering(recorder, "B4", "C3");
}
@Test
public void testDag3() throws Exception {
Injector injector = LifecycleInjector.builder().build().createInjector();
injector.getInstance(Dag3.A.class);
injector.getInstance(LifecycleManager.class).start();
Recorder recorder = injector.getInstance(Recorder.class);
LOG.info("" + recorder.getRecordings());
LOG.info("" + recorder.getConcurrents());
assertSingleExecution(recorder);
assertNotConcurrent(recorder, "C", "D");
assertNotConcurrent(recorder, "B", "D");
assertNotConcurrent(recorder, "A", "B");
assertNotConcurrent(recorder, "A", "C");
Assert.assertEquals(recorder.getInterruptions().size(), 0);
assertOrdering(recorder, "A", "C");
assertOrdering(recorder, "C", "D");
assertOrdering(recorder, "A", "D");
assertOrdering(recorder, "B", "D");
}
@Test
public void testDag4() throws Exception {
Injector injector = LifecycleInjector.builder().build().createInjector();
injector.getInstance(Dag4.A.class);
injector.getInstance(LifecycleManager.class).start();
Recorder recorder = injector.getInstance(Recorder.class);
LOG.info("" + recorder.getRecordings());
LOG.info("" + recorder.getConcurrents());
assertSingleExecution(recorder);
Assert.assertEquals(recorder.getInterruptions().size(), 0);
assertOrdering(recorder, "D", "E");
assertOrdering(recorder, "C", "E");
assertOrdering(recorder, "B", "D");
assertOrdering(recorder, "A", "B");
}
@Test
public void testFlat() throws Exception {
Injector injector = LifecycleInjector.builder().build().createInjector();
Recorder recorder = injector.getInstance(Recorder.class);
injector.getInstance(Flat.A.class).recorder = recorder;
injector.getInstance(Flat.B.class).recorder = recorder;
injector.getInstance(LifecycleManager.class).start();
LOG.info("" + recorder.getRecordings());
LOG.info("" + recorder.getConcurrents());
assertSingleExecution(recorder);
Assert.assertEquals(recorder.getInterruptions().size(), 0);
Assert.assertTrue(recorder.getRecordings().indexOf("A") >= 0);
Assert.assertTrue(recorder.getRecordings().indexOf("B") >= 0);
}
private void assertSingleExecution(Recorder recorder) {
Set<String> duplicateCheck = Sets.newHashSet();
for (String s : recorder.getRecordings()) {
Assert.assertFalse(s + " ran more than once: " + recorder.getRecordings(), duplicateCheck.contains(s));
duplicateCheck.add(s);
}
}
private void assertOrdering(Recorder recorder, String base, String dependency) {
int baseIndex = recorder.getRecordings().indexOf(base);
int dependencyIndex = recorder.getRecordings().indexOf(dependency);
Assert.assertTrue(baseIndex >= 0);
Assert.assertTrue(dependencyIndex >= 0);
Assert.assertTrue("baseIndex: " + baseIndex + " - dependencyIndex: " + dependencyIndex,
baseIndex > dependencyIndex);
}
private void assertNotConcurrent(Recorder recorder, String task1, String task2) {
for (Set<String> s : recorder.getConcurrents()) {
Assert.assertTrue(String.format("Incorrect concurrency for %s and %s: %s", task1, task2, s),
!s.contains(task1) || !s.contains(task2));
}
}
}