blob: 8d7e2b5a78e7a0d91f458be440f330faefe51f91 [file] [log] [blame]
// Copyright 2018 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.
#ifndef SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_REMOTE_API_TEST_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_REMOTE_API_TEST_H_
#include <initializer_list>
#include <memory>
#include <vector>
#include <gtest/gtest.h>
#include "src/developer/debug/shared/platform_message_loop.h"
#include "src/developer/debug/shared/test_stream_buffer.h"
#include "src/developer/debug/zxdb/client/remote_api.h"
#include "src/developer/debug/zxdb/common/test_with_loop.h"
#include "src/lib/fxl/memory/ref_counted.h"
namespace zxdb {
class Frame;
class MockModuleSymbols;
class MockRemoteAPI;
class ModuleSymbols;
class Process;
class Session;
class Thread;
// This is a test harness for client tests that mock out the RemoteAPI. This class sets up a message
// loop and the necessary plumbing.
//
// The individual tests supply their own implementation of RemoteAPI.
class RemoteAPITest : public TestWithLoop {
public:
// testing::Test implementation.
void SetUp() override;
void TearDown() override;
// TODO(dangyi): Use pointer instead of reference to maintain consistency with ClientObject.
Session& session() { return *session_; }
// Returns the MockRemoteAPI constructed by the default implementation of GetRemoteAPIImpl()
// below.
//
// Subclasses can provide any remote API implementation, but most tests want to use the standard
// MockRemoteAPI. When GetRemoteAPIImpl() has not been overridden, it will create a MockRemoteAPI
// and this getter will return it.
//
// If a derived implementation overrides GetRemoteAPIImpl(), this will return null. Such tests
// should provide their own getter for their specific implementation.
MockRemoteAPI* mock_remote_api() const { return mock_remote_api_; }
// Injects the given module into the process. Most callers will want InjectMockModule() below.
void InjectModule(Process* process, fxl::RefPtr<ModuleSymbols> mod_sym, const std::string& name,
uint64_t load_address, const std::string& build_id);
// Creates a MockModuleSymbols with a random name and build ID and reports it as loaded at the
// given address. If the load address is 0, an arbitrary one will be generated.
fxl::RefPtr<MockModuleSymbols> InjectMockModule(Process* process, uint64_t load_address = 0);
// Makes the target have a fake running process with the given KOID. This assumes there is only
// one target in the system and that it is not currently running.
Process* InjectProcess(uint64_t process_koid);
// Sends a "thread created" notifications to the client for the given fake KOID. The thread will
// be reported as running.
Thread* InjectThread(uint64_t process_koid, uint64_t thread_koid);
// Sends the exception notification to the session.
void InjectException(const debug_ipc::NotifyException& exception);
// Sends the exception notification and forces the given stack information. This bypasses the
// normal thread metadata computation. The exception address will be taken from the address of the
// top of the stack.
//
// If you use the one that takes a NotifyException, the calling code need not populate the thread
// vector and stack amount, they will be ignored.
void InjectExceptionWithStack(const debug_ipc::NotifyException& exception,
std::vector<std::unique_ptr<Frame>> frames, bool has_all_frames);
void InjectExceptionWithStack(uint64_t process_koid, uint64_t thread_koid,
debug_ipc::ExceptionType exception_type,
std::vector<std::unique_ptr<Frame>> frames, bool has_all_frames,
const std::vector<debug_ipc::BreakpointStats>& breakpoints = {});
protected:
// Constructs the remote API implementation for this test.
//
// Derived classes can override this to provide their own IPC mocks. Ownership will be transferred
// to the Session so it will be valid until TearDown (most implementations will want to keep a
// pointer).
//
// The default implementation will construct a MockRemoteAPI which will be available from
// mock_remote_api();
virtual std::unique_ptr<RemoteAPI> GetRemoteAPIImpl();
// Allows tests to override the architecture for the test to run in. Defaults to x64.
virtual debug::Arch GetArch() const { return debug::Arch::kX64; }
private:
std::unique_ptr<Session> session_;
MockRemoteAPI* mock_remote_api_ = nullptr; // See getter above. Owned by System.
};
} // namespace zxdb
#endif // SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_REMOTE_API_TEST_H_