Skip to content

Commit

Permalink
Pass unknown args to inner command
Browse files Browse the repository at this point in the history
Fixes: #51
  • Loading branch information
asmacdo committed Jun 7, 2024
1 parent 8b1e218 commit 76d9a50
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,5 @@ options:
--memory-size MEMORY_SIZE
Amount of memory to allocate in MB.

duct --report-interval 4 -- ./test_script.py --duration 12 --cpu-load 50000 --memory-size 50 | jq
duct --report-interval 4 ./test_script.py --duration 12 --cpu-load 50000 --memory-size 50
```
14 changes: 7 additions & 7 deletions src/duct.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ def create_and_parse_args():
choices=["all", "system-summary", "processes-samples"],
help="Record system-summary, processes-samples, or all",
)
return parser.parse_args()
return parser.parse_known_args()


class TailPipe:
Expand Down Expand Up @@ -365,11 +365,11 @@ def ensure_directories(path: str) -> None:


def main():
args = create_and_parse_args()
execute(args)
args, command_args = create_and_parse_args()
execute(args, command_args)


def execute(args):
def execute(args, command_args):
"""A wrapper to execute a command, monitor and log the process details."""
datetime_filesafe = datetime.now().strftime("%Y.%m.%dT%H.%M.%S")
duct_pid = os.getpid()
Expand All @@ -389,11 +389,11 @@ def execute(args):
else:
stderr_file = stderr

full_command = " ".join([str(args.command)] + args.arguments)
full_command = " ".join([str(args.command)] + command_args)
print(f"{Colors.OKCYAN}duct is executing {full_command}...")
print(f"Log files will be written to {formatted_output_prefix}{Colors.ENDC}")
process = subprocess.Popen(
[str(args.command)] + args.arguments,
[str(args.command)] + command_args,
stdout=stdout_file,
stderr=stderr_file,
preexec_fn=os.setsid,
Expand All @@ -405,7 +405,7 @@ def execute(args):

report = Report(
args.command,
args.arguments,
command_args,
session_id,
formatted_output_prefix,
process,
Expand Down
32 changes: 16 additions & 16 deletions test/test_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,26 @@ def temp_output_dir(tmp_path):


def test_sanity_green(temp_output_dir):
command_args = ["hello", "world"]
args = argparse.Namespace(
command="echo",
arguments=["hello", "world"],
output_prefix=temp_output_dir,
sample_interval=1.0,
report_interval=60.0,
capture_outputs="all",
outputs="all",
record_types="all",
)
execute(args)
execute(args, command_args)
# When runtime < sample_interval, we won't have a usage.json
expected_files = ["stdout", "stderr", "info.json"]
assert_files(temp_output_dir, expected_files, exists=True)


def test_sanity_red(temp_output_dir):
command_args = []
args = argparse.Namespace(
command="false",
arguments=[],
output_prefix=temp_output_dir,
sample_interval=1.0,
report_interval=60.0,
Expand All @@ -42,7 +42,7 @@ def test_sanity_red(temp_output_dir):
record_types="all",
)
with mock.patch("sys.stdout", new_callable=mock.MagicMock) as mock_stdout:
execute(args)
execute(args, command_args)
mock_stdout.write.assert_has_calls([mock.call("Exit Code: 1")])

# We still should execute normally
Expand All @@ -54,69 +54,69 @@ def test_sanity_red(temp_output_dir):


def test_outputs_full(temp_output_dir):
command_args = ["--duration", "1"]
args = argparse.Namespace(
command="./test_script.py",
arguments=["--duration", "1"],
output_prefix=temp_output_dir,
sample_interval=0.01,
report_interval=0.1,
capture_outputs="all",
outputs="all",
record_types="all",
)
execute(args)
execute(args, command_args)
expected_files = ["stdout", "stderr", "info.json", "usage.json"]
assert_files(temp_output_dir, expected_files, exists=True)


def test_outputs_passthrough(temp_output_dir):
command_args = ["--duration", "1"]
args = argparse.Namespace(
command="./test_script.py",
arguments=["--duration", "1"],
output_prefix=temp_output_dir,
sample_interval=0.01,
report_interval=0.1,
capture_outputs="none",
outputs="all",
record_types="all",
)
execute(args)
execute(args, command_args)
expected_files = ["info.json", "usage.json"]
assert_files(temp_output_dir, expected_files, exists=True)
not_expected_files = ["stdout", "stderr"]
assert_files(temp_output_dir, not_expected_files, exists=False)


def test_outputs_capture(temp_output_dir):
command_args = ["--duration", "1"]
args = argparse.Namespace(
command="./test_script.py",
arguments=["--duration", "1"],
output_prefix=temp_output_dir,
sample_interval=0.01,
report_interval=0.1,
capture_outputs="all",
outputs="none",
record_types="all",
)
execute(args)
execute(args, command_args)
# TODO make this work assert mock.call("this is of test of STDOUT\n") not in mock_stdout.write.mock_calls

expected_files = ["stdout", "stderr", "info.json", "usage.json"]
assert_files(temp_output_dir, expected_files, exists=True)


def test_outputs_none(temp_output_dir):
command_args = ["--duration", "1"]
args = argparse.Namespace(
command="./test_script.py",
arguments=["--duration", "1"],
output_prefix=temp_output_dir,
sample_interval=0.01,
report_interval=0.1,
capture_outputs="none",
outputs="none",
record_types="all",
)
execute(args)
execute(args, command_args)
# assert mock.call("this is of test of STDOUT\n") not in mock_stdout.write.mock_calls

expected_files = ["info.json", "usage.json"]
Expand All @@ -127,35 +127,35 @@ def test_outputs_none(temp_output_dir):


def test_exit_before_first_sample(temp_output_dir):
command_args = []
args = argparse.Namespace(
command="ls",
arguments=[],
output_prefix=temp_output_dir,
sample_interval=0.1,
report_interval=0.1,
capture_outputs="all",
outputs="none",
record_types="all",
)
execute(args)
execute(args, command_args)
expected_files = ["stdout", "stderr", "info.json"]
assert_files(temp_output_dir, expected_files, exists=True)
not_expected_files = ["usage.json"]
assert_files(temp_output_dir, not_expected_files, exists=False)


def test_run_less_than_report_interval(temp_output_dir):
command_args = ["0.01"]
args = argparse.Namespace(
command="sleep",
arguments=["0.01"],
output_prefix=temp_output_dir,
sample_interval=0.001,
report_interval=0.1,
capture_outputs="all",
outputs="none",
record_types="all",
)
execute(args)
execute(args, command_args)
# Specifically we need to assert that usage.json gets written anyway.
expected_files = ["stdout", "stderr", "usage.json", "info.json"]
assert_files(temp_output_dir, expected_files, exists=True)

0 comments on commit 76d9a50

Please sign in to comment.