1// Copyright (c) 2012 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 "net/ftp/ftp_directory_listing_parser.h" 6 7#include "base/files/file_util.h" 8#include "base/format_macros.h" 9#include "base/path_service.h" 10#include "base/strings/string_number_conversions.h" 11#include "base/strings/string_split.h" 12#include "base/strings/stringprintf.h" 13#include "base/strings/utf_string_conversions.h" 14#include "net/base/net_errors.h" 15#include "net/ftp/ftp_directory_listing_parser.h" 16#include "testing/gtest/include/gtest/gtest.h" 17 18namespace net { 19 20namespace { 21 22class FtpDirectoryListingParserTest 23 : public testing::TestWithParam<const char*> { 24}; 25 26TEST_P(FtpDirectoryListingParserTest, Parse) { 27 base::FilePath test_dir; 28 PathService::Get(base::DIR_SOURCE_ROOT, &test_dir); 29 test_dir = test_dir.AppendASCII("net"); 30 test_dir = test_dir.AppendASCII("data"); 31 test_dir = test_dir.AppendASCII("ftp"); 32 33 base::Time::Exploded mock_current_time_exploded = { 0 }; 34 mock_current_time_exploded.year = 1994; 35 mock_current_time_exploded.month = 11; 36 mock_current_time_exploded.day_of_month = 15; 37 mock_current_time_exploded.hour = 12; 38 mock_current_time_exploded.minute = 45; 39 base::Time mock_current_time( 40 base::Time::FromLocalExploded(mock_current_time_exploded)); 41 42 SCOPED_TRACE(base::StringPrintf("Test case: %s", GetParam())); 43 44 std::string test_listing; 45 EXPECT_TRUE(base::ReadFileToString(test_dir.AppendASCII(GetParam()), 46 &test_listing)); 47 48 std::vector<FtpDirectoryListingEntry> entries; 49 EXPECT_EQ(OK, ParseFtpDirectoryListing(test_listing, 50 mock_current_time, 51 &entries)); 52 53 std::string expected_listing; 54 ASSERT_TRUE(base::ReadFileToString( 55 test_dir.AppendASCII(std::string(GetParam()) + ".expected"), 56 &expected_listing)); 57 58 std::vector<std::string> lines; 59 base::SplitStringUsingSubstr(expected_listing, "\r\n", &lines); 60 61 // Special case for empty listings. 62 if (lines.size() == 1 && lines[0].empty()) 63 lines.clear(); 64 65 ASSERT_EQ(9 * entries.size(), lines.size()); 66 67 for (size_t i = 0; i < lines.size() / 9; i++) { 68 std::string type(lines[9 * i]); 69 std::string name(lines[9 * i + 1]); 70 int64 size; 71 base::StringToInt64(lines[9 * i + 2], &size); 72 73 SCOPED_TRACE(base::StringPrintf("Filename: %s", name.c_str())); 74 75 int year, month, day_of_month, hour, minute; 76 base::StringToInt(lines[9 * i + 3], &year); 77 base::StringToInt(lines[9 * i + 4], &month); 78 base::StringToInt(lines[9 * i + 5], &day_of_month); 79 base::StringToInt(lines[9 * i + 6], &hour); 80 base::StringToInt(lines[9 * i + 7], &minute); 81 82 const FtpDirectoryListingEntry& entry = entries[i]; 83 84 if (type == "d") { 85 EXPECT_EQ(FtpDirectoryListingEntry::DIRECTORY, entry.type); 86 } else if (type == "-") { 87 EXPECT_EQ(FtpDirectoryListingEntry::FILE, entry.type); 88 } else if (type == "l") { 89 EXPECT_EQ(FtpDirectoryListingEntry::SYMLINK, entry.type); 90 } else { 91 ADD_FAILURE() << "invalid gold test data: " << type; 92 } 93 94 EXPECT_EQ(base::UTF8ToUTF16(name), entry.name); 95 EXPECT_EQ(size, entry.size); 96 97 base::Time::Exploded time_exploded; 98 entry.last_modified.LocalExplode(&time_exploded); 99 EXPECT_EQ(year, time_exploded.year); 100 EXPECT_EQ(month, time_exploded.month); 101 EXPECT_EQ(day_of_month, time_exploded.day_of_month); 102 EXPECT_EQ(hour, time_exploded.hour); 103 EXPECT_EQ(minute, time_exploded.minute); 104 } 105} 106 107const char* kTestFiles[] = { 108 "dir-listing-ls-1", 109 "dir-listing-ls-1-utf8", 110 "dir-listing-ls-2", 111 "dir-listing-ls-3", 112 "dir-listing-ls-4", 113 "dir-listing-ls-5", 114 "dir-listing-ls-6", 115 "dir-listing-ls-7", 116 "dir-listing-ls-8", 117 "dir-listing-ls-9", 118 "dir-listing-ls-10", 119 "dir-listing-ls-11", 120 "dir-listing-ls-12", 121 "dir-listing-ls-13", 122 "dir-listing-ls-14", 123 "dir-listing-ls-15", 124 "dir-listing-ls-16", 125 "dir-listing-ls-17", 126 "dir-listing-ls-18", 127 "dir-listing-ls-19", 128 "dir-listing-ls-20", // TODO(phajdan.jr): should use windows-1251 encoding. 129 "dir-listing-ls-21", // TODO(phajdan.jr): should use windows-1251 encoding. 130 "dir-listing-ls-22", // TODO(phajdan.jr): should use windows-1251 encoding. 131 "dir-listing-ls-23", 132 "dir-listing-ls-24", 133 134 // Tests for Russian listings. The only difference between those 135 // files is character encoding: 136 "dir-listing-ls-25", // UTF-8 137 "dir-listing-ls-26", // KOI8-R 138 "dir-listing-ls-27", // windows-1251 139 140 "dir-listing-ls-28", // Hylafax FTP server 141 "dir-listing-ls-29", 142 "dir-listing-ls-30", 143 "dir-listing-ls-31", 144 "dir-listing-ls-32", // busybox 145 146 "dir-listing-netware-1", 147 "dir-listing-netware-2", 148 "dir-listing-netware-3", // Spaces in file names. 149 "dir-listing-os2-1", 150 "dir-listing-vms-1", 151 "dir-listing-vms-2", 152 "dir-listing-vms-3", 153 "dir-listing-vms-4", 154 "dir-listing-vms-5", 155 "dir-listing-vms-6", 156 "dir-listing-vms-7", 157 "dir-listing-vms-8", 158 "dir-listing-windows-1", 159 "dir-listing-windows-2", 160}; 161 162INSTANTIATE_TEST_CASE_P(, FtpDirectoryListingParserTest, 163 testing::ValuesIn(kTestFiles)); 164 165} // namespace 166 167} // namespace net 168