| 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,66 @@ 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, args=['checkout', '--hardlinks', '--no-integrate', 'compose-all.bst', checkout])
 | 
|  | 389 | +        result.assert_success()
 | 
|  | 390 | +
 | 
|  | 391 | +        st = os.lstat(os.path.join(checkout, 'usr/include/pony.h'))
 | 
|  | 392 | +        assert stat.S_ISREG(st.st_mode)
 | 
|  | 393 | +        assert stat.S_IMODE(st.st_mode) == 0o0644
 | 
|  | 394 | +
 | 
|  | 395 | +        st = os.lstat(os.path.join(checkout, 'usr/bin/hello'))
 | 
|  | 396 | +        assert stat.S_ISREG(st.st_mode)
 | 
|  | 397 | +        assert stat.S_IMODE(st.st_mode) == 0o0755
 | 
|  | 398 | +
 | 
|  | 399 | +        st = os.lstat(os.path.join(checkout, 'usr/share/big-file'))
 | 
|  | 400 | +        assert stat.S_ISREG(st.st_mode)
 | 
|  | 401 | +        assert stat.S_IMODE(st.st_mode) == 0o0644
 | 
|  | 402 | +
 | 
|  | 403 | +        shutil.rmtree(checkout)
 | 
|  | 404 | +
 | 
|  | 405 | +        artifacts = os.path.join(cli.directory, 'artifacts')
 | 
|  | 406 | +        shutil.rmtree(artifacts)
 | 
|  | 407 | +
 | 
|  | 408 | +        result = cli.run(project=project, args=['pull', 'compose-all.bst'])
 | 
|  | 409 | +        result.assert_success()
 | 
|  | 410 | +
 | 
|  | 411 | +        result = cli.run(project=project, args=['checkout', '--hardlinks', '--no-integrate', 'compose-all.bst', checkout])
 | 
|  | 412 | +        result.assert_success()
 | 
|  | 413 | +
 | 
|  | 414 | +        st = os.lstat(os.path.join(checkout, 'usr/include/pony.h'))
 | 
|  | 415 | +        assert stat.S_ISREG(st.st_mode)
 | 
|  | 416 | +        assert stat.S_IMODE(st.st_mode) == 0o0644
 | 
|  | 417 | +
 | 
|  | 418 | +        st = os.lstat(os.path.join(checkout, 'usr/bin/hello'))
 | 
|  | 419 | +        assert stat.S_ISREG(st.st_mode)
 | 
|  | 420 | +        assert stat.S_IMODE(st.st_mode) == 0o0755
 | 
|  | 421 | +
 | 
|  | 422 | +        st = os.lstat(os.path.join(checkout, 'usr/share/big-file'))
 | 
|  | 423 | +        assert stat.S_ISREG(st.st_mode)
 | 
|  | 424 | +        assert stat.S_IMODE(st.st_mode) == 0o0644 |