Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

UN-3098 [FIX] Fixed graceful shutdown in tool container to ensure in-progress tasks complete#1708

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
kirtimanmishrazipstack wants to merge8 commits intomain
base:main
Choose a base branch
Loading
fromUN-3098-resolve-issue-with-graceful-shutdown

Conversation

@kirtimanmishrazipstack
Copy link
Contributor

What

Why

How

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

Database Migrations

Env Config

Relevant Docs

Related Issues or PRs

Dependencies Versions

Notes on Testing

Screenshots

Checklist

I have read and understood theContribution Guidelines.

@coderabbitai
Copy link
Contributor

coderabbitaibot commentedDec 17, 2025
edited
Loading

Summary by CodeRabbit

  • Bug Fixes

    • Processes now ignore termination signals at startup and log that execution will continue instead of attempting graceful shutdown.
  • Improvements

    • Error reporting includes exception type and full traceback for clearer diagnostics.
    • Interrupted operations produce specific warnings when detected (e.g., KeyboardInterrupt or interrupted system calls).
    • Signal handling updated to avoid interrupting system calls.
  • Other

    • Simplified container startup and streamlined tool output logging with an explicit exit marker.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Signal handlers were removed and SIGINT/SIGTERM are now ignored at startup in the sidecar and SDK entrypoint; container start command no longer usesdumb-init and invokes/bin/sh -c directly; executor error handling now includes exception type names, full tracebacks, and special handling/logging for interruption-related errors.

Changes

Cohort / File(s)Change Summary
Signal handling: ignore termination signals
tool-sidecar/src/unstract/tool_sidecar/log_processor.py,unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py
Removed in-process signal handler functions and their registration. At startup, setSIGINT/SIGTERM toSIG_IGN, addedsiginterrupt calls to avoid interrupting system calls, removed an unusedtypes import, and updated logs to state monitoring/execution will be uninterrupted.
Container entrypoint invocation
runner/src/unstract/runner/runner.py
Replaced the prior two-stage wrapper anddumb-init usage with a single shell invocation: the container command is composed into one/bin/sh -c "<...>" invocation that traps SIGTERM/SIGINT and runs the tool, removing the previous execute_cmd wrapper.
Executor: richer error handling and logging
unstract/sdk1/src/unstract/sdk1/tool/executor.py
EnhancedToolExecutor.execute_run error messages to include the exception type name, logged the full traceback, and added special-case handling/logging forInterruptedError/KeyboardInterrupt and errors mentioning “interrupted system call”. Exit-on-error behavior remains.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Verify that ignoring SIGINT/SIGTERM inlog_processor.py andentrypoint.py does not prevent required cleanup, shutdown hooks, or orchestration-driven termination.
  • Confirm removingdumb-init and running/bin/sh -c inrunner.py preserves proper PID 1 responsibilities (signal propagation, child reaping) and that the new trap logic behaves correctly across shells.
  • Review the new traceback logging inexecutor.py for potential sensitive data leakage and log formatting issues.
  • Test interactions end-to-end (sidecar, SDK entrypoint, runner) to ensure no regressions in shutdown, restart, or log capture behavior.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Description check⚠️ WarningThe PR description contains only the template structure with no substantive content filled in any required sections, including the critical 'Can this PR break existing features' section marked mandatory for admin approval.Fill in all required sections: What (summary of changes), Why (motivation), How (implementation details), and the mandatory section on breaking changes. Add testing notes and related issue references.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly describes the main change: fixing graceful shutdown in tool containers to ensure tasks complete, which aligns with the code changes removing signal handlers.
Docstring Coverage✅ PassedDocstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branchUN-3098-resolve-issue-with-graceful-shutdown

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge base: Disabled due toReviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and betweenbf16e1e and579076f.

📒 Files selected for processing (1)
  • runner/src/unstract/runner/runner.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
