Skip to content

Commit 86decfa

Browse files
committed
test: add unit test for hard links in shared packages
1 parent be29e8d commit 86decfa

1 file changed

Lines changed: 76 additions & 0 deletions

File tree

test/unit/test_share.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Bob Build Tool
2+
# Copyright (C) 2025 Jan Klötzke
3+
#
4+
# SPDX-License-Identifier: GPL-3.0-or-later
5+
from tempfile import NamedTemporaryFile, TemporaryDirectory
6+
from unittest import TestCase, skipIf
7+
from unittest.mock import MagicMock, patch
8+
import os
9+
import sys
10+
11+
from bob.share import LocalShare
12+
from bob.utils import hashDirectory
13+
from bob.errors import BuildError
14+
15+
class TestLocalShare(TestCase):
16+
17+
def setUp(self):
18+
# create repo
19+
self.repo = TemporaryDirectory()
20+
self.share = LocalShare({ 'path' : self.repo.name })
21+
self.pkg_tmp = TemporaryDirectory()
22+
self.pkg = self.pkg_tmp.name
23+
with open(os.path.join(self.pkg, "audit.json.gz"), "wb") as f:
24+
pass
25+
self.workspace = os.path.join(self.pkg, "workspace")
26+
os.mkdir(self.workspace)
27+
28+
def tearDown(self):
29+
self.pkg_tmp.cleanup()
30+
self.repo.cleanup()
31+
32+
@skipIf(sys.platform.startswith("win"), "requires POSIX platform")
33+
def testInstallHardLinks(self):
34+
"""Hard links are preserved when copying"""
35+
with open(os.path.join(self.workspace, "a"), "wb") as f:
36+
f.write(b'a')
37+
os.link(os.path.join(self.workspace, "a"), os.path.join(self.workspace, "b"))
38+
os.link(os.path.join(self.workspace, "a"), os.path.join(self.workspace, "c"))
39+
40+
with patch('bob.share.warnEscapedHardLink') as warning:
41+
warning.show = MagicMock()
42+
bid = b'a'*20
43+
self.share.installSharedPackage(self.workspace, bid, hashDirectory(self.workspace), False)
44+
warning.show.assert_not_called()
45+
46+
sharePath = self.share._LocalShare__buildPath(bid)
47+
s1 = os.stat(os.path.join(sharePath, "workspace", "a"))
48+
s2 = os.stat(os.path.join(sharePath, "workspace", "b"))
49+
s3 = os.stat(os.path.join(sharePath, "workspace", "c"))
50+
self.assertEqual(s1.st_nlink, 3)
51+
self.assertEqual(s2.st_nlink, 3)
52+
self.assertEqual(s3.st_nlink, 3)
53+
self.assertEqual(s1.st_dev, s2.st_dev)
54+
self.assertEqual(s1.st_ino, s2.st_ino)
55+
self.assertEqual(s2.st_dev, s3.st_dev)
56+
self.assertEqual(s2.st_ino, s3.st_ino)
57+
58+
@skipIf(sys.platform.startswith("win"), "requires POSIX platform")
59+
def testInstallHardLinkOutsideWorkspace(self):
60+
"""Hard links outside the workspace create a warning"""
61+
with open(os.path.join(self.pkg, "outside"), "wb") as f:
62+
f.write(b'a')
63+
os.link(os.path.join(self.pkg, "outside"), os.path.join(self.workspace, "file"))
64+
65+
with patch('bob.share.warnEscapedHardLink') as warning:
66+
warning.show = MagicMock()
67+
bid = b'a'*20
68+
self.share.installSharedPackage(self.workspace, bid, hashDirectory(self.workspace), False)
69+
warning.show.assert_called()
70+
71+
def testInstallCorrupted(self):
72+
"""Changes to the hash sum at the destination are detected"""
73+
with self.assertRaises(BuildError):
74+
self.share.installSharedPackage(self.workspace, b'a'*20, b'0'*20, False)
75+
with self.assertRaises(BuildError):
76+
self.share.installSharedPackage(self.workspace, b'a'*20, b'0'*20, True)

0 commit comments

Comments
 (0)