Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media_galleries / fileapi / picasa_data_provider_browsertest.cc
1 // Copyright 2013 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 <vector>
6
7 #include "base/file_util.h"
8 #include "base/files/file_enumerator.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "build/build_config.h"
15 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
16 #include "chrome/browser/media_galleries/fileapi/picasa_data_provider.h"
17 #include "chrome/common/media_galleries/picasa_test_util.h"
18 #include "chrome/common/media_galleries/picasa_types.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "content/public/test/test_browser_thread.h"
21
22 namespace picasa {
23
24 namespace {
25
26 void VerifyTestAlbumTable(PicasaDataProvider* data_provider,
27                           base::FilePath test_folder_1_path,
28                           base::FilePath test_folder_2_path) {
29   scoped_ptr<AlbumMap> folders = data_provider->GetFolders();
30   ASSERT_TRUE(folders.get());
31   EXPECT_EQ(2u, folders->size());
32
33   AlbumMap::const_iterator folder_1 = folders->find(
34       test_folder_1_path.BaseName().AsUTF8Unsafe() + " 1899-12-30");
35   EXPECT_NE(folders->end(), folder_1);
36   EXPECT_EQ(test_folder_1_path.BaseName().AsUTF8Unsafe(),
37             folder_1->second.name);
38   EXPECT_EQ(test_folder_1_path, folder_1->second.path);
39   EXPECT_EQ("uid1", folder_1->second.uid);
40
41   AlbumMap::const_iterator folder_2 = folders->find(
42       test_folder_2_path.BaseName().AsUTF8Unsafe() + " 1899-12-30");
43   EXPECT_NE(folders->end(), folder_2);
44   EXPECT_EQ(test_folder_2_path.BaseName().AsUTF8Unsafe(),
45             folder_2->second.name);
46   EXPECT_EQ(test_folder_2_path, folder_2->second.path);
47   EXPECT_EQ("uid4", folder_2->second.uid);
48
49   scoped_ptr<AlbumMap> albums = data_provider->GetAlbums();
50   ASSERT_TRUE(albums.get());
51   EXPECT_EQ(2u, albums->size());
52
53   AlbumMap::const_iterator album_1 = albums->find("Album 1 Name 1899-12-30");
54   EXPECT_NE(albums->end(), album_1);
55   EXPECT_EQ("Album 1 Name", album_1->second.name);
56   EXPECT_EQ(base::FilePath(), album_1->second.path);
57   EXPECT_EQ("uid3", album_1->second.uid);
58
59   AlbumMap::const_iterator album_2 = albums->find("Album 2 Name 1899-12-30");
60   EXPECT_NE(albums->end(), album_2);
61   EXPECT_EQ("Album 2 Name", album_2->second.name);
62   EXPECT_EQ(base::FilePath(), album_2->second.path);
63   EXPECT_EQ("uid5", album_2->second.uid);
64 }
65
66 void VerifyTestAlbumsImagesIndex(PicasaDataProvider* data_provider,
67                                  base::FilePath test_folder_1_path,
68                                  base::FilePath test_folder_2_path) {
69   base::File::Error error;
70   scoped_ptr<AlbumImages> album_1_images =
71       data_provider->FindAlbumImages("uid3", &error);
72   ASSERT_TRUE(album_1_images);
73   EXPECT_EQ(base::File::FILE_OK, error);
74   EXPECT_EQ(2u, album_1_images->size());
75   EXPECT_NE(album_1_images->end(), album_1_images->find("InBoth.jpg"));
76   EXPECT_EQ(test_folder_1_path.AppendASCII("InBoth.jpg"),
77             (*album_1_images)["InBoth.jpg"]);
78   EXPECT_NE(album_1_images->end(),
79             album_1_images->find("InFirstAlbumOnly.jpg"));
80   EXPECT_EQ(test_folder_2_path.AppendASCII("InFirstAlbumOnly.jpg"),
81             (*album_1_images)["InFirstAlbumOnly.jpg"]);
82
83   scoped_ptr<AlbumImages> album_2_images =
84       data_provider->FindAlbumImages("uid5", &error);
85   ASSERT_TRUE(album_2_images);
86   EXPECT_EQ(base::File::FILE_OK, error);
87   EXPECT_EQ(2u, album_2_images->size());
88   EXPECT_NE(album_2_images->end(), album_2_images->find("InBoth.jpg"));
89   EXPECT_EQ(test_folder_1_path.AppendASCII("InBoth.jpg"),
90             (*album_2_images)["InBoth.jpg"]);
91   EXPECT_NE(album_2_images->end(),
92             album_2_images->find("InSecondAlbumOnly.jpg"));
93   EXPECT_EQ(test_folder_1_path.AppendASCII("InSecondAlbumOnly.jpg"),
94             (*album_2_images)["InSecondAlbumOnly.jpg"]);
95 }
96
97 }  // namespace
98
99 class TestPicasaDataProvider : public PicasaDataProvider {
100  public:
101   explicit TestPicasaDataProvider(const base::FilePath& database_path)
102       : PicasaDataProvider(database_path),
103         file_watch_request_returned_(false)  {
104   }
105
106   virtual ~TestPicasaDataProvider() {}
107
108   // |ready_callback| called with true if and when the file watch is started
109   // successfully. If the file watch fails, it's called with false.
110   void EnsureFileWatchStartedForTesting(const ReadyCallback& ready_callback) {
111     if (!file_watch_request_returned_) {
112       file_watch_started_callbacks_.push_back(ready_callback);
113       return;
114     }
115     ready_callback.Run(temp_dir_watcher_.get() != NULL);
116   }
117
118   // Simulates the actual writing process of moving all the database files
119   // from the temporary directory to the database directory in a loop.
120   void MoveTempFilesToDatabase() {
121     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
122
123     base::FileEnumerator file_enumerator(
124         database_path_.DirName().AppendASCII(kPicasaTempDirName),
125         false /* recursive */,
126         base::FileEnumerator::FILES);
127
128     for (base::FilePath src_path = file_enumerator.Next(); !src_path.empty();
129          src_path = file_enumerator.Next()) {
130       ASSERT_TRUE(
131           base::Move(src_path, database_path_.Append(src_path.BaseName())));
132     }
133   }
134
135   void SetInvalidateCallback(const base::Closure& callback) {
136     DCHECK(invalidate_callback_.is_null());
137     invalidate_callback_ = callback;
138   }
139
140   virtual void InvalidateData() OVERRIDE {
141     PicasaDataProvider::InvalidateData();
142
143     if (!invalidate_callback_.is_null()) {
144       invalidate_callback_.Run();
145       invalidate_callback_.Reset();
146     }
147   }
148
149   void SetAlbumMapsForTesting(const AlbumMap& album_map,
150                               const AlbumMap& folder_map) {
151     album_map_ = album_map;
152     folder_map_ = folder_map;
153   }
154
155  private:
156   virtual void OnTempDirWatchStarted(
157       scoped_ptr<base::FilePathWatcher> temp_dir_watcher) OVERRIDE {
158     PicasaDataProvider::OnTempDirWatchStarted(temp_dir_watcher.Pass());
159
160     file_watch_request_returned_ = true;
161     for (std::vector<ReadyCallback>::const_iterator it =
162              file_watch_started_callbacks_.begin();
163          it != file_watch_started_callbacks_.end();
164          ++it) {
165       it->Run(temp_dir_watcher_.get() != NULL);
166     }
167     file_watch_started_callbacks_.clear();
168   }
169
170   // Used for test that utilizes file watch
171   bool file_watch_request_returned_;
172   std::vector<ReadyCallback> file_watch_started_callbacks_;
173
174   base::Closure invalidate_callback_;
175 };
176
177 class PicasaDataProviderTest : public InProcessBrowserTest {
178  public:
179   PicasaDataProviderTest() {}
180   virtual ~PicasaDataProviderTest() {}
181
182  protected:
183   // Runs on the MediaTaskRunner and designed to be overridden by subclasses.
184   virtual void InitializeTestData() {}
185
186   void RunTest() {
187     DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
188     base::RunLoop loop;
189     quit_closure_ = loop.QuitClosure();
190     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
191         FROM_HERE,
192         base::Bind(&PicasaDataProviderTest::SetupFoldersAndDataProvider,
193                    base::Unretained(this)));
194     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
195         FROM_HERE,
196         base::Bind(&PicasaDataProviderTest::InitializeTestData,
197                    base::Unretained(this)));
198     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
199         FROM_HERE,
200         base::Bind(&PicasaDataProviderTest::StartTestOnMediaTaskRunner,
201                    base::Unretained(this)));
202     loop.Run();
203   }
204
205   virtual PicasaDataProvider::DataType RequestedDataType() const = 0;
206
207   // Start the test. The data provider is refreshed before calling StartTest
208   // and the result of the refresh is passed in.
209   virtual void VerifyRefreshResults(bool parse_success) {};
210
211   void TestDone() {
212     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
213
214     // The data provider must be destructed on the MediaTaskRunner. This is done
215     // in a posted task rather than directly because TestDone is called by
216     // PicasaDataProvider. The callee should not destroy the caller.
217     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
218         FROM_HERE,
219         base::Bind(&PicasaDataProviderTest::DestructDataProviderThenQuit,
220                    base::Unretained(this)));
221   }
222
223   const base::FilePath& test_folder_1_path() { return test_folder_1_.path(); }
224   const base::FilePath& test_folder_2_path() { return test_folder_2_.path(); }
225
226   TestPicasaDataProvider* data_provider() const {
227     return picasa_data_provider_.get();
228   }
229
230   const base::FilePath GetTempDirPath() const {
231     return picasa_root_dir_.path().AppendASCII(kPicasaTempDirName);
232   }
233
234   virtual base::FilePath GetColumnFileDestination() const {
235     return picasa_root_dir_.path().AppendASCII(kPicasaDatabaseDirName);
236   }
237
238  private:
239   void SetupFoldersAndDataProvider() {
240     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
241     ASSERT_TRUE(test_folder_1_.CreateUniqueTempDir());
242     ASSERT_TRUE(test_folder_2_.CreateUniqueTempDir());
243     ASSERT_TRUE(picasa_root_dir_.CreateUniqueTempDir());
244     ASSERT_TRUE(base::CreateDirectory(
245         picasa_root_dir_.path().AppendASCII(kPicasaDatabaseDirName)));
246     ASSERT_TRUE(base::CreateDirectory(
247         picasa_root_dir_.path().AppendASCII(kPicasaTempDirName)));
248
249     picasa_data_provider_.reset(new TestPicasaDataProvider(
250         picasa_root_dir_.path().AppendASCII(kPicasaDatabaseDirName)));
251   }
252
253   virtual void StartTestOnMediaTaskRunner() {
254     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
255
256     data_provider()->RefreshData(
257         RequestedDataType(),
258         base::Bind(&PicasaDataProviderTest::VerifyRefreshResults,
259                    base::Unretained(this)));
260   }
261
262   void DestructDataProviderThenQuit() {
263     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
264     picasa_data_provider_.reset();
265     content::BrowserThread::PostTask(
266         content::BrowserThread::UI, FROM_HERE, quit_closure_);
267   }
268
269   base::ScopedTempDir test_folder_1_;
270   base::ScopedTempDir test_folder_2_;
271   base::ScopedTempDir picasa_root_dir_;
272
273   scoped_ptr<TestPicasaDataProvider> picasa_data_provider_;
274
275   base::Closure quit_closure_;
276
277   DISALLOW_COPY_AND_ASSIGN(PicasaDataProviderTest);
278 };
279
280 class PicasaDataProviderNoDatabaseGetListTest : public PicasaDataProviderTest {
281  protected:
282   virtual PicasaDataProvider::DataType RequestedDataType() const OVERRIDE {
283     return PicasaDataProvider::LIST_OF_ALBUMS_AND_FOLDERS_DATA;
284   }
285   virtual void VerifyRefreshResults(bool parse_success) OVERRIDE {
286     EXPECT_FALSE(parse_success);
287     TestDone();
288   }
289 };
290
291 IN_PROC_BROWSER_TEST_F(PicasaDataProviderNoDatabaseGetListTest,
292                        NoDatabaseGetList) {
293   RunTest();
294 }
295
296 class PicasaDataProviderNoDatabaseGetAlbumsImagesTest
297     : public PicasaDataProviderTest {
298  protected:
299   virtual PicasaDataProvider::DataType RequestedDataType() const OVERRIDE {
300     return PicasaDataProvider::ALBUMS_IMAGES_DATA;
301   }
302   virtual void VerifyRefreshResults(bool parse_success) OVERRIDE {
303     EXPECT_FALSE(parse_success);
304     TestDone();
305   }
306 };
307
308 IN_PROC_BROWSER_TEST_F(PicasaDataProviderNoDatabaseGetAlbumsImagesTest,
309                        NoDatabaseGetAlbumsImages) {
310   RunTest();
311 }
312
313 class PicasaDataProviderGetListTest : public PicasaDataProviderTest {
314  protected:
315   virtual void InitializeTestData() OVERRIDE {
316     WriteTestAlbumTable(GetColumnFileDestination(), test_folder_1_path(),
317                         test_folder_2_path());
318   }
319
320   virtual PicasaDataProvider::DataType RequestedDataType() const OVERRIDE {
321     return PicasaDataProvider::LIST_OF_ALBUMS_AND_FOLDERS_DATA;
322   }
323
324   virtual void VerifyRefreshResults(bool parse_success) OVERRIDE {
325     ASSERT_TRUE(parse_success);
326     VerifyTestAlbumTable(
327         data_provider(), test_folder_1_path(), test_folder_2_path());
328     TestDone();
329   }
330 };
331
332 IN_PROC_BROWSER_TEST_F(PicasaDataProviderGetListTest, GetListTest) {
333   RunTest();
334 }
335
336 class PicasaDataProviderGetAlbumsImagesTest : public PicasaDataProviderTest {
337  protected:
338   virtual void InitializeTestData() OVERRIDE {
339     WriteTestAlbumTable(GetColumnFileDestination(), test_folder_1_path(),
340                         test_folder_2_path());
341     WriteTestAlbumsImagesIndex(test_folder_1_path(), test_folder_2_path());
342   }
343
344   virtual PicasaDataProvider::DataType RequestedDataType() const OVERRIDE {
345     return PicasaDataProvider::ALBUMS_IMAGES_DATA;
346   }
347
348   virtual void VerifyRefreshResults(bool parse_success) OVERRIDE {
349     ASSERT_TRUE(parse_success);
350     VerifyTestAlbumTable(
351         data_provider(), test_folder_1_path(), test_folder_2_path());
352     VerifyTestAlbumsImagesIndex(
353         data_provider(), test_folder_1_path(), test_folder_2_path());
354     TestDone();
355   }
356 };
357
358 IN_PROC_BROWSER_TEST_F(PicasaDataProviderGetAlbumsImagesTest,
359                        GetAlbumsImagesTest) {
360   RunTest();
361 }
362
363 class PicasaDataProviderMultipleMixedCallbacksTest
364     : public PicasaDataProviderTest {
365  public:
366   PicasaDataProviderMultipleMixedCallbacksTest()
367       : list_callbacks_called_(0), albums_images_callbacks_called_(0) {}
368
369   virtual void InitializeTestData() OVERRIDE {
370     WriteTestAlbumTable(GetColumnFileDestination(), test_folder_1_path(),
371                         test_folder_2_path());
372     WriteTestAlbumsImagesIndex(test_folder_1_path(), test_folder_2_path());
373   }
374
375   virtual PicasaDataProvider::DataType RequestedDataType() const OVERRIDE {
376     return PicasaDataProvider::ALBUMS_IMAGES_DATA;
377   }
378
379  protected:
380   virtual void ListCallback(int expected_list_callbacks_called,
381                             bool parse_success) {
382     ASSERT_TRUE(parse_success);
383     ASSERT_EQ(expected_list_callbacks_called, ++list_callbacks_called_);
384     VerifyTestAlbumTable(
385         data_provider(), test_folder_1_path(), test_folder_2_path());
386     CheckTestDone();
387   }
388
389   virtual void AlbumsImagesCallback(int expected_albums_images_callbacks_called,
390                                     bool parse_success) {
391     ASSERT_TRUE(parse_success);
392     ASSERT_EQ(expected_albums_images_callbacks_called,
393               ++albums_images_callbacks_called_);
394     VerifyTestAlbumsImagesIndex(
395         data_provider(), test_folder_1_path(), test_folder_2_path());
396     CheckTestDone();
397   }
398
399  private:
400   void CheckTestDone() {
401     ASSERT_LE(list_callbacks_called_, 2);
402     ASSERT_LE(albums_images_callbacks_called_, 2);
403     if (list_callbacks_called_ == 2 && albums_images_callbacks_called_ == 2)
404       TestDone();
405   }
406
407   virtual void StartTestOnMediaTaskRunner() OVERRIDE {
408     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
409
410     data_provider()->RefreshData(
411         PicasaDataProvider::LIST_OF_ALBUMS_AND_FOLDERS_DATA,
412         base::Bind(&PicasaDataProviderMultipleMixedCallbacksTest::ListCallback,
413                    base::Unretained(this),
414                    1));
415     data_provider()->RefreshData(
416         PicasaDataProvider::ALBUMS_IMAGES_DATA,
417         base::Bind(
418             &PicasaDataProviderMultipleMixedCallbacksTest::AlbumsImagesCallback,
419             base::Unretained(this),
420             1));
421     data_provider()->RefreshData(
422         PicasaDataProvider::LIST_OF_ALBUMS_AND_FOLDERS_DATA,
423         base::Bind(&PicasaDataProviderMultipleMixedCallbacksTest::ListCallback,
424                    base::Unretained(this),
425                    2));
426     data_provider()->RefreshData(
427         PicasaDataProvider::ALBUMS_IMAGES_DATA,
428         base::Bind(
429             &PicasaDataProviderMultipleMixedCallbacksTest::AlbumsImagesCallback,
430             base::Unretained(this),
431             2));
432   }
433
434   int list_callbacks_called_;
435   int albums_images_callbacks_called_;
436 };
437
438 IN_PROC_BROWSER_TEST_F(PicasaDataProviderMultipleMixedCallbacksTest,
439                        MultipleMixedCallbacks) {
440   RunTest();
441 }
442
443 class PicasaDataProviderFileWatcherInvalidateTest
444     : public PicasaDataProviderGetListTest {
445  protected:
446   virtual void ListCallback(bool parse_success) {
447     ASSERT_FALSE(parse_success);
448     data_provider()->EnsureFileWatchStartedForTesting(
449         base::Bind(&PicasaDataProviderFileWatcherInvalidateTest::
450                        OnPicasaTempDirWatchStarted,
451                    base::Unretained(this)));
452   }
453
454   void OnPicasaTempDirWatchStarted(bool file_watch_successful) {
455     ASSERT_TRUE(file_watch_successful);
456
457     // Validate the list after the file move triggers an invalidate.
458     data_provider()->SetInvalidateCallback(base::Bind(
459         &PicasaDataProvider::RefreshData,
460         base::Unretained(data_provider()),
461         RequestedDataType(),
462         base::Bind(
463             &PicasaDataProviderFileWatcherInvalidateTest::VerifyRefreshResults,
464             base::Unretained(this))));
465
466     data_provider()->MoveTempFilesToDatabase();
467   }
468
469   virtual base::FilePath GetColumnFileDestination() const OVERRIDE {
470     return GetTempDirPath();
471   }
472
473  private:
474   virtual void StartTestOnMediaTaskRunner() OVERRIDE {
475     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
476
477     // Refresh before moving album table to database dir, guaranteeing failure.
478     data_provider()->RefreshData(
479         RequestedDataType(),
480         base::Bind(
481             &PicasaDataProviderFileWatcherInvalidateTest::ListCallback,
482             base::Unretained(this)));
483   }
484 };
485
486 IN_PROC_BROWSER_TEST_F(PicasaDataProviderFileWatcherInvalidateTest,
487                        FileWatcherInvalidateTest) {
488   RunTest();
489 }
490
491 class PicasaDataProviderInvalidateInflightTableReaderTest
492     : public PicasaDataProviderGetListTest {
493  protected:
494   // Don't write the database files until later.
495   virtual void InitializeTestData() OVERRIDE {}
496
497  private:
498   virtual void StartTestOnMediaTaskRunner() OVERRIDE {
499     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
500
501     // Refresh before the database files have been written.
502     // This is guaranteed to fail to read the album table.
503     data_provider()->RefreshData(
504         RequestedDataType(),
505         base::Bind(&PicasaDataProviderInvalidateInflightTableReaderTest::
506                        VerifyRefreshResults,
507                    base::Unretained(this)));
508
509     // Now write the album table and invalidate the inflight table reader.
510     PicasaDataProviderGetListTest::InitializeTestData();
511     data_provider()->InvalidateData();
512
513     // VerifyRefreshResults callback should receive correct results now.
514   }
515 };
516
517 IN_PROC_BROWSER_TEST_F(PicasaDataProviderInvalidateInflightTableReaderTest,
518                        InvalidateInflightTableReaderTest) {
519   RunTest();
520 }
521
522 class PicasaDataProviderInvalidateInflightAlbumsIndexerTest
523     : public PicasaDataProviderGetAlbumsImagesTest {
524  protected:
525   virtual void ListCallback(bool parse_success) {
526     ASSERT_TRUE(parse_success);
527
528     // Empty the album maps to guarantee that the first utility process will
529     // fail to get the correct albums-images index.
530     data_provider()->SetAlbumMapsForTesting(AlbumMap(), AlbumMap());
531     data_provider()->RefreshData(
532         PicasaDataProvider::ALBUMS_IMAGES_DATA,
533         base::Bind(&PicasaDataProviderInvalidateInflightAlbumsIndexerTest::
534                        VerifyRefreshResults,
535                    base::Unretained(this)));
536
537     // Now invalidate all the data. The album maps will be re-read.
538     data_provider()->InvalidateData();
539
540     // VerifyRefreshResults callback should receive correct results now.
541   }
542
543  private:
544   virtual void StartTestOnMediaTaskRunner() OVERRIDE {
545     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
546
547     data_provider()->RefreshData(
548         PicasaDataProvider::LIST_OF_ALBUMS_AND_FOLDERS_DATA,
549         base::Bind(&PicasaDataProviderInvalidateInflightAlbumsIndexerTest::
550                        ListCallback,
551                    base::Unretained(this)));
552   }
553 };
554
555 IN_PROC_BROWSER_TEST_F(PicasaDataProviderInvalidateInflightAlbumsIndexerTest,
556                        InvalidateInflightAlbumsIndexerTest) {
557   RunTest();
558 }
559
560 }  // namespace picasa