runner/src/unstract/runner/runner.py (1)
unstract/core/src/unstract/core/constants.py (1)
  • LogFieldName (1-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

Thanks for usingCodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment@coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitaicoderabbitaibot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tool-sidecar/src/unstract/tool_sidecar/log_processor.py (1)

226-259:Critical: Monitoring loop never checks shutdown flag.

Themonitor_logs() method'swhile True loop (starting at line 236) never checks the_shutdown_requested flag. Even after the signal handler sets this flag, the monitoring loop will continue running indefinitely. For graceful shutdown to work, you must check the flag within the loop.

Add a flag check in the monitoring loop:

         # Monitor the file for new content         with open(self.log_path) as f:             while True:+                # Check if shutdown was requested+                if _shutdown_requested:+                    logger.info("Shutdown requested - exiting monitoring loop gracefully")+                    self._update_tool_execution_status(+                        status=ToolExecutionStatus.STOPPED,+                        error="Shutdown signal received"+                    )+                    break+                 # Remember current position                 where = f.tell()                 line = f.readline()

Note: You may also want to check the flag at line 249 (during the sleep) to ensure more responsive shutdown during idle periods.

🧹 Nitpick comments (1)
tool-sidecar/src/unstract/tool_sidecar/log_processor.py (1)

261-326:Optional: Consider logging shutdown reason after monitoring completes.

While the signal handlers are correctly registered and the monitoring loop is started, consider adding a check afterprocessor.monitor_logs() completes to log whether the exit was due to graceful shutdown or normal completion. This improves observability.

     processor.monitor_logs()++    if _shutdown_requested:+        logger.info("Log processor exited due to shutdown signal")+    else:+        logger.info("Log processor completed normally")
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge base: Disabled due toReviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and betweena70a178 andfc511ff.

📒 Files selected for processing (2)
  • tool-sidecar/src/unstract/tool_sidecar/log_processor.py (1 hunks)
  • unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py (1)
tool-sidecar/src/unstract/tool_sidecar/log_processor.py (1)
  • _signal_handler (31-42)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

Comment on lines 11 to 12
# Global flag for graceful shutdown
_shutdown_requested=False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

⚠️ Potential issue |🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash# Search for all usages of _shutdown_requested flag in the codebaseecho"=== Searching for _shutdown_requested usages ==="rg -n'_shutdown_requested' --type pyecho -e"\n=== Searching for conditional checks on shutdown flag ==="rg -n'if.*shutdown|while.*shutdown' --type py -A 2

Repository: Zipstack/unstract

Length of output: 1548


🏁 Script executed:

cat -n unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py

Repository: Zipstack/unstract

Length of output: 2003


🏁 Script executed:

cat -n unstract/sdk1/src/unstract/sdk1/tool/executor.py

Repository: Zipstack/unstract

Length of output: 3547


Critical: Global flag defined and set but never checked.

The_shutdown_requested flag is set toTrue by the signal handler but is never checked anywhere in the codebase. Theexecute_run() method callsself.tool.run() at line 73, which blocks until completion. Without a check of the flag (such as in a loop or before/after the blocking call), the signal handler's attempt to initiate graceful shutdown has no effect—the tool will continue running regardless of the SIGTERM or SIGINT signal.

Copy link
Contributor

@coderabbitaicoderabbitaibot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
runner/src/unstract/runner/runner.py (1)

292-321:The generated shell script lacks signal handling for graceful shutdown.

The_get_container_command method builds a shell script that runs the tool command, but it doesn't include signal forwarding or trap handlers. With the removal ofdumb-init (line 458) andexec inentrypoint.sh, this shell script needs explicit signal management to enable graceful shutdown.

To support graceful shutdown after removingdumb-init, add signal forwarding to the generated shell script:

def _get_container_command(    self, shared_log_dir: str, shared_log_file: str, settings: dict[str, Any]):    """Returns the container command to run the tool."""    settings_json = json.dumps(settings).replace("'", "\\'")    # Prepare the tool execution command    tool_cmd = (        f"python main.py --command RUN "        f"--settings '{settings_json}' --log-level DEBUG"    )    if not self.sidecar_enabled:        return tool_cmd    # Shell script components+   signal_handling = (+       "trap 'kill -TERM $tool_pid 2>/dev/null' TERM INT; "+       "trap 'kill -HUP $tool_pid 2>/dev/null' HUP; "+   )    mkdir_cmd = f"mkdir -p {shared_log_dir}"    run_tool_fn = (        "run_tool() { "        f"{tool_cmd}; "        "exit_code=$?; "        f'echo "{LogFieldName.TOOL_TERMINATION_MARKER} with exit code $exit_code" '        f">> {shared_log_file}; "        "return $exit_code; "        "}"    )-   execute_cmd = f"run_tool > {shared_log_file} 2>&1"+   execute_cmd = f"run_tool > {shared_log_file} 2>&1 & tool_pid=$!; wait $tool_pid"    # Combine all commands-   shell_script = f"{mkdir_cmd} && {run_tool_fn}; {execute_cmd}"+   shell_script = f"{mkdir_cmd} && {signal_handling} {run_tool_fn}; {execute_cmd}"    return shell_script

This ensures signals are forwarded to the Python process for proper graceful shutdown handling.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge base: Disabled due toReviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and betweenfc511ff and24d9333.

📒 Files selected for processing (2)
  • runner/src/unstract/runner/runner.py (1 hunks)
  • tool-sidecar/entrypoint.sh (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

Copy link
Contributor

@coderabbitaicoderabbitaibot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py (1)

16-25:Critical: Ignoring SIGTERM/SIGINT breaks container orchestration and prevents graceful shutdown.

The PR objectives state this change "Fixed graceful shutdown in tool container to ensure in-progress tasks complete", but settingsignal.SIG_IGN does the opposite—it tells the OS to ignore shutdown signals entirely. This creates several critical problems:

  1. Container orchestration failure: Container platforms (Kubernetes, Docker) send SIGTERM to request graceful shutdown. If the process ignores SIGTERM, the platform waits for a grace period (typically 30s) then sends SIGKILL, forcefully terminating the container. This defeats the purpose of graceful shutdown.

  2. Misleading behavior: The comment states "prevents the signal from interrupting the current operation," but the signal hasalready interrupted execution (that's why the handler was invoked). SettingSIG_IGN only affectsfuture signals, not the current one.

  3. No actual shutdown logic: After the handler returns, control goes back to the interrupted code with no shutdown mechanism. The process continues indefinitely until force-killed.

For proper graceful shutdown in a container environment, you should:

  • Let the signal handler set a flag or trigger shutdown logic
  • Allow the current operation to complete naturally
  • Exit the process cleanly so the container terminates with exit code 0

Apply this diff to implement proper graceful shutdown:

+# Global flag for graceful shutdown+_shutdown_requested = False+ class ToolEntrypoint:     """Class that contains methods for the entrypoint for a tool."""      @staticmethod     def _signal_handler(signum: int, _frame: types.FrameType | None) -> None:         """Handle SIGTERM and SIGINT signals."""+        global _shutdown_requested         sig = signal.Signals(signum)         signal_name = sig.name         logger.warning(f"RECEIVED SIGNAL: {signal_name}")-        logger.warning("Allowing tool to complete current operation...")--        # Ignore the signal to allow the process to continue-        # This prevents the signal from interrupting the current operation-        signal.signal(signum, signal.SIG_IGN)+        logger.warning("Initiating graceful shutdown after current operation...")+        _shutdown_requested = True

Then check the flag afterexecutor.execute(parsed_args) completes:

     parsed_args = ToolArgsParser.parse_args(args)     executor = ToolExecutor(tool=tool)     executor.execute(parsed_args)++    # Exit cleanly if shutdown was requested+    if _shutdown_requested:+        logger.info("Shutdown completed gracefully")+        sys.exit(0)

Additionally, the executor's long-running operations should periodically check_shutdown_requested and break/cleanup when set.

♻️ Duplicate comments (1)
tool-sidecar/src/unstract/tool_sidecar/log_processor.py (1)

31-40:Critical: Identical issue—ignoring shutdown signals breaks sidecar termination.

This signal handler has the same critical flaw as inentrypoint.py: settingsignal.SIG_IGN prevents the sidecar from responding to SIGTERM/SIGINT, which breaks container orchestration.

Specific concerns for the sidecar:

  1. Pod-level coordination: In Kubernetes, when a pod is terminated, all containers receive SIGTERM simultaneously. The sidecar should honor this signal and shut down gracefully alongside the main tool container.

  2. Existing completion detection: Themonitor_logs() method already has proper completion detection at lines 241-244 (checking for the "completed" file). The signal handler should complement this, not ignore signals.

  3. Orphaned sidecar: If the main tool container exits but the sidecar ignores shutdown signals, the sidecar becomes orphaned and must be force-killed.

Apply this diff for proper graceful shutdown:

+# Global flag for graceful shutdown+_shutdown_requested = False++ def _signal_handler(signum: int, _frame: types.FrameType | None):     """Handle shutdown signals gracefully."""+    global _shutdown_requested     sig = signal.Signals(signum)     signal_name = sig.name     logger.warning(f"RECEIVED SIGNAL: {signal_name}")-    logger.warning("Allowing sidecar to continue monitoring...")--    # Ignore the signal to allow the process to continue-    # This prevents the signal from interrupting the monitoring operation-    signal.signal(signum, signal.SIG_IGN)+    logger.warning("Initiating graceful shutdown of sidecar...")+    _shutdown_requested = True

Then modifymonitor_logs() to check the flag:

             # Remember current position             where = f.tell()             line = f.readline()              if not line:+                # Check for shutdown signal+                if _shutdown_requested:+                    logger.info("Shutdown signal received, exiting monitoring loop")+                    break+                 # No new data, check if tool container is done                 if os.path.exists(                     os.path.join(os.path.dirname(self.log_path), "completed")                 ):                     break
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge base: Disabled due toReviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between24d9333 and80596a8.

📒 Files selected for processing (2)
  • tool-sidecar/src/unstract/tool_sidecar/log_processor.py (1 hunks)
  • unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

Copy link
Contributor

@coderabbitaicoderabbitaibot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
unstract/sdk1/src/unstract/sdk1/tool/executor.py (1)

79-85:Remove redundant traceback logging.

The full traceback is already captured byexc_info=True on line 80. Lines 82-85 duplicate this information unnecessarily.

Apply this diff to remove the redundancy:

-            msg = f"Error while running tool '{tool_name}': {type(e).__name__}: {str(e)}"-            logger.error(msg, stack_info=True, exc_info=True)--            # Log more details about the exception-            import traceback--            logger.error(f"Full traceback:\n{traceback.format_exc()}")+            msg = f"Error while running tool '{tool_name}': {type(e).__name__}: {str(e)}"+            logger.error(msg, stack_info=True, exc_info=True)

The enhanced error message with exception type (line 79) is a good improvement and should be kept.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge base: Disabled due toReviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between0a0f67e andda025fb.

📒 Files selected for processing (2)
  • runner/src/unstract/runner/runner.py (1 hunks)
  • unstract/sdk1/src/unstract/sdk1/tool/executor.py (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (1)
runner/src/unstract/runner/runner.py (1)

458-458:Architectural decision confirmed: Signal ignoring is intentional and works as designed.

The review comment's concerns arevalid and confirmed. The codebase deliberately ignores SIGTERM and SIGINT at startup (entrypoint.py lines 27-28, log_processor.py lines 252-253), with explicit documentation stating this prevents "any interruption of tool operations." This is paired with direct shell invocation (/bin/sh -c) without dumb-init, making the shell PID 1.

Confirmed implications:

  1. Kubernetes compatibility: Containers will not respond to graceful SIGTERM. The orchestrator will force-kill (SIGKILL) after the grace period, bypassing graceful shutdown. This aligns with the PR objective ("ensure in-progress tasks complete") but trades responsive termination for guaranteed completion.

  2. PID 1 zombie process handling: Without an init system, shell processes won't reap child zombies. The codebase acknowledges this risk (health.py detectspsutil.STATUS_ZOMBIE processes) but only monitors, not prevents, accumulation.

  3. PR objective fulfilled: Tasks will complete without interruption, but at the cost of Kubernetes-standard graceful termination behavior.

Recommendation: This architectural decision should be explicitly documented with:

  • Why signal ignoring is preferable to graceful shutdown for this use case
  • Expected behavior when Kubernetes sends SIGTERM (acknowledge it won't trigger shutdown)
  • Guidance on monitoring zombie process accumulation in production deployments

Copy link
Contributor

@coderabbitaicoderabbitaibot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge base: Disabled due toReviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between1ddd43c andbf16e1e.

📒 Files selected for processing (3)
  • runner/src/unstract/runner/runner.py (1 hunks)
  • tool-sidecar/src/unstract/tool_sidecar/log_processor.py (1 hunks)
  • unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

@github-actions
Copy link
Contributor

Test Results

Summary
  • Runner Tests: 11 passed, 0 failed (11 total)
  • SDK1 Tests: 66 passed, 0 failed (66 total)

Runner Tests - Full Report
filepathfunction$$\textcolor{#23d18b}{\tt{passed}}$$SUBTOTAL
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_logs}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_cleanup}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_cleanup\_skip}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_client\_init}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_get\_image\_exists}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_get\_image}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_get\_container\_run\_config}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_get\_container\_run\_config\_without\_mount}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_run\_container}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_get\_image\_for\_sidecar}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$$$\textcolor{#23d18b}{\tt{test\_sidecar\_container}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{TOTAL}}$$$$\textcolor{#23d18b}{\tt{11}}$$$$\textcolor{#23d18b}{\tt{11}}$$
SDK1 Tests - Full Report
filepathfunction$$\textcolor{#23d18b}{\tt{passed}}$$SUBTOTAL
$$\textcolor{#23d18b}{\tt{tests/test\_platform.py}}$$$$\textcolor{#23d18b}{\tt{TestPlatformHelperRetry.test\_success\_on\_first\_attempt}}$$$$\textcolor{#23d18b}{\tt{2}}$$$$\textcolor{#23d18b}{\tt{2}}$$
$$\textcolor{#23d18b}{\tt{tests/test\_platform.py}}$$$$\textcolor{#23d18b}{\tt{TestPlatformHelperRetry.test\_retry\_on\_connection\_error}}$$$$\textcolor{#23d18b}{\tt{2}}$$$$\textcolor{#23d18b}{\tt{2}}$$
$$\textcolor{#23d18b}{\tt{tests/test\_platform.py}}$$$$\textcolor{#23d18b}{\tt{TestPlatformHelperRetry.test\_non\_retryable\_http\_error}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/test\_platform.py}}$$$$\textcolor{#23d18b}{\tt{TestPlatformHelperRetry.test\_retryable\_http\_errors}}$$$$\textcolor{#23d18b}{\tt{3}}$$$$\textcolor{#23d18b}{\tt{3}}$$
$$\textcolor{#23d18b}{\tt{tests/test\_platform.py}}$$$$\textcolor{#23d18b}{\tt{TestPlatformHelperRetry.test\_post\_method\_retry}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/test\_platform.py}}$$$$\textcolor{#23d18b}{\tt{TestPlatformHelperRetry.test\_retry\_logging}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/test\_prompt.py}}$$$$\textcolor{#23d18b}{\tt{TestPromptToolRetry.test\_success\_on\_first\_attempt}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/test\_prompt.py}}$$$$\textcolor{#23d18b}{\tt{TestPromptToolRetry.test\_retry\_on\_errors}}$$$$\textcolor{#23d18b}{\tt{2}}$$$$\textcolor{#23d18b}{\tt{2}}$$
$$\textcolor{#23d18b}{\tt{tests/test\_prompt.py}}$$$$\textcolor{#23d18b}{\tt{TestPromptToolRetry.test\_wrapper\_methods\_retry}}$$$$\textcolor{#23d18b}{\tt{4}}$$$$\textcolor{#23d18b}{\tt{4}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestIsRetryableError.test\_connection\_error\_is\_retryable}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestIsRetryableError.test\_timeout\_is\_retryable}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestIsRetryableError.test\_http\_error\_retryable\_status\_codes}}$$$$\textcolor{#23d18b}{\tt{3}}$$$$\textcolor{#23d18b}{\tt{3}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestIsRetryableError.test\_http\_error\_non\_retryable\_status\_codes}}$$$$\textcolor{#23d18b}{\tt{5}}$$$$\textcolor{#23d18b}{\tt{5}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestIsRetryableError.test\_http\_error\_without\_response}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestIsRetryableError.test\_os\_error\_retryable\_errno}}$$$$\textcolor{#23d18b}{\tt{5}}$$$$\textcolor{#23d18b}{\tt{5}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestIsRetryableError.test\_os\_error\_non\_retryable\_errno}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestIsRetryableError.test\_other\_exception\_not\_retryable}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCalculateDelay.test\_exponential\_backoff\_without\_jitter}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCalculateDelay.test\_exponential\_backoff\_with\_jitter}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCalculateDelay.test\_max\_delay\_cap}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCalculateDelay.test\_max\_delay\_cap\_with\_jitter}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryWithExponentialBackoff.test\_successful\_call\_first\_attempt}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryWithExponentialBackoff.test\_retry\_after\_transient\_failure}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryWithExponentialBackoff.test\_max\_retries\_exceeded}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryWithExponentialBackoff.test\_max\_time\_exceeded}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryWithExponentialBackoff.test\_retry\_with\_custom\_predicate}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryWithExponentialBackoff.test\_no\_retry\_with\_predicate\_false}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryWithExponentialBackoff.test\_exception\_not\_in\_tuple\_not\_retried}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryWithExponentialBackoff.test\_delay\_would\_exceed\_max\_time}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_default\_configuration}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_environment\_variable\_configuration}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_invalid\_max\_retries}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_invalid\_max\_time}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_invalid\_base\_delay}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_invalid\_multiplier}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_jitter\_values}}$$$$\textcolor{#23d18b}{\tt{2}}$$$$\textcolor{#23d18b}{\tt{2}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_custom\_exceptions\_only}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_custom\_predicate\_only}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_both\_exceptions\_and\_predicate}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestCreateRetryDecorator.test\_exceptions\_match\_but\_predicate\_false}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestPreconfiguredDecorators.test\_retry\_platform\_service\_call\_exists}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestPreconfiguredDecorators.test\_retry\_prompt\_service\_call\_exists}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestPreconfiguredDecorators.test\_platform\_service\_decorator\_retries\_on\_connection\_error}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestPreconfiguredDecorators.test\_prompt\_service\_decorator\_retries\_on\_timeout}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryLogging.test\_warning\_logged\_on\_retry}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryLogging.test\_info\_logged\_on\_success\_after\_retry}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{tests/utils/test\_retry\_utils.py}}$$$$\textcolor{#23d18b}{\tt{TestRetryLogging.test\_exception\_logged\_on\_giving\_up}}$$$$\textcolor{#23d18b}{\tt{1}}$$$$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{TOTAL}}$$$$\textcolor{#23d18b}{\tt{66}}$$$$\textcolor{#23d18b}{\tt{66}}$$

@sonarqubecloud
Copy link

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@coderabbitaicoderabbitai[bot]coderabbitai[bot] left review comments

At least 2 approving reviews are required to merge this pull request.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants

@kirtimanmishrazipstack

[8]ページ先頭

©2009-2025 Movatter.jp