Add cmd_on_bind functionality to fetch_web plugin & testing plugin#899
Add cmd_on_bind functionality to fetch_web plugin & testing plugin#899glowwserrano7 wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
Lintly has detected code quality issues in this pull request.
There was a problem hiding this comment.
Lintly has detected code quality issues in this pull request.
There was a problem hiding this comment.
Lintly has detected code quality issues in this pull request.
There was a problem hiding this comment.
Pull request overview
This PR extends the existing fetch_web actuation plugin to optionally execute post-bind commands (host or guest) after a web service bind is detected, and adds a new fetch_web_testing plugin to validate both fetched web output and cmd-on-bind side effects/output.
Changes:
- Add
cmd_on_bindsupport tofetch_web, including host/guest execution modes and optional shutdown after commands. - Persist guest command output to
guest_commands_output.txtfor later verification. - Introduce
fetch_web_testingplugin to verify fetch outputs, host marker files, and expected guest command output.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| pyplugins/actuation/fetch_web.py | Adds cmd-on-bind parsing/execution, host/guest modes, optional shutdown behavior, and guest-output capture. |
| pyplugins/testing/fetch_web_testing.py | New integration-test plugin to verify fetch outputs and validate cmd-on-bind host/guest outcomes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Only trigger cmd_on_bind for 0.0.0.0 to avoid running commands | ||
| # multiple times | ||
| if self.cmd_on_bind_structured and guest_ip == "0.0.0.0": | ||
| self.logger.info( | ||
| f"Bind detected on {guest_ip}:{guest_port}, spawning cmd_on_bind thread") | ||
| t = threading.Thread( | ||
| target=self._delayed_bind_workflow, args=(guest_ip, guest_port) | ||
| ) | ||
| t.daemon = True | ||
| t.start() | ||
|
|
| # Determine working directory for host mode | ||
| if self.outdir: | ||
| cwd = os.path.abspath( | ||
| os.path.join(self.outdir, "../..")) | ||
| self.logger.info( | ||
| f"Derived project root from outdir: {cwd}") | ||
| if not os.path.isdir(cwd): | ||
| self.logger.warning( | ||
| f"Project root does not exist: {cwd}" | ||
| ) | ||
| cwd = os.getcwd() | ||
| else: | ||
| cwd = os.getcwd() | ||
|
|
| if self.cmd_on_bind is not None: | ||
| # Check if it's list of dicts with mode/cmd | ||
| if isinstance( | ||
| self.cmd_on_bind, list) and len( | ||
| self.cmd_on_bind) > 0: | ||
| if isinstance(self.cmd_on_bind[0], dict): | ||
| self.cmd_on_bind_structured = self.cmd_on_bind | ||
| self.logger.info( | ||
| "Using structured cmd_on_bind with mode specification" | ||
| ) | ||
| else: | ||
| # List of strings (backward compatibility) | ||
| self.cmd_on_bind_structured = [ | ||
| {"mode": "guest", "cmd": [str(c)]} for c in self.cmd_on_bind | ||
| ] | ||
| self.logger.info("Converting legacy cmd_on_bind format") | ||
| elif isinstance(self.cmd_on_bind, str): | ||
| # Single string command (backward compatibility) | ||
| self.cmd_on_bind_structured = [ | ||
| {"mode": "guest", "cmd": [str(self.cmd_on_bind)]} | ||
| ] | ||
| self.logger.info("Converting single string cmd_on_bind") | ||
| else: | ||
| self.cmd_on_bind_structured = [] |
| self.cmd_on_bind_marker = self.get_arg("cmd_on_bind_marker") | ||
| self.cmd_on_bind_guest_output_contains = self.get_arg( | ||
| "cmd_on_bind_guest_output_contains") | ||
| self.cmd_wait_timeout = int(self.get_arg("cmd_wait_timeout") or 30) |
| project_root = os.path.abspath( | ||
| os.path.join(self.outdir, "../..")) | ||
| marker_path = os.path.join(project_root, marker) |
| # Guest-cmd must be enabled if any guest commands exist | ||
| has_guest_cmds = any( | ||
| entry.get("mode") == "guest" for entry in self.cmd_on_bind_structured) |
Extends the
fetch_webplugin by adding support for executing commands automatically after a web service bind event is detected. Commands can be executed on either the host or the emulated guest, making it easier to automate testing and verification.Changes
Added the ability to execute commands after a web service bind event is detected, extending the
fetch_webplugin for automated testing and verification:guest_cmd.pywrapper.guest_cmd: trueunder thecoresection ofconfig.yaml.guest_commands_output.txtin the results directory for later analysis.Added the
shutdown_after_cmdoption to automatically terminate the emulation after allcmd_on_bindcommands have completed, similar to the existingshutdown_after_wwwbehavior.Added the
fetch_web_testingplugin:cmd_on_bind_guest_output_containsto verify expected guest command output.cmd_wait_timeoutto configure how long the test waits forcmd_on_bindcommands to complete.Example
fetch_webCommands are executed automatically after the web service bind event is detected. Host commands execute from the project root, while guest commands execute inside the emulated guest via
guest_cmd.py.fetch_web_testingThis configuration verifies that:
fetch_websuccessfully downloads content from the detected web service.