aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2019-10-19 17:55:09 -0700
committerZac Medico <zmedico@gentoo.org>2019-10-20 01:33:09 -0700
commit52bc75a60b84d709712e91c68782f2f207bfce4e (patch)
treed604680e1a4867442853f43ae08d3c95b9c07a3c /lib/portage/tests
parentfetch: add docstring (diff)
downloadportage-52bc75a60b84d709712e91c68782f2f207bfce4e.tar.gz
portage-52bc75a60b84d709712e91c68782f2f207bfce4e.tar.bz2
portage-52bc75a60b84d709712e91c68782f2f207bfce4e.zip
fetch: add force parameter (bug 697566)
Add a force parameter which forces download even when a file already exists in DISTDIR (and no digests are available to verify it). This avoids the need to remove the existing file in advance, which makes it possible to atomically replace the file and avoid interference with concurrent processes. This is useful when using FETCHCOMMAND to fetch a mirror's layout.conf file, for the purposes of bug 697566. Bug: https://bugs.gentoo.org/697566 Reviewed-by: Michał Górny <mgorny@gentoo.org> Signed-off-by: Zac Medico <zmedico@gentoo.org>
Diffstat (limited to 'lib/portage/tests')
-rw-r--r--lib/portage/tests/ebuild/test_fetch.py40
1 files changed, 37 insertions, 3 deletions
diff --git a/lib/portage/tests/ebuild/test_fetch.py b/lib/portage/tests/ebuild/test_fetch.py
index f50fea0dd..538fb1754 100644
--- a/lib/portage/tests/ebuild/test_fetch.py
+++ b/lib/portage/tests/ebuild/test_fetch.py
@@ -119,10 +119,44 @@ class EbuildFetchTestCase(TestCase):
with open(foo_path, 'rb') as f:
self.assertNotEqual(f.read(), distfiles['foo'])
- # Remove the stale file in order to forcefully update it.
- os.unlink(foo_path)
+ # Use force=True to update the stale file.
+ self.assertTrue(bool(run_async(fetch, foo_uri, settings, try_mirrors=False, force=True)))
- self.assertTrue(bool(run_async(fetch, foo_uri, settings, try_mirrors=False)))
+ with open(foo_path, 'rb') as f:
+ self.assertEqual(f.read(), distfiles['foo'])
+
+ # Test force=True with FEATURES=skiprocheck, using read-only DISTDIR.
+ # FETCHCOMMAND is set to temporarily chmod +w DISTDIR. Note that
+ # FETCHCOMMAND must perform atomic rename itself due to read-only
+ # DISTDIR.
+ with open(foo_path, 'wb') as f:
+ f.write(b'stale content\n')
+ orig_fetchcommand = settings['FETCHCOMMAND']
+ orig_distdir_mode = os.stat(settings['DISTDIR']).st_mode
+ temp_fetchcommand = os.path.join(eubin, 'fetchcommand')
+ with open(temp_fetchcommand, 'w') as f:
+ f.write("""
+ set -e
+ URI=$1
+ DISTDIR=$2
+ FILE=$3
+ trap 'chmod a-w "${DISTDIR}"' EXIT
+ chmod ug+w "${DISTDIR}"
+ %s
+ mv -f "${DISTDIR}/${FILE}.__download__" "${DISTDIR}/${FILE}"
+ """ % orig_fetchcommand.replace('${FILE}', '${FILE}.__download__'))
+ settings['FETCHCOMMAND'] = '"%s" "%s" "${URI}" "${DISTDIR}" "${FILE}"' % (BASH_BINARY, temp_fetchcommand)
+ settings.features.add('skiprocheck')
+ settings.features.remove('distlocks')
+ os.chmod(settings['DISTDIR'], 0o555)
+ try:
+ self.assertTrue(bool(run_async(fetch, foo_uri, settings, try_mirrors=False, force=True)))
+ finally:
+ settings['FETCHCOMMAND'] = orig_fetchcommand
+ os.chmod(settings['DISTDIR'], orig_distdir_mode)
+ settings.features.remove('skiprocheck')
+ settings.features.add('distlocks')
+ os.unlink(temp_fetchcommand)
with open(foo_path, 'rb') as f:
self.assertEqual(f.read(), distfiles['foo'])