aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/py
diff options
context:
space:
mode:
authorGravatar Laszlo Csomor <laszlocsomor@google.com>2018-05-30 02:47:38 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-05-30 02:48:59 -0700
commit22f4bb9afa6a8454a15fbd21edbb69c4518fbbf2 (patch)
tree8bf36113542c4ae40e730e25b6a827401368d411 /src/test/py
parent2cbcde33478756d265a57e88c89732126f33879a (diff)
runfiles,cc: C++ runfiles library in @bazel_tools
Add the C++ runfiles library to @bazel_tools//tools/cpp/runfiles:runfiles. RELNOTES[NEW]: C++,runfiles: to access data-dependencies (runfiles) in C++ programs, use the runfiles library built into Bazel. For usage info, see https://github.com/bazelbuild/bazel/blob/master/tools/cpp/runfiles/runfiles.h Change-Id: I5057a9f477289eea7244c60105e77fc71652a817 Closes #5293. Change-Id: I90cba6fa4c6595c838ae42f9d2c17548c8387e5d PiperOrigin-RevId: 198531849
Diffstat (limited to 'src/test/py')
-rw-r--r--src/test/py/bazel/runfiles_test.py64
-rw-r--r--src/test/py/bazel/testdata/runfiles_test/bar/BUILD.mock7
-rw-r--r--src/test/py/bazel/testdata/runfiles_test/bar/bar-cc-data.txt1
-rw-r--r--src/test/py/bazel/testdata/runfiles_test/bar/bar.cc59
-rw-r--r--src/test/py/bazel/testdata/runfiles_test/foo/BUILD.mock20
-rw-r--r--src/test/py/bazel/testdata/runfiles_test/foo/Foo.java2
-rw-r--r--src/test/py/bazel/testdata/runfiles_test/foo/foo.cc170
-rw-r--r--src/test/py/bazel/testdata/runfiles_test/foo/foo.py2
-rwxr-xr-xsrc/test/py/bazel/testdata/runfiles_test/foo/foo.sh2
9 files changed, 301 insertions, 26 deletions
diff --git a/src/test/py/bazel/runfiles_test.py b/src/test/py/bazel/runfiles_test.py
index 86c40b9cbb..9131cd2072 100644
--- a/src/test/py/bazel/runfiles_test.py
+++ b/src/test/py/bazel/runfiles_test.py
@@ -32,20 +32,24 @@ class RunfilesTest(test_base.TestBase):
"\n".join(stderr))
def _AssertRunfilesLibraryInBazelToolsRepo(self, family, lang_name):
- for s, t, exe in [
- ("WORKSPACE.mock", "WORKSPACE", False),
- ("foo/BUILD.mock", "foo/BUILD", False),
- ("foo/foo.py", "foo/foo.py", True),
- ("foo/Foo.java", "foo/Foo.java", False),
- ("foo/foo.sh", "foo/foo.sh", True),
- ("foo/datadep/hello.txt", "foo/datadep/hello.txt", False),
- ("bar/BUILD.mock", "bar/BUILD", False),
- ("bar/bar.py", "bar/bar.py", True),
- ("bar/bar-py-data.txt", "bar/bar-py-data.txt", False),
- ("bar/Bar.java", "bar/Bar.java", False),
- ("bar/bar-java-data.txt", "bar/bar-java-data.txt", False),
- ("bar/bar.sh", "bar/bar.sh", True),
- ("bar/bar-sh-data.txt", "bar/bar-sh-data.txt", False)]:
+ for s, t, exe in [("WORKSPACE.mock", "WORKSPACE",
+ False), ("foo/BUILD.mock", "foo/BUILD",
+ False), ("foo/foo.py", "foo/foo.py", True),
+ ("foo/Foo.java", "foo/Foo.java",
+ False), ("foo/foo.sh", "foo/foo.sh",
+ True), ("foo/foo.cc", "foo/foo.cc", False),
+ ("foo/datadep/hello.txt", "foo/datadep/hello.txt",
+ False), ("bar/BUILD.mock", "bar/BUILD",
+ False), ("bar/bar.py", "bar/bar.py", True),
+ ("bar/bar-py-data.txt", "bar/bar-py-data.txt",
+ False), ("bar/Bar.java", "bar/Bar.java",
+ False), ("bar/bar-java-data.txt",
+ "bar/bar-java-data.txt", False),
+ ("bar/bar.sh", "bar/bar.sh",
+ True), ("bar/bar-sh-data.txt", "bar/bar-sh-data.txt",
+ False), ("bar/bar.cc", "bar/bar.cc",
+ False), ("bar/bar-cc-data.txt",
+ "bar/bar-cc-data.txt", False)]:
self.CopyFile(
self.Rlocation("io_bazel/src/test/py/bazel/testdata/runfiles_test/" +
s), t, exe)
@@ -54,7 +58,10 @@ class RunfilesTest(test_base.TestBase):
self.AssertExitCode(exit_code, 0, stderr)
bazel_bin = stdout[0]
- exit_code, _, stderr = self.RunBazel(["build", "//foo:runfiles-" + family])
+ exit_code, _, stderr = self.RunBazel([
+ "build", "--verbose_failures", "--experimental_shortened_obj_file_path",
+ "//foo:runfiles-" + family
+ ])
self.AssertExitCode(exit_code, 0, stderr)
if test_base.TestBase.IsWindows():
@@ -67,7 +74,8 @@ class RunfilesTest(test_base.TestBase):
exit_code, stdout, stderr = self.RunProgram(
[bin_path], env_add={"TEST_SRCDIR": "__ignore_me__"})
self.AssertExitCode(exit_code, 0, stderr)
- if len(stdout) != 8:
+ # 10 output lines: 2 from foo-<family>, and 2 from each of bar-<lang>.
+ if len(stdout) != 10:
self.fail("stdout: %s" % stdout)
self.assertEqual(stdout[0], "Hello %s Foo!" % lang_name)
@@ -82,7 +90,7 @@ class RunfilesTest(test_base.TestBase):
i = 2
for lang in [("py", "Python", "bar.py"), ("java", "Java", "Bar.java"),
- ("sh", "Bash", "bar.sh")]:
+ ("sh", "Bash", "bar.sh"), ("cc", "C++", "bar.cc")]:
self.assertEqual(stdout[i], "Hello %s Bar!" % lang[1])
six.assertRegex(self, stdout[i + 1],
"^rloc=.*/bar/bar-%s-data.txt" % lang[0])
@@ -105,6 +113,9 @@ class RunfilesTest(test_base.TestBase):
def testBashRunfilesLibraryInBazelToolsRepo(self):
self._AssertRunfilesLibraryInBazelToolsRepo("sh", "Bash")
+ def testCppRunfilesLibraryInBazelToolsRepo(self):
+ self._AssertRunfilesLibraryInBazelToolsRepo("cc", "C++")
+
def testRunfilesLibrariesFindRunfilesWithoutEnvvars(self):
for s, t, exe in [
("WORKSPACE.mock", "WORKSPACE", False),
@@ -115,6 +126,8 @@ class RunfilesTest(test_base.TestBase):
("bar/bar-java-data.txt", "bar/bar-java-data.txt", False),
("bar/bar.sh", "bar/bar.sh", True),
("bar/bar-sh-data.txt", "bar/bar-sh-data.txt", False),
+ ("bar/bar.cc", "bar/bar.cc", False),
+ ("bar/bar-cc-data.txt", "bar/bar-cc-data.txt", False),
]:
self.CopyFile(
self.Rlocation("io_bazel/src/test/py/bazel/testdata/runfiles_test/" +
@@ -124,12 +137,14 @@ class RunfilesTest(test_base.TestBase):
self.AssertExitCode(exit_code, 0, stderr)
bazel_bin = stdout[0]
- exit_code, _, stderr = self.RunBazel(
- ["build", "//bar:bar-py", "//bar:bar-java", "//bar:bar-sh"])
+ exit_code, _, stderr = self.RunBazel([
+ "build", "--verbose_failures", "--experimental_shortened_obj_file_path",
+ "//bar:bar-py", "//bar:bar-java", "//bar:bar-sh", "//bar:bar-cc"
+ ])
self.AssertExitCode(exit_code, 0, stderr)
for lang in [("py", "Python", "bar.py"), ("java", "Java", "Bar.java"),
- ("sh", "Bash", "bar.sh")]:
+ ("sh", "Bash", "bar.sh"), ("cc", "C++", "bar.cc")]:
if test_base.TestBase.IsWindows():
bin_path = os.path.join(bazel_bin, "bar/bar-%s.exe" % lang[0])
else:
@@ -171,6 +186,8 @@ class RunfilesTest(test_base.TestBase):
("bar/bar-java-data.txt", "bar/bar-java-data.txt", False),
("bar/bar.sh", "bar/bar.sh", True),
("bar/bar-sh-data.txt", "bar/bar-sh-data.txt", False),
+ ("bar/bar.cc", "bar/bar.cc", False),
+ ("bar/bar-cc-data.txt", "bar/bar-cc-data.txt", False),
]:
self.CopyFile(
self.Rlocation("io_bazel/src/test/py/bazel/testdata/runfiles_test/" +
@@ -180,10 +197,11 @@ class RunfilesTest(test_base.TestBase):
self.AssertExitCode(exit_code, 0, stderr)
bazel_bin = stdout[0]
- for lang in [("java", "Java"),
- ("sh", "Bash")]: # TODO(laszlocsomor): add "cc" when ready.
+ for lang in [("java", "Java"), ("sh", "Bash"), ("cc", "C++")]:
exit_code, _, stderr = self.RunBazel([
- "build", "--experimental_enable_runfiles=no", "//bar:bar-" + lang[0]
+ "build", "--verbose_failures",
+ "--experimental_shortened_obj_file_path",
+ "--experimental_enable_runfiles=no", "//bar:bar-" + lang[0]
])
self.AssertExitCode(exit_code, 0, stderr)
diff --git a/src/test/py/bazel/testdata/runfiles_test/bar/BUILD.mock b/src/test/py/bazel/testdata/runfiles_test/bar/BUILD.mock
index ab97f8d9eb..930884b45a 100644
--- a/src/test/py/bazel/testdata/runfiles_test/bar/BUILD.mock
+++ b/src/test/py/bazel/testdata/runfiles_test/bar/BUILD.mock
@@ -22,3 +22,10 @@ sh_binary(
data = ["bar-sh-data.txt"],
deps = ["@bazel_tools//tools/bash/runfiles"],
)
+
+cc_binary(
+ name = "bar-cc",
+ srcs = ["bar.cc"],
+ data = ["bar-cc-data.txt"],
+ deps = ["@bazel_tools//tools/cpp/runfiles"],
+)
diff --git a/src/test/py/bazel/testdata/runfiles_test/bar/bar-cc-data.txt b/src/test/py/bazel/testdata/runfiles_test/bar/bar-cc-data.txt
new file mode 100644
index 0000000000..09db5f47ce
--- /dev/null
+++ b/src/test/py/bazel/testdata/runfiles_test/bar/bar-cc-data.txt
@@ -0,0 +1 @@
+data for bar.cc
diff --git a/src/test/py/bazel/testdata/runfiles_test/bar/bar.cc b/src/test/py/bazel/testdata/runfiles_test/bar/bar.cc
new file mode 100644
index 0000000000..1101b1df11
--- /dev/null
+++ b/src/test/py/bazel/testdata/runfiles_test/bar/bar.cc
@@ -0,0 +1,59 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Mock C++ binary, only used in tests.
+
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include "tools/cpp/runfiles/runfiles.h"
+
+namespace {
+
+using bazel::tools::cpp::runfiles::Runfiles;
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::ifstream;
+using std::string;
+using std::unique_ptr;
+
+bool is_file(const string& path) {
+ if (path.empty()) {
+ return false;
+ }
+ return ifstream(path).is_open();
+}
+
+int _main(int argc, char** argv) {
+ cout << "Hello C++ Bar!" << endl;
+ string error;
+ unique_ptr<Runfiles> runfiles(Runfiles::Create(argv[0], &error));
+ if (runfiles == nullptr) {
+ cerr << "ERROR[" << __FILE__ << "]: " << error << endl;
+ return 1;
+ }
+ string path = runfiles->Rlocation("foo_ws/bar/bar-cc-data.txt");
+ if (!is_file(path)) {
+ return 1;
+ }
+ cout << "rloc=" << path << endl;
+ return 0;
+}
+
+} // namespace
+
+int main(int argc, char** argv) { return _main(argc, argv); }
diff --git a/src/test/py/bazel/testdata/runfiles_test/foo/BUILD.mock b/src/test/py/bazel/testdata/runfiles_test/foo/BUILD.mock
index f35b840887..42c7d84241 100644
--- a/src/test/py/bazel/testdata/runfiles_test/foo/BUILD.mock
+++ b/src/test/py/bazel/testdata/runfiles_test/foo/BUILD.mock
@@ -6,6 +6,7 @@ py_binary(
"//bar:bar-java",
"//bar:bar-py",
"//bar:bar-sh",
+ "//bar:bar-cc",
],
main = "foo.py",
deps = ["@bazel_tools//tools/python/runfiles"],
@@ -19,6 +20,7 @@ java_binary(
"//bar:bar-py",
"//bar:bar-java",
"//bar:bar-sh",
+ "//bar:bar-cc",
],
main_class = "Foo",
deps = ["@bazel_tools//tools/runfiles:java-runfiles"],
@@ -32,6 +34,24 @@ sh_binary(
"//bar:bar-java",
"//bar:bar-py",
"//bar:bar-sh",
+ "//bar:bar-cc",
],
deps = ["@bazel_tools//tools/bash/runfiles"],
)
+
+cc_binary(
+ name = "runfiles-cc",
+ srcs = ["foo.cc"],
+ data = [
+ "datadep/hello.txt",
+ "//bar:bar-java",
+ "//bar:bar-py",
+ "//bar:bar-sh",
+ "//bar:bar-cc",
+ ],
+ copts = select({
+ "@bazel_tools//src/conditions:windows": ["/DIS_WINDOWS=1"],
+ "//conditions:default": [],
+ }),
+ deps = ["@bazel_tools//tools/cpp/runfiles"],
+)
diff --git a/src/test/py/bazel/testdata/runfiles_test/foo/Foo.java b/src/test/py/bazel/testdata/runfiles_test/foo/Foo.java
index 3571de1942..898cb03d76 100644
--- a/src/test/py/bazel/testdata/runfiles_test/foo/Foo.java
+++ b/src/test/py/bazel/testdata/runfiles_test/foo/Foo.java
@@ -28,7 +28,7 @@ public class Foo {
Runfiles r = Runfiles.create();
System.out.println("rloc=" + r.rlocation("foo_ws/foo/datadep/hello.txt"));
- for (String lang : new String[] {"py", "java", "sh"}) {
+ for (String lang : new String[] {"py", "java", "sh", "cc"}) {
String path = r.rlocation(childBinaryName(lang));
if (path == null || path.isEmpty()) {
throw new IOException("cannot find child binary for " + lang);
diff --git a/src/test/py/bazel/testdata/runfiles_test/foo/foo.cc b/src/test/py/bazel/testdata/runfiles_test/foo/foo.cc
new file mode 100644
index 0000000000..07ec268e3c
--- /dev/null
+++ b/src/test/py/bazel/testdata/runfiles_test/foo/foo.cc
@@ -0,0 +1,170 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Mock C++ binary, only used in tests.
+
+#include "tools/cpp/runfiles/runfiles.h"
+
+#ifdef IS_WINDOWS
+#include <windows.h>
+#else // not IS_WINDOWS
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#endif // IS_WINDOWS
+
+#include <string.h>
+
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <string>
+
+namespace {
+
+using bazel::tools::cpp::runfiles::Runfiles;
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::ifstream;
+using std::string;
+using std::unique_ptr;
+
+string child_binary_name(const char* lang) {
+#ifdef IS_WINDOWS
+ return string("foo_ws/bar/bar-") + lang + ".exe";
+#else
+ return string("foo_ws/bar/bar-") + lang;
+#endif // IS_WINDOWS
+}
+
+bool is_file(const string& path) {
+ if (path.empty()) {
+ return false;
+ }
+ return ifstream(path).is_open();
+}
+
+#ifdef IS_WINDOWS
+unique_ptr<char[]> create_env_block(const Runfiles& runfiles) {
+ char systemroot[MAX_PATH];
+ DWORD systemroot_size =
+ GetEnvironmentVariable("SYSTEMROOT", systemroot, MAX_PATH);
+ if (!systemroot_size || systemroot_size == MAX_PATH) {
+ cerr << "ERROR[" << __FILE__ << "]: %SYSTEMROOT% is too long" << endl;
+ return std::move(unique_ptr<char[]>());
+ }
+
+ size_t total_envblock_size =
+ 10 /* the string "SYSTEMROOT" */ + 1 /* equals-sign */ + systemroot_size +
+ 1 /* null-terminator */ +
+ 2 /* two null-terminator at the end of the environment block */;
+
+ // count total size of the environment block
+ const auto envvars = runfiles.EnvVars();
+ for (const auto i : envvars) {
+ total_envblock_size += i.first.size() + 1 /* equals-sign */ +
+ i.second.size() + 1 /* null-terminator */;
+ }
+
+ // copy environment variables from `envvars`
+ unique_ptr<char[]> result(new char[total_envblock_size]);
+ char* p = result.get();
+ for (const auto i : envvars) {
+ strncpy(p, i.first.c_str(), i.first.size());
+ p += i.first.size();
+ *p++ = '=';
+ strncpy(p, i.second.c_str(), i.second.size());
+ p += i.second.size();
+ *p++ = '\0';
+ }
+
+ // SYSTEMROOT environment variable
+ strncpy(p, "SYSTEMROOT=", 11);
+ p += 11;
+ strncpy(p, systemroot, systemroot_size);
+ p += systemroot_size;
+ *p++ = '\0';
+
+ // final two null-terminators
+ p[0] = '\0';
+ p[1] = '\0';
+
+ return std::move(result);
+}
+#endif
+
+int _main(int argc, char** argv) {
+ cout << "Hello C++ Foo!" << endl;
+ string error;
+ unique_ptr<Runfiles> runfiles(Runfiles::Create(argv[0], &error));
+ if (runfiles == nullptr) {
+ cerr << "ERROR[" << __FILE__ << "]: " << error << endl;
+ return 1;
+ }
+ string path = runfiles->Rlocation("foo_ws/foo/datadep/hello.txt");
+ if (!is_file(path)) {
+ return 1;
+ }
+ cout << "rloc=" << path << endl;
+
+#ifdef IS_WINDOWS
+ auto envvars = create_env_block(*runfiles);
+#else
+ const auto envvars = runfiles->EnvVars();
+#endif
+
+ // Run a subprocess, propagate the runfiles envvar to it. The subprocess will
+ // use this process's runfiles manifest or runfiles directory.
+ for (const char* lang : {"py", "java", "sh", "cc"}) {
+ const string bar = runfiles->Rlocation(child_binary_name(lang));
+
+ unique_ptr<char[]> argv0(new char[bar.size() + 1]);
+ strncpy(argv0.get(), bar.c_str(), bar.size());
+ argv0.get()[bar.size()] = 0;
+
+#ifdef IS_WINDOWS
+ PROCESS_INFORMATION processInfo;
+ STARTUPINFOA startupInfo = {0};
+ BOOL ok = CreateProcessA(NULL, argv0.get(), NULL, NULL, FALSE, 0,
+ envvars.get(), NULL, &startupInfo, &processInfo);
+ if (!ok) {
+ DWORD err = GetLastError();
+ fprintf(stderr, "ERROR: CreateProcessA error: %d\n", err);
+ return 1;
+ }
+ WaitForSingleObject(processInfo.hProcess, INFINITE);
+ CloseHandle(processInfo.hProcess);
+ CloseHandle(processInfo.hThread);
+#else
+ char* args[2] = {argv0.get(), NULL};
+ pid_t child = fork();
+ if (child) {
+ int status;
+ waitpid(child, &status, 0);
+ } else {
+ for (const auto i : envvars) {
+ setenv(i.first.c_str(), i.second.c_str(), 1);
+ }
+ execv(args[0], args);
+ }
+#endif
+ }
+ return 0;
+}
+
+} // namespace
+
+int main(int argc, char** argv) { return _main(argc, argv); }
diff --git a/src/test/py/bazel/testdata/runfiles_test/foo/foo.py b/src/test/py/bazel/testdata/runfiles_test/foo/foo.py
index d526531c9a..e6422b7ddb 100644
--- a/src/test/py/bazel/testdata/runfiles_test/foo/foo.py
+++ b/src/test/py/bazel/testdata/runfiles_test/foo/foo.py
@@ -53,7 +53,7 @@ def main():
else:
env = {}
env.update(r.EnvVars())
- for lang in ["py", "java", "sh"]:
+ for lang in ["py", "java", "sh", "cc"]:
p = subprocess.Popen(
[r.Rlocation(ChildBinaryName(lang))],
env=env,
diff --git a/src/test/py/bazel/testdata/runfiles_test/foo/foo.sh b/src/test/py/bazel/testdata/runfiles_test/foo/foo.sh
index ec934ed498..687d6121c2 100755
--- a/src/test/py/bazel/testdata/runfiles_test/foo/foo.sh
+++ b/src/test/py/bazel/testdata/runfiles_test/foo/foo.sh
@@ -68,7 +68,7 @@ function main() {
if is_windows; then
export SYSTEMROOT="${SYSTEMROOT:-}"
fi
- for lang in py java sh; do
+ for lang in py java sh cc; do
child_bin="$(rlocation "$(child_binary_name $lang)")"
if ! "$child_bin"; then
echo >&2 "ERROR: error running bar-$lang"