You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/08/06 18:33:48 UTC
[2/4] incubator-brooklyn git commit: Test lifecycle phases of
BasicStartable
Test lifecycle phases of BasicStartable
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/379d6a1d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/379d6a1d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/379d6a1d
Branch: refs/heads/master
Commit: 379d6a1d5908dd25cccaf82e853ff9d7693734ed
Parents: 614cbb2
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Thu Aug 6 16:01:36 2015 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Thu Aug 6 16:01:57 2015 +0100
----------------------------------------------------------------------
.../entity/basic/ServiceStateLogic.java | 7 +-
.../entity/basic/BasicStartableTest.java | 33 +++++-
.../basic/RecordingSensorEventListener.java | 115 +++++++++++++++++++
3 files changed, 148 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/379d6a1d/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
index eff8e2d..3b1efbe 100644
--- a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
+++ b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
@@ -149,8 +149,11 @@ public class ServiceStateLogic {
if (!Boolean.TRUE.equals(up) && !Boolean.TRUE.equals(Entities.isReadOnly(entity))) {
// pause briefly to allow any recent problem-clearing processing to complete
Stopwatch timer = Stopwatch.createStarted();
- boolean nowUp = Repeater.create().every(ValueResolver.REAL_QUICK_PERIOD).limitTimeTo(ValueResolver.PRETTY_QUICK_WAIT).until(entity,
- EntityPredicates.attributeEqualTo(Attributes.SERVICE_UP, true)).run();
+ boolean nowUp = Repeater.create()
+ .every(ValueResolver.REAL_QUICK_PERIOD)
+ .limitTimeTo(ValueResolver.PRETTY_QUICK_WAIT)
+ .until(entity, EntityPredicates.attributeEqualTo(Attributes.SERVICE_UP, true))
+ .run();
if (nowUp) {
log.debug("Had to wait "+Duration.of(timer)+" for "+entity+" "+Attributes.SERVICE_UP+" to be true before setting "+state);
} else {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/379d6a1d/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java b/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
index b7d47e5..2f8db0c 100644
--- a/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
@@ -21,13 +21,20 @@ package brooklyn.entity.basic;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
+import org.apache.brooklyn.entity.basic.RecordingSensorEventListener;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
import brooklyn.entity.Entity;
import brooklyn.entity.proxying.EntitySpec;
import brooklyn.location.Location;
@@ -40,11 +47,6 @@ import brooklyn.test.entity.TestApplication;
import brooklyn.test.entity.TestEntity;
import brooklyn.util.collections.MutableSet;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
public class BasicStartableTest {
private ManagementContext managementContext;
@@ -141,6 +143,27 @@ public class BasicStartableTest {
assertEqualsIgnoringOrder(entity.getLocations(), ImmutableSet.of());
assertNull(called.get());
}
+
+ @Test
+ public void testTransitionsThroughLifecycles() throws Exception {
+ startable = app.addChild(EntitySpec.create(BasicStartable.class));
+ RecordingSensorEventListener<Lifecycle> listener = new RecordingSensorEventListener<Lifecycle>(true);
+ managementContext.getSubscriptionContext(startable)
+ .subscribe(startable, Attributes.SERVICE_STATE_ACTUAL, listener);
+
+ Entities.startManagement(startable);
+ app.start(ImmutableList.of(loc1));
+ app.stop();
+
+ ArrayList<Lifecycle> expected = Lists.newArrayList(
+ Lifecycle.STARTING,
+ Lifecycle.RUNNING,
+ Lifecycle.STOPPING,
+ Lifecycle.STOPPED);
+ Iterable<Lifecycle> actual = listener.getEventValuesSortedByTimestamp();
+ assertEquals(actual, expected,
+ "Expected=" + Iterables.toString(expected) + ", actual=" + Iterables.toString(actual));
+ }
private void assertEqualsIgnoringOrder(Iterable<? extends Object> col1, Iterable<? extends Object> col2) {
assertEquals(Iterables.size(col1), Iterables.size(col2), "col2="+col1+"; col2="+col2);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/379d6a1d/core/src/test/java/org/apache/brooklyn/entity/basic/RecordingSensorEventListener.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/entity/basic/RecordingSensorEventListener.java b/core/src/test/java/org/apache/brooklyn/entity/basic/RecordingSensorEventListener.java
new file mode 100644
index 0000000..067b7d4
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/entity/basic/RecordingSensorEventListener.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.brooklyn.entity.basic;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.primitives.Longs;
+
+import brooklyn.event.SensorEvent;
+import brooklyn.event.SensorEventListener;
+
+/**
+ * An event listener that records each event and allows callers to access all values and
+ * all values sorted by event timestamp.
+ */
+public class RecordingSensorEventListener<T> implements SensorEventListener<T>, Iterable<SensorEvent<T>> {
+
+ private final List<SensorEvent<T>> events = Lists.newCopyOnWriteArrayList();
+ private final boolean suppressDuplicates;
+ private T lastValue;
+
+ public RecordingSensorEventListener() {
+ this(false);
+ }
+
+ public RecordingSensorEventListener(boolean suppressDuplicates) {
+ this.suppressDuplicates = suppressDuplicates;
+ }
+
+ @Override
+ public void onEvent(SensorEvent<T> event) {
+ if (!suppressDuplicates || events.isEmpty() || !Objects.equals(lastValue, event.getValue())) {
+ events.add(event);
+ lastValue = event.getValue();
+ }
+ }
+
+ /**
+ * @return An immutable iterable of the recorded events.
+ */
+ public Iterable<SensorEvent<T>> getEvents() {
+ return ImmutableList.copyOf(events);
+ }
+
+ /**
+ * @return A live read-only view of recorded events.
+ */
+ public Iterable<T> getEventValues() {
+ return FluentIterable.from(events)
+ .transform(new GetValueFunction<T>());
+ }
+
+ /**
+ * @return A static read-only view of event values sorted by the time at which they occurred.
+ */
+ public Iterable<T> getEventValuesSortedByTimestamp() {
+ List<SensorEvent<T>> copy = Lists.newArrayList(events);
+ Collections.sort(copy, new EventTimestampComparator());
+ return FluentIterable.from(copy)
+ .transform(new GetValueFunction<T>());
+ }
+
+ /**
+ * Clears all events recorded by the listener.
+ */
+ public void clearEvents() {
+ this.events.clear();
+ lastValue = null;
+ }
+
+ @Override
+ public Iterator<SensorEvent<T>> iterator() {
+ return getEvents().iterator();
+ }
+
+ private static class GetValueFunction<T> implements Function<SensorEvent<T>, T> {
+ @Override
+ public T apply(SensorEvent<T> input) {
+ return input.getValue();
+ }
+ }
+
+ private static class EventTimestampComparator implements Comparator<SensorEvent<?>> {
+ @Override
+ public int compare(SensorEvent<?> o1, SensorEvent<?> o2) {
+ return Longs.compare(o1.getTimestamp(), o2.getTimestamp());
+ }
+ }
+
+}