Home | History | Annotate | Download | only in protobuf
      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