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 PairingSession.
16
17 #include <gtest/gtest.h>
18 #include <polo/pairing/clientpairingsession.h>
19 #include "polo/pairing/mocks.h"
20 #include "polo/wire/mocks.h"
21
22 using ::testing::Const;
23 using ::testing::InSequence;
24 using ::testing::Mock;
25 using ::testing::Return;
26 using ::testing::ReturnRef;
27 using ::testing::StrictMock;
28 using ::testing::_;
29
30 namespace polo {
31 namespace pairing {
32
33 class TestPairingSession : public PairingSession {
34 public:
TestPairingSession(wire::PoloWireAdapter * wire,PairingContext * context,PoloChallengeResponse * challenge)35 TestPairingSession(wire::PoloWireAdapter* wire,
36 PairingContext* context,
37 PoloChallengeResponse* challenge)
38 : PairingSession(wire, context, challenge) {
39 }
40
TestDoPairingPhase()41 void TestDoPairingPhase() {
42 DoPairingPhase();
43 }
44
TestSetConfiguration(const message::ConfigurationMessage & message)45 bool TestSetConfiguration(const message::ConfigurationMessage& message) {
46 return SetConfiguration(message);
47 }
48
GetConfiguration()49 const message::ConfigurationMessage* GetConfiguration() {
50 return configuration();
51 }
52
GetLocalOptions()53 const message::OptionsMessage& GetLocalOptions() {
54 return local_options();
55 }
56
TestOnSecretMessage(const message::SecretMessage & message)57 void TestOnSecretMessage(const message::SecretMessage& message) {
58 OnSecretMessage(message);
59 }
60
TestOnSecretAckmessage(const message::SecretAckMessage & message)61 void TestOnSecretAckmessage(const message::SecretAckMessage& message) {
62 OnSecretAckMessage(message);
63 }
64
65 MOCK_METHOD0(DoInitializationPhase, void());
66 MOCK_METHOD0(DoConfigurationPhase, void());
67 MOCK_METHOD1(OnConfigurationMessage,
68 void(const pairing::message::ConfigurationMessage& message));
69 MOCK_METHOD1(OnConfigurationAckMessage,
70 void(const pairing::message::ConfigurationAckMessage& message));
71 MOCK_METHOD1(OnOptionsMessage,
72 void(const pairing::message::OptionsMessage& message));
73 MOCK_METHOD1(OnPairingRequestMessage,
74 void(const pairing::message::PairingRequestMessage& message));
75 MOCK_METHOD1(OnPairingRequestAckMessage,
76 void(const pairing::message::PairingRequestAckMessage& message));
77 };
78
79 class PairingSessionTest : public ::testing::Test {
80 protected:
PairingSessionTest()81 PairingSessionTest()
82 : interface_(),
83 wire_(&interface_),
84 challenge_(),
85 context_(NULL, NULL, false),
86 session_(&wire_, &context_, &challenge_) {
87 }
88
SetUp()89 virtual void SetUp() {
90 }
91
TearDown()92 virtual void TearDown() {
93 }
94
InitSession()95 void InitSession() {
96 InSequence sequence;
97
98 EXPECT_CALL(listener_, OnSessionCreated());
99 EXPECT_CALL(session_, DoInitializationPhase());
100
101 session_.DoPair(&listener_);
102 }
103
104 StrictMock<wire::MockWireInterface> interface_;
105 StrictMock<wire::MockWireAdapter> wire_;
106 StrictMock<MockChallengeResponse> challenge_;
107 PairingContext context_;
108 StrictMock<MockPairingListener> listener_;
109 StrictMock<TestPairingSession> session_;
110 };
111
TEST_F(PairingSessionTest,DoPair)112 TEST_F(PairingSessionTest, DoPair) {
113 // Test the base SetUp case which initializes the pairing session.
114 InitSession();
115 }
116
TEST_F(PairingSessionTest,SetConfiguration)117 TEST_F(PairingSessionTest, SetConfiguration) {
118 encoding::EncodingOption encoding(encoding::EncodingOption::kHexadecimal, 8);
119 message::ConfigurationMessage configuration(encoding,
120 message::OptionsMessage::kInputDevice);
121 session_.TestSetConfiguration(configuration);
122
123 ASSERT_TRUE(session_.GetConfiguration());
124 ASSERT_EQ(encoding::EncodingOption::kHexadecimal,
125 session_.GetConfiguration()->encoding().encoding_type());
126 ASSERT_EQ(8, session_.GetConfiguration()->encoding().symbol_length());
127 ASSERT_EQ(message::OptionsMessage::kInputDevice,
128 session_.GetConfiguration()->client_role());
129
130 ASSERT_TRUE(session_.encoder());
131 ASSERT_EQ(2, session_.encoder()->symbols_per_byte());
132 }
133
TEST_F(PairingSessionTest,DoPairingPhaseInputDevice)134 TEST_F(PairingSessionTest, DoPairingPhaseInputDevice) {
135 InitSession();
136 InSequence sequence;
137
138 encoding::EncodingOption encoding(encoding::EncodingOption::kHexadecimal, 8);
139 message::ConfigurationMessage configuration(encoding,
140 message::OptionsMessage::kInputDevice);
141 session_.TestSetConfiguration(configuration);
142
143 EXPECT_CALL(listener_, OnPerformInputDeviceRole());
144
145 session_.TestDoPairingPhase();
146 }
147
TEST_F(PairingSessionTest,DoPairingPhaseDisplayDevice)148 TEST_F(PairingSessionTest, DoPairingPhaseDisplayDevice) {
149 InitSession();
150 InSequence sequence;
151
152 encoding::EncodingOption encoding(encoding::EncodingOption::kHexadecimal, 8);
153 message::ConfigurationMessage configuration(encoding,
154 message::OptionsMessage::kDisplayDevice);
155 session_.TestSetConfiguration(configuration);
156
157 EXPECT_CALL(challenge_, GetGamma(_)).WillOnce(Return(new Gamma(10, 0x5)));
158 EXPECT_CALL(listener_, OnPerformOutputDeviceRole(Gamma(10, 0x5)));
159 EXPECT_CALL(wire_, GetNextMessage());
160
161 session_.TestDoPairingPhase();
162 }
163
TEST_F(PairingSessionTest,AddInputEncoding)164 TEST_F(PairingSessionTest, AddInputEncoding) {
165 encoding::EncodingOption encoding(encoding::EncodingOption::kHexadecimal, 8);
166 session_.AddInputEncoding(encoding);
167 ASSERT_TRUE(session_.GetLocalOptions().SupportsInputEncoding(encoding));
168 }
169
TEST_F(PairingSessionTest,AddInputEncodingInvalidEncoding)170 TEST_F(PairingSessionTest, AddInputEncodingInvalidEncoding) {
171 encoding::EncodingOption encoding(encoding::EncodingOption::kHexadecimal, 1);
172 session_.AddInputEncoding(encoding);
173 ASSERT_FALSE(session_.GetLocalOptions().SupportsInputEncoding(encoding));
174 }
175
TEST_F(PairingSessionTest,AddOutputEncoding)176 TEST_F(PairingSessionTest, AddOutputEncoding) {
177 encoding::EncodingOption encoding(encoding::EncodingOption::kHexadecimal, 8);
178 session_.AddOutputEncoding(encoding);
179 ASSERT_TRUE(session_.GetLocalOptions().SupportsOutputEncoding(encoding));
180 }
181
TEST_F(PairingSessionTest,AddOutputEncodingInvalidEncoding)182 TEST_F(PairingSessionTest, AddOutputEncodingInvalidEncoding) {
183 encoding::EncodingOption encoding(encoding::EncodingOption::kUnknown, 8);
184 session_.AddOutputEncoding(encoding);
185 ASSERT_FALSE(session_.GetLocalOptions().SupportsOutputEncoding(encoding));
186 }
187
TEST_F(PairingSessionTest,SetSecret)188 TEST_F(PairingSessionTest, SetSecret) {
189 InitSession();
190 InSequence sequence;
191
192 // Do the setup so the session is expecting the secret.
193 encoding::EncodingOption encoding(encoding::EncodingOption::kHexadecimal, 8);
194 message::ConfigurationMessage configuration(encoding,
195 message::OptionsMessage::kInputDevice);
196 session_.TestSetConfiguration(configuration);
197
198 EXPECT_CALL(listener_, OnPerformInputDeviceRole());
199
200 session_.TestDoPairingPhase();
201
202 Gamma gamma(5, 0x1);
203 Nonce nonce(5, 0x2);
204 Alpha alpha(5, 0x3);
205
206 EXPECT_CALL(challenge_, CheckGamma(gamma)).WillOnce(Return(true));
207 EXPECT_CALL(challenge_, ExtractNonce(gamma))
208 .WillOnce(Return(new Nonce(nonce)));
209 EXPECT_CALL(challenge_, GetAlpha(nonce))
210 .WillOnce(Return(new Alpha(alpha)));
211
212 EXPECT_CALL(wire_, SendSecretMessage(_));
213 EXPECT_CALL(wire_, GetNextMessage());
214
215 session_.SetSecret(gamma);
216 }
217
TEST_F(PairingSessionTest,OnSecretMessage)218 TEST_F(PairingSessionTest, OnSecretMessage) {
219 InitSession();
220 InSequence sequence;
221
222 // Do the setup to set the secret.
223 encoding::EncodingOption encoding(encoding::EncodingOption::kHexadecimal, 8);
224 message::ConfigurationMessage configuration(encoding,
225 message::OptionsMessage::kInputDevice);
226 session_.TestSetConfiguration(configuration);
227
228 EXPECT_CALL(listener_, OnPerformInputDeviceRole());
229
230 session_.TestDoPairingPhase();
231
232 Gamma gamma(5, 0x1);
233 Nonce nonce(5, 0x2);
234 Alpha alpha(5, 0x3);
235
236 EXPECT_CALL(challenge_, CheckGamma(gamma)).WillOnce(Return(true));
237 EXPECT_CALL(challenge_, ExtractNonce(gamma))
238 .WillOnce(Return(new Nonce(nonce)));
239 EXPECT_CALL(challenge_, GetAlpha(nonce))
240 .WillOnce(Return(new Alpha(alpha)));
241
242 EXPECT_CALL(wire_, SendSecretMessage(_));
243 EXPECT_CALL(wire_, GetNextMessage());
244
245 session_.SetSecret(gamma);
246
247 EXPECT_CALL(challenge_, GetAlpha(nonce))
248 .WillOnce(Return(new Alpha(alpha)));
249
250 EXPECT_CALL(challenge_, GetAlpha(nonce))
251 .WillOnce(Return(new Alpha(alpha)));
252
253 EXPECT_CALL(wire_, SendSecretAckMessage(_));
254 EXPECT_CALL(listener_, OnPairingSuccess());
255
256 message::SecretMessage message(alpha);
257 session_.TestOnSecretMessage(message);
258 }
259
TEST_F(PairingSessionTest,OnSecretAckMessage)260 TEST_F(PairingSessionTest, OnSecretAckMessage) {
261 EXPECT_CALL(listener_, OnPairingSuccess());
262
263 Alpha alpha(5, 0x3);
264 message::SecretAckMessage message(alpha);
265 session_.TestOnSecretAckmessage(message);
266 }
267
268 } // namespace pairing
269 } // namespace polo
270