testgenie-py 0.1.9__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/PKG-INFO +1 -1
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/pyproject.toml +1 -1
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/.coverage +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/controller/docker_controller.py +56 -38
- testgenie_py-0.2.1/testgen/docker/Dockerfile +31 -0
- testgenie_py-0.2.1/testgen/tests/test_boolean.py +69 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/tests/test_decisions.py +68 -50
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/file_utils.py +40 -10
- testgenie_py-0.1.9/testgen/docker/Dockerfile +0 -22
- testgenie_py-0.1.9/testgen/docker/poetry.lock +0 -599
- testgenie_py-0.1.9/testgen/docker/pyproject.toml +0 -29
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/README.md +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/ast_analyzer.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/contracts/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/contracts/contract.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/contracts/no_exception_contract.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/contracts/nonnull_contract.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/fuzz_analyzer.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/random_feedback_analyzer.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/reinforcement_analyzer.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/test_case_analyzer.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/analyzer/test_case_analyzer_context.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/code_to_test/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/code_to_test/boolean.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/code_to_test/calculator.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/code_to_test/code_to_fuzz.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/code_to_test/code_to_fuzz_lite.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/code_to_test/decisions.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/code_to_test/math_utils.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/code_to_test/no_types.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/code_to_test/sample_code_bin.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/controller/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/controller/cli_controller.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/generator/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/generator/code_generator.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/generator/doctest_generator.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/generator/generator.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/generator/pytest_generator.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/generator/test_generator.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/generator/unit_test_generator.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/inspector/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/inspector/inspector.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/main.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/models/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/models/analysis_context.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/models/function_metadata.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/models/generator_context.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/models/test_case.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/presentation/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/presentation/cli_view.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/q_table/global_q_table.json +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/reinforcement/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/reinforcement/abstract_state.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/reinforcement/agent.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/reinforcement/environment.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/reinforcement/statement_coverage_state.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/service/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/service/analysis_service.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/service/cfg_service.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/service/generator_service.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/service/logging_service.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/service/service.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/sqlite/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/sqlite/db.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/sqlite/db_service.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/testgen.db +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/tests/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/tree/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/tree/node.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/tree/tree_utils.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/coverage_utils.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/coverage_visualizer.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/randomizer.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/utils.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/z3_utils/__init__.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/z3_utils/ast_to_z3.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/z3_utils/branch_condition.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/z3_utils/constraint_extractor.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/z3_utils/variable_finder.py +0 -0
- {testgenie_py-0.1.9 → testgenie_py-0.2.1}/testgen/util/z3_utils/z3_test_case.py +0 -0
Binary file
|
@@ -30,6 +30,7 @@ class DockerController:
|
|
30
30
|
def run_in_docker(self, project_root: str, docker_client: DockerClient, args: Namespace) -> bool:
|
31
31
|
self.args = args
|
32
32
|
self.debug_mode = True if args.debug else False
|
33
|
+
|
33
34
|
os.environ["RUNNING_IN_DOCKER"] = "1"
|
34
35
|
|
35
36
|
# Check if Docker image exists, build it if not
|
@@ -41,6 +42,7 @@ class DockerController:
|
|
41
42
|
return False
|
42
43
|
|
43
44
|
docker_args = [args.file_path] + [arg for arg in sys.argv[2:] if arg != "--safe"]
|
45
|
+
docker_args[0] = f"/controller/testgen/code_to_test/{os.path.basename(docker_args[0])}"
|
44
46
|
|
45
47
|
# Run the container with the same arguments
|
46
48
|
try:
|
@@ -51,48 +53,44 @@ class DockerController:
|
|
51
53
|
logs_output = self.get_logs(container)
|
52
54
|
self.debug(logs_output)
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
target_path = os.path.join(os.getcwd(), 'tests')
|
58
|
-
else:
|
59
|
-
target_path = args.output
|
60
|
-
os.makedirs(target_path, exist_ok=True)
|
56
|
+
except Exception as e:
|
57
|
+
print(f"Error running container: {e}")
|
58
|
+
sys.exit(1)
|
61
59
|
|
62
|
-
|
60
|
+
# Create the target directory if it doesn't exist
|
61
|
+
if args.output is None:
|
62
|
+
target_path = os.path.join(os.getcwd(), 'tests')
|
63
|
+
else:
|
64
|
+
target_path = args.output
|
65
|
+
os.makedirs(target_path, exist_ok=True)
|
63
66
|
|
64
|
-
|
67
|
+
self.debug(f"SERVICE target path after logs: {target_path}")
|
65
68
|
|
66
|
-
|
69
|
+
test_cases = self.service.parse_test_cases_from_logs(logs_output)
|
67
70
|
|
68
|
-
|
69
|
-
self.debug(f"Filepath in CLI CONTROLLER: {file_path}")
|
70
|
-
self.service.set_file_path(file_path)
|
71
|
+
print(f"Extracted {len(test_cases)} test cases from container.")
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
self.service.set_test_generator_format(DOCTEST_FORMAT)
|
76
|
-
else:
|
77
|
-
self.service.set_test_generator_format(UNITTEST_FORMAT)
|
73
|
+
file_path = os.path.abspath(args.file_path)
|
74
|
+
self.debug(f"Filepath in CLI CONTROLLER: {file_path}")
|
75
|
+
self.service.set_file_path(file_path)
|
78
76
|
|
79
|
-
|
80
|
-
|
77
|
+
if args.test_format == "pytest":
|
78
|
+
self.service.set_test_generator_format(PYTEST_FORMAT)
|
79
|
+
elif args.test_format == "doctest":
|
80
|
+
self.service.set_test_generator_format(DOCTEST_FORMAT)
|
81
|
+
else:
|
82
|
+
self.service.set_test_generator_format(UNITTEST_FORMAT)
|
81
83
|
|
82
|
-
|
83
|
-
|
84
|
-
self.service.run_coverage(test_file)
|
85
|
-
|
86
|
-
# Add explicit return True here
|
87
|
-
return True
|
84
|
+
test_file = self.service.generate_test_file(test_cases, target_path)
|
85
|
+
print(f"Unit tests saved to: {test_file}")
|
88
86
|
|
89
|
-
|
90
|
-
|
91
|
-
|
87
|
+
if not args.generate_only:
|
88
|
+
print("Running coverage...")
|
89
|
+
self.service.run_coverage(test_file)
|
90
|
+
|
91
|
+
# Add explicit return True here
|
92
|
+
return True
|
92
93
|
|
93
|
-
except Exception as e:
|
94
|
-
print(f"Error running container: {e}")
|
95
|
-
sys.exit(1)
|
96
94
|
|
97
95
|
def get_image(self, docker_client: DockerClient, image_name: str, project_root: str):
|
98
96
|
try:
|
@@ -129,15 +127,30 @@ class DockerController:
|
|
129
127
|
# Create Docker-specific environment variables
|
130
128
|
docker_env = {
|
131
129
|
"RUNNING_IN_DOCKER": "1",
|
132
|
-
"PYTHONPATH": "/controller"
|
133
|
-
"COVERAGE_FILE": "/tmp/.coverage", # Move coverage file to /tmp
|
134
|
-
"DB_PATH": "/tmp/testgen.db" # Move DB to /tmp
|
130
|
+
"PYTHONPATH": "/controller"
|
135
131
|
}
|
136
132
|
|
133
|
+
# Join arguments with proper escaping
|
134
|
+
args_str = ' '.join(f'"{arg}"' for arg in docker_args)
|
135
|
+
|
136
|
+
print(f"Docker args: {docker_args}")
|
137
|
+
print(f"Project root: {project_root}")
|
138
|
+
|
139
|
+
# Debug command to find file and then run testgenie with args
|
140
|
+
debug_cmd = f'find /controller -type f -name "*.py" | grep -i boolean || echo "File not found"; ' \
|
141
|
+
f'ls -la /controller; ' \
|
142
|
+
f'testgenie /controller/testgen/code_to_test/boolean.py --test-mode=fuzz --test-format=pytest'
|
143
|
+
|
137
144
|
return docker_client.containers.run(
|
138
145
|
image=image_name,
|
139
|
-
command=["
|
140
|
-
volumes={
|
146
|
+
command=["sh", "-c", debug_cmd],
|
147
|
+
volumes={
|
148
|
+
os.path.abspath(project_root): {
|
149
|
+
"bind": "/controller",
|
150
|
+
"mode": "rw"
|
151
|
+
}
|
152
|
+
},
|
153
|
+
working_dir="/controller",
|
141
154
|
environment=docker_env,
|
142
155
|
detach=True,
|
143
156
|
remove=True,
|
@@ -203,6 +216,11 @@ class DockerController:
|
|
203
216
|
print("Dockerfile not found in local project or package.")
|
204
217
|
sys.exit(1)
|
205
218
|
|
219
|
+
@staticmethod
|
220
|
+
def is_inside_docker() -> bool:
|
221
|
+
"""Check if the current process is running inside a Docker container."""
|
222
|
+
return os.environ.get("RUNNING_IN_DOCKER") in ("1", "true", "True")
|
223
|
+
|
206
224
|
def debug(self, message: str):
|
207
225
|
"""Log debug message"""
|
208
226
|
if self.debug_mode:
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Use Python 3.10 image
|
2
|
+
FROM python:3.10
|
3
|
+
|
4
|
+
# Install system dependencies
|
5
|
+
RUN apt-get update && apt-get install -y \
|
6
|
+
build-essential \
|
7
|
+
graphviz \
|
8
|
+
libgraphviz-dev \
|
9
|
+
pkg-config \
|
10
|
+
curl
|
11
|
+
|
12
|
+
# Install Poetry (optional, in case you ever need it)
|
13
|
+
RUN curl -sSL https://install.python-poetry.org | python3 - && \
|
14
|
+
ln -s /root/.local/bin/poetry /usr/local/bin/poetry
|
15
|
+
|
16
|
+
# Set environment variables
|
17
|
+
ENV POETRY_VIRTUALENVS_CREATE=false \
|
18
|
+
PYTHONUNBUFFERED=1 \
|
19
|
+
RUNNING_IN_DOCKER=true
|
20
|
+
|
21
|
+
# Install your package from PyPI
|
22
|
+
RUN python3 -m pip install --no-cache-dir testgenie-py
|
23
|
+
|
24
|
+
# Set a working directory (where your code will be mounted at runtime)
|
25
|
+
WORKDIR /controller
|
26
|
+
|
27
|
+
# Set up PYTHONPATH
|
28
|
+
ENV PYTHONPATH=/controller:/controller/testgen
|
29
|
+
|
30
|
+
# Default command
|
31
|
+
CMD ["testgenie"]
|
@@ -0,0 +1,69 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
import testgen.code_to_test.boolean as boolean
|
4
|
+
|
5
|
+
def test_bin_and_0():
|
6
|
+
args = (False, False)
|
7
|
+
expected = False
|
8
|
+
result = boolean.bin_and(*args)
|
9
|
+
assert result == expected
|
10
|
+
|
11
|
+
def test_bin_and_1():
|
12
|
+
args = (True, True)
|
13
|
+
expected = True
|
14
|
+
result = boolean.bin_and(*args)
|
15
|
+
assert result == expected
|
16
|
+
|
17
|
+
def test_bin_and_2():
|
18
|
+
args = (True, False)
|
19
|
+
expected = False
|
20
|
+
result = boolean.bin_and(*args)
|
21
|
+
assert result == expected
|
22
|
+
|
23
|
+
def test_bin_xor_3():
|
24
|
+
args = (True, True)
|
25
|
+
expected = False
|
26
|
+
result = boolean.bin_xor(*args)
|
27
|
+
assert result == expected
|
28
|
+
|
29
|
+
def test_bin_xor_4():
|
30
|
+
args = (True, False)
|
31
|
+
expected = True
|
32
|
+
result = boolean.bin_xor(*args)
|
33
|
+
assert result == expected
|
34
|
+
|
35
|
+
def test_bin_xor_5():
|
36
|
+
args = (False, False)
|
37
|
+
expected = False
|
38
|
+
result = boolean.bin_xor(*args)
|
39
|
+
assert result == expected
|
40
|
+
|
41
|
+
def test_status_flags_6():
|
42
|
+
args = (True, False, True)
|
43
|
+
expected = 'admin-unverified'
|
44
|
+
result = boolean.status_flags(*args)
|
45
|
+
assert result == expected
|
46
|
+
|
47
|
+
def test_status_flags_7():
|
48
|
+
args = (False, False, False)
|
49
|
+
expected = 'inactive'
|
50
|
+
result = boolean.status_flags(*args)
|
51
|
+
assert result == expected
|
52
|
+
|
53
|
+
def test_status_flags_8():
|
54
|
+
args = (True, False, False)
|
55
|
+
expected = 'user-unverified'
|
56
|
+
result = boolean.status_flags(*args)
|
57
|
+
assert result == expected
|
58
|
+
|
59
|
+
def test_status_flags_9():
|
60
|
+
args = (False, True, True)
|
61
|
+
expected = 'admin-verified'
|
62
|
+
result = boolean.status_flags(*args)
|
63
|
+
assert result == expected
|
64
|
+
|
65
|
+
def test_status_flags_10():
|
66
|
+
args = (True, True, False)
|
67
|
+
expected = 'user-verified'
|
68
|
+
result = boolean.status_flags(*args)
|
69
|
+
assert result == expected
|
@@ -3,174 +3,192 @@ import pytest
|
|
3
3
|
import testgen.code_to_test.decisions as decisions
|
4
4
|
|
5
5
|
def test_add_or_subtract_0():
|
6
|
-
args = (
|
7
|
-
expected =
|
6
|
+
args = (12, 71)
|
7
|
+
expected = 83
|
8
8
|
result = decisions.add_or_subtract(*args)
|
9
9
|
assert result == expected
|
10
10
|
|
11
11
|
def test_add_or_subtract_1():
|
12
|
-
args = (
|
13
|
-
expected =
|
12
|
+
args = (7, 81)
|
13
|
+
expected = 88
|
14
14
|
result = decisions.add_or_subtract(*args)
|
15
15
|
assert result == expected
|
16
16
|
|
17
17
|
def test_add_or_subtract_2():
|
18
|
-
args = (
|
19
|
-
expected =
|
18
|
+
args = (97, 75)
|
19
|
+
expected = 22
|
20
20
|
result = decisions.add_or_subtract(*args)
|
21
21
|
assert result == expected
|
22
22
|
|
23
23
|
def test_add_or_subtract_3():
|
24
|
-
args = (
|
25
|
-
expected =
|
24
|
+
args = (38, 40)
|
25
|
+
expected = 78
|
26
26
|
result = decisions.add_or_subtract(*args)
|
27
27
|
assert result == expected
|
28
28
|
|
29
29
|
def test_add_or_subtract_4():
|
30
|
-
args = (
|
31
|
-
expected =
|
30
|
+
args = (66, 3)
|
31
|
+
expected = 63
|
32
32
|
result = decisions.add_or_subtract(*args)
|
33
33
|
assert result == expected
|
34
34
|
|
35
35
|
def test_add_or_subtract_5():
|
36
|
-
args = (
|
37
|
-
expected =
|
36
|
+
args = (84, 10)
|
37
|
+
expected = 74
|
38
38
|
result = decisions.add_or_subtract(*args)
|
39
39
|
assert result == expected
|
40
40
|
|
41
41
|
def test_add_or_subtract_6():
|
42
|
-
args = (
|
43
|
-
expected =
|
42
|
+
args = (95, 89)
|
43
|
+
expected = 6
|
44
44
|
result = decisions.add_or_subtract(*args)
|
45
45
|
assert result == expected
|
46
46
|
|
47
47
|
def test_add_or_subtract_7():
|
48
|
-
args = (
|
49
|
-
expected =
|
48
|
+
args = (57, 12)
|
49
|
+
expected = 45
|
50
50
|
result = decisions.add_or_subtract(*args)
|
51
51
|
assert result == expected
|
52
52
|
|
53
53
|
def test_add_or_subtract_8():
|
54
|
-
args = (
|
55
|
-
expected =
|
54
|
+
args = (64, 98)
|
55
|
+
expected = 162
|
56
56
|
result = decisions.add_or_subtract(*args)
|
57
57
|
assert result == expected
|
58
58
|
|
59
59
|
def test_add_or_subtract_9():
|
60
|
-
args = (
|
61
|
-
expected =
|
60
|
+
args = (94, 80)
|
61
|
+
expected = 14
|
62
62
|
result = decisions.add_or_subtract(*args)
|
63
63
|
assert result == expected
|
64
64
|
|
65
65
|
def test_add_or_subtract_10():
|
66
|
-
args = (
|
67
|
-
expected =
|
66
|
+
args = (26, 3)
|
67
|
+
expected = 23
|
68
68
|
result = decisions.add_or_subtract(*args)
|
69
69
|
assert result == expected
|
70
70
|
|
71
71
|
def test_add_or_subtract_11():
|
72
|
-
args = (
|
73
|
-
expected =
|
72
|
+
args = (91, 39)
|
73
|
+
expected = 52
|
74
74
|
result = decisions.add_or_subtract(*args)
|
75
75
|
assert result == expected
|
76
76
|
|
77
77
|
def test_add_or_subtract_12():
|
78
|
-
args = (
|
79
|
-
expected =
|
78
|
+
args = (53, 42)
|
79
|
+
expected = 11
|
80
80
|
result = decisions.add_or_subtract(*args)
|
81
81
|
assert result == expected
|
82
82
|
|
83
83
|
def test_add_or_subtract_13():
|
84
|
-
args = (
|
85
|
-
expected =
|
84
|
+
args = (15, 42)
|
85
|
+
expected = 57
|
86
86
|
result = decisions.add_or_subtract(*args)
|
87
87
|
assert result == expected
|
88
88
|
|
89
89
|
def test_add_or_subtract_14():
|
90
|
-
args = (
|
91
|
-
expected =
|
90
|
+
args = (13, 67)
|
91
|
+
expected = 80
|
92
92
|
result = decisions.add_or_subtract(*args)
|
93
93
|
assert result == expected
|
94
94
|
|
95
95
|
def test_add_or_subtract_15():
|
96
|
-
args = (
|
97
|
-
expected =
|
96
|
+
args = (62, 92)
|
97
|
+
expected = 154
|
98
98
|
result = decisions.add_or_subtract(*args)
|
99
99
|
assert result == expected
|
100
100
|
|
101
|
-
def
|
102
|
-
args =
|
103
|
-
expected =
|
104
|
-
result = decisions.
|
101
|
+
def test_add_or_subtract_16():
|
102
|
+
args = (91, 2)
|
103
|
+
expected = 89
|
104
|
+
result = decisions.add_or_subtract(*args)
|
105
105
|
assert result == expected
|
106
106
|
|
107
|
-
def
|
108
|
-
args =
|
107
|
+
def test_email_type_17():
|
108
|
+
args = 'abc'
|
109
109
|
expected = 'invalid'
|
110
|
-
result = decisions.
|
110
|
+
result = decisions.email_type(args)
|
111
111
|
assert result == expected
|
112
112
|
|
113
113
|
def test_http_code_18():
|
114
|
-
args =
|
114
|
+
args = 81
|
115
115
|
expected = 'invalid'
|
116
116
|
result = decisions.http_code(args)
|
117
117
|
assert result == expected
|
118
118
|
|
119
119
|
def test_http_code_19():
|
120
|
-
args =
|
120
|
+
args = 60
|
121
121
|
expected = 'invalid'
|
122
122
|
result = decisions.http_code(args)
|
123
123
|
assert result == expected
|
124
124
|
|
125
125
|
def test_http_code_20():
|
126
|
-
args =
|
126
|
+
args = 29
|
127
127
|
expected = 'invalid'
|
128
128
|
result = decisions.http_code(args)
|
129
129
|
assert result == expected
|
130
130
|
|
131
131
|
def test_http_code_21():
|
132
|
-
args =
|
132
|
+
args = 11
|
133
133
|
expected = 'invalid'
|
134
134
|
result = decisions.http_code(args)
|
135
135
|
assert result == expected
|
136
136
|
|
137
137
|
def test_http_code_22():
|
138
|
-
args =
|
138
|
+
args = 79
|
139
139
|
expected = 'invalid'
|
140
140
|
result = decisions.http_code(args)
|
141
141
|
assert result == expected
|
142
142
|
|
143
143
|
def test_http_code_23():
|
144
|
-
args =
|
144
|
+
args = 70
|
145
145
|
expected = 'invalid'
|
146
146
|
result = decisions.http_code(args)
|
147
147
|
assert result == expected
|
148
148
|
|
149
149
|
def test_http_code_24():
|
150
|
-
args =
|
150
|
+
args = 52
|
151
151
|
expected = 'invalid'
|
152
152
|
result = decisions.http_code(args)
|
153
153
|
assert result == expected
|
154
154
|
|
155
155
|
def test_http_code_25():
|
156
|
-
args =
|
156
|
+
args = 41
|
157
157
|
expected = 'invalid'
|
158
158
|
result = decisions.http_code(args)
|
159
159
|
assert result == expected
|
160
160
|
|
161
161
|
def test_http_code_26():
|
162
|
-
args =
|
162
|
+
args = 6
|
163
163
|
expected = 'invalid'
|
164
164
|
result = decisions.http_code(args)
|
165
165
|
assert result == expected
|
166
166
|
|
167
167
|
def test_http_code_27():
|
168
|
-
args =
|
168
|
+
args = 63
|
169
|
+
expected = 'invalid'
|
170
|
+
result = decisions.http_code(args)
|
171
|
+
assert result == expected
|
172
|
+
|
173
|
+
def test_http_code_28():
|
174
|
+
args = 47
|
175
|
+
expected = 'invalid'
|
176
|
+
result = decisions.http_code(args)
|
177
|
+
assert result == expected
|
178
|
+
|
179
|
+
def test_http_code_29():
|
180
|
+
args = 58
|
181
|
+
expected = 'invalid'
|
182
|
+
result = decisions.http_code(args)
|
183
|
+
assert result == expected
|
184
|
+
|
185
|
+
def test_http_code_30():
|
186
|
+
args = 87
|
169
187
|
expected = 'invalid'
|
170
188
|
result = decisions.http_code(args)
|
171
189
|
assert result == expected
|
172
190
|
|
173
|
-
def
|
191
|
+
def test_password_strength_31():
|
174
192
|
args = 'abc'
|
175
193
|
expected = 'weak'
|
176
194
|
result = decisions.password_strength(args)
|
@@ -109,8 +109,23 @@ def load_and_parse_file_for_tree(file) -> Module:
|
|
109
109
|
tree = ast.parse(code)
|
110
110
|
return tree
|
111
111
|
|
112
|
-
def adjust_file_path_for_docker(file_path) -> str:
|
113
|
-
|
112
|
+
def adjust_file_path_for_docker(file_path: str) -> str:
|
113
|
+
"""Adjust the file path to be valid inside the Docker container."""
|
114
|
+
print(f"Docker - adjusting path: {file_path}")
|
115
|
+
|
116
|
+
# If already absolute to /controller, return as-is
|
117
|
+
if file_path.startswith("/controller/"):
|
118
|
+
print(f"Docker - already adjusted: {file_path}")
|
119
|
+
return file_path
|
120
|
+
|
121
|
+
# If relative, make absolute
|
122
|
+
adjusted_path = f"/controller/{file_path.lstrip('/')}"
|
123
|
+
print(f"Docker - adjusted to: {adjusted_path}")
|
124
|
+
return adjusted_path
|
125
|
+
|
126
|
+
|
127
|
+
"""def adjust_file_path_for_docker(file_path) -> str:
|
128
|
+
#Adjust file path for Docker environment to handle subdirectories and relative paths.
|
114
129
|
print(f"Docker - adjusting path: {file_path}")
|
115
130
|
|
116
131
|
# Try direct path first (maybe it's correct already)
|
@@ -144,13 +159,28 @@ def adjust_file_path_for_docker(file_path) -> str:
|
|
144
159
|
|
145
160
|
# Return original path if we couldn't find a better match
|
146
161
|
print(f"Docker - couldn't find file, returning original: {file_path}")
|
147
|
-
return file_path
|
162
|
+
return file_path"""
|
163
|
+
|
164
|
+
|
148
165
|
|
149
166
|
def get_project_root_in_docker(script_path) -> str:
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
project_root =
|
155
|
-
|
156
|
-
|
167
|
+
# Don't use sys.argv[0] as it points to the virtualenv
|
168
|
+
# Instead, find the actual project root
|
169
|
+
if os.path.exists('/mnt/c/Users/cjsei/thesis/dev/testgen'):
|
170
|
+
# Hard-coded path for now
|
171
|
+
project_root = '/mnt/c/Users/cjsei/thesis/dev/testgen'
|
172
|
+
else:
|
173
|
+
# Try to find project root by looking for pyproject.toml or similar
|
174
|
+
current_dir = os.path.dirname(os.path.abspath(script_path))
|
175
|
+
while current_dir != '/':
|
176
|
+
if os.path.exists(os.path.join(current_dir, 'pyproject.toml')) or \
|
177
|
+
os.path.exists(os.path.join(current_dir, 'setup.py')):
|
178
|
+
project_root = current_dir
|
179
|
+
break
|
180
|
+
current_dir = os.path.dirname(current_dir)
|
181
|
+
else:
|
182
|
+
# Fallback - use parent of script dir
|
183
|
+
project_root = os.path.dirname(os.path.dirname(os.path.abspath(script_path)))
|
184
|
+
|
185
|
+
print(f"Project root directory: {project_root}")
|
186
|
+
return project_root
|
@@ -1,22 +0,0 @@
|
|
1
|
-
FROM python:3.10
|
2
|
-
|
3
|
-
RUN apt-get update && apt-get install -y curl build-essential
|
4
|
-
|
5
|
-
RUN curl -sSL https://install.python-poetry.org | python3 - \
|
6
|
-
&& ln -s /root/.local/bin/poetry /usr/local/bin/poetry
|
7
|
-
|
8
|
-
ENV POETRY_VIRTUALENVS_CREATE=false \
|
9
|
-
PYTHONUNBUFFERED=1 \
|
10
|
-
RUNNING_IN_DOCKER=true
|
11
|
-
|
12
|
-
WORKDIR /controller
|
13
|
-
|
14
|
-
# Copy poetry files
|
15
|
-
COPY . .
|
16
|
-
|
17
|
-
ENV PYTHONPATH=/controller:/controller/testgen
|
18
|
-
|
19
|
-
RUN poetry install --no-root
|
20
|
-
|
21
|
-
# Entrypoint (Can be overridden by Docker SDK in Python)
|
22
|
-
CMD ["poetry", "run", "python", "-m", "testgen.main"]
|