Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Retry all RPC commands to fix MacOS CI jobs #5171

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
18 changes: 18 additions & 0 deletions .github/actions/dependencies/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ runs:
# Do not quote the URL. An empty string will be accepted (with
# a non-fatal warning), but a missing argument will not.
conan remote add ripple ${{ env.CONAN_URL }} --insert 0
if [[ "${RUNNER_OS}" = "macOS" ]]
then
conan profile update 'env.CXXFLAGS="-DBOOST_ASIO_DISABLE_CONCEPTS"' default
conan profile update 'conf.tools.build:cxxflags+=["-DBOOST_ASIO_DISABLE_CONCEPTS"]' default
fi
- name: try to authenticate to Ripple Conan remote
id: remote
shell: bash
Expand All @@ -47,6 +52,19 @@ runs:
run: |
mkdir ${build_dir}
cd ${build_dir}
# This fixes some dependency build issues, especially on MacOS
if [[ "${RUNNER_OS}" = "macOS" && \
"${{ steps.binaries.outputs.missing }}" =~ "boost" ]]
then
conan install \
--output-folder . \
--build boost \
--options tests=True \
--options xrpld=True \
--settings build_type=${{ inputs.configuration }} \
.. || \
rm -rfv ~/.conan
fi
conan install \
--output-folder . \
--build missing \
Expand Down
20 changes: 19 additions & 1 deletion .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@ jobs:

test:
strategy:
fail-fast: false
matrix:
platform:
- macos
generator:
- Ninja
configuration:
- Release
- Debug
cmake-args:
-
- "-Dunity=ON"
runs-on: [self-hosted, macOS]
env:
# The `build` action requires these variables.
Expand All @@ -41,13 +46,19 @@ jobs:
- name: install Ninja
if: matrix.generator == 'Ninja'
run: brew install ninja
- name: install nproc
run: |
brew install coreutils
- name: check environment
run: |
env | sort
echo ${PATH} | tr ':' '\n'
python --version
conan --version
cmake --version
nproc --version
echo -n "nproc returns: "
nproc
- name: configure Conan
run : |
conan profile new default --detect || true
Expand All @@ -66,6 +77,13 @@ jobs:
with:
generator: ${{ matrix.generator }}
configuration: ${{ matrix.configuration }}
cmake-args: ${{ matrix.cmake-args }}
- name: test
run: |
${build_dir}/rippled --unittest
n=$(nproc)
if [[ $n -gt 2 ]]
then
: $[ n/=2 ]
fi
echo "Using $n test jobs"
${build_dir}/rippled --unittest --unittest-jobs $n
2 changes: 1 addition & 1 deletion include/xrpl/protocol/TxFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ constexpr std::uint32_t const tfTrustLine = 0x00000004;
constexpr std::uint32_t const tfTransferable = 0x00000008;

// MPTokenIssuanceCreate flags:
// NOTE - there is intentionally no flag here for lsfMPTLocked, which this transaction cannot mutate.
// NOTE - there is intentionally no flag here for lsfMPTLocked, which this transaction cannot mutate.
constexpr std::uint32_t const tfMPTCanLock = lsfMPTCanLock;
constexpr std::uint32_t const tfMPTRequireAuth = lsfMPTRequireAuth;
constexpr std::uint32_t const tfMPTCanEscrow = lsfMPTCanEscrow;
Expand Down
5 changes: 3 additions & 2 deletions include/xrpl/server/detail/Door.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,9 @@ Door<Handler>::reOpen()
acceptor_.bind(local_address, ec);
if (ec)
{
JLOG(j_.error()) << "Bind port '" << port_.name
<< "' failed:" << ec.message();
JLOG(j_.error()) << "Bind port '" << port_.name << "', ("
<< local_address << ")"
<< "failed:" << ec.message();
Throw<std::exception>();
}

Expand Down
1 change: 1 addition & 0 deletions src/test/app/MultiSign_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,7 @@ class MultiSign_test : public beast::unit_test::suite
Json::Value jv_submit;
jv_submit[jss::tx_json] = jrr[jss::tx_json];
jrr = env.rpc(
env.rejectNever,
"json",
"submit_multisigned",
to_string(jv_submit))[jss::result];
Expand Down
77 changes: 76 additions & 1 deletion src/test/jtx/Env.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,26 @@ class Env
return *bundle_.client;
}

