[netemul] Refactor error codes
- Sandbox was using fuchsia::sys::TerminationReason for its termination
codes, refactored termination process to return a netemul-specific
status code.
- Unit tests now check for expected status codes.
Change-Id: I7bc48a34da311d8de1f5a5d6caab27f600e3c5ba
diff --git a/src/connectivity/network/testing/netemul/runner/main.cc b/src/connectivity/network/testing/netemul/runner/main.cc
index cd75919..8e99495 100644
--- a/src/connectivity/network/testing/netemul/runner/main.cc
+++ b/src/connectivity/network/testing/netemul/runner/main.cc
@@ -57,14 +57,10 @@
}
Sandbox sandbox(std::move(args));
- sandbox.SetTerminationCallback([](int64_t exit_code,
- Sandbox::TerminationReason reason) {
- FXL_LOG(INFO) << "Sandbox terminated with (" << exit_code << ") reason: "
- << sys::HumanReadableTerminationReason(reason);
- if (reason != Sandbox::TerminationReason::EXITED) {
- exit_code = 1;
- }
- zx_process_exit(exit_code);
+ sandbox.SetTerminationCallback([](SandboxResult result) {
+ FXL_LOG(INFO) << "Sandbox terminated with status: " << result;
+ int64_t exit = result.is_success() ? 0 : 1;
+ zx_process_exit(exit);
});
sandbox.Start(loop.dispatcher());
diff --git a/src/connectivity/network/testing/netemul/runner/sandbox.cc b/src/connectivity/network/testing/netemul/runner/sandbox.cc
index ce7fd45..35907c1 100644
--- a/src/connectivity/network/testing/netemul/runner/sandbox.cc
+++ b/src/connectivity/network/testing/netemul/runner/sandbox.cc
@@ -25,8 +25,6 @@
namespace netemul {
static const char* kEndpointMountPath = "class/ethernet/";
-constexpr int64_t kFailureTerminationCode = -1;
-constexpr int64_t kTimeoutTerminationCode = 1;
#define STATIC_MSG_STRUCT(name, msgv) \
struct name { \
@@ -75,19 +73,19 @@
test_spawned_ = false;
if (!parent_env_ || !loader_) {
- Terminate(TerminationReason::INTERNAL_ERROR);
+ Terminate(SandboxResult::Status::INTERNAL_ERROR,
+ "Missing parent environment or loader");
return;
} else if (env_config_.disabled()) {
- FXL_LOG(INFO) << "test is disabled, skipping.";
- Terminate(0, TerminationReason::EXITED);
+ Terminate(SandboxResult::Status::SUCCESS, "Test is disabled");
return;
}
helper_loop_ =
std::make_unique<async::Loop>(&kAsyncLoopConfigNoAttachToThread);
if (helper_loop_->StartThread("helper-thread") != ZX_OK) {
- FXL_LOG(ERROR) << "Can't start config thread";
- Terminate(TerminationReason::INTERNAL_ERROR);
+ Terminate(SandboxResult::Status::INTERNAL_ERROR,
+ "Can't start config thread");
return;
}
helper_executor_ =
@@ -99,8 +97,10 @@
TerminationReason reason) {
if (helper_loop_ &&
(reason != TerminationReason::EXITED || exit_code != 0)) {
- async::PostTask(helper_loop_->dispatcher(), [this]() {
- PostTerminate(TerminationReason::INTERNAL_ERROR);
+ async::PostTask(helper_loop_->dispatcher(), [this, service]() {
+ std::stringstream ss;
+ ss << service << " terminated prematurely";
+ PostTerminate(SandboxResult::Status::SERVICE_EXITED, ss.str());
});
}
};
@@ -114,7 +114,7 @@
StartEnvironments();
}
-void Sandbox::Terminate(int64_t exit_code, Sandbox::TerminationReason reason) {
+void Sandbox::Terminate(SandboxResult result) {
// all processes must have been emptied to call callback
ASSERT_MAIN_DISPATCHER;
ZX_ASSERT(procs_.empty());
@@ -125,7 +125,8 @@
helper_loop_ = nullptr;
}
- if (exit_code != 0 || env_config_.capture() == config::CaptureMode::ALWAYS) {
+ if (!result.is_success() ||
+ env_config_.capture() == config::CaptureMode::ALWAYS) {
// check if any of the network dumps have data, and just dump them to
// stdout:
if (net_dumps_ && net_dumps_->HasData()) {
@@ -138,27 +139,28 @@
}
if (termination_callback_) {
- termination_callback_(exit_code, reason);
+ termination_callback_(std::move(result));
}
}
-void Sandbox::PostTerminate(TerminationReason reason) {
- ASSERT_HELPER_DISPATCHER;
- PostTerminate(kFailureTerminationCode, reason);
+void Sandbox::Terminate(netemul::SandboxResult::Status status,
+ std::string description) {
+ Terminate(SandboxResult(status, std::move(description)));
}
-void Sandbox::PostTerminate(int64_t exit_code, TerminationReason reason) {
+void Sandbox::PostTerminate(SandboxResult result) {
ASSERT_HELPER_DISPATCHER;
// kill all component controllers before posting termination
procs_.clear();
- async::PostTask(main_dispatcher_, [this, exit_code, reason]() {
- Terminate(exit_code, reason);
- });
+ async::PostTask(main_dispatcher_,
+ [this, result = std::move(result)]() mutable {
+ Terminate(std::move(result));
+ });
}
-void Sandbox::Terminate(Sandbox::TerminationReason reason) {
- ASSERT_MAIN_DISPATCHER;
- Terminate(kFailureTerminationCode, reason);
+void Sandbox::PostTerminate(netemul::SandboxResult::Status status,
+ std::string description) {
+ PostTerminate(SandboxResult(status, std::move(description)));
}
void Sandbox::StartEnvironments() {
@@ -166,13 +168,15 @@
async::PostTask(helper_loop_->dispatcher(), [this]() {
if (!ConfigureNetworks()) {
- PostTerminate(TerminationReason::INTERNAL_ERROR);
+ PostTerminate(
+ SandboxResult(SandboxResult::Status::NETWORK_CONFIG_FAILED));
return;
}
ManagedEnvironment::Options root_options;
if (!CreateEnvironmentOptions(env_config_.environment(), &root_options)) {
- PostTerminate(TerminationReason::INTERNAL_ERROR);
+ PostTerminate(SandboxResult::Status::ENVIRONMENT_CONFIG_FAILED,
+ "Root environment can't load options");
return;
}
@@ -360,26 +364,29 @@
fit::schedule_for_consumer(
helper_executor_.get(),
ConfigureEnvironment(std::move(svc), &env_config_.environment(), true)
- .or_else(
- [this]() { PostTerminate(TerminationReason::INTERNAL_ERROR); }));
+ .or_else([this](SandboxResult& result) {
+ PostTerminate(std::move(result));
+ }));
}
-fit::promise<> Sandbox::StartChildEnvironment(
+Sandbox::Promise Sandbox::StartChildEnvironment(
ConfiguringEnvironmentPtr parent, const config::Environment* config) {
ASSERT_HELPER_DISPATCHER;
return fit::make_promise(
- [this, parent,
- config]() -> fit::result<ConfiguringEnvironmentPtr> {
+ [this, parent, config]()
+ -> fit::result<ConfiguringEnvironmentPtr, SandboxResult> {
ManagedEnvironment::Options options;
if (!CreateEnvironmentOptions(*config, &options)) {
- return fit::error();
+ return fit::error(SandboxResult(
+ SandboxResult::Status::ENVIRONMENT_CONFIG_FAILED));
}
auto child_env =
std::make_shared<environment::ManagedEnvironmentSyncPtr>();
if ((*parent)->CreateChildEnvironment(
child_env->NewRequest(), std::move(options)) != ZX_OK) {
- return fit::error();
+ return fit::error(SandboxResult(
+ SandboxResult::Status::ENVIRONMENT_CONFIG_FAILED));
}
return fit::ok(std::move(child_env));
@@ -389,11 +396,11 @@
});
}
-fit::promise<> Sandbox::StartEnvironmentSetup(
+Sandbox::Promise Sandbox::StartEnvironmentSetup(
const config::Environment* config,
ConfiguringEnvironmentLauncher launcher) {
return fit::make_promise([this, config, launcher = std::move(launcher)] {
- auto prom = fit::make_ok_promise().box();
+ auto prom = fit::make_result_promise(PromiseResult(fit::ok())).box();
for (const auto& setup : config->setup()) {
prom = prom.and_then([this, setup = &setup, launcher]() {
return LaunchSetup(
@@ -407,43 +414,49 @@
});
}
-fit::promise<> Sandbox::StartEnvironmentAppsAndTests(
+Sandbox::Promise Sandbox::StartEnvironmentAppsAndTests(
const netemul::config::Environment* config,
netemul::Sandbox::ConfiguringEnvironmentLauncher launcher) {
- return fit::make_promise([this, config,
- launcher = std::move(launcher)]() -> fit::result<> {
- for (const auto& app : config->apps()) {
- if (!LaunchProcess<kMsgApp>(
- launcher.get(), app.GetUrlOrDefault(sandbox_env_->default_name()),
- app.arguments(), false)) {
- return fit::error();
- }
- }
+ return fit::make_promise(
+ [this, config, launcher = std::move(launcher)]() -> PromiseResult {
+ for (const auto& app : config->apps()) {
+ auto& url = app.GetUrlOrDefault(sandbox_env_->default_name());
+ if (!LaunchProcess<kMsgApp>(launcher.get(), url, app.arguments(),
+ false)) {
+ std::stringstream ss;
+ ss << "Failed to launch app " << url;
+ return fit::error(
+ SandboxResult(SandboxResult::Status::INTERNAL_ERROR, ss.str()));
+ }
+ }
- for (const auto& test : config->test()) {
- if (!LaunchProcess<kMsgTest>(
- launcher.get(),
- test.GetUrlOrDefault(sandbox_env_->default_name()),
- test.arguments(), true)) {
- return fit::error();
- }
- // save that at least one test was spawned.
- test_spawned_ = true;
- }
+ for (const auto& test : config->test()) {
+ auto& url = test.GetUrlOrDefault(sandbox_env_->default_name());
+ if (!LaunchProcess<kMsgTest>(launcher.get(), url, test.arguments(),
+ true)) {
+ std::stringstream ss;
+ ss << "Failed to launch test " << url;
+ return fit::error(
+ SandboxResult(SandboxResult::Status::INTERNAL_ERROR, ss.str()));
+ }
+ // save that at least one test was spawned.
+ test_spawned_ = true;
+ }
- return fit::ok();
- });
+ return fit::ok();
+ });
}
-fit::promise<> Sandbox::StartEnvironmentInner(
+Sandbox::Promise Sandbox::StartEnvironmentInner(
ConfiguringEnvironmentPtr env, const config::Environment* config) {
ASSERT_HELPER_DISPATCHER;
auto launcher = std::make_shared<fuchsia::sys::LauncherSyncPtr>();
- return fit::make_promise([this, launcher, env]() -> fit::result<> {
+ return fit::make_promise([this, launcher, env]() -> PromiseResult {
// get launcher
if ((*env)->GetLauncher(launcher->NewRequest()) != ZX_OK) {
- FXL_LOG(ERROR) << "Can't get environment launcher";
- return fit::error();
+ return fit::error(
+ SandboxResult(SandboxResult::Status::INTERNAL_ERROR,
+ "Can't get environment launcher"));
}
return fit::ok();
})
@@ -451,12 +464,12 @@
.and_then(StartEnvironmentAppsAndTests(config, launcher));
}
-fit::promise<> Sandbox::ConfigureEnvironment(ConfiguringEnvironmentPtr env,
- const config::Environment* config,
- bool root) {
+Sandbox::Promise Sandbox::ConfigureEnvironment(
+ ConfiguringEnvironmentPtr env, const config::Environment* config,
+ bool root) {
ASSERT_HELPER_DISPATCHER;
- std::vector<fit::promise<>> promises;
+ std::vector<Sandbox::Promise> promises;
// iterate on children
for (const auto& child : config->children()) {
@@ -469,21 +482,25 @@
if (root) {
// if root, after everything is set up, enable observing
// test returns.
- promises.emplace_back(
- self_start.and_then([this]() { EnableTestObservation(); }));
+ promises.emplace_back(self_start.and_then([this]() -> PromiseResult {
+ EnableTestObservation();
+ return fit::ok();
+ }));
} else {
promises.emplace_back(std::move(self_start));
}
return fit::join_promise_vector(std::move(promises))
- .and_then([](std::vector<fit::result<>>& results) -> fit::result<> {
- for (const auto& r : results) {
- if (r.is_error()) {
- return fit::error();
- }
- }
- return fit::ok();
- });
+ .then(
+ [](fit::result<std::vector<PromiseResult>>& result) -> PromiseResult {
+ auto results = result.take_value();
+ for (auto& r : results) {
+ if (r.is_error()) {
+ return r;
+ }
+ }
+ return fit::ok();
+ });
}
template <typename T>
@@ -505,8 +522,11 @@
RegisterTest(ticket);
}
- proc.set_error_handler([this](zx_status_t status) {
- PostTerminate(TerminationReason::INTERNAL_ERROR);
+ proc.set_error_handler([this, url](zx_status_t status) {
+ std::stringstream ss;
+ ss << "Component controller for " << url << " reported error "
+ << zx_status_get_string(status);
+ PostTerminate(SandboxResult::Status::COMPONENT_FAILURE, ss.str());
});
// we observe test processes return code
@@ -518,12 +538,19 @@
// remove the error handler:
procs_[ticket].set_error_handler(nullptr);
if (is_test) {
- if (code != 0 || reason != TerminationReason::EXITED) {
- // test failed, early bail
- PostTerminate(code, reason);
+ if (reason == TerminationReason::EXITED) {
+ if (code != 0) {
+ // test failed, early bail
+ PostTerminate(SandboxResult::Status::TEST_FAILED, url);
+ } else {
+ // unregister test ticket
+ UnregisterTest(ticket);
+ }
} else {
- // unregister test ticket
- UnregisterTest(ticket);
+ std::stringstream ss;
+ ss << "Test component " << url
+ << " failure: " << sys::HumanReadableTerminationReason(reason);
+ PostTerminate(SandboxResult::Status::COMPONENT_FAILURE, ss.str());
}
}
};
@@ -537,12 +564,12 @@
return true;
}
-fit::promise<> Sandbox::LaunchSetup(fuchsia::sys::LauncherSyncPtr* launcher,
- const std::string& url,
- const std::vector<std::string>& arguments) {
+Sandbox::Promise Sandbox::LaunchSetup(
+ fuchsia::sys::LauncherSyncPtr* launcher, const std::string& url,
+ const std::vector<std::string>& arguments) {
ASSERT_HELPER_DISPATCHER;
- fit::bridge<> bridge;
+ fit::bridge<void, SandboxResult> bridge;
fuchsia::sys::LaunchInfo linfo;
linfo.url = url;
@@ -554,11 +581,16 @@
if ((*launcher)->CreateComponent(std::move(linfo), proc.NewRequest()) !=
ZX_OK) {
- FXL_LOG(ERROR) << "couldn't launch setup: " << url;
- bridge.completer.complete_error();
+ std::stringstream ss;
+ ss << "Failed to launch setup " << url;
+ bridge.completer.complete_error(
+ SandboxResult(SandboxResult::Status::INTERNAL_ERROR, ss.str()));
} else {
- proc.set_error_handler([this](zx_status_t status) {
- PostTerminate(TerminationReason::INTERNAL_ERROR);
+ proc.set_error_handler([this, url](zx_status_t status) {
+ std::stringstream ss;
+ ss << "Component controller for " << url << " reported error "
+ << zx_status_get_string(status);
+ PostTerminate(SandboxResult::Status::COMPONENT_FAILURE, ss.str());
});
// we observe test processes return code
@@ -573,7 +605,8 @@
if (code == 0 && reason == TerminationReason::EXITED) {
completer.complete_ok();
} else {
- completer.complete_error();
+ completer.complete_error(
+ SandboxResult(SandboxResult::Status::SETUP_FAILED, url));
}
};
}
@@ -590,13 +623,13 @@
// consider it a failure.
if (!test_spawned_) {
FXL_LOG(ERROR) << "No tests were specified";
- PostTerminate(TerminationReason::INTERNAL_ERROR);
+ PostTerminate(SandboxResult::EMPTY_TEST_SET);
return;
}
if (tests_.empty()) {
// all tests finished successfully
- PostTerminate(0, TerminationReason::EXITED);
+ PostTerminate(SandboxResult::SUCCESS);
return;
}
@@ -606,7 +639,7 @@
helper_loop_->dispatcher(),
[this]() {
FXL_LOG(ERROR) << "Test timed out.";
- PostTerminate(kTimeoutTerminationCode, TerminationReason::EXITED);
+ PostTerminate(SandboxResult::TIMEOUT);
},
env_config_.timeout());
}
@@ -624,7 +657,7 @@
tests_.erase(ticket);
if (setup_done_ && tests_.empty()) {
// all tests finished successfully
- PostTerminate(0, TerminationReason::EXITED);
+ PostTerminate(SandboxResult::SUCCESS);
}
}
@@ -661,4 +694,47 @@
return ParseFromJSON(cmx.GetFacet(config::Config::Facet), &json_parser);
}
+std::ostream& operator<<(std::ostream& os, const SandboxResult& result) {
+ switch (result.status_) {
+ case SandboxResult::Status::SUCCESS:
+ os << "Success";
+ break;
+ case SandboxResult::Status::NETWORK_CONFIG_FAILED:
+ os << "Network configuration failed";
+ break;
+ case SandboxResult::Status::SERVICE_EXITED:
+ os << "Service exited";
+ break;
+ case SandboxResult::Status::ENVIRONMENT_CONFIG_FAILED:
+ os << "Environment configuration failed";
+ break;
+ case SandboxResult::Status::TEST_FAILED:
+ os << "Test failed";
+ break;
+ case SandboxResult::Status::COMPONENT_FAILURE:
+ os << "Component failure";
+ break;
+ case SandboxResult::Status::SETUP_FAILED:
+ os << "Setup failed";
+ break;
+ case SandboxResult::Status::EMPTY_TEST_SET:
+ os << "Test set is empty";
+ break;
+ case SandboxResult::Status::TIMEOUT:
+ os << "Timeout";
+ break;
+ case SandboxResult::Status::INTERNAL_ERROR:
+ os << "Internal Error";
+ break;
+ case SandboxResult::Status::UNSPECIFIED:
+ os << "Unspecified error";
+ break;
+ default:
+ os << "Undefined(" << static_cast<uint32_t>(result.status_) << ")";
+ }
+ if (!result.description_.empty()) {
+ os << ": " << result.description_;
+ }
+ return os;
+}
} // namespace netemul
diff --git a/src/connectivity/network/testing/netemul/runner/sandbox.h b/src/connectivity/network/testing/netemul/runner/sandbox.h
index 9504f72..248b6c0 100644
--- a/src/connectivity/network/testing/netemul/runner/sandbox.h
+++ b/src/connectivity/network/testing/netemul/runner/sandbox.h
@@ -29,11 +29,46 @@
config::Config config;
};
+class SandboxResult {
+ public:
+ enum Status {
+ SUCCESS,
+ NETWORK_CONFIG_FAILED,
+ SERVICE_EXITED,
+ ENVIRONMENT_CONFIG_FAILED,
+ TEST_FAILED,
+ SETUP_FAILED,
+ COMPONENT_FAILURE,
+ EMPTY_TEST_SET,
+ TIMEOUT,
+ INTERNAL_ERROR,
+ UNSPECIFIED
+ };
+
+ SandboxResult() : status_(SUCCESS) {}
+ explicit SandboxResult(Status status) : status_(status) {}
+
+ SandboxResult(Status status, std::string description)
+ : status_(status), description_(std::move(description)) {}
+
+ bool is_success() const { return status_ == Status::SUCCESS; }
+
+ Status status() const { return status_; }
+
+ const std::string& description() const { return description_; }
+
+ friend std::ostream& operator<<(std::ostream& os,
+ const SandboxResult& result);
+
+ private:
+ Status status_;
+ std::string description_;
+};
+
class Sandbox {
public:
using TerminationReason = fuchsia::sys::TerminationReason;
- using TerminationCallback =
- fit::function<void(int64_t code, TerminationReason reason)>;
+ using TerminationCallback = fit::function<void(SandboxResult)>;
using ServicesCreatedCallback = fit::function<void()>;
using RootEnvironmentCreatedCallback =
fit::function<void(ManagedEnvironment*)>;
@@ -62,12 +97,16 @@
fidl::SynchronousInterfacePtr<ManagedEnvironment::FManagedEnvironment>>;
using ConfiguringEnvironmentLauncher =
std::shared_ptr<fidl::SynchronousInterfacePtr<fuchsia::sys::Launcher>>;
+ using Promise = fit::promise<void, SandboxResult>;
+ using PromiseResult = fit::result<void, SandboxResult>;
void StartEnvironments();
- void Terminate(TerminationReason reason);
- void Terminate(int64_t exit_code, TerminationReason reason);
- void PostTerminate(TerminationReason reason);
- void PostTerminate(int64_t exit_code, TerminationReason reason);
+ void Terminate(SandboxResult result);
+ void Terminate(SandboxResult::Status status,
+ std::string description = std::string());
+ void PostTerminate(SandboxResult result);
+ void PostTerminate(SandboxResult::Status status,
+ std::string description = std::string());
void EnableTestObservation();
void RegisterTest(size_t ticket);
@@ -78,26 +117,25 @@
const std::string& url,
const std::vector<std::string>& arguments, bool is_test);
- fit::promise<> LaunchSetup(fuchsia::sys::LauncherSyncPtr* launcher,
- const std::string& url,
- const std::vector<std::string>& arguments);
+ Promise LaunchSetup(fuchsia::sys::LauncherSyncPtr* launcher,
+ const std::string& url,
+ const std::vector<std::string>& arguments);
- fit::promise<> StartChildEnvironment(ConfiguringEnvironmentPtr parent,
- const config::Environment* config);
- fit::promise<> StartEnvironmentInner(ConfiguringEnvironmentPtr environment,
- const config::Environment* config);
- fit::promise<> StartEnvironmentSetup(const config::Environment* config,
+ Promise StartChildEnvironment(ConfiguringEnvironmentPtr parent,
+ const config::Environment* config);
+ Promise StartEnvironmentInner(ConfiguringEnvironmentPtr environment,
+ const config::Environment* config);
+ Promise StartEnvironmentSetup(const config::Environment* config,
+ ConfiguringEnvironmentLauncher launcher);
+ Promise StartEnvironmentAppsAndTests(const config::Environment* config,
ConfiguringEnvironmentLauncher launcher);
- fit::promise<> StartEnvironmentAppsAndTests(
- const config::Environment* config,
- ConfiguringEnvironmentLauncher launcher);
bool CreateEnvironmentOptions(const config::Environment& config,
ManagedEnvironment::Options* options);
void ConfigureRootEnvironment();
- fit::promise<> ConfigureEnvironment(ConfiguringEnvironmentPtr env,
- const config::Environment* config,
- bool root = false);
+ Promise ConfigureEnvironment(ConfiguringEnvironmentPtr env,
+ const config::Environment* config,
+ bool root = false);
bool ConfigureNetworks();
async_dispatcher_t* main_dispatcher_;
diff --git a/src/connectivity/network/testing/netemul/runner/sandbox_unittest.cc b/src/connectivity/network/testing/netemul/runner/sandbox_unittest.cc
index 2e5c752..db668ee 100644
--- a/src/connectivity/network/testing/netemul/runner/sandbox_unittest.cc
+++ b/src/connectivity/network/testing/netemul/runner/sandbox_unittest.cc
@@ -34,11 +34,10 @@
protected:
using TerminationReason = Sandbox::TerminationReason;
- void RunSandbox(bool expect_success, TerminationReason expect_reason) {
+ void RunSandbox(SandboxResult::Status expect) {
Sandbox sandbox(std::move(sandbox_args_));
bool done = false;
- int64_t o_exit_code;
- TerminationReason o_term_reason;
+ SandboxResult o_result;
sandbox.SetServicesCreatedCallback([this, &sandbox]() {
if (connect_to_network_) {
@@ -49,13 +48,9 @@
}
});
- sandbox.SetTerminationCallback([&done, &o_exit_code, &o_term_reason](
- int64_t exit_code,
- TerminationReason reason) {
- FXL_LOG(INFO) << "Sandbox terminated with (" << exit_code << ") reason: "
- << sys::HumanReadableTerminationReason(reason);
- o_exit_code = exit_code;
- o_term_reason = reason;
+ sandbox.SetTerminationCallback([&done, &o_result](SandboxResult result) {
+ FXL_LOG(INFO) << "Sandbox terminated with status: " << result;
+ o_result = std::move(result);
done = true;
});
@@ -70,17 +65,19 @@
// last chance to read any events pending.
RunLoopUntilIdle();
- EXPECT_EQ(o_exit_code == 0, expect_success);
- EXPECT_EQ(o_term_reason, expect_reason);
+ // If we're expecting unspecified status, we will just check for expected
+ // failure. That's for failure cases that can have races on different
+ // failure points.
+ if (expect == SandboxResult::Status::UNSPECIFIED) {
+ EXPECT_FALSE(o_result.is_success());
+ } else {
+ EXPECT_EQ(o_result.status(), expect);
+ }
}
- void RunSandboxSuccess() { RunSandbox(true, TerminationReason::EXITED); }
+ void RunSandboxSuccess() { RunSandbox(SandboxResult::SUCCESS); }
- void RunSandboxInternalError() {
- RunSandbox(false, TerminationReason::INTERNAL_ERROR);
- }
-
- void RunSandboxFailure() { RunSandbox(false, TerminationReason::EXITED); }
+ void RunSandboxFailure() { RunSandbox(SandboxResult::TEST_FAILED); }
void SetCmx(const std::string& cmx) {
ASSERT_TRUE(sandbox_args_.ParseFromString(cmx));
@@ -294,7 +291,7 @@
}
)");
EnableEventCollection();
- RunSandboxInternalError();
+ RunSandbox(SandboxResult::Status::SETUP_FAILED);
// root proc should not have run, so events should be empty
EXPECT_TRUE(events().empty());
}
@@ -481,7 +478,7 @@
]
}
)");
- RunSandboxInternalError();
+ RunSandbox(SandboxResult::Status::NETWORK_CONFIG_FAILED);
}
TEST_F(SandboxTest, DuplicateEndpointNameFails) {
@@ -503,7 +500,7 @@
]
}
)");
- RunSandboxInternalError();
+ RunSandbox(SandboxResult::Status::NETWORK_CONFIG_FAILED);
}
TEST_F(SandboxTest, ValidNetworkSetup) {
@@ -649,7 +646,7 @@
}
}
)");
- RunSandboxInternalError();
+ RunSandbox(SandboxResult::Status::EMPTY_TEST_SET);
}
TEST_F(SandboxTest, DisabledTestSucceeds) {
@@ -676,7 +673,7 @@
}
}
)");
- RunSandbox(false, TerminationReason::PACKAGE_NOT_FOUND);
+ RunSandbox(SandboxResult::Status::COMPONENT_FAILURE);
}
TEST_F(SandboxTest, TimeoutFires) {
@@ -691,7 +688,7 @@
)");
// expect that we'll fail due to the timeout of 1s < 10s of wait in the dummy
// proc:
- RunSandbox(false, TerminationReason::EXITED);
+ RunSandbox(SandboxResult::Status::TIMEOUT);
}
TEST_F(SandboxTest, ProcessSucceedsBeforeTimeoutFires) {
@@ -722,7 +719,7 @@
}
}
)");
- RunSandboxInternalError();
+ RunSandbox(SandboxResult::Status::SERVICE_EXITED);
}
TEST_F(SandboxTest, ServiceExittingCausesFailure) {
@@ -742,7 +739,7 @@
}
}
)");
- RunSandboxInternalError();
+ RunSandbox(SandboxResult::Status::SERVICE_EXITED);
}
TEST_F(SandboxTest, DestructorRunsCleanly) {
@@ -764,9 +761,7 @@
)");
auto sandbox = std::make_unique<Sandbox>(TakeArgs());
sandbox->SetTerminationCallback(
- [](int64_t exit_code, TerminationReason reason) {
- FAIL() << "Shouldn't exit";
- });
+ [](SandboxResult result) { FAIL() << "Shouldn't exit"; });
sandbox->Start(dispatcher());
// Give enough time for the process to actually open the file:
RunLoopWithTimeout(zx::msec(15));
@@ -790,7 +785,11 @@
]
}
})");
- RunSandboxInternalError();
+ // Failures for environment with same name can come
+ // from different sources and is racy, to prevent
+ // test flakiness we just check that it'll fail cleanly,
+ // and not expect a specific return code.
+ RunSandbox(SandboxResult::Status::UNSPECIFIED);
}
} // namespace testing