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:
Paolo Tranquilli
2022-07-01 13:39:28 +02:00
parent 5b5a52fa25
commit 901e066355
53 changed files with 143 additions and 6 deletions

View 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

View File

@@ -6,3 +6,4 @@ xcuserdata/
DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
*.actual
db

View 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)

View File

@@ -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 | ~ |

View File

@@ -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 | ~(_:_:) |

View 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)