@@ -862,3 +862,50 @@ def test_gather_reconsolidation_candidates(tmp_path):
862862 assert len (candidates_filtered ) == 2
863863 filtered_names = {c .name for c in candidates_filtered }
864864 assert filtered_names == {"tools/small 1.0.0" , "tools/small 2.0.0" }
865+
866+
867+ def test_duplicate_subdir_names_in_consolidation_group_are_rejected (tmp_path ):
868+ """Regression test: fresh item + reconsolidation item with the same name must not appear
869+ in the same consolidation group.
870+
871+ Production failure (2026-04-10, run #24232582644):
872+ OSError: [Errno 39] Directory not empty:
873+ .tmp_extract_2d3e5ffc/compilers_swift_static-sdk_sdk-0-1-0_6.2.4
874+ -> compilers_swift_static-sdk_sdk-0-1-0_6.2.4
875+
876+ Both 'compilers/swift/static-sdk/sdk-0-1-0 6.2.4' (fresh install) and a
877+ reconsolidation candidate from an existing consolidated image produced the
878+ same sanitized subdir_name. Parallel workers raced to write the same
879+ directory, and the second found it non-empty.
880+ """
881+ mount_point = Path ("/cefs" )
882+
883+ fresh_path = tmp_path / "swift-static-sdk-6.2.4"
884+ cefs_target = mount_point / "7e" / "7e37bea4f759832456d69f12_swift-6.2.4-static-sdk"
885+ fresh_path .symlink_to (cefs_target )
886+
887+ recon_path = tmp_path / "swift-static-sdk-6.2.4-recon"
888+
889+ group = [
890+ ConsolidationCandidate (
891+ name = "compilers/swift/static-sdk/sdk-0-1-0 6.2.4" ,
892+ nfs_path = fresh_path ,
893+ squashfs_path = Path ("/efs/cefs-images/7e/7e37bea4f759832456d69f12_swift-6.2.4-static-sdk.sqfs" ),
894+ size = 238_000_000 ,
895+ from_reconsolidation = False ,
896+ ),
897+ ConsolidationCandidate (
898+ name = "compilers/swift/static-sdk/sdk-0-1-0 6.2.4" , # same name as above
899+ nfs_path = recon_path ,
900+ squashfs_path = Path ("/efs/cefs-images/26/26ccf7a2fd1f9d4667de2307_consolidated.sqfs" ),
901+ size = 50_000_000 ,
902+ extraction_path = Path ("compilers_swift_static-sdk_sdk-0-1-0_6.2.4" ),
903+ from_reconsolidation = True ,
904+ ),
905+ ]
906+
907+ # Both items sanitize to the same subdir_name: 'compilers_swift_static-sdk_sdk-0-1-0_6.2.4'.
908+ # prepare_consolidation_items must detect this and raise ValueError — if it silently
909+ # returned both, parallel workers would race to extract to the same directory.
910+ with pytest .raises (ValueError , match = "Duplicate subdir name" ):
911+ prepare_consolidation_items (group , mount_point )
0 commit comments