http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/functions/ParseSearchDataBagItemFromJsonTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseSearchDataBagItemFromJsonTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseSearchDataBagItemFromJsonTest.java new file mode 100644 index 0000000..3daf3a8 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseSearchDataBagItemFromJsonTest.java @@ -0,0 +1,62 @@ +/* + * 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.chef.functions; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; + +import org.jclouds.chef.ChefApiMetadata; +import org.jclouds.chef.config.ChefParserModule; +import org.jclouds.chef.domain.DatabagItem; +import org.jclouds.chef.domain.SearchResult; +import org.jclouds.http.HttpResponse; +import org.jclouds.json.config.GsonModule; +import org.jclouds.rest.annotations.ApiVersion; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; + +@Test(groups = { "unit" }) +public class ParseSearchDataBagItemFromJsonTest { + private ParseSearchDatabagFromJson handler; + + @BeforeTest + protected void setUpInjector() throws IOException { + Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bind(String.class).annotatedWith(ApiVersion.class).toInstance(ChefApiMetadata.DEFAULT_API_VERSION); + } + }, new ChefParserModule(), new GsonModule()); + + handler = injector.getInstance(ParseSearchDatabagFromJson.class); + } + + public void test1() { + String itemJson = "{\"my_key\":\"my_data\"}"; + String searchJson = "{\"rows\":[{\"raw_data\": {\"id\":\"item1\",\"my_key\":\"my_data\"}}]}"; + DatabagItem item = new DatabagItem("item1", itemJson); + SearchResult<DatabagItem> result = handler.apply(HttpResponse.builder().statusCode(200).message("ok") + .payload(searchJson).build()); + assertEquals(result.size(), 1); + assertEquals(result.iterator().next(), item); + } +}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java new file mode 100644 index 0000000..b92fb3a --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java @@ -0,0 +1,87 @@ +/* + * 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.chef.functions; + +import static com.google.common.io.BaseEncoding.base16; +import static com.google.common.primitives.Bytes.asList; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.net.URI; + +import org.jclouds.chef.ChefApiMetadata; +import org.jclouds.chef.config.ChefParserModule; +import org.jclouds.chef.domain.ChecksumStatus; +import org.jclouds.chef.domain.UploadSandbox; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.config.GsonModule; +import org.jclouds.rest.annotations.ApiVersion; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code ParseUploadSiteFromJson} + */ +@Test(groups = { "unit" }, singleThreaded = true) +public class ParseUploadSandboxFromJsonTest { + + private ParseJson<UploadSandbox> handler; + private Injector injector; + + @BeforeTest + protected void setUpInjector() throws IOException { + injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bind(String.class).annotatedWith(ApiVersion.class).toInstance(ChefApiMetadata.DEFAULT_API_VERSION); + } + }, new ChefParserModule(), new GsonModule()); + + handler = injector.getInstance(Key.get(new TypeLiteral<ParseJson<UploadSandbox>>() { + })); + } + + public void test() { + assertEquals( + handler.apply(HttpResponse.builder().statusCode(200).message("ok") + .payload(ParseUploadSandboxFromJsonTest.class.getResourceAsStream("/upload-site.json")).build()), + UploadSandbox + .builder() + .uri(URI + .create("https://api.opscode.com/organizations/jclouds/sandboxes/d454f71e2a5f400c808d0c5d04c2c88c")) + .checksum( + asList(base16().lowerCase().decode("0c5ecd7788cf4f6c7de2a57193897a6c")), + ChecksumStatus + .builder() + .url(URI + .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/sandbox-d454f71e2a5f400c808d0c5d04c2c88c/checksum-0c5ecd7788cf4f6c7de2a57193897a6c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277344702&Signature=FtKyqvYEjhhEKmRY%2B0M8aGPMM7g%3D")) + .needsUpload(true).build()) + .checksum(asList(base16().lowerCase().decode("0189e76ccc476701d6b374e5a1a27347")), + ChecksumStatus.builder().build()) + .checksum(asList(base16().lowerCase().decode("1dda05ed139664f1f89b9dec482b77c0")), + ChecksumStatus.builder().build()).sandboxId("d454f71e2a5f400c808d0c5d04c2c88c").build() + + ); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/functions/RunListForGroupTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/RunListForGroupTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/RunListForGroupTest.java new file mode 100644 index 0000000..28b8833 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/RunListForGroupTest.java @@ -0,0 +1,92 @@ +/* + * 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.chef.functions; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.ChefApiMetadata; +import org.jclouds.chef.config.ChefParserModule; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.domain.DatabagItem; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import org.jclouds.rest.annotations.Api; +import org.jclouds.rest.annotations.ApiVersion; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; + +@Test(groups = "unit", testName = "RunListForGroupTest") +public class RunListForGroupTest { + private Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bind(String.class).annotatedWith(ApiVersion.class).toInstance(ChefApiMetadata.DEFAULT_API_VERSION); + } + }, new ChefParserModule(), new GsonModule()); + + private Json json = injector.getInstance(Json.class); + + @Test(expectedExceptions = IllegalStateException.class) + public void testWhenNoDatabagItem() throws IOException { + ChefApi chefApi = createMock(ChefApi.class); + Client client = createMock(Client.class); + + RunListForGroup fn = new RunListForGroup(new BootstrapConfigForGroup("jclouds", chefApi), json); + + expect(chefApi.getDatabagItem("jclouds", "foo")).andReturn(null); + + replay(client); + replay(chefApi); + + fn.apply("foo"); + + verify(client); + verify(chefApi); + } + + @Test + public void testReadRunList() throws IOException { + ChefApi chefApi = createMock(ChefApi.class); + Api api = createMock(Api.class); + + RunListForGroup fn = new RunListForGroup(new BootstrapConfigForGroup("jclouds", chefApi), json); + DatabagItem config = new DatabagItem("foo", + "{\"tomcat6\":{\"ssl_port\":8433},\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}"); + + expect(chefApi.getDatabagItem("jclouds", "foo")).andReturn(config); + + replay(api); + replay(chefApi); + + assertEquals(fn.apply("foo"), ImmutableList.of("recipe[apache2]", "role[webserver]")); + + verify(api); + verify(chefApi); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java new file mode 100644 index 0000000..3285a1c --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java @@ -0,0 +1,54 @@ +/* + * 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.chef.functions; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; + +import org.jclouds.chef.domain.Resource; +import org.testng.annotations.Test; + +import com.google.common.base.Function; + +/** + * Tests behavior of {@code UriForResource} + */ +@Test(groups = { "unit" }) +public class UriForResourceTest { + + @Test(expectedExceptions = NullPointerException.class) + public void testWithNullInput() { + Function<Object, URI> function = new UriForResource(); + function.apply(null); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testWithInvalidInput() { + Function<Object, URI> function = new UriForResource(); + function.apply(new Object()); + } + + @Test + public void testWithValidResource() { + Function<Object, URI> function = new UriForResource(); + Resource res = Resource.builder().name("test").url(URI.create("http://foo/bar")).build(); + URI result = function.apply(res); + assertEquals(res.getUrl().toString(), result.toString()); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/handlers/ChefApiErrorRetryHandlerTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/handlers/ChefApiErrorRetryHandlerTest.java b/apis/chef/src/test/java/org/jclouds/chef/handlers/ChefApiErrorRetryHandlerTest.java new file mode 100644 index 0000000..5e99675 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/handlers/ChefApiErrorRetryHandlerTest.java @@ -0,0 +1,115 @@ +/* + * 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.chef.handlers; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; + +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.handlers.BackoffLimitedRetryHandler; +import org.testng.annotations.Test; + +/** + * Tests behavior of {@code ChefClientErrorRetryHandler} + */ +@Test(groups = { "unit" }) +public class ChefApiErrorRetryHandlerTest { + @Test + public void test401DoesNotRetry() { + + HttpCommand command = createMock(HttpCommand.class); + HttpResponse response = createMock(HttpResponse.class); + BackoffLimitedRetryHandler retry = createMock(BackoffLimitedRetryHandler.class); + + expect(command.getFailureCount()).andReturn(0); + expect(response.getStatusCode()).andReturn(401).atLeastOnce(); + + replay(response); + replay(retry); + replay(command); + + ChefApiErrorRetryHandler handler = new ChefApiErrorRetryHandler(retry); + + assert !handler.shouldRetryRequest(command, response); + + verify(retry); + verify(command); + verify(response); + + } + + @Test + public void test400DoesNotRetry() { + + HttpCommand command = createMock(HttpCommand.class); + HttpResponse response = createMock(HttpResponse.class); + BackoffLimitedRetryHandler retry = createMock(BackoffLimitedRetryHandler.class); + + expect(command.getFailureCount()).andReturn(0); + expect(response.getStatusCode()).andReturn(401).atLeastOnce(); + + replay(response); + replay(retry); + replay(command); + + ChefApiErrorRetryHandler handler = new ChefApiErrorRetryHandler(retry); + + assert !handler.shouldRetryRequest(command, response); + + verify(retry); + verify(command); + verify(response); + + } + + @Test + public void testRetryOn400PutSandbox() { + + HttpCommand command = createMock(HttpCommand.class); + BackoffLimitedRetryHandler retry = createMock(BackoffLimitedRetryHandler.class); + + HttpRequest request = HttpRequest.builder().method("PUT") + .endpoint("https://api.opscode.com/organizations/jclouds/sandboxes/bfd68d4052f44053b2e593a33b5e1cd5") + .build(); + HttpResponse response = HttpResponse + .builder() + .statusCode(400) + .message("400 Bad Request") + .payload( + "{\"error\":[\"Cannot update sandbox bfd68d4052f44053b2e593a33b5e1cd5: checksum 9b7c23369f4b576451216c39f214af6c was not uploaded\"]}") + .build(); + + expect(command.getFailureCount()).andReturn(0); + expect(command.getCurrentRequest()).andReturn(request).atLeastOnce(); + expect(retry.shouldRetryRequest(command, response)).andReturn(true); + + replay(retry); + replay(command); + + ChefApiErrorRetryHandler handler = new ChefApiErrorRetryHandler(retry); + + assert handler.shouldRetryRequest(command, response); + + verify(retry); + verify(command); + + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java new file mode 100644 index 0000000..225e593 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java @@ -0,0 +1,542 @@ +/* + * 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.chef.internal; + +import static com.google.common.base.Throwables.propagate; +import static com.google.common.collect.Iterables.any; +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.hash.Hashing.md5; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.jclouds.util.Predicates2.retry; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.domain.ChecksumStatus; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.domain.CookbookDefinition; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.domain.DatabagItem; +import org.jclouds.chef.domain.Environment; +import org.jclouds.chef.domain.Metadata; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.domain.Resource; +import org.jclouds.chef.domain.Role; +import org.jclouds.chef.domain.Sandbox; +import org.jclouds.chef.domain.SearchResult; +import org.jclouds.chef.domain.UploadSandbox; +import org.jclouds.chef.options.CreateClientOptions; +import org.jclouds.chef.options.SearchOptions; +import org.jclouds.crypto.Pems; +import org.jclouds.io.ByteStreams2; +import org.jclouds.io.Payloads; +import org.jclouds.io.payloads.FilePayload; +import org.jclouds.rest.ResourceNotFoundException; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.hash.Hashing; +import com.google.common.io.Closeables; +import com.google.common.io.Files; +import com.google.common.primitives.Bytes; + +/** + * Tests behavior of {@code ChefApi} + */ +@Test(groups = { "live", "integration" }) +public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiveTest<A> { + public static final String PREFIX = "jcloudstest-" + System.getProperty("user.name"); + public static final String ADMIN_PREFIX = "jcloudstest-adm-" + System.getProperty("user.name"); + public static final String ENV_NODE = PREFIX + "-env-node"; + + // It may take a bit until the search index is populated + protected int maxWaitForIndexInMs = 60000; + + // The id of the data bag item used in search tests + private String databagitemId; + + public void testCreateNewCookbook() throws Exception { + // Define the file you want in the cookbook + File file = new File(System.getProperty("user.dir"), "pom.xml"); + FilePayload content = Payloads.newFilePayload(file); + content.getContentMetadata().setContentType("application/x-binary"); + + // Get an md5 so that you can see if the server already has it or not + content.getContentMetadata().setContentMD5(Files.asByteSource(file).hash(Hashing.md5()).asBytes()); + + // Note that java collections cannot effectively do equals or hashcodes on + // byte arrays, so let's convert to a list of bytes. + List<Byte> md5 = Bytes.asList(content.getContentMetadata().getContentMD5()); + + // Request an upload site for this file + UploadSandbox site = api.createUploadSandboxForChecksums(ImmutableSet.of(md5)); + assertTrue(site.getChecksums().containsKey(md5), md5 + " not in " + site.getChecksums()); + + try { + // Upload the file contents, if still not uploaded + ChecksumStatus status = site.getChecksums().get(md5); + if (status.needsUpload()) { + api.uploadContent(status.getUrl(), content); + } + Sandbox sandbox = api.commitSandbox(site.getSandboxId(), true); + assertTrue(sandbox.isCompleted(), "Sandbox should be completed after uploading"); + } catch (RuntimeException e) { + api.commitSandbox(site.getSandboxId(), false); + fail("Could not upload content"); + } + + // Create the metadata of the cookbook + Metadata metadata = Metadata.builder() // + .name(PREFIX) // + .version("0.0.0") // + .description("Jclouds test uploaded cookbook") // + .maintainer("jclouds") // + .maintainerEmail("[email protected]") // + .license("Apache 2.0") // + .build(); + + // Create a new cookbook + CookbookVersion cookbook = CookbookVersion.builder(PREFIX, "0.0.0") // + .metadata(metadata) // + .rootFile(Resource.builder().fromPayload(content).build()) // + .build(); + + // upload the cookbook to the remote server + api.updateCookbook(PREFIX, "0.0.0", cookbook); + } + + public void testListCookbooks() throws Exception { + Set<String> cookbookNames = api.listCookbooks(); + assertFalse(cookbookNames.isEmpty(), "No cookbooks were found"); + + for (String cookbookName : cookbookNames) { + Set<String> versions = api.listVersionsOfCookbook(cookbookName); + assertFalse(versions.isEmpty(), "There are no versions of the cookbook: " + cookbookName); + + for (String version : api.listVersionsOfCookbook(cookbookName)) { + CookbookVersion cookbook = api.getCookbook(cookbookName, version); + assertNotNull(cookbook, "Could not get cookbook: " + cookbookName); + } + } + } + + @Test(dependsOnMethods = "testListCookbooks") + public void testListCookbookVersionsWithChefService() throws Exception { + Iterable<? extends CookbookVersion> cookbooks = chefService.listCookbookVersions(); + assertFalse(isEmpty(cookbooks), "No cookbooks were found"); + } + + @Test(dependsOnMethods = "testListCookbookVersionsWithChefService") + public void testDownloadCookbooks() throws Exception { + Iterable<? extends CookbookVersion> cookbooks = chefService.listCookbookVersions(); + for (CookbookVersion cookbook : cookbooks) { + for (Resource resource : ImmutableList.<Resource> builder().addAll(cookbook.getDefinitions()) + .addAll(cookbook.getFiles()).addAll(cookbook.getLibraries()).addAll(cookbook.getSuppliers()) + .addAll(cookbook.getRecipes()).addAll(cookbook.getResources()).addAll(cookbook.getRootFiles()) + .addAll(cookbook.getTemplates()).build()) { + + InputStream stream = api.getResourceContents(resource); + assertNotNull(stream, "Resource contents are null for resource: " + resource.getName()); + + byte[] md5 = ByteStreams2.hashAndClose(stream, md5()).asBytes(); + assertEquals(md5, resource.getChecksum()); + } + } + } + + @Test(dependsOnMethods = "testCreateNewCookbook") + public void testUpdateCookbook() throws Exception { + CookbookVersion cookbook = api.getCookbook(PREFIX, "0.0.0"); + assertNotNull(cookbook, "Cookbook not found: " + PREFIX); + assertNotNull(api.updateCookbook(PREFIX, "0.0.0", cookbook), "Updated cookbook was null"); + } + + @Test(dependsOnMethods = { "testCreateNewCookbook", "testUpdateCookbook" }) + public void testDeleteCookbook() throws Exception { + assertNotNull(api.deleteCookbook(PREFIX, "0.0.0"), "Deleted cookbook was null"); + } + + @Test + public void testCreateClient() throws Exception { + api.deleteClient(PREFIX); + String credential = Pems.pem(api.createClient(PREFIX).getPrivateKey()); + assertClientCreated(PREFIX, credential); + } + + @Test + public void testCreateAdminClient() throws Exception { + api.deleteClient(ADMIN_PREFIX); + String credential = Pems.pem(api.createClient(ADMIN_PREFIX, CreateClientOptions.Builder.admin()).getPrivateKey()); + assertClientCreated(ADMIN_PREFIX, credential); + } + + @Test(dependsOnMethods = "testCreateClient") + public void testGenerateKeyForClient() throws Exception { + String credential = Pems.pem(api.generateKeyForClient(PREFIX).getPrivateKey()); + assertClientCreated(PREFIX, credential); + } + + @Test + public void testListNodes() throws Exception { + Set<String> nodes = api.listNodes(); + assertNotNull(nodes, "No nodes were found"); + } + + @Test(dependsOnMethods = "testCreateRole") + public void testCreateNode() throws Exception { + api.deleteNode(PREFIX); + api.createNode(Node.builder().name(PREFIX).runListElement("role[" + PREFIX + "]").environment("_default").build()); + Node node = api.getNode(PREFIX); + // TODO check recipes + assertNotNull(node, "Created node should not be null"); + Set<String> nodes = api.listNodes(); + assertTrue(nodes.contains(PREFIX), String.format("node %s not in %s", PREFIX, nodes)); + } + + @Test(dependsOnMethods = "testCreateNode") + public void testUpdateNode() throws Exception { + for (String nodename : api.listNodes()) { + Node node = api.getNode(nodename); + api.updateNode(node); + } + } + + @Test + public void testListRoles() throws Exception { + Set<String> roles = api.listRoles(); + assertNotNull(roles, "Role list was null"); + } + + @Test + public void testCreateRole() throws Exception { + api.deleteRole(PREFIX); + api.createRole(Role.builder().name(PREFIX).runListElement("recipe[java]").build()); + Role role = api.getRole(PREFIX); + assertNotNull(role, "Created role should not be null"); + assertEquals(role.getName(), PREFIX); + assertEquals(role.getRunList(), Collections.singleton("recipe[java]")); + } + + @Test(dependsOnMethods = "testCreateRole") + public void testUpdateRole() throws Exception { + for (String rolename : api.listRoles()) { + Role role = api.getRole(rolename); + api.updateRole(role); + } + } + + @Test + public void testListDatabags() throws Exception { + Set<String> databags = api.listDatabags(); + assertNotNull(databags, "Data bag list was null"); + } + + @Test + public void testCreateDatabag() throws Exception { + api.deleteDatabag(PREFIX); + api.createDatabag(PREFIX); + } + + @Test(dependsOnMethods = "testCreateDatabagItem") + public void testListDatabagItems() throws Exception { + Set<String> databagItems = api.listDatabagItems(PREFIX); + assertNotNull(databagItems, "Data bag item list was null"); + } + + @Test(dependsOnMethods = "testCreateDatabag") + public void testCreateDatabagItem() throws Exception { + Properties config = new Properties(); + config.setProperty("foo", "bar"); + api.deleteDatabagItem(PREFIX, PREFIX); + DatabagItem databagItem = api.createDatabagItem(PREFIX, new DatabagItem("config", json.toJson(config))); + databagitemId = databagItem.getId(); + assertNotNull(databagItem, "Created data bag item should not be null"); + assertEquals(databagItem.getId(), "config"); + + // The databagItem json contains extra keys: (the name and the type if the + // item) + Properties props = json.fromJson(databagItem.toString(), Properties.class); + for (Object key : config.keySet()) { + assertTrue(props.containsKey(key)); + assertEquals(config.get(key), props.get(key)); + } + } + + @Test(dependsOnMethods = "testCreateDatabagItem") + public void testUpdateDatabagItem() throws Exception { + for (String databagItemId : api.listDatabagItems(PREFIX)) { + DatabagItem databagItem = api.getDatabagItem(PREFIX, databagItemId); + api.updateDatabagItem(PREFIX, databagItem); + } + } + + @Test(dependsOnMethods = "testSearchDatabagWithOptions") + public void testDeleteDatabagItem() throws Exception { + for (String databagItemId : api.listDatabagItems(PREFIX)) { + DatabagItem databagItem = api.deleteDatabagItem(PREFIX, databagItemId); + assertNotNull(databagItem, "Deleted data bag item should not be null"); + assertEquals(databagItem.getId(), databagItemId, "Deleted data bag item id must match the original id"); + assertNull(api.getDatabagItem(PREFIX, databagItemId), "Data bag item should not exist"); + } + } + + @Test + public void testListSearchIndexes() throws Exception { + Set<String> indexes = api.listSearchIndexes(); + assertNotNull(indexes, "The index list should not be null"); + assertTrue(indexes.contains("node")); + assertTrue(indexes.contains("client")); + assertTrue(indexes.contains("role")); + } + + @Test + public void testSearchNodes() throws Exception { + SearchResult<? extends Node> results = api.searchNodes(); + assertNotNull(results, "Node result list should not be null"); + } + + @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateNode" }) + public void testSearchNodesWithOptions() throws Exception { + Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() { + @Override + public boolean apply(SearchOptions input) { + SearchResult<? extends Node> results = api.searchNodes(input); + assertNotNull(results); + if (results.size() > 0) { + assertEquals(results.size(), 1); + assertEquals(results.iterator().next().getName(), PREFIX); + return true; + } else { + // The index may still not be populated + return false; + } + } + }, maxWaitForIndexInMs, 5000L, MILLISECONDS); + + SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX); + assertTrue(waitForIndex.apply(options)); + } + + @Test + public void testSearchClients() throws Exception { + SearchResult<? extends Client> results = api.searchClients(); + assertNotNull(results, "Client result list should not be null"); + } + + @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateClient" }) + public void testSearchClientsWithOptions() throws Exception { + Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() { + @Override + public boolean apply(SearchOptions input) { + SearchResult<? extends Client> results = api.searchClients(input); + assertNotNull(results); + if (results.size() > 0) { + assertEquals(results.size(), 1); + assertEquals(results.iterator().next().getName(), PREFIX); + return true; + } else { + // The index may still not be populated + return false; + } + } + }, maxWaitForIndexInMs, 5000L, MILLISECONDS); + + SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX); + assertTrue(waitForIndex.apply(options)); + } + + @Test + public void testSearchRoles() throws Exception { + SearchResult<? extends Role> results = api.searchRoles(); + assertNotNull(results, "Role result list should not be null"); + } + + @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateRole" }) + public void testSearchRolesWithOptions() throws Exception { + Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() { + @Override + public boolean apply(SearchOptions input) { + SearchResult<? extends Role> results = api.searchRoles(input); + assertNotNull(results); + if (results.size() > 0) { + assertEquals(results.size(), 1); + assertEquals(results.iterator().next().getName(), PREFIX); + return true; + } else { + // The index may still not be populated + return false; + } + } + }, maxWaitForIndexInMs, 5000L, MILLISECONDS); + + SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX); + assertTrue(waitForIndex.apply(options)); + } + + @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateDatabagItem" }) + public void testSearchDatabag() throws Exception { + SearchResult<? extends DatabagItem> results = api.searchDatabagItems(PREFIX); + assertNotNull(results, "Data bag item result list should not be null"); + } + + @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateDatabagItem" }) + public void testSearchDatabagWithOptions() throws Exception { + Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() { + @Override + public boolean apply(SearchOptions input) { + SearchResult<? extends DatabagItem> results = api.searchDatabagItems(PREFIX, input); + assertNotNull(results); + if (results.size() > 0) { + assertEquals(results.size(), 1); + assertEquals(results.iterator().next().getId(), databagitemId); + return true; + } else { + // The index may still not be populated + return false; + } + } + }, maxWaitForIndexInMs, 5000L, MILLISECONDS); + + SearchOptions options = SearchOptions.Builder.query("id:" + databagitemId); + assertTrue(waitForIndex.apply(options)); + } + + @Test(expectedExceptions = ResourceNotFoundException.class, dependsOnMethods = "testListSearchIndexes") + public void testSearchDatabagNotFound() throws Exception { + SearchResult<? extends DatabagItem> results = api.searchDatabagItems("whoopie"); + assertNotNull(results, "Data bag item result list should not be null"); + } + + @Test + public void testCreateEnvironment() { + api.deleteEnvironment(PREFIX); + api.createEnvironment(Environment.builder().name(PREFIX).description(PREFIX).build()); + Environment env = api.getEnvironment(PREFIX); + assertNotNull(env, "Created environment should not be null"); + assertEquals(env.getName(), PREFIX); + assertEquals(env.getDescription(), PREFIX); + } + + @Test(dependsOnMethods = "testCreateEnvironment") + public void testListEnvironment() { + Set<String> envList = api.listEnvironments(); + assertNotNull(envList, "Environment list was null"); + assertTrue(envList.contains(PREFIX)); + } + + @Test(dependsOnMethods = "testCreateEnvironment") + public void testSearchEnvironments() throws Exception { + SearchResult<? extends Environment> results = api.searchEnvironments(); + assertNotNull(results, "Environment result list was null"); + } + + @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateEnvironment" }) + public void testSearchEnvironmentsWithOptions() throws Exception { + Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() { + @Override + public boolean apply(SearchOptions input) { + SearchResult<? extends Environment> results = api.searchEnvironments(input); + assertNotNull(results); + if (results.size() > 0) { + assertEquals(results.size(), 1); + assertEquals(results.iterator().next().getName(), PREFIX); + return true; + } else { + // The index may still not be populated + return false; + } + } + }, maxWaitForIndexInMs, 5000L, MILLISECONDS); + + SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX); + assertTrue(waitForIndex.apply(options)); + } + + @Test(dependsOnMethods = "testCreateEnvironment") + public void testListRecipesInEnvironment() { + Set<String> recipeList = api.listRecipesInEnvironment(PREFIX); + assertTrue(!recipeList.isEmpty()); + } + + @Test(dependsOnMethods = "testCreateEnvironment") + public void testListNodesInEnvironment() { + api.deleteNode(ENV_NODE); + api.createNode(Node.builder().name(ENV_NODE).runListElement("role[" + PREFIX + "]").environment(PREFIX).build()); + Node node = api.getNode(ENV_NODE); + assertNotNull(node, "Created node should not be null"); + Set<String> nodeList = api.listNodesInEnvironment(PREFIX); + assertTrue(!nodeList.isEmpty()); + } + + @Test(dependsOnMethods = "testCreateNewCookbook") + public void testListCookbooksInEnvironment() throws Exception { + Set<CookbookDefinition> cookbooks = api.listCookbooksInEnvironment("_default"); + assertTrue(any(cookbooks, new Predicate<CookbookDefinition>() { + @Override + public boolean apply(CookbookDefinition input) { + return PREFIX.equals(input.getName()); + }}), String.format("Cookbook %s not in %s", PREFIX, cookbooks)); + } + + @AfterClass(groups = { "live", "integration" }) + @Override + public void tearDown() { + api.deleteClient(PREFIX); + api.deleteClient(ADMIN_PREFIX); + api.deleteNode(PREFIX); + api.deleteNode(ENV_NODE); + api.deleteRole(PREFIX); + api.deleteDatabag(PREFIX); + api.deleteEnvironment(PREFIX); + super.tearDown(); + } + + private void assertClientCreated(String identity, String credential) { + Properties overrides = super.setupProperties(); + overrides.setProperty(provider + ".identity", identity); + overrides.setProperty(provider + ".credential", credential); + + A clientApi = create(overrides, setupModules()); + + try { + Client client = clientApi.getClient(identity); + assertNotNull(client, "Client not found: " + identity); + } finally { + try { + Closeables.close(clientApi, true); + } catch (IOException e) { + throw propagate(e); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefLiveTest.java new file mode 100644 index 0000000..e314418 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefLiveTest.java @@ -0,0 +1,96 @@ +/* + * 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.chef.internal; + +import static org.jclouds.reflect.Types2.checkBound; + +import java.io.File; +import java.io.IOException; +import java.util.Properties; + +import org.jclouds.apis.BaseApiLiveTest; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.ChefService; +import org.jclouds.json.Json; +import org.testng.annotations.Test; + +import com.google.common.base.Charsets; +import com.google.common.base.Throwables; +import com.google.common.io.Files; +import com.google.common.reflect.TypeToken; +import com.google.inject.Injector; +import com.google.inject.Module; + +@Test(groups = "live") +public abstract class BaseChefLiveTest<A extends ChefApi> extends BaseApiLiveTest<A> { + + protected Injector injector; + protected ChefService chefService; + protected Json json; + + protected BaseChefLiveTest() { + provider = "chef"; + } + + /** + * the credential is a path to the pem file. + */ + @Override + protected Properties setupProperties() { + Properties overrides = super.setupProperties(); + credential = setCredentialFromPemFile(overrides, identity, provider + ".credential"); + return overrides; + } + + @Override + protected void initialize() { + super.initialize(); + chefService = injector.getInstance(ChefService.class); + json = injector.getInstance(Json.class); + } + + @Override + protected A create(Properties props, Iterable<Module> modules) { + injector = newBuilder().modules(modules).overrides(props).buildInjector(); + return injector.getInstance(resolveApiClass()); + } + + protected String setCredentialFromPemFile(Properties overrides, String identity, String key) { + String val = null; + String credentialFromFile = null; + if (System.getProperties().containsKey("test." + key)) { + val = System.getProperty("test." + key); + } else { + val = System.getProperty("user.home") + "/.chef/" + identity + ".pem"; + } + try { + credentialFromFile = Files.toString(new File(val), Charsets.UTF_8); + } catch (IOException e) { + throw Throwables.propagate(e); + } + overrides.setProperty(key, credentialFromFile); + return credentialFromFile; + } + + @SuppressWarnings("unchecked") + private Class<A> resolveApiClass() { + return Class.class.cast(checkBound(new TypeToken<A>(getClass()) { + private static final long serialVersionUID = 1L; + }).getRawType()); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java new file mode 100644 index 0000000..e763d8f --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java @@ -0,0 +1,99 @@ +/* + * 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.chef.internal; + +import static org.testng.Assert.assertEquals; + +import java.util.List; + +import org.jclouds.ContextBuilder; +import org.jclouds.chef.ChefApiMetadata; +import org.jclouds.chef.domain.BootstrapConfig; +import org.jclouds.chef.filters.SignedHeaderAuthTest; +import org.jclouds.chef.util.RunListBuilder; +import org.jclouds.domain.JsonBall; +import org.jclouds.logging.config.NullLoggingModule; +import org.jclouds.rest.internal.BaseRestApiTest.MockModule; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.inject.Injector; +import com.google.inject.Module; + +/** + * Unit tests for the <code>BaseChefService</code> class. + */ +@Test(groups = "unit", testName = "BaseChefServiceTest") +public class BaseChefServiceTest { + + private BaseChefService chefService; + + @BeforeClass + public void setup() { + Injector injector = ContextBuilder.newBuilder(new ChefApiMetadata()) + .credentials(SignedHeaderAuthTest.USER_ID, SignedHeaderAuthTest.PRIVATE_KEY) + .modules(ImmutableSet.<Module> of(new MockModule(), new NullLoggingModule())).buildInjector(); + + chefService = injector.getInstance(BaseChefService.class); + } + + @Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "bootstrapConfig must not be null") + public void testBuildBootstrapConfigurationWithNullConfig() { + chefService.buildBootstrapConfiguration(null); + } + + public void testBuildBootstrapConfigurationWithEmptyRunlist() { + BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(ImmutableList.<String> of()).build(); + String config = chefService.buildBootstrapConfiguration(bootstrapConfig); + assertEquals(config, "{\"run_list\":[]}"); + } + + public void testBuildBootstrapConfigurationWithRunlist() { + List<String> runlist = new RunListBuilder().addRecipe("apache2").addRole("webserver").build(); + BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist).build(); + String config = chefService.buildBootstrapConfiguration(bootstrapConfig); + assertEquals(config, "{\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}"); + } + + public void testBuildBootstrapConfigurationWithRunlistAndEmptyAttributes() { + List<String> runlist = new RunListBuilder().addRecipe("apache2").addRole("webserver").build(); + BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist).attributes(new JsonBall("{}")) + .build(); + String config = chefService.buildBootstrapConfiguration(bootstrapConfig); + assertEquals(config, "{\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}"); + } + + public void testBuildBootstrapConfigurationWithRunlistAndAttributes() { + List<String> runlist = new RunListBuilder().addRecipe("apache2").addRole("webserver").build(); + BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist) + .attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}")).build(); + String config = chefService.buildBootstrapConfiguration(bootstrapConfig); + assertEquals(config, "{\"tomcat6\":{\"ssl_port\":8433},\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}"); + } + + public void testBuildBootstrapConfigurationWithRunlistAndAttributesAndEnvironment() { + List<String> runlist = new RunListBuilder().addRecipe("apache2").addRole("webserver").build(); + BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist) + .attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}")).environment("env").build(); + String config = chefService.buildBootstrapConfiguration(bootstrapConfig); + assertEquals(config, + "{\"tomcat6\":{\"ssl_port\":8433},\"environment\":\"env\",\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}"); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/internal/BaseStubbedOhaiLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/internal/BaseStubbedOhaiLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseStubbedOhaiLiveTest.java new file mode 100644 index 0000000..8779017 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseStubbedOhaiLiveTest.java @@ -0,0 +1,60 @@ +/* + * 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.chef.internal; + +import java.util.Map; + +import org.jclouds.apis.ApiMetadata; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.ChefApiMetadata; +import org.jclouds.chef.config.ChefBootstrapModule; +import org.jclouds.chef.config.ChefHttpApiModule; +import org.jclouds.chef.config.ChefParserModule; +import org.jclouds.domain.JsonBall; +import org.jclouds.ohai.AutomaticSupplier; +import org.jclouds.ohai.config.ConfiguresOhai; +import org.jclouds.ohai.config.OhaiModule; +import org.testng.annotations.Test; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.inject.Module; + +@Test(groups = "live") +@Deprecated +public class BaseStubbedOhaiLiveTest extends BaseChefLiveTest<ChefApi> { + + @ConfiguresOhai + static class TestOhaiModule extends OhaiModule { + + @Override + protected Supplier<Map<String, JsonBall>> provideAutomatic(AutomaticSupplier in) { + return Suppliers.<Map<String, JsonBall>> ofInstance(ImmutableMap.of("foo", new JsonBall("bar"))); + } + } + + @Override + protected ApiMetadata createApiMetadata() { + return new ChefApiMetadata() + .toBuilder() + .defaultModules( + ImmutableSet.<Class<? extends Module>> of(ChefHttpApiModule.class, ChefParserModule.class, + ChefBootstrapModule.class, TestOhaiModule.class)).build(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImplLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImplLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImplLiveTest.java new file mode 100644 index 0000000..e8b249b --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImplLiveTest.java @@ -0,0 +1,61 @@ +/* + * 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.chef.strategy.internal; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.internal.BaseChefLiveTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Tests behavior of {@code CleanupStaleNodesAndClientsImpl} strategies + */ +@Test(groups = "live", testName = "CleanupStaleNodesAndClientsImplLiveTest") +public class CleanupStaleNodesAndClientsImplLiveTest extends BaseChefLiveTest<ChefApi> { + + private CreateNodeAndPopulateAutomaticAttributesImpl creator; + private CleanupStaleNodesAndClientsImpl strategy; + + @Override + protected void initialize() { + super.initialize(); + this.creator = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class); + this.strategy = injector.getInstance(CleanupStaleNodesAndClientsImpl.class); + } + + @Test + public void testExecute() throws InterruptedException { + try { + creator.execute(prefix, ImmutableSet.<String> of()); + // http://tickets.corp.opscode.com/browse/PL-522 + // assert chef.nodeExists(prefix); + assertNotNull(api.getNode(prefix)); + strategy.execute(prefix, 10); + assertNotNull(api.getNode(prefix)); + Thread.sleep(1000); + strategy.execute(prefix, 1); + assertNull(api.getNode(prefix)); + } finally { + api.deleteNode(prefix); + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java new file mode 100644 index 0000000..60f2661 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java @@ -0,0 +1,62 @@ +/* + * 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.chef.strategy.internal; + +import static org.testng.Assert.assertEquals; + +import java.util.Set; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.internal.BaseChefLiveTest; +import org.jclouds.ohai.config.OhaiModule.CurrentUserProvider; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Tests behavior of {@code CreateNodeAndPopulateAutomaticAttributesImpl} + * strategies + */ +@Test(groups = "live", testName = "CreateNodeAndPopulateAutomaticAttributesImplLiveTest") +public class CreateNodeAndPopulateAutomaticAttributesImplLiveTest extends BaseChefLiveTest<ChefApi> { + + private CurrentUserProvider currentUserProvider; + private CreateNodeAndPopulateAutomaticAttributesImpl strategy; + + @Override + protected void initialize() { + super.initialize(); + this.currentUserProvider = injector.getInstance(CurrentUserProvider.class); + this.strategy = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class); + } + + @Test + public void testExecute() { + Set<String> runList = ImmutableSet.of("role[" + prefix + "]"); + try { + strategy.execute(prefix, runList); + Node node = api.getNode(prefix); + assertEquals(node.getName(), prefix); + assertEquals(node.getRunList(), runList); + assertEquals(node.getAutomaticAttributes().get("current_user").toString(), currentUserProvider.get().toString()); + } finally { + api.deleteNode(prefix); + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java new file mode 100644 index 0000000..3ba7110 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java @@ -0,0 +1,61 @@ +/* + * 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.chef.strategy.internal; + +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; + +import java.util.Map; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.domain.Node; +import org.jclouds.domain.JsonBall; +import org.testng.annotations.Test; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +/** + * Tests behavior of {@code CreateNodeAndPopulateAutomaticAttributesImpl} + */ +@Test(groups = "unit", testName = "CreateNodeAndPopulateAutomaticAttributesImplTest") +public class CreateNodeAndPopulateAutomaticAttributesImplTest { + + @Test + public void testWithNoRunlist() { + ChefApi chef = createMock(ChefApi.class); + + Supplier<Map<String, JsonBall>> automaticSupplier = Suppliers.<Map<String, JsonBall>> ofInstance(ImmutableMap.<String, JsonBall> of()); + + Node nodeWithAutomatic = Node.builder().name("name").environment("_default") + .automaticAttributes(automaticSupplier.get()).build(); + + chef.createNode(nodeWithAutomatic); + + replay(chef); + + CreateNodeAndPopulateAutomaticAttributesImpl updater = new CreateNodeAndPopulateAutomaticAttributesImpl(chef, + automaticSupplier); + + updater.execute("name", ImmutableSet.<String> of()); + verify(chef); + + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/DeleteAllApisAndNodesInListImplLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/DeleteAllApisAndNodesInListImplLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/DeleteAllApisAndNodesInListImplLiveTest.java new file mode 100644 index 0000000..6f0e595 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/DeleteAllApisAndNodesInListImplLiveTest.java @@ -0,0 +1,64 @@ +/* + * 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.chef.strategy.internal; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.internal.BaseChefLiveTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Tests behavior of {@code DeleteAllApisAndNodesInListImpl} strategies + */ +@Test(groups = "live", testName = "DeleteAllApisAndNodesInListImplLiveTest") +public class DeleteAllApisAndNodesInListImplLiveTest extends BaseChefLiveTest<ChefApi> { + + private DeleteAllNodesInListImpl strategy; + private CreateNodeAndPopulateAutomaticAttributesImpl creator; + + @Override + protected void initialize() { + super.initialize(); + this.creator = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class); + this.strategy = injector.getInstance(DeleteAllNodesInListImpl.class); + } + + @Test + public void testExecute() throws InterruptedException { + try { + creator.execute(prefix, ImmutableSet.<String> of()); + creator.execute(prefix + 1, ImmutableSet.<String> of()); + + // http://tickets.corp.opscode.com/browse/PL-522 + // assert api.nodeExists(prefix); + assertNotNull(api.getNode(prefix)); + assertNotNull(api.getNode(prefix + 1)); + + strategy.execute(ImmutableSet.of(prefix, prefix + 1)); + assertNull(api.getNode(prefix)); + assertNull(api.getNode(prefix + 1)); + } finally { + api.deleteNode(prefix); + api.deleteNode(prefix + 1); + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImplLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImplLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImplLiveTest.java new file mode 100644 index 0000000..5f68fcf --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImplLiveTest.java @@ -0,0 +1,217 @@ +/* + * 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.chef.strategy.internal; + +import static com.google.common.collect.Iterables.size; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.io.File; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.domain.ChecksumStatus; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.domain.Metadata; +import org.jclouds.chef.domain.Resource; +import org.jclouds.chef.domain.Sandbox; +import org.jclouds.chef.domain.UploadSandbox; +import org.jclouds.chef.internal.BaseChefLiveTest; +import org.jclouds.io.Payloads; +import org.jclouds.io.payloads.FilePayload; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.hash.Hashing; +import com.google.common.io.Files; +import com.google.common.primitives.Bytes; + +/** + * Tests behavior of {@code ListCookbookVersionsInEnvironmentImpl} strategies + */ +@Test(groups = "live", testName = "ListCookbookVersionsInEnvironmentImplLiveTest") +public class ListCookbookVersionsInEnvironmentImplLiveTest extends BaseChefLiveTest<ChefApi> { + public static final String PREFIX = "jcloudstest-strategy-" + System.getProperty("user.name"); + + private ListCookbookVersionsInEnvironmentImpl strategy; + private CreateNodeAndPopulateAutomaticAttributesImpl creator; + + private ExecutorService testExecutorService; + private ListeningExecutorService testListeningExecutorService; + + @Override + protected void initialize() { + super.initialize(); + + try { + createCookbooksWithMultipleVersions(PREFIX); + createCookbooksWithMultipleVersions(PREFIX + 1); + } catch (Exception e) { + fail("Could not create cookbooks", e); + } + + this.strategy = injector.getInstance(ListCookbookVersionsInEnvironmentImpl.class); + this.testExecutorService = Executors.newFixedThreadPool(5); + this.testListeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5)); + } + + @AfterClass(groups = { "integration", "live" }) + @Override + protected void tearDown() { + api.deleteCookbook(PREFIX, "0.0.0"); + api.deleteCookbook(PREFIX, "1.0.0"); + api.deleteCookbook(PREFIX + 1, "0.0.0"); + api.deleteCookbook(PREFIX + 1, "1.0.0"); + + this.testExecutorService.shutdown(); + this.testListeningExecutorService.shutdown(); + + super.tearDown(); + } + + @Test + public void testExecute() { + assertTrue(size(strategy.execute("_default")) > 0, "Expected one or more elements"); + } + + @Test + public void testExecuteConcurrentlyWithExecutorService() { + assertTrue(size(strategy.execute(testExecutorService, "_default")) > 0, + "Expected one or more elements"); + } + + @Test + public void testExecuteConcurrentlyWithListeningExecutorService() { + assertTrue(size(strategy.execute(testListeningExecutorService, "_default")) > 0, + "Expected one or more elements"); + } + + @Test + public void testExecuteWithNumVersions() { + assertTrue(size(strategy.execute("_default", "2")) > 0, "Expected one or more elements"); + } + + @Test + public void testExecuteConcurrentlyWithNumVersionsAndExecutorService() { + assertTrue(size(strategy.execute(testExecutorService, "_default", "2")) > 0, + "Expected one or more elements"); + } + + @Test + public void testExecuteConcurrentlyWithNumVersionsAndListeningExecutorService() { + assertTrue(size(strategy.execute(testListeningExecutorService, "_default", "2")) > 0, + "Expected one or more elements"); + } + + @Test + public void testExecuteWithNumVersionsAll() { + assertTrue(size(strategy.execute("_default", "all")) > 0, "Expected one or more elements"); + } + + @Test + public void testExecuteConcurrentlyWithNumVersionsAllAndExecutorService() { + assertTrue(size(strategy.execute(testExecutorService, "_default", "all")) > 0, + "Expected one or more elements"); + } + + @Test + public void testExecuteConcurrentlyWithNumVersionsAllAndListeningExecutorService() { + assertTrue(size(strategy.execute(testListeningExecutorService, "_default", "all")) > 0, + "Expected one or more elements"); + } + + private FilePayload uploadContent(String fileName) throws Exception { + // Define the file you want in the cookbook + File file = new File(System.getProperty("user.dir"), fileName); + FilePayload content = Payloads.newFilePayload(file); + content.getContentMetadata().setContentType("application/x-binary"); + + // Get an md5 so that you can see if the server already has it or not + content.getContentMetadata().setContentMD5(Files.asByteSource(file).hash(Hashing.md5()).asBytes()); + + // Note that java collections cannot effectively do equals or hashcodes on + // byte arrays, so let's convert to a list of bytes. + List<Byte> md5 = Bytes.asList(content.getContentMetadata().getContentMD5()); + + // Request an upload site for this file + UploadSandbox site = api.createUploadSandboxForChecksums(ImmutableSet.of(md5)); + assertTrue(site.getChecksums().containsKey(md5), md5 + " not in " + site.getChecksums()); + + try { + // Upload the file contents, if still not uploaded + ChecksumStatus status = site.getChecksums().get(md5); + if (status.needsUpload()) { + api.uploadContent(status.getUrl(), content); + } + Sandbox sandbox = api.commitSandbox(site.getSandboxId(), true); + assertTrue(sandbox.isCompleted(), "Sandbox should be completed after uploading"); + } catch (RuntimeException e) { + api.commitSandbox(site.getSandboxId(), false); + fail("Could not upload content", e); + } + + return content; + } + + private void createCookbooksWithMultipleVersions(String cookbookName) throws Exception { + FilePayload v0content = uploadContent("pom.xml"); + FilePayload v1content = uploadContent("../README.md"); + + // Create the metadata of the cookbook + Metadata metadata = Metadata.builder() // + .name(cookbookName) // + .version("0.0.0") // + .description("Jclouds test uploaded cookbook") // + .maintainer("jclouds") // + .maintainerEmail("[email protected]") // + .license("Apache 2.0") // + .build(); + + // Create new cookbook version + CookbookVersion cookbook = CookbookVersion.builder(cookbookName, "0.0.0") // + .metadata(metadata) // + .rootFile(Resource.builder().fromPayload(v0content).build()) // + .build(); + + // upload the cookbook to the remote server + api.updateCookbook(cookbookName, "0.0.0", cookbook); + + // Create the metadata of the cookbook + metadata = Metadata.builder() // + .name(cookbookName) // + .version("1.0.0") // + .description("Jclouds test uploaded cookbook") // + .maintainer("jclouds") // + .maintainerEmail("[email protected]") // + .license("Apache 2.0") // + .build(); + + // Create a new cookbook version + cookbook = CookbookVersion.builder(cookbookName, "1.0.0") // + .metadata(metadata) // + .rootFile(Resource.builder().fromPayload(v1content).build()) // + .build(); + + // upload the cookbook to the remote server + api.updateCookbook(cookbookName, "1.0.0", cookbook); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListNodesImplLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListNodesImplLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListNodesImplLiveTest.java new file mode 100644 index 0000000..903b998 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListNodesImplLiveTest.java @@ -0,0 +1,82 @@ +/* + * 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.chef.strategy.internal; + +import static com.google.common.collect.Iterables.size; +import static org.testng.Assert.assertTrue; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.internal.BaseChefLiveTest; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Tests behavior of {@code ListNodesImpl} strategies + */ +@Test(groups = "live", testName = "ListNodesImplLiveTest") +public class ListNodesImplLiveTest extends BaseChefLiveTest<ChefApi> { + + private ListNodesImpl strategy; + private CreateNodeAndPopulateAutomaticAttributesImpl creator; + + private ExecutorService testExecutorService; + private ListeningExecutorService testListeningExecutorService; + + @Override + protected void initialize() { + super.initialize(); + this.creator = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class); + this.strategy = injector.getInstance(ListNodesImpl.class); + creator.execute(prefix, ImmutableSet.<String> of()); + creator.execute(prefix + 1, ImmutableSet.<String> of()); + + this.testExecutorService = Executors.newFixedThreadPool(5); + this.testListeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5)); + } + + @AfterClass(groups = { "integration", "live" }) + @Override + protected void tearDown() { + api.deleteNode(prefix); + api.deleteNode(prefix + 1); + + this.testExecutorService.shutdown(); + this.testListeningExecutorService.shutdown(); + + super.tearDown(); + } + + @Test + public void testExecute() { + assertTrue(size(strategy.execute()) > 0, "Expected one or more elements"); + } + + public void testExecuteConcurrentlyWithExecutorService() { + assertTrue(size(strategy.execute(testExecutorService)) > 0, "Expected one or more elements"); + } + + public void testExecuteConcurrentlyWithListeningExecutorService() { + assertTrue(size(strategy.execute(testListeningExecutorService)) > 0, "Expected one or more elements"); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListNodesInEnvironmentImplLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListNodesInEnvironmentImplLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListNodesInEnvironmentImplLiveTest.java new file mode 100644 index 0000000..f655d52 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListNodesInEnvironmentImplLiveTest.java @@ -0,0 +1,86 @@ +/* + * 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.chef.strategy.internal; + +import static com.google.common.collect.Iterables.size; +import static org.testng.Assert.assertTrue; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.internal.BaseChefLiveTest; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Tests behavior of {@code ListNodesInEnvironmentImpl} strategies + */ +@Test(groups = "live", testName = "ListNodesInEnvironmentImplLiveTest") +public class ListNodesInEnvironmentImplLiveTest extends BaseChefLiveTest<ChefApi> { + + private ListNodesInEnvironmentImpl strategy; + private CreateNodeAndPopulateAutomaticAttributesImpl creator; + + private ExecutorService testExecutorService; + private ListeningExecutorService testListeningExecutorService; + + @Override + protected void initialize() { + super.initialize(); + this.creator = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class); + this.strategy = injector.getInstance(ListNodesInEnvironmentImpl.class); + creator.execute(prefix, ImmutableSet.<String>of()); + creator.execute(prefix + 1, ImmutableSet.<String>of()); + + this.testExecutorService = Executors.newFixedThreadPool(5); + this.testListeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5)); + } + + @AfterClass(groups = { "integration", "live" }) + @Override + protected void tearDown() { + api.deleteNode(prefix); + api.deleteNode(prefix + 1); + + this.testExecutorService.shutdown(); + this.testListeningExecutorService.shutdown(); + + super.tearDown(); + } + + @Test + public void testExecute() { + assertTrue(size(strategy.execute("_default")) > 0, "Expected one or more elements"); + } + + @Test + public void testExecuteConcurrentlyWithExecutorService() { + assertTrue(size(strategy.execute(testExecutorService, "_default")) > 0, + "Expected one or more elements"); + } + + @Test + public void testExecuteConcurrentlyWithListeningExecutorService() { + assertTrue(size(strategy.execute(testListeningExecutorService, "_default")) > 0, + "Expected one or more elements"); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java new file mode 100644 index 0000000..a8f7438 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java @@ -0,0 +1,61 @@ +/* + * 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.chef.strategy.internal; + +import static org.testng.Assert.assertEquals; + +import java.util.Set; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.internal.BaseChefLiveTest; +import org.jclouds.ohai.config.OhaiModule.CurrentUserProvider; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Tests behavior of {@code UpdateAutomaticAttributesOnNodeImpl} strategies + */ +@Test(groups = "live", testName = "UpdateAutomaticAttributesOnNodeImplLiveTest") +public class UpdateAutomaticAttributesOnNodeImplLiveTest extends BaseChefLiveTest<ChefApi> { + + private CurrentUserProvider currentUserProvider; + private UpdateAutomaticAttributesOnNodeImpl strategy; + + @Override + protected void initialize() { + super.initialize(); + this.currentUserProvider = injector.getInstance(CurrentUserProvider.class); + this.strategy = injector.getInstance(UpdateAutomaticAttributesOnNodeImpl.class); + } + + @Test + public void testExecute() { + Set<String> runList = ImmutableSet.of("role[" + prefix + "]"); + try { + api.createNode(Node.builder().name(prefix).runList(runList).environment("_default").build()); + strategy.execute(prefix); + Node node = api.getNode(prefix); + assertEquals(node.getName(), prefix); + assertEquals(node.getRunList(), runList); + assertEquals(node.getAutomaticAttributes().get("current_user").toString(), currentUserProvider.get().toString()); + } finally { + api.deleteNode(prefix); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java new file mode 100644 index 0000000..2e0d198 --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java @@ -0,0 +1,63 @@ +/* + * 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.chef.strategy.internal; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; + +import java.util.Map; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.domain.Node; +import org.jclouds.domain.JsonBall; +import org.testng.annotations.Test; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableMap; + +/** + * Tests behavior of {@code UpdateAutomaticAttributesOnNodeImpl} + */ +@Test(groups = { "unit" }) +public class UpdateAutomaticAttributesOnNodeImplTest { + + @Test + public void test() { + ChefApi chef = createMock(ChefApi.class); + + Map<String, JsonBall> automatic = ImmutableMap.<String, JsonBall> of(); + Supplier<Map<String, JsonBall>> automaticSupplier = Suppliers.<Map<String, JsonBall>> ofInstance(automatic); + + Node node = Node.builder().name("name").environment("_default").build(); + Node nodeWithAutomatic = Node.builder().name("name").environment("_default").automaticAttributes(automatic) + .build(); + + expect(chef.getNode("name")).andReturn(node); + expect(chef.updateNode(nodeWithAutomatic)).andReturn(null); + + replay(chef); + + UpdateAutomaticAttributesOnNodeImpl updater = new UpdateAutomaticAttributesOnNodeImpl(chef, automaticSupplier); + + updater.execute("name"); + verify(chef); + + } +}
