@@ -370,6 +370,10 @@ verify_objects_in_shared_cache () {
370
370
return 0
371
371
}
372
372
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
+ #
373
377
verify_received_packfile_count () {
374
378
if test $# -eq 1
375
379
then
@@ -412,6 +416,19 @@ verify_prefetch_keeps () {
412
416
return 0
413
417
}
414
418
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
+
415
432
per_test_cleanup () {
416
433
stop_gvfs_protocol_server
417
434
@@ -1174,4 +1191,101 @@ test_expect_success 'integration: fully implicit: diff 2 commits' '
1174
1191
>OUT.output 2>OUT.stderr
1175
1192
'
1176
1193
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
+
1177
1291
test_done
0 commit comments