blob: 66e5a13b18c0c9184aa5dc31925707781a0102e1 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "test_helper_fixture.h"
#include <lib/fdio/spawn.h>
#include <zircon/processargs.h>
#include "src/lib/fxl/arraysize.h"
#include "src/lib/fxl/logging.h"
#include "test_helper.h"
#include "util.h"
namespace debugger_utils {
const char* const TestWithHelper::kWaitPeerClosedArgv[] = {
kTestHelperPath,
"wait-peer-closed",
nullptr,
};
void TestWithHelper::SetUp() {}
void TestWithHelper::TearDown() {
// Closing the channel should cause the helper to terminate, if it
// hasn't already.
channel_.reset();
zx_signals_t pending;
zx_status_t status = process_.wait_one(ZX_PROCESS_TERMINATED, zx::time::infinite(), &pending);
ASSERT_EQ(status, ZX_OK);
}
zx_status_t TestWithHelper::RunHelperProgram(const zx::job& job, const char* const argv[]) {
zx::channel our_channel, their_channel;
zx_status_t status = zx::channel::create(0, &our_channel, &their_channel);
if (status != ZX_OK) {
FX_LOGS(ERROR) << "zx::channel::create failed: " << ZxErrorString(status);
return status;
}
fdio_spawn_action actions[1];
actions[0].action = FDIO_SPAWN_ACTION_ADD_HANDLE;
actions[0].h.id = PA_HND(PA_USER0, 0);
actions[0].h.handle = their_channel.release();
uint32_t flags = FDIO_SPAWN_CLONE_ALL;
char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
zx::process process;
status = fdio_spawn_etc(job.get(), flags, kTestHelperPath, argv, nullptr, arraysize(actions),
actions, process.reset_and_get_address(), err_msg);
if (status != ZX_OK) {
FX_LOGS(ERROR) << "fdio_spawn_etc failed: " << ZxErrorString(status) << ", " << err_msg;
return status;
}
process_ = std::move(process);
channel_ = std::move(our_channel);
return status;
}
zx_status_t TestWithHelper::GetHelperThread(zx::thread* out_thread) {
zx_signals_t pending;
zx_status_t status = channel_.wait_one(ZX_CHANNEL_READABLE, zx::time::infinite(), &pending);
if (status != ZX_OK) {
FX_LOGS(ERROR) << "channel->wait_one failed: " << ZxErrorString(status);
return status;
}
uint32_t actual_bytes, actual_handles;
status = channel_.read(0u, nullptr, out_thread->reset_and_get_address(), 0u, 1u, &actual_bytes,
&actual_handles);
if (status != ZX_OK) {
FX_LOGS(ERROR) << "channel->read failed: " << ZxErrorString(status);
return status;
}
EXPECT_EQ(actual_bytes, 0u);
EXPECT_EQ(actual_handles, 1u);
// At this point the inferior is generally waiting for us to close the
// channel.
return ZX_OK;
}
} // namespace debugger_utils