From 1bf24546758421e47b04288e56bf0e0650af3071 Mon Sep 17 00:00:00 2001 From: Jonas Finnemann Jensen Date: Wed, 6 Nov 2024 11:35:35 +0100 Subject: [PATCH] Test synchronizeTarballs --- .../package/api_export/exported_api_test.dart | 243 +++++++++++++++++- 1 file changed, 242 insertions(+), 1 deletion(-) diff --git a/app/test/package/api_export/exported_api_test.dart b/app/test/package/api_export/exported_api_test.dart index 9838d97b21..4f42cc8a3d 100644 --- a/app/test/package/api_export/exported_api_test.dart +++ b/app/test/package/api_export/exported_api_test.dart @@ -6,6 +6,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:_pub_shared/data/advisories_api.dart'; import 'package:_pub_shared/data/package_api.dart'; import 'package:clock/clock.dart'; import 'package:gcloud/storage.dart'; @@ -30,6 +31,164 @@ void main() { versions: [], ); + final retryPkgData2 = PackageData( + name: 'retry', + latest: VersionInfo( + version: '1.2.3', + retracted: false, + pubspec: {}, + archiveUrl: '-', + archiveSha256: '-', + published: clock.now(), + ), + versions: [ + VersionInfo( + version: '1.2.3', + retracted: false, + pubspec: {}, + archiveUrl: '-', + archiveSha256: '-', + published: clock.now(), + ) + ], + ); + + final retryAdvisoryData1 = ListAdvisoriesResponse( + advisories: [], + ); + + testWithProfile('ExportedApi.package().versions/advisories', fn: () async { + await storageService.createBucket('exported-api'); + final bucket = storageService.bucket('exported-api'); + final exportedApi = ExportedApi(storageService, bucket); + + // Check that we can write JSON files + await exportedApi.package('retry').versions.write(retryPkgData1); + await exportedApi.package('retry').advisories.write(retryAdvisoryData1); + + // Check contents of the files + expect( + await bucket.readGzippedJson('latest/api/packages/retry'), + json.decode(json.encode(retryPkgData1.toJson())), + ); + expect( + await bucket.readGzippedJson('latest/api/packages/retry/advisories'), + json.decode(json.encode(retryAdvisoryData1.toJson())), + ); + + // Check that we can update JSON files + await exportedApi.package('retry').versions.write(retryPkgData2); + expect( + await bucket.readGzippedJson('latest/api/packages/retry'), + json.decode(json.encode(retryPkgData2.toJson())), + ); + + // CHeck that we can delete files + await exportedApi.package('retry').versions.delete(); + await exportedApi.package('retry').advisories.delete(); + expect( + await bucket.readGzippedJson('latest/api/packages/retry'), + isNull, + ); + expect( + await bucket.readGzippedJson('latest/api/packages/retry/advisories'), + isNull, + ); + }); + + testWithProfile('ExportedApi.package().tarball().write/copyFrom', + fn: () async { + await storageService.createBucket('exported-api'); + final bucket = storageService.bucket('exported-api'); + final exportedApi = ExportedApi(storageService, bucket); + + // Check that we can write tarballs + await exportedApi.package('retry').tarball('1.2.3').write([1, 2, 3]); + // Check that we can copy tarballs + await exportedApi.package('retry').tarball('1.2.4').copyFrom( + SourceObjectInfo.fromObjectInfo( + bucket, + await bucket.info('latest/api/archives/retry-1.2.3.tar.gz'), + ), + ); + + // Check files created + expect( + await bucket.readBytes('latest/api/archives/retry-1.2.3.tar.gz'), + [1, 2, 3], + ); + expect( + await bucket.readBytes('latest/api/archives/retry-1.2.4.tar.gz'), + [1, 2, 3], + ); + + // Check that we can update tarballs, but writing or copying + await exportedApi.package('retry').tarball('1.2.3').write([1, 2, 4]); + await exportedApi.package('retry').tarball('1.2.4').copyFrom( + SourceObjectInfo.fromObjectInfo( + bucket, + await bucket.info('latest/api/archives/retry-1.2.3.tar.gz'), + ), + ); + + // Check files are updated + expect( + await bucket.readBytes('latest/api/archives/retry-1.2.3.tar.gz'), + [1, 2, 4], + ); + expect( + await bucket.readBytes('latest/api/archives/retry-1.2.4.tar.gz'), + [1, 2, 4], + ); + + // Check that we can delete files + await exportedApi.package('retry').tarball('1.2.3').delete(); + await exportedApi.package('retry').tarball('1.2.4').delete(); + expect( + await bucket.readBytes('latest/api/archives/retry-1.2.3.tar.gz'), + isNull, + ); + expect( + await bucket.readBytes('latest/api/archives/retry-1.2.4.tar.gz'), + isNull, + ); + }); + + testWithProfile('ExportedApi.package().tarball() version encoding', + fn: () async { + await storageService.createBucket('exported-api'); + final bucket = storageService.bucket('exported-api'); + final exportedApi = ExportedApi(storageService, bucket); + + await exportedApi.package('_foo').tarball('1.2.3').write([1, 2, 3]); + await exportedApi.package('_foo').tarball('1.2.3-dev+2').copyFrom( + SourceObjectInfo.fromObjectInfo( + bucket, + await bucket.info('latest/api/archives/_foo-1.2.3.tar.gz'), + ), + ); + await exportedApi.package('_foo').tarball('1.2.3-d.tar.gz').write([42]); + await exportedApi.package('_foo').tarball('1.2.3-d+4.tar.gz').write([42]); + + expect( + await bucket.readBytes('latest/api/archives/_foo-1.2.3.tar.gz'), + [1, 2, 3], + ); + expect( + await bucket.readBytes('latest/api/archives/_foo-1.2.3-dev%2B2.tar.gz'), + [1, 2, 3], + ); + expect( + await bucket.readBytes('latest/api/archives/_foo-1.2.3-d.tar.gz.tar.gz'), + [42], + ); + expect( + await bucket + .readBytes('latest/api/archives/_foo-1.2.3-d%2B4.tar.gz.tar.gz'), + [42], + ); + }); + testWithFakeTime('ExportedApi.garbageCollect()', (fakeTime) async { await storageService.createBucket('exported-api'); final bucket = storageService.bucket('exported-api'); @@ -97,7 +256,89 @@ void main() { } }); - testWithFakeTime('ExportedApi.garbageCollect()', (fakeTime) async { + testWithFakeTime('ExportedApi.package().synchronizeTarballs()', + (fakeTime) async { + await storageService.createBucket('exported-api'); + final bucket = storageService.bucket('exported-api'); + final exportedApi = ExportedApi(storageService, bucket); + + await storageService.createBucket('canonical-packages'); + final canonical = storageService.bucket('canonical-packages'); + + final src1 = SourceObjectInfo.fromObjectInfo( + canonical, + await canonical.writeBytes('packages/retry-1.0.0.tar.gz', [1, 0, 0]), + ); + final src2 = SourceObjectInfo.fromObjectInfo( + canonical, + await canonical.writeBytes('packages/retry-2.0.0.tar.gz', [2, 0, 0]), + ); + final src3 = SourceObjectInfo.fromObjectInfo( + canonical, + await canonical.writeBytes('packages/retry-3.0.0+1.tar.gz', [3, 0, 0]), + ); + + await exportedApi.package('retry').tarball('1.0.0').copyFrom(src1); + await exportedApi.package('retry').tarball('1.0.5').copyFrom(src2); + + expect( + await bucket.readBytes('latest/api/archives/retry-1.0.0.tar.gz'), + [1, 0, 0], + ); + expect( + await bucket.readBytes('latest/api/archives/retry-1.0.5.tar.gz'), + [2, 0, 0], + ); + + await exportedApi.package('retry').synchronizeTarballs({ + '1.0.0': src1, + '2.0.0': src2, + '3.0.0+1': src3, + }); + + expect( + await bucket.readBytes('latest/api/archives/retry-1.0.0.tar.gz'), + [1, 0, 0], + ); + expect( + await bucket.readBytes('latest/api/archives/retry-1.0.5.tar.gz'), + [2, 0, 0], + ); + expect( + await bucket.readBytes('latest/api/archives/retry-2.0.0.tar.gz'), + [2, 0, 0], + ); + expect( + await bucket.readBytes('latest/api/archives/retry-3.0.0%2B1.tar.gz'), + [3, 0, 0], + ); + + fakeTime.elapseSync(days: 2); + + await exportedApi.package('retry').synchronizeTarballs({ + '1.0.0': src1, + '2.0.0': src2, + '3.0.0+1': src3, + }); + expect( + await bucket.readBytes('latest/api/archives/retry-1.0.0.tar.gz'), + [1, 0, 0], + ); + expect( + await bucket.readBytes('latest/api/archives/retry-1.0.5.tar.gz'), + isNull, + ); + expect( + await bucket.readBytes('latest/api/archives/retry-2.0.0.tar.gz'), + [2, 0, 0], + ); + expect( + await bucket.readBytes('latest/api/archives/retry-3.0.0%2B1.tar.gz'), + [3, 0, 0], + ); + }); + + testWithFakeTime('ExportedApi.package().garbageCollect()', (fakeTime) async { await storageService.createBucket('exported-api'); final bucket = storageService.bucket('exported-api'); final exportedApi = ExportedApi(storageService, bucket);