1 // Copyright (c) 2012 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 #ifndef PPAPI_TESTS_TESTING_INSTANCE_H_
6 #define PPAPI_TESTS_TESTING_INSTANCE_H_
7 
8 #include <stdint.h>
9 
10 #include <string>
11 
12 #include "ppapi/utility/completion_callback_factory.h"
13 
14 #if defined(__native_client__)
15 #include "ppapi/cpp/instance.h"
16 #else
17 #include "ppapi/cpp/private/instance_private.h"
18 #endif
19 
20 // Windows defines 'PostMessage', so we have to undef it.
21 #ifdef PostMessage
22 #undef PostMessage
23 #endif
24 
25 class TestCase;
26 
27 // How signaling works:
28 //
29 // We want to signal to the Chrome browser test harness
30 // (chrome/test/ppapi/ppapi_browsertest.cc) that we're making progress and when
31 // we're done. This is done using the DOM controlller. The browser test waits
32 // for a message from it. We don't want to have a big wait for all tests in a
33 // TestCase since they can take a while and it might timeout.  So we send it
34 // pings between each test to tell it that we're still running tests and aren't
35 // stuck.
36 //
37 // If the value of the message is "..." then that tells the test runner that
38 // the test is progressing. It then waits for the next message until it either
39 // times out or the value is something other than "...". In this case, the value
40 // will be either "PASS" or "FAIL [optional message]" corresponding to the
41 // outcome of the entire test case. Timeout will be treated just like a failure
42 // of the entire test case and the test will be terminated.
43 //
44 // In trusted builds, we use InstancePrivate and allow tests that use
45 // synchronous scripting. NaCl does not support synchronous scripting.
46 class TestingInstance : public
47 #if defined(__native_client__)
48 pp::Instance {
49 #else
50 pp::InstancePrivate {
51 #endif
52  public:
53   explicit TestingInstance(PP_Instance instance);
54   virtual ~TestingInstance();
55 
56   // pp::Instance override.
57   virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
58   virtual void DidChangeView(const pp::View& view);
59   virtual bool HandleInputEvent(const pp::InputEvent& event);
60 
61 #if !(defined __native_client__)
62   virtual pp::Var GetInstanceObject();
63 #endif
64 
65   // Outputs the information from one test run, using the format
66   //   <test_name> [PASS|FAIL <error_message>]
67   //
68   // You should generally use one of the RUN_TEST* macros in test_case.h
69   // instead.
70   //
71   // If error_message is empty, we say the test passed and emit PASS. If
72   // error_message is nonempty, the test failed with that message as the error
73   // string.
74   //
75   // Intended usage:
76   //   PP_TimeTicks start_time(core.GetTimeTicks());
77   //   LogTest("Foo", FooTest(), start_time);
78   //
79   // Where FooTest is defined as:
80   //   std::string FooTest() {
81   //     if (something_horrible_happened)
82   //       return "Something horrible happened";
83   //     return "";
84   //   }
85   //
86   // NOTE: It's important to get the start time in the previous line, rather
87   //       than calling GetTimeTicks in the LogTestLine. There's no guarantee
88   //       that GetTimeTicks will be evaluated before FooTest().
89   void LogTest(const std::string& test_name,
90                const std::string& error_message,
91                PP_TimeTicks start_time);
current_test_name()92   const std::string& current_test_name() { return current_test_name_; }
93 
94   // Appends an error message to the log.
95   void AppendError(const std::string& message);
96 
97   // Passes the message_data through to the HandleMessage method on the
98   // TestClass object that's associated with this instance.
99   virtual void HandleMessage(const pp::Var& message_data);
100 
protocol()101   const std::string& protocol() {
102     return protocol_;
103   }
104 
ssl_server_port()105   int ssl_server_port() { return ssl_server_port_; }
106 
websocket_host()107   const std::string& websocket_host() { return websocket_host_; }
websocket_port()108   int websocket_port() { return websocket_port_; }
109 
110   // Posts a message to the test page to eval() the script.
111   void EvalScript(const std::string& script);
112 
113   // Sets the given cookie in the current document.
114   void SetCookie(const std::string& name, const std::string& value);
115 
116   void ReportProgress(const std::string& progress_value);
117 
118   // Logs the amount of time that a given test took to run. This is to help
119   // debug test timeouts that occur in automated testing.
120   void LogTestTime(const std::string& test_time);
121 
122   // Add a post-condition to the JavaScript on the test_case.html page. This
123   // JavaScript code will be run after the instance is shut down and must
124   // evaluate to |true| or the test will fail.
125   void AddPostCondition(const std::string& script);
126 
127   // See doc for |remove_plugin_|.
set_remove_plugin(bool remove)128   void set_remove_plugin(bool remove) { remove_plugin_ = remove; }
129 
130  private:
131   void ExecuteTests(int32_t unused);
132 
133   // Creates a new TestCase for the give test name, or NULL if there is no such
134   // test. Ownership is passed to the caller. The given string is split by '_'.
135   // The test case name is the first part.
136   TestCase* CaseForTestName(const std::string& name);
137 
138   // Sends a test command to the page using PostMessage.
139   void SendTestCommand(const std::string& command);
140   void SendTestCommand(const std::string& command, const std::string& params);
141 
142   // Appends a list of available tests to the console in the document.
143   void LogAvailableTests();
144 
145   // Appends the given error test to the console in the document.
146   void LogError(const std::string& text);
147 
148   // Appends the given HTML string to the console in the document.
149   void LogHTML(const std::string& html);
150 
151   pp::CompletionCallbackFactory<TestingInstance> callback_factory_;
152 
153   // Owning pointer to the current test case. Valid after Init has been called.
154   TestCase* current_case_;
155 
156   std::string current_test_name_;
157 
158   // A filter to use when running tests. This is passed to 'RunTests', which
159   // runs only tests whose name contains test_filter_ as a substring.
160   std::string test_filter_;
161 
162   // Set once the tests are run so we know not to re-run when the view is sized.
163   bool executed_tests_;
164 
165   // The number of tests executed so far.
166   int32_t number_tests_executed_;
167 
168   // Collects all errors to send the the browser. Empty indicates no error yet.
169   std::string errors_;
170 
171   // True if running in Native Client.
172   bool nacl_mode_;
173 
174   // String representing the protocol.  Used for detecting whether we're running
175   // with http.
176   std::string protocol_;
177 
178   // SSL server port.
179   int ssl_server_port_;
180 
181   // WebSocket host.
182   std::string websocket_host_;
183 
184   // WebSocket port.
185   int websocket_port_;
186 
187   // At the end of each set of tests, the plugin is removed from the web-page.
188   // However, for some tests, it is desirable to not remove the plguin from the
189   // page.
190   bool remove_plugin_;
191 };
192 
193 #endif  // PPAPI_TESTS_TESTING_INSTANCE_H_
194