diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /config-model/src/test/java/com/yahoo/config/model/deploy |
Publish
Diffstat (limited to 'config-model/src/test/java/com/yahoo/config/model/deploy')
-rw-r--r-- | config-model/src/test/java/com/yahoo/config/model/deploy/DeployStateTest.java | 148 | ||||
-rw-r--r-- | config-model/src/test/java/com/yahoo/config/model/deploy/SystemModelTestCase.java | 183 |
2 files changed, 331 insertions, 0 deletions
diff --git a/config-model/src/test/java/com/yahoo/config/model/deploy/DeployStateTest.java b/config-model/src/test/java/com/yahoo/config/model/deploy/DeployStateTest.java new file mode 100644 index 00000000000..a84cb7ca7f6 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/config/model/deploy/DeployStateTest.java @@ -0,0 +1,148 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.config.model.deploy; + +import com.yahoo.config.application.api.ApplicationPackage; +import com.yahoo.config.codegen.InnerCNode; +import com.yahoo.config.model.api.ConfigDefinitionRepo; +import com.yahoo.config.model.api.HostProvisioner; +import com.yahoo.config.model.application.provider.FilesApplicationPackage; +import com.yahoo.config.model.provision.InMemoryProvisioner; +import com.yahoo.config.model.test.MockApplicationPackage; +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.Rotation; +import com.yahoo.vespa.config.ConfigDefinition; +import com.yahoo.vespa.config.ConfigDefinitionKey; +import com.yahoo.vespa.model.VespaModel; +import org.junit.Test; +import org.xml.sax.SAXException; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +/** + * @author lulf + * @since 5.12 + */ +public class DeployStateTest { + @Test + public void testProvisionerIsSet() { + DeployState.Builder builder = new DeployState.Builder(); + HostProvisioner provisioner = new InMemoryProvisioner(true, "foo.yahoo.com"); + builder.modelHostProvisioner(provisioner); + DeployState state = builder.build(); + assertThat(state.getProvisioner(), is(provisioner)); + } + + @Test + public void testBuilder() { + DeployState.Builder builder = new DeployState.Builder(); + ApplicationPackage app = MockApplicationPackage.createEmpty(); + builder.permanentApplicationPackage(Optional.of(app)); + DeployState state = builder.build(); + assertThat(state.getPermanentApplicationPackage().get(), is(app)); + } + + @Test + public void testPreviousModelIsProvided() throws IOException, SAXException { + VespaModel prevModel = new VespaModel(MockApplicationPackage.createEmpty()); + DeployState.Builder builder = new DeployState.Builder(); + assertThat(builder.previousModel(prevModel).build().getPreviousModel().get(), is(prevModel)); + } + + @Test + public void testProperties() { + DeployState.Builder builder = new DeployState.Builder(); + DeployState state = builder.build(); + assertThat(state.getProperties().applicationId(), is(ApplicationId.defaultId())); + ApplicationId customId = new ApplicationId.Builder() + .tenant("bar") + .applicationName("foo").instanceName("quux").build(); + DeployProperties properties = new DeployProperties.Builder().applicationId(customId).build(); + builder.properties(properties); + state = builder.build(); + assertThat(state.getProperties().applicationId(), is(customId)); + } + + @Test + public void testDefinitionRepoIsUsed() { + final Map<ConfigDefinitionKey, com.yahoo.vespa.config.buildergen.ConfigDefinition> defs = new LinkedHashMap<>(); + defs.put(new ConfigDefinitionKey("foo", "bar"), new com.yahoo.vespa.config.buildergen.ConfigDefinition("foo", new String[]{"namespace=bar", "foo int default=0"})); + defs.put(new ConfigDefinitionKey("test2", "a.b"), + new com.yahoo.vespa.config.buildergen.ConfigDefinition("test2", new String[]{"namespace=a.b", "doubleVal double default=1.0"})); + ApplicationPackage app = FilesApplicationPackage.fromFile(new File("src/test/cfg//application/app1")); + DeployState state = createDeployState(app, defs); + + assertNotNull(state.getConfigDefinition(new ConfigDefinitionKey("foo", "bar"))); + assertNotNull(state.getConfigDefinition(new ConfigDefinitionKey("test1", ""))); + ConfigDefinition overridden = state.getConfigDefinition(new ConfigDefinitionKey("test2", "a.b")); + assertNotNull(overridden); + Double defaultValue = overridden.getDoubleDefs().get("doubleVal").getDefVal(); + assertNotNull(defaultValue); + assertThat(defaultValue.intValue(), is(0)); + } + + @Test + public void testGetConfigDefinition() { + final Map<ConfigDefinitionKey, com.yahoo.vespa.config.buildergen.ConfigDefinition> defs = new LinkedHashMap<>(); + defs.put(new ConfigDefinitionKey("test2", "a.b"), new com.yahoo.vespa.config.buildergen.ConfigDefinition("test2", new String[]{"namespace=a.b", "doubleVal double default=1.0"})); + defs.put(new ConfigDefinitionKey("test2", "c.d"), new com.yahoo.vespa.config.buildergen.ConfigDefinition("test2", new String[]{"namespace=c.d", "doubleVal double default=1.0"})); + defs.put(new ConfigDefinitionKey("test3", "xyzzy"), new com.yahoo.vespa.config.buildergen.ConfigDefinition("test3", new String[]{"namespace=xyzzy", "message string"})); + ApplicationPackage app = FilesApplicationPackage.fromFile(new File("src/test/cfg//application/app1")); + DeployState state = createDeployState(app, defs); + + assertNotNull(state.getConfigDefinition(new ConfigDefinitionKey("test2", "a.b"))); + + // Should not fallback to using test2 with another namespace + try { + state.getConfigDefinition(new ConfigDefinitionKey("test2", "")); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage(), is("Using config definition 'test2' is ambiguous, there are more than one config definitions with this name, please specify namespace")); + } + + final ConfigDefinition test1 = state.getConfigDefinition(new ConfigDefinitionKey("test2", "a.b")); + assertNotNull(test1); + assertThat(test1.getName(), is("test2")); + assertThat(test1.getNamespace(), is("a.b")); + + // Should fallback to using test3 with another namespace, since only one exists + ConfigDefinition test3 = state.getConfigDefinition(new ConfigDefinitionKey("test3", "")); + assertNotNull(test3); + assertThat(test3.getName(), is("test3")); + assertThat(test3.getNamespace(), is("xyzzy")); + } + + @Test + public void testRotations() { + final Set<Rotation> rotations = new HashSet<>(); + assertThat(new DeployState.Builder().rotations(rotations).build().getRotations().size(), is(0)); + for (String name : new String[]{"rotation-001.vespa.a02.yahoodns.net", "rotation-002.vespa.a02.yahoodns.net"}) { + rotations.add(new Rotation(name)); + } + assertThat(new DeployState.Builder().rotations(rotations).build().getRotations(), equalTo(rotations)); + } + + private DeployState createDeployState(ApplicationPackage app, final Map<ConfigDefinitionKey, com.yahoo.vespa.config.buildergen.ConfigDefinition> defs) { + DeployState.Builder builder = new DeployState.Builder().applicationPackage(app); + builder.configDefinitionRepo(new ConfigDefinitionRepo() { + @Override + public Map<ConfigDefinitionKey, com.yahoo.vespa.config.buildergen.ConfigDefinition> getConfigDefinitions() { + return defs; + } + }); + return builder.build(); + } +} + diff --git a/config-model/src/test/java/com/yahoo/config/model/deploy/SystemModelTestCase.java b/config-model/src/test/java/com/yahoo/config/model/deploy/SystemModelTestCase.java new file mode 100644 index 00000000000..6be85fb19e4 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/config/model/deploy/SystemModelTestCase.java @@ -0,0 +1,183 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.config.model.deploy; + +import com.yahoo.cloud.config.SentinelConfig; +import com.yahoo.test.StandardConfig; +import com.yahoo.config.model.ConfigModel; +import com.yahoo.config.model.ConfigModelRegistry; +import com.yahoo.config.model.MapConfigModelRegistry; +import com.yahoo.config.model.ApplicationConfigProducerRoot; +import com.yahoo.net.HostName; +import com.yahoo.vespa.model.*; +import com.yahoo.vespa.model.test.ApiConfigModel; +import com.yahoo.vespa.model.test.SimpleConfigModel; +import com.yahoo.vespa.model.test.SimpleService; +import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithFilePkg; +import org.junit.Test; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +/** + * @author bratseth + */ +public class SystemModelTestCase { + + private static final String TESTDIR = "src/test/cfg/application/"; + + private static VespaModel getVespaModelDoNotValidateXml(String configPath) { + ConfigModelRegistry registry = MapConfigModelRegistry.createFromList(new SimpleConfigModel.Builder(), new ApiConfigModel.Builder()); + VespaModelCreatorWithFilePkg creator = new VespaModelCreatorWithFilePkg(configPath,registry); + return creator.create(false); // do not validate against schema -- the xml files used here are not valid + } + + // Debugging + @SuppressWarnings({"UnusedDeclaration"}) + private void dumpTree(ConfigProducer producer) { + Map<String,? extends ConfigProducer> id2cp = producer.getChildren(); + for (ConfigProducer c : id2cp.values()) { + System.out.println("id: " + c.getConfigId()); + if (c.getChildren().size() > 0) { + dumpTree(c); + } + } + } + + @Test + public void testMetrics() { + VespaModel vespaModel = getVespaModelDoNotValidateXml(TESTDIR + "metricsconfig"); + SimpleService service0 = (SimpleService)vespaModel.getConfigProducer("simple/simpleservice.0").get(); + vespaModel.getConfigProducer("simple/simpleservice.1"); + assertThat(service0.getDefaultMetricDimensions().get("clustername"), is("testClusterName")); + } + + @Test + public void testVespaModel() { + VespaModel vespaModel = getVespaModelDoNotValidateXml(TESTDIR + "simpleconfig/"); + assertNotNull(vespaModel); + + assertEquals("There are two instances of the simple model + Routing and AdminModel (set up implicitly)", 4, vespaModel.configModelRepo().asMap().size()); + assertNotNull("One gets the default name as there is no explicit id", vespaModel.configModelRepo().asMap().get("simple")); + assertNotNull("The other gets the explicit id as name", vespaModel.configModelRepo().asMap().get("second")); + + ApplicationConfigProducerRoot root = vespaModel.getVespa(); + assertNotNull(root); + + // Verify configIds from vespa + assertTrue(6 <= root.getConfigIds().size()); + assertTrue(root.getConfigIds().contains("client")); + assertTrue(root.getConfigIds().contains("simple")); + assertTrue(root.getConfigIds().contains("second")); + assertTrue(root.getConfigIds().contains("simple/simpleservice.0")); + assertTrue(root.getConfigIds().contains("simple/simpleservice.1")); + assertTrue(root.getConfigIds().contains("second/simpleservice.0")); + + // Verify configIds from vespaModel + assertTrue(12 <= vespaModel.getConfigIds().size()); + String localhost = HostName.getLocalhost(); + String localhostConfigId = "hosts/" + localhost; + Set<String> configIds = vespaModel.getConfigIds(); + assertTrue(configIds.contains("client")); + assertTrue(configIds.contains(localhostConfigId)); + assertTrue(configIds.contains("simple/simpleservice.0")); + assertTrue(configIds.contains("second/simpleservice.0")); + assertTrue(configIds.contains("hosts/" + localhost + "/logd")); + + // Verify sentinel config + SentinelConfig sentinelConfig = new SentinelConfig((SentinelConfig.Builder) vespaModel.getConfig(new SentinelConfig.Builder(), localhostConfigId)); + boolean found = false; + for (SentinelConfig.Service service : sentinelConfig.service()) { + if ("logd".equals(service.name())) { + found = true; + } + } + assertTrue(found); + + // Get the simple model config from VespaModel + assertEquals(vespaModel.getConfig(StandardConfig.class, "simple/simpleservice.0").astring(), "simpleservice"); + assertEquals(vespaModel.getConfig(StandardConfig.class, "second/simpleservice.0").astring(), "simpleservice"); + } + + @Test + public void testHostSystem() { + VespaModel vespaModel = getVespaModelDoNotValidateXml(TESTDIR + "simpleconfig/"); + HostSystem hostSystem = vespaModel.getHostSystem(); + + HostResource host1 = hostSystem.getHost("host1"); + HostResource host2 = hostSystem.getHost("host2"); + HostResource host3 = hostSystem.getHost("host3"); + + assertEquals(host1, host2); + assertEquals(host2, host3); + + // all three host aliases are for the same host, so the number of services should be 3 + 8 + // (3 simpleservices and logd, configproxy, config sentinel, admin server config server, slobrok, log server and file distribution) + assertEquals(10, host1.getServices().size()); + + assertNotNull(host1.getService("simpleservice")); + assertNotNull(host1.getService("simpleservice2")); + assertNotNull(host3.getService("simpleservice3")); + } + + @Test + public void testBasePorts() { + VespaModel vespaModel = getVespaModelDoNotValidateXml(TESTDIR + "simpleconfig"); + assertNotNull(vespaModel); + + assertEquals(vespaModel.getConfig(StandardConfig.class, "simple/simpleservice.0").baseport(), 10000); + assertTrue(vespaModel.getConfig(StandardConfig.class, "simple/simpleservice.1").baseport() != 10000); + } + + /** + * This test is the same as the system test cloudconfig/plugins. + * Be sure to update it as well if you change this. + */ + @Test + public void testPlugins() { + VespaModel vespaModel = getVespaModelDoNotValidateXml(TESTDIR + "plugins"); + + assertNotNull(vespaModel); + ApplicationConfigProducerRoot root = vespaModel.getVespa(); + + assertEquals(5, vespaModel.configModelRepo().asMap().size()); + assertTrue(vespaModel.configModelRepo().asMap().keySet().contains("simple")); + assertTrue(vespaModel.configModelRepo().asMap().keySet().contains("api")); + assertTrue(root.getConfigIds().contains("simple/simpleservice.0")); + assertTrue(root.getConfigIds().contains("simple/simpleservice.1")); + assertTrue(root.getConfigIds().contains("api/apiservice.0")); + + // Verify that configModelRegistry iterates in dependency order + Iterator<ConfigModel> i = vespaModel.configModelRepo().iterator(); + ConfigModel plugin = i.next(); + assertEquals("admin", plugin.getId()); + plugin = i.next(); + assertEquals("simple", plugin.getId()); + plugin = i.next(); + assertEquals("simple2", plugin.getId()); + plugin = i.next(); + assertEquals("api", plugin.getId()); + plugin = i.next(); + assertEquals("routing", plugin.getId()); + + assertEquals(vespaModel.getConfig(StandardConfig.class, "api/apiservice.0").astring(), "apiservice"); + + assertEquals(vespaModel.getConfig(StandardConfig.class, "simple/simpleservice.0").astring(), "simpleservice"); + assertEquals(vespaModel.getConfig(StandardConfig.class, "simple/simpleservice.1").astring(), "simpleservice"); + assertEquals(vespaModel.getConfig(StandardConfig.class, "simple2/simpleservice.0").astring(), "simpleservice"); + } + + @Test + public void testEqualPlugins() { + try { + getVespaModelDoNotValidateXml(TESTDIR + "doubleconfig"); + fail("No exception upon two plugins with the same name"); + } catch (RuntimeException expected) { + assertThat(expected.getMessage(), is("Could not resolve tag <simpleplugin version=\"1.0\"> to a config model component")); + } + } + +} |