http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/DropletStatusToStatusTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/DropletStatusToStatusTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/DropletStatusToStatusTest.java new file mode 100644 index 0000000..9da855c --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/DropletStatusToStatusTest.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.compute.functions; + +import static org.jclouds.compute.domain.NodeMetadata.Status.UNRECOGNIZED; +import static org.testng.Assert.assertNotEquals; + +import org.jclouds.digitalocean2.domain.Droplet.Status; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "DropletStatusToStatusTest") +public class DropletStatusToStatusTest { + + @Test + public void testAllStatesHaveMapping() { + DropletStatusToStatus function = new DropletStatusToStatus(); + for (Status status : Status.values()) { + assertNotEquals(function.apply(status), UNRECOGNIZED); + } + + } +}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/DropletToNodeMetadataTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/DropletToNodeMetadataTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/DropletToNodeMetadataTest.java new file mode 100644 index 0000000..27dbad9 --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/DropletToNodeMetadataTest.java @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.compute.functions; + +import static com.google.common.collect.Iterables.getOnlyElement; +import static org.jclouds.compute.domain.Image.Status.AVAILABLE; +import static org.jclouds.compute.domain.NodeMetadata.Status.RUNNING; +import static org.jclouds.digitalocean2.domain.Droplet.Status.ACTIVE; +import static org.testng.Assert.assertEquals; + +import java.text.ParseException; +import java.util.Date; +import java.util.Map; +import java.util.Set; + +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.ImageBuilder; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadataBuilder; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.domain.Processor; +import org.jclouds.compute.domain.Volume.Type; +import org.jclouds.compute.domain.VolumeBuilder; +import org.jclouds.compute.functions.GroupNamingConvention; +import org.jclouds.digitalocean2.domain.Droplet; +import org.jclouds.digitalocean2.domain.Networks; +import org.jclouds.digitalocean2.domain.Networks.Address; +import org.jclouds.digitalocean2.domain.Region; +import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.jclouds.domain.LoginCredentials; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.inject.Guice; + +@Test(groups = "unit", testName = "DropletToNodeMetadataTest") +public class DropletToNodeMetadataTest { + + private org.jclouds.digitalocean2.domain.Image image; + + private Region region; + + private Set<Hardware> hardwares; + + private Set<Image> images; + + private Set<Location> locations; + + private LoginCredentials credentials; + + private DropletToNodeMetadata function; + + @BeforeMethod + public void setup() { + image = org.jclouds.digitalocean2.domain.Image.create(1, "14.04 x64", + "distribution", "Ubuntu", "ubuntu-1404-x86", true, ImmutableList.of("sfo1"), new Date()); + region = Region.create("sfo1", "San Francisco 1", ImmutableList.of("2gb"), true, ImmutableList.<String> of()); + + images = ImmutableSet.of(new ImageBuilder() + .id("ubuntu-1404-x86") + .providerId("1") + .name("mock image") + .status(AVAILABLE) + .operatingSystem( + OperatingSystem.builder().name("Ubuntu 14.04 x86_64").description("Ubuntu").family(OsFamily.UBUNTU) + .version("10.04").arch("x86_64").is64Bit(true).build()).build()); + + hardwares = ImmutableSet.of(new HardwareBuilder().id("2gb").providerId("2gb").name("mock hardware") + .processor(new Processor(1.0, 1.0)).ram(2048) + .volume(new VolumeBuilder().size(20f).type(Type.LOCAL).build()).build()); + + locations = ImmutableSet.of(new LocationBuilder() + .id("sfo1") + .description("sfo1/San Francisco 1") + .scope(LocationScope.REGION) + .parent( + new LocationBuilder().id("0").description("mock parent location").scope(LocationScope.PROVIDER) + .build()).build()); + + credentials = LoginCredentials.builder().user("foo").password("bar").build(); + + function = createNodeParser(hardwares, images, locations, ImmutableMap.of("node#1", (Credentials) credentials)); + } + + @Test + public void testConvertDroplet() throws ParseException { + Droplet droplet = Droplet.create( + 1, + "mock-droplet", + 1, + 1, + 1, + false, + new Date(), + Droplet.Status.ACTIVE, + ImmutableList.<Integer> of(), + ImmutableList.<Integer> of(), + ImmutableList.<String> of(), + region, + image, + null, + "2gb", + Networks.create( + ImmutableList.of(Address.create("84.45.69.3", "255.255.255.0", "84.45.69.1", "public"), + Address.create("192.168.2.5", "255.255.255.0", "192.168.2.1", "private")), + ImmutableList.<Networks.Address> of()), null); + + NodeMetadata expected = new NodeMetadataBuilder().ids("1").hardware(getOnlyElement(hardwares)) + .imageId("ubuntu-1404-x86").status(RUNNING).location(getOnlyElement(locations)).name("mock-droplet") + .hostname("mock-droplet").group("mock").credentials(credentials) + .publicAddresses(ImmutableSet.of("84.45.69.3")).privateAddresses(ImmutableSet.of("192.168.2.5")) + .providerId("1").backendStatus(ACTIVE.name()).operatingSystem(getOnlyElement(images).getOperatingSystem()) + .build(); + + NodeMetadata actual = function.apply(droplet); + assertNodeEquals(actual, expected); + } + + @Test + public void testConvertDropletOldImage() throws ParseException { + // Use an image id that is not in the list of images + org.jclouds.digitalocean2.domain.Image image = org.jclouds.digitalocean2.domain.Image.create(2, "14.04 x64", + "distribution", "Ubuntu", "ubuntu2-1404-x86", true, ImmutableList.of("sfo1"), new Date()); + + Droplet droplet = Droplet.create( + 1, + "mock-droplet", + 1, + 1, + 1, + false, + new Date(), + Droplet.Status.ACTIVE, + ImmutableList.<Integer> of(), + ImmutableList.<Integer> of(), + ImmutableList.<String> of(), + region, + image, + null, + "2gb", + Networks.create( + ImmutableList.of(Address.create("84.45.69.3", "255.255.255.0", "84.45.69.1", "public"), + Address.create("192.168.2.5", "255.255.255.0", "192.168.2.1", "private")), + ImmutableList.<Networks.Address> of()), null); + + NodeMetadata expected = new NodeMetadataBuilder().ids("1").hardware(getOnlyElement(hardwares)).imageId(null) + .status(RUNNING).location(getOnlyElement(locations)).name("mock-droplet").hostname("mock-droplet") + .group("mock").credentials(credentials).publicAddresses(ImmutableSet.of("84.45.69.3")) + .privateAddresses(ImmutableSet.of("192.168.2.5")).providerId("1").backendStatus(ACTIVE.name()) + .operatingSystem(null).build(); + + NodeMetadata actual = function.apply(droplet); + assertNodeEquals(actual, expected); + } + + private static void assertNodeEquals(NodeMetadata actual, NodeMetadata expected) { + assertEquals(actual, expected); + // NodeMetadata equals method does not use all fields in equals. It assumes that same ids in same locations + // determine the equivalence + assertEquals(actual.getStatus(), expected.getStatus()); + assertEquals(actual.getBackendStatus(), expected.getBackendStatus()); + assertEquals(actual.getLoginPort(), expected.getLoginPort()); + assertEquals(actual.getPublicAddresses(), expected.getPublicAddresses()); + assertEquals(actual.getPrivateAddresses(), expected.getPrivateAddresses()); + assertEquals(actual.getCredentials(), expected.getCredentials()); + assertEquals(actual.getGroup(), expected.getGroup()); + assertEquals(actual.getImageId(), expected.getImageId()); + assertEquals(actual.getHardware(), expected.getHardware()); + assertEquals(actual.getOperatingSystem(), expected.getOperatingSystem()); + assertEquals(actual.getHostname(), expected.getHostname()); + } + + private DropletToNodeMetadata createNodeParser(final Set<Hardware> hardware, final Set<Image> images, + final Set<Location> locations, Map<String, Credentials> credentialStore) { + Supplier<Set<? extends Location>> locationSupplier = new Supplier<Set<? extends Location>>() { + @Override + public Set<? extends Location> get() { + return locations; + } + }; + + Supplier<Map<String, ? extends Hardware>> hardwareSupplier = new Supplier<Map<String, ? extends Hardware>>() { + @Override + public Map<String, ? extends Hardware> get() { + return Maps.uniqueIndex(hardware, new Function<Hardware, String>() { + @Override + public String apply(Hardware input) { + return input.getId(); + } + }); + } + }; + + Supplier<Map<String, ? extends Image>> imageSupplier = new Supplier<Map<String, ? extends Image>>() { + @Override + public Map<String, ? extends Image> get() { + return Maps.uniqueIndex(images, new Function<Image, String>() { + @Override + public String apply(Image input) { + return input.getId(); + } + }); + } + }; + + GroupNamingConvention.Factory namingConvention = Guice.createInjector().getInstance(GroupNamingConvention.Factory.class); + + return new DropletToNodeMetadata(imageSupplier, hardwareSupplier, locationSupplier, new DropletStatusToStatus(), + namingConvention, credentialStore); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/ImageToImageTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/ImageToImageTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/ImageToImageTest.java new file mode 100644 index 0000000..6ab020c --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/ImageToImageTest.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.compute.functions; + +import static org.jclouds.compute.domain.Image.Status.AVAILABLE; +import static org.testng.Assert.assertEquals; + +import java.util.Date; + +import org.jclouds.compute.domain.ImageBuilder; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.digitalocean2.domain.Image; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +@Test(groups = "unit", testName = "ImageToImageTest") +public class ImageToImageTest { + + @Test + public void testConvertImage() { + Image image = Image.create(1, "14.04 x64", "distribution", "Ubuntu", "ubuntu-1404-x86", true, + ImmutableList.of("sfo1"), new Date()); + org.jclouds.compute.domain.Image expected = new ImageBuilder() + .id("ubuntu-1404-x86") + .providerId("1") + .name("14.04 x64") + .description("Ubuntu 14.04 x64") + .status(AVAILABLE) + .operatingSystem( + OperatingSystem.builder().name("Ubuntu").description("Ubuntu 14.04 x64").family(OsFamily.UBUNTU) + .version("14.04").arch("x64").is64Bit(true).build()) + .userMetadata(ImmutableMap.of("publicImage", "true")).build(); + + org.jclouds.compute.domain.Image result = new ImageToImage().apply(image); + assertEquals(result, expected); + assertEquals(result.getDescription(), expected.getDescription()); + assertEquals(result.getOperatingSystem(), expected.getOperatingSystem()); + assertEquals(result.getStatus(), expected.getStatus()); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/RegionToLocationTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/RegionToLocationTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/RegionToLocationTest.java new file mode 100644 index 0000000..879091b --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/RegionToLocationTest.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.compute.functions; + +import static com.google.common.collect.Iterables.getOnlyElement; +import static org.testng.Assert.assertEquals; + +import java.net.URI; + +import org.jclouds.digitalocean2.DigitalOcean2ProviderMetadata; +import org.jclouds.digitalocean2.domain.Region; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.jclouds.location.suppliers.all.JustProvider; +import org.testng.annotations.Test; + +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +@Test(groups = "unit", testName = "RegionToLocationTest") +public class RegionToLocationTest { + + @Test + public void testConvertRegion() { + DigitalOcean2ProviderMetadata metadata = new DigitalOcean2ProviderMetadata(); + JustProvider locationsSupplier = new JustProvider(metadata.getId(), Suppliers.<URI> ofInstance(URI + .create(metadata.getEndpoint())), ImmutableSet.<String> of()); + + Region region = Region.create("reg1", "Region1", ImmutableList.<String> of(), true, ImmutableList.<String> of()); + Location expected = new LocationBuilder().id("reg1").description("reg1/Region 1") + .parent(getOnlyElement(locationsSupplier.get())).scope(LocationScope.REGION).build(); + + RegionToLocation function = new RegionToLocation(locationsSupplier); + assertEquals(function.apply(region), expected); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/SizeToHardwareTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/SizeToHardwareTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/SizeToHardwareTest.java new file mode 100644 index 0000000..cba55bf --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/SizeToHardwareTest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.compute.functions; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.Processor; +import org.jclouds.compute.domain.Volume.Type; +import org.jclouds.compute.domain.VolumeBuilder; +import org.jclouds.digitalocean2.domain.Size; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +/** + * Unit tests for the {@link SizeToHardware} class. + */ +@Test(groups = "unit", testName = "SizeToHardwareTest") +public class SizeToHardwareTest { + + @Test + public void testConvertSize() { + Size size = Size.create("2gb", true, 1.0f, 10f, 0.05f, 2048, 1, 20, ImmutableList.<String> of()); + Hardware expected = new HardwareBuilder().id("2gb").providerId("2gb").name("2gb") + .processor(new Processor(1.0, 1.0)).ram(2048) + .volume(new VolumeBuilder().size(20f).type(Type.LOCAL).build()) + .userMetadata(ImmutableMap.of("costPerHour", "0.05", "costPerMonth", "10")).build(); + + SizeToHardware function = new SizeToHardware(); + assertEquals(function.apply(size), expected); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/TemplateOptionsToStatementWithoutPublicKeyTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/TemplateOptionsToStatementWithoutPublicKeyTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/TemplateOptionsToStatementWithoutPublicKeyTest.java new file mode 100644 index 0000000..c3a6cd2 --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/functions/TemplateOptionsToStatementWithoutPublicKeyTest.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.compute.functions; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import java.util.Map; + +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.scriptbuilder.domain.OsFamily; +import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.scriptbuilder.domain.StatementList; +import org.jclouds.scriptbuilder.statements.ssh.InstallRSAPrivateKey; +import org.jclouds.ssh.SshKeys; +import org.testng.annotations.Test; + +/** + * Unit tests for the {@link TemplateOptionsToStatementWithoutPublicKey} class. + */ +@Test(groups = "unit", testName = "TemplateOptionsToStatementWithoutPublicKeyTest") +public class TemplateOptionsToStatementWithoutPublicKeyTest { + + @Test + public void testPublicKeyDoesNotGenerateAuthorizePublicKeyStatementIfOnlyPublicKeyOptionsConfigured() { + Map<String, String> keys = SshKeys.generate(); + TemplateOptions options = TemplateOptions.Builder.authorizePublicKey(keys.get("public")); + + TemplateOptionsToStatementWithoutPublicKey function = new TemplateOptionsToStatementWithoutPublicKey(); + assertNull(function.apply(options)); + } + + @Test + public void testPublicAndRunScriptKeyDoesNotGenerateAuthorizePublicKeyStatementIfRunScriptPresent() { + Map<String, String> keys = SshKeys.generate(); + TemplateOptions options = TemplateOptions.Builder.authorizePublicKey(keys.get("public")).runScript("uptime"); + + TemplateOptionsToStatementWithoutPublicKey function = new TemplateOptionsToStatementWithoutPublicKey(); + Statement statement = function.apply(options); + + assertEquals(statement.render(OsFamily.UNIX), "uptime\n"); + } + + @Test + public void testPublicAndPrivateKeyAndRunScriptDoesNotGenerateAuthorizePublicKeyStatementIfOtherOptionsPresent() { + Map<String, String> keys = SshKeys.generate(); + TemplateOptions options = TemplateOptions.Builder.authorizePublicKey(keys.get("public")) + .installPrivateKey(keys.get("private")).runScript("uptime"); + + TemplateOptionsToStatementWithoutPublicKey function = new TemplateOptionsToStatementWithoutPublicKey(); + Statement statement = function.apply(options); + + assertTrue(statement instanceof StatementList); + StatementList statements = (StatementList) statement; + + assertEquals(statements.size(), 2); + assertEquals(statements.get(0).render(OsFamily.UNIX), "uptime\n"); + assertTrue(statements.get(1) instanceof InstallRSAPrivateKey); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/options/DigitalOcean2TemplateOptionsTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/options/DigitalOcean2TemplateOptionsTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/options/DigitalOcean2TemplateOptionsTest.java new file mode 100644 index 0000000..982224c --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/options/DigitalOcean2TemplateOptionsTest.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.compute.options; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.compute.options.TemplateOptions; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +@Test(groups = "unit", testName = "DigitalOcean2TemplateOptionsTest") +public class DigitalOcean2TemplateOptionsTest { + + @Test + public void testSShKeyIds() { + TemplateOptions options = new DigitalOcean2TemplateOptions().sshKeyIds(ImmutableSet.of(1, 2, 3)); + assertEquals(options.as(DigitalOcean2TemplateOptions.class).getSshKeyIds(), ImmutableSet.of(1, 2, 3)); + } + + @Test + public void testPrivateNetworking() { + TemplateOptions options = new DigitalOcean2TemplateOptions().privateNetworking(true); + assertEquals(options.as(DigitalOcean2TemplateOptions.class).getPrivateNetworking(), true); + } + + @Test + public void testBackupsEnabled() { + TemplateOptions options = new DigitalOcean2TemplateOptions().backupsEnabled(true); + assertEquals(options.as(DigitalOcean2TemplateOptions.class).getBackupsEnabled(), true); + } + + @Test + public void testAutoCreateKeyPair() { + TemplateOptions options = new DigitalOcean2TemplateOptions().autoCreateKeyPair(false); + assertEquals(options.as(DigitalOcean2TemplateOptions.class).getAutoCreateKeyPair(), false); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/domain/OperatingSystemTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/domain/OperatingSystemTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/domain/OperatingSystemTest.java new file mode 100644 index 0000000..d6bd0fc --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/domain/OperatingSystemTest.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.domain; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "OperatingSystemTest") +public class OperatingSystemTest { + + public void testParseStandard64bit() { + OperatingSystem os = OperatingSystem.create("12.10 x64", "Ubuntu"); + + assertEquals(os.distribution(), Distribution.UBUNTU); + assertEquals(os.version(), "12.10"); + assertEquals(os.arch(), "x64"); + assertTrue(os.is64bit()); + } + + public void testLongVersionStandard64bit() { + OperatingSystem os = OperatingSystem.create("12.10.1 x64", "Ubuntu"); + + assertEquals(os.distribution(), Distribution.UBUNTU); + assertEquals(os.version(), "12.10.1"); + assertEquals(os.arch(), "x64"); + assertTrue(os.is64bit()); + } + + public void testParseStandard64bitWithPrefix() { + OperatingSystem os = OperatingSystem.create("Arch Linux 12.10 x64 Desktop", "Arch Linux"); + + assertEquals(os.distribution(), Distribution.ARCHLINUX); + assertEquals(os.version(), "12.10"); + assertEquals(os.arch(), "x64"); + assertTrue(os.is64bit()); + } + + public void testParseStandard() { + OperatingSystem os = OperatingSystem.create("12.10 x32", "Ubuntu"); + + assertEquals(os.distribution(), Distribution.UBUNTU); + assertEquals(os.version(), "12.10"); + assertEquals(os.arch(), "x32"); + assertFalse(os.is64bit()); + + os = OperatingSystem.create("6.5 x64", "CentOS"); + + assertEquals(os.distribution(), Distribution.CENTOS); + assertEquals(os.version(), "6.5"); + assertEquals(os.arch(), "x64"); + assertTrue(os.is64bit()); + + os = OperatingSystem.create("6.5 x64", "Centos"); + + assertEquals(os.distribution(), Distribution.CENTOS); + assertEquals(os.version(), "6.5"); + assertEquals(os.arch(), "x64"); + assertTrue(os.is64bit()); + } + + public void testParseNoArch() { + OperatingSystem os = OperatingSystem.create("12.10", "Ubuntu"); + + assertEquals(os.distribution(), Distribution.UBUNTU); + assertEquals(os.version(), "12.10"); + assertEquals(os.arch(), ""); + assertFalse(os.is64bit()); + } + + public void testParseNoVersion() { + OperatingSystem os = OperatingSystem.create("x64", "Ubuntu"); + + assertEquals(os.distribution(), Distribution.UBUNTU); + assertEquals(os.version(), ""); + assertEquals(os.arch(), "x64"); + assertTrue(os.is64bit()); + } + + public void testParseUnknownDistribution() { + OperatingSystem os = OperatingSystem.create("12.04 x64", "Foo"); + + assertEquals(os.distribution(), Distribution.UNRECOGNIZED); + assertEquals(os.version(), "12.04"); + assertEquals(os.arch(), "x64"); + assertTrue(os.is64bit()); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ActionApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ActionApiLiveTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ActionApiLiveTest.java new file mode 100644 index 0000000..44a9a17 --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ActionApiLiveTest.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.features; + +import static org.jclouds.digitalocean2.domain.options.ImageListOptions.Builder.page; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import static org.testng.util.Strings.isNullOrEmpty; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.jclouds.digitalocean2.domain.Action; +import org.jclouds.digitalocean2.internal.BaseDigitalOcean2ApiLiveTest; +import org.testng.annotations.Test; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; + +@Test(groups = "live", testName = "ActionApiLiveTest") +public class ActionApiLiveTest extends BaseDigitalOcean2ApiLiveTest { + + public void testListActions() { + final AtomicInteger found = new AtomicInteger(0); + // DigitalOcean return 25 records per page by default. Inspect at most 2 pages + assertTrue(api().list().concat().limit(50).allMatch(new Predicate<Action>() { + @Override + public boolean apply(Action input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.type()); + } + }), "All actions must have the 'type' field populated"); + assertTrue(found.get() > 0, "Expected some actions to be returned"); + } + + public void testListActionsOnePage() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(api().list(page(1).perPage(5)).allMatch(new Predicate<Action>() { + @Override + public boolean apply(Action input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.type()); + } + }), "All actions must have the 'type' field populated"); + assertTrue(found.get() > 0, "Expected some actions to be returned"); + } + + public void testGetAction() { + Optional<Action> first = api().list().concat().first(); + assertTrue(first.isPresent(), "At least one action was expected to exist"); + assertNotNull(api().get(first.get().id())); + } + + private ActionApi api() { + return api.actionApi(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ActionApiMockTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ActionApiMockTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ActionApiMockTest.java new file mode 100644 index 0000000..aa890d5 --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ActionApiMockTest.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.features; + +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.collect.Iterables.size; +import static org.jclouds.digitalocean2.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import java.util.Map; + +import org.jclouds.digitalocean2.domain.Action; +import org.jclouds.digitalocean2.internal.BaseDigitalOcean2ApiMockTest; +import org.testng.annotations.Test; + +import com.google.common.reflect.TypeToken; + +@Test(groups = "unit", testName = "ActionApiMockTest", singleThreaded = true) +public class ActionApiMockTest extends BaseDigitalOcean2ApiMockTest { + + public void testListActions() throws InterruptedException { + server.enqueue(jsonResponse("/actions-first.json")); + server.enqueue(jsonResponse("/actions-last.json")); + + Iterable<Action> actions = api.actionApi().list().concat(); + + assertEquals(size(actions), 8); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/actions"); + assertSent(server, "GET", "/actions?page=2&per_page=5"); + } + + public void testListActionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Action> actions = api.actionApi().list().concat(); + + assertTrue(isEmpty(actions)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/actions"); + } + + public void testListActionsWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/actions-first.json")); + + Iterable<Action> actions = api.actionApi().list(page(1).perPage(5)); + + assertEquals(size(actions), 5); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/actions?page=1&per_page=5"); + } + + public void testListActionsWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Action> actions = api.actionApi().list(page(1).perPage(5)); + + assertTrue(isEmpty(actions)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/actions?page=1&per_page=5"); + } + + public void testGetAction() throws InterruptedException { + server.enqueue(jsonResponse("/action.json")); + + Action action = api.actionApi().get(1); + + assertEquals(action, actionFromResource("/action.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/actions/1"); + } + + public void testGetActionReturns404() throws InterruptedException { + server.enqueue(response404()); + + Action action = api.actionApi().get(1); + + assertNull(action); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/actions/1"); + } + + private Action actionFromResource(String resource) { + return onlyObjectFromResource(resource, new TypeToken<Map<String, Action>>() { + private static final long serialVersionUID = 1L; + }); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/DropletApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/DropletApiLiveTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/DropletApiLiveTest.java new file mode 100644 index 0000000..f451d2e --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/DropletApiLiveTest.java @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.features; + +import static com.google.common.collect.Iterables.getOnlyElement; +import static java.util.logging.Logger.getAnonymousLogger; +import static org.jclouds.digitalocean2.domain.Droplet.Status.ACTIVE; +import static org.jclouds.digitalocean2.domain.Droplet.Status.OFF; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import java.util.List; +import java.util.Map; + +import org.jclouds.compute.ComputeTestUtils; +import org.jclouds.digitalocean2.domain.Action; +import org.jclouds.digitalocean2.domain.Backup; +import org.jclouds.digitalocean2.domain.Droplet; +import org.jclouds.digitalocean2.domain.DropletCreate; +import org.jclouds.digitalocean2.domain.Image; +import org.jclouds.digitalocean2.domain.Kernel; +import org.jclouds.digitalocean2.domain.Key; +import org.jclouds.digitalocean2.domain.Region; +import org.jclouds.digitalocean2.domain.Size; +import org.jclouds.digitalocean2.domain.Snapshot; +import org.jclouds.digitalocean2.domain.options.CreateDropletOptions; +import org.jclouds.digitalocean2.internal.BaseDigitalOcean2ApiLiveTest; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; + +@Test(groups = "live", testName = "DropletApiLiveTest") +public class DropletApiLiveTest extends BaseDigitalOcean2ApiLiveTest { + + private Region region; + private Size size; + private Image image; + private Key key; + private int dropletId = -1; + + @BeforeClass + public void setupDroplet() { + region = firstAvailableRegion(); + size = cheapestSizeInRegion(region); + image = ubuntuImageInRegion(region); + + Map<String, String> keyPair = ComputeTestUtils.setupKeyPair(); + key = api.keyApi().create(prefix + "-droplet-livetest", keyPair.get("public")); + } + + @AfterClass(alwaysRun = true) + public void tearDown() { + if (key != null) { + api.keyApi().delete(key.id()); + } + } + + public void testCreate() { + DropletCreate dropletCreate = api().create(prefix + "-droplet-livetest", region.slug(), size.slug(), image.slug(), + CreateDropletOptions.builder().backupsEnabled(true).addSshKeyId(key.id()).build()); + assertActionCompleted(getOnlyElement(dropletCreate.links().actions()).id()); + dropletId = dropletCreate.droplet().id(); + Droplet droplet = api().get(dropletId); + assertNotNull(droplet, "Droplet should not be null"); + } + + @Test(groups = "live", dependsOnMethods = "testCreate") + public void testListDroplets() { + assertTrue(api().list().concat().anyMatch(new Predicate<Droplet>() { + @Override + public boolean apply(Droplet input) { + return input.id() == dropletId; + } + }), "The created droplet must be in the list"); + } + + @Test(dependsOnMethods = "testCreate") + public void testListKernels() { + Iterable<Kernel> kernels = api().listKernels(dropletId).concat(); + assertEquals(kernels.iterator().next().name(), "DO-recovery-static-fsck"); + } + + @Test(dependsOnMethods = "testListKernels") + public void testPowerOff() { + Action action = api().powerOff(dropletId); + assertActionCompleted(action.id()); + Droplet droplet = api().get(dropletId); + assertEquals(droplet.status(), OFF, "Droplet should be off"); + } + + @Test(groups = "live", dependsOnMethods = "testPowerOff") + public void testSnapshots() { + Action action = api().snapshot(dropletId, prefix + dropletId + "-snapshot"); + assertActionCompleted(action.id()); + + List<Snapshot> snapshots = api().listSnapshots(dropletId).concat().toList(); + assertEquals(snapshots.size(), 1, "Must contain 1 snapshot"); + + for (Snapshot snapshot : snapshots) { + try { + api.imageApi().delete(snapshot.id()); + } catch (Exception ex) { + getAnonymousLogger().warning("Could not delete snapshot: " + snapshot.id()); + } + } + } + + @Test(groups = "live", dependsOnMethods = "testSnapshots") + public void testBackups() { + Iterable<Backup> backups = api().listBackups(dropletId).concat(); + // Backups are automatically taken by DO on a weekly basis, so we can't guarantee + // there will be any backup available. Just check that the call succeeds + assertNotNull(backups); + } + + @Test(groups = "live", dependsOnMethods = "testSnapshots") + public void testListActions() { + FluentIterable<Action> actions = api().listActions(dropletId).concat(); + assertTrue(actions.anyMatch(new Predicate<Action>() { + @Override + public boolean apply(Action input) { + return "snapshot".equals(input.type()); + } + })); + } + + @Test(groups = "live", dependsOnMethods = "testSnapshots") + public void testPowerOn() { + // Apparently droplets are automatically powered on after the snapshot process + Action action = api().powerOff(dropletId); + assertActionCompleted(action.id()); + + action = api().powerOn(dropletId); + assertActionCompleted(action.id()); + Droplet droplet = api().get(dropletId); + assertEquals(droplet.status(), ACTIVE, "Droplet should be Active"); + } + + @Test(groups = "live", dependsOnMethods = "testPowerOn") + public void testReboot() { + Action action = api().reboot(dropletId); + assertActionCompleted(action.id()); + Droplet droplet = api().get(dropletId); + assertEquals(droplet.status(), ACTIVE, "Droplet should be off"); + } + + @Test(groups = "live", dependsOnMethods = "testReboot") + public void testPowerCycle() { + Action action = api().powerCycle(dropletId); + assertActionCompleted(action.id()); + Droplet droplet = api().get(dropletId); + assertEquals(droplet.status(), ACTIVE, "Droplet should be off"); + } + + @Test(groups = "live", dependsOnMethods = "testPowerCycle") + public void testShutdown() { + Action action = api().shutdown(dropletId); + assertActionCompleted(action.id()); + // The shutdown action can fail if the shutdown command fails in the guest OS + // We can not guarantee that a graceful shutdown action will en up in the droplet + // being in OFF state + } + + @Test(groups = "live", dependsOnMethods = "testShutdown", alwaysRun = true) + public void testDelete() throws InterruptedException { + if (dropletId != -1) { + api().delete(dropletId); + assertNodeTerminated(dropletId); + assertNull(api().get(dropletId)); + } + } + + private DropletApi api() { + return api.dropletApi(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/DropletApiMockTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/DropletApiMockTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/DropletApiMockTest.java new file mode 100644 index 0000000..dcd6352 --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/DropletApiMockTest.java @@ -0,0 +1,401 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.features; + +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.collect.Iterables.size; +import static org.jclouds.digitalocean2.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import java.util.Map; + +import org.jclouds.digitalocean2.domain.Action; +import org.jclouds.digitalocean2.domain.Backup; +import org.jclouds.digitalocean2.domain.Droplet; +import org.jclouds.digitalocean2.domain.DropletCreate; +import org.jclouds.digitalocean2.domain.Kernel; +import org.jclouds.digitalocean2.domain.Snapshot; +import org.jclouds.digitalocean2.domain.options.CreateDropletOptions; +import org.jclouds.digitalocean2.internal.BaseDigitalOcean2ApiMockTest; +import org.testng.annotations.Test; + +import com.google.common.reflect.TypeToken; + +@Test(groups = "unit", testName = "DropletApiMockTest", singleThreaded = true) +public class DropletApiMockTest extends BaseDigitalOcean2ApiMockTest { + + public void testListDroplets() throws InterruptedException { + server.enqueue(jsonResponse("/droplets-first.json")); + server.enqueue(jsonResponse("/droplets-last.json")); + + Iterable<Droplet> droplets = api.dropletApi().list().concat(); + + assertEquals(size(droplets), 2); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/droplets"); + assertSent(server, "GET", "/droplets?page=2&per_page=1"); + } + + public void testListDropletsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Droplet> droplets = api.dropletApi().list().concat(); + + assertTrue(isEmpty(droplets)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets"); + } + + public void testListDropletsWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/droplets-first.json")); + + Iterable<Droplet> droplets = api.dropletApi().list(page(1).perPage(20)); + + assertEquals(size(droplets), 1); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/droplets?page=1&per_page=20"); + } + + public void testListDropletsWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Droplet> droplets = api.dropletApi().list(page(1).perPage(20)); + + assertTrue(isEmpty(droplets)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets?page=1&per_page=20"); + } + + public void testGetDroplet() throws InterruptedException { + server.enqueue(jsonResponse("/droplet.json")); + + Droplet droplet = api.dropletApi().get(1); + + assertEquals(droplet, dropletFromResource("/droplet.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets/1"); + } + + public void testGetDropletReturns404() throws InterruptedException { + server.enqueue(response404()); + + Droplet droplet = api.dropletApi().get(1); + + assertNull(droplet); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets/1"); + } + + public void testCreateDroplet() throws InterruptedException { + server.enqueue(jsonResponse("/droplet-create-res.json")); + + DropletCreate droplet = api.dropletApi().create("digitalocean2-s-d5e", "sfo1", "512mb", "6374124", CreateDropletOptions.builder().addSshKeyId(421192).build()); + + assertEquals(droplet, objectFromResource("/droplet-create-res.json", DropletCreate.class)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/droplets", stringFromResource("/droplet-create-req.json")); + } + + public void testListKernels() throws InterruptedException { + server.enqueue(jsonResponse("/kernels-first.json")); + server.enqueue(jsonResponse("/kernels-last.json")); + + Iterable<Kernel> kernels = api.dropletApi().listKernels(5425561).concat(); + + assertEquals(size(kernels), 10); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/droplets/5425561/kernels"); + assertSent(server, "GET", "/droplets/5425561/kernels?page=2"); + } + + public void testListKernelsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Kernel> kernels = api.dropletApi().listKernels(5425561).concat(); + + assertTrue(isEmpty(kernels)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets/5425561/kernels"); + } + + public void testListKernelsWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/kernels-first.json")); + + Iterable<Kernel> kernels = api.dropletApi().listKernels(5425561, page(1).perPage(20)); + + assertEquals(size(kernels), 5); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/droplets/5425561/kernels?page=1&per_page=20"); + } + + public void testListKernelsWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Kernel> kernels = api.dropletApi().listKernels(5425561, page(1).perPage(20)); + + assertTrue(isEmpty(kernels)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets/5425561/kernels?page=1&per_page=20"); + } + + public void testListActions() throws InterruptedException { + server.enqueue(jsonResponse("/actions-first.json")); + server.enqueue(jsonResponse("/actions-last.json")); + + Iterable<Action> actions = api.dropletApi().listActions(1).concat(); + + assertEquals(size(actions), 8); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/droplets/1/actions"); + assertSent(server, "GET", "/droplets/1/actions?page=2&per_page=5"); + } + + public void testListActionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Action> actions = api.dropletApi().listActions(1).concat(); + + assertTrue(isEmpty(actions)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets/1/actions"); + } + + public void testListActionsWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/actions-first.json")); + + Iterable<Action> actions = api.dropletApi().listActions(1, page(1).perPage(5)); + + assertEquals(size(actions), 5); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/droplets/1/actions?page=1&per_page=5"); + } + + public void testListActionsWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Action> actions = api.dropletApi().listActions(1, page(1).perPage(5)); + + assertTrue(isEmpty(actions)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets/1/actions?page=1&per_page=5"); + } + + public void testListBackups() throws InterruptedException { + server.enqueue(jsonResponse("/backups-first.json")); + server.enqueue(jsonResponse("/backups-last.json")); + + Iterable<Backup> backups = api.dropletApi().listBackups(5425561).concat(); + + assertEquals(size(backups), 2); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/droplets/5425561/backups"); + assertSent(server, "GET", "/droplets/5425561/backups?page=2"); + } + + public void testListBackupsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Backup> backups = api.dropletApi().listBackups(5425561).concat(); + + assertTrue(isEmpty(backups)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets/5425561/backups"); + } + + public void testListBackupsWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/backups-first.json")); + + Iterable<Backup> backups = api.dropletApi().listBackups(5425561, page(1).perPage(20)); + + assertEquals(size(backups), 1); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/droplets/5425561/backups?page=1&per_page=20"); + } + + public void testListBackupsWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Backup> backups = api.dropletApi().listBackups(5425561, page(1).perPage(20)); + + assertTrue(isEmpty(backups)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets/5425561/backups?page=1&per_page=20"); + } + + public void testListSnapshots() throws InterruptedException { + server.enqueue(jsonResponse("/snapshots-first.json")); + server.enqueue(jsonResponse("/snapshots-last.json")); + + Iterable<Snapshot> snapshots = api.dropletApi().listSnapshots(5425561).concat(); + + assertEquals(size(snapshots), 2); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/droplets/5425561/snapshots"); + assertSent(server, "GET", "/droplets/5425561/snapshots?page=2"); + } + + public void testListSnapshotsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Snapshot> snapshots = api.dropletApi().listSnapshots(5425561).concat(); + + assertTrue(isEmpty(snapshots)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets/5425561/snapshots"); + } + + public void testListSnapshotsWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/snapshots-first.json")); + + Iterable<Snapshot> snapshots = api.dropletApi().listSnapshots(5425561, page(1).perPage(20)); + + assertEquals(size(snapshots), 1); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/droplets/5425561/snapshots?page=1&per_page=20"); + } + + public void testListSnapshotsWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Snapshot> snapshots = api.dropletApi().listSnapshots(5425561, page(1).perPage(20)); + + assertTrue(isEmpty(snapshots)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/droplets/5425561/snapshots?page=1&per_page=20"); + } + + public void testDeleteDroplet() throws InterruptedException { + server.enqueue(response204()); + + api.dropletApi().delete(1); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "DELETE", "/droplets/1"); + } + + public void testDeleteDropletReturns404() throws InterruptedException { + server.enqueue(response404()); + + api.dropletApi().delete(1); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "DELETE", "/droplets/1"); + } + + public void testPowerCycleDroplet() throws InterruptedException { + server.enqueue(jsonResponse("/power-cycle.json")); + + Action action = api.dropletApi().powerCycle(1); + + assertEquals(action, actionFromResource("/power-cycle.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/droplets/1/actions", "{\"type\":\"power_cycle\"}"); + } + + public void testPowerOn() throws InterruptedException { + server.enqueue(jsonResponse("/power-on.json")); + + Action action = api.dropletApi().powerOn(1); + + assertEquals(action, actionFromResource("/power-on.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/droplets/1/actions", "{\"type\":\"power_on\"}"); + } + + public void testPowerOff() throws InterruptedException { + server.enqueue(jsonResponse("/power-off.json")); + + Action action = api.dropletApi().powerOff(1); + + assertEquals(action, actionFromResource("/power-off.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/droplets/1/actions", "{\"type\":\"power_off\"}"); + } + + public void testReboot() throws InterruptedException { + server.enqueue(jsonResponse("/reboot.json")); + + Action action = api.dropletApi().reboot(1); + + assertEquals(action, actionFromResource("/reboot.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/droplets/1/actions", "{\"type\":\"reboot\"}"); + } + + public void testShutdown() throws InterruptedException { + server.enqueue(jsonResponse("/shutdown.json")); + + Action action = api.dropletApi().shutdown(1); + + assertEquals(action, actionFromResource("/shutdown.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/droplets/1/actions", "{\"type\":\"shutdown\"}"); + } + + public void testSnapshot() throws InterruptedException { + server.enqueue(jsonResponse("/snapshot.json")); + + Action action = api.dropletApi().snapshot(1, "foo"); + + assertEquals(action, actionFromResource("/snapshot.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/droplets/1/actions", "{\"type\":\"snapshot\",\"name\":\"foo\"}"); + } + + private Droplet dropletFromResource(String resource) { + return onlyObjectFromResource(resource, new TypeToken<Map<String, Droplet>>() { + private static final long serialVersionUID = 1L; + }); + } + + private Action actionFromResource(String resource) { + return onlyObjectFromResource(resource, new TypeToken<Map<String, Action>>() { + private static final long serialVersionUID = 1L; + }); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ImageApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ImageApiLiveTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ImageApiLiveTest.java new file mode 100644 index 0000000..8c4c96e --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ImageApiLiveTest.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.features; + +import static org.jclouds.digitalocean2.domain.options.ImageListOptions.Builder.page; +import static org.jclouds.digitalocean2.domain.options.ImageListOptions.Builder.type; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import static org.testng.util.Strings.isNullOrEmpty; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.jclouds.digitalocean2.domain.Image; +import org.jclouds.digitalocean2.internal.BaseDigitalOcean2ApiLiveTest; +import org.testng.annotations.Test; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; + +@Test(groups = "live", testName = "ImageApiLiveTest") +public class ImageApiLiveTest extends BaseDigitalOcean2ApiLiveTest { + + public void testListImages() { + final AtomicInteger found = new AtomicInteger(0); + // DigitalOcean return 25 records per page by default. Inspect at most 2 pages + assertTrue(api().list().concat().limit(50).allMatch(new Predicate<Image>() { + @Override + public boolean apply(Image input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.name()); + } + }), "All images must have the 'name' field populated"); + assertTrue(found.get() > 0, "Expected some images to be returned"); + } + + public void testListImagesOnePage() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(api().list(page(1).perPage(5)).allMatch(new Predicate<Image>() { + @Override + public boolean apply(Image input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.name()); + } + }), "All images must have the 'name' field populated"); + assertTrue(found.get() > 0, "Expected some images to be returned"); + } + + public void testListImagesByType() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(api().list(type("distribution").perPage(5)).allMatch(new Predicate<Image>() { + @Override + public boolean apply(Image input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.distribution()); + } + }), "All images must have the 'distribution' field populated"); + assertTrue(found.get() > 0, "Expected some images to be returned"); + } + + public void testGetImage() { + Optional<Image> first = api().list().concat().first(); + assertTrue(first.isPresent(), "At least one image was expected to exist"); + assertNotNull(api().get(first.get().id())); + } + + public void testGetImageBySlug() { + Optional<Image> first = api().list().concat().firstMatch(new Predicate<Image>() { + @Override + public boolean apply(Image input) { + return !isNullOrEmpty(input.slug()); + } + }); + + assertTrue(first.isPresent(), "At least one image with the 'slug' field set was expected to exist"); + assertNotNull(api().get(first.get().slug())); + } + + // TODO: Delete live test once the create/transfer operations are implemented + + private ImageApi api() { + return api.imageApi(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ImageApiMockTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ImageApiMockTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ImageApiMockTest.java new file mode 100644 index 0000000..d172174 --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/ImageApiMockTest.java @@ -0,0 +1,150 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.features; + +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.collect.Iterables.size; +import static org.jclouds.digitalocean2.domain.options.ImageListOptions.Builder.page; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import java.util.Map; + +import org.jclouds.digitalocean2.domain.Image; +import org.jclouds.digitalocean2.internal.BaseDigitalOcean2ApiMockTest; +import org.testng.annotations.Test; + +import com.google.common.reflect.TypeToken; + +@Test(groups = "unit", testName = "ImageApiMockTest", singleThreaded = true) +public class ImageApiMockTest extends BaseDigitalOcean2ApiMockTest { + + public void testListImages() throws InterruptedException { + server.enqueue(jsonResponse("/images-first.json")); + server.enqueue(jsonResponse("/images-last.json")); + + Iterable<Image> images = api.imageApi().list().concat(); + + assertEquals(size(images), 10); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/images"); + assertSent(server, "GET", "/images?page=2&per_page=5&type=distribution"); + } + + public void testListImagesReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Image> images = api.imageApi().list().concat(); + + assertTrue(isEmpty(images)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/images"); + } + + public void testListImagesWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/images-first.json")); + + Iterable<Image> images = api.imageApi().list(page(1).perPage(5).type("distribution")); + + assertEquals(size(images), 5); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/images?page=1&per_page=5&type=distribution"); + } + + public void testListImagesWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Image> images = api.imageApi().list(page(1).perPage(5).type("distribution")); + + assertTrue(isEmpty(images)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/images?page=1&per_page=5&type=distribution"); + } + + public void testGetImage() throws InterruptedException { + server.enqueue(jsonResponse("/image.json")); + + Image image = api.imageApi().get(1); + + assertEquals(image, imageFromResource("/image.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/images/1"); + } + + public void testGetImageReturns404() throws InterruptedException { + server.enqueue(response404()); + + Image image = api.imageApi().get(1); + + assertNull(image); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/images/1"); + } + + public void testGetImageUsingSlug() throws InterruptedException { + server.enqueue(jsonResponse("/image.json")); + + Image image = api.imageApi().get("foo"); + + assertEquals(image, imageFromResource("/image.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/images/foo"); + } + + public void testGetImageUsingSlugReturns404() throws InterruptedException { + server.enqueue(response404()); + + Image image = api.imageApi().get("foo"); + + assertNull(image); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/images/foo"); + } + + public void testDeleteImage() throws InterruptedException { + server.enqueue(response204()); + + api.imageApi().delete(1); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "DELETE", "/images/1"); + } + + public void testDeleteImageReturns404() throws InterruptedException { + server.enqueue(response404()); + + api.imageApi().delete(1); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "DELETE", "/images/1"); + } + + private Image imageFromResource(String resource) { + return onlyObjectFromResource(resource, new TypeToken<Map<String, Image>>() { + private static final long serialVersionUID = 1L; + }); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/KeyApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/KeyApiLiveTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/KeyApiLiveTest.java new file mode 100644 index 0000000..2911d79 --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/KeyApiLiveTest.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.features; + +import static org.jclouds.digitalocean2.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.io.IOException; + +import org.jclouds.digitalocean2.domain.Key; +import org.jclouds.digitalocean2.internal.BaseDigitalOcean2ApiLiveTest; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +import com.google.common.base.Charsets; +import com.google.common.base.Throwables; +import com.google.common.collect.FluentIterable; +import com.google.common.io.Resources; + +@Test(groups = "live", testName = "KeyApiLiveTest") +public class KeyApiLiveTest extends BaseDigitalOcean2ApiLiveTest { + + private Key dsa; + private Key ecdsa; + + public void testCreateKey() { + dsa = api().create("jclouds-test-dsa", loadKey("/ssh-dsa.pub")); + ecdsa = api().create("jclouds-test-ecdsa", loadKey("/ssh-ecdsa.pub")); + + assertEquals(dsa.name(), "jclouds-test-dsa"); + assertEquals(ecdsa.name(), "jclouds-test-ecdsa"); + } + + @Test(dependsOnMethods = "testCreateKey") + public void testListKeys() { + FluentIterable<Key> keys = api().list().concat(); + assertTrue(keys.size() >= 2, "At least the two created keys must exist"); + } + + @Test(dependsOnMethods = "testCreateKey") + public void testListKeysOnePAge() { + FluentIterable<Key> keys = api().list(page(1)); + assertTrue(keys.size() >= 2, "At least the two created keys must exist"); + } + + @Test(dependsOnMethods = "testCreateKey") + public void testGetKey() { + assertEquals(api().get(dsa.id()).fingerprint(), dsa.fingerprint()); + assertEquals(api().get(ecdsa.fingerprint()).id(), ecdsa.id()); + } + + @Test(dependsOnMethods = "testCreateKey") + public void testUpdateKey() { + api().update(dsa.id(), "jclouds-test-dsa-updated"); + assertEquals(api().get(dsa.id()).name(), "jclouds-test-dsa-updated"); + api().update(dsa.fingerprint(), "jclouds-test-dsa-updated2"); + assertEquals(api().get(dsa.id()).name(), "jclouds-test-dsa-updated2"); + } + + @AfterClass(alwaysRun = true) + public void testDeleteKey() { + if (dsa != null) { + api().delete(dsa.id()); + FluentIterable<Key> keys = api().list().concat(); + assertFalse(keys.contains(dsa), "dsa key must not be present in list"); + } + if (ecdsa != null) { + api().delete(ecdsa.fingerprint()); + FluentIterable<Key> keys = api().list().concat(); + assertFalse(keys.contains(ecdsa), "dsa key must not be present in list"); + } + } + + private String loadKey(String resourceName) { + try { + return Resources.toString(getClass().getResource(resourceName), Charsets.UTF_8); + } catch (IOException e) { + throw Throwables.propagate(e); + } + } + + private KeyApi api() { + return api.keyApi(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/057be8df/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/KeyApiMockTest.java ---------------------------------------------------------------------- diff --git a/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/KeyApiMockTest.java b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/KeyApiMockTest.java new file mode 100644 index 0000000..2f9d5d3 --- /dev/null +++ b/providers/digitalocean2/src/test/java/org/jclouds/digitalocean2/features/KeyApiMockTest.java @@ -0,0 +1,203 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.digitalocean2.features; + +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.collect.Iterables.size; +import static org.jclouds.digitalocean2.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import java.util.Map; + +import org.jclouds.digitalocean2.domain.Key; +import org.jclouds.digitalocean2.internal.BaseDigitalOcean2ApiMockTest; +import org.testng.annotations.Test; + +import com.google.common.reflect.TypeToken; + +@Test(groups = "unit", testName = "KeyApiMockTest", singleThreaded = true) +public class KeyApiMockTest extends BaseDigitalOcean2ApiMockTest { + + public void testListKeys() throws InterruptedException { + server.enqueue(jsonResponse("/keys-first.json")); + server.enqueue(jsonResponse("/keys-last.json")); + + Iterable<Key> keys = api.keyApi().list().concat(); + + assertEquals(size(keys), 7); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/account/keys"); + assertSent(server, "GET", "/account/keys?page=2&per_page=5"); + } + + public void testListKeysReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Key> keys = api.keyApi().list().concat(); + + assertTrue(isEmpty(keys)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/account/keys"); + } + + public void testListKeysWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/keys-first.json")); + + Iterable<Key> keys = api.keyApi().list(page(1).perPage(5)); + + assertEquals(size(keys), 5); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/account/keys?page=1&per_page=5"); + } + + public void testListKeysWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Key> keys = api.keyApi().list(page(1).perPage(5)); + + assertTrue(isEmpty(keys)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/account/keys?page=1&per_page=5"); + } + + public void testCreateKey() throws InterruptedException { + server.enqueue(jsonResponse("/key.json").setStatus("HTTP/1.1 201 Created")); + + String dsa = stringFromResource("/ssh-dsa.pub"); + + Key key = api.keyApi().create("foo", dsa); + + assertEquals(key, keyFromResource("/key.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/account/keys", String.format("{\"name\":\"foo\", \"public_key\":\"%s\"}", dsa)); + } + + public void testGetKey() throws InterruptedException { + server.enqueue(jsonResponse("/key.json")); + + Key key = api.keyApi().get(1); + + assertEquals(key, keyFromResource("/key.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/account/keys/1"); + } + + public void testGetKeyReturns404() throws InterruptedException { + server.enqueue(response404()); + + Key key = api.keyApi().get(1); + + assertNull(key); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/account/keys/1"); + } + + public void testGetKeyUsingFingerprint() throws InterruptedException { + server.enqueue(jsonResponse("/key.json")); + + Key key = api.keyApi().get("1a:cc:9b:88:c8:4f:b8:77:96:15:d2:0c:95:86:ff:90"); + + assertEquals(key, keyFromResource("/key.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/account/keys/1a:cc:9b:88:c8:4f:b8:77:96:15:d2:0c:95:86:ff:90"); + } + + public void testGetKeyUsingFingerprintReturns404() throws InterruptedException { + server.enqueue(response404()); + + Key key = api.keyApi().get("1a:cc:9b:88:c8:4f:b8:77:96:15:d2:0c:95:86:ff:90"); + + assertNull(key); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/account/keys/1a:cc:9b:88:c8:4f:b8:77:96:15:d2:0c:95:86:ff:90"); + } + + public void testUpdateKey() throws InterruptedException { + server.enqueue(jsonResponse("/key.json")); + + Key key = api.keyApi().update(1, "foo"); + + assertEquals(key, keyFromResource("/key.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "PUT", "/account/keys/1", "{\"name\":\"foo\"}"); + } + + public void testUpdateKeyUsingFingerprint() throws InterruptedException { + server.enqueue(jsonResponse("/key.json")); + + Key key = api.keyApi().update("1a:cc:9b:88:c8:4f:b8:77:96:15:d2:0c:95:86:ff:90", "foo"); + + assertEquals(key, keyFromResource("/key.json")); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "PUT", "/account/keys/1a:cc:9b:88:c8:4f:b8:77:96:15:d2:0c:95:86:ff:90", "{\"name\":\"foo\"}"); + } + + public void testDeleteKey() throws InterruptedException { + server.enqueue(response204()); + + api.keyApi().delete(1); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "DELETE", "/account/keys/1"); + } + + public void testDeleteKeyReturns404() throws InterruptedException { + server.enqueue(response404()); + + api.keyApi().delete(1); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "DELETE", "/account/keys/1"); + } + + public void testDeleteKeyUsingFingerprint() throws InterruptedException { + server.enqueue(response204()); + + api.keyApi().delete("1a:cc:9b:88:c8:4f:b8:77:96:15:d2:0c:95:86:ff:90"); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "DELETE", "/account/keys/1a:cc:9b:88:c8:4f:b8:77:96:15:d2:0c:95:86:ff:90"); + } + + public void testDeleteKeyUsingfingerprintReturns404() throws InterruptedException { + server.enqueue(response404()); + + api.keyApi().delete("1a:cc:9b:88:c8:4f:b8:77:96:15:d2:0c:95:86:ff:90"); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "DELETE", "/account/keys/1a:cc:9b:88:c8:4f:b8:77:96:15:d2:0c:95:86:ff:90"); + } + + private Key keyFromResource(String resource) { + return onlyObjectFromResource(resource, new TypeToken<Map<String, Key>>() { + private static final long serialVersionUID = 1L; + }); + } +}
