Skip to content

Commit

Permalink
Merge branch 'master' into rmr
Browse files Browse the repository at this point in the history
  • Loading branch information
aiuto committed May 26, 2020
2 parents 5c859db + 19930f0 commit a02e872
Show file tree
Hide file tree
Showing 5 changed files with 289 additions and 2 deletions.
8 changes: 8 additions & 0 deletions .bazelci/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ common: &common
working_directory: /workdir/pkg
test_targets:
- "..."
# Cannot run until #183 is resolved; none of the CI images have rpmbuild(8)
- "-//experimental/tests:pkg_rpm_basic_test"

tasks:
centos7:
platform: centos7
<<: *common
ubuntu1604:
platform: ubuntu1604
<<: *common
Expand All @@ -14,5 +19,8 @@ tasks:
working_directory: ../pkg
test_targets:
- "..."
# This uses dpkg-deb(1), which is not available by default in macOS
- "-//tests:build_test_deb"
# rpmbuild(8) is not available by default on macOS
- "-//tests:make_rpm_test"
- "-//experimental/tests:pkg_rpm_basic_test"
103 changes: 103 additions & 0 deletions pkg/experimental/tests/BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,108 @@
# 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.

load(":pkg_filegroup_test.bzl", "pkg_filegroup_analysis_tests", "pkg_filegroup_unit_tests")
load("@rules_pkg//experimental:pkg_filegroup.bzl", "pkg_filegroup", "pkg_mkdirs")
load("@rules_pkg//experimental:rpm.bzl", "pkg_rpm")
load("@rules_python//python:defs.bzl", "py_test")

pkg_filegroup_analysis_tests()

pkg_filegroup_unit_tests()

filegroup(
name = "ars",
srcs = glob(["testdata/*.ar"]),
)

pkg_filegroup(
name = "ars_pfg",
prefix = "/test",
srcs = [
":ars",
],
attrs = {"unix": ["0755", "root", "root"]},
)

pkg_mkdirs(
name = "var_log_foo",
dirs = ["/var/log/foo"],
attrs = {"unix": ["0755", "root", "root"]},
)

pkg_rpm(
name = "test_rpm",
data = [":ars_pfg", "var_log_foo"],
version = "1.1.1",
release = "2222",
license = "Apache 2.0",
architecture = "noarch",
summary = "pkg_rpm test rpm summary",
description = """pkg_rpm test rpm description""",
pre_scriptlet = """echo pre""",
post_scriptlet = """echo post""",
preun_scriptlet = """echo preun""",
postun_scriptlet = """echo postun""",
testonly = True,
spec_template = "template-test.spec.in",
)

# Emit a CSV file providing a manifest providing the expected RPM contents
genrule(
name = "test_rpm_manifest",
srcs = [":ars"],
outs = ["manifest.txt"],
# 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
md5sum $$f | cut -d' ' -f1 | tr '\\n' ,
# User,Group,Mode,Fflags (fflags not provided)
echo -n 'root,root,100755,'
# 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 -n ,root,root,40755,,
) >> $@
""",
)

# 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",
data = [":test_rpm", ":test_rpm_manifest"],
testonly = True,
)

py_test(
name = "pkg_rpm_basic_test",
srcs = ["pkg_rpm_basic_test.py"],
deps = ["@rules_python//python/runfiles"],
data = [":pkg_rpm_basic_test_data"],
tags = [
"no_windows", # Windows doesn't have rpmbuild(8)
],
)
132 changes: 132 additions & 0 deletions pkg/experimental/tests/pkg_rpm_basic_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#!/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
from rules_python.python.runfiles import runfiles

# 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/experimental/tests/test_rpm.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):
self.manifest_file = self.runfiles.Rlocation(
"rules_pkg/experimental/tests/manifest.txt")
manifest_specs = {}
with open(self.manifest_file, "r", newline='', encoding="utf-8") as fh:
manifest_reader = csv.DictReader(fh)
manifest_specs = {r['path']: r for r in manifest_reader}

# 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

rpm_queryformat = (
"[%{FILENAMES}"
",%{FILEDIGESTS}"
",%{FILEUSERNAME}"
",%{FILEGROUPNAME}"
",%{FILEMODES:octal}"
",%{FILEFLAGS:fflags}"
",%{FILELINKTOS}"
"\n]"
)

rpm_queryformat_fieldnames = [
"path",
"digest",
"user",
"group",
"mode",
"fflags",
"symlink",
]

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, fieldnames=rpm_queryformat_fieldnames)
for rpm_file_info in rpm_output_reader:
my_path = rpm_file_info['path']
self.assertIn(my_path, manifest_specs)
self.assertDictEqual(manifest_specs[my_path], rpm_file_info)


if __name__ == "__main__":
unittest.main()
46 changes: 46 additions & 0 deletions pkg/experimental/tests/template-test.spec.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# -*- 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/experimental/template.spec.in!

################################################################################


# 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}
2 changes: 0 additions & 2 deletions pkg/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ py_test(
python_version = "PY3",
srcs_version = "PY2AND3",
tags = [
# archive.py requires xzcat, which is not available by default on Mac
"noci",
# TODO(laszlocsomor): fix on Windows or describe why it cannot pass.
"no_windows",
],
Expand Down

0 comments on commit a02e872

Please sign in to comment.