Home | History | Annotate | Download | only in inbrowser_test_runner
      1 /*
      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.
      5  */
      6 
      7 #include "native_client/tests/inbrowser_test_runner/test_runner.h"
      8 
      9 #include <stdio.h>
     10 #include <string.h>
     11 
     12 #include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h"
     13 
     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"
     22 
     23 
     24 /*
     25  * Remembers the callback that actually performs the tests once the browser
     26  * has posted a message to run the test.
     27  */
     28 static int (*g_test_func)(void);
     29 
     30 /*
     31  * Browser interfaces invoked by the plugin.
     32  */
     33 static PPB_GetInterface g_get_browser_interface;
     34 const static PPB_Messaging *g_browser_messaging;
     35 const static PPB_Var *g_browser_var;
     36 
     37 
     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) {
     45     return test_func();
     46   } else {
     47     g_test_func = test_func;
     48     return PpapiPluginMain();
     49   }
     50 }
     51 
     52 int TestRunningInBrowser(void) {
     53   return 1;
     54 }
     55 
     56 /***************************************************************************
     57  * PPP_Instance allows the browser to create an instance of the plugin.
     58  **************************************************************************/
     59 static PP_Bool PppInstanceDidCreate(PP_Instance instance,
     60                                     uint32_t argc,
     61                                     const char *argn[],
     62                                     const char *argv[]) {
     63   g_browser_messaging = (*g_get_browser_interface)(PPB_MESSAGING_INTERFACE);
     64   g_browser_var = (*g_get_browser_interface)(PPB_VAR_INTERFACE);
     65   return PP_TRUE;
     66 }
     67 
     68 static void PppInstanceDidDestroy(PP_Instance instance) {
     69   /* Do nothing. */
     70 }
     71 
     72 static void PppInstanceDidChangeView(PP_Instance instance, PP_Resource view) {
     73   /* Do nothing. */
     74 }
     75 
     76 void PppInstanceDidChangeFocus(PP_Instance instance, PP_Bool has_focus) {
     77   /* Do nothing. */
     78 }
     79 
     80 PP_Bool PppInstanceHandleDocumentLoad(PP_Instance instance,
     81                                       PP_Resource url_loader) {
     82   /* Signal document loading failed. */
     83   return PP_FALSE;
     84 }
     85 
     86 static const PPP_Instance kPppInstance = {
     87   PppInstanceDidCreate,
     88   PppInstanceDidDestroy,
     89   PppInstanceDidChangeView,
     90   PppInstanceDidChangeFocus,
     91   PppInstanceHandleDocumentLoad
     92 };
     93 
     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) {
     99   const char *data;
    100   uint32_t len;
    101   static const char kStartMessage[] = "run_tests";
    102   int num_fails;
    103   struct PP_Var result;
    104 
    105   /* Ensure the start message is valid. */
    106   data = g_browser_var->VarToUtf8(message, &len);
    107   if (len == 0) {
    108     return;
    109   }
    110   if (strcmp(data, kStartMessage) != 0) {
    111     return;
    112   }
    113   /* Run the tests. */
    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));
    119   } else {
    120     static const char kFailed[] = "failed";
    121     result = g_browser_var->VarFromUtf8(kFailed, strlen(kFailed));
    122   }
    123 
    124   /*
    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.
    128    */
    129   fprintf(stderr, "\nEND_OF_LOG\n");
    130 
    131   g_browser_messaging->PostMessage(instance, result);
    132 }
    133 
    134 static const PPP_Messaging kPppMessaging = {
    135   PppMessagingHandleMessage
    136 };
    137 
    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;
    144   return PP_OK;
    145 }
    146 
    147 void PPP_ShutdownModule(void) {
    148 }
    149 
    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;
    154   }
    155   if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) {
    156     return (const void*) &kPppMessaging;
    157   }
    158   return NULL;
    159 }
    160