| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.ignite.internal.network.processor; |
| |
| import static com.google.testing.compile.CompilationSubject.assertThat; |
| import static com.google.testing.compile.JavaFileObjects.forResource; |
| import static com.google.testing.compile.JavaFileObjects.forSourceLines; |
| import static org.junit.jupiter.params.provider.Arguments.arguments; |
| |
| import com.google.testing.compile.Compilation; |
| import com.google.testing.compile.Compiler; |
| import java.util.Collection; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.locks.Lock; |
| import java.util.stream.Stream; |
| import javax.tools.JavaFileObject; |
| import org.apache.ignite.internal.network.processor.messages.MarshallableTypesBlackList; |
| import org.junit.jupiter.api.Test; |
| import org.junit.jupiter.params.ParameterizedTest; |
| import org.junit.jupiter.params.provider.Arguments; |
| import org.junit.jupiter.params.provider.MethodSource; |
| |
| /** |
| * Test case for the marshallable types blacklist. |
| */ |
| public class MarshallableBlacklistTest { |
| private static final JavaFileObject MESSAGE_GROUP = forResource("org/apache/ignite/internal/network/processor/TestMessageGroup.java"); |
| |
| /** |
| * Compiler instance configured with the annotation processor being tested. |
| */ |
| private final Compiler compiler = Compiler.javac().withProcessors(new TransferableObjectProcessor()); |
| |
| private static List<String> marshallableFieldSourceCode(Class<?> fieldType) { |
| return testMessageSourceCode(String.format("%s foo();", fieldType.getName())); |
| } |
| |
| private static List<String> marshallableCollectionSourceCode(Class<?> collectionType, Class<?> fieldType) { |
| return testMessageSourceCode(String.format("%s<%s> foo();", collectionType.getName(), fieldType.getName())); |
| } |
| |
| private static List<String> marshallableArraySourceCode(Class<?> fieldType) { |
| return testMessageSourceCode(String.format("%s[] foo();", fieldType.getName())); |
| } |
| |
| private static List<String> marshallableMapSourceCode(Class<?> keyType, Class<?> valueType) { |
| return testMessageSourceCode(String.format("%s<%s, %s> foo();", Map.class.getName(), keyType.getName(), valueType.getName())); |
| } |
| |
| private static List<String> marshallableNestedMapSourceCode(Class<?> keyType, Class<?> valueType) { |
| return testMessageSourceCode(String.format( |
| "%s<%s, %s<%s>> foo();", |
| Map.class.getName(), keyType.getName(), List.class.getName(), valueType.getName()) |
| ); |
| } |
| |
| private static List<String> testMessageSourceCode(String fieldDeclaration) { |
| return List.of( |
| "package org.apache.ignite.internal.network.processor;", |
| |
| "import org.apache.ignite.network.NetworkMessage;", |
| "import org.apache.ignite.network.annotations.Transferable;", |
| "import org.apache.ignite.network.annotations.Marshallable;", |
| |
| "@Transferable(1)", |
| "public interface TestMessage extends NetworkMessage {", |
| " @Marshallable", |
| fieldDeclaration, |
| "}" |
| ); |
| } |
| |
| private static List<Class<?>> nativeTypes() { |
| return MarshallableTypesBlackList.NATIVE_TYPES; |
| } |
| |
| private static Stream<Arguments> collectionTypes() { |
| return Stream.of(Collection.class, List.class, Set.class) |
| .flatMap(collectionType -> nativeTypes().stream().map(type -> arguments(collectionType, type))); |
| } |
| |
| @ParameterizedTest(name = "{0}") |
| @MethodSource("nativeTypes") |
| void testMessageWithNativeTypeField(Class<?> type) { |
| Compilation compilation = compile(marshallableFieldSourceCode(type)); |
| |
| assertThat(compilation).hadErrorContaining( |
| "\"foo\" field is marked as @Marshallable but this type is supported by native serialization" |
| ); |
| } |
| |
| @ParameterizedTest(name = "{0}[]") |
| @MethodSource("nativeTypes") |
| void testMessageWithNativeArrayTypeField(Class<?> type) { |
| Compilation compilation = compile(marshallableArraySourceCode(type)); |
| |
| assertThat(compilation).hadErrorContaining( |
| "\"foo\" field is marked as @Marshallable but this type is supported by native serialization" |
| ); |
| } |
| |
| @ParameterizedTest(name = "{0}<{1}>") |
| @MethodSource("collectionTypes") |
| void testMessageWithCollectionNativeTypeField(Class<?> collectionType, Class<?> type) { |
| Compilation compilation = compile(marshallableCollectionSourceCode(collectionType, type)); |
| |
| assertThat(compilation).hadErrorContaining( |
| "\"foo\" field is marked as @Marshallable but this type is supported by native serialization" |
| ); |
| } |
| |
| @Test |
| void testMessageWithMarshallableMapNativeKey() { |
| Compilation compilation = compile(marshallableMapSourceCode(Integer.class, Lock.class)); |
| |
| assertThat(compilation).succeededWithoutWarnings(); |
| } |
| |
| @Test |
| void testMessageWithMarshallableMapNativeValue() { |
| Compilation compilation = compile(marshallableMapSourceCode(Lock.class, Integer.class)); |
| |
| assertThat(compilation).succeededWithoutWarnings(); |
| } |
| |
| @Test |
| void testMessageWithNativeTypeMap() { |
| Compilation compilation = compile(marshallableMapSourceCode(Integer.class, String.class)); |
| |
| assertThat(compilation).hadErrorContaining( |
| "\"foo\" field is marked as @Marshallable but this type is supported by native serialization" |
| ); |
| } |
| |
| @Test |
| void testMessageWithNestedNativeTypeMap() { |
| Compilation compilation = compile(marshallableNestedMapSourceCode(Integer.class, String.class)); |
| |
| assertThat(compilation).hadErrorContaining( |
| "\"foo\" field is marked as @Marshallable but this type is supported by native serialization" |
| ); |
| } |
| |
| @Test |
| void testMessageWithNestedMarshallableTypeMap() { |
| Compilation compilation = compile(marshallableNestedMapSourceCode(Integer.class, Lock.class)); |
| |
| assertThat(compilation).succeededWithoutWarnings(); |
| } |
| |
| private Compilation compile(List<String> code) { |
| return compiler.compile( |
| forSourceLines("org.apache.ignite.internal.network.processor.TestMessage", code), |
| MESSAGE_GROUP |
| ); |
| } |
| } |