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