15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <list> 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <utility> 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/file_util_icu.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/directory_lister.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/platform_test.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListerDelegate : public DirectoryLister::DirectoryListerDelegate { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListerDelegate(bool recursive, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool quit_loop_after_each_file) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : error_(-1), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recursive_(recursive), 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_loop_after_each_file_(quit_loop_after_each_file) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnListFile( 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DirectoryLister::DirectoryListerData& data) OVERRIDE { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_list_.push_back(data.info); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paths_.push_back(data.path); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quit_loop_after_each_file_) 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnListDone(int error) OVERRIDE { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = error; 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (recursive_) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckRecursiveSort(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckSort(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CheckRecursiveSort() { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that we got files in the right order. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_list_.empty()) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t previous = 0, current = 1; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current < file_list_.size(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous++, current++) { 536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(base::i18n::LocaleAwareCompareFilenames( 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paths_[previous], paths_[current])); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CheckSort() { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that we got files in the right order. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_list_.empty()) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t previous = 0, current = 1; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current < file_list_.size(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous++, current++) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Directories should come before files. 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (file_list_[previous].IsDirectory() && 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !file_list_[current].IsDirectory()) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_NE(FILE_PATH_LITERAL(".."), 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_list_[current].GetName().BaseName().value()); 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(file_list_[previous].IsDirectory(), 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_list_[current].IsDirectory()); 746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(base::i18n::LocaleAwareCompareFilenames( 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_list_[previous].GetName(), 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_list_[current].GetName())); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error() const { return error_; } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_files() const { return file_list_.size(); } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool recursive_; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool quit_loop_after_each_file_; 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<base::FileEnumerator::FileInfo> file_list_; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath> paths_; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DirectoryListerTest : public PlatformTest { 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() OVERRIDE { 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int kMaxDepth = 3; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int kBranchingFactor = 4; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int kFilesPerDirectory = 5; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Randomly create a directory structure of depth 3 in a temporary root 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // directory. 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::list<std::pair<base::FilePath, int> > directories; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(temp_root_dir_.CreateUniqueTempDir()); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directories.push_back(std::make_pair(temp_root_dir_.path(), 0)); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (!directories.empty()) { 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::pair<base::FilePath, int> dir_data = directories.front(); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directories.pop_front(); 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int i = 0; i < kFilesPerDirectory; i++) { 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string file_name = base::StringPrintf("file_id_%d", i); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath file_path = dir_data.first.AppendASCII(file_name); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File file(file_path, 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::FLAG_CREATE | base::File::FLAG_WRITE); 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(file.IsValid()); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (dir_data.second < kMaxDepth - 1) { 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int i = 0; i < kBranchingFactor; i++) { 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string dir_name = base::StringPrintf("child_dir_%d", i); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath dir_path = dir_data.first.AppendASCII(dir_name); 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(base::CreateDirectory(dir_path)); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) directories.push_back(std::make_pair(dir_path, dir_data.second + 1)); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PlatformTest::SetUp(); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& root_path() const { 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return temp_root_dir_.path(); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ScopedTempDir temp_root_dir_; 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(DirectoryListerTest, BigDirTest) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListerDelegate delegate(false, false); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DirectoryLister lister(root_path(), &delegate); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lister.Start(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, delegate.error()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(DirectoryListerTest, BigDirRecursiveTest) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListerDelegate delegate(true, false); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DirectoryLister lister(root_path(), true, DirectoryLister::FULL_PATH, 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &delegate); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lister.Start(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, delegate.error()); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(DirectoryListerTest, CancelTest) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListerDelegate delegate(false, true); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DirectoryLister lister(root_path(), &delegate); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lister.Start(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_files = delegate.num_files(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lister.Cancel(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(num_files, delegate.num_files()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(DirectoryListerTest, EmptyDirTest) { 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ScopedTempDir tempDir; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(tempDir.CreateUniqueTempDir()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool kRecursive = false; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool kQuitLoopAfterEachFile = false; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListerDelegate delegate(kRecursive, kQuitLoopAfterEachFile); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DirectoryLister lister(tempDir.path(), &delegate); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lister.Start(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Contains only the parent directory ("..") 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, delegate.num_files()); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(OK, delegate.error()); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 191