/* * 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.util.core.task; import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import org.apache.brooklyn.api.mgmt.ExecutionContext; import org.apache.brooklyn.api.mgmt.Task; import org.apache.brooklyn.core.entity.EntityFunctions; import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; import org.apache.brooklyn.core.test.entity.TestApplication; import org.apache.brooklyn.core.test.entity.TestEntity; import org.apache.brooklyn.util.core.task.TaskInternal; import org.apache.brooklyn.util.core.task.Tasks; import org.apache.brooklyn.util.core.task.ValueResolver; import org.apache.brooklyn.util.guava.Functionals; import org.apache.brooklyn.util.repeat.Repeater; import org.apache.brooklyn.util.time.Duration; import org.testng.Assert; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.util.concurrent.Callables; public class TasksTest extends BrooklynAppUnitTestSupport { private ExecutionContext executionContext; @BeforeMethod(alwaysRun=true) @Override public void setUp() throws Exception { super.setUp(); executionContext = app.getExecutionContext(); } @Test public void testResolveNull() throws Exception { assertResolvesValue(null, String.class, null); } @Test public void testResolveValueCastsToType() throws Exception { assertResolvesValue(123, String.class, "123"); } @Test public void testResolvesAttributeWhenReady() throws Exception { app.sensors().set(TestApplication.MY_ATTRIBUTE, "myval"); assertResolvesValue(attributeWhenReady(app, TestApplication.MY_ATTRIBUTE), String.class, "myval"); } @Test public void testResolvesMapWithAttributeWhenReady() throws Exception { app.sensors().set(TestApplication.MY_ATTRIBUTE, "myval"); Map<?,?> orig = ImmutableMap.of("mykey", attributeWhenReady(app, TestApplication.MY_ATTRIBUTE)); Map<?,?> expected = ImmutableMap.of("mykey", "myval"); assertResolvesValue(orig, String.class, expected); } @Test public void testResolvesSetWithAttributeWhenReady() throws Exception { app.sensors().set(TestApplication.MY_ATTRIBUTE, "myval"); Set<?> orig = ImmutableSet.of(attributeWhenReady(app, TestApplication.MY_ATTRIBUTE)); Set<?> expected = ImmutableSet.of("myval"); assertResolvesValue(orig, String.class, expected); } @Test public void testResolvesMapOfMapsWithAttributeWhenReady() throws Exception { app.sensors().set(TestApplication.MY_ATTRIBUTE, "myval"); Map<?,?> orig = ImmutableMap.of("mykey", ImmutableMap.of("mysubkey", attributeWhenReady(app, TestApplication.MY_ATTRIBUTE))); Map<?,?> expected = ImmutableMap.of("mykey", ImmutableMap.of("mysubkey", "myval")); assertResolvesValue(orig, String.class, expected); } @SuppressWarnings("unchecked") @Test public void testResolvesIterableOfMapsWithAttributeWhenReady() throws Exception { app.sensors().set(TestApplication.MY_ATTRIBUTE, "myval"); // using Iterables.concat so that orig is of type FluentIterable rather than List etc Iterable<?> orig = Iterables.concat(ImmutableList.of(ImmutableMap.of("mykey", attributeWhenReady(app, TestApplication.MY_ATTRIBUTE)))); Iterable<Map<?,?>> expected = ImmutableList.<Map<?,?>>of(ImmutableMap.of("mykey", "myval")); assertResolvesValue(orig, String.class, expected); } private void assertResolvesValue(Object actual, Class<?> type, Object expected) throws Exception { Object result = Tasks.resolveValue(actual, type, executionContext); assertEquals(result, expected); } @Test public void testErrorsResolvingPropagatesOrSwallowedAllCorrectly() throws Exception { app.config().set(TestEntity.CONF_OBJECT, ValueResolverTest.newThrowTask(Duration.ZERO)); Task<Object> t = Tasks.builder().body(Functionals.callable(EntityFunctions.config(TestEntity.CONF_OBJECT), app)).build(); ValueResolver<Object> v = Tasks.resolving(t).as(Object.class).context(app.getExecutionContext()); ValueResolverTest.assertThrowsOnMaybe(v); ValueResolverTest.assertThrowsOnGet(v); v.swallowExceptions(); ValueResolverTest.assertMaybeIsAbsent(v); ValueResolverTest.assertThrowsOnGet(v); v.defaultValue("foo"); ValueResolverTest.assertMaybeIsAbsent(v); assertEquals(v.clone().get(), "foo"); assertResolvesValue(v, Object.class, "foo"); } @Test public void testRepeater() throws Exception { Task<?> t; t = Tasks.requiring(Repeater.create().until(Callables.returning(true)).every(Duration.millis(1))).build(); app.getExecutionContext().submit(t); t.get(Duration.TEN_SECONDS); t = Tasks.testing(Repeater.create().until(Callables.returning(true)).every(Duration.millis(1))).build(); app.getExecutionContext().submit(t); Assert.assertEquals(t.get(Duration.TEN_SECONDS), true); t = Tasks.requiring(Repeater.create().until(Callables.returning(false)).limitIterationsTo(2).every(Duration.millis(1))).build(); app.getExecutionContext().submit(t); try { t.get(Duration.TEN_SECONDS); Assert.fail("Should have failed"); } catch (Exception e) { // expected } t = Tasks.testing(Repeater.create().until(Callables.returning(false)).limitIterationsTo(2).every(Duration.millis(1))).build(); app.getExecutionContext().submit(t); Assert.assertEquals(t.get(Duration.TEN_SECONDS), false); } @Test public void testRepeaterDescription() throws Exception{ final String description = "task description"; Repeater repeater = Repeater.create(description) .repeat(Callables.returning(null)) .every(Duration.ONE_MILLISECOND) .limitIterationsTo(1) .until(new Callable<Boolean>() { @Override public Boolean call() { TaskInternal<?> current = (TaskInternal<?>)Tasks.current(); assertEquals(current.getBlockingDetails(), description); return true; } }); Task<Boolean> t = Tasks.testing(repeater).build(); app.getExecutionContext().submit(t); assertTrue(t.get(Duration.TEN_SECONDS)); } }