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