/// Given the return value of an RPC call, returns true if it is acceptable.
using RpcCallback = std::function<bool(Json::Value const&)>;
/// Used as the default callback - any result is acceptable, except an
/// internal error, which usually indicates a timeout.
const RpcCallback rejectInternalError = [](Json::Value const& jr) {
auto const parsedResult = parseResult(jr);
return parsedResult.rpcCode != rpcINTERNAL;
};
/// Used as the callback when any result is acceptable, particularly when an
/// internal error is expected.
const RpcCallback rejectNever = [](Json::Value const&) { return true; };
/// Returns the appropriate callback when the decision of what is acceptible
/// is made at run time. For example, when conditional on API version
/// number.
RpcCallback
rejectInternalErrorIf(bool shouldFail)
{
return shouldFail ? rejectNever : rejectInternalError;
}

/** Execute an RPC command.

The command is examined and used to build
Expand All @@ -303,16 +323,43 @@ class Env
Json::Value
rpc(unsigned apiVersion, std::string const& cmd, Args&&... args);

template <class... Args>
Json::Value
rpc(RpcCallback cb,
std::unordered_map<std::string, std::string> const& headers,
std::string const& cmd,
Args&&... args);

template <class... Args>
Json::Value
rpc(std::unordered_map<std::string, std::string> const& headers,
std::string const& cmd,
Args&&... args);

template <class... Args>
Json::Value
rpc(RpcCallback cb, std::string const& cmd, Args&&... args);

template <class... Args>
Json::Value
rpc(std::string const& cmd, Args&&... args);

void
retry(std::function<void()> cb, std::string const& context);

static void
retry(
std::function<void()> cb,
std::string const& context,
std::chrono::milliseconds delay);

static void
retry(
std::function<void()> cb,
std::string const& context,
beast::unit_test::suite* test,
std::chrono::milliseconds delay);

/** Returns the current ledger.

This is a non-modifiable snapshot of the
Expand Down Expand Up @@ -511,7 +558,10 @@ class Env
jtx::required(args...)(*this);
}

/** Gets the TER result and `didApply` flag from a RPC Json result object.
/** Parses the Json result of an RPC request.
*
* Includes RPC result status, transaction engine result (TER) if
* appropriate, and error information, if any.
*/
static ParsedResult
parseResult(Json::Value const& jr);
Expand Down Expand Up @@ -696,6 +746,7 @@ class Env

Json::Value
do_rpc(
RpcCallback cb,
unsigned apiVersion,
std::vector<std::string> const& args,
std::unordered_map<std::string, std::string> const& headers = {});
Expand Down Expand Up @@ -746,6 +797,7 @@ Env::rpc(
Args&&... args)
{
return do_rpc(
rejectInternalError,
apiVersion,
std::vector<std::string>{cmd, std::forward<Args>(args)...},
headers);
Expand All @@ -765,16 +817,39 @@ Env::rpc(unsigned apiVersion, std::string const& cmd, Args&&... args)
template <class... Args>
Json::Value
Env::rpc(
RpcCallback cb,
std::unordered_map<std::string, std::string> const& headers,
std::string const& cmd,
Args&&... args)
{
return do_rpc(
cb,
RPC::apiCommandLineVersion,
std::vector<std::string>{cmd, std::forward<Args>(args)...},
headers);
}

template <class... Args>
Json::Value
Env::rpc(
std::unordered_map<std::string, std::string> const& headers,
std::string const& cmd,
Args&&... args)
{
return rpc(rejectInternalError, headers, cmd, std::forward<Args>(args)...);
}

template <class... Args>
Json::Value
Env::rpc(RpcCallback cb, std::string const& cmd, Args&&... args)
{
return rpc(
cb,
std::unordered_map<std::string, std::string>(),
cmd,
std::forward<Args>(args)...);
}

template <class... Args>
Json::Value
Env::rpc(std::string const& cmd, Args&&... args)
Expand Down
Loading
Loading