Adds testcase for PR policy checks
This commit is contained in:
1 parent
2d681d6c2d
commit
6d986b8967
6 files changed
+187
-3
No files matched your search
@@ -0,0 +1,28 @@
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
ColumnLimit: 120
|
||||
Language: Cpp
|
||||
Standard: c++20
|
||||
PointerAlignment: Left
|
||||
ReferenceAlignment: Left
|
||||
SortIncludes: true
|
||||
IncludeBlocks: Regroup
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterStruct: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
NamespaceIndentation: None
|
||||
IndentCaseLabels: true
|
||||
AlignTrailingComments: true
|
||||
SeparateDefinitionBlocks: Always
|
||||
SpaceBeforeParens: ControlStatements
|
||||
Cpp11BracedListStyle: true
|
||||
@@ -0,0 +1,7 @@
|
||||
enable_testing()
|
||||
|
||||
add_executable(test_main tests/test_main.cpp)
|
||||
target_link_libraries(test_main GTest::gtest_main)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(test_main)
|
||||
@@ -0,0 +1,16 @@
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
python3 \
|
||||
clang-format \
|
||||
cmake \
|
||||
ninja-build \
|
||||
git \
|
||||
build-essential \
|
||||
ca-certificates && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /workspace
|
||||
Vendored
+39
-3
@@ -1,23 +1,59 @@
|
||||
pipeline {
|
||||
agent any
|
||||
agent {
|
||||
dockerfile {
|
||||
filename 'Dockerfile.ci'
|
||||
reuseNode true
|
||||
}
|
||||
}
|
||||
|
||||
options {
|
||||
skipDefaultCheckout()
|
||||
timestamps()
|
||||
disableConcurrentBuilds()
|
||||
}
|
||||
|
||||
environment {
|
||||
BUILD_DIR = "build"
|
||||
CHANGE_TARGET = "${env.CHANGE_TARGET ?: 'origin/main'}"
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
checkout scm
|
||||
sh 'git fetch --all --prune'
|
||||
sh 'git submodule update --init --recursive || true'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Policy Checks') {
|
||||
steps {
|
||||
sh 'python3 ci/check_pr_policies.py'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Configure') {
|
||||
steps {
|
||||
sh 'cmake -S . -B ${BUILD_DIR} -G Ninja -DCMAKE_BUILD_TYPE=Debug'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'echo Build works'
|
||||
sh 'cmake --build ${BUILD_DIR} --parallel'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh 'echo Tests work'
|
||||
sh 'ctest --test-dir ${BUILD_DIR} --output-on-failure'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
cleanWs deleteDirs: true, disableDeferredWipeout: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(".").resolve()
|
||||
TEST_DIR = ROOT / "tests"
|
||||
CPP_EXTENSIONS = {".c", ".cc", ".cpp", ".cxx", ".h", ".hh", ".hpp", ".hxx"}
|
||||
|
||||
TEST_PATTERNS = [
|
||||
"test_{name}.cpp",
|
||||
"test_{name}.h",
|
||||
"{name}_test.cpp",
|
||||
"{name}_test.h",
|
||||
"{name}test.cpp",
|
||||
"{name}test.h",
|
||||
"{name}gtest.cpp",
|
||||
"{name}gtest.h",
|
||||
]
|
||||
|
||||
def run(cmd: str) -> str:
|
||||
return subprocess.check_output(cmd, shell=True, text=True).strip()
|
||||
|
||||
def changed_files():
|
||||
target = os.environ.get("CHANGE_TARGET", "origin/main")
|
||||
out = run(f"git diff --name-only {target}...HEAD")
|
||||
return [line.strip() for line in out.splitlines() if line.strip()]
|
||||
|
||||
def is_cpp_file(path: Path) -> bool:
|
||||
return path.suffix.lower() in CPP_EXTENSIONS
|
||||
|
||||
def require_clang_format():
|
||||
if not (ROOT / ".clang-format").exists():
|
||||
print("ERROR: .clang-format fehlt im Repository-Root.")
|
||||
sys.exit(1)
|
||||
|
||||
def check_format(path: Path):
|
||||
subprocess.check_call(f"clang-format --dry-run --Werror '{path}'", shell=True)
|
||||
|
||||
def candidate_names(path: Path):
|
||||
stem = path.stem.lower()
|
||||
names = {stem}
|
||||
for suffix in ["_p", "_impl", "_private", "_priv", "_ui"]:
|
||||
if stem.endswith(suffix):
|
||||
names.add(stem[:-len(suffix)])
|
||||
return sorted(n for n in names if n)
|
||||
|
||||
def has_related_test(path: Path) -> bool:
|
||||
if not TEST_DIR.exists():
|
||||
return False
|
||||
|
||||
test_files = [p for p in TEST_DIR.rglob("*") if p.is_file()]
|
||||
test_names = [p.name.lower() for p in test_files]
|
||||
|
||||
for name in candidate_names(path):
|
||||
for pattern in TEST_PATTERNS:
|
||||
if pattern.format(name=name).lower() in test_names:
|
||||
return True
|
||||
for test_name in test_names:
|
||||
if name in test_name and ("test" in test_name or "gtest" in test_name):
|
||||
return True
|
||||
return False
|
||||
|
||||
def main():
|
||||
require_clang_format()
|
||||
|
||||
files = changed_files()
|
||||
if not files:
|
||||
print("Keine geänderten Dateien erkannt.")
|
||||
return
|
||||
|
||||
for rel in files:
|
||||
path = ROOT / rel
|
||||
if not path.exists():
|
||||
continue
|
||||
if is_cpp_file(path):
|
||||
print(f"Prüfe: {rel}")
|
||||
try:
|
||||
check_format(path)
|
||||
except subprocess.CalledProcessError:
|
||||
print(f"ERROR: Formatfehler in {rel}")
|
||||
sys.exit(1)
|
||||
|
||||
if not has_related_test(path):
|
||||
print(f"ERROR: Kein passender Test unter tests/ für {rel} gefunden.")
|
||||
sys.exit(1)
|
||||
|
||||
print("Policy-Checks erfolgreich.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,5 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(MainTest, Smoke) {
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
Reference in new issue
Block a user