Fixed skipped chef-core live tests

* Refactored client creation tests and their dependencies to avoid
  errors related to context re-creation.
* Added method to ChefAsyncClient to get the contents of a resource
  (like a file in a cookbook) sending the authentication headers.
* Refactored chef-core live tests dependencies to avoid unnecessary test
  skips.
This commit is contained in:
Ignasi Barrera 2012-06-28 15:50:55 +02:00
parent de89539c85
commit 56fe3069a8
7 changed files with 256 additions and 122 deletions

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.chef;
import java.io.InputStream;
import java.net.URI;
import java.util.List;
import java.util.Set;
@ -45,6 +46,7 @@ import org.jclouds.chef.domain.Client;
import org.jclouds.chef.domain.CookbookVersion;
import org.jclouds.chef.domain.DatabagItem;
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;
@ -55,6 +57,7 @@ import org.jclouds.chef.functions.ParseSearchClientsFromJson;
import org.jclouds.chef.functions.ParseSearchDatabagFromJson;
import org.jclouds.chef.functions.ParseSearchNodesFromJson;
import org.jclouds.chef.functions.ParseSearchRolesFromJson;
import org.jclouds.chef.functions.UriForResource;
import org.jclouds.chef.options.CreateClientOptions;
import org.jclouds.io.Payload;
import org.jclouds.rest.annotations.BinderParam;
@ -90,7 +93,7 @@ public interface ChefAsyncClient {
public static final String VERSION = "0.9.8";
/**
* @see ChefClient#getUploadSandboxForChecksums
* @see ChefClient#getUploadSandboxForChecksums(Set)
*/
@POST
@Path("/sandboxes")
@ -105,7 +108,7 @@ public interface ChefAsyncClient {
ListenableFuture<Void> uploadContent(@EndpointParam URI location, Payload content);
/**
* @see ChefClient#commitSandbox
* @see ChefClient#commitSandbox(String, boolean)
*/
@PUT
@Path("/sandboxes/{id}")
@ -113,7 +116,7 @@ public interface ChefAsyncClient {
@BinderParam(BindIsCompletedToJsonPayload.class) boolean isCompleted);
/**
* @see ChefCookbooks#listCookbooks
* @see ChefClient#listCookbooks()
*/
@GET
@Path("/cookbooks")
@ -122,7 +125,7 @@ public interface ChefAsyncClient {
ListenableFuture<Set<String>> listCookbooks();
/**
* @see ChefClient#updateCookbook
* @see ChefClient#updateCookbook(String, String, CookbookVersion)
*/
@PUT
@Path("/cookbooks/{cookbookname}/{version}")
@ -130,7 +133,7 @@ public interface ChefAsyncClient {
@PathParam("version") String version, @BinderParam(BindToJsonPayload.class) CookbookVersion cookbook);
/**
* @see ChefCookbook#deleteCookbook(String)
* @see ChefClient#deleteCookbook(String, String)
*/
@DELETE
@Path("/cookbooks/{cookbookname}/{version}")
@ -139,7 +142,7 @@ public interface ChefAsyncClient {
@PathParam("version") String version);
/**
* @see ChefCookbook#getVersionsOfCookbook
* @see ChefClient#getVersionsOfCookbook(String)
*/
@GET
@Path("/cookbooks/{cookbookname}")
@ -148,7 +151,7 @@ public interface ChefAsyncClient {
ListenableFuture<Set<String>> getVersionsOfCookbook(@PathParam("cookbookname") String cookbookName);
/**
* @see ChefCookbook#getCookbook
* @see ChefClient#getCookbook(String, String)
*/
@GET
@Path("/cookbooks/{cookbookname}/{version}")
@ -173,7 +176,7 @@ public interface ChefAsyncClient {
ListenableFuture<Client> createClient(@PayloadParam("name") String clientname, CreateClientOptions options);
/**
* @see ChefClient#generateKeyForClient
* @see ChefClient#generateKeyForClient(String)
*/
@PUT
@Path("/clients/{clientname}")
@ -181,7 +184,7 @@ public interface ChefAsyncClient {
@PathParam("clientname") @BinderParam(BindGenerateKeyForClientToJsonPayload.class) String clientname);
/**
* @see ChefClient#clientExists
* @see ChefClient#clientExists(String)
*/
@HEAD
@Path("/clients/{clientname}")
@ -189,7 +192,7 @@ public interface ChefAsyncClient {
ListenableFuture<Boolean> clientExists(@PathParam("clientname") String clientname);
/**
* @see ChefClient#getClient
* @see ChefClient#getClient(String)
*/
@GET
@Path("/clients/{clientname}")
@ -197,7 +200,7 @@ public interface ChefAsyncClient {
ListenableFuture<Client> getClient(@PathParam("clientname") String clientname);
/**
* @see ChefClient#deleteClient
* @see ChefClient#deleteClient(String)
*/
@DELETE
@Path("/clients/{clientname}")
@ -205,7 +208,7 @@ public interface ChefAsyncClient {
ListenableFuture<Client> deleteClient(@PathParam("clientname") String clientname);
/**
* @see ChefClient#listClients
* @see ChefClient#listClients()
*/
@GET
@Path("/clients")
@ -214,14 +217,14 @@ public interface ChefAsyncClient {
ListenableFuture<Set<String>> listClients();
/**
* @see ChefClient#createNode
* @see ChefClient#createNode(Node)
*/
@POST
@Path("/nodes")
ListenableFuture<Void> createNode(@BinderParam(BindToJsonPayload.class) Node node);
/**
* @see ChefClient#updateNode
* @see ChefClient#updateNode(Node)
*/
@PUT
@Path("/nodes/{nodename}")
@ -229,7 +232,7 @@ public interface ChefAsyncClient {
@PathParam("nodename") @ParamParser(NodeName.class) @BinderParam(BindToJsonPayload.class) Node node);
/**
* @see ChefNode#nodeExists
* @see ChefClient#nodeExists(String)
*/
@HEAD
@Path("/nodes/{nodename}")
@ -237,7 +240,7 @@ public interface ChefAsyncClient {
ListenableFuture<Boolean> nodeExists(@PathParam("nodename") String nodename);
/**
* @see ChefNode#getNode
* @see ChefClient#getNode(String)
*/
@GET
@Path("/nodes/{nodename}")
@ -253,7 +256,7 @@ public interface ChefAsyncClient {
ListenableFuture<Node> deleteNode(@PathParam("nodename") String nodename);
/**
* @see ChefNode#listNodes
* @see ChefClient#listNodes()
*/
@GET
@Path("/nodes")
@ -262,14 +265,14 @@ public interface ChefAsyncClient {
ListenableFuture<Set<String>> listNodes();
/**
* @see ChefClient#createRole
* @see ChefClient#createRole(Role)
*/
@POST
@Path("/roles")
ListenableFuture<Void> createRole(@BinderParam(BindToJsonPayload.class) Role role);
/**
* @see ChefClient#updateRole
* @see ChefClient#updateRole(Role)
*/
@PUT
@Path("/roles/{rolename}")
@ -277,7 +280,7 @@ public interface ChefAsyncClient {
@PathParam("rolename") @ParamParser(RoleName.class) @BinderParam(BindToJsonPayload.class) Role role);
/**
* @see ChefRole#roleExists
* @see ChefClient#roleExists(String)
*/
@HEAD
@Path("/roles/{rolename}")
@ -285,7 +288,7 @@ public interface ChefAsyncClient {
ListenableFuture<Boolean> roleExists(@PathParam("rolename") String rolename);
/**
* @see ChefRole#getRole
* @see ChefClient#getRole(String)
*/
@GET
@Path("/roles/{rolename}")
@ -293,7 +296,7 @@ public interface ChefAsyncClient {
ListenableFuture<Role> getRole(@PathParam("rolename") String rolename);
/**
* @see ChefRole#deleteRole
* @see ChefClient#deleteRole(String)
*/
@DELETE
@Path("/roles/{rolename}")
@ -301,7 +304,7 @@ public interface ChefAsyncClient {
ListenableFuture<Role> deleteRole(@PathParam("rolename") String rolename);
/**
* @see ChefRole#listRoles
* @see ChefClient#listRoles()
*/
@GET
@Path("/roles")
@ -310,7 +313,7 @@ public interface ChefAsyncClient {
ListenableFuture<Set<String>> listRoles();
/**
* @see ChefClient#listDatabags
* @see ChefClient#listDatabags()
*/
@GET
@Path("/data")
@ -319,14 +322,14 @@ public interface ChefAsyncClient {
ListenableFuture<Set<String>> listDatabags();
/**
* @see ChefClient#createDatabag
* @see ChefClient#createDatabag(String)
*/
@POST
@Path("/data")
ListenableFuture<Void> createDatabag(@BinderParam(BindNameToJsonPayload.class) String databagName);
/**
* @see ChefClient#databagExists
* @see ChefClient#databagExists(String)
*/
@HEAD
@Path("/data/{name}")
@ -334,7 +337,7 @@ public interface ChefAsyncClient {
ListenableFuture<Boolean> databagExists(@PathParam("name") String databagName);
/**
* @see ChefClient#deleteDatabag
* @see ChefClient#deleteDatabag(String)
*/
@DELETE
@Path("/data/{name}")
@ -342,7 +345,7 @@ public interface ChefAsyncClient {
ListenableFuture<Void> deleteDatabag(@PathParam("name") String databagName);
/**
* @see ChefClient#listDatabagItems
* @see ChefClient#listDatabagItems(String)
*/
@GET
@Path("/data/{name}")
@ -351,7 +354,7 @@ public interface ChefAsyncClient {
ListenableFuture<Set<String>> listDatabagItems(@PathParam("name") String databagName);
/**
* @see ChefClient#createDatabagItem
* @see ChefClient#createDatabagItem(String, DatabagItem)
*/
@POST
@Path("/data/{databagName}")
@ -359,7 +362,7 @@ public interface ChefAsyncClient {
@BinderParam(BindToJsonPayload.class) DatabagItem databagItem);
/**
* @see ChefClient#updateDatabagItem
* @see ChefClient#updateDatabagItem(String, DatabagItem)
*/
@PUT
@Path("/data/{databagName}/{databagItemId}")
@ -368,7 +371,7 @@ public interface ChefAsyncClient {
@PathParam("databagItemId") @ParamParser(DatabagItemId.class) @BinderParam(BindToJsonPayload.class) DatabagItem item);
/**
* @see ChefClient#databagItemExists
* @see ChefClient#databagItemExists(String, String)
*/
@HEAD
@Path("/data/{databagName}/{databagItemId}")
@ -377,7 +380,7 @@ public interface ChefAsyncClient {
@PathParam("databagItemId") String databagItemId);
/**
* @see ChefClient#getDatabagItem
* @see ChefClient#getDatabagItem(String, String)
*/
@GET
@Path("/data/{databagName}/{databagItemId}")
@ -386,7 +389,7 @@ public interface ChefAsyncClient {
@PathParam("databagItemId") String databagItemId);
/**
* @see ChefClient#deleteDatabagItem
* @see ChefClient#deleteDatabagItem(String, String)
*/
@DELETE
@Path("/data/{databagName}/{databagItemId}")
@ -395,7 +398,7 @@ public interface ChefAsyncClient {
@PathParam("databagItemId") String databagItemId);
/**
* @see ChefClient#listSearchIndexes
* @see ChefClient#listSearchIndexes()
*/
@GET
@Path("/search")
@ -404,7 +407,7 @@ public interface ChefAsyncClient {
ListenableFuture<Set<String>> listSearchIndexes();
/**
* @see ChefClient#searchRoles
* @see ChefClient#searchRoles()
*/
@GET
@Path("/search/role")
@ -412,7 +415,7 @@ public interface ChefAsyncClient {
ListenableFuture<? extends SearchResult<? extends Role>> searchRoles();
/**
* @see ChefClient#searchClients
* @see ChefClient#searchClients()
*/
@GET
@Path("/search/client")
@ -420,7 +423,7 @@ public interface ChefAsyncClient {
ListenableFuture<? extends SearchResult<? extends Client>> searchClients();
/**
* @see ChefClient#searchNodes
* @see ChefClient#searchNodes()
*/
@GET
@Path("/search/node")
@ -428,11 +431,18 @@ public interface ChefAsyncClient {
ListenableFuture<? extends SearchResult<? extends Node>> searchNodes();
/**
* @see ChefClient#searchDatabag
* @see ChefClient#searchDatabag(String)
*/
@GET
@Path("/search/{databagName}")
@ResponseParser(ParseSearchDatabagFromJson.class)
ListenableFuture<? extends SearchResult<? extends DatabagItem>> searchDatabag(
@PathParam("databagName") String databagName);
/**
* @see ChefClient#getResourceContents(Resource)
*/
@GET
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<InputStream> getResourceContents(@EndpointParam(parser=UriForResource.class) Resource resource);
}

View File

@ -18,26 +18,36 @@
*/
package org.jclouds.chef;
import java.io.InputStream;
import java.net.URI;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.GET;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.domain.CookbookVersion;
import org.jclouds.chef.domain.DatabagItem;
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.functions.UriForResource;
import org.jclouds.chef.options.CreateClientOptions;
import org.jclouds.concurrent.Timeout;
import org.jclouds.http.HttpResponseException;
import org.jclouds.io.Payload;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.binders.BindToJsonPayload;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides synchronous access to Chef.
@ -565,4 +575,10 @@ public interface ChefClient {
*/
SearchResult<? extends DatabagItem> searchDatabag(String databagName);
/**
* Get the contents of the given resource.
* @param resource The resource to get.
* @return An input stream for the content of the requested resource.
*/
InputStream getResourceContents(Resource resource);
}

View File

@ -0,0 +1,44 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import org.jclouds.chef.domain.Resource;
import com.google.common.base.Function;
/**
* Extracts the uri field of the given {@link Resource}.
*
* @author Ignasi Barrera
*/
public class UriForResource implements Function<Object, URI> {
@Override
public URI apply(Object input) {
checkArgument(checkNotNull(input, "input") instanceof Resource,
"This function can only be applied to Resource objects");
return ((Resource) input).getUrl();
}
}

View File

@ -25,6 +25,7 @@ import static com.google.common.collect.Sets.newLinkedHashSet;
import static org.jclouds.concurrent.Futures.compose;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.List;
import java.util.Set;
@ -44,6 +45,7 @@ import org.jclouds.chef.domain.Client;
import org.jclouds.chef.domain.CookbookVersion;
import org.jclouds.chef.domain.DatabagItem;
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;
@ -325,4 +327,9 @@ public class TransientChefAsyncClient implements ChefAsyncClient {
throw new UnsupportedOperationException();
}
@Override
public ListenableFuture<InputStream> getResourceContents(Resource resource) {
throw new UnsupportedOperationException();
}
}

View File

@ -30,6 +30,7 @@ import org.jclouds.chef.config.ChefRestClientModule;
import org.jclouds.chef.domain.CookbookVersion;
import org.jclouds.chef.domain.DatabagItem;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.domain.Resource;
import org.jclouds.chef.domain.Role;
import org.jclouds.chef.filters.SignedHeaderAuth;
import org.jclouds.chef.filters.SignedHeaderAuthTest;
@ -44,6 +45,7 @@ import org.jclouds.date.TimeStamp;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.http.functions.ReturnInputStream;
import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.io.Payload;
import org.jclouds.io.payloads.StringPayload;
@ -741,6 +743,23 @@ public class ChefAsyncClientTest extends BaseAsyncClientTest<ChefAsyncClient> {
checkFilters(httpRequest);
}
public void testGetResourceContents() throws SecurityException, NoSuchMethodException, IOException {
Method method = ChefAsyncClient.class.getMethod("getResourceContents", Resource.class);
GeneratedHttpRequest<ChefAsyncClient> httpRequest = processor.createRequest(method,
new Resource("test", URI.create("http://foo/bar"), new byte[]{}, null, null));
assertRequestLineEquals(httpRequest, "GET http://foo/bar HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: 0.9.8\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ReturnInputStream.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override
protected void checkFilters(HttpRequest request) {

View File

@ -0,0 +1,58 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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}
*
* @author Ignasi Barrera
*/
@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 = new Resource("test", URI.create("http://foo/bar"), null, null, null);
URI result = function.apply(res);
assertEquals(res.getUrl().toString(), result.toString());
}
}

View File

@ -19,7 +19,9 @@
package org.jclouds.chef.internal;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.io.File;
import java.io.InputStream;
@ -62,26 +64,8 @@ import com.google.common.primitives.Bytes;
@Test(groups = { "live", "integration" })
public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
public static final String PREFIX = System.getProperty("user.name") + "-jcloudstest";
protected String clientIdentity = PREFIX;
protected String clientCredential;
protected ChefContext clientContext;
/**
* at runtime, we attempt to create a new chef client
* @throws InterruptedException
*/
protected void recreateClientConnection() throws InterruptedException {
Closeables.closeQuietly(clientContext);
clientContext = createContext(setupClientProperties(), setupModules());
}
protected Properties setupClientProperties() {
Properties overrides = setupProperties();
overrides.setProperty(provider + ".identity", clientIdentity);
overrides.setProperty(provider + ".credential", clientCredential);
return overrides;
}
public static final String ADMIN_PREFIX = System.getProperty("user.name") + "-jcloudstest-adm";
public static final String VALIDATOR_PREFIX = System.getProperty("user.name") + "-jcloudstest-val";
private String validatorIdentity;
private String validatorCredential;
@ -155,37 +139,36 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
@Test(dependsOnMethods = "testCreateClient")
public void testGenerateKeyForClient() throws Exception {
testCreateClient(); // Make sure we use the right client
clientCredential = Pems.pem(clientContext.getApi().generateKeyForClient(PREFIX).getPrivateKey());
assertNotNull(clientCredential);
recreateClientConnection();
clientContext.getApi().clientExists(PREFIX);
String credential = Pems.pem(context.getApi().generateKeyForClient(PREFIX).getPrivateKey());
assertClientCreated(PREFIX, credential);
}
@Test(dependsOnMethods = "testCreateNewCookbook")
@Test
public void testListCookbooks() throws Exception {
for (String cookbook : context.getApi().listCookbooks())
Set<String> cookbooksNames = context.getApi().listCookbooks();
assertFalse(cookbooksNames.isEmpty());
for (String cookbook : cookbooksNames)
for (String version : context.getApi().getVersionsOfCookbook(cookbook)) {
System.err.printf("%s/%s:%n", cookbook, version);
//System.err.printf("%s/%s:%n", cookbook, version);
CookbookVersion cookbookO = context.getApi().getCookbook(cookbook, version);
for (Resource resource : ImmutableList.<Resource> builder().addAll(cookbookO.getDefinitions()).addAll(
cookbookO.getFiles()).addAll(cookbookO.getLibraries()).addAll(cookbookO.getSuppliers()).addAll(
cookbookO.getRecipes()).addAll(cookbookO.getResources()).addAll(cookbookO.getRootFiles()).addAll(
cookbookO.getTemplates()).build()) {
try {
InputStream stream = context.utils().http().get(resource.getUrl());
InputStream stream = context.getApi().getResourceContents(resource);
byte[] md5 = CryptoStreams.md5(InputSuppliers.of(stream));
assertEquals(md5, resource.getChecksum());
} catch (NullPointerException e) {
assert false : "resource not found: " + resource;
}
System.err.printf("resource %s ok%n", resource.getName());
//System.err.printf("resource %s ok%n", resource.getName());
}
}
}
@Test(dependsOnMethods = "testListCookbooks")
@Test(dependsOnMethods = "testCreateNewCookbook")
public void testUpdateCookbook() throws Exception {
for (String cookbook : context.getApi().listCookbooks())
for (String version : context.getApi().getVersionsOfCookbook(cookbook)) {
@ -195,7 +178,7 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
}
}
@Test(dependsOnMethods = "testUpdateCookbook")
@Test(dependsOnMethods = {"testCreateNewCookbook", "testUpdateCookbook"}, enabled = false)
public void testCreateCookbook() throws Exception {
for (String cookbook : context.getApi().listCookbooks())
for (String version : context.getApi().getVersionsOfCookbook(cookbook)) {
@ -220,47 +203,26 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
@Test
public void testValidatorCanCreateClient() throws Exception {
context.getApi().deleteClient(PREFIX);
clientCredential = Pems.pem(validatorContext.getApi().createClient(PREFIX).getPrivateKey());
recreateClientConnection();
clientContext.getApi().clientExists(PREFIX);
Set<String> clients = context.getApi().listClients();
assert clients.contains(PREFIX) : String.format("client %s not in %s", PREFIX, clients);
assertNotNull(clientContext.getApi().getClient(PREFIX));
String credential = Pems.pem(validatorContext.getApi().createClient(VALIDATOR_PREFIX).getPrivateKey());
assertClientCreated(VALIDATOR_PREFIX, credential);
}
@Test
public void testCreateClient() throws Exception {
context.getApi().deleteClient(PREFIX);
clientCredential = Pems.pem(context.getApi().createClient(PREFIX).getPrivateKey());
recreateClientConnection();
clientContext.getApi().clientExists(PREFIX);
Set<String> clients = context.getApi().listClients();
assert clients.contains(PREFIX) : String.format("client %s not in %s", PREFIX, clients);
assertNotNull(clientContext.getApi().getClient(PREFIX));
String credential = Pems.pem(context.getApi().createClient(PREFIX).getPrivateKey());
assertClientCreated(PREFIX, credential);
}
@Test
public void testCreateAdminClient() throws Exception {
context.getApi().deleteClient(PREFIX);
clientCredential = Pems.pem(context.getApi().createClient(PREFIX, CreateClientOptions.Builder.admin())
.getPrivateKey());
recreateClientConnection();
clientContext.getApi().clientExists(PREFIX);
Set<String> clients = context.getApi().listClients();
assert clients.contains(PREFIX) : String.format("client %s not in %s", PREFIX, clients);
assertNotNull(clientContext.getApi().getClient(PREFIX));
String credential = Pems.pem(context.getApi().createClient(ADMIN_PREFIX, CreateClientOptions.Builder.admin())
.getPrivateKey());
assertClientCreated(ADMIN_PREFIX, credential);
}
@Test(dependsOnMethods = "testCreateClient")
@Test
public void testClientExists() throws Exception {
assertNotNull(validatorContext.getApi().clientExists(PREFIX));
assertNotNull(context.getApi().clientExists(validatorIdentity));
}
@Test
@ -272,7 +234,7 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
@Test(dependsOnMethods = "testCreateRole")
public void testCreateNode() throws Exception {
context.getApi().deleteNode(PREFIX);
clientContext.getApi().createNode(new Node(PREFIX, Collections.singleton("role[" + PREFIX + "]")));
context.getApi().createNode(new Node(PREFIX, Collections.singleton("role[" + PREFIX + "]")));
node = context.getApi().getNode(PREFIX);
// TODO check recipes
assertNotNull(node);
@ -282,12 +244,12 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
@Test(dependsOnMethods = "testCreateNode")
public void testNodeExists() throws Exception {
assertNotNull(clientContext.getApi().nodeExists(PREFIX));
assertNotNull(context.getApi().nodeExists(PREFIX));
}
@Test(dependsOnMethods = "testNodeExists")
public void testUpdateNode() throws Exception {
for (String nodename : clientContext.getApi().listNodes()) {
for (String nodename : context.getApi().listNodes()) {
Node node = context.getApi().getNode(nodename);
context.getApi().updateNode(node);
}
@ -299,7 +261,7 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
assertNotNull(roles);
}
@Test(dependsOnMethods = "testCreateClient")
@Test
public void testCreateRole() throws Exception {
context.getApi().deleteRole(PREFIX);
context.getApi().createRole(new Role(PREFIX, Collections.singleton("recipe[java]")));
@ -311,12 +273,12 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
@Test(dependsOnMethods = "testCreateRole")
public void testRoleExists() throws Exception {
assertNotNull(clientContext.getApi().roleExists(PREFIX));
assertNotNull(context.getApi().roleExists(PREFIX));
}
@Test(dependsOnMethods = "testRoleExists")
public void testUpdateRole() throws Exception {
for (String rolename : clientContext.getApi().listRoles()) {
for (String rolename : context.getApi().listRoles()) {
Role role = context.getApi().getRole(rolename);
context.getApi().updateRole(role);
}
@ -328,7 +290,7 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
assertNotNull(databags);
}
@Test(dependsOnMethods = "testCreateClient")
@Test
public void testCreateDatabag() throws Exception {
context.getApi().deleteDatabag(PREFIX);
context.getApi().createDatabag(PREFIX);
@ -336,7 +298,7 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
@Test(dependsOnMethods = "testCreateDatabag")
public void testDatabagExists() throws Exception {
assertNotNull(clientContext.getApi().databagExists(PREFIX));
assertNotNull(context.getApi().databagExists(PREFIX));
}
@Test(dependsOnMethods = "testCreateDatabagItem")
@ -345,7 +307,7 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
assertNotNull(databagItems);
}
@Test(dependsOnMethods = { "testCreateDatabag", "testCreateRole" })
@Test(dependsOnMethods = "testCreateDatabag")
public void testCreateDatabagItem() throws Exception {
Properties config = new Properties();
config.setProperty("foo", "bar");
@ -354,17 +316,23 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
new DatabagItem("config", context.utils().json().toJson(config)));
assertNotNull(databagItem);
assertEquals(databagItem.getId(), "config");
assertEquals(config, context.utils().json().fromJson(databagItem.toString(), Properties.class));
// The databagItem json contains extra keys: (the name and the type if the item)
Properties props = context.utils().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 testDatabagItemExists() throws Exception {
assertNotNull(clientContext.getApi().databagItemExists(PREFIX, PREFIX));
assertNotNull(context.getApi().databagItemExists(PREFIX, PREFIX));
}
@Test(dependsOnMethods = "testDatabagItemExists")
public void testUpdateDatabagItem() throws Exception {
for (String databagItemId : clientContext.getApi().listDatabagItems(PREFIX)) {
for (String databagItemId : context.getApi().listDatabagItems(PREFIX)) {
DatabagItem databagItem = context.getApi().getDatabagItem(PREFIX, databagItemId);
context.getApi().updateDatabagItem(PREFIX, databagItem);
}
@ -412,17 +380,29 @@ public abstract class BaseChefClientLiveTest extends BaseChefContextLiveTest {
@AfterClass(groups = { "live", "integration" })
@Override
public void tearDownContext() {
Closeables.closeQuietly(clientContext);
if (validatorContext.getApi().clientExists(PREFIX))
validatorContext.getApi().deleteClient(PREFIX);
Closeables.closeQuietly(validatorContext);
if (context.getApi().nodeExists(PREFIX))
context.getApi().deleteNode(PREFIX);
if (context.getApi().roleExists(PREFIX))
context.getApi().deleteRole(PREFIX);
if (context.getApi().databagExists(PREFIX))
context.getApi().deleteDatabag(PREFIX);
context.getApi().deleteClient(PREFIX);
context.getApi().deleteClient(ADMIN_PREFIX);
context.getApi().deleteClient(VALIDATOR_PREFIX);
context.getApi().deleteNode(PREFIX);
context.getApi().deleteRole(PREFIX);
context.getApi().deleteDatabag(PREFIX);
super.tearDownContext();
}
private void assertClientCreated(String identity, String credential) {
Properties overrides = super.setupProperties();
overrides.setProperty(provider + ".identity", identity);
overrides.setProperty(provider + ".credential", credential);
ChefContext clientContext = createContext(overrides, setupModules());
try {
Client client = clientContext.getApi().getClient(identity);
assertNotNull(client);
} finally {
Closeables.closeQuietly(clientContext);
}
}
}