You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ri...@apache.org on 2014/06/01 22:15:33 UTC
[18/25] git commit: Rebind test for WebClusterDatabaseExampleApp (WIP)
Rebind test for WebClusterDatabaseExampleApp (WIP)
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/57e670c7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/57e670c7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/57e670c7
Branch: refs/heads/master
Commit: 57e670c74a06ba7cc706581fd0998de757ca5842
Parents: ade78fa
Author: Aled Sage <al...@gmail.com>
Authored: Wed May 28 19:15:18 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Fri May 30 10:24:39 2014 +0100
----------------------------------------------------------------------
examples/simple-web-cluster/pom.xml | 8 +
.../demo/WebClusterDatabaseExampleApp.java | 2 +-
...lusterDatabaseExampleAppIntegrationTest.java | 186 +++++++++++++++++++
3 files changed, 195 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/57e670c7/examples/simple-web-cluster/pom.xml
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/pom.xml b/examples/simple-web-cluster/pom.xml
index 9191c51..d2d93e9 100644
--- a/examples/simple-web-cluster/pom.xml
+++ b/examples/simple-web-cluster/pom.xml
@@ -25,6 +25,14 @@
<version>${project.version}</version>
<optional>true</optional>
</dependency>
+
+ <dependency>
+ <groupId>io.brooklyn</groupId>
+ <artifactId>brooklyn-core</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/57e670c7/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleApp.java b/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleApp.java
index 38f53a2..6c1f7b8 100644
--- a/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleApp.java
+++ b/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleApp.java
@@ -92,7 +92,7 @@ public class WebClusterDatabaseExampleApp extends AbstractApplication implements
public static final String DB_USERNAME = "brooklyn";
public static final String DB_PASSWORD = "br00k11n";
- AttributeSensor<Integer> APPSERVERS_COUNT = Sensors.newIntegerSensor(
+ public static final AttributeSensor<Integer> APPSERVERS_COUNT = Sensors.newIntegerSensor(
"appservers.count", "Number of app servers deployed");
public static final AttributeSensor<Double> REQUESTS_PER_SECOND_IN_WINDOW =
WebAppServiceConstants.REQUESTS_PER_SECOND_IN_WINDOW;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/57e670c7/examples/simple-web-cluster/src/test/java/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/test/java/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java b/examples/simple-web-cluster/src/test/java/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
new file mode 100644
index 0000000..2b94727
--- /dev/null
+++ b/examples/simple-web-cluster/src/test/java/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
@@ -0,0 +1,186 @@
+package brooklyn.demo;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.enricher.HttpLatencyDetector;
+import brooklyn.enricher.basic.Propagator;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.database.mysql.MySqlNode;
+import brooklyn.entity.group.DynamicCluster;
+import brooklyn.entity.java.JavaEntityMethods;
+import brooklyn.entity.proxy.nginx.NginxController;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.rebind.RebindTestFixture;
+import brooklyn.entity.rebind.RebindTestUtils;
+import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
+import brooklyn.entity.webapp.DynamicWebAppCluster;
+import brooklyn.entity.webapp.jboss.JBoss7Server;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.SensorEvent;
+import brooklyn.event.SensorEventListener;
+import brooklyn.location.Location;
+import brooklyn.management.SubscriptionHandle;
+import brooklyn.policy.Enricher;
+import brooklyn.policy.autoscaling.AutoScalerPolicy;
+import brooklyn.test.Asserts;
+import brooklyn.test.EntityTestUtils;
+import brooklyn.test.HttpTestUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+
+
+public class RebindWebClusterDatabaseExampleAppIntegrationTest extends RebindTestFixture<StartableApplication> {
+
+ private Location origLoc;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ origLoc = origManagementContext.getLocationRegistry().resolve("localhost");
+ }
+
+ @Override
+ protected StartableApplication createApp() {
+ return origManagementContext.getEntityManager().createEntity(EntitySpec.create(StartableApplication.class)
+ .impl(WebClusterDatabaseExampleApp.class)
+ .configure(DynamicCluster.INITIAL_SIZE, 2));
+ }
+
+ @Override
+ protected StartableApplication rebind(boolean checkSerializable) throws Exception {
+ RebindTestUtils.waitForPersisted(origApp);
+ if (checkSerializable) {
+ RebindTestUtils.checkCurrentMementoSerializable(origApp);
+ }
+
+ // Must also terminate the original management context, otherwise it will keep trying to write
+ // mementos due to the frequent attribute-changes
+ origManagementContext.terminate();
+
+ return (StartableApplication) RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
+ }
+
+
+ @Test(groups="Integration")
+ public void testRestoresSimpleApp() throws Exception {
+ origApp.start(ImmutableList.of(origLoc));
+
+ assertAppFunctional(origApp);
+
+ newApp = rebind(false);
+ assertAppFunctional(newApp);
+ }
+
+ private void assertAppFunctional(StartableApplication app) throws Exception {
+ // expect standard config to (still) be set
+ assertNotNull(app.getConfig(WebClusterDatabaseExampleApp.WAR_PATH));
+ assertEquals(app.getConfig(WebClusterDatabaseExampleApp.USE_HTTPS), Boolean.FALSE);
+ assertNotNull(app.getConfig(WebClusterDatabaseExampleApp.DB_SETUP_SQL_URL));
+
+ // expect entities to be there
+ MySqlNode mysql = (MySqlNode) Iterables.find(app.getChildren(), Predicates.instanceOf(MySqlNode.class));
+ ControlledDynamicWebAppCluster web = (ControlledDynamicWebAppCluster) Iterables.find(app.getChildren(), Predicates.instanceOf(ControlledDynamicWebAppCluster.class));
+ final NginxController nginx = (NginxController) Iterables.find(web.getChildren(), Predicates.instanceOf(NginxController.class));
+ DynamicWebAppCluster webCluster = (DynamicWebAppCluster) Iterables.find(web.getChildren(), Predicates.instanceOf(DynamicWebAppCluster.class));
+ Collection<Entity> appservers = web.getMembers();
+ assertEquals(appservers.size(), 2);
+ String clusterUrl = checkNotNull(app.getAttribute(WebClusterDatabaseExampleApp.ROOT_URL), "cluster url");
+ String dbUrl = checkNotNull(mysql.getAttribute(MySqlNode.DATASTORE_URL), "database url");
+ final String expectedJdbcUrl = String.format("jdbc:%s%s?user=%s\\&password=%s", dbUrl, WebClusterDatabaseExampleApp.DB_TABLE,
+ WebClusterDatabaseExampleApp.DB_USERNAME, WebClusterDatabaseExampleApp.DB_PASSWORD);
+
+ // FIXME the rebind policy is reconfiguring nginx temporarily; the members are being removed!
+ Thread.sleep(10000);
+
+ // expect web-app to be reachable, and wired up to database
+ HttpTestUtils.assertHttpStatusCodeEquals(clusterUrl, 200);
+ for (Entity appserver : appservers) {
+ String appserverUrl = checkNotNull(appserver.getAttribute(JBoss7Server.ROOT_URL), "appserver url of "+appserver);
+
+ HttpTestUtils.assertHttpStatusCodeEquals(appserverUrl, 200);
+ assertEquals(expectedJdbcUrl, appserver.getConfig(JavaEntityMethods.javaSysProp("brooklyn.example.db.url")), "of "+appserver);
+ }
+
+ // expect auto-scaler policy to be there, and to be functional (e.g. can trigger resize)
+ AutoScalerPolicy autoScalerPolicy = (AutoScalerPolicy) Iterables.find(webCluster.getPolicies(), Predicates.instanceOf(AutoScalerPolicy.class));
+
+ autoScalerPolicy.setConfig(AutoScalerPolicy.MIN_POOL_SIZE, 3);
+ EntityTestUtils.assertGroupSizeEqualsEventually(web, 3);
+ final Collection<Entity> webMembersAfterGrow = web.getMembers();
+
+ for (final Entity appserver : webMembersAfterGrow) {
+ Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TWO_MINUTES), new Runnable() {
+ @Override public void run() {
+ String appserverUrl = checkNotNull(appserver.getAttribute(JBoss7Server.ROOT_URL), "appserver url of "+appserver);
+ HttpTestUtils.assertHttpStatusCodeEquals(appserverUrl, 200);
+ assertEquals(expectedJdbcUrl, appserver.getConfig(JavaEntityMethods.javaSysProp("brooklyn.example.db.url")), "of "+appserver);
+ Asserts.assertEqualsIgnoringOrder(nginx.getAttribute(NginxController.SERVER_POOL_TARGETS).keySet(), webMembersAfterGrow);
+ }});
+ }
+
+ // expect enrichers to be there
+ Iterables.find(web.getEnrichers(), Predicates.instanceOf(HttpLatencyDetector.class));
+ Iterable<Enricher> propagatorEnrichers = Iterables.filter(web.getEnrichers(), Predicates.instanceOf(Propagator.class));
+ assertEquals(Iterables.size(propagatorEnrichers), 2, "propagatorEnrichers="+propagatorEnrichers);
+
+ // check we see evidence of the enrichers having an effect, and first triggering some activity
+ for (int i = 0; i < 10; i++) {
+ HttpTestUtils.assertHttpStatusCodeEquals(clusterUrl, 200);
+ }
+ EntityTestUtils.assertAttributeEqualsEventually(app, WebClusterDatabaseExampleApp.APPSERVERS_COUNT, 3);
+ assertAttributeChangesEventually(web, DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW);
+ assertAttributeChangesEventually(app, DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW);
+ assertAttributeChangesEventually(web, HttpLatencyDetector.REQUEST_LATENCY_IN_SECONDS_MOST_RECENT);
+ assertAttributeChangesEventually(web, HttpLatencyDetector.REQUEST_LATENCY_IN_SECONDS_IN_WINDOW);
+
+ // Restore the web-cluster to its original size of 2
+ autoScalerPolicy.setConfig(AutoScalerPolicy.MIN_POOL_SIZE, 2);
+ EntityTestUtils.assertGroupSizeEqualsEventually(web, 2);
+
+ final Entity removedAppserver = Iterables.getOnlyElement(Sets.difference(ImmutableSet.copyOf(webMembersAfterGrow), ImmutableSet.copyOf(web.getMembers())));
+ Asserts.succeedsEventually(new Runnable() {
+ @Override public void run() {
+ assertFalse(Entities.isManaged(removedAppserver));
+ }});
+ }
+
+ private void assertAttributeChangesEventually(final Entity entity, final AttributeSensor<?> attribute) {
+ final Object origValue = entity.getAttribute(attribute);
+ final AtomicBoolean changed = new AtomicBoolean();
+ SubscriptionHandle handle = ((EntityInternal)entity).subscribe(entity, attribute, new SensorEventListener<Object>() {
+ @Override public void onEvent(SensorEvent<Object> event) {
+ if (!Objects.equal(origValue, event.getValue())) {
+ changed.set(true);
+ }
+ }});
+ try {
+ Asserts.succeedsEventually(new Runnable() {
+ @Override public void run() {
+ assertTrue(changed.get(), entity+" -> "+attribute+" not changed");
+ }});
+ } finally {
+ ((EntityInternal)entity).unsubscribe(entity, handle);
+ }
+ }
+}