summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/ppp_messaging_proxy_unittest.cc
blob: d1fa9b60fde77fbbdd59ee7dedb7c391125b6c79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <cstring>

#include "base/synchronization/waitable_event.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/c/ppp_messaging.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
#include "ppapi/proxy/serialized_var.h"
#include "ppapi/shared_impl/api_id.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/var.h"

namespace ppapi {
namespace proxy {

namespace {

// This is a poor man's mock of PPP_Messaging using global variables. Eventually
// we should generalize making PPAPI interface mocks by using IDL or macro/
// template magic.
PP_Instance received_instance;
PP_Var received_var;
base::WaitableEvent handle_message_called(false, false);

void HandleMessage(PP_Instance instance, PP_Var message_data) {
  received_instance = instance;
  received_var = message_data;
  handle_message_called.Signal();
}

// Clear all the 'received' values for our mock.  Call this before you expect
// one of the functions to be invoked.
void ResetReceived() {
  received_instance = 0;
  received_var.type = PP_VARTYPE_UNDEFINED;
  received_var.value.as_id = 0;
}

PPP_Messaging ppp_messaging_mock = {
  &HandleMessage
};

// CallHandleMessage does the host-side work to cause HandleMessage to be called
// in the plugin side.
void CallHandleMessage(Dispatcher* dispatcher,
                       PP_Instance instance,
                       PP_Var message) {
  dispatcher->Send(new PpapiMsg_PPPMessaging_HandleMessage(
      API_ID_PPP_MESSAGING,
      instance,
      SerializedVarSendInputShmem(dispatcher, message, instance)));
}

class PPP_Messaging_ProxyTest : public TwoWayTest {
 public:
  PPP_Messaging_ProxyTest()
      : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) {
    plugin().RegisterTestInterface(PPP_MESSAGING_INTERFACE,
                                   &ppp_messaging_mock);
  }
};

void CompareAndReleaseStringVar(PluginProxyTestHarness* plugin_harness,
                                PP_Var received_var,
                                const std::string& test_string) {
  ProxyAutoLock lock;
  Var* received_string = plugin_harness->var_tracker().GetVar(received_var);
  ASSERT_TRUE(received_string);
  ASSERT_TRUE(received_string->AsStringVar());
  EXPECT_EQ(test_string, received_string->AsStringVar()->value());
  // Now release the var, and the string should go away (because the ref
  // count should be one).
  plugin_harness->var_tracker().ReleaseVar(received_var);
  EXPECT_FALSE(StringVar::FromPPVar(received_var));
}

}  // namespace

TEST_F(PPP_Messaging_ProxyTest, SendMessages) {
  PP_Instance expected_instance = pp_instance();
  PP_Var expected_var = PP_MakeUndefined();
  ResetReceived();
  Dispatcher* host_dispatcher = host().GetDispatcher();
  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
  handle_message_called.Wait();
  EXPECT_EQ(expected_instance, received_instance);
  EXPECT_EQ(expected_var.type, received_var.type);

  expected_var = PP_MakeNull();
  ResetReceived();
  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
  handle_message_called.Wait();
  EXPECT_EQ(expected_instance, received_instance);
  EXPECT_EQ(expected_var.type, received_var.type);

  expected_var = PP_MakeBool(PP_TRUE);
  ResetReceived();
  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
  handle_message_called.Wait();
  EXPECT_EQ(expected_instance, received_instance);
  EXPECT_EQ(expected_var.type, received_var.type);
  EXPECT_EQ(expected_var.value.as_bool, received_var.value.as_bool);

  expected_var = PP_MakeInt32(12345);
  ResetReceived();
  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
  handle_message_called.Wait();
  EXPECT_EQ(expected_instance, received_instance);
  EXPECT_EQ(expected_var.type, received_var.type);
  EXPECT_EQ(expected_var.value.as_int, received_var.value.as_int);

  expected_var = PP_MakeDouble(3.1415);
  ResetReceived();
  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
  handle_message_called.Wait();
  EXPECT_EQ(expected_instance, received_instance);
  EXPECT_EQ(expected_var.type, received_var.type);
  EXPECT_EQ(expected_var.value.as_double, received_var.value.as_double);

  const std::string kTestString("Hello world!");
  expected_var = StringVar::StringToPPVar(kTestString);
  ResetReceived();
  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
  // Now release the var, and the string should go away (because the ref
  // count should be one).
  host().var_tracker().ReleaseVar(expected_var);
  EXPECT_FALSE(StringVar::FromPPVar(expected_var));

  handle_message_called.Wait();
  EXPECT_EQ(expected_instance, received_instance);
  EXPECT_EQ(expected_var.type, received_var.type);
  PostTaskOnRemoteHarness(
      base::Bind(CompareAndReleaseStringVar,
                 &plugin(),
                 received_var,
                 kTestString));
}

}  // namespace proxy
}  // namespace ppapi