This is an automated email from the ASF dual-hosted git repository.

apolovtsev pushed a commit to branch ignite-20086
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit 0beda7a18a8c8db934a4476a7b5fe5cf11edc601
Author: amashenkov <[email protected]>
AuthorDate: Fri Jul 28 19:45:17 2023 +0300

    Implement ArchUnit rule to detect wrong test classes hierarchy.
---
 .../internal/TestClassHierarchyArchTest.java       | 65 ++++++++++++++++++++++
 .../ignite/lang/TestsWithFixturesImportOption.java | 38 +++++++++++++
 2 files changed, 103 insertions(+)

diff --git 
a/modules/arch-test/src/test/java/org/apache/ignite/internal/TestClassHierarchyArchTest.java
 
b/modules/arch-test/src/test/java/org/apache/ignite/internal/TestClassHierarchyArchTest.java
new file mode 100644
index 0000000000..915cb1b01f
--- /dev/null
+++ 
b/modules/arch-test/src/test/java/org/apache/ignite/internal/TestClassHierarchyArchTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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;
+
+import static 
com.tngtech.archunit.core.domain.properties.CanBeAnnotated.Predicates.annotatedWith;
+
+import com.tngtech.archunit.base.DescribedPredicate;
+import com.tngtech.archunit.core.domain.AccessTarget;
+import com.tngtech.archunit.core.domain.JavaCall;
+import com.tngtech.archunit.core.domain.JavaClass.Functions;
+import com.tngtech.archunit.core.domain.JavaClass.Predicates;
+import com.tngtech.archunit.core.domain.properties.HasName;
+import com.tngtech.archunit.junit.AnalyzeClasses;
+import com.tngtech.archunit.junit.ArchTest;
+import com.tngtech.archunit.lang.ArchRule;
+import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
+import org.apache.ignite.lang.LocationProvider.RootLocationProvider;
+import org.apache.ignite.lang.TestsWithFixturesImportOption;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+
+/**
+ * Tests that tests classes, which uses Mockito spies, extends 
BaseIgniteAbstractTest. Using BaseIgniteAbstractTest guarantees the Mockito
+ * resources will be released after tests finishes.
+ */
+@SuppressWarnings("JUnitTestCaseWithNoTests")
+@AnalyzeClasses(
+        packages = "org.apache.ignite",
+        importOptions = TestsWithFixturesImportOption.class,
+        locations = RootLocationProvider.class)
+public class TestClassHierarchyArchTest {
+    private static final String BASE_IGNITE_ABSTRACT_TEST_CLASSNAME = 
"org.apache.ignite.internal.testframework.BaseIgniteAbstractTest";
+
+    @ArchTest
+    public static final ArchRule TEST_CLASS_WITH_MOCKS_EXTENDS_BASE_TEST_CLASS 
= ArchRuleDefinition
+            .classes()
+            // are classes with tests
+            
.that(Predicates.containAnyMethodsThat(annotatedWith(Test.class).or(annotatedWith(ParameterizedTest.class))))
+            // uses Mockito framework
+            
.and(Functions.GET_METHOD_CALLS_FROM_SELF.is(DescribedPredicate.anyElementThat(
+                    JavaCall.Predicates.target(
+                            
AccessTarget.Predicates.declaredIn("org.mockito.Mockito")
+                                    .and(HasName.Predicates.name("spy"))
+                    )
+            )))
+            .should()
+            .beAssignableTo(BASE_IGNITE_ABSTRACT_TEST_CLASSNAME)
+            .as("Test classes, which use Mockito spies, must extends 
BaseIgniteAbstractTest")
+            .allowEmptyShould(true);
+}
diff --git 
a/modules/arch-test/src/test/java/org/apache/ignite/lang/TestsWithFixturesImportOption.java
 
b/modules/arch-test/src/test/java/org/apache/ignite/lang/TestsWithFixturesImportOption.java
new file mode 100644
index 0000000000..4954fde668
--- /dev/null
+++ 
b/modules/arch-test/src/test/java/org/apache/ignite/lang/TestsWithFixturesImportOption.java
@@ -0,0 +1,38 @@
+/*
+ * 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.lang;
+
+import com.tngtech.archunit.core.importer.ImportOption;
+import com.tngtech.archunit.core.importer.Location;
+import java.util.regex.Pattern;
+
+/**
+ * Provide the ability to evaluate every class location, to determine if the 
class should be treated as a test fixture class.
+ */
+public class TestsWithFixturesImportOption implements ImportOption {
+    private static final Pattern fixturesTestPattern = 
Pattern.compile(".*/build/classes/([^/]+/)testFixtures/.*");
+    private static final Pattern integrationTestPattern = 
Pattern.compile(".*/build/classes/([^/]+/)integrationTest/.*");
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean includes(Location location) {
+        return Predefined.ONLY_INCLUDE_TESTS.includes(location)
+                || location.matches(integrationTestPattern)
+                || location.matches(fixturesTestPattern);
+    }
+}

Reply via email to