summaryrefslogtreecommitdiffstats
path: root/container-di/src/test/scala/com/yahoo/container/di
diff options
context:
space:
mode:
Diffstat (limited to 'container-di/src/test/scala/com/yahoo/container/di')
-rw-r--r--container-di/src/test/scala/com/yahoo/container/di/ConfigRetrieverTest.scala107
-rw-r--r--container-di/src/test/scala/com/yahoo/container/di/ContainerTest.scala398
-rw-r--r--container-di/src/test/scala/com/yahoo/container/di/DirConfigSource.scala50
-rw-r--r--container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/ComponentGraphTest.scala540
-rw-r--r--container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/JerseyNodeTest.scala66
-rw-r--r--container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/ReuseComponentsTest.scala249
6 files changed, 0 insertions, 1410 deletions
diff --git a/container-di/src/test/scala/com/yahoo/container/di/ConfigRetrieverTest.scala b/container-di/src/test/scala/com/yahoo/container/di/ConfigRetrieverTest.scala
deleted file mode 100644
index 7f1d9a73a82..00000000000
--- a/container-di/src/test/scala/com/yahoo/container/di/ConfigRetrieverTest.scala
+++ /dev/null
@@ -1,107 +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
-
-import com.yahoo.config.test.{Bootstrap1Config, Bootstrap2Config, TestConfig}
-import com.yahoo.container.di.ConfigRetriever.{BootstrapConfigs, ComponentsConfigs}
-import com.yahoo.vespa.config.ConfigKey
-import org.hamcrest.CoreMatchers.{is, instanceOf => hamcrestInstanceOf}
-import org.hamcrest.Matcher
-import org.junit.Assert._
-import org.junit.{After, Before, Ignore, Test}
-
-import scala.reflect.ClassTag
-import scala.collection.JavaConverters._
-
-/**
- *
- * @author gjoranv
- * @author tonytv
- */
-class ConfigRetrieverTest {
-
- var dirConfigSource: DirConfigSource = null
-
- @Before def setup() {
- dirConfigSource = new DirConfigSource("ConfigRetrieverTest-")
- }
-
- @After def cleanup() { dirConfigSource.cleanup() }
-
- @Test
- def require_that_bootstrap_configs_come_first() {
- writeConfigs()
- val retriever = createConfigRetriever()
- val bootstrapConfigs = retriever.getConfigs(Set(), 0)
-
- assertThat(bootstrapConfigs, instanceOf[BootstrapConfigs])
- }
-
- @Test
- def require_that_components_comes_after_bootstrap() {
- writeConfigs()
- val retriever = createConfigRetriever()
- val bootstrapConfigs = retriever.getConfigs(Set(), 0)
-
- val testConfigKey = new ConfigKey(classOf[TestConfig], dirConfigSource.configId)
- val componentsConfigs = retriever.getConfigs(Set(testConfigKey), 0)
-
- componentsConfigs match {
- case ComponentsConfigs(configs) => assertThat(configs.size, is(3))
- case _ => fail("ComponentsConfigs has unexpected type: " + componentsConfigs)
- }
- }
-
- @Test
- def require_no_reconfig_when_restart_on_redeploy() {
- // TODO
- writeConfigs()
- val retriever = createConfigRetriever()
- val bootstrapConfigs = retriever.getConfigs(Set(), 0)
-
- val testConfigKey = new ConfigKey(classOf[TestConfig], dirConfigSource.configId)
- val componentsConfigs = retriever.getConfigsOnce(Set(testConfigKey), 0, true)
-
- componentsConfigs match {
- case Some(snapshot) => fail("Expected no configs")
- case _ => // ok
- }
- }
-
- @Test(expected = classOf[IllegalArgumentException])
- @Ignore
- def require_exception_upon_modified_components_keys_without_bootstrap() {
- writeConfigs()
- val retriever = createConfigRetriever()
- val testConfigKey = new ConfigKey(classOf[TestConfig], dirConfigSource.configId)
- val bootstrapConfigs = retriever.getConfigs(Set(), 0)
- val componentsConfigs = retriever.getConfigs(Set(testConfigKey), 0)
- retriever.getConfigs(Set(testConfigKey, new ConfigKey(classOf[TestConfig],"")), 0)
- }
-
- @Test
- def require_that_empty_components_keys_after_bootstrap_returns_components_configs() {
- writeConfigs()
- val retriever = createConfigRetriever()
- assertThat(retriever.getConfigs(Set(), 0), instanceOf[BootstrapConfigs])
- assertThat(retriever.getConfigs(Set(), 0), instanceOf[ComponentsConfigs])
- }
-
- def writeConfigs() {
- writeConfig("bootstrap1", """dummy "ignored" """")
- writeConfig("bootstrap2", """dummy "ignored" """")
- writeConfig("test", """stringVal "ignored" """")
- }
-
- def createConfigRetriever() = {
- val configId = dirConfigSource.configId
- val subscriber = new CloudSubscriberFactory(dirConfigSource.configSource)
- new ConfigRetriever(
- Set(new ConfigKey(classOf[Bootstrap1Config], configId),
- new ConfigKey(classOf[Bootstrap2Config], configId)),
- (keys) => subscriber.getSubscriber(keys.asJava))
- }
-
- def writeConfig = dirConfigSource.writeConfig _
-
- def instanceOf[T: ClassTag] = hamcrestInstanceOf(implicitly[ClassTag[T]].runtimeClass): Matcher[AnyRef]
-}
diff --git a/container-di/src/test/scala/com/yahoo/container/di/ContainerTest.scala b/container-di/src/test/scala/com/yahoo/container/di/ContainerTest.scala
deleted file mode 100644
index 9f07acc7dc9..00000000000
--- a/container-di/src/test/scala/com/yahoo/container/di/ContainerTest.scala
+++ /dev/null
@@ -1,398 +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
-
-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.ContainerTest._
-import com.yahoo.container.di.componentgraph.Provider
-import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.{SimpleComponent, SimpleComponent2}
-import com.yahoo.container.di.componentgraph.core.ComponentNode.ComponentConstructorException
-import com.yahoo.container.di.componentgraph.core.{ComponentGraph, Node}
-import com.yahoo.container.di.config.RestApiContext
-import org.hamcrest.CoreMatchers._
-import org.junit.Assert._
-import org.junit.{After, Before, Ignore, Test}
-
-import scala.collection.JavaConverters._
-import scala.concurrent.ExecutionContext.Implicits.global
-import scala.concurrent.duration._
-import scala.concurrent.{Await, Future}
-import scala.language.{existentials, postfixOps}
-import scala.util.Try
-
-/**
- * @author tonytv
- * @author gjoranv
- */
-class ContainerTest {
- var dirConfigSource: DirConfigSource = _
-
- @Before def setup() {
- dirConfigSource = new DirConfigSource("ContainerTest-")
- }
-
- @After def cleanup() {
- dirConfigSource.cleanup()
- }
-
- @Test
- def components_can_be_created_from_config() {
- writeBootstrapConfigs()
- dirConfigSource.writeConfig("test", """stringVal "myString" """)
-
- val container = newContainer(dirConfigSource)
-
- val component = createComponentTakingConfig(container.getNewComponentGraph())
- assertThat(component.config.stringVal(), is("myString"))
-
- container.shutdownConfigurer()
- }
-
- @Test
- def components_are_reconfigured_after_config_update_without_bootstrap_configs() {
- writeBootstrapConfigs()
- dirConfigSource.writeConfig("test", """stringVal "original" """)
-
- val container = newContainer(dirConfigSource)
-
- val componentGraph = container.getNewComponentGraph()
- val component = createComponentTakingConfig(componentGraph)
-
- assertThat(component.config.stringVal(), is("original"))
-
- // Reconfigure
- dirConfigSource.writeConfig("test", """stringVal "reconfigured" """)
- container.reloadConfig(2)
-
- val newComponentGraph = container.getNewComponentGraph(componentGraph)
- val component2 = createComponentTakingConfig(newComponentGraph)
- assertThat(component2.config.stringVal(), is("reconfigured"))
-
- container.shutdownConfigurer()
- }
-
- @Test
- def graph_is_updated_after_bootstrap_update() {
- dirConfigSource.writeConfig("test", """stringVal "original" """)
- writeBootstrapConfigs("id1")
-
- val container = newContainer(dirConfigSource)
-
- val graph = container.getNewComponentGraph()
- val component = createComponentTakingConfig(graph)
- assertThat(component.getId.toString, is("id1"))
-
- writeBootstrapConfigsWithMultipleComponents(Array(
- ("id1", classOf[ComponentTakingConfig]),
- ("id2", classOf[ComponentTakingConfig])))
-
- container.reloadConfig(2)
- val newGraph = container.getNewComponentGraph(graph)
-
- assertThat(ComponentGraph.getNode(newGraph, "id1"), notNullValue(classOf[Node]))
- assertThat(ComponentGraph.getNode(newGraph, "id2"), notNullValue(classOf[Node]))
-
- container.shutdownConfigurer()
- }
-
- //@Test TODO
- def deconstructor_is_given_guice_components() {
- }
-
- @Test
- def osgi_component_is_deconstructed_when_not_reused() {
- writeBootstrapConfigs("id1", classOf[DestructableComponent])
-
- val container = newContainer(dirConfigSource)
-
- val oldGraph = container.getNewComponentGraph()
- val componentToDestruct = oldGraph.getInstance(classOf[DestructableComponent])
-
- writeBootstrapConfigs("id2", classOf[DestructableComponent])
- container.reloadConfig(2)
- container.getNewComponentGraph(oldGraph)
- assertTrue(componentToDestruct.deconstructed)
- }
-
- @Ignore // because logAndDie is impossible(?) to verify programmatically
- @Test
- def manually_verify_what_happens_when_first_graph_contains_component_that_throws_exception_in_ctor() {
- writeBootstrapConfigs("thrower", classOf[ComponentThrowingExceptionInConstructor])
- val container = newContainer(dirConfigSource)
- var currentGraph: ComponentGraph = null
- try {
- currentGraph = container.getNewComponentGraph()
- fail("Expected to log and die.")
- } catch {
- case _: Throwable => fail("Expected to log and die")
- }
- }
-
- @Test
- def previous_graph_is_retained_when_new_graph_contains_component_that_throws_exception_in_ctor() {
- val simpleComponentEntry = ComponentEntry("simpleComponent", classOf[SimpleComponent])
-
- writeBootstrapConfigs(Array(simpleComponentEntry))
- val container = newContainer(dirConfigSource)
- var currentGraph = container.getNewComponentGraph()
-
- val simpleComponent = currentGraph.getInstance(classOf[SimpleComponent])
-
- writeBootstrapConfigs("thrower", classOf[ComponentThrowingExceptionInConstructor])
- container.reloadConfig(2)
- try {
- currentGraph = container.getNewComponentGraph(currentGraph)
- fail("Expected exception")
- } catch {
- case _: ComponentConstructorException => // Expected, do nothing
- case _: Throwable => fail("Expected ComponentConstructorException")
- }
- assertEquals(1, currentGraph.generation)
-
- // Also verify that next reconfig is successful
- val componentTakingConfigEntry = ComponentEntry("componentTakingConfig", classOf[ComponentTakingConfig])
- dirConfigSource.writeConfig("test", """stringVal "myString" """)
- writeBootstrapConfigs(Array(simpleComponentEntry, componentTakingConfigEntry))
- container.reloadConfig(3)
- currentGraph = container.getNewComponentGraph(currentGraph)
-
- assertEquals(3, currentGraph.generation)
- assertSame(simpleComponent, currentGraph.getInstance(classOf[SimpleComponent]))
- assertNotNull(currentGraph.getInstance(classOf[ComponentTakingConfig]))
- }
-
- @Test
- def previous_graph_is_retained_when_new_graph_throws_exception_for_missing_config() {
- val simpleComponentEntry = ComponentEntry("simpleComponent", classOf[SimpleComponent])
-
- writeBootstrapConfigs(Array(simpleComponentEntry))
- val container = newContainer(dirConfigSource)
- var currentGraph = container.getNewComponentGraph()
-
- val simpleComponent = currentGraph.getInstance(classOf[SimpleComponent])
-
- writeBootstrapConfigs("thrower", classOf[ComponentThrowingExceptionForMissingConfig])
- dirConfigSource.writeConfig("test", """stringVal "myString" """)
- container.reloadConfig(2)
- try {
- currentGraph = container.getNewComponentGraph(currentGraph)
- fail("Expected exception")
- } catch {
- case _: IllegalArgumentException => // Expected, do nothing
- case _: Throwable => fail("Expected IllegalArgumentException")
- }
- assertEquals(1, currentGraph.generation)
- }
-
- @Test
- def runOnce_hangs_waiting_for_valid_config_after_invalid_config() {
- dirConfigSource.writeConfig("test", """stringVal "original" """)
- writeBootstrapConfigs("myId", classOf[ComponentTakingConfig])
-
- val container = newContainer(dirConfigSource)
- var currentGraph = container.getNewComponentGraph()
-
- writeBootstrapConfigs("thrower", classOf[ComponentThrowingExceptionForMissingConfig])
- container.reloadConfig(2)
-
- try {
- currentGraph = container.getNewComponentGraph(currentGraph)
- fail("expected exception")
- } catch {
- case e: Exception =>
- }
-
- val newGraph = Future {
- currentGraph = container.getNewComponentGraph(currentGraph)
- currentGraph
- }
-
- Try {
- Await.ready(newGraph, 1 second)
- } foreach { x => fail("Expected waiting for new config.") }
-
-
- writeBootstrapConfigs("myId2", classOf[ComponentTakingConfig])
- container.reloadConfig(3)
-
- assertNotNull(Await.result(newGraph, 5 minutes))
- }
-
-
- @Test
- def bundle_info_is_set_on_rest_api_context() {
- val clazz = classOf[RestApiContext]
-
- writeBootstrapConfigs("restApiContext", clazz)
- dirConfigSource.writeConfig("jersey-bundles", """bundles[0].spec "mock-entry-to-enforce-a-MockBundle" """)
- dirConfigSource.writeConfig("jersey-injection", """inject[0]" """)
-
- val container = newContainer(dirConfigSource)
- val componentGraph = container.getNewComponentGraph()
-
- val restApiContext = componentGraph.getInstance(clazz)
- assertNotNull(restApiContext)
-
- assertThat(restApiContext.getBundles.size, is(1))
- assertThat(restApiContext.getBundles.get(0).symbolicName, is(MockBundle.SymbolicName))
- assertThat(restApiContext.getBundles.get(0).version, is(MockBundle.BundleVersion))
-
- container.shutdownConfigurer()
- }
-
- @Test
- def restApiContext_has_all_components_injected() {
- new JerseyInjectionTest {
- assertFalse(restApiContext.getInjectableComponents.isEmpty)
- assertThat(restApiContext.getInjectableComponents.size(), is(2))
-
- container.shutdownConfigurer()
- }
- }
-
- // TODO: reuse injectedComponent as a named component when we support that
- trait JerseyInjectionTest {
- val restApiClass = classOf[RestApiContext]
- val injectedClass = classOf[SimpleComponent]
- val injectedComponentId = "injectedComponent"
- val anotherComponentClass = classOf[SimpleComponent2]
- val anotherComponentId = "anotherComponent"
-
- val componentsConfig: String =
- ComponentEntry(injectedComponentId, injectedClass).asConfig(0) + "\n" +
- ComponentEntry(anotherComponentId, anotherComponentClass).asConfig(1) + "\n" +
- ComponentEntry("restApiContext", restApiClass).asConfig(2) + "\n" +
- s"components[2].inject[0].id $injectedComponentId\n" +
- s"components[2].inject[1].id $anotherComponentId\n"
-
- val injectionConfig = s"""inject[1]
- |inject[0].instance $injectedComponentId
- |inject[0].forClass "${injectedClass.getName}"
- """.stripMargin
-
- dirConfigSource.writeConfig("components", componentsConfig)
- dirConfigSource.writeConfig("bundles", "")
- dirConfigSource.writeConfig("jersey-bundles", """bundles[0].spec "mock-entry-to-enforce-a-MockBundle" """)
- dirConfigSource.writeConfig("jersey-injection", injectionConfig)
-
- val container = newContainer(dirConfigSource)
- val componentGraph = container.getNewComponentGraph()
-
- val restApiContext = componentGraph.getInstance(restApiClass)
- }
-
- case class ComponentEntry(componentId: String, classId: Class[_]) {
- def asConfig(position: Int): String = {
- <config>
- |components[{position}].id "{componentId}"
- |components[{position}].classId "{classId.getName}"
- |components[{position}].configId "{dirConfigSource.configId}"
- </config>.text.stripMargin.trim
- }
- }
-
- def writeBootstrapConfigs(componentEntries: Array[ComponentEntry]) {
- dirConfigSource.writeConfig("bundles", "")
- dirConfigSource.writeConfig("components", """
- components[%s]
- %s
- """.format(componentEntries.length,
- componentEntries.zipWithIndex.map{ case (entry, index) => entry.asConfig(index) }.mkString("\n")))
- }
-
- def writeBootstrapConfigs(componentId: String = classOf[ComponentTakingConfig].getName,
- classId: Class[_] = classOf[ComponentTakingConfig]) {
-
- writeBootstrapConfigs(Array(ComponentEntry(componentId, classId)))
- }
-
- def writeBootstrapConfigsWithMultipleComponents(idAndClass: Array[(String, Class[_])]) {
- writeBootstrapConfigs(idAndClass.map{case(id, classId) => ComponentEntry(id, classId)})
- }
-
-
- @Test
- def providers_are_destructed() {
- writeBootstrapConfigs("id1", classOf[DestructableProvider])
-
- val deconstructor = new ComponentDeconstructor {
- def deconstruct(component: AnyRef) {
- component match {
- case c : AbstractComponent => c.deconstruct()
- case p : Provider[_] => p.deconstruct()
- }
- }
- }
-
- val container = newContainer(dirConfigSource, deconstructor)
-
- val oldGraph = container.getNewComponentGraph()
- val destructableEntity = oldGraph.getInstance(classOf[DestructableEntity])
-
- writeBootstrapConfigs("id2", classOf[DestructableProvider])
- container.reloadConfig(2)
- container.getNewComponentGraph(oldGraph)
-
- assertTrue(destructableEntity.deconstructed)
- }
-}
-
-
-object ContainerTest {
- class DestructableEntity {
- var deconstructed = false
- }
-
- class DestructableProvider extends Provider[DestructableEntity] {
- val instance = new DestructableEntity
-
- def get() = instance
-
- def deconstruct() {
- require(! instance.deconstructed)
- instance.deconstructed = true
- }
- }
-
- class ComponentTakingConfig(val config: TestConfig) extends AbstractComponent {
- require(config != null)
- }
-
- class ComponentThrowingExceptionInConstructor() {
- throw new RuntimeException("This component fails upon construction.")
- }
-
- class ComponentThrowingExceptionForMissingConfig(intConfig: IntConfig) extends AbstractComponent {
- fail("This component should never be created. Only used for tests where 'int' config is missing.")
- }
-
- class DestructableComponent extends AbstractComponent {
- var deconstructed = false
- override def deconstruct() {
- deconstructed = true
- }
- }
-
- class TestDeconstructor extends ComponentDeconstructor {
- def deconstruct(component: AnyRef) {
- component match {
- case vespaComponent: DestructableComponent => vespaComponent.deconstruct()
- case _ =>
- }
- }
- }
-
- private def newContainer(dirConfigSource: DirConfigSource,
- deconstructor: ComponentDeconstructor = new TestDeconstructor()):
- Container = {
- new Container(new CloudSubscriberFactory(dirConfigSource.configSource), dirConfigSource.configId, deconstructor)
- }
-
- def createComponentTakingConfig(componentGraph: ComponentGraph): ComponentTakingConfig = {
- componentGraph.getInstance(classOf[ComponentTakingConfig])
- }
-
- def convertMap[K, V](map: java.util.Map[K, V]): Map[K, V] = map.asScala.toMap
-}
diff --git a/container-di/src/test/scala/com/yahoo/container/di/DirConfigSource.scala b/container-di/src/test/scala/com/yahoo/container/di/DirConfigSource.scala
deleted file mode 100644
index 4f80b25a247..00000000000
--- a/container-di/src/test/scala/com/yahoo/container/di/DirConfigSource.scala
+++ /dev/null
@@ -1,50 +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
-
-import java.io.{FileOutputStream, OutputStream, File}
-import DirConfigSource._
-import java.util.Random
-import org.junit.rules.TemporaryFolder
-import com.yahoo.config.subscription.{ConfigSource, ConfigSourceSet}
-
-/**
- * @author tonytv
- * @author gjoranv
- */
-class DirConfigSource(val testSourcePrefix: String) {
-
- private val tempFolder = createTemporaryFolder()
-
- val configSource : ConfigSource = new ConfigSourceSet(testSourcePrefix + new Random().nextLong)
-
- def writeConfig(name: String, contents: String) {
- val file = new File(tempFolder.getRoot, name + ".cfg")
- if (!file.exists())
- file.createNewFile()
-
- printFile(file, contents + "\n")
- }
-
- def configId = "dir:" + tempFolder.getRoot.getPath
-
- def cleanup() {
- tempFolder.delete()
- }
-
-}
-
-private object DirConfigSource {
-
- def printFile(f: File, content: String) {
- var out: OutputStream = new FileOutputStream(f)
- out.write(content.getBytes("UTF-8"))
- out.close()
- }
-
- def createTemporaryFolder() = {
- val folder = new TemporaryFolder
- folder.create()
- folder
- }
-
-}
diff --git a/container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/ComponentGraphTest.scala b/container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/ComponentGraphTest.scala
deleted file mode 100644
index 05194cb911b..00000000000
--- a/container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/ComponentGraphTest.scala
+++ /dev/null
@@ -1,540 +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 java.util.concurrent.{Executor, Executors}
-
-import com.google.inject.name.{Named, Names}
-import com.google.inject.{AbstractModule, Guice, Inject, Key, Provider => GuiceProvider}
-import com.yahoo.component.provider.ComponentRegistry
-import com.yahoo.component.{AbstractComponent, ComponentId}
-import com.yahoo.config.ConfigInstance
-import com.yahoo.config.subscription.ConfigGetter
-import com.yahoo.config.test.{Test2Config, TestConfig}
-import com.yahoo.container.di._
-import com.yahoo.container.di.componentgraph.Provider
-import com.yahoo.container.di.config.{JerseyBundlesConfig, JerseyInjectionConfig, RestApiContext}
-import com.yahoo.vespa.config.ConfigKey
-import org.hamcrest.CoreMatchers.{containsString, equalTo, is, not, sameInstance}
-import org.hamcrest.Matcher
-import org.junit.Assert._
-import org.junit.Test
-
-import scala.language.implicitConversions
-
-/**
- * @author gjoranv
- * @author tonytv
- */
-class ComponentGraphTest {
- import ComponentGraphTest._
-
- private def keyAndConfig[T <: ConfigInstance](clazz: Class[T], configId: String): (ConfigKey[T], T) = {
- val key = new ConfigKey(clazz, configId)
- key -> ConfigGetter.getConfig(key.getConfigClass, key.getConfigId.toString)
- }
-
- @Test
- def component_taking_config_can_be_instantiated() {
- val componentGraph = new ComponentGraph
- val configId = "raw:stringVal \"test-value\""
- val componentNode = mockComponentNode(classOf[ComponentTakingConfig], configId)
-
- componentGraph.add(componentNode)
- componentGraph.complete()
- componentGraph.setAvailableConfigs(Map(keyAndConfig(classOf[TestConfig], configId)))
-
- val instance = componentGraph.getInstance(classOf[ComponentTakingConfig])
- assertNotNull(instance)
- assertThat(instance.config.stringVal(), is("test-value"))
- }
-
- @Test
- def component_can_be_injected_into_another_component() {
- val injectedComponent = mockComponentNode(classOf[SimpleComponent])
- val targetComponent = mockComponentNode(classOf[ComponentTakingComponent])
- targetComponent.inject(injectedComponent)
-
- val destroyGlobalLookupComponent = mockComponentNode(classOf[SimpleComponent])
-
- val componentGraph = new ComponentGraph
- componentGraph.add(injectedComponent)
- componentGraph.add(targetComponent)
- componentGraph.add(destroyGlobalLookupComponent)
- componentGraph.complete()
-
-
- val instance = componentGraph.getInstance(classOf[ComponentTakingComponent])
- assertNotNull(instance)
- }
-
- @Test
- def all_components_of_a_type_can_be_injected() {
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[SimpleComponent]))
- componentGraph.add(mockComponentNode(classOf[SimpleComponent]))
- componentGraph.add(mockComponentNode(classOf[SimpleDerivedComponent]))
- componentGraph.add(mockComponentNode(classOf[ComponentTakingAllSimpleComponents]))
- componentGraph.complete()
-
- val instance = componentGraph.getInstance(classOf[ComponentTakingAllSimpleComponents])
- assertThat(instance.simpleComponents.allComponents().size(), is(3))
- }
-
- @Test
- def empty_component_registry_can_be_injected() {
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[ComponentTakingAllSimpleComponents]))
- componentGraph.complete()
-
- val instance = componentGraph.getInstance(classOf[ComponentTakingAllSimpleComponents])
- assertThat(instance.simpleComponents.allComponents().size(), is(0))
- }
-
- @Test
- def component_registry_with_wildcard_upper_bound_can_be_injected() {
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[SimpleComponent]))
- componentGraph.add(mockComponentNode(classOf[SimpleDerivedComponent]))
- componentGraph.add(mockComponentNode(classOf[ComponentTakingAllSimpleComponentsUpperBound]))
- componentGraph.complete()
-
- val instance = componentGraph.getInstance(classOf[ComponentTakingAllSimpleComponentsUpperBound])
- assertThat(instance.simpleComponents.allComponents().size(), is(2))
- }
-
- @Test(expected = classOf[RuntimeException])
- def require_exception_when_injecting_registry_with_unknown_type_variable() {
- val clazz = classOf[ComponentTakingAllComponentsWithTypeVariable[_]]
-
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[SimpleComponent]))
- componentGraph.add(mockComponentNode(classOf[SimpleDerivedComponent]))
- componentGraph.add(mockComponentNode(clazz))
- componentGraph.complete()
-
- componentGraph.getInstance(clazz)
- }
-
- @Test
- def components_are_shared() {
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[SimpleComponent]))
- componentGraph.complete()
-
- val instance1 = componentGraph.getInstance(classOf[SimpleComponent])
- val instance2 = componentGraph.getInstance(classOf[SimpleComponent])
- assertThat(instance1, sameInstance(instance2))
- }
-
- @Test
- def singleton_components_can_be_injected() {
- val componentGraph = new ComponentGraph
- val configId = """raw:stringVal "test-value" """
-
- componentGraph.add(mockComponentNode(classOf[ComponentTakingComponent]))
- componentGraph.add(mockComponentNode(classOf[ComponentTakingConfig], configId))
- componentGraph.add(mockComponentNode(classOf[SimpleComponent2]))
- componentGraph.complete()
- componentGraph.setAvailableConfigs(Map(keyAndConfig(classOf[TestConfig], configId)))
-
- val instance = componentGraph.getInstance(classOf[ComponentTakingComponent])
- assertThat(instance.injectedComponent.asInstanceOf[ComponentTakingConfig].config.stringVal(), is("test-value"))
- }
-
- @Test(expected = classOf[RuntimeException])
- def require_error_when_multiple_components_match_a_singleton_dependency() {
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[SimpleDerivedComponent]))
- componentGraph.add(mockComponentNode(classOf[SimpleComponent]))
- componentGraph.add(mockComponentNode(classOf[ComponentTakingComponent]))
- componentGraph.complete()
- }
-
- @Test
- def named_component_can_be_injected() {
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[SimpleComponent]))
- componentGraph.add(mockComponentNode(classOf[SimpleComponent], key = Names.named("named-test")))
- componentGraph.add(mockComponentNode(classOf[ComponentTakingNamedComponent]))
- componentGraph.complete()
- }
-
- @Test
- def config_keys_can_be_retrieved() {
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[ComponentTakingConfig], configId = """raw:stringVal "component1" """""))
- componentGraph.add(mockComponentNode(classOf[ComponentTakingConfig], configId = """raw:stringVal "component2" """""))
- componentGraph.add(new ComponentRegistryNode(classOf[ComponentTakingConfig]))
- componentGraph.complete()
-
- val configKeys = componentGraph.configKeys
- assertThat(configKeys.size, is(2))
-
- configKeys.foreach{ key =>
- assertThat(key.getConfigClass, equalTo(classOf[TestConfig]))
- assertThat(key.getConfigId.toString, containsString("component"))
- }
- }
-
- @Test
- def providers_can_be_instantiated() {
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[ExecutorProvider]))
- componentGraph.complete()
-
- assertNotNull(componentGraph.getInstance(classOf[Executor]))
- }
-
- @Test
- def providers_can_be_inherited() {
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[DerivedExecutorProvider]))
- componentGraph.complete()
-
- assertNotNull(componentGraph.getInstance(classOf[Executor]))
- }
-
- @Test
- def providers_can_deliver_a_new_instance_for_each_component() {
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNode(classOf[NewIntProvider]))
- componentGraph.complete()
-
- val instance1 = componentGraph.getInstance(classOf[Int])
- val instance2 = componentGraph.getInstance(classOf[Int])
- assertThat(instance1, not(equalTo(instance2)))
- }
-
- @Test
- def providers_can_be_injected_explicitly() {
- val componentGraph = new ComponentGraph
-
- val componentTakingExecutor = mockComponentNode(classOf[ComponentTakingExecutor])
- val executorProvider = mockComponentNode(classOf[ExecutorProvider])
- componentTakingExecutor.inject(executorProvider)
-
- componentGraph.add(executorProvider)
- componentGraph.add(mockComponentNode(classOf[ExecutorProvider]))
-
- componentGraph.add(componentTakingExecutor)
-
- componentGraph.complete()
- assertNotNull(componentGraph.getInstance(classOf[ComponentTakingExecutor]))
- }
-
- @Test
- def global_providers_can_be_injected() {
- val componentGraph = new ComponentGraph
-
- componentGraph.add(mockComponentNode(classOf[ComponentTakingExecutor]))
- componentGraph.add(mockComponentNode(classOf[ExecutorProvider]))
- componentGraph.add(mockComponentNode(classOf[IntProvider]))
- componentGraph.complete()
-
- assertNotNull(componentGraph.getInstance(classOf[ComponentTakingExecutor]))
- }
-
- @Test(expected = classOf[RuntimeException])
- def throw_if_multiple_global_providers_exist(): Unit = {
- val componentGraph = new ComponentGraph
-
- componentGraph.add(mockComponentNode(classOf[ExecutorProvider]))
- componentGraph.add(mockComponentNode(classOf[ExecutorProvider]))
- componentGraph.add(mockComponentNode(classOf[ComponentTakingExecutor]))
- componentGraph.complete()
- }
-
- @Test
- def provider_is_not_used_when_component_of_provided_class_exists() {
- val componentGraph = new ComponentGraph
-
- componentGraph.add(mockComponentNode(classOf[SimpleComponent]))
- componentGraph.add(mockComponentNode(classOf[SimpleComponentProviderThatThrows]))
- componentGraph.add(mockComponentNode(classOf[ComponentTakingComponent]))
- componentGraph.complete()
-
- val injectedComponent = componentGraph.getInstance(classOf[ComponentTakingComponent]).injectedComponent
- assertNotNull(injectedComponent)
- }
-
- //TODO: move
- @Test
- def check_if_annotation_is_a_binding_annotation() {
- import ComponentGraph.isBindingAnnotation
-
- assertTrue(isBindingAnnotation(Names.named("name")))
- assertFalse(isBindingAnnotation(classOf[Named].getAnnotations.head))
- }
-
- @Test
- def cycles_gives_exception() {
- val componentGraph = new ComponentGraph
-
- def mockNode = mockComponentNode(classOf[ComponentCausingCycle])
-
- val node1 = mockNode
- val node2 = mockNode
-
- node1.inject(node2)
- node2.inject(node1)
-
- componentGraph.add(node1)
- componentGraph.add(node2)
-
- try {
- componentGraph.complete()
- fail("Cycle exception expected.")
- } catch {
- case e : Throwable => assertThat(e.getMessage, containsString("cycle"))
- }
- }
-
- @Test(expected = classOf[IllegalArgumentException])
- def abstract_classes_are_rejected() {
- new ComponentNode(ComponentId.fromString("Test"), "", classOf[AbstractClass])
- }
-
- @Test
- def inject_constructor_is_preferred() {
- assertThatComponentCanBeCreated(classOf[ComponentWithInjectConstructor])
- }
-
- @Test
- def constructor_with_most_parameters_is_preferred() {
- assertThatComponentCanBeCreated(classOf[ComponentWithMultipleConstructors])
- }
-
- def assertThatComponentCanBeCreated(clazz: Class[AnyRef]) {
- val componentGraph = new ComponentGraph
- val configId = """raw:stringVal "dummy" """"
-
- componentGraph.add(mockComponentNode(clazz, configId))
- componentGraph.complete()
-
- componentGraph.setAvailableConfigs(Map(
- keyAndConfig(classOf[TestConfig], configId),
- keyAndConfig(classOf[Test2Config], configId)))
-
- assertNotNull(componentGraph.getInstance(clazz))
- }
-
- @Test
- def require_fallback_to_child_injector() {
- val componentGraph = new ComponentGraph
-
- componentGraph.add(mockComponentNode(classOf[ComponentTakingExecutor]))
-
- componentGraph.complete(singletonExecutorInjector)
- assertNotNull(componentGraph.getInstance(classOf[ComponentTakingExecutor]))
- }
-
- @Test
- def child_injector_can_inject_multiple_instances_for_same_key() {
- def executorProvider() = Executors.newSingleThreadExecutor()
-
- val (graphSize, executorA, executorB) = buildGraphWithChildInjector(() => executorProvider())
-
- assertThat(graphSize, is(4))
- assertThat(executorA, not(sameInstance(executorB)))
- }
-
- @Test
- def components_injected_via_child_injector_can_be_shared() {
- val commonExecutor = Executors.newSingleThreadExecutor()
- val (graphSize, executorA, executorB) = buildGraphWithChildInjector(() => commonExecutor)
-
- assertThat(graphSize, is(3))
- assertThat(executorA, sameInstance(executorB))
- }
-
- def buildGraphWithChildInjector(executorProvider: () => Executor) = {
- val childInjector = Guice.createInjector(new AbstractModule {
- override def configure() {
- bind(classOf[Executor]).toProvider(new GuiceProvider[Executor] {
- def get() = executorProvider()
- })
- }
- })
-
- val componentGraph = new ComponentGraph
-
- def key(name: String) = Key.get(classOf[ComponentTakingExecutor], Names.named(name))
- val keyA = key("A")
- val keyB = key("B")
-
- componentGraph.add(mockComponentNode(keyA))
- componentGraph.add(mockComponentNode(keyB))
-
- componentGraph.complete(childInjector)
-
- (componentGraph.size, componentGraph.getInstance(keyA).executor, componentGraph.getInstance(keyB).executor)
- }
-
- @Test
- def providers_can_be_reused() {
- def createGraph() = {
- val graph = new ComponentGraph()
- graph.add(mockComponentNodeWithId(classOf[ExecutorProvider], "dummyId"))
- graph.complete()
- graph.setAvailableConfigs(Map())
- graph
- }
-
- val oldGraph = createGraph()
- val executor = oldGraph.getInstance(classOf[Executor])
-
- val newGraph = createGraph()
- newGraph.reuseNodes(oldGraph)
-
- val newExecutor = newGraph.getInstance(classOf[Executor])
- assertThat(executor, sameInstance(newExecutor))
- }
-
- @Test
- def component_id_can_be_injected() {
- val componentId: String = "myId:1.2@namespace"
-
- val componentGraph = new ComponentGraph
- componentGraph.add(mockComponentNodeWithId(classOf[ComponentTakingComponentId], componentId))
- componentGraph.complete()
-
- assertThat(componentGraph.getInstance(classOf[ComponentTakingComponentId]).componentId,
- is(ComponentId.fromString(componentId)))
- }
-
- @Test
- def rest_api_context_can_be_instantiated() {
- val configId = """raw:"" """
-
- val clazz = classOf[RestApiContext]
- val jerseyNode = new JerseyNode(uniqueComponentId(clazz.getName), configId, clazz, new Osgi {})
-
- val componentGraph = new ComponentGraph
- componentGraph.add(jerseyNode)
- componentGraph.complete()
- componentGraph.setAvailableConfigs(Map(keyAndConfig(classOf[JerseyBundlesConfig], configId),
- keyAndConfig(classOf[JerseyInjectionConfig], configId)))
-
- val 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.
-object ComponentGraphTest {
- var counter = 0
-
-
- class SimpleComponent extends AbstractComponent
- class SimpleComponent2 extends AbstractComponent
- class SimpleDerivedComponent extends SimpleComponent
-
- class ComponentTakingConfig(val config: TestConfig) extends SimpleComponent {
- require(config != null)
- }
-
- class ComponentTakingComponent(val injectedComponent: SimpleComponent) extends AbstractComponent {
- require(injectedComponent != null)
- }
-
- class ComponentTakingConfigAndComponent(val config: TestConfig, val injectedComponent: SimpleComponent) extends AbstractComponent {
- require(config != null)
- require(injectedComponent != null)
- }
-
- class ComponentTakingAllSimpleComponents(val simpleComponents: ComponentRegistry[SimpleComponent]) extends AbstractComponent {
- require(simpleComponents != null)
- }
-
- class ComponentTakingAllSimpleComponentsUpperBound(val simpleComponents: ComponentRegistry[_ <: SimpleComponent])
- extends AbstractComponent {
-
- require(simpleComponents != null)
- }
-
- class ComponentTakingAllComponentsWithTypeVariable[COMPONENT <: AbstractComponent](val simpleComponents: ComponentRegistry[COMPONENT])
- extends AbstractComponent {
-
- require(simpleComponents != null)
- }
-
- class ComponentTakingNamedComponent(@Named("named-test") injectedComponent: SimpleComponent) extends AbstractComponent {
- require(injectedComponent != null)
- }
-
- class ComponentCausingCycle(component: ComponentCausingCycle) extends AbstractComponent
-
- class SimpleComponentProviderThatThrows extends Provider[SimpleComponent] {
- def get() = throw new AssertionError("Should never be called.")
- def deconstruct() {}
- }
-
- class ExecutorProvider extends Provider[Executor] {
- val executor = Executors.newSingleThreadExecutor()
- def get() = executor
- def deconstruct() { /*TODO */ }
- }
-
- class DerivedExecutorProvider extends ExecutorProvider
-
- class IntProvider extends Provider[java.lang.Integer] {
- def get() = throw new AssertionError("Should never be called.")
- def deconstruct() {}
- }
-
- class NewIntProvider extends Provider[Integer] {
- var i: Int = 0
- def get() = {
- i += 1
- i
- }
- def deconstruct() {}
- }
-
- class ComponentTakingExecutor(val executor: Executor) extends AbstractComponent {
- require(executor != null)
- }
-
- class ComponentWithInjectConstructor private () {
- def this(c: TestConfig, c2: Test2Config) = { this(); sys.error("Should not be called") }
- @Inject
- def this(c: Test2Config) = { this() }
- }
-
- class ComponentWithMultipleConstructors private (dummy : Int) {
- def this(c: TestConfig, c2: Test2Config) = { this(0); }
-
- def this() = { this(0); sys.error("Should not be called") }
- def this(c: Test2Config) = { this() }
- }
-
- class ComponentTakingComponentId(val componentId: ComponentId)
-
- def uniqueComponentId(className: String): ComponentId = {
- counter += 1
- ComponentId.fromString(className + counter)
- }
-
- def mockComponentNode(key: Key[_ <: AnyRef]): Node =
- mockComponentNode(key.getTypeLiteral.getRawType.asInstanceOf[Class[AnyRef]], key=key.getAnnotation)
-
- def mockComponentNode(clazz: Class[_ <: AnyRef], configId: String = "", key: JavaAnnotation = null): Node =
- new ComponentNode(uniqueComponentId(clazz.getName), configId, clazz, key)
-
- def mockComponentNodeWithId(clazz: Class[_ <: AnyRef], componentId: String, configId: String = "", key: JavaAnnotation = null): Node =
- new ComponentNode(ComponentId.fromString(componentId), configId, clazz, key)
-
- val singletonExecutorInjector = Guice.createInjector(new AbstractModule {
- override def configure() {
- bind(classOf[Executor]).toInstance(Executors.newSingleThreadExecutor())
- }
- })
-
- implicit def makeMatcherCovariant[T, U >: T](matcher: Matcher[T]) : Matcher[U] = matcher.asInstanceOf[Matcher[U]]
-
- abstract class AbstractClass
-}
-
diff --git a/container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/JerseyNodeTest.scala b/container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/JerseyNodeTest.scala
deleted file mode 100644
index e55ac65680d..00000000000
--- a/container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/JerseyNodeTest.scala
+++ /dev/null
@@ -1,66 +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 java.util
-import java.util.Collections
-import com.yahoo.container.di.osgi.OsgiUtil
-import org.junit.Test
-import org.junit.Assert._
-import org.hamcrest.CoreMatchers.is
-import org.hamcrest.Matchers.{contains, containsInAnyOrder}
-import org.osgi.framework.wiring.BundleWiring
-import scala.collection.JavaConverters._
-import com.yahoo.container.bundle.MockBundle
-
-/**
- *
- * @author gjoranv
- * @since 5.17
- */
-
-class JerseyNodeTest {
-
- trait WithMockBundle {
- object bundle extends MockBundle {
- val entry = Map(
- "com/foo" -> "Foo.class",
- "com/bar" -> "Bar.class)"
- ) map { case (packageName, className) => (packageName, packageName + "/" + className)}
-
-
- override def listResources(path: String, ignored: String, options: Int): util.Collection[String] = {
- if ((options & BundleWiring.LISTRESOURCES_RECURSE) != 0 && path == "/") entry.values.asJavaCollection
- else Collections.singleton(entry(path))
- }
- }
-
- val bundleClasses = bundle.entry.values.toList
- }
-
- @Test
- def all_bundle_entries_are_returned_when_no_packages_are_given() {
- new WithMockBundle {
- val entries = OsgiUtil.getClassEntriesInBundleClassPath(bundle, Set()).asJavaCollection
- assertThat(entries, containsInAnyOrder(bundleClasses: _*))
- }
- }
-
- @Test
- def only_bundle_entries_from_the_given_packages_are_returned() {
- new WithMockBundle {
- val entries = OsgiUtil.getClassEntriesInBundleClassPath(bundle, Set("com.foo")).asJavaCollection
- assertThat(entries, contains(bundle.entry("com/foo")))
- }
- }
-
- @Test
- def bundle_info_is_initialized() {
- new WithMockBundle {
- val bundleInfo = JerseyNode.createBundleInfo(bundle, List())
- 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/scala/com/yahoo/container/di/componentgraph/core/ReuseComponentsTest.scala b/container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/ReuseComponentsTest.scala
deleted file mode 100644
index 33c6d2a3e89..00000000000
--- a/container-di/src/test/scala/com/yahoo/container/di/componentgraph/core/ReuseComponentsTest.scala
+++ /dev/null
@@ -1,249 +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.yahoo.component.{ComponentId, AbstractComponent}
-import org.junit.Assert._
-import org.hamcrest.CoreMatchers.{is, not, sameInstance, equalTo}
-import com.yahoo.vespa.config.ConfigKey
-import java.util.concurrent.Executor
-import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.{ExecutorProvider, SimpleComponent, SimpleComponent2}
-import com.yahoo.container.di.componentgraph.core.ComponentGraphTest.{ComponentTakingConfig, ComponentTakingExecutor, singletonExecutorInjector}
-import com.yahoo.container.di.makeClassCovariant
-import org.junit.Test
-import com.yahoo.config.subscription.ConfigGetter
-import com.yahoo.config.test.TestConfig
-
-/**
- * @author gjoranv
- * @author tonytv
- */
-class ReuseComponentsTest {
- import ReuseComponentsTest._
-
- @Test
- def require_that_component_is_reused_when_componentNode_is_unmodified() {
- def reuseAndTest(classToRegister: Class[AnyRef], classToLookup: Class[AnyRef]) {
- val graph = buildGraphAndSetNoConfigs(classToRegister)
- val instance = getComponent(graph, classToLookup)
-
- val newGraph = buildGraphAndSetNoConfigs(classToRegister)
- newGraph.reuseNodes(graph)
- val instance2 = getComponent(newGraph, classToLookup)
-
- assertThat(instance2, sameInstance(instance))
- }
-
- reuseAndTest(classOf[SimpleComponent], classOf[SimpleComponent])
- reuseAndTest(classOf[ExecutorProvider], classOf[Executor])
- }
-
-
- @Test(expected = classOf[IllegalStateException])
- def require_that_component_is_not_reused_when_class_is_changed() {
- val graph = buildGraphAndSetNoConfigs(classOf[SimpleComponent])
- val instance = getComponent(graph, classOf[SimpleComponent])
-
- val newGraph = buildGraphAndSetNoConfigs(classOf[SimpleComponent2])
- newGraph.reuseNodes(graph)
- val instance2 = getComponent(newGraph, classOf[SimpleComponent2])
-
- assertThat(instance2.getId, is(instance.getId))
- val throwsException = getComponent(newGraph, classOf[SimpleComponent])
- }
-
- @Test
- def require_that_component_is_not_reused_when_config_is_changed() {
- def setConfig(graph: ComponentGraph, config: String) {
- graph.setAvailableConfigs(
- Map(new ConfigKey(classOf[TestConfig], "component") ->
- ConfigGetter.getConfig(classOf[TestConfig], """raw: stringVal "%s" """.format(config))))
- }
-
- val componentClass = classOf[ComponentTakingConfig]
-
- val graph = buildGraph(componentClass)
- setConfig(graph, "oldConfig")
- val instance = getComponent(graph, componentClass)
-
- val newGraph = buildGraph(componentClass)
- setConfig(newGraph, "newConfig")
- newGraph.reuseNodes(graph)
- val instance2 = getComponent(newGraph, componentClass)
-
- assertThat(instance2, not(sameInstance(instance)))
- }
-
- @Test
- def require_that_component_is_not_reused_when_injected_component_is_changed() {
- import ComponentGraphTest.{ComponentTakingComponent, ComponentTakingConfig}
-
- def buildGraph(config: String) = {
- val graph = new ComponentGraph
-
- val rootComponent = mockComponentNode(classOf[ComponentTakingComponent], "root_component")
-
- val configId = "componentTakingConfigId"
- val injectedComponent = mockComponentNode(classOf[ComponentTakingConfig], "injected_component", configId)
-
- rootComponent.inject(injectedComponent)
-
- graph.add(rootComponent)
- graph.add(injectedComponent)
-
- graph.complete()
- graph.setAvailableConfigs(Map(new ConfigKey(classOf[TestConfig], configId) ->
- ConfigGetter.getConfig(classOf[TestConfig], """raw: stringVal "%s" """.format(config))))
-
- graph
- }
-
- val oldGraph = buildGraph(config="oldGraph")
- val oldInstance = getComponent(oldGraph, classOf[ComponentTakingComponent])
-
- val newGraph = buildGraph(config="newGraph")
- newGraph.reuseNodes(oldGraph)
- val newInstance = getComponent(newGraph, classOf[ComponentTakingComponent])
-
- assertThat(newInstance, not(sameInstance(oldInstance)))
- }
-
- @Test
- def require_that_component_is_not_reused_when_injected_component_registry_has_one_component_removed() {
- import ComponentGraphTest.ComponentTakingAllSimpleComponents
-
- def buildGraph(useBothInjectedComponents: Boolean) = {
- val graph = new ComponentGraph
- graph.add(mockComponentNode(classOf[ComponentTakingAllSimpleComponents], "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(classOf[SimpleComponent], "injected_component2"))
- graph.add(mockComponentNode(classOf[SimpleComponent], "injected_component1"))
- } else {
- graph.add(mockComponentNode(classOf[SimpleComponent], "injected_component1"))
- }
-
- graph.complete()
- graph.setAvailableConfigs(Map())
- graph
- }
-
- val oldGraph = buildGraph(useBothInjectedComponents = true)
- val oldSimpleComponentRegistry = getComponent(oldGraph, classOf[ComponentTakingAllSimpleComponents]).simpleComponents
-
- val newGraph = buildGraph(useBothInjectedComponents = false)
- newGraph.reuseNodes(oldGraph)
- val newSimpleComponentRegistry = getComponent(newGraph, classOf[ComponentTakingAllSimpleComponents]).simpleComponents
-
- assertThat(newSimpleComponentRegistry, not(sameInstance(oldSimpleComponentRegistry)))
- }
-
- @Test
- def require_that_injected_component_is_reused_even_when_dependent_component_is_changed() {
- import ComponentGraphTest.{ComponentTakingConfigAndComponent, SimpleComponent}
-
- def buildGraph(config: String) = {
- val graph = new ComponentGraph
-
- val configId = "componentTakingConfigAndComponent"
- val rootComponent = mockComponentNode(classOf[ComponentTakingConfigAndComponent], "root_component", configId)
-
- val injectedComponent = mockComponentNode(classOf[SimpleComponent], "injected_component")
-
- rootComponent.inject(injectedComponent)
-
- graph.add(rootComponent)
- graph.add(injectedComponent)
-
- graph.complete()
- graph.setAvailableConfigs(Map(new ConfigKey(classOf[TestConfig], configId) ->
- ConfigGetter.getConfig(classOf[TestConfig], """raw: stringVal "%s" """.format(config))))
-
- graph
- }
-
- val oldGraph = buildGraph(config="oldGraph")
- val oldInjectedComponent = getComponent(oldGraph, classOf[SimpleComponent])
- val oldDependentComponent = getComponent(oldGraph, classOf[ComponentTakingConfigAndComponent])
-
- val newGraph = buildGraph(config="newGraph")
- newGraph.reuseNodes(oldGraph)
- val newInjectedComponent = getComponent(newGraph, classOf[SimpleComponent])
- val newDependentComponent = getComponent(newGraph, classOf[ComponentTakingConfigAndComponent])
-
- assertThat(newDependentComponent, not(sameInstance(oldDependentComponent)))
- assertThat(newInjectedComponent, sameInstance(oldInjectedComponent))
- }
-
- @Test
- def require_that_node_depending_on_guice_node_is_reused() {
- def makeGraph = {
- val graph = new ComponentGraph
- graph.add(mockComponentNode(classOf[ComponentTakingExecutor], "dummyId"))
- graph.complete(singletonExecutorInjector)
- graph.setAvailableConfigs(Map())
- graph
- }
-
- val getComponentTakingExecutor = getComponent(_: ComponentGraph, classOf[ComponentTakingExecutor])
-
- val oldGraph = makeGraph
- getComponentTakingExecutor(oldGraph) // Ensure creation of GuiceNode
- val newGraph = makeGraph
- newGraph.reuseNodes(oldGraph)
- assertThat(getComponentTakingExecutor(oldGraph), sameInstance(getComponentTakingExecutor(newGraph)))
- }
-
- @Test
- def require_that_node_equals_only_checks_first_level_components_to_inject() {
-
- def createNodeWithInjectedNodeWithInjectedNode(indirectlyInjectedComponentId: String): Node = {
- val targetComponent = mockComponentNode(classOf[SimpleComponent], "target")
- val directlyInjectedComponent = mockComponentNode(classOf[SimpleComponent], "directlyInjected")
- val indirectlyInjectedComponent = mockComponentNode(classOf[SimpleComponent], indirectlyInjectedComponentId)
- directlyInjectedComponent.inject(indirectlyInjectedComponent)
- targetComponent.inject(directlyInjectedComponent)
-
- completeNode(targetComponent)
- completeNode(directlyInjectedComponent)
- completeNode(indirectlyInjectedComponent)
-
- targetComponent
- }
- val targetNode1 = createNodeWithInjectedNodeWithInjectedNode("indirectlyInjected_1")
- val targetNode2 = createNodeWithInjectedNodeWithInjectedNode("indirectlyInjected_2")
- assertThat(targetNode1, equalTo(targetNode2))
- }
-
- private def completeNode(node: ComponentNode) {
- node.setArguments(Array())
- node.setAvailableConfigs(Map())
- }
-
- private def buildGraph(componentClass: Class[_ <: AnyRef]) = {
- val commonComponentId = "component"
- val g = new ComponentGraph
- g.add(mockComponentNode(componentClass, commonComponentId, configId = commonComponentId))
- g.complete()
- g
- }
-
- private def buildGraphAndSetNoConfigs(componentClass: Class[_ <: AnyRef]) = {
- val g = buildGraph(componentClass)
- g.setAvailableConfigs(Map())
- g
- }
-}
-
-object ReuseComponentsTest {
-
- def mockComponentNode(clazz: Class[_ <: AnyRef], componentId: String = "", configId: String="") =
- new ComponentNode(new ComponentId(componentId), configId, clazz)
-
- def getComponent[T](graph: ComponentGraph, clazz: Class[T]) = {
- graph.getInstance(clazz)
- }
-}