OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <string> | |
6 #include <vector> | |
7 | |
8 #include "base/bind.h" | |
9 #include "base/location.h" | |
10 #include "base/macros.h" | |
11 #include "base/message_loop/message_loop.h" | |
12 #include "base/run_loop.h" | |
13 #include "base/single_thread_task_runner.h" | |
14 #include "base/task_runner.h" | |
15 #include "base/thread_task_runner_handle.h" | |
16 #include "chromeos/dbus/fake_cryptohome_client.h" | |
17 #include "chromeos/tpm_token_info_getter.h" | |
18 #include "testing/gtest/include/gtest/gtest.h" | |
19 | |
20 namespace { | |
21 | |
22 // The struct holding information returned by TPMTokenInfoGetter::Start | |
23 // callback. | |
24 struct TestTPMTokenInfo { | |
25 TestTPMTokenInfo() : enabled(false), slot_id(-2) {} | |
26 | |
27 bool IsReady() const { | |
28 return slot_id >= 0; | |
29 } | |
30 | |
31 bool enabled; | |
32 std::string name; | |
33 std::string pin; | |
34 int slot_id; | |
35 }; | |
36 | |
37 // Callback for TPMTokenInfoGetter::Start. It records the values returned | |
38 // by TPMTokenInfoGetter to |info|. | |
39 void RecordGetterResult(TestTPMTokenInfo* target, | |
40 const chromeos::TPMTokenInfo& source) { | |
41 target->enabled = source.tpm_is_enabled; | |
42 target->name = source.token_name; | |
43 target->pin = source.user_pin; | |
44 target->slot_id = source.token_slot_id; | |
45 } | |
46 | |
47 // Task runner for handling delayed tasks posted by TPMTokenInfoGetter when | |
48 // retrying failed cryptohome method calls. It just records the requested | |
49 // delay and immediately runs the task. The task is run asynchronously to be | |
50 // closer to what's actually happening in production. | |
51 // The delays used by TPMTokenGetter should be monotonically increasing, so | |
52 // the fake task runner does not handle task reordering based on the delays. | |
53 class FakeTaskRunner : public base::TaskRunner { | |
54 public: | |
55 // |delays|: Vector to which the dalays seen by the task runner are saved. | |
56 explicit FakeTaskRunner(std::vector<int64>* delays) : delays_(delays) {} | |
57 | |
58 // base::TaskRunner overrides: | |
59 bool PostDelayedTask(const tracked_objects::Location& from_here, | |
60 const base::Closure& task, | |
61 base::TimeDelta delay) override { | |
62 delays_->push_back(delay.InMilliseconds()); | |
63 base::ThreadTaskRunnerHandle::Get()->PostTask(from_here, task); | |
64 return true; | |
65 } | |
66 bool RunsTasksOnCurrentThread() const override { return true; } | |
67 | |
68 protected: | |
69 ~FakeTaskRunner() override {} | |
70 | |
71 private: | |
72 // The vector of delays. | |
73 std::vector<int64>* delays_; | |
74 | |
75 DISALLOW_COPY_AND_ASSIGN(FakeTaskRunner); | |
76 }; | |
77 | |
78 // Implementation of CryptohomeClient used in these tests. Note that | |
79 // TestCryptohomeClient implements FakeCryptohomeClient purely for convenience | |
80 // of not having to implement whole CryptohomeClient interface. | |
81 // TestCryptohomeClient overrides all CryptohomeClient methods used in | |
82 // TPMTokenInfoGetter tests. | |
83 class TestCryptohomeClient : public chromeos::FakeCryptohomeClient { | |
84 public: | |
85 // |user_id|: The user associated with the TPMTokenInfoGetter that will be | |
86 // using the TestCryptohomeClient. Should be empty for system token. | |
87 explicit TestCryptohomeClient(const std::string& user_id) | |
88 : user_id_(user_id), | |
89 tpm_is_enabled_(true), | |
90 tpm_is_enabled_failure_count_(0), | |
91 tpm_is_enabled_succeeded_(false), | |
92 get_tpm_token_info_failure_count_(0), | |
93 get_tpm_token_info_not_set_count_(0), | |
94 get_tpm_token_info_succeeded_(false) { | |
95 } | |
96 | |
97 ~TestCryptohomeClient() override {} | |
98 | |
99 void set_tpm_is_enabled(bool value) { | |
100 tpm_is_enabled_ = value; | |
101 } | |
102 | |
103 void set_tpm_is_enabled_failure_count(int value) { | |
104 ASSERT_GT(value, 0); | |
105 tpm_is_enabled_failure_count_ = value; | |
106 } | |
107 | |
108 void set_get_tpm_token_info_failure_count(int value) { | |
109 ASSERT_GT(value, 0); | |
110 get_tpm_token_info_failure_count_ = value; | |
111 } | |
112 | |
113 void set_get_tpm_token_info_not_set_count(int value) { | |
114 ASSERT_GT(value, 0); | |
115 get_tpm_token_info_not_set_count_ = value; | |
116 } | |
117 | |
118 // Sets the tpm tpken info to be reported by the test CryptohomeClient. | |
119 // If there is |Pkcs11GetTpmTokenInfo| in progress, runs the pending | |
120 // callback with the set tpm token info. | |
121 void SetTPMTokenInfo(const std::string& token_name, | |
122 const std::string& pin, | |
123 int slot_id) { | |
124 tpm_token_info_.name = token_name; | |
125 tpm_token_info_.pin = pin; | |
126 tpm_token_info_.slot_id = slot_id; | |
127 | |
128 ASSERT_TRUE(tpm_token_info_.IsReady()); | |
129 | |
130 InvokeGetTpmTokenInfoCallbackIfReady(); | |
131 } | |
132 | |
133 private: | |
134 // FakeCryptohomeClient override. | |
135 void TpmIsEnabled(const chromeos::BoolDBusMethodCallback& callback) override { | |
136 ASSERT_FALSE(tpm_is_enabled_succeeded_); | |
137 if (tpm_is_enabled_failure_count_ > 0) { | |
138 --tpm_is_enabled_failure_count_; | |
139 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
140 FROM_HERE, | |
141 base::Bind(callback, chromeos::DBUS_METHOD_CALL_FAILURE, false)); | |
142 } else { | |
143 tpm_is_enabled_succeeded_ = true; | |
144 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
145 FROM_HERE, | |
146 base::Bind(callback, | |
147 chromeos::DBUS_METHOD_CALL_SUCCESS, tpm_is_enabled_)); | |
148 } | |
149 } | |
150 | |
151 void Pkcs11GetTpmTokenInfo( | |
152 const Pkcs11GetTpmTokenInfoCallback& callback) override { | |
153 ASSERT_TRUE(user_id_.empty()); | |
154 | |
155 HandleGetTpmTokenInfo(callback); | |
156 } | |
157 | |
158 void Pkcs11GetTpmTokenInfoForUser( | |
159 const std::string& user_id, | |
160 const Pkcs11GetTpmTokenInfoCallback& callback) override { | |
161 ASSERT_FALSE(user_id_.empty()); | |
162 ASSERT_EQ(user_id_, user_id); | |
163 | |
164 HandleGetTpmTokenInfo(callback); | |
165 } | |
166 | |
167 // Handles Pkcs11GetTpmTokenInfo calls (both for system and user token). The | |
168 // CryptohomeClient method overrides should make sure that |user_id_| is | |
169 // properly set before calling this. | |
170 void HandleGetTpmTokenInfo(const Pkcs11GetTpmTokenInfoCallback& callback) { | |
171 ASSERT_TRUE(tpm_is_enabled_succeeded_); | |
172 ASSERT_FALSE(get_tpm_token_info_succeeded_); | |
173 ASSERT_TRUE(pending_get_tpm_token_info_callback_.is_null()); | |
174 | |
175 if (get_tpm_token_info_failure_count_ > 0) { | |
176 --get_tpm_token_info_failure_count_; | |
177 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
178 FROM_HERE, | |
179 base::Bind(callback, | |
180 chromeos::DBUS_METHOD_CALL_FAILURE, | |
181 std::string() /* token name */, | |
182 std::string() /* user pin */, | |
183 -1 /* slot id */)); | |
184 return; | |
185 } | |
186 | |
187 if (get_tpm_token_info_not_set_count_ > 0) { | |
188 --get_tpm_token_info_not_set_count_; | |
189 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
190 FROM_HERE, | |
191 base::Bind(callback, | |
192 chromeos::DBUS_METHOD_CALL_SUCCESS, | |
193 std::string() /* token name */, | |
194 std::string() /* user pin */, | |
195 -1 /* slot id */)); | |
196 return; | |
197 } | |
198 | |
199 pending_get_tpm_token_info_callback_ = callback; | |
200 InvokeGetTpmTokenInfoCallbackIfReady(); | |
201 } | |
202 | |
203 void InvokeGetTpmTokenInfoCallbackIfReady() { | |
204 if (!tpm_token_info_.IsReady() || | |
205 pending_get_tpm_token_info_callback_.is_null()) | |
206 return; | |
207 | |
208 get_tpm_token_info_succeeded_ = true; | |
209 // Called synchronously for convenience (to avoid using extra RunLoop in | |
210 // tests). Unlike with other Cryptohome callbacks, TPMTokenInfoGetter does | |
211 // not rely on this callback being called asynchronously. | |
212 pending_get_tpm_token_info_callback_.Run( | |
213 chromeos::DBUS_METHOD_CALL_SUCCESS, | |
214 tpm_token_info_.name, | |
215 tpm_token_info_.pin, | |
216 tpm_token_info_.slot_id); | |
217 } | |
218 | |
219 std::string user_id_; | |
220 bool tpm_is_enabled_; | |
221 int tpm_is_enabled_failure_count_; | |
222 bool tpm_is_enabled_succeeded_; | |
223 int get_tpm_token_info_failure_count_; | |
224 int get_tpm_token_info_not_set_count_; | |
225 bool get_tpm_token_info_succeeded_; | |
226 Pkcs11GetTpmTokenInfoCallback pending_get_tpm_token_info_callback_; | |
227 TestTPMTokenInfo tpm_token_info_; | |
228 | |
229 DISALLOW_COPY_AND_ASSIGN(TestCryptohomeClient); | |
230 }; | |
231 | |
232 class SystemTPMTokenInfoGetterTest : public testing::Test { | |
233 public: | |
234 SystemTPMTokenInfoGetterTest() {} | |
235 ~SystemTPMTokenInfoGetterTest() override {} | |
236 | |
237 void SetUp() override { | |
238 cryptohome_client_.reset(new TestCryptohomeClient(std::string())); | |
239 tpm_token_info_getter_ = | |
240 chromeos::TPMTokenInfoGetter::CreateForSystemToken( | |
241 cryptohome_client_.get(), | |
242 scoped_refptr<base::TaskRunner>(new FakeTaskRunner(&delays_))); | |
243 } | |
244 | |
245 protected: | |
246 scoped_ptr<TestCryptohomeClient> cryptohome_client_; | |
247 scoped_ptr<chromeos::TPMTokenInfoGetter> tpm_token_info_getter_; | |
248 | |
249 std::vector<int64> delays_; | |
250 | |
251 private: | |
252 base::MessageLoop message_loop_; | |
253 | |
254 DISALLOW_COPY_AND_ASSIGN(SystemTPMTokenInfoGetterTest); | |
255 }; | |
256 | |
257 class UserTPMTokenInfoGetterTest : public testing::Test { | |
258 public: | |
259 UserTPMTokenInfoGetterTest() : user_id_("user") {} | |
260 ~UserTPMTokenInfoGetterTest() override {} | |
261 | |
262 void SetUp() override { | |
263 cryptohome_client_.reset(new TestCryptohomeClient(user_id_)); | |
264 tpm_token_info_getter_ = | |
265 chromeos::TPMTokenInfoGetter::CreateForUserToken( | |
266 user_id_, | |
267 cryptohome_client_.get(), | |
268 scoped_refptr<base::TaskRunner>(new FakeTaskRunner(&delays_))); | |
269 } | |
270 | |
271 protected: | |
272 scoped_ptr<TestCryptohomeClient> cryptohome_client_; | |
273 scoped_ptr<chromeos::TPMTokenInfoGetter> tpm_token_info_getter_; | |
274 | |
275 std::string user_id_; | |
276 std::vector<int64> delays_; | |
277 | |
278 private: | |
279 base::MessageLoop message_loop_; | |
280 | |
281 DISALLOW_COPY_AND_ASSIGN(UserTPMTokenInfoGetterTest); | |
282 }; | |
283 | |
284 TEST_F(SystemTPMTokenInfoGetterTest, BasicFlow) { | |
285 TestTPMTokenInfo reported_info; | |
286 tpm_token_info_getter_->Start( | |
287 base::Bind(&RecordGetterResult, &reported_info)); | |
288 base::RunLoop().RunUntilIdle(); | |
289 | |
290 EXPECT_FALSE(reported_info.IsReady()); | |
291 cryptohome_client_->SetTPMTokenInfo("TOKEN_1", "2222", 1); | |
292 | |
293 EXPECT_TRUE(reported_info.IsReady()); | |
294 EXPECT_TRUE(reported_info.enabled); | |
295 EXPECT_EQ("TOKEN_1", reported_info.name); | |
296 EXPECT_EQ("2222", reported_info.pin); | |
297 EXPECT_EQ(1, reported_info.slot_id); | |
298 | |
299 EXPECT_EQ(std::vector<int64>(), delays_); | |
300 } | |
301 | |
302 TEST_F(SystemTPMTokenInfoGetterTest, TokenSlotIdEqualsZero) { | |
303 TestTPMTokenInfo reported_info; | |
304 tpm_token_info_getter_->Start( | |
305 base::Bind(&RecordGetterResult, &reported_info)); | |
306 base::RunLoop().RunUntilIdle(); | |
307 | |
308 EXPECT_FALSE(reported_info.IsReady()); | |
309 cryptohome_client_->SetTPMTokenInfo("TOKEN_0", "2222", 0); | |
310 | |
311 EXPECT_TRUE(reported_info.IsReady()); | |
312 base::RunLoop().RunUntilIdle(); | |
313 | |
314 EXPECT_TRUE(reported_info.enabled); | |
315 EXPECT_EQ("TOKEN_0", reported_info.name); | |
316 EXPECT_EQ("2222", reported_info.pin); | |
317 EXPECT_EQ(0, reported_info.slot_id); | |
318 | |
319 EXPECT_EQ(std::vector<int64>(), delays_); | |
320 } | |
321 | |
322 TEST_F(SystemTPMTokenInfoGetterTest, TPMNotEnabled) { | |
323 cryptohome_client_->set_tpm_is_enabled(false); | |
324 | |
325 TestTPMTokenInfo reported_info; | |
326 tpm_token_info_getter_->Start( | |
327 base::Bind(&RecordGetterResult, &reported_info)); | |
328 base::RunLoop().RunUntilIdle(); | |
329 | |
330 EXPECT_FALSE(reported_info.IsReady()); | |
331 EXPECT_FALSE(reported_info.enabled); | |
332 | |
333 EXPECT_EQ(std::vector<int64>(), delays_); | |
334 } | |
335 | |
336 TEST_F(SystemTPMTokenInfoGetterTest, TpmEnabledCallFails) { | |
337 cryptohome_client_->set_tpm_is_enabled_failure_count(1); | |
338 | |
339 TestTPMTokenInfo reported_info; | |
340 tpm_token_info_getter_->Start( | |
341 base::Bind(&RecordGetterResult, &reported_info)); | |
342 base::RunLoop().RunUntilIdle(); | |
343 | |
344 EXPECT_FALSE(reported_info.IsReady()); | |
345 cryptohome_client_->SetTPMTokenInfo("TOKEN_1", "2222", 1); | |
346 | |
347 EXPECT_TRUE(reported_info.IsReady()); | |
348 EXPECT_TRUE(reported_info.enabled); | |
349 EXPECT_EQ("TOKEN_1", reported_info.name); | |
350 EXPECT_EQ("2222", reported_info.pin); | |
351 EXPECT_EQ(1, reported_info.slot_id); | |
352 | |
353 const int64 kExpectedDelays[] = {100}; | |
354 EXPECT_EQ(std::vector<int64>(kExpectedDelays, | |
355 kExpectedDelays + arraysize(kExpectedDelays)), | |
356 delays_); | |
357 } | |
358 | |
359 TEST_F(SystemTPMTokenInfoGetterTest, GetTpmTokenInfoInitiallyNotReady) { | |
360 cryptohome_client_->set_get_tpm_token_info_not_set_count(1); | |
361 | |
362 TestTPMTokenInfo reported_info; | |
363 tpm_token_info_getter_->Start( | |
364 base::Bind(&RecordGetterResult, &reported_info)); | |
365 base::RunLoop().RunUntilIdle(); | |
366 | |
367 EXPECT_FALSE(reported_info.IsReady()); | |
368 cryptohome_client_->SetTPMTokenInfo("TOKEN_1", "2222", 1); | |
369 | |
370 EXPECT_TRUE(reported_info.IsReady()); | |
371 EXPECT_TRUE(reported_info.enabled); | |
372 EXPECT_EQ("TOKEN_1", reported_info.name); | |
373 EXPECT_EQ("2222", reported_info.pin); | |
374 EXPECT_EQ(1, reported_info.slot_id); | |
375 | |
376 const int64 kExpectedDelays[] = {100}; | |
377 EXPECT_EQ(std::vector<int64>(kExpectedDelays, | |
378 kExpectedDelays + arraysize(kExpectedDelays)), | |
379 delays_); | |
380 } | |
381 | |
382 TEST_F(SystemTPMTokenInfoGetterTest, GetTpmTokenInfoInitiallyFails) { | |
383 cryptohome_client_->set_get_tpm_token_info_failure_count(1); | |
384 | |
385 TestTPMTokenInfo reported_info; | |
386 tpm_token_info_getter_->Start( | |
387 base::Bind(&RecordGetterResult, &reported_info)); | |
388 base::RunLoop().RunUntilIdle(); | |
389 | |
390 EXPECT_FALSE(reported_info.IsReady()); | |
391 cryptohome_client_->SetTPMTokenInfo("TOKEN_1", "2222", 1); | |
392 | |
393 EXPECT_TRUE(reported_info.IsReady()); | |
394 EXPECT_TRUE(reported_info.enabled); | |
395 EXPECT_EQ("TOKEN_1", reported_info.name); | |
396 EXPECT_EQ("2222", reported_info.pin); | |
397 EXPECT_EQ(1, reported_info.slot_id); | |
398 | |
399 const int64 kExpectedDelays[] = {100}; | |
400 EXPECT_EQ(std::vector<int64>(kExpectedDelays, | |
401 kExpectedDelays + arraysize(kExpectedDelays)), | |
402 delays_); | |
403 } | |
404 | |
405 TEST_F(SystemTPMTokenInfoGetterTest, RetryDelaysIncreaseExponentially) { | |
406 cryptohome_client_->set_tpm_is_enabled_failure_count(2); | |
407 cryptohome_client_->set_get_tpm_token_info_failure_count(1); | |
408 cryptohome_client_->set_get_tpm_token_info_not_set_count(3); | |
409 | |
410 TestTPMTokenInfo reported_info; | |
411 tpm_token_info_getter_->Start( | |
412 base::Bind(&RecordGetterResult, &reported_info)); | |
413 base::RunLoop().RunUntilIdle(); | |
414 | |
415 EXPECT_FALSE(reported_info.IsReady()); | |
416 cryptohome_client_->SetTPMTokenInfo("TOKEN_1", "2222", 2); | |
417 | |
418 EXPECT_TRUE(reported_info.IsReady()); | |
419 EXPECT_TRUE(reported_info.enabled); | |
420 EXPECT_EQ("TOKEN_1", reported_info.name); | |
421 EXPECT_EQ("2222", reported_info.pin); | |
422 EXPECT_EQ(2, reported_info.slot_id); | |
423 | |
424 int64 kExpectedDelays[] = { 100, 200, 400, 800, 1600, 3200 }; | |
425 ASSERT_EQ( | |
426 std::vector<int64>(kExpectedDelays, | |
427 kExpectedDelays + arraysize(kExpectedDelays)), | |
428 delays_); | |
429 } | |
430 | |
431 TEST_F(SystemTPMTokenInfoGetterTest, RetryDelayBounded) { | |
432 cryptohome_client_->set_tpm_is_enabled_failure_count(4); | |
433 cryptohome_client_->set_get_tpm_token_info_failure_count(5); | |
434 cryptohome_client_->set_get_tpm_token_info_not_set_count(6); | |
435 | |
436 TestTPMTokenInfo reported_info; | |
437 tpm_token_info_getter_->Start( | |
438 base::Bind(&RecordGetterResult, &reported_info)); | |
439 base::RunLoop().RunUntilIdle(); | |
440 | |
441 EXPECT_FALSE(reported_info.IsReady()); | |
442 cryptohome_client_->SetTPMTokenInfo("TOKEN_1", "2222", 1); | |
443 | |
444 EXPECT_TRUE(reported_info.IsReady()); | |
445 EXPECT_TRUE(reported_info.enabled); | |
446 EXPECT_EQ("TOKEN_1", reported_info.name); | |
447 EXPECT_EQ("2222", reported_info.pin); | |
448 EXPECT_EQ(1, reported_info.slot_id); | |
449 | |
450 int64 kExpectedDelays[] = { | |
451 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800, | |
452 300000, 300000, 300000 | |
453 }; | |
454 ASSERT_EQ( | |
455 std::vector<int64>(kExpectedDelays, | |
456 kExpectedDelays + arraysize(kExpectedDelays)), | |
457 delays_); | |
458 } | |
459 | |
460 TEST_F(UserTPMTokenInfoGetterTest, BasicFlow) { | |
461 TestTPMTokenInfo reported_info; | |
462 tpm_token_info_getter_->Start( | |
463 base::Bind(&RecordGetterResult, &reported_info)); | |
464 base::RunLoop().RunUntilIdle(); | |
465 | |
466 EXPECT_FALSE(reported_info.IsReady()); | |
467 cryptohome_client_->SetTPMTokenInfo("TOKEN_1", "2222", 1); | |
468 | |
469 EXPECT_TRUE(reported_info.IsReady()); | |
470 EXPECT_TRUE(reported_info.enabled); | |
471 EXPECT_EQ("TOKEN_1", reported_info.name); | |
472 EXPECT_EQ("2222", reported_info.pin); | |
473 EXPECT_EQ(1, reported_info.slot_id); | |
474 | |
475 EXPECT_EQ(std::vector<int64>(), delays_); | |
476 } | |
477 | |
478 TEST_F(UserTPMTokenInfoGetterTest, GetTpmTokenInfoInitiallyFails) { | |
479 cryptohome_client_->set_get_tpm_token_info_failure_count(1); | |
480 | |
481 TestTPMTokenInfo reported_info; | |
482 tpm_token_info_getter_->Start( | |
483 base::Bind(&RecordGetterResult, &reported_info)); | |
484 base::RunLoop().RunUntilIdle(); | |
485 | |
486 EXPECT_FALSE(reported_info.IsReady()); | |
487 cryptohome_client_->SetTPMTokenInfo("TOKEN_1", "2222", 1); | |
488 | |
489 EXPECT_TRUE(reported_info.IsReady()); | |
490 EXPECT_TRUE(reported_info.enabled); | |
491 EXPECT_EQ("TOKEN_1", reported_info.name); | |
492 EXPECT_EQ("2222", reported_info.pin); | |
493 EXPECT_EQ(1, reported_info.slot_id); | |
494 | |
495 const int64 kExpectedDelays[] = {100}; | |
496 EXPECT_EQ(std::vector<int64>(kExpectedDelays, | |
497 kExpectedDelays + arraysize(kExpectedDelays)), | |
498 delays_); | |
499 } | |
500 | |
501 TEST_F(UserTPMTokenInfoGetterTest, GetTpmTokenInfoInitiallyNotReady) { | |
502 cryptohome_client_->set_get_tpm_token_info_not_set_count(1); | |
503 | |
504 TestTPMTokenInfo reported_info; | |
505 tpm_token_info_getter_->Start( | |
506 base::Bind(&RecordGetterResult, &reported_info)); | |
507 base::RunLoop().RunUntilIdle(); | |
508 | |
509 EXPECT_FALSE(reported_info.IsReady()); | |
510 cryptohome_client_->SetTPMTokenInfo("TOKEN_1", "2222", 1); | |
511 | |
512 EXPECT_TRUE(reported_info.IsReady()); | |
513 EXPECT_TRUE(reported_info.enabled); | |
514 EXPECT_EQ("TOKEN_1", reported_info.name); | |
515 EXPECT_EQ("2222", reported_info.pin); | |
516 EXPECT_EQ(1, reported_info.slot_id); | |
517 | |
518 const int64 kExpectedDelays[] = {100}; | |
519 EXPECT_EQ(std::vector<int64>(kExpectedDelays, | |
520 kExpectedDelays + arraysize(kExpectedDelays)), | |
521 delays_); | |
522 } | |
523 | |
524 } // namespace | |
525 | |
OLD | NEW |