• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 Code Intelligence GmbH
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 package com.code_intelligence.jazzer.junit;
16 
17 import static com.code_intelligence.jazzer.junit.Utils.durationStringToSeconds;
18 import static com.code_intelligence.jazzer.junit.Utils.getMarkedArguments;
19 import static com.code_intelligence.jazzer.junit.Utils.getMarkedInstance;
20 import static com.code_intelligence.jazzer.junit.Utils.isMarkedInstance;
21 import static com.code_intelligence.jazzer.junit.Utils.isMarkedInvocation;
22 import static com.google.common.truth.Truth.assertThat;
23 import static com.google.common.truth.Truth8.assertThat;
24 import static java.nio.file.Files.createDirectories;
25 import static java.nio.file.Files.createFile;
26 import static java.util.Arrays.stream;
27 import static java.util.Collections.singletonList;
28 import static java.util.stream.Collectors.joining;
29 import static org.junit.jupiter.params.provider.Arguments.arguments;
30 
31 import java.io.File;
32 import java.io.IOException;
33 import java.lang.reflect.Method;
34 import java.nio.file.Path;
35 import java.util.AbstractList;
36 import java.util.AbstractMap;
37 import java.util.Arrays;
38 import java.util.HashMap;
39 import java.util.LinkedHashMap;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.stream.Stream;
43 import org.junit.jupiter.api.Test;
44 import org.junit.jupiter.api.extension.ExtendWith;
45 import org.junit.jupiter.api.extension.ExtensionContext;
46 import org.junit.jupiter.api.extension.InvocationInterceptor;
47 import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
48 import org.junit.jupiter.api.io.TempDir;
49 import org.junit.jupiter.params.ParameterizedTest;
50 import org.junit.jupiter.params.provider.Arguments;
51 import org.junit.jupiter.params.provider.MethodSource;
52 import org.junit.jupiter.params.provider.ValueSource;
53 
54 public class UtilsTest implements InvocationInterceptor {
55   @TempDir Path temp;
56 
57   @Test
testDurationStringToSeconds()58   void testDurationStringToSeconds() {
59     assertThat(durationStringToSeconds("1m")).isEqualTo(60);
60     assertThat(durationStringToSeconds("1min")).isEqualTo(60);
61     assertThat(durationStringToSeconds("1h")).isEqualTo(60 * 60);
62     assertThat(durationStringToSeconds("1h   2m 30s")).isEqualTo(60 * 60 + 2 * 60 + 30);
63     assertThat(durationStringToSeconds("1hr2min30sec")).isEqualTo(60 * 60 + 2 * 60 + 30);
64     assertThat(durationStringToSeconds("1h2m30s")).isEqualTo(60 * 60 + 2 * 60 + 30);
65   }
66 
67   @ValueSource(classes = {int.class, Class.class, Object.class, String.class, HashMap.class,
68                    Map.class, int[].class, int[][].class, AbstractMap.class, AbstractList.class})
69   @ParameterizedTest
70   void
testMarkedInstances(Class<?> clazz)71   testMarkedInstances(Class<?> clazz) {
72     Object instance = getMarkedInstance(clazz);
73     if (clazz == int.class) {
74       assertThat(instance).isInstanceOf(Integer.class);
75     } else {
76       assertThat(instance).isInstanceOf(clazz);
77     }
78     assertThat(isMarkedInstance(instance)).isTrue();
79     assertThat(getMarkedInstance(clazz)).isSameInstanceAs(instance);
80   }
81 
testWithMarkedNamedParametersSource()82   static Stream<Arguments> testWithMarkedNamedParametersSource() {
83     Method testMethod =
84         stream(UtilsTest.class.getDeclaredMethods())
85             .filter(method -> method.getName().equals("testWithMarkedNamedParameters"))
86             .findFirst()
87             .get();
88     return Stream.of(
89         arguments("foo", 0, new HashMap<>(), singletonList(5), UtilsTest.class, new int[] {1}),
90         getMarkedArguments(testMethod, "some name"),
91         arguments("baz", 1, new LinkedHashMap<>(), Arrays.asList(5, 7), String.class, new int[0]),
92         getMarkedArguments(testMethod, "some other name"));
93   }
94 
95   @MethodSource("testWithMarkedNamedParametersSource")
96   @ExtendWith(UtilsTest.class)
97   @ParameterizedTest
testWithMarkedNamedParameters(String str, int num, AbstractMap<String, String> map, List<Integer> list, Class<?> clazz, int[] array)98   void testWithMarkedNamedParameters(String str, int num, AbstractMap<String, String> map,
99       List<Integer> list, Class<?> clazz, int[] array) {}
100 
101   boolean argumentsExpectedToBeMarked = false;
102 
103   @Override
interceptTestTemplateMethod(Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext)104   public void interceptTestTemplateMethod(Invocation<Void> invocation,
105       ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext)
106       throws Throwable {
107     assertThat(isMarkedInvocation(invocationContext)).isEqualTo(argumentsExpectedToBeMarked);
108     argumentsExpectedToBeMarked = !argumentsExpectedToBeMarked;
109     invocation.proceed();
110   }
111 
112   @Test
testGetClassPathBasedInstrumentationFilter()113   public void testGetClassPathBasedInstrumentationFilter() throws IOException {
114     Path firstDir = createDirectories(temp.resolve("first_dir"));
115     Path orgExample = createDirectories(firstDir.resolve("org").resolve("example"));
116     createFile(orgExample.resolve("Application.class"));
117 
118     Path nonExistentDir = temp.resolve("does not exist");
119 
120     Path secondDir = createDirectories(temp.resolve("second").resolve("dir"));
121     createFile(secondDir.resolve("Root.class"));
122     Path comExampleProject =
123         createDirectories(secondDir.resolve("com").resolve("example").resolve("project"));
124     createFile(comExampleProject.resolve("Main.class"));
125     Path comExampleOtherProject =
126         createDirectories(secondDir.resolve("com").resolve("example").resolve("other_project"));
127     createFile(comExampleOtherProject.resolve("Lib.class"));
128 
129     Path emptyDir = createDirectories(temp.resolve("some").resolve("empty").resolve("dir"));
130 
131     Path firstJar = createFile(temp.resolve("first.jar"));
132     Path secondJar = createFile(temp.resolve("second.jar"));
133 
134     assertThat(Utils.getClassPathBasedInstrumentationFilter(makeClassPath(
135                    firstDir, firstJar, nonExistentDir, secondDir, secondJar, emptyDir)))
136         .hasValue("*,com.example.other_project.**,com.example.project.**,org.example.**");
137   }
138 
139   @Test
testGetClassPathBasedInstrumentationFilter_noDirs()140   public void testGetClassPathBasedInstrumentationFilter_noDirs() throws IOException {
141     Path firstJar = createFile(temp.resolve("first.jar"));
142     Path secondJar = createFile(temp.resolve("second.jar"));
143 
144     assertThat(Utils.getClassPathBasedInstrumentationFilter(makeClassPath(firstJar, secondJar)))
145         .isEmpty();
146   }
147 
makeClassPath(Path... paths)148   private static String makeClassPath(Path... paths) {
149     return Arrays.stream(paths).map(Path::toString).collect(joining(File.pathSeparator));
150   }
151 }
152