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 23 using ::testing::InSequence; 24 using ::testing::Mock; 25 using ::testing::Return; 26 using ::testing::StrictMock; 27 28 namespace polo { 29 namespace wire { 30 namespace protobuf { 31 32 // A mock MessageListener. 33 class 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. 59 class 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. 111 TEST_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. 117 TEST_F(ProtobufWireAdapterTest, OnBytesReceivedPreamble) { 118 InSequence sequence; 119 120 ExpectReadPreamble(0xAABBCCDD); 121 } 122 123 // Verifies that a ConfigurationMessage is successfully sent over the interface. 124 TEST_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. 149 TEST_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. 167 TEST_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. 217 TEST_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. 238 TEST_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. 257 TEST_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. 282 TEST_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. 307 TEST_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