From 95530cc4b3801084f2c1771fb3067bf5d63d0da5 Mon Sep 17 00:00:00 2001 From: Zhangmei Li Date: Wed, 27 Feb 2019 21:48:21 +0800 Subject: [PATCH] add PerfUtil.clear()/Bytes.concat()/CollectionUtil.randomSet() also add some unit tests: HugeConfigTest, PerfUtilTest, NumericUtilTest, ReflectionUtilTest and TimeUtilTest. Change-Id: Ida64154a0bdee62e281585836c5e7ccfc6061c06 --- pom.xml | 9 +- .../baidu/hugegraph/config/HugeConfig.java | 45 ++-- .../com/baidu/hugegraph/perf/PerfUtil.java | 37 +-- .../baidu/hugegraph/testutil/Whitebox.java | 8 +- .../java/com/baidu/hugegraph/util/Bytes.java | 7 + .../baidu/hugegraph/util/CollectionUtil.java | 13 + .../com/baidu/hugegraph/util/NumericUtil.java | 9 +- .../baidu/hugegraph/util/ReflectionUtil.java | 18 +- .../hugegraph/version/CommonVersion.java | 2 +- .../baidu/hugegraph/testclass/TestClass.java | 53 ++++ .../baidu/hugegraph/unit/UnitTestSuite.java | 12 +- .../hugegraph/unit/config/HugeConfigTest.java | 232 ++++++++++++++++++ .../com/baidu/hugegraph/unit/config/test.conf | 16 ++ .../hugegraph/unit/perf/PerfUtilTest.java | 112 +++++++++ .../baidu/hugegraph/unit/util/BytesTest.java | 37 +-- .../unit/util/CollectionUtilTest.java | 23 ++ .../hugegraph/unit/util/NumericUtilTest.java | 109 ++++++++ .../unit/util/ReflectionUtilTest.java | 114 +++++++++ .../hugegraph/unit/util/TimeUtilTest.java | 63 +++++ 19 files changed, 849 insertions(+), 70 deletions(-) create mode 100644 src/test/java/com/baidu/hugegraph/testclass/TestClass.java create mode 100644 src/test/java/com/baidu/hugegraph/unit/config/HugeConfigTest.java create mode 100644 src/test/java/com/baidu/hugegraph/unit/config/test.conf create mode 100644 src/test/java/com/baidu/hugegraph/unit/perf/PerfUtilTest.java create mode 100644 src/test/java/com/baidu/hugegraph/unit/util/NumericUtilTest.java create mode 100644 src/test/java/com/baidu/hugegraph/unit/util/ReflectionUtilTest.java create mode 100644 src/test/java/com/baidu/hugegraph/unit/util/TimeUtilTest.java diff --git a/pom.xml b/pom.xml index aff3d224e..079239dd9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.baidu.hugegraph hugegraph-common - 1.5.7 + 1.5.8 hugegraph-common https://github.com/hugegraph/hugegraph-common @@ -60,8 +60,8 @@ 1.10 2.1.1 3.2.2 - 20030203.000550 - 20041127.091804 + 2.4 + 1.11 19.0 1.0 3.0.1 @@ -146,6 +146,7 @@ ${javassist.version} + org.glassfish.jersey.core jersey-client @@ -198,7 +199,7 @@ - 1.5.6.0 + 1.5.8.0 diff --git a/src/main/java/com/baidu/hugegraph/config/HugeConfig.java b/src/main/java/com/baidu/hugegraph/config/HugeConfig.java index d38902696..c61b8fd7e 100644 --- a/src/main/java/com/baidu/hugegraph/config/HugeConfig.java +++ b/src/main/java/com/baidu/hugegraph/config/HugeConfig.java @@ -60,30 +60,31 @@ public class HugeConfig extends PropertiesConfiguration { this(loadConfigFile(configFile)); } - private void reloadIfNeed(Configuration config) { - if (config instanceof AbstractFileConfiguration) { - AbstractFileConfiguration fileConfig = - (AbstractFileConfiguration) config; + private void reloadIfNeed(Configuration conf) { + if (!(conf instanceof AbstractFileConfiguration)) { + return; + } - File file = fileConfig.getFile(); - if (file != null) { - // May need to use the original file - this.setFile(file); - } + AbstractFileConfiguration fileConfig = (AbstractFileConfiguration) conf; - if (!fileConfig.isDelimiterParsingDisabled()) { - /* - * PropertiesConfiguration will parse the containing comma - * config options into list directly, but we want to do - * this work by ourselves, so reload it and parse into `String` - */ - fileConfig.setDelimiterParsingDisabled(true); - try { - fileConfig.refresh(); - } catch (ConfigurationException e) { - throw new ConfigException("Unable to load config file: %s", - e, file); - } + File file = fileConfig.getFile(); + if (file != null) { + // May need to use the original file + this.setFile(file); + } + + if (!fileConfig.isDelimiterParsingDisabled()) { + /* + * PropertiesConfiguration will parse the containing comma + * config options into list directly, but we want to do + * this work by ourselves, so reload it and parse into `String` + */ + fileConfig.setDelimiterParsingDisabled(true); + try { + fileConfig.refresh(); + } catch (ConfigurationException e) { + throw new ConfigException("Unable to load config file: %s", + e, file); } } } diff --git a/src/main/java/com/baidu/hugegraph/perf/PerfUtil.java b/src/main/java/com/baidu/hugegraph/perf/PerfUtil.java index 7335e984e..1cf22ae06 100644 --- a/src/main/java/com/baidu/hugegraph/perf/PerfUtil.java +++ b/src/main/java/com/baidu/hugegraph/perf/PerfUtil.java @@ -26,8 +26,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.security.InvalidParameterException; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -39,6 +39,7 @@ import java.util.stream.Stream; import org.slf4j.Logger; import com.baidu.hugegraph.func.TriFunction; +import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; import com.baidu.hugegraph.util.ReflectionUtil; import com.google.common.reflect.ClassPath.ClassInfo; @@ -52,10 +53,10 @@ import javassist.NotFoundException; public class PerfUtil { private static final Logger LOG = Log.logger(PerfUtil.class); - private static ThreadLocal instance = new ThreadLocal<>(); + private static final ThreadLocal INSTANCE = new ThreadLocal<>(); - private Map stopwatches; - private Stack callStack; + private final Map stopwatches; + private final Stack callStack; private PerfUtil() { this.stopwatches = new HashMap<>(); @@ -63,10 +64,10 @@ public class PerfUtil { } public static PerfUtil instance() { - PerfUtil p = instance.get(); + PerfUtil p = INSTANCE.get(); if (p == null) { p = new PerfUtil(); - instance.set(p); + INSTANCE.set(p); } return p; } @@ -89,6 +90,7 @@ public class PerfUtil { } public boolean end(String name) { + long time = now(); String current = this.callStack.pop(); assert current.endsWith(name); @@ -97,15 +99,21 @@ public class PerfUtil { if (item == null) { throw new InvalidParameterException(name); } - item.endTime(now()); + item.endTime(time); return true; } - public void profilePackage(String... packages) throws - NotFoundException, CannotCompileException, - ClassNotFoundException, IOException { - Set loadedClasses = new LinkedHashSet<>(); + public void clear() { + E.checkState(this.callStack.empty(), + "Can't be cleared when the call has not ended yet"); + this.stopwatches.clear(); + } + + public void profilePackage(String... packages) + throws NotFoundException, IOException, + ClassNotFoundException, CannotCompileException { + Set loadedClasses = new HashSet<>(); Iterator classes = ReflectionUtil.classes(packages); while (classes.hasNext()) { @@ -125,8 +133,9 @@ public class PerfUtil { } } - public void profileClass(String... classes) throws - NotFoundException, CannotCompileException, ClassNotFoundException { + public void profileClass(String... classes) + throws NotFoundException, CannotCompileException, + ClassNotFoundException { ClassPool classPool = ClassPool.getDefault(); for (String cls : classes) { @@ -145,7 +154,7 @@ public class PerfUtil { } private void profile(CtMethod ctMethod) - throws CannotCompileException, ClassNotFoundException { + throws CannotCompileException, ClassNotFoundException { final String START = "com.baidu.hugegraph.perf.PerfUtil.instance().start(\"%s\");"; final String END = diff --git a/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java b/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java index 1b90a5d01..f4436765a 100644 --- a/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java +++ b/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java @@ -26,12 +26,12 @@ public class Whitebox { public static void setInternalState(Object target, String fieldName, Object value) { try { - Field field = target.getClass().getDeclaredField(fieldName); - field.setAccessible(true); - field.set(target, value); + Field f = getFieldFromHierarchy(target.getClass(), fieldName); + f.setAccessible(true); + f.set(target, value); } catch (Exception e) { Assert.fail(String.format("Can't change value of '%s' against " + - "target '%s'", fieldName, target)); + "target '%s': %s", fieldName, target, e)); } } diff --git a/src/main/java/com/baidu/hugegraph/util/Bytes.java b/src/main/java/com/baidu/hugegraph/util/Bytes.java index 8a2a72ef0..795130b28 100644 --- a/src/main/java/com/baidu/hugegraph/util/Bytes.java +++ b/src/main/java/com/baidu/hugegraph/util/Bytes.java @@ -44,6 +44,13 @@ public final class Bytes { return CMP.compare(bytes1, bytes2); } + public static byte[] concat(byte[] bytes1, byte[] bytes2) { + byte[] result = new byte[bytes1.length + bytes2.length]; + System.arraycopy(bytes1, 0, result, 0, bytes1.length); + System.arraycopy(bytes2, 0, result, bytes1.length, bytes2.length); + return result; + } + public static boolean prefixWith(byte[] bytes, byte[] prefix) { if (bytes.length < prefix.length) { return false; diff --git a/src/main/java/com/baidu/hugegraph/util/CollectionUtil.java b/src/main/java/com/baidu/hugegraph/util/CollectionUtil.java index ca8ef5eb7..2a4c7ca63 100644 --- a/src/main/java/com/baidu/hugegraph/util/CollectionUtil.java +++ b/src/main/java/com/baidu/hugegraph/util/CollectionUtil.java @@ -29,6 +29,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; public final class CollectionUtil { @@ -68,6 +69,18 @@ public final class CollectionUtil { return true; } + public static Set randomSet(int min, int max, int count) { + E.checkArgument(max > min, "Invalid min/max: %s/%s", min, max); + E.checkArgument(0 < count && count <= max - min, + "Invalid count %s", count); + + Set randoms = new HashSet<>(); + while (randoms.size() < count) { + randoms.add(ThreadLocalRandom.current().nextInt(min, max)); + } + return randoms; + } + public static boolean allUnique(Collection collection) { return collection.stream().allMatch(new HashSet<>()::add); } diff --git a/src/main/java/com/baidu/hugegraph/util/NumericUtil.java b/src/main/java/com/baidu/hugegraph/util/NumericUtil.java index ee608d3e1..9ab7c74d0 100644 --- a/src/main/java/com/baidu/hugegraph/util/NumericUtil.java +++ b/src/main/java/com/baidu/hugegraph/util/NumericUtil.java @@ -90,7 +90,7 @@ public final class NumericUtil { * @return The sortable long value */ public static long sortableDoubleBits(long bits) { - return bits ^ (bits >> 63) & 0x7fffffffffffffffL; + return bits ^ ((bits >> 63) & 0x7fffffffffffffffL); } /** @@ -100,7 +100,12 @@ public final class NumericUtil { * @return The sortable int value */ public static int sortableFloatBits(int bits) { - return bits ^ (bits >> 31) & 0x7fffffff; + /* + * Convert to its inverse digits if negative else keep the origin + * NOTE: (bits >> 31) is 0x00000000 if bits >= 0 + * (bits >> 31) is 0xFFFFFFFF if bits < 0 + */ + return bits ^ ((bits >> 31) & 0x7fffffff); } public static long numberToSortableLong(Number number) { diff --git a/src/main/java/com/baidu/hugegraph/util/ReflectionUtil.java b/src/main/java/com/baidu/hugegraph/util/ReflectionUtil.java index e5aa3ec7b..7b0eca174 100644 --- a/src/main/java/com/baidu/hugegraph/util/ReflectionUtil.java +++ b/src/main/java/com/baidu/hugegraph/util/ReflectionUtil.java @@ -42,6 +42,7 @@ public final class ReflectionUtil { if (type.isPrimitive() || type.equals(String.class) || type.equals(Boolean.class) || + type.equals(Character.class) || NumericUtil.isNumber(type)) { return true; } @@ -49,9 +50,9 @@ public final class ReflectionUtil { } public static List getMethodsAnnotatedWith( - Class type, - Class annotation, - boolean withSuperClass) { + Class type, + Class annotation, + boolean withSuperClass) { final List methods = new LinkedList<>(); Class klass = type; do { @@ -66,9 +67,10 @@ public final class ReflectionUtil { } public static List getMethodsAnnotatedWith( - CtClass type, - Class annotation, - boolean withSuperClass) throws NotFoundException { + CtClass type, + Class annotation, + boolean withSuperClass) + throws NotFoundException { final List methods = new LinkedList<>(); CtClass klass = type; @@ -84,7 +86,7 @@ public final class ReflectionUtil { } public static Iterator classes(String... packages) - throws IOException { + throws IOException { ClassPath path = ClassPath.from(ReflectionUtil.class.getClassLoader()); ExtendableIterator results = new ExtendableIterator<>(); for (String p : packages) { @@ -94,7 +96,7 @@ public final class ReflectionUtil { } public static List superClasses(String clazz) - throws NotFoundException { + throws NotFoundException { CtClass klass = ClassPool.getDefault().get(clazz); klass = klass.getSuperclass(); diff --git a/src/main/java/com/baidu/hugegraph/version/CommonVersion.java b/src/main/java/com/baidu/hugegraph/version/CommonVersion.java index f3f1a0f49..b7bafdefa 100644 --- a/src/main/java/com/baidu/hugegraph/version/CommonVersion.java +++ b/src/main/java/com/baidu/hugegraph/version/CommonVersion.java @@ -27,5 +27,5 @@ public class CommonVersion { // The second parameter of Version.of() is for all-in-one JAR public static final Version VERSION = Version.of(CommonVersion.class, - "1.5.7"); + "1.5.8"); } diff --git a/src/test/java/com/baidu/hugegraph/testclass/TestClass.java b/src/test/java/com/baidu/hugegraph/testclass/TestClass.java new file mode 100644 index 000000000..0fe47a1b6 --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/testclass/TestClass.java @@ -0,0 +1,53 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * 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 com.baidu.hugegraph.testclass; + +import com.baidu.hugegraph.perf.PerfUtil.Watched; + +public class TestClass { + + public static class Foo { + + @Watched + public void foo() { + this.bar(); + } + + @Watched + public void bar() {} + } + + public static class Base { + + @Watched + public void func() {} + } + + public static class Sub extends Base { + + @Watched + public void func1() {} + + public void func2() {} + + @Watched + public void func3() {} + } +} diff --git a/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java b/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java index 2ea760eb7..c8f6e4cfb 100644 --- a/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java +++ b/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java @@ -22,24 +22,31 @@ package com.baidu.hugegraph.unit; import org.junit.runner.RunWith; import org.junit.runners.Suite; +import com.baidu.hugegraph.unit.config.HugeConfigTest; import com.baidu.hugegraph.unit.event.EventHubTest; import com.baidu.hugegraph.unit.iterator.ExtendableIteratorTest; import com.baidu.hugegraph.unit.iterator.FilterIteratorTest; import com.baidu.hugegraph.unit.iterator.FlatMapperFilterIteratorTest; import com.baidu.hugegraph.unit.iterator.FlatMapperIteratorTest; import com.baidu.hugegraph.unit.iterator.MapperIteratorTest; +import com.baidu.hugegraph.unit.perf.PerfUtilTest; import com.baidu.hugegraph.unit.util.BytesTest; import com.baidu.hugegraph.unit.util.CollectionUtilTest; import com.baidu.hugegraph.unit.util.HashUtilTest; import com.baidu.hugegraph.unit.util.InsertionOrderUtilTest; import com.baidu.hugegraph.unit.util.LongEncodingTest; +import com.baidu.hugegraph.unit.util.NumericUtilTest; +import com.baidu.hugegraph.unit.util.ReflectionUtilTest; +import com.baidu.hugegraph.unit.util.TimeUtilTest; import com.baidu.hugegraph.unit.util.VersionUtilTest; import com.baidu.hugegraph.unit.version.VersionTest; @RunWith(Suite.class) @Suite.SuiteClasses({ - VersionTest.class, + HugeConfigTest.class, EventHubTest.class, + PerfUtilTest.class, + VersionTest.class, ExtendableIteratorTest.class, FilterIteratorTest.class, @@ -51,6 +58,9 @@ import com.baidu.hugegraph.unit.version.VersionTest; CollectionUtilTest.class, HashUtilTest.class, InsertionOrderUtilTest.class, + NumericUtilTest.class, + ReflectionUtilTest.class, + TimeUtilTest.class, VersionUtilTest.class, LongEncodingTest.class }) diff --git a/src/test/java/com/baidu/hugegraph/unit/config/HugeConfigTest.java b/src/test/java/com/baidu/hugegraph/unit/config/HugeConfigTest.java new file mode 100644 index 000000000..6d5066a9d --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/unit/config/HugeConfigTest.java @@ -0,0 +1,232 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * 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 com.baidu.hugegraph.unit.config; + +import static com.baidu.hugegraph.config.OptionChecker.allowValues; +import static com.baidu.hugegraph.config.OptionChecker.disallowEmpty; +import static com.baidu.hugegraph.config.OptionChecker.nonNegativeInt; +import static com.baidu.hugegraph.config.OptionChecker.positiveInt; +import static com.baidu.hugegraph.config.OptionChecker.rangeDouble; +import static com.baidu.hugegraph.config.OptionChecker.rangeInt; + +import java.util.Arrays; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.baidu.hugegraph.config.ConfigListOption; +import com.baidu.hugegraph.config.ConfigOption; +import com.baidu.hugegraph.config.HugeConfig; +import com.baidu.hugegraph.config.OptionHolder; +import com.baidu.hugegraph.config.OptionSpace; +import com.baidu.hugegraph.testutil.Assert; +import com.baidu.hugegraph.testutil.Whitebox; +import com.baidu.hugegraph.unit.BaseUnitTest; +import com.google.common.collect.ImmutableMap; + +public class HugeConfigTest extends BaseUnitTest { + + private static final String CONF = + "src/test/java/com/baidu/hugegraph/unit/config/test.conf"; + + @BeforeClass + public static void init() { + OptionSpace.register("test", TestOptions.class.getName()); + } + + @Test + public void testHugeConfig() throws Exception { + Configuration conf = new PropertiesConfiguration(); + Whitebox.setInternalState(conf, "delimiterParsingDisabled", true); + + HugeConfig config = new HugeConfig(conf); + + Assert.assertEquals("text1-value", config.get(TestOptions.text1)); + Assert.assertEquals("text2-value", config.get(TestOptions.text2)); + Assert.assertEquals("CHOICE-1", config.get(TestOptions.text3)); + + Assert.assertEquals(1, (int) config.get(TestOptions.int1)); + Assert.assertEquals(10, (int) config.get(TestOptions.int2)); + Assert.assertEquals(10, (int) config.get(TestOptions.int3)); + + Assert.assertEquals(100L, (long) config.get(TestOptions.long1)); + + Assert.assertEquals(100.0f, config.get(TestOptions.float1), 0f); + Assert.assertEquals(100.0f, config.get(TestOptions.double1), 0d); + + Assert.assertEquals(true, config.get(TestOptions.bool)); + + Assert.assertEquals(Arrays.asList("list-value1", "list-value2"), + config.get(TestOptions.list)); + + Assert.assertEquals(ImmutableMap.of("key1", "value1", "key2", "value2"), + config.getMap(TestOptions.map)); + } + + @Test + public void testHugeConfigWithFile() throws Exception { + HugeConfig config = new HugeConfig(CONF); + + Assert.assertEquals("file-text1-value", config.get(TestOptions.text1)); + Assert.assertEquals("file-text2-value", config.get(TestOptions.text2)); + Assert.assertEquals("CHOICE-3", config.get(TestOptions.text3)); + + Assert.assertEquals(2, (int) config.get(TestOptions.int1)); + Assert.assertEquals(0, (int) config.get(TestOptions.int2)); + Assert.assertEquals(1, (int) config.get(TestOptions.int3)); + + Assert.assertEquals(99L, (long) config.get(TestOptions.long1)); + + Assert.assertEquals(66.0f, config.get(TestOptions.float1), 0f); + Assert.assertEquals(66.0f, config.get(TestOptions.double1), 0d); + + Assert.assertEquals(false, config.get(TestOptions.bool)); + + Assert.assertEquals(Arrays.asList("file-v1", "file-v2", "file-v3"), + config.get(TestOptions.list)); + + Assert.assertEquals(ImmutableMap.of("key1", "value1", "key3", "value3"), + config.getMap(TestOptions.map)); + } + + @Test + public void testHugeConfigWithConfiguration() throws Exception { + HugeConfig config = new HugeConfig(new PropertiesConfiguration(CONF)); + + Assert.assertEquals("file-text1-value", config.get(TestOptions.text1)); + Assert.assertEquals("file-text2-value", config.get(TestOptions.text2)); + Assert.assertEquals("CHOICE-3", config.get(TestOptions.text3)); + } + + public static final class TestOptions extends OptionHolder { + + private static volatile TestOptions instance; + + public static synchronized TestOptions instance() { + if (instance == null) { + instance = new TestOptions(); + instance.registerOptions(); + } + return instance; + } + + public static final ConfigOption text1 = + new ConfigOption<>( + "group1.text1", + "description of group1.text1", + disallowEmpty(), + "text1-value" + ); + + public static final ConfigOption text2 = + new ConfigOption<>( + "group1.text2", + "description of group1.text2", + disallowEmpty(), + "text2-value" + ); + + public static final ConfigOption text3 = + new ConfigOption<>( + "group1.text3", + "description of group1.text3", + allowValues("CHOICE-1", "CHOICE-2", "CHOICE-3"), + "CHOICE-1" + ); + + public static final ConfigOption int1 = + new ConfigOption<>( + "group1.int1", + "description of group1.int1", + rangeInt(1, 100), + 1 + ); + + public static final ConfigOption int2 = + new ConfigOption<>( + "group1.int2", + "description of group1.int2", + nonNegativeInt(), + 10 + ); + + public static final ConfigOption int3 = + new ConfigOption<>( + "group1.int3", + "description of group1.int3", + positiveInt(), + 10 + ); + + public static final ConfigOption long1 = + new ConfigOption<>( + "group1.long1", + "description of group1.long1", + rangeInt(1L, 100L), + 100L + ); + + public static final ConfigOption float1 = + new ConfigOption<>( + "group1.float1", + "description of group1.float1", + rangeDouble(1.0f, 100.0f), + 100.0f + ); + + public static final ConfigOption double1 = + new ConfigOption<>( + "group1.double1", + "description of group1.double1", + rangeDouble(1.0, 100.0), + 100.0 + ); + + public static final ConfigOption bool = + new ConfigOption<>( + "group1.bool", + "description of group1.bool", + disallowEmpty(), + true + ); + + public static final ConfigListOption list = + new ConfigListOption<>( + "group1.list", + false, + "description of group1.list", + disallowEmpty(), + String.class, + "list-value1", "list-value2" + ); + + public static final ConfigListOption map = + new ConfigListOption<>( + "group1.map", + false, + "description of group1.map", + disallowEmpty(), + String.class, + "key1:value1", "key2:value2" + ); + } +} diff --git a/src/test/java/com/baidu/hugegraph/unit/config/test.conf b/src/test/java/com/baidu/hugegraph/unit/config/test.conf new file mode 100644 index 000000000..bf31c70f6 --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/unit/config/test.conf @@ -0,0 +1,16 @@ +group1.text1=file-text1-value +group1.text2=file-text2-value +group1.text3=CHOICE-3 + +group1.int1=2 +group1.int2=0 +group1.int3=1 +group1.long1=99 + +group1.float1=66 +group1.double1=66 + +group1.bool=false + +group1.list=[file-v1, file-v2, file-v3] +group1.map=[key1:value1, key3:value3] diff --git a/src/test/java/com/baidu/hugegraph/unit/perf/PerfUtilTest.java b/src/test/java/com/baidu/hugegraph/unit/perf/PerfUtilTest.java new file mode 100644 index 000000000..f7a5c524a --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/unit/perf/PerfUtilTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * 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 com.baidu.hugegraph.unit.perf; + +import java.io.IOException; +import java.util.Map; + +import org.junit.After; +import org.junit.Test; + +import com.baidu.hugegraph.perf.PerfUtil; +import com.baidu.hugegraph.testclass.TestClass.Foo; +import com.baidu.hugegraph.testclass.TestClass.Sub; +import com.baidu.hugegraph.testutil.Assert; +import com.baidu.hugegraph.unit.BaseUnitTest; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class PerfUtilTest extends BaseUnitTest { + + private static final PerfUtil perf = PerfUtil.instance(); + + @After + public void teardown() { + perf.clear(); + } + + @Test + public void testPerfUtil() throws Exception { + /* + * TODO: call profilePackage("com.baidu.hugegraph.testclass") and + * remove class Foo. now exception "duplicate class definition" throws + * since JUnit loaded class TestClass before testPerfUtil() + */ + perf.profilePackage("com.baidu.hugegraph.testclass"); + perf.profileClass("com.baidu.hugegraph.testclass.TestClass$Foo"); + + Foo obj = new Foo(); + obj.foo(); + + perf.toString(); + perf.toECharts(); + String json = perf.toJson(); + + assertContains(json, "foo.times", 1); + assertContains(json, "foo/bar.times", 1); + + perf.clear(); + + obj.foo(); + obj.foo(); + + perf.toString(); + perf.toECharts(); + json = perf.toJson(); + + assertContains(json, "foo.times", 2); + assertContains(json, "foo/bar.times", 2); + } + + @Test + public void testPerfUtilWithProfileClass() throws Exception { + perf.profileClass("com.baidu.hugegraph.testclass.TestClass$Base"); + perf.profileClass("com.baidu.hugegraph.testclass.TestClass$Sub"); + + Sub obj = new Sub(); + obj.func(); + obj.func1(); + obj.func2(); + obj.func3(); + obj.func3(); + obj.func3(); + + String json = perf.toJson(); + assertContains(json, "func.times", 1); + assertContains(json, "func1.times", 1); + assertContains(json, "func3.times", 3); + } + + private static void assertContains(String json, String key, Object value) + throws JsonParseException, JsonMappingException, IOException { + ObjectMapper mapper = new ObjectMapper(); + Map map = mapper.readValue(json, Map.class); + String[] keys = key.split("\\."); + Object actual = null; + for (String k : keys) { + actual = map.get(k); + if (actual instanceof Map) { + map = (Map) actual; + } + } + Assert.assertEquals(value, actual); + } +} diff --git a/src/test/java/com/baidu/hugegraph/unit/util/BytesTest.java b/src/test/java/com/baidu/hugegraph/unit/util/BytesTest.java index 6e5a554e8..f09c5e1e0 100644 --- a/src/test/java/com/baidu/hugegraph/unit/util/BytesTest.java +++ b/src/test/java/com/baidu/hugegraph/unit/util/BytesTest.java @@ -30,8 +30,8 @@ public class BytesTest extends BaseUnitTest { @Test public void testBytesEquals() { - Assert.assertTrue(Bytes.equals("12345678".getBytes(), - "12345678".getBytes())); + Assert.assertTrue(Bytes.equals(b("12345678"), + b("12345678"))); Assert.assertTrue(Bytes.equals(new byte[]{1, 3, 5, 7}, new byte[]{1, 3, 5, 7})); @@ -43,10 +43,8 @@ public class BytesTest extends BaseUnitTest { @Test public void testBytesPrefixWith() { - Assert.assertTrue(Bytes.prefixWith("12345678".getBytes(), - "12345678".getBytes())); - Assert.assertTrue(Bytes.prefixWith("12345678".getBytes(), - "1234567".getBytes())); + Assert.assertTrue(Bytes.prefixWith(b("12345678"), b("12345678"))); + Assert.assertTrue(Bytes.prefixWith(b("12345678"), b("1234567"))); Assert.assertTrue(Bytes.prefixWith(new byte[]{1, 3, 5, 7}, new byte[]{1, 3, 5, 7})); @@ -65,12 +63,9 @@ public class BytesTest extends BaseUnitTest { @Test public void testBytesCompare() { - Assert.assertTrue(Bytes.compare("12345678".getBytes(), - "12345678".getBytes()) == 0); - Assert.assertTrue(Bytes.compare("12345678".getBytes(), - "1234567".getBytes()) > 0); - Assert.assertTrue(Bytes.compare("12345678".getBytes(), - "12345679".getBytes()) < 0); + Assert.assertTrue(Bytes.compare(b("12345678"), b("12345678")) == 0); + Assert.assertTrue(Bytes.compare(b("12345678"), b("1234567")) > 0); + Assert.assertTrue(Bytes.compare(b("12345678"), b("12345679")) < 0); Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7}, new byte[]{1, 3, 5, 7}) == 0); @@ -113,15 +108,29 @@ public class BytesTest extends BaseUnitTest { } @Test - public void testBytesTohex() { + public void testBytesConcat() { + Assert.assertArrayEquals(b("12345678"), + Bytes.concat(b("1234"), b("5678"))); + Assert.assertArrayEquals(b("12345678"), + Bytes.concat(b("12345678"), b(""))); + Assert.assertArrayEquals(b("12345678"), + Bytes.concat(b(""), b("12345678"))); + } + + @Test + public void testBytesToHex() { int value = 0x0103807f; byte[] bytes = NumericUtil.intToBytes(value); Assert.assertEquals("0103807f", Bytes.toHex(bytes)); } @Test - public void testBytesFromhex() { + public void testBytesFromHex() { Assert.assertEquals(0x0103807f, NumericUtil.bytesToInt(Bytes.fromHex("0103807f"))); } + + private static byte[] b(String string) { + return string.getBytes(); + } } diff --git a/src/test/java/com/baidu/hugegraph/unit/util/CollectionUtilTest.java b/src/test/java/com/baidu/hugegraph/unit/util/CollectionUtilTest.java index ec0e1b7e5..72ba0239d 100644 --- a/src/test/java/com/baidu/hugegraph/unit/util/CollectionUtilTest.java +++ b/src/test/java/com/baidu/hugegraph/unit/util/CollectionUtilTest.java @@ -73,6 +73,29 @@ public class CollectionUtilTest extends BaseUnitTest { Assert.assertFalse(CollectionUtil.prefixOf(list4, list)); } + @Test + public void testRandomSet() { + Set set = CollectionUtil.randomSet(0, 100, 10); + for (int i : set) { + Assert.assertTrue(0 <= i && i < 100); + } + + // invalid min + Assert.assertThrows(IllegalArgumentException.class, () -> { + CollectionUtil.randomSet(200, 100, 10); + }); + + // invalid count = 0 + Assert.assertThrows(IllegalArgumentException.class, () -> { + CollectionUtil.randomSet(1, 100, 0); + }); + + // invalid count > max - min + Assert.assertThrows(IllegalArgumentException.class, () -> { + CollectionUtil.randomSet(1, 100, 100); + }); + } + @Test public void testAllUnique() { List list = ImmutableList.of(); diff --git a/src/test/java/com/baidu/hugegraph/unit/util/NumericUtilTest.java b/src/test/java/com/baidu/hugegraph/unit/util/NumericUtilTest.java new file mode 100644 index 000000000..bd64f7935 --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/unit/util/NumericUtilTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * 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 com.baidu.hugegraph.unit.util; + +import java.math.BigDecimal; + +import org.junit.Test; + +import com.baidu.hugegraph.testutil.Assert; +import com.baidu.hugegraph.unit.BaseUnitTest; +import com.baidu.hugegraph.util.Bytes; +import com.baidu.hugegraph.util.NumericUtil; + +public class NumericUtilTest extends BaseUnitTest { + + @Test + public void testNumberToSortableBytes() { + // byte + byte[] bytes = NumericUtil.numberToSortableBytes((byte) 0x33); + assertEquals(new byte[]{0x33}, bytes); + + // short + bytes = NumericUtil.numberToSortableBytes((short) 0x11223344); + assertEquals(new byte[]{0, 0, 0x33, 0x44}, bytes); + + // int + bytes = NumericUtil.numberToSortableBytes(0x11223344); + assertEquals(new byte[]{0x11, 0x22, 0x33, 0x44}, bytes); + + // long + bytes = NumericUtil.numberToSortableBytes(0x1122334455L); + assertEquals(new byte[]{0, 0, 0, 0x11, 0x22, 0x33, 0x44, 0x55}, bytes); + + // float + bytes = NumericUtil.numberToSortableBytes(3.14f); + assertEquals(new byte[]{0x40, 0x48, (byte) 0xf5, (byte) 0xc3}, bytes); + + // double + bytes = NumericUtil.numberToSortableBytes(3.1415926d); + assertEquals(new byte[]{0x40, 0x09, 0x21, (byte) 0xfb, + 0x4d, 0x12, (byte) 0xd8, 0x4a}, bytes); + + // BigDecimal + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.numberToSortableBytes(new BigDecimal(123)); + }); + } + @Test + public void testSortableBytesToNumber() { + // byte + Number value = NumericUtil.sortableBytesToNumber(new byte[]{0x33}, + Byte.class); + Assert.assertEquals(value, (byte) 0x33); + + // short + value = NumericUtil.sortableBytesToNumber(new byte[]{0, 0, 0x33, 0x44}, + Short.class); + Assert.assertEquals((short) 0x3344, value); + + // int + value = NumericUtil.sortableBytesToNumber( + new byte[]{0x11, 0x22, 0x33, 0x44}, Integer.class); + Assert.assertEquals(0x11223344, value); + + // long + value = NumericUtil.sortableBytesToNumber( + new byte[]{0, 0, 0, 0x11, 0x22, 0x33, 0x44, 0x55}, Long.class); + Assert.assertEquals(0x1122334455L, value); + + // float + value = NumericUtil.sortableBytesToNumber( + new byte[]{0x40, 0x48, (byte) 0xf5, (byte) 0xc3}, Float.class); + Assert.assertEquals(3.14f, value); + + // double + value = NumericUtil.sortableBytesToNumber( + new byte[]{0x40, 0x09, 0x21, (byte) 0xfb, + 0x4d, 0x12, (byte) 0xd8, 0x4a}, + Double.class); + Assert.assertEquals(3.1415926d, value); + + // BigDecimal + Assert.assertThrows(IllegalArgumentException.class, () -> { + NumericUtil.sortableBytesToNumber(new byte[123], BigDecimal.class); + }); + } + + private static void assertEquals(byte[] bytes1, byte[] bytes2) { + Assert.assertTrue(Bytes.toHex(bytes1) + " != " + Bytes.toHex(bytes2), + Bytes.equals(bytes1, bytes2)); + } +} diff --git a/src/test/java/com/baidu/hugegraph/unit/util/ReflectionUtilTest.java b/src/test/java/com/baidu/hugegraph/unit/util/ReflectionUtilTest.java new file mode 100644 index 000000000..c619fdc08 --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/unit/util/ReflectionUtilTest.java @@ -0,0 +1,114 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * 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 com.baidu.hugegraph.unit.util; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.List; + +import org.apache.commons.collections.IteratorUtils; +import org.junit.Test; + +import com.baidu.hugegraph.perf.PerfUtil.Watched; +import com.baidu.hugegraph.testclass.TestClass.Base; +import com.baidu.hugegraph.testclass.TestClass.Sub; +import com.baidu.hugegraph.testutil.Assert; +import com.baidu.hugegraph.unit.BaseUnitTest; +import com.baidu.hugegraph.util.ReflectionUtil; +import com.google.common.reflect.ClassPath.ClassInfo; + +import javassist.NotFoundException; + +public class ReflectionUtilTest extends BaseUnitTest { + + @Test + public void testIsSimpleType() { + Assert.assertTrue(ReflectionUtil.isSimpleType(byte.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(char.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(short.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(int.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(long.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(float.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(double.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(boolean.class)); + + Assert.assertTrue(ReflectionUtil.isSimpleType(Byte.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Character.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Short.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Integer.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Long.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Float.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Double.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(Boolean.class)); + Assert.assertTrue(ReflectionUtil.isSimpleType(String.class)); + + Assert.assertFalse(ReflectionUtil.isSimpleType(Object.class)); + Assert.assertFalse(ReflectionUtil.isSimpleType(BaseUnitTest.class)); + } + + @Test + public void testGetMethodsAnnotatedWith() { + List methods; + + methods = ReflectionUtil.getMethodsAnnotatedWith(Sub.class, + Watched.class, + false); + methods.sort((m1, m2) -> m1.getName().compareTo(m2.getName())); + Assert.assertEquals(2, methods.size()); + Assert.assertEquals("func1", methods.get(0).getName()); + Assert.assertEquals("func3", methods.get(1).getName()); + + + methods = ReflectionUtil.getMethodsAnnotatedWith(Sub.class, + Watched.class, + true); + methods.sort((m1, m2) -> m1.getName().compareTo(m2.getName())); + Assert.assertEquals(3, methods.size()); + Assert.assertEquals("func", methods.get(0).getName()); + Assert.assertEquals("func1", methods.get(1).getName()); + Assert.assertEquals("func3", methods.get(2).getName()); + } + + @Test + public void testClasses() throws IOException { + @SuppressWarnings("unchecked") + List classes = IteratorUtils.toList(ReflectionUtil.classes( + "com.baidu.hugegraph.util")); + Assert.assertEquals(13, classes.size()); + classes.sort((c1, c2) -> c1.getName().compareTo(c2.getName())); + Assert.assertEquals("com.baidu.hugegraph.util.Bytes", + classes.get(0).getName()); + Assert.assertEquals("com.baidu.hugegraph.util.CheckSocket", + classes.get(1).getName()); + Assert.assertEquals("com.baidu.hugegraph.util.CollectionUtil", + classes.get(2).getName()); + Assert.assertEquals("com.baidu.hugegraph.util.VersionUtil", + classes.get(12).getName()); + } + + @Test + public void testSuperClasses() throws NotFoundException { + List classes = ReflectionUtil.superClasses(Sub.class.getName()); + Assert.assertEquals(2, classes.size()); + classes.sort((c1, c2) -> c1.compareTo(c2)); + Assert.assertEquals(Base.class.getName(), classes.get(0)); + Assert.assertEquals(Object.class.getName(), classes.get(1)); + } +} diff --git a/src/test/java/com/baidu/hugegraph/unit/util/TimeUtilTest.java b/src/test/java/com/baidu/hugegraph/unit/util/TimeUtilTest.java new file mode 100644 index 000000000..218e4dccd --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/unit/util/TimeUtilTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * 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 com.baidu.hugegraph.unit.util; + +import java.util.Date; + +import org.junit.Test; + +import com.baidu.hugegraph.testutil.Assert; +import com.baidu.hugegraph.unit.BaseUnitTest; +import com.baidu.hugegraph.util.TimeUtil; + +public class TimeUtilTest extends BaseUnitTest { + + @Test + public void testTimeGen() { + long time = TimeUtil.timeGen(); + long base = TimeUtil.BASE_TIME; + long difference = time - base - System.currentTimeMillis(); + Assert.assertTrue(difference < 1000); + } + + @Test + public void testTimeGenWithDate() { + @SuppressWarnings("deprecation") + Date date = new Date(2019 - 1900, 2, 28); + long time = TimeUtil.timeGen(date); + Assert.assertEquals(41904000000L, time); + } + + @Test + public void testTimeGenWithLong() { + long date = TimeUtil.BASE_TIME + 123L; + long time = TimeUtil.timeGen(date); + Assert.assertEquals(123L, time); + } + + @Test + public void testTillNextMillis() { + for (int i = 0; i < 100; i++) { + long lastTimestamp = TimeUtil.timeGen(); + long time = TimeUtil.tillNextMillis(lastTimestamp); + Assert.assertNotEquals(lastTimestamp, time); + } + } +}