Tristan Van Berkom pushed to branch tristan/fix-cache-size-race at BuildStream / buildstream
Commits:
-
3bf895d2
by Jonathan Maw at 2018-10-03T11:48:48Z
-
e4969807
by Jonathan Maw at 2018-10-03T12:48:07Z
-
5f408fc3
by Tristan Van Berkom at 2018-10-03T13:06:16Z
-
f66604ec
by Tristan Van Berkom at 2018-10-03T13:06:16Z
-
5c6183a8
by Tristan Van Berkom at 2018-10-03T13:06:16Z
3 changed files:
Changes:
| ... | ... | @@ -506,7 +506,7 @@ class CASCache(ArtifactCache): |
| 506 | 506 |
def set_ref(self, ref, tree):
|
| 507 | 507 |
refpath = self._refpath(ref)
|
| 508 | 508 |
os.makedirs(os.path.dirname(refpath), exist_ok=True)
|
| 509 |
- with utils.save_file_atomic(refpath, 'wb') as f:
|
|
| 509 |
+ with utils.save_file_atomic(refpath, 'wb', tempdir=self.tmpdir) as f:
|
|
| 510 | 510 |
f.write(tree.SerializeToString())
|
| 511 | 511 |
|
| 512 | 512 |
# resolve_ref():
|
| ... | ... | @@ -502,7 +502,7 @@ def get_bst_version(): |
| 502 | 502 |
|
| 503 | 503 |
@contextmanager
|
| 504 | 504 |
def save_file_atomic(filename, mode='w', *, buffering=-1, encoding=None,
|
| 505 |
- errors=None, newline=None, closefd=True, opener=None):
|
|
| 505 |
+ errors=None, newline=None, closefd=True, opener=None, tempdir=None):
|
|
| 506 | 506 |
"""Save a file with a temporary name and rename it into place when ready.
|
| 507 | 507 |
|
| 508 | 508 |
This is a context manager which is meant for saving data to files.
|
| ... | ... | @@ -529,8 +529,9 @@ def save_file_atomic(filename, mode='w', *, buffering=-1, encoding=None, |
| 529 | 529 |
# https://bugs.python.org/issue8604
|
| 530 | 530 |
|
| 531 | 531 |
assert os.path.isabs(filename), "The utils.save_file_atomic() parameter ``filename`` must be an absolute path"
|
| 532 |
- dirname = os.path.dirname(filename)
|
|
| 533 |
- fd, tempname = tempfile.mkstemp(dir=dirname)
|
|
| 532 |
+ if tempdir is None:
|
|
| 533 |
+ tempdir = os.path.dirname(filename)
|
|
| 534 |
+ fd, tempname = tempfile.mkstemp(dir=tempdir)
|
|
| 534 | 535 |
os.close(fd)
|
| 535 | 536 |
|
| 536 | 537 |
f = open(tempname, mode=mode, buffering=buffering, encoding=encoding,
|
| ... | ... | @@ -562,6 +563,9 @@ def save_file_atomic(filename, mode='w', *, buffering=-1, encoding=None, |
| 562 | 563 |
#
|
| 563 | 564 |
# Get the disk usage of a given directory in bytes.
|
| 564 | 565 |
#
|
| 566 |
+# This function assumes that files do not inadvertantly
|
|
| 567 |
+# disappear while this function is running.
|
|
| 568 |
+#
|
|
| 565 | 569 |
# Arguments:
|
| 566 | 570 |
# (str) The path whose size to check.
|
| 567 | 571 |
#
|
| ... | ... | @@ -139,6 +139,82 @@ def test_mirror_fetch(cli, tmpdir, datafiles, kind): |
| 139 | 139 |
result.assert_success()
|
| 140 | 140 |
|
| 141 | 141 |
|
| 142 |
+@pytest.mark.datafiles(DATA_DIR)
|
|
| 143 |
+@pytest.mark.parametrize("ref_storage", [("inline"), ("project.refs")])
|
|
| 144 |
+@pytest.mark.parametrize("mirror", [("no-mirror"), ("mirror"), ("unrelated-mirror")])
|
|
| 145 |
+def test_mirror_fetch_ref_storage(cli, tmpdir, datafiles, ref_storage, mirror):
|
|
| 146 |
+ bin_files_path = os.path.join(str(datafiles), 'files', 'bin-files', 'usr')
|
|
| 147 |
+ dev_files_path = os.path.join(str(datafiles), 'files', 'dev-files', 'usr')
|
|
| 148 |
+ upstream_repodir = os.path.join(str(tmpdir), 'upstream')
|
|
| 149 |
+ mirror_repodir = os.path.join(str(tmpdir), 'mirror')
|
|
| 150 |
+ project_dir = os.path.join(str(tmpdir), 'project')
|
|
| 151 |
+ os.makedirs(project_dir)
|
|
| 152 |
+ element_dir = os.path.join(project_dir, 'elements')
|
|
| 153 |
+ |
|
| 154 |
+ # Create repo objects of the upstream and mirror
|
|
| 155 |
+ upstream_repo = create_repo('tar', upstream_repodir)
|
|
| 156 |
+ upstream_ref = upstream_repo.create(bin_files_path)
|
|
| 157 |
+ mirror_repo = upstream_repo.copy(mirror_repodir)
|
|
| 158 |
+ mirror_ref = upstream_ref
|
|
| 159 |
+ upstream_ref = upstream_repo.create(dev_files_path)
|
|
| 160 |
+ |
|
| 161 |
+ element = {
|
|
| 162 |
+ 'kind': 'import',
|
|
| 163 |
+ 'sources': [
|
|
| 164 |
+ upstream_repo.source_config(ref=upstream_ref if ref_storage == 'inline' else None)
|
|
| 165 |
+ ]
|
|
| 166 |
+ }
|
|
| 167 |
+ element_name = 'test.bst'
|
|
| 168 |
+ element_path = os.path.join(element_dir, element_name)
|
|
| 169 |
+ full_repo = element['sources'][0]['url']
|
|
| 170 |
+ upstream_map, repo_name = os.path.split(full_repo)
|
|
| 171 |
+ alias = 'foo'
|
|
| 172 |
+ aliased_repo = alias + ':' + repo_name
|
|
| 173 |
+ element['sources'][0]['url'] = aliased_repo
|
|
| 174 |
+ full_mirror = mirror_repo.source_config()['url']
|
|
| 175 |
+ mirror_map, _ = os.path.split(full_mirror)
|
|
| 176 |
+ os.makedirs(element_dir)
|
|
| 177 |
+ _yaml.dump(element, element_path)
|
|
| 178 |
+ |
|
| 179 |
+ if ref_storage == 'project.refs':
|
|
| 180 |
+ # Manually set project.refs to avoid caching the repo prematurely
|
|
| 181 |
+ project_refs = {'projects': {
|
|
| 182 |
+ 'test': {
|
|
| 183 |
+ element_name: [
|
|
| 184 |
+ {'ref': upstream_ref}
|
|
| 185 |
+ ]
|
|
| 186 |
+ }
|
|
| 187 |
+ }}
|
|
| 188 |
+ project_refs_path = os.path.join(project_dir, 'project.refs')
|
|
| 189 |
+ _yaml.dump(project_refs, project_refs_path)
|
|
| 190 |
+ |
|
| 191 |
+ project = {
|
|
| 192 |
+ 'name': 'test',
|
|
| 193 |
+ 'element-path': 'elements',
|
|
| 194 |
+ 'aliases': {
|
|
| 195 |
+ alias: upstream_map + "/"
|
|
| 196 |
+ },
|
|
| 197 |
+ 'ref-storage': ref_storage
|
|
| 198 |
+ }
|
|
| 199 |
+ if mirror != 'no-mirror':
|
|
| 200 |
+ mirror_data = [{
|
|
| 201 |
+ 'name': 'middle-earth',
|
|
| 202 |
+ 'aliases': {alias: [mirror_map + '/']}
|
|
| 203 |
+ }]
|
|
| 204 |
+ if mirror == 'unrelated-mirror':
|
|
| 205 |
+ mirror_data.insert(0, {
|
|
| 206 |
+ 'name': 'narnia',
|
|
| 207 |
+ 'aliases': {'frob': ['http://www.example.com/repo']}
|
|
| 208 |
+ })
|
|
| 209 |
+ project['mirrors'] = mirror_data
|
|
| 210 |
+ |
|
| 211 |
+ project_file = os.path.join(project_dir, 'project.conf')
|
|
| 212 |
+ _yaml.dump(project, project_file)
|
|
| 213 |
+ |
|
| 214 |
+ result = cli.run(project=project_dir, args=['fetch', element_name])
|
|
| 215 |
+ result.assert_success()
|
|
| 216 |
+ |
|
| 217 |
+ |
|
| 142 | 218 |
@pytest.mark.datafiles(DATA_DIR)
|
| 143 | 219 |
@pytest.mark.parametrize("kind", [(kind) for kind in ALL_REPO_KINDS])
|
| 144 | 220 |
def test_mirror_fetch_upstream_absent(cli, tmpdir, datafiles, kind):
|
