Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
30 changes: 23 additions & 7 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,28 @@ inputs:
driver:
description: 'Driver to use'
required: false
scenarioDir:
description: 'Directory containing scenario files'
required: false
dockerSharedNetwork:
Comment thread
darklight3it marked this conversation as resolved.
Outdated
description: 'Docker network to attach lambda containers to'
required: false

runs:
using: 'docker'
image: 'Dockerfile'
env:
INPUT_SUITE_FILE_ARRAY: ${{ inputs.suiteFileArray }}
DOCKER_IMAGE_NAME: ${{ inputs.dockerImageName }}
TASK_FOLDER: ${{ inputs.taskFolder }}
DRIVER: ${{ inputs.driver }}
using: 'composite'
Comment thread
darklight3it marked this conversation as resolved.
Outdated
steps:
- name: Install test runner
shell: bash
run: pip install ${{ github.action_path }}

- name: Run tests
shell: bash
env:
INPUT_SUITE_FILE_ARRAY: ${{ inputs.suiteFileArray }}
DOCKER_IMAGE_NAME: ${{ inputs.dockerImageName }}
TASK_FOLDER: ${{ inputs.taskFolder }}
DRIVER: ${{ inputs.driver }}
INPUT_SCENARIO_DIR: ${{ inputs.scenarioDir }}
DOCKER_SHARED_NETWORK: ${{ inputs.dockerSharedNetwork }}
GITHUB_WORKSPACE: ${{ github.workspace }}
run: python ${{ github.action_path }}/run.py
19 changes: 15 additions & 4 deletions run.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,26 @@
import subprocess
import sys

def run_test_command(json_path, docker_image_name, driver):

def run_test_command(json_path, docker_image_name, driver, scenario_dir=None):
"""Run the test command for a specific JSON file path."""
cmd = [
'python',
'-m',
'containerized_test_runner.cli',
'--test-image',
docker_image_name,
'--debug',
json_path
'--debug'
]

if json_path:
cmd.append(json_path) #

if driver:
cmd += ['--driver', driver]

if scenario_dir:
cmd += ['--scenario-dir', scenario_dir]

try:
# Use Popen to get real-time output
Expand Down Expand Up @@ -81,6 +87,7 @@ def run():
task_folder = get_required_env_var('TASK_FOLDER')
github_workspace = get_required_env_var('GITHUB_WORKSPACE')
driver = os.environ.get('DRIVER')
scenario_dir= os.environ.get("INPUT_SCENARIO_DIR")
test_image_with_tasks = f"{docker_image_name}-with-tasks"
print(f"Building test image with tasks: {test_image_with_tasks}")

Expand All @@ -103,17 +110,21 @@ def run():

print(f"Successfully built {test_image_with_tasks}")

# todo change it with suite loader
suite_files = json.loads(suite_files_input)

if not isinstance(suite_files, list):
raise ValueError("Input must be a JSON array")

suite_files = json.loads(suite_files_input)
success = True
for file in suite_files:
if not run_test_command(file, test_image_with_tasks, driver):
success = False

if scenario_dir:
if not run_test_command(None, test_image_with_tasks, driver, scenario_dir=scenario_dir):
success = False

# Exit with appropriate status code
sys.exit(0 if success else 1)

Expand Down
32 changes: 18 additions & 14 deletions src/containerized_test_runner/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ def _start_container(self, handler: str, environment_variables: Dict[str, str])

cmd = ["docker", "run", "-d", "-i", "--rm", "-p", "127.0.0.1:0:8080"]

# If a shared network is specified, attach to it so containers can reach each other
shared_network = os.environ.get("DOCKER_SHARED_NETWORK")
if shared_network:
cmd += ["--network", shared_network]

if self.task_root is not None:
cmd += ["-v", f"{self.task_root}:/var/task"]

Expand Down Expand Up @@ -346,27 +351,26 @@ def _render_response(self, resp):
return resp

def _get_local_addr(self, container_id):
# When running in Docker-in-Docker, use the container's IP address directly
# First try to get the container's IP address
docker_inspect_cmd = ["docker", "inspect", "-f", "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}", container_id]
docker_inspect_proc = subprocess.Popen(docker_inspect_cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
ip_address = docker_inspect_proc.communicate()[0].decode().rstrip()

if ip_address and ip_address != "":
return "{}:8080".format(ip_address)

# Fallback: try docker port (works when running on host)
# If on a shared network, use the container's IP directly (no port mapping needed)
shared_network = os.environ.get("DOCKER_SHARED_NETWORK")
if shared_network:
docker_inspect_cmd = ["docker", "inspect", "-f",
f'{{{{index .NetworkSettings.Networks "{shared_network}" "IPAddress"}}}}', container_id]
docker_inspect_proc = subprocess.Popen(docker_inspect_cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
ip_address = docker_inspect_proc.communicate()[0].decode().rstrip()
import re
if ip_address and re.match(r'^\d+\.\d+\.\d+\.\d+$', ip_address):
self.logger.debug(f"shared network: using container IP {ip_address}")
return f"{ip_address}:8080"

# Fallback: use mapped host port
docker_port_cmd = ["docker", "port", container_id, "8080"]
docker_port_proc = subprocess.Popen(docker_port_cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
port_output = docker_port_proc.communicate()[0].decode().rstrip()

self.logger.debug(f"docker port output: '{port_output}'")

# If docker port returns a valid address, use it
if port_output and port_output != "":
return port_output

# Last resort: try localhost with port 8080
self.logger.warning("Could not determine container address, using localhost:8080")
return "127.0.0.1:8080"

Expand Down