Skip to content

Commit 3ee5210

Browse files
committed
Make localFileOwnership test more robust
Assert the expected GID according to documented semantics on Linux vs BSDs.
1 parent 1d88f6d commit 3ee5210

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

Diff for: Tests/SWBUtilTests/FSProxyTests.swift

+23-1
Original file line numberDiff line numberDiff line change
@@ -472,9 +472,31 @@ import SWBTestSupport
472472
let testDataPath = tmpDir.join("test-data.txt")
473473
try localFS.write(testDataPath, contents: ByteString(testData))
474474

475+
let parentDirOwnership = try localFS.getFileOwnership(tmpDir)
475476
let ownership = try localFS.getFileOwnership(testDataPath)
477+
478+
// The owner of newly created files is guaranteed to the be process effective UID on Linux. It is not documented on BSDs but generally also expected to be the process effective UID.
476479
#expect(current_uid == ownership.owner)
477-
#expect(current_gid == ownership.group)
480+
481+
// Considering the following man page documentation for open(2):
482+
// [Darwin/BSD] When a new file is created it is given the group of the directory which contains it.
483+
// [Linux] The group ownership (group ID) of the new file is set either to the effective group ID of the process (System V semantics) or to the group ID of the parent directory (BSD semantics). On Linux, the behavior depends on whether the set-group-ID mode bit is set on the parent directory: if that bit is set, then BSD semantics apply; otherwise, System V semantics apply. For some filesystems, the behavior also depends on the bsdgroups and sysvgroups mount options described in mount(8).
484+
// ...and the following man page documentation for mkdir(2):
485+
// [Darwin/BSD] The directory's group ID is set to that of the parent directory in which it is created.
486+
// [Linux] If the directory containing the file has the set-group-ID bit set, or if the filesystem is mounted with BSD group semantics (mount -o bsdgroups or, synonymously mount -o grpid), the new directory will inherit the group ownership from its parent; otherwise it will be owned by the effective group ID of the process.
487+
switch try ProcessInfo.processInfo.hostOperatingSystem() {
488+
case .android, .linux:
489+
// This will _usually_ be correct on Linux-derived OSes (see above), but not always.
490+
#expect(current_gid == ownership.group)
491+
case .macOS, .iOS, .tvOS, .watchOS, .visionOS:
492+
#expect(parentDirOwnership.group == ownership.group)
493+
case .windows:
494+
// POSIX permissions don't exist, so everything is hardcoded to zero.
495+
#expect(current_gid == 0)
496+
#expect(ownership.group == 0)
497+
case .unknown:
498+
break
499+
}
478500

479501
try localFS.setFileOwnership(testDataPath, owner: current_uid, group: current_gid)
480502
let ownershipAfterChange = try localFS.getFileOwnership(testDataPath)

0 commit comments

Comments
 (0)