Valentin David pushed to branch bst-1.2 at BuildStream / buildstream
Commits:
- 
1ad0a778
by Valentin David at 2019-02-13T09:42:43Z
- 
e4b6b855
by Valentin David at 2019-02-13T11:41:24Z
2 changed files:
Changes:
| ... | ... | @@ -395,9 +395,7 @@ class CASCache(ArtifactCache): | 
| 395 | 395 |                      for chunk in iter(lambda: tmp.read(4096), b""):
 | 
| 396 | 396 |                          h.update(chunk)
 | 
| 397 | 397 |                  else:
 | 
| 398 | -                    tmp = stack.enter_context(tempfile.NamedTemporaryFile(dir=self.tmpdir))
 | |
| 399 | -                    # Set mode bits to 0644
 | |
| 400 | -                    os.chmod(tmp.name, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
 | |
| 398 | +                    tmp = stack.enter_context(self._temporary_object())
 | |
| 401 | 399 |  | 
| 402 | 400 |                      if path:
 | 
| 403 | 401 |                          with open(path, 'rb') as f:
 | 
| ... | ... | @@ -834,6 +832,19 @@ class CASCache(ArtifactCache): | 
| 834 | 832 |  | 
| 835 | 833 |          assert digest.size_bytes == os.fstat(stream.fileno()).st_size
 | 
| 836 | 834 |  | 
| 835 | +    # _temporary_object():
 | |
| 836 | +    #
 | |
| 837 | +    # Returns:
 | |
| 838 | +    #     (file): A file object to a named temporary file.
 | |
| 839 | +    #
 | |
| 840 | +    # Create a named temporary file with 0o0644 access rights.
 | |
| 841 | +    @contextlib.contextmanager
 | |
| 842 | +    def _temporary_object(self):
 | |
| 843 | +        with tempfile.NamedTemporaryFile(dir=self.tmpdir) as f:
 | |
| 844 | +            os.chmod(f.name,
 | |
| 845 | +                     stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
 | |
| 846 | +            yield f
 | |
| 847 | + | |
| 837 | 848 |      # _ensure_blob():
 | 
| 838 | 849 |      #
 | 
| 839 | 850 |      # Fetch and add blob if it's not already local.
 | 
| ... | ... | @@ -851,7 +862,7 @@ class CASCache(ArtifactCache): | 
| 851 | 862 |              # already in local repository
 | 
| 852 | 863 |              return objpath
 | 
| 853 | 864 |  | 
| 854 | -        with tempfile.NamedTemporaryFile(dir=self.tmpdir) as f:
 | |
| 865 | +        with self._temporary_object() as f:
 | |
| 855 | 866 |              self._fetch_blob(remote, digest, f)
 | 
| 856 | 867 |  | 
| 857 | 868 |              added_digest = self.add_object(path=f.name, link_directly=True)
 | 
| ... | ... | @@ -861,7 +872,7 @@ class CASCache(ArtifactCache): | 
| 861 | 872 |  | 
| 862 | 873 |      def _batch_download_complete(self, batch):
 | 
| 863 | 874 |          for digest, data in batch.send():
 | 
| 864 | -            with tempfile.NamedTemporaryFile(dir=self.tmpdir) as f:
 | |
| 875 | +            with self._temporary_object() as f:
 | |
| 865 | 876 |                  f.write(data)
 | 
| 866 | 877 |                  f.flush()
 | 
| 867 | 878 |  | 
| 1 | 1 |  import os
 | 
| 2 | 2 |  import shutil
 | 
| 3 | +import stat
 | |
| 3 | 4 |  import pytest
 | 
| 4 | 5 |  from tests.testutils import cli, create_artifact_share, generate_junction
 | 
| 5 | 6 |  | 
| ... | ... | @@ -358,3 +359,70 @@ def test_pull_missing_notifies_user(caplog, cli, tmpdir, datafiles): | 
| 358 | 359 |  | 
| 359 | 360 |          assert "INFO    Remote ({}) does not have".format(share.repo) in result.stderr
 | 
| 360 | 361 |          assert "SKIPPED Pull" in result.stderr
 | 
| 362 | + | |
| 363 | + | |
| 364 | +@pytest.mark.datafiles(DATA_DIR)
 | |
| 365 | +def test_pull_access_rights(caplog, cli, tmpdir, datafiles):
 | |
| 366 | +    project = str(datafiles)
 | |
| 367 | +    checkout = os.path.join(str(tmpdir), 'checkout')
 | |
| 368 | + | |
| 369 | +    # Work-around datafiles not preserving mode
 | |
| 370 | +    os.chmod(os.path.join(project, 'files/bin-files/usr/bin/hello'), 0o0755)
 | |
| 371 | + | |
| 372 | +    # We need a big file that does not go into a batch to test a different
 | |
| 373 | +    # code path
 | |
| 374 | +    os.makedirs(os.path.join(project, 'files/dev-files/usr/share'), exist_ok=True)
 | |
| 375 | +    with open(os.path.join(project, 'files/dev-files/usr/share/big-file'), 'w') as f:
 | |
| 376 | +        buf = ' ' * 4096
 | |
| 377 | +        for _ in range(1024):
 | |
| 378 | +            f.write(buf)
 | |
| 379 | + | |
| 380 | +    with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare')) as share:
 | |
| 381 | + | |
| 382 | +        cli.configure({
 | |
| 383 | +            'artifacts': {'url': share.repo, 'push': True}
 | |
| 384 | +        })
 | |
| 385 | +        result = cli.run(project=project, args=['build', 'compose-all.bst'])
 | |
| 386 | +        result.assert_success()
 | |
| 387 | + | |
| 388 | +        result = cli.run(project=project,
 | |
| 389 | +                         args=['checkout', '--hardlinks', '--no-integrate',
 | |
| 390 | +                               'compose-all.bst', checkout])
 | |
| 391 | +        result.assert_success()
 | |
| 392 | + | |
| 393 | +        st = os.lstat(os.path.join(checkout, 'usr/include/pony.h'))
 | |
| 394 | +        assert stat.S_ISREG(st.st_mode)
 | |
| 395 | +        assert stat.S_IMODE(st.st_mode) == 0o0644
 | |
| 396 | + | |
| 397 | +        st = os.lstat(os.path.join(checkout, 'usr/bin/hello'))
 | |
| 398 | +        assert stat.S_ISREG(st.st_mode)
 | |
| 399 | +        assert stat.S_IMODE(st.st_mode) == 0o0755
 | |
| 400 | + | |
| 401 | +        st = os.lstat(os.path.join(checkout, 'usr/share/big-file'))
 | |
| 402 | +        assert stat.S_ISREG(st.st_mode)
 | |
| 403 | +        assert stat.S_IMODE(st.st_mode) == 0o0644
 | |
| 404 | + | |
| 405 | +        shutil.rmtree(checkout)
 | |
| 406 | + | |
| 407 | +        artifacts = os.path.join(cli.directory, 'artifacts')
 | |
| 408 | +        shutil.rmtree(artifacts)
 | |
| 409 | + | |
| 410 | +        result = cli.run(project=project, args=['pull', 'compose-all.bst'])
 | |
| 411 | +        result.assert_success()
 | |
| 412 | + | |
| 413 | +        result = cli.run(project=project,
 | |
| 414 | +                         args=['checkout', '--hardlinks', '--no-integrate',
 | |
| 415 | +                               'compose-all.bst', checkout])
 | |
| 416 | +        result.assert_success()
 | |
| 417 | + | |
| 418 | +        st = os.lstat(os.path.join(checkout, 'usr/include/pony.h'))
 | |
| 419 | +        assert stat.S_ISREG(st.st_mode)
 | |
| 420 | +        assert stat.S_IMODE(st.st_mode) == 0o0644
 | |
| 421 | + | |
| 422 | +        st = os.lstat(os.path.join(checkout, 'usr/bin/hello'))
 | |
| 423 | +        assert stat.S_ISREG(st.st_mode)
 | |
| 424 | +        assert stat.S_IMODE(st.st_mode) == 0o0755
 | |
| 425 | + | |
| 426 | +        st = os.lstat(os.path.join(checkout, 'usr/share/big-file'))
 | |
| 427 | +        assert stat.S_ISREG(st.st_mode)
 | |
| 428 | +        assert stat.S_IMODE(st.st_mode) == 0o0644 | 
