1 /*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "test/testsupport/file_utils_override.h"
12
13 #include <limits.h>
14 #include <stdio.h>
15
16 #if defined(WEBRTC_WIN)
17 #include <direct.h>
18 #include <tchar.h>
19 #include <windows.h>
20
21 #include <algorithm>
22 #include <codecvt>
23 #include <locale>
24
25 #include "Shlwapi.h"
26 #include "WinDef.h"
27 #include "rtc_base/win32.h"
28
29 #define GET_CURRENT_DIR _getcwd
30 #else
31 #include <unistd.h>
32
33 #define GET_CURRENT_DIR getcwd
34 #endif
35
36 #if defined(WEBRTC_IOS)
37 #include "test/testsupport/ios_file_utils.h"
38 #endif
39
40 #if defined(WEBRTC_MAC)
41 #include "test/testsupport/mac_file_utils.h"
42 #endif
43
44 #include "absl/types/optional.h"
45 #include "rtc_base/arraysize.h"
46 #include "rtc_base/checks.h"
47 #include "rtc_base/string_utils.h"
48
49 namespace webrtc {
50 namespace test {
51
52 std::string DirName(const std::string& path);
53 bool CreateDir(const std::string& directory_name);
54
55 namespace internal {
56
57 namespace {
58 #if defined(WEBRTC_WIN)
59 const char* kPathDelimiter = "\\";
60 #elif !defined(WEBRTC_IOS)
61 const char* kPathDelimiter = "/";
62 #endif
63
64 #if defined(WEBRTC_ANDROID)
65 // This is a special case in Chrome infrastructure. See
66 // base/test/test_support_android.cc.
67 const char* kAndroidChromiumTestsRoot = "/sdcard/chromium_tests_root/";
68 #endif
69
70 #if !defined(WEBRTC_IOS)
71 const char* kResourcesDirName = "resources";
72 #endif
73
74 } // namespace
75
76 // Finds the WebRTC src dir.
77 // The returned path always ends with a path separator.
ProjectRootPath()78 absl::optional<std::string> ProjectRootPath() {
79 #if defined(WEBRTC_ANDROID)
80 return kAndroidChromiumTestsRoot;
81 #elif defined WEBRTC_IOS
82 return IOSRootPath();
83 #elif defined(WEBRTC_MAC)
84 std::string path;
85 GetNSExecutablePath(&path);
86 std::string exe_dir = DirName(path);
87 // On Mac, tests execute in out/Whatever, so src is two levels up except if
88 // the test is bundled (which our tests are not), in which case it's 5 levels.
89 return DirName(DirName(exe_dir)) + kPathDelimiter;
90 #elif defined(WEBRTC_POSIX)
91 char buf[PATH_MAX];
92 ssize_t count = ::readlink("/proc/self/exe", buf, arraysize(buf));
93 if (count <= 0) {
94 RTC_NOTREACHED() << "Unable to resolve /proc/self/exe.";
95 return absl::nullopt;
96 }
97 // On POSIX, tests execute in out/Whatever, so src is two levels up.
98 std::string exe_dir = DirName(std::string(buf, count));
99 return DirName(DirName(exe_dir)) + kPathDelimiter;
100 #elif defined(WEBRTC_WIN)
101 wchar_t buf[MAX_PATH];
102 buf[0] = 0;
103 if (GetModuleFileNameW(NULL, buf, MAX_PATH) == 0)
104 return absl::nullopt;
105
106 std::string exe_path = rtc::ToUtf8(std::wstring(buf));
107 std::string exe_dir = DirName(exe_path);
108 return DirName(DirName(exe_dir)) + kPathDelimiter;
109 #endif
110 }
111
OutputPath()112 std::string OutputPath() {
113 #if defined(WEBRTC_IOS)
114 return IOSOutputPath();
115 #elif defined(WEBRTC_ANDROID)
116 return kAndroidChromiumTestsRoot;
117 #else
118 absl::optional<std::string> path_opt = ProjectRootPath();
119 RTC_DCHECK(path_opt);
120 std::string path = *path_opt + "out";
121 if (!CreateDir(path)) {
122 return "./";
123 }
124 return path + kPathDelimiter;
125 #endif
126 }
127
WorkingDir()128 std::string WorkingDir() {
129 #if defined(WEBRTC_ANDROID)
130 return kAndroidChromiumTestsRoot;
131 #else
132 char path_buffer[FILENAME_MAX];
133 if (!GET_CURRENT_DIR(path_buffer, sizeof(path_buffer))) {
134 fprintf(stderr, "Cannot get current directory!\n");
135 return "./";
136 } else {
137 return std::string(path_buffer);
138 }
139 #endif
140 }
141
ResourcePath(const std::string & name,const std::string & extension)142 std::string ResourcePath(const std::string& name,
143 const std::string& extension) {
144 #if defined(WEBRTC_IOS)
145 return IOSResourcePath(name, extension);
146 #else
147 absl::optional<std::string> path_opt = ProjectRootPath();
148 RTC_DCHECK(path_opt);
149 std::string resources_path = *path_opt + kResourcesDirName + kPathDelimiter;
150 return resources_path + name + "." + extension;
151 #endif
152 }
153
154 } // namespace internal
155 } // namespace test
156 } // namespace webrtc
157