// Copyright 2022 Code Intelligence GmbH // // Licensed 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.code_intelligence.jazzer.junit; import static com.code_intelligence.jazzer.junit.Utils.durationStringToSeconds; import static com.code_intelligence.jazzer.junit.Utils.getMarkedArguments; import static com.code_intelligence.jazzer.junit.Utils.getMarkedInstance; import static com.code_intelligence.jazzer.junit.Utils.isMarkedInstance; import static com.code_intelligence.jazzer.junit.Utils.isMarkedInvocation; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth8.assertThat; import static java.nio.file.Files.createDirectories; import static java.nio.file.Files.createFile; import static java.util.Arrays.stream; import static java.util.Collections.singletonList; import static java.util.stream.Collectors.joining; import static org.junit.jupiter.params.provider.Arguments.arguments; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.nio.file.Path; import java.util.AbstractList; import java.util.AbstractMap; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.InvocationInterceptor; import org.junit.jupiter.api.extension.ReflectiveInvocationContext; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; public class UtilsTest implements InvocationInterceptor { @TempDir Path temp; @Test void testDurationStringToSeconds() { assertThat(durationStringToSeconds("1m")).isEqualTo(60); assertThat(durationStringToSeconds("1min")).isEqualTo(60); assertThat(durationStringToSeconds("1h")).isEqualTo(60 * 60); assertThat(durationStringToSeconds("1h 2m 30s")).isEqualTo(60 * 60 + 2 * 60 + 30); assertThat(durationStringToSeconds("1hr2min30sec")).isEqualTo(60 * 60 + 2 * 60 + 30); assertThat(durationStringToSeconds("1h2m30s")).isEqualTo(60 * 60 + 2 * 60 + 30); } @ValueSource(classes = {int.class, Class.class, Object.class, String.class, HashMap.class, Map.class, int[].class, int[][].class, AbstractMap.class, AbstractList.class}) @ParameterizedTest void testMarkedInstances(Class clazz) { Object instance = getMarkedInstance(clazz); if (clazz == int.class) { assertThat(instance).isInstanceOf(Integer.class); } else { assertThat(instance).isInstanceOf(clazz); } assertThat(isMarkedInstance(instance)).isTrue(); assertThat(getMarkedInstance(clazz)).isSameInstanceAs(instance); } static Stream testWithMarkedNamedParametersSource() { Method testMethod = stream(UtilsTest.class.getDeclaredMethods()) .filter(method -> method.getName().equals("testWithMarkedNamedParameters")) .findFirst() .get(); return Stream.of( arguments("foo", 0, new HashMap<>(), singletonList(5), UtilsTest.class, new int[] {1}), getMarkedArguments(testMethod, "some name"), arguments("baz", 1, new LinkedHashMap<>(), Arrays.asList(5, 7), String.class, new int[0]), getMarkedArguments(testMethod, "some other name")); } @MethodSource("testWithMarkedNamedParametersSource") @ExtendWith(UtilsTest.class) @ParameterizedTest void testWithMarkedNamedParameters(String str, int num, AbstractMap map, List list, Class clazz, int[] array) {} boolean argumentsExpectedToBeMarked = false; @Override public void interceptTestTemplateMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { assertThat(isMarkedInvocation(invocationContext)).isEqualTo(argumentsExpectedToBeMarked); argumentsExpectedToBeMarked = !argumentsExpectedToBeMarked; invocation.proceed(); } @Test public void testGetClassPathBasedInstrumentationFilter() throws IOException { Path firstDir = createDirectories(temp.resolve("first_dir")); Path orgExample = createDirectories(firstDir.resolve("org").resolve("example")); createFile(orgExample.resolve("Application.class")); Path nonExistentDir = temp.resolve("does not exist"); Path secondDir = createDirectories(temp.resolve("second").resolve("dir")); createFile(secondDir.resolve("Root.class")); Path comExampleProject = createDirectories(secondDir.resolve("com").resolve("example").resolve("project")); createFile(comExampleProject.resolve("Main.class")); Path comExampleOtherProject = createDirectories(secondDir.resolve("com").resolve("example").resolve("other_project")); createFile(comExampleOtherProject.resolve("Lib.class")); Path emptyDir = createDirectories(temp.resolve("some").resolve("empty").resolve("dir")); Path firstJar = createFile(temp.resolve("first.jar")); Path secondJar = createFile(temp.resolve("second.jar")); assertThat(Utils.getClassPathBasedInstrumentationFilter(makeClassPath( firstDir, firstJar, nonExistentDir, secondDir, secondJar, emptyDir))) .hasValue("*,com.example.other_project.**,com.example.project.**,org.example.**"); } @Test public void testGetClassPathBasedInstrumentationFilter_noDirs() throws IOException { Path firstJar = createFile(temp.resolve("first.jar")); Path secondJar = createFile(temp.resolve("second.jar")); assertThat(Utils.getClassPathBasedInstrumentationFilter(makeClassPath(firstJar, secondJar))) .isEmpty(); } private static String makeClassPath(Path... paths) { return Arrays.stream(paths).map(Path::toString).collect(joining(File.pathSeparator)); } }