| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "mojo/public/cpp/application/application_test_base.h" | |
| 6 | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "mojo/public/cpp/bindings/binding.h" | |
| 10 #include "mojo/public/cpp/environment/environment.h" | |
| 11 #include "mojo/public/cpp/system/message_pipe.h" | |
| 12 #include "mojo/public/interfaces/application/application.mojom.h" | |
| 13 | |
| 14 namespace mojo { | |
| 15 namespace test { | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 // Share the application command-line arguments with multiple application tests. | |
| 20 Array<String> g_args; | |
| 21 | |
| 22 // Share the application URL with multiple application tests. | |
| 23 String g_url; | |
| 24 | |
| 25 // Application request handle passed from the shell in MojoMain, stored in | |
| 26 // between SetUp()/TearDown() so we can (re-)intialize new ApplicationImpls. | |
| 27 InterfaceRequest<Application> g_application_request; | |
| 28 | |
| 29 // Shell pointer passed in the initial mojo.Application.Initialize() call, | |
| 30 // stored in between initial setup and the first test and between SetUp/TearDown | |
| 31 // calls so we can (re-)initialize new ApplicationImpls. | |
| 32 ShellPtr g_shell; | |
| 33 | |
| 34 void InitializeArgs(int argc, const char** argv) { | |
| 35 MOJO_CHECK(g_args.is_null()); | |
| 36 for (int i = 0; i < argc; i++) { | |
| 37 MOJO_CHECK(argv[i]); | |
| 38 g_args.push_back(argv[i]); | |
| 39 } | |
| 40 } | |
| 41 | |
| 42 class ShellAndArgumentGrabber : public Application { | |
| 43 public: | |
| 44 ShellAndArgumentGrabber(Array<String>* args, | |
| 45 InterfaceRequest<Application> application_request) | |
| 46 : args_(args), binding_(this, application_request.Pass()) {} | |
| 47 | |
| 48 void WaitForInitialize() { | |
| 49 // Initialize is always the first call made on Application. | |
| 50 MOJO_CHECK(binding_.WaitForIncomingMethodCall()); | |
| 51 } | |
| 52 | |
| 53 private: | |
| 54 // Application implementation. | |
| 55 void Initialize(InterfaceHandle<Shell> shell, | |
| 56 Array<String> args, | |
| 57 const mojo::String& url) override { | |
| 58 *args_ = args.Pass(); | |
| 59 g_url = url; | |
| 60 g_application_request = binding_.Unbind(); | |
| 61 g_shell = ShellPtr::Create(std::move(shell)); | |
| 62 } | |
| 63 | |
| 64 void AcceptConnection(const String& requestor_url, | |
| 65 const String& url, | |
| 66 InterfaceRequest<ServiceProvider> services) override { | |
| 67 MOJO_CHECK(false); | |
| 68 } | |
| 69 | |
| 70 void RequestQuit() override { MOJO_CHECK(false); } | |
| 71 | |
| 72 Array<String>* args_; | |
| 73 Binding<Application> binding_; | |
| 74 }; | |
| 75 | |
| 76 } // namespace | |
| 77 | |
| 78 MojoResult RunAllTests(MojoHandle application_request_handle) { | |
| 79 { | |
| 80 // This loop is used for init, and then destroyed before running tests. | |
| 81 Environment::InstantiateDefaultRunLoop(); | |
| 82 | |
| 83 // Grab the shell handle and GTEST commandline arguments. | |
| 84 // GTEST command line arguments are supported amid application arguments: | |
| 85 // $ mojo_shell mojo:example_apptests | |
| 86 // --args-for='mojo:example_apptests arg1 --gtest_filter=foo arg2' | |
| 87 Array<String> args; | |
| 88 ShellAndArgumentGrabber grabber( | |
| 89 &args, InterfaceRequest<Application>(MakeScopedHandle( | |
| 90 MessagePipeHandle(application_request_handle)))); | |
| 91 grabber.WaitForInitialize(); | |
| 92 MOJO_CHECK(g_shell); | |
| 93 MOJO_CHECK(g_application_request.is_pending()); | |
| 94 | |
| 95 // InitGoogleTest expects (argc + 1) elements, including a terminating null. | |
| 96 // It also removes GTEST arguments from |argv| and updates the |argc| count. | |
| 97 MOJO_CHECK(args.size() < | |
| 98 static_cast<size_t>(std::numeric_limits<int>::max())); | |
| 99 // We'll put our URL in at |argv[0]| (|args| doesn't include a "command | |
| 100 // name"). | |
| 101 int argc = static_cast<int>(args.size()) + 1; | |
| 102 std::vector<const char*> argv(argc + 1); | |
| 103 argv[0] = g_url.get().c_str(); | |
| 104 for (size_t i = 0; i < args.size(); ++i) | |
| 105 argv[i + 1] = args[i].get().c_str(); | |
| 106 argv[argc] = nullptr; | |
| 107 | |
| 108 // Note: |InitGoogleTest()| will modify |argc| and |argv[...]|. | |
| 109 testing::InitGoogleTest(&argc, const_cast<char**>(&argv[0])); | |
| 110 InitializeArgs(argc, &argv[0]); | |
| 111 | |
| 112 Environment::DestroyDefaultRunLoop(); | |
| 113 } | |
| 114 | |
| 115 int result = RUN_ALL_TESTS(); | |
| 116 | |
| 117 // Shut down our message pipes before exiting. | |
| 118 (void)g_application_request.PassMessagePipe(); | |
| 119 (void)g_shell.PassInterfaceHandle(); | |
| 120 | |
| 121 return (result == 0) ? MOJO_RESULT_OK : MOJO_RESULT_UNKNOWN; | |
| 122 } | |
| 123 | |
| 124 ApplicationTestBase::ApplicationTestBase() {} | |
| 125 | |
| 126 ApplicationTestBase::~ApplicationTestBase() {} | |
| 127 | |
| 128 void ApplicationTestBase::SetUp() { | |
| 129 // A run loop is recommended for ApplicationImpl initialization and | |
| 130 // communication. | |
| 131 if (ShouldCreateDefaultRunLoop()) | |
| 132 Environment::InstantiateDefaultRunLoop(); | |
| 133 | |
| 134 MOJO_CHECK(g_application_request.is_pending()); | |
| 135 MOJO_CHECK(g_shell); | |
| 136 MOJO_CHECK(args_.empty()); | |
| 137 | |
| 138 shell_ = g_shell.Pass(); | |
| 139 for (size_t i = 0; i < g_args.size(); i++) | |
| 140 args_.push_back(g_args[i]); | |
| 141 } | |
| 142 | |
| 143 void ApplicationTestBase::TearDown() { | |
| 144 MOJO_CHECK(!g_shell); | |
| 145 | |
| 146 // TODO(vtl): The straightforward |g_shell = shell_.Pass();| causes tests to | |
| 147 // hang. Presumably, it's because there are still requests to the shell | |
| 148 // pending. :-( | |
| 149 g_shell.Bind(shell_.PassInterfaceHandle()); | |
| 150 args_.clear(); | |
| 151 | |
| 152 if (ShouldCreateDefaultRunLoop()) | |
| 153 Environment::DestroyDefaultRunLoop(); | |
| 154 } | |
| 155 | |
| 156 bool ApplicationTestBase::ShouldCreateDefaultRunLoop() { | |
| 157 return true; | |
| 158 } | |
| 159 | |
| 160 } // namespace test | |
| 161 } // namespace mojo | |
| OLD | NEW |