protobufwireadaptertest.cc revision 7c9978567a202d6aa98beac5da5e1b3b34792862
1// Copyright 2012 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Tests for ProtobufWireAdapter.
16
17#include <gmock/gmock.h>
18#include <gtest/gtest.h>
19#include <polo/util/poloutil.h>
20#include <polo/wire/protobuf/protobufwireadapter.h>
21#include "polo/wire/mocks.h"
22
23using ::testing::InSequence;
24using ::testing::Mock;
25using ::testing::Return;
26using ::testing::StrictMock;
27
28namespace polo {
29namespace wire {
30namespace protobuf {
31
32// A mock MessageListener.
33class MockMessageListener : public pairing::message::MessageListener {
34  MOCK_METHOD1(OnConfigurationMessage,
35               void(const pairing::message::ConfigurationMessage& message));
36
37  MOCK_METHOD1(OnConfigurationAckMessage,
38               void(const pairing::message::ConfigurationAckMessage& message));
39
40  MOCK_METHOD1(OnOptionsMessage,
41               void(const pairing::message::OptionsMessage& message));
42
43  MOCK_METHOD1(OnPairingRequestMessage,
44               void(const pairing::message::PairingRequestMessage& message));
45
46  MOCK_METHOD1(OnPairingRequestAckMessage,
47               void(const pairing::message::PairingRequestAckMessage& message));
48
49  MOCK_METHOD1(OnSecretMessage,
50               void(const pairing::message::SecretMessage& message));
51
52  MOCK_METHOD1(OnSecretAckMessage,
53               void(const pairing::message::SecretAckMessage& message));
54
55  MOCK_METHOD1(OnError, void(pairing::PoloError error));
56};
57
58// Test fixture for ProtobufWireAdapter tests.
59class ProtobufWireAdapterTest : public ::testing::Test {
60 public:
61  ProtobufWireAdapterTest() : interface_(), adapter_(&interface_) {}
62
63 protected:
64  virtual void SetUp() {
65    adapter_.set_listener(&listener_);
66  }
67
68  // Expects that a call to GetNextMessage will be made which triggers a read
69  // for the 4 byte preamble.
70  void ExpectGetPreamble() {
71    EXPECT_CALL(interface_, Receive(4));
72    adapter_.GetNextMessage();
73  }
74
75  // Expects that a call to GetNextMessage will be made, and the preamble will
76  // be read containing the given message size. This will trigger another read
77  // for the full message.
78  void ExpectReadPreamble(uint32_t message_size) {
79    ExpectGetPreamble();
80
81    unsigned char* size_bytes;
82    util::PoloUtil::IntToBigEndianBytes(message_size, size_bytes);
83    EXPECT_CALL(interface_, Receive(message_size));
84
85    adapter_.OnBytesReceived(
86        std::vector<uint8_t>(size_bytes, size_bytes + 4));
87  }
88
89  // Expects that the given OuterMessage will be sent over the interface.
90  void ExpectSend(const OuterMessage& message) {
91    std::string outer_string = message.SerializeAsString();
92
93    unsigned char* size_bytes;
94    util::PoloUtil::IntToBigEndianBytes(outer_string.length(), size_bytes);
95
96    std::vector<unsigned char> data(outer_string.length() + 4);
97    unsigned char* buffer = &data[0];
98    memcpy(buffer, size_bytes, 4);
99    memcpy((buffer + 4), &outer_string[0], outer_string.length());
100
101    EXPECT_CALL(interface_, Send(data));
102  }
103
104  StrictMock<MockWireInterface> interface_;
105  StrictMock<MockMessageListener> listener_;
106  ProtobufWireAdapter adapter_;
107};
108
109// Verifies that a call to GetNextMessage will trigger a read for the 4 byte
110// preamble.
111TEST_F(ProtobufWireAdapterTest, GetNextMessage) {
112  ExpectGetPreamble();
113}
114
115// Verifies that once the preamble is received, a read will be triggered for
116// the full message.
117TEST_F(ProtobufWireAdapterTest, OnBytesReceivedPreamble) {
118  InSequence sequence;
119
120  ExpectReadPreamble(0xAABBCCDD);
121}
122
123// Verifies that a ConfigurationMessage is successfully sent over the interface.
124TEST_F(ProtobufWireAdapterTest, SendConfigurationMessage) {
125  InSequence sequence;
126
127  Configuration proto;
128  proto.set_client_role(Options_RoleType_ROLE_TYPE_OUTPUT);
129  proto.mutable_encoding()->set_type(
130      Options_Encoding_EncodingType_ENCODING_TYPE_QRCODE);
131  proto.mutable_encoding()->set_symbol_length(64);
132
133  OuterMessage outer;
134  outer.set_type(OuterMessage_MessageType_MESSAGE_TYPE_CONFIGURATION);
135  outer.set_payload(proto.SerializeAsString());
136  outer.set_protocol_version(1);
137  outer.set_status(OuterMessage_Status_STATUS_OK);
138
139  ExpectSend(outer);
140
141  pairing::message::ConfigurationMessage message(
142      encoding::EncodingOption(encoding::EncodingOption::kQRCode, 64),
143      pairing::message::OptionsMessage::kDisplayDevice);
144  adapter_.SendConfigurationMessage(message);
145}
146
147// Verifies that a ConfigurationAckMessage is successfully sent over the
148// interface.
149TEST_F(ProtobufWireAdapterTest, SendConfigurationAckMessage) {
150  InSequence sequence;
151
152  ConfigurationAck proto;
153
154  OuterMessage outer;
155  outer.set_type(OuterMessage_MessageType_MESSAGE_TYPE_CONFIGURATION_ACK);
156  outer.set_payload(proto.SerializeAsString());
157  outer.set_protocol_version(1);
158  outer.set_status(OuterMessage_Status_STATUS_OK);
159
160  ExpectSend(outer);
161
162  pairing::message::ConfigurationAckMessage message;
163  adapter_.SendConfigurationAckMessage(message);
164}
165
166// Verifies that an OptionsMessage is successfully sent over the interface.
167TEST_F(ProtobufWireAdapterTest, SendOptionsMessage) {
168  InSequence sequence;
169
170  Options proto;
171  proto.set_preferred_role(Options_RoleType_ROLE_TYPE_INPUT);
172  Options_Encoding* encoding = proto.add_input_encodings();
173  encoding->set_type(Options_Encoding_EncodingType_ENCODING_TYPE_NUMERIC);
174  encoding->set_symbol_length(16);
175
176  encoding = proto.add_input_encodings();
177  encoding->set_type(Options_Encoding_EncodingType_ENCODING_TYPE_ALPHANUMERIC);
178  encoding->set_symbol_length(32);
179
180  encoding = proto.add_output_encodings();
181  encoding->set_type(Options_Encoding_EncodingType_ENCODING_TYPE_HEXADECIMAL);
182  encoding->set_symbol_length(128);
183
184  encoding = proto.add_output_encodings();
185  encoding->set_type(Options_Encoding_EncodingType_ENCODING_TYPE_QRCODE);
186  encoding->set_symbol_length(512);
187
188  OuterMessage outer;
189  outer.set_type(OuterMessage_MessageType_MESSAGE_TYPE_OPTIONS);
190  outer.set_payload(proto.SerializeAsString());
191  outer.set_protocol_version(1);
192  outer.set_status(OuterMessage_Status_STATUS_OK);
193
194  ExpectSend(outer);
195
196  pairing::message::OptionsMessage message;
197  message.set_protocol_role_preference(
198      pairing::message::OptionsMessage::kInputDevice);
199
200  // Note, the input and output encoding sets are sorted by complexity, so these
201  // should be in the same order as the encodings added to the proto above to
202  // ensure the assert matches.
203  message.AddInputEncoding(
204      encoding::EncodingOption(encoding::EncodingOption::kNumeric, 16));
205  message.AddInputEncoding(
206      encoding::EncodingOption(encoding::EncodingOption::kAlphaNumeric, 32));
207  message.AddOutputEncoding(
208      encoding::EncodingOption(encoding::EncodingOption::kHexadecimal, 128));
209  message.AddOutputEncoding(
210      encoding::EncodingOption(encoding::EncodingOption::kQRCode, 512));
211
212  adapter_.SendOptionsMessage(message);
213}
214
215// Verifies that a PairingRequestMessage is successfully sent over the
216// interface.
217TEST_F(ProtobufWireAdapterTest, SendPairingRequestMessage) {
218  InSequence sequence;
219
220  PairingRequest proto;
221  proto.set_client_name("foo-client");
222  proto.set_service_name("foo-service");
223
224  OuterMessage outer;
225  outer.set_type(OuterMessage_MessageType_MESSAGE_TYPE_PAIRING_REQUEST);
226  outer.set_payload(proto.SerializeAsString());
227  outer.set_protocol_version(1);
228  outer.set_status(OuterMessage_Status_STATUS_OK);
229
230  ExpectSend(outer);
231
232  pairing::message::PairingRequestMessage message("foo-service", "foo-client");
233  adapter_.SendPairingRequestMessage(message);
234}
235
236// Verifies that a SendPairingRequestAckMesssage is successfully sent over the
237// interface.
238TEST_F(ProtobufWireAdapterTest, SendPairingRequestAckMessage) {
239  InSequence sequence;
240
241  PairingRequestAck proto;
242  proto.set_server_name("foo-server");
243
244  OuterMessage outer;
245  outer.set_type(OuterMessage_MessageType_MESSAGE_TYPE_PAIRING_REQUEST_ACK);
246  outer.set_payload(proto.SerializeAsString());
247  outer.set_protocol_version(1);
248  outer.set_status(OuterMessage_Status_STATUS_OK);
249
250  ExpectSend(outer);
251
252  pairing::message::PairingRequestAckMessage message("foo-server");
253  adapter_.SendPairingRequestAckMessage(message);
254}
255
256// Verifies that a SecretMessage is successfully sent over the interface.
257TEST_F(ProtobufWireAdapterTest, SendSecretMessage) {
258  InSequence sequence;
259
260  std::vector<unsigned char> secret(4);
261  secret[0] = 0xAA;
262  secret[1] = 0xBB;
263  secret[2] = 0xCC;
264  secret[3] = 0xDD;
265
266  Secret proto;
267  proto.set_secret(&secret[0], secret.size());
268
269  OuterMessage outer;
270  outer.set_type(OuterMessage_MessageType_MESSAGE_TYPE_SECRET);
271  outer.set_payload(proto.SerializeAsString());
272  outer.set_protocol_version(1);
273  outer.set_status(OuterMessage_Status_STATUS_OK);
274
275  ExpectSend(outer);
276
277  pairing::message::SecretMessage message(secret);
278  adapter_.SendSecretMessage(message);
279}
280
281// Verifies that a SecretAckMessage is successfully sent over the interface.
282TEST_F(ProtobufWireAdapterTest, SendSecretAckMessage) {
283  InSequence sequence;
284
285  std::vector<unsigned char> secret(4);
286  secret[0] = 0xAA;
287  secret[1] = 0xBB;
288  secret[2] = 0xCC;
289  secret[3] = 0xDD;
290
291  SecretAck proto;
292  proto.set_secret(&secret[0], secret.size());
293
294  OuterMessage outer;
295  outer.set_type(OuterMessage_MessageType_MESSAGE_TYPE_SECRET_ACK);
296  outer.set_payload(proto.SerializeAsString());
297  outer.set_protocol_version(1);
298  outer.set_status(OuterMessage_Status_STATUS_OK);
299
300  ExpectSend(outer);
301
302  pairing::message::SecretAckMessage message(secret);
303  adapter_.SendSecretAckMessage(message);
304}
305
306// Verifies that an ErrorMessage is successfully sent over the interface.
307TEST_F(ProtobufWireAdapterTest, SendErrorMessage) {
308  InSequence sequence;
309
310  OuterMessage outer;
311  outer.set_protocol_version(1);
312  outer.set_status(OuterMessage_Status_STATUS_BAD_SECRET);
313
314  ExpectSend(outer);
315
316  adapter_.SendErrorMessage(pairing::kErrorInvalidChallengeResponse);
317}
318
319}  // namespace protobuf
320}  // namespace wire
321}  // namespace polo
322