@@ -370,6 +370,10 @@ verify_objects_in_shared_cache () {
370370 return 0
371371}
372372
373+ # gvfs-helper prints a "packfile <path>" message for each received
374+ # packfile to stdout. Verify that we received the expected number
375+ # of packfiles.
376+ #
373377verify_received_packfile_count () {
374378 if test $# -eq 1
375379 then
@@ -412,6 +416,19 @@ verify_prefetch_keeps () {
412416 return 0
413417}
414418
419+ # Verify that the number of vfs- packfile present in the shared-cache
420+ # matches our expectations.
421+ #
422+ verify_vfs_packfile_count () {
423+ count=$(( $(ls - 1 "$SHARED_CACHE_T1 "/ pack/ vfs-* .pack | wc - l) ))
424+ if test $count -ne $1
425+ then
426+ echo " verify_vfs_packfile_count: expected $1 ; actual $count "
427+ return 1
428+ fi
429+ return 0
430+ }
431+
415432per_test_cleanup () {
416433 stop_gvfs_protocol_server
417434
@@ -1174,4 +1191,101 @@ test_expect_success 'integration: fully implicit: diff 2 commits' '
11741191 >OUT.output 2>OUT.stderr
11751192'
11761193
1194+ # ################################################################
1195+ # Duplicate packfile tests.
1196+ #
1197+ # If we request a fixed set of blobs, we should get a unique packfile
1198+ # of the form "vfs-<sha>.{pack,idx}". It we request that same set
1199+ # again, the server should create and send the exact same packfile.
1200+ # True webservers might build the custom packfile in random order,
1201+ # but our test webserver should give us consistent results.
1202+ #
1203+ # Verify that we can handle the duplicate pack and idx file properly.
1204+ # ################################################################
1205+
1206+ test_expect_success ' duplicate: vfs- packfile' '
1207+ test_when_finished "per_test_cleanup" &&
1208+ start_gvfs_protocol_server &&
1209+
1210+ git -C "$REPO_T1" gvfs-helper \
1211+ --cache-server=disable \
1212+ --remote=origin \
1213+ --no-progress \
1214+ post \
1215+ <"$OIDS_BLOBS_FILE" >OUT.output 2>OUT.stderr &&
1216+ verify_received_packfile_count 1 &&
1217+ verify_vfs_packfile_count 1 &&
1218+
1219+ # Re-fetch the same packfile. We do not care if it replaces
1220+ # first one or if it silently fails to overwrite the existing
1221+ # one. We just confirm that afterwards we only have 1 packfile.
1222+ #
1223+ git -C "$REPO_T1" gvfs-helper \
1224+ --cache-server=disable \
1225+ --remote=origin \
1226+ --no-progress \
1227+ post \
1228+ <"$OIDS_BLOBS_FILE" >OUT.output 2>OUT.stderr &&
1229+ verify_received_packfile_count 1 &&
1230+ verify_vfs_packfile_count 1 &&
1231+
1232+ stop_gvfs_protocol_server
1233+ '
1234+
1235+ # Return the absolute pathname of the first received packfile.
1236+ #
1237+ first_received_packfile_pathname () {
1238+ fn=$( sed -n ' /^packfile/p' < OUT.output | head -1 | sed -n ' s/^packfile \(.*\)/\1/p' )
1239+ echo " $SHARED_CACHE_T1 " /pack/" $fn "
1240+ return 0
1241+ }
1242+
1243+ test_expect_success ' duplicate and busy: vfs- packfile' '
1244+ test_when_finished "per_test_cleanup" &&
1245+ start_gvfs_protocol_server &&
1246+
1247+ git -C "$REPO_T1" gvfs-helper \
1248+ --cache-server=disable \
1249+ --remote=origin \
1250+ --no-progress \
1251+ post \
1252+ <"$OIDS_BLOBS_FILE" \
1253+ >OUT.output \
1254+ 2>OUT.stderr &&
1255+ verify_received_packfile_count 1 &&
1256+ verify_vfs_packfile_count 1 &&
1257+
1258+ # Re-fetch the same packfile, but hold the existing packfile
1259+ # open for writing on an obscure (and randomly-chosen) file
1260+ # descriptor.
1261+ #
1262+ # This should cause the replacement-install to fail (at least
1263+ # on Windows) with an EBUSY or EPERM or something.
1264+ #
1265+ # Verify that that error is eaten. We do not care if the
1266+ # replacement is retried or if gvfs-helper simply discards the
1267+ # second instance. We just confirm that afterwards we only
1268+ # have 1 packfile on disk and that the command "lies" and reports
1269+ # that it created the existing packfile. (We want the lie because
1270+ # in normal usage, gh-client has already built the packed-git list
1271+ # in memory and is using gvfs-helper to fetch missing objects;
1272+ # gh-client does not care who does the fetch, but it needs to
1273+ # update its packed-git list and restart the object lookup.)
1274+ #
1275+ PACK=$(first_received_packfile_pathname) &&
1276+ git -C "$REPO_T1" gvfs-helper \
1277+ --cache-server=disable \
1278+ --remote=origin \
1279+ --no-progress \
1280+ post \
1281+ <"$OIDS_BLOBS_FILE" \
1282+ >OUT.output \
1283+ 2>OUT.stderr \
1284+ 9>>"$PACK" &&
1285+ verify_received_packfile_count 1 &&
1286+ verify_vfs_packfile_count 1 &&
1287+
1288+ stop_gvfs_protocol_server
1289+ '
1290+
11771291test_done
0 commit comments