Skip to content

Conversation

@hebasto
Copy link
Member

@hebasto hebasto commented May 23, 2025

This PR addresses two issues related to the "Return non-zero exit code, with error message for stderr" check in the system_tests/run_command test:

  1. The test now checks the exact exit code, which must be 1.
  2. The process invocation string is removed from the exception message before checking the stderr output, as the latter is a substring of the former.

This is an alternative to #32577 without introducing a shell wrapper and altering quotation in src/external_signer.cpp.

The main idea is to avoid parsing the problematic sh -c 'echo err 1>&2 && false' command with subprocess::Popen.

In the past, this check used:

// Return non-zero exit code, with error message for stderr
const std::string command{"ls nosuchfile"};
const std::string expected{"No such file or directory"};

which was problematic due to its dependence on the system locale.

Fixes #32574.

This change addresses two issues for the "Return non-zero exit code,
with error message for stderr" case:
1. The test now checks the exact exit code, which must be 1.
2. The process invocation string is removed from the exception message
   before checking the stderr output, as the latter is a substring of
   the former.
@hebasto hebasto added the Tests label May 23, 2025
@DrahtBot
Copy link
Contributor

DrahtBot commented May 23, 2025

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32601.

Reviews

See the guideline for information on the review process.
A summary of reviews will appear here.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #32577 (subprocess: Let shell parse command on non-Windows systems by hebasto)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@DrahtBot
Copy link
Contributor

🚧 At least one of the CI tasks failed.
Task lint: https://github.com/bitcoin/bitcoin/runs/42784049574
LLM reason (✨ experimental): The CI failure is due to a missing export LC_ALL=C statement in a shell script, as reported by a lint test.

Hints

Try to run the tests locally, according to the documentation. However, a CI failure may still
happen due to a number of reasons, for example:

  • Possibly due to a silent merge conflict (the changes in this pull request being
    incompatible with the current code in the target branch). If so, make sure to rebase on the latest
    commit of the target branch.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

Leave a comment here, if you need help tracking down a confusing failure.

versionbits_tests.cpp
)
set_property(SOURCE system_tests.cpp PROPERTY
COMPILE_DEFINITIONS PRINT_ERR_AND_FAIL_SCRIPT_PATH="${CMAKE_CURRENT_SOURCE_DIR}/print_err_and_fail.sh"
Copy link
Member

Choose a reason for hiding this comment

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

This will just re-introduce the bugs fixed in #31542, no?

Copy link
Member

Choose a reason for hiding this comment

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

A better option would be to use the test's temp dir as scratch space

Copy link
Member Author

Choose a reason for hiding this comment

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

This will just re-introduce the bugs fixed in #31542, no?

Oops, forgot about it 🤦

Copy link
Member Author

Choose a reason for hiding this comment

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

A better option would be to use the test's temp dir as scratch space

That doesn't work with the currently used std::string overload of subprocess::Popen() because of to the space in the full path. Is using fs::temp_directory_path() acceptable?

Copy link
Member

Choose a reason for hiding this comment

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

Does quoting not work?

Copy link
Member Author

Choose a reason for hiding this comment

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

subprocess uses space and tab as delimiters:

/*!
* Function: split
* Parameters:
* [in] str : Input string which needs to be split based upon the
* delimiters provided.
* [in] deleims : Delimiter characters based upon which the string needs
* to be split. Default constructed to ' '(space) and '\t'(tab)
* [out] vector<string> : Vector of strings split at deleimiter.
*/
static inline std::vector<std::string>
split(const std::string& str, const std::string& delims=" \t")
{
std::vector<std::string> res;
size_t init = 0;
while (true) {
auto pos = str.find_first_of(delims, init);
if (pos == std::string::npos) {
res.emplace_back(str.substr(init, str.length()));
break;
}
res.emplace_back(str.substr(init, pos - init));
pos++;
init = pos;
}
return res;
}

Copy link
Member

Choose a reason for hiding this comment

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

Then it seems like it should be fixed in RunCommandParseJSON, because real users could run into the bug as well?

RunCommandParseJSON should just take a string and then pass it to the shell as-is?

Copy link
Member Author

Choose a reason for hiding this comment

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

That was the approach in #32577.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, but it is unclear to me why it was closed, when it looks like the correct approach

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, but it is unclear to me why it was closed, when it looks like the correct approach

Reopened.

@hebasto hebasto marked this pull request as draft May 23, 2025 13:07
@fanquake
Copy link
Member

fanquake commented Jul 4, 2025

Probably close this now, if #32577 has been re-opened, and the approach here has been nacked for re-introducing bugs?

@hebasto hebasto closed this Jul 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

subprocess: sh -c 'echo err 1>&2 && false' must return 1

4 participants