Index: third_party/mojo/src/mojo/public/cpp/application/lib/application_test_base.cc |
diff --git a/third_party/mojo/src/mojo/public/cpp/application/lib/application_test_base.cc b/third_party/mojo/src/mojo/public/cpp/application/lib/application_test_base.cc |
index 20a60a11b3ee49086801c60f1fd28de4b6e771a7..72058a40f35a1b86a088054ee9f428938de51550 100644 |
--- a/third_party/mojo/src/mojo/public/cpp/application/lib/application_test_base.cc |
+++ b/third_party/mojo/src/mojo/public/cpp/application/lib/application_test_base.cc |
@@ -4,33 +4,27 @@ |
#include "mojo/public/cpp/application/application_test_base.h" |
-#include "mojo/public/cpp/application/application_delegate.h" |
#include "mojo/public/cpp/application/application_impl.h" |
+#include "mojo/public/cpp/bindings/binding.h" |
#include "mojo/public/cpp/environment/environment.h" |
#include "mojo/public/cpp/system/message_pipe.h" |
+#include "mojo/public/interfaces/application/application.mojom.h" |
namespace mojo { |
namespace test { |
namespace { |
- |
-// This shell handle is shared by multiple test application instances. |
-MessagePipeHandle g_shell_handle; |
// Share the application command-line arguments with multiple application tests. |
Array<String> g_args; |
-ScopedMessagePipeHandle PassShellHandle() { |
- MOJO_CHECK(g_shell_handle.is_valid()); |
- ScopedMessagePipeHandle scoped_handle(g_shell_handle); |
- g_shell_handle = MessagePipeHandle(); |
- return scoped_handle.Pass(); |
-} |
+// Application request handle passed from the shell in MojoMain, stored in |
+// between SetUp()/TearDown() so we can (re-)intialize new ApplicationImpls. |
+InterfaceRequest<Application> g_application_request; |
-void SetShellHandle(ScopedMessagePipeHandle handle) { |
- MOJO_CHECK(handle.is_valid()); |
- MOJO_CHECK(!g_shell_handle.is_valid()); |
- g_shell_handle = handle.release(); |
-} |
+// Shell pointer passed in the initial mojo.Application.Initialize() call, |
+// stored in between initial setup and the first test and between SetUp/TearDown |
+// calls so we can (re-)initialize new ApplicationImpls. |
+ShellPtr g_shell; |
void InitializeArgs(int argc, std::vector<const char*> argv) { |
MOJO_CHECK(g_args.is_null()); |
@@ -40,38 +34,71 @@ void InitializeArgs(int argc, std::vector<const char*> argv) { |
} |
} |
+class ShellAndArgumentGrabber : public Application { |
+ public: |
+ ShellAndArgumentGrabber(Array<String>* args, |
+ InterfaceRequest<Application> application_request) |
+ : args_(args), binding_(this, application_request.Pass()) {} |
+ |
+ void WaitForInitialize() { |
+ // Initialize is always the first call made on Application. |
+ binding_.WaitForIncomingMethodCall(); |
+ } |
+ |
+ private: |
+ // Application implementation. |
+ void Initialize(ShellPtr shell, Array<String> args) override { |
+ *args_ = args.Pass(); |
+ g_application_request = binding_.Unbind(); |
+ g_shell = shell.Pass(); |
+ } |
+ |
+ void AcceptConnection(const String& requestor_url, |
+ InterfaceRequest<ServiceProvider> services, |
+ ServiceProviderPtr exposed_services) override { |
+ MOJO_CHECK(false); |
+ } |
+ |
+ void RequestQuit() override { MOJO_CHECK(false); } |
+ |
+ Array<String>* args_; |
+ Binding<Application> binding_; |
+}; |
+ |
} // namespace |
const Array<String>& Args() { |
return g_args; |
} |
-MojoResult RunAllTests(MojoHandle shell_handle) { |
+MojoResult RunAllTests(MojoHandle application_request_handle) { |
{ |
// This loop is used for init, and then destroyed before running tests. |
Environment::InstantiateDefaultRunLoop(); |
- // Construct an ApplicationImpl just for the GTEST commandline arguments. |
+ // Grab the shell handle and GTEST commandline arguments. |
// GTEST command line arguments are supported amid application arguments: |
// $ mojo_shell mojo:example_apptests |
// --args-for='mojo:example_apptests arg1 --gtest_filter=foo arg2' |
- mojo::ApplicationDelegate dummy_application_delegate; |
- mojo::ApplicationImpl app(&dummy_application_delegate, shell_handle); |
- MOJO_CHECK(app.WaitForInitialize()); |
+ Array<String> args; |
+ ShellAndArgumentGrabber grabber( |
+ &args, MakeRequest<Application>(MakeScopedHandle( |
+ MessagePipeHandle(application_request_handle)))); |
+ grabber.WaitForInitialize(); |
+ MOJO_CHECK(g_shell); |
+ MOJO_CHECK(g_application_request.is_pending()); |
// InitGoogleTest expects (argc + 1) elements, including a terminating null. |
// It also removes GTEST arguments from |argv| and updates the |argc| count. |
- const std::vector<std::string>& args = app.args(); |
MOJO_CHECK(args.size() < |
static_cast<size_t>(std::numeric_limits<int>::max())); |
int argc = static_cast<int>(args.size()); |
std::vector<const char*> argv(argc + 1); |
for (int i = 0; i < argc; ++i) |
- argv[i] = args[i].c_str(); |
+ argv[i] = args[i].get().c_str(); |
argv[argc] = nullptr; |
testing::InitGoogleTest(&argc, const_cast<char**>(&(argv[0]))); |
- SetShellHandle(app.UnbindShell()); |
InitializeArgs(argc, argv); |
Environment::DestroyDefaultRunLoop(); |
@@ -79,9 +106,9 @@ MojoResult RunAllTests(MojoHandle shell_handle) { |
int result = RUN_ALL_TESTS(); |
- shell_handle = mojo::test::PassShellHandle().release().value(); |
- MojoResult close_result = MojoClose(shell_handle); |
- MOJO_CHECK(close_result == MOJO_RESULT_OK); |
+ // Shut down our message pipes before exiting. |
+ (void)g_application_request.PassMessagePipe(); |
+ (void)g_shell.PassMessagePipe(); |
return (result == 0) ? MOJO_RESULT_OK : MOJO_RESULT_UNKNOWN; |
} |
@@ -96,26 +123,28 @@ ApplicationDelegate* ApplicationTestBase::GetApplicationDelegate() { |
return &default_application_delegate_; |
} |
-void ApplicationTestBase::SetUpWithArgs(const Array<String>& args) { |
+void ApplicationTestBase::SetUp() { |
// A run loop is recommended for ApplicationImpl initialization and |
// communication. |
if (ShouldCreateDefaultRunLoop()) |
Environment::InstantiateDefaultRunLoop(); |
+ MOJO_CHECK(g_application_request.is_pending()); |
+ MOJO_CHECK(g_shell); |
+ |
// New applications are constructed for each test to avoid persisting state. |
application_impl_ = new ApplicationImpl(GetApplicationDelegate(), |
- PassShellHandle()); |
+ g_application_request.Pass()); |
// Fake application initialization with the given command line arguments. |
- application_impl_->Initialize(args.Clone()); |
-} |
- |
-void ApplicationTestBase::SetUp() { |
- SetUpWithArgs(Args()); |
+ application_impl_->Initialize(g_shell.Pass(), g_args.Clone()); |
} |
void ApplicationTestBase::TearDown() { |
- SetShellHandle(application_impl_->UnbindShell()); |
+ MOJO_CHECK(!g_application_request.is_pending()); |
+ MOJO_CHECK(!g_shell); |
+ |
+ application_impl_->UnbindConnections(&g_application_request, &g_shell); |
delete application_impl_; |
if (ShouldCreateDefaultRunLoop()) |
Environment::DestroyDefaultRunLoop(); |