diff options
author | Yifan Hong <elsk@google.com> | 2024-01-03 09:32:22 -0800 |
---|---|---|
committer | Yifan Hong <elsk@google.com> | 2024-01-04 13:49:10 -0800 |
commit | 727182a720fcb5c8ec1b4cc523c32c49b0824250 (patch) | |
tree | 8034de2b58193e5b23ba8b935d01dd5cb0a1fa37 /tests | |
parent | 1d38077f1ca6bc8698f31c68e9678d4075538d71 (diff) | |
download | rules_pkg-main.tar.gz |
This git repository is deprecated and moved to
bazelbuild-rules_pkg.
Also remove METADATA file.
Also update README.md to point to the new repository.
The following files are kept unchanged:
- LICENSE
- MODULE_LICENSE_APACHE2
- OWNERS
Test: TH
Bug: 315857945
Bug: 306192195
Change-Id: I64ab31d8adc3bd566280fb6aba6f43f36b2c18d8
Diffstat (limited to 'tests')
105 files changed, 0 insertions, 8290 deletions
diff --git a/tests/BUILD b/tests/BUILD deleted file mode 100644 index 07b993a..0000000 --- a/tests/BUILD +++ /dev/null @@ -1,214 +0,0 @@ -# Copyright 2020 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. -# -*- coding: utf-8 -*- - -load("@rules_python//python:defs.bzl", "py_test") -load(":my_package_name.bzl", "my_package_naming") -load(":path_test.bzl", "path_tests") -load("//pkg:deb.bzl", "pkg_deb") -load("//pkg:mappings.bzl", "pkg_attributes", "pkg_files", "strip_prefix") -load("//pkg:tar.bzl", "pkg_tar") -load("//pkg:zip.bzl", "pkg_zip") - -package( - default_applicable_licenses = ["//:license"], - default_visibility = ["//tests:__subpackages__"], -) - -licenses(["notice"]) - -exports_files(glob(["testdata/**"])) - -filegroup( - name = "loremipsum_txt", - srcs = [ - "testdata/loremipsum.txt", - ], - visibility = ["//visibility:public"], -) - -filegroup( - name = "file_and_link", - srcs = [ - "BUILD", - "testdata/outer_BUILD", - ], - visibility = ["//visibility:public"], -) - -filegroup( - name = "glob_for_texts", - srcs = glob(["**/*.txt"]), -) - -# -# Data source for Unicode handling tests -# -pkg_files( - name = "utf8_files", - srcs = [ - "//tests/testdata/utf8:files", - ], - # Note: This is temporary. We need to fix a latent bug where - # we are using 555 as the default for many things. That was the - # Google internal behavior. - # See https://github.com/bazelbuild/rules_pkg/issues/302 for thoughts. - attributes = pkg_attributes(mode = "0o555"), - strip_prefix = strip_prefix.from_pkg(), - visibility = ["//tests:__subpackages__"], -) - -py_test( - name = "archive_test", - srcs = [ - "archive_test.py", - ], - imports = [".."], - data = [ - "//tests:testdata/empty.ar", - "//tests:testdata/a_ab.ar", - "//tests:testdata/a.ar", - "//tests:testdata/a_b_ab.ar", - "//tests:testdata/a_b.ar", - "//tests:testdata/ab.ar", - "//tests:testdata/b.ar", - ], - python_version = "PY3", - srcs_version = "PY3", - deps = [ - "//pkg/private:archive", - "@bazel_tools//tools/python/runfiles", - ], -) - -py_test( - name = "path_test", - srcs = ["path_test.py"], - data = ["//pkg:path.bzl"], - python_version = "PY3", - srcs_version = "PY3", -) - -cc_library( - name = "liba", - srcs = ["a.cc"], - data = ["testdata/hello.txt"], -) - -cc_library( - name = "libb", - srcs = ["b.cc"], - data = ["testdata/hello.txt"], -) - -cc_binary( - name = "an_executable", - srcs = ["foo.cc"], - data = ["BUILD"], - deps = [ - ":liba", - ":libb", - ], -) - -py_test( - name = "helpers_test", - srcs = ["helpers_test.py"], - imports = [".."], - python_version = "PY3", - srcs_version = "PY3", - deps = [ - "//pkg/private:helpers", - ], -) - -# -# Tests for package_file_name -# -my_package_naming( - name = "my_package_variables", - label = "some_value", -) - -pkg_tar( - name = "test_tar_naming", - srcs = [ - ":BUILD", - ], - package_file_name = "test_naming_{label}.tar", - package_variables = ":my_package_variables", -) - -pkg_deb( - name = "test_deb_naming", - data = ":test_tar_naming", - description = "desc", - maintainer = "someone@somewhere.com", - package = "some_name", - package_file_name = "test_naming_{label}.deb", - package_variables = ":my_package_variables", - version = "1", -) - -pkg_zip( - name = "test_zip_naming", - srcs = [ - ":BUILD", - ], - package_file_name = "test_naming_{label}.zip", - package_variables = ":my_package_variables", -) - -# This just proves that we would create the files via package_file_name rather -# than the default out file. -sh_test( - name = "package_naming_aggregate_test", - srcs = ["package_naming_aggregate_test.sh"], - data = [ - ":test_deb_naming", - ":test_tar_naming", - ":test_zip_naming", - ], -) - -pkg_tar( - name = "stamped_tar", - srcs = ["BUILD"], - stamp = 1, -) - -pkg_zip( - name = "stamped_zip", - srcs = ["BUILD"], - stamp = 1, -) - -# Note that this only tests that stamping works. Other tests cover the case -# of archive members having the default, epoch, time stamp. -py_test( - name = "stamp_test", - srcs = [ - "stamp_test.py", - ], - data = [ - "stamped_tar.tar", - "stamped_zip.zip", - ], - python_version = "PY3", - deps = [ - "@bazel_tools//tools/python/runfiles", - ], -) - -path_tests(name = "path_tests") diff --git a/tests/a.cc b/tests/a.cc deleted file mode 100644 index d46545e..0000000 --- a/tests/a.cc +++ /dev/null @@ -1 +0,0 @@ -int a = 1; diff --git a/tests/archive_test.py b/tests/archive_test.py deleted file mode 100644 index 21ddd5e..0000000 --- a/tests/archive_test.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright 2015 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. -"""Testing for archive.""" - -import unittest - -from bazel_tools.tools.python.runfiles import runfiles -from pkg.private import archive - - -class SimpleArReaderTest(unittest.TestCase): - """Testing for SimpleArReader class.""" - - def setUp(self): - super(SimpleArReaderTest, self).setUp() - self.data_files = runfiles.Create() - - def assertArFileContent(self, arfile, content): - """Assert that arfile contains exactly the entry described by `content`. - - Args: - arfile: the path to the AR file to test. - content: an array describing the expected content of the AR file. - Each entry in that list should be a dictionary where each field - is a field to test in the corresponding SimpleArFileEntry. For - testing the presence of a file "x", then the entry could simply - be `{"filename": "x"}`, the missing field will be ignored. - """ - print("READING: %s" % arfile) - with archive.SimpleArReader(arfile) as f: - current = f.next() - i = 0 - while current: - error_msg = "Extraneous file at end of archive %s: %s" % ( - arfile, - current.filename - ) - self.assertLess(i, len(content), error_msg) - for k, v in content[i].items(): - value = getattr(current, k) - error_msg = " ".join([ - "Value `%s` for key `%s` of file" % (value, k), - "%s in archive %s does" % (current.filename, arfile), - "not match expected value `%s`" % v - ]) - self.assertEqual(value, v, error_msg) - current = f.next() - i += 1 - if i < len(content): - self.fail("Missing file %s in archive %s" % (content[i], arfile)) - - def testEmptyArFile(self): - self.assertArFileContent( - self.data_files.Rlocation("rules_pkg/tests/testdata/empty.ar"), - []) - - def assertSimpleFileContent(self, names): - datafile = self.data_files.Rlocation( - "rules_pkg/tests/testdata/" + "_".join(names) + ".ar") - # pylint: disable=g-complex-comprehension - content = [{"filename": n, - "size": len(n.encode("utf-8")), - "data": n.encode("utf-8")} - for n in names] - self.assertArFileContent(datafile, content) - - def testAFile(self): - self.assertSimpleFileContent(["a"]) - - def testBFile(self): - self.assertSimpleFileContent(["b"]) - - def testABFile(self): - self.assertSimpleFileContent(["ab"]) - - def testA_BFile(self): - self.assertSimpleFileContent(["a", "b"]) - - def testA_ABFile(self): - self.assertSimpleFileContent(["a", "ab"]) - - def testA_B_ABFile(self): - self.assertSimpleFileContent(["a", "b", "ab"]) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/b.cc b/tests/b.cc deleted file mode 100644 index b20302a..0000000 --- a/tests/b.cc +++ /dev/null @@ -1 +0,0 @@ -int b = 2; diff --git a/tests/deb/BUILD b/tests/deb/BUILD deleted file mode 100644 index 655b46b..0000000 --- a/tests/deb/BUILD +++ /dev/null @@ -1,150 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2021 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. - -# Tests for pkg_deb specific behavior - -load("@rules_python//python:defs.bzl", "py_test") -load(":deb_tests.bzl", "package_naming_test") -load("//pkg:mappings.bzl", "pkg_mklink") -load("//pkg:deb.bzl", "pkg_deb") -load("//pkg:tar.bzl", "pkg_tar") -load("//tests:my_package_name.bzl", "my_package_naming") - -package(default_applicable_licenses = ["//:license"]) - -genrule( - name = "generate_files", - outs = [ - "etc/nsswitch.conf", - "usr/fizzbuzz", - ], - cmd = "for i in $(OUTS); do echo 1 >$$i; done", -) - -my_package_naming( - name = "my_package_variables", - label = "some_value", -) - -pkg_mklink( - name = "java_link", - link_name = "usr/bin/java", - target = "/path/to/bin/java", -) - -pkg_tar( - name = "tar_input", - srcs = [ - ":etc/nsswitch.conf", - ":java_link", - ":usr/fizzbuzz", - ], - extension = "tar.gz", - mode = "0644", - modes = {"usr/fizzbuzz": "0755"}, - owner = "42.24", - ownername = "fizzbuzz.foobar", - ownernames = {"etc/nsswitch.conf": "foobar.fizzbuzz"}, - owners = {"etc/nsswitch.conf": "24.42"}, - package_dir = "/", - strip_prefix = ".", -) - -pkg_deb( - name = "test_deb", - breaks = ["oldbrokenpkg"], - built_using = "some_test_data (0.1.2)", - conffiles = [ - "/etc/nsswitch.conf", - "/etc/other", - ], - config = "config", - data = ":tar_input", - depends = [ - "dep1", - "dep2", - ], - description = "toto ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é\n more", - distribution = "trusty", - license = "Apache-2.0", - maintainer = "soméone@somewhere.com", - package = "fizzbuzz", - preinst = "deb_preinst", - provides = ["hello"], - replaces = ["oldpkg"], - templates = "templates", - triggers = "deb_triggers", - urgency = "low", - version = "4.5.6", -) - -py_test( - name = "pkg_deb_test", - size = "medium", - srcs = [ - "pkg_deb_test.py", - ], - imports = ["../.."], - data = [ - # The target includes both the .deb and .changes files in DefaultInfo - ":test_deb", - ], - python_version = "PY3", - deps = [ - "//pkg/private:archive", - "@bazel_tools//tools/python/runfiles", - ], -) - -package_naming_test( - name = "naming_test", - expected_name = "fizzbuzz_4.5.6_all.deb", - target_under_test = ":test_deb", -) - -py_test( - name = "control_field_test", - size = "small", - srcs = [ - "control_field_test.py", - ], - imports = ["../.."], - python_version = "PY3", - deps = [ - "//pkg/private/deb:make_deb_lib", - ], -) - -# Test case for expanding $(var) constructions and for using ctx.var directly -pkg_deb( - name = "deb_using_ctxvar", - config = "config", - data = ":tar_input", - description = "Compiled with $(COMPILATION_MODE)", - #distribution = "trusty", - maintainer = "soméone@somewhere.com", - package = "fizzbuzz", - version = "7", - # This does not make sense for architecture, but for testing, compilation - # mode is more stable than cpu. - architecture = "$(COMPILATION_MODE)", -) - -package_naming_test( - name = "expand_from_ctx_var", - # Heads up. If the default compilation mode ever changes this will break. - expected_name = "fizzbuzz_7_fastbuild.deb", - target_under_test = ":deb_using_ctxvar", -) diff --git a/tests/deb/config b/tests/deb/config deleted file mode 100644 index d39edc7..0000000 --- a/tests/deb/config +++ /dev/null @@ -1 +0,0 @@ -# test config file diff --git a/tests/deb/control_field_test.py b/tests/deb/control_field_test.py deleted file mode 100644 index 5f4f5e9..0000000 --- a/tests/deb/control_field_test.py +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright 2022 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. -# -# -*- coding: utf-8 -*- -"""Testing for archive.""" - -import codecs -from io import BytesIO -import os -import sys -import tarfile -import unittest - -from pkg.private.deb import make_deb - -class MakeControlFieldTest(unittest.TestCase): - """Tests for MakeControlField. - - https://www.debian.org/doc/debian-policy/ch-controlfields.html#syntax-of-control-files - """ - - def test_simple(self): - self.assertEqual( - 'Package: fizzbuzz\n', - make_deb.MakeDebianControlField('Package', 'fizzbuzz')) - - def test_simple_strip(self): - self.assertEqual( - 'Package: fizzbuzz\n', - make_deb.MakeDebianControlField('Package', ' fizzbuzz')) - self.assertEqual( - 'Package: fizzbuzz\n', - make_deb.MakeDebianControlField('Package', ' fizzbuzz ')) - - def test_simple_no_newline(self): - with self.assertRaises(ValueError): - make_deb.MakeDebianControlField('Package', ' fizz\nbuzz ') - - - def test_multiline(self): - self.assertEqual( - 'Description: fizzbuzz\n', - make_deb.MakeDebianControlField( - 'Description', 'fizzbuzz', multiline=make_deb.Multiline.YES)) - self.assertEqual( - 'Description: fizz\n buzz\n', - make_deb.MakeDebianControlField( - 'Description', 'fizz\n buzz\n', multiline=make_deb.Multiline.YES)) - self.assertEqual( - 'Description:\n fizz\n buzz\n', - make_deb.MakeDebianControlField( - 'Description', ' fizz\n buzz\n', multiline=make_deb.Multiline.YES_ADD_NEWLINE)) - - def test_multiline_add_required_space(self): - self.assertEqual( - 'Description: fizz\n buzz\n', - make_deb.MakeDebianControlField( - 'Description', 'fizz\nbuzz', multiline=make_deb.Multiline.YES)) - self.assertEqual( - 'Description:\n fizz\n buzz\n', - make_deb.MakeDebianControlField( - 'Description', 'fizz\nbuzz\n', multiline=make_deb.Multiline.YES_ADD_NEWLINE)) - - def test_multiline_add_trailing_newline(self): - self.assertEqual( - 'Description: fizz\n buzz\n baz\n', - make_deb.MakeDebianControlField( - 'Description', 'fizz\n buzz\n baz', multiline=make_deb.Multiline.YES)) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/deb/deb_preinst b/tests/deb/deb_preinst deleted file mode 100644 index 9a88ab0..0000000 --- a/tests/deb/deb_preinst +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -# tete ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é -echo fnord diff --git a/tests/deb/deb_tests.bzl b/tests/deb/deb_tests.bzl deleted file mode 100644 index 0227d05..0000000 --- a/tests/deb/deb_tests.bzl +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2021 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. -"""Helpers for pkg_deb tests.""" - -load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") - -def _package_naming_test_impl(ctx): - env = analysistest.begin(ctx) - target_under_test = analysistest.target_under_test(env) - - ogi = target_under_test[OutputGroupInfo] - - deb_path = ogi.deb.to_list()[0].path - - # Test that the .changes file is computed correctly - changes_path = ogi.changes.to_list()[0].path - expected_changes_path = deb_path[0:-3] + "changes" - asserts.equals( - env, - changes_path, - expected_changes_path, - "Changes file does not have the correct name", - ) - - # Is the generated file name what we expect - if ctx.attr.expected_name: - asserts.equals( - env, - deb_path.split("/")[-1], # basename(path) - ctx.attr.expected_name, - "Deb package file name is not correct", - ) - return analysistest.end(env) - -package_naming_test = analysistest.make( - _package_naming_test_impl, - attrs = { - "expected_name": attr.string(), - }, -) diff --git a/tests/deb/deb_triggers b/tests/deb/deb_triggers deleted file mode 100644 index e7c1249..0000000 --- a/tests/deb/deb_triggers +++ /dev/null @@ -1,2 +0,0 @@ -# tutu ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é -some-trigger diff --git a/tests/deb/pkg_deb_test.py b/tests/deb/pkg_deb_test.py deleted file mode 100644 index 285a965..0000000 --- a/tests/deb/pkg_deb_test.py +++ /dev/null @@ -1,280 +0,0 @@ -# Copyright 2020 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. -# -# -*- coding: utf-8 -*- -"""Testing for archive.""" - -import codecs -from io import BytesIO -import os -import sys -import tarfile -import unittest - -from bazel_tools.tools.python.runfiles import runfiles -from pkg.private import archive - - -class DebInspect(object): - """Class to open and unpack a .deb file so we can examine it.""" - - def __init__(self, deb_file): - self.deb_version = None - self.data = None - self.control = None - with archive.SimpleArReader(deb_file) as f: - info = f.next() - while info: - if info.filename == 'debian-binary': - self.deb_version = info.data - elif info.filename == 'control.tar.gz': - self.control = info.data - elif info.filename == 'data.tar.gz': - self.data = info.data - else: - raise Exception('Unexpected file: %s' % info.filename) - info = f.next() - - def get_deb_ctl_file(self, file_name): - """Extract a control file.""" - - with tarfile.open(mode='r:gz', fileobj=BytesIO(self.control)) as f: - for info in f: - if info.name == './' + file_name: - return codecs.decode(f.extractfile(info).read(), 'utf-8') - raise Exception('Could not find control file: %s' % file_name) - - -class PkgDebTest(unittest.TestCase): - """Testing for pkg_deb rule.""" - - def setUp(self): - super(PkgDebTest, self).setUp() - self.runfiles = runfiles.Create() - # Note: Rlocation requires forward slashes. os.path.join() will not work. - self.deb_path = self.runfiles.Rlocation('rules_pkg/tests/deb/fizzbuzz_4.5.6_all.deb') - self.deb_file = DebInspect(self.deb_path) - - def assert_control_content(self, expected, match_order=False): - self.assert_tar_stream_content( - BytesIO(self.deb_file.control), - expected, - match_order=match_order) - - def assert_data_content(self, expected, match_order=True): - self.assert_tar_stream_content( - BytesIO(self.deb_file.data), - expected, - match_order=match_order) - - def assert_tar_stream_content(self, data, expected, match_order=True): - """Assert that tarfile contains exactly the entry described by `expected`. - - Args: - data: the tar file stream to check. - expected: an array describing the expected content of the TAR file. - Each entry in that list should be a dictionary where each field - is a field to test in the corresponding TarInfo. For - testing the presence of a file "x", then the entry could simply - be `{'name': 'x'}`, the missing field will be ignored. To match - the content of a file entry, use the key 'data'. - match_order: True if files must match in order as well as properties. - """ - expected_by_name = {} - for e in expected: - expected_by_name[e['name']] = e - - with tarfile.open(mode='r:*', fileobj=data) as f: - i = 0 - for info in f: - error_msg = 'Extraneous file at end of archive: %s' % ( - info.name - ) - self.assertLess(i, len(expected), error_msg) - name_in_tar_file = getattr(info, 'name') - if match_order: - want = expected[i] - else: - want = expected_by_name[name_in_tar_file] - for k, v in want.items(): - if k == 'data': - value = f.extractfile(info).read() - elif k == 'name': - # The test data uses / as path sep, but the tarball is in OS native - # format. This aligns the tarball name back to what we expect. - value = name_in_tar_file.replace(os.path.sep, '/') - elif k == 'isdir': - value = info.isdir() - elif k == "name" and sys.platform == 'win32': - value = getattr(current, k).replace("\\", "/") - else: - value = getattr(info, k) - error_msg = ' '.join([ - 'Value `%s` for key `%s` of file' % (value, k), - '%s in archive does' % info.name, - 'not match expected value `%s`' % v - ]) - self.assertEqual(value, v, error_msg) - i += 1 - if i < len(expected): - self.fail('Missing file %s' % expected[i]) - - def test_expected_files(self): - # Check the set of 'test-tar-basic-*' smoke test. - expected = [ - {'name': 'etc', 'isdir': True, - 'uid': 24, 'gid': 42, 'uname': 'foobar', 'gname': 'fizzbuzz'}, - {'name': 'etc/nsswitch.conf', - 'mode': 0o644, - 'uid': 24, 'gid': 42, 'uname': 'foobar', 'gname': 'fizzbuzz' - }, - {'name': 'usr', 'isdir': True, - 'uid': 42, 'gid': 24, 'uname': 'fizzbuzz', 'gname': 'foobar'}, - {'name': 'usr/bin', 'isdir': True}, - {'name': 'usr/bin/java', 'linkname': '/path/to/bin/java'}, - {'name': 'usr/fizzbuzz', - 'mode': 0o755, - 'uid': 42, 'gid': 24, 'uname': 'fizzbuzz', 'gname': 'foobar'}, - ] - self.assert_data_content(expected) - - def test_description(self): - control = self.deb_file.get_deb_ctl_file('control') - fields = [ - 'Package: fizzbuzz', - 'Depends: dep1, dep2', - 'Built-Using: some_test_data', - 'Replaces: oldpkg', - 'Breaks: oldbrokenpkg', - 'Provides: hello', - 'License: Apache-2.0', - ] - # TODO(https://github.com/bazelbuild/rules_pkg/issues/214): This can not - # pass on Windows Until we rewrite how description is passed - if sys.platform != 'win32': - fields.extend([ - 'Description: toto ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é\n more\n', - 'Maintainer: soméone@somewhere.com', - ]) - for field in fields: - if control.find(field) < 0: - self.fail('Missing control field: <%s> in <%s>' % (field, control)) - - def test_control_files(self): - expected = [ - {'name': './conffiles', 'mode': 0o644}, - {'name': './config', 'mode': 0o755}, - {'name': './control', 'mode': 0o644}, - {'name': './preinst', 'mode': 0o755}, - {'name': './templates', 'mode': 0o644}, - {'name': './triggers', 'mode': 0o644}, - ] - self.assert_control_content(expected, match_order=False) - - def test_conffiles(self): - conffiles = self.deb_file.get_deb_ctl_file('conffiles') - self.assertEqual( - conffiles, - '/etc/nsswitch.conf\n/etc/other\n') - - def test_config(self): - config = self.deb_file.get_deb_ctl_file('config') - self.assertEqual(config, '# test config file\n') - - def test_preinst(self): - preinst = self.deb_file.get_deb_ctl_file('preinst') - self.assertEqual( - preinst, - '#!/usr/bin/env bash\n' - '# tete ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é\n' - 'echo fnord\n') - - def test_templates(self): - templates = self.deb_file.get_deb_ctl_file('templates') - for field in ('Template: deb/test', 'Type: string'): - if templates.find(field) < 0: - self.fail('Missing template field: <%s> in <%s>' % (field, templates)) - - def test_triggers(self): - triggers = self.deb_file.get_deb_ctl_file('triggers') - self.assertEqual( - triggers, - '# tutu ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é\n' - 'some-trigger\n') - - def test_changes(self): - changes_path = self.runfiles.Rlocation( - 'rules_pkg/tests/deb/fizzbuzz_4.5.6_all.changes') - with open(changes_path, 'r', encoding='utf-8') as f: - content = f.read() - for field in ( - 'Urgency: low', - 'Distribution: trusty'): - if content.find(field) < 0: - self.fail('Missing template field: <%s> in <%s>' % (field, content)) - - # TODO(https://github.com/bazelbuild/rules_pkg/issues/214): This can not - # pass on Windows until we rewrite how description is passed. - if sys.platform == 'win32': - return - - # From the spec: - # In a .changes file, the Description field contains a summary of the - # descriptions for the packages being uploaded. For this case, the first - # line of the field value (the part on the same line as Description:) is - # always empty. It is a multiline field, with one line per package. Each - # line is indented by one space and contains the name of a binary package, - # a space, a hyphen (-), a space, and the short description line from that - # package. - d_expect = 'Description:\n fizzbuzz - toto ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é\n' - d_start = content.find(d_expect) - if d_start < 0: - self.fail( - 'Could not find expected description (%s) in\n=====%s=====' % - (d_expect, content)) - # Check that the next line is the start of a new description, rather than - # a continuation. - self.assertTrue( - content[d_start + len(d_expect)].isupper(), - 'Description has unexpected characters at end (%s)' % content) - - self.maxDiff = None - expect = '''Format: 1\.8 -Date: Thu Jan 1 \d{2}:00:00 1970 -Source: fizzbuzz -Binary: fizzbuzz -Architecture: all -Version: 4\.5\.6 -Distribution: trusty -Urgency: low -Maintainer: soméone@somewhere.com -Changed-By: soméone@somewhere.com -Description: - fizzbuzz - toto ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é -Changes: - fizzbuzz \(4\.5\.6\) trusty; urgency=low - Changes are tracked in revision control\. -Files: - [a-f0-9]{32} \d{4} contrib/devel optional fizzbuzz_4\.5\.6_all\.deb -Checksums-Sha1: - [a-f0-9]{40} \d{4} fizzbuzz_4\.5\.6_all\.deb -Checksums-Sha256: - [a-f0-9]{64} \d{4} fizzbuzz_4\.5\.6_all\.deb -''' - - self.assertRegex(content, expect) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/deb/templates b/tests/deb/templates deleted file mode 100644 index 0576bc0..0000000 --- a/tests/deb/templates +++ /dev/null @@ -1,6 +0,0 @@ -Template: deb/test -Type: string -Default: -Description: test question - test question to check that templates are included into - debian directory diff --git a/tests/foo.cc b/tests/foo.cc deleted file mode 100644 index 3274cf8..0000000 --- a/tests/foo.cc +++ /dev/null @@ -1,20 +0,0 @@ -#include <fstream> -#include <iostream> -#include <string> - -extern int a, b; - -// A very roundabout hello world. -int main(int argc, char* argv[]) { - std::string runfiles(argv[0]); - runfiles.append(".runfiles"); - std::string hello(runfiles + "/rules_pkg/tests/testdata/hello.txt"); - std::fstream fs; - fs.open(hello, std::iostream::in); - char tmp[1000]; - fs.read(tmp, sizeof(tmp)); - fs.close(); - std::cout << tmp; - - return (a + b > 0) ? 0 : 1; -} diff --git a/tests/helpers_test.py b/tests/helpers_test.py deleted file mode 100644 index 0e6f005..0000000 --- a/tests/helpers_test.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright 2019 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. - -import os -import tempfile -import unittest - -from pkg.private import helpers - - -class GetFlagValueTestCase(unittest.TestCase): - - def testNonStripped(self): - self.assertEqual(helpers.GetFlagValue('value ', strip=False), 'value ') - - def testStripped(self): - self.assertEqual(helpers.GetFlagValue('value ', strip=True), 'value') - - def testNonStripped_fromFile(self): - with tempfile.TemporaryDirectory() as temp_d: - argfile_path = os.path.join(temp_d, 'argfile') - with open(argfile_path, 'wb') as f: - f.write(b'value ') - self.assertEqual( - helpers.GetFlagValue('@'+argfile_path, strip=False), 'value ') - - def testStripped_fromFile(self): - with tempfile.TemporaryDirectory() as temp_d: - argfile_path = os.path.join(temp_d, 'argfile') - with open(argfile_path, 'wb') as f: - f.write(b'value ') - self.assertEqual( - helpers.GetFlagValue('@'+argfile_path, strip=True), 'value') - - -class SplitNameValuePairAtSeparatorTestCase(unittest.TestCase): - - def testNoSep(self): - key, val = helpers.SplitNameValuePairAtSeparator('abc', '=') - self.assertEqual(key, 'abc') - self.assertEqual(val, '') - - def testNoSepWithEscape(self): - key, val = helpers.SplitNameValuePairAtSeparator('a\\=bc', '=') - self.assertEqual(key, 'a=bc') - self.assertEqual(val, '') - - def testNoSepWithDanglingEscape(self): - key, val = helpers.SplitNameValuePairAtSeparator('abc\\', '=') - self.assertEqual(key, 'abc') - self.assertEqual(val, '') - - def testHappyCase(self): - key, val = helpers.SplitNameValuePairAtSeparator('abc=xyz', '=') - self.assertEqual(key, 'abc') - self.assertEqual(val, 'xyz') - - def testHappyCaseWithEscapes(self): - key, val = helpers.SplitNameValuePairAtSeparator('a\\=\\=b\\=c=xyz', '=') - self.assertEqual(key, 'a==b=c') - self.assertEqual(val, 'xyz') - - def testStopsAtFirstSep(self): - key, val = helpers.SplitNameValuePairAtSeparator('a=b=c', '=') - self.assertEqual(key, 'a') - self.assertEqual(val, 'b=c') - - def testDoesntUnescapeVal(self): - key, val = helpers.SplitNameValuePairAtSeparator('abc=x\\=yz\\', '=') - self.assertEqual(key, 'abc') - # the val doesn't get unescaped at all - self.assertEqual(val, 'x\\=yz\\') - - def testUnescapesNonsepCharsToo(self): - key, val = helpers.SplitNameValuePairAtSeparator('na\\xffme=value', '=') - # this behaviour is surprising - self.assertEqual(key, 'naxffme') - self.assertEqual(val, 'value') - -if __name__ == '__main__': - unittest.main() diff --git a/tests/install/BUILD b/tests/install/BUILD deleted file mode 100644 index df97dff..0000000 --- a/tests/install/BUILD +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright 2021 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. - -load("@rules_python//python:defs.bzl", "py_test") -load("//pkg:install.bzl", "pkg_install") -load("//pkg:mappings.bzl", "pkg_attributes", "pkg_files", "pkg_mkdirs") -load("//tests/util:defs.bzl", "fake_artifact") - -package(default_applicable_licenses = ["//:license"]) - -py_test( - name = "install_test", - srcs = ["test.py"], - args = ["-v"], - imports = ["../.."], - data = [ - ":test_installer", - ], - main = "test.py", - tags = [ - # TODO(nacl): investigate this. See also - # https://buildkite.com/bazel/rules-pkg/builds/961#992dbe09-7e4b-4e34-91b6-491120476ed3 - "no-windows", - # TODO(nacl): consider enabling this for testing on Linux. - #"requires-fakeroot" - ], - deps = [ - "//pkg/private:manifest", - "@rules_python//python/runfiles", - ], -) - -pkg_install( - name = "test_installer", - srcs = [ - ":artifact-in-owned-dir", - ":artifact-in-unowned-dir", - ":dirs", - ], -) - -fake_artifact( - name = "artifact", -) - -pkg_files( - name = "artifact-in-owned-dir", - srcs = ["artifact"], - attributes = pkg_attributes(mode = "0700"), - prefix = "owned-dir", -) - -pkg_files( - name = "artifact-in-unowned-dir", - srcs = ["artifact"], - attributes = pkg_attributes(mode = "0755"), - prefix = "unowned-dir", -) - -pkg_mkdirs( - name = "dirs", - dirs = [ - "empty-owned-dir", - "owned-dir", - ], -) diff --git a/tests/install/test.py b/tests/install/test.py deleted file mode 100644 index 996ae09..0000000 --- a/tests/install/test.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2021 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. - -import itertools -import os -import unittest -import stat -import subprocess - -from rules_python.python.runfiles import runfiles -from pkg.private import manifest - - -class PkgInstallTest(unittest.TestCase): - @classmethod - def setUpClass(cls): - cls.runfiles = runfiles.Create() - # Somewhat of an implementation detail, but it works. I think. - manifest_file = cls.runfiles.Rlocation("rules_pkg/tests/install/test_installer_install_script-install-manifest.json") - - with open(manifest_file, 'r') as fh: - manifest_entries = manifest.read_entries_from(fh) - cls.manifest_data = {} - - for entry in manifest_entries: - cls.manifest_data[entry.dest] = entry - cls.installdir = os.path.join(os.getenv("TEST_TMPDIR"), "installdir") - env = {} - env.update(cls.runfiles.EnvVars()) - subprocess.check_call([ - cls.runfiles.Rlocation("rules_pkg/tests/install/test_installer"), - "--destdir", cls.installdir, - "--verbose", - ], - env=env) - - def entity_type_at_path(self, path): - if os.path.islink(path): - return manifest.ENTRY_IS_LINK - elif os.path.isfile(path): - return manifest.ENTRY_IS_FILE - elif os.path.isdir(path): - return manifest.ENTRY_IS_DIR - else: - # We can't infer what TreeArtifacts are by looking at them -- the - # build system is not aware of their contents. - raise ValueError("Entity {} is not a link, file, or directory") - - def assertEntryTypeMatches(self, entry, actual_path): - actual_entry_type = self.entity_type_at_path(actual_path) - self.assertEqual(actual_entry_type, entry.type, - "Entity {} should be a {}, but was actually {}".format( - entry.dest, - manifest.entry_type_to_string(entry.type), - manifest.entry_type_to_string(actual_entry_type), - )) - - def assertEntryModeMatches(self, entry, actual_path): - # TODO: permissions in windows are... tricky. Don't bother - # testing for them if we're in it for the time being - if os.name == 'nt': - return - - actual_mode = stat.S_IMODE(os.stat(actual_path).st_mode) - expected_mode = int(entry.mode, 8) - self.assertEqual(actual_mode, expected_mode, - "Entry {} has mode {:04o}, expected {:04o}".format( - entry.dest, actual_mode, expected_mode, - )) - - def test_manifest_matches(self): - unowned_dirs = set() - owned_dirs = set() - - # Figure out what directories we are supposed to own, and which ones we - # aren't. - # - # Unowned directories are created implicitly by requesting other - # elements be created or installed. - # - # Owned directories are created explicitly with the pkg_mkdirs rule. - for dest, data in self.manifest_data.items(): - if data.type == manifest.ENTRY_IS_DIR: - owned_dirs.add(dest) - - # TODO(nacl): The initial stage of the accumulation returns an empty string, - # which end up in the set representing the root of the manifest. - # This may not be the best thing. - unowned_dirs.update([p for p in itertools.accumulate(os.path.dirname(dest).split('/'), - func=lambda accum, new: accum + '/' + new)]) - - # In the above loop, unowned_dirs contains all possible directories that - # are in the manifest. Prune them here. - unowned_dirs -= owned_dirs - - # TODO: check for ownership (user, group) - found_entries = {dest: False for dest in self.manifest_data.keys()} - for root, dirs, files in os.walk(self.installdir): - rel_root_path = os.path.relpath(root, self.installdir) - - # The rest of this uses string comparison. To reduce potential - # confusion, ensure that the "." doesn't show up elsewhere. - # - # TODO(nacl) consider using pathlib here, which will reduce the - # need for path cleverness. - if rel_root_path == '.': - rel_root_path = '' - - # TODO(nacl): check for treeartifacts here. If so, prune `dirs`, - # and set the rest aside for future processing. - - # Directory ownership tests - if len(files) == 0 and len(dirs) == 0: - # Empty directories must be explicitly requested by something - if rel_root_path not in self.manifest_data: - self.fail("Directory {} not in manifest".format(rel_root_path)) - - entry = self.manifest_data[rel_root_path] - self.assertEntryTypeMatches(entry, root) - self.assertEntryModeMatches(entry, root) - - found_entries[rel_root_path] = True - else: - # There's something in here. Depending on how it was set up, it - # could either be owned or unowned. - if rel_root_path in self.manifest_data: - entry = self.manifest_data[rel_root_path] - self.assertEntryTypeMatches(entry, root) - self.assertEntryModeMatches(entry, root) - - found_entries[rel_root_path] = True - else: - # If any unowned directories are here, they must be the - # prefix of some entity in the manifest. - self.assertIn(rel_root_path, unowned_dirs) - - for f in files: - # The path on the filesystem in which the file actually exists. - - # TODO(#382): This part of the test assumes that the path - # separator is '/', which is not the case in Windows. However, - # paths emitted in the JSON manifests may also be using - # '/'-separated paths. - # - # Confirm the degree to which this is a problem, and remedy as - # needed. It maybe worth setting the keys in the manifest_data - # dictionary to pathlib.Path or otherwise converting them to - # native paths. - fpath = os.path.normpath("/".join([root, f])) - # The path inside the manifest (relative to the install - # destdir). - rel_fpath = os.path.normpath("/".join([rel_root_path, f])) - if rel_fpath not in self.manifest_data: - self.fail("Entity {} not in manifest".format(rel_fpath)) - - entry = self.manifest_data[rel_fpath] - self.assertEntryTypeMatches(entry, fpath) - self.assertEntryModeMatches(entry, fpath) - - found_entries[rel_fpath] = True - - # TODO(nacl): check for TreeArtifacts - - num_missing = 0 - for dest, present in found_entries.items(): - if present is False: - print("Entity {} is missing from the tree".format(dest)) - num_missing += 1 - self.assertEqual(num_missing, 0) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/mappings/BUILD b/tests/mappings/BUILD deleted file mode 100644 index eb97f9f..0000000 --- a/tests/mappings/BUILD +++ /dev/null @@ -1,189 +0,0 @@ -# Copyright 2021 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. - -load( - ":mappings_test.bzl", - "manifest_golden_test", - "mappings_analysis_tests", - "mappings_unit_tests", -) -load(":mappings_external_repo_test.bzl", "mappings_external_repo_analysis_tests") -load( - "//pkg:mappings.bzl", - "pkg_attributes", - "pkg_filegroup", - "pkg_files", - "pkg_mkdirs", - "strip_prefix", -) -load("//tests/util:defs.bzl", "directory", "link_tree", "write_content_manifest") -load("@rules_python//python:defs.bzl", "py_test") - -package(default_applicable_licenses = ["//:license"]) - -py_library( - name = "manifest_test_lib", - srcs = ["manifest_test_lib.py"], - imports = ["../.."], - srcs_version = "PY3", - deps = [ - "@bazel_tools//tools/python/runfiles", - ], -) - -mappings_unit_tests() - -mappings_analysis_tests() - -mappings_external_repo_analysis_tests() - -################################################################################ -# Packaging rule manifest tests -################################################################################ - -directory( - name = "treeartifact", - filenames = [ - "artifact_in_tree1", - "artifact_in_tree2", - ], -) - -pkg_files( - name = "directory-with-contents", - srcs = ["treeartifact"], - attributes = pkg_attributes(mode = "0644"), -) - -pkg_mkdirs( - name = "dirs", - attributes = pkg_attributes( - group = "bar", - mode = "711", - user = "foo", - ), - dirs = [ - "foodir", - ], -) - -pkg_files( - name = "files", - srcs = [ - "mappings_test.bzl", - ], -) - -write_content_manifest( - name = "all", - srcs = [ - "BUILD", - ":directory-with-contents", - ":dirs", - ":files", - ], -) - -manifest_golden_test( - name = "all_test", - expected = "all.manifest.golden", - target = "all", -) - -# -# Unicode handling tests -# -pkg_files( - name = "utf8_files", - srcs = [ - "//tests/testdata/utf8:files", - ], - strip_prefix = strip_prefix.from_pkg(), - visibility = ["//tests:__subpackages__"], -) - -write_content_manifest( - name = "utf8", - srcs = [ - ":utf8_files", - ], -) - -manifest_golden_test( - name = "utf8_manifest_test", - expected = "utf8_manifest.golden", - target = "utf8", -) - -# Test handling of executable + runfiles -write_content_manifest( - name = "executable_manifest", - srcs = [ - "mappings_test.bzl", - "//tests:an_executable", - ], - include_runfiles = True, -) - -alias( - name = "executable_test_expected", - actual = select({ - "@platforms//os:windows": "executable.manifest.windows.golden", - "//conditions:default": "executable.manifest.golden", - }), -) - -manifest_golden_test( - name = "executable_test", - expected = ":executable_test_expected", - target = "executable_manifest", -) - -write_content_manifest( - name = "glob_for_texts_manifest", - srcs = ["//tests:glob_for_texts"], -) - -manifest_golden_test( - name = "glob_for_texts_manifest_test", - expected = "glob_for_texts_manifest.golden", - target = "glob_for_texts_manifest", -) - -link_tree( - name = "node_modules", - links = { - "foo": ".pnpm/foo@1.0.0/node_modules/foo", - ".pnpm/bar@1.0.0/node_modules/bar": "STORE/bar", - ".pnpm/bar@1.0.0/node_modules/qar": "../../qar@2.0.0/node_modules/qar", - ".pnpm/foo@1.0.0/node_modules/foo": "STORE/foo", - ".pnpm/foo@1.0.0/node_modules/bar": "../../bar@1.0.0/node_modules/bar", - ".pnpm/foo@1.0.0/node_modules/qar": "../../qar@2.0.0/node_modules/qar", - ".pnpm/qar@2.0.0/node_modules/qar": "STORE/qar", - }, - package_dir = "node_modules", -) - -write_content_manifest( - name = "node_modules_manifest", - srcs = [ - ":node_modules", - ], -) - -manifest_golden_test( - name = "link_tree_test", - expected = "node_modules_manifest.golden", - target = "node_modules_manifest", -) diff --git a/tests/mappings/all.manifest.golden b/tests/mappings/all.manifest.golden deleted file mode 100644 index 6a5f107..0000000 --- a/tests/mappings/all.manifest.golden +++ /dev/null @@ -1,7 +0,0 @@ -[ - {"type": "file", "dest": "BUILD", "src": "tests/mappings/BUILD", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:BUILD"}, - {"type": "dir", "dest": "foodir", "src": null, "mode": "711", "user": "foo", "group": "bar", "uid": null, "gid": null, "origin": "@//tests/mappings:dirs"}, - - {"type": "file", "dest": "mappings_test.bzl", "src": "tests/mappings/mappings_test.bzl", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:files"}, - {"type": "tree", "dest": "treeartifact", "src": "tests/mappings/treeartifact", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:directory-with-contents"} -] diff --git a/tests/mappings/executable.manifest.golden b/tests/mappings/executable.manifest.golden deleted file mode 100644 index ee86633..0000000 --- a/tests/mappings/executable.manifest.golden +++ /dev/null @@ -1,7 +0,0 @@ -[ -{"dest":"an_executable.runfiles/tests/BUILD","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src":"tests/BUILD","type":"file","uid":null,"user":null}, -{"dest":"an_executable.runfiles/tests/an_executable","gid":null,"group":null,"mode":"0755","origin":"@//tests:an_executable","src":"tests/an_executable","type":"file","uid":null,"user":null}, -{"dest":"an_executable.runfiles/tests/testdata/hello.txt","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src":"tests/testdata/hello.txt","type":"file","uid":null,"user":null}, -{"dest":"an_executable","gid":null,"group":null,"mode":"0755","origin":"@//tests:an_executable","src":"tests/an_executable","type":"file","uid":null,"user":null}, -{"dest":"mappings_test.bzl","gid":null,"group":null,"mode":"","origin":"@//tests/mappings:mappings_test.bzl","src":"tests/mappings/mappings_test.bzl","type":"file","uid":null,"user":null} -] diff --git a/tests/mappings/executable.manifest.windows.golden b/tests/mappings/executable.manifest.windows.golden deleted file mode 100644 index d853c0d..0000000 --- a/tests/mappings/executable.manifest.windows.golden +++ /dev/null @@ -1,7 +0,0 @@ -[ -{"dest":"an_executable.exe.runfiles/tests/BUILD","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src":"tests/BUILD","type":"file","uid":null,"user":null}, -{"dest":"an_executable.exe.runfiles/tests/an_executable.exe","gid":null,"group":null,"mode":"0755","origin":"@//tests:an_executable","src":"tests/an_executable.exe","type":"file","uid":null,"user":null}, -{"dest":"an_executable.exe.runfiles/tests/testdata/hello.txt","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src":"tests/testdata/hello.txt","type":"file","uid":null,"user":null}, -{"dest":"an_executable.exe","gid":null,"group":null,"mode":"0755","origin":"@//tests:an_executable","src":"tests/an_executable.exe","type":"file","uid":null,"user":null}, -{"dest":"mappings_test.bzl","gid":null,"group":null,"mode":"","origin":"@//tests/mappings:mappings_test.bzl","src":"tests/mappings/mappings_test.bzl","type":"file","uid":null,"user":null} -] diff --git a/tests/mappings/external_repo/WORKSPACE b/tests/mappings/external_repo/WORKSPACE deleted file mode 100644 index ff40799..0000000 --- a/tests/mappings/external_repo/WORKSPACE +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2021 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. - -workspace(name = "test_external_project") diff --git a/tests/mappings/external_repo/pkg/BUILD b/tests/mappings/external_repo/pkg/BUILD deleted file mode 100644 index 33db6a8..0000000 --- a/tests/mappings/external_repo/pkg/BUILD +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2021 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. - -load("@//pkg:mappings.bzl", "pkg_files", "strip_prefix") -load("@//pkg:tar.bzl", "pkg_tar") -load("@//pkg:verify_archive.bzl", "verify_archive_test") -load("@//tests/util:defs.bzl", "fake_artifact") -load("test.bzl", "test_referencing_remote_file") - -package(default_visibility = ["//visibility:public"]) - -exports_files( - glob(["**"]), -) - -fake_artifact( - name = "dir/script", - files = ["dir/extproj.sh"], - visibility = ["//visibility:public"], -) - -pkg_files( - name = "extproj_script_pf", - srcs = ["dir/extproj.sh"], - prefix = "usr/bin", - strip_prefix = strip_prefix.from_pkg(), - tags = ["manual"], -) - -test_referencing_remote_file( - name = "pf_local_file_in_extrepo", -) - -# Add a target to ensure verify_archive_test can be -# called from another workspace -pkg_tar( - name = "external_archive", - srcs = ["dir/extproj.sh"], -) - -verify_archive_test( - name = "external_archive_test", - max_size = 1, - min_size = 1, - must_contain = ["extproj.sh"], - target = ":external_archive", -) diff --git a/tests/mappings/external_repo/pkg/dir/extproj.sh b/tests/mappings/external_repo/pkg/dir/extproj.sh deleted file mode 100644 index 3d6f2af..0000000 --- a/tests/mappings/external_repo/pkg/dir/extproj.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# Copyright 2021 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. - -echo "External project script!" diff --git a/tests/mappings/external_repo/pkg/test.bzl b/tests/mappings/external_repo/pkg/test.bzl deleted file mode 100644 index c0a7713..0000000 --- a/tests/mappings/external_repo/pkg/test.bzl +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright 2021 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. - -"""Tests for file mapping routines in pkg/mappings.bzl. - -Test implementation copied from pkg/mappings.bzl - -""" - -load("@//pkg:mappings.bzl", "pkg_files", "strip_prefix") -load("@//pkg:providers.bzl", "PackageFilesInfo") -load("@bazel_skylib//lib:new_sets.bzl", "sets") -load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") - -#### BEGIN copied code - -def _pkg_files_contents_test_impl(ctx): - env = analysistest.begin(ctx) - target_under_test = analysistest.target_under_test(env) - - expected_dests = sets.make(ctx.attr.expected_dests) - actual_dests = sets.make(target_under_test[PackageFilesInfo].dest_src_map.keys()) - - asserts.new_set_equals(env, expected_dests, actual_dests, "pkg_files dests do not match expectations") - - return analysistest.end(env) - -pkg_files_contents_test = analysistest.make( - _pkg_files_contents_test_impl, - attrs = { - # Other attributes can be tested here, but the most important one is the - # destinations. - "expected_dests": attr.string_list( - mandatory = True, - ), - # attrs are always passed through unchanged (and maybe rejected) - }, -) - -#### END copied code - -# Called from the rules_pkg tests -def test_referencing_remote_file(name): - pkg_files( - name = "{}_g".format(name), - prefix = "usr/share", - srcs = ["@//tests:loremipsum_txt"], - # The prefix in rules_pkg. Why yes, this is knotty - strip_prefix = strip_prefix.from_root("tests"), - tags = ["manual"], - ) - - pkg_files_contents_test( - name = name, - target_under_test = ":{}_g".format(name), - expected_dests = ["usr/share/testdata/loremipsum.txt"], - ) diff --git a/tests/mappings/filter_directory/BUILD b/tests/mappings/filter_directory/BUILD deleted file mode 100644 index 4b0399b..0000000 --- a/tests/mappings/filter_directory/BUILD +++ /dev/null @@ -1,233 +0,0 @@ -# Copyright 2021 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. - -load("@rules_python//python:defs.bzl", "py_test") -load(":defs.bzl", "inspect_directory_test") -load("//pkg:mappings.bzl", "filter_directory") -load("//tests/util:defs.bzl", "directory") - -# TODO: the below tests only check for rule success and confirmation that -# directory structure matches expectations. A more thorough test implementation -# would also ensure that the contents also match expectations. - -############################################################################ -# Base case -############################################################################ - -package(default_applicable_licenses = ["//:license"]) - -inspect_directory_test( - name = "base", - directory = ":test_directory", - expected_structure = [ - "a", - "b", - "subdir/c", - "subdir/d", - ], -) - -############################################################################ -# Renames -############################################################################ - -inspect_directory_test( - name = "renames", - directory = ":renames_in", - expected_structure = [ - "b", - "c", - "subdir/a", - "subdir/d", - ], -) - -filter_directory( - name = "renames_in", - src = ":test_directory", - renames = { - "subdir/a": "a", - "c": "subdir/c", - }, -) - -inspect_directory_test( - name = "renames_loop", - directory = ":renames_loop_in", - expected_structure = [ - "a", - "b", - "subdir/c", - "subdir/d", - ], -) - -filter_directory( - name = "renames_loop_in", - src = ":test_directory", - renames = { - "subdir/c": "a", - "a": "subdir/c", - }, -) - -############################################################################ -# Prefix stripping -############################################################################ - -inspect_directory_test( - name = "strip_prefix", - directory = ":strip_prefix_in", - expected_structure = [ - "a", - "b", - "subdir/c", - "subdir/d", - ], -) - -filter_directory( - name = "strip_prefix_in", - src = ":test_directory_same_root", - strip_prefix = "root/", -) - -############################################################################ -# Prefixing -############################################################################ - -inspect_directory_test( - name = "prefix", - directory = ":prefix_in", - expected_structure = [ - "extra/a", - "extra/b", - "extra/subdir/c", - "extra/subdir/d", - ], -) - -filter_directory( - name = "prefix_in", - src = ":test_directory", - prefix = "extra/", -) - -############################################################################ -# Exclusions -############################################################################ - -inspect_directory_test( - name = "exclusions", - directory = ":exclusions_in", - expected_structure = [ - "a", - "subdir/c", - ], -) - -filter_directory( - name = "exclusions_in", - src = ":test_directory", - excludes = [ - "b", - "subdir/d", - ], -) - -############################################################################ -# Combinations -############################################################################ - -inspect_directory_test( - name = "combo_all", - directory = ":combo_all_in", - expected_structure = [ - "foo/root/not_a", - "foo/subdir/c", - ], -) - -filter_directory( - name = "combo_all_in", - src = ":test_directory_same_root", - excludes = [ - "root/b", - "root/subdir/d", - ], - prefix = "foo", - renames = {"root/not_a": "root/a"}, - strip_prefix = "root/", -) - -inspect_directory_test( - name = "combo_rename_to_exclude", - directory = ":combo_rename_to_exclude_in", - expected_structure = [ - "a", - "subdir/c", - "subdir/d", - ], -) - -filter_directory( - name = "combo_rename_to_exclude_in", - src = ":test_directory", - excludes = ["a"], - renames = {"a": "b"}, -) - -############################################################################ -# Inputs -############################################################################ - -directory( - name = "test_directory_same_root", - filenames = [ - "root/a", - "root/b", - "root/subdir/c", - "root/subdir/d", - ], -) - -directory( - name = "test_directory", - filenames = [ - "a", - "b", - "subdir/c", - "subdir/d", - ], -) - -############################################################################ -# Negative tests -############################################################################ - -# The filter_directory script has numerous failing edge cases that must be -# tested. We cannot test whether a build action failed without introducing -# test-related hacks into the `filter_directory` rule that captures the test -# outputs. - -# Given that the interface to filter_directory.py is close to the -# filter_directory rule, doing the tests in Python should suffice. It will also -# allow us to test some cases that might not be reachable from Bazel. -py_test( - name = "negative_tests", - srcs = ["test_filter_directory.py"], - data = ["//pkg:filter_directory"], - main = "test_filter_directory.py", - deps = ["@rules_python//python/runfiles"], -) diff --git a/tests/mappings/filter_directory/defs.bzl b/tests/mappings/filter_directory/defs.bzl deleted file mode 100644 index eb1dd62..0000000 --- a/tests/mappings/filter_directory/defs.bzl +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2021 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. - -"""Rules and macros to support testing rules that output directories.""" - -load("@rules_python//python:defs.bzl", "py_test") - -def _inspect_directory_script_impl(ctx): - script = ctx.actions.declare_file("{}.py".format(ctx.attr.name)) - ctx.actions.expand_template( - template = ctx.file._inspector_template, - output = script, - substitutions = { - "%EXPECTED_STRUCTURE%": json.encode(ctx.attr.expected_structure), - "%DIRECTORY_ROOT%": ctx.file.directory.short_path, - }, - ) - - return [DefaultInfo(files = depset([script]))] - -_inspect_directory_script = rule( - doc = """Create a script for testing the contents of directories.""", - implementation = _inspect_directory_script_impl, - attrs = { - "directory": attr.label( - mandatory = True, - allow_single_file = True, - ), - "expected_structure": attr.string_list( - mandatory = True, - ), - "_inspector_template": attr.label( - default = ":inspect_directory.py.tpl", - allow_single_file = True, - ), - }, -) - -def inspect_directory_test(name, directory, expected_structure, **kwargs): - script_name = name + "_script" - - _inspect_directory_script( - name = script_name, - directory = directory, - expected_structure = expected_structure, - ) - - # This appears to be necessary because of - # https://github.com/bazelbuild/bazel/issues/1147 - native.sh_library( - name = name + "_dir_lib", - srcs = [directory], - ) - - py_test( - name = name, - srcs = [":" + script_name], - main = ":" + script_name + ".py", - data = [name + "_dir_lib"], - deps = ["@rules_python//python/runfiles"], - **kwargs - ) diff --git a/tests/mappings/filter_directory/inspect_directory.py.tpl b/tests/mappings/filter_directory/inspect_directory.py.tpl deleted file mode 100644 index 938ddd7..0000000 --- a/tests/mappings/filter_directory/inspect_directory.py.tpl +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2021 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. - -import json -import os -import unittest -from rules_python.python.runfiles import runfiles - -DIRECTORY_ROOT = "%DIRECTORY_ROOT%" -# This is JSON, which shouldn't have any triple quotes in it. -EXPECTED_STRUCTURE = """%EXPECTED_STRUCTURE%""" - - -class DirectoryStructureTest(unittest.TestCase): - def setUp(self): - self.runfiles = runfiles.Create() - - def test_directory_structure_matches_global(self): - real_directory_root = self.runfiles.Rlocation( - os.path.join(os.environ["TEST_WORKSPACE"], DIRECTORY_ROOT) - ) - - # This may be a bazel bug -- shouldn't an empty directory be passed in - # anyway? - self.assertTrue( - os.path.isdir(real_directory_root), - "TreeArtifact root does not exist, is the input empty?", - ) - - expected_set = set(json.loads(EXPECTED_STRUCTURE)) - actual_set = set() - for root, dirs, files in os.walk(real_directory_root): - if root != real_directory_root: - rel_root = os.path.relpath(root, real_directory_root) - else: - # We are in the root. Don't bother with path relativization. - rel_root = '' - for f in files: - actual_set.add(os.path.join(rel_root, f)) - - self.assertEqual( - expected_set, - actual_set, - "Directory structure mismatch" - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/mappings/filter_directory/test_filter_directory.py b/tests/mappings/filter_directory/test_filter_directory.py deleted file mode 100644 index a63c20f..0000000 --- a/tests/mappings/filter_directory/test_filter_directory.py +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2021 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. - -"""Negative tests for the filter_directory script - -For a discussion as for why this needs to exist, see """ - -import pathlib -import os -import sys -import tempfile -import unittest - -from rules_python.python.runfiles import runfiles - -# Get the filter_directory script into the import path. There might be a -# better way to do this, but it works. - -rf = runfiles.Create() -filter_directory_script = rf.Rlocation('/'.join([ - os.environ["TEST_WORKSPACE"], - "pkg", - "filter_directory" -])) - -sys.path.append(os.path.dirname(filter_directory_script)) -import filter_directory # noqa: E402 - - -# TODO: These tests are largely to ensure that filter_directory fails, but it -# does not check _why_ they fail. -# -# This would involve changing how filter_directory returns errors, or maybe -# restructuring it to make it unit-testable. -# -# Regardless, this would be significantly more code, and is not yet attempted. -class FilterDirectoryInternalTest(unittest.TestCase): - - def setUp(self): - self.indir = tempfile.TemporaryDirectory(dir=os.environ["TEST_TMPDIR"]) - self.outdir = tempfile.TemporaryDirectory(dir=os.environ["TEST_TMPDIR"]) - indir_path = pathlib.Path(self.indir.name) - - (indir_path / "root").mkdir() - (indir_path / "root" / "a").open(mode='w').close() - (indir_path / "root" / "b").open(mode='w').close() - (indir_path / "root" / "subdir").mkdir() - (indir_path / "root" / "subdir" / "c").open(mode='w').close() - (indir_path / "root" / "subdir" / "d").open(mode='w').close() - - def tearDown(self): - self.indir.cleanup() - self.outdir.cleanup() - - ########################################################################### - # Test helpers - ########################################################################### - def callFilterDirectory(self, - prefix=None, # str - strip_prefix=None, # str - renames=None, # list of tuple - exclusions=None): # list - args = [] - if prefix: - args.append("--prefix={}".format(prefix)) - if strip_prefix: - args.append("--strip_prefix={}".format(prefix)) - if renames: - args.extend(["--rename={}={}".format(dest, src) for dest, src in renames]) - if exclusions: - args.extend(["--exclude={}".format(e) for e in exclusions]) - - args.append(self.indir.name) - args.append(self.outdir.name) - - try: - filter_directory.main(args) - return 0 # Success - except SystemExit as e: - return e.code - - def assertFilterDirectoryFails(self, message=None, **kwargs): - self.assertNotEqual(self.callFilterDirectory(**kwargs), 0, message) - - def assertFilterDirectorySucceeds(self, message=None, **kwargs): - self.assertEqual(self.callFilterDirectory(**kwargs), 0, message) - - ########################################################################### - # Actual tests - ########################################################################### - - def test_base(self): - # Simply verify that the "null" transformation works - self.assertFilterDirectorySucceeds() - - def test_invalid_prefixes(self): - self.assertFilterDirectoryFails( - prefix="/absolute/path", - message="--prefix with absolute paths should be rejected", - ) - - self.assertFilterDirectoryFails( - prefix="/absolute/path", - message="--prefix with paths outside the destroot should be rejected", - ) - - def test_invalid_strip_prefixes(self): - self.assertFilterDirectoryFails( - strip_prefix="invalid", - message="--strip_prefix that does not apply anywhere should be rejected", - ) - - self.assertFilterDirectoryFails( - strip_prefix="subdir", - message="--strip_prefix that does not apply everywhere should be rejected", - ) - - def test_invalid_excludes(self): - self.assertFilterDirectoryFails( - exclusions=["root/a", "foo"], - message="--exclude's that are unused should be rejected", - ) - - def test_invalid_renames(self): - self.assertFilterDirectoryFails( - renames=[("../outside", "root/a")], - message="--rename's with paths outside the destroot should be rejected", - ) - - # Can't rename files to outputs that already exist - self.assertFilterDirectoryFails( - renames=[("root/a", "root/subdir/c")], - message="--rename's that clobber other output files should be rejected", - ) - - # This is unreachable from the bazel rule, but it's worth double-checking. - # - # Can't rename multiple files to the same destination - self.assertFilterDirectoryFails( - renames=[("root/a", "root/subdir/c"), ("root/a", "root/subdir/d")], - message="Multiple --rename's to the same destination should be rejected.", - ) - - # Can't rename files twice - self.assertFilterDirectoryFails( - renames=[("bar", "root/a"), ("foo", "root/a")], - message="--rename's that attempt to rename the same source twice should be rejected", - ) - - def test_invalid_interactions(self): - # Renames are supposed to occur after exclusions, the rename here should - # thus be unused. - self.assertFilterDirectoryFails( - renames=[("foo", "root/a")], - exclusions=["root/a"], - message="--rename's of excluded files should be rejected", - ) - - # strip_prefix and renames can cause collisions, check that they they're - # detected. - self.assertFilterDirectoryFails( - strip_prefix="root", # valid - renames=[("a", "root/subdir/c")], # Since we're stripping "root/" - # from "root/a", this should - # cause an output collision. - message="--rename's to paths adjusted by strip_prefix should be rejected", - ) - -if __name__ == "__main__": - unittest.main() diff --git a/tests/mappings/glob_for_texts_manifest.golden b/tests/mappings/glob_for_texts_manifest.golden deleted file mode 100644 index 9ff7e21..0000000 --- a/tests/mappings/glob_for_texts_manifest.golden +++ /dev/null @@ -1,6 +0,0 @@ -[ - {"type": "file", "dest": "file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt", "src": "tests/testdata/file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:glob_for_texts"}, - {"type": "file", "dest": "hello.txt", "src": "tests/testdata/hello.txt", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:glob_for_texts"}, - {"type": "file", "dest": "loremipsum.txt", "src": "tests/testdata/loremipsum.txt", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:glob_for_texts"}, - {"type": "file", "dest": "test_tar_package_dir_file.txt", "src": "tests/testdata/test_tar_package_dir_file.txt", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:glob_for_texts"} -] diff --git a/tests/mappings/manifest_test_lib.py b/tests/mappings/manifest_test_lib.py deleted file mode 100644 index f403304..0000000 --- a/tests/mappings/manifest_test_lib.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright 2021 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. -"""Compare to content manifest files.""" - -import json -import unittest - -from bazel_tools.tools.python.runfiles import runfiles - -class ContentManifestTest(unittest.TestCase): - """Test harness to see if we wrote the content manifest correctly.""" - - run_files = runfiles.Create() - - def assertManifestsMatch(self, expected_path, got_path): - """Check two manifest files for equality. - - Args: - expected_path: The path to the content we expect. - got_path: The path to the content we got. - """ - e_file = ContentManifestTest.run_files.Rlocation('rules_pkg/' + expected_path) - with open(e_file, mode='rt', encoding='utf-8') as e_fp: - expected = json.loads(e_fp.read()) - expected_dict = {x['dest']: x for x in expected} - g_file = ContentManifestTest.run_files.Rlocation('rules_pkg/' + got_path) - with open(g_file, mode='rt', encoding='utf-8') as g_fp: - got = json.loads(g_fp.read()) - got_dict = {x['dest']: x for x in got} - # self.assertEqual(expected_dict, got_dict) - - ok = True - expected_dests = set(expected_dict.keys()) - got_dests = set(got_dict.keys()) - for dest, what in expected_dict.items(): - got = got_dict.get(dest) - if got: - self.assertDictEqual(what, got) - else: - print('Missing expected path "%s" in manifest' % dest) - ok = False - for dest, what in got_dict.items(): - expected = expected_dict.get(dest) - if expected: - self.assertDictEqual(expected, what) - else: - print('Got unexpected path "%s" in manifest:' % dest, what) - ok = False - - if not ok: - print('To update the golden file:') - print(' cp bazel-bin/%s %s' % (got_path, expected_path)) - print('or') - print('============= snip ==========') - print(got_dict.values()) - print('============= snip ==========') - self.assertTrue(ok) diff --git a/tests/mappings/manifest_test_main.py.tpl b/tests/mappings/manifest_test_main.py.tpl deleted file mode 100644 index c0e9960..0000000 --- a/tests/mappings/manifest_test_main.py.tpl +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2021 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. -"""Tests for generated content manifest.""" - -import unittest - -from tests.mappings import manifest_test_lib - -class ${TEST_NAME}(manifest_test_lib.ContentManifestTest): - - def test_match(self): - self.assertManifestsMatch('${EXPECTED}', '${TARGET}') - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/mappings/mappings_external_repo_test.bzl b/tests/mappings/mappings_external_repo_test.bzl deleted file mode 100644 index 09d0e67..0000000 --- a/tests/mappings/mappings_external_repo_test.bzl +++ /dev/null @@ -1,142 +0,0 @@ -# Copyright 2021 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. - -"""Tests for file mapping routines in pkg/mappings.bzl""" - -load("@bazel_skylib//lib:new_sets.bzl", "sets") -load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts", "unittest") -load(":mappings_test.bzl", "pkg_files_contents_test") -load("//pkg:providers.bzl", "PackageFilegroupInfo", "PackageFilesInfo") -load("//pkg:mappings.bzl", "pkg_files", "strip_prefix") - -########## -# pkg_files tests involving external repositories -########## - -# Tests involving external repositories -def _test_pkg_files_extrepo(): - # From external repo root, basenames only - pkg_files( - name = "pf_extrepo_strip_all_g", - srcs = ["@mappings_test_external_repo//pkg:dir/script"], - tags = ["manual"], - ) - - pkg_files_contents_test( - name = "pf_extrepo_strip_all", - target_under_test = ":pf_extrepo_strip_all_g", - expected_dests = ["extproj.sh", "script"], - ) - - # From external repo root, relative to the "pkg" package - pkg_files( - name = "pf_extrepo_strip_from_pkg_g", - srcs = ["@mappings_test_external_repo//pkg:dir/script"], - strip_prefix = strip_prefix.from_pkg("dir"), - tags = ["manual"], - ) - pkg_files_contents_test( - name = "pf_extrepo_strip_from_pkg", - target_under_test = ":pf_extrepo_strip_from_pkg_g", - expected_dests = [ - "extproj.sh", - "script", - ], - ) - - # From external repo root, relative to the "pkg" directory - pkg_files( - name = "pf_extrepo_strip_from_root_g", - srcs = ["@mappings_test_external_repo//pkg:dir/script"], - strip_prefix = strip_prefix.from_root("pkg"), - tags = ["manual"], - ) - pkg_files_contents_test( - name = "pf_extrepo_strip_from_root", - target_under_test = ":pf_extrepo_strip_from_root_g", - expected_dests = ["dir/extproj.sh", "dir/script"], - ) - - native.filegroup( - name = "extrepo_test_fg", - srcs = ["@mappings_test_external_repo//pkg:dir/extproj.sh"], - ) - - # Test the case when a have a pkg_files that targets a local filegroup - # that has files in an external repo. - pkg_files( - name = "pf_extrepo_filegroup_strip_from_pkg_g", - srcs = [":extrepo_test_fg"], - # Files within filegroups should be considered relative to their - # destination paths. - strip_prefix = strip_prefix.from_pkg(""), - ) - pkg_files_contents_test( - name = "pf_extrepo_filegroup_strip_from_pkg", - target_under_test = ":pf_extrepo_filegroup_strip_from_pkg_g", - expected_dests = ["dir/extproj.sh"], - ) - - # Ditto, except strip from the workspace root instead - pkg_files( - name = "pf_extrepo_filegroup_strip_from_root_g", - srcs = [":extrepo_test_fg"], - # Files within filegroups should be considered relative to their - # destination paths. - strip_prefix = strip_prefix.from_root("pkg"), - ) - pkg_files_contents_test( - name = "pf_extrepo_filegroup_strip_from_root", - target_under_test = ":pf_extrepo_filegroup_strip_from_root_g", - expected_dests = ["dir/extproj.sh"], - ) - - # Reference a pkg_files in @mappings_test_external_repo - pkg_files_contents_test( - name = "pf_pkg_files_in_extrepo", - target_under_test = "@mappings_test_external_repo//pkg:extproj_script_pf", - expected_dests = ["usr/bin/dir/extproj.sh"], - ) - -def mappings_external_repo_analysis_tests(): - """Declare mappings.bzl analysis tests""" - _test_pkg_files_extrepo() - - native.test_suite( - name = "pkg_files_external_repo_analysis_tests", - # We should find a way to get rid of this test list; it would be nice if - # it could be derived from something else... - tests = [ - # buildifier: don't sort - # Tests involving external repositories - ":pf_extrepo_strip_all", - ":pf_extrepo_strip_from_pkg", - ":pf_extrepo_strip_from_root", - ":pf_extrepo_filegroup_strip_from_pkg", - ":pf_extrepo_filegroup_strip_from_root", - ":pf_pkg_files_in_extrepo", - ":pf_file_rename_to_empty", - ":pf_directory_rename_to_empty", - # This one fits into the same category, but can't be aliased, apparently. - # - # The main purpose behind it is to verify cases wherein we build a - # file, but then have it consumed by some remote package. - "@mappings_test_external_repo//pkg:pf_local_file_in_extrepo", - # This test is more focused around the verify_archive_test repo but is still - # based on using someting from another repo. In particular, ensuring the - # verify_archive_test macro can be called properly from a workspace outside - # of the main one. - "@mappings_test_external_repo//pkg:external_archive_test", - ], - ) diff --git a/tests/mappings/mappings_test.bzl b/tests/mappings/mappings_test.bzl deleted file mode 100644 index fcb4639..0000000 --- a/tests/mappings/mappings_test.bzl +++ /dev/null @@ -1,1002 +0,0 @@ -# Copyright 2021 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. - -"""Tests for file mapping routines in pkg/mappings.bzl""" - -load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts", "unittest") -load( - "//pkg:providers.bzl", - "PackageDirsInfo", - "PackageFilegroupInfo", - "PackageFilesInfo", - "PackageSymlinkInfo", -) -load( - "//pkg:mappings.bzl", - "REMOVE_BASE_DIRECTORY", - "pkg_attributes", - "pkg_filegroup", - "pkg_files", - "pkg_mkdirs", - "pkg_mklink", - "strip_prefix", -) -load( - "//tests/util:defs.bzl", - "directory", - "fake_artifact", - "generic_base_case_test", - "generic_negative_test", -) -load("@bazel_skylib//lib:new_sets.bzl", "sets") -load("@rules_python//python:defs.bzl", "py_test") - -########## -# Helpers -########## - -def _flatten(list_of_lists): - """Transform a list of lists into a single list, preserving relative order.""" - return [item for sublist in list_of_lists for item in sublist] - -########## -# pkg_files tests -########## - -def _pkg_files_contents_test_impl(ctx): - env = analysistest.begin(ctx) - target_under_test = analysistest.target_under_test(env) - - expected_dests = {e: None for e in ctx.attr.expected_dests} - n_found = 0 - for got in target_under_test[PackageFilesInfo].dest_src_map.keys(): - asserts.true( - got in expected_dests, - "got <%s> not in expected set: %s" % (got, ctx.attr.expected_dests), - ) - n_found += 1 - asserts.equals(env, len(expected_dests), n_found) - - # Simple equality checks for the others, if specified - if ctx.attr.expected_attributes: - asserts.equals( - env, - json.decode(ctx.attr.expected_attributes), - target_under_test[PackageFilesInfo].attributes, - "pkg_files attributes do not match expectations", - ) - - # TODO(nacl): verify DefaultInfo propagation - - return analysistest.end(env) - -pkg_files_contents_test = analysistest.make( - _pkg_files_contents_test_impl, - attrs = { - # Other attributes can be tested here, but the most important one is the - # destinations. - "expected_dests": attr.string_list( - mandatory = True, - ), - "expected_attributes": attr.string(), - }, -) - -def _test_pkg_files_contents(): - # Test stripping when no arguments are provided (same as strip_prefix.files_only()) - pkg_files( - name = "pf_no_strip_prefix_g", - srcs = ["testdata/hello.txt"], - attributes = pkg_attributes( - mode = "0755", - user = "foo", - group = "bar", - # kwargs begins here - foo = "bar", - ), - tags = ["manual"], - ) - - pkg_files_contents_test( - name = "pf_no_strip_prefix", - target_under_test = ":pf_no_strip_prefix_g", - expected_dests = ["hello.txt"], - expected_attributes = pkg_attributes( - mode = "0755", - user = "foo", - group = "bar", - foo = "bar", - ), - ) - - # And now, files_only = True - pkg_files( - name = "pf_files_only_g", - srcs = ["testdata/hello.txt"], - strip_prefix = strip_prefix.files_only(), - tags = ["manual"], - ) - - pkg_files_contents_test( - name = "pf_files_only", - target_under_test = ":pf_files_only_g", - expected_dests = ["hello.txt"], - ) - - # Used in the following tests - fake_artifact( - name = "testdata/test_script", - files = ["testdata/a_script.sh"], - tags = ["manual"], - ) - - # Test stripping from the package root - pkg_files( - name = "pf_from_pkg_g", - srcs = [ - "testdata/hello.txt", - ":testdata/test_script", - ], - strip_prefix = strip_prefix.from_pkg("testdata/"), - tags = ["manual"], - ) - - pkg_files_contents_test( - name = "pf_strip_testdata_from_pkg", - target_under_test = ":pf_from_pkg_g", - expected_dests = [ - # Static file - "hello.txt", - # The script itself - "a_script.sh", - # The generated target output, in this case, a symlink - "test_script", - ], - ) - - # Test the stripping from root. - # - # In this case, the components to be stripped are taken relative to the root - # of the package. Local and generated files should have the same prefix in - # all cases. - - pkg_files( - name = "pf_from_root_g", - srcs = [":testdata/test_script"], - strip_prefix = strip_prefix.from_root("tests/mappings"), - tags = ["manual"], - ) - - pkg_files_contents_test( - name = "pf_strip_prefix_from_root", - target_under_test = ":pf_from_root_g", - expected_dests = [ - # The script itself - "testdata/a_script.sh", - # The generated target output, in this case, a symlink - "testdata/test_script", - ], - ) - - # Test that the default mode (0644) is always set regardless of the other - # values in "attributes". - pkg_files( - name = "pf_attributes_mode_overlay_if_not_provided_g", - srcs = ["foo"], - strip_prefix = strip_prefix.from_pkg(), - attributes = pkg_attributes( - user = "foo", - group = "bar", - foo = "bar", - ), - tags = ["manual"], - ) - pkg_files_contents_test( - name = "pf_attributes_mode_overlay_if_not_provided", - target_under_test = ":pf_attributes_mode_overlay_if_not_provided_g", - expected_dests = ["foo"], - expected_attributes = pkg_attributes( - mode = "0644", - user = "foo", - group = "bar", - foo = "bar", - ), - ) - - # Test that pkg_files rejects cases where two targets resolve to the same - # destination. - pkg_files( - name = "pf_destination_collision_invalid_g", - srcs = ["foo", "bar/foo"], - tags = ["manual"], - ) - generic_negative_test( - name = "pf_destination_collision_invalid", - target_under_test = ":pf_destination_collision_invalid_g", - ) - - # Test strip_prefix when it can't complete the strip operation as requested. - pkg_files( - name = "pf_strip_prefix_from_package_invalid_g", - srcs = ["foo/foo", "bar/foo"], - strip_prefix = strip_prefix.from_pkg("bar"), - tags = ["manual"], - ) - generic_negative_test( - name = "pf_strip_prefix_from_package_invalid", - target_under_test = ":pf_strip_prefix_from_package_invalid_g", - ) - - # Ditto, except strip from the root. - pkg_files( - name = "pf_strip_prefix_from_root_invalid_g", - srcs = ["foo", "bar"], - strip_prefix = strip_prefix.from_root("not/the/root"), - tags = ["manual"], - ) - generic_negative_test( - name = "pf_strip_prefix_from_root_invalid", - target_under_test = ":pf_strip_prefix_from_root_invalid_g", - ) - -def _test_pkg_files_exclusions(): - # Normal filegroup, used in all of the below tests - # - # Needs to be here to test the distinction between files and label inputs to - # "excludes". This, admittedly, may be unnecessary. - native.filegroup( - name = "test_base_fg", - srcs = [ - "testdata/config", - "testdata/hello.txt", - ], - ) - - # Tests to exclude from the case where stripping is done up to filenames - pkg_files( - name = "pf_exclude_by_label_strip_all_g", - srcs = [":test_base_fg"], - excludes = ["//tests/mappings:testdata/config"], - tags = ["manual"], - ) - pkg_files_contents_test( - name = "pf_exclude_by_label_strip_all", - target_under_test = ":pf_exclude_by_label_strip_all_g", - expected_dests = ["hello.txt"], - ) - - pkg_files( - name = "pf_exclude_by_filename_strip_all_g", - srcs = [":test_base_fg"], - excludes = ["testdata/config"], - tags = ["manual"], - ) - pkg_files_contents_test( - name = "pf_exclude_by_filename_strip_all", - target_under_test = ":pf_exclude_by_filename_strip_all_g", - expected_dests = ["hello.txt"], - ) - - # Tests to exclude from the case where stripping is done from the package root - pkg_files( - name = "pf_exclude_by_label_strip_from_pkg_g", - srcs = [":test_base_fg"], - excludes = ["//tests/mappings:testdata/config"], - strip_prefix = strip_prefix.from_pkg("testdata"), - tags = ["manual"], - ) - pkg_files_contents_test( - name = "pf_exclude_by_label_strip_from_pkg", - target_under_test = ":pf_exclude_by_label_strip_from_pkg_g", - expected_dests = ["hello.txt"], - ) - - pkg_files( - name = "pf_exclude_by_filename_strip_from_pkg_g", - srcs = [":test_base_fg"], - excludes = ["testdata/config"], - strip_prefix = strip_prefix.from_pkg("testdata"), - tags = ["manual"], - ) - pkg_files_contents_test( - name = "pf_exclude_by_filename_strip_from_pkg", - target_under_test = ":pf_exclude_by_filename_strip_from_pkg_g", - expected_dests = ["hello.txt"], - ) - - # Tests to exclude from the case where stripping is done from the root - pkg_files( - name = "pf_exclude_by_label_strip_from_root_g", - srcs = [":test_base_fg"], - excludes = ["//tests/mappings:testdata/config"], - strip_prefix = strip_prefix.from_root("tests/mappings"), - tags = ["manual"], - ) - pkg_files_contents_test( - name = "pf_exclude_by_label_strip_from_root", - target_under_test = ":pf_exclude_by_label_strip_from_root_g", - expected_dests = ["testdata/hello.txt"], - ) - - pkg_files( - name = "pf_exclude_by_filename_strip_from_root_g", - srcs = [":test_base_fg"], - excludes = ["testdata/config"], - strip_prefix = strip_prefix.from_root("tests/mappings"), - tags = ["manual"], - ) - pkg_files_contents_test( - name = "pf_exclude_by_filename_strip_from_root", - target_under_test = ":pf_exclude_by_filename_strip_from_root_g", - expected_dests = ["testdata/hello.txt"], - ) - -def _test_pkg_files_rename(): - pkg_files( - name = "pf_rename_multiple_g", - srcs = [ - "testdata/hello.txt", - "testdata/loremipsum.txt", - ], - prefix = "usr", - renames = { - "testdata/hello.txt": "share/goodbye.txt", - "testdata/loremipsum.txt": "doc/dolorsitamet.txt", - }, - tags = ["manual"], - ) - pkg_files_contents_test( - name = "pf_rename_multiple", - target_under_test = ":pf_rename_multiple_g", - expected_dests = [ - "usr/share/goodbye.txt", - "usr/doc/dolorsitamet.txt", - ], - ) - - # Used in the following tests - fake_artifact( - name = "test_script_rename", - files = ["testdata/a_script.sh"], - tags = ["manual"], - ) - - # test_script_rename produces multiple outputs. Thus, this test should - # fail, as pkg_files can't figure out what should actually be mapped to - # the output destination. - pkg_files( - name = "pf_rename_rule_with_multiple_outputs_g", - srcs = ["test_script_rename"], - renames = { - ":test_script_rename": "still_a_script", - }, - tags = ["manual"], - ) - generic_negative_test( - name = "pf_rename_rule_with_multiple_outputs", - target_under_test = ":pf_rename_rule_with_multiple_outputs_g", - ) - - # Fail because we tried to install a file that wasn't mentioned in the deps - # list - pkg_files( - name = "pf_rename_single_missing_value_g", - srcs = ["testdata/hello.txt"], - prefix = "usr", - renames = { - "a_script": "an_output_location", - }, - tags = ["manual"], - ) - generic_negative_test( - name = "pf_rename_single_missing_value", - target_under_test = ":pf_rename_single_missing_value_g", - ) - - # Ditto, except for exclusions - pkg_files( - name = "pf_rename_single_excluded_value_g", - srcs = [ - "testdata/hello.txt", - "testdata/loremipsum.txt", - ], - prefix = "usr", - excludes = [ - "testdata/hello.txt", - ], - renames = { - "testdata/hello.txt": "share/goodbye.txt", - }, - tags = ["manual"], - ) - generic_negative_test( - name = "pf_rename_single_excluded_value", - target_under_test = ":pf_rename_single_excluded_value_g", - ) - - # Test whether or not destination collisions are detected after renaming. - pkg_files( - name = "pf_rename_destination_collision_g", - srcs = [ - "foo", - "bar", - ], - renames = {"foo": "bar"}, - tags = ["manual"], - ) - generic_negative_test( - name = "pf_rename_destination_collision", - target_under_test = ":pf_rename_destination_collision_g", - ) - - # Test that we are *not* allowed to rename a file to nothing - pkg_files( - name = "pf_file_rename_to_empty_g", - srcs = ["foo"], - renames = {"foo": REMOVE_BASE_DIRECTORY}, - tags = ["manual"], - ) - generic_negative_test( - name = "pf_file_rename_to_empty", - target_under_test = ":pf_file_rename_to_empty_g", - ) - - # Test that we are allowed to rename a directory to nothing (to "strip" it) - directory( - name = "a_directory", - filenames = ["a_file"], - tags = ["manual"], - ) - pkg_files( - name = "pf_directory_rename_to_empty_g", - srcs = [":a_directory"], - renames = {":a_directory": REMOVE_BASE_DIRECTORY}, - tags = ["manual"], - ) - generic_base_case_test( - name = "pf_directory_rename_to_empty", - target_under_test = ":pf_directory_rename_to_empty_g", - ) - -########## -# Test pkg_mkdirs -########## - -def _pkg_mkdirs_contents_test_impl(ctx): - env = analysistest.begin(ctx) - target_under_test = analysistest.target_under_test(env) - - expected_dirs = sets.make(ctx.attr.expected_dirs) - actual_dirs = sets.make(target_under_test[PackageDirsInfo].dirs) - - asserts.new_set_equals(env, expected_dirs, actual_dirs, "pkg_mkdirs dirs do not match expectations") - - # Simple equality checks for the others - if ctx.attr.expected_attributes != None: - asserts.equals( - env, - json.decode(ctx.attr.expected_attributes), - target_under_test[PackageDirsInfo].attributes, - "pkg_mkdir attributes do not match expectations", - ) - - return analysistest.end(env) - -pkg_mkdirs_contents_test = analysistest.make( - _pkg_mkdirs_contents_test_impl, - attrs = { - "expected_attributes": attr.string(), - "expected_dirs": attr.string_list( - mandatory = True, - ), - }, -) - -def _test_pkg_mkdirs(): - # Reasonable base case - pkg_mkdirs( - name = "pkg_mkdirs_base_g", - dirs = ["foo/bar", "baz"], - attributes = pkg_attributes( - mode = "0711", - user = "root", - group = "sudo", - ), - tags = ["manual"], - ) - pkg_mkdirs_contents_test( - name = "pkg_mkdirs_base", - target_under_test = ":pkg_mkdirs_base_g", - expected_dirs = ["foo/bar", "baz"], - expected_attributes = pkg_attributes( - mode = "0711", - user = "root", - group = "sudo", - ), - ) - - # Test that the default mode (0755) is always set regardless of the other - # values in "attributes". - pkg_mkdirs( - name = "pkg_mkdirs_mode_overlay_if_not_provided_g", - dirs = ["foo"], - attributes = pkg_attributes( - user = "root", - group = "sudo", - ), - tags = ["manual"], - ) - pkg_mkdirs_contents_test( - name = "pkg_mkdirs_mode_overlay_if_not_provided", - target_under_test = ":pkg_mkdirs_mode_overlay_if_not_provided_g", - expected_dirs = ["foo"], - expected_attributes = pkg_attributes( - mode = "0755", - user = "root", - group = "sudo", - ), - ) - -########## -# Test pkg_mklink -########## -def _pkg_mklink_contents_test_impl(ctx): - env = analysistest.begin(ctx) - target_under_test = analysistest.target_under_test(env) - - asserts.equals( - env, - ctx.attr.expected_target, - target_under_test[PackageSymlinkInfo].target, - "pkg_mklink target does not match expectations", - ) - - asserts.equals( - env, - ctx.attr.expected_link_name, - target_under_test[PackageSymlinkInfo].destination, - "pkg_mklink destination does not match expectations", - ) - - # Simple equality checks for the others, if specified - if ctx.attr.expected_attributes: - asserts.equals( - env, - json.decode(ctx.attr.expected_attributes), - target_under_test[PackageSymlinkInfo].attributes, - "pkg_mklink attributes do not match expectations", - ) - - return analysistest.end(env) - -pkg_mklink_contents_test = analysistest.make( - _pkg_mklink_contents_test_impl, - attrs = { - "expected_attributes": attr.string(), - "expected_link_name": attr.string(mandatory = True), - "expected_target": attr.string(mandatory = True), - }, -) - -def _test_pkg_mklink(): - pkg_mklink( - name = "pkg_mklink_base_g", - link_name = "foo", - target = "bar", - tags = ["manual"], - attributes = pkg_attributes(mode = "0111"), - ) - - pkg_mklink_contents_test( - name = "pkg_mklink_base", - target_under_test = ":pkg_mklink_base_g", - expected_link_name = "foo", - expected_target = "bar", - expected_attributes = pkg_attributes(mode = "0111"), - ) - - # Test that the default mode (0755) is always set regardless of the other - # values in "attributes". - pkg_mklink( - name = "pkg_mklink_mode_overlay_if_not_provided_g", - link_name = "foo", - target = "bar", - attributes = pkg_attributes( - user = "root", - group = "sudo", - ), - tags = ["manual"], - ) - pkg_mklink_contents_test( - name = "pkg_mklink_mode_overlay_if_not_provided", - target_under_test = ":pkg_mklink_mode_overlay_if_not_provided_g", - expected_link_name = "foo", - expected_target = "bar", - expected_attributes = pkg_attributes( - mode = "0777", - user = "root", - group = "sudo", - ), - ) - -############################################################ -# Test pkg_filegroup -############################################################ -def _pkg_filegroup_contents_test_impl(ctx): - env = analysistest.begin(ctx) - target_under_test = analysistest.target_under_test(env) - - asserts.equals( - env, - [t[PackageFilesInfo] for t in ctx.attr.expected_pkg_files], - [info for info, _ in target_under_test[PackageFilegroupInfo].pkg_files], - "pkg_filegroup file list does not match expectations", - ) - if ctx.attr.verify_origins: - asserts.equals( - env, - [t.label for t in ctx.attr.expected_pkg_files], - [origin for _, origin in target_under_test[PackageFilegroupInfo].pkg_files], - "pkg_filegroup file origin list does not match expectations", - ) - - asserts.equals( - env, - [t[PackageDirsInfo] for t in ctx.attr.expected_pkg_dirs], - [info for info, _ in target_under_test[PackageFilegroupInfo].pkg_dirs], - "pkg_filegroup directory list does not match expectations", - ) - if ctx.attr.verify_origins: - asserts.equals( - env, - [t.label for t in ctx.attr.expected_pkg_dirs], - [origin for _, origin in target_under_test[PackageFilegroupInfo].pkg_dirs], - "pkg_filegroup directory origin list does not match expectations", - ) - - asserts.equals( - env, - [t[PackageSymlinkInfo] for t in ctx.attr.expected_pkg_symlinks], - [info for info, _ in target_under_test[PackageFilegroupInfo].pkg_symlinks], - "pkg_filegroup symlink map does not match expectations", - ) - if ctx.attr.verify_origins: - asserts.equals( - env, - [t.label for t in ctx.attr.expected_pkg_symlinks], - [origin for _, origin in target_under_test[PackageFilegroupInfo].pkg_symlinks], - "pkg_filegroup symlink origin list does not match expectations", - ) - - # Verify that the DefaultInfo is propagated properly out of the input - # pkg_files's -- these are the files that need to be passed along to the - # packaging rules. - expected_packaged_files = sorted(_flatten([ - t[DefaultInfo].files.to_list() - for t in ctx.attr.expected_pkg_files - ])) - packaged_files = sorted(target_under_test[DefaultInfo].files.to_list()) - - asserts.equals( - env, - expected_packaged_files, - packaged_files, - "pkg_filegroup does not propagate DefaultInfo from pkg_file inputs", - ) - - return analysistest.end(env) - -pkg_filegroup_contents_test = analysistest.make( - _pkg_filegroup_contents_test_impl, - attrs = { - "expected_pkg_files": attr.label_list( - providers = [PackageFilesInfo], - default = [], - ), - "expected_pkg_dirs": attr.label_list( - providers = [PackageDirsInfo], - default = [], - ), - "expected_pkg_symlinks": attr.label_list( - providers = [PackageSymlinkInfo], - default = [], - ), - "verify_origins": attr.bool( - default = True, - ), - }, -) - -def _test_pkg_filegroup(name): - pkg_files( - name = "{}_pkg_files".format(name), - srcs = ["foo", "bar"], - prefix = "bin", - tags = ["manual"], - ) - - pkg_mkdirs( - name = "{}_pkg_dirs".format(name), - dirs = ["etc"], - tags = ["manual"], - ) - - pkg_mklink( - name = "{}_pkg_symlink".format(name), - link_name = "dest", - target = "src", - tags = ["manual"], - ) - - pkg_filegroup( - name = "{}_pfg".format(name), - srcs = [t.format(name) for t in ["{}_pkg_files", "{}_pkg_dirs", "{}_pkg_symlink"]], - tags = ["manual"], - ) - - pkg_filegroup( - name = "{}_pfg_nested".format(name), - srcs = [":{}_pfg".format(name)], - tags = ["manual"], - ) - - # Base case: confirm that basic data translation is working - pkg_filegroup_contents_test( - name = "{}_contents_valid".format(name), - target_under_test = "{}_pfg".format(name), - expected_pkg_files = ["{}_pkg_files".format(name)], - expected_pkg_dirs = ["{}_pkg_dirs".format(name)], - expected_pkg_symlinks = ["{}_pkg_symlink".format(name)], - ) - - # Base case': ditto for nested `pkg_filegroup`s. - pkg_filegroup_contents_test( - name = "{}_nested_contents_valid".format(name), - target_under_test = "{}_pfg_nested".format(name), - expected_pkg_files = ["{}_pkg_files".format(name)], - expected_pkg_dirs = ["{}_pkg_dirs".format(name)], - expected_pkg_symlinks = ["{}_pkg_symlink".format(name)], - # See below re: "The origins for everything will be wrong here...". - verify_origins = False, - ) - - ################################################## - - pkg_files( - name = "{}_pkg_files_prefixed".format(name), - srcs = ["foo", "bar"], - prefix = "prefix/bin", - tags = ["manual"], - ) - - pkg_mkdirs( - name = "{}_pkg_dirs_prefixed".format(name), - dirs = ["prefix/etc"], - tags = ["manual"], - ) - - pkg_mklink( - name = "{}_pkg_symlink_prefixed".format(name), - link_name = "prefix/dest", - target = "src", - tags = ["manual"], - ) - - # Test that prefixing works by using the unprefixed mapping rules we - # initially created, and set a prefix. - pkg_filegroup( - name = "{}_prefixed_pfg".format(name), - srcs = [t.format(name) for t in ["{}_pkg_files", "{}_pkg_dirs", "{}_pkg_symlink"]], - prefix = "prefix", - tags = ["manual"], - ) - - # Then test that the results are equivalent to manually specifying the - # prefix everywhere. - pkg_filegroup_contents_test( - name = "{}_contents_prefix_translated".format(name), - target_under_test = "{}_prefixed_pfg".format(name), - expected_pkg_files = ["{}_pkg_files_prefixed".format(name)], - expected_pkg_dirs = ["{}_pkg_dirs_prefixed".format(name)], - expected_pkg_symlinks = ["{}_pkg_symlink_prefixed".format(name)], - # The origins for everything will be wrong here, since they're derived - # from the labels of the inputs to pkg_filegroup. - # - # The first test here should be adequate for this purpose. - verify_origins = False, - ) - - # Now do the same for a nested `pkg_filegroup`. - pkg_files( - name = "{}_pkg_files_nested_prefixed".format(name), - srcs = ["foo", "bar"], - prefix = "nest/prefix/bin", - tags = ["manual"], - ) - - pkg_mkdirs( - name = "{}_pkg_dirs_nested_prefixed".format(name), - dirs = ["nest/prefix/etc"], - tags = ["manual"], - ) - - pkg_mklink( - name = "{}_pkg_symlink_nested_prefixed".format(name), - link_name = "nest/prefix/dest", - target = "src", - tags = ["manual"], - ) - - pkg_filegroup( - name = "{}_nested_prefixed_pfg".format(name), - srcs = [":{}_prefixed_pfg".format(name)], - prefix = "nest", - tags = ["manual"], - ) - - pkg_filegroup_contents_test( - name = "{}_contents_nested_prefix_translated".format(name), - target_under_test = "{}_nested_prefixed_pfg".format(name), - expected_pkg_files = ["{}_pkg_files_nested_prefixed".format(name)], - expected_pkg_dirs = ["{}_pkg_dirs_nested_prefixed".format(name)], - expected_pkg_symlinks = ["{}_pkg_symlink_nested_prefixed".format(name)], - # See above re: "The origins for everything will be wrong here...". - verify_origins = False, - ) - - native.test_suite( - name = name, - tests = [ - t.format(name) - for t in [ - "{}_contents_valid", - "{}_nested_contents_valid", - "{}_contents_prefix_translated", - "{}_contents_nested_prefix_translated", - ] - ], - ) - -########## -# Test strip_prefix pseudo-module -########## - -def _strip_prefix_test_impl(ctx): - env = unittest.begin(ctx) - asserts.equals(env, ".", strip_prefix.files_only()) - asserts.equals(env, "path", strip_prefix.from_pkg("path")) - asserts.equals(env, "path", strip_prefix.from_pkg("/path")) - asserts.equals(env, "/path", strip_prefix.from_root("path")) - asserts.equals(env, "/path", strip_prefix.from_root("/path")) - return unittest.end(env) - -strip_prefix_test = unittest.make(_strip_prefix_test_impl) - -def mappings_analysis_tests(): - """Declare mappings.bzl analysis tests""" - _test_pkg_files_contents() - _test_pkg_files_exclusions() - _test_pkg_files_rename() - _test_pkg_mkdirs() - _test_pkg_mklink() - - # TODO(nacl) migrate the above to use a scheme the one used here. At the very - # least, the test suites should be easy to find/name. - _test_pkg_filegroup(name = "pfg_tests") - - native.test_suite( - name = "pkg_files_analysis_tests", - # We should find a way to get rid of this test list; it would be nice if - # it could be derived from something else... - tests = [ - # buildifier: don't sort - # Simple tests - ":pf_no_strip_prefix", - ":pf_files_only", - ":pf_strip_testdata_from_pkg", - ":pf_strip_prefix_from_root", - ":pf_attributes_mode_overlay_if_not_provided", - # Tests involving excluded files - ":pf_exclude_by_label_strip_all", - ":pf_exclude_by_filename_strip_all", - ":pf_exclude_by_label_strip_from_pkg", - ":pf_exclude_by_filename_strip_from_pkg", - ":pf_exclude_by_label_strip_from_root", - ":pf_exclude_by_filename_strip_from_root", - # Negative tests - ":pf_destination_collision_invalid", - ":pf_strip_prefix_from_package_invalid", - ":pf_strip_prefix_from_root_invalid", - # - # Tests involving file renaming - ":pf_rename_multiple", - ":pf_rename_rule_with_multiple_outputs", - ":pf_rename_single_missing_value", - ":pf_rename_single_excluded_value", - # Tests involving pkg_mkdirs - ":pkg_mkdirs_base", - ":pkg_mkdirs_mode_overlay_if_not_provided", - # Tests involving pkg_mklink - ":pkg_mklink_base", - ":pkg_mklink_mode_overlay_if_not_provided", - # Tests involving pkg_filegroup - ":pfg_tests", - ], - ) - -def mappings_unit_tests(): - unittest.suite( - "mappings_unit_tests", - strip_prefix_test, - ) - -def _gen_manifest_test_main_impl(ctx): - ctx.actions.expand_template( - template = ctx.file._template, - output = ctx.outputs.out, - substitutions = { - "${EXPECTED}": ctx.files.expected[0].short_path, - "${TARGET}": ctx.files.target[0].short_path, - "${TEST_NAME}": ctx.attr.test_name, - }, - ) - return [ - DefaultInfo(files = depset([ctx.outputs.out])), - ] - -_gen_manifest_test_main = rule( - implementation = _gen_manifest_test_main_impl, - attrs = { - "out": attr.output(mandatory = True), - "expected": attr.label(mandatory = True, allow_single_file = True), - "target": attr.label(mandatory = True, allow_single_file = True), - "test_name": attr.string(mandatory = True), - "_template": attr.label( - default = Label("//tests/mappings:manifest_test_main.py.tpl"), - allow_single_file = True, - ), - }, -) - -def manifest_golden_test(name, target, expected): - """Tests that a content manifest file matches a golden copy. - - This test is used to verify that a generated manifest file matches the - expected content. - - Args: - target: A target which produces a content manifest with the name - <target> + ".manifest" - expected: label of a file containing the expected content. - """ - _gen_manifest_test_main( - name = name + "_main", - out = name + ".py", - expected = expected, - target = target + ".manifest", - test_name = target + "Test", - ) - py_test( - name = name, - srcs = [":" + name + ".py"], - data = [ - ":" + target, - ":" + target + ".manifest", - expected, - ], - python_version = "PY3", - deps = [ - ":manifest_test_lib", - ], - ) diff --git a/tests/mappings/node_modules_manifest.golden b/tests/mappings/node_modules_manifest.golden deleted file mode 100755 index b234629..0000000 --- a/tests/mappings/node_modules_manifest.golden +++ /dev/null @@ -1,9 +0,0 @@ -[ - {"type": "symlink", "dest": "node_modules/.pnpm/bar@1.0.0/node_modules/bar", "src": "STORE/bar", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/.pnpm/bar@1.0.0/node_modules/qar", "src": "../../qar@2.0.0/node_modules/qar", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/.pnpm/foo@1.0.0/node_modules/bar", "src": "../../bar@1.0.0/node_modules/bar", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/.pnpm/foo@1.0.0/node_modules/foo", "src": "STORE/foo", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/.pnpm/foo@1.0.0/node_modules/qar", "src": "../../qar@2.0.0/node_modules/qar", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/.pnpm/qar@2.0.0/node_modules/qar", "src": "STORE/qar", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/foo", "src": ".pnpm/foo@1.0.0/node_modules/foo", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"} -] diff --git a/tests/mappings/testdata/a_script.sh b/tests/mappings/testdata/a_script.sh deleted file mode 100644 index dac2554..0000000 --- a/tests/mappings/testdata/a_script.sh +++ /dev/null @@ -1 +0,0 @@ -echo a_script diff --git a/tests/mappings/testdata/config b/tests/mappings/testdata/config deleted file mode 100644 index d39edc7..0000000 --- a/tests/mappings/testdata/config +++ /dev/null @@ -1 +0,0 @@ -# test config file diff --git a/tests/mappings/testdata/hello.txt b/tests/mappings/testdata/hello.txt deleted file mode 100644 index af5626b..0000000 --- a/tests/mappings/testdata/hello.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! diff --git a/tests/mappings/utf8_manifest.golden b/tests/mappings/utf8_manifest.golden deleted file mode 100644 index 11352ca..0000000 --- a/tests/mappings/utf8_manifest.golden +++ /dev/null @@ -1,8 +0,0 @@ -[ - {"type": "file", "dest": "1-a", "src": "tests/testdata/utf8/1-a", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"}, - {"type": "file", "dest": "2-λ", "src": "tests/testdata/utf8/2-λ", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"}, - {"type": "file", "dest": "3-世", "src": "tests/testdata/utf8/3-世", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"}, - {"type": "file", "dest": "BUILD", "src": "tests/testdata/utf8/BUILD", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"}, - {"type": "file", "dest": "sübdir/2-λ", "src": "tests/testdata/utf8/sübdir/2-λ", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"}, - {"type": "file", "dest": "sübdir/hello", "src": "tests/testdata/utf8/sübdir/hello", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"} -] diff --git a/tests/my_package_name.bzl b/tests/my_package_name.bzl deleted file mode 100644 index ebca81b..0000000 --- a/tests/my_package_name.bzl +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2020 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. - -"""Sample rule to show package naming.""" - -load("//pkg:providers.bzl", "PackageVariablesInfo") - -def _my_package_naming_impl(ctx): - values = {} - - # then add in my own custom values - values["label"] = ctx.attr.label - return PackageVariablesInfo(values = values) - -my_package_naming = rule( - implementation = _my_package_naming_impl, - attrs = { - "label": attr.string(doc = "A label that matters to me."), - }, -) diff --git a/tests/package_naming_aggregate_test.sh b/tests/package_naming_aggregate_test.sh deleted file mode 100755 index 4951b24..0000000 --- a/tests/package_naming_aggregate_test.sh +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2021 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. - -# This test simply checks that when we create packages with package_file_name -# that we get the expected file names. -set -e - -# Portably find the absolute path to the test data, even if this code has been -# vendored in to a source tree and re-rooted. -TEST_PACKAGE="$(echo ${TEST_TARGET} | sed -e 's/:.*$//' -e 's@//@@')" -declare -r DATA_DIR="${TEST_SRCDIR}/${TEST_WORKSPACE}/${TEST_PACKAGE}" - -for pkg in test_naming_some_value.deb test_naming_some_value.tar test_naming_some_value.zip ; do - ls -l "${DATA_DIR}/$pkg" -done -echo "PASS" diff --git a/tests/path_test.bzl b/tests/path_test.bzl deleted file mode 100644 index a2a46d2..0000000 --- a/tests/path_test.bzl +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright 2021 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. - -"""Tests for path.bzl""" - -load("//pkg:mappings.bzl", "pkg_mkdirs") -load("//pkg:path.bzl", "compute_data_path") -load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts", "unittest") - -########## -# Test compute_data_path -########## -def _compute_data_path_test_impl(ctx): - env = analysistest.begin(ctx) - target_under_test = analysistest.target_under_test(env) - - # Subtle: This allows you to vendor the library into your own repo at some - # arbitrary path. - expect = ctx.attr.expected_path - if expect.startswith("tests"): - expect = ctx.label.package + expect[5:] - asserts.equals( - env, - expect, - compute_data_path(ctx, ctx.attr.in_path), - ) - return analysistest.end(env) - -compute_data_path_test = analysistest.make( - _compute_data_path_test_impl, - attrs = { - "in_path": attr.string(mandatory = True), - "expected_path": attr.string(mandatory = True), - }, -) - -def _test_compute_data_path(name): - pkg_mkdirs( - name = "dummy", - dirs = [], - tags = ["manual"], - ) - - compute_data_path_test( - name = name + "_normal_test", - target_under_test = ":dummy", - in_path = "a/b/c", - expected_path = "tests/a/b/c", - ) - - compute_data_path_test( - name = name + "_absolute_test", - target_under_test = ":dummy", - in_path = "/a/b/c", - expected_path = "a/b/c", - ) - - compute_data_path_test( - name = name + "_relative_test", - target_under_test = ":dummy", - in_path = "./a/b/c", - expected_path = "tests/a/b/c", - ) - - compute_data_path_test( - name = name + "_empty_test", - target_under_test = ":dummy", - in_path = "./", - expected_path = "tests", - ) - - compute_data_path_test( - name = name + "_empty2_test", - target_under_test = ":dummy", - in_path = "./.", - expected_path = "tests", - ) - -def path_tests(name): - """Declare path.bzl analysis tests.""" - _test_compute_data_path(name = name + "_compute_data_path") diff --git a/tests/path_test.py b/tests/path_test.py deleted file mode 100644 index 85d133f..0000000 --- a/tests/path_test.py +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright 2016 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. -"""Testing for helper functions.""" - -import collections -import imp -import os -import unittest - - -pkg_bzl = imp.load_source('pkg_bzl', 'pkg/path.bzl') - -Owner = collections.namedtuple('Owner', ['workspace_name', 'workspace_root']) -Root = collections.namedtuple('Root', ['path']) - - -class File(object): - """Mock Skylark File class for testing.""" - - def __init__(self, short_path, is_generated=False, is_external=False): - self.is_source = not is_generated - self.root = Root('bazel-out/k8-fastbuild/bin' if is_generated else '') - if is_external: - self.owner = Owner('repo', 'external/repo') - self.short_path = '../repo/' + short_path - else: - self.owner = Owner('', '') - self.short_path = short_path - self.path = os.path.join( - self.root.path, self.owner.workspace_root, short_path) - - -class SafeShortPathTest(unittest.TestCase): - """Testing for safe_short_path.""" - - def testSafeShortPath(self): - path = pkg_bzl.safe_short_path(File('foo/bar/baz')) - self.assertEqual('foo/bar/baz', path) - - def testSafeShortPathGen(self): - path = pkg_bzl.safe_short_path(File('foo/bar/baz', is_generated=True)) - self.assertEqual('foo/bar/baz', path) - - def testSafeShortPathExt(self): - path = pkg_bzl.safe_short_path(File('foo/bar/baz', is_external=True)) - self.assertEqual('external/repo/foo/bar/baz', path) - - def testSafeShortPathGenExt(self): - path = pkg_bzl.safe_short_path( - File('foo/bar/baz', is_generated=True, is_external=True)) - self.assertEqual('external/repo/foo/bar/baz', path) - - -class ShortPathDirnameTest(unittest.TestCase): - """Testing for _short_path_dirname.""" - - def testShortPathDirname(self): - path = pkg_bzl._short_path_dirname(File('foo/bar/baz')) - self.assertEqual('foo/bar', path) - - def testShortPathDirnameGen(self): - path = pkg_bzl._short_path_dirname(File('foo/bar/baz', is_generated=True)) - self.assertEqual('foo/bar', path) - - def testShortPathDirnameExt(self): - path = pkg_bzl._short_path_dirname(File('foo/bar/baz', is_external=True)) - self.assertEqual('external/repo/foo/bar', path) - - def testShortPathDirnameGenExt(self): - path = pkg_bzl._short_path_dirname( - File('foo/bar/baz', is_generated=True, is_external=True)) - self.assertEqual('external/repo/foo/bar', path) - - def testTopLevel(self): - path = pkg_bzl._short_path_dirname(File('baz')) - self.assertEqual('', path) - - def testTopLevelGen(self): - path = pkg_bzl._short_path_dirname(File('baz', is_generated=True)) - self.assertEqual('', path) - - def testTopLevelExt(self): - path = pkg_bzl._short_path_dirname(File('baz', is_external=True)) - self.assertEqual('external/repo', path) - - -class DestPathTest(unittest.TestCase): - """Testing for _dest_path.""" - - def testDestPath(self): - path = pkg_bzl.dest_path(File('foo/bar/baz'), 'foo') - self.assertEqual('/bar/baz', path) - - def testDestPathGen(self): - path = pkg_bzl.dest_path(File('foo/bar/baz', is_generated=True), 'foo') - self.assertEqual('/bar/baz', path) - - def testDestPathExt(self): - path = pkg_bzl.dest_path( - File('foo/bar/baz', is_external=True), 'external/repo/foo') - self.assertEqual('/bar/baz', path) - - def testDestPathExtWrong(self): - path = pkg_bzl.dest_path(File('foo/bar/baz', is_external=True), 'foo') - self.assertEqual('external/repo/foo/bar/baz', path) - - def testNoMatch(self): - path = pkg_bzl.dest_path(File('foo/bar/baz'), 'qux') - self.assertEqual('foo/bar/baz', path) - - def testNoStrip(self): - path = pkg_bzl.dest_path(File('foo/bar/baz'), None) - self.assertEqual('/baz', path) - - def testTopLevel(self): - path = pkg_bzl.dest_path(File('baz'), None) - self.assertEqual('baz', path) - - def testPartialDirectoryMatch(self): - path = pkg_bzl.dest_path(File('foo/bar/baz'), 'fo') - self.assertEqual('foo/bar/baz', path) - - def testPartialDirectoryMatchWithDataPath(self): - path = pkg_bzl.dest_path(File('foo/bar/baz'), 'foo/ba', 'foo') - self.assertEqual('/bar/baz', path) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/rpm/BUILD b/tests/rpm/BUILD deleted file mode 100644 index b1dd70b..0000000 --- a/tests/rpm/BUILD +++ /dev/null @@ -1,423 +0,0 @@ -# Copyright 2020 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. -# -*- coding: utf-8 -*- - -load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("@bazel_skylib//rules:diff_test.bzl", "diff_test") -load("@rules_python//python:defs.bzl", "py_library", "py_test") -load( - "//pkg:mappings.bzl", - "pkg_attributes", - "pkg_filegroup", - "pkg_files", - "pkg_mkdirs", - "pkg_mklink", -) -load("//pkg:rpm.bzl", "pkg_rpm") -load("analysis_tests.bzl", "analysis_tests") -load("toolchain_tests.bzl", "create_toolchain_analysis_tests") - -############################################################################ -# analysis tests -############################################################################ - -package(default_applicable_licenses = ["//:license"]) - -analysis_tests(name = "analysis_tests") - -create_toolchain_analysis_tests() - -exports_files( - ["template-test.spec.tpl"], - visibility = [":__subpackages__"], -) - -############################################################################ -# pkg_filegroups for testing -############################################################################ - -filegroup( - name = "ars", - srcs = [ - "//tests:testdata/a.ar", - "//tests:testdata/a_ab.ar", - "//tests:testdata/a_b.ar", - "//tests:testdata/a_b_ab.ar", - "//tests:testdata/ab.ar", - "//tests:testdata/b.ar", - "//tests:testdata/empty.ar", - ], -) - -pkg_files( - name = "ars_pf", - srcs = [ - ":ars", - ], - attributes = pkg_attributes( - group = "root", - mode = "0755", - user = "root", - ), - prefix = "/test", -) - -genrule( - name = "config_empty", - outs = ["config.txt"], - cmd = "touch $@", -) - -pkg_files( - name = "config_file", - srcs = [":config_empty"], - attributes = pkg_attributes( - group = "root", - mode = "0644", - rpm_filetag = "%config(missingok, noreplace)", - user = "root", - ), -) - -pkg_mkdirs( - name = "var_log_foo", - attributes = pkg_attributes( - group = "root", - mode = "0755", - user = "root", - ), - dirs = ["/var/log/foo"], -) - -pkg_mklink( - name = "test_links", - attributes = pkg_attributes( - group = "root", - mode = "0777", - user = "root", - ), - link_name = "/usr/bin/link-name", - target = "/usr/bin/link-target", -) - -pkg_filegroup( - name = "test_pfg", - # Keep this list in sync with the values of "srcs" in "test_rpm_direct", - # below - srcs = [ - ":ars_pf", - ":config_file", - ":test_links", - ":var_log_foo", - ], -) - -############################################################################ -# Test RPMs -############################################################################ - -pkg_rpm( - name = "test_rpm", - srcs = [ - ":test_pfg", - ], - architecture = "noarch", - conflicts = ["not-a-test"], - description = """pkg_rpm test rpm description""", - license = "Apache 2.0", - post_scriptlet = """echo post""", - postun_scriptlet = """echo postun""", - pre_scriptlet = """echo pre""", - preun_scriptlet = """echo preun""", - provides = ["test"], - release = "2222", - requires = ["test-lib > 1.0"], - requires_contextual = {"preun": ["bash"]}, - spec_template = "template-test.spec.tpl", - summary = "pkg_rpm test rpm summary", - version = "1.1.1", -) - -# Just like the above one, except the compression is changed. -pkg_rpm( - name = "test_rpm_bzip2", - srcs = [ - ":test_pfg", - ], - architecture = "noarch", - binary_payload_compression = "w2.bzdio", - conflicts = ["not-a-test"], - description = """pkg_rpm test rpm description""", - license = "Apache 2.0", - post_scriptlet = """echo post""", - postun_scriptlet = """echo postun""", - pre_scriptlet = """echo pre""", - preun_scriptlet = """echo preun""", - provides = ["test"], - release = "2222", - requires = ["test-lib > 1.0"], - requires_contextual = {"preun": ["bash"]}, - spec_template = "template-test.spec.tpl", - summary = "pkg_rpm test rpm summary", - version = "1.1.1", -) - -# Like the first one, except `srcs` is now passed in without using a -# pkg_filegroup. -pkg_rpm( - name = "test_rpm_direct", - srcs = [ - ":ars_pf", - ":config_file", - ":test_links", - ":var_log_foo", - ], - architecture = "noarch", - conflicts = ["not-a-test"], - description = """pkg_rpm test rpm description""", - license = "Apache 2.0", - post_scriptlet = """echo post""", - postun_scriptlet = """echo postun""", - pre_scriptlet = """echo pre""", - preun_scriptlet = """echo preun""", - provides = ["test"], - release = "2222", - requires = ["test-lib > 1.0"], - requires_contextual = {"preun": ["bash"]}, - spec_template = "template-test.spec.tpl", - summary = "pkg_rpm test rpm summary", - version = "1.1.1", -) - -############################################################################ -# Test RPM metadata -- used to verify RPM contents in tests -############################################################################ - -# Emit a CSV file providing a manifest providing the expected RPM contents -genrule( - name = "test_rpm_manifest", - srcs = [ - ":ars", - ":config_file", - ], - outs = ["manifest.csv"], - # Keep the header (the first line echo'd below) in sync with - # rpm_queryformat_fieldnames in pkg_rpm_basic_test.py - cmd = """ - echo 'path,digest,user,group,mode,fflags,symlink' > $@ - for f in $(locations :ars); do - # Destination path - ( - echo -n /test/$$(basename $$f), - # Hash - $(execpath //tests/util:md5) $$f | tr '\\n' , - # User,Group,Mode,Fflags (fflags not provided) - echo -n 'root,root,100755,' - # Symlink destination (not provided) - echo , - ) >> $@ - done - # Config file - for f in $(location :config_file); do - ( - echo -n /$$(basename $$f), - $(execpath //tests/util:md5) $$f | tr '\\n' , - # User,Group,Mode,Fflags (fflags "cmn" = config + missingok + noreplace) - echo -n 'root,root,100644,cmn' - # Symlink destination (not provided) - echo , - ) >> $@ - done - # Directory (has no hash) - ( - echo -n /var/log/foo, - # No hash (beginning), fflags (end), or symlink destination (end) - echo ,root,root,40755,, - ) >> $@ - - # Symlink (has no hash) - ( - echo -n /usr/bin/link-name, - # No hash (beginning), or fflags (second-to-last) - echo ,root,root,120777,,/usr/bin/link-target - ) >> $@ - """, - tools = ["//tests/util:md5"], -) - -genrule( - name = "test_rpm_metadata", - srcs = [], - outs = [ - "conflicts.csv", - "provides.csv", - "requires.csv", - ], - # In the below, we don't use the "," separator for everything, because the - # query tags used to get the associated dependency types - # (e.g. %{REQUIREFLAGS:deptype}) itself uses commas. This makes it so the test - # doesn't have to rely on knowing the number of fields in each CSV file. - cmd = """ - ( - echo 'capability:sense' - echo 'not-a-test:manual' - ) > $(RULEDIR)/conflicts.csv - ( - # NOTE: excludes the "self-require" (we did nothing special to make it - # appear) - - echo 'capability:sense' - echo 'test:manual' - echo 'config(test_rpm) = 1.1.1-2222:config' - ) > $(RULEDIR)/provides.csv - ( - # NOTE: excludes 'rpmlib' requires that may be version-dependent - echo 'capability:sense' - # Common, automatically generated - echo '/bin/sh:pre,interp' - echo '/bin/sh:post,interp' - echo '/bin/sh:preun,interp' - echo '/bin/sh:postun,interp' - # Hand-specified, specific dependencies - echo 'bash:preun' - # Hand-specified - echo 'test-lib > 1.0:manual' - echo 'config(test_rpm) = 1.1.1-2222:config' - ) > $(RULEDIR)/requires.csv - """, -) - -# One cannot simply pass the output of pkg_rpm as runfiles content (#161). This -# seems to be the easiest way around this problem. -sh_library( - name = "pkg_rpm_basic_test_data", - testonly = True, - srcs = [ - ":test_rpm", - ":test_rpm_bzip2", - ":test_rpm_direct", - ":test_rpm_manifest", - ":test_rpm_metadata", - ], -) - -############################################################################ -# Confirm that the %dir tag is being applied properly (#473) -############################################################################ - -pkg_mkdirs( - name = "dirtest_dirs", - attributes = pkg_attributes(mode = "0755"), - dirs = [ - "dir", - ], -) - -pkg_files( - name = "dirtest_file", - srcs = [ - ":config_empty", - ], - attributes = pkg_attributes(mode = "0644"), - prefix = "dir", -) - -pkg_rpm( - name = "test_rpm_dirs", - srcs = [ - # Do not sort. Order important for testing. - ":dirtest_file", - ":dirtest_dirs", - ], - architecture = "noarch", - description = """pkg_rpm test rpm description""", - license = "Apache 2.0", - release = "2222", - spec_template = "template-test.spec.tpl", - summary = "pkg_rpm test rpm summary", - version = "1.1.1", -) - -genrule( - name = "test_rpm_dirs_contents", - srcs = [":test_rpm_dirs"], - outs = [":test_rpm_dirs_contents.txt"], - cmd = """ - # pkg_rpm emits two outputs - RPMS=($(SRCS)) - rpm -qp --queryformat '[%{FILEMODES:perms} %{FILENAMES}\n]' $${RPMS[0]} > $@ - """, -) - -diff_test( - name = "test_rpm_dirs_contents_golden_test", - file1 = ":test_rpm_dirs_contents", - file2 = "test_rpm_dirs_contents.txt.golden", -) - -############################################################################ -# Common tests -############################################################################ - -py_library( - name = "rpm_util", - srcs = ["rpm_util.py"], - imports = ["../.."], - visibility = [":__subpackages__"], -) - -py_test( - name = "make_rpm_test", - srcs = ["make_rpm_test.py"], - python_version = "PY3", - srcs_version = "PY3", - deps = [ - "//pkg:make_rpm_lib", - ], -) - -# RPM content verification tests -py_test( - name = "pkg_rpm_basic_test", - srcs = ["pkg_rpm_basic_test.py"], - data = [":pkg_rpm_basic_test_data"], - python_version = "PY3", - tags = [ - "no_windows", # Windows doesn't have rpm(8) or rpmbuild(8) - ], - deps = [ - ":rpm_util", - "@rules_python//python/runfiles", - ], -) - -# Smoke test for defaults -pkg_rpm( - name = "test_rpm_default_template", - testonly = True, - srcs = [ - ":test_pfg", - ], - architecture = "noarch", - description = """pkg_rpm test rpm description""", - license = "Apache 2.0", - release = "2222", - summary = "pkg_rpm test rpm summary", - version = "1.1.1", -) - -build_test( - name = "pkg_rpm_smoke", - targets = [":test_rpm_default_template"], -) diff --git a/tests/rpm/analysis_tests.bzl b/tests/rpm/analysis_tests.bzl deleted file mode 100644 index 3565b47..0000000 --- a/tests/rpm/analysis_tests.bzl +++ /dev/null @@ -1,318 +0,0 @@ -# Copyright 2021 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. - -"""Tests for RPM generation analysis""" - -load( - "//pkg:mappings.bzl", - "pkg_filegroup", - "pkg_files", - "pkg_mkdirs", - "pkg_mklink", -) -load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") -load("//pkg:providers.bzl", "PackageVariablesInfo") -load("//pkg:rpm.bzl", "pkg_rpm") -load("//tests/util:defs.bzl", "directory", "generic_base_case_test", "generic_negative_test") - -def _declare_pkg_rpm(name, srcs_ungrouped, tags = None, **kwargs): - pfg_name = "{}_pfg".format(name) - _tags = tags or ["manual"] - - pkg_filegroup( - name = pfg_name, - srcs = srcs_ungrouped, - tags = _tags, - ) - - pkg_rpm( - name = name, - srcs = [":" + pfg_name], - version = "1.0", - release = "1", - architecture = "noarch", - license = "N/A", - summary = "A test", - description = "very much a test", - tags = _tags, - **kwargs - ) - -def _declare_conflicts_test(name, srcs, **kwargs): - rpm_name = name + "_rpm" - _declare_pkg_rpm( - name = rpm_name, - srcs_ungrouped = srcs, - tags = ["manual"], - ) - - generic_negative_test( - name = name, - target_under_test = ":" + rpm_name, - ) - -############################################################ -# Begin tests. Check that the conflict detection system works. -############################################################ - -def _test_conflicting_inputs(name): - # The test here is to confirm if pkg_rpm rejects conflicting inputs - # - # The structure of the code is such that it's only necessary to test any one - # packaged item conflicts with all others; order is irrelevant. - # - # So, we test how everything would conflict with a "file" entry - pkg_files( - name = "{}_file_base".format(name), - srcs = ["foo"], - tags = ["manual"], - ) - - _declare_pkg_rpm( - name = name + "_base", - srcs_ungrouped = [":{}_file_base".format(name)], - ) - - generic_base_case_test( - name = name + "_base_case_passes_analysis", - target_under_test = ":" + name + "_base", - ) - - ################################################## - # file vs conflicting file - ################################################## - - pkg_files( - name = "{}_file_conflict".format(name), - srcs = ["foo"], - tags = ["manual"], - ) - - _declare_conflicts_test( - name = name + "_conflict_with_file", - srcs = [ - ":{}_file_base".format(name), - ":{}_file_conflict".format(name), - ], - ) - - ################################################## - # file vs conflicting dir - ################################################## - - pkg_mkdirs( - name = "{}_dir_conflict".format(name), - dirs = ["foo"], - tags = ["manual"], - ) - - _declare_conflicts_test( - name = name + "_conflict_with_dir", - srcs = [ - ":{}_file_base".format(name), - ":{}_dir_conflict".format(name), - ], - ) - - ################################################## - # file vs conflicting symbolic link - ################################################## - - pkg_mklink( - name = "{}_symlink_conflict".format(name), - link_name = "foo", - target = "bar", - tags = ["manual"], - ) - - _declare_conflicts_test( - name = name + "_conflict_with_symlink", - srcs = [ - ":{}_file_base".format(name), - ":{}_symlink_conflict".format(name), - ], - ) - - native.test_suite( - name = name, - tests = [ - ":{}_{}".format(name, test_name) - for test_name in [ - "base_case_passes_analysis", - "conflict_with_file", - "conflict_with_dir", - "conflict_with_symlink", - ] - ], - ) - -############################################################ -# Verify that rules produce expected named outputs -############################################################ - -#### Setup; helpers - -def _package_naming_test_impl(ctx): - env = analysistest.begin(ctx) - target_under_test = analysistest.target_under_test(env) - - ogi = target_under_test[OutputGroupInfo] - - out_file = ogi.out.to_list()[0] - rpm_file = ogi.rpm.to_list()[0] - changes_file = ogi.changes.to_list()[0] if ogi.changes else None - asserts.equals( - env, - rpm_file.basename, - ctx.attr.expected_name, - "OutputGroupInfo rpm name does not match expected value.", - ) - - # Try to find the expected files in the DefaultInfo. - out_file_found = False - rpm_file_found = False - changes_file_found = False - default_name_found = False - - for f in target_under_test[DefaultInfo].files.to_list(): - if f == out_file: - out_file_found = True - if f == rpm_file: - rpm_file_found = True - if f == changes_file: - changes_file_found = True - if f.basename == ctx.attr.expected_name: - default_name_found = True - - asserts.true( - env, - rpm_file_found, - "rpm component of OutputGroupInfo '{}' is not in DefaultInfo".format(rpm_file), - ) - asserts.false( - env, - out_file_found, - "out component of OutputGroupInfo '{}' is not in DefaultInfo".format(out_file), - ) - asserts.false( - env, - changes_file_found, - "changes component of OutputGroupInfo '{}' is not in DefaultInfo".format(changes_file), - ) - asserts.true( - env, - default_name_found, - "Expected package file with default name '{}' is not in DefaultInfo".format(ctx.attr.expected_name), - ) - - return analysistest.end(env) - -package_naming_test = analysistest.make( - _package_naming_test_impl, - attrs = { - "expected_name": attr.string(), - }, -) - -# Dummy substitution set, used in below test cases -def _dummy_pkg_variables_impl(ctx): - return [ - PackageVariablesInfo( - values = { - "FOO": "foo", - "BAR": "bar", - }, - ), - ] - -dummy_pkg_variables = rule( - implementation = _dummy_pkg_variables_impl, - attrs = {}, -) - -#### Tests start here - -def _test_naming(name): - # Test whether name templating via PackageVariablesInfo functions as expected, and ensure that - # outputs are passed through to OutputGroupInfo. - pkg_files( - name = "{}_file_base".format(name), - srcs = ["foo"], - tags = ["manual"], - ) - - _declare_pkg_rpm( - name = name + "_no_extra_rpm", - srcs_ungrouped = [":{}_file_base".format(name)], - ) - - # Default "full" name defaults to the "NVR.A" format. - package_naming_test( - name = name + "_no_extra", - target_under_test = ":" + name + "_no_extra_rpm", - expected_name = name + "_no_extra_rpm-1.0-1.noarch.rpm", - ) - - ################################################## - # With pkg_variables - ################################################## - - dummy_pkg_variables( - name = name + "_pkg_variables", - ) - - _declare_pkg_rpm( - name = name + "_with_different_name_rpm", - srcs_ungrouped = [":{}_file_base".format(name)], - package_variables = ":{}_pkg_variables".format(name), - package_file_name = name + "-{FOO}-{BAR}.rpm", - ) - - # Default "full" name defaults to the "NVR.A" format. Set it to something - # super arbitrary. - package_naming_test( - name = name + "_with_different_name", - target_under_test = ":" + name + "_with_different_name_rpm", - expected_name = name + "-foo-bar.rpm", - ) - - ################################################## - # Test suite declaration - ################################################## - - native.test_suite( - name = name, - tests = [ - ":{}_{}".format(name, test_name) - for test_name in [ - "no_extra", - "with_different_name", - ] - ], - ) - -def analysis_tests(name, **kwargs): - # Need to test: - # - # - Mutual exclusivity of certain options (low priority) - # - _test_conflicting_inputs(name = name + "_conflicting_inputs") - _test_naming(name = name + "_naming") - native.test_suite( - name = name, - tests = [ - name + "_conflicting_inputs", - name + "_naming", - ], - ) diff --git a/tests/rpm/make_rpm_test.py b/tests/rpm/make_rpm_test.py deleted file mode 100644 index cb8608b..0000000 --- a/tests/rpm/make_rpm_test.py +++ /dev/null @@ -1,179 +0,0 @@ -# Copyright 2017 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. -"""Tests for make_rpm.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import contextlib -import os -import unittest - -from pkg import make_rpm - - -@contextlib.contextmanager -def PrependPath(dirs): - with ReplacePath(dirs + [os.environ['PATH']]): - yield - - -@contextlib.contextmanager -def ReplacePath(dirs): - original_path = os.environ['PATH'] - try: - os.environ['PATH'] = os.pathsep.join(dirs) - yield - finally: - os.environ['PATH'] = original_path - - -def WriteFile(filename, *contents): - with open(filename, 'w') as text_file: - text_file.write('\n'.join(contents)) - - -def DirExists(dirname): - return os.path.exists(dirname) and os.path.isdir(dirname) - - -def FileExists(filename): - return os.path.exists(filename) and not os.path.isdir(filename) - - -def FileContents(filename): - with open(filename, 'r') as text_file: - return [s.strip() for s in text_file.readlines()] - - -class MakeRpmTest(unittest.TestCase): - - # Python 2 alias - if not hasattr(unittest.TestCase, 'assertCountEqual'): - - def assertCountEqual(self, a, b): - # pylint: disable=g-deprecated-assert - return self.assertItemsEqual(a, b) - - def testFindOutputFile(self): - log = """ - Lots of data. - Wrote: /path/to/file/here.rpm - More data present. - """ - - result = make_rpm.FindOutputFile(log) - self.assertEqual('/path/to/file/here.rpm', result) - - def testFindOutputFile_missing(self): - log = """ - Lots of data. - More data present. - """ - - result = make_rpm.FindOutputFile(log) - self.assertEqual(None, result) - - def testCopyAndRewrite(self): - with make_rpm.Tempdir(): - WriteFile('test.txt', 'Some: data1', 'Other: data2', 'More: data3') - make_rpm.CopyAndRewrite('test.txt', 'out.txt', { - 'Some:': 'data1a', - 'More:': 'data3a', - }) - - self.assertTrue(FileExists('out.txt')) - self.assertCountEqual(['Some: data1a', 'Other: data2', 'More: data3a'], - FileContents('out.txt')) - - def testFindRpmbuild_present(self): - with make_rpm.Tempdir() as outer: - dummy = os.sep.join([outer, 'rpmbuild']) - WriteFile(dummy, 'dummy rpmbuild') - os.chmod(dummy, 0o777) - with PrependPath([outer]): - path = make_rpm.FindRpmbuild('') - self.assertEqual(dummy, path) - - def testFindRpmbuild_missing(self): - with make_rpm.Tempdir() as outer: - with ReplacePath([outer]): - with self.assertRaises(make_rpm.NoRpmbuildFoundError) as context: - make_rpm.FindRpmbuild('') - self.assertIsNotNone(context) - - def testSetupWorkdir(self): - with make_rpm.Tempdir() as outer: - dummy = os.sep.join([outer, 'rpmbuild']) - WriteFile(dummy, 'dummy rpmbuild') - os.chmod(dummy, 0o777) - - with PrependPath([outer]): - # Create the builder and exercise it. - builder = make_rpm.RpmBuilder('test', '1.0', '0', 'x86', None) - - # Create spec_file, test files. - WriteFile('test.spec', 'Name: test', 'Version: 0.1', - 'Summary: test data') - WriteFile('file1.txt', 'Hello') - WriteFile('file2.txt', 'Goodbye') - builder.AddFiles(['file1.txt', 'file2.txt']) - - with make_rpm.Tempdir(): - # Call RpmBuilder. - builder.SetupWorkdir('test.spec', outer) - - # Make sure files exist. - self.assertTrue(DirExists('SOURCES')) - self.assertTrue(DirExists('BUILD')) - self.assertTrue(DirExists('TMP')) - self.assertTrue(FileExists('test.spec')) - self.assertCountEqual( - ['Name: test', 'Version: 1.0', 'Summary: test data'], - FileContents('test.spec')) - self.assertTrue(FileExists('BUILD/file1.txt')) - self.assertCountEqual(['Hello'], FileContents('BUILD/file1.txt')) - self.assertTrue(FileExists('BUILD/file2.txt')) - self.assertCountEqual(['Goodbye'], FileContents('BUILD/file2.txt')) - - def testBuild(self): - with make_rpm.Tempdir() as outer: - dummy = os.sep.join([outer, 'rpmbuild']) - WriteFile( - dummy, - '#!/bin/sh', - 'mkdir -p RPMS', - 'touch RPMS/test.rpm', - 'echo "Wrote: $PWD/RPMS/test.rpm"', - ) - os.chmod(dummy, 0o777) - - with PrependPath([outer]): - # Create the builder and exercise it. - builder = make_rpm.RpmBuilder('test', '1.0', '0', 'x86', None) - - # Create spec_file, test files. - WriteFile('test.spec', 'Name: test', 'Version: 0.1', - 'Summary: test data') - - # Call RpmBuilder. - builder.Build('test.spec', 'test.rpm') - - # Make sure files exist. - self.assertTrue(FileExists('test.rpm')) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/rpm/pkg_rpm_basic_test.py b/tests/rpm/pkg_rpm_basic_test.py deleted file mode 100644 index 990fc4f..0000000 --- a/tests/rpm/pkg_rpm_basic_test.py +++ /dev/null @@ -1,255 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2020 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. - -import unittest -import subprocess -import csv -import io -import os - -from rules_python.python.runfiles import runfiles -from tests.rpm import rpm_util - -# This provides some tests for built RPMs, mostly by taking the built RPM and -# running rpm queries on it. -# -# Useful reading: -# -# - RPM queryformat documentation (shortish): -# https://rpm.org/user_doc/query_format.html -# -# - In-depth RPM query documentation: -# http://ftp.rpm.org/max-rpm/s1-rpm-query-parts.html -# -# - Specifically, about the --qf/--queryformat syntax: -# http://ftp.rpm.org/max-rpm/s1-rpm-query-parts.html#S3-RPM-QUERY-QUERYFORMAT-OPTION -# -# - --queryformat tags list: http://ftp.rpm.org/max-rpm/ch-queryformat-tags.html -# -class PkgRpmBasicTest(unittest.TestCase): - def setUp(self): - self.runfiles = runfiles.Create() - self.test_rpm_path = self.runfiles.Rlocation( - "rules_pkg/tests/rpm/test_rpm-1.1.1-2222.noarch.rpm") - self.test_rpm_direct_path = self.runfiles.Rlocation( - "rules_pkg/tests/rpm/test_rpm_direct-1.1.1-2222.noarch.rpm") - self.test_rpm_bzip2_path = self.runfiles.Rlocation( - "rules_pkg/tests/rpm/test_rpm_bzip2-1.1.1-2222.noarch.rpm") - self.maxDiff = None - - def test_scriptlet_content(self): - expected = b"""\ -preinstall scriptlet (using /bin/sh): -echo pre -postinstall scriptlet (using /bin/sh): -echo post -preuninstall scriptlet (using /bin/sh): -echo preun -postuninstall scriptlet (using /bin/sh): -echo postun -""" - - output = subprocess.check_output( - ["rpm", "-qp", "--scripts", self.test_rpm_path]) - - self.assertEqual(output, expected) - - def test_basic_headers(self): - fields = { - "NAME": b"test_rpm", - "VERSION": b"1.1.1", - "RELEASE": b"2222", - "ARCH": b"noarch", - "GROUP": b"Unspecified", - "SUMMARY": b"pkg_rpm test rpm summary", - } - for fieldname, expected in fields.items(): - output = subprocess.check_output([ - "rpm", "-qp", "--queryformat", "%{" + fieldname + "}", - self.test_rpm_path - ]) - - self.assertEqual( - output, expected, - "RPM Tag {} does not match expected value".format(fieldname)) - - def test_contents(self): - manifest_file = self.runfiles.Rlocation( - "rules_pkg/tests/rpm/manifest.csv") - manifest_specs = {} - with open(manifest_file, "r", newline='', encoding="utf-8") as fh: - manifest_reader = csv.DictReader(fh) - manifest_specs = {r['path']: r for r in manifest_reader} - - rpm_specs = rpm_util.read_rpm_filedata(self.test_rpm_path) - - self.assertDictEqual(manifest_specs, rpm_specs) - # Transitively, this one should work too -- doesn't use pkg_filegroup - # directly. - rpm_direct_specs = rpm_util.read_rpm_filedata(self.test_rpm_direct_path) - self.assertDictEqual(rpm_specs, rpm_direct_specs) - - def test_preamble_metadata(self): - metadata_prefix = "rules_pkg/tests/rpm" - - rpm_filename = os.path.basename(self.test_rpm_path) - rpm_basename = os.path.splitext(rpm_filename)[0] - - # Tuples of: - # Metadata name, RPM Tag prefix, exclusion list (currently only support "startswith") - # - # The exclusions should probably be regexps at some point, but right - # now, our job is relatively easy. They only operate on the - # "capability" portion of the tag. - test_md = [ - ("conflicts", "CONFLICT", []), - # rpm packages implicitly provide themselves, something like: - # "test_rpm = 1.1.1-2222". We don't bother testing this, since we - # don't take direct action to specify it. - ("provides", "PROVIDE", [rpm_basename]), - # Skip rpmlib-related requirements; they are often dependent on the - # version of `rpm` we are using. - ("requires", "REQUIRE", ["rpmlib"]), - ] - for (mdtype, tag, exclusions) in test_md: - md_file = self.runfiles.Rlocation( - os.path.join(metadata_prefix, mdtype + ".csv")) - - with open(md_file, "r", newline='', encoding="utf-8") as fh: - md_reader = csv.DictReader(fh, delimiter=':') - # I heard you like functional programming ;) - # - # This produces a list of outputs whenever the "capability" - # attribute starts with any of the values in the "exclusions" - # list. - md_specs_unsorted = [line for line in md_reader - if not any(line['capability'].startswith(e) - for e in exclusions)] - # And this sorts it, ordering by the sorted "association list" - # form of the dictionary. - # - # The sorting of the key values is not necessary with versions - # of python3 (3.5+, I believe) that have dicts maintain - # insertion order. - md_specs = sorted(md_specs_unsorted, - key = lambda x: sorted(x.items())) - - - # This typically becomes the equivalent of: - # - # '[%{PROVIDENEVRS};%{PROVIDEFLAGS:deptype}\n]' - # - # as passed to `rpm --queryformat` - rpm_queryformat = ( - # NEVRS = Name Epoch Version Release (plural), which look something like: - # rpmlib(CompressedFileNames) <= 3.0.4-1 - # or: - # bash - "[%{{{tag}NEVRS}}" - # Flags associated with the dependency type. This used to - # evaluate in what "sense" the dependency was added. - # - # Values often include things like: - # - # - "interp" for scriptlet interpreter dependencies - # - "postun" for dependencies of the "postun" scriptlet - # - "manual" for values that are explicitly specified - ":%{{{tag}FLAGS:deptype}}" - "\n]" - ).format(tag = tag) - - rpm_queryformat_fieldnames = [ - "capability", - "sense", - ] - - rpm_output = subprocess.check_output( - ["rpm", "-qp", "--queryformat", rpm_queryformat, self.test_rpm_path]) - - sio = io.StringIO(rpm_output.decode('utf-8')) - rpm_output_reader = csv.DictReader( - sio, delimiter=':', fieldnames=rpm_queryformat_fieldnames) - - # Get everything in the same order as the read-in metadata file - rpm_outputs_filtered_unsorted = [line for line in rpm_output_reader - if not any(line['capability'].startswith(e) - for e in exclusions)] - - rpm_outputs_filtered = sorted(rpm_outputs_filtered_unsorted, key = lambda x: sorted(x.items())) - - for expected, actual in zip(md_specs, rpm_outputs_filtered): - self.assertDictEqual(expected, actual, - msg="{} metadata discrepancy".format(mdtype)) - - def test_compression_none_provided(self): - # Test when we don't provide "binary_payload_compression" to pkg_rpm - my_rpm = self.test_rpm_path - rpm_output = subprocess.check_output( - ["rpm", "-qp", "--queryformat", "%{PAYLOADCOMPRESSOR}", my_rpm]) - sio = io.StringIO(rpm_output.decode('utf-8')) - actual_compressor = sio.read() - # `bzip2` compression was, AFAICT, never the default for rpmbuild(8), - # and never will be, so this should be fine. - self.assertNotEqual(actual_compressor, 'bzip2') - - def test_compression_passthrough(self): - # Test when we provide "binary_payload_compression" to pkg_rpm - my_rpm = self.test_rpm_bzip2_path - rpm_output = subprocess.check_output( - ["rpm", "-qp", "--queryformat", "%{PAYLOADCOMPRESSOR}", my_rpm]) - sio = io.StringIO(rpm_output.decode('utf-8')) - actual_compressor = sio.read() - self.assertEqual(actual_compressor, 'bzip2') - - def test_mtimes(self): - # Modification times should be something close to when the package was - # built. Since we do not know when the package was actually built, we - # can just check for something that is non-zero. - # - # See also #486. - - filedata = rpm_util.read_rpm_filedata( - self.test_rpm_path, - query_tag_map={ - "FILENAMES": "path", - "FILEMTIMES": "mtime", - } - ) - - self.assertNotEqual( - len(filedata), - 0, - "rpm_util.read_rpm_filedata() produced no output" - ) - - filedata_shortened = { - path: int(data["mtime"]) - for path, data in filedata.items() - } - - files_with_zero_mtimes = dict(filter( - lambda kv: kv[1] == 0, - filedata_shortened.items(), - )) - - self.assertDictEqual( - files_with_zero_mtimes, - {}, - "No files should have zero mtimes without source_date_epoch or source_date_epoch_file") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/rpm/rpm_util.py b/tests/rpm/rpm_util.py deleted file mode 100644 index 5655fc5..0000000 --- a/tests/rpm/rpm_util.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright 2021 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. - -import io -import csv -import subprocess - - -def get_rpm_version_as_tuple(rpm_bin_path="rpm"): - """Get the current version of the requested rpm(8) binary.""" - output = subprocess.check_output( - [rpm_bin_path, "--version"]).decode('utf-8') - - # e.g. RPM Version 4.13.1 - version_str = output.split()[2] - - return tuple(int(component) for component in version_str.split('.')) - - -def invoke_rpm_with_queryformat(rpm_file_path, queryformat, rpm_bin_path="rpm"): - """Helper to ease the invocation of an rpm query with a custom queryformat. - - Returns any output as a UTF-8 decoded string if the command succeeds. If it - fails, throws CalledProcessException, like `subprocess.check_output`. - """ - - # The RPM tooling (at least the copy I have here, 4.14.2.1) is a bit buggy: - # - # - If you don't pass "-p/--package" argument, `rpm -q --queryformat` run - # against a package will always "fail" with no explanation. - # - # - If you do pass "-p/--package" argument, `rpm -q --queryformat` run - # against a package will always succeed if it can read a file, even when - # there is an error in some other aspect of the query. - # - # As a workaround, you should generally know if you're expecting output. - # Check if the output contains anything not whitespace, or if you're using - # `read_rpm_filedata`, check if the output dict is nonempty. - return subprocess.check_output([rpm_bin_path, "-qp", "--queryformat", queryformat, rpm_file_path]).decode("utf-8") - - -# TODO(nacl): "rpm_bin_path" should be derived from a toolchain somewhere. -# -# At this time, the "Rpmbuild" toolchain only contains rpmbuild. Since `rpm` -# itself is only useful for tests, this may be overkill. -def read_rpm_filedata(rpm_file_path, rpm_bin_path="rpm", query_tag_map=None): - """Read rpm file-based metadata into a dictionary - - Keys are the file names (absolute paths), values are the metadata as another - dictionary. - - The metadata fields are those defined in an RPM query, and is a map of query - tags to simple variable names. The fields must be plural, as identified by - the names. Some examples are in the default argument, described below. - - - FILENAMES -> path (file absolute path) - - FILEDIGESTS -> digest (hash of file. MD5 for compatibility) - - FILEUSERNAME -> user (UNIX owning user) - - FILEGROUPNAME -> group (UNIX owning group) - - FILEMODES:octal -> mode (UNIX mode, as an octal string) - - FILEFLAGS:fflags -> fflags (RPM file flags as a string, see upstream documentation) - - FILELINKTOS -> Symlink target, or nothing (something "falsy") if not provided - - Check out the implementation for more details, and consult the RPM - documentation even more more details. You can get a list of all tags by - invoking `rpm --querytags`. - - NOTE: see also caveats in `invoke_rpm_with_queryformat`, above. - - """ - # It is not necessary to check for file sizes, as the hashes are - # sufficient for determining whether or not files are the same. - # - # This also simplifies behavior where RPM's size calculations have - # sometimes changed, e.g.: - # - # https://github.com/rpm-software-management/rpm/commit/2cf7096ba534b065feb038306c792784458ac9c7 - - if query_tag_map is None: - rpm_queryformat = ( - "[%{FILENAMES}" - ",%{FILEDIGESTS}" - ",%{FILEUSERNAME}" - ",%{FILEGROUPNAME}" - ",%{FILEMODES:octal}" - ",%{FILEFLAGS:fflags}" - ",%{FILELINKTOS}" - "\n]" - ) - rpm_queryformat_fieldnames = [ - "path", - "digest", - "user", - "group", - "mode", - "fflags", - "symlink", - ] - else: - rpm_queryformat = "[" - rpm_queryformat += ",".join(["%{{{}}}".format(query_tag) - for query_tag in query_tag_map.keys()]) - rpm_queryformat += "\n]" - - rpm_queryformat_fieldnames = list(query_tag_map.values()) - - rpm_output = invoke_rpm_with_queryformat( - rpm_file_path, - rpm_queryformat, - rpm_bin_path, - ) - - sio = io.StringIO(rpm_output) - rpm_output_reader = csv.DictReader( - sio, - fieldnames=rpm_queryformat_fieldnames - ) - - return {r['path']: r for r in rpm_output_reader} diff --git a/tests/rpm/source_date_epoch/BUILD b/tests/rpm/source_date_epoch/BUILD deleted file mode 100644 index 156f844..0000000 --- a/tests/rpm/source_date_epoch/BUILD +++ /dev/null @@ -1,131 +0,0 @@ -# Copyright 2021 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. - -load("@rules_python//python:defs.bzl", "py_test") -load("//pkg:mappings.bzl", "pkg_filegroup", "pkg_files") -load("//pkg:rpm.bzl", "pkg_rpm") - -############################################################################ -# Test handling the source_date_epoch attribute -############################################################################ - -package(default_applicable_licenses = ["//:license"]) - -# The actual test. It tests whether the contents match a particular desired -# "manifest", most notably with regards to file structure. -py_test( - name = "source_date_epoch_insource", - srcs = ["rpm_contents_vs_manifest_test.py"], - data = [":rpm_sde_insource_data"], - env = {"TEST_RPM": "rpm_sde_insource-1.1.1-2222.noarch.rpm"}, - main = "rpm_contents_vs_manifest_test.py", - tags = [ - "no_windows", # Windows doesn't have rpm(8) or rpmbuild(8) - ], - deps = [ - "//tests/rpm:rpm_util", - "@rules_python//python/runfiles", - ], -) - -# One cannot simply pass the output of pkg_rpm as runfiles content (#161). This -# seems to be the easiest way around this problem. -sh_library( - name = "rpm_sde_insource_data", - testonly = True, - srcs = [":rpm_sde_insource"], -) - -# The RPM (target under test) -pkg_rpm( - name = "rpm_sde_insource", - srcs = [ - ":pfg", - ], - architecture = "noarch", - description = """pkg_rpm test rpm description""", - license = "Apache 2.0", - release = "2222", - # Tue Mar 23 00:00:00 EDT 2021 - source_date_epoch = 1616472000, - spec_template = "//tests/rpm:template-test.spec.tpl", - summary = "pkg_rpm test rpm summary", - version = "1.1.1", -) - -pkg_filegroup( - name = "pfg", - srcs = [":pf"], -) - -pkg_files( - name = "pf", - srcs = [":files"], - prefix = "test_dir", -) - -genrule( - name = "files", - outs = [ - "a", - "b", - ], - cmd = """ - touch $(OUTS) - """, -) - -############################################################################ -# Test handling the source_date_epoch attribute -############################################################################ - -py_test( - name = "source_date_epoch_from_file", - srcs = ["rpm_contents_vs_manifest_test.py"], - data = [":rpm_sde_fromfile_data"], - env = {"TEST_RPM": "rpm_sde_fromfile-1.1.1-2222.noarch.rpm"}, - main = "rpm_contents_vs_manifest_test.py", - tags = [ - "no_windows", # Windows doesn't have rpm(8) or rpmbuild(8) - ], - deps = [ - "//tests/rpm:rpm_util", - "@rules_python//python/runfiles", - ], -) - -# One cannot simply pass the output of pkg_rpm as runfiles content (#161). This -# seems to be the easiest way around this problem. -sh_library( - name = "rpm_sde_fromfile_data", - testonly = True, - srcs = [":rpm_sde_fromfile"], -) - -# The RPM (target under test) -pkg_rpm( - name = "rpm_sde_fromfile", - srcs = [ - ":pfg", - ], - architecture = "noarch", - description = """pkg_rpm test rpm description""", - license = "Apache 2.0", - release = "2222", - # Tue Mar 23 00:00:00 EDT 2021 - source_date_epoch_file = "epoch.txt", - spec_template = "//tests/rpm:template-test.spec.tpl", - summary = "pkg_rpm test rpm summary", - version = "1.1.1", -) diff --git a/tests/rpm/source_date_epoch/epoch.txt b/tests/rpm/source_date_epoch/epoch.txt deleted file mode 100644 index 7e33e1a..0000000 --- a/tests/rpm/source_date_epoch/epoch.txt +++ /dev/null @@ -1 +0,0 @@ -1616472000 diff --git a/tests/rpm/source_date_epoch/rpm_contents_vs_manifest_test.py b/tests/rpm/source_date_epoch/rpm_contents_vs_manifest_test.py deleted file mode 100644 index ca249c7..0000000 --- a/tests/rpm/source_date_epoch/rpm_contents_vs_manifest_test.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2021 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. - -import csv -import io -import os -import unittest - -from rules_python.python.runfiles import runfiles -from tests.rpm import rpm_util - -# Tue Mar 23 00:00:00 EDT 2021 -EXPECTED_EPOCH = '1616472000' -EXPECTED_RPM_MANIFEST_CSV = """ -path,mtime -/test_dir/a,{epoch} -/test_dir/b,{epoch} -""".strip().format(epoch=EXPECTED_EPOCH) - - -def version_to_string(version): - return ".".join(str(i) for i in version) - - -class PkgRpmCompManifest(unittest.TestCase): - # Support for SOURCE_DATE_EPOCH is only available as of rpm - # 4.14: http://rpm.org/wiki/Releases/4.14.0 - # - # TODO(nacl): it would probably be better to ask the rpmbuild(8) binary for - # this instead, since that's ultimately what's going to make or break this - # test. - SOURCE_DATE_EPOCH_MIN_VERSION = (4, 14, 0) - - def rpmBinSupportsSourceDateEpoch(self): - return self.rpm_bin_version >= self.SOURCE_DATE_EPOCH_MIN_VERSION - - # TODO(nacl) consider making a fixture out of this - def setUp(self): - self.runfiles = runfiles.Create() - self.maxDiff = None - - self.rpm_bin_version = rpm_util.get_rpm_version_as_tuple() - - # These tests will fail on unsupported versions of rpm(8), so skip them - # in that case. - if not self.rpmBinSupportsSourceDateEpoch(): - self.skipTest("RPM version too old to support SOURCE_DATE_EPOCH." - " Must be {} or newer (is {})".format( - version_to_string(self.SOURCE_DATE_EPOCH_MIN_VERSION), - version_to_string(self.rpm_bin_version), - )) - - if "TEST_RPM" not in os.environ: - self.fail("TEST_RPM must be set in the environment, containing " - "the name of the RPM to test") - - # Allow for parameterization of this test based on the desired RPM to - # test. - self.rpm_file_path = self.runfiles.Rlocation("/".join([ - os.environ["TEST_WORKSPACE"], - "tests", "rpm", "source_date_epoch", - # The object behind os.environ is not a dict, and thus doesn't have - # the "getdefault()" we'd otherwise use here. - os.environ["TEST_RPM"], - ])) - - def test_contents_match(self): - sio = io.StringIO(EXPECTED_RPM_MANIFEST_CSV) - manifest_reader = csv.DictReader(sio) - manifest_specs = {r['path']: r for r in manifest_reader} - - rpm_specs = rpm_util.read_rpm_filedata( - self.rpm_file_path, - query_tag_map={ - "FILENAMES": "path", - "FILEMTIMES": "mtime", - }) - - self.assertDictEqual(manifest_specs, rpm_specs) - - # Test if the RPM build time field is set to the provided SOURCE_DATE_EPOCH. - def test_buildtime_set(self): - actual_epoch = rpm_util.invoke_rpm_with_queryformat( - self.rpm_file_path, - "%{BUILDTIME}", - ) - self.assertEqual(actual_epoch, EXPECTED_EPOCH) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/rpm/template-test.spec.tpl b/tests/rpm/template-test.spec.tpl deleted file mode 100644 index f771f37..0000000 --- a/tests/rpm/template-test.spec.tpl +++ /dev/null @@ -1,45 +0,0 @@ -# -*- rpm-spec -*- - -################################################################################ -# Test customizations - -# Force MD5 file digesting to preserve compatibility with (very old) versions of -# rpm. -# -# For valid values to set here, see: -# https://github.com/rpm-software-management/rpm/blob/8d628a138ee4c3d1b77b993a3c5b71345ce052e8/macros.in#L393-L405 -# -# At some point, we might want to consider bumping this up to use SHA-1 (2), but -# that would be best reserved for when we don't know of anyone using rpm < 4.6. -%define _source_filedigest_algorithm 1 -%define _binary_filedigest_algorithm 1 - -# Do not try to use magic to determine file types -%define __spec_install_post %{nil} - -################################################################################ - -# Hey! -# -# Keep the below in sync with pkg/rpm/template.spec.tpl! - -################################################################################ - -# This comprises the entirety of the preamble -%include %build_rpm_options - -%description -%include %build_rpm_description - -%install -%include %build_rpm_install - -%files -f %build_rpm_files - -${PRE_SCRIPTLET} - -${POST_SCRIPTLET} - -${PREUN_SCRIPTLET} - -${POSTUN_SCRIPTLET} diff --git a/tests/rpm/test_rpm_dirs_contents.txt.golden b/tests/rpm/test_rpm_dirs_contents.txt.golden deleted file mode 100644 index 8f5b9ef..0000000 --- a/tests/rpm/test_rpm_dirs_contents.txt.golden +++ /dev/null @@ -1,2 +0,0 @@ -drwxr-xr-x /dir --rw-r--r-- /dir/config.txt diff --git a/tests/rpm/toolchain_tests.bzl b/tests/rpm/toolchain_tests.bzl deleted file mode 100644 index 0f6a499..0000000 --- a/tests/rpm/toolchain_tests.bzl +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright 2020 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. - -"""Tests for rpmbuild toolchain type.""" - -load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") -load("//toolchains/rpm:rpmbuild.bzl", "rpmbuild_toolchain") - -# Generic negative test boilerplate -def _generic_neg_test_impl(ctx): - env = analysistest.begin(ctx) - asserts.expect_failure(env, ctx.attr.reason) - return analysistest.end(env) - -generic_neg_test = analysistest.make( - _generic_neg_test_impl, - attrs = { - "reason": attr.string( - default = "", - ), - }, - expect_failure = True, -) - -def _toolchain_contents_test_impl(ctx): - env = analysistest.begin(ctx) - target_under_test = analysistest.target_under_test(env) - - info = target_under_test[platform_common.ToolchainInfo].rpmbuild - asserts.equals( - env, - ctx.attr.expect_valid, - info.valid, - ) - asserts.equals( - env, - ctx.attr.expect_label, - info.label, - ) - asserts.equals( - env, - ctx.attr.expect_path, - info.path, - ) - return analysistest.end(env) - -toolchain_contents_test = analysistest.make( - _toolchain_contents_test_impl, - attrs = { - "expect_valid": attr.bool(default = True), - "expect_label": attr.label( - cfg = "exec", - executable = True, - allow_files = True, - ), - "expect_path": attr.string(), - }, -) - -def _create_toolchain_creation_tests(): - rpmbuild_toolchain( - name = "tc_label_and_path", - label = "foo", - path = "bar", - tags = ["manual"], - ) - generic_neg_test( - name = "tc_label_and_path_test", - target_under_test = ":tc_label_and_path", - reason = "rpmbuild_toolchain must not specify both label and path.", - ) - - rpmbuild_toolchain( - name = "tc_no_label_or_path", - tags = ["manual"], - ) - toolchain_contents_test( - name = "tc_no_label_or_path_test", - target_under_test = ":tc_no_label_or_path", - expect_valid = False, - expect_label = None, - expect_path = "", - ) - - rpmbuild_toolchain( - name = "tc_just_label", - label = ":toolchain_test.bzl", # Using self so we have a real target. - tags = ["manual"], - ) - toolchain_contents_test( - name = "tc_just_label_test", - target_under_test = ":tc_just_label", - expect_valid = True, - expect_label = Label("//tests/rpm:toolchain_test.bzl"), - expect_path = "", - ) - - rpmbuild_toolchain( - name = "tc_just_path", - path = "/usr/bin/foo", - tags = ["manual"], - ) - toolchain_contents_test( - name = "tc_just_path_test", - target_under_test = ":tc_just_path", - expect_valid = True, - expect_label = None, - expect_path = "/usr/bin/foo", - ) - -def create_toolchain_analysis_tests(): - _create_toolchain_creation_tests() diff --git a/tests/rpm/tree_artifacts/BUILD b/tests/rpm/tree_artifacts/BUILD deleted file mode 100644 index f962faa..0000000 --- a/tests/rpm/tree_artifacts/BUILD +++ /dev/null @@ -1,257 +0,0 @@ -# Copyright 2021 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. - -load( - "//pkg:mappings.bzl", - "REMOVE_BASE_DIRECTORY", - "pkg_attributes", - "pkg_filegroup", - "pkg_files", - "strip_prefix", -) -load("//pkg:rpm.bzl", "pkg_rpm") -load("//tests/util:defs.bzl", "directory") -load("@rules_python//python:defs.bzl", "py_test") - -############################################################################ -# Test handling of directory outputs -############################################################################ - -# This package defines tests related to the installation of directory outputs -# (TreeArtifacts) in RPM packages. The rules in common are: -# -# - The order of incoming pkg_filegroups (and their contents) does not matter -# -# - Each file in a TreeArtifact is installed relative to its position in the -# TreeArtifact, which itself is relative to the desired install prefix. - -package(default_applicable_licenses = ["//:license"]) - -# The actual test. It tests whether the contents match a particular desired -# "manifest", most notably with regards to file structure. -py_test( - name = "layer_with_files", - srcs = ["rpm_contents_vs_manifest_test.py"], - data = [":layer_with_files_test_data"], - main = "rpm_contents_vs_manifest_test.py", - tags = [ - "no_windows", # Windows doesn't have rpm(8) or rpmbuild(8) - ], - env = {"TEST_RPM": "test_dirs_rpm-1.1.1-2222.noarch.rpm"}, - deps = [ - "//tests/rpm:rpm_util", - "@rules_python//python/runfiles", - ], -) - -# One cannot simply pass the output of pkg_rpm as runfiles content (#161). This -# seems to be the easiest way around this problem. -sh_library( - name = "layer_with_files_test_data", - testonly = True, - srcs = [":test_dirs_rpm"], -) - -# The RPM (target under test) -pkg_rpm( - name = "test_dirs_rpm", - srcs = [ - ":dirs_test_pfg", - ], - architecture = "noarch", - description = """pkg_rpm test rpm description""", - license = "Apache 2.0", - release = "2222", - spec_template = "//tests/rpm:template-test.spec.tpl", - summary = "pkg_rpm test rpm summary", - version = "1.1.1", -) - -############################################################################ -# Test RPM Contents -############################################################################ - -# Establish a directory structure. This will end up looking like: - -# test_dir/a (created by a "directory" rule) -# test_dir/b (created by a "directory" rule) -# test_dir/subdir/c (created by a "directory" rule) -# test_dir/subdir/d (created by a "directory" rule) -# test_dir/e (created by a genrule) -# test_dir/f (created by a genrule) - -pkg_filegroup( - name = "dirs_test_pfg", - srcs = [ - # do not sort - ":test_dir1_pf", - ":test_files_from_rules", - ], -) - -pkg_files( - name = "test_dir1_pf", - srcs = [":test_dir1"], - attributes = pkg_attributes( - group = "root", - mode = "0644", - user = "root", - ), - strip_prefix = strip_prefix.from_pkg(""), -) - -directory( - name = "test_dir1", - contents = "test_dir1", - filenames = [ - "a", - "b", - "subdir/c", - "subdir/d", - ], - outdir = "test_dir", -) - -pkg_files( - name = "test_files_from_rules", - srcs = [":my_files"], - attributes = pkg_attributes( - group = "root", - mode = "0644", - user = "root", - ), - prefix = "test_dir", -) - -genrule( - name = "my_files", - outs = [ - "e", - "f", - ], - cmd = "touch $(OUTS)", -) - -############################################################################ -# Regression: Ensure that TreeArtifact installation WRT files is independent of install order -############################################################################ - -# The actual test, just like before, except the pkg_filegroup input is slightly -# different. -py_test( - name = "layer_with_files_reversed", - srcs = ["rpm_contents_vs_manifest_test.py"], - data = [":layer_with_files_reversed_test_data"], - env = {"TEST_RPM": "test_dirs_rpm_reversed-1.1.1-2222.noarch.rpm"}, - main = "rpm_contents_vs_manifest_test.py", - tags = [ - "no_windows", # Windows doesn't have rpm(8) or rpmbuild(8) - ], - deps = [ - "//tests/rpm:rpm_util", - "@rules_python//python/runfiles", - ], -) - -# One cannot simply pass the output of pkg_rpm as runfiles content (#161). This -# seems to be the easiest way around this problem. -sh_library( - name = "layer_with_files_reversed_test_data", - testonly = True, - srcs = [":test_dirs_rpm_reversed"], -) - -pkg_rpm( - name = "test_dirs_rpm_reversed", - srcs = [ - ":dirs_test_pfg_reversed", - ], - architecture = "noarch", - description = """pkg_rpm test rpm description""", - license = "Apache 2.0", - release = "2222", - spec_template = "//tests/rpm:template-test.spec.tpl", - summary = "pkg_rpm test rpm summary", - version = "1.1.1", -) - -# Like dirs_test_pfg, but the contents are reversed. One of the major issues -# with #292 was inconsistency due to install order. -pkg_filegroup( - name = "dirs_test_pfg_reversed", - srcs = [ - # do not sort - ":test_files_from_rules", - ":test_dir1_pf", - ], -) - -############################################################################ -# Test that renaming TreeArtifacts to nothing results in the files being dropped -# in their prefix. -############################################################################ -py_test( - name = "treeartifact_ops", - srcs = ["rpm_treeartifact_ops_test.py"], - data = [":treeartifact_ops_rpm_test_data"], - main = "rpm_treeartifact_ops_test.py", - env = {"TEST_RPM": "treeartifact_ops_rpm-1.1.1-2222.noarch.rpm"}, - tags = [ - "no_windows", # Windows doesn't have rpm(8) or rpmbuild(8) - ], - deps = [ - "//tests/rpm:rpm_util", - "@rules_python//python/runfiles", - ], -) - -sh_library( - name = "treeartifact_ops_rpm_test_data", - testonly = True, - srcs = [":treeartifact_ops_rpm"], -) - -pkg_rpm( - name = "treeartifact_ops_rpm", - srcs = [ - ":treeartifact_ops_pfg", - ], - architecture = "noarch", - description = """pkg_rpm test rpm description""", - license = "Apache 2.0", - release = "2222", - spec_template = "//tests/rpm:template-test.spec.tpl", - summary = "pkg_rpm test rpm summary", - version = "1.1.1", -) - -pkg_filegroup( - name = "treeartifact_ops_pfg", - srcs = [ - ":stripped_treeartifact_pf", - ], -) - -pkg_files( - name = "stripped_treeartifact_pf", - srcs = [ - ":test_dir1", - ], - attributes = pkg_attributes( - group = "root", - mode = "0644", - user = "root", - ), - renames = {":test_dir1": REMOVE_BASE_DIRECTORY}, -) diff --git a/tests/rpm/tree_artifacts/rpm_contents_vs_manifest_test.py b/tests/rpm/tree_artifacts/rpm_contents_vs_manifest_test.py deleted file mode 100644 index f0f8b3a..0000000 --- a/tests/rpm/tree_artifacts/rpm_contents_vs_manifest_test.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2021 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. - -import unittest -import csv -import io -import os - -from rules_python.python.runfiles import runfiles -from tests.rpm import rpm_util - -EXPECTED_RPM_MANIFEST_CSV = """ -path,digest,user,group,mode,fflags,symlink -/test_dir/a,dc35e5df50b75e25610e1aaaa29edaa4,root,root,100644,, -/test_dir/b,dc35e5df50b75e25610e1aaaa29edaa4,root,root,100644,, -/test_dir/subdir/c,dc35e5df50b75e25610e1aaaa29edaa4,root,root,100644,, -/test_dir/subdir/d,dc35e5df50b75e25610e1aaaa29edaa4,root,root,100644,, -/test_dir/e,d41d8cd98f00b204e9800998ecf8427e,root,root,100644,, -/test_dir/f,d41d8cd98f00b204e9800998ecf8427e,root,root,100644,, -""".strip() - - -class PkgRpmCompManifest(unittest.TestCase): - def setUp(self): - self.runfiles = runfiles.Create() - self.maxDiff = None - # Allow for parameterization of this test based on the desired RPM to - # test. - - # runfiles prefers Bazely (POSIX-style) relative paths, so we can't - # really use os.path.join() here. - self.rpm_path = self.runfiles.Rlocation('/'.join([ - os.environ["TEST_WORKSPACE"], - "tests", "rpm", "tree_artifacts", - # The object behind os.environ is not a dict, and thus doesn't have - # the "getdefault()" we'd otherwise use here. - os.environ["TEST_RPM"] if "TEST_RPM" in os.environ else "test_dirs_rpm.rpm", - ])) - - def test_contents_match(self): - sio = io.StringIO(EXPECTED_RPM_MANIFEST_CSV) - manifest_reader = csv.DictReader(sio) - manifest_specs = {r['path']: r for r in manifest_reader} - - rpm_specs = rpm_util.read_rpm_filedata(self.rpm_path) - - self.assertDictEqual(manifest_specs, rpm_specs) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/rpm/tree_artifacts/rpm_treeartifact_ops_test.py b/tests/rpm/tree_artifacts/rpm_treeartifact_ops_test.py deleted file mode 100644 index 2f74bc9..0000000 --- a/tests/rpm/tree_artifacts/rpm_treeartifact_ops_test.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2021 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. - -import csv -import io -import os -import unittest - -from rules_python.python.runfiles import runfiles -from tests.rpm import rpm_util - -EXPECTED_RPM_MANIFEST_CSV = """ -path,digest,user,group,mode,fflags,symlink -/a,dc35e5df50b75e25610e1aaaa29edaa4,root,root,100644,, -/b,dc35e5df50b75e25610e1aaaa29edaa4,root,root,100644,, -/subdir/c,dc35e5df50b75e25610e1aaaa29edaa4,root,root,100644,, -/subdir/d,dc35e5df50b75e25610e1aaaa29edaa4,root,root,100644,, -""".strip() - - -class PkgRpmCompManifest(unittest.TestCase): - def setUp(self): - self.runfiles = runfiles.Create() - self.maxDiff = None - # Allow for parameterization of this test based on the desired RPM to - # test. - self.rpm_path = self.runfiles.Rlocation(os.path.join( - os.environ["TEST_WORKSPACE"], - "tests", "rpm", "tree_artifacts", - # The object behind os.environ is not a dict, and thus doesn't have - # the "getdefault()" we'd otherwise use here. - os.environ["TEST_RPM"] if "TEST_RPM" in os.environ else "treeartifact_ops_rpm.rpm", - )) - - def test_contents_match(self): - sio = io.StringIO(EXPECTED_RPM_MANIFEST_CSV) - manifest_reader = csv.DictReader(sio) - manifest_specs = {r['path']: r for r in manifest_reader} - - rpm_specs = rpm_util.read_rpm_filedata(self.rpm_path) - - self.assertDictEqual(manifest_specs, rpm_specs) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/stamp_test.py b/tests/stamp_test.py deleted file mode 100644 index 7ba722b..0000000 --- a/tests/stamp_test.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright 2021 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. -"""Test time stamping in pkg_tar""" - -import datetime -import tarfile -import time -import unittest -import zipfile - -from bazel_tools.tools.python.runfiles import runfiles - -# keep in sync with archive.py -PORTABLE_MTIME = 946684800 # 2000-01-01 00:00:00.000 UTC - - -class StampTest(unittest.TestCase): - """Test for non-epoch time stamps in packages.""" - - target_mtime = int(time.time()) - zip_epoch_dt = datetime.datetime(1980, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc) - ZIP_EPOCH = int(zip_epoch_dt.timestamp()) - # We allow the stamp on the build file to be within this delta back in - # time from now. That allows for the test data to be built early in a clean - # CI run and have the test run a few seconds later. Ideally, this would - # be no greater than the expected total CI run time, but the extra margin - # does not hurt. - ALLOWED_DELTA_FROM_NOW = 30000 # seconds - - def check_mtime(self, mtime, file_path, file_name): - """Checks that a time stamp is reasonable. - - This checks that a timestamp is not 0 or any of the well known EPOCH values, - and that it is within some delta from the current time. - - Args: - mtime: timestamp in seconds - file_path: path to archive name - file_name: file within archive - """ - if mtime == 0: - self.fail('Archive %s contains file %s with mtime == 0' % ( - file_path, file_name)) - if mtime == PORTABLE_MTIME: - self.fail('Archive %s contains file %s with portable mtime' % ( - file_path, file_name)) - if mtime == StampTest.ZIP_EPOCH: - self.fail('Archive %s contains file %s with ZIP epoch' % ( - file_path, file_name)) - if ((mtime < self.target_mtime - StampTest.ALLOWED_DELTA_FROM_NOW) - or (mtime > self.target_mtime)): - self.fail( - 'Archive %s contains file %s with mtime:%d, expected:%d +/- %d.' % ( - file_path, file_name, mtime, self.target_mtime, - StampTest.ALLOWED_DELTA_FROM_NOW) + - ' This may be a false positive if your build cache is more than' + - ' %s seconds old. If so, try bazel clean and rerun the test.' % - StampTest.ALLOWED_DELTA_FROM_NOW) - - def assertTarFilesAreAlmostNew(self, file_name): - """Assert that tarfile contains files with an mtime of roughly now. - - This is used to prove that the test data was a file which was presumably: - built with 'stamp=1' or ('stamp=-1' and --stamp) contains files which - all have a fairly recent mtime, thus indicating they are "current" time - rather than the epoch or some other time. - - Args: - file_name: the path to the TAR file to test. - """ - file_path = runfiles.Create().Rlocation('rules_pkg/tests/' + file_name) - with tarfile.open(file_path, 'r:*') as f: - for info in f: - self.check_mtime(info.mtime, file_path, info.name) - - def assertZipFilesAreAlmostNew(self, file_name): - """Assert that zipfile contains files with an mtime of roughly now. - - This is used to prove that the test data was a file which was presumably: - built with 'stamp=1' or ('stamp=-1' and --stamp) contains files which - all have a fairly recent mtime, thus indicating they are "current" time - rather than the epoch or some other time. - - Args: - file_name: the path to the ZIP file to test. - """ - file_path = runfiles.Create().Rlocation('rules_pkg/tests/' + file_name) - target_mtime = int(time.time()) - with zipfile.ZipFile(file_path, mode='r') as f: - for info in f.infolist(): - d = info.date_time - dt = datetime.datetime(d[0], d[1], d[2], d[3], d[4], d[5], tzinfo=datetime.timezone.utc) - self.check_mtime(int(dt.timestamp()), file_path, info.filename) - - def test_not_epoch_times_tar(self): - self.assertTarFilesAreAlmostNew('stamped_tar.tar') - - def test_not_epoch_times_zip(self): - self.assertZipFilesAreAlmostNew('stamped_zip.zip') - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/tar/BUILD b/tests/tar/BUILD deleted file mode 100644 index 93f2e47..0000000 --- a/tests/tar/BUILD +++ /dev/null @@ -1,609 +0,0 @@ -# Copyright 2021 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. -# -*- coding: utf-8 -*- -"""Tests for pkg_tar.""" - -# buildifier: disable=bzl-visibility -load("//pkg:mappings.bzl", "pkg_attributes") -load("//pkg:mappings.bzl", "pkg_files", "pkg_mkdirs", "pkg_mklink", "strip_prefix") -load("//pkg:verify_archive.bzl", "verify_archive_test") -load("//pkg/private/tar:tar.bzl", "SUPPORTED_TAR_COMPRESSIONS", "pkg_tar") -load("//tests:my_package_name.bzl", "my_package_naming") -load("//tests/util:defs.bzl", "directory", "fake_artifact", "link_tree") -load("@rules_python//python:defs.bzl", "py_test") -load("@bazel_skylib//rules:copy_file.bzl", "copy_file") - -package( - default_applicable_licenses = ["//:license"], - default_visibility = ["//visibility:private"], -) - -py_test( - name = "tar_writer_test", - srcs = [ - "tar_writer_test.py", - ], - imports = ["../.."], - data = [ - ":compressor", - ":test_tar_compression", - ":test_tar_package_dir", - ":test_tar_package_dir_file", - "//tests:testdata/tar_test.tar", - "//tests:testdata/tar_test.tar.bz2", - "//tests:testdata/tar_test.tar.gz", - "//tests:testdata/tar_test.tar.xz", - "//tests:testdata/test_tar_package_dir_file.txt", - ], - python_version = "PY3", - srcs_version = "PY3", - deps = [ - "//pkg/private/tar:tar_writer", - "@bazel_tools//tools/python/runfiles", - ], -) - -genrule( - name = "generate_files", - outs = [ - "etc/nsswitch.conf", - "usr/titi", - ], - cmd = "for i in $(OUTS); do echo 1 >$$i; done", -) - -directory( - name = "generate_tree", - contents = "hello there", - filenames = [ - # buildifier: don't sort - "b/e", - "a/a", - "b/c/d", - "b/d", - "a/b/c", - ], -) - -py_binary( - name = "compressor", - srcs = ["compressor.py"], - python_version = "PY3", - srcs_version = "PY3", -) - -pkg_tar( - name = "test_tar_compression", - compressor = ":compressor", - compressor_args = "-a -b -c", - deps = ["//tests:testdata/tar_test.tar"], -) - -# -# Tests for package_file_name -# -my_package_naming( - name = "my_package_variables", - label = "some_value", -) - -pkg_tar( - name = "test_tar_naming", - srcs = [ - ":BUILD", - ], - package_file_name = "test_naming_{label}.tar", - package_variables = ":my_package_variables", -) - -pkg_mkdirs( - name = "mydir", - dirs = [ - "mydir", - ], -) - -pkg_tar( - name = "test_tar_package_dir_substitution", - srcs = [ - ":BUILD", - ":mydir", - ], - package_dir = "level1/{label}/level3", - package_variables = ":my_package_variables", -) - -pkg_mklink( - name = "mylink", - link_name = "mylink", - target = "dangling", -) - -pkg_tar( - name = "test_tar_package_dir", - srcs = [ - ":etc/nsswitch.conf", - ":mylink", - ], - package_dir = "/my/package", -) - -pkg_tar( - name = "test_tar_package_dir_file", - srcs = [ - ":etc/nsswitch.conf", - ], - package_dir_file = "//tests:testdata/test_tar_package_dir_file.txt", -) - -pkg_tar( - name = "test_tar_out", - srcs = [ - ":BUILD", - ], - out = "out.tar", -) - -[pkg_tar( - name = "test-tar-basic-%s" % ext, - srcs = [ - ":etc/nsswitch.conf", - ":usr/titi", - ], - extension = "tar.%s" % ext if ext else "tar", - mode = "0644", - modes = {"usr/titi": "0755"}, - owner = "42.24", - ownername = "titi.tata", - ownernames = {"etc/nsswitch.conf": "tata.titi"}, - owners = {"etc/nsswitch.conf": "24.42"}, - package_dir = "/", - strip_prefix = ".", - symlinks = {"usr/bin/java": "/path/to/bin/java"}, -) for ext in SUPPORTED_TAR_COMPRESSIONS] - -[pkg_tar( - name = "test-tar-inclusion-%s" % ext, - deps = [ - ":test-tar-basic-%s" % ext, - ":test_tar_naming", - ], -) for ext in SUPPORTED_TAR_COMPRESSIONS] - -pkg_tar( - name = "test-tar-strip_prefix-empty", - srcs = [ - ":etc/nsswitch.conf", - ], - strip_prefix = "", -) - -pkg_tar( - name = "test-tar-strip_prefix-none", - srcs = [ - ":etc/nsswitch.conf", - ], -) - -pkg_tar( - name = "test-tar-strip_prefix-etc", - srcs = [ - ":etc/nsswitch.conf", - ], - strip_prefix = "etc", -) - -pkg_tar( - name = "test-tar-strip_prefix-dot", - srcs = [ - ":etc/nsswitch.conf", - "@bazel_tools//tools/python/runfiles", - ], - strip_prefix = ".", -) - -pkg_tar( - name = "test-tar-strip_prefix-substring", - srcs = [ - ":etc/nsswitch.conf", - ], - strip_prefix = "et", -) - -pkg_tar( - name = "test-tar-files_dict", - files = { - ":etc/nsswitch.conf": "not-etc/mapped-filename.conf", - }, -) - -pkg_tar( - name = "test-tar-empty_files", - empty_files = [ - "/a", - "/b", - ], - mode = "0o777", -) - -pkg_tar( - name = "test-tar-empty_dirs", - empty_dirs = [ - "/tmp", - "/pmt", - ], - mode = "0o777", -) - -pkg_tar( - name = "test-tar-mtime", - srcs = [ - ":etc/nsswitch.conf", - ], - mtime = 946684740, # 1999-12-31, 23:59 - portable_mtime = False, -) - -pkg_tar( - name = "test-tar-long-filename", - srcs = [ - "//tests:testdata/file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt", - ], - # TODO(https://github.com/bazelbuild/rules_pkg/issues/462): The old test - # used to have strip_prefix. But strip_prefix is just plain broken w.r.t. - # files from other packages. We end up with an internal expected data_path - # of tests/tar/<strip_prefix>. But the files coming in have the real paths. - # strip_prefix = "testdata", -) - -pkg_tar( - name = "test-tar-repackaging-long-filename", - package_dir = "can_i_repackage_a_file_with_a_long_name", - deps = [ - ":test-tar-long-filename", - ], -) - -verify_archive_test( - name = "repackaging_long_filename_test", - max_size = 2, - must_contain = [ - "can_i_repackage_a_file_with_a_long_name/file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt", - ], - must_contain_regex = [ - ".*can_i_repackage_a_file_with_a_long_name/$", - ], - # there is really no need for these cases. I just want to use all the test capabilities. - must_not_contain = [ - "i_am_not here", - ], - must_not_contain_regex = [ - "^five.is.right.out", - ], - target = ":test-tar-repackaging-long-filename", -) - -pkg_tar( - name = "test-tar-tree-artifact", - srcs = [ - ":generate_tree", - "//tests:loremipsum_txt", - ], - package_dir = "a_tree", -) - -pkg_files( - name = "tree_noroot", - srcs = [ - ":generate_tree", - ], - strip_prefix = "generate_tree", -) - -pkg_tar( - name = "test-tar-tree-artifact-noroot", - srcs = [ - ":tree_noroot", - "//tests:loremipsum_txt", - ], - package_dir = "a_tree", -) - -fake_artifact( - name = "a_program", - files = ["//tests:testdata/executable.sh"], - runfiles = ["BUILD"], -) - -pkg_tar( - name = "test-tar-with-runfiles", - srcs = [ - ":a_program", - ], - include_runfiles = True, -) - -pkg_tar( - name = "test_tar_leading_dotslash", - srcs = [ - "//tests:loremipsum_txt", - ], - package_dir = ".", -) - -py_test( - name = "pkg_tar_test", - size = "medium", - srcs = [ - "pkg_tar_test.py", - ], - imports = ["../.."], - data = [ - ":test-pkg-tar-from-pkg-files-with-attributes", - ":test-pkg-tar-with-attributes", - ":test-remap-paths-tree-artifact", - ":test-tar-empty_dirs.tar", - ":test-tar-empty_files.tar", - ":test-tar-files_dict.tar", - ":test-tar-long-filename", - ":test-tar-mtime.tar", - ":test-tar-repackaging-long-filename.tar", - ":test-tar-strip_prefix-dot.tar", - ":test-tar-strip_prefix-empty.tar", - ":test-tar-strip_prefix-etc.tar", - ":test-tar-strip_prefix-none.tar", - ":test-tar-strip_prefix-substring.tar", - ":test-tar-tree-artifact", - ":test-tar-tree-artifact-noroot", - ":test-tar-with-runfiles", - ":test-tree-input-with-strip-prefix", - ":test_tar_leading_dotslash", - ":test_tar_package_dir_substitution.tar", - "//tests:testdata/tar_test.tar", - "//tests:testdata/tar_test.tar.bz2", - "//tests:testdata/tar_test.tar.gz", - "//tests:testdata/tar_test.tar.xz", - "//tests:testdata/test_tar_package_dir_file.txt", - ] + [ - ":test-tar-basic-%s" % compression - for compression in SUPPORTED_TAR_COMPRESSIONS - ] + [ - ":test-tar-inclusion-%s" % compression - for compression in SUPPORTED_TAR_COMPRESSIONS - ], - python_version = "PY3", - deps = [ - "//pkg/private/tar:tar_writer", - "@bazel_tools//tools/python/runfiles", - ], -) - -test_suite( - name = "windows_tests", - tags = [ - "-slow", - ], - visibility = ["//visibility:private"], -) - -test_suite( - name = "all_windows_tests", - tests = [":windows_tests"], -) - -pkg_tar( - name = "test-tar-compression-from-extension-targz", - srcs = [ - "//tests:testdata/loremipsum.txt", - ], - extension = ".tar.gz", -) - -pkg_files( - name = "test-pkg-files-with-attributes", - srcs = [ - "//tests:testdata/loremipsum.txt", - ], - attributes = pkg_attributes( - gid = 1000, - group = "grp", - mode = "0440", - uid = 0, - user = "person", - ), - prefix = "/foo/bar", -) - -pkg_tar( - name = "test-pkg-tar-from-pkg-files-with-attributes", - srcs = [ - ":test-pkg-files-with-attributes", - ], -) - -pkg_tar( - name = "test-pkg-tar-with-attributes", - srcs = [ - "//tests:testdata/loremipsum.txt", - ], - owner = "0.1000", - package_dir = "/foo/bar", -) - -pkg_tar( - name = "test-tar-compression-from-extension-tgz", - srcs = [ - "//tests:testdata/loremipsum.txt", - ], - extension = "tgz", -) - -pkg_tar( - name = "test-tar-compression-from-extension-bz2", - srcs = [ - "//tests:testdata/loremipsum.txt", - ], - extension = ".bz2", -) - -py_test( - name = "is_compressed_test", - srcs = ["is_compressed_test.py"], - data = [ - ":test-tar-compression-from-extension-bz2", - ":test-tar-compression-from-extension-targz", - ":test-tar-compression-from-extension-tgz", - ], - python_version = "PY3", - srcs_version = "PY3", - deps = [ - "@bazel_tools//tools/python/runfiles", - ], -) - -directory( - name = "generate_tree_with_prefix", - contents = "hello there", - filenames = [ - "a/a", - "a/b", - ], - outdir = "tree_prefix_to_strip", -) - -pkg_tar( - name = "test-tree-input-with-strip-prefix", - srcs = [ - ":generate_tree_with_prefix", - ], - strip_prefix = "tree_prefix_to_strip", -) - -directory( - name = "tree_artifact_to_rename", - contents = "hello there", - filenames = [ - "a", - "rename_me/should_not_rename", - ], - outdir = "rename_me", -) - -pkg_tar( - name = "test-remap-paths-tree-artifact", - srcs = [ - ":tree_artifact_to_rename", - ], - remap_paths = { - "/rename_me": "a_new_name", - }, -) - -# -# Test with symlinks -# - -link_tree( - name = "node_modules", - links = { - "foo": ".pnpm/foo@1.0.0/node_modules/foo", - ".pnpm/bar@1.0.0/node_modules/bar": "STORE/bar", - ".pnpm/foo@1.0.0/node_modules/foo": "STORE/foo", - ".pnpm/foo@1.0.0/node_modules/bar": "../../bar@1.0.0/node_modules/bar", - }, - package_dir = "node_modules", -) - -directory( - name = "tree_artifact_with_links", - contents = "hello there", - filenames = [ - "foo/hello.txt", - "foo/bar/baz", - ], - # TODO(https://github.com/bazelbuild/rules_pkg/issues/750) - #links = { - # "foo/bar/hello": "../hello.txt", - # "foo/bar/alt_baz": "baz", - # "foo/alt_baz": "bar/baz", - #}, -) - -# This target has symlinks 3 ways. -# - mklinks rules. -# - source files that are symlinks -# - tree artifacts -pkg_tar( - name = "relative_links_tar", - srcs = [ - ":node_modules", - ":tree_artifact_with_links", - "//tests:file_and_link", - ], - symlinks = { - "tree_artifact/toss_in_another": "/foo", - }, -) - -verify_archive_test( - name = "relative_links_test", - min_size = 10, - must_contain = [ - "BUILD", - "outer_BUILD", - "node_modules/.pnpm/bar@1.0.0/node_modules/bar", - ], - tags = ["nowindows"], - target = ":relative_links_tar", - verify_links = { - "node_modules/.pnpm/foo@1.0.0/node_modules/bar": "../../bar@1.0.0/node_modules/bar", - "tree_artifact/toss_in_another": "/foo", - }, -) - -pkg_tar( - name = "relative_links_re_tar", - package_dir = "new/base", - symlinks = { - # We expect package_dir to apply to this - "tree_artifact/toss_in_another": "some_target", - # But we protect the user from duplicationg package_dir in their - # link. That was the old behavior of symlink. - "new/base/something/this": "that", - }, - deps = [ - ":relative_links_tar", - ], -) - -verify_archive_test( - name = "relative_links_re_test", - min_size = 10, - must_contain = [ - "new/base/BUILD", - "new/base/outer_BUILD", - "new/base/node_modules/.pnpm/bar@1.0.0/node_modules/bar", - ], - must_not_contain = [ - "BUILD", - "new/base/new/base/something/this", - ], - tags = ["nowindows"], - target = ":relative_links_re_tar", - verify_links = { - "new/base/node_modules/.pnpm/foo@1.0.0/node_modules/bar": "../../bar@1.0.0/node_modules/bar", - "new/base/tree_artifact/toss_in_another": "some_target", - "new/base/something/this": "that", - }, -) diff --git a/tests/tar/compressor.py b/tests/tar/compressor.py deleted file mode 100644 index 3603d0d..0000000 --- a/tests/tar/compressor.py +++ /dev/null @@ -1,10 +0,0 @@ -'''Fake compressor that just prepends garbage bytes.''' - -import sys - -GARBAGE = b'garbage' - -if __name__ == '__main__': - assert sys.argv[1:] == ['-a', '-b', '-c'] - sys.stdout.buffer.write(GARBAGE) - sys.stdout.buffer.write(sys.stdin.buffer.read()) diff --git a/tests/tar/is_compressed_test.py b/tests/tar/is_compressed_test.py deleted file mode 100644 index 6ed7386..0000000 --- a/tests/tar/is_compressed_test.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2021 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. -"""Tests if input files are compressed.""" - -import unittest - -from bazel_tools.tools.python.runfiles import runfiles - - -class IsCompressedTest(unittest.TestCase): - - def setUp(self): - self.data_files = runfiles.Create() - - def get_file_under_test(self, file_name): - """Get the file path to a generated archive in the runfiles.""" - - return self.data_files.Rlocation( - "rules_pkg/tests/tar/" + file_name - ) - - def is_zip_compressed(self, file_name): - """Returns true if file_name is zip compressed.""" - with open(self.get_file_under_test(file_name), 'rb') as inp: - content = inp.read(2) - # A quick web search will show these magic constants are correct. - return content[0] == 0x1f and content[1] == 0x8b - - def is_bz2_compressed(self, file_name): - """Returns true if file_name is bz2 compressed.""" - with open(self.get_file_under_test(file_name), 'rb') as inp: - content = inp.read(7) - # A quick web search will show these magic constants are correct. - # This is probably well beyond what we need in this test, but why not? - return (content[0] == ord('B') and content[1] == ord('Z') - and ord('1') <= content[3] and content[3] <= ord('9') - and content[4] == 0x31 and content[5] == 0x41 and content[6] == 0x59) - - def test_guess_compression_from_extension(self): - self.assertTrue( - self.is_bz2_compressed("test-tar-compression-from-extension-bz2.bz2")) - self.assertTrue( - self.is_zip_compressed("test-tar-compression-from-extension-targz.tar.gz")) - self.assertTrue( - self.is_zip_compressed("test-tar-compression-from-extension-tgz.tgz")) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/tar/pkg_tar_test.py b/tests/tar/pkg_tar_test.py deleted file mode 100644 index eb8a127..0000000 --- a/tests/tar/pkg_tar_test.py +++ /dev/null @@ -1,298 +0,0 @@ -# Copyright 2015 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. -"""Testing for pkg_tar.""" - -import tarfile -import unittest - -from bazel_tools.tools.python.runfiles import runfiles -from pkg.private.tar import tar_writer - -PORTABLE_MTIME = 946684800 # 2000-01-01 00:00:00.000 UTC - - -class PkgTarTest(unittest.TestCase): - """Testing for pkg_tar rule.""" - - def assertTarFileContent(self, file_name, content, verbose=False): - """Assert that tarfile contains exactly the entry described by `content`. - - Args: - file_name: the path to the TAR file to test. - content: an array describing the expected content of the TAR file. - Each entry in that list should be a dictionary where each field - is a field to test in the corresponding TarInfo. For - testing the presence of a file "x", then the entry could simply - be `{'name': 'x'}`, the missing field will be ignored. To match - the content of a file entry, use the key 'data'. - """ - # NOTE: This is portable to Windows. os.path.join('rules_pkg', 'tests', - # filename) is not. - file_path = runfiles.Create().Rlocation('rules_pkg/tests/tar/' + file_name) - got = [] - with tarfile.open(file_path, 'r:*') as f: - i = 0 - for info in f: - if verbose: - print(' >> from tar file:', info.name) - error_msg = 'Extraneous file at end of archive %s: %s' % ( - file_path, - info.name - ) - self.assertLess(i, len(content), error_msg) - for k, v in content[i].items(): - if k == 'halt': - return - elif k == 'data': - value = f.extractfile(info).read() - elif k == 'isdir': - value = info.isdir() - else: - value = getattr(info, k) - if k == 'mode': - p_value = '0o%o' % value - p_v = '0o%o' % v - else: - p_value = str(value) - p_v = str(v) - error_msg = ' '.join([ - 'Value `%s` for key `%s` of file' % (p_value, k), - '%s in archive %s does' % (info.name, file_path), - 'not match expected value `%s`' % p_v - ]) - self.assertEqual(value, v, error_msg) - if value != v: - print(error_msg) - i += 1 - if i < len(content): - self.fail('Missing file %s in archive %s of [%s]' % ( - content[i], file_path, ',\n '.join(got))) - - def test_strip_prefix_empty(self): - content = [ - {'name': 'nsswitch.conf'}, - ] - self.assertTarFileContent('test-tar-strip_prefix-empty.tar', content) - - def test_strip_prefix_none(self): - content = [ - {'name': 'nsswitch.conf'}, - ] - self.assertTarFileContent('test-tar-strip_prefix-none.tar', content) - - def test_strip_prefix_etc(self): - content = [ - {'name': 'nsswitch.conf'}, - ] - self.assertTarFileContent('test-tar-strip_prefix-etc.tar', content) - - def test_strip_prefix_substring(self): - content = [ - {'name': 'etc', 'isdir': True}, - {'name': 'etc/nsswitch.conf'}, - ] - self.assertTarFileContent('test-tar-strip_prefix-substring.tar', content) - - def test_strip_prefix_dot(self): - content = [ - {'name': 'etc'}, - {'name': 'etc/nsswitch.conf'}, - {'name': 'external'}, - {'name': 'external/bazel_tools'}, - {'name': 'external/bazel_tools/tools'}, - {'name': 'external/bazel_tools/tools/python'}, - {'name': 'external/bazel_tools/tools/python/runfiles'}, - # This is brittle. In old bazel the next file would be - # external/bazel_tools/tools/python/runfiles/runfiles.py, but there - # is now _runfiles_constants.py, first. So this is too brittle. - {'halt': None}, - ] - self.assertTarFileContent('test-tar-strip_prefix-dot.tar', content) - - def test_strip_files_dict(self): - content = [ - {'name': 'not-etc'}, - {'name': 'not-etc/mapped-filename.conf'}, - ] - self.assertTarFileContent('test-tar-files_dict.tar', content) - - def test_empty_files(self): - content = [ - {'name': 'a', 'size': 0, 'uid': 0}, - {'name': 'b', 'size': 0, 'uid': 0, 'mtime': PORTABLE_MTIME}, - ] - self.assertTarFileContent('test-tar-empty_files.tar', content) - - def test_empty_dirs(self): - content = [ - {'name': 'pmt', 'isdir': True, 'size': 0, 'uid': 0, - 'mtime': PORTABLE_MTIME}, - {'name': 'tmp', 'isdir': True, 'size': 0, 'uid': 0, - 'mtime': PORTABLE_MTIME}, - ] - self.assertTarFileContent('test-tar-empty_dirs.tar', content) - - def test_mtime(self): - # Note strange mtime. It is specified in the BUILD file. - content = [ - {'name': 'nsswitch.conf', 'mtime': 946684740}, - ] - self.assertTarFileContent('test-tar-mtime.tar', content) - - def test_basic(self): - # Check the set of 'test-tar-basic-*' smoke test. - content = [ - {'name': 'etc', - 'uid': 24, 'gid': 42, 'uname': 'tata', 'gname': 'titi'}, - {'name': 'etc/nsswitch.conf', - 'mode': 0o644, - 'uid': 24, 'gid': 42, 'uname': 'tata', 'gname': 'titi' - }, - {'name': 'usr', - 'uid': 42, 'gid': 24, 'uname': 'titi', 'gname': 'tata'}, - {'name': 'usr/bin'}, - {'name': 'usr/bin/java', 'linkname': '/path/to/bin/java'}, - {'name': 'usr/titi', - 'mode': 0o755, - 'uid': 42, 'gid': 24, 'uname': 'titi', 'gname': 'tata'}, - ] - for ext in [('.' + comp if comp else '') - for comp in tar_writer.COMPRESSIONS]: - with self.subTest(ext=ext): - self.assertTarFileContent('test-tar-basic-%s.tar%s' % (ext[1:], ext), - content) - - def test_file_inclusion(self): - content = [ - {'name': 'etc', 'uid': 24, 'gid': 42}, - {'name': 'etc/nsswitch.conf', 'mode': 0o644, 'uid': 24, 'gid': 42}, - {'name': 'usr', 'uid': 42, 'gid': 24}, - {'name': 'usr/bin'}, - {'name': 'usr/bin/java', 'linkname': '/path/to/bin/java'}, - {'name': 'usr/titi', 'mode': 0o755, 'uid': 42, 'gid': 24}, - {'name': 'BUILD'}, - ] - for ext in [('.' + comp if comp else '') - for comp in tar_writer.COMPRESSIONS]: - with self.subTest(ext=ext): - self.assertTarFileContent('test-tar-inclusion-%s.tar' % ext[1:], - content) - - def test_strip_prefix_empty(self): - content = [ - {'name': 'level1'}, - {'name': 'level1/some_value'}, - {'name': 'level1/some_value/level3'}, - {'name': 'level1/some_value/level3/BUILD'}, - {'name': 'level1/some_value/level3/mydir'}, - ] - self.assertTarFileContent('test_tar_package_dir_substitution.tar', content) - - def test_tar_with_long_file_name(self): - content = [ - {'name': 'file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt'} - ] - self.assertTarFileContent('test-tar-long-filename.tar', content) - - def test_repackage_file_with_long_name(self): - content = [ - {'name': 'can_i_repackage_a_file_with_a_long_name'}, - {'name': 'can_i_repackage_a_file_with_a_long_name/file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt'} - ] - self.assertTarFileContent('test-tar-repackaging-long-filename.tar', content) - - def test_tar_with_tree_artifact(self): - # (sorted) list of files: - # "a/a" - # "a/b/c" - # "b/c/d" - # "b/d" - # "b/e" - - content = [ - {'name': 'a_tree', 'isdir': True}, - {'name': 'a_tree/generate_tree', 'isdir': True, 'mode': 0o755}, - {'name': 'a_tree/generate_tree/a', 'isdir': True, 'mode': 0o755}, - {'name': 'a_tree/generate_tree/a/a'}, - {'name': 'a_tree/generate_tree/a/b', 'isdir': True, 'mode': 0o755}, - {'name': 'a_tree/generate_tree/a/b/c'}, - {'name': 'a_tree/generate_tree/b', 'isdir': True, 'mode': 0o755}, - {'name': 'a_tree/generate_tree/b/c', 'isdir': True, 'mode': 0o755}, - {'name': 'a_tree/generate_tree/b/c/d'}, - {'name': 'a_tree/generate_tree/b/d'}, - {'name': 'a_tree/generate_tree/b/e'}, - {'name': 'a_tree/loremipsum.txt'}, - ] - self.assertTarFileContent('test-tar-tree-artifact.tar', content) - - # Now test against the tree artifact with the dir name stripped. - noroot_content = [] - for c in content[1:]: # one less level in tree. Skip first element. - nc = dict(c) - nc['name'] = c['name'].replace('/generate_tree', '') - noroot_content.append(nc) - self.assertTarFileContent('test-tar-tree-artifact-noroot.tar', - noroot_content) - - def test_tar_with_runfiles(self): - content = [ - {'name': 'BUILD' }, - {'name': 'a_program' }, - {'name': 'executable.sh' }, - ] - self.assertTarFileContent('test-tar-with-runfiles.tar', content) - - def test_tar_leading_dotslash(self): - content = [ - {'name': './loremipsum.txt'}, - ] - self.assertTarFileContent('test_tar_leading_dotslash.tar', content) - - - def test_pkg_tar_with_attributes(self): - content = [ - {'name': 'foo','uid': 0, 'gid': 1000, 'uname': '', 'gname': ''}, - {'name': 'foo/bar','uid': 0, 'gid': 1000, 'uname': '', 'gname': ''}, - {'name': 'foo/bar/loremipsum.txt','uid': 0, 'gid': 1000, 'uname': '', 'gname': ''}, - ] - self.assertTarFileContent('test-pkg-tar-with-attributes.tar', content) - - def test_pkg_files_with_attributes(self): - content = [ - {'name': 'foo','uid': 0, 'gid': 1000, 'uname': 'person', 'gname': 'grp'}, - {'name': 'foo/bar','uid': 0, 'gid': 1000, 'uname': 'person', 'gname': 'grp'}, - {'name': 'foo/bar/loremipsum.txt','uid': 0, 'gid': 1000, 'uname': 'person', 'gname': 'grp'}, - ] - self.assertTarFileContent('test-pkg-tar-from-pkg-files-with-attributes.tar', content) - - def test_tar_with_tree_artifact_and_strip_prefix(self): - content = [ - {'name': 'a', 'isdir': True}, - {'name': 'a/a'}, - {'name': 'a/b'}, - ] - self.assertTarFileContent('test-tree-input-with-strip-prefix.tar', content) - - def test_remap_paths_tree_artifact(self): - content = [ - {'name': 'a_new_name', 'isdir': True}, - {'name': 'a_new_name/a'}, - {'name': 'a_new_name/rename_me', 'isdir': True}, - {'name': 'a_new_name/rename_me/should_not_rename'}, - ] - self.assertTarFileContent('test-remap-paths-tree-artifact.tar', content) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/tar/tar_writer_test.py b/tests/tar/tar_writer_test.py deleted file mode 100644 index 39008ea..0000000 --- a/tests/tar/tar_writer_test.py +++ /dev/null @@ -1,253 +0,0 @@ -# Copyright 2015 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. -"""Testing for tar_writer.""" - -import os -import tarfile -import unittest - -from bazel_tools.tools.python.runfiles import runfiles -from pkg.private.tar import tar_writer -from tests.tar import compressor - - -class TarFileWriterTest(unittest.TestCase): - """Testing for TarFileWriter class.""" - - def assertTarFileContent(self, tar, content): - """Assert that tarfile contains exactly the entry described by `content`. - - Args: - tar: the path to the TAR file to test. - content: an array describing the expected content of the TAR file. - Each entry in that list should be a dictionary where each field - is a field to test in the corresponding TarInfo. For - testing the presence of a file "x", then the entry could simply - be `{"name": "x"}`, the missing field will be ignored. To match - the content of a file entry, use the key "data". - """ - got_names = [] - with tarfile.open(tar, "r:*") as f: - for current in f: - got_names.append(getattr(current, "name")) - - with tarfile.open(tar, "r:*") as f: - i = 0 - for current in f: - error_msg = "Extraneous file at end of archive %s: %s" % ( - tar, - current.name - ) - self.assertLess(i, len(content), error_msg) - for k, v in content[i].items(): - if k == "data": - value = f.extractfile(current).read() - elif k == "name" and os.name == "nt": - value = getattr(current, k).replace("\\", "/") - else: - value = getattr(current, k) - error_msg = " ".join([ - "Value `%s` for key `%s` of file" % (value, k), - "%s in archive %s does" % (current.name, tar), - "not match expected value `%s`" % v - ]) - error_msg += str(got_names) - self.assertEqual(value, v, error_msg) - i += 1 - if i < len(content): - self.fail("Missing file %s in archive %s" % (content[i], tar)) - - def setUp(self): - super(TarFileWriterTest, self).setUp() - self.tempfile = os.path.join(os.environ["TEST_TMPDIR"], "test.tar") - self.data_files = runfiles.Create() - - def tearDown(self): - super(TarFileWriterTest, self).tearDown() - if os.path.exists(self.tempfile): - os.remove(self.tempfile) - - def testEmptyTarFile(self): - with tar_writer.TarFileWriter(self.tempfile): - pass - self.assertTarFileContent(self.tempfile, []) - - def assertSimpleFileContent(self, names): - with tar_writer.TarFileWriter(self.tempfile) as f: - for n in names: - f.add_file(n, content=n) - # pylint: disable=g-complex-comprehension - content = ([{"name": n, - "size": len(n.encode("utf-8")), - "data": n.encode("utf-8")} - for n in names]) - self.assertTarFileContent(self.tempfile, content) - - def testAddFile(self): - self.assertSimpleFileContent(["./a"]) - self.assertSimpleFileContent(["./b"]) - self.assertSimpleFileContent(["./ab"]) - self.assertSimpleFileContent(["./a", "./b"]) - self.assertSimpleFileContent(["./a", "./ab"]) - self.assertSimpleFileContent(["./a", "./b", "./ab"]) - - def testDottedFiles(self): - with tar_writer.TarFileWriter(self.tempfile) as f: - f.add_file("a") - f.add_file("/b") - f.add_file("./c") - f.add_file("./.d") - f.add_file("..e") - f.add_file(".f") - content = [ - {"name": "a"}, - {"name": "/b"}, - {"name": "./c"}, - {"name": "./.d"}, - {"name": "..e"}, - {"name": ".f"} - ] - self.assertTarFileContent(self.tempfile, content) - - def testMergeTar(self): - content = [ - {"name": "./a", "data": b"a"}, - {"name": "./ab", "data": b"ab"}, - ] - for ext in [("." + comp if comp else "") for comp in tar_writer.COMPRESSIONS]: - with tar_writer.TarFileWriter(self.tempfile) as f: - datafile = self.data_files.Rlocation( - "rules_pkg/tests/testdata/tar_test.tar" + ext) - f.add_tar(datafile, name_filter=lambda n: n != "./b") - self.assertTarFileContent(self.tempfile, content) - - def testMergeTarRelocated(self): - content = [ - {"name": "foo", "mode": 0o755}, - {"name": "foo/a", "data": b"a"}, - {"name": "foo/ab", "data": b"ab"}, - ] - with tar_writer.TarFileWriter(self.tempfile) as f: - datafile = self.data_files.Rlocation( - "rules_pkg/tests/testdata/tar_test.tar") - f.add_tar(datafile, name_filter=lambda n: n != "./b", prefix="foo") - self.assertTarFileContent(self.tempfile, content) - - def testDefaultMtimeNotProvided(self): - with tar_writer.TarFileWriter(self.tempfile) as f: - self.assertEqual(f.default_mtime, 0) - - def testDefaultMtimeProvided(self): - with tar_writer.TarFileWriter(self.tempfile, default_mtime=1234) as f: - self.assertEqual(f.default_mtime, 1234) - - def testPortableMtime(self): - with tar_writer.TarFileWriter(self.tempfile, default_mtime="portable") as f: - self.assertEqual(f.default_mtime, 946684800) - - def testPreserveTarMtimesTrueByDefault(self): - with tar_writer.TarFileWriter(self.tempfile) as f: - input_tar_path = self.data_files.Rlocation( - "rules_pkg/tests/testdata/tar_test.tar") - f.add_tar(input_tar_path) - input_tar = tarfile.open(input_tar_path, "r") - for file_name in f.members: - input_file = input_tar.getmember(file_name) - output_file = f.tar.getmember(file_name) - self.assertEqual(input_file.mtime, output_file.mtime) - - def testPreserveTarMtimesFalse(self): - with tar_writer.TarFileWriter(self.tempfile, preserve_tar_mtimes=False) as f: - input_tar_path = self.data_files.Rlocation( - "rules_pkg/tests/testdata/tar_test.tar") - f.add_tar(input_tar_path) - for output_file in f.tar: - self.assertEqual(output_file.mtime, 0) - - def testAddingDirectoriesForFile(self): - with tar_writer.TarFileWriter(self.tempfile) as f: - f.add_file("d/f") - content = [ - {"name": "d", "mode": 0o755}, - {"name": "d/f"}, - ] - self.assertTarFileContent(self.tempfile, content) - - def testAddingDirectoriesForFileManually(self): - with tar_writer.TarFileWriter(self.tempfile) as f: - f.add_file("d", tarfile.DIRTYPE) - f.add_file("d/f") - - f.add_file("a", tarfile.DIRTYPE) - f.add_file("a/b", tarfile.DIRTYPE) - f.add_file("a/b", tarfile.DIRTYPE) - f.add_file("a/b/", tarfile.DIRTYPE) - f.add_file("a/b/c/f") - - f.add_file("x/y/f") - f.add_file("x", tarfile.DIRTYPE) - content = [ - {"name": "d", "mode": 0o755}, - {"name": "d/f"}, - {"name": "a", "mode": 0o755}, - {"name": "a/b", "mode": 0o755}, - {"name": "a/b/c", "mode": 0o755}, - {"name": "a/b/c/f"}, - {"name": "x", "mode": 0o755}, - {"name": "x/y", "mode": 0o755}, - {"name": "x/y/f"}, - ] - self.assertTarFileContent(self.tempfile, content) - - def testPackageDirAttribute(self): - """Tests package_dir of pkg_tar.""" - package_dir = self.data_files.Rlocation( - "rules_pkg/tests/tar/test_tar_package_dir.tar") - expected_content = [ - {"name": "my"}, - {"name": "my/package"}, - {"name": "my/package/mylink"}, - {"name": "my/package/nsswitch.conf"}, - ] - self.assertTarFileContent(package_dir, expected_content) - - def testPackageDirFileAttribute(self): - """Tests package_dir_file attributes of pkg_tar.""" - package_dir_file = self.data_files.Rlocation( - "rules_pkg/tests/tar/test_tar_package_dir_file.tar") - expected_content = [ - {"name": "package"}, - {"name": "package/nsswitch.conf"}, - ] - self.assertTarFileContent(package_dir_file, expected_content) - - def testCustomCompression(self): - original = self.data_files.Rlocation( - "rules_pkg/tests/testdata/tar_test.tar") - compressed = self.data_files.Rlocation( - "rules_pkg/tests/tar/test_tar_compression.tar") - with open(compressed, "rb") as f_in, open(self.tempfile, "wb") as f_out: - # "Decompress" by skipping garbage bytes - f_in.seek(len(compressor.GARBAGE)) - f_out.write(f_in.read()) - - expected_content = [ - {"name": "./" + x, "data": x.encode("utf-8")} for x in ["a", "b", "ab"] - ] - self.assertTarFileContent(original, expected_content) - self.assertTarFileContent(self.tempfile, expected_content) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/testdata/README.md b/tests/testdata/README.md deleted file mode 100644 index d833016..0000000 --- a/tests/testdata/README.md +++ /dev/null @@ -1,20 +0,0 @@ -This folder contains test data. - -The utf8 folder contains a set of files whose names are not ASCII or ISO-8859-1. -They may be used for testing the ability to handle files using non ASCII -file names. Along with those we have 4 samples of what native tar and zip -utilities do with these file names: - -- utf8_linux.tar: From linux: `tar cf utf8_linux.tar utf8` -- utf8_linux.zip From linux: `zip -r utf8_linux.zip utf8` -- utf8_mac.tar: From macos: `tar cf utf8_linux.tar utf8` -- utf8_mac.zip From macos: `zip -r utf8_linux.zip utf8` -- utf8_win.tar: From window: `tar cf utf8_win.tar utf8` -- utf8_win.zip From window: `7z a -r utf8_win.zip utf8` - -The samples are are intended to be used as input data for tests -of capabilities that read data (such as unpacking and filtering -a tar file). Code must be able to read tar and zip files produced -on a different OS and interpret file names correctly. For now we -can study the differences by platform. - diff --git a/tests/testdata/a.ar b/tests/testdata/a.ar deleted file mode 100644 index d2594df..0000000 --- a/tests/testdata/a.ar +++ /dev/null @@ -1,3 +0,0 @@ -!<arch> -a/ 1439231934 1000 1000 100664 1 ` -a diff --git a/tests/testdata/a_ab.ar b/tests/testdata/a_ab.ar deleted file mode 100644 index f6b7217..0000000 --- a/tests/testdata/a_ab.ar +++ /dev/null @@ -1,5 +0,0 @@ -!<arch> -a/ 1439231934 1000 1000 100664 1 ` -a -ab/ 1439231936 1000 1000 100664 2 ` -ab diff --git a/tests/testdata/a_b.ar b/tests/testdata/a_b.ar deleted file mode 100644 index 6f2d79c..0000000 --- a/tests/testdata/a_b.ar +++ /dev/null @@ -1,5 +0,0 @@ -!<arch> -a/ 1439231934 1000 1000 100664 1 ` -a -b/ 1439231939 1000 1000 100664 1 ` -b diff --git a/tests/testdata/a_b_ab.ar b/tests/testdata/a_b_ab.ar deleted file mode 100644 index 07dc3e7..0000000 --- a/tests/testdata/a_b_ab.ar +++ /dev/null @@ -1,7 +0,0 @@ -!<arch> -a/ 1439231934 1000 1000 100664 1 ` -a -b/ 1439231939 1000 1000 100664 1 ` -b -ab/ 1439231936 1000 1000 100664 2 ` -ab diff --git a/tests/testdata/ab.ar b/tests/testdata/ab.ar deleted file mode 100644 index 29f56be..0000000 --- a/tests/testdata/ab.ar +++ /dev/null @@ -1,3 +0,0 @@ -!<arch> -ab/ 1439231936 1000 1000 100664 2 ` -ab diff --git a/tests/testdata/b.ar b/tests/testdata/b.ar deleted file mode 100644 index 3f41a7e..0000000 --- a/tests/testdata/b.ar +++ /dev/null @@ -1,3 +0,0 @@ -!<arch> -b/ 1439231939 1000 1000 100664 1 ` -b diff --git a/tests/testdata/config b/tests/testdata/config deleted file mode 100644 index d39edc7..0000000 --- a/tests/testdata/config +++ /dev/null @@ -1 +0,0 @@ -# test config file diff --git a/tests/testdata/deb_preinst b/tests/testdata/deb_preinst deleted file mode 100644 index 9a88ab0..0000000 --- a/tests/testdata/deb_preinst +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -# tete ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é -echo fnord diff --git a/tests/testdata/deb_triggers b/tests/testdata/deb_triggers deleted file mode 100644 index e7c1249..0000000 --- a/tests/testdata/deb_triggers +++ /dev/null @@ -1,2 +0,0 @@ -# tutu ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é -some-trigger diff --git a/tests/testdata/empty.ar b/tests/testdata/empty.ar deleted file mode 100644 index 8b277f0..0000000 --- a/tests/testdata/empty.ar +++ /dev/null @@ -1 +0,0 @@ -!<arch> diff --git a/tests/testdata/executable.sh b/tests/testdata/executable.sh deleted file mode 100755 index e5d3986..0000000 --- a/tests/testdata/executable.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -echo "Hello" diff --git a/tests/testdata/file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt b/tests/testdata/file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt deleted file mode 100644 index cd773cd..0000000 --- a/tests/testdata/file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt +++ /dev/null @@ -1 +0,0 @@ -Hello there!
\ No newline at end of file diff --git a/tests/testdata/hello.txt b/tests/testdata/hello.txt deleted file mode 100644 index af5626b..0000000 --- a/tests/testdata/hello.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! diff --git a/tests/testdata/loremipsum.txt b/tests/testdata/loremipsum.txt deleted file mode 100644 index ab7ff0e..0000000 --- a/tests/testdata/loremipsum.txt +++ /dev/null @@ -1,7 +0,0 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sit amet nunc -lectus. Sed at nulla vel turpis egestas pharetra et at velit. Cras pharetra -iaculis dui, id vestibulum odio auctor eget. Class aptent taciti sociosqu ad -litora torquent per conubia nostra, per inceptos himenaeos. Ut massa lectus, -lobortis vel vehicula id, mattis id odio. Mauris eget imperdiet nisi. Nunc id -urna a lorem porttitor varius ut vitae risus. Ut faucibus, magna eget rutrum -efficitur, nulla nulla porta lectus, venenatis convallis nisi magna auctor arcu. diff --git a/tests/testdata/outer_BUILD b/tests/testdata/outer_BUILD deleted file mode 120000 index c447d20..0000000 --- a/tests/testdata/outer_BUILD +++ /dev/null @@ -1 +0,0 @@ -../BUILD
\ No newline at end of file diff --git a/tests/testdata/tar_test.tar b/tests/testdata/tar_test.tar Binary files differdeleted file mode 100644 index 70b043b..0000000 --- a/tests/testdata/tar_test.tar +++ /dev/null diff --git a/tests/testdata/tar_test.tar.bz2 b/tests/testdata/tar_test.tar.bz2 Binary files differdeleted file mode 100644 index c6f7edf..0000000 --- a/tests/testdata/tar_test.tar.bz2 +++ /dev/null diff --git a/tests/testdata/tar_test.tar.gz b/tests/testdata/tar_test.tar.gz Binary files differdeleted file mode 100644 index 4b85171..0000000 --- a/tests/testdata/tar_test.tar.gz +++ /dev/null diff --git a/tests/testdata/tar_test.tar.xz b/tests/testdata/tar_test.tar.xz Binary files differdeleted file mode 100644 index 1ea3c8b..0000000 --- a/tests/testdata/tar_test.tar.xz +++ /dev/null diff --git a/tests/testdata/templates b/tests/testdata/templates deleted file mode 100644 index 0576bc0..0000000 --- a/tests/testdata/templates +++ /dev/null @@ -1,6 +0,0 @@ -Template: deb/test -Type: string -Default: -Description: test question - test question to check that templates are included into - debian directory diff --git a/tests/testdata/test_tar_package_dir_file.txt b/tests/testdata/test_tar_package_dir_file.txt deleted file mode 100755 index 1337ba4..0000000 --- a/tests/testdata/test_tar_package_dir_file.txt +++ /dev/null @@ -1 +0,0 @@ -/package diff --git a/tests/testdata/utf8/1-a b/tests/testdata/utf8/1-a deleted file mode 100644 index c4d36ef..0000000 --- a/tests/testdata/utf8/1-a +++ /dev/null @@ -1 +0,0 @@ -my name takes 3 octets in utf-8 diff --git a/tests/testdata/utf8/2-λ b/tests/testdata/utf8/2-λ deleted file mode 100644 index 259e8c7..0000000 --- a/tests/testdata/utf8/2-λ +++ /dev/null @@ -1 +0,0 @@ -my name takes 4 octets in utf-8 diff --git a/tests/testdata/utf8/3-世 b/tests/testdata/utf8/3-世 deleted file mode 100644 index 5eee6f9..0000000 --- a/tests/testdata/utf8/3-世 +++ /dev/null @@ -1 +0,0 @@ -my name takes 5 octets in utf-8 diff --git a/tests/testdata/utf8/BUILD b/tests/testdata/utf8/BUILD deleted file mode 100644 index 7f7df7b..0000000 --- a/tests/testdata/utf8/BUILD +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2021 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. - -package(default_applicable_licenses = ["//:license"]) - -filegroup( - name = "files", - srcs = glob(["**"]), - visibility = ["//visibility:public"], -) diff --git a/tests/testdata/utf8/sübdir/2-λ b/tests/testdata/utf8/sübdir/2-λ deleted file mode 100644 index 259e8c7..0000000 --- a/tests/testdata/utf8/sübdir/2-λ +++ /dev/null @@ -1 +0,0 @@ -my name takes 4 octets in utf-8 diff --git a/tests/testdata/utf8/sübdir/hello b/tests/testdata/utf8/sübdir/hello deleted file mode 100644 index ce01362..0000000 --- a/tests/testdata/utf8/sübdir/hello +++ /dev/null @@ -1 +0,0 @@ -hello diff --git a/tests/testdata/utf8_linux.tar b/tests/testdata/utf8_linux.tar Binary files differdeleted file mode 100644 index 9d80445..0000000 --- a/tests/testdata/utf8_linux.tar +++ /dev/null diff --git a/tests/testdata/utf8_linux.zip b/tests/testdata/utf8_linux.zip Binary files differdeleted file mode 100644 index d9bd445..0000000 --- a/tests/testdata/utf8_linux.zip +++ /dev/null diff --git a/tests/testdata/utf8_mac.tar b/tests/testdata/utf8_mac.tar Binary files differdeleted file mode 100644 index e2957e6..0000000 --- a/tests/testdata/utf8_mac.tar +++ /dev/null diff --git a/tests/testdata/utf8_mac.zip b/tests/testdata/utf8_mac.zip Binary files differdeleted file mode 100644 index 3709637..0000000 --- a/tests/testdata/utf8_mac.zip +++ /dev/null diff --git a/tests/testdata/utf8_win.tar b/tests/testdata/utf8_win.tar Binary files differdeleted file mode 100755 index c5b934b..0000000 --- a/tests/testdata/utf8_win.tar +++ /dev/null diff --git a/tests/testdata/utf8_win.zip b/tests/testdata/utf8_win.zip Binary files differdeleted file mode 100755 index 7ede87f..0000000 --- a/tests/testdata/utf8_win.zip +++ /dev/null diff --git a/tests/util/BUILD b/tests/util/BUILD deleted file mode 100644 index c4f4a31..0000000 --- a/tests/util/BUILD +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2021 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. - -# Test utilities - -load("@rules_python//python:defs.bzl", "py_binary") - -package(default_applicable_licenses = ["//:license"]) - -licenses(["notice"]) - -exports_files(["defs.bzl"]) - -py_binary( - name = "md5", - srcs = ["md5.py"], - python_version = "PY3", - srcs_version = "PY3", - visibility = ["//visibility:public"], -) - -py_binary( - name = "create_directory_with_contents", - srcs = ["create_directory_with_contents.py"], - python_version = "PY3", - srcs_version = "PY3", - visibility = ["//visibility:public"], -) diff --git a/tests/util/create_directory_with_contents.py b/tests/util/create_directory_with_contents.py deleted file mode 100644 index 7138884..0000000 --- a/tests/util/create_directory_with_contents.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2021 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. - -import sys -import os - -"""Creates a directory containing some files with provided contents - -Usage: ./this.py output_dir_name file1 contents1 ... fileN contentsN -""" - -dirname = sys.argv[1] - -files_contents_map = {} - -# Simple way of grouping over pairs. There are other ones, like -# https://stackoverflow.com/a/16789836, but they either requiring copying a -# bunch of code around or having something that's a smidge unreadable. -rest_args_iter = iter(sys.argv[2:]) -for a in rest_args_iter: - files_contents_map[a] = next(rest_args_iter) - -os.makedirs(dirname, exist_ok=True) - -for fname, contents in files_contents_map.items(): - path = os.path.join(dirname, fname) - os.makedirs( - os.path.dirname(path), - exist_ok=True, - ) - if contents.startswith('@@'): - os.symlink(contents[2:], path) - else: - with open(path, 'w') as fh: - fh.write(contents) diff --git a/tests/util/defs.bzl b/tests/util/defs.bzl deleted file mode 100644 index e26b16f..0000000 --- a/tests/util/defs.bzl +++ /dev/null @@ -1,219 +0,0 @@ -# Copyright 2021 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. -"""Rules to aid testing""" - -load("//pkg/private:pkg_files.bzl", "add_label_list", "write_manifest") -load("//pkg:providers.bzl", "PackageFilegroupInfo", "PackageSymlinkInfo") -load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") - -def _directory_impl(ctx): - out_dir_file = ctx.actions.declare_directory(ctx.attr.outdir or ctx.attr.name) - - args = ctx.actions.args() - args.add(out_dir_file.path) - - # This helper is horrible. We should pass all the args in files. - for fn in ctx.attr.filenames: - args.add(fn) - args.add(ctx.attr.contents) - - for link, target in ctx.attr.links.items(): - args.add(link) - args.add('@@' + target) - - ctx.actions.run( - outputs = [out_dir_file], - inputs = [], - executable = ctx.executable._dir_creator, - arguments = [args], - ) - return DefaultInfo(files = depset([out_dir_file])) - -directory = rule( - doc = """Helper rule to create simple TreeArtifact structures - -We would normally just use genrules for this, but their directory output -creation capabilities are "unsound". - """, - implementation = _directory_impl, - attrs = { - "filenames": attr.string_list( - doc = """Paths to create in the directory. - -Paths containing directories will also have the intermediate directories created too.""", - ), - "links": attr.string_dict( - doc = """Set of (virtual) links to create. - -The keys of links are paths to create. The values are the target of the links.""", - ), - "contents": attr.string(), - "outdir": attr.string(), - "_dir_creator": attr.label( - default = ":create_directory_with_contents", - executable = True, - cfg = "exec", - ), - }, -) - -def _fake_artifact_impl(ctx): - out_file = ctx.actions.declare_file(ctx.attr.name) - content = ["echo " + rf.path for rf in ctx.files.runfiles] - ctx.actions.write( - output = out_file, - content = "\r\n".join(content), - is_executable = ctx.attr.executable, - ) - return DefaultInfo( - files = depset([out_file] + ctx.files.files), - runfiles = ctx.runfiles(files = ctx.files.runfiles), - executable = out_file if ctx.attr.executable else None, - ) - -fake_artifact = rule( - doc = """Rule to create a fake artifact that depends on its srcs. - -This rule creates a file that appears to depend on its srcs and passes along -other targets in DefaultInfo as files and/or runfiles. It creates a script that -echos all the file names. It is useful for building an object that is like a -cc_binary in complexity, but does not depend on a large toolchain.""", - implementation = _fake_artifact_impl, - attrs = { - "deps": attr.label_list( - doc = "Dependencies to trigger other rules, but are then discarded.", - allow_files = True, - ), - "files": attr.label_list( - doc = "Deps which are passed in DefaultInfo as files.", - allow_files = True, - ), - "runfiles": attr.label_list( - doc = "Deps which are passed in DefaultInfo as runfiles.", - allow_files = True, - ), - "executable": attr.bool( - doc = "If True, the DefaultInfo will be marked as executable.", - default = False, - ), - }, -) - -def _link_tree_impl(ctx): - links = [] - prefix = ctx.attr.package_dir or "" - if prefix and not prefix.endswith('/'): - prefix = prefix + "/" - for link, target in ctx.attr.links.items(): - # DBG print(' %s -> %s ' % (link, target)) - links.append( - (PackageSymlinkInfo(destination = prefix + link, target = target), - ctx.label)) - return [PackageFilegroupInfo(pkg_symlinks = links)] - -link_tree = rule( - doc = """Helper rule to create a lot of fake symlinks. - -The inspiration is to create test data for the kinds of layouts needed by -nodejs. See. https://pnpm.io/symlinked-node-modules-structure - """, - implementation = _link_tree_impl, - attrs = { - "links": attr.string_dict( - doc = """Set of (virtual) links to create. - -The keys of links are paths to create. The values are the target of the links.""", - mandatory = True, - ), - "package_dir": attr.string(doc = """Prefix to apply to all link paths."""), - }, - provides = [PackageFilegroupInfo], -) - -def _write_content_manifest_impl(ctx): - content_map = {} # content handled in the manifest - file_deps = [] # inputs we depend on - add_label_list(ctx, content_map, file_deps, ctx.attr.srcs) - write_manifest(ctx, ctx.outputs.out, content_map, use_short_path = ctx.attr.use_short_path) - -_write_content_manifest = rule( - doc = """Helper rule to write the content manifest for a pkg_*. - -This is intended only for testing the manifest creation features.""", - implementation = _write_content_manifest_impl, - attrs = { - "srcs": attr.label_list( - doc = """List of source inputs.""", - allow_files = True, - ), - "out": attr.output(), - "use_short_path": attr.bool( - doc = """Use the rootless path in the manifest. - - Useful to ensure that the platform-specific prefix (i.e. parts - including something like "x64_windows-fastbuild") isn't present in - paths in the manifest. - - See also https://docs.bazel.build/versions/main/skylark/lib/File.html#path - """, - default = True, - ), - "include_runfiles": attr.bool(), - }, -) - -def write_content_manifest(name, srcs, **kwargs): - out = kwargs.pop("out", name + ".manifest") - use_short_path = kwargs.pop("use_short_path", True) - _write_content_manifest( - name = name, - srcs = srcs, - out = out, - use_short_path = use_short_path, - **kwargs, - ) - -############################################################ -# Test boilerplate -############################################################ -def _generic_base_case_test_impl(ctx): - env = analysistest.begin(ctx) - - # Nothing here intentionally, this is simply an attempt to verify successful - # analysis. - - return analysistest.end(env) - -generic_base_case_test = analysistest.make( - _generic_base_case_test_impl, - attrs = {}, -) - -# Generic negative test boilerplate -def _generic_negative_test_impl(ctx): - env = analysistest.begin(ctx) - - asserts.expect_failure(env, ctx.attr.reason) - - return analysistest.end(env) - -generic_negative_test = analysistest.make( - _generic_negative_test_impl, - attrs = { - "reason": attr.string( - default = "", - ), - }, - expect_failure = True, -) diff --git a/tests/util/md5.py b/tests/util/md5.py deleted file mode 100644 index 6f0f81c..0000000 --- a/tests/util/md5.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2021 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. - -'''Simple cross-platform md5sum tool for computing hashes in packaging tests.''' - -import hashlib -import sys - -fname = sys.argv[1] - -md5 = hashlib.md5() - -with open(fname, 'rb') as fh: - md5.update(fh.read()) - -print(md5.hexdigest()) diff --git a/tests/zip/BUILD b/tests/zip/BUILD deleted file mode 100644 index 52b17f0..0000000 --- a/tests/zip/BUILD +++ /dev/null @@ -1,338 +0,0 @@ -# Copyright 2021 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. -# -*- coding: utf-8 -*- - -load("//pkg:mappings.bzl", "pkg_attributes", "pkg_mkdirs", "pkg_mklink") -load("//pkg:zip.bzl", "pkg_zip") -load("//tests:my_package_name.bzl", "my_package_naming") -load("//tests/util:defs.bzl", "directory", "fake_artifact") -load("@rules_python//python:defs.bzl", "py_library", "py_test") -load("@bazel_skylib//rules:copy_file.bzl", "copy_file") - -package(default_applicable_licenses = ["//:license"]) - -licenses(["notice"]) - -py_library( - name = "zip_test_lib", - srcs = [ - "zip_test_lib.py", - ], - imports = ["../.."], - srcs_version = "PY3", - deps = [ - "@bazel_tools//tools/python/runfiles", - ], -) - -genrule( - name = "generate_files", - outs = [ - "etc/nsswitch.conf", - "usr/titi", - ], - cmd = "for i in $(OUTS); do echo 1 >$$i; done", -) - -pkg_mkdirs( - name = "dirs", - attributes = pkg_attributes( - group = "bar", - mode = "711", - user = "foo", - ), - dirs = [ - "foodir", - ], -) - -pkg_mklink( - name = "link", - attributes = pkg_attributes( - mode = "555", - ), - link_name = "/usr/bin/foo", - target = "/usr/local/foo/foo.real", -) - -directory( - name = "generate_tree", - contents = "hello there", - filenames = [ - # buildifier: don't sort - "b/e", - "a/a", - "b/c/d", - "b/d", - "a/b/c", - ], -) - -copy_file( - name = "zipcontent_loremipsum", - src = "//tests:testdata/loremipsum.txt", - out = "zipcontent/loremipsum.txt", -) - -pkg_zip( - name = "test_zip_empty", - srcs = [], -) - -# The contents of this file should equal test_zip_empty -pkg_zip( - name = "test_zip_basic_renamed", - srcs = [ - ":dirs", - ":link", - "//tests:an_executable", - "//tests:testdata/hello.txt", - "//tests:testdata/loremipsum.txt", - ], - package_file_name = "test_zip_basic_renamed.foo", -) - -pkg_zip( - name = "test_zip_basic", - srcs = [ - ":dirs", - ":link", - "//tests:an_executable", - "//tests:testdata/hello.txt", - "//tests:testdata/loremipsum.txt", - ], -) - -pkg_zip( - name = "test_zip_out", - srcs = [ - "//tests:testdata/hello.txt", - "//tests:testdata/loremipsum.txt", - ], - out = "test_zip_out.foo", -) - -pkg_zip( - name = "test_zip_timestamp", - srcs = [ - "//tests:testdata/hello.txt", - ], - timestamp = 1234567890, -) - -pkg_zip( - name = "test_zip_tree", - srcs = [":generate_tree"], -) - -pkg_zip( - name = "test_zip_permissions", - srcs = [ - "//tests:testdata/executable.sh", - ], - mode = "644", - timestamp = 1234567890, -) - -# This should be equal to test_zip_basic because timestamps are rounded -# up to Jan 1 1980. -pkg_zip( - name = "test_zip_basic_timestamp_before_epoch", - srcs = [ - ":dirs", - ":link", - "//tests:an_executable", - "//tests:testdata/hello.txt", - "//tests:testdata/loremipsum.txt", - ], - timestamp = 0, -) - -pkg_zip( - name = "test-zip-strip_prefix-empty", - srcs = [ - "zipcontent_loremipsum", - ], - strip_prefix = "", -) - -pkg_zip( - name = "test-zip-strip_prefix-none", - srcs = [ - "zipcontent_loremipsum", - ], -) - -pkg_zip( - name = "test-zip-strip_prefix-zipcontent", - srcs = [ - "zipcontent_loremipsum", - ], - strip_prefix = "zipcontent", -) - -pkg_zip( - name = "test-zip-strip_prefix-dot", - srcs = [ - "zipcontent_loremipsum", - ], - strip_prefix = ".", -) - -filegroup( - name = "test_zip_strip_prefix", - srcs = [ - "test-zip-strip_prefix-dot", - "test-zip-strip_prefix-empty", - "test-zip-strip_prefix-none", - "test-zip-strip_prefix-zipcontent", - ], -) - -pkg_mklink( - name = "mylink", - link_name = "mylink", - target = "dangling", -) - -# All of these should produce the same zip file. -[pkg_zip( - name = "test_zip_package_dir" + str(idx), - srcs = [ - ":mylink", - "//tests:testdata/hello.txt", - "//tests:testdata/loremipsum.txt", - ], - package_dir = package_dir, -) for (idx, package_dir) in enumerate([ - "abc/def", - "/abc/def", - "/abc/def/", -])] - -my_package_naming( - name = "my_package_variables", - label = "some_value", -) - -pkg_zip( - name = "test_zip_package_dir_substitution", - srcs = [ - "//tests:testdata/hello.txt", - "//tests:testdata/loremipsum.txt", - ], - package_dir = "/level1/{label}/level3", - package_variables = ":my_package_variables", -) - -# Different compressions -pkg_zip( - name = "test_zip_deflated_level_3", - srcs = [ - "//tests:testdata/loremipsum.txt", - ], - compression_type = "deflated", - compression_level = 3, -) -pkg_zip( - name = "test_zip_bzip2", - srcs = [ - "//tests:testdata/loremipsum.txt", - ], - compression_type = "bzip2", -) -pkg_zip( - name = "test_zip_lzma", - srcs = [ - "//tests:testdata/loremipsum.txt", - ], - compression_type = "lzma", -) -pkg_zip( - name = "test_zip_stored", - srcs = [ - "//tests:testdata/loremipsum.txt", - ], - compression_type = "stored", -) - -py_test( - name = "zip_test", - srcs = [ - "zip_test.py", - ], - data = [ - ":test-zip-strip_prefix-dot.zip", - ":test-zip-strip_prefix-empty.zip", - ":test-zip-strip_prefix-none.zip", - ":test-zip-strip_prefix-zipcontent.zip", - ":test_zip_basic.zip", - ":test_zip_empty.zip", - ":test_zip_package_dir0.zip", - ":test_zip_package_dir_substitution.zip", - ":test_zip_permissions.zip", - ":test_zip_timestamp.zip", - ":test_zip_tree.zip", - ":test_zip_deflated_level_3", - ":test_zip_bzip2", - ":test_zip_lzma", - ":test_zip_stored", - ], - python_version = "PY3", - deps = [ - ":zip_test_lib", - ], -) - -py_test( - name = "zip_byte_for_byte_test", - srcs = [ - "zip_byte_for_byte_test.py", - ], - data = [ - ":test_zip_basic.zip", - ":test_zip_basic_renamed", - # We do not actually use this file, we just want to make sure we build - # it with this name. - ":test_zip_out.foo", - ":test_zip_package_dir0.zip", - # these could be replaced with diff_test() rules (from skylib) - ":test_zip_basic_timestamp_before_epoch.zip", - ":test_zip_package_dir1.zip", - ":test_zip_package_dir2.zip", - ], - python_version = "PY3", - deps = [ - ":zip_test_lib", - ], -) - -pkg_zip( - name = "unicode_names", - srcs = ["//tests:utf8_files"] -) - -py_test( - name = "unicode_test", - srcs = [ - "unicode_test.py", - ], - data = [ - ":unicode_names", - ], - python_version = "PY3", - deps = [ - ":zip_test_lib", - ], -) diff --git a/tests/zip/unicode_test.py b/tests/zip/unicode_test.py deleted file mode 100644 index 641394a..0000000 --- a/tests/zip/unicode_test.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2022 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. - -import unittest - -from tests.zip import zip_test_lib - -class UnicodeHandlingTests(zip_test_lib.ZipContentsTestBase): - - def test_unicode_file_names(self): - self.assertZipFileContent("unicode_names.zip", [ - {"filename": "1-a"}, - {"filename": "2-λ"}, - {"filename": "3-世"}, - {"filename": "BUILD"}, - {"filename": "sübdir/", "isdir": True}, - {"filename": "sübdir/2-λ"}, - {"filename": "sübdir/hello"}, - ]) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/zip/zip_byte_for_byte_test.py b/tests/zip/zip_byte_for_byte_test.py deleted file mode 100644 index 05744d4..0000000 --- a/tests/zip/zip_byte_for_byte_test.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2019 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. - -import filecmp -import unittest - -from tests.zip import zip_test_lib - - -class ZipEquivalency(zip_test_lib.ZipTest): - """Check that some generated zip files are equivalent to each-other.""" - - def assertFilesEqual(self, actual, expected): - """Assert that two zip files contain the same bytes.""" - - zips_are_equal = filecmp.cmp( - self.get_test_zip(actual), - self.get_test_zip(expected), - ) - self.assertTrue(zips_are_equal) - - def test_small_timestamp(self): - self.assertFilesEqual( - "test_zip_basic_timestamp_before_epoch.zip", - "test_zip_basic.zip", - ) - - def test_extension(self): - self.assertFilesEqual( - "test_zip_basic_renamed.foo", - "test_zip_basic.zip", - ) - - def test_package_dir1(self): - self.assertFilesEqual( - "test_zip_package_dir1.zip", - "test_zip_package_dir0.zip", - ) - - def test_package_dir2(self): - self.assertFilesEqual( - "test_zip_package_dir2.zip", - "test_zip_package_dir0.zip", - ) - -if __name__ == "__main__": - unittest.main() diff --git a/tests/zip/zip_test.py b/tests/zip/zip_test.py deleted file mode 100644 index e5955eb..0000000 --- a/tests/zip/zip_test.py +++ /dev/null @@ -1,156 +0,0 @@ -# Copyright 2019 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. - -import datetime -import filecmp -import os -import sys -import unittest -import zipfile - -from bazel_tools.tools.python.runfiles import runfiles -from tests.zip import zip_test_lib - -HELLO_CRC = 2069210904 -LOREM_CRC = 2178844372 -EXECUTABLE_CRC = 342626072 - - -class ZipContentsTests(zip_test_lib.ZipContentsTestBase): - - def test_empty(self): - self.assertZipFileContent("test_zip_empty.zip", []) - - def test_basic(self): - if os.name == "nt": - expect = [ - {"filename": "an_executable.exe", "isexe": True}, - {"filename": "foodir/", "isdir": True, "attr": 0o711}, - {"filename": "hello.txt", "crc": HELLO_CRC}, - {"filename": "loremipsum.txt", "crc": LOREM_CRC}, - {"filename": "usr/", "isdir": True, "attr": 0o755}, - {"filename": "usr/bin/", "isdir": True, "attr": 0o755}, - {"filename": "usr/bin/foo", "isexe": True, "data": "/usr/local/foo/foo.real"}, - ] - else: - expect = [ - {"filename": "an_executable", "isexe": True}, - {"filename": "foodir/", "isdir": True, "attr": 0o711}, - {"filename": "hello.txt", "crc": HELLO_CRC}, - {"filename": "loremipsum.txt", "crc": LOREM_CRC}, - {"filename": "usr/", "isdir": True, "attr": 0o755}, - {"filename": "usr/bin/", "isdir": True, "attr": 0o755}, - {"filename": "usr/bin/foo", "isexe": True, "data": "/usr/local/foo/foo.real"}, - ] - - self.assertZipFileContent("test_zip_basic.zip", expect) - - def test_timestamp(self): - self.assertZipFileContent("test_zip_timestamp.zip", [ - {"filename": "hello.txt", "crc": HELLO_CRC, "timestamp": 1234567890}, - ]) - - def test_permissions(self): - self.assertZipFileContent("test_zip_permissions.zip", [ - { - "filename": "executable.sh", - "crc": EXECUTABLE_CRC, - "timestamp": 1234567890, - "attr": 0o644, - } - ]) - - def test_package_dir(self): - self.assertZipFileContent("test_zip_package_dir0.zip", [ - {"filename": "abc/", "isdir": True, "attr": 0o755}, - {"filename": "abc/def/", "isdir": True, "attr": 0o755}, - {"filename": "abc/def/hello.txt", "crc": HELLO_CRC}, - {"filename": "abc/def/loremipsum.txt", "crc": LOREM_CRC}, - {"filename": "abc/def/mylink", "attr": 0o777}, - ]) - - def test_package_dir_substitution(self): - self.assertZipFileContent("test_zip_package_dir_substitution.zip", [ - {"filename": "level1/", "isdir": True, "attr": 0o755}, - {"filename": "level1/some_value/", "isdir": True, "attr": 0o755}, - {"filename": "level1/some_value/level3/", "isdir": True, "attr": 0o755}, - {"filename": "level1/some_value/level3/hello.txt", "crc": HELLO_CRC}, - {"filename": "level1/some_value/level3/loremipsum.txt", "crc": LOREM_CRC}, - ]) - - def test_zip_strip_prefix_empty(self): - self.assertZipFileContent("test-zip-strip_prefix-empty.zip", [ - {"filename": "loremipsum.txt", "crc": LOREM_CRC}, - ]) - - def test_zip_strip_prefix_none(self): - self.assertZipFileContent("test-zip-strip_prefix-none.zip", [ - {"filename": "loremipsum.txt", "crc": LOREM_CRC}, - ]) - - def test_zip_strip_prefix_zipcontent(self): - self.assertZipFileContent("test-zip-strip_prefix-zipcontent.zip", [ - {"filename": "loremipsum.txt", "crc": LOREM_CRC}, - ]) - - def test_zip_strip_prefix_dot(self): - self.assertZipFileContent("test-zip-strip_prefix-dot.zip", [ - {"filename": "zipcontent/", "isdir": True, "attr": 0o755}, - {"filename": "zipcontent/loremipsum.txt", "crc": LOREM_CRC}, - ]) - - def test_zip_tree(self): - self.assertZipFileContent("test_zip_tree.zip", [ - {"filename": "generate_tree/", "isdir": True, "attr": 0o755}, - {"filename": "generate_tree/a/", "isdir": True, "attr": 0o755}, - {"filename": "generate_tree/a/a"}, - {"filename": "generate_tree/a/b/", "isdir": True, "attr": 0o755}, - {"filename": "generate_tree/a/b/c"}, - {"filename": "generate_tree/b/", "isdir": True, "attr": 0o755}, - {"filename": "generate_tree/b/c/", "isdir": True, "attr": 0o755}, - {"filename": "generate_tree/b/c/d"}, - {"filename": "generate_tree/b/d"}, - {"filename": "generate_tree/b/e"}, - ]) - - def test_compression_deflated(self): - if sys.version_info >= (3, 7): - self.assertZipFileContent("test_zip_deflated_level_3.zip", [ - {"filename": "loremipsum.txt", "crc": LOREM_CRC, "size": 312}, - ]) - else: - # Python 3.6 doesn't support setting compresslevel, so the file size differs - self.assertZipFileContent("test_zip_deflated_level_3.zip", [ - {"filename": "loremipsum.txt", "crc": LOREM_CRC, "size": 309}, - ]) - - def test_compression_bzip2(self): - self.assertZipFileContent("test_zip_bzip2.zip", [ - {"filename": "loremipsum.txt", "crc": LOREM_CRC, "size": 340}, - ]) - - def test_compression_lzma(self): - self.assertZipFileContent("test_zip_lzma.zip", [ - {"filename": "loremipsum.txt", "crc": LOREM_CRC, "size": 378}, - ]) - - def test_compression_stored(self): - self.assertZipFileContent("test_zip_stored.zip", [ - {"filename": "loremipsum.txt", "crc": LOREM_CRC, "size": 543}, - ]) - - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/zip/zip_test_lib.py b/tests/zip/zip_test_lib.py deleted file mode 100644 index a9d237c..0000000 --- a/tests/zip/zip_test_lib.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright 2019 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. - -import datetime -import filecmp -import unittest -import zipfile - -from bazel_tools.tools.python.runfiles import runfiles - - -# Unix dir bit and Windows dir bit. Magic from zip spec -UNIX_DIR_BIT = 0o40000 -MSDOS_DIR_BIT = 0x10 -UNIX_RWX_BITS = 0o777 -UNIX_RX_BITS = 0o555 - -# The ZIP epoch date: (1980, 1, 1, 0, 0, 0) -_ZIP_EPOCH_DT = datetime.datetime(1980, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc) -_ZIP_EPOCH_S = int(_ZIP_EPOCH_DT.timestamp()) - -def seconds_to_ziptime(s): - dt = datetime.datetime.utcfromtimestamp(s) - return (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) - - -class ZipTest(unittest.TestCase): - - def setUp(self): - super(ZipTest, self).setUp() - self.data_files = runfiles.Create() - - def get_test_zip(self, zip_file): - """Get the file path to a generated zip in the runfiles.""" - - return self.data_files.Rlocation( - "rules_pkg/tests/zip/" + zip_file - ) - - -class ZipContentsTestBase(ZipTest): - """Use zipfile to check the contents of some generated zip files.""" - - def assertZipFileContent(self, zip_file, content): - """Assert that zip_file contains the entries described by content. - - Args: - zip_file: the test-package-relative path to a zip file to test. - content: an array of dictionaries containing a filename and crc key, - and optionally a timestamp key. - """ - with zipfile.ZipFile(self.get_test_zip(zip_file)) as f: - infos = f.infolist() - self.assertEqual(len(infos), len(content)) - - for info, expected in zip(infos, content): - self.assertEqual(info.filename, expected["filename"]) - if "crc" in expected: - self.assertEqual(info.CRC, expected["crc"]) - - ts = seconds_to_ziptime(expected.get("timestamp", _ZIP_EPOCH_S)) - self.assertEqual(info.date_time, ts) - if "isdir" in expected: - expect_dir_bits = UNIX_DIR_BIT << 16 | MSDOS_DIR_BIT - self.assertEqual(oct(info.external_attr & expect_dir_bits), - oct(expect_dir_bits)) - self.assertEqual(oct((info.external_attr >> 16) & UNIX_RWX_BITS), - oct(expected.get("attr", 0o755))) - elif "isexe" in expected: - got_mode = (info.external_attr >> 16) & UNIX_RX_BITS - self.assertEqual(oct(got_mode), oct(UNIX_RX_BITS)) - elif "size" in expected: - self.assertEqual(info.compress_size, expected["size"]) - - else: - if "attr" in expected: - attr = expected.get("attr") - if "attr_mask" in expected: - attr &= expected.get("attr_mask") - else: - # I would argue this is a dumb choice, but it matches the - # legacy rule implementation. - attr = 0o555 - self.assertEqual(oct((info.external_attr >> 16) & UNIX_RWX_BITS), - oct(attr), - msg = info.filename) |