From 9b8d633048186d9ef7741e78dd205db7e6089bda Mon Sep 17 00:00:00 2001 From: LinShunKang Date: Fri, 19 Oct 2018 00:30:34 +0800 Subject: [PATCH] add test cases --- MyPerf4J-ASM/pom.xml | 6 + .../java/cn/myperf4j/asm/ASMBootstrap.java | 2 +- .../myperf4j/asm/ASMRecorderMaintainer.java | 4 +- .../cn/myperf4j/asm/aop/ProfilingAspect.java | 2 +- .../asm/aop/ProfilingMethodVisitor.java | 2 +- .../cn/myperf4j/asm/utils/TypeDescUtils.java | 11 -- .../test/java/MyPerf4J/ClassFileUtils.java | 110 ++++++++++++++++++ .../src/test/java/MyPerf4J/ClassToTest.java | 17 +++ .../src/test/java/MyPerf4J/PreMainTest.java | 71 +++++++++++ .../test/java/MyPerf4J/TypeDestUtilsTest.java | 25 ++++ .../src/test/java/MyPerf4J/test2/Test2.java | 4 + MyPerf4J-Base/pom.xml | 8 ++ .../myperf4j/base/util/DateFormatUtils.java | 1 + .../cn/myperf4j/base/util/NumFormatUtils.java | 7 -- .../cn/myperf4j/base/util/ThreadUtils.java | 8 ++ .../cn/myperf4j/base/test/ChunkPoolTest.java | 38 ++++++ .../base/test/DailyRollingFileWriterTest.java | 16 --- .../base/test/DateFormatUtilsTest.java | 22 ++++ .../cn/myperf4j/base/test/ILoggerTest.java | 27 +++++ .../base/test/LineProtocolUtilsTest.java | 17 +++ .../cn/myperf4j/base/test/LoggerTest.java | 20 ++++ .../cn/myperf4j/base/test/MapUtilsTest.java | 26 +++++ .../base/test/NumFormatUtilsTest.java | 24 ++++ .../base/test/RollingFileWriterTest.java | 34 ++++++ MyPerf4J-Core/pom.xml | 1 - .../cn/myperf4j/core/AbstractBootstrap.java | 1 + ...ator.java => MethodMetricsCalculator.java} | 5 +- .../cn/myperf4j/core/MethodTagMaintainer.java | 2 +- .../AbstractRecorderMaintainer.java | 6 +- .../core/{ => recorder}/AccurateRecorder.java | 2 +- .../core/{ => recorder}/Recorder.java | 2 +- .../core/{ => recorder}/Recorders.java | 2 +- .../core/{ => recorder}/RoughRecorder.java | 2 +- .../test/java/MyPerf4J/MethodMetricsTest.java | 57 +++++++++ .../java/MyPerf4J/RecorderBenchmarkTest.java | 18 +-- pom.xml | 7 ++ 36 files changed, 549 insertions(+), 58 deletions(-) create mode 100644 MyPerf4J-ASM/src/test/java/MyPerf4J/ClassFileUtils.java create mode 100644 MyPerf4J-ASM/src/test/java/MyPerf4J/ClassToTest.java create mode 100644 MyPerf4J-ASM/src/test/java/MyPerf4J/PreMainTest.java create mode 100644 MyPerf4J-ASM/src/test/java/MyPerf4J/TypeDestUtilsTest.java create mode 100644 MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/ChunkPoolTest.java delete mode 100644 MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/DailyRollingFileWriterTest.java create mode 100644 MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/DateFormatUtilsTest.java create mode 100644 MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/LineProtocolUtilsTest.java create mode 100644 MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/LoggerTest.java create mode 100644 MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/MapUtilsTest.java create mode 100644 MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/NumFormatUtilsTest.java create mode 100644 MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/RollingFileWriterTest.java rename MyPerf4J-Core/src/main/java/cn/myperf4j/core/{PerfStatsCalculator.java => MethodMetricsCalculator.java} (95%) rename MyPerf4J-Core/src/main/java/cn/myperf4j/core/{ => recorder}/AbstractRecorderMaintainer.java (95%) rename MyPerf4J-Core/src/main/java/cn/myperf4j/core/{ => recorder}/AccurateRecorder.java (99%) rename MyPerf4J-Core/src/main/java/cn/myperf4j/core/{ => recorder}/Recorder.java (96%) rename MyPerf4J-Core/src/main/java/cn/myperf4j/core/{ => recorder}/Recorders.java (98%) rename MyPerf4J-Core/src/main/java/cn/myperf4j/core/{ => recorder}/RoughRecorder.java (98%) create mode 100644 MyPerf4J-Core/src/test/java/MyPerf4J/MethodMetricsTest.java diff --git a/MyPerf4J-ASM/pom.xml b/MyPerf4J-ASM/pom.xml index a7e2d808..b9cebfda 100644 --- a/MyPerf4J-ASM/pom.xml +++ b/MyPerf4J-ASM/pom.xml @@ -30,6 +30,12 @@ MyPerf4J-Core ${project.version} + + + junit + junit + test + diff --git a/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/ASMBootstrap.java b/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/ASMBootstrap.java index bd5e43c1..c4c294aa 100644 --- a/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/ASMBootstrap.java +++ b/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/ASMBootstrap.java @@ -2,7 +2,7 @@ import cn.myperf4j.asm.aop.ProfilingAspect; import cn.myperf4j.core.AbstractBootstrap; -import cn.myperf4j.core.AbstractRecorderMaintainer; +import cn.myperf4j.core.recorder.AbstractRecorderMaintainer; import cn.myperf4j.base.config.ProfilingConfig; import cn.myperf4j.base.util.Logger; diff --git a/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/ASMRecorderMaintainer.java b/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/ASMRecorderMaintainer.java index de135094..ac6380a3 100644 --- a/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/ASMRecorderMaintainer.java +++ b/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/ASMRecorderMaintainer.java @@ -1,7 +1,7 @@ package cn.myperf4j.asm; -import cn.myperf4j.core.AbstractRecorderMaintainer; -import cn.myperf4j.core.Recorders; +import cn.myperf4j.core.recorder.AbstractRecorderMaintainer; +import cn.myperf4j.core.recorder.Recorders; import cn.myperf4j.base.config.ProfilingParams; /** diff --git a/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/aop/ProfilingAspect.java b/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/aop/ProfilingAspect.java index 1d1b56b9..7a803469 100644 --- a/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/aop/ProfilingAspect.java +++ b/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/aop/ProfilingAspect.java @@ -2,7 +2,7 @@ import cn.myperf4j.asm.ASMRecorderMaintainer; import cn.myperf4j.core.MethodTagMaintainer; -import cn.myperf4j.core.Recorder; +import cn.myperf4j.core.recorder.Recorder; import cn.myperf4j.base.util.Logger; /** diff --git a/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/aop/ProfilingMethodVisitor.java b/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/aop/ProfilingMethodVisitor.java index 15b53602..3c32658b 100644 --- a/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/aop/ProfilingMethodVisitor.java +++ b/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/aop/ProfilingMethodVisitor.java @@ -3,7 +3,7 @@ import cn.myperf4j.asm.ASMRecorderMaintainer; import cn.myperf4j.asm.utils.TypeDescUtils; import cn.myperf4j.base.MethodTag; -import cn.myperf4j.core.AbstractRecorderMaintainer; +import cn.myperf4j.core.recorder.AbstractRecorderMaintainer; import cn.myperf4j.core.MethodTagMaintainer; import cn.myperf4j.base.config.ProfilingConfig; import org.objectweb.asm.MethodVisitor; diff --git a/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/utils/TypeDescUtils.java b/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/utils/TypeDescUtils.java index 2abbf91c..40140d59 100644 --- a/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/utils/TypeDescUtils.java +++ b/MyPerf4J-ASM/src/main/java/cn/myperf4j/asm/utils/TypeDescUtils.java @@ -120,15 +120,4 @@ private static void appendArrDesc(StringBuilder sb, int arrayLevel) { } } - public static void main(String[] args) { - System.out.println(getMethodParamsDesc("()V")); - System.out.println(getMethodParamsDesc("(IF)V")); - System.out.println(getMethodParamsDesc("(Ljava/lang/Object;)I")); - System.out.println(getMethodParamsDesc("(ILjava/lang/String;)[I")); - System.out.println(getMethodParamsDesc("(ILjava/lang/Map;)[I")); - System.out.println(getMethodParamsDesc("([I)Ljava/lang/Object;")); - System.out.println(getMethodParamsDesc("([ILjava/lang/Object;[Ljava/lang/Object;[Ljava/lang/String;)Ljava/lang/Object;")); - System.out.println(getMethodParamsDesc("([[ILjava/lang/Object;[[[Ljava/lang/Object;[[[[[Ljava/lang/String;)Ljava/lang/Object;")); - } - } diff --git a/MyPerf4J-ASM/src/test/java/MyPerf4J/ClassFileUtils.java b/MyPerf4J-ASM/src/test/java/MyPerf4J/ClassFileUtils.java new file mode 100644 index 00000000..d61d9311 --- /dev/null +++ b/MyPerf4J-ASM/src/test/java/MyPerf4J/ClassFileUtils.java @@ -0,0 +1,110 @@ +package MyPerf4J; + +import cn.myperf4j.base.util.Logger; +import cn.myperf4j.core.recorder.RoughRecorder; + +import java.io.*; +import java.net.URL; +import java.net.URLDecoder; +import java.util.Arrays; +import java.util.Enumeration; + +/** + * Created by LinShunkang on 2018/10/17 + */ +public class ClassFileUtils { + + public static void main(String[] args) throws IOException { + System.out.println(Arrays.toString(getClassFileContent(RoughRecorder.class.getName()))); + } + + public static byte[] getClassFileContent(String fullClassName) throws IOException { + int idx = fullClassName.lastIndexOf("."); + String simpleClassName = fullClassName.substring(idx + 1); + File targetClassFile = getClasses(fullClassName.substring(0, idx), true, simpleClassName + ".class"); + if (targetClassFile == null) { + return null; + } + + return toByteArray(new FileInputStream(targetClassFile)); + } + + private static File getClasses(String basePackage, boolean recursive, String targetClassName) { + String packageName = basePackage; + if (packageName.endsWith(".")) { + packageName = packageName.substring(0, packageName.lastIndexOf('.')); + } + + String package2Path = packageName.replace('.', '/'); + try { + Enumeration dirs = Thread.currentThread().getContextClassLoader().getResources(package2Path); + while (dirs.hasMoreElements()) { + URL url = dirs.nextElement(); + String protocol = url.getProtocol(); + if ("file".equals(protocol)) { + Logger.debug("ClassScanner scanning file type class...."); + String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); + File file = scanByFile(packageName, filePath, recursive, targetClassName); + if (file != null) { + return file; + } + } + } + } catch (IOException e) { + Logger.error("ClassScanner.getClasses(" + basePackage + ", " + recursive + ")", e); + } + return null; + } + + private static File scanByFile(String packageName, + String packagePath, + final boolean recursive, + String targetClassName) { + File dir = new File(packagePath); + if (!dir.exists() || !dir.isDirectory()) { + return null; + } + + File[] dirFiles = dir.listFiles(new FileFilter() { + // 自定义文件过滤规则 + public boolean accept(File file) { + if (file.isDirectory()) { + return recursive; + } + return filterClassName(file.getName()); + } + }); + + if (dirFiles == null) { + return null; + } + + for (File file : dirFiles) { + if (file.isDirectory()) { + scanByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, targetClassName); + continue; + } + + if (file.getName().equals(targetClassName)) { + return file; + } + } + return null; + } + + private static boolean filterClassName(String className) { + return className.endsWith(".class"); + } + + private static byte[] toByteArray(InputStream in) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024 * 4]; + int n; + while ((n = in.read(buffer)) != -1) { + out.write(buffer, 0, n); + } + return out.toByteArray(); + } + + +} diff --git a/MyPerf4J-ASM/src/test/java/MyPerf4J/ClassToTest.java b/MyPerf4J-ASM/src/test/java/MyPerf4J/ClassToTest.java new file mode 100644 index 00000000..5745051e --- /dev/null +++ b/MyPerf4J-ASM/src/test/java/MyPerf4J/ClassToTest.java @@ -0,0 +1,17 @@ +package MyPerf4J; + +import cn.myperf4j.base.util.ThreadUtils; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; + +/** + * Created by LinShunkang on 2018/10/18 + */ +public class ClassToTest { + + public String getStr() { + ThreadUtils.sleepQuietly(ThreadLocalRandom.current().nextInt(10), TimeUnit.MILLISECONDS); + return "111"; + } +} diff --git a/MyPerf4J-ASM/src/test/java/MyPerf4J/PreMainTest.java b/MyPerf4J-ASM/src/test/java/MyPerf4J/PreMainTest.java new file mode 100644 index 00000000..8e5cf46c --- /dev/null +++ b/MyPerf4J-ASM/src/test/java/MyPerf4J/PreMainTest.java @@ -0,0 +1,71 @@ +package MyPerf4J; + +import cn.myperf4j.asm.ASMBootstrap; +import cn.myperf4j.asm.aop.ProfilingTransformer; +import cn.myperf4j.base.constant.PropertyKeys; +import cn.myperf4j.base.constant.PropertyValues; +import cn.myperf4j.base.util.ThreadUtils; +import cn.myperf4j.base.util.file.AutoRollingFileWriter; +import cn.myperf4j.base.util.file.MinutelyRollingFileWriter; +import org.junit.Test; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +/** + * Created by LinShunkang on 2018/10/17 + */ +public class PreMainTest { + + @Test + public void test() { + test(PropertyValues.METRICS_PROCESS_TYPE_STDOUT); +// test(PropertyValues.METRICS_PROCESS_TYPE_INFLUX_DB); + } + + private void test(int metricsProcessorType) { + prepare(metricsProcessorType); + if (ASMBootstrap.getInstance().initial()) { + MyClassLoader loader = new MyClassLoader(); + Class aClass = loader.findClass("MyPerf4J.ClassToTest"); + try { + Object obj = aClass.newInstance(); + Method method = aClass.getMethod("getStr"); + for (int i = 0; i < 100; ++i) { + method.invoke(obj); + } + } catch (Exception e) { + e.printStackTrace(); + } + ThreadUtils.sleepQuietly(3, TimeUnit.SECONDS); + } + } + + private void prepare(int metricsProcessorType) { + String propertiesFile = "/tmp/MyPerf4J.properties"; + System.setProperty(PropertyKeys.PRO_FILE_NAME, propertiesFile); + AutoRollingFileWriter writer = new MinutelyRollingFileWriter(propertiesFile); + writer.write("AppName=MyPerf4JTest\n"); + writer.write("MetricsProcessorType=" + metricsProcessorType + "\n"); + writer.write("IncludePackages=MyPerf4J\n"); + writer.write("MillTimeSlice=1000\n"); + writer.closeFile(true); + } + + public class MyClassLoader extends ClassLoader { + @Override + protected Class findClass(String name) { + ProfilingTransformer transformer = new ProfilingTransformer(); + Class targetClass = ClassToTest.class; + try { + byte[] transformBytes = transformer.transform(PreMainTest.class.getClassLoader(), targetClass.getName(), targetClass, null, ClassFileUtils.getClassFileContent(targetClass.getName())); + return defineClass(name, transformBytes, 0, transformBytes.length); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + } + +} diff --git a/MyPerf4J-ASM/src/test/java/MyPerf4J/TypeDestUtilsTest.java b/MyPerf4J-ASM/src/test/java/MyPerf4J/TypeDestUtilsTest.java new file mode 100644 index 00000000..3053851a --- /dev/null +++ b/MyPerf4J-ASM/src/test/java/MyPerf4J/TypeDestUtilsTest.java @@ -0,0 +1,25 @@ +package MyPerf4J; + +import org.junit.Assert; +import org.junit.Test; + +import static cn.myperf4j.asm.utils.TypeDescUtils.getMethodParamsDesc; + +/** + * Created by LinShunkang on 2018/10/19 + */ +public class TypeDestUtilsTest { + + @Test + public void test() { + Assert.assertEquals(getMethodParamsDesc("()V"),""); + Assert.assertEquals(getMethodParamsDesc("(IF)V"),"int, float"); + Assert.assertEquals(getMethodParamsDesc("(Ljava/lang/Object;)I"),"Object"); + Assert.assertEquals(getMethodParamsDesc("(ILjava/lang/String;)[I"),"int, String"); + Assert.assertEquals(getMethodParamsDesc("(ILjava/lang/Map;)[I"),"int, Map"); + Assert.assertEquals(getMethodParamsDesc("([I)Ljava/lang/Object;"),"int[]"); + Assert.assertEquals(getMethodParamsDesc("([ILjava/lang/Object;[Ljava/lang/Object;[Ljava/lang/String;)Ljava/lang/Object;"),"int[], Object, Object[], String[]"); + Assert.assertEquals(getMethodParamsDesc("([[ILjava/lang/Object;[[[Ljava/lang/Object;[[[[[Ljava/lang/String;)Ljava/lang/Object;"),"int[][], Object, Object[][][], String[][][][][]"); + } + +} diff --git a/MyPerf4J-ASM/src/test/java/MyPerf4J/test2/Test2.java b/MyPerf4J-ASM/src/test/java/MyPerf4J/test2/Test2.java index 089582cf..249c253a 100644 --- a/MyPerf4J-ASM/src/test/java/MyPerf4J/test2/Test2.java +++ b/MyPerf4J-ASM/src/test/java/MyPerf4J/test2/Test2.java @@ -1,6 +1,8 @@ package MyPerf4J.test2; +import cn.myperf4j.asm.ASMRecorderMaintainer; import cn.myperf4j.asm.aop.ProfilingClassAdapter; +import cn.myperf4j.base.metric.processor.stdout.StdoutMethodMetricsProcessor; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; @@ -16,6 +18,8 @@ public class Test2 { public static void main(String[] args) throws IOException { + ASMRecorderMaintainer instance = ASMRecorderMaintainer.getInstance(); + instance.initial(new StdoutMethodMetricsProcessor(), true, 1); test2(); // runNewFoo2(); } diff --git a/MyPerf4J-Base/pom.xml b/MyPerf4J-Base/pom.xml index b7dc9c74..89767727 100644 --- a/MyPerf4J-Base/pom.xml +++ b/MyPerf4J-Base/pom.xml @@ -16,6 +16,14 @@ 1.7 + + + junit + junit + test + + + diff --git a/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/DateFormatUtils.java b/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/DateFormatUtils.java index 1a969001..a697d7b9 100644 --- a/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/DateFormatUtils.java +++ b/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/DateFormatUtils.java @@ -8,6 +8,7 @@ * Created by LinShunkang on 2018/8/22 */ public class DateFormatUtils { + private static final ThreadLocal DEFAULT_DATE_FORMAT = new ThreadLocal() { @Override protected DateFormat initialValue() { diff --git a/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/NumFormatUtils.java b/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/NumFormatUtils.java index 97195b75..5c811530 100644 --- a/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/NumFormatUtils.java +++ b/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/NumFormatUtils.java @@ -17,11 +17,4 @@ protected DecimalFormat initialValue() { public static String getFormatStr(double num) { return decimalFormat.get().format(num); } - - public static void main(String[] args) { - System.out.println(getFormatStr(10011.22222D)); - System.out.println(getFormatStr(10011.22D)); - System.out.println(getFormatStr(1.2222D)); - System.out.println(getFormatStr(1.2D)); - } } diff --git a/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/ThreadUtils.java b/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/ThreadUtils.java index d2fca440..e1020497 100644 --- a/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/ThreadUtils.java +++ b/MyPerf4J-Base/src/main/java/cn/myperf4j/base/util/ThreadUtils.java @@ -1,6 +1,7 @@ package cn.myperf4j.base.util; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** @@ -19,4 +20,11 @@ public Thread newThread(Runnable r) { }; } + public static void sleepQuietly(long time, TimeUnit timeUnit) { + try { + timeUnit.sleep(time); + } catch (Exception e) { + //empty + } + } } diff --git a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/ChunkPoolTest.java b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/ChunkPoolTest.java new file mode 100644 index 00000000..ae6e9c2b --- /dev/null +++ b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/ChunkPoolTest.java @@ -0,0 +1,38 @@ +package cn.myperf4j.base.test; + +import cn.myperf4j.base.util.ChunkPool; +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by LinShunkang on 2018/10/17 + */ +public class ChunkPoolTest { + + @Test + public void test() { + ChunkPool pool = ChunkPool.getInstance(); + test(pool, 16); + test(pool, 1024); + test(pool, 10 * 1024); + test(pool, 100 * 1024); + test(pool, 1024 * 1024); + pool.returnChunk(new int[]{1}); + } + + private void test(ChunkPool pool, int chunkLength) { + int[] chunk = null; + try { + chunk = pool.getChunk(chunkLength); + Assert.assertNotNull(chunk); + + for (int i = 0; i < chunkLength; ++i) { + chunk[i] = i; + } + } finally { + if (chunk != null) { + pool.returnChunk(chunk); + } + } + } +} diff --git a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/DailyRollingFileWriterTest.java b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/DailyRollingFileWriterTest.java deleted file mode 100644 index defd956d..00000000 --- a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/DailyRollingFileWriterTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package cn.myperf4j.base.test; - -import cn.myperf4j.base.util.file.DailyRollingFileWriter; - -public class DailyRollingFileWriterTest { - - - public static void main(String[] args) { - DailyRollingFileWriter writer = new DailyRollingFileWriter("/tmp/test.log"); - - writer.write("111111"); - writer.write("222222"); - writer.write("333333"); - writer.writeAndFlush("44444"); - } -} diff --git a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/DateFormatUtilsTest.java b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/DateFormatUtilsTest.java new file mode 100644 index 00000000..5ad0bbd1 --- /dev/null +++ b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/DateFormatUtilsTest.java @@ -0,0 +1,22 @@ +package cn.myperf4j.base.test; + +import cn.myperf4j.base.util.DateFormatUtils; +import org.junit.Assert; +import org.junit.Test; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Created by LinShunkang on 2018/10/17 + */ +public class DateFormatUtilsTest { + + @Test + public void test() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + long mills = System.currentTimeMillis(); + Assert.assertEquals(DateFormatUtils.format(mills), format.format(new Date(mills))); + } + +} diff --git a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/ILoggerTest.java b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/ILoggerTest.java index 114b600b..774e3bc1 100644 --- a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/ILoggerTest.java +++ b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/ILoggerTest.java @@ -1,10 +1,35 @@ package cn.myperf4j.base.test; +import cn.myperf4j.base.config.ProfilingConfig; +import cn.myperf4j.base.constant.PropertyValues; import cn.myperf4j.base.log.ILogger; import cn.myperf4j.base.log.LoggerFactory; +import org.junit.Assert; +import org.junit.Test; public class ILoggerTest { + @Test + public void test() { + ProfilingConfig.getInstance().setLogRollingTimeUnit(PropertyValues.LOG_ROLLING_TIME_MINUTELY); + + test(LoggerFactory.getLogger("/tmp/testLogger.log")); + test(LoggerFactory.getLogger(PropertyValues.NULL_FILE)); + } + + private void test(ILogger logger) { + logger.log("111111111"); + logger.log("222222222"); + logger.log("333333333"); + logger.log("444444444"); + logger.flushLog(); + + logger.logAndFlush("555555"); + + logger.preCloseLog(); + logger.closeLog(); + } + public static void main(String[] args) { for (int i = 0; i < 100; ++i) { final String file = "/tmp/testLogger.log"; @@ -19,6 +44,8 @@ public void run() { private static void writeFile(String file) { ILogger logger = LoggerFactory.getLogger(file); + Assert.assertNotNull(logger); + logger.log("111111111"); logger.log("222222222"); logger.log("333333333"); diff --git a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/LineProtocolUtilsTest.java b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/LineProtocolUtilsTest.java new file mode 100644 index 00000000..cd86d847 --- /dev/null +++ b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/LineProtocolUtilsTest.java @@ -0,0 +1,17 @@ +package cn.myperf4j.base.test; + +import cn.myperf4j.base.util.LineProtocolUtils; +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by LinShunkang on 2018/10/17 + */ +public class LineProtocolUtilsTest { + + @Test + public void test() { + String expect = "method_metrics\\,AppName\\=TestApp\\,ClassName\\=TestClass\\,Method\\=TestClass.test\\ RPS\\=1i\\,Avg\\=0.00\\,Min\\=0i\\,Max\\=0i\\,StdDev\\=0.00\\,Count\\=17i\\,TP50\\=0i\\,TP90\\=0i\\,TP95\\=0i\\,TP99\\=0i\\,TP999\\=0i\\,TP9999\\=0i\\,TP99999\\=0i\\,TP100\\=0i\\ 1539705590006000000"; + Assert.assertEquals(expect, LineProtocolUtils.processTagOrField("method_metrics,AppName=TestApp,ClassName=TestClass,Method=TestClass.test RPS=1i,Avg=0.00,Min=0i,Max=0i,StdDev=0.00,Count=17i,TP50=0i,TP90=0i,TP95=0i,TP99=0i,TP999=0i,TP9999=0i,TP99999=0i,TP100=0i 1539705590006000000")); + } +} diff --git a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/LoggerTest.java b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/LoggerTest.java new file mode 100644 index 00000000..527a3403 --- /dev/null +++ b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/LoggerTest.java @@ -0,0 +1,20 @@ +package cn.myperf4j.base.test; + +import cn.myperf4j.base.util.Logger; +import org.junit.Test; + +/** + * Created by LinShunkang on 2018/10/17 + */ +public class LoggerTest { + + @Test + public void test() { + Logger.setDebugEnable(true); + Logger.debug("debug test"); + Logger.info("info test"); + Logger.warn("warn test"); + Logger.error("error test"); + Logger.error("error test", new UnknownError()); + } +} diff --git a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/MapUtilsTest.java b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/MapUtilsTest.java new file mode 100644 index 00000000..b1d40acc --- /dev/null +++ b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/MapUtilsTest.java @@ -0,0 +1,26 @@ +package cn.myperf4j.base.test; + +import cn.myperf4j.base.util.MapUtils; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by LinShunkang on 2018/10/17 + */ +public class MapUtilsTest { + + @Test + public void test() { + Map hashMap = MapUtils.createHashMap(1); + Assert.assertNotNull(hashMap); + + Map hashMap2 = MapUtils.createHashMap(10, 0.01F); + Assert.assertNotNull(hashMap2); + + ConcurrentHashMap concHashMap = MapUtils.createConcHashMap(10, 0.1F); + Assert.assertNotNull(concHashMap); + } +} diff --git a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/NumFormatUtilsTest.java b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/NumFormatUtilsTest.java new file mode 100644 index 00000000..e00aa534 --- /dev/null +++ b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/NumFormatUtilsTest.java @@ -0,0 +1,24 @@ +package cn.myperf4j.base.test; + +import org.junit.Assert; +import org.junit.Test; + +import static cn.myperf4j.base.util.NumFormatUtils.getFormatStr; + +/** + * Created by LinShunkang on 2018/10/17 + */ +public class NumFormatUtilsTest { + + @Test + public void test() { + Assert.assertEquals("10011.22", getFormatStr(10011.22222D)); + Assert.assertEquals("10011.22", getFormatStr(10011.22D)); + Assert.assertEquals("1.22", getFormatStr(1.2222D)); + Assert.assertEquals("1.20", getFormatStr(1.2D)); + Assert.assertEquals("1.00", getFormatStr(1D)); + Assert.assertEquals("0.00", getFormatStr(0D)); + Assert.assertEquals("-1.00", getFormatStr(-1D)); + Assert.assertEquals("-1.10", getFormatStr(-1.1D)); + } +} diff --git a/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/RollingFileWriterTest.java b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/RollingFileWriterTest.java new file mode 100644 index 00000000..bae9400a --- /dev/null +++ b/MyPerf4J-Base/src/test/java/cn/myperf4j/base/test/RollingFileWriterTest.java @@ -0,0 +1,34 @@ +package cn.myperf4j.base.test; + +import cn.myperf4j.base.util.file.AutoRollingFileWriter; +import cn.myperf4j.base.util.file.DailyRollingFileWriter; +import cn.myperf4j.base.util.file.HourlyRollingFileWriter; +import cn.myperf4j.base.util.file.MinutelyRollingFileWriter; +import org.junit.Test; + +/** + * Created by LinShunkang on 2018/10/17 + */ +public class RollingFileWriterTest { + + @Test + public void test() { + AutoRollingFileWriter writer1 = new MinutelyRollingFileWriter("/tmp/test1.log"); + test(writer1); + + AutoRollingFileWriter writer2 = new HourlyRollingFileWriter("/tmp/test2.log"); + test(writer2); + + AutoRollingFileWriter writer3 = new DailyRollingFileWriter("/tmp/test3.log"); + test(writer3); + } + + private void test(AutoRollingFileWriter writer) { + writer.write("111111"); + writer.write("222222"); + writer.write("333333"); + writer.writeAndFlush("44444"); + writer.preCloseFile(); + writer.closeFile(true); + } +} diff --git a/MyPerf4J-Core/pom.xml b/MyPerf4J-Core/pom.xml index 655dfe15..e138711d 100644 --- a/MyPerf4J-Core/pom.xml +++ b/MyPerf4J-Core/pom.xml @@ -23,7 +23,6 @@ junit junit - 4.11 test diff --git a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/AbstractBootstrap.java b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/AbstractBootstrap.java index da4d32e5..42c7c3b0 100644 --- a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/AbstractBootstrap.java +++ b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/AbstractBootstrap.java @@ -9,6 +9,7 @@ import cn.myperf4j.base.util.IOUtils; import cn.myperf4j.base.util.Logger; import cn.myperf4j.base.config.MyProperties; +import cn.myperf4j.core.recorder.AbstractRecorderMaintainer; import cn.myperf4j.core.scheduler.JvmMetricsScheduler; import cn.myperf4j.base.Scheduler; diff --git a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/PerfStatsCalculator.java b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/MethodMetricsCalculator.java similarity index 95% rename from MyPerf4J-Core/src/main/java/cn/myperf4j/core/PerfStatsCalculator.java rename to MyPerf4J-Core/src/main/java/cn/myperf4j/core/MethodMetricsCalculator.java index f937a1c4..36db6217 100644 --- a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/PerfStatsCalculator.java +++ b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/MethodMetricsCalculator.java @@ -5,11 +5,12 @@ import cn.myperf4j.base.MethodTag; import cn.myperf4j.base.util.ChunkPool; import cn.myperf4j.base.util.Logger; +import cn.myperf4j.core.recorder.Recorder; /** * Created by LinShunkang on 2018/3/11 */ -public final class PerfStatsCalculator { +public final class MethodMetricsCalculator { private static final ThreadLocal threadLocalIntArr = new ThreadLocal() { @Override @@ -26,7 +27,7 @@ public static MethodMetrics calPerfStats(Recorder recorder, MethodTag methodTag, recorder.fillSortedRecords(sortedRecords); return calPerfStats(methodTag, startTime, stopTime, sortedRecords, effectiveCount); } catch (Exception e) { - Logger.error("PerfStatsCalculator.calPerfStats(" + recorder + ", " + methodTag + ", " + startTime + ", " + stopTime + ")", e); + Logger.error("MethodMetricsCalculator.calPerfStats(" + recorder + ", " + methodTag + ", " + startTime + ", " + stopTime + ")", e); } finally { ChunkPool.getInstance().returnChunk(sortedRecords); } diff --git a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/MethodTagMaintainer.java b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/MethodTagMaintainer.java index 3467b69c..2e7df470 100644 --- a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/MethodTagMaintainer.java +++ b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/MethodTagMaintainer.java @@ -11,7 +11,7 @@ */ public class MethodTagMaintainer extends AbstractMethodTagMaintainer { - static final int MAX_NUM = 1024 * 128; + public static final int MAX_NUM = 1024 * 128; private final AtomicInteger index = new AtomicInteger(0); diff --git a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/AbstractRecorderMaintainer.java b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/AbstractRecorderMaintainer.java similarity index 95% rename from MyPerf4J-Core/src/main/java/cn/myperf4j/core/AbstractRecorderMaintainer.java rename to MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/AbstractRecorderMaintainer.java index bd06ab5f..22b38c73 100644 --- a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/AbstractRecorderMaintainer.java +++ b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/AbstractRecorderMaintainer.java @@ -1,4 +1,4 @@ -package cn.myperf4j.core; +package cn.myperf4j.core.recorder; import cn.myperf4j.base.metric.MethodMetrics; import cn.myperf4j.base.MethodTag; @@ -9,6 +9,8 @@ import cn.myperf4j.base.util.Logger; import cn.myperf4j.base.util.ThreadUtils; import cn.myperf4j.base.Scheduler; +import cn.myperf4j.core.MethodMetricsCalculator; +import cn.myperf4j.core.MethodTagMaintainer; import java.util.ArrayList; import java.util.List; @@ -146,7 +148,7 @@ public void run() { } MethodTag methodTag = methodTagMaintainer.getMethodTag(recorder.getMethodTagId()); - MethodMetrics metrics = PerfStatsCalculator.calPerfStats(recorder, methodTag, tmpCurRecorders.getStartTime(), tmpCurRecorders.getStopTime()); + MethodMetrics metrics = MethodMetricsCalculator.calPerfStats(recorder, methodTag, tmpCurRecorders.getStartTime(), tmpCurRecorders.getStopTime()); methodMetricsProcessor.process(metrics, tmpCurRecorders.getStartTime(), tmpCurRecorders.getStartTime(), tmpCurRecorders.getStopTime()); } } catch (Exception e) { diff --git a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/AccurateRecorder.java b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/AccurateRecorder.java similarity index 99% rename from MyPerf4J-Core/src/main/java/cn/myperf4j/core/AccurateRecorder.java rename to MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/AccurateRecorder.java index e98e8551..d5792a99 100644 --- a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/AccurateRecorder.java +++ b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/AccurateRecorder.java @@ -1,4 +1,4 @@ -package cn.myperf4j.core; +package cn.myperf4j.core.recorder; import cn.myperf4j.base.util.MapUtils; diff --git a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/Recorder.java b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/Recorder.java similarity index 96% rename from MyPerf4J-Core/src/main/java/cn/myperf4j/core/Recorder.java rename to MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/Recorder.java index 07653199..6a632cec 100644 --- a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/Recorder.java +++ b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/Recorder.java @@ -1,4 +1,4 @@ -package cn.myperf4j.core; +package cn.myperf4j.core.recorder; /** * Created by LinShunkang on 2018/3/13 diff --git a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/Recorders.java b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/Recorders.java similarity index 98% rename from MyPerf4J-Core/src/main/java/cn/myperf4j/core/Recorders.java rename to MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/Recorders.java index 38914b24..2eddbd13 100644 --- a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/Recorders.java +++ b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/Recorders.java @@ -1,4 +1,4 @@ -package cn.myperf4j.core; +package cn.myperf4j.core.recorder; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReferenceArray; diff --git a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/RoughRecorder.java b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/RoughRecorder.java similarity index 98% rename from MyPerf4J-Core/src/main/java/cn/myperf4j/core/RoughRecorder.java rename to MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/RoughRecorder.java index 29ec4f7d..1390cf6e 100644 --- a/MyPerf4J-Core/src/main/java/cn/myperf4j/core/RoughRecorder.java +++ b/MyPerf4J-Core/src/main/java/cn/myperf4j/core/recorder/RoughRecorder.java @@ -1,4 +1,4 @@ -package cn.myperf4j.core; +package cn.myperf4j.core.recorder; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicIntegerArray; diff --git a/MyPerf4J-Core/src/test/java/MyPerf4J/MethodMetricsTest.java b/MyPerf4J-Core/src/test/java/MyPerf4J/MethodMetricsTest.java new file mode 100644 index 00000000..8bb46932 --- /dev/null +++ b/MyPerf4J-Core/src/test/java/MyPerf4J/MethodMetricsTest.java @@ -0,0 +1,57 @@ +package MyPerf4J; + +import cn.myperf4j.base.MethodTag; +import cn.myperf4j.base.metric.MethodMetrics; +import cn.myperf4j.core.*; +import cn.myperf4j.core.recorder.AccurateRecorder; +import cn.myperf4j.core.recorder.Recorder; +import cn.myperf4j.core.recorder.Recorders; +import cn.myperf4j.core.recorder.RoughRecorder; +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicReferenceArray; + +/** + * Created by LinShunkang on 2018/10/17 + */ +public class MethodMetricsTest { + + @Test + public void test() { + Recorders recorders = new Recorders(new AtomicReferenceArray(10)); + MethodTagMaintainer methodTagMaintainer = MethodTagMaintainer.getInstance(); + + int methodId1 = methodTagMaintainer.addMethodTag(MethodTag.getInstance("Test", "test1", "")); + recorders.setRecorder(methodId1, AccurateRecorder.getInstance(0, 100000, 50)); + + int methodId2 = methodTagMaintainer.addMethodTag(MethodTag.getInstance("Test", "test1", "")); + recorders.setRecorder(methodId2, RoughRecorder.getInstance(0, 100000)); + + testRecorder(recorders, methodTagMaintainer, methodId1); + testRecorder(recorders, methodTagMaintainer, methodId2); + } + + private void testRecorder(Recorders recorders, MethodTagMaintainer methodTagMaintainer, int methodId) { + Recorder recorder = recorders.getRecorder(methodId); + recorders.setStartTime(System.currentTimeMillis()); + long start = System.nanoTime(); + for (long i = 0; i < 100000; ++i) { + recorder.recordTime(start, start + (i + 1) * 1000 * 1000); + } + recorders.setStopTime(System.currentTimeMillis()); + + MethodTag methodTag = methodTagMaintainer.getMethodTag(methodId); + MethodMetrics methodMetrics = MethodMetricsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime()); + System.out.println(methodMetrics); + recorder.resetRecord(); + + System.out.println(methodMetrics.getTP50() == 50000); + System.out.println(methodMetrics.getTP90() == 90000); + System.out.println(methodMetrics.getTP95() == 95000); + System.out.println(methodMetrics.getTP99() == 99000); + System.out.println(methodMetrics.getTP999() == 99900); + System.out.println(methodMetrics.getTP9999() == 99990); + System.out.println(methodMetrics.getTP99999() == 99999); + System.out.println(methodMetrics.getTP100() == 100000); + } +} diff --git a/MyPerf4J-Core/src/test/java/MyPerf4J/RecorderBenchmarkTest.java b/MyPerf4J-Core/src/test/java/MyPerf4J/RecorderBenchmarkTest.java index 9bac800f..b264a10d 100644 --- a/MyPerf4J-Core/src/test/java/MyPerf4J/RecorderBenchmarkTest.java +++ b/MyPerf4J-Core/src/test/java/MyPerf4J/RecorderBenchmarkTest.java @@ -1,10 +1,10 @@ package MyPerf4J; import cn.myperf4j.base.MethodTag; -import cn.myperf4j.core.Recorder; -import cn.myperf4j.core.AccurateRecorder; -import cn.myperf4j.core.Recorders; -import cn.myperf4j.core.PerfStatsCalculator; +import cn.myperf4j.core.MethodMetricsCalculator; +import cn.myperf4j.core.recorder.Recorder; +import cn.myperf4j.core.recorder.AccurateRecorder; +import cn.myperf4j.core.recorder.Recorders; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReferenceArray; @@ -24,23 +24,23 @@ public static void main(String[] args) { int times = 100000000; singleThreadBenchmark(recorders, times / 10);//warm up - System.out.println(PerfStatsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime())); + System.out.println(MethodMetricsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime())); recorder.resetRecord(); singleThreadBenchmark(recorders, times); - System.out.println(PerfStatsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime())); + System.out.println(MethodMetricsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime())); recorder.resetRecord(); multiThreadBenchmark(recorders, times, 2); - System.out.println(PerfStatsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime())); + System.out.println(MethodMetricsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime())); recorder.resetRecord(); multiThreadBenchmark(recorders, times, 4); - System.out.println(PerfStatsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime())); + System.out.println(MethodMetricsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime())); recorder.resetRecord(); multiThreadBenchmark(recorders, times, 8); - System.out.println(PerfStatsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime())); + System.out.println(MethodMetricsCalculator.calPerfStats(recorder, methodTag, recorders.getStartTime(), recorders.getStopTime())); } private static void singleThreadBenchmark(Recorders recorders, int times) { diff --git a/pom.xml b/pom.xml index 8d6c94fb..50d4e8fd 100644 --- a/pom.xml +++ b/pom.xml @@ -29,6 +29,13 @@ + + + junit + junit + 4.11 + test +