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.
5 #include "net/ftp/ftp_directory_listing_parser.h"
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/string_util.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "net/base/net_errors.h"
16 #include "net/ftp/ftp_directory_listing_parser.h"
17 #include "testing/gtest/include/gtest/gtest.h"
25 Error expected_result
;
28 std::string
TestName(testing::TestParamInfo
<FtpTestParam
> info
) {
30 base::ReplaceChars(info
.param
.name
, "-", "_", &result
);
34 class FtpDirectoryListingParserTest
35 : public testing::TestWithParam
<FtpTestParam
> {};
37 TEST_P(FtpDirectoryListingParserTest
, Parse
) {
38 FtpTestParam param
= GetParam();
39 base::FilePath test_dir
;
40 PathService::Get(base::DIR_SOURCE_ROOT
, &test_dir
);
41 test_dir
= test_dir
.AppendASCII("net");
42 test_dir
= test_dir
.AppendASCII("data");
43 test_dir
= test_dir
.AppendASCII("ftp");
45 base::Time::Exploded mock_current_time_exploded
= { 0 };
46 mock_current_time_exploded
.year
= 1994;
47 mock_current_time_exploded
.month
= 11;
48 mock_current_time_exploded
.day_of_month
= 15;
49 mock_current_time_exploded
.hour
= 12;
50 mock_current_time_exploded
.minute
= 45;
51 base::Time
mock_current_time(
52 base::Time::FromLocalExploded(mock_current_time_exploded
));
54 SCOPED_TRACE(base::StringPrintf("Test case: %s", param
.name
));
56 std::string test_listing
;
58 base::ReadFileToString(test_dir
.AppendASCII(param
.name
), &test_listing
));
60 std::vector
<FtpDirectoryListingEntry
> entries
;
62 param
.expected_result
,
63 ParseFtpDirectoryListing(test_listing
, mock_current_time
, &entries
));
64 if (param
.expected_result
!= OK
)
67 std::string expected_listing
;
68 ASSERT_TRUE(base::ReadFileToString(
69 test_dir
.AppendASCII(std::string(param
.name
) + ".expected"),
72 std::vector
<std::string
> lines
;
73 base::SplitStringUsingSubstr(expected_listing
, "\r\n", &lines
);
75 // Special case for empty listings.
76 if (lines
.size() == 1 && lines
[0].empty())
79 ASSERT_EQ(9 * entries
.size(), lines
.size());
81 for (size_t i
= 0; i
< lines
.size() / 9; i
++) {
82 std::string
type(lines
[9 * i
]);
83 std::string
name(lines
[9 * i
+ 1]);
85 base::StringToInt64(lines
[9 * i
+ 2], &size
);
87 SCOPED_TRACE(base::StringPrintf("Filename: %s", name
.c_str()));
89 int year
, month
, day_of_month
, hour
, minute
;
90 base::StringToInt(lines
[9 * i
+ 3], &year
);
91 base::StringToInt(lines
[9 * i
+ 4], &month
);
92 base::StringToInt(lines
[9 * i
+ 5], &day_of_month
);
93 base::StringToInt(lines
[9 * i
+ 6], &hour
);
94 base::StringToInt(lines
[9 * i
+ 7], &minute
);
96 const FtpDirectoryListingEntry
& entry
= entries
[i
];
99 EXPECT_EQ(FtpDirectoryListingEntry::DIRECTORY
, entry
.type
);
100 } else if (type
== "-") {
101 EXPECT_EQ(FtpDirectoryListingEntry::FILE, entry
.type
);
102 } else if (type
== "l") {
103 EXPECT_EQ(FtpDirectoryListingEntry::SYMLINK
, entry
.type
);
105 ADD_FAILURE() << "invalid gold test data: " << type
;
108 EXPECT_EQ(base::UTF8ToUTF16(name
), entry
.name
);
109 EXPECT_EQ(size
, entry
.size
);
111 base::Time::Exploded time_exploded
;
112 entry
.last_modified
.LocalExplode(&time_exploded
);
113 EXPECT_EQ(year
, time_exploded
.year
);
114 EXPECT_EQ(month
, time_exploded
.month
);
115 EXPECT_EQ(day_of_month
, time_exploded
.day_of_month
);
116 EXPECT_EQ(hour
, time_exploded
.hour
);
117 EXPECT_EQ(minute
, time_exploded
.minute
);
121 const FtpTestParam kTestParams
[] = {
122 {"dir-listing-ls-1", OK
},
123 {"dir-listing-ls-1-utf8", OK
},
124 {"dir-listing-ls-2", OK
},
125 {"dir-listing-ls-3", OK
},
126 {"dir-listing-ls-4", OK
},
127 {"dir-listing-ls-5", OK
},
128 {"dir-listing-ls-6", OK
},
129 {"dir-listing-ls-7", OK
},
130 {"dir-listing-ls-8", OK
},
131 {"dir-listing-ls-9", OK
},
132 {"dir-listing-ls-10", OK
},
133 {"dir-listing-ls-11", OK
},
134 {"dir-listing-ls-12", OK
},
135 {"dir-listing-ls-13", OK
},
136 {"dir-listing-ls-14", OK
},
137 {"dir-listing-ls-15", OK
},
138 {"dir-listing-ls-16", OK
},
139 {"dir-listing-ls-17", OK
},
140 {"dir-listing-ls-18", OK
},
141 {"dir-listing-ls-19", OK
},
142 {"dir-listing-ls-20", OK
},
143 {"dir-listing-ls-21", OK
},
144 {"dir-listing-ls-22", OK
},
145 {"dir-listing-ls-23", OK
},
146 {"dir-listing-ls-24", OK
},
148 // Tests for Russian listings. The only difference between those
149 // files is character encoding:
150 {"dir-listing-ls-25", OK
}, // UTF-8
151 {"dir-listing-ls-26", OK
}, // KOI8-R
152 {"dir-listing-ls-27", OK
}, // windows-1251
154 {"dir-listing-ls-28", OK
}, // Hylafax FTP server
155 {"dir-listing-ls-29", OK
},
156 {"dir-listing-ls-30", OK
},
157 {"dir-listing-ls-31", OK
},
158 {"dir-listing-ls-32", OK
}, // busybox
160 {"dir-listing-netware-1", OK
},
161 {"dir-listing-netware-2", OK
},
162 {"dir-listing-netware-3", OK
},
163 {"dir-listing-os2-1", ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT
},
164 {"dir-listing-vms-1", OK
},
165 {"dir-listing-vms-2", OK
},
166 {"dir-listing-vms-3", OK
},
167 {"dir-listing-vms-4", OK
},
168 {"dir-listing-vms-5", OK
},
169 {"dir-listing-vms-6", OK
},
170 {"dir-listing-vms-7", OK
},
171 {"dir-listing-vms-8", OK
},
172 {"dir-listing-windows-1", OK
},
173 {"dir-listing-windows-2", OK
},
176 INSTANTIATE_TEST_CASE_P(,
177 FtpDirectoryListingParserTest
,
178 testing::ValuesIn(kTestParams
),