2 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
7 #include "native_client/tests/inbrowser_test_runner/test_runner.h"
12 #include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h"
14 #include "ppapi/c/pp_bool.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/c/pp_var.h"
17 #include "ppapi/c/ppb_messaging.h"
18 #include "ppapi/c/ppb_var.h"
19 #include "ppapi/c/ppp.h"
20 #include "ppapi/c/ppp_instance.h"
21 #include "ppapi/c/ppp_messaging.h"
25 * Remembers the callback that actually performs the tests once the browser
26 * has posted a message to run the test.
28 static int (*g_test_func)(void);
31 * Browser interfaces invoked by the plugin.
33 static PPB_GetInterface g_get_browser_interface;
34 const static PPB_Messaging *g_browser_messaging;
35 const static PPB_Var *g_browser_var;
38 /***************************************************************************
39 * The entry point invoked by tests using this library.
40 **************************************************************************/
41 int RunTests(int (*test_func)(void)) {
42 /* Turn off stdout buffering to aid debugging in case of a crash. */
43 setvbuf(stdout, NULL, _IONBF, 0);
44 if (getenv("OUTSIDE_BROWSER") != NULL) {
47 g_test_func = test_func;
48 return PpapiPluginMain();
52 int TestRunningInBrowser(void) {
56 /***************************************************************************
57 * PPP_Instance allows the browser to create an instance of the plugin.
58 **************************************************************************/
59 static PP_Bool PppInstanceDidCreate(PP_Instance instance,
63 g_browser_messaging = (*g_get_browser_interface)(PPB_MESSAGING_INTERFACE);
64 g_browser_var = (*g_get_browser_interface)(PPB_VAR_INTERFACE);
68 static void PppInstanceDidDestroy(PP_Instance instance) {
72 static void PppInstanceDidChangeView(PP_Instance instance, PP_Resource view) {
76 void PppInstanceDidChangeFocus(PP_Instance instance, PP_Bool has_focus) {
80 PP_Bool PppInstanceHandleDocumentLoad(PP_Instance instance,
81 PP_Resource url_loader) {
82 /* Signal document loading failed. */
86 static const PPP_Instance kPppInstance = {
88 PppInstanceDidDestroy,
89 PppInstanceDidChangeView,
90 PppInstanceDidChangeFocus,
91 PppInstanceHandleDocumentLoad
94 /***************************************************************************
95 * PPP_Messaging allows the browser to do postMessage to the plugin.
96 **************************************************************************/
97 static void PppMessagingHandleMessage(PP_Instance instance,
98 struct PP_Var message) {
101 static const char kStartMessage[] = "run_tests";
103 struct PP_Var result;
105 /* Ensure the start message is valid. */
106 data = g_browser_var->VarToUtf8(message, &len);
110 if (strcmp(data, kStartMessage) != 0) {
114 num_fails = (*g_test_func)();
115 /* Report the results. */
116 if (num_fails == 0) {
117 static const char kPassed[] = "passed";
118 result = g_browser_var->VarFromUtf8(kPassed, strlen(kPassed));
120 static const char kFailed[] = "failed";
121 result = g_browser_var->VarFromUtf8(kFailed, strlen(kFailed));
125 * This is a workaround for the problem that the messages sent by
126 * the "dev://postmessage" are unsynchronized. The Javascript code
127 * looks for this message before finishing the test.
129 fprintf(stderr, "\nEND_OF_LOG\n");
131 g_browser_messaging->PostMessage(instance, result);
134 static const PPP_Messaging kPppMessaging = {
135 PppMessagingHandleMessage
138 /***************************************************************************
139 * The three entry points every PPAPI plugin must export.
140 **************************************************************************/
141 int32_t PPP_InitializeModule(PP_Module module,
142 PPB_GetInterface get_browser_interface) {
143 g_get_browser_interface = get_browser_interface;
147 void PPP_ShutdownModule(void) {
150 const void *PPP_GetInterface(const char *interface_name) {
151 /* Export PPP_Instance and PPP_Messaging. */
152 if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
153 return (const void*) &kPppInstance;
155 if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) {
156 return (const void*) &kPppMessaging;