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

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 182b236e7bf Add more test cases on FirebirdArchTypeTest (#38154)
182b236e7bf is described below

commit 182b236e7bf3e620b94a70ca7d794d18e5252337
Author: Liang Zhang <[email protected]>
AuthorDate: Mon Feb 23 12:43:52 2026 +0800

    Add more test cases on FirebirdArchTypeTest (#38154)
---
 .codex/skills/gen-ut/SKILL.md                      |  49 ++++++++++
 .../firebird/constant/FirebirdArchTypeTest.java    | 106 +++++++++++++++++++--
 2 files changed, 147 insertions(+), 8 deletions(-)

diff --git a/.codex/skills/gen-ut/SKILL.md b/.codex/skills/gen-ut/SKILL.md
index f20dcab7fdd..c56bbee1075 100644
--- a/.codex/skills/gen-ut/SKILL.md
+++ b/.codex/skills/gen-ut/SKILL.md
@@ -157,6 +157,8 @@ Module resolution order:
 
 - `R14`: boolean assertion hard gate
   - Boolean literal/boolean constant assertions `MUST` use 
`assertTrue`/`assertFalse`.
+  - For boolean assertions where expected value is variable-driven (for 
example: parameter/local variable/field), `MUST` use `assertThat(actual, 
is(expected))`.
+  - `MUST NOT` dispatch boolean assertions through control flow (for example 
`if/else`, `switch`, or ternary) only to choose between `assertTrue` and 
`assertFalse`.
   - `MUST NOT` use:
     - `assertThat(<boolean expression>, 
is(true|false|Boolean.TRUE|Boolean.FALSE))`
     - `assertEquals(true|false|Boolean.TRUE|Boolean.FALSE, ...)`
@@ -171,6 +173,7 @@ Module resolution order:
   - `R15-E` (parameterized name parameter): each `@ParameterizedTest` method 
`MUST` declare the first parameter exactly as `final String name`.
   - `R15-F` (parameterized switch ban): `@ParameterizedTest` method bodies 
`MUST NOT` contain `switch` statements.
   - `R15-G` (parameterized nested-type ban): when a file contains 
`@ParameterizedTest`, newly introduced diff lines `MUST NOT` add nested helper 
type declarations (`class` / `interface` / `enum` / `record`) inside the test 
class.
+  - `R15-H` (boolean variable assertion style): for variable-driven boolean 
expectations, tests `MUST` assert with `assertThat(actual, is(expected))`, and 
`MUST NOT` use control-flow dispatch only to choose `assertTrue`/`assertFalse`.
 
 ## Workflow
 
@@ -574,6 +577,52 @@ if rg -n -U --pcre2 "$BOOLEAN_ASSERTION_BAN_REGEX" 
<ResolvedTestFileSet>; then
 fi'
 ```
 
+6.1 `R15-H` boolean control-flow dispatch scan:
+```bash
+bash -lc '
+python3 - <ResolvedTestFileSet> <<'"'"'PY'"'"'
+import re
+import sys
+from pathlib import Path
+
+METHOD_DECL_PATTERN = 
re.compile(r"(?:@Test|@ParameterizedTest(?:\\s*\\([^)]*\\))?(?:\\s*@\\w+(?:\\s*\\([^)]*\\))?)*)\\s*void\\s+(assert\\w+)\\s*\\([^)]*\\)\\s*\\{",
 re.S)
+IF_ELSE_PATTERN = 
re.compile(r"if\\s*\\([^)]*\\)\\s*\\{[\\s\\S]*?assertTrue\\s*\\([^;]+\\)\\s*;[\\s\\S]*?\\}\\s*else\\s*\\{[\\s\\S]*?assertFalse\\s*\\([^;]+\\)\\s*;[\\s\\S]*?\\}|if\\s*\\([^)]*\\)\\s*\\{[\\s\\S]*?assertFalse\\s*\\([^;]+\\)\\s*;[\\s\\S]*?\\}\\s*else\\s*\\{[\\s\\S]*?assertTrue\\s*\\([^;]+\\)\\s*;[\\s\\S]*?\\}",
 re.S)
+IF_RETURN_PATTERN = 
re.compile(r"if\\s*\\([^)]*\\)\\s*\\{[\\s\\S]*?assertTrue\\s*\\([^;]+\\)\\s*;[\\s\\S]*?return\\s*;[\\s\\S]*?\\}\\s*assertFalse\\s*\\([^;]+\\)\\s*;|if\\s*\\([^)]*\\)\\s*\\{[\\s\\S]*?assertFalse\\s*\\([^;]+\\)\\s*;[\\s\\S]*?return\\s*;[\\s\\S]*?\\}\\s*assertTrue\\s*\\([^;]+\\)\\s*;",
 re.S)
+
+def extract_block(text, brace_index):
+    depth = 0
+    i = brace_index
+    while i < len(text):
+        if "{" == text[i]:
+            depth += 1
+        elif "}" == text[i]:
+            depth -= 1
+            if 0 == depth:
+                return text[brace_index + 1:i]
+        i += 1
+    return ""
+
+violations = []
+for path in (each for each in sys.argv[1:] if each.endswith(".java")):
+    source = Path(path).read_text(encoding="utf-8")
+    for match in METHOD_DECL_PATTERN.finditer(source):
+        method_name = match.group(1)
+        line = source.count("\\n", 0, match.start()) + 1
+        brace_index = source.find("{", match.start())
+        if brace_index < 0:
+            continue
+        body = extract_block(source, brace_index)
+        if IF_ELSE_PATTERN.search(body) or IF_RETURN_PATTERN.search(body):
+            violations.append(f"{path}:{line} method={method_name}")
+if violations:
+    print("[R15-H] do not dispatch boolean assertions by control flow to 
choose assertTrue/assertFalse")
+    for each in violations:
+        print(each)
+    sys.exit(1)
+PY
+'
+```
+
 7. `R15-B` metadata accessor test ban scan (skip only when explicitly 
requested by user):
 ```bash
 bash -lc '
diff --git 
a/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/constant/FirebirdArchTypeTest.java
 
b/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/constant/FirebirdArchTypeTest.java
index 997ec448389..0c7cff1b7ae 100644
--- 
a/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/constant/FirebirdArchTypeTest.java
+++ 
b/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/constant/FirebirdArchTypeTest.java
@@ -18,24 +18,114 @@
 package org.apache.shardingsphere.database.protocol.firebird.constant;
 
 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Paths;
+import java.util.stream.Stream;
 
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 
 class FirebirdArchTypeTest {
     
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("valueOfCases")
+    void assertValueOf(final String name, final int code, final 
FirebirdArchType expected) {
+        assertThat(FirebirdArchType.valueOf(code), is(expected));
+    }
+    
     @Test
-    void assertValueOf() {
-        assertThat(FirebirdArchType.valueOf(29), 
is(FirebirdArchType.ARCH_INTEL_32));
+    void assertValueOfWithInvalidCode() {
         assertThrows(NullPointerException.class, () -> 
FirebirdArchType.valueOf(999));
     }
     
-    @Test
-    void assertIsValid() {
-        assertTrue(FirebirdArchType.isValid(FirebirdArchType.ARCHITECTURE));
-        assertFalse(FirebirdArchType.isValid(FirebirdArchType.ARCH_ARM));
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("isValidCases")
+    void assertIsValid(final String name, final FirebirdArchType arch, final 
boolean expectedValid) {
+        assertThat(FirebirdArchType.isValid(arch), is(expectedValid));
+    }
+    
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("architectureCases")
+    void assertArchitecture(final String name, final String osName, final 
String osArch, final String expectedArchitecture) throws 
ReflectiveOperationException, IOException {
+        assertThat(resolveArchitectureByEnvironment(osName, osArch), 
is(expectedArchitecture));
+    }
+    
+    private String resolveArchitectureByEnvironment(final String osName, final 
String osArch) throws ReflectiveOperationException, IOException {
+        String originalOsName = System.getProperty("os.name");
+        String originalOsArch = System.getProperty("os.arch");
+        try {
+            setOrClearProperty("os.name", osName);
+            setOrClearProperty("os.arch", osArch);
+            try (URLClassLoader classLoader = new 
URLClassLoader(classPathUrls(), null)) {
+                Class<?> archTypeClass = 
Class.forName(FirebirdArchType.class.getName(), true, classLoader);
+                Object architecture = 
archTypeClass.getField("ARCHITECTURE").get(null);
+                return ((Enum<?>) architecture).name();
+            }
+        } finally {
+            setOrClearProperty("os.name", originalOsName);
+            setOrClearProperty("os.arch", originalOsArch);
+        }
+    }
+    
+    private void setOrClearProperty(final String key, final String value) {
+        if (null == value) {
+            System.clearProperty(key);
+            return;
+        }
+        System.setProperty(key, value);
+    }
+    
+    private URL[] classPathUrls() throws MalformedURLException {
+        String[] classPathEntries = 
System.getProperty("java.class.path").split(File.pathSeparator);
+        URL[] result = new URL[classPathEntries.length];
+        for (int i = 0; i < classPathEntries.length; i++) {
+            result[i] = Paths.get(classPathEntries[i]).toUri().toURL();
+        }
+        return result;
+    }
+    
+    private static Stream<Arguments> valueOfCases() {
+        return Stream.of(
+                Arguments.of("resolve ARCH_GENERIC by code", 1, 
FirebirdArchType.ARCH_GENERIC),
+                Arguments.of("resolve ARCH_INTEL_32 by code", 29, 
FirebirdArchType.ARCH_INTEL_32),
+                Arguments.of("resolve duplicate linux code to ARCH_LINUX", 36, 
FirebirdArchType.ARCH_LINUX));
+    }
+    
+    private static Stream<Arguments> isValidCases() {
+        return Stream.of(
+                Arguments.of("ARCH_GENERIC is valid", 
FirebirdArchType.ARCH_GENERIC, true),
+                Arguments.of("ARCHITECTURE is valid", 
FirebirdArchType.ARCHITECTURE, true),
+                Arguments.of("ARCH_MAX is not valid", 
FirebirdArchType.ARCH_MAX, false));
+    }
+    
+    private static Stream<Arguments> architectureCases() {
+        return Stream.of(
+                Arguments.of("sun sparc maps to ARCH_SUN4", "SunOS", "sparc", 
"ARCH_SUN4"),
+                Arguments.of("sun amd64 maps to ARCH_SUNX86", "SunOS", 
"amd64", "ARCH_SUNX86"),
+                Arguments.of("sun unknown arch maps to ARCH_SUN", "SunOS", 
"mips", "ARCH_SUN"),
+                Arguments.of("hpux maps to ARCH_HPUX", "HP-UX", "ia64", 
"ARCH_HPUX"),
+                Arguments.of("aix maps to ARCH_RT", "AIX", "ppc", "ARCH_RT"),
+                Arguments.of("linux loong maps to ARCH_LINUX_LOONG", "Linux", 
"loongarch64", "ARCH_LINUX_LOONG"),
+                Arguments.of("linux non loong maps to ARCH_LINUX", "Linux", 
"x86_64", "ARCH_LINUX"),
+                Arguments.of("freebsd maps to ARCH_FREEBSD", "FreeBSD", 
"amd64", "ARCH_FREEBSD"),
+                Arguments.of("netbsd maps to ARCH_NETBSD", "NetBSD", "amd64", 
"ARCH_NETBSD"),
+                Arguments.of("mac powerpc maps to ARCH_DARWIN_PPC", "Mac OS 
X", "powerpc", "ARCH_DARWIN_PPC"),
+                Arguments.of("darwin ppc64 maps to ARCH_DARWIN_PPC64", 
"Darwin", "ppc64", "ARCH_DARWIN_PPC64"),
+                Arguments.of("darwin arm maps to ARCH_DARWIN_X64_ARM", 
"Darwin", "aarch64", "ARCH_DARWIN_X64_ARM"),
+                Arguments.of("darwin x64 maps to ARCH_DARWIN_X64", "Darwin", 
"x86_64", "ARCH_DARWIN_X64"),
+                Arguments.of("windows amd64 maps to ARCH_WINNT_64", "Windows 
10", "amd64", "ARCH_WINNT_64"),
+                Arguments.of("windows non amd64 i386 maps to ARCH_INTEL_32", 
"Windows 10", "i386", "ARCH_INTEL_32"),
+                Arguments.of("i386 maps to ARCH_INTEL_32", "Unknown", "i386", 
"ARCH_INTEL_32"),
+                Arguments.of("arm maps to ARCH_ARM", "Unknown", "arm", 
"ARCH_ARM"),
+                Arguments.of("other os and arch maps to ARCH_GENERIC", 
"Unknown", "x86_64", "ARCH_GENERIC"));
     }
 }

Reply via email to