Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions easybuild/base/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ def get_stderr(self):
"""Return output captured from stderr until now."""
return sys.stderr.getvalue()

@contextmanager
def mocked_stdout(self):
"""Context manager to mock stdout"""
self.mock_stdout(True)
try:
yield sys.stdout
finally:
self.mock_stdout(False)

@contextmanager
def mocked_stdout_stderr(self, mock_stdout=True, mock_stderr=True):
"""Context manager to mock stdout and stderr"""
Expand Down
23 changes: 11 additions & 12 deletions easybuild/tools/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
from easybuild.framework.easyconfig.easyconfig import EASYCONFIGS_ARCHIVE_DIR
from easybuild.framework.easyconfig.easyconfig import copy_easyconfigs, copy_patch_files, det_file_info
from easybuild.framework.easyconfig.easyconfig import process_easyconfig
from easybuild.framework.easyconfig.parser import EasyConfigParser
from easybuild.framework.easyconfig.parser import ALTERNATIVE_EASYCONFIG_PARAMETERS, EasyConfigParser
from easybuild.tools import LooseVersion
from easybuild.tools.build_log import EasyBuildError, EasyBuildExit, print_msg, print_warning
from easybuild.tools.config import build_option
Expand Down Expand Up @@ -753,13 +753,6 @@ def commit_request_fn(gh):
# download tarball for specific commit
repo_commit = download_repo(repo=github_repo, commit=commit, account=github_account)

if github_repo == GITHUB_EASYCONFIGS_REPO:
files_subdir = 'easybuild/easyconfigs/'
elif github_repo == GITHUB_EASYBLOCKS_REPO:
files_subdir = 'easybuild/easyblocks/'
else:
raise EasyBuildError("Unknown repo: %s", github_repo, exit_code=EasyBuildExit.OPTION_ERROR)

# symlink subdirectories of 'easybuild/easy{blocks,configs}' into path that gets added to robot search path
mkdir(path, parents=True)
dirpath = os.path.join(repo_commit, easybuild_subdir)
Expand All @@ -768,6 +761,7 @@ def commit_request_fn(gh):

# copy specified files to directory where they're expected to be found
file_paths = []
subdir_prefix = easybuild_subdir + os.path.sep
for file in files:

# if only filename is specified, we need to determine the file path
Expand All @@ -782,8 +776,8 @@ def commit_request_fn(gh):

# strip of leading subdirectory like easybuild/easyconfigs/ or easybuild/easyblocks/
# because that's what expected by robot_find_easyconfig
if file.startswith(files_subdir):
file = file[len(files_subdir):]
if file.startswith(subdir_prefix):
file = file[len(subdir_prefix):]

# if file is found, copy it to dedicated directory;
# if not, just skip it (may be an easyconfig file in local directory);
Expand Down Expand Up @@ -1340,7 +1334,7 @@ def get_name(patch):
exit_code=EasyBuildExit.VALUE_ERROR)
return patch

patches = [get_name(p) for p in ec['patches']]
patches = [get_name(p) for p in itertools.chain(ec['patches'], ec['postinstallpatches'])]

with ec.disable_templating():
# take into account both list of extensions (via exts_list) and components (cfr. Bundle easyblock)
Expand All @@ -1352,7 +1346,12 @@ def get_name(patch):
'version': entry[1],
}
options = entry[2]
patches.extend(get_name(p) % templates for p in options.get('patches', []))
patches.extend(get_name(p) % templates for p in
itertools.chain(
options.get('patches', []),
options.get(ALTERNATIVE_EASYCONFIG_PARAMETERS['post_install_patches'],
options.get('post_install_patches', []))
))

return patch_name in patches

Expand Down
37 changes: 20 additions & 17 deletions test/framework/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ def tearDown(self):

