diff options
author | gjoranv <gv@verizonmedia.com> | 2021-04-02 18:28:31 +0200 |
---|---|---|
committer | gjoranv <gv@verizonmedia.com> | 2021-04-12 16:19:31 +0200 |
commit | 2cf3e1b141dac0581664bce897806815cfd00316 (patch) | |
tree | c1e9ae7075cb7492cb06ac50f571133e01cbc4e3 /container-di/src/test/java/com/yahoo/container | |
parent | 12bc324dde697b522aaf99277001f03b2af421b1 (diff) |
Remove the container-di module.
Diffstat (limited to 'container-di/src/test/java/com/yahoo/container')
10 files changed, 0 insertions, 2098 deletions
diff --git a/container-di/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java b/container-di/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java deleted file mode 100644 index 290836d7842..00000000000 --- a/container-di/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.di; - -import com.yahoo.config.ConfigInstance; -import com.yahoo.config.test.Bootstrap1Config; -import com.yahoo.config.test.Bootstrap2Config; -import com.yahoo.config.test.TestConfig; -import com.yahoo.container.di.ConfigRetriever.BootstrapConfigs; -import com.yahoo.container.di.ConfigRetriever.ComponentsConfigs; -import com.yahoo.container.di.ConfigRetriever.ConfigSnapshot; -import com.yahoo.vespa.config.ConfigKey; -import org.hamcrest.Matchers; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; - -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; - -/** - * - * @author gjoranv - * @author Tony Vaagenes - * @author ollivir - */ -public class ConfigRetrieverTest { - - private DirConfigSource dirConfigSource = null; - - @Before - public void setup() { - dirConfigSource = new DirConfigSource("ConfigRetrieverTest-"); - } - - @After - public void cleanup() { - dirConfigSource.cleanup(); - } - - @Test - public void require_that_bootstrap_configs_come_first() { - writeConfigs(); - ConfigRetriever retriever = createConfigRetriever(); - ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0, true); - - assertThat(bootstrapConfigs, Matchers.instanceOf(BootstrapConfigs.class)); - } - - @Test - @SuppressWarnings("unused") - public void require_that_components_comes_after_bootstrap() { - writeConfigs(); - ConfigRetriever retriever = createConfigRetriever(); - ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0, true); - - ConfigKey<? extends ConfigInstance> testConfigKey = new ConfigKey<>(TestConfig.class, dirConfigSource.configId()); - ConfigSnapshot componentsConfigs = retriever.getConfigs(Collections.singleton(testConfigKey), 0, true); - - if (componentsConfigs instanceof ComponentsConfigs) { - assertThat(componentsConfigs.size(), is(3)); - } else { - fail("ComponentsConfigs has unexpected type: " + componentsConfigs); - } - } - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Ignore - @SuppressWarnings("unused") - public void require_exception_upon_modified_components_keys_without_bootstrap() { - expectedException.expect(IllegalArgumentException.class); - - writeConfigs(); - ConfigRetriever retriever = createConfigRetriever(); - ConfigKey<? extends ConfigInstance> testConfigKey = new ConfigKey<>(TestConfig.class, dirConfigSource.configId()); - ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0, true); - ConfigSnapshot componentsConfigs = retriever.getConfigs(Collections.singleton(testConfigKey), 0, true); - Set<ConfigKey<? extends ConfigInstance>> keys = new HashSet<>(); - keys.add(testConfigKey); - keys.add(new ConfigKey<>(TestConfig.class, "")); - retriever.getConfigs(keys, 0, true); - } - - @Test - public void require_that_empty_components_keys_after_bootstrap_returns_components_configs() { - writeConfigs(); - ConfigRetriever retriever = createConfigRetriever(); - assertThat(retriever.getConfigs(Collections.emptySet(), 0, true), instanceOf(BootstrapConfigs.class)); - assertThat(retriever.getConfigs(Collections.emptySet(), 0, true), instanceOf(ComponentsConfigs.class)); - } - - public void writeConfigs() { - writeConfig("bootstrap1", "dummy \"ignored\""); - writeConfig("bootstrap2", "dummy \"ignored\""); - writeConfig("test", "stringVal \"ignored\""); - } - - private ConfigRetriever createConfigRetriever() { - String configId = dirConfigSource.configId(); - CloudSubscriberFactory subscriber = new CloudSubscriberFactory(dirConfigSource.configSource()); - Set<ConfigKey<? extends ConfigInstance>> keys = new HashSet<>(); - keys.add(new ConfigKey<>(Bootstrap1Config.class, configId)); - keys.add(new ConfigKey<>(Bootstrap2Config.class, configId)); - return new ConfigRetriever(keys, keySet -> subscriber.getSubscriber(keySet)); - } - - private void writeConfig(String name, String contents) { - dirConfigSource.writeConfig(name, contents); - } -} diff --git a/container-di/src/test/java/com/yahoo/container/di/ContainerTest.java b/container-di/src/test/java/com/yahoo/container/di/ContainerTest.java deleted file mode 100644 index b596246a43d..00000000000 --- a/container-di/src/test/java/com/yahoo/container/di/ContainerTest.java +++ /dev/null @@ -1,408 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.di; - -import com.google.inject.Guice; -import com.yahoo.component.AbstractComponent; -import com.yahoo.config.di.IntConfig; -import com.yahoo.config.test.TestConfig; -import com.yahoo.container.bundle.MockBundle; -import com.yahoo.container.di.componentgraph.Provider; -import com.yahoo.container.di.componentgraph.core.ComponentGraph; -import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.SimpleComponent; -import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.SimpleComponent2; -import com.yahoo.container.di.componentgraph.core.ComponentNode.ComponentConstructorException; -import com.yahoo.container.di.config.RestApiContext; -import org.junit.Ignore; -import org.junit.Test; -import org.osgi.framework.Bundle; - -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * @author Tony Vaagenes - * @author gjoranv - * @author ollivir - */ -public class ContainerTest extends ContainerTestBase { - - @Test - public void components_can_be_created_from_config() { - writeBootstrapConfigs(); - dirConfigSource.writeConfig("test", "stringVal \"myString\""); - - Container container = newContainer(dirConfigSource); - - ComponentTakingConfig component = createComponentTakingConfig(getNewComponentGraph(container)); - assertEquals("myString", component.config.stringVal()); - - container.shutdownConfigurer(); - } - - @Test - public void components_are_reconfigured_after_config_update_without_bootstrap_configs() { - writeBootstrapConfigs(); - dirConfigSource.writeConfig("test", "stringVal \"original\""); - - Container container = newContainer(dirConfigSource); - ComponentGraph componentGraph = getNewComponentGraph(container); - ComponentTakingConfig component = createComponentTakingConfig(componentGraph); - - assertEquals("original", component.config.stringVal()); - - // Reconfigure - dirConfigSource.writeConfig("test", "stringVal \"reconfigured\""); - container.reloadConfig(2); - - ComponentGraph newComponentGraph = getNewComponentGraph(container, componentGraph); - ComponentTakingConfig component2 = createComponentTakingConfig(newComponentGraph); - assertEquals("reconfigured", component2.config.stringVal()); - - container.shutdownConfigurer(); - } - - @Test - public void graph_is_updated_after_bootstrap_update() { - dirConfigSource.writeConfig("test", "stringVal \"original\""); - writeBootstrapConfigs("id1"); - - Container container = newContainer(dirConfigSource); - - ComponentGraph graph = getNewComponentGraph(container); - ComponentTakingConfig component = createComponentTakingConfig(graph); - assertEquals("id1", component.getId().toString()); - - writeBootstrapConfigs( - new ComponentEntry("id1", ComponentTakingConfig.class), - new ComponentEntry("id2", ComponentTakingConfig.class)); - - container.reloadConfig(2); - ComponentGraph newGraph = getNewComponentGraph(container, graph); - - assertNotNull(ComponentGraph.getNode(newGraph, "id1")); - assertNotNull(ComponentGraph.getNode(newGraph, "id2")); - - container.shutdownConfigurer(); - } - - //@Test TODO - public void deconstructor_is_given_guice_components() { - } - - @Test - public void component_is_deconstructed_when_not_reused() { - writeBootstrapConfigs("id1", DestructableComponent.class); - - Container container = newContainer(dirConfigSource); - - ComponentGraph oldGraph = getNewComponentGraph(container); - DestructableComponent componentToDestruct = oldGraph.getInstance(DestructableComponent.class); - - writeBootstrapConfigs("id2", DestructableComponent.class); - container.reloadConfig(2); - getNewComponentGraph(container, oldGraph); - assertTrue(componentToDestruct.deconstructed); - } - - @Ignore // because logAndDie is impossible(?) to verify programmatically - @Test - public void manually_verify_what_happens_when_first_graph_contains_component_that_throws_exception_in_ctor() { - writeBootstrapConfigs("thrower", ComponentThrowingExceptionInConstructor.class); - Container container = newContainer(dirConfigSource); - try { - getNewComponentGraph(container); - fail("Expected to log and die."); - } catch (Throwable t) { - fail("Expected to log and die"); - } - } - - @Test - public void previous_graph_is_retained_when_new_graph_contains_component_that_throws_exception_in_ctor() { - ComponentEntry simpleComponentEntry = new ComponentEntry("simpleComponent", SimpleComponent.class); - - writeBootstrapConfigs(simpleComponentEntry); - Container container = newContainer(dirConfigSource); - ComponentGraph currentGraph = getNewComponentGraph(container); - - SimpleComponent simpleComponent = currentGraph.getInstance(SimpleComponent.class); - - writeBootstrapConfigs("thrower", ComponentThrowingExceptionInConstructor.class); - container.reloadConfig(2); - try { - currentGraph = getNewComponentGraph(container, currentGraph); - fail("Expected exception"); - } catch (ComponentConstructorException ignored) { - // Expected, do nothing - } catch (Throwable t) { - fail("Expected ComponentConstructorException"); - } - assertEquals(1, currentGraph.generation()); - - // Also verify that next reconfig is successful - ComponentEntry componentTakingConfigEntry = new ComponentEntry("componentTakingConfig", ComponentTakingConfig.class); - dirConfigSource.writeConfig("test", "stringVal \"myString\""); - writeBootstrapConfigs(simpleComponentEntry, componentTakingConfigEntry); - container.reloadConfig(3); - currentGraph = getNewComponentGraph(container, currentGraph); - - assertEquals(3, currentGraph.generation()); - assertSame(simpleComponent, currentGraph.getInstance(SimpleComponent.class)); - assertNotNull(currentGraph.getInstance(ComponentTakingConfig.class)); - } - - @Test - public void previous_graph_is_retained_when_new_graph_throws_exception_for_missing_config() { - ComponentEntry simpleComponentEntry = new ComponentEntry("simpleComponent", SimpleComponent.class); - - writeBootstrapConfigs(simpleComponentEntry); - Container container = newContainer(dirConfigSource); - ComponentGraph currentGraph = getNewComponentGraph(container); - - currentGraph.getInstance(SimpleComponent.class); - - writeBootstrapConfigs("thrower", ComponentThrowingExceptionForMissingConfig.class); - dirConfigSource.writeConfig("test", "stringVal \"myString\""); - container.reloadConfig(2); - try { - currentGraph = getNewComponentGraph(container, currentGraph); - fail("Expected exception"); - } catch (IllegalArgumentException ignored) { - // Expected, do nothing - } catch (Throwable t) { - fail("Expected IllegalArgumentException"); - } - assertEquals(1, currentGraph.generation()); - } - - @Test - public void getNewComponentGraph_hangs_waiting_for_valid_config_after_invalid_config() throws Exception { - dirConfigSource.writeConfig("test", "stringVal \"original\""); - writeBootstrapConfigs("myId", ComponentTakingConfig.class); - - Container container = newContainer(dirConfigSource); - final ComponentGraph currentGraph = getNewComponentGraph(container); - - writeBootstrapConfigs("thrower", ComponentThrowingExceptionForMissingConfig.class); - container.reloadConfig(2); - - try { - getNewComponentGraph(container, currentGraph); - fail("expected exception"); - } catch (Exception ignored) { - } - ExecutorService exec = Executors.newFixedThreadPool(1); - Future<ComponentGraph> newGraph = exec.submit(() -> getNewComponentGraph(container, currentGraph)); - - try { - newGraph.get(1, TimeUnit.SECONDS); - fail("Expected waiting for new config."); - } catch (Exception ignored) { - // expect to time out - } - - writeBootstrapConfigs("myId2", ComponentTakingConfig.class); - container.reloadConfig(3); - - assertNotNull(newGraph.get(5, TimeUnit.MINUTES)); - } - - - @Test - public void bundle_info_is_set_on_rest_api_context() { - Class<RestApiContext> clazz = RestApiContext.class; - - writeBootstrapConfigs("restApiContext", clazz); - dirConfigSource.writeConfig("jersey-bundles", "bundles[0].spec \"mock-entry-to-enforce-a-MockBundle\""); - dirConfigSource.writeConfig("jersey-injection", "inject[0]"); - - Container container = newContainer(dirConfigSource); - ComponentGraph componentGraph = getNewComponentGraph(container); - - RestApiContext restApiContext = componentGraph.getInstance(clazz); - assertNotNull(restApiContext); - - assertEquals(1, restApiContext.getBundles().size()); - assertEquals(MockBundle.SymbolicName, restApiContext.getBundles().get(0).symbolicName); - assertEquals(MockBundle.BundleVersion, restApiContext.getBundles().get(0).version); - - container.shutdownConfigurer(); - } - - @Test - public void restApiContext_has_all_components_injected() { - Class<RestApiContext> restApiClass = RestApiContext.class; - Class<SimpleComponent> injectedClass = SimpleComponent.class; - String injectedComponentId = "injectedComponent"; - Class<SimpleComponent2> anotherComponentClass = SimpleComponent2.class; - String anotherComponentId = "anotherComponent"; - - String componentsConfig = - new ComponentEntry(injectedComponentId, injectedClass).asConfig(0) + "\n" + - new ComponentEntry(anotherComponentId, anotherComponentClass).asConfig(1) + "\n" + - new ComponentEntry("restApiContext", restApiClass).asConfig(2) + "\n" + - "components[2].inject[0].id " + injectedComponentId + "\n" + - "components[2].inject[1].id " + anotherComponentId + "\n"; - - String injectionConfig = "inject[1]\n" +// - "inject[0].instance " + injectedComponentId + "\n" +// - "inject[0].forClass \"" + injectedClass.getName() + "\"\n"; - - dirConfigSource.writeConfig("components", componentsConfig); - dirConfigSource.writeConfig("platform-bundles", ""); - dirConfigSource.writeConfig("application-bundles", ""); - dirConfigSource.writeConfig("jersey-bundles", "bundles[0].spec \"mock-entry-to-enforce-a-MockBundle\""); - dirConfigSource.writeConfig("jersey-injection", injectionConfig); - - Container container = newContainer(dirConfigSource); - ComponentGraph componentGraph = getNewComponentGraph(container); - - RestApiContext restApiContext = componentGraph.getInstance(restApiClass); - - assertFalse(restApiContext.getInjectableComponents().isEmpty()); - assertEquals(2, restApiContext.getInjectableComponents().size()); - - container.shutdownConfigurer(); - } - - @Test - public void providers_are_destructed() { - writeBootstrapConfigs("id1", DestructableProvider.class); - - ComponentDeconstructor deconstructor = (components, bundles) -> { - components.forEach(component -> { - if (component instanceof AbstractComponent) { - ((AbstractComponent) component).deconstruct(); - } else if (component instanceof Provider) { - ((Provider<?>) component).deconstruct(); - } - }); - if (! bundles.isEmpty()) throw new IllegalArgumentException("This test should not use bundles"); - }; - - Container container = newContainer(dirConfigSource, deconstructor); - - ComponentGraph oldGraph = getNewComponentGraph(container); - DestructableEntity destructableEntity = oldGraph.getInstance(DestructableEntity.class); - - writeBootstrapConfigs("id2", DestructableProvider.class); - container.reloadConfig(2); - getNewComponentGraph(container, oldGraph); - - assertTrue(destructableEntity.deconstructed); - } - - @Test - public void providers_are_invoked_only_when_needed() { - writeBootstrapConfigs("id1", FailOnGetProvider.class); - - Container container = newContainer(dirConfigSource); - - ComponentGraph oldGraph = getNewComponentGraph(container); - } - - static class DestructableEntity { - private boolean deconstructed = false; - } - - public static class DestructableProvider implements Provider<DestructableEntity> { - DestructableEntity instance = new DestructableEntity(); - - public DestructableEntity get() { - return instance; - } - - public void deconstruct() { - assertFalse(instance.deconstructed); - instance.deconstructed = true; - } - } - - public static class FailOnGetProvider implements Provider<Integer> { - - public Integer get() { - fail("Should never be called."); - return null; - } - - public void deconstruct() { - } - - } - - public static class ComponentTakingConfig extends AbstractComponent { - private final TestConfig config; - - public ComponentTakingConfig(TestConfig config) { - assertNotNull(config); - this.config = config; - } - } - - public static class ComponentThrowingExceptionInConstructor { - public ComponentThrowingExceptionInConstructor() { - throw new RuntimeException("This component fails upon construction."); - } - } - - public static class ComponentThrowingExceptionForMissingConfig extends AbstractComponent { - public ComponentThrowingExceptionForMissingConfig(IntConfig intConfig) { - fail("This component should never be created. Only used for tests where 'int' config is missing."); - } - } - - public static class DestructableComponent extends AbstractComponent { - private boolean deconstructed = false; - - @Override - public void deconstruct() { - deconstructed = true; - } - } - - public static class TestDeconstructor implements ComponentDeconstructor { - @Override - public void deconstruct(List<Object> components, Collection<Bundle> bundles) { - components.forEach(component -> { - if (component instanceof DestructableComponent) { - DestructableComponent vespaComponent = (DestructableComponent) component; - vespaComponent.deconstruct(); - } - }); - if (! bundles.isEmpty()) throw new IllegalArgumentException("This test should not use bundles"); - } - } - - private static Container newContainer(DirConfigSource dirConfigSource, - ComponentDeconstructor deconstructor) { - return new Container(new CloudSubscriberFactory(dirConfigSource.configSource), dirConfigSource.configId(), deconstructor); - } - - private static Container newContainer(DirConfigSource dirConfigSource) { - return newContainer(dirConfigSource, new TestDeconstructor()); - } - - ComponentGraph getNewComponentGraph(Container container, ComponentGraph oldGraph) { - return container.getNewComponentGraph(oldGraph, Guice.createInjector(), true); - } - - ComponentGraph getNewComponentGraph(Container container) { - return container.getNewComponentGraph(new ComponentGraph(), Guice.createInjector(), true); - } - - private ComponentTakingConfig createComponentTakingConfig(ComponentGraph componentGraph) { - return componentGraph.getInstance(ComponentTakingConfig.class); - } - -} diff --git a/container-di/src/test/java/com/yahoo/container/di/ContainerTestBase.java b/container-di/src/test/java/com/yahoo/container/di/ContainerTestBase.java deleted file mode 100644 index 2106a1f3671..00000000000 --- a/container-di/src/test/java/com/yahoo/container/di/ContainerTestBase.java +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.di; - -import com.google.inject.Guice; -import com.yahoo.component.ComponentSpecification; -import com.yahoo.config.FileReference; -import com.yahoo.container.bundle.BundleInstantiationSpecification; -import com.yahoo.container.di.ContainerTest.ComponentTakingConfig; -import com.yahoo.container.di.componentgraph.core.ComponentGraph; -import com.yahoo.container.di.osgi.BundleClasses; -import org.junit.After; -import org.junit.Before; -import org.osgi.framework.Bundle; - -import java.util.Collection; -import java.util.Set; - -import static java.util.Collections.emptySet; - -/** - * @author Tony Vaagenes - * @author gjoranv - * @author ollivir - */ -public class ContainerTestBase { - - private ComponentGraph componentGraph; - protected DirConfigSource dirConfigSource = null; - - @Before - public void setup() { - dirConfigSource = new DirConfigSource("ContainerTest-"); - } - - @After - public void cleanup() { - dirConfigSource.cleanup(); - } - - @Before - public void createGraph() { - componentGraph = new ComponentGraph(0); - } - - public void complete() { - try { - Container container = new Container(new CloudSubscriberFactory(dirConfigSource.configSource()), dirConfigSource.configId(), - new ContainerTest.TestDeconstructor(), new Osgi() { - @SuppressWarnings("unchecked") - @Override - public Class<Object> resolveClass(BundleInstantiationSpecification spec) { - try { - return (Class<Object>) Class.forName(spec.classId.getName()); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - - @Override - public BundleClasses getBundleClasses(ComponentSpecification bundle, Set<String> packagesToScan) { - throw new UnsupportedOperationException("getBundleClasses not supported"); - } - - @Override - public Set<Bundle> useApplicationBundles(Collection<FileReference> bundles) { - return emptySet(); - } - - @Override - public Bundle getBundle(ComponentSpecification spec) { - throw new UnsupportedOperationException("getBundle not supported."); - } - }); - componentGraph = container.getNewComponentGraph(componentGraph, Guice.createInjector(), true); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public <T> T getInstance(Class<T> componentClass) { - return componentGraph.getInstance(componentClass); - } - - protected void writeBootstrapConfigs(ComponentEntry... componentEntries) { - dirConfigSource.writeConfig("platform-bundles", ""); - dirConfigSource.writeConfig("application-bundles", ""); - StringBuilder components = new StringBuilder(); - for (int i = 0; i < componentEntries.length; i++) { - components.append(componentEntries[i].asConfig(i)); - components.append('\n'); - } - dirConfigSource.writeConfig("components", String.format("components[%s]\n%s", componentEntries.length, components)); - } - - protected void writeBootstrapConfigs(String componentId, Class<?> classId) { - writeBootstrapConfigs(new ComponentEntry(componentId, classId)); - } - - protected void writeBootstrapConfigs(String componentId) { - writeBootstrapConfigs(componentId, ComponentTakingConfig.class); - } - - protected void writeBootstrapConfigs() { - writeBootstrapConfigs(ComponentTakingConfig.class.getName(), ComponentTakingConfig.class); - } - - protected class ComponentEntry { - private final String componentId; - private final Class<?> classId; - - ComponentEntry(String componentId, Class<?> classId) { - this.componentId = componentId; - this.classId = classId; - } - - String asConfig(int position) { - return "<config>\n" + // - "components[" + position + "].id \"" + componentId + "\"\n" + // - "components[" + position + "].classId \"" + classId.getName() + "\"\n" + // - "components[" + position + "].configId \"" + dirConfigSource.configId() + "\"\n" + // - "</config>"; - } - } - -} diff --git a/container-di/src/test/java/com/yahoo/container/di/DirConfigSource.java b/container-di/src/test/java/com/yahoo/container/di/DirConfigSource.java deleted file mode 100644 index ec937a1a4ef..00000000000 --- a/container-di/src/test/java/com/yahoo/container/di/DirConfigSource.java +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.di; - -import com.yahoo.config.subscription.ConfigSource; -import com.yahoo.config.subscription.ConfigSourceSet; -import org.junit.rules.TemporaryFolder; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Random; - -/** - * @author Tony Vaagenes - * @author gjoranv - * @author ollivir - */ -public class DirConfigSource { - private final TemporaryFolder tempFolder = createTemporaryFolder(); - public final ConfigSource configSource; - - public DirConfigSource(String testSourcePrefix) { - this.configSource = new ConfigSourceSet(testSourcePrefix + new Random().nextLong()); - } - - public void writeConfig(String name, String contents) { - File file = new File(tempFolder.getRoot(), name + ".cfg"); - if (!file.exists()) { - try { - file.createNewFile(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - printFile(file, contents + "\n"); - } - - public String configId() { - return "dir:" + tempFolder.getRoot().getPath(); - } - - public ConfigSource configSource() { - return configSource; - } - - public void cleanup() { - tempFolder.delete(); - } - - private static void printFile(File f, String content) { - try (OutputStream out = new FileOutputStream(f)) { - out.write(content.getBytes("UTF-8")); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static TemporaryFolder createTemporaryFolder() { - TemporaryFolder folder = new TemporaryFolder(); - try { - folder.create(); - } catch (IOException e) { - throw new RuntimeException(e); - } - return folder; - } -} diff --git a/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/ComponentGraphTest.java b/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/ComponentGraphTest.java deleted file mode 100644 index 70dc4c8665c..00000000000 --- a/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/ComponentGraphTest.java +++ /dev/null @@ -1,750 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.di.componentgraph.core; - -import com.google.inject.AbstractModule; -import com.google.inject.Guice; -import com.google.inject.Inject; -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.name.Named; -import com.google.inject.name.Names; -import com.yahoo.collections.Pair; -import com.yahoo.component.AbstractComponent; -import com.yahoo.component.ComponentId; -import com.yahoo.component.provider.ComponentRegistry; -import com.yahoo.config.ConfigInstance; -import com.yahoo.config.subscription.ConfigGetter; -import com.yahoo.config.test.Test2Config; -import com.yahoo.config.test.TestConfig; -import com.yahoo.container.di.Osgi; -import com.yahoo.container.di.componentgraph.Provider; -import com.yahoo.container.di.config.JerseyBundlesConfig; -import com.yahoo.container.di.config.JerseyInjectionConfig; -import com.yahoo.container.di.config.RestApiContext; -import com.yahoo.vespa.config.ConfigKey; -import org.junit.Test; - -import java.lang.annotation.Annotation; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.function.Supplier; - -import static com.yahoo.container.di.componentgraph.core.ComponentGraph.isBindingAnnotation; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.CoreMatchers.sameInstance; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * @author gjoranv - * @author Tony Vaagenes - * @author ollivir - */ -public class ComponentGraphTest { - - public static class ConfigMap extends HashMap<ConfigKey<? extends ConfigInstance>, ConfigInstance> { - public ConfigMap() { - super(); - } - - public <T extends ConfigInstance> ConfigMap add(Class<T> clazz, String configId) { - ConfigKey<T> key = new ConfigKey<>(clazz, configId); - put(key, ConfigGetter.getConfig(key.getConfigClass(), key.getConfigId())); - return this; - } - - public static <T extends ConfigInstance> ConfigMap newMap(Class<T> clazz, String configId) { - ConfigMap ret = new ConfigMap(); - ret.add(clazz, configId); - return ret; - } - } - - @Test - public void component_taking_config_can_be_instantiated() { - ComponentGraph componentGraph = new ComponentGraph(); - String configId = "raw:stringVal \"test-value\""; - Node componentNode = mockComponentNode(ComponentTakingConfig.class, configId); - - componentGraph.add(componentNode); - componentGraph.complete(); - componentGraph.setAvailableConfigs(ConfigMap.newMap(TestConfig.class, configId)); - - ComponentTakingConfig instance = componentGraph.getInstance(ComponentTakingConfig.class); - assertNotNull(instance); - assertThat(instance.config.stringVal(), is("test-value")); - } - - @Test - public void all_created_components_are_returned_in_reverse_topological_order() { - for (int i = 0; i < 10; i++) { - Node innerComponent = mockComponentNode(SimpleComponent.class); - Node middleComponent = mockComponentNode(ComponentTakingComponent.class); - Node outerComponent = mockComponentNode(ComponentTakingComponentTakingComponent.class); - - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(innerComponent); - componentGraph.add(middleComponent); - componentGraph.add(outerComponent); - componentGraph.complete(); - - innerComponent.constructInstance(); - middleComponent.constructInstance(); - outerComponent.constructInstance(); - - assertEquals(List.of(outerComponent.constructedInstance().get(), middleComponent.constructedInstance().get(), innerComponent.constructedInstance().get()), - componentGraph.allConstructedComponentsAndProviders()); - } - } - - @Test - public void component_can_be_injected_into_another_component() { - Node injectedComponent = mockComponentNode(SimpleComponent.class); - Node targetComponent = mockComponentNode(ComponentTakingComponent.class); - targetComponent.inject(injectedComponent); - - Node destroyGlobalLookupComponent = mockComponentNode(SimpleComponent.class); - - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(injectedComponent); - componentGraph.add(targetComponent); - componentGraph.add(destroyGlobalLookupComponent); - componentGraph.complete(); - - ComponentTakingComponent instance = componentGraph.getInstance(ComponentTakingComponent.class); - assertNotNull(instance); - } - - @Test - public void interface_implementation_can_be_injected() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(ComponentImpl.class)); - componentGraph.add(mockComponentNode(ComponentTakingInterface.class)); - componentGraph.complete(); - - ComponentTakingInterface instance = componentGraph.getInstance(ComponentTakingInterface.class); - assertTrue(instance.injected instanceof ComponentImpl); - } - - @Test - public void private_class_with_public_ctor_can_be_instantiated() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(PrivateClassComponent.class)); - componentGraph.complete(); - - PrivateClassComponent instance = componentGraph.getInstance(PrivateClassComponent.class); - assertNotNull(instance); - } - - @Test - public void all_components_of_a_type_can_be_injected() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(SimpleComponent.class)); - componentGraph.add(mockComponentNode(SimpleComponent.class)); - componentGraph.add(mockComponentNode(SimpleDerivedComponent.class)); - componentGraph.add(mockComponentNode(ComponentTakingAllSimpleComponents.class)); - componentGraph.complete(); - - ComponentTakingAllSimpleComponents instance = componentGraph.getInstance(ComponentTakingAllSimpleComponents.class); - assertThat(instance.simpleComponents.allComponents().size(), is(3)); - } - - @Test - public void empty_component_registry_can_be_injected() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(ComponentTakingAllSimpleComponents.class)); - componentGraph.complete(); - - ComponentTakingAllSimpleComponents instance = componentGraph.getInstance(ComponentTakingAllSimpleComponents.class); - assertThat(instance.simpleComponents.allComponents().size(), is(0)); - } - - @Test - public void component_registry_with_wildcard_upper_bound_can_be_injected() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(SimpleComponent.class)); - componentGraph.add(mockComponentNode(SimpleDerivedComponent.class)); - componentGraph.add(mockComponentNode(ComponentTakingAllSimpleComponentsUpperBound.class)); - componentGraph.complete(); - - ComponentTakingAllSimpleComponentsUpperBound instance = componentGraph - .getInstance(ComponentTakingAllSimpleComponentsUpperBound.class); - assertThat(instance.simpleComponents.allComponents().size(), is(2)); - } - - @Test(expected = RuntimeException.class) - public void require_exception_when_injecting_registry_with_unknown_type_variable() { - @SuppressWarnings("rawtypes") - Class<ComponentTakingAllComponentsWithTypeVariable> clazz = ComponentTakingAllComponentsWithTypeVariable.class; - - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(SimpleComponent.class)); - componentGraph.add(mockComponentNode(SimpleDerivedComponent.class)); - componentGraph.add(mockComponentNode(clazz)); - componentGraph.complete(); - - componentGraph.getInstance(clazz); - } - - @Test - public void components_are_shared() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(SimpleComponent.class)); - componentGraph.complete(); - - SimpleComponent instance1 = componentGraph.getInstance(SimpleComponent.class); - SimpleComponent instance2 = componentGraph.getInstance(SimpleComponent.class); - assertThat(instance1, sameInstance(instance2)); - } - - @Test - public void singleton_components_can_be_injected() { - ComponentGraph componentGraph = new ComponentGraph(); - String configId = "raw:stringVal \"test-value\""; - - componentGraph.add(mockComponentNode(ComponentTakingComponent.class)); - componentGraph.add(mockComponentNode(ComponentTakingConfig.class, configId)); - componentGraph.add(mockComponentNode(SimpleComponent2.class)); - componentGraph.complete(); - componentGraph.setAvailableConfigs(ConfigMap.newMap(TestConfig.class, configId)); - - ComponentTakingComponent instance = componentGraph.getInstance(ComponentTakingComponent.class); - ComponentTakingConfig injected = (ComponentTakingConfig) instance.injectedComponent; - assertThat(injected.config.stringVal(), is("test-value")); - } - - @Test(expected = RuntimeException.class) - public void require_error_when_multiple_components_match_a_singleton_dependency() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(SimpleDerivedComponent.class)); - componentGraph.add(mockComponentNode(SimpleComponent.class)); - componentGraph.add(mockComponentNode(ComponentTakingComponent.class)); - componentGraph.complete(); - } - - @Test - public void named_component_can_be_injected() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(SimpleComponent.class)); - componentGraph.add(mockComponentNode(SimpleComponent.class, Names.named("named-test"))); - componentGraph.add(mockComponentNode(ComponentTakingNamedComponent.class)); - componentGraph.complete(); - } - - @Test - public void config_keys_can_be_retrieved() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(ComponentTakingConfig.class, "raw:stringVal \"component1\"")); - componentGraph.add(mockComponentNode(ComponentTakingConfig.class, "raw:stringVal \"component2\"")); - componentGraph.add(new ComponentRegistryNode(ComponentTakingConfig.class)); - componentGraph.complete(); - - Set<ConfigKey<? extends ConfigInstance>> configKeys = componentGraph.configKeys(); - assertThat(configKeys.size(), is(2)); - - configKeys.forEach(key -> { - assertThat(key.getConfigClass(), equalTo(TestConfig.class)); - assertThat(key.getConfigId(), containsString("component")); - }); - } - - @Test - public void providers_can_be_instantiated() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(ExecutorProvider.class)); - componentGraph.complete(); - - assertNotNull(componentGraph.getInstance(Executor.class)); - } - - @Test - public void providers_can_be_inherited() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(DerivedExecutorProvider.class)); - componentGraph.complete(); - - assertNotNull(componentGraph.getInstance(Executor.class)); - } - - @Test - public void providers_can_deliver_a_new_instance_for_each_component() { - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNode(NewIntProvider.class)); - componentGraph.complete(); - - Integer instance1 = componentGraph.getInstance(Integer.class); - Integer instance2 = componentGraph.getInstance(Integer.class); - assertEquals(1, instance1.intValue()); - assertEquals(2, instance2.intValue()); - } - - @Test - public void providers_can_be_injected_explicitly() { - ComponentGraph componentGraph = new ComponentGraph(); - - Node componentTakingExecutor = mockComponentNode(ComponentTakingExecutor.class); - Node executorProvider = mockComponentNode(ExecutorProvider.class); - componentTakingExecutor.inject(executorProvider); - - componentGraph.add(executorProvider); - componentGraph.add(mockComponentNode(ExecutorProvider.class)); - - componentGraph.add(componentTakingExecutor); - - componentGraph.complete(); - assertNotNull(componentGraph.getInstance(ComponentTakingExecutor.class)); - } - - @Test - public void global_providers_can_be_injected() { - ComponentGraph componentGraph = new ComponentGraph(); - - componentGraph.add(mockComponentNode(ComponentTakingExecutor.class)); - componentGraph.add(mockComponentNode(ExecutorProvider.class)); - componentGraph.add(mockComponentNode(FailOnGetIntProvider.class)); - componentGraph.complete(); - - assertNotNull(componentGraph.getInstance(ComponentTakingExecutor.class)); - } - - @Test(expected = RuntimeException.class) - public void throw_if_multiple_global_providers_exist() { - ComponentGraph componentGraph = new ComponentGraph(); - - componentGraph.add(mockComponentNode(ExecutorProvider.class)); - componentGraph.add(mockComponentNode(ExecutorProvider.class)); - componentGraph.add(mockComponentNode(ComponentTakingExecutor.class)); - componentGraph.complete(); - } - - @Test - public void provider_is_not_used_when_component_of_provided_class_exists() { - ComponentGraph componentGraph = new ComponentGraph(); - - componentGraph.add(mockComponentNode(SimpleComponent.class)); - componentGraph.add(mockComponentNode(SimpleComponentProviderThatThrows.class)); - componentGraph.add(mockComponentNode(ComponentTakingComponent.class)); - componentGraph.complete(); - - SimpleComponent injectedComponent = componentGraph.getInstance(ComponentTakingComponent.class).injectedComponent; - assertNotNull(injectedComponent); - } - - //TODO: move - @Test - public void check_if_annotation_is_a_binding_annotation() { - assertTrue(isBindingAnnotation(Names.named("name"))); - assertFalse(isBindingAnnotation(Named.class.getAnnotations()[0])); - } - - @Test - public void cycles_gives_exception() { - ComponentGraph componentGraph = new ComponentGraph(); - - Node node1 = mockComponentNode(ComponentCausingCycle.class); - Node node2 = mockComponentNode(ComponentCausingCycle.class); - - node1.inject(node2); - node2.inject(node1); - - componentGraph.add(node1); - componentGraph.add(node2); - - try { - componentGraph.complete(); - fail("Cycle exception expected."); - } catch (Throwable e) { - assertThat(e.getMessage(), containsString("cycle")); - assertThat(e.getMessage(), containsString("ComponentCausingCycle")); - } - } - - @Test(expected = IllegalArgumentException.class) - public void abstract_classes_are_rejected() { - new ComponentNode(ComponentId.fromString("Test"), "", AbstractClass.class); - } - - @Test - public void inject_constructor_is_preferred() { - assertThatComponentCanBeCreated(ComponentWithInjectConstructor.class); - } - - @Test - public void constructor_with_most_parameters_is_preferred() { - assertThatComponentCanBeCreated(ComponentWithMultipleConstructors.class); - } - - public void assertThatComponentCanBeCreated(Class<?> clazz) { - ComponentGraph componentGraph = new ComponentGraph(); - String configId = "raw:stringVal \"dummy\""; - - componentGraph.add(mockComponentNode(clazz, configId)); - componentGraph.complete(); - - componentGraph.setAvailableConfigs(ConfigMap.newMap(TestConfig.class, configId).add(Test2Config.class, configId)); - - assertNotNull(componentGraph.getInstance(clazz)); - } - - @Test - public void require_fallback_to_child_injector() { - ComponentGraph componentGraph = new ComponentGraph(); - - componentGraph.add(mockComponentNode(ComponentTakingExecutor.class)); - - componentGraph.complete(singletonExecutorInjector); - assertNotNull(componentGraph.getInstance(ComponentTakingExecutor.class)); - } - - @Test - public void child_injector_can_inject_multiple_instances_for_same_key() { - Pair<Integer, Pair<Executor, Executor>> graph = buildGraphWithChildInjector(Executors::newSingleThreadExecutor); - int graphSize = graph.getFirst(); - Executor executorA = graph.getSecond().getFirst(); - Executor executorB = graph.getSecond().getSecond(); - - assertThat(graphSize, is(4)); - assertThat(executorA, not(sameInstance(executorB))); - } - - @Test - public void components_injected_via_child_injector_can_be_shared() { - Executor commonExecutor = Executors.newSingleThreadExecutor(); - Pair<Integer, Pair<Executor, Executor>> graph = buildGraphWithChildInjector(() -> commonExecutor); - int graphSize = graph.getFirst(); - Executor executorA = graph.getSecond().getFirst(); - Executor executorB = graph.getSecond().getSecond(); - - assertThat(graphSize, is(3)); - assertThat(executorA, sameInstance(executorB)); - } - - private Pair<Integer, Pair<Executor, Executor>> buildGraphWithChildInjector(Supplier<Executor> executorProvider) { - Injector childInjector = Guice.createInjector(new AbstractModule() { - @Override - public void configure() { - bind(Executor.class).toProvider(executorProvider::get); - } - }); - - ComponentGraph componentGraph = new ComponentGraph(); - - Key<ComponentTakingExecutor> keyA = Key.get(ComponentTakingExecutor.class, Names.named("A")); - Key<ComponentTakingExecutor> keyB = Key.get(ComponentTakingExecutor.class, Names.named("B")); - - componentGraph.add(mockComponentNode(keyA)); - componentGraph.add(mockComponentNode(keyB)); - - componentGraph.complete(childInjector); - - return new Pair<>(componentGraph.size(), - new Pair<>(componentGraph.getInstance(keyA).executor, componentGraph.getInstance(keyB).executor)); - } - - @Test - public void providers_can_be_reused() { - - ComponentGraph oldGraph = createReusingGraph(); - Executor executor = oldGraph.getInstance(Executor.class); - - ComponentGraph newGraph = createReusingGraph(); - newGraph.reuseNodes(oldGraph); - - Executor newExecutor = newGraph.getInstance(Executor.class); - assertThat(executor, sameInstance(newExecutor)); - } - - private ComponentGraph createReusingGraph() { - ComponentGraph graph = new ComponentGraph(); - graph.add(mockComponentNodeWithId(ExecutorProvider.class, "dummyId")); - graph.complete(); - graph.setAvailableConfigs(Collections.emptyMap()); - return graph; - } - - @Test - public void component_id_can_be_injected() { - String componentId = "myId:1.2@namespace"; - - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(mockComponentNodeWithId(ComponentTakingComponentId.class, componentId)); - componentGraph.complete(); - - assertThat(componentGraph.getInstance(ComponentTakingComponentId.class).componentId, is(ComponentId.fromString(componentId))); - } - - @Test - public void rest_api_context_can_be_instantiated() { - String configId = "raw:\"\""; - - Class<RestApiContext> clazz = RestApiContext.class; - JerseyNode jerseyNode = new JerseyNode(uniqueComponentId(clazz.getName()), configId, clazz, new Osgi() { - }); - - ComponentGraph componentGraph = new ComponentGraph(); - componentGraph.add(jerseyNode); - componentGraph.complete(); - - componentGraph - .setAvailableConfigs(ConfigMap.newMap(JerseyBundlesConfig.class, configId).add(JerseyInjectionConfig.class, configId)); - - RestApiContext restApiContext = componentGraph.getInstance(clazz); - assertNotNull(restApiContext); - assertThat(restApiContext.getBundles().size(), is(0)); - } - - //Note that all Components must be defined in a static context, - //otherwise their constructor will take the outer class as the first parameter. - private static int counter = 0; - - private class PrivateClassComponent { - public PrivateClassComponent() { } - } - - public static class SimpleComponent extends AbstractComponent { - } - - public static class SimpleComponent2 extends AbstractComponent { - } - - public static class SimpleDerivedComponent extends SimpleComponent { - } - - public interface ComponentBase { } - public static class ComponentImpl implements ComponentBase { } - public static class ComponentTakingInterface { - ComponentBase injected; - public ComponentTakingInterface(ComponentBase componentBase) { - injected = componentBase; - } - } - - public static class ComponentTakingConfig extends SimpleComponent { - private final TestConfig config; - - public ComponentTakingConfig(TestConfig config) { - assertThat(config, notNullValue()); - this.config = config; - } - } - - public static class ComponentTakingComponent extends AbstractComponent { - private final SimpleComponent injectedComponent; - - public ComponentTakingComponent(SimpleComponent injectedComponent) { - assertThat(injectedComponent, notNullValue()); - this.injectedComponent = injectedComponent; - } - } - - public static class ComponentTakingComponentTakingComponent extends AbstractComponent { - private final ComponentTakingComponent injectedComponent; - - public ComponentTakingComponentTakingComponent(ComponentTakingComponent injectedComponent) { - assertThat(injectedComponent, notNullValue()); - this.injectedComponent = injectedComponent; - } - } - - @SuppressWarnings("unused") - public static class ComponentTakingConfigAndComponent extends AbstractComponent { - private final TestConfig config; - private final SimpleComponent simpleComponent; - - public ComponentTakingConfigAndComponent(TestConfig config, SimpleComponent injectedComponent) { - assertThat(config, notNullValue()); - assertThat(injectedComponent, notNullValue()); - this.config = config; - this.simpleComponent = injectedComponent; - } - } - - public static class ComponentTakingAllSimpleComponents extends AbstractComponent { - public final ComponentRegistry<SimpleComponent> simpleComponents; - - public ComponentTakingAllSimpleComponents(ComponentRegistry<SimpleComponent> simpleComponents) { - assertThat(simpleComponents, notNullValue()); - this.simpleComponents = simpleComponents; - } - } - - public static class ComponentTakingAllSimpleComponentsUpperBound extends AbstractComponent { - private final ComponentRegistry<? extends SimpleComponent> simpleComponents; - - public ComponentTakingAllSimpleComponentsUpperBound(ComponentRegistry<? extends SimpleComponent> simpleComponents) { - assertThat(simpleComponents, notNullValue()); - this.simpleComponents = simpleComponents; - } - } - - public static class ComponentTakingAllComponentsWithTypeVariable<COMPONENT extends AbstractComponent> extends AbstractComponent { - public ComponentTakingAllComponentsWithTypeVariable(ComponentRegistry<COMPONENT> simpleComponents) { - assertThat(simpleComponents, notNullValue()); - } - } - - public static class ComponentTakingNamedComponent extends AbstractComponent { - public ComponentTakingNamedComponent(@Named("named-test") SimpleComponent injectedComponent) { - assertThat(injectedComponent, notNullValue()); - } - } - - public static class ComponentCausingCycle extends AbstractComponent { - public ComponentCausingCycle(ComponentCausingCycle component) { - } - } - - public static class SimpleComponentProviderThatThrows implements Provider<SimpleComponent> { - public SimpleComponent get() { - throw new AssertionError("Should never be called."); - } - - public void deconstruct() { - } - } - - public static class ExecutorProvider implements Provider<Executor> { - private Executor executor = Executors.newSingleThreadExecutor(); - - public Executor get() { - return executor; - } - - public void deconstruct() { - /*TODO */ } - } - - public static class DerivedExecutorProvider extends ExecutorProvider { - } - - public static class FailOnGetIntProvider implements Provider<Integer> { - - public Integer get() { - fail("Should never be called."); - return null; - } - - public void deconstruct() { - } - - } - - public static class NewIntProvider implements Provider<Integer> { - int i = 0; - - public Integer get() { - return ++i; - } - - public void deconstruct() { - } - } - - public static class ComponentTakingExecutor extends AbstractComponent { - private final Executor executor; - - public ComponentTakingExecutor(Executor executor) { - assertThat(executor, notNullValue()); - this.executor = executor; - } - } - - public static class ComponentWithInjectConstructor { - - public ComponentWithInjectConstructor(TestConfig c, Test2Config c2) { - throw new RuntimeException("Should not be called"); - } - - @Inject - public ComponentWithInjectConstructor(Test2Config c) { - } - - } - - public static class ComponentWithMultipleConstructors { - - private ComponentWithMultipleConstructors(int dummy) { - } - - public ComponentWithMultipleConstructors() { - this(0); - throw new RuntimeException("Should not be called"); - } - - public ComponentWithMultipleConstructors(TestConfig c, Test2Config c2) { - this(0); - } - - public ComponentWithMultipleConstructors(Test2Config c) { - this(); - } - - } - - public static class ComponentTakingComponentId { - private final ComponentId componentId; - - public ComponentTakingComponentId(ComponentId componentId) { - this.componentId = componentId; - } - } - - public static ComponentId uniqueComponentId(String className) { - counter += 1; - return ComponentId.fromString(className + counter); - } - - public static Node mockComponentNode(Key<?> key) { - return mockComponentNode(key.getTypeLiteral().getRawType(), "", key.getAnnotation()); - } - - public static Node mockComponentNode(Class<?> clazz, String configId, Annotation key) { - return new ComponentNode(uniqueComponentId(clazz.getName()), configId, clazz, key); - } - - public static Node mockComponentNode(Class<?> clazz, String configId) { - return new ComponentNode(uniqueComponentId(clazz.getName()), configId, clazz, null); - } - - public static Node mockComponentNode(Class<?> clazz, Annotation key) { - return new ComponentNode(uniqueComponentId(clazz.getName()), "", clazz, key); - } - - public static Node mockComponentNode(Class<?> clazz) { - return new ComponentNode(uniqueComponentId(clazz.getName()), "", clazz, null); - } - - public static Node mockComponentNodeWithId(Class<?> clazz, String componentId, String configId /*= ""*/, Annotation key /*= null*/) { - return new ComponentNode(ComponentId.fromString(componentId), configId, clazz, key); - } - - public static Node mockComponentNodeWithId(Class<?> clazz, String componentId, String configId /*= ""*/) { - return new ComponentNode(ComponentId.fromString(componentId), configId, clazz, null); - } - - public static Node mockComponentNodeWithId(Class<?> clazz, String componentId) { - return new ComponentNode(ComponentId.fromString(componentId), "", clazz, null); - } - - public static Injector singletonExecutorInjector = Guice.createInjector(new AbstractModule() { - @Override - public void configure() { - bind(Executor.class).toInstance(Executors.newSingleThreadExecutor()); - } - }); - - public static abstract class AbstractClass { - } -} diff --git a/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/FallbackToGuiceInjectorTest.java b/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/FallbackToGuiceInjectorTest.java deleted file mode 100644 index 7c517d67960..00000000000 --- a/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/FallbackToGuiceInjectorTest.java +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.di.componentgraph.core; - -import com.google.inject.AbstractModule; -import com.google.inject.Guice; -import com.google.inject.Inject; -import com.google.inject.Injector; -import com.google.inject.name.Named; -import com.google.inject.name.Names; -import com.yahoo.component.AbstractComponent; -import com.yahoo.component.ComponentId; -import com.yahoo.config.ConfigInstance; -import com.yahoo.container.di.componentgraph.core.ComponentGraph; -import com.yahoo.container.di.componentgraph.core.ComponentNode; -import com.yahoo.container.di.componentgraph.core.Node; -import com.yahoo.vespa.config.ConfigKey; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertNotNull; - -/** - * @author Tony Vaagenes - * @author gjoranv - */ -@SuppressWarnings("unused") -public class FallbackToGuiceInjectorTest { - - private ComponentGraph componentGraph; - private Injector injector; - private Map<ConfigKey<? extends ConfigInstance>, ConfigInstance> configs = - new HashMap<>(); - - @Rule - public final ExpectedException exception = ExpectedException.none(); - - @Before - public void createGraph() { - injector = Guice.createInjector(); - componentGraph = new ComponentGraph(0); - } - - public static class MyComponent extends AbstractComponent { - private final String url; - private final Executor executor; - - @Inject - public MyComponent(@Named("url") String url, Executor executor) { - this.url = url; - this.executor = executor; - } - - public MyComponent() { - throw new RuntimeException("Constructor annotated with @Inject is preferred."); - } - } - - public static class ComponentTakingDefaultString{ - private final String injectedString; - - public ComponentTakingDefaultString(String empty_string_created_by_guice) { - this.injectedString = empty_string_created_by_guice; - } - } - - public static class ComponentThatCannotBeConstructed { - public ComponentThatCannotBeConstructed(Integer cannot_be_injected_because_Integer_has_no_default_ctor) { } - } - - @Test - public void guice_injector_is_used_when_no_global_component_exists() { - setInjector( - Guice.createInjector(new AbstractModule() { - @Override - protected void configure() { - bind(Executor.class).toInstance(Executors.newSingleThreadExecutor()); - bind(String.class).annotatedWith(Names.named("url")).toInstance("http://yahoo.com"); - } - })); - - register(MyComponent.class); - complete(); - - MyComponent component = getInstance(MyComponent.class); - assertThat(component.url, is("http://yahoo.com")); - assertNotNull(component.executor); - } - - @Test - public void guice_injector_creates_a_new_instance_with_default_ctor_when_no_explicit_binding_exists() { - setInjector(emptyGuiceInjector()); - register(ComponentTakingDefaultString.class); - complete(); - - ComponentTakingDefaultString component = getInstance(ComponentTakingDefaultString.class); - assertThat(component.injectedString, is("")); - } - - @Test - public void guice_injector_fails_when_no_explicit_binding_exists_and_class_has_no_default_ctor() { - setInjector(emptyGuiceInjector()); - register(ComponentThatCannotBeConstructed.class); - - exception.expect(RuntimeException.class); - exception.expectMessage("When resolving dependencies of 'com.yahoo.container.di.componentgraph.core.FallbackToGuiceInjectorTest$ComponentThatCannotBeConstructed'"); - complete(); - } - - public void register(Class<?> componentClass) { - componentGraph.add(mockComponentNode(componentClass)); - } - - public ComponentId toId(Class<?> componentClass) { - return ComponentId.fromString(componentClass.getName()); - } - - @SuppressWarnings("unchecked") - private Node mockComponentNode(Class<?> componentClass) { - return new ComponentNode(toId(componentClass), toId(componentClass).toString(), (Class<Object>)componentClass, null); - } - - public <T> T getInstance(Class<T> componentClass) { - return componentGraph.getInstance(componentClass); - } - - public void complete() { - componentGraph.complete(injector); - componentGraph.setAvailableConfigs(configs); - } - - public void setInjector(Injector injector) { - this.injector = injector; - } - - private Injector emptyGuiceInjector() { - return Guice.createInjector(new AbstractModule() { - @Override - protected void configure() { - } - }); - } -} diff --git a/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/JerseyNodeTest.java b/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/JerseyNodeTest.java deleted file mode 100644 index f30f9260830..00000000000 --- a/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/JerseyNodeTest.java +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.di.componentgraph.core; - -import com.yahoo.container.bundle.MockBundle; -import com.yahoo.container.di.config.RestApiContext; -import com.yahoo.container.di.osgi.OsgiUtil; -import org.junit.Test; -import org.osgi.framework.wiring.BundleWiring; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.junit.Assert.assertThat; - -/** - * @author gjoranv - * @author ollivir - */ - -public class JerseyNodeTest { - private MockBundle bundle; - private List<String> bundleClasses; - private final Map<String, String> resources; - - public JerseyNodeTest() { - resources = new HashMap<>(); - resources.put("com/foo", "com/foo/Foo.class"); - resources.put("com/bar", "com/bar/Bar.class"); - bundle = new MockBundle() { - @Override - public Collection<String> listResources(String path, String ignored, int options) { - if ((options & BundleWiring.LISTRESOURCES_RECURSE) != 0 && path.equals("/")) { - return resources.values(); - } else { - return Collections.singleton(resources.get(path)); - } - } - }; - bundleClasses = new ArrayList<>(resources.values()); - } - - @Test - public void all_bundle_entries_are_returned_when_no_packages_are_given() { - Collection<String> entries = OsgiUtil.getClassEntriesInBundleClassPath(bundle, Collections.emptySet()); - assertThat(entries, containsInAnyOrder(bundleClasses.toArray())); - } - - @Test - public void only_bundle_entries_from_the_given_packages_are_returned() { - Collection<String> entries = OsgiUtil.getClassEntriesInBundleClassPath(bundle, Collections.singleton("com.foo")); - assertThat(entries, contains(resources.get("com/foo"))); - } - - @Test - public void bundle_info_is_initialized() { - RestApiContext.BundleInfo bundleInfo = JerseyNode.createBundleInfo(bundle, Collections.emptyList()); - assertThat(bundleInfo.symbolicName, is(bundle.getSymbolicName())); - assertThat(bundleInfo.version, is(bundle.getVersion())); - assertThat(bundleInfo.fileLocation, is(bundle.getLocation())); - } -} diff --git a/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/ReuseComponentsTest.java b/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/ReuseComponentsTest.java deleted file mode 100644 index e61e90cd718..00000000000 --- a/container-di/src/test/java/com/yahoo/container/di/componentgraph/core/ReuseComponentsTest.java +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.di.componentgraph.core; - -import com.yahoo.component.ComponentId; -import com.yahoo.component.provider.ComponentRegistry; -import com.yahoo.config.subscription.ConfigGetter; -import com.yahoo.config.test.TestConfig; -import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.ComponentTakingAllSimpleComponents; -import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.ComponentTakingComponent; -import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.ComponentTakingConfig; -import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.ComponentTakingConfigAndComponent; -import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.ComponentTakingExecutor; -import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.ExecutorProvider; -import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.SimpleComponent; -import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.SimpleComponent2; -import com.yahoo.vespa.config.ConfigKey; -import org.junit.Test; - -import java.util.Collections; -import java.util.concurrent.Executor; -import java.util.function.Function; -import java.util.function.Supplier; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.sameInstance; -import static org.junit.Assert.assertThat; - -/** - * @author gjoranv - * @author Tony Vaagenes - * @author ollivir - */ -public class ReuseComponentsTest { - @Test - public void require_that_component_is_reused_when_componentNode_is_unmodified() { - reuseAndTest(SimpleComponent.class, SimpleComponent.class); - reuseAndTest(ExecutorProvider.class, Executor.class); - } - - private <T> void reuseAndTest(Class<?> classToRegister, Class<T> classToLookup) { - ComponentGraph graph = buildGraphAndSetNoConfigs(classToRegister); - T instance = getComponent(graph, classToLookup); - - ComponentGraph newGraph = buildGraphAndSetNoConfigs(classToRegister); - newGraph.reuseNodes(graph); - T instance2 = getComponent(newGraph, classToLookup); - - assertThat(instance2, sameInstance(instance)); - } - - @Test(expected = IllegalStateException.class) - public void require_that_component_is_not_reused_when_class_is_changed() { - ComponentGraph graph = buildGraphAndSetNoConfigs(SimpleComponent.class); - SimpleComponent instance = getComponent(graph, SimpleComponent.class); - - ComponentGraph newGraph = buildGraphAndSetNoConfigs(SimpleComponent2.class); - newGraph.reuseNodes(graph); - SimpleComponent2 instance2 = getComponent(newGraph, SimpleComponent2.class); - - assertThat(instance2.getId(), is(instance.getId())); - @SuppressWarnings("unused") - SimpleComponent throwsException = getComponent(newGraph, SimpleComponent.class); - } - - @Test - public void require_that_component_is_not_reused_when_config_is_changed() { - Class<ComponentTakingConfig> componentClass = ComponentTakingConfig.class; - - ComponentGraph graph = buildGraph(componentClass); - graph.setAvailableConfigs(Collections.singletonMap(new ConfigKey<>(TestConfig.class, "component"), - ConfigGetter.getConfig(TestConfig.class, "raw: stringVal \"oldConfig\""))); - ComponentTakingConfig instance = getComponent(graph, componentClass); - - ComponentGraph newGraph = buildGraph(componentClass); - newGraph.setAvailableConfigs(Collections.singletonMap(new ConfigKey<>(TestConfig.class, "component"), - ConfigGetter.getConfig(TestConfig.class, "raw: stringVal \"newConfig\""))); - newGraph.reuseNodes(graph); - ComponentTakingConfig instance2 = getComponent(newGraph, componentClass); - - assertThat(instance2, not(sameInstance(instance))); - } - - @Test - public void require_that_component_is_not_reused_when_injected_component_is_changed() { - Function<String, ComponentGraph> buildGraph = config -> { - ComponentGraph graph = new ComponentGraph(); - - ComponentNode rootComponent = mockComponentNode(ComponentTakingComponent.class, "root_component"); - - String configId = "componentTakingConfigId"; - ComponentNode injectedComponent = mockComponentNode(ComponentTakingConfig.class, "injected_component", configId); - - rootComponent.inject(injectedComponent); - - graph.add(rootComponent); - graph.add(injectedComponent); - - graph.complete(); - graph.setAvailableConfigs(Collections.singletonMap(new ConfigKey<>(TestConfig.class, configId), - ConfigGetter.getConfig(TestConfig.class, "raw: stringVal \"" + config + "\""))); - - return graph; - }; - - ComponentGraph oldGraph = buildGraph.apply("oldGraph"); - ComponentTakingComponent oldInstance = getComponent(oldGraph, ComponentTakingComponent.class); - - ComponentGraph newGraph = buildGraph.apply("newGraph"); - newGraph.reuseNodes(oldGraph); - ComponentTakingComponent newInstance = getComponent(newGraph, ComponentTakingComponent.class); - - assertThat(newInstance, not(sameInstance(oldInstance))); - } - - @Test - public void require_that_component_is_not_reused_when_injected_component_registry_has_one_component_removed() { - Function<Boolean, ComponentGraph> buildGraph = useBothInjectedComponents -> { - ComponentGraph graph = new ComponentGraph(); - graph.add(mockComponentNode(ComponentTakingAllSimpleComponents.class, "root_component")); - - /* Below if-else has code duplication, but explicit ordering of the two components - * was necessary to reproduce erroneous behaviour in ComponentGraph.reuseNodes that - * occurred before ComponentRegistryNode got its own 'equals' implementation. - */ - if (useBothInjectedComponents) { - graph.add(mockComponentNode(SimpleComponent.class, "injected_component2")); - graph.add(mockComponentNode(SimpleComponent.class, "injected_component1")); - } else { - graph.add(mockComponentNode(SimpleComponent.class, "injected_component1")); - } - - graph.complete(); - graph.setAvailableConfigs(Collections.emptyMap()); - return graph; - }; - - ComponentGraph oldGraph = buildGraph.apply(true); - ComponentRegistry<SimpleComponent> oldSimpleComponentRegistry = getComponent(oldGraph, ComponentTakingAllSimpleComponents.class).simpleComponents; - - ComponentGraph newGraph = buildGraph.apply(false); - newGraph.reuseNodes(oldGraph); - ComponentRegistry<SimpleComponent> newSimpleComponentRegistry = getComponent(newGraph, ComponentTakingAllSimpleComponents.class).simpleComponents; - - assertThat(newSimpleComponentRegistry, not(sameInstance(oldSimpleComponentRegistry))); - } - - @Test - public void require_that_injected_component_is_reused_even_when_dependent_component_is_changed() { - Function<String, ComponentGraph> buildGraph = config -> { - ComponentGraph graph = new ComponentGraph(); - - String configId = "componentTakingConfigAndComponent"; - ComponentNode rootComponent = mockComponentNode(ComponentTakingConfigAndComponent.class, "root_component", configId); - - ComponentNode injectedComponent = mockComponentNode(SimpleComponent.class, "injected_component"); - - rootComponent.inject(injectedComponent); - - graph.add(rootComponent); - graph.add(injectedComponent); - - graph.complete(); - graph.setAvailableConfigs(Collections.singletonMap(new ConfigKey<>(TestConfig.class, configId), - ConfigGetter.getConfig(TestConfig.class, "raw: stringVal \"" + config + "\""))); - - return graph; - }; - - ComponentGraph oldGraph = buildGraph.apply("oldGraph"); - SimpleComponent oldInjectedComponent = getComponent(oldGraph, SimpleComponent.class); - ComponentTakingConfigAndComponent oldDependentComponent = getComponent(oldGraph, ComponentTakingConfigAndComponent.class); - - ComponentGraph newGraph = buildGraph.apply("newGraph"); - newGraph.reuseNodes(oldGraph); - SimpleComponent newInjectedComponent = getComponent(newGraph, SimpleComponent.class); - ComponentTakingConfigAndComponent newDependentComponent = getComponent(newGraph, ComponentTakingConfigAndComponent.class); - - assertThat(newDependentComponent, not(sameInstance(oldDependentComponent))); - assertThat(newInjectedComponent, sameInstance(oldInjectedComponent)); - } - - @Test - public void require_that_node_depending_on_guice_node_is_reused() { - Supplier<ComponentGraph> makeGraph = () -> { - ComponentGraph graph = new ComponentGraph(); - graph.add(mockComponentNode(ComponentTakingExecutor.class, "dummyId")); - graph.complete(ComponentGraphTest.singletonExecutorInjector); - graph.setAvailableConfigs(Collections.emptyMap()); - return graph; - }; - - Function<ComponentGraph, ComponentTakingExecutor> componentRetriever = graph -> getComponent(graph, ComponentTakingExecutor.class); - - ComponentGraph oldGraph = makeGraph.get(); - componentRetriever.apply(oldGraph); // Ensure creation of GuiceNode - ComponentGraph newGraph = makeGraph.get(); - newGraph.reuseNodes(oldGraph); - assertThat(componentRetriever.apply(oldGraph), sameInstance(componentRetriever.apply(newGraph))); - } - - @Test - public void require_that_node_equals_only_checks_first_level_components_to_inject() { - Function<String, Node> createNodeWithInjectedNodeWithInjectedNode = indirectlyInjectedComponentId -> { - ComponentNode targetComponent = mockComponentNode(SimpleComponent.class, "target"); - ComponentNode directlyInjectedComponent = mockComponentNode(SimpleComponent.class, "directlyInjected"); - ComponentNode indirectlyInjectedComponent = mockComponentNode(SimpleComponent.class, indirectlyInjectedComponentId); - directlyInjectedComponent.inject(indirectlyInjectedComponent); - targetComponent.inject(directlyInjectedComponent); - - completeNode(targetComponent); - completeNode(directlyInjectedComponent); - completeNode(indirectlyInjectedComponent); - - return targetComponent; - }; - - Node targetNode1 = createNodeWithInjectedNodeWithInjectedNode.apply("indirectlyInjected_1"); - Node targetNode2 = createNodeWithInjectedNodeWithInjectedNode.apply("indirectlyInjected_2"); - assertThat(targetNode1, equalTo(targetNode2)); - } - - private void completeNode(ComponentNode node) { - node.setArguments(new Object[0]); - node.setAvailableConfigs(Collections.emptyMap()); - } - - private ComponentGraph buildGraph(Class<?> componentClass) { - String commonComponentId = "component"; - ComponentGraph g = new ComponentGraph(); - g.add(mockComponentNode(componentClass, commonComponentId, commonComponentId)); - g.complete(); - return g; - } - - private ComponentGraph buildGraphAndSetNoConfigs(Class<?> componentClass) { - ComponentGraph g = buildGraph(componentClass); - g.setAvailableConfigs(Collections.emptyMap()); - return g; - } - - private static ComponentNode mockComponentNode(Class<?> clazz, String componentId, String configId) { - return new ComponentNode(new ComponentId(componentId), configId, clazz); - } - - private static ComponentNode mockComponentNode(Class<?> clazz, String componentId) { - return mockComponentNode(clazz, componentId, ""); - } - - private static <T> T getComponent(ComponentGraph graph, Class<T> clazz) { - return graph.getInstance(clazz); - } -} diff --git a/container-di/src/test/java/com/yahoo/container/di/componentgraph/cycle/CycleFinderTest.java b/container-di/src/test/java/com/yahoo/container/di/componentgraph/cycle/CycleFinderTest.java deleted file mode 100644 index 174ca301c59..00000000000 --- a/container-di/src/test/java/com/yahoo/container/di/componentgraph/cycle/CycleFinderTest.java +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -package com.yahoo.container.di.componentgraph.cycle; - -import org.junit.Test; - -import static com.yahoo.container.di.componentgraph.cycle.CycleFinderTest.Vertices.A; -import static com.yahoo.container.di.componentgraph.cycle.CycleFinderTest.Vertices.B; -import static com.yahoo.container.di.componentgraph.cycle.CycleFinderTest.Vertices.C; -import static com.yahoo.container.di.componentgraph.cycle.CycleFinderTest.Vertices.D; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.empty; -import static org.junit.Assert.assertThat; - -/** - * @author gjoranv - */ -public class CycleFinderTest { - - enum Vertices {A, B, C, D} - - @Test - public void graph_without_cycles_returns_no_cycle() { - var graph = new Graph<Vertices>(); - graph.edge(A, B); - graph.edge(B, C); - graph.edge(A, C); - graph.edge(D, A); - - var cycleFinder = new CycleFinder<>(graph); - assertThat(cycleFinder.findCycle(), empty()); - } - - @Test - public void graph_with_cycle_returns_cycle() { - var graph = new Graph<Vertices>(); - graph.edge(A, B); - graph.edge(B, C); - graph.edge(C, A); - - var cycleFinder = new CycleFinder<>(graph); - assertThat(cycleFinder.findCycle(), contains(A, B, C, A)); - } - - @Test - public void graph_with_self_referencing_vertex_returns_cycle() { - var graph = new Graph<Vertices>(); - graph.edge(A, A); - - var cycleFinder = new CycleFinder<>(graph); - assertThat(cycleFinder.findCycle(), contains(A, A)); - } - - @Test - public void leading_nodes_are_stripped_from_cycle() { - var graph = new Graph<Vertices>(); - graph.edge(A, B); - graph.edge(B, C); - graph.edge(C, B); - - var cycleFinder = new CycleFinder<>(graph); - assertThat(cycleFinder.findCycle(), contains(B, C, B)); - } - - @Test - public void findCycle_is_idempotent_with_cycle() { - var graph = new Graph<Vertices>(); - graph.edge(A, A); - - var cycleFinder = new CycleFinder<>(graph); - assertThat(cycleFinder.findCycle(), contains(A, A)); - assertThat(cycleFinder.findCycle(), contains(A, A)); - } - - @Test - public void findCycle_is_idempotent_without_cycle() { - var graph = new Graph<Vertices>(); - graph.edge(A, B); - - var cycleFinder = new CycleFinder<>(graph); - assertThat(cycleFinder.findCycle(), empty()); - assertThat(cycleFinder.findCycle(), empty()); - } - -} diff --git a/container-di/src/test/java/com/yahoo/container/di/componentgraph/cycle/GraphTest.java b/container-di/src/test/java/com/yahoo/container/di/componentgraph/cycle/GraphTest.java deleted file mode 100644 index 069f72ad8e7..00000000000 --- a/container-di/src/test/java/com/yahoo/container/di/componentgraph/cycle/GraphTest.java +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -package com.yahoo.container.di.componentgraph.cycle; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static com.yahoo.container.di.componentgraph.cycle.GraphTest.Vertices.A; -import static com.yahoo.container.di.componentgraph.cycle.GraphTest.Vertices.B; -import static com.yahoo.container.di.componentgraph.cycle.GraphTest.Vertices.C; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.empty; -import static org.junit.Assert.assertThat; - -/** - * @author gjoranv - */ -public class GraphTest { - - enum Vertices {A, B, C} - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void vertices_and_edges_are_added_and_can_be_retrieved() { - var graph = new Graph<Vertices>(); - graph.edge(A, B); - graph.edge(B, C); - graph.edge(A, C); - - assertThat(graph.getVertices().size(), is(3)); - assertThat(graph.getAdjacent(A), containsInAnyOrder(B, C)); - assertThat(graph.getAdjacent(B), containsInAnyOrder(C)); - assertThat(graph.getAdjacent(C), empty()); - } - - @Test - public void null_vertices_are_not_allowed() { - var graph = new Graph<Vertices>(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Null vertices are not allowed"); - graph.edge(A, null); - } - - @Test - public void duplicate_edges_are_ignored() { - var graph = new Graph<Vertices>(); - graph.edge(A, B); - graph.edge(A, B); - - assertThat(graph.getAdjacent(A).size(), is(1)); - } - - @Test - public void self_edges_are_allowed() { - var graph = new Graph<Vertices>(); - graph.edge(A, A); - - assertThat(graph.getAdjacent(A), contains(A)); - } - -} |