blob: 4283341656a2db2829c2e52d53f3a6faddc77a2c [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkova4766822011-07-07 10:42:22 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Chris Masone7aa5f902011-07-11 11:13:35 -07005#include "shill/profile.h"
6
Chris Masone6791a432011-07-12 13:23:19 -07007#include <string>
8#include <vector>
9
Chris Masone6515aab2011-10-12 16:19:09 -070010#include <base/file_path.h>
Paul Stewart2ebc16d2012-08-23 10:38:39 -070011#include <base/file_util.h>
Chris Masoneb9c00592011-10-06 13:10:39 -070012#include <base/memory/scoped_ptr.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050013#include <base/stringprintf.h>
Darin Petkova4766822011-07-07 10:42:22 -070014#include <base/string_util.h>
15#include <gtest/gtest.h>
16
Chris Masone6515aab2011-10-12 16:19:09 -070017#include "shill/glib.h"
18#include "shill/key_file_store.h"
Paul Stewart75225512012-01-26 22:51:33 -080019#include "shill/mock_manager.h"
Thieu Le5133b712013-02-19 14:47:21 -080020#include "shill/mock_metrics.h"
Chris Masone6791a432011-07-12 13:23:19 -070021#include "shill/mock_profile.h"
22#include "shill/mock_service.h"
Chris Masone9d779932011-08-25 16:33:41 -070023#include "shill/mock_store.h"
Chris Masone6791a432011-07-12 13:23:19 -070024#include "shill/property_store_unittest.h"
Chris Masone6515aab2011-10-12 16:19:09 -070025#include "shill/service_under_test.h"
Chris Masone6791a432011-07-12 13:23:19 -070026
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080027using base::FilePath;
Chris Masone6791a432011-07-12 13:23:19 -070028using std::set;
Darin Petkova4766822011-07-07 10:42:22 -070029using std::string;
Chris Masone6791a432011-07-12 13:23:19 -070030using std::vector;
Chris Masone9d779932011-08-25 16:33:41 -070031using testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070032using testing::Invoke;
Paul Stewart75225512012-01-26 22:51:33 -080033using testing::Mock;
Chris Masone6791a432011-07-12 13:23:19 -070034using testing::Return;
Chris Masone9d779932011-08-25 16:33:41 -070035using testing::SetArgumentPointee;
Chris Masone6791a432011-07-12 13:23:19 -070036using testing::StrictMock;
Darin Petkova4766822011-07-07 10:42:22 -070037
38namespace shill {
39
Chris Masone6791a432011-07-12 13:23:19 -070040class ProfileTest : public PropertyStoreTest {
41 public:
Thieu Le5133b712013-02-19 14:47:21 -080042 ProfileTest() : mock_metrics_(new MockMetrics(NULL)) {
Chris Masone6515aab2011-10-12 16:19:09 -070043 Profile::Identifier id("rather", "irrelevant");
Thieu Le5133b712013-02-19 14:47:21 -080044 profile_ =
45 new Profile(control_interface(), metrics(), manager(), id, "", false);
Chris Masone9d779932011-08-25 16:33:41 -070046 }
47
48 MockService *CreateMockService() {
Chris Masone2176a882011-09-14 22:29:15 -070049 return new StrictMock<MockService>(control_interface(),
50 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080051 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -070052 manager());
Chris Masone6791a432011-07-12 13:23:19 -070053 }
54
Chris Masone6515aab2011-10-12 16:19:09 -070055 virtual void SetUp() {
56 PropertyStoreTest::SetUp();
57 FilePath final_path(storage_path());
58 final_path = final_path.Append("test.profile");
59 scoped_ptr<KeyFileStore> storage(new KeyFileStore(&real_glib_));
60 storage->set_path(final_path);
61 ASSERT_TRUE(storage->Open());
62 profile_->set_storage(storage.release()); // Passes ownership.
63 }
64
Paul Stewart5dc40aa2011-10-28 19:43:43 -070065 bool ProfileInitStorage(const Profile::Identifier &id,
66 Profile::InitStorageOption storage_option,
67 bool save,
68 Error::Type error_type) {
69 Error error;
70 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -080071 new Profile(control_interface(), mock_metrics_.get(), manager(), id,
72 storage_path(), false));
Paul Stewart5dc40aa2011-10-28 19:43:43 -070073 bool ret = profile->InitStorage(&real_glib_, storage_option, &error);
74 EXPECT_EQ(error_type, error.type());
75 if (ret && save) {
76 EXPECT_TRUE(profile->Save());
77 }
78 return ret;
79 }
80
Chris Masone6791a432011-07-12 13:23:19 -070081 protected:
Chris Masone6515aab2011-10-12 16:19:09 -070082 GLib real_glib_;
Thieu Le5133b712013-02-19 14:47:21 -080083 scoped_ptr<MockMetrics> mock_metrics_;
Chris Masone6515aab2011-10-12 16:19:09 -070084 ProfileRefPtr profile_;
Darin Petkova4766822011-07-07 10:42:22 -070085};
86
Paul Stewart75225512012-01-26 22:51:33 -080087TEST_F(ProfileTest, DeleteEntry) {
88 scoped_ptr<MockManager> manager(new StrictMock<MockManager>(
89 control_interface(), dispatcher(), metrics(), glib()));
90 profile_->manager_ = manager.get();
91
92 MockStore *storage(new StrictMock<MockStore>());
93 profile_->storage_.reset(storage); // Passes ownership
94 const string kEntryName("entry_name");
95
96 // If entry does not appear in storage, DeleteEntry() should return an error.
97 EXPECT_CALL(*storage, ContainsGroup(kEntryName))
98 .WillOnce(Return(false));
99 {
100 Error error;
101 profile_->DeleteEntry(kEntryName, &error);
102 EXPECT_EQ(Error::kNotFound, error.type());
103 }
104
105 Mock::VerifyAndClearExpectations(storage);
Paul Stewart75225512012-01-26 22:51:33 -0800106
107 // If HandleProfileEntryDeletion() returns false, Profile should call
108 // DeleteGroup() itself.
Paul Stewart0756db92012-01-27 08:34:47 -0800109 EXPECT_CALL(*storage, ContainsGroup(kEntryName))
110 .WillOnce(Return(true));
Paul Stewart75225512012-01-26 22:51:33 -0800111 EXPECT_CALL(*manager.get(), HandleProfileEntryDeletion(_, kEntryName))
112 .WillOnce(Return(false));
113 EXPECT_CALL(*storage, DeleteGroup(kEntryName))
114 .WillOnce(Return(true));
Paul Stewart0756db92012-01-27 08:34:47 -0800115 EXPECT_CALL(*storage, Flush())
116 .WillOnce(Return(true));
Paul Stewart75225512012-01-26 22:51:33 -0800117 {
118 Error error;
119 profile_->DeleteEntry(kEntryName, &error);
120 EXPECT_TRUE(error.IsSuccess());
121 }
122
Paul Stewart0756db92012-01-27 08:34:47 -0800123 Mock::VerifyAndClearExpectations(storage);
124
Paul Stewart75225512012-01-26 22:51:33 -0800125 // If HandleProfileEntryDeletion() returns true, Profile should not call
126 // DeleteGroup() itself.
Paul Stewart0756db92012-01-27 08:34:47 -0800127 EXPECT_CALL(*storage, ContainsGroup(kEntryName))
128 .WillOnce(Return(true));
Paul Stewart75225512012-01-26 22:51:33 -0800129 EXPECT_CALL(*manager.get(), HandleProfileEntryDeletion(_, kEntryName))
130 .WillOnce(Return(true));
131 EXPECT_CALL(*storage, DeleteGroup(kEntryName))
132 .Times(0);
Paul Stewart0756db92012-01-27 08:34:47 -0800133 EXPECT_CALL(*storage, Flush())
134 .WillOnce(Return(true));
Paul Stewart75225512012-01-26 22:51:33 -0800135 {
136 Error error;
137 profile_->DeleteEntry(kEntryName, &error);
138 EXPECT_TRUE(error.IsSuccess());
139 }
140}
141
Darin Petkova4766822011-07-07 10:42:22 -0700142TEST_F(ProfileTest, IsValidIdentifierToken) {
143 EXPECT_FALSE(Profile::IsValidIdentifierToken(""));
144 EXPECT_FALSE(Profile::IsValidIdentifierToken(" "));
145 EXPECT_FALSE(Profile::IsValidIdentifierToken("-"));
146 EXPECT_FALSE(Profile::IsValidIdentifierToken("~"));
147 EXPECT_FALSE(Profile::IsValidIdentifierToken("_"));
148 EXPECT_TRUE(Profile::IsValidIdentifierToken("a"));
149 EXPECT_TRUE(Profile::IsValidIdentifierToken("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
150 EXPECT_TRUE(Profile::IsValidIdentifierToken("abcdefghijklmnopqrstuvwxyz"));
151 EXPECT_TRUE(Profile::IsValidIdentifierToken("0123456789"));
152}
153
154TEST_F(ProfileTest, ParseIdentifier) {
155 Profile::Identifier identifier;
156 EXPECT_FALSE(Profile::ParseIdentifier("", &identifier));
157 EXPECT_FALSE(Profile::ParseIdentifier("~", &identifier));
158 EXPECT_FALSE(Profile::ParseIdentifier("~foo", &identifier));
159 EXPECT_FALSE(Profile::ParseIdentifier("~/", &identifier));
160 EXPECT_FALSE(Profile::ParseIdentifier("~bar/", &identifier));
161 EXPECT_FALSE(Profile::ParseIdentifier("~/zoo", &identifier));
162 EXPECT_FALSE(Profile::ParseIdentifier("~./moo", &identifier));
163 EXPECT_FALSE(Profile::ParseIdentifier("~valid/?", &identifier));
164 EXPECT_FALSE(Profile::ParseIdentifier("~no//no", &identifier));
165 EXPECT_FALSE(Profile::ParseIdentifier("~no~no", &identifier));
166
167 static const char kUser[] = "user";
168 static const char kIdentifier[] = "identifier";
169 EXPECT_TRUE(Profile::ParseIdentifier(
170 base::StringPrintf("~%s/%s", kUser, kIdentifier),
171 &identifier));
172 EXPECT_EQ(kUser, identifier.user);
173 EXPECT_EQ(kIdentifier, identifier.identifier);
174
175 EXPECT_FALSE(Profile::ParseIdentifier("!", &identifier));
176 EXPECT_FALSE(Profile::ParseIdentifier("/nope", &identifier));
177
178 static const char kIdentifier2[] = "something";
179 EXPECT_TRUE(Profile::ParseIdentifier(kIdentifier2, &identifier));
180 EXPECT_EQ("", identifier.user);
181 EXPECT_EQ(kIdentifier2, identifier.identifier);
182}
183
Chris Masone7df0c672011-07-15 10:24:54 -0700184TEST_F(ProfileTest, GetFriendlyName) {
Darin Petkova4766822011-07-07 10:42:22 -0700185 static const char kUser[] = "theUser";
186 static const char kIdentifier[] = "theIdentifier";
Chris Masone6515aab2011-10-12 16:19:09 -0700187 Profile::Identifier id(kIdentifier);
Chris Masone7df0c672011-07-15 10:24:54 -0700188 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800189 new Profile(control_interface(), metrics(), manager(), id, "", false));
Chris Masone7df0c672011-07-15 10:24:54 -0700190 EXPECT_EQ(kIdentifier, profile->GetFriendlyName());
191 id.user = kUser;
Thieu Le5133b712013-02-19 14:47:21 -0800192 profile =
193 new Profile(control_interface(), metrics(), manager(), id, "", false);
Chris Masone7df0c672011-07-15 10:24:54 -0700194 EXPECT_EQ(string(kUser) + "/" + kIdentifier, profile->GetFriendlyName());
Darin Petkova4766822011-07-07 10:42:22 -0700195}
196
197TEST_F(ProfileTest, GetStoragePath) {
198 static const char kUser[] = "chronos";
199 static const char kIdentifier[] = "someprofile";
Chris Masone2ae797d2011-08-23 20:41:00 -0700200 static const char kFormat[] = "/a/place/for/%s";
Darin Petkova4766822011-07-07 10:42:22 -0700201 FilePath path;
Chris Masone6515aab2011-10-12 16:19:09 -0700202 Profile::Identifier id(kIdentifier);
Chris Masone2ae797d2011-08-23 20:41:00 -0700203 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800204 new Profile(control_interface(), metrics(), manager(), id, "", false));
Chris Masone2ae797d2011-08-23 20:41:00 -0700205 EXPECT_FALSE(profile->GetStoragePath(&path));
206 id.user = kUser;
207 profile =
Thieu Le5133b712013-02-19 14:47:21 -0800208 new Profile(control_interface(), metrics(), manager(), id, kFormat,
209 false);
Chris Masone2ae797d2011-08-23 20:41:00 -0700210 EXPECT_TRUE(profile->GetStoragePath(&path));
211 string suffix = base::StringPrintf("/%s.profile", kIdentifier);
212 EXPECT_EQ(base::StringPrintf(kFormat, kUser) + suffix, path.value());
Darin Petkova4766822011-07-07 10:42:22 -0700213}
214
Chris Masone6791a432011-07-12 13:23:19 -0700215TEST_F(ProfileTest, ServiceManagement) {
Chris Masone6515aab2011-10-12 16:19:09 -0700216 scoped_refptr<MockService> service1(CreateMockService());
217 scoped_refptr<MockService> service2(CreateMockService());
Chris Masone6791a432011-07-12 13:23:19 -0700218
Chris Masone6515aab2011-10-12 16:19:09 -0700219 EXPECT_CALL(*service1.get(), Save(_))
220 .WillRepeatedly(Invoke(service1.get(), &MockService::FauxSave));
221 EXPECT_CALL(*service2.get(), Save(_))
222 .WillRepeatedly(Invoke(service2.get(), &MockService::FauxSave));
Chris Masone6791a432011-07-12 13:23:19 -0700223
Chris Masone6515aab2011-10-12 16:19:09 -0700224 ASSERT_TRUE(profile_->AdoptService(service1));
225 ASSERT_TRUE(profile_->AdoptService(service2));
226
227 // Ensure services are in the profile now.
228 ASSERT_TRUE(profile_->ContainsService(service1));
229 ASSERT_TRUE(profile_->ContainsService(service2));
230
231 // Ensure we can't add them twice.
232 ASSERT_FALSE(profile_->AdoptService(service1));
233 ASSERT_FALSE(profile_->AdoptService(service2));
234
235 // Ensure that we can abandon individually, and that doing so is idempotent.
236 ASSERT_TRUE(profile_->AbandonService(service1));
237 ASSERT_FALSE(profile_->ContainsService(service1));
238 ASSERT_TRUE(profile_->AbandonService(service1));
239 ASSERT_TRUE(profile_->ContainsService(service2));
240
241 // Clean up.
242 ASSERT_TRUE(profile_->AbandonService(service2));
243 ASSERT_FALSE(profile_->ContainsService(service1));
244 ASSERT_FALSE(profile_->ContainsService(service2));
Chris Masone6791a432011-07-12 13:23:19 -0700245}
246
Paul Stewartbba6a5b2011-11-02 18:45:59 -0700247TEST_F(ProfileTest, ServiceConfigure) {
Chris Masone6515aab2011-10-12 16:19:09 -0700248 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
249 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800250 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700251 manager()));
mukesh agrawal00917ce2011-11-22 23:56:55 +0000252 service1->set_priority(service1->priority() + 1); // Change from default.
Chris Masone6515aab2011-10-12 16:19:09 -0700253 ASSERT_TRUE(profile_->AdoptService(service1));
254 ASSERT_TRUE(profile_->ContainsService(service1));
255
256 // Create new service; ask Profile to merge it with a known, matching,
257 // service; ensure that settings from |service1| wind up in |service2|.
258 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
259 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800260 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700261 manager()));
mukesh agrawal00917ce2011-11-22 23:56:55 +0000262 int32 orig_priority = service2->priority();
Paul Stewartbba6a5b2011-11-02 18:45:59 -0700263 ASSERT_TRUE(profile_->ConfigureService(service2));
mukesh agrawal00917ce2011-11-22 23:56:55 +0000264 ASSERT_EQ(service1->priority(), service2->priority());
265 ASSERT_NE(orig_priority, service2->priority());
Chris Masone6515aab2011-10-12 16:19:09 -0700266
267 // Clean up.
268 ASSERT_TRUE(profile_->AbandonService(service1));
269 ASSERT_FALSE(profile_->ContainsService(service1));
270 ASSERT_FALSE(profile_->ContainsService(service2));
271}
272
273TEST_F(ProfileTest, Save) {
Chris Masone9d779932011-08-25 16:33:41 -0700274 scoped_refptr<MockService> service1(CreateMockService());
275 scoped_refptr<MockService> service2(CreateMockService());
276 EXPECT_CALL(*service1.get(), Save(_)).WillOnce(Return(true));
277 EXPECT_CALL(*service2.get(), Save(_)).WillOnce(Return(true));
278
Chris Masone6515aab2011-10-12 16:19:09 -0700279 ASSERT_TRUE(profile_->AdoptService(service1));
280 ASSERT_TRUE(profile_->AdoptService(service2));
Chris Masone9d779932011-08-25 16:33:41 -0700281
Chris Masone6515aab2011-10-12 16:19:09 -0700282 profile_->Save();
Chris Masone9d779932011-08-25 16:33:41 -0700283}
284
Chris Masone6791a432011-07-12 13:23:19 -0700285TEST_F(ProfileTest, EntryEnumeration) {
Chris Masone6515aab2011-10-12 16:19:09 -0700286 scoped_refptr<MockService> service1(CreateMockService());
287 scoped_refptr<MockService> service2(CreateMockService());
Paul Stewart1b253142012-01-26 14:05:52 -0800288 string service1_storage_name = Technology::NameFromIdentifier(
289 Technology::kCellular) + "_1";
290 string service2_storage_name = Technology::NameFromIdentifier(
291 Technology::kCellular) + "_2";
Chris Masone6515aab2011-10-12 16:19:09 -0700292 EXPECT_CALL(*service1.get(), Save(_))
293 .WillRepeatedly(Invoke(service1.get(), &MockService::FauxSave));
294 EXPECT_CALL(*service2.get(), Save(_))
295 .WillRepeatedly(Invoke(service2.get(), &MockService::FauxSave));
Paul Stewart1b253142012-01-26 14:05:52 -0800296 EXPECT_CALL(*service1.get(), GetStorageIdentifier())
297 .WillRepeatedly(Return(service1_storage_name));
298 EXPECT_CALL(*service2.get(), GetStorageIdentifier())
299 .WillRepeatedly(Return(service2_storage_name));
Chris Masone6515aab2011-10-12 16:19:09 -0700300
Darin Petkov457728b2013-01-09 09:49:08 +0100301 string service1_name(service1->unique_name());
302 string service2_name(service2->unique_name());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700303
Chris Masone6791a432011-07-12 13:23:19 -0700304 ASSERT_TRUE(profile_->AdoptService(service1));
305 ASSERT_TRUE(profile_->AdoptService(service2));
306
Paul Stewart1b253142012-01-26 14:05:52 -0800307 Error error;
308 ASSERT_EQ(2, profile_->EnumerateEntries(&error).size());
Chris Masone6791a432011-07-12 13:23:19 -0700309
Chris Masone6515aab2011-10-12 16:19:09 -0700310 ASSERT_TRUE(profile_->AbandonService(service1));
Paul Stewart1b253142012-01-26 14:05:52 -0800311 ASSERT_EQ(service2_storage_name, profile_->EnumerateEntries(&error)[0]);
Chris Masone6791a432011-07-12 13:23:19 -0700312
Chris Masone6515aab2011-10-12 16:19:09 -0700313 ASSERT_TRUE(profile_->AbandonService(service2));
Paul Stewart1b253142012-01-26 14:05:52 -0800314 ASSERT_EQ(0, profile_->EnumerateEntries(&error).size());
Chris Masone6791a432011-07-12 13:23:19 -0700315}
316
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700317TEST_F(ProfileTest, MatchesIdentifier) {
318 static const char kUser[] = "theUser";
319 static const char kIdentifier[] = "theIdentifier";
320 Profile::Identifier id(kUser, kIdentifier);
321 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800322 new Profile(control_interface(), metrics(), manager(), id, "", false));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700323 EXPECT_TRUE(profile->MatchesIdentifier(id));
324 EXPECT_FALSE(profile->MatchesIdentifier(Profile::Identifier(kUser, "")));
325 EXPECT_FALSE(
326 profile->MatchesIdentifier(Profile::Identifier("", kIdentifier)));
327 EXPECT_FALSE(
328 profile->MatchesIdentifier(Profile::Identifier(kIdentifier, kUser)));
329}
330
331TEST_F(ProfileTest, InitStorage) {
332 Profile::Identifier id("theUser", "theIdentifier");
333
334 // Profile doesn't exist but we wanted it to.
335 EXPECT_FALSE(ProfileInitStorage(id, Profile::kOpenExisting, false,
336 Error::kNotFound));
337
338 // Success case, with a side effect of creating the profile.
339 EXPECT_TRUE(ProfileInitStorage(id, Profile::kCreateNew, true,
340 Error::kSuccess));
341
342 // The results from our two test cases above will now invert since
343 // the profile now exists. First, we now succeed if we require that
344 // the profile already exist...
345 EXPECT_TRUE(ProfileInitStorage(id, Profile::kOpenExisting, false,
346 Error::kSuccess));
347
348 // And we fail if we require that it doesn't.
349 EXPECT_FALSE(ProfileInitStorage(id, Profile::kCreateNew, false,
350 Error::kAlreadyExists));
351
352 // As a sanity check, ensure "create or open" works for both profile-exists...
353 EXPECT_TRUE(ProfileInitStorage(id, Profile::kCreateOrOpenExisting, false,
354 Error::kSuccess));
355
356 // ...and for a new profile that doesn't exist.
357 Profile::Identifier id2("theUser", "theIdentifier2");
358 // Let's just make double-check that this profile really doesn't exist.
359 ASSERT_FALSE(ProfileInitStorage(id2, Profile::kOpenExisting, false,
360 Error::kNotFound));
361
362 // Then test that with "create or open" we succeed.
363 EXPECT_TRUE(ProfileInitStorage(id2, Profile::kCreateOrOpenExisting, false,
364 Error::kSuccess));
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700365
366 // Corrupt the profile storage.
367 string suffix(base::StringPrintf("/%s.profile", id.identifier.c_str()));
368 FilePath final_path(
369 base::StringPrintf(storage_path().c_str(), id.user.c_str()) + suffix);
370 string data = "]corrupt_data[";
371 EXPECT_EQ(data.size(),
372 file_util::WriteFile(final_path, data.data(), data.size()));
373
374 // Then test that we fail to open this file.
Thieu Le5133b712013-02-19 14:47:21 -0800375 EXPECT_CALL(*mock_metrics_, NotifyCorruptedProfile());
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700376 EXPECT_FALSE(ProfileInitStorage(id, Profile::kOpenExisting, false,
377 Error::kInternalError));
Thieu Le5133b712013-02-19 14:47:21 -0800378 Mock::VerifyAndClearExpectations(mock_metrics_.get());
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700379
380 // But then on a second try the file no longer exists.
Thieu Le5133b712013-02-19 14:47:21 -0800381 EXPECT_CALL(*mock_metrics_, NotifyCorruptedProfile()).Times(0);
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700382 ASSERT_FALSE(ProfileInitStorage(id, Profile::kOpenExisting, false,
383 Error::kNotFound));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700384}
385
Darin Petkove7c6ad32012-06-29 10:22:09 +0200386TEST_F(ProfileTest, UpdateDevice) {
387 EXPECT_FALSE(profile_->UpdateDevice(NULL));
388}
389
Paul Stewart7355ce12011-09-02 10:47:01 -0700390} // namespace shill