def test_det_pr_title(self):
"""Test det_pr_title function"""
# check if patches for extensions are found
rawtxt = textwrap.dedent("""
easyblock = 'ConfigureMake'
name = '%s'
Expand Down Expand Up @@ -995,9 +994,8 @@ def test_github_det_patch_specs(self):
file_info['ecs'].append(EasyConfig(None, rawtxt=rawtxt))

error_pattern = "Failed to determine software name to which patch file .*/2.patch relates"
self.mock_stdout(True)
self.assertErrorRegex(EasyBuildError, error_pattern, gh.det_patch_specs, patch_paths, file_info, [])
self.mock_stdout(False)
with self.mocked_stdout():
self.assertErrorRegex(EasyBuildError, error_pattern, gh.det_patch_specs, patch_paths, file_info, [])

rawtxt = textwrap.dedent("""
easyblock = 'ConfigureMake'
Expand All @@ -1007,12 +1005,11 @@ def test_github_det_patch_specs(self):
description = ''
toolchain = {"name":"GCC", "version": "4.6.3"}

patches = [('3.patch', 'subdir'), '2.patch']
postinstallpatches = [('3.patch', 'subdir'), '2.patch']
""")
file_info['ecs'].append(EasyConfig(None, rawtxt=rawtxt))
self.mock_stdout(True)
res = gh.det_patch_specs(patch_paths, file_info, [])
self.mock_stdout(False)
with self.mocked_stdout():
res = gh.det_patch_specs(patch_paths, file_info, [])

self.assertEqual([i[0] for i in res], patch_paths)
self.assertEqual([i[1] for i in res], ['A', 'C', 'C'])
Expand All @@ -1031,20 +1028,24 @@ def test_github_det_patch_specs(self):
('bar', '1.2.3'),
('patched', '4.5.6', {
'patches': [('%(name)s-2.patch', 1), '%(name)s-3.patch'],
'postinstallpatches': ['%(name)s-4.patch'],
}),
]
postinstallpatches = ['%(name)s-5.patch'],
""")
patch_paths[1:3] = [os.path.join(self.test_prefix, p) for p in ['patched-2.patch', 'patched-3.patch']]
patch_paths[1:] = [os.path.join(self.test_prefix, p) for p in
['patched-2.patch', 'patched-3.patch', 'patched-4.patch', 'patched_ext-5.patch']]
file_info['ecs'][-1] = EasyConfig(None, rawtxt=rawtxt)

self.mock_stdout(True)
res = gh.det_patch_specs(patch_paths, file_info, [])
self.mock_stdout(False)
with self.mocked_stdout():
res = gh.det_patch_specs(patch_paths, file_info, [])

self.assertEqual([i[0] for i in res], patch_paths)
self.assertEqual([i[1] for i in res], ['A', 'patched_ext', 'patched_ext'])
self.assertEqual([i[1] for i in res], ['A'] + ['patched_ext'] * 4)

# check if patches for components are found
# NOTE: Using alternative name and tuple format for post_install_patches, different to above test case
# to verify handling either way works without adding another sub-test
rawtxt = textwrap.dedent("""
easyblock = 'PythonBundle'
name = 'patched_bundle'
Expand All @@ -1057,17 +1058,19 @@ def test_github_det_patch_specs(self):
('bar', '1.2.3'),
('patched', '4.5.6', {
'patches': [('%(name)s-2.patch', 1), '%(name)s-3.patch'],
'post_install_patches': [('%(name)s-4.patch', 1)],
}),
]
post_install_patches = [('%(name)s-5.patch', 2)]
""")
patch_paths[-1] = 'patched_bundle-5.patch'
file_info['ecs'][-1] = EasyConfig(None, rawtxt=rawtxt)

self.mock_stdout(True)
res = gh.det_patch_specs(patch_paths, file_info, [])
self.mock_stdout(False)
with self.mocked_stdout():
res = gh.det_patch_specs(patch_paths, file_info, [])

self.assertEqual([i[0] for i in res], patch_paths)
self.assertEqual([i[1] for i in res], ['A', 'patched_bundle', 'patched_bundle'])
self.assertEqual([i[1] for i in res], ['A'] + ['patched_bundle'] * 4)

def test_github_restclient(self):
"""Test use of RestClient."""
Expand Down