<rdar://problem/12500212> Test case for the new plugin feature

git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@166453 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/dotest.py b/test/dotest.py
index 1379428..36678c2 100755
--- a/test/dotest.py
+++ b/test/dotest.py
@@ -827,6 +827,9 @@
         print relPath + ', or ' + baiPath
         sys.exit(-1)
 
+    # If tests need to find LLDB_FRAMEWORK, now they can do it
+    os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPath))
+
     # This is to locate the lldb.py module.  Insert it right after sys.path[0].
     sys.path[1:1] = [lldbPath]
     if dumpSysPath:
diff --git a/test/functionalities/plugins/commands/Makefile b/test/functionalities/plugins/commands/Makefile
new file mode 100644
index 0000000..2d79cf6
--- /dev/null
+++ b/test/functionalities/plugins/commands/Makefile
@@ -0,0 +1,11 @@
+all: foo.dylib
+
+CWD := $(shell pwd)
+
+all: foo.dylib
+
+foo.dylib:
+	clang++ -O0 -g -stdlib=libc++ -dynamiclib -o plugin.dylib plugin.cpp -framework LLDB -F $(LLDB_FRAMEWORK)/..
+
+clean:
+	rm -rf plugin.dylib plugin.dylib.dSYM/* plugin.dylib.dSYM
diff --git a/test/functionalities/plugins/commands/TestPluginCommands.py b/test/functionalities/plugins/commands/TestPluginCommands.py
new file mode 100644
index 0000000..a53edca
--- /dev/null
+++ b/test/functionalities/plugins/commands/TestPluginCommands.py
@@ -0,0 +1,57 @@
+"""
+Test that plugins that load commands work correctly.
+"""
+
+import os, time
+import re
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class PluginCommandTestCase(TestBase):
+
+    mydir = os.path.join("functionalities", "plugins", "commands")
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_load_plugin(self):
+        """Test that plugins that load commands work correctly."""
+
+        # Invoke the default build rule.
+        self.buildDefault()
+        
+        debugger = lldb.SBDebugger.Create()
+
+        retobj = lldb.SBCommandReturnObject()
+        
+        retval = debugger.GetCommandInterpreter().HandleCommand("plugin load plugin.dylib",retobj)
+
+        retobj.Clear()
+
+        retval = debugger.GetCommandInterpreter().HandleCommand("plugin_loaded_command child abc def ghi",retobj)
+
+        if self.TraceOn():
+            print retobj.GetOutput()
+
+        self.expect(retobj,substrs = ['abc def ghi'], exe=False)
+
+        retobj.Clear()
+
+        # check that abbreviations work correctly in plugin commands.
+        retval = debugger.GetCommandInterpreter().HandleCommand("plugin_loaded_ ch abc def ghi",retobj)
+
+        if self.TraceOn():
+            print retobj.GetOutput()
+
+        self.expect(retobj,substrs = ['abc def ghi'], exe=False)
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()
diff --git a/test/functionalities/plugins/commands/plugin.cpp b/test/functionalities/plugins/commands/plugin.cpp
new file mode 100644
index 0000000..7b4e46f
--- /dev/null
+++ b/test/functionalities/plugins/commands/plugin.cpp
@@ -0,0 +1,56 @@
+//===-- fooplugin.cpp -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/*
+An example plugin for LLDB that provides a new foo command with a child subcommand
+Compile this into a dylib foo.dylib and load by placing in appropriate locations on disk or
+by typing plugin load foo.dylib at the LLDB command line
+*/
+
+#include <LLDB/SBCommandInterpreter.h>
+#include <LLDB/SBCommandReturnObject.h>
+#include <LLDB/SBDebugger.h>
+
+namespace lldb {
+    bool
+    PluginInitialize (lldb::SBDebugger debugger);
+}
+
+class ChildCommand : public lldb::SBCommandPluginInterface
+{
+public:
+    virtual bool
+    DoExecute (lldb::SBDebugger debugger,
+               char** command,
+               lldb::SBCommandReturnObject &result)
+    {
+        if (command)
+        {
+            const char* arg = *command;
+            while (arg)
+            {
+                result.Printf("%s ",arg);
+                arg = *(++command);
+            }
+            result.Printf("\n");
+            return true;
+        }
+        return false;
+    }
+    
+};
+
+bool
+lldb::PluginInitialize (lldb::SBDebugger debugger)
+{
+    lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter();
+    lldb::SBCommand foo = interpreter.AddMultiwordCommand("plugin_loaded_command",NULL);
+    foo.AddCommand("child",new ChildCommand(),"a child of plugin_loaded_command");
+    return true;
+}
diff --git a/test/lldbtest.py b/test/lldbtest.py
index 7353e22..122fa5a 100644
--- a/test/lldbtest.py
+++ b/test/lldbtest.py
@@ -1184,7 +1184,10 @@
                                  "Command '" + str + "' is expected to fail!")
         else:
             # No execution required, just compare str against the golden input.
-            output = str
+            if isinstance(str,lldb.SBCommandReturnObject):
+                output = str.GetOutput()
+            else:
+                output = str
             with recording(self, trace) as sbuf:
                 print >> sbuf, "looking at:", output