Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion dodo.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,17 @@ def task_crlf_check():
yield {"name": "notsupported", "actions": None}


def task_mypy():
return {
"actions": ["mypy testplan --config-file pyproject.toml"],
"doc": "Run mypy type checking",
}


def task_lint():
return {
"actions": None,
"task_dep": ["ruff_fmt", "pylint", "crlf_check"],
"task_dep": ["ruff_fmt", "pylint", "mypy", "crlf_check"],
"doc": "Run lint on python and javascript code",
}

Expand Down
34 changes: 21 additions & 13 deletions examples/Cpp/HobbesTest/test/hobbes-test
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,47 @@
"""
This is a mock of hobbes-test binary
"""

import argparse
import json
import sys


def main():
parser = argparse.ArgumentParser(description='Start a mock of hobbes-test binary')

parser.add_argument('--list_tests', action='store_true', help='List all tests')
parser.add_argument('--tests', metavar='TEST', nargs='+', help='Specify the tests to run')
parser.add_argument('--json', metavar='JSON_FILE', help='Specify the output json file')
parser = argparse.ArgumentParser(
description="Start a mock of hobbes-test binary"
)

parser.add_argument(
"--list_tests", action="store_true", help="List all tests"
)
parser.add_argument(
"--tests", metavar="TEST", nargs="+", help="Specify the tests to run"
)
parser.add_argument(
"--json", metavar="JSON_FILE", help="Specify the output json file"
)

args, _ = parser.parse_known_args()

with open('input.json') as fp:
with open("input.json") as fp:
test_data = json.load(fp)

if args.list_tests:
print('\n'.join([test['name'] for test in test_data]))
print("\n".join([test["name"] for test in test_data]))
return

if args.tests:
for test in test_data:
if test['name'] not in args.tests:
for case in test['data']:
case['status'] = 'skipped'
case['duration'] = '0ns'
if test["name"] not in args.tests:
for case in test["data"]:
case["status"] = "skipped"
case["duration"] = "0ns"

if args.json:
with open(args.json, 'w+') as fp:
with open(args.json, "w+") as fp:
json.dump(test_data, fp)


if __name__ == "__main__":
sys.exit(main())

14 changes: 6 additions & 8 deletions install-testplan-ui
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""
Installs & Builds the Testplan UI code.
"""

import argparse
import logging
import os
Expand Down Expand Up @@ -57,9 +58,7 @@ def is_manager_installed(command: str) -> bool:
with open(os.devnull, "w") as FNULL:
try:
subprocess.check_call(
f"{command} --version",
shell=True,
stdout=FNULL
f"{command} --version", shell=True, stdout=FNULL
)
except subprocess.CalledProcessError:
return False
Expand All @@ -68,9 +67,7 @@ def is_manager_installed(command: str) -> bool:


def install_and_build_ui(
path: str = TESTPLAN_UI_DIR,
dev: bool = False,
verbose: bool = False
path: str = TESTPLAN_UI_DIR, dev: bool = False, verbose: bool = False
) -> None:
"""
Installs dependencies & builds the UI code.
Expand All @@ -83,11 +80,12 @@ def install_and_build_ui(
:type verbose: ``bool``
"""

if not is_manager_installed('pnpm'):
if not is_manager_installed("pnpm"):
logging.warning("=" * 54)
logging.warning("PNPM IS NOT INSTALLED.")
logging.warning(
"Testplan UI is built using PNPM, follow instructions at:")
"Testplan UI is built using PNPM, follow instructions at:"
)
logging.warning("https://pnpm.io/installation")
logging.warning("=" * 54)
sys.exit(1)
Expand Down
84 changes: 84 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ all = ["testplan[interactive,observability,plotly]"]
namespaces = false

[tool.setuptools.package-data]
"testplan" = ["py.typed"]
"testplan.web_ui" = ["testing/build/**/*"]
[tool.setuptools.exclude-package-data]
"testplan.web_ui" = ["testing/build/**/*.map"]
Expand Down Expand Up @@ -147,6 +148,9 @@ releaseherald = { git = "https://github.com/morganstanley/releaseherald.git", re
[dependency-groups]
dev = [
"doit>=0.34.2",
"mypy>=1.9.0",
"types-paramiko>=3.0.0",
"types-requests>=2.28.0",
"pre-commit>=2.21.0",
"pylint>=2.13.9",
"pytest-dotenv>=0.5.2",
Expand All @@ -166,6 +170,86 @@ test = [
"numpy>=1.21.6",
]

[tool.mypy]
python_version = "3.9"
warn_return_any = true
warn_unused_configs = true
warn_redundant_casts = true
warn_unused_ignores = true
no_implicit_optional = true
# Start permissive - enable strict per-module as typing progresses
disallow_untyped_defs = false
disallow_incomplete_defs = false
# Ignore missing stubs for third-party libraries without type information
ignore_missing_imports = true

# Exclude vendored code from type checking
[[tool.mypy.overrides]]
module = "testplan.vendor.*"
ignore_errors = true

# Skip type checking of third-party internals (match statements require Python 3.10+)
[[tool.mypy.overrides]]
module = [
"_pytest.*",
"coverage.*",
]
follow_imports = "skip"

# Strictly typed modules - enforced per-module as typing progresses
[[tool.mypy.overrides]]
module = [
"testplan.common.utils.timing",
"testplan.common.utils.logger",
"testplan.common.config.base",
"testplan.common.entity.base",
"testplan.testing.base",
"testplan.testing.multitest.base",
"testplan.runnable.base",
"testplan.report.testing.base",
"testplan.runners.pools.base",
"testplan.testing.multitest.driver.base",
"testplan.common.remote.remote_resource",
"testplan.base",
"testplan.parser",
"testplan.testing.result",
"testplan.runners.local",
"testplan.common.utils.comparison",
"testplan.testing.multitest.driver.app",
"testplan.runners.pools.remote",
"testplan.testing.multitest.entries.assertions",
"testplan.runners.pools.connection",
"testplan.runners.pools.process",
"testplan.testing.multitest.driver.http.server",
"testplan.testing.multitest.driver.connection.connection_extractor",
"testplan.exporters.testing.pdf.renderers.reports",
"testplan.monitor.resource",
"testplan.common.utils.logfile",
"testplan.common.utils.process",
"testplan.common.utils.helper",
"testplan.common.utils.convert",
"testplan.testing.multitest.driver.fix.client",
"testplan.testing.multitest.driver.tcp.client",
"testplan.testing.multitest.driver.kafka",
"testplan.common.utils.sockets.client",
"testplan.common.utils.match",
"testplan.common.remote.remote_runtime",
"testplan.testing.listing",
"testplan.common.remote.ssh_client",
"testplan.common.exporters.pdf",
"testplan.runners.pools.tasks.base",
"testplan.testing.filtering",
"testplan.testing.pyunit",
"testplan.testing.py_test",
"testplan.exporters.testing.xml",
"testplan.testing.multitest.driver.http.client",
"testplan.testing.multitest.driver.connection.connection_info",
"testplan.runnable.interactive.base",
"testplan.common.utils.observability.tracing",
]
disallow_untyped_defs = true
disallow_incomplete_defs = true

[tool.ruff]
line-length = 79
exclude = ["testplan/vendor", "releaseherald"]
Expand Down
Loading
Loading