mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Swift: locally run integration tests
Minimal recreations of internal `integration-tests-runner.py` and `create_database_utils.py` are provided to be able to run the integration tests on the codeql repository with a released codeql CLI. For the moment we skip the database checks by default, as we are still producing inconsistent results.
This commit is contained in:
32
.github/workflows/swift-integration-tests.yml
vendored
Normal file
32
.github/workflows/swift-integration-tests.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: "Swift: Run Integration Tests"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "swift/**"
|
||||
- .github/workflows/swift-integration-tests.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
defaults:
|
||||
run:
|
||||
working-directory: swift
|
||||
|
||||
jobs:
|
||||
integration-tests:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os : [ubuntu-20.04, macos-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/fetch-codeql
|
||||
- uses: bazelbuild/setup-bazelisk@v2
|
||||
- uses: actions/setup-python@v3
|
||||
- name: Build Swift extractor
|
||||
run: |
|
||||
bazel run //swift:create-extractor-pack
|
||||
- name: Run integration tests
|
||||
run: |
|
||||
python integration-tests/runner.py
|
||||
1
swift/integration-tests/.gitignore
vendored
1
swift/integration-tests/.gitignore
vendored
@@ -6,3 +6,4 @@ xcuserdata/
|
||||
DerivedData/
|
||||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||
*.actual
|
||||
db
|
||||
|
||||
26
swift/integration-tests/create_database_utils.py
Normal file
26
swift/integration-tests/create_database_utils.py
Normal file
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
recreation of internal `create_database_utils.py` to run the tests locally, with minimal
|
||||
and swift-specialized functionality
|
||||
"""
|
||||
import subprocess
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
|
||||
def run_codeql_database_create(cmds, lang, keep_trap=True):
|
||||
assert lang == 'swift'
|
||||
codeql_root = pathlib.Path(__file__).parents[2]
|
||||
cmd = [
|
||||
"codeql", "database", "create",
|
||||
"-s", ".", "-l", "swift", "--internal-use-lua-tracing", f"--search-path={codeql_root}",
|
||||
]
|
||||
if keep_trap:
|
||||
cmd.append("--keep-trap")
|
||||
for c in cmds:
|
||||
cmd += ["-c", c]
|
||||
cmd.append("db")
|
||||
res = subprocess.run(cmd)
|
||||
if res.returncode:
|
||||
print("FAILED", file=sys.stderr)
|
||||
print(" ", *cmd, file=sys.stderr)
|
||||
sys.exit(res.returncode)
|
||||
@@ -1,4 +0,0 @@
|
||||
| Sources/cross-references/lib.swift:1:1:1:11 | f |
|
||||
| Sources/cross-references/lib.swift:17:8:19:1 | ~ |
|
||||
| Sources/cross-references/lib.swift:22:9:24:1 | ~ |
|
||||
| Sources/cross-references/lib.swift:27:1:29:1 | ~ |
|
||||
@@ -0,0 +1,4 @@
|
||||
| Sources/cross-references/lib.swift:1:1:1:11 | f() |
|
||||
| Sources/cross-references/lib.swift:17:8:19:1 | ~(_:) |
|
||||
| Sources/cross-references/lib.swift:22:9:24:1 | ~(_:) |
|
||||
| Sources/cross-references/lib.swift:27:1:29:1 | ~(_:_:) |
|
||||
@@ -27,4 +27,3 @@ infix operator ~
|
||||
func ~(lhs: Int, rhs: Int) -> Int {
|
||||
return lhs
|
||||
}
|
||||
|
||||
@@ -15,4 +15,3 @@ struct s : P {}
|
||||
42~
|
||||
|
||||
15 ~ 42
|
||||
|
||||
80
swift/integration-tests/runner.py
Executable file
80
swift/integration-tests/runner.py
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/bin/env python3
|
||||
"""
|
||||
recreation of internal `integration-tests-runner.py` to run the tests locally, with minimal
|
||||
and swift-specialized functionality.
|
||||
|
||||
This runner requires:
|
||||
* a codeql CLI binary in PATH
|
||||
* `bazel run //swift:create_extractor_pack` to have been run
|
||||
"""
|
||||
|
||||
import pathlib
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import argparse
|
||||
import shutil
|
||||
import platform
|
||||
|
||||
this_dir = pathlib.Path(__file__).parent
|
||||
|
||||
|
||||
def options():
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument("--test-dir", "-d", type=pathlib.Path, action="append")
|
||||
#FIXME: the following should be the default
|
||||
p.add_argument("--check-databases", action="store_true")
|
||||
p.add_argument("--learn", action="store_true")
|
||||
p.add_argument("--threads", "-j", type=int, default=0)
|
||||
return p.parse_args()
|
||||
|
||||
|
||||
def execute_test(path):
|
||||
shutil.rmtree(path.parent / "db", ignore_errors=True)
|
||||
return subprocess.run([sys.executable, "-u", path.name], cwd=path.parent).returncode == 0
|
||||
|
||||
def skipped(test):
|
||||
return platform.system() != "Darwin" and "osx-only" in test.parts
|
||||
|
||||
|
||||
def main(opts):
|
||||
test_dirs = opts.test_dir or [this_dir]
|
||||
tests = [t for d in test_dirs for t in d.rglob("test.py") if not skipped(t)]
|
||||
|
||||
if not tests:
|
||||
print("No tests found", file=sys.stderr)
|
||||
return False
|
||||
|
||||
os.environ["PYTHONPATH"] = str(this_dir)
|
||||
failed_db_creation = []
|
||||
succesful_db_creation = []
|
||||
for t in tests:
|
||||
(succesful_db_creation if execute_test(t) else failed_db_creation).append(t)
|
||||
|
||||
if succesful_db_creation:
|
||||
codeql_root = this_dir.parents[1]
|
||||
cmd = [
|
||||
"codeql", "test", "run",
|
||||
f"--search-path={codeql_root}",
|
||||
"--keep-databases",
|
||||
"--dataset=db/db-swift",
|
||||
f"--threads={opts.threads}",
|
||||
]
|
||||
if opts.check_databases:
|
||||
cmd.append("--check-databases")
|
||||
if opts.learn:
|
||||
cmd.append("--learn")
|
||||
cmd.extend(str(t.parent) for t in succesful_db_creation)
|
||||
ql_test_success = subprocess.run(cmd).returncode == 0
|
||||
|
||||
if failed_db_creation:
|
||||
print("Database creation failed:", file=sys.stderr)
|
||||
for t in failed_db_creation:
|
||||
print(" ", t.parent, file=sys.stderr)
|
||||
return False
|
||||
|
||||
return ql_test_success
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(0 if main(options()) else 1)
|
||||
Reference in New Issue
Block a user