1 // Copyright 2015 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 "components/test_runner/test_info_extractor.h"
9 #include "base/base_paths.h"
10 #include "base/files/file_util.h"
11 #include "base/path_service.h"
12 #include "base/strings/sys_string_conversions.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/threading/thread_restrictions.h"
15 #include "net/base/filename_util.h"
17 namespace test_runner
{
21 #if defined(OS_ANDROID)
22 // On Android, all passed tests will be paths to a local temporary directory.
23 // However, because we can't transfer all test files to the device, translate
24 // those paths to a local, forwarded URL so the host can serve them.
25 bool GetTestUrlForAndroid(std::string
& path_or_url
, GURL
* url
) {
26 // Path to search for when translating a layout test path to an URL.
27 const char kAndroidLayoutTestPath
[] =
28 "/data/local/tmp/third_party/WebKit/LayoutTests/";
29 // The base URL from which layout tests are being served on Android.
30 const char kAndroidLayoutTestBase
[] = "http://127.0.0.1:8000/all-tests/";
32 if (path_or_url
.find(kAndroidLayoutTestPath
) == std::string::npos
)
35 std::string
test_location(kAndroidLayoutTestBase
);
36 test_location
.append(path_or_url
.substr(strlen(kAndroidLayoutTestPath
)));
38 *url
= GURL(test_location
);
41 #endif // defined(OS_ANDROID)
43 scoped_ptr
<TestInfo
> GetTestInfoFromLayoutTestName(
44 const std::string
& test_name
) {
45 // A test name is formated like file:///path/to/test'--pixel-test'pixelhash
46 std::string path_or_url
= test_name
;
47 std::string pixel_switch
;
48 std::string::size_type separator_position
= path_or_url
.find('\'');
49 if (separator_position
!= std::string::npos
) {
50 pixel_switch
= path_or_url
.substr(separator_position
+ 1);
51 path_or_url
.erase(separator_position
);
53 separator_position
= pixel_switch
.find('\'');
54 std::string expected_pixel_hash
;
55 if (separator_position
!= std::string::npos
) {
56 expected_pixel_hash
= pixel_switch
.substr(separator_position
+ 1);
57 pixel_switch
.erase(separator_position
);
59 const bool enable_pixel_dumping
=
60 (pixel_switch
== "--pixel-test" || pixel_switch
== "-p");
63 #if defined(OS_ANDROID)
64 if (GetTestUrlForAndroid(path_or_url
, &test_url
)) {
65 return make_scoped_ptr(new TestInfo(test_url
, enable_pixel_dumping
,
66 expected_pixel_hash
, base::FilePath()));
70 test_url
= GURL(path_or_url
);
71 if (!(test_url
.is_valid() && test_url
.has_scheme())) {
72 // We're outside of the message loop here, and this is a test.
73 base::ThreadRestrictions::ScopedAllowIO allow_io
;
75 base::FilePath::StringType wide_path_or_url
=
76 base::SysNativeMBToWide(path_or_url
);
77 base::FilePath
local_file(wide_path_or_url
);
79 base::FilePath
local_file(path_or_url
);
81 if (!base::PathExists(local_file
)) {
82 base::FilePath base_path
;
83 PathService::Get(base::DIR_SOURCE_ROOT
, &base_path
);
84 local_file
= base_path
.Append(FILE_PATH_LITERAL("third_party"))
85 .Append(FILE_PATH_LITERAL("WebKit"))
86 .Append(FILE_PATH_LITERAL("LayoutTests"))
89 test_url
= net::FilePathToFileURL(base::MakeAbsoluteFilePath(local_file
));
91 base::FilePath local_path
;
92 base::FilePath current_working_directory
;
94 // We're outside of the message loop here, and this is a test.
95 base::ThreadRestrictions::ScopedAllowIO allow_io
;
96 if (net::FileURLToFilePath(test_url
, &local_path
))
97 current_working_directory
= local_path
.DirName();
99 base::GetCurrentDirectory(¤t_working_directory
);
100 return make_scoped_ptr(new TestInfo(test_url
, enable_pixel_dumping
,
102 current_working_directory
));
107 TestInfo::TestInfo(const GURL
& url
,
108 bool enable_pixel_dumping
,
109 const std::string
& expected_pixel_hash
,
110 const base::FilePath
& current_working_directory
)
112 enable_pixel_dumping(enable_pixel_dumping
),
113 expected_pixel_hash(expected_pixel_hash
),
114 current_working_directory(current_working_directory
) {}
115 TestInfo::~TestInfo() {}
117 TestInfoExtractor::TestInfoExtractor(
118 const base::CommandLine::StringVector
& cmd_args
)
119 : cmdline_args_(cmd_args
), cmdline_position_(0) {}
121 TestInfoExtractor::~TestInfoExtractor() {}
123 scoped_ptr
<TestInfo
> TestInfoExtractor::GetNextTest() {
124 if (cmdline_position_
>= cmdline_args_
.size())
127 std::string test_string
;
128 if (cmdline_args_
[cmdline_position_
] == FILE_PATH_LITERAL("-")) {
130 bool success
= !!std::getline(std::cin
, test_string
, '\n');
133 } while (test_string
.empty());
136 test_string
= base::WideToUTF8(cmdline_args_
[cmdline_position_
++]);
138 test_string
= cmdline_args_
[cmdline_position_
++];
142 DCHECK(!test_string
.empty());
143 if (test_string
== "QUIT")
145 return GetTestInfoFromLayoutTestName(test_string
);
148 } // namespace test_runner