1c5011aedSJim Ingham //===-- ProcessEventDataTest.cpp ------------------------------------------===//
2c5011aedSJim Ingham //
3c5011aedSJim Ingham // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c5011aedSJim Ingham // See https://llvm.org/LICENSE.txt for license information.
5c5011aedSJim Ingham // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c5011aedSJim Ingham //
7c5011aedSJim Ingham //===----------------------------------------------------------------------===//
8c5011aedSJim Ingham
9c5011aedSJim Ingham #include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
10f24532aeSJim Ingham #include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h"
11c5011aedSJim Ingham #include "lldb/Core/Debugger.h"
12c5011aedSJim Ingham #include "lldb/Host/FileSystem.h"
13c5011aedSJim Ingham #include "lldb/Host/HostInfo.h"
14c5011aedSJim Ingham #include "lldb/Interpreter/CommandInterpreter.h"
15c5011aedSJim Ingham #include "lldb/Interpreter/CommandObject.h"
16c5011aedSJim Ingham #include "lldb/Interpreter/CommandObjectMultiword.h"
17c5011aedSJim Ingham #include "lldb/Interpreter/CommandReturnObject.h"
18c5011aedSJim Ingham #include "lldb/Utility/Args.h"
19c5011aedSJim Ingham #include "lldb/Utility/Reproducer.h"
20c5011aedSJim Ingham #include "lldb/Utility/Status.h"
21c5011aedSJim Ingham
22c5011aedSJim Ingham #include "gtest/gtest.h"
23c5011aedSJim Ingham
24c5011aedSJim Ingham using namespace lldb_private;
25c5011aedSJim Ingham using namespace lldb_private::repro;
26c5011aedSJim Ingham using namespace lldb;
27c5011aedSJim Ingham
28c5011aedSJim Ingham namespace {
29c5011aedSJim Ingham class VerifyUserMultiwordCmdPathTest : public ::testing::Test {
SetUp()30c5011aedSJim Ingham void SetUp() override {
31c5011aedSJim Ingham llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None));
32c5011aedSJim Ingham FileSystem::Initialize();
33c5011aedSJim Ingham HostInfo::Initialize();
34c5011aedSJim Ingham PlatformMacOSX::Initialize();
35c5011aedSJim Ingham }
TearDown()36c5011aedSJim Ingham void TearDown() override {
37c5011aedSJim Ingham PlatformMacOSX::Terminate();
38c5011aedSJim Ingham HostInfo::Terminate();
39c5011aedSJim Ingham FileSystem::Terminate();
40c5011aedSJim Ingham Reproducer::Terminate();
41c5011aedSJim Ingham }
42c5011aedSJim Ingham };
43c5011aedSJim Ingham } // namespace
44c5011aedSJim Ingham
45c5011aedSJim Ingham class CommandObjectLeaf : public CommandObjectParsed {
46c5011aedSJim Ingham public:
CommandObjectLeaf(CommandInterpreter & interpreter)47c5011aedSJim Ingham CommandObjectLeaf(CommandInterpreter &interpreter)
48c5011aedSJim Ingham : CommandObjectParsed(interpreter, "dummy subcommand leaf",
49c5011aedSJim Ingham "Does nothing", "dummy subcommand leaf") {
50c5011aedSJim Ingham SetIsUserCommand(true);
51c5011aedSJim Ingham }
52c5011aedSJim Ingham
53c5011aedSJim Ingham protected:
DoExecute(Args & command,CommandReturnObject & result)54*fd146460SShafik Yaghmour bool DoExecute(Args &command, CommandReturnObject &result) override {
55c5011aedSJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult);
56c5011aedSJim Ingham result.AppendMessage("I did nothing");
57c5011aedSJim Ingham return true;
58c5011aedSJim Ingham }
59c5011aedSJim Ingham };
60c5011aedSJim Ingham
61c5011aedSJim Ingham class CommandObjectMultiwordSubDummy : public CommandObjectMultiword {
62c5011aedSJim Ingham public:
CommandObjectMultiwordSubDummy(CommandInterpreter & interpreter)63c5011aedSJim Ingham CommandObjectMultiwordSubDummy(CommandInterpreter &interpreter)
64c5011aedSJim Ingham : CommandObjectMultiword(interpreter, "dummy subcommand", "Does nothing",
65c5011aedSJim Ingham "dummy subcommand") {
66c5011aedSJim Ingham SetIsUserCommand(true);
67c5011aedSJim Ingham LoadSubCommand("leaf", CommandObjectSP(new CommandObjectLeaf(interpreter)));
68c5011aedSJim Ingham }
69c5011aedSJim Ingham
70c5011aedSJim Ingham ~CommandObjectMultiwordSubDummy() override = default;
71c5011aedSJim Ingham };
72c5011aedSJim Ingham
73c5011aedSJim Ingham class CommandObjectMultiwordDummy : public CommandObjectMultiword {
74c5011aedSJim Ingham public:
CommandObjectMultiwordDummy(CommandInterpreter & interpreter)75c5011aedSJim Ingham CommandObjectMultiwordDummy(CommandInterpreter &interpreter)
76c5011aedSJim Ingham : CommandObjectMultiword(interpreter, "dummy", "Does nothing", "dummy") {
77c5011aedSJim Ingham SetIsUserCommand(true);
78c5011aedSJim Ingham LoadSubCommand(
79c5011aedSJim Ingham "subcommand",
80c5011aedSJim Ingham CommandObjectSP(new CommandObjectMultiwordSubDummy(interpreter)));
81c5011aedSJim Ingham }
82c5011aedSJim Ingham
83c5011aedSJim Ingham ~CommandObjectMultiwordDummy() override = default;
84c5011aedSJim Ingham };
85c5011aedSJim Ingham
86c5011aedSJim Ingham // Pass in the command path to args. If success is true, we make sure the MWC
87c5011aedSJim Ingham // returned matches the test string. If success is false, we make sure the
88c5011aedSJim Ingham // lookup error matches test_str.
RunTest(CommandInterpreter & interp,const char * args,bool is_leaf,bool success,const char * test_str)89c5011aedSJim Ingham void RunTest(CommandInterpreter &interp, const char *args, bool is_leaf,
90c5011aedSJim Ingham bool success, const char *test_str) {
91c5011aedSJim Ingham CommandObjectMultiword *multi_word_cmd = nullptr;
92c5011aedSJim Ingham Args test_args(args);
93c5011aedSJim Ingham Status error;
94c5011aedSJim Ingham multi_word_cmd =
95c5011aedSJim Ingham interp.VerifyUserMultiwordCmdPath(test_args, is_leaf, error);
96c5011aedSJim Ingham if (success) {
97c5011aedSJim Ingham ASSERT_NE(multi_word_cmd, nullptr);
98c5011aedSJim Ingham ASSERT_TRUE(error.Success());
99c5011aedSJim Ingham ASSERT_STREQ(multi_word_cmd->GetCommandName().str().c_str(), test_str);
100c5011aedSJim Ingham } else {
101c5011aedSJim Ingham ASSERT_EQ(multi_word_cmd, nullptr);
102c5011aedSJim Ingham ASSERT_TRUE(error.Fail());
103c5011aedSJim Ingham ASSERT_STREQ(error.AsCString(), test_str);
104c5011aedSJim Ingham }
105c5011aedSJim Ingham }
106c5011aedSJim Ingham
TEST_F(VerifyUserMultiwordCmdPathTest,TestErrors)107c5011aedSJim Ingham TEST_F(VerifyUserMultiwordCmdPathTest, TestErrors) {
108f24532aeSJim Ingham ArchSpec arch("x86_64-apple-macosx-");
109f24532aeSJim Ingham
110f24532aeSJim Ingham Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch));
111f24532aeSJim Ingham
112c5011aedSJim Ingham DebuggerSP debugger_sp = Debugger::CreateInstance();
113c5011aedSJim Ingham ASSERT_TRUE(debugger_sp);
114c5011aedSJim Ingham
115c5011aedSJim Ingham CommandInterpreter &interp = debugger_sp->GetCommandInterpreter();
116c5011aedSJim Ingham
117c5011aedSJim Ingham Status error;
118c5011aedSJim Ingham bool success;
119c5011aedSJim Ingham bool is_leaf;
120c5011aedSJim Ingham
121c5011aedSJim Ingham // Test that we reject non-user path components:
122c5011aedSJim Ingham success = false;
123c5011aedSJim Ingham is_leaf = true;
124c5011aedSJim Ingham RunTest(interp, "process launch", is_leaf, success,
125c5011aedSJim Ingham "Path component: 'process' is not a user command");
126c5011aedSJim Ingham
127c5011aedSJim Ingham // Test that we reject non-existent commands:
128c5011aedSJim Ingham is_leaf = true;
129c5011aedSJim Ingham success = false;
130c5011aedSJim Ingham RunTest(interp, "wewouldnevernameacommandthis subcommand", is_leaf, success,
131c5011aedSJim Ingham "Path component: 'wewouldnevernameacommandthis' not found");
132c5011aedSJim Ingham
133c5011aedSJim Ingham // Now we have to add a multiword command, and then probe it.
134c5011aedSJim Ingham error = interp.AddUserCommand(
135c5011aedSJim Ingham "dummy", CommandObjectSP(new CommandObjectMultiwordDummy(interp)), true);
136c5011aedSJim Ingham ASSERT_TRUE(error.Success());
137c5011aedSJim Ingham
138c5011aedSJim Ingham // Now pass the correct path, and make sure we get back the right MWC.
139c5011aedSJim Ingham is_leaf = false;
140c5011aedSJim Ingham success = true;
141c5011aedSJim Ingham RunTest(interp, "dummy subcommand", is_leaf, success, "dummy subcommand");
142c5011aedSJim Ingham
143c5011aedSJim Ingham is_leaf = true;
144c5011aedSJim Ingham RunTest(interp, "dummy subcommand", is_leaf, success, "dummy");
145c5011aedSJim Ingham
146c5011aedSJim Ingham // If you tell us the last node is a leaf, we don't check that. Make sure
147c5011aedSJim Ingham // that is true:
148c5011aedSJim Ingham is_leaf = true;
149c5011aedSJim Ingham success = true;
150c5011aedSJim Ingham RunTest(interp, "dummy subcommand leaf", is_leaf, success,
151c5011aedSJim Ingham "dummy subcommand");
152c5011aedSJim Ingham // But we should fail if we say the last component is a multiword:
153c5011aedSJim Ingham
154c5011aedSJim Ingham is_leaf = false;
155c5011aedSJim Ingham success = false;
156c5011aedSJim Ingham RunTest(interp, "dummy subcommand leaf", is_leaf, success,
157c5011aedSJim Ingham "Path component: 'leaf' is not a container command");
158c5011aedSJim Ingham
159c5011aedSJim Ingham // We should fail if we get the second path component wrong:
160c5011aedSJim Ingham is_leaf = false;
161c5011aedSJim Ingham success = false;
162c5011aedSJim Ingham RunTest(interp, "dummy not-subcommand", is_leaf, success,
163c5011aedSJim Ingham "Path component: 'not-subcommand' not found");
164c5011aedSJim Ingham }
165