From 9eb43a50b89f844ae0c1ac23f5d81d6fa816b8eb Mon Sep 17 00:00:00 2001 From: Kim-Adeline Miguel Date: Fri, 19 Nov 2021 11:03:10 -0800 Subject: [PATCH 01/87] Add json-rpc dependency --- requirements.in | 3 +++ requirements.txt | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/requirements.in b/requirements.in index cf488dd47758..6ed7315cf018 100644 --- a/requirements.in +++ b/requirements.in @@ -5,3 +5,6 @@ # Sort Imports isort==5.10.0 + +# Test adapter +json-rpc==1.13.0 diff --git a/requirements.txt b/requirements.txt index 91541236262d..41ce0d64b28b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with python 3.6 +# This file is autogenerated by pip-compile # To update, run: # # pip-compile --generate-hashes requirements.in @@ -8,3 +8,7 @@ isort==5.10.0 \ --hash=sha256:1a18ccace2ed8910bd9458b74a3ecbafd7b2f581301b0ab65cfdd4338272d76f \ --hash=sha256:e52ff6d38012b131628cf0f26c51e7bd3a7c81592eefe3ac71411e692f1b9345 # via -r requirements.in +json-rpc==1.13.0 \ + --hash=sha256:84b45058e5ba95f49c7b6afcf7e03ab86bee89bf2c01f3ad8dd41fe114fc1f84 \ + --hash=sha256:def0dbcf5b7084fc31d677f2f5990d988d06497f2f47f13024274cfb2d5d7589 + # via -r requirements.in From 35a359ea00fb258d3988d487908f02f4e2d7da3e Mon Sep 17 00:00:00 2001 From: Kim-Adeline Miguel Date: Thu, 25 Nov 2021 16:42:44 -0800 Subject: [PATCH 02/87] Basic test discovery (no server yet) --- pythonFiles/unittestadapter/discovery.py | 113 +++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 pythonFiles/unittestadapter/discovery.py diff --git a/pythonFiles/unittestadapter/discovery.py b/pythonFiles/unittestadapter/discovery.py new file mode 100644 index 000000000000..fb493ffdc2bf --- /dev/null +++ b/pythonFiles/unittestadapter/discovery.py @@ -0,0 +1,113 @@ +import getopt +import inspect +import json +import os +import sys +import traceback +import unittest + +from jsonrpc import JSONRPCResponseManager, dispatcher + +sys.path.insert(0, os.getcwd()) + +# Get arguments: -v, -s, -p, -t in that order +argv = sys.argv[1:] +opts, args = getopt.getopt(argv, "vs:p:t:") + +pattern = "test*.py" +top_level_dir = None + +for opt in opts: + if opt[0] == "-s": + start_dir = opt[1] + elif opt[0] == "-p": + pattern = opt[1] + elif opt[0] == "-t": + top_level_dir = opt[1] + +# Helper functions +def get_test_cases(suite): + for test in suite: + if isinstance(test, unittest.TestCase): + yield test + else: + for test_case in get_test_cases(test): + yield test_case + + +def get_source_line(obj): + try: + sourcelines, lineno = inspect.getsourcelines(obj) + except: + try: + sourcelines, lineno = inspect.getsourcelines(obj.orig_method) + except: + return "*" + + # Return the line number of the first line of the test case definition. + for i, v in enumerate(sourcelines): + if v.strip().startswith(("def", "async def")): + return str(lineno + i) + return "*" + + +# Test discovery +payload = {"command": " ".join(sys.argv[:]), "cwd": os.getcwd()} +tests = [] + +try: + loader = unittest.TestLoader() + suite = loader.discover(start_dir, pattern, top_level_dir) + loader_errors = [] + + for test in get_test_cases(suite): + test_id = test.id() + test_method = getattr(test, test._testMethodName) + lineno = get_source_line(test_method) + + # Build payload + if test_id.startswith("unittest.loader._FailedTest"): + loader_errors.append(test._exception.__str__()) + else: + tests.append({"id": test_id, "lineno": lineno}) +except: + payload["status"] = "error" + payload["errors"] = [traceback.format_exc()] + +if len(tests): + payload["tests"] = tests + +if len(loader_errors): + payload["errors"] = loader_errors + +print(json.dumps(payload)) +# Send payload with results +# r = requests.post("http://localhost:8080/", json=payload) +# print(r.text) + + +# Message formatting: +# +# Successful discovery: +# { +# "command":