You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/08/18 17:04:01 UTC

[52/64] [abbrv] incubator-brooklyn git commit: BROOKLYN-162 - apply org.apache package prefix to utils-groovy

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/412a5a1a/utils/groovy/src/main/java/org/apache/brooklyn/util/internal/TimeExtras.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/main/java/org/apache/brooklyn/util/internal/TimeExtras.groovy b/utils/groovy/src/main/java/org/apache/brooklyn/util/internal/TimeExtras.groovy
new file mode 100644
index 0000000..58aca75
--- /dev/null
+++ b/utils/groovy/src/main/java/org/apache/brooklyn/util/internal/TimeExtras.groovy
@@ -0,0 +1,83 @@
+/*
+ * 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.internal
+
+import groovy.time.TimeDuration
+
+import java.util.concurrent.TimeUnit
+
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import org.apache.brooklyn.util.time.Time
+
+
+/**
+ * Classloading this class will cause multiply/add to be made available on TimeDuration.
+ * For example, I could write: 2*TimeUnit.MINUTES+5*TimeUnit.SECONDS.
+ * 
+ * That is why nothing seems to use this class, because the methods it defines are not 
+ * on this class!
+ * 
+ * @author alex
+ * 
+ * @deprecated since 0.6.0 - just use brooklyn.util.time.Duration, simpler and easier to configure, and avoids language problems
+ */
+@Deprecated
+class TimeExtras {
+    public static final Logger log = LoggerFactory.getLogger(TimeExtras.class);
+    
+    public static void init() {
+        Number.metaClass.multiply << { TimeUnit t -> new TimeDuration(t.toMillis(intValue())) }
+        Number.metaClass.multiply << { TimeDuration t -> t.multiply(doubleValue()) }
+        Integer.metaClass.multiply << { TimeUnit t -> new TimeDuration(t.toMillis(intValue())) }
+        
+        TimeDuration.metaClass.multiply << { Number n -> new TimeDuration( (int)(toMilliseconds()*n) ) }
+        TimeDuration.metaClass.constructor << { long millis ->
+            def shift = { int modulus -> int v=millis%modulus; millis/=modulus; v }
+            def l = [shift(1000), shift(60), shift(60), shift(24), (int)millis]
+            Collections.reverse(l)
+            l as TimeDuration
+        }
+    }
+    
+    static { init(); }
+    
+    /** creates a duration object
+     * <p>
+     * fix for irritating classloading/metaclass order 
+     * where an int may get constructed too early and not have the multiply syntax available
+     * (because grail is invoked?; if e.g. 5*SECONDS throws an error, try duration(5, SECONDS)  */ 
+    public static TimeDuration duration(int value, TimeUnit unit) {
+        return new TimeDuration(0, 0, 0, (int)unit.toMillis(value));
+    }
+    
+    public static final TimeDuration ONE_SECOND = duration(1, TimeUnit.SECONDS);
+    public static final TimeDuration FIVE_SECONDS = duration(5, TimeUnit.SECONDS);
+    public static final TimeDuration TEN_SECONDS = duration(10, TimeUnit.SECONDS);
+    public static final TimeDuration THIRTY_SECONDS = duration(30, TimeUnit.SECONDS);
+    public static final TimeDuration ONE_MINUTE = duration(1, TimeUnit.MINUTES);
+    public static final TimeDuration TWO_MINUTES = duration(2, TimeUnit.MINUTES);
+    public static final TimeDuration FIVE_MINUTES = duration(5, TimeUnit.MINUTES);
+
+    public static void sleep(TimeDuration duration) {
+        Time.sleep(duration.toMilliseconds());
+    }    
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/412a5a1a/utils/groovy/src/test/java/brooklyn/util/internal/LanguageUtilsTest.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/brooklyn/util/internal/LanguageUtilsTest.groovy b/utils/groovy/src/test/java/brooklyn/util/internal/LanguageUtilsTest.groovy
deleted file mode 100644
index 142e202..0000000
--- a/utils/groovy/src/test/java/brooklyn/util/internal/LanguageUtilsTest.groovy
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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 brooklyn.util.internal;
-
-import static org.testng.Assert.*
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.annotations.Test
-
-import brooklyn.util.internal.LanguageUtils.FieldVisitor
-
-
-/**
- * Test the operation of the {@link LanguageUtils} utilities.
- */
-public class LanguageUtilsTest {
-    private static final Logger log = LoggerFactory.getLogger(LanguageUtilsTest.class)
- 
-    @Test
-    public void testSetFieldsFromMap() {
-        A a = []
-        Map unused = LanguageUtils.setFieldsFromMap(a, [num:1,mun:2])
-        assertEquals(1, a.num);
-        assertEquals([mun:2], unused)
-    }
-    
-    @Test
-    public void testVisitingFieldsDeepNonLooping() {
-        BigUn b2 = new BigUn(name:"L'il Guy", num:10, dates:[ new Date() ])
-//        b2.dates = [ new Date() ] as Date[]
-        BigUn b1 = new BigUn(name:"Big Guy", num:40)
-        b1.child = b2;
-        b1.children += b2
-        b2.child = b1
-        
-        int sum = 0;
-        FieldVisitor numSummer = { parent, name, value -> if ("num"==name) sum+=value } as FieldVisitor
-        LanguageUtils.visitFields(b1, numSummer)
-        
-        assertEquals(50, sum) 
-    }
-    
-    private static class A {
-        int num;
-    }
-    
-    private static class BigUn {
-        String name;
-        int num;
-        BigUn child;
-        Set children = []
-        Date[] dates;
-    }
-
-    //test the default getter, and equals
-    static class TestingFieldA {
-        public int a = 6;
-        int getAt(A aa) { return aa.num * a; }
-        static A aa = [num:10];
-        int x = -1;
-    }
-    static class TestingFields extends TestingFieldA {
-        int b = 7;
-        int getB() { -7 }
-        public int c = 8;
-        int getD() { 9 }
-    }
-    @Test
-    public void testSomeGet() {
-        TestingFields tf = []
-        assertEquals( [6, -7, 7, 8, 9, 60],
-            ["a", "b", "@b", "c", "d", TestingFields.aa].collect {
-                LanguageUtils.DEFAULT_FIELD_GETTER.call(tf, it)
-            })
-    }
-    
-    @Test
-    public void testEquals() {
-        //basic
-        TestingFields t1 = [], t2 = []
-        assertTrue LanguageUtils.equals(t1, t2, null, ["a", "b"])
-        assertTrue LanguageUtils.equals(t1, t2, TestingFields, ["a", "b"])
-        assertFalse LanguageUtils.equals(t1, t2, String, ["a", "b"])
-        assertFalse LanguageUtils.equals(t1, t2, null, ["z"])
-        assertTrue LanguageUtils.equals(t1, t2, null, (["a", "b"] as String[]))
-        
-        //type hierarchy
-        TestingFieldA t1a = []
-        assertTrue LanguageUtils.equals(t1, t1a, null, "a")
-        assertTrue LanguageUtils.equals(t1, t1a, TestingFieldA, "a")
-        assertFalse LanguageUtils.equals(t1, t1a, TestingFields, "a")
-        assertFalse LanguageUtils.equals(t1, t1a, null, "a", "b")
-        t1.b = 0
-        assertTrue LanguageUtils.equals(t1, t1a, null, "a")
-        t1a.a = -6
-        assertFalse LanguageUtils.equals(t1, t1a, null, "a")
-        
-        //direct access to field
-        assertTrue LanguageUtils.equals(t1, t2, null, "b")
-        assertFalse LanguageUtils.equals(t1, t2, null, "@b")
-        assertTrue LanguageUtils.equals(t1, t2, null, "@a")
-        
-        //and complex field
-        assertTrue LanguageUtils.equals(t1, t2, null, TestingFields.aa)
-        //because we changed t1a.a, and getAt(A) refers to int a
-        assertFalse LanguageUtils.equals(t1, t1a, null, TestingFields.aa)
-        
-        //test it works with POJO objects (non-groovy)
-        assertTrue LanguageUtils.equals(new PojoTestingFields(1), new PojoTestingFields(1), null, "privateInt")
-        assertFalse LanguageUtils.equals(new PojoTestingFields(1), new PojoTestingFields(2), null, "privateInt")
-        
-        //and a tricky one, because x is a groovy property, it is _private_ so we cannot see it as a field wrt t1
-        assertFalse LanguageUtils.equals(t1, t1a, null, "@x")
-        //but in the context of t1a we can.. in short, be careful with fields
-        assertTrue LanguageUtils.equals(t1a, t1a, null, "@x")
-    }
-
-    @Test
-    public void testHashCode() {
-        //basic
-        TestingFields t1 = [], t2 = []
-        assertTrue LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "b"])
-        assertTrue LanguageUtils.hashCode(t1, ["a", "@b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
-        assertFalse LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
-        t2.b = 0;
-        assertTrue LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "b"])
-        assertTrue LanguageUtils.hashCode(t1, ["a", "@b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
-        assertEquals 0, LanguageUtils.hashCode(null, ["a", "@b"])
-    }
-    
-    @Test
-    public void testToString() {
-        TestingFields t1 = [];
-        assertEquals(LanguageUtils.toString(t1, ["a", "b"]), "TestingFields[a=6,b=-7]");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/412a5a1a/utils/groovy/src/test/java/brooklyn/util/internal/PojoTestingFields.java
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/brooklyn/util/internal/PojoTestingFields.java b/utils/groovy/src/test/java/brooklyn/util/internal/PojoTestingFields.java
deleted file mode 100644
index c37a9b0..0000000
--- a/utils/groovy/src/test/java/brooklyn/util/internal/PojoTestingFields.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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 brooklyn.util.internal;
-
-public class PojoTestingFields {
-    private final int privateInt;
-    
-    public PojoTestingFields(int privateInt) {
-        this.privateInt = privateInt;
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/412a5a1a/utils/groovy/src/test/java/brooklyn/util/internal/TimeExtrasTest.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/brooklyn/util/internal/TimeExtrasTest.groovy b/utils/groovy/src/test/java/brooklyn/util/internal/TimeExtrasTest.groovy
deleted file mode 100644
index ca12c5e..0000000
--- a/utils/groovy/src/test/java/brooklyn/util/internal/TimeExtrasTest.groovy
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 brooklyn.util.internal;
-
-import static java.util.concurrent.TimeUnit.*
-import static org.testng.Assert.*
-
-import groovy.time.TimeDuration
-
-import org.testng.annotations.BeforeMethod
-import org.testng.annotations.Test
-
-/**
- * Test the operation of the {@link TimeExtras} class.
- * 
- * TODO clarify test purpose
- */
-public class TimeExtrasTest {
-    @BeforeMethod
-    public void setUp() throws Exception {
-        TimeExtras.init();
-    }
-
-    @Test
-    public void testMultiplyTimeDurations() {
-        assertEquals(new TimeDuration(6).toMilliseconds(), (new TimeDuration(3)*2).toMilliseconds());
-    }
-
-    @Test
-    public void testAddTimeDurations() {
-        assertEquals(new TimeDuration(0,2,5,0).toMilliseconds(), (5*SECONDS + 2*MINUTES).toMilliseconds());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/412a5a1a/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/LanguageUtilsTest.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/LanguageUtilsTest.groovy b/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/LanguageUtilsTest.groovy
new file mode 100644
index 0000000..18952d5
--- /dev/null
+++ b/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/LanguageUtilsTest.groovy
@@ -0,0 +1,154 @@
+/*
+ * 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.internal;
+
+import static org.testng.Assert.*
+
+import org.apache.brooklyn.util.internal.LanguageUtils;
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.testng.annotations.Test
+
+import org.apache.brooklyn.util.internal.LanguageUtils.FieldVisitor
+
+
+/**
+ * Test the operation of the {@link LanguageUtils} utilities.
+ */
+public class LanguageUtilsTest {
+    private static final Logger log = LoggerFactory.getLogger(LanguageUtilsTest.class)
+ 
+    @Test
+    public void testSetFieldsFromMap() {
+        A a = []
+        Map unused = LanguageUtils.setFieldsFromMap(a, [num:1,mun:2])
+        assertEquals(1, a.num);
+        assertEquals([mun:2], unused)
+    }
+    
+    @Test
+    public void testVisitingFieldsDeepNonLooping() {
+        BigUn b2 = new BigUn(name:"L'il Guy", num:10, dates:[ new Date() ])
+//        b2.dates = [ new Date() ] as Date[]
+        BigUn b1 = new BigUn(name:"Big Guy", num:40)
+        b1.child = b2;
+        b1.children += b2
+        b2.child = b1
+        
+        int sum = 0;
+        FieldVisitor numSummer = { parent, name, value -> if ("num"==name) sum+=value } as FieldVisitor
+        LanguageUtils.visitFields(b1, numSummer)
+        
+        assertEquals(50, sum) 
+    }
+    
+    private static class A {
+        int num;
+    }
+    
+    private static class BigUn {
+        String name;
+        int num;
+        BigUn child;
+        Set children = []
+        Date[] dates;
+    }
+
+    //test the default getter, and equals
+    static class TestingFieldA {
+        public int a = 6;
+        int getAt(A aa) { return aa.num * a; }
+        static A aa = [num:10];
+        int x = -1;
+    }
+    static class TestingFields extends TestingFieldA {
+        int b = 7;
+        int getB() { -7 }
+        public int c = 8;
+        int getD() { 9 }
+    }
+    @Test
+    public void testSomeGet() {
+        TestingFields tf = []
+        assertEquals( [6, -7, 7, 8, 9, 60],
+            ["a", "b", "@b", "c", "d", TestingFields.aa].collect {
+                LanguageUtils.DEFAULT_FIELD_GETTER.call(tf, it)
+            })
+    }
+    
+    @Test
+    public void testEquals() {
+        //basic
+        TestingFields t1 = [], t2 = []
+        assertTrue LanguageUtils.equals(t1, t2, null, ["a", "b"])
+        assertTrue LanguageUtils.equals(t1, t2, TestingFields, ["a", "b"])
+        assertFalse LanguageUtils.equals(t1, t2, String, ["a", "b"])
+        assertFalse LanguageUtils.equals(t1, t2, null, ["z"])
+        assertTrue LanguageUtils.equals(t1, t2, null, (["a", "b"] as String[]))
+        
+        //type hierarchy
+        TestingFieldA t1a = []
+        assertTrue LanguageUtils.equals(t1, t1a, null, "a")
+        assertTrue LanguageUtils.equals(t1, t1a, TestingFieldA, "a")
+        assertFalse LanguageUtils.equals(t1, t1a, TestingFields, "a")
+        assertFalse LanguageUtils.equals(t1, t1a, null, "a", "b")
+        t1.b = 0
+        assertTrue LanguageUtils.equals(t1, t1a, null, "a")
+        t1a.a = -6
+        assertFalse LanguageUtils.equals(t1, t1a, null, "a")
+        
+        //direct access to field
+        assertTrue LanguageUtils.equals(t1, t2, null, "b")
+        assertFalse LanguageUtils.equals(t1, t2, null, "@b")
+        assertTrue LanguageUtils.equals(t1, t2, null, "@a")
+        
+        //and complex field
+        assertTrue LanguageUtils.equals(t1, t2, null, TestingFields.aa)
+        //because we changed t1a.a, and getAt(A) refers to int a
+        assertFalse LanguageUtils.equals(t1, t1a, null, TestingFields.aa)
+        
+        //test it works with POJO objects (non-groovy)
+        assertTrue LanguageUtils.equals(new PojoTestingFields(1), new PojoTestingFields(1), null, "privateInt")
+        assertFalse LanguageUtils.equals(new PojoTestingFields(1), new PojoTestingFields(2), null, "privateInt")
+        
+        //and a tricky one, because x is a groovy property, it is _private_ so we cannot see it as a field wrt t1
+        assertFalse LanguageUtils.equals(t1, t1a, null, "@x")
+        //but in the context of t1a we can.. in short, be careful with fields
+        assertTrue LanguageUtils.equals(t1a, t1a, null, "@x")
+    }
+
+    @Test
+    public void testHashCode() {
+        //basic
+        TestingFields t1 = [], t2 = []
+        assertTrue LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "b"])
+        assertTrue LanguageUtils.hashCode(t1, ["a", "@b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
+        assertFalse LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
+        t2.b = 0;
+        assertTrue LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "b"])
+        assertTrue LanguageUtils.hashCode(t1, ["a", "@b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
+        assertEquals 0, LanguageUtils.hashCode(null, ["a", "@b"])
+    }
+    
+    @Test
+    public void testToString() {
+        TestingFields t1 = [];
+        assertEquals(LanguageUtils.toString(t1, ["a", "b"]), "TestingFields[a=6,b=-7]");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/412a5a1a/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/PojoTestingFields.java
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/PojoTestingFields.java b/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/PojoTestingFields.java
new file mode 100644
index 0000000..4048300
--- /dev/null
+++ b/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/PojoTestingFields.java
@@ -0,0 +1,28 @@
+/*
+ * 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.internal;
+
+public class PojoTestingFields {
+    private final int privateInt;
+    
+    public PojoTestingFields(int privateInt) {
+        this.privateInt = privateInt;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/412a5a1a/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/TimeExtrasTest.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/TimeExtrasTest.groovy b/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/TimeExtrasTest.groovy
new file mode 100644
index 0000000..7165a58
--- /dev/null
+++ b/utils/groovy/src/test/java/org/apache/brooklyn/util/internal/TimeExtrasTest.groovy
@@ -0,0 +1,49 @@
+/*
+ * 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.internal;
+
+import static java.util.concurrent.TimeUnit.*
+import static org.testng.Assert.*
+import groovy.time.TimeDuration
+
+import org.apache.brooklyn.util.internal.TimeExtras;
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+
+/**
+ * Test the operation of the {@link TimeExtras} class.
+ * 
+ * TODO clarify test purpose
+ */
+public class TimeExtrasTest {
+    @BeforeMethod
+    public void setUp() throws Exception {
+        TimeExtras.init();
+    }
+
+    @Test
+    public void testMultiplyTimeDurations() {
+        assertEquals(new TimeDuration(6).toMilliseconds(), (new TimeDuration(3)*2).toMilliseconds());
+    }
+
+    @Test
+    public void testAddTimeDurations() {
+        assertEquals(new TimeDuration(0,2,5,0).toMilliseconds(), (5*SECONDS + 2*MINUTES).toMilliseconds());
+    }
+}