// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.application.api; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.RegionName; import org.junit.Test; import java.io.StringReader; import java.util.Optional; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * @author bratseth */ public class DeploymentSpecTest { @Test public void testSpec() { String specXml = "" + " " + ""; StringReader r = new StringReader(specXml); DeploymentSpec spec = DeploymentSpec.fromXml(r); assertEquals(specXml, spec.xmlForm()); assertEquals(1, spec.steps().size()); assertTrue(spec.steps().get(0).deploysTo(Environment.test)); assertTrue(spec.includes(Environment.test, Optional.empty())); assertFalse(spec.includes(Environment.test, Optional.of(RegionName.from("region1")))); assertFalse(spec.includes(Environment.staging, Optional.empty())); assertFalse(spec.includes(Environment.prod, Optional.empty())); assertFalse(spec.globalServiceId().isPresent()); } @Test public void stagingSpec() { StringReader r = new StringReader( "" + " " + "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); assertEquals(2, spec.steps().size()); assertTrue(spec.steps().get(0).deploysTo(Environment.test)); assertTrue(spec.steps().get(1).deploysTo(Environment.staging)); assertTrue(spec.includes(Environment.test, Optional.empty())); assertFalse(spec.includes(Environment.test, Optional.of(RegionName.from("region1")))); assertTrue(spec.includes(Environment.staging, Optional.empty())); assertFalse(spec.includes(Environment.prod, Optional.empty())); assertFalse(spec.globalServiceId().isPresent()); } @Test public void minimalProductionSpec() { StringReader r = new StringReader( "" + " " + " us-east1" + " us-west1" + " " + "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); assertEquals(4, spec.steps().size()); assertTrue(spec.steps().get(0).deploysTo(Environment.test)); assertTrue(spec.steps().get(1).deploysTo(Environment.staging)); assertTrue(spec.steps().get(2).deploysTo(Environment.prod, Optional.of(RegionName.from("us-east1")))); assertFalse(((DeploymentSpec.DeclaredZone)spec.steps().get(2)).active()); assertTrue(spec.steps().get(3).deploysTo(Environment.prod, Optional.of(RegionName.from("us-west1")))); assertTrue(((DeploymentSpec.DeclaredZone)spec.steps().get(3)).active()); assertTrue(spec.includes(Environment.test, Optional.empty())); assertFalse(spec.includes(Environment.test, Optional.of(RegionName.from("region1")))); assertTrue(spec.includes(Environment.staging, Optional.empty())); assertTrue(spec.includes(Environment.prod, Optional.of(RegionName.from("us-east1")))); assertTrue(spec.includes(Environment.prod, Optional.of(RegionName.from("us-west1")))); assertFalse(spec.includes(Environment.prod, Optional.of(RegionName.from("no-such-region")))); assertFalse(spec.globalServiceId().isPresent()); assertEquals(DeploymentSpec.UpgradePolicy.defaultPolicy, spec.upgradePolicy()); } @Test public void maximalProductionSpec() { StringReader r = new StringReader( "" + " " + " " + " " + " " + " us-east1" + " us-east1" + " " + " us-west1" + " " + "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); assertEquals(5, spec.steps().size()); assertEquals(4, spec.zones().size()); assertTrue(spec.steps().get(0).deploysTo(Environment.test)); assertTrue(spec.steps().get(1).deploysTo(Environment.staging)); assertTrue(spec.steps().get(2).deploysTo(Environment.prod, Optional.of(RegionName.from("us-east1")))); assertFalse(((DeploymentSpec.DeclaredZone)spec.steps().get(2)).active()); assertTrue(spec.steps().get(3) instanceof DeploymentSpec.Delay); assertEquals(3 * 60 * 60 + 30 * 60, ((DeploymentSpec.Delay)spec.steps().get(3)).duration().getSeconds()); assertTrue(spec.steps().get(4).deploysTo(Environment.prod, Optional.of(RegionName.from("us-west1")))); assertTrue(((DeploymentSpec.DeclaredZone)spec.steps().get(4)).active()); assertTrue(spec.includes(Environment.test, Optional.empty())); assertFalse(spec.includes(Environment.test, Optional.of(RegionName.from("region1")))); assertTrue(spec.includes(Environment.staging, Optional.empty())); assertTrue(spec.includes(Environment.prod, Optional.of(RegionName.from("us-east1")))); assertTrue(spec.includes(Environment.prod, Optional.of(RegionName.from("us-west1")))); assertFalse(spec.includes(Environment.prod, Optional.of(RegionName.from("no-such-region")))); assertFalse(spec.globalServiceId().isPresent()); } @Test public void productionSpecWithGlobalServiceId() { StringReader r = new StringReader( "" + " " + " us-east-1" + " us-west-1" + " " + "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); assertEquals(spec.globalServiceId(), Optional.of("query")); } @Test(expected=IllegalArgumentException.class) public void globalServiceIdInTest() { StringReader r = new StringReader( "" + " " + "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); } @Test(expected=IllegalArgumentException.class) public void globalServiceIdInStaging() { StringReader r = new StringReader( "" + " " + "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); } @Test public void productionSpecWithGlobalServiceIdBeforeStaging() { StringReader r = new StringReader( "" + " " + " " + " us-west-1" + " us-central-1" + " us-east-3" + " " + " " + "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); assertEquals("qrs", spec.globalServiceId().get()); } @Test public void productionSpecWithUpgradePolicy() { StringReader r = new StringReader( "" + " " + " " + " us-west-1" + " us-central-1" + " us-east-3" + " " + "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); assertEquals("canary", spec.upgradePolicy().toString()); } @Test public void maxDelayExceeded() { try { StringReader r = new StringReader( "" + " " + " " + " us-west-1" + " " + " us-central-1" + " " + " us-east-3" + " " + "" ); DeploymentSpec.fromXml(r); fail("Expected exception due to exceeding the max total delay"); } catch (IllegalArgumentException e) { // success assertEquals("The total delay specified is PT24H1S but max 24 hours is allowed", e.getMessage()); } } @Test public void testEmpty() { assertFalse(DeploymentSpec.empty.globalServiceId().isPresent()); assertEquals(DeploymentSpec.UpgradePolicy.defaultPolicy, DeploymentSpec.empty.upgradePolicy()); assertTrue(DeploymentSpec.empty.steps().isEmpty()); assertEquals("", DeploymentSpec.empty.xmlForm()); } @Test public void productionSpecWithParallelDeployments() { StringReader r = new StringReader( "\n" + " \n" + " us-west-1\n" + " \n" + " us-central-1\n" + " us-east-3\n" + " \n" + " \n" + "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); DeploymentSpec.ParallelZones parallelZones = ((DeploymentSpec.ParallelZones) spec.steps().get(3)); assertEquals(2, parallelZones.zones().size()); assertEquals(RegionName.from("us-central-1"), parallelZones.zones().get(0).region().get()); assertEquals(RegionName.from("us-east-3"), parallelZones.zones().get(1).region().get()); } @Test public void productionSpecWithDuplicateRegions() { StringReader r = new StringReader( "\n" + " \n" + " us-west-1\n" + " \n" + " us-west-1\n" + " us-central-1\n" + " us-east-3\n" + " \n" + " \n" + " eu-west-1\n" + " us-central-1\n" + " \n" + " \n" + "" ); try { DeploymentSpec.fromXml(r); fail("Expected exception"); } catch (IllegalArgumentException e) { assertEquals("prod.us-west-1 is listed twice in deployment.xml", e.getMessage()); } } }