http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeLiveTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeLiveTest.java new file mode 100644 index 0000000..c098d13 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeLiveTest.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.entity.nosql.cassandra; + +import java.util.Map; + +import org.apache.brooklyn.entity.nosql.cassandra.CassandraNode; +import org.apache.brooklyn.entity.nosql.cassandra.AstyanaxSupport.AstyanaxSample; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.test.EntityTestUtils; +import brooklyn.util.collections.MutableMap; +import brooklyn.util.text.Strings; + +import com.google.common.collect.ImmutableList; + +/** + * Cassandra live tests. + * + * Test the operation of the {@link CassandraNode} class using the jclouds {@code rackspace-cloudservers-uk} + * and {@code aws-ec2} providers, with different OS images. The tests use the {@link AstyanaxSupport#astyanaxTest()} method + * to exercise the node, and will need to have {@code brooklyn.jclouds.provider.identity} and {@code .credential} + * set, usually in the {@code .brooklyn/bropoklyn.properties} file. + */ +public class CassandraNodeLiveTest extends AbstractCassandraNodeTest { + + private static final Logger log = LoggerFactory.getLogger(CassandraNodeLiveTest.class); + + @DataProvider(name = "virtualMachineData") + public Object[][] provideVirtualMachineData() { + return new Object[][] { // ImageId, Provider, Region, Description (for logging) + new Object[] { "eu-west-1/ami-0307d674", "aws-ec2", "eu-west-1", "Ubuntu Server 14.04 LTS (HVM), SSD Volume Type" }, + new Object[] { "LON/f9b690bf-88eb-43c2-99cf-391f2558732e", "rackspace-cloudservers-uk", "", "Ubuntu 12.04 LTS (Precise Pangolin)" }, + new Object[] { "LON/a84b1592-6817-42da-a57c-3c13f3cfc1da", "rackspace-cloudservers-uk", "", "CentOS 6.5 (PVHVM)" }, + }; + } + + @Test(groups = "Live", dataProvider = "virtualMachineData") + protected void testOperatingSystemProvider(String imageId, String provider, String region, String description) throws Exception { + log.info("Testing Cassandra on {}{} using {} ({})", new Object[] { provider, Strings.isNonEmpty(region) ? ":" + region : "", description, imageId }); + + Map<String, String> properties = MutableMap.of("imageId", imageId); + testLocation = app.getManagementContext().getLocationRegistry() + .resolve(provider + (Strings.isNonEmpty(region) ? ":" + region : ""), properties); + + cassandra = app.createAndManageChild(EntitySpec.create(CassandraNode.class) + .configure("thriftPort", "9876+") + .configure("clusterName", "TestCluster")); + app.start(ImmutableList.of(testLocation)); + EntityTestUtils.assertAttributeEqualsEventually(cassandra, CassandraNode.SERVICE_UP, true); + + AstyanaxSample astyanax = new AstyanaxSample(cassandra); + astyanax.astyanaxTest(); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/NonNegTokenGeneratorTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/NonNegTokenGeneratorTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/NonNegTokenGeneratorTest.java new file mode 100644 index 0000000..281ae6d --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/NonNegTokenGeneratorTest.java @@ -0,0 +1,116 @@ +/* + * 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.entity.nosql.cassandra; + +import static org.testng.Assert.assertEquals; + +import java.math.BigInteger; +import java.util.List; + +import org.apache.brooklyn.entity.nosql.cassandra.TokenGenerators.AbstractTokenGenerator; +import org.apache.brooklyn.entity.nosql.cassandra.TokenGenerators.NonNeg127TokenGenerator; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +public class NonNegTokenGeneratorTest { + + public static final BigInteger C4_1 = new BigInteger("42535295865117307932921825928971026432"); + public static final BigInteger C4_2 = new BigInteger("85070591730234615865843651857942052864"); + public static final BigInteger C4_3 = new BigInteger("127605887595351923798765477786913079296"); + + // TODO Expect this behaviour to change when we better support dynamically growing/shrinking. + // In particular, the expected behaviour for testReturnsNullWhenClusterSizeUnknown + // and testReturnsNullWhenGrowingClusterUnknownAmount will change. + + private AbstractTokenGenerator generator; + + @BeforeMethod(alwaysRun=true) + public void setUp() throws Exception { + generator = new NonNeg127TokenGenerator(); + } + + @Test + public void testGetTokenForReplacementNode() { + assertEquals(generator.getTokenForReplacementNode(BigInteger.ONE), BigInteger.ZERO); + assertEquals(generator.getTokenForReplacementNode(BigInteger.ZERO), generator.max()); + assertEquals(generator.getTokenForReplacementNode(generator.max()), generator.max().subtract(BigInteger.ONE)); + } + + @Test + public void testGeneratesInitialTokens() throws Exception { + List<BigInteger> tokens = Lists.newArrayList(); + generator.growingCluster(4); + for (int i = 0; i < 4; i++) { + tokens.add(generator.newToken()); + } + + assertEquals(tokens, ImmutableList.of( + BigInteger.ZERO, + C4_1, + C4_2, + C4_3)); + } + + // Expect behaviour to be changed to better choose tokens for growing clusters + // (but eg need to take into account how busy each node is!) + @Test + public void testGeneratesTokensForGrowingCluster() throws Exception { + List<BigInteger> tokens = Lists.newArrayList(); + generator.growingCluster(4); + for (int i = 0; i < 4; i++) { + tokens.add(generator.newToken()); + } + generator.growingCluster(1); + assertEquals(generator.newToken(), C4_3.add(generator.max().add(BigInteger.ONE)).divide(BigInteger.valueOf(2))); + generator.growingCluster(2); + assertEquals(generator.newToken(), C4_1.divide(BigInteger.valueOf(2))); + assertEquals(generator.newToken(), C4_2.add(C4_1).divide(BigInteger.valueOf(2))); + } + + @Test + public void testGeneratesTokensForGrowingClusterWhenInitialSizeIsOne() throws Exception { + // initial size 1 has to do a special "average with ourself by half phase shift" computation + List<BigInteger> tokens = Lists.newArrayList(); + generator.growingCluster(1); + tokens.add(generator.newToken()); + + generator.growingCluster(1); + assertEquals(generator.newToken(), C4_2); + generator.growingCluster(2); + assertEquals(generator.newToken(), C4_3); + assertEquals(generator.newToken(), C4_1); + } + + @Test + public void testReturnsNullWhenClusterSizeUnknown() throws Exception { + assertEquals(generator.newToken(), null); + } + + @Test + public void testReturnsNullWhenGrowingClusterUnknownAmount() throws Exception { + generator.growingCluster(4); + for (int i = 0; i < 4; i++) { + generator.newToken(); + } + assertEquals(generator.newToken(), null); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/PosNegTokenGeneratorTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/PosNegTokenGeneratorTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/PosNegTokenGeneratorTest.java new file mode 100644 index 0000000..e353f41 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/PosNegTokenGeneratorTest.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.entity.nosql.cassandra; + +import static org.testng.Assert.assertEquals; + +import java.math.BigInteger; + +import org.apache.brooklyn.entity.nosql.cassandra.TokenGenerators.AbstractTokenGenerator; +import org.apache.brooklyn.entity.nosql.cassandra.TokenGenerators.PosNeg63TokenGenerator; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class PosNegTokenGeneratorTest { + + // TODO Expect this behaviour to change when we better support dynamically growing/shrinking. + // In particular, the expected behaviour for testReturnsNullWhenClusterSizeUnknown + // and testReturnsNullWhenGrowingClusterUnknownAmount will change. + + private AbstractTokenGenerator generator; + + @BeforeMethod(alwaysRun=true) + public void setUp() throws Exception { + generator = new PosNeg63TokenGenerator(); + } + + @Test + public void testGetTokenForReplacementNode() { + assertEquals(generator.getTokenForReplacementNode(BigInteger.ONE), BigInteger.ZERO); + assertEquals(generator.getTokenForReplacementNode(BigInteger.ZERO), BigInteger.ONE.negate()); + assertEquals(generator.getTokenForReplacementNode(generator.min()), generator.max()); + assertEquals(generator.getTokenForReplacementNode(generator.max()), generator.max().subtract(BigInteger.ONE)); + } + + @Test + public void testGeneratesInitialTokens() throws Exception { + generator.growingCluster(4); + assertEquals(generator.newToken(), generator.min()); + assertEquals(generator.newToken(), generator.min().add(generator.range().divide(BigInteger.valueOf(4)))); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseOfflineTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseOfflineTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseOfflineTest.java new file mode 100644 index 0000000..de1d49a --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseOfflineTest.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.entity.nosql.couchbase; + +import org.apache.brooklyn.entity.nosql.couchbase.CouchbaseNodeSshDriver; +import org.testng.Assert; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import brooklyn.entity.basic.Entities; +import brooklyn.location.basic.BasicOsDetails; +import brooklyn.location.basic.BasicOsDetails.OsArchs; +import brooklyn.management.internal.LocalManagementContext; +import brooklyn.test.entity.LocalManagementContextForTests; + +public class CouchbaseOfflineTest { + + private LocalManagementContext mgmt; + + @BeforeMethod + public void setUp() { + mgmt = LocalManagementContextForTests.newInstance(); + } + + @AfterMethod + public void tearDown() { + Entities.destroyAll(mgmt); + } + + @Test + public void testResolvingDownloadLinks() { + checkOsTag("linux", OsArchs.I386, "unknown", true, "centos6.x86.rpm"); + checkOsTag("linux", OsArchs.I386, "unknown", false, "x86.rpm"); + checkOsTag("rhel", OsArchs.X_86_64, "6", true, "centos6.x86_64.rpm"); + checkOsTag("Ubuntu 14", OsArchs.X_86_64, "14.04", true, "ubuntu12.04_amd64.deb"); + checkOsTag("Ubuntu 14", OsArchs.X_86_64, "14.04", false, "x86_64.deb"); + checkOsTag("Debian 7up", OsArchs.I386, "7ish", true, "debian7_x86.deb"); + Assert.assertEquals(new CouchbaseNodeSshDriver.DownloadLinkSegmentComputer(null, true, "test").getOsTag(), "centos6.x86_64.rpm"); + Assert.assertEquals(new CouchbaseNodeSshDriver.DownloadLinkSegmentComputer(null, false, "test").getOsTag(), "x86_64.rpm"); + } + + protected void checkOsTag(String os, String arch, String version, boolean isV30, String expectedTag) { + Assert.assertEquals(new CouchbaseNodeSshDriver.DownloadLinkSegmentComputer(new BasicOsDetails(os, arch, version), isV30, "test").getOsTag(), expectedTag); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java new file mode 100644 index 0000000..89297be --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java @@ -0,0 +1,140 @@ +/* + * 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.entity.nosql.couchbase; + +import java.util.List; +import java.util.Map; + +import org.apache.brooklyn.entity.nosql.couchbase.CouchbaseCluster; +import org.apache.brooklyn.entity.nosql.couchbase.CouchbaseNode; +import org.apache.brooklyn.entity.nosql.couchbase.CouchbaseSyncGateway; +import org.testng.annotations.Test; + +import brooklyn.entity.AbstractEc2LiveTest; +import brooklyn.entity.group.DynamicCluster; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.trait.Startable; +import brooklyn.location.Location; +import brooklyn.test.EntityTestUtils; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +public class CouchbaseSyncGatewayEc2LiveTest extends AbstractEc2LiveTest { + + @Override + protected void doTest(Location loc) throws Exception { + CouchbaseCluster cluster = app.createAndManageChild(EntitySpec.create(CouchbaseCluster.class) + .configure(CouchbaseNode.COUCHBASE_ADMIN_USERNAME, "Administrator") + .configure(CouchbaseNode.COUCHBASE_ADMIN_PASSWORD, "Password") + .configure(DynamicCluster.INITIAL_SIZE, 3) + .configure(CouchbaseCluster.CREATE_BUCKETS, (List<Map<String,Object>>)ImmutableList.of( + (Map<String,Object>)ImmutableMap.<String, Object>of( + "bucket", "default", + "bucket-ramsize", 100, + "bucket-type", "couchbase", + "bucket-port", 11211 + ), + (Map<String,Object>)ImmutableMap.<String, Object>of( + "bucket", "my_bucket", + "bucket-ramsize", 100, + "bucket-type", "couchbase", + "bucket-port", 11223 + ), + (Map<String,Object>)ImmutableMap.<String, Object>of( + "bucket", "another", + "bucket-ramsize", 100, + "bucket-type", "couchbase", + "bucket-port", 11224 + )) + ) + ); + CouchbaseSyncGateway gateway = app.createAndManageChild(EntitySpec.create(CouchbaseSyncGateway.class) + .configure(CouchbaseSyncGateway.COUCHBASE_SERVER, cluster) + .configure(CouchbaseSyncGateway.COUCHBASE_SERVER_BUCKET, "my_bucket") + ); + + app.start(ImmutableList.of(loc)); + + EntityTestUtils.assertAttributeEqualsEventually(gateway, Startable.SERVICE_UP, true); + } + + + // Supported operating systems + @Test(groups = {"Live"}) + @Override + public void test_Ubuntu_12_0() throws Exception { + super.test_Ubuntu_12_0(); + } + + @Test(groups = {"Live"}) + @Override + public void test_Red_Hat_Enterprise_Linux_6() throws Exception { + super.test_Red_Hat_Enterprise_Linux_6(); + } + + @Test(groups = {"Live"}) + @Override + public void test_CentOS_6_3() throws Exception { + super.test_CentOS_6_3(); + } + + // Unsupported operating systems + + @Test(groups = {"Live"}) + @Override + public void test_CentOS_5() throws Exception { + // Unsupported + // error: Failed dependencies: + // libc.so.6(GLIBC_2.7)(64bit) is needed by couchbase-server-2.5.1-1083.x86_64 + // libcrypto.so.10()(64bit) is needed by couchbase-server-2.5.1-1083.x86_64 + // libreadline.so.6()(64bit) is needed by couchbase-server-2.5.1-1083.x86_64 + // libssl.so.10()(64bit) is needed by couchbase-server-2.5.1-1083.x86_64 + // libstdc++.so.6(GLIBCXX_3.4.10)(64bit) is needed by couchbase-server-2.5.1-1083.x86_64 + // libstdc++.so.6(GLIBCXX_3.4.11)(64bit) is needed by couchbase-server-2.5.1-1083.x86_64 + // libstdc++.so.6(GLIBCXX_3.4.9)(64bit) is needed by couchbase-server-2.5.1-1083.x86_64 + // libtinfo.so.5()(64bit) is needed by couchbase-server-2.5.1-1083.x86_64 + // openssl >= 1.0.0 is needed by couchbase-server-2.5.1-1083.x86_64 + // rpmlib(FileDigests) <= 4.6.0-1 is needed by couchbase-server-2.5.1-1083.x86_64 + // rpmlib(PayloadIsXz) <= 5.2-1 is needed by couchbase-server-2.5.1-1083.x86_64 + } + + @Test(groups = {"Live"}) + @Override + public void test_Debian_6() throws Exception { + // Unsupported + } + + @Test(groups = {"Live"}) + @Override + public void test_Debian_7_2() throws Exception { + // Unsupported + } + + @Test(groups = {"Live"}) + @Override + public void test_Ubuntu_10_0() throws Exception { + // Unsupported + // Installing cannot proceed since the package 'libssl1*' is missing. + // Please install libssl1* and try again. + // $sudo apt-get install libssl1* + // + // Installing libssl1* doesn't fix the issue + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java new file mode 100644 index 0000000..d7bfa6b --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.entity.nosql.couchdb; + +import org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; + +import brooklyn.entity.basic.ApplicationBuilder; +import brooklyn.entity.basic.Entities; +import brooklyn.location.Location; +import brooklyn.location.basic.LocalhostMachineProvisioningLocation; +import brooklyn.test.entity.TestApplication; +import brooklyn.util.internal.TimeExtras; + +/** + * CouchDB test framework for integration and live tests. + */ +public class AbstractCouchDBNodeTest { + + private static final Logger log = LoggerFactory.getLogger(AbstractCouchDBNodeTest.class); + + static { + TimeExtras.init(); + } + + protected TestApplication app; + protected Location testLocation; + protected CouchDBNode couchdb; + + @BeforeMethod(alwaysRun = true) + public void setup() throws Exception { + app = ApplicationBuilder.newManagedApp(TestApplication.class); + testLocation = new LocalhostMachineProvisioningLocation(); + // testLocation = app.managementContext.locationRegistry.resolve("named:test"); + } + + @AfterMethod(alwaysRun = true) + public void shutdown() { + Entities.destroyAll(app.getManagementContext()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java new file mode 100644 index 0000000..0fd7796 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.entity.nosql.couchdb; + +import static org.testng.Assert.assertEquals; + +import org.apache.brooklyn.entity.nosql.couchdb.CouchDBCluster; +import org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import brooklyn.entity.basic.ApplicationBuilder; +import brooklyn.entity.basic.Entities; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.trait.Startable; +import brooklyn.location.Location; +import brooklyn.test.EntityTestUtils; +import brooklyn.test.entity.TestApplication; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; + +/** + * A live test of the {@link CouchDBCluster} entity. + * + * Tests that a two node cluster can be started on Amazon EC2 and data written on one {@link CouchDBNode} + * can be read from another, using the Astyanax API. + */ +public class CouchDBClusterLiveTest { + + // private String provider = "rackspace-cloudservers-uk"; + private String provider = "aws-ec2:eu-west-1"; + + protected TestApplication app; + protected Location testLocation; + protected CouchDBCluster cluster; + + @BeforeMethod(alwaysRun = true) + public void setup() { + app = ApplicationBuilder.newManagedApp(TestApplication.class); + testLocation = app.getManagementContext().getLocationRegistry().resolve(provider); + } + + @AfterMethod(alwaysRun = true) + public void shutdown() { + Entities.destroyAll(app.getManagementContext()); + } + + /** + * Test that a two node cluster starts up and allows access via the Astyanax API through both nodes. + */ + @Test(groups = "Live") + public void canStartupAndShutdown() throws Exception { + cluster = app.createAndManageChild(EntitySpec.create(CouchDBCluster.class) + .configure("initialSize", 2) + .configure("clusterName", "AmazonCluster")); + assertEquals(cluster.getCurrentSize().intValue(), 0); + + app.start(ImmutableList.of(testLocation)); + + EntityTestUtils.assertAttributeEqualsEventually(cluster, CouchDBCluster.GROUP_SIZE, 2); + Entities.dumpInfo(app); + + CouchDBNode first = (CouchDBNode) Iterables.get(cluster.getMembers(), 0); + CouchDBNode second = (CouchDBNode) Iterables.get(cluster.getMembers(), 1); + + EntityTestUtils.assertAttributeEqualsEventually(first, Startable.SERVICE_UP, true); + EntityTestUtils.assertAttributeEqualsEventually(second, Startable.SERVICE_UP, true); + + JcouchdbSupport jcouchdbFirst = new JcouchdbSupport(first); + JcouchdbSupport jcouchdbSecond = new JcouchdbSupport(second); + jcouchdbFirst.jcouchdbTest(); + jcouchdbSecond.jcouchdbTest(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java new file mode 100644 index 0000000..1838354 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java @@ -0,0 +1,50 @@ +/* + * 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.entity.nosql.couchdb; + +import org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import brooklyn.entity.AbstractEc2LiveTest; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.trait.Startable; +import brooklyn.location.Location; +import brooklyn.test.EntityTestUtils; + +import com.google.common.collect.ImmutableList; + +public class CouchDBNodeEc2LiveTest extends AbstractEc2LiveTest { + + private static final Logger log = LoggerFactory.getLogger(CouchDBNodeEc2LiveTest.class); + + @Override + protected void doTest(Location loc) throws Exception { + log.info("Testing Cassandra on {}", loc); + + CouchDBNode couchdb = app.createAndManageChild(EntitySpec.create(CouchDBNode.class) + .configure("httpPort", "8000+")); + app.start(ImmutableList.of(loc)); + + EntityTestUtils.assertAttributeEqualsEventually(couchdb, Startable.SERVICE_UP, true); + + JcouchdbSupport jcouchdb = new JcouchdbSupport(couchdb); + jcouchdb.jcouchdbTest(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeIntegrationTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeIntegrationTest.java new file mode 100644 index 0000000..0f8cbd2 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeIntegrationTest.java @@ -0,0 +1,67 @@ +/* + * 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.entity.nosql.couchdb; + +import org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode; +import org.testng.annotations.Test; + +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.trait.Startable; +import brooklyn.test.EntityTestUtils; + +import com.google.common.collect.ImmutableList; + +/** + * CouchDB integration tests. + * + * Test the operation of the {@link CouchDBNode} class. + */ +public class CouchDBNodeIntegrationTest extends AbstractCouchDBNodeTest { + + /** + * Test that a node starts and sets SERVICE_UP correctly. + */ + @Test(groups = {"Integration", "WIP"}) + public void canStartupAndShutdown() { + couchdb = app.createAndManageChild(EntitySpec.create(CouchDBNode.class) + .configure("httpPort", "8000+")); + app.start(ImmutableList.of(testLocation)); + + EntityTestUtils.assertAttributeEqualsEventually(couchdb, Startable.SERVICE_UP, true); + + couchdb.stop(); + + EntityTestUtils.assertAttributeEquals(couchdb, Startable.SERVICE_UP, false); + } + + /** + * Test that a node can be used with jcouchdb client. + */ + @Test(groups = {"Integration", "WIP"}) + public void testConnection() throws Exception { + couchdb = app.createAndManageChild(EntitySpec.create(CouchDBNode.class) + .configure("httpPort", "8000+")); + app.start(ImmutableList.of(testLocation)); + + EntityTestUtils.assertAttributeEqualsEventually(couchdb, Startable.SERVICE_UP, true); + + JcouchdbSupport jcouchdb = new JcouchdbSupport(couchdb); + jcouchdb.jcouchdbTest(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeLiveTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeLiveTest.java new file mode 100644 index 0000000..05ce053 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeLiveTest.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.entity.nosql.couchdb; + +import java.util.Map; + +import org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.trait.Startable; +import brooklyn.test.EntityTestUtils; +import brooklyn.util.collections.MutableMap; +import brooklyn.util.text.Strings; + +import com.google.common.collect.ImmutableList; + +/** + * CouchDB live tests. + * + * Test the operation of the {@link CouchDBNode} class using the jclouds {@code rackspace-cloudservers-uk} + * and {@code aws-ec2} providers, with different OS images. The tests use the {@link JcouchdbSupport#jcouchdbTest(CouchDBNode)} method + * to exercise the node, and will need to have {@code brooklyn.jclouds.provider.identity} and {@code .credential} + * set, usually in the {@code .brooklyn/brooklyn.properties} file. + */ +public class CouchDBNodeLiveTest extends AbstractCouchDBNodeTest { + + private static final Logger log = LoggerFactory.getLogger(CouchDBNodeLiveTest.class); + + @DataProvider(name = "virtualMachineData") + public Object[][] provideVirtualMachineData() { + return new Object[][] { // ImageId, Provider, Region, Description (for logging) + new Object[] { "eu-west-1/ami-0307d674", "aws-ec2", "eu-west-1", "Ubuntu Server 14.04 LTS (HVM), SSD Volume Type" }, + new Object[] { "LON/f9b690bf-88eb-43c2-99cf-391f2558732e", "rackspace-cloudservers-uk", "", "Ubuntu 12.04 LTS (Precise Pangolin)" }, + new Object[] { "LON/a84b1592-6817-42da-a57c-3c13f3cfc1da", "rackspace-cloudservers-uk", "", "CentOS 6.5 (PVHVM)" }, + }; + } + + @Test(groups = "Live", dataProvider = "virtualMachineData") + protected void testOperatingSystemProvider(String imageId, String provider, String region, String description) throws Exception { + log.info("Testing CouchDB on {}{} using {} ({})", new Object[] { provider, Strings.isNonEmpty(region) ? ":" + region : "", description, imageId }); + + Map<String, String> properties = MutableMap.of("imageId", imageId); + testLocation = app.getManagementContext().getLocationRegistry() + .resolve(provider + (Strings.isNonEmpty(region) ? ":" + region : ""), properties); + + couchdb = app.createAndManageChild(EntitySpec.create(CouchDBNode.class) + .configure("httpPort", "12345+") + .configure("clusterName", "TestCluster")); + app.start(ImmutableList.of(testLocation)); + EntityTestUtils.assertAttributeEqualsEventually(couchdb, Startable.SERVICE_UP, true); + + JcouchdbSupport jcouchdb = new JcouchdbSupport(couchdb); + jcouchdb.jcouchdbTest(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/JcouchdbSupport.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/JcouchdbSupport.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/JcouchdbSupport.java new file mode 100644 index 0000000..d1c7cf6 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/JcouchdbSupport.java @@ -0,0 +1,78 @@ +/* + * 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.entity.nosql.couchdb; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode; +import org.jcouchdb.db.Database; +import org.jcouchdb.db.Server; +import org.jcouchdb.db.ServerImpl; + +import brooklyn.entity.basic.Attributes; + +/** + * CouchDB test framework for integration and live tests, using jcouchdb API. + */ +public class JcouchdbSupport { + + private CouchDBNode node; + + public JcouchdbSupport(CouchDBNode node) { + this.node = node; + } + + /** + * Exercise the {@link CouchDBNode} using the jcouchdb API. + */ + public void jcouchdbTest() throws Exception { + Server server = new ServerImpl(node.getAttribute(Attributes.HOSTNAME), node.getHttpPort()); + assertTrue(server.createDatabase("brooklyn")); + + Database db = new Database(node.getAttribute(Attributes.HOSTNAME), node.getHttpPort(), "brooklyn"); + + // create a hash map document with two fields + Map<String,String> doc = new HashMap<String, String>(); + doc.put("first", "one"); + doc.put("second", "two"); + + // create the document in couchdb + int before = db.listDocuments(null, null).getTotalRows(); + db.createDocument(doc); + int after = db.listDocuments(null, null).getTotalRows(); + + assertEquals(before + 1, after); + } + + /** + * Write to a {@link CouchDBNode} using the jcouchdb API. + */ + protected void writeData() throws Exception { + } + + /** + * Read from a {@link CouchDBNode} using the jcouchdb API. + */ + protected void readData() throws Exception { + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java new file mode 100644 index 0000000..9f794a1 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java @@ -0,0 +1,130 @@ +/* + * 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.entity.nosql.elasticsearch; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.brooklyn.entity.nosql.elasticsearch.ElasticSearchCluster; +import org.apache.brooklyn.entity.nosql.elasticsearch.ElasticSearchNode; +import org.apache.http.client.methods.HttpGet; +import org.bouncycastle.util.Strings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import brooklyn.entity.BrooklynAppLiveTestSupport; +import brooklyn.entity.Entity; +import brooklyn.entity.basic.Attributes; +import brooklyn.entity.group.DynamicCluster; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.trait.Startable; +import brooklyn.event.feed.http.HttpValueFunctions; +import brooklyn.location.Location; +import brooklyn.test.Asserts; +import brooklyn.test.EntityTestUtils; +import brooklyn.util.http.HttpTool; +import brooklyn.util.http.HttpToolResponse; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +public class ElasticSearchClusterIntegrationTest extends BrooklynAppLiveTestSupport { + + // FIXME Exception in thread "main" java.lang.UnsupportedClassVersionError: org/elasticsearch/bootstrap/Elasticsearch : Unsupported major.minor version 51.0 + + private static final Logger LOG = LoggerFactory.getLogger(ElasticSearchClusterIntegrationTest.class); + + protected Location testLocation; + protected ElasticSearchCluster elasticSearchCluster; + + @BeforeMethod(alwaysRun = true) + @Override + public void setUp() throws Exception { + super.setUp(); + testLocation = app.newLocalhostProvisioningLocation(); + } + + @Test(groups = {"Integration"}) + public void testStartupAndShutdown() { + elasticSearchCluster = app.createAndManageChild(EntitySpec.create(ElasticSearchCluster.class) + .configure(DynamicCluster.INITIAL_SIZE, 3)); + app.start(ImmutableList.of(testLocation)); + + EntityTestUtils.assertAttributeEqualsEventually(elasticSearchCluster, Startable.SERVICE_UP, true); + + elasticSearchCluster.stop(); + + EntityTestUtils.assertAttributeEqualsEventually(elasticSearchCluster, Startable.SERVICE_UP, false); + } + + @Test(groups = {"Integration"}) + public void testPutAndGet() throws URISyntaxException { + elasticSearchCluster = app.createAndManageChild(EntitySpec.create(ElasticSearchCluster.class) + .configure(DynamicCluster.INITIAL_SIZE, 3)); + app.start(ImmutableList.of(testLocation)); + + EntityTestUtils.assertAttributeEqualsEventually(elasticSearchCluster, Startable.SERVICE_UP, true); + assertEquals(elasticSearchCluster.getMembers().size(), 3); + assertEquals(clusterDocumentCount(), 0); + + ElasticSearchNode anyNode = (ElasticSearchNode)elasticSearchCluster.getMembers().iterator().next(); + + String document = "{\"foo\" : \"bar\",\"baz\" : \"quux\"}"; + + String putBaseUri = "http://" + anyNode.getAttribute(Attributes.HOSTNAME) + ":" + anyNode.getAttribute(Attributes.HTTP_PORT); + + HttpToolResponse putResponse = HttpTool.httpPut( + HttpTool.httpClientBuilder() + .port(anyNode.getAttribute(Attributes.HTTP_PORT)) + .build(), + new URI(putBaseUri + "/mydocuments/docs/1"), + ImmutableMap.<String, String>of(), + Strings.toByteArray(document)); + assertEquals(putResponse.getResponseCode(), 201); + + for (Entity entity : elasticSearchCluster.getMembers()) { + ElasticSearchNode node = (ElasticSearchNode)entity; + String getBaseUri = "http://" + node.getAttribute(Attributes.HOSTNAME) + ":" + node.getAttribute(Attributes.HTTP_PORT); + HttpToolResponse getResponse = HttpTool.execAndConsume( + HttpTool.httpClientBuilder().build(), + new HttpGet(getBaseUri + "/mydocuments/docs/1/_source")); + assertEquals(getResponse.getResponseCode(), 200); + assertEquals(HttpValueFunctions.jsonContents("foo", String.class).apply(getResponse), "bar"); + } + Asserts.succeedsEventually(new Runnable() { + public void run() { + int count = clusterDocumentCount(); + assertTrue(count >= 1, "count="+count); + LOG.debug("Document count is {}", count); + }}); + } + + private int clusterDocumentCount() { + int result = 0; + for (Entity entity : elasticSearchCluster.getMembers()) { + result += entity.getAttribute(ElasticSearchNode.DOCUMENT_COUNT); + } + return result; + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java new file mode 100644 index 0000000..c0c140d --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java @@ -0,0 +1,113 @@ +/* + * 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.entity.nosql.elasticsearch; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.brooklyn.entity.nosql.elasticsearch.ElasticSearchNode; +import org.apache.http.client.methods.HttpGet; +import org.bouncycastle.util.Strings; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import brooklyn.entity.basic.ApplicationBuilder; +import brooklyn.entity.basic.Attributes; +import brooklyn.entity.basic.Entities; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.trait.Startable; +import brooklyn.event.feed.http.HttpValueFunctions; +import brooklyn.location.Location; +import brooklyn.location.basic.LocalhostMachineProvisioningLocation; +import brooklyn.test.EntityTestUtils; +import brooklyn.test.entity.TestApplication; +import brooklyn.util.http.HttpTool; +import brooklyn.util.http.HttpToolResponse; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +public class ElasticSearchNodeIntegrationTest { + + protected TestApplication app; + protected Location testLocation; + protected ElasticSearchNode elasticSearchNode; + + @BeforeMethod(alwaysRun = true) + public void setup() throws Exception { + app = ApplicationBuilder.newManagedApp(TestApplication.class); + testLocation = new LocalhostMachineProvisioningLocation(); + } + + @AfterMethod(alwaysRun = true) + public void shutdown() { + Entities.destroyAll(app.getManagementContext()); + } + + @Test(groups = {"Integration"}) + public void testStartupAndShutdown() { + elasticSearchNode = app.createAndManageChild(EntitySpec.create(ElasticSearchNode.class)); + app.start(ImmutableList.of(testLocation)); + + EntityTestUtils.assertAttributeEqualsEventually(elasticSearchNode, Startable.SERVICE_UP, true); + + elasticSearchNode.stop(); + + EntityTestUtils.assertAttributeEqualsEventually(elasticSearchNode, Startable.SERVICE_UP, false); + } + + @Test(groups = {"Integration"}) + public void testDocumentCount() throws URISyntaxException { + elasticSearchNode = app.createAndManageChild(EntitySpec.create(ElasticSearchNode.class)); + app.start(ImmutableList.of(testLocation)); + + EntityTestUtils.assertAttributeEqualsEventually(elasticSearchNode, Startable.SERVICE_UP, true); + + EntityTestUtils.assertAttributeEquals(elasticSearchNode, ElasticSearchNode.DOCUMENT_COUNT, 0); + + String baseUri = "http://" + elasticSearchNode.getAttribute(Attributes.HOSTNAME) + ":" + elasticSearchNode.getAttribute(Attributes.HTTP_PORT); + + HttpToolResponse pingResponse = HttpTool.execAndConsume( + HttpTool.httpClientBuilder().build(), + new HttpGet(baseUri)); + assertEquals(pingResponse.getResponseCode(), 200); + + String document = "{\"foo\" : \"bar\",\"baz\" : \"quux\"}"; + + HttpToolResponse putResponse = HttpTool.httpPut( + HttpTool.httpClientBuilder() + .port(elasticSearchNode.getAttribute(Attributes.HTTP_PORT)) + .build(), + new URI(baseUri + "/mydocuments/docs/1"), + ImmutableMap.<String, String>of(), + Strings.toByteArray(document)); + assertEquals(putResponse.getResponseCode(), 201); + + HttpToolResponse getResponse = HttpTool.execAndConsume( + HttpTool.httpClientBuilder().build(), + new HttpGet(baseUri + "/mydocuments/docs/1/_source")); + assertEquals(getResponse.getResponseCode(), 200); + assertEquals(HttpValueFunctions.jsonContents("foo", String.class).apply(getResponse), "bar"); + + EntityTestUtils.assertAttributeEqualsEventually(elasticSearchNode, ElasticSearchNode.DOCUMENT_COUNT, 1); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java new file mode 100644 index 0000000..413f0c9 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java @@ -0,0 +1,56 @@ +/* + * 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.entity.nosql.mongodb; + +import brooklyn.entity.AbstractEc2LiveTest; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.location.Location; +import brooklyn.test.EntityTestUtils; +import com.google.common.collect.ImmutableList; +import com.mongodb.DBObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer; + +public class MongoDBEc2LiveTest extends AbstractEc2LiveTest { + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(MongoDBEc2LiveTest.class); + + @Override + protected void doTest(Location loc) throws Exception { + MongoDBServer entity = app.createAndManageChild(EntitySpec.create(MongoDBServer.class) + .configure("mongodbConfTemplateUrl", "classpath:///test-mongodb.conf")); + app.start(ImmutableList.of(loc)); + + EntityTestUtils.assertAttributeEqualsEventually(entity, MongoDBServer.SERVICE_UP, true); + + String id = MongoDBTestHelper.insert(entity, "hello", "world!"); + DBObject docOut = MongoDBTestHelper.getById(entity, id); + assertEquals(docOut.get("hello"), "world!"); + } + + @Test(enabled=false) + public void testDummy() {} // Convince TestNG IDE integration that this really does have test methods + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBIntegrationTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBIntegrationTest.java new file mode 100644 index 0000000..eb9c362 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBIntegrationTest.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.entity.nosql.mongodb; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; + +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import brooklyn.entity.basic.ApplicationBuilder; +import brooklyn.entity.basic.Entities; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.trait.Startable; +import brooklyn.location.basic.LocalhostMachineProvisioningLocation; +import brooklyn.test.EntityTestUtils; +import brooklyn.test.entity.TestApplication; + +import com.google.common.collect.ImmutableList; +import com.mongodb.DBObject; + +public class MongoDBIntegrationTest { + + private TestApplication app; + private LocalhostMachineProvisioningLocation localhostProvisioningLocation; + + @BeforeMethod(alwaysRun=true) + public void setUp() throws Exception { + localhostProvisioningLocation = new LocalhostMachineProvisioningLocation(); + app = ApplicationBuilder.newManagedApp(TestApplication.class); + } + + @AfterMethod(alwaysRun=true) + public void tearDown() throws Exception { + if (app != null) Entities.destroyAll(app.getManagementContext()); + } + + @Test(groups = "Integration") + public void testCanStartAndStop() throws Exception { + MongoDBServer entity = app.createAndManageChild(EntitySpec.create(MongoDBServer.class) + .configure("mongodbConfTemplateUrl", "classpath:///test-mongodb.conf")); + app.start(ImmutableList.of(localhostProvisioningLocation)); + + EntityTestUtils.assertAttributeEqualsEventually(entity, Startable.SERVICE_UP, true); + entity.stop(); + assertFalse(entity.getAttribute(Startable.SERVICE_UP)); + } + + @Test(groups = "Integration", dependsOnMethods = { "testCanStartAndStop" }) + public void testCanReadAndWrite() throws Exception { + MongoDBServer entity = app.createAndManageChild(EntitySpec.create(MongoDBServer.class) + .configure("mongodbConfTemplateUrl", "classpath:///test-mongodb.conf")); + app.start(ImmutableList.of(localhostProvisioningLocation)); + + String id = MongoDBTestHelper.insert(entity, "hello", "world!"); + DBObject docOut = MongoDBTestHelper.getById(entity, id); + assertEquals(docOut.get("hello"), "world!"); + } + + @Test(groups = "Integration", dependsOnMethods = { "testCanStartAndStop" }) + public void testPollInsertCountSensor() throws Exception { + MongoDBServer entity = app.createAndManageChild(EntitySpec.create(MongoDBServer.class) + .configure("mongodbConfTemplateUrl", "classpath:///test-mongodb.conf")); + app.start(ImmutableList.of(localhostProvisioningLocation)); + EntityTestUtils.assertAttributeEqualsEventually(entity, Startable.SERVICE_UP, true); + + EntityTestUtils.assertAttributeEventuallyNonNull(entity, MongoDBServer.OPCOUNTERS_INSERTS); + Long initialInserts = entity.getAttribute(MongoDBServer.OPCOUNTERS_INSERTS); + MongoDBTestHelper.insert(entity, "a", Boolean.TRUE); + MongoDBTestHelper.insert(entity, "b", Boolean.FALSE); + EntityTestUtils.assertAttributeEqualsEventually(entity, MongoDBServer.OPCOUNTERS_INSERTS, initialInserts + 2); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRebindIntegrationTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRebindIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRebindIntegrationTest.java new file mode 100644 index 0000000..b7c7739 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRebindIntegrationTest.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.entity.nosql.mongodb; + +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.rebind.RebindTestFixtureWithApp; +import brooklyn.location.basic.LocalhostMachineProvisioningLocation; +import brooklyn.test.EntityTestUtils; + +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; + +public class MongoDBRebindIntegrationTest extends RebindTestFixtureWithApp { + + private LocalhostMachineProvisioningLocation loc; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + loc = origApp.newLocalhostProvisioningLocation(); + } + + @Test(groups = {"Integration"}) + public void testRebindMongoDb() throws Exception { + MongoDBServer origEntity = origApp.createAndManageChild(EntitySpec.create(MongoDBServer.class) + .configure("mongodbConfTemplateUrl", "classpath:///test-mongodb.conf")); + origApp.start(ImmutableList.of(loc)); + EntityTestUtils.assertAttributeEventuallyNonNull(origEntity, MongoDBServer.STATUS_BSON); + + // rebind + rebind(); + final MongoDBServer newEntity = (MongoDBServer) Iterables.find(newApp.getChildren(), Predicates.instanceOf(MongoDBServer.class)); + + // confirm effectors still work on entity + EntityTestUtils.assertAttributeEqualsEventually(newEntity, MongoDBServer.SERVICE_UP, true); + newEntity.stop(); + EntityTestUtils.assertAttributeEqualsEventually(newEntity, MongoDBServer.SERVICE_UP, false); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java new file mode 100644 index 0000000..051a698 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java @@ -0,0 +1,98 @@ +/* + * 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.entity.nosql.mongodb; + +import brooklyn.entity.AbstractEc2LiveTest; +import brooklyn.entity.basic.Entities; +import brooklyn.entity.group.DynamicCluster; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.location.Location; +import brooklyn.test.Asserts; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.mongodb.DBObject; + +import groovy.time.TimeDuration; + +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet; +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import java.util.concurrent.Callable; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +public class MongoDBReplicaSetEc2LiveTest extends AbstractEc2LiveTest { + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(MongoDBReplicaSetEc2LiveTest.class); + private static final Integer REPLICA_SET_SIZE = 3; + private static final TimeDuration TIMEOUT = new TimeDuration(0, 0, 180, 0); + + /** + * Test that a three node replica set starts and allows access through both nodes. + */ + @Override + protected void doTest(Location loc) throws Exception { + final MongoDBReplicaSet replicaSet = app.createAndManageChild(EntitySpec.create(MongoDBReplicaSet.class) + .configure(DynamicCluster.INITIAL_SIZE, REPLICA_SET_SIZE) + .configure("replicaSetName", "mongodb-live-test-replica-set") + .configure("memberSpec", EntitySpec.create(MongoDBServer.class) + .configure("mongodbConfTemplateUrl", "classpath:///test-mongodb.conf") + .configure("port", "27017+"))); + + assertEquals(replicaSet.getCurrentSize().intValue(), 0); + + app.start(ImmutableList.of(loc)); + + Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT), new Callable<Boolean>() { + @Override + public Boolean call() { + assertEquals(replicaSet.getCurrentSize(), REPLICA_SET_SIZE); + assertNotNull(replicaSet.getPrimary()); + assertEquals(replicaSet.getSecondaries().size(), REPLICA_SET_SIZE-1); + return true; + } + }); + + Entities.dumpInfo(app); + + // Test inserting a document and reading from secondaries + final String documentId = MongoDBTestHelper.insert(replicaSet.getPrimary(), "meaning-of-life", 42); + Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT), new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + assertEquals(replicaSet.getCurrentSize().intValue(), 3); + for (MongoDBServer secondary : replicaSet.getSecondaries()) { + DBObject docOut = MongoDBTestHelper.getById(secondary, documentId); + assertEquals(docOut.get("meaning-of-life"), 42); + } + return true; + } + }); + + } + + @Test(enabled=false) + public void testDummy() {} // Convince TestNG IDE integration that this really does have test methods +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetIntegrationTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetIntegrationTest.java new file mode 100644 index 0000000..56ed82f --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetIntegrationTest.java @@ -0,0 +1,208 @@ +/* + * 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.entity.nosql.mongodb; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; +import static org.testng.Assert.assertNotNull; + +import java.util.Collection; +import java.util.concurrent.TimeUnit; + +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet; +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import brooklyn.entity.BrooklynAppLiveTestSupport; +import brooklyn.entity.Entity; +import brooklyn.entity.group.DynamicCluster; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.trait.Startable; +import brooklyn.location.basic.LocalhostMachineProvisioningLocation; +import brooklyn.test.Asserts; +import brooklyn.util.time.Duration; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.mongodb.DBObject; + +public class MongoDBReplicaSetIntegrationTest extends BrooklynAppLiveTestSupport { + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(MongoDBReplicaSetIntegrationTest.class); + + private Collection<LocalhostMachineProvisioningLocation> locs; + + // Replica sets can take a while to start + private static final Duration TIMEOUT = Duration.of(3, TimeUnit.MINUTES); + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + locs = ImmutableList.of(app.newLocalhostProvisioningLocation()); + } + + /** + * Creates and starts a replica set, asserts it reaches the given size + * and that the primary and secondaries are non-null. + */ + private MongoDBReplicaSet makeAndStartReplicaSet(final Integer size, final String testDescription) { + // Sets secondaryPreferred so we can read from slaves. + final MongoDBReplicaSet replicaSet = app.createAndManageChild(EntitySpec.create(MongoDBReplicaSet.class) + .configure(DynamicCluster.INITIAL_SIZE, size) + .configure("replicaSetName", "test-rs-"+testDescription) + .configure("memberSpec", EntitySpec.create(MongoDBServer.class) + .configure("mongodbConfTemplateUrl", "classpath:///test-mongodb.conf") + .configure("port", "27017+"))); + app.start(locs); + + Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT), new Runnable() { + @Override + public void run() { + assertEquals(replicaSet.getCurrentSize(), size); + assertNotNull(replicaSet.getPrimary(), "replica set has no primary"); + assertEquals(replicaSet.getPrimary().getReplicaSet().getName(), "test-rs-"+testDescription+replicaSet.getId()); + assertEquals(replicaSet.getSecondaries().size(), size-1); + } + }); + return replicaSet; + } + + @Test(groups = "Integration") + public void testCanStartAndStopAReplicaSet() { + final MongoDBReplicaSet replicaSet = makeAndStartReplicaSet(3, "can-start-and-stop"); + replicaSet.stop(); + assertFalse(replicaSet.getAttribute(Startable.SERVICE_UP)); + } + + @Test(groups = "Integration") + public void testWriteToMasterAndReadFromSecondary() { + final MongoDBReplicaSet replicaSet = makeAndStartReplicaSet(3, "master-write-secondary-read"); + + // Test we can read a document written to the primary from all secondaries + final String documentId = MongoDBTestHelper.insert(replicaSet.getPrimary(), "meaning-of-life", 42); + Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT), new Runnable() { + @Override + public void run() { + assertEquals(replicaSet.getCurrentSize().intValue(), 3); + for (MongoDBServer secondary : replicaSet.getSecondaries()) { + DBObject docOut = MongoDBTestHelper.getById(secondary, documentId); + assertEquals(docOut.get("meaning-of-life"), 42); + } + } + }); + } + + @Test(groups = "Integration") + public void testCanResizeAndReadFromNewInstances() { + final MongoDBReplicaSet replicaSet = makeAndStartReplicaSet(3, "resize-and-read-from-secondaries"); + + // Test we can a document written to the primary from all secondaries + final String documentId = MongoDBTestHelper.insert(replicaSet.getPrimary(), "meaning-of-life", 42); + Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT), new Runnable() { + @Override + public void run() { + assertEquals(replicaSet.getCurrentSize().intValue(), 3); + for (MongoDBServer secondary : replicaSet.getSecondaries()) { + DBObject docOut = MongoDBTestHelper.getById(secondary, documentId); + assertEquals(docOut.get("meaning-of-life"), 42); + } + } + }); + + // Resize and confirm new members get data + replicaSet.resize(5); + Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT), new Runnable() { + @Override + public void run() { + assertEquals(replicaSet.getCurrentSize().intValue(), 5); + Collection<MongoDBServer> secondaries = replicaSet.getSecondaries(); + assertEquals(secondaries.size(), 4); + for (MongoDBServer secondary : secondaries) { + DBObject docOut = MongoDBTestHelper.getById(secondary, documentId); + assertEquals(docOut.get("meaning-of-life"), 42); + } + } + }); + + } + + @Test(groups = "Integration") + public void testResizeToEvenNumberOfMembers() { + final MongoDBReplicaSet replicaSet = makeAndStartReplicaSet(3, "resize-even-ignored"); + assertEquals(replicaSet.getCurrentSize().intValue(), 3); + replicaSet.resize(4); + Asserts.succeedsEventually(new Runnable() { + @Override + public void run() { + assertEquals(replicaSet.getCurrentSize().intValue(), 4); + } + }); + } + + /** + * Test replacing the primary succeeds. More interesting than replacing a secondary + * because the removal of a primary must happen _through_ the primary. The flow is: + * - Brooklyn removes the server from the set and stops it + * - The remaining members of the set elect a new primary + * - We remove the original primary from the new primary. + */ + @Test(groups = "Integration") + public void testReplacePrimary() { + final MongoDBReplicaSet replicaSet = makeAndStartReplicaSet(3, "replace-primary"); + final MongoDBServer replaced = replicaSet.getPrimary(); + replicaSet.replaceMember(replaced.getId()); + Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT), new Runnable() { + @Override + public void run() { + assertEquals(replicaSet.getCurrentSize().intValue(), 3); + for (Entity member : replicaSet.getMembers()) { + assertNotEquals(member.getId(), replaced.getId()); + } + assertNotNull(replicaSet.getPrimary()); + assertNotEquals(replicaSet.getPrimary().getId(), replaced.getId(), "Expected a new primary to have been elected"); + } + }); + } + + @Test(groups = "Integration") + public void testRemovePrimary() { + final MongoDBReplicaSet replicaSet = makeAndStartReplicaSet(3, "remove-primary"); + final MongoDBServer removed = replicaSet.getPrimary(); + + replicaSet.removeMember(removed); + removed.stop(); + Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT), new Runnable() { + @Override + public void run() { + assertEquals(replicaSet.getCurrentSize().intValue(), 2); + for (Entity member : replicaSet.getMembers()) { + assertNotEquals(member.getId(), removed.getId()); + } + assertNotNull(replicaSet.getPrimary()); + assertNotEquals(replicaSet.getPrimary().getId(), removed.getId(), "Expected a new primary to have been elected"); + } + }); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRestartIntegrationTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRestartIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRestartIntegrationTest.java new file mode 100644 index 0000000..3ef722a --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRestartIntegrationTest.java @@ -0,0 +1,43 @@ +/* + * 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.entity.nosql.mongodb; + +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import brooklyn.entity.basic.AbstractSoftwareProcessRestartIntegrationTest; +import brooklyn.entity.basic.SoftwareProcess; +import brooklyn.entity.proxying.EntitySpec; + +/** + * Tests restart of the software *process* (as opposed to the VM). + */ +@Test(groups="Integration") +public class MongoDBRestartIntegrationTest extends AbstractSoftwareProcessRestartIntegrationTest { + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(MongoDBRestartIntegrationTest.class); + + @Override + protected EntitySpec<? extends SoftwareProcess> newEntitySpec() { + return EntitySpec.create(MongoDBServer.class); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d5cf5285/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java new file mode 100644 index 0000000..de6e597 --- /dev/null +++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.entity.nosql.mongodb; + +import static org.testng.Assert.assertEquals; + +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.mongodb.DBObject; + +import brooklyn.entity.AbstractSoftlayerLiveTest; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.location.Location; +import brooklyn.test.EntityTestUtils; + +public class MongoDBSoftLayerLiveTest extends AbstractSoftlayerLiveTest { + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(MongoDBSoftLayerLiveTest.class); + + @Override + protected void doTest(Location loc) throws Exception { + MongoDBServer entity = app.createAndManageChild(EntitySpec.create(MongoDBServer.class) + .configure("mongodbConfTemplateUrl", "classpath:///test-mongodb.conf")); + app.start(ImmutableList.of(loc)); + + EntityTestUtils.assertAttributeEqualsEventually(entity, MongoDBServer.SERVICE_UP, true); + + String id = MongoDBTestHelper.insert(entity, "hello", "world!"); + DBObject docOut = MongoDBTestHelper.getById(entity, id); + assertEquals(docOut.get("hello"), "world!"); + } + + @Test(enabled=false) + public void testDummy() {} // Convince TestNG IDE integration that this really does have test methods + +}
