http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/test/java/org/apache/brooklyn/core/util/file/ArchiveBuilderTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/util/file/ArchiveBuilderTest.java b/core/src/test/java/org/apache/brooklyn/core/util/file/ArchiveBuilderTest.java new file mode 100644 index 0000000..0ce8298 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/util/file/ArchiveBuilderTest.java @@ -0,0 +1,194 @@ +/* + * 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.apache.brooklyn.core.util.file; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.annotation.Nullable; + +import org.apache.brooklyn.core.util.file.ArchiveBuilder; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import brooklyn.util.collections.MutableSet; +import brooklyn.util.os.Os; +import brooklyn.util.text.Identifiers; + +import com.google.common.base.Charsets; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.io.Files; + +/** + * Test the operation of the {@link ArchiveBuilder} class. + */ +@Test +public class ArchiveBuilderTest { + + private File parentDir, tmpDir, tmpDir2; + private Predicate<ZipEntry> isDirectory = new Predicate<ZipEntry>() { + @Override + public boolean apply(@Nullable ZipEntry input) { + return input.isDirectory(); + } + }; + + @BeforeClass + public void createTmpDirAndFiles() throws IOException { + parentDir = Os.newTempDir(getClass().getSimpleName()); + Os.deleteOnExitRecursively(parentDir); + tmpDir = new File(parentDir, Identifiers.makeRandomId(4)); + Os.mkdirs(tmpDir); + Files.write("abcdef", new File(tmpDir, "data01.txt"), Charsets.US_ASCII); + Files.write("123456", new File(tmpDir, "data02.txt"), Charsets.US_ASCII); + Files.write("qqqqqq", new File(tmpDir, "data03.txt"), Charsets.US_ASCII); + + tmpDir2 = new File(parentDir, Identifiers.makeRandomId(4)); + Os.mkdirs(tmpDir2); + Files.write("zzzzzz", new File(tmpDir2, "data04.txt"), Charsets.US_ASCII); + } + + @Test + public void testCreateZipFromDir() throws Exception { + File archive = ArchiveBuilder.zip().addDirContentsAt(tmpDir, ".").create(); + archive.deleteOnExit(); + + List<ZipEntry> entries = Lists.newArrayList(); + ZipInputStream input = new ZipInputStream(new FileInputStream(archive)); + ZipEntry entry = input.getNextEntry(); + while (entry != null) { + entries.add(entry); + entry = input.getNextEntry(); + } + assertEquals(entries.size(), 4); + Iterable<ZipEntry> directories = Iterables.filter(entries, isDirectory); + Iterable<ZipEntry> files = Iterables.filter(entries, Predicates.not(isDirectory)); + assertEquals(Iterables.size(directories), 1); + assertEquals(Iterables.size(files), 3); + String dirName = Iterables.getOnlyElement(directories).getName(); + assertEquals(dirName, "./"); + + Set<String> names = MutableSet.of(); + for (ZipEntry file : files) { + assertTrue(file.getName().startsWith(dirName)); + names.add(file.getName()); + } + assertTrue(names.contains("./data01.txt")); + assertFalse(names.contains("./data04.txt")); + input.close(); + } + + @Test + public void testCreateZipFromTwoDirs() throws Exception { + File archive = ArchiveBuilder.zip().addDirContentsAt(tmpDir, ".").addDirContentsAt(tmpDir2, ".").create(); + archive.deleteOnExit(); + + List<ZipEntry> entries = Lists.newArrayList(); + ZipInputStream input = new ZipInputStream(new FileInputStream(archive)); + ZipEntry entry = input.getNextEntry(); + while (entry != null) { + entries.add(entry); + entry = input.getNextEntry(); + } + assertEquals(entries.size(), 5); + Iterable<ZipEntry> directories = Iterables.filter(entries, isDirectory); + Iterable<ZipEntry> files = Iterables.filter(entries, Predicates.not(isDirectory)); + assertEquals(Iterables.size(directories), 1); + assertEquals(Iterables.size(files), 4); + String dirName = Iterables.getOnlyElement(directories).getName(); + assertEquals(dirName, "./"); + + Set<String> names = MutableSet.of(); + for (ZipEntry file : files) { + assertTrue(file.getName().startsWith(dirName)); + names.add(file.getName()); + } + assertTrue(names.contains("./data01.txt")); + assertTrue(names.contains("./data04.txt")); + input.close(); + } + @Test + public void testCreateZipFromFiles() throws Exception { + ArchiveBuilder builder = ArchiveBuilder.zip(); + for (String fileName : Arrays.asList("data01.txt", "data02.txt", "data03.txt")) { + builder.addAt(new File(tmpDir, fileName), "."); + } + File archive = builder.create(); + archive.deleteOnExit(); + + List<ZipEntry> entries = Lists.newArrayList(); + ZipInputStream input = new ZipInputStream(new FileInputStream(archive)); + ZipEntry entry = input.getNextEntry(); + while (entry != null) { + entries.add(entry); + entry = input.getNextEntry(); + } + assertEquals(entries.size(), 3); + Iterable<ZipEntry> directories = Iterables.filter(entries, isDirectory); + Iterable<ZipEntry> files = Iterables.filter(entries, Predicates.not(isDirectory)); + assertTrue(Iterables.isEmpty(directories)); + assertEquals(Iterables.size(files), 3); + for (ZipEntry file : files) { + assertTrue(file.getName().startsWith(Os.mergePathsUnix(".", "data"))); + } + input.close(); + } + + @Test + public void testCreateZipFromFilesWithBaseDir() throws Exception { + ArchiveBuilder builder = ArchiveBuilder.zip(); + String baseDir = tmpDir.getName(); + for (String fileName : Arrays.asList("data01.txt", "data02.txt", "data03.txt")) { + builder.addFromLocalBaseDir(parentDir, Os.mergePaths(baseDir, fileName)); + } + File archive = builder.create(); + archive.deleteOnExit(); + + List<ZipEntry> entries = Lists.newArrayList(); + ZipInputStream input = new ZipInputStream(new FileInputStream(archive)); + ZipEntry entry = input.getNextEntry(); + while (entry != null) { + entries.add(entry); + entry = input.getNextEntry(); + } + assertEquals(entries.size(), 3); + Iterable<ZipEntry> directories = Iterables.filter(entries, isDirectory); + Iterable<ZipEntry> files = Iterables.filter(entries, Predicates.not(isDirectory)); + assertTrue(Iterables.isEmpty(directories)); + assertEquals(Iterables.size(files), 3); + for (ZipEntry file : files) { + assertTrue(file.getName().startsWith(Os.mergePathsUnix(".", baseDir))); + } + input.close(); + } + +}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/test/java/org/apache/brooklyn/core/util/file/ArchiveUtilsTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/util/file/ArchiveUtilsTest.java b/core/src/test/java/org/apache/brooklyn/core/util/file/ArchiveUtilsTest.java new file mode 100644 index 0000000..a13ef63 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/util/file/ArchiveUtilsTest.java @@ -0,0 +1,139 @@ +/* + * 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.apache.brooklyn.core.util.file; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.io.File; +import java.util.Map; + +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import brooklyn.entity.BrooklynAppUnitTestSupport; + +import org.apache.brooklyn.core.util.ResourceUtils; +import org.apache.brooklyn.core.util.file.ArchiveBuilder; +import org.apache.brooklyn.core.util.file.ArchiveUtils; +import org.apache.brooklyn.location.basic.SshMachineLocation; + +import brooklyn.util.os.Os; + +import com.google.api.client.repackaged.com.google.common.base.Joiner; +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableMap; +import com.google.common.io.Files; + +// Test are integration, because relies on ssh/scp via SshMachineLocation +public class ArchiveUtilsTest extends BrooklynAppUnitTestSupport { + + private SshMachineLocation machine; + private ResourceUtils resourceUtils; + + private Map<String, String> archiveContents = ImmutableMap.of("a.txt", "mya"); + private File destDir; + private File origZip; + private File origJar; + + @BeforeClass(alwaysRun=true) + public void setUpClass() throws Exception { + origZip = newZip(archiveContents); + origJar = Os.newTempFile(ArchiveUtilsTest.class, ".jar"); + Files.copy(origZip, origJar); + } + + @AfterClass(alwaysRun=true) + public void tearDownClass() throws Exception { + if (origZip != null) origZip.delete(); + if (origJar != null) origJar.delete(); + } + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + machine = app.newLocalhostProvisioningLocation().obtain(); + resourceUtils = ResourceUtils.create(ArchiveUtilsTest.class); + destDir = Os.newTempDir(getClass().getSimpleName()); + } + + @AfterMethod(alwaysRun=true) + @Override + public void tearDown() throws Exception { + super.tearDown(); + if (destDir != null) Os.deleteRecursively(destDir); + } + + @Test(groups="Integration") + public void testDeployZipWithNoOptionalArgsSupplied() throws Exception { + boolean result = ArchiveUtils.deploy(resourceUtils, ImmutableMap.<String, Object>of(), origZip.getAbsolutePath(), machine, destDir.getAbsolutePath(), true, null, null); + assertTrue(result); + assertFilesEqual(new File(destDir, origZip.getName()), origZip); + assertSubFilesEqual(destDir, archiveContents); + } + + @Test(groups="Integration") + public void testDeployZipDeletingArchiveAfterUnpack() throws Exception { + boolean result = ArchiveUtils.deploy(resourceUtils, ImmutableMap.<String, Object>of(), origZip.getAbsolutePath(), machine, destDir.getAbsolutePath(), false, null, null); + assertTrue(result); + assertFalse(new File(destDir, origZip.getName()).exists()); + assertSubFilesEqual(destDir, archiveContents); + } + + @Test(groups="Integration") + public void testDeployJarNotUnpacked() throws Exception { + ArchiveUtils.deploy(origJar.getAbsolutePath(), machine, destDir.getAbsolutePath()); + assertFilesEqual(new File(destDir, origJar.getName()), origJar); + } + + @Test(groups="Integration") + public void testDeployExplicitDestFile() throws Exception { + String destFile = "custom-destFile.jar"; + ArchiveUtils.deploy(origJar.getAbsolutePath(), machine, destDir.getAbsolutePath(), destFile); + assertFilesEqual(new File(destDir, destFile), origJar); + } + + private File newZip(Map<String, String> files) throws Exception { + File parentDir = Os.newTempDir(getClass().getSimpleName()+"-archive"); + for (Map.Entry<String, String> entry : files.entrySet()) { + File subFile = new File(Os.mergePaths(parentDir.getAbsolutePath(), entry.getKey())); + subFile.getParentFile().mkdirs(); + Files.write(entry.getValue(), subFile, Charsets.UTF_8); + } + return ArchiveBuilder.zip().addDirContentsAt(parentDir, ".").create(); + } + + private void assertFilesEqual(File f1, File f2) throws Exception { + byte[] bytes1 = Files.asByteSource(f1).read(); + byte[] bytes2 = Files.asByteSource(f1).read(); + assertEquals(bytes1, bytes2, "f1="+f1+"; f2="+f2); + } + + private void assertSubFilesEqual(File parentDir, Map<String, String> files) throws Exception { + for (Map.Entry<String, String> entry : archiveContents.entrySet()) { + File subFile = new File(Os.mergePaths(parentDir.getAbsolutePath(), entry.getKey())); + assertEquals(Joiner.on("\n").join(Files.readLines(subFile, Charsets.UTF_8)), entry.getValue()); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/test/java/org/apache/brooklyn/core/util/flags/MethodCoercionsTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/util/flags/MethodCoercionsTest.java b/core/src/test/java/org/apache/brooklyn/core/util/flags/MethodCoercionsTest.java new file mode 100644 index 0000000..2d1efa3 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/util/flags/MethodCoercionsTest.java @@ -0,0 +1,149 @@ +/* + * 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.apache.brooklyn.core.util.flags; + +import brooklyn.util.exceptions.Exceptions; +import brooklyn.util.guava.Maybe; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; + +import org.apache.brooklyn.core.util.flags.MethodCoercions; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; +import java.util.List; + +import static org.testng.Assert.*; + +public class MethodCoercionsTest { + + private Method singleParameterMethod; + private Method multiParameterMethod; + private Method singleCollectionParameterMethod; + + @BeforeClass + public void testFixtureSetUp() { + try { + singleParameterMethod = TestClass.class.getMethod("singleParameterMethod", int.class); + multiParameterMethod = TestClass.class.getMethod("multiParameterMethod", boolean.class, int.class); + singleCollectionParameterMethod = TestClass.class.getMethod("singleCollectionParameterMethod", List.class); + } catch (NoSuchMethodException e) { + throw Exceptions.propagate(e); + } + } + + @Test + public void testMatchSingleParameterMethod() throws Exception { + Predicate<Method> predicate = MethodCoercions.matchSingleParameterMethod("singleParameterMethod", "42"); + assertTrue(predicate.apply(singleParameterMethod)); + assertFalse(predicate.apply(multiParameterMethod)); + assertFalse(predicate.apply(singleCollectionParameterMethod)); + } + + @Test + public void testTryFindAndInvokeSingleParameterMethod() throws Exception { + TestClass instance = new TestClass(); + Maybe<?> maybe = MethodCoercions.tryFindAndInvokeSingleParameterMethod(instance, "singleParameterMethod", "42"); + assertTrue(maybe.isPresent()); + assertTrue(instance.wasSingleParameterMethodCalled()); + } + + @Test + public void testMatchMultiParameterMethod() throws Exception { + Predicate<Method> predicate = MethodCoercions.matchMultiParameterMethod("multiParameterMethod", ImmutableList.of("true", "42")); + assertFalse(predicate.apply(singleParameterMethod)); + assertTrue(predicate.apply(multiParameterMethod)); + assertFalse(predicate.apply(singleCollectionParameterMethod)); + } + + @Test + public void testTryFindAndInvokeMultiParameterMethod() throws Exception { + TestClass instance = new TestClass(); + Maybe<?> maybe = MethodCoercions.tryFindAndInvokeMultiParameterMethod(instance, "multiParameterMethod", ImmutableList.of("true", "42")); + assertTrue(maybe.isPresent()); + assertTrue(instance.wasMultiParameterMethodCalled()); + } + + @Test + public void testTryFindAndInvokeBestMatchingMethod() throws Exception { + TestClass instance = new TestClass(); + Maybe<?> maybe = MethodCoercions.tryFindAndInvokeBestMatchingMethod(instance, "singleParameterMethod", "42"); + assertTrue(maybe.isPresent()); + assertTrue(instance.wasSingleParameterMethodCalled()); + + instance = new TestClass(); + maybe = MethodCoercions.tryFindAndInvokeBestMatchingMethod(instance, "multiParameterMethod", ImmutableList.of("true", "42")); + assertTrue(maybe.isPresent()); + assertTrue(instance.wasMultiParameterMethodCalled()); + + instance = new TestClass(); + maybe = MethodCoercions.tryFindAndInvokeBestMatchingMethod(instance, "singleCollectionParameterMethod", ImmutableList.of("fred", "joe")); + assertTrue(maybe.isPresent()); + assertTrue(instance.wasSingleCollectionParameterMethodCalled()); + } +/* + @Test + public void testMatchSingleCollectionParameterMethod() throws Exception { + Predicate<Method> predicate = MethodCoercions.matchSingleCollectionParameterMethod("singleCollectionParameterMethod", ImmutableList.of("42")); + assertFalse(predicate.apply(singleParameterMethod)); + assertFalse(predicate.apply(multiParameterMethod)); + assertTrue(predicate.apply(singleCollectionParameterMethod)); + } + + @Test + public void testTryFindAndInvokeSingleCollectionParameterMethod() throws Exception { + TestClass instance = new TestClass(); + Maybe<?> maybe = MethodCoercions.tryFindAndInvokeSingleCollectionParameterMethod(instance, "singleCollectionParameterMethod", ImmutableList.of("42")); + assertTrue(maybe.isPresent()); + assertTrue(instance.wasSingleCollectionParameterMethodCalled()); + } +*/ + public static class TestClass { + + private boolean singleParameterMethodCalled; + private boolean multiParameterMethodCalled; + private boolean singleCollectionParameterMethodCalled; + + public void singleParameterMethod(int parameter) { + singleParameterMethodCalled = true; + } + + public void multiParameterMethod(boolean parameter1, int parameter2) { + multiParameterMethodCalled = true; + } + + public void singleCollectionParameterMethod(List<String> parameter) { + singleCollectionParameterMethodCalled = true; + } + + public boolean wasSingleParameterMethodCalled() { + return singleParameterMethodCalled; + } + + public boolean wasMultiParameterMethodCalled() { + return multiParameterMethodCalled; + } + + public boolean wasSingleCollectionParameterMethodCalled() { + return singleCollectionParameterMethodCalled; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/test/java/org/apache/brooklyn/core/util/http/BetterMockWebServer.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/util/http/BetterMockWebServer.java b/core/src/test/java/org/apache/brooklyn/core/util/http/BetterMockWebServer.java new file mode 100644 index 0000000..f02689b --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/util/http/BetterMockWebServer.java @@ -0,0 +1,138 @@ +/* + * 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.apache.brooklyn.core.util.http; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.Proxy; +import java.net.URL; + +import javax.net.ssl.SSLSocketFactory; + +import com.google.common.base.Throwables; +import com.google.mockwebserver.Dispatcher; +import com.google.mockwebserver.MockResponse; +import com.google.mockwebserver.MockWebServer; +import com.google.mockwebserver.RecordedRequest; + +/** like MockWebServer (and delegating) but: + * <li> allows subclassing + * <li> easy way to create instance which returns localhost for {@link #getHostName()} + * (since otherwise you can get failures on networks which misconfigure hostname) + * */ +public class BetterMockWebServer { + + final MockWebServer delegate = new MockWebServer(); + String hostname = null; + boolean isHttps = false; + + public static BetterMockWebServer newInstanceLocalhost() { + return new BetterMockWebServer().setHostName("localhost"); + } + + /** use {@link #newInstanceLocalhost()} or subclass */ + protected BetterMockWebServer() {} + + public BetterMockWebServer setHostName(String hostname) { + this.hostname = hostname; + return this; + } + + + // --- delegate methods (unchanged) + + public void enqueue(MockResponse response) { + delegate.enqueue(response); + } + + public boolean equals(Object obj) { + return delegate.equals(obj); + } + + public String getCookieDomain() { + return delegate.getCookieDomain(); + } + + public String getHostName() { + if (hostname!=null) return hostname; + return delegate.getHostName(); + } + + public int getPort() { + return delegate.getPort(); + } + + public int getRequestCount() { + return delegate.getRequestCount(); + } + + public URL getUrl(String path) { + try { + return isHttps + ? new URL("https://" + getHostName() + ":" + getPort() + path) + : new URL("http://" + getHostName() + ":" + getPort() + path); + } catch (MalformedURLException e) { + throw Throwables.propagate(e); + } + } + + public int hashCode() { + return delegate.hashCode(); + } + + public void play() throws IOException { + delegate.play(); + } + + public void play(int port) throws IOException { + delegate.play(port); + } + + public void setBodyLimit(int maxBodyLength) { + delegate.setBodyLimit(maxBodyLength); + } + + public void setDispatcher(Dispatcher dispatcher) { + delegate.setDispatcher(dispatcher); + } + + public void shutdown() throws IOException { + delegate.shutdown(); + } + + public RecordedRequest takeRequest() throws InterruptedException { + return delegate.takeRequest(); + } + + public Proxy toProxyAddress() { + return delegate.toProxyAddress(); + } + + public String toString() { + return delegate.toString(); + } + + public void useHttps(SSLSocketFactory sslSocketFactory, boolean tunnelProxy) { + isHttps = true; + delegate.useHttps(sslSocketFactory, tunnelProxy); + } + + + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/test/java/org/apache/brooklyn/core/util/http/HttpToolIntegrationTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/util/http/HttpToolIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/core/util/http/HttpToolIntegrationTest.java new file mode 100644 index 0000000..f557955 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/util/http/HttpToolIntegrationTest.java @@ -0,0 +1,100 @@ +/* + * 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.apache.brooklyn.core.util.http; + +import static org.testng.Assert.assertTrue; + +import java.net.URI; + +import org.apache.http.client.HttpClient; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.apache.brooklyn.core.util.http.HttpTool; +import org.apache.brooklyn.core.util.http.HttpToolResponse; +import org.apache.brooklyn.location.basic.PortRanges; + +import brooklyn.test.HttpService; + +import com.google.common.collect.ImmutableMap; + +public class HttpToolIntegrationTest { + + // TODO Expand test coverage for credentials etc + + private HttpService httpService; + private HttpService httpsService; + + @BeforeMethod(alwaysRun=true) + public void setUp() throws Exception { + httpService = new HttpService(PortRanges.fromString("9000+"), false).start(); + httpsService = new HttpService(PortRanges.fromString("9000+"), true).start(); + } + + @AfterMethod(alwaysRun=true) + public void tearDown() throws Exception { + if (httpService != null) httpService.shutdown(); + if (httpsService != null) httpsService.shutdown(); + } + + @Test(groups = {"Integration"}) + public void testHttpGet() throws Exception { + URI baseUri = new URI(httpService.getUrl()); + + HttpClient client = HttpTool.httpClientBuilder().build(); + HttpToolResponse result = HttpTool.httpGet(client, baseUri, ImmutableMap.<String,String>of()); + assertTrue(new String(result.getContent()).contains("Hello, World"), "val="+new String(result.getContent())); + } + + @Test(groups = {"Integration"}) + public void testHttpRedirect() throws Exception { + URI baseUri = new URI(httpService.getUrl() + "hello/redirectAbsolute"); + + HttpClient client = HttpTool.httpClientBuilder().laxRedirect(true).build(); + HttpToolResponse result = HttpTool.httpGet(client, baseUri, ImmutableMap.<String,String>of()); + assertTrue(new String(result.getContent()).contains("Hello, World"), "val="+new String(result.getContent())); + } + + @Test(groups = {"Integration"}) + public void testHttpPost() throws Exception { + URI baseUri = new URI(httpService.getUrl()); + + HttpClient client = HttpTool.httpClientBuilder().build(); + HttpToolResponse result = HttpTool.httpPost(client, baseUri, ImmutableMap.<String,String>of(), new byte[0]); + assertTrue(new String(result.getContent()).contains("Hello, World"), "val="+new String(result.getContent())); + } + + @Test(groups = {"Integration"}) + public void testHttpsGetWithTrustAll() throws Exception { + URI baseUri = new URI(httpsService.getUrl()); + + HttpClient client = HttpTool.httpClientBuilder().https(true).trustAll().build(); + HttpToolResponse result = HttpTool.httpGet(client, baseUri, ImmutableMap.<String,String>of()); + assertTrue(new String(result.getContent()).contains("Hello, World"), "val="+new String(result.getContent())); + } + + @Test(groups = {"Integration"}) + public void testHttpsPostWithTrustSelfSigned() throws Exception { + URI baseUri = new URI(httpsService.getUrl()); + + HttpClient client = HttpTool.httpClientBuilder().https(true).trustSelfSigned().build(); + HttpToolResponse result = HttpTool.httpPost(client, baseUri, ImmutableMap.<String,String>of(), new byte[0]); + assertTrue(new String(result.getContent()).contains("Hello, World"), "val="+new String(result.getContent())); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/test/java/org/apache/brooklyn/core/util/internal/FlagUtilsTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/util/internal/FlagUtilsTest.java b/core/src/test/java/org/apache/brooklyn/core/util/internal/FlagUtilsTest.java new file mode 100644 index 0000000..02becf6 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/util/internal/FlagUtilsTest.java @@ -0,0 +1,314 @@ +/* + * 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.apache.brooklyn.core.util.internal; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.lang.reflect.Field; +import java.net.InetAddress; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.brooklyn.api.entity.trait.Configurable; +import org.apache.brooklyn.api.management.Task; +import org.apache.brooklyn.core.util.config.ConfigBag; +import org.apache.brooklyn.core.util.flags.FlagUtils; +import org.apache.brooklyn.core.util.flags.SetFromFlag; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import brooklyn.config.ConfigKey; +import brooklyn.config.ConfigKey.HasConfigKey; +import brooklyn.entity.basic.ConfigKeys; +import brooklyn.event.basic.BasicConfigKey; +import brooklyn.util.collections.MutableMap; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +public class FlagUtilsTest { + + public static final Logger log = LoggerFactory.getLogger(FlagUtilsTest.class); + + @Test + public void testGetAllFields() { + log.info("types {}", FlagUtils.getAllAssignableTypes(Baz.class)); + assertEquals(FlagUtils.getAllAssignableTypes(Baz.class), ImmutableList.of(Baz.class, Foo.class, Bar.class)); + List<Field> fs = FlagUtils.getAllFields(Baz.class); + for (Field f : fs) { + log.info("field {} {}", f.getName(), f); + } + List<String> fsn = ImmutableList.copyOf(Iterables.transform(fs, new Function<Field, String>() { + @Override public String apply(Field f) { + return f.getName(); + }})); + assertTrue(fsn.indexOf("A") >= 0); + assertTrue(fsn.indexOf("w") > fsn.indexOf("A")); + assertTrue(fsn.indexOf("x") > fsn.indexOf("A") ); + assertTrue(fsn.indexOf("yNotY") > fsn.indexOf("A")); + assertTrue(fsn.indexOf("Z") > fsn.indexOf("yNotY") ); + } + + @Test + public void testSetFieldsFromFlags() { + Foo f = new Foo(); + Map<?,?> m = MutableMap.of("w", 3, "x", 1, "y", 7, "z", 9); + Map<?, ?> unused = FlagUtils.setFieldsFromFlags(m, f); + assertEquals(f.w, 3); + assertEquals(f.x, 1); + assertEquals(f.yNotY, 7); + assertEquals(unused, ImmutableMap.of("z", 9)); + Map<?,?> m2 = FlagUtils.getFieldsWithValues(f); + m.remove("z"); + assertEquals(m2, m); + } + + @Test + public void testCollectionCoercionOnSetFromFlags() { + WithSpecialFieldTypes s = new WithSpecialFieldTypes(); + Map<?,?> m = ImmutableMap.of("set", ImmutableSet.of(1)); + FlagUtils.setFieldsFromFlags(m, s); + assertEquals(s.set, ImmutableSet.of(1)); + } + + @Test + public void testInetAddressCoercionOnSetFromFlags() { + WithSpecialFieldTypes s = new WithSpecialFieldTypes(); + Map<?,?> m = ImmutableMap.of("inet", "127.0.0.1"); + FlagUtils.setFieldsFromFlags(m, s); + assertEquals(s.inet.getHostAddress(), "127.0.0.1"); + } + + @Test + public void testNonImmutableField() { + Foo f = new Foo(); + FlagUtils.setFieldsFromFlags(ImmutableMap.of("w", 8), f); + assertEquals(f.w, 8); + FlagUtils.setFieldsFromFlags(ImmutableMap.of("w", 9), f); + assertEquals(f.w, 9); + } + + @Test + public void testImmutableIntField() { + Foo f = new Foo(); + FlagUtils.setFieldsFromFlags(ImmutableMap.of("x", 8), f); + assertEquals(f.x, 8); + boolean succeededWhenShouldntHave = false; + try { + FlagUtils.setFieldsFromFlags(ImmutableMap.of("x", 9), f); + succeededWhenShouldntHave = true; + } catch (IllegalStateException e) { + //expected + } + assertFalse(succeededWhenShouldntHave); + assertEquals(f.x, 8); + } + + @Test + public void testImmutableObjectField() { + WithImmutableNonNullableObject o = new WithImmutableNonNullableObject(); + FlagUtils.setFieldsFromFlags(ImmutableMap.of("a", "a", "b", "b"), o); + assertEquals(o.a, "a"); + assertEquals(o.b, "b"); + + FlagUtils.setFieldsFromFlags(ImmutableMap.of("a", "a2"), o); + assertEquals(o.a, "a2"); + + boolean succeededWhenShouldntHave = false; + try { + FlagUtils.setFieldsFromFlags(ImmutableMap.of("b", "b2"), o); + succeededWhenShouldntHave = true; + } catch (IllegalStateException e) { + //expected + } + assertFalse(succeededWhenShouldntHave); + assertEquals(o.b, "b"); + } + + @Test + public void testNonNullable() { + WithImmutableNonNullableObject o = new WithImmutableNonNullableObject(); + //allowed + FlagUtils.setFieldsFromFlags(MutableMap.of("a", null), o); + assertEquals(o.a, null); + assertEquals(o.b, null); + //not allowed + boolean succeededWhenShouldntHave = false; + try { + FlagUtils.setFieldsFromFlags(MutableMap.of("b", null), o); + succeededWhenShouldntHave = true; + } catch (IllegalArgumentException e) { + //expected + } + assertFalse(succeededWhenShouldntHave); + assertEquals(o.b, null); + } + + @Test + public void testGetAnnotatedFields() throws Exception { + Map<Field, SetFromFlag> fm = FlagUtils.getAnnotatedFields(WithImmutableNonNullableObject.class); + assertEquals(fm.keySet().size(), 2); + assertTrue(fm.get(WithImmutableNonNullableObject.class.getDeclaredField("b")).immutable()); + } + + @Test + public void testCheckRequired() { + WithImmutableNonNullableObject f = new WithImmutableNonNullableObject(); + FlagUtils.setFieldsFromFlags(ImmutableMap.of("a", "a is a"), f); + assertEquals(f.a, "a is a"); + assertEquals(f.b, null); + int exceptions = 0; + try { + FlagUtils.checkRequiredFields(f); + } catch (IllegalStateException e) { + exceptions++; + } + assertEquals(exceptions, 1); + } + + @Test + public void testSetConfigKeys() { + FooCK f = new FooCK(); + Map<?,?> unused = FlagUtils.setFieldsFromFlags(ImmutableMap.of("f1", 9, "ck1", "do-set", "ck2", "dont-set", "c3", "do-set"), f); + assertEquals(f.bag.get(FooCK.CK1), "do-set"); + assertEquals(f.bag.get(FooCK.CK3), "do-set"); + assertEquals(f.f1, 9); + assertEquals(f.bag.containsKey(FooCK.CK2), false); + assertEquals(unused, ImmutableMap.of("ck2", "dont-set")); + } + + @Test + public void testSetAllConfigKeys() { + FooCK f = new FooCK(); + Map<?,?> unused = FlagUtils.setAllConfigKeys(ImmutableMap.of("f1", 9, "ck1", "do-set", "ck2", "do-set-2", "c3", "do-set"), f, true); + assertEquals(f.bag.get(FooCK.CK1), "do-set"); + assertEquals(f.bag.get(FooCK.CK3), "do-set"); + assertEquals(f.bag.containsKey(FooCK.CK2), true); + assertEquals(f.bag.get(FooCK.CK2), "do-set-2"); + assertEquals(unused, ImmutableMap.of("f1", 9)); + } + + @Test + public void testSetFromConfigKeys() { + FooCK f = new FooCK(); + Map<?, ?> unused = FlagUtils.setFieldsFromFlags(ImmutableMap.of(new BasicConfigKey<Integer>(Integer.class, "f1"), 9, "ck1", "do-set", "ck2", "dont-set"), f); + assertEquals(f.bag.get(FooCK.CK1), "do-set"); + assertEquals(f.f1, 9); + assertEquals(f.bag.containsKey(FooCK.CK2), false); + assertEquals(unused, ImmutableMap.of("ck2", "dont-set")); + } + + public static class Foo { + @SetFromFlag + int w; + + @SetFromFlag(immutable=true) + private int x; + + @SetFromFlag("y") + public int yNotY; + } + + public static interface Bar { + static final String Z = "myzval"; + } + + public static class Baz extends Foo implements Bar { + @SuppressWarnings("unused") //inspected by reflection + private static int A; + } + + public static class WithImmutableNonNullableObject { + @SetFromFlag + Object a; + @SetFromFlag(immutable=true, nullable=false) + public Object b; + } + + public static class WithSpecialFieldTypes { + @SetFromFlag Set<?> set; + @SetFromFlag InetAddress inet; + } + + public static class FooCK implements Configurable { + @SetFromFlag + public static ConfigKey<String> CK1 = ConfigKeys.newStringConfigKey("ck1"); + + public static ConfigKey<String> CK2 = ConfigKeys.newStringConfigKey("ck2"); + + @SetFromFlag("c3") + public static ConfigKey<String> CK3 = ConfigKeys.newStringConfigKey("ck3"); + + @SetFromFlag + int f1; + + ConfigBag bag = new ConfigBag(); + BasicConfigurationSupport configSupport = new BasicConfigurationSupport(); + + @Override + public ConfigurationSupport config() { + return configSupport; + } + + public <T> T setConfig(ConfigKey<T> key, T val) { + return config().set(key, val); + } + + private class BasicConfigurationSupport implements ConfigurationSupport { + @Override + public <T> T get(ConfigKey<T> key) { + return bag.get(key); + } + + @Override + public <T> T get(HasConfigKey<T> key) { + return get(key.getConfigKey()); + } + + @Override + public <T> T set(ConfigKey<T> key, T val) { + T old = bag.get(key); + bag.configure(key, val); + return old; + } + + @Override + public <T> T set(HasConfigKey<T> key, T val) { + return set(key.getConfigKey(), val); + } + + @Override + public <T> T set(ConfigKey<T> key, Task<T> val) { + throw new UnsupportedOperationException(); + } + + @Override + public <T> T set(HasConfigKey<T> key, Task<T> val) { + return set(key.getConfigKey(), val); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/test/java/org/apache/brooklyn/core/util/internal/RepeaterTest.groovy ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/util/internal/RepeaterTest.groovy b/core/src/test/java/org/apache/brooklyn/core/util/internal/RepeaterTest.groovy new file mode 100644 index 0000000..08ef0da --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/util/internal/RepeaterTest.groovy @@ -0,0 +1,257 @@ +/* + * 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.apache.brooklyn.core.util.internal + +import static java.util.concurrent.TimeUnit.* +import static org.testng.Assert.* + +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit + +import org.apache.brooklyn.core.util.internal.Repeater; +import org.testng.annotations.Test + +import brooklyn.util.internal.TimeExtras; +import brooklyn.util.time.Duration; + +import com.google.common.base.Stopwatch + +public class RepeaterTest { + static { TimeExtras.init() } + + @Test + public void sanityTest() { + new Repeater("Sanity test") + .repeat() + .until { true } + .every(10 * MILLISECONDS); + } + + @Test + public void sanityTestDescription() { + new Repeater() + .repeat() + .until { true } + .every(10 * MILLISECONDS); + } + + @Test + public void sanityTestBuilder() { + Repeater.create("Sanity test") + .repeat() + .until { true } + .every(10 * MILLISECONDS); + } + + @Test + public void sanityTestBuilderDescription() { + Repeater.create() + .repeat() + .until { true } + .every(10 * MILLISECONDS); + } + + @Test(expectedExceptions = [ NullPointerException.class ]) + public void repeatFailsIfClosureIsNull() { + new Repeater("repeatFailsIfClosureIsNull").repeat((Callable<?>)null); + fail "Expected exception was not thrown" + } + + @Test + public void repeatSucceedsIfClosureIsNonNull() { + new Repeater("repeatSucceedsIfClosureIsNonNull").repeat { true }; + } + + @Test(expectedExceptions = [ NullPointerException.class ]) + public void untilFailsIfClosureIsNull() { + new Repeater("untilFailsIfClosureIsNull").until(null); + fail "Expected exception was not thrown" + } + + @Test + public void untilSucceedsIfClosureIsNonNull() { + new Repeater("untilSucceedsIfClosureIsNonNull").until { true }; + } + + @Test(expectedExceptions = [ IllegalArgumentException.class ]) + public void everyFailsIfPeriodIsZero() { + new Repeater("everyFailsIfPeriodIsZero").every(0 * MILLISECONDS); + fail "Expected exception was not thrown" + } + + @Test(expectedExceptions = [ IllegalArgumentException.class ]) + public void everyFailsIfPeriodIsNegative() { + new Repeater("everyFailsIfPeriodIsNegative").every(-1 * MILLISECONDS); + fail "Expected exception was not thrown" + } + + @Test(expectedExceptions = [ NullPointerException.class ]) + public void everyFailsIfUnitsIsNull() { + new Repeater("everyFailsIfUnitsIsNull").every(10, null); + fail "Expected exception was not thrown" + } + + @Test + public void everySucceedsIfPeriodIsPositiveAndUnitsIsNonNull() { + new Repeater("repeatSucceedsIfClosureIsNonNull").every(10 * MILLISECONDS); + } + + @Test(expectedExceptions = [ IllegalArgumentException.class ]) + public void limitTimeToFailsIfPeriodIsZero() { + new Repeater("limitTimeToFailsIfPeriodIsZero").limitTimeTo(0, TimeUnit.MILLISECONDS); + fail "Expected exception was not thrown" + } + + @Test(expectedExceptions = [ IllegalArgumentException.class ]) + public void limitTimeToFailsIfPeriodIsNegative() { + new Repeater("limitTimeToFailsIfPeriodIsNegative").limitTimeTo(-1, TimeUnit.MILLISECONDS); + fail "Expected exception was not thrown" + } + + @Test(expectedExceptions = [ NullPointerException.class ]) + public void limitTimeToFailsIfUnitsIsNull() { + new Repeater("limitTimeToFailsIfUnitsIsNull").limitTimeTo(10, null); + fail "Expected exception was not thrown" + } + + @Test + public void limitTimeToSucceedsIfPeriodIsPositiveAndUnitsIsNonNull() { + new Repeater("limitTimeToSucceedsIfClosureIsNonNull").limitTimeTo(10, TimeUnit.MILLISECONDS); + } + + @Test + public void everyAcceptsDuration() { + new Repeater("everyAcceptsDuration").every(Duration.ONE_SECOND); + } + + @Test + public void everyAcceptsLong() { + new Repeater("everyAcceptsLong").every(1000L); + } + + @Test + public void everyAcceptsTimeUnit() { + new Repeater("everyAcceptsTimeUnit").every(1000000L, TimeUnit.MICROSECONDS); + } + + @Test + public void runReturnsTrueIfExitConditionIsTrue() { + assertTrue new Repeater("runReturnsTrueIfExitConditionIsTrue") + .repeat() + .every(1 * MILLISECONDS) + .until { true } + .run(); + } + + @Test + public void runRespectsMaximumIterationLimitAndReturnsFalseIfReached() { + int iterations = 0; + assertFalse new Repeater("runRespectsMaximumIterationLimitAndReturnsFalseIfReached") + .repeat { iterations++ } + .every(1 * MILLISECONDS) + .until { false } + .limitIterationsTo(5) + .run(); + assertEquals 5, iterations; + } + + /** + * Check that the {@link Repeater} will stop after a time limit. + * + * The repeater is configured to run every 100ms and never stop until the limit is reached. + * This is given as {@link Repeater#limitTimeTo(groovy.time.Duration)} and the execution time + * is then checked to ensure it is between 100% and 400% of the specified value. Due to scheduling + * delays and other factors in a non RTOS system it is expected that the repeater will take much + * longer to exit occasionally. + * + * @see #runRespectsMaximumIterationLimitAndReturnsFalseIfReached() + */ + @Test(groups="Integration") + public void runRespectsTimeLimitAndReturnsFalseIfReached() { + final long LIMIT = 2000l; + Repeater repeater = new Repeater("runRespectsTimeLimitAndReturnsFalseIfReached") + .repeat() + .every(100 * MILLISECONDS) + .until { false } + .limitTimeTo(LIMIT, TimeUnit.MILLISECONDS); + + Stopwatch stopwatch = new Stopwatch().start(); + boolean result = repeater.run(); + stopwatch.stop(); + + assertFalse result; + + long difference = stopwatch.elapsed(TimeUnit.MILLISECONDS); + assertTrue(difference >= LIMIT, "Difference was: " + difference); + assertTrue(difference < 4 * LIMIT, "Difference was: " + difference); + } + + @Test(expectedExceptions = [ IllegalStateException.class ]) + public void runFailsIfUntilWasNotSet() { + new Repeater("runFailsIfUntilWasNotSet") + .repeat() + .every(10 * MILLISECONDS) + .run(); + fail "Expected exception was not thrown" + } + + @Test(expectedExceptions = [ IllegalStateException.class ]) + public void runFailsIfEveryWasNotSet() { + new Repeater("runFailsIfEveryWasNotSet") + .repeat() + .until { true } + .run(); + fail "Expected exception was not thrown" + } + + @Test(expectedExceptions = [ UnsupportedOperationException.class ]) + public void testRethrowsException() { + boolean result = new Repeater("throwRuntimeException") + .repeat() + .every(10 * MILLISECONDS) + .until { throw new UnsupportedOperationException("fail") } + .rethrowException() + .limitIterationsTo(2) + .run(); + fail "Expected exception was not thrown" + } + + @Test + public void testNoRethrowsException() { + try { + boolean result = new Repeater("throwRuntimeException") + .repeat() + .every(10 * MILLISECONDS) + .until { throw new UnsupportedOperationException("fail") } + .limitIterationsTo(2) + .run(); + assertFalse result + } catch (RuntimeException re) { + fail "Exception should not have been thrown: " + re.getMessage() + } + } + + public void testFlags() { + int count=0; + new Repeater(period: 5*MILLISECONDS, timeout: 100*MILLISECONDS).repeat({ count++ }).until({ count>100}).run(); + assertTrue count>10 + assertTrue count<30 + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/test/java/org/apache/brooklyn/core/util/internal/TypeCoercionsTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/util/internal/TypeCoercionsTest.java b/core/src/test/java/org/apache/brooklyn/core/util/internal/TypeCoercionsTest.java new file mode 100644 index 0000000..f1bb3f9 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/util/internal/TypeCoercionsTest.java @@ -0,0 +1,360 @@ +/* + * 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.apache.brooklyn.core.util.internal; + +import static org.testng.Assert.assertEquals; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.brooklyn.core.util.flags.ClassCoercionException; +import org.apache.brooklyn.core.util.flags.TypeCoercions; +import org.codehaus.groovy.runtime.GStringImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.Assert; +import org.testng.annotations.Test; + +import brooklyn.entity.basic.Lifecycle; +import brooklyn.util.collections.MutableSet; +import brooklyn.util.text.StringPredicates; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.TypeToken; + +public class TypeCoercionsTest { + + private static final Logger log = LoggerFactory.getLogger(TypeCoercionsTest.class); + + @Test + public void testCoerceCharSequenceToString() { + assertEquals(TypeCoercions.coerce(new StringBuilder("abc"), String.class), "abc"); + assertEquals(TypeCoercions.coerce(new GStringImpl(new Object[0], new String[0]), String.class), ""); + } + + @Test + public void testCoerceStringToPrimitive() { + assertEquals(TypeCoercions.coerce("1", Character.class), (Character)'1'); + assertEquals(TypeCoercions.coerce(" ", Character.class), (Character)' '); + assertEquals(TypeCoercions.coerce("1", Short.class), (Short)((short)1)); + assertEquals(TypeCoercions.coerce("1", Integer.class), (Integer)1); + assertEquals(TypeCoercions.coerce("1", Long.class), (Long)1l); + assertEquals(TypeCoercions.coerce("1", Float.class), (Float)1f); + assertEquals(TypeCoercions.coerce("1", Double.class), (Double)1d); + assertEquals(TypeCoercions.coerce("true", Boolean.class), (Boolean)true); + assertEquals(TypeCoercions.coerce("False", Boolean.class), (Boolean)false); + assertEquals(TypeCoercions.coerce("true ", Boolean.class), (Boolean)true); + + assertEquals(TypeCoercions.coerce("1", char.class), (Character)'1'); + assertEquals(TypeCoercions.coerce("1", short.class), (Short)((short)1)); + assertEquals(TypeCoercions.coerce("1", int.class), (Integer)1); + assertEquals(TypeCoercions.coerce("1", long.class), (Long)1l); + assertEquals(TypeCoercions.coerce("1", float.class), (Float)1f); + assertEquals(TypeCoercions.coerce("1", double.class), (Double)1d); + assertEquals(TypeCoercions.coerce("TRUE", boolean.class), (Boolean)true); + assertEquals(TypeCoercions.coerce("false", boolean.class), (Boolean)false); + } + + @Test + public void testCoercePrimitivesToSameType() { + assertEquals(TypeCoercions.coerce('1', Character.class), (Character)'1'); + assertEquals(TypeCoercions.coerce((short)1, Short.class), (Short)((short)1)); + assertEquals(TypeCoercions.coerce(1, Integer.class), (Integer)1); + assertEquals(TypeCoercions.coerce(1l, Long.class), (Long)1l); + assertEquals(TypeCoercions.coerce(1f, Float.class), (Float)1f); + assertEquals(TypeCoercions.coerce(1d, Double.class), (Double)1d); + assertEquals(TypeCoercions.coerce(true, Boolean.class), (Boolean)true); + } + + @Test + public void testCastPrimitives() { + assertEquals(TypeCoercions.coerce(1L, Character.class), (Character)(char)1); + assertEquals(TypeCoercions.coerce(1L, Byte.class), (Byte)(byte)1); + assertEquals(TypeCoercions.coerce(1L, Short.class), (Short)(short)1); + assertEquals(TypeCoercions.coerce(1L, Integer.class), (Integer)1); + assertEquals(TypeCoercions.coerce(1L, Long.class), (Long)(long)1); + assertEquals(TypeCoercions.coerce(1L, Float.class), (Float)(float)1); + assertEquals(TypeCoercions.coerce(1L, Double.class), (Double)(double)1); + + assertEquals(TypeCoercions.coerce(1L, char.class), (Character)(char)1); + assertEquals(TypeCoercions.coerce(1L, byte.class), (Byte)(byte)1); + assertEquals(TypeCoercions.coerce(1L, short.class), (Short)(short)1); + assertEquals(TypeCoercions.coerce(1L, int.class), (Integer)1); + assertEquals(TypeCoercions.coerce(1L, long.class), (Long)(long)1); + assertEquals(TypeCoercions.coerce(1L, float.class), (Float)(float)1); + assertEquals(TypeCoercions.coerce(1L, double.class), (Double)(double)1); + + assertEquals(TypeCoercions.coerce((char)1, Integer.class), (Integer)1); + assertEquals(TypeCoercions.coerce((byte)1, Integer.class), (Integer)1); + assertEquals(TypeCoercions.coerce((short)1, Integer.class), (Integer)1); + assertEquals(TypeCoercions.coerce((int)1, Integer.class), (Integer)1); + assertEquals(TypeCoercions.coerce((long)1, Integer.class), (Integer)1); + assertEquals(TypeCoercions.coerce((float)1, Integer.class), (Integer)1); + assertEquals(TypeCoercions.coerce((double)1, Integer.class), (Integer)1); + } + + @Test + public void testCoercePrimitiveFailures() { + // error messages don't have to be this exactly, but they should include sufficient information... + assertCoercionFailsWithErrorMatching("maybe", boolean.class, StringPredicates.containsAllLiterals("String", "boolean", "maybe")); + assertCoercionFailsWithErrorMatching("NaN", int.class, StringPredicates.containsAllLiterals("int", "NaN")); + assertCoercionFailsWithErrorMatching('c', boolean.class, StringPredicates.containsAllLiterals("boolean", "(c)")); // will say 'string' rather than 'char' + assertCoercionFailsWithErrorMatching(0, boolean.class, StringPredicates.containsAllLiterals("Integer", "boolean", "0")); + } + + protected void assertCoercionFailsWithErrorMatching(Object input, Class<?> type, Predicate<? super String> errorMessageRequirement) { + try { + Object result = TypeCoercions.coerce(input, type); + Assert.fail("Should have failed type coercion of "+input+" to "+type+", instead got: "+result); + } catch (Exception e) { + if (errorMessageRequirement==null || errorMessageRequirement.apply(e.toString())) + log.info("Primitive coercion failed as expected, with: "+e); + else + Assert.fail("Error from type coercion of "+input+" to "+type+" failed with wrong exception; expected match of "+errorMessageRequirement+" but got: "+e); + } + + } + + @Test + public void testCastToNumericPrimitives() { + assertEquals(TypeCoercions.coerce(BigInteger.ONE, Integer.class), (Integer)1); + assertEquals(TypeCoercions.coerce(BigInteger.ONE, int.class), (Integer)1); + assertEquals(TypeCoercions.coerce(BigInteger.valueOf(Long.MAX_VALUE), Long.class), (Long)Long.MAX_VALUE); + assertEquals(TypeCoercions.coerce(BigInteger.valueOf(Long.MAX_VALUE), long.class), (Long)Long.MAX_VALUE); + + assertEquals(TypeCoercions.coerce(BigDecimal.valueOf(0.5), Double.class), 0.5d, 0.00001d); + assertEquals(TypeCoercions.coerce(BigDecimal.valueOf(0.5), double.class), 0.5d, 0.00001d); + } + + @Test + public void testCoerceStringToBigNumber() { + assertEquals(TypeCoercions.coerce("0.5", BigDecimal.class), BigDecimal.valueOf(0.5)); + assertEquals(TypeCoercions.coerce("1", BigInteger.class), BigInteger.valueOf(1)); + } + + @Test + public void testCoerceStringToEnum() { + assertEquals(TypeCoercions.coerce("STARTING", Lifecycle.class), Lifecycle.STARTING); + assertEquals(TypeCoercions.coerce("Starting", Lifecycle.class), Lifecycle.STARTING); + assertEquals(TypeCoercions.coerce("starting", Lifecycle.class), Lifecycle.STARTING); + + assertEquals(TypeCoercions.coerce("LOWERCASE", PerverseEnum.class), PerverseEnum.lowercase); + assertEquals(TypeCoercions.coerce("CAMELCASE", PerverseEnum.class), PerverseEnum.camelCase); + assertEquals(TypeCoercions.coerce("upper", PerverseEnum.class), PerverseEnum.UPPER); + assertEquals(TypeCoercions.coerce("upper_with_underscore", PerverseEnum.class), PerverseEnum.UPPER_WITH_UNDERSCORE); + assertEquals(TypeCoercions.coerce("LOWER_WITH_UNDERSCORE", PerverseEnum.class), PerverseEnum.lower_with_underscore); + } + public static enum PerverseEnum { + lowercase, + camelCase, + UPPER, + UPPER_WITH_UNDERSCORE, + lower_with_underscore; + } + + @Test(expectedExceptions = ClassCoercionException.class) + public void testCoerceStringToEnumFailure() { + TypeCoercions.coerce("scrambled-eggs", Lifecycle.class); + } + + @Test + public void testListToSetCoercion() { + Set<?> s = TypeCoercions.coerce(ImmutableList.of(1), Set.class); + Assert.assertEquals(s, ImmutableSet.of(1)); + } + + @Test + public void testSetToListCoercion() { + List<?> s = TypeCoercions.coerce(ImmutableSet.of(1), List.class); + Assert.assertEquals(s, ImmutableList.of(1)); + } + + @Test + public void testIterableToArrayCoercion() { + String[] s = TypeCoercions.coerce(ImmutableList.of("a", "b"), String[].class); + Assert.assertTrue(Arrays.equals(s, new String[] {"a", "b"}), "result="+Arrays.toString(s)); + + Integer[] i = TypeCoercions.coerce(ImmutableList.of(1, 2), Integer[].class); + Assert.assertTrue(Arrays.equals(i, new Integer[] {1, 2}), "result="+Arrays.toString(i)); + + int[] i2 = TypeCoercions.coerce(ImmutableList.of(1, 2), int[].class); + Assert.assertTrue(Arrays.equals(i2, new int[] {1, 2}), "result="+Arrays.toString(i2)); + + int[] i3 = TypeCoercions.coerce(MutableSet.of("1", 2), int[].class); + Assert.assertTrue(Arrays.equals(i3, new int[] {1, 2}), "result="+Arrays.toString(i3)); + } + + @Test + public void testListEntryCoercion() { + List<?> s = TypeCoercions.coerce(ImmutableList.of("java.lang.Integer", "java.lang.Double"), new TypeToken<List<Class<?>>>() { }); + Assert.assertEquals(s, ImmutableList.of(Integer.class, Double.class)); + } + + @Test + public void testListEntryToSetCoercion() { + Set<?> s = TypeCoercions.coerce(ImmutableList.of("java.lang.Integer", "java.lang.Double"), new TypeToken<Set<Class<?>>>() { }); + Assert.assertEquals(s, ImmutableSet.of(Integer.class, Double.class)); + } + + @Test + public void testListEntryToCollectionCoercion() { + Collection<?> s = TypeCoercions.coerce(ImmutableList.of("java.lang.Integer", "java.lang.Double"), new TypeToken<Collection<Class<?>>>() { }); + Assert.assertEquals(s, ImmutableList.of(Integer.class, Double.class)); + } + + @Test + public void testMapValueCoercion() { + Map<?,?> s = TypeCoercions.coerce(ImmutableMap.of("int", "java.lang.Integer", "double", "java.lang.Double"), new TypeToken<Map<String, Class<?>>>() { }); + Assert.assertEquals(s, ImmutableMap.of("int", Integer.class, "double", Double.class)); + } + + @Test + public void testMapKeyCoercion() { + Map<?,?> s = TypeCoercions.coerce(ImmutableMap.of("java.lang.Integer", "int", "java.lang.Double", "double"), new TypeToken<Map<Class<?>, String>>() { }); + Assert.assertEquals(s, ImmutableMap.of(Integer.class, "int", Double.class, "double")); + } + + @Test + public void testStringToListCoercion() { + List<?> s = TypeCoercions.coerce("a,b,c", List.class); + Assert.assertEquals(s, ImmutableList.of("a", "b", "c")); + } + + @Test + @SuppressWarnings("serial") + public void testCoerceRecursivelyStringToGenericsCollection() { + assertEquals(TypeCoercions.coerce("1,2", new TypeToken<List<Integer>>() {}), ImmutableList.of(1, 2)); + } + + @Test + public void testJsonStringToMapCoercion() { + Map<?,?> s = TypeCoercions.coerce("{ \"a\" : \"1\", b : 2 }", Map.class); + Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", 2)); + } + + @Test + public void testJsonStringWithoutQuotesToMapCoercion() { + Map<?,?> s = TypeCoercions.coerce("{ a : 1 }", Map.class); + Assert.assertEquals(s, ImmutableMap.of("a", 1)); + } + + @Test + public void testJsonComplexTypesToMapCoercion() { + Map<?,?> s = TypeCoercions.coerce("{ a : [1, \"2\", '\"3\"'], b: { c: d, 'e': \"f\" } }", Map.class); + Assert.assertEquals(s, ImmutableMap.of("a", ImmutableList.<Object>of(1, "2", "\"3\""), + "b", ImmutableMap.of("c", "d", "e", "f"))); + } + + @Test + public void testJsonStringWithoutBracesToMapCoercion() { + Map<?,?> s = TypeCoercions.coerce("a : 1", Map.class); + Assert.assertEquals(s, ImmutableMap.of("a", 1)); + } + + @Test + public void testJsonStringWithoutBracesWithMultipleToMapCoercion() { + Map<?,?> s = TypeCoercions.coerce("a : 1, b : 2", Map.class); + Assert.assertEquals(s, ImmutableMap.of("a", 1, "b", 2)); + } + + @Test + public void testKeyEqualsValueStringToMapCoercion() { + Map<?,?> s = TypeCoercions.coerce("a=1,b=2", Map.class); + Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", "2")); + } + + @Test(expectedExceptions=IllegalArgumentException.class) + public void testJsonStringWithoutBracesOrSpaceDisallowedAsMapCoercion() { + // yaml requires spaces after the colon + Map<?,?> s = TypeCoercions.coerce("a:1,b:2", Map.class); + Assert.assertEquals(s, ImmutableMap.of("a", 1, "b", 2)); + } + + @Test + public void testEqualsInBracesMapCoercion() { + Map<?,?> s = TypeCoercions.coerce("{ a = 1, b = '2' }", Map.class); + Assert.assertEquals(s, ImmutableMap.of("a", 1, "b", "2")); + } + + @Test + public void testKeyEqualsOrColonValueWithBracesStringToMapCoercion() { + Map<?,?> s = TypeCoercions.coerce("{ a=1, b: 2 }", Map.class); + Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", 2)); + } + + @Test + public void testKeyEqualsOrColonValueWithoutBracesStringToMapCoercion() { + Map<?,?> s = TypeCoercions.coerce("a=1, b: 2", Map.class); + Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", 2)); + } + + @Test + public void testAs() { + Integer x = TypeCoercions.coerce(new WithAs("3"), Integer.class); + Assert.assertEquals(x, (Integer)3); + } + + @Test + public void testFrom() { + WithFrom x = TypeCoercions.coerce("3", WithFrom.class); + Assert.assertEquals(x.value, 3); + } + + @Test + public void testCoerceStringToNumber() { + assertEquals(TypeCoercions.coerce("1", Number.class), (Number) Double.valueOf(1)); + assertEquals(TypeCoercions.coerce("1.0", Number.class), (Number) Double.valueOf(1.0)); + } + + @Test(expectedExceptions = ClassCoercionException.class) + public void testInvalidCoercionThrowsClassCoercionException() { + TypeCoercions.coerce(new Object(), TypeToken.of(Integer.class)); + } + + @Test + public void testCoercionFunction() { + assertEquals(TypeCoercions.function(Double.class).apply("1"), Double.valueOf(1)); + } + + public static class WithAs { + String value; + public WithAs(Object x) { value = ""+x; } + public Integer asInteger() { + return Integer.parseInt(value); + } + } + + public static class WithFrom { + int value; + public static WithFrom fromString(String s) { + WithFrom result = new WithFrom(); + result.value = Integer.parseInt(s); + return result; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/test/java/org/apache/brooklyn/core/util/internal/ssh/RecordingSshTool.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/util/internal/ssh/RecordingSshTool.java b/core/src/test/java/org/apache/brooklyn/core/util/internal/ssh/RecordingSshTool.java new file mode 100644 index 0000000..fdf3e73 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/util/internal/ssh/RecordingSshTool.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +*/ +package org.apache.brooklyn.core.util.internal.ssh; + +import java.io.File; +import java.io.InputStream; +import java.util.List; +import java.util.Map; + +import org.apache.brooklyn.core.util.internal.ssh.SshTool; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; + +/** Mock tool */ +public class RecordingSshTool implements SshTool { + + public static class ExecCmd { + public final Map<String,?> props; + public final String summaryForLogging; + public final List<String> commands; + public final Map<?,?> env; + + ExecCmd(Map<String,?> props, String summaryForLogging, List<String> commands, Map env) { + this.props = props; + this.summaryForLogging = summaryForLogging; + this.commands = commands; + this.env = env; + } + + @Override + public String toString() { + return "ExecCmd["+summaryForLogging+": "+commands+"; "+props+"; "+env+"]"; + } + } + + public static List<ExecCmd> execScriptCmds = Lists.newCopyOnWriteArrayList(); + + private boolean connected; + + public RecordingSshTool(Map<?,?> props) { + } + @Override public void connect() { + connected = true; + } + @Override public void connect(int maxAttempts) { + connected = true; + } + @Override public void disconnect() { + connected = false; + } + @Override public boolean isConnected() { + return connected; + } + @Override public int execScript(Map<String, ?> props, List<String> commands, Map<String, ?> env) { + execScriptCmds.add(new ExecCmd(props, "", commands, env)); + return 0; + } + @Override public int execScript(Map<String, ?> props, List<String> commands) { + return execScript(props, commands, ImmutableMap.<String,Object>of()); + } + @Override public int execCommands(Map<String, ?> props, List<String> commands, Map<String, ?> env) { + execScriptCmds.add(new ExecCmd(props, "", commands, env)); + return 0; + } + @Override public int execCommands(Map<String, ?> props, List<String> commands) { + return execCommands(props, commands, ImmutableMap.<String,Object>of()); + } + @Override public int copyToServer(Map<String, ?> props, File localFile, String pathAndFileOnRemoteServer) { + return 0; + } + @Override public int copyToServer(Map<String, ?> props, InputStream contents, String pathAndFileOnRemoteServer) { + return 0; + } + @Override public int copyToServer(Map<String, ?> props, byte[] contents, String pathAndFileOnRemoteServer) { + return 0; + } + @Override public int copyFromServer(Map<String, ?> props, String pathAndFileOnRemoteServer, File local) { + return 0; + } +} \ No newline at end of file
