@Test public void testSubscribeToEntityWithAttributeWildcard() throws Exception { final CountDownLatch latch = new CountDownLatch(1); app.subscriptions().subscribe(entity, null, new SensorEventListener<Object>() { @Override public void onEvent(SensorEvent<Object> event) { latch.countDown(); }}); entity.setSequenceValue(1234); if (!latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) { fail("Timeout waiting for Event on TestEntity listener"); } }
@Test public void testSubscribeToEntityAttributeChange() throws Exception { final CountDownLatch latch = new CountDownLatch(1); app.subscriptions().subscribe(entity, TestEntity.SEQUENCE, new SensorEventListener<Object>() { @Override public void onEvent(SensorEvent<Object> event) { latch.countDown(); }}); entity.setSequenceValue(1234); if (!latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) { fail("Timeout waiting for Event on TestEntity listener"); } }
@Test public void testSubscribeToAttributeChangeWithEntityWildcard() throws Exception { final CountDownLatch latch = new CountDownLatch(1); app.subscriptions().subscribe(null, TestEntity.SEQUENCE, new SensorEventListener<Object>() { @Override public void onEvent(SensorEvent<Object> event) { latch.countDown(); }}); entity.setSequenceValue(1234); if (!latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) { fail("Timeout waiting for Event on TestEntity listener"); } }
@Test public void testEmitsFailureEventWhenRestarterFails() throws Exception { final FailingEntity e2 = app.createAndManageChild(EntitySpec.create(FailingEntity.class) .configure(FailingEntity.FAIL_ON_RESTART, true)); app.subscriptions().subscribe(e2, ServiceRestarter.ENTITY_RESTART_FAILED, eventListener); policy = e2.policies().add(PolicySpec.create(ServiceRestarter.class) .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, HASensors.ENTITY_FAILED)); e2.sensors().emit(HASensors.ENTITY_FAILED, new FailureDescriptor(e2, "simulate failure")); Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertEquals(Iterables.getOnlyElement(events).getSensor(), ServiceRestarter.ENTITY_RESTART_FAILED, "events="+events); assertEquals(Iterables.getOnlyElement(events).getSource(), e2, "events="+events); assertEquals(((FailureDescriptor)Iterables.getOnlyElement(events).getValue()).getComponent(), e2, "events="+events); }}); assertEquals(e2.getAttribute(Attributes.SERVICE_STATE_ACTUAL), Lifecycle.ON_FIRE); }
@Test(groups="Integration") // because takes a second public void testNotNotifiedDuplicateAddedLocations() throws Exception { final Location l = app.newSimulatedLocation(); final RecordingSensorEventListener<Object> addedEvents = new RecordingSensorEventListener<>(); final RecordingSensorEventListener<Object> removedEvents = new RecordingSensorEventListener<>(); app.subscriptions().subscribe(app, AbstractEntity.LOCATION_ADDED, addedEvents); app.subscriptions().subscribe(app, AbstractEntity.LOCATION_REMOVED, removedEvents); // Add first location app.addLocations(ImmutableList.of(l, l)); assertEventValuesEqualsEventually(addedEvents, ImmutableList.of(l)); assertEventValuesEquals(removedEvents, ImmutableList.of()); // Add second location app.addLocations(ImmutableList.of(l)); assertEventValuesEqualsContinually(addedEvents, ImmutableList.of(l)); assertEventValuesEquals(removedEvents, ImmutableList.of()); }
@BeforeMethod(alwaysRun=true) @Override public void setUp() throws Exception { super.setUp(); added = Lists.newCopyOnWriteArrayList(); removed = Lists.newCopyOnWriteArrayList(); app.subscriptions().subscribe(app, AbstractEntity.CHILD_ADDED, new SensorEventListener<Entity>() { @Override public void onEvent(SensorEvent<Entity> event) { added.add(event.getValue()); }}); app.subscriptions().subscribe(app, AbstractEntity.CHILD_REMOVED, new SensorEventListener<Entity>() { @Override public void onEvent(SensorEvent<Entity> event) { removed.add(event.getValue()); }}); }
@BeforeMethod(alwaysRun=true) @Override public void setUp() throws Exception { super.setUp(); entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).impl(TestEntityNoEnrichersImpl.class)); added = Lists.newCopyOnWriteArrayList(); removed = Lists.newCopyOnWriteArrayList(); app.subscriptions().subscribe(entity, AbstractEntity.POLICY_ADDED, new SensorEventListener<PolicyDescriptor>() { @Override public void onEvent(SensorEvent<PolicyDescriptor> event) { added.add(event.getValue()); }}); app.subscriptions().subscribe(entity, AbstractEntity.POLICY_REMOVED, new SensorEventListener<PolicyDescriptor>() { @Override public void onEvent(SensorEvent<PolicyDescriptor> event) { removed.add(event.getValue()); }}); }
@Test public void testContextEntityOnSubscriptionCallbackTask() { observedEntity.sensors().set(TestEntity.NAME, "myval"); entity.subscriptions().subscribe(ImmutableMap.of("notifyOfInitialValue", true), observedEntity, TestEntity.NAME, listener); // notify-of-initial-value should give us our entity assertListenerCalledOnceWithContextEntityEventually(listener, entity); listener.clearEvents(); // as should subsequent events observedEntity.sensors().set(TestEntity.NAME, "myval2"); assertListenerCalledOnceWithContextEntityEventually(listener, entity); listener.clearEvents(); // same for subscribing to children: context should be the subscriber entity.subscriptions().subscribeToChildren(observedEntity, TestEntity.SEQUENCE, listener); observedChildEntity.sensors().set(TestEntity.SEQUENCE, 123); assertListenerCalledOnceWithContextEntityEventually(listener, entity); }
@Test public void testUnsubscribeUsingHandleStopsEvents() { SubscriptionHandle handle1 = entity.subscriptions().subscribe(observedEntity, TestEntity.SEQUENCE, listener); SubscriptionHandle handle2 = entity.subscriptions().subscribe(observedEntity, TestEntity.NAME, listener); SubscriptionHandle handle3 = entity.subscriptions().subscribe(otherEntity, TestEntity.SEQUENCE, listener); entity.subscriptions().unsubscribe(observedEntity, handle2); observedEntity.sensors().set(TestEntity.SEQUENCE, 123); observedEntity.sensors().set(TestEntity.NAME, "myname"); otherEntity.sensors().set(TestEntity.SEQUENCE, 456); Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertEquals(listener.getEvents(), ImmutableList.of( new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, observedEntity, 123), new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, otherEntity, 456))); }}); }
@Test public void testDoesNotSetOnFireOnFailure() throws Exception { final FailingEntity e2 = app.createAndManageChild(EntitySpec.create(FailingEntity.class) .configure(FailingEntity.SET_SERVICE_DOWN_ON_FAILURE, false) .configure(FailingEntity.FAIL_ON_RESTART, true)); app.subscriptions().subscribe(e2, ServiceRestarter.ENTITY_RESTART_FAILED, eventListener); policy = e2.policies().add(PolicySpec.create(ServiceRestarter.class) .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, HASensors.ENTITY_FAILED) .configure(ServiceRestarter.SET_ON_FIRE_ON_FAILURE, false)); e2.sensors().emit(HASensors.ENTITY_FAILED, new FailureDescriptor(e2, "simulate failure")); Asserts.succeedsContinually(new Runnable() { @Override public void run() { assertNotEquals(e2.getAttribute(Attributes.SERVICE_STATE_ACTUAL), Lifecycle.ON_FIRE); }}); }
@Test public void testSubscriptionReceivesEventsInOrder() { final int NUM_EVENTS = 100; entity.subscriptions().subscribe(observedEntity, TestEntity.MY_NOTIF, listener); for (int i = 0; i < NUM_EVENTS; i++) { observedEntity.sensors().emit(TestEntity.MY_NOTIF, i); } Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertEquals(Iterables.size(listener.getEvents()), NUM_EVENTS); for (int i = 0; i < NUM_EVENTS; i++) { assertEquals(Iterables.get(listener.getEvents(), i).getValue(), i); } }}); }
@Test public void testPublishesIsBusySensor() { final List<Boolean> isBusyValues = new CopyOnWriteArrayList<>(); testEntity.subscriptions().subscribe(testEntity, IS_BUSY_SENSOR, new SensorEventListener<Boolean>() { @Override public void onEvent(SensorEvent<Boolean> event) { isBusyValues.add(event.getValue()); } }); addSetChangePolicy(true, false); testEntity.sensors().set(DEFAULT_SENSOR, ImmutableSet.of(1)); List<Boolean> expected = ImmutableList.of(false, true, false); Asserts.eventually(Suppliers.ofInstance(isBusyValues), Predicates.equalTo(expected)); }
@BeforeMethod(alwaysRun=true) @Override public void setUp() throws Exception{ super.setUp(); entity = (EntityInternal) app.createAndManageChild(EntitySpec.create(Entity.class, EmptyEntityForTesting.class)); listener = new RecordingSensorEventListener<>(); app.subscriptions().subscribe(entity, SENSOR_ADDED, listener); app.subscriptions().subscribe(entity, SENSOR_REMOVED, listener); }
@Test public void testSubscriptionReceivesInitialValueEvents() { observedEntity.sensors().set(TestEntity.SEQUENCE, 123); observedEntity.sensors().set(TestEntity.NAME, "myname"); entity.subscriptions().subscribe(ImmutableMap.of("notifyOfInitialValue", true), observedEntity, TestEntity.SEQUENCE, listener); entity.subscriptions().subscribe(ImmutableMap.of("notifyOfInitialValue", true), observedEntity, TestEntity.NAME, listener); Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertEquals(listener.getEvents(), ImmutableList.of( new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, observedEntity, 123), new BasicSensorEvent<String>(TestEntity.NAME, observedEntity, "myname"))); }}); }
protected void assertAttributeNotRepublished(Entity entity, AttributeSensor<String> sensor) { final List<SensorEvent<String>> events = Lists.newCopyOnWriteArrayList(); app.subscriptions().subscribe(entity, sensor, new SensorEventListener<String>() { @Override public void onEvent(SensorEvent<String> event) { events.add(event); }}); app.sensors().set(sensor, "myval"); assertSizeEventually(events, 1); assertSizeContinually(events, 1, Duration.millis(100)); }
@Test public void testSubscriptionForInitialValueWhenNotValid() { entity.subscriptions().subscribe(ImmutableMap.of("notifyOfInitialValue", true), observedEntity, TestEntity.MY_NOTIF, listener); entity.subscriptions().subscribe(ImmutableMap.of("notifyOfInitialValue", true), observedEntity, null, listener); entity.subscriptions().subscribe(ImmutableMap.of("notifyOfInitialValue", true), null, TestEntity.NAME, listener); entity.subscriptions().subscribe(ImmutableMap.of("notifyOfInitialValue", true), null, null, listener); }
@Test public void testSubscriptionNotReceivesInitialValueEventsByDefault() { observedEntity.sensors().set(TestEntity.SEQUENCE, 123); observedEntity.sensors().set(TestEntity.NAME, "myname"); entity.subscriptions().subscribe(observedEntity, TestEntity.SEQUENCE, listener); entity.subscriptions().subscribe(observedEntity, TestEntity.NAME, listener); Asserts.succeedsContinually(ImmutableMap.of("timeout", SHORT_WAIT_MS), new Runnable() { @Override public void run() { assertEquals(listener.getEvents(), ImmutableList.of()); }}); }
@Test public void testSubscriptionToAllReceivesEvents() { entity.subscriptions().subscribe(null, TestEntity.SEQUENCE, listener); observedEntity.sensors().set(TestEntity.SEQUENCE, 123); otherEntity.sensors().set(TestEntity.SEQUENCE, 456); Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertEquals(listener.getEvents(), ImmutableList.of( new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, observedEntity, 123), new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, otherEntity, 456))); }}); }
protected TestApplication newApp() { final TestApplication result = managementContext.getEntityManager().createEntity(EntitySpec.create(TestApplication.class)); weakApps.put(result, null); TestEntity entity = result.createAndManageChild(EntitySpec.create(TestEntity.class)); result.subscriptions().subscribe(entity, TestEntity.NAME, new SensorEventListener<String>() { @Override public void onEvent(SensorEvent<String> event) { result.sensors().set(TestApplication.MY_ATTRIBUTE, event.getValue()); }}); entity.sensors().set(TestEntity.NAME, "myname"); return result; }
@BeforeMethod(alwaysRun=true) @Override public void setUp() throws Exception{ super.setUp(); entity = (EntityInternal) app.createAndManageChild(EntitySpec.create(ConfigEntityForTesting.class) .parameters(ImmutableList.of(new BasicSpecParameter<>("spec config", true, SPEC_CONFIG)))); listener = new RecordingSensorEventListener<>(); app.subscriptions().subscribe(entity, AbstractEntity.CONFIG_KEY_ADDED, listener); app.subscriptions().subscribe(entity, AbstractEntity.CONFIG_KEY_REMOVED, listener); }