mirror of
https://github.com/clearlinux/autospec.git
synced 2026-06-16 02:45:56 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 356da62750 | |||
| b5caddc404 | |||
| 2181c1fe68 | |||
| d6606ad5a8 | |||
| 4d708b6fe2 | |||
| 1bec16fc2e | |||
| 9f33e630cd | |||
| b858a2a990 | |||
| 43d564b0b7 | |||
| 2659038eaa |
@@ -163,7 +163,7 @@ def dump_symbols(path):
|
||||
try:
|
||||
lines = get_output(cmd)
|
||||
except Exception as e:
|
||||
print("Fatal error inspecting {}: {}".format(path, e))
|
||||
util.print_fatal("Fatal error inspecting {}: {}".format(path, e))
|
||||
sys.exit(1)
|
||||
for line in lines.split("\n"):
|
||||
line = line.strip()
|
||||
@@ -236,6 +236,7 @@ def examine_abi_host(download_path, results_dir, name):
|
||||
cwd=download_path)
|
||||
except Exception as e:
|
||||
util.print_fatal("Error invoking abireport: {}".format(e))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def examine_abi_fallback(download_path, results_dir, name):
|
||||
@@ -272,6 +273,7 @@ def examine_abi_fallback(download_path, results_dir, name):
|
||||
subprocess.check_call(cmd, shell=True)
|
||||
except Exception as e:
|
||||
util.print_fatal("Error extracting RPMS: {}".format(e))
|
||||
sys.exit(1)
|
||||
|
||||
os.chdir(download_path)
|
||||
collected_files = set()
|
||||
|
||||
@@ -38,7 +38,7 @@ import specfiles
|
||||
import tarball
|
||||
from abireport import examine_abi
|
||||
from logcheck import logcheck
|
||||
from util import binary_in_path, print_fatal, write_out
|
||||
from util import binary_in_path, print_build_failed, print_fatal, write_out
|
||||
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
|
||||
@@ -269,9 +269,13 @@ def package(args, url, name, archives, workingdir):
|
||||
pkg_integrity.check(url, conf, interactive=interactive_mode)
|
||||
pkg_integrity.load_specfile(specfile)
|
||||
|
||||
specfile.write_spec()
|
||||
spec_type = specfile.write_spec()
|
||||
|
||||
while 1:
|
||||
package.package(filemanager, args.mock_config, args.mock_opts, conf, requirements, content, args.cleanup)
|
||||
if spec_type == "template":
|
||||
# specfile template is assumed "correct" and any failures need to be manually addressed
|
||||
break
|
||||
filemanager.load_specfile(specfile)
|
||||
specfile.write_spec()
|
||||
filemanager.newfiles_printed = 0
|
||||
@@ -291,7 +295,7 @@ def package(args, url, name, archives, workingdir):
|
||||
|
||||
if package.success == 0:
|
||||
conf.create_buildreq_cache(content.version, requirements.buildreqs_cache)
|
||||
print_fatal("Build failed, aborting")
|
||||
print_build_failed()
|
||||
sys.exit(1)
|
||||
elif os.path.isfile("README.clear"):
|
||||
try:
|
||||
@@ -304,7 +308,8 @@ def package(args, url, name, archives, workingdir):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
check.check_regression(conf.download_path, conf.config_opts['skip_tests'], package.round - 1)
|
||||
if spec_type == "generate":
|
||||
check.check_regression(conf.download_path, conf.config_opts['skip_tests'], package.round - 1)
|
||||
|
||||
examine_abi(conf.download_path, content.name)
|
||||
if os.path.exists("/var/lib/rpm"):
|
||||
|
||||
+10
-9
@@ -22,6 +22,7 @@
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
import util
|
||||
|
||||
@@ -153,7 +154,7 @@ class Build(object):
|
||||
return True
|
||||
self.must_restart = 0
|
||||
self.file_restart = 0
|
||||
is_clean = True
|
||||
fatals = []
|
||||
util.call("sync")
|
||||
with util.open_auto(filename, "r") as rootlog:
|
||||
loglines = rootlog.readlines()
|
||||
@@ -161,9 +162,10 @@ class Build(object):
|
||||
for line in loglines:
|
||||
match = missing_pat.match(line)
|
||||
if match is not None:
|
||||
util.print_fatal("Cannot resolve dependency name: {}".format(match.group(1)))
|
||||
is_clean = False
|
||||
return is_clean
|
||||
fatals.append(f"Cannot resolve dependency name: {match.group(1)}")
|
||||
if fatals:
|
||||
util.print_fatal('\n'.join(fatals))
|
||||
sys.exit(1)
|
||||
|
||||
def parse_build_results(self, filename, returncode, filemanager, config, requirements, content):
|
||||
"""Handle build log contents."""
|
||||
@@ -283,7 +285,7 @@ class Build(object):
|
||||
mockopts,
|
||||
]
|
||||
|
||||
if not cleanup and self.must_restart == 0 and self.file_restart > 0 and set(filemanager.excludes) == set(filemanager.manual_excludes):
|
||||
if config.config_opts.get('avoid_rebuild') and not cleanup and self.must_restart == 0 and self.file_restart > 0 and set(filemanager.excludes) == set(filemanager.manual_excludes):
|
||||
cmd_args.append("--no-clean")
|
||||
cmd_args.append("--short-circuit=binary")
|
||||
|
||||
@@ -295,12 +297,11 @@ class Build(object):
|
||||
# sanity check the build log
|
||||
if not os.path.exists(config.download_path + "/results/build.log"):
|
||||
util.print_fatal("Mock command failed, results log does not exist. User may not have correct permissions.")
|
||||
exit(1)
|
||||
sys.exit(1)
|
||||
|
||||
if not self.parse_buildroot_log(config.download_path + "/results/root.log", ret):
|
||||
return
|
||||
self.parse_buildroot_log(config.download_path + "/results/root.log", ret)
|
||||
|
||||
self.parse_build_results(config.download_path + "/results/build.log", ret, filemanager, config, requirements, content)
|
||||
if filemanager.has_banned:
|
||||
util.print_fatal("Content in banned paths found, aborting build")
|
||||
exit(1)
|
||||
sys.exit(1)
|
||||
|
||||
@@ -147,7 +147,7 @@ def parse_modules_list(modules_string, is_cmake=False):
|
||||
modules = [m for m in re.split(r'\s*([><]?=|\${?[^}]*}?)\s*', modules_string)]
|
||||
modules = filter(None, modules)
|
||||
else:
|
||||
modules = [m.strip('[]') for m in modules_string.split()]
|
||||
modules = [m.strip('[]').strip('"') for m in modules_string.split()]
|
||||
res = []
|
||||
next_is_ver = False
|
||||
for mod in modules:
|
||||
|
||||
+3
-3
@@ -98,15 +98,15 @@ def scan_for_tests(src_dir, config, requirements, content):
|
||||
if config.config_opts.get('32bit'):
|
||||
testsuites["makecheck"] += "\ncd ../build32;\n" + make_check + " || :"
|
||||
testsuites["cmake"] += "\ncd ../../build32/clr-build32;\n" + cmake_check + " || :"
|
||||
testsuites["meson"] += "\ncd ../buildapx;\n" + meson_check + " || :"
|
||||
testsuites["meson"] += "\ncd ../build32;\n" + meson_check + " || :"
|
||||
if config.config_opts.get('use_avx2'):
|
||||
testsuites["makecheck"] += "\ncd ../buildavx2;\n" + make_check + " || :"
|
||||
testsuites["cmake"] += "\ncd ../../buildavx2/clr-build-avx2;\n" + cmake_check + " || :"
|
||||
testsuites["meson"] += "\ncd ../buildapx;\n" + meson_check + " || :"
|
||||
testsuites["meson"] += "\ncd ../buildavx2;\n" + meson_check + " || :"
|
||||
if config.config_opts.get('use_avx512'):
|
||||
testsuites["makecheck"] += "\ncd ../buildavx512;\n" + make_check + " || :"
|
||||
testsuites["cmake"] += "\ncd ../../buildavx512/clr-build-avx512;\n" + cmake_check + " || :"
|
||||
testsuites["meson"] += "\ncd ../buildapx;\n" + meson_check + " || :"
|
||||
testsuites["meson"] += "\ncd ../buildavx512;\n" + meson_check + " || :"
|
||||
if config.config_opts.get('use_apx'):
|
||||
testsuites["makecheck"] += "\ncd ../buildapx;\n" + make_check + " || :"
|
||||
testsuites["cmake"] += "\ncd ../../buildapx/clr-build-apx;\n" + cmake_check + " || :"
|
||||
|
||||
@@ -49,7 +49,7 @@ def scan_for_changes(download_path, directory, transforms):
|
||||
shutil.copy(source, target)
|
||||
os.chmod(target, 0o644)
|
||||
except Exception as e:
|
||||
print("Error copying file: {}".format(e))
|
||||
util.print_fatal("Error copying file: {}".format(e))
|
||||
sys.exit(1)
|
||||
found.append(item)
|
||||
|
||||
|
||||
+14
-3
@@ -28,7 +28,8 @@ from collections import OrderedDict
|
||||
|
||||
import check
|
||||
import license
|
||||
from util import call, open_auto, print_info, print_warning, write_out
|
||||
from util import (call, open_auto, print_fatal, print_info, print_warning,
|
||||
write_out)
|
||||
|
||||
|
||||
def read_pattern_conf(filename, dest, list_format=False, path=None):
|
||||
@@ -68,6 +69,7 @@ class Config(object):
|
||||
|
||||
def __init__(self, download_path):
|
||||
"""Initialize Default configuration settings."""
|
||||
self.cargo_vendors = ""
|
||||
self.content = None # hack to avoid circular init dependency
|
||||
self.extra_configure = ""
|
||||
self.extra_configure32 = ""
|
||||
@@ -155,6 +157,7 @@ class Config(object):
|
||||
}
|
||||
self.config_opts = {}
|
||||
self.config_options = {
|
||||
"avoid_rebuild": "Try to use mock short circuit to avoid full rebuilds",
|
||||
"broken_c++": "extend flags with '-std=gnu++98",
|
||||
"cargo_vendor": "create vendor archive with cargo",
|
||||
"use_lto": "configure build for lto",
|
||||
@@ -296,6 +299,7 @@ class Config(object):
|
||||
(r"Perhaps you should add the directory containing `([a-zA-Z0-9\-:]*)\.pc'", 0, 'pkgconfig'),
|
||||
(r"Program (.*) found: NO", 0, None),
|
||||
(r"Target '[a-zA-Z0-9\-]' can't be generated as '(.*)' could not be found", 0, None),
|
||||
(r"The missing Perl modules are:\s*(\S+)", 0, 'perl'),
|
||||
(r"Unable to `import (.*)`", 0, None),
|
||||
(r"Unable to find '(.*)'", 0, None),
|
||||
(r"Warning: prerequisite ([a-zA-Z:]+) [0-9\.]+ not found.", 0, 'perl'),
|
||||
@@ -448,6 +452,8 @@ class Config(object):
|
||||
|
||||
# default lto to true for new things
|
||||
config_f['autospec']['use_lto'] = 'true'
|
||||
# default autoupdate to true for new things
|
||||
config_f['autospec']['autoupdate'] = 'true'
|
||||
|
||||
# renamed options need special care
|
||||
skip_path = os.path.join(self.download_path, "skip_test_suite")
|
||||
@@ -484,7 +490,7 @@ class Config(object):
|
||||
config_f = configparser.ConfigParser(interpolation=None)
|
||||
config_f.read(opts_path)
|
||||
if "autospec" not in config_f.sections():
|
||||
print("Missing autospec section in options.conf")
|
||||
print_fatal("Missing autospec section in options.conf")
|
||||
sys.exit(1)
|
||||
|
||||
if 'package' in config_f.sections() and config_f['package'].get('alias'):
|
||||
@@ -706,7 +712,7 @@ class Config(object):
|
||||
config.read(self.config_file)
|
||||
|
||||
if "autospec" not in config.sections():
|
||||
print("Missing autospec section..")
|
||||
print_fatal("Missing autospec section..")
|
||||
sys.exit(1)
|
||||
|
||||
self.git_uri = config['autospec'].get('git', None)
|
||||
@@ -989,6 +995,11 @@ class Config(object):
|
||||
if not license.add_license(word, self.license_translations, self.license_blacklist):
|
||||
print_warning("{}: blacklisted license {} ignored.".format(self.content.name + ".license", word))
|
||||
|
||||
# cargo_vendors is the output of 'cargo vendor' and should be read as is
|
||||
content = self.read_file(os.path.join(self.download_path, "cargo_vendors"), track=True)
|
||||
if content:
|
||||
self.cargo_vendors = "".join(content)
|
||||
|
||||
if self.config_opts['use_clang']:
|
||||
self.config_opts['funroll-loops'] = False
|
||||
requirements.add_buildreq("llvm")
|
||||
|
||||
@@ -42,7 +42,7 @@ KEYID_TRY = ""
|
||||
KEYID = ""
|
||||
IMPORTED = ""
|
||||
EMAIL = ""
|
||||
GNUPGCONF = """keyserver keys.gnupg.net"""
|
||||
GNUPGCONF = """keyserver keyserver.ubuntu.com"""
|
||||
CMD_TIMEOUT = 20
|
||||
ENV = os.environ
|
||||
INPUT_GETTER_TIMEOUT = 60
|
||||
@@ -205,9 +205,9 @@ class Verifier(object):
|
||||
@staticmethod
|
||||
def quit():
|
||||
"""Stop verification."""
|
||||
print('Critical error quitting...')
|
||||
util.print_fatal("Verification required for build (verify_required option set)")
|
||||
print(SEPT)
|
||||
exit(1)
|
||||
sys.exit(1)
|
||||
|
||||
@staticmethod
|
||||
def calc_sum(filepath, digest_algo):
|
||||
@@ -264,12 +264,12 @@ def get_signature_file(package_url, package_path):
|
||||
def compare_keys(newkey, oldkey):
|
||||
"""Key comparison to check against key tampering."""
|
||||
if newkey != oldkey:
|
||||
util.print_error('Public key has changed:\n'
|
||||
util.print_fatal('Public key has changed:\n'
|
||||
' old key: {}\n'
|
||||
' new key: {}\n'
|
||||
'this is a critical security error, quitting...'
|
||||
.format(oldkey, newkey))
|
||||
exit(1)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# sha256sum Verifier
|
||||
@@ -521,7 +521,6 @@ class GPGVerifier(Verifier):
|
||||
|
||||
def quit_verify():
|
||||
"""Halt build due to verification being required."""
|
||||
util.print_error("Verification required for build (verify_required option set)")
|
||||
Verifier.quit()
|
||||
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ def main():
|
||||
pkg_name = sys.argv[1]
|
||||
pypi_name = get_pypi_name(pkg_name)
|
||||
if not pypi_name:
|
||||
print(f"Couldn't find {pkg_name} in pypi")
|
||||
util.print_fatal(f"Couldn't find {pkg_name} in pypi")
|
||||
sys.exit(1)
|
||||
pypi_metadata = get_pypi_metadata(pypi_name)
|
||||
print(pypi_metadata)
|
||||
|
||||
+39
-11
@@ -26,6 +26,8 @@ import types
|
||||
from collections import OrderedDict
|
||||
|
||||
import git
|
||||
from jinja2 import Environment
|
||||
from jinja2.loaders import DictLoader
|
||||
from util import _file_write, open_auto
|
||||
|
||||
AVX2_CFLAGS = "-march=x86-64-v3"
|
||||
@@ -73,12 +75,42 @@ class Specfile(object):
|
||||
|
||||
def write_spec(self):
|
||||
"""Write spec file."""
|
||||
self.specfile = open_auto("{}/{}.spec".format(self.config.download_path, self.name), "w")
|
||||
spec_path = f"{os.path.join(self.config.download_path, self.name)}.spec"
|
||||
self.specfile = open_auto(spec_path, "w")
|
||||
self.specfile.write_strip = types.MethodType(_file_write, self.specfile)
|
||||
|
||||
# last chance to sanitize url for template and build types
|
||||
if self.config.urlban:
|
||||
clean_url = re.sub(self.config.urlban, "localhost", self.url)
|
||||
# Duplicate prefixes entry before we change the url
|
||||
self.content.prefixes[clean_url] = self.content.prefixes.get(self.url)
|
||||
self.url = clean_url
|
||||
|
||||
template_path = f"{spec_path}.template"
|
||||
|
||||
if os.path.isfile(template_path):
|
||||
# make templates have a template build pattern
|
||||
self.config.default_pattern = "template"
|
||||
# spec file comment header
|
||||
self.write_comment_header()
|
||||
|
||||
if os.path.isfile(template_path):
|
||||
with open_auto(template_path) as tfile:
|
||||
template_content = tfile.read()
|
||||
template = Environment(loader=DictLoader({'spec': template_content})).get_template('spec')
|
||||
kw = {
|
||||
'package_name': self.name,
|
||||
'package_version': self.version,
|
||||
'package_url': self.url,
|
||||
'package_release': self.release,
|
||||
}
|
||||
self.specfile.write(template.render(**kw))
|
||||
self.specfile.write_strip('\n')
|
||||
self.specfile.close()
|
||||
# return specfile type built so autospec knows how to
|
||||
# handle build results (template should only builds once)
|
||||
return "template"
|
||||
|
||||
if self.config.config_opts.get('keepstatic'):
|
||||
self._write("%define keepstatic 1\n")
|
||||
|
||||
@@ -110,6 +142,10 @@ class Specfile(object):
|
||||
|
||||
self.specfile.close()
|
||||
|
||||
# return specfile type built so autospec knows how to
|
||||
# handle build results (generate has multiple builds)
|
||||
return "generate"
|
||||
|
||||
def write_comment_header(self):
|
||||
"""Write comment header to spec file."""
|
||||
self._write("#\n")
|
||||
@@ -132,11 +168,6 @@ class Specfile(object):
|
||||
|
||||
def write_nvr(self):
|
||||
"""Write name, version, and release information."""
|
||||
if self.config.urlban:
|
||||
clean_url = re.sub(self.config.urlban, "localhost", self.url)
|
||||
# Duplicate prefixes entry before we change the url
|
||||
self.content.prefixes[clean_url] = self.content.prefixes.get(self.url)
|
||||
self.url = clean_url
|
||||
self._write("Name : {}\n".format(self.name))
|
||||
self._write("Version : {}\n".format(self.version))
|
||||
self._write("Release : {}\n".format(str(self.release)))
|
||||
@@ -509,14 +540,11 @@ class Specfile(object):
|
||||
self.apply_patches()
|
||||
|
||||
# setup cargo.toml vendoring if needed
|
||||
if self.config.config_opts['cargo_vendor']:
|
||||
if self.config.cargo_vendors:
|
||||
if self.config.subdir:
|
||||
self._write_strip("pushd " + self.config.subdir)
|
||||
self._write_strip("mkdir -p .cargo")
|
||||
self._write_strip("echo '[source.crates-io]' >> .cargo/config.toml")
|
||||
self._write_strip("""echo 'replace-with = "vendored-sources"' >> .cargo/config.toml""")
|
||||
self._write_strip("echo '[source.vendored-sources]' >> .cargo/config.toml")
|
||||
self._write_strip("""echo 'directory = "vendor"' >> .cargo/config.toml""")
|
||||
self._write_strip(f"echo '{self.config.cargo_vendors}' >> .cargo/config.toml")
|
||||
if self.config.subdir:
|
||||
self._write_strip("popd")
|
||||
|
||||
|
||||
@@ -27,6 +27,87 @@ import sys
|
||||
dictionary_filename = os.path.dirname(__file__) + "/translate.dic"
|
||||
dictionary = [line.strip() for line in open(dictionary_filename, 'r')]
|
||||
os_paths = None
|
||||
ERROR_FILE = 'pumpAutospec'
|
||||
ERROR_ENV = 'AUTOSPEC_UPDATE'
|
||||
|
||||
|
||||
def _log_error(error):
|
||||
write_out(ERROR_FILE, f"{error}\n", mode='a')
|
||||
|
||||
|
||||
def _commit_result():
|
||||
if not os.path.isfile(ERROR_FILE):
|
||||
return
|
||||
call(f"git add {ERROR_FILE}", check=False, stderr=subprocess.DEVNULL)
|
||||
call(f"git commit {ERROR_FILE} -m 'Notes update'", check=False, stderr=subprocess.DEVNULL)
|
||||
call("git push", check=False, stderr=subprocess.DEVNULL)
|
||||
|
||||
|
||||
def _process_line(line, prev_line, current_patch, reported_patches, error):
|
||||
if m := re.match('^Patch #[0-9]+ .(?P<patch>.*).:', line):
|
||||
current_patch[0] = m.group('patch')
|
||||
|
||||
if m := re.match('Hunk #[0-9]+ FAILED at [0-9]+', line):
|
||||
if current_patch[0] not in reported_patches:
|
||||
_log_error("Patch " + current_patch[0] + " does not apply")
|
||||
reported_patches[current_patch[0]] = True
|
||||
return True
|
||||
|
||||
if m := re.match(".*can't find file to patch at input line ", line):
|
||||
if current_patch[0] not in reported_patches:
|
||||
_log_error("Patch " + current_patch[0] + " does not apply")
|
||||
reported_patches[current_patch[0]] = True
|
||||
return True
|
||||
|
||||
if m := re.match('.*meson.build:[0-9]+:[0-9]+: ERROR: Unknown options: "(?P<option>.*)"', line):
|
||||
_log_error("Unknown meson option: " + m.group('option'))
|
||||
return True
|
||||
|
||||
if m := re.match('Error: package ‘(?P<module>.*)’ .* was found, but', line):
|
||||
_log_error("R package " + m.group('module') + " not found")
|
||||
return True
|
||||
|
||||
if m := re.match('.*CMake Error at .*/CMake', prev_line):
|
||||
if m := re.match('(?P<module>.*) not found', line):
|
||||
_log_error("CMake module " + m.group('module') + "not found")
|
||||
return True
|
||||
|
||||
if m := re.match(r'go: download.*connect: connection refused', line):
|
||||
_log_error("Go online update")
|
||||
return True
|
||||
|
||||
if 'Updating crates.io index' in line:
|
||||
_log_error("Rust crates.io online update")
|
||||
return True
|
||||
|
||||
if "error: '__builtin_ctzs' needs isa option -mbmi" in line:
|
||||
_log_error(" error: '__builtin_ctzs' needs isa option -mbmi")
|
||||
return True
|
||||
|
||||
if "error:" in line and 'Bad exit status from' not in line:
|
||||
m = re.match('.*error:(?P<error>.*)', line)
|
||||
if m and not error:
|
||||
_log_error("Compiler: " + m.group('error'))
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def _process_build_log(filename):
|
||||
with open_auto(filename, "r") as lfile:
|
||||
lines = lfile.readlines()
|
||||
|
||||
prev_line = ''
|
||||
current_patch = ''
|
||||
reported_patches = {}
|
||||
error = False
|
||||
for line in lines:
|
||||
if _process_line(line, prev_line, current_patch, reported_patches, error):
|
||||
error = True
|
||||
prev_line = line
|
||||
|
||||
if error:
|
||||
_commit_result()
|
||||
|
||||
|
||||
def call(command, logfile=None, check=True, **kwargs):
|
||||
@@ -116,9 +197,22 @@ def print_error(message):
|
||||
_print_message(message, 'ERROR', 'red')
|
||||
|
||||
|
||||
def print_build_failed():
|
||||
"""Print final fatal error, color coded for TTYs."""
|
||||
_print_message('Build failed, aborting', 'FATAL', 'red')
|
||||
try:
|
||||
if os.environ.get(ERROR_ENV):
|
||||
_process_build_log('results/build.log')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def print_fatal(message):
|
||||
"""Print fatal error, color coded for TTYs."""
|
||||
_print_message(message, 'FATAL', 'red')
|
||||
if os.environ.get(ERROR_ENV):
|
||||
write_out(ERROR_FILE, f"{message}\n", mode='a')
|
||||
_commit_result()
|
||||
|
||||
|
||||
def print_warning(message):
|
||||
|
||||
+19
-9
@@ -190,25 +190,36 @@ class TestBuildpattern(unittest.TestCase):
|
||||
def mock_util_call(cmd):
|
||||
del cmd
|
||||
|
||||
def mock_wrap_fatal():
|
||||
output = ['']
|
||||
def mock_print_fatal(msg):
|
||||
output[0] = msg
|
||||
return output, mock_print_fatal
|
||||
|
||||
result, mock_print_fatal = mock_wrap_fatal()
|
||||
|
||||
exit_backup = build.sys.exit
|
||||
call_backup = build.util.call
|
||||
print_backup = build.util.print_fatal
|
||||
build.sys.exit = MagicMock()
|
||||
build.util.call = mock_util_call
|
||||
build.util.print_fatal = mock_print_fatal
|
||||
|
||||
open_name = 'build.util.open_auto'
|
||||
content = "line1\nDEBUG util.py:399: No matching package to install: 'foobar'\nDEBUG util.py:399: No matching package to install: 'foobarbaz'\nline 4"
|
||||
m_open = mock_open(read_data=content)
|
||||
pkg = build.Build()
|
||||
pkg.must_restart = 1
|
||||
pkg.file_restart = 1
|
||||
|
||||
result = True
|
||||
with patch(open_name, m_open, create=True):
|
||||
result = pkg.parse_buildroot_log('testname', 1)
|
||||
pkg.parse_buildroot_log('testname', 1)
|
||||
|
||||
build.util.print_fatal = print_backup
|
||||
build.util.call = call_backup
|
||||
mock_exit = build.sys.exit
|
||||
build.sys.exit = exit_backup
|
||||
|
||||
self.assertFalse(result)
|
||||
self.assertEqual(pkg.must_restart, 0)
|
||||
self.assertEqual(pkg.file_restart, 0)
|
||||
self.assertEqual(result[0], 'Cannot resolve dependency name: foobar\nCannot resolve dependency name: foobarbaz')
|
||||
mock_exit.assert_called_once()
|
||||
|
||||
def test_parse_buildroot_log_pass(self):
|
||||
"""
|
||||
@@ -227,11 +238,10 @@ class TestBuildpattern(unittest.TestCase):
|
||||
|
||||
result = True
|
||||
with patch(open_name, m_open, create=True):
|
||||
result = pkg.parse_buildroot_log('testname', 1)
|
||||
pkg.parse_buildroot_log('testname', 1)
|
||||
|
||||
build.util.call = call_backup
|
||||
|
||||
self.assertTrue(result)
|
||||
self.assertEqual(pkg.must_restart, 0)
|
||||
|
||||
def test_parse_buildroot_log_noop(self):
|
||||
|
||||
+1
-14
@@ -47,7 +47,7 @@ class TestSpecfileWrite(unittest.TestCase):
|
||||
self.WRITES = self.WRITES[:4] + self.WRITES[6:]
|
||||
self.assertEqual(expect, self.WRITES)
|
||||
|
||||
def test_write_nvr_no_urlban(self):
|
||||
def test_write_nvr(self):
|
||||
"""
|
||||
test Specfile.write_nvr with no urlban set
|
||||
"""
|
||||
@@ -59,19 +59,6 @@ class TestSpecfileWrite(unittest.TestCase):
|
||||
"Source0 : http://www.testpkg.com/testpkg/pkg-1.0.tar.gz\n"]
|
||||
self.assertEqual(expect, self.WRITES)
|
||||
|
||||
def test_write_nvr_urlban(self):
|
||||
"""
|
||||
test Specfile.write_nvr with urlban set
|
||||
"""
|
||||
self.specfile.config.urlban = "www.testpkg.com"
|
||||
self.specfile.write_nvr()
|
||||
expect = ["Name : pkg\n",
|
||||
"Version : 1.0\n",
|
||||
"Release : 2\n",
|
||||
"URL : http://localhost/testpkg/pkg-1.0.tar.gz\n",
|
||||
"Source0 : http://localhost/testpkg/pkg-1.0.tar.gz\n"]
|
||||
self.assertEqual(expect, self.WRITES)
|
||||
|
||||
def test_write_sources(self):
|
||||
"""
|
||||
test write_sources with all Specfile.sources set.
|
||||
|
||||
Reference in New Issue
Block a user