This is a command-line tool for running compatibility tests against a Swift package registry server that implements SE-0292, SE-0321 and the corresponding service specification.
The compatibility test suite covers these API endpoints:
Sub-Command | API Endpoint | API Required |
---|---|---|
list-package-releases |
GET /{scope}/{name} |
Yes |
fetch-package-release-info |
GET /{scope}/{name}/{version} |
Yes |
fetch-package-release-manifest |
GET /{scope}/{name}/{version}/Package.swift{?swift-version} |
Yes |
download-source-archive |
GET /{scope}/{name}/{version}.zip |
Yes |
lookup-package-identifiers |
GET /identifiers{?url} |
Yes |
create-package-release |
PUT /{scope}/{name}/{version} |
No |
all |
All of the above | N/A |
All of the sub-commands have the same arguments and options:
package-registry-compatibility <sub-command> <url> <config-path> [--auth-token <auth-token>] [--api-version <api-version>] [--allow-http] [--generate-data]
The URL of the package registry being tested is set via the url
argument. https
scheme is required, but user may choose to allow
http
by setting the --allow-http
flag.
Each sub-command requires a JSON configuration file, described in their corresponding section below.
The path of the configuration file is specified with the config-path
argument.
Sub-commands operate in one of two modes:
- Data already exists in the registry. The tests simply verify that the values returned by the server match the expected values specified in the configuration file.
- Generate data for the test requests. The registry must implement the "create package release" API in this case, since the tool will use it to create the package releases needed for testing. The
--generate-data
flag enables this mode.
The two test modes require different configuration format. See the corresponding sub-command section for more details.
The optional auth-token
argument specifies the authentication token to be used for registry requests (i.e., the Authorization
HTTP header).
It is in the format of <type>:<token>
where <type>
is one of: basic
, bearer
, token
. For example, for basic authentication, <token>
would be
username:password
(i.e., basic:username:password
).
There is also an optional api-version
argument for specifying the API version to use in the Accept
HTTP request header. It
defaults to 1
if omitted.
All HTTP requests sent by the test HTTP client include the following headers:
Accept: application/vnd.swift.registry.v{apiVersion}+{mediaType}
(3.5)
The tool can be used to test success and/or failure scenarios. Anything that the server must do according to the API specification but does not would result in an error. Anything that the server should do but does not would result in a warning. The tool tries to execute as many assertions as it can unless it encounters a fatal error (e.g., invalid JSON). All warnings and errors are collected and printed at the end of each test case.
All HTTP server responses must include the following headers:
package-registry-compatibility list-package-releases <url> <config-path>
This sub-command tests the "list package release" (GET /{scope}/{name}
) API endpoint (4.1).
HTTP/1.1 200 OK
Content-Type: application/json
Content-Version: 1
Content-Length: 508
Link: <https://github.com/mona/LinkedList>; rel="canonical",
<ssh://[email protected]:mona/LinkedList.git>; rel="alternate",
<https://packages.example.com/mona/LinkedList/1.1.1>; rel="latest-version",
<https://github.com/sponsors/mona>; rel="payment"
{
"releases": {
"1.1.1": {
"url": "https://packages.example.com/mona/LinkedList/1.1.1"
},
"1.1.0": {
"url": "https://packages.example.com/mona/LinkedList/1.1.0",
"problem": {
"status": 410,
"title": "Gone",
"detail": "this release was removed from the registry"
}
},
"1.0.0": {
"url": "https://packages.example.com/mona/LinkedList/1.0.0"
}
}
}
The test configuration is a listPackageReleases
JSON object with the following key-values:
packages
: An array of JSON objects describing packages found in the registry and their expected responses:package
: A JSON object that includes the packagescope
andname
.numberOfReleases
: The total number of releases expected for the package. If pagination is supported by the server, the test will fetch all pages to obtain the total.versions
: A set of versions that must be present in the response. This can be a subset of all versions. If pagination is supported by the server, the test will fetch all pages to collect all version details.unavailableVersions
: Package versions that are unavailable (e.g., deleted). The server should communicate unavailability using aproblem
object, which the test enforces ifproblemProvided
istrue
.linkRelations
: Relations that should be included in theLink
response header (e.g.,latest-version
,canonical
,alternate
). Omit this if the server does not set theLink
header. Do not include pagination relations (e.g.,next
,last
, etc.) in this.
unknownPackages
: An array of packagescope
andname
JSON objects for packages that do not exist in the registry. In other words, the server is expected to return HTTP status code404
for these.packageURLProvided
: Iftrue
, each package release detail JSON object must include theurl
key.problemProvided
: Iftrue
, the detail JSON object of an unavailable version must includeproblem
key.paginationSupported
: Iftrue
, theLink
HTTP response header should includenext
,last
,first
,prev
relations, and a response may potentially contain only a subset of a package's releases.
{
"listPackageReleases": {
"packages": [
{
"package": { "scope": "apple", "name": "swift-nio" },
"numberOfReleases": 3,
"versions": [ "1.14.2", "2.29.0", "2.30.0" ],
"unavailableVersions": [ "2.29.0" ],
"linkRelations": [ "latest-version", "canonical" ]
}
],
"unknownPackages": [
{ "scope": "unknown", "name": "unknown" }
],
"packageURLProvided": true,
"problemProvided": true,
"paginationSupported": false
}
}
See the corresponding section for the create-package-release
sub-command for required
configuration when --generate-data
flag is set.
The listPackageReleases
object is also required:
linkHeaderIsSet
:true
indicates the server includesLink
header (e.g.,latest-version
,canonical
,alternate
relations) in the response, thus the generate should setlinkRelations
accordingly.packageURLProvided
: Iftrue
, each package release object in the response must include theurl
key.problemProvided
: Iftrue
, the detail JSON object of an unavailable release must includeproblem
key.paginationSupported
: Iftrue
, theLink
HTTP response header should includenext
,last
,first
,prev
relations.
The tool will use these configurations to construct the listPackageReleases
configuration described in the previous section for testing.
{
"listPackageReleases": {
"linkHeaderIsSet": true,
"packageURLProvided": true,
"problemProvided": true,
"paginationSupported": false
}
}
A. For each package in packages
:
- Send
GET /{scope}/{name}
request and wait for server response. - Response status code must be
200
. Response must includeContent-Type
(application/json
) andContent-Version
headers. - If
linkRelations
is specified, then theLink
response header must include these relations. - Response body must be a JSON object with
releases
key. If pagination is supported (i.e.,paginationSupported == true
), the test will fetch all pages using URL links in theLink
header. Otherwise, the test will assume the response contains all of the releases. - The number of releases must match
numberOfReleases
. - The keys (i.e., versions) in the
releases
JSON object must containversions
. - For each package release detail JSON object:
- There must be
url
key ifpackageURLProvided
istrue
. - If a version belongs to
unavailableVersions
andproblemProvided
istrue
, then there must beproblem
key.
- There must be
- Repeat steps 1-7 with flipcased
scope
andname
in the request URL to test for case-insensitivity.
B. For each package in unknownPackages
:
- Send
GET /{scope}/{name}
request and wait for server response. - Response status code must be
404
. - Response body should be a problem details JSON object.
C. The same as A except the request URI is /{scope}/{name}.json
.
D. The same as B except the request URI is /{scope}/{name}.json
.
package-registry-compatibility fetch-package-release-info <url> <config-path>
This sub-command tests the "fetch information about a package release" (GET /{scope}/{name}/{version}
) API endpoint (4.2).
HTTP/1.1 200 OK
Content-Version: 1
Content-Type: application/json
Content-Length: 720
Link: <https://packages.example.com/mona/LinkedList/1.1.1>; rel="latest-version",
<https://packages.example.com/mona/LinkedList/1.0.0>; rel="predecessor-version"
{
"id": "mona.LinkedList",
"version": "1.1.1",
"resources": [
{
"name": "source-archive",
"type": "application/zip",
"checksum": "a2ac54cf25fbc1ad0028f03f0aa4b96833b83bb05a14e510892bb27dea4dc812"
}
],
"metadata": { ... }
}
The test configuration is a fetchPackageReleaseInfo
JSON object with the following key-values:
packageReleases
: An array of JSON objects describing package releases found in the registry and their expected responses:packageRelease
: A JSON object that includes thepackage
(scope
andname
) andversion
.resources
: An array of JSON objects describing the package release's resources (e.g., source archive).keyValues
: Key-value pairs that must be found in the package release'smetadata
. Currently only string values are supported.linkRelations
: Relations that should be included in theLink
response header (e.g.,latest-version
,successor-version
,predecessor-version
). Omit this if the server does not set theLink
header.
unknownPackageReleases
: An array of "package release" JSON objects for package releases that do not exist in the registry. In other words, the server is expected to return HTTP status code404
for these.
{
"fetchPackageReleaseInfo": {
"packageReleases": [
{
"packageRelease": {
"package": { "scope": "apple", "name": "swift-nio" },
"version": "2.30.0"
},
"resources": [
{
"name": "source-archive",
"type": "application/zip",
"checksum": "e9a5540d37bf4fa0b5d5a071b366eeca899b37ece4ce93b26cc14286d57fbcef"
}
],
"keyValues": {
"repositoryURL": "https://github.com/apple/swift-nio",
"commitHash": "d79e333"
},
"linkRelations": [ "latest-version", "predecessor-version" ]
}
],
"unknownPackageReleases": [
{
"package": { "scope": "unknown", "name": "unknown" },
"version": "1.0.0"
}
]
}
}
See the corresponding section for the create-package-release
sub-command for required
configuration when --generate-data
flag is set.
The fetchPackageReleaseInfo
object is also required:
linkHeaderIsSet
:true
indicates the server includesLink
header (e.g.,latest-version
,successor-version
,predecessor-version
relations) in the response, thus the generate should setlinkRelations
accordingly.
The tool will use these configurations to construct the fetchPackageReleaseInfo
configuration described in the previous section for testing.
{
"fetchPackageReleaseInfo": {
"linkHeaderIsSet": true
}
}
A. For each package release in packageReleases
:
- Send
GET /{scope}/{name}/{version}
request and wait for server response. - Response status code must be
200
. Response must includeContent-Type
(application/json
) andContent-Version
headers. - If
linkRelations
is specified, then theLink
response header must include these relations. - Response body must be a JSON map with keys
id
andversion
. - The response JSON map must have matching
resources
. - If
metadata
is specified, the response JSON map'smetadata
must have matching key-value pairs. - Repeat steps 1-6 with flipcased
scope
andname
in the request URL to test for case-insensitivity.
B. For each packageRelease in unknownPackageReleases
:
- Send
GET /{scope}/{name}/{version}
request and wait for server response. - Response status code must be
404
. - Response body should be a problem details JSON object.
C. The same as A except the request URI is /{scope}/{name}/{version}.json
.
D. The same as B except the request URI is /{scope}/{name}/{version}.json
.
package-registry-compatibility fetch-package-release-manifest <url> <config-path>
This sub-command tests the "fetch manifest for a package release" (GET /{scope}/{name}/{version}/Package.swift
) API endpoint (4.3).
HTTP/1.1 200 OK
Cache-Control: public, immutable
Content-Type: text/x-swift
Content-Disposition: attachment; filename="Package.swift"
Content-Length: 361
Content-Version: 1
Link: <http://packages.example.com/mona/LinkedList/1.1.1/Package.swift?swift-version=4>; rel="alternate"; filename="[email protected]"; swift-tools-version="4.0",
<http://packages.example.com/mona/LinkedList/1.1.1/Package.swift?swift-version=4.2>; rel="alternate"; filename="[email protected]"; swift-tools-version="4.0"
// swift-tools-version:5.0
import PackageDescription
let package = Package(
name: "LinkedList",
products: [
.library(name: "LinkedList", targets: ["LinkedList"])
],
targets: [
.target(name: "LinkedList"),
.testTarget(name: "LinkedListTests", dependencies: ["LinkedList"]),
],
swiftLanguageVersions: [.v4, .v5]
)
The test configuration is a fetchPackageReleaseManifest
JSON object with the following key-values:
packageReleases
: An array of JSON objects describing package releases found in the registry:packageRelease
: A JSON object that includes thepackage
(scope
andname
) andversion
.swiftVersions
: An array of Swift versions that have version-specific manifest (i.e.,Package@swift-{swift-version}.swift
).noSwiftVersions
: An array of Swift versions that do not have version-specific manifest (i.e.,Package@swift-{swift-version}.swift
). The server is expected to return HTTP status code303
which redirects client to the unqualified manifest (i.e.,Package.swift
).
unknownPackageReleases
: An array of "package release" JSON objects for package releases that do not exist in the registry. In other words, the server is expected to return HTTP status code404
for these.contentLengthHeaderIsSet
: Iftrue
, theContent-Length
HTTP response header must be set.contentDispositionHeaderIsSet
: Iftrue
, theContent-Disposition
HTTP response header must be set.
The registry must include alternate
relation(s) in the Link
HTTP response header when fetching the
unqualified manifest (i.e., Package.swift
) and if the release has version-specific manifests.
{
"fetchPackageReleaseManifest": {
"packageReleases": [
{
"packageRelease": {
"package": { "scope": "sunshinejr", "name": "SwiftyUserDefaults" },
"version": "5.3.0"
},
"swiftVersions": [ "4.2" ],
"noSwiftVersions": [ "5.0" ]
}
],
"unknownPackageReleases": [
{
"package": { "scope": "unknown", "name": "unknown" },
"version": "1.0.0"
}
],
"contentLengthHeaderIsSet": true,
"contentDispositionHeaderIsSet": true
}
}
See the corresponding section for the create-package-release
sub-command for required
configuration when --generate-data
flag is set.
The fetchPackageReleaseManifest
object is also required:
contentLengthHeaderIsSet
: Iftrue
, theContent-Length
HTTP response header must be set.contentDispositionHeaderIsSet
: Iftrue
, theContent-Disposition
HTTP response header must be set.
The registry must include alternate
relation(s) in the Link
HTTP response header when fetching the
unqualified manifest (i.e., Package.swift
) and if the release has version-specific manifests.
The tool will use these configurations to construct the fetchPackageReleaseManifest
configuration described in the previous section for testing.
{
"fetchPackageReleaseManifest": {
"contentLengthHeaderIsSet": true,
"contentDispositionHeaderIsSet": true
}
}
For each package release in packageReleases
:
- Send
GET /{scope}/{name}/{version}/Package.swift
request and wait for server response. - Response status code must be
200
. Response must includeContent-Type
(text/x-swift
) andContent-Version
headers. - If
contentLengthHeaderIsSet == true
, the response must includeContent-Length
header and response body length must match. - If
contentDispositionHeaderIsSet == true
, the response must includeContent-Disposition
header and its value must containattachment; filename={filename}
. - If
swiftVersions
is specified, then theLink
response header must includealternate
relation(s). - Response body must be non-empty.
- Repeat steps 1-6 with flipcased
scope
andname
in the request URL to test for case-insensitivity. - For each Swift version in
swiftVersions
:- Send
GET /{scope}/{name}/{version}/Package.swift?swift-version={swiftVersion}
request and wait for server response. - Response status code must be
200
. Response must includeContent-Type
(text/x-swift
) andContent-Version
headers. - If
contentLengthHeaderIsSet == true
, the response must includeContent-Length
header and response body length must match. - If
contentDispositionHeaderIsSet == true
, the response must includeContent-Disposition
header and its value must containattachment; filename={filename}
. - Response body must be non-empty.
- Send
- For each Swift version in
noSwiftVersions
:- Send
GET /{scope}/{name}/{version}/Package.swift?swift-version={swiftVersion}
request and wait for server response. - Response status code must be
303
. - Response must include
Location
header. - The redirected response should have status code
200
. Response must includeContent-Type
(text/x-swift
) andContent-Version
headers. - If
contentLengthHeaderIsSet == true
, the response must includeContent-Length
header and response body length must match. - If
contentDispositionHeaderIsSet == true
, the response must includeContent-Disposition
header and its value must containattachment; filename={filename}
. - Response body must be non-empty.
- Send
For each package in unknownPackageReleases
:
- Send
GET /{scope}/{name}/{version}/Package.swift
request and wait for server response. - Response status code must be
404
. - Response body should be a problem details JSON object.
package-registry-compatibility download-source-archive <url> <config-path>
This sub-command tests the "download source archive" (GET /{scope}/{name}/{version}.zip
) API endpoint (4.4).
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: public, immutable
Content-Type: application/zip
Content-Disposition: attachment; filename="LinkedList-1.1.1.zip"
Content-Length: 2048
Content-Version: 1
Digest: sha-256=oqxUzyX7wa0AKPA/CqS5aDO4O7BaFOUQiSuyfepNyBI=
Link: <https://mirror-japanwest.example.com/mona-LinkedList-1.1.1.zip>; rel=duplicate; geo=jp; pri=10; type="application/zip"
The test configuration is a downloadSourceArchive
JSON object with the following key-values:
sourceArchives
: An array of JSON objects describing package releases found in the registry:packageRelease
: A JSON object that includes thepackage
(scope
andname
) andversion
.hasDuplicateLinks
: Iftrue
, the registry should includeduplicate
relation(s) in theLink
HTTP response header.
unknownSourceArchives
: An array of "package release" JSON objects for source archives that do not exist in the registry. In other words, the server is expected to return HTTP status code404
for these.contentDispositionHeaderIsSet
: Iftrue
, theContent-Disposition
HTTP response header must be set.digestHeaderIsSet
: Iftrue
, theDigest
HTTP response header must be set.
{
"downloadSourceArchive": {
"sourceArchives": [
{
"packageRelease": {
"package": { "scope": "apple", "name": "swift-nio" },
"version": "2.30.0",
},
"hasDuplicateLinks": false
}
],
"unknownSourceArchives": [
{
"package": { "scope": "unknown", "name": "unknown" },
"version": "1.0.0"
}
],
"contentDispositionHeaderIsSet": true,
"digestHeaderIsSet": true
}
}
See the corresponding section for the create-package-release
sub-command for required
configuration when --generate-data
flag is set.
The downloadSourceArchive
object is also required:
contentDispositionHeaderIsSet
: Iftrue
, theContent-Disposition
HTTP response header must be set.digestHeaderIsSet
: Iftrue
, theDigest
HTTP response header must be set.linkHeaderHasDuplicateRelations
: Iftrue
, theLink
HTTP response header must includeduplicate
relation(s).
The tool will use these configurations to construct the downloadSourceArchive
configuration described in the previous section for testing.
{
"downloadSourceArchive": {
"contentDispositionHeaderIsSet": true,
"digestHeaderIsSet": true,
"linkHeaderHasDuplicateRelations": false
}
}
For each package release in sourceArchives
:
- Send
GET /{scope}/{name}/{version}.zip
request and wait for server response. - Response status code must be
200
. Response must includeContent-Type
(application/zip
) andContent-Version
headers. - Response must include
Content-Length
header. - Response body must be non-empty and size must match
Content-Length
header. - If
digestHeaderIsSet == true
, theDigest
header must be set. It must match the checksum of the downloaded archive. - Perform integrity check:
- Send
GET /{scope}/{name}/{version}
request and wait for server response. - The package release information response must include one resource with name
source-archive
and typeapplication/zip
. The resource's checksum will be used to verify integrity. - Run
swift package compute-checksum
tool on the downloaded archive. - The resulting checksum must match that from step 2.
- If
contentDispositionHeaderIsSet == true
, theContent-Disposition
header must be set and its value must containattachment; filename={name}-{version}.zip
. - If
hasDuplicateLinks == true
, then theLink
response header must includeduplicate
relation(s).
For each package in unknownSourceArchives
:
- Send
GET /{scope}/{name}/{version}.zip
request and wait for server response. - Response status code must be
404
. - Response body should be a problem details JSON object.
package-registry-compatibility lookup-package-identifiers <url> <config-path>
This sub-command tests the "lookup package identifiers registered for a URL" (GET /identifiers{?url}
) API endpoint (4.5).
HTTP/1.1 200 OK
Content-Type: application/json
Content-Version: 1
{
"identifiers": [
"mona.LinkedList"
]
}
The test configuration is a lookupPackageIdentifiers
JSON object with the following key-values:
urls
: An array of JSON objects describing URLs recognized by the registry and their expected responses:url
: The URL to query package identifiers for.packageIdentifiers
: An array of package identifiers associated withurl
.
unknownURLs
: An array of URLs that are not recognized by the registry. In other words, the server is expected to return HTTP status code404
for these.
{
"lookupPackageIdentifiers": {
"urls": [
{
"url": "https://github.com/apple/swift-nio",
"packageIdentifiers": [ "apple.swift-nio" ]
}
],
"unknownURLs": [
"https://github.com/unknown/unknown"
]
}
}
See the corresponding section for the create-package-release
sub-command for required
configuration when --generate-data
flag is set.
The lookupPackageIdentifiers
object is also required:
repositoryURLMetadataKey
: Key in the package metadata whose value is the package's repository URL. Repository URLs will be used to lookup package identifiers.
The tool will use these configurations to construct the lookupPackageIdentifiers
configuration described in the previous section for testing.
{
"lookupPackageIdentifiers": {
"repositoryURLMetadataKey": "repositoryURL"
}
}
For each URL in urls
:
- Send
GET /identifiers{?url}
request and wait for server response. - Response status code must be
200
. Response must includeContent-Type
(application/json
) andContent-Version
headers. - Response body must be a JSON object with
identifiers
key. - The value of
identifiers
must matchpackageIdentifiers
. - Repeat steps 1-4 with flipcased
url
query param to test for case-insensitivity.
For each URL in unknownURLs
:
- Send
GET /identifiers{?url}
request and wait for server response. - Response status code must be
404
. - Response body should be a problem details JSON object.
package-registry-compatibility create-package-release <url> <config-path>
This sub-command tests the "create a package release" (PUT /{scope}/{name}/{version}
) API endpoint (4.6). Both synchronous and asynchronous publication are supported.
Synchronous publication:
HTTP/1.1 201 Created
Content-Version: 1
Location: https://packages.example.com/github.com/mona/LinkedList/1.1.1
Asynchronous publication:
HTTP/1.1 202 Accepted
Content-Version: 1
Location: https://packages.example.com/submissions/90D8CC77-A576-47AE-A531-D6402C4E33BC
Retry-After: 120
The test polls the Location
URL until the server redirects (301
) to the package release (which should return HTTP status 200
).
HTTP/1.1 301 Moved Permanently
Content-Version: 1
Location: https://packages.example.com/mona/LinkedList/1.1.1
The test configuration is a createPackageRelease
JSON object with the following key-values:
packageReleases
: An array of JSON objects describing package release to be published:package
: An optional JSON object withscope
andname
strings. They are used in the request URL if specified, otherwise the test will generate random values.version
: The package release version.sourceArchivePath
: The path of the source archive, which can be absolute or relative. If the latter, the tool will assume the parent directory of the configuration file (i.e., theconfig-path
argument) as the base directory.metadataPath
: The path of an optional JSON file containing metadata for the package release, which can be absolute or relative. If the latter, the tool will assume the parent directory of the configuration file (i.e., theconfig-path
argument) as the base directory.
maxProcessingTimeInSeconds
: The maximum processing time in seconds before the test considers the publication has failed. Optional.
{
"createPackageRelease": {
"packageReleases": [
{
"version": "1.14.2",
"sourceArchivePath": "../SourceArchives/[email protected]",
"metadataPath": "Metadata/[email protected]"
},
{
"version": "2.29.0",
"sourceArchivePath": "../SourceArchives/[email protected]",
"metadataPath": "Metadata/[email protected]"
}
],
"maxProcessingTimeInSeconds": 10
}
}
When the --generate-data
flag is set, the tool will generate the necessary data and configuration for the individual compatibility
tests (as documented in the "without --generate-data
flag" sections).
The following key-values are required in the configuration file:
resourceBaseDirectory
: The path of the directory containing test resource files (e.g., source archives, metadata JSON files, etc.), which can be absolute or relative. If the latter, the tool will assume the parent directory of the configuration file (i.e., theconfig-path
argument) as the base directory.packages
: An array of JSON objects containing information about package releases that will serve as the basis of compatibility test configuration. This must NOT be empty.id
: An optional JSON object withscope
andname
strings. The tool will generate a random package identity if this is unspecified.repositoryURL
: Repository URL of the package. Optional.releases
: An array of JSON package release objects. This must NOT be empty.version
: The package release version. Optional. The tool will generate a random version if unspecified.sourceArchivePath
: The path of the source archive, which can be absolute or relative. If the latter, the tool will useresourceBaseDirectory
as the base directory.metadataPath
: The path of an optional JSON file containing metadata for the package release, which can be absolute or relative. If the latter, the tool will useresourceBaseDirectory
as the base directory. The tool automatically replaces{TEST_SCOPE}
,{TEST_NAME}
, and{TEST_VERSION}
with generated values.versionManifests
: An array of Swift version strings with version-specific manifest. This is optional, but it is recommended for there to be at least one package release with version-specific manifests such that the "fetch package manifest" API can be tested properly.
The createPackageRelease
object is also required:
maxProcessingTimeInSeconds
: The maximum processing time in seconds before the test considers the publication has failed. Optional.
The tool will use these configurations to construct the createPackageRelease
configuration described in the previous section to
call the "create package release" API to create package releases for testing.
{
"resourceBaseDirectory": ".",
"packages": [
{
"releases": [
{
"sourceArchivePath": "../SourceArchives/[email protected]",
"metadataPath": "Metadata/Templates/[email protected]"
},
{
"sourceArchivePath": "../SourceArchives/[email protected]",
"metadataPath": "Metadata/Templates/[email protected]"
},
{
"sourceArchivePath": "../SourceArchives/[email protected]",
"metadataPath": "Metadata/Templates/[email protected]"
}
]
},
{
"releases": [
{
"sourceArchivePath": "../SourceArchives/[email protected]",
"metadataPath": "Metadata/Templates/[email protected]",
"versionManifests": [ "4.2" ]
}
]
}
],
"createPackageRelease": {
"maxProcessingTimeInSeconds": 10
}
}
A. For each package release in packageReleases
:
- Send
PUT /{scope}/{name}/{version}
request and wait for server response. - Response status code must be
201
(synchronous) or202
(asynchronous). Response must includeContent-Version
header.
- In case of status
201
, response should includeLocation
header. - In case of status
202
, response must includeLocation
header and should includeRetry-After
header. TheLocation
URL will be polled until it yields a301
(success) or4xx
(failure) response status.
- The test waits up to
maxProcessingTimeInSeconds
for publication to complete before failing.
B. For each package release in packageReleases
:
- Send
PUT /{scope}/{name}/{version}
request with flipcasedscope
andname
and wait for server response. - Response status code must be
409
since the package release already exists and package identity should be case-insensitive. - Response body should be non-empty since the server should return a problem details JSON object.
package-registry-compatibility all <url> <config-path>
This sub-command tests all the API endpoints mentioned in the previous sections.
The test configuration is a JSON object with the following key-values:
createPackageRelease
: configuration for thecreate-package-release
sub-command (without--generate-data
flag)listPackageReleases
: configuration for thelist-package-releases
sub-command (without--generate-data
flag)
{
"createPackageRelease" {
// create-package-release sub-command
},
"listPackageReleases" {
// list-package-releases sub-command
}
}
The test configuration is a JSON object with the following key-values:
createPackageRelease
: configuration for thecreate-package-release
sub-command (with--generate-data
flag)listPackageReleases
: configuration for thelist-package-releases
sub-command (with--generate-data
flag)
{
"resourceBaseDirectory": ...,
"packages": [...],
"createPackageRelease": {
// create-package-release sub-command
},
"listPackageReleases": {
// list-package-releases sub-command
}
}
package-registry-compatibility all http://localhost:9229 ./Fixtures/CompatibilityTestSuite/gendata.json --allow-http --generate-data
[0/0] Build complete!
Checking package registry URL...
Warning: Package registry URL must be HTTPS
Reading configuration file at ./Fixtures/CompatibilityTestSuite/gendata.json
Running other test preparations...
------------------------------------------------------------
Create Package Release
------------------------------------------------------------
- Package registry URL: http://localhost:9229
- API version: 1
Test case: Create package release [email protected]
OK - Read source archive file
OK - Read metadata file
OK - HTTP request to create package release
OK - HTTP response status
OK - "Content-Version" response header
OK - "Location" response header
Passed
...
Test case: Publish duplicate package release [email protected]
OK - Read source archive file
OK - Read metadata file
OK - HTTP request to create package release
OK - HTTP response status
OK - Response body
Passed
------------------------------------------------------------
List Package Releases
------------------------------------------------------------
- Package registry URL: http://localhost:9229
- API version: 1
Test case: List releases for package test-c1dz00.package-c1dz00 (without .json in the URI)
OK - HTTP request: GET http://localhost:9229/test-c1dz00/package-c1dz00
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - "latest-version" relation in "Link" response header
OK - Parse response body
OK - Number of releases
OK - Release versions
OK - Parse details object for release 1.0.0
OK - "url" for release 1.0.0
OK - Parse details object for release 2.1.0
OK - "url" for release 2.1.0
OK - Parse details object for release 2.0.0
OK - "url" for release 2.0.0
Passed
Test case: List releases for package TEST-C1DZ00.PACKAGE-C1DZ00 (without .json in the URI)
OK - HTTP request: GET http://localhost:9229/TEST-C1DZ00/PACKAGE-C1DZ00
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - "latest-version" relation in "Link" response header
OK - Parse response body
OK - Number of releases
OK - Release versions
OK - Parse details object for release 2.1.0
OK - "url" for release 2.1.0
OK - Parse details object for release 2.0.0
OK - "url" for release 2.0.0
OK - Parse details object for release 1.0.0
OK - "url" for release 1.0.0
Passed
...
Test case: List releases for unknown package test-bveboo.package-bveboo (without .json in the URI)
OK - HTTP request: GET http://localhost:9229/test-bveboo/package-bveboo
OK - HTTP response status
OK - Response body
Passed
Test case: List releases for package test-c1dz00.package-c1dz00 (with .json in the URI)
OK - HTTP request: GET http://localhost:9229/test-c1dz00/package-c1dz00.json
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - "latest-version" relation in "Link" response header
OK - Parse response body
OK - Number of releases
OK - Release versions
OK - Parse details object for release 2.1.0
OK - "url" for release 2.1.0
OK - Parse details object for release 2.0.0
OK - "url" for release 2.0.0
OK - Parse details object for release 1.0.0
OK - "url" for release 1.0.0
Passed
Test case: List releases for package TEST-C1DZ00.PACKAGE-C1DZ00 (with .json in the URI)
OK - HTTP request: GET http://localhost:9229/TEST-C1DZ00/PACKAGE-C1DZ00.json
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - "latest-version" relation in "Link" response header
OK - Parse response body
OK - Number of releases
OK - Release versions
OK - Parse details object for release 2.0.0
OK - "url" for release 2.0.0
OK - Parse details object for release 2.1.0
OK - "url" for release 2.1.0
OK - Parse details object for release 1.0.0
OK - "url" for release 1.0.0
Passed
...
Test case: List releases for unknown package test-bveboo.package-bveboo (with .json in the URI)
OK - HTTP request: GET http://localhost:9229/test-bveboo/package-bveboo.json
OK - HTTP response status
OK - Response body
Passed
------------------------------------------------------------
Fetch Package Release Information
------------------------------------------------------------
- Package registry URL: http://localhost:9229
- API version: 1
Test case: Fetch info for package release [email protected] (without .json in the URI)
OK - HTTP request: GET http://localhost:9229/test-c1dz00/package-c1dz00/1.0.0
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Response body
OK - Parse response body
OK - Key "id"
OK - Key "version"
OK - Key "resources"
OK - Resource name=source-archive, type=application/zip
OK - Key "metadata"
OK - Metadata key "repositoryURL"
OK - Metadata key "commitHash"
OK - "successor-version" relation in "Link" response header
OK - "latest-version" relation in "Link" response header
Passed
Test case: Fetch info for package release [email protected] (without .json in the URI)
OK - HTTP request: GET http://localhost:9229/TEST-C1DZ00/PACKAGE-C1DZ00/1.0.0
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Response body
OK - Parse response body
OK - Key "id"
OK - Key "version"
OK - Key "resources"
OK - Resource name=source-archive, type=application/zip
OK - Key "metadata"
OK - Metadata key "repositoryURL"
OK - Metadata key "commitHash"
OK - "successor-version" relation in "Link" response header
OK - "latest-version" relation in "Link" response header
Passed
...
Test case: Fetch info for unknown package release [email protected] (without .json in the URI)
OK - HTTP request: GET http://localhost:9229/test-bveboo/package-bveboo/1.0.0
OK - HTTP response status
OK - Response body
Passed
Test case: Fetch info for package release [email protected] (with .json in the URI)
OK - HTTP request: GET http://localhost:9229/test-c1dz00/package-c1dz00/1.0.0.json
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Response body
OK - Parse response body
OK - Key "id"
OK - Key "version"
OK - Key "resources"
OK - Resource name=source-archive, type=application/zip
OK - Key "metadata"
OK - Metadata key "repositoryURL"
OK - Metadata key "commitHash"
OK - "successor-version" relation in "Link" response header
OK - "latest-version" relation in "Link" response header
Passed
Test case: Fetch info for package release [email protected] (with .json in the URI)
OK - HTTP request: GET http://localhost:9229/TEST-C1DZ00/PACKAGE-C1DZ00/1.0.0.json
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Response body
OK - Parse response body
OK - Key "id"
OK - Key "version"
OK - Key "resources"
OK - Resource name=source-archive, type=application/zip
OK - Key "metadata"
OK - Metadata key "repositoryURL"
OK - Metadata key "commitHash"
OK - "successor-version" relation in "Link" response header
OK - "latest-version" relation in "Link" response header
Passed
...
Test case: Fetch info for unknown package release [email protected] (with .json in the URI)
OK - HTTP request: GET http://localhost:9229/test-bveboo/package-bveboo/1.0.0.json
OK - HTTP response status
OK - Response body
Passed
------------------------------------------------------------
Fetch Package Release Manifest
------------------------------------------------------------
- Package registry URL: http://localhost:9229
- API version: 1
Test case: Fetch Package.swift for package release [email protected]
OK - HTTP request: GET http://localhost:9229/test-c1dz00/package-c1dz00/1.0.0/Package.swift
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Response body
OK - "Content-Disposition" response header
OK - "Content-Length" response header
Passed
Test case: Fetch Package.swift for package release [email protected]
OK - HTTP request: GET http://localhost:9229/TEST-C1DZ00/PACKAGE-C1DZ00/1.0.0/Package.swift
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Response body
OK - "Content-Disposition" response header
OK - "Content-Length" response header
Passed
...
Test case: Fetch Package.swift for package release [email protected]
OK - HTTP request: GET http://localhost:9229/test-rhs1cp/package-rhs1cp/1.0.0/Package.swift
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Response body
OK - "Content-Disposition" response header
OK - "Content-Length" response header
OK - "alternate" relation in "Link" response header
Passed
Test case: Fetch Package.swift for package release [email protected]
OK - HTTP request: GET http://localhost:9229/TEST-RHS1CP/PACKAGE-RHS1CP/1.0.0/Package.swift
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Response body
OK - "Content-Disposition" response header
OK - "Content-Length" response header
OK - "alternate" relation in "Link" response header
Passed
Test case: Fetch [email protected] for package release [email protected]
OK - HTTP request: GET http://localhost:9229/test-rhs1cp/package-rhs1cp/1.0.0/Package.swift?swift-version=4.2
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Response body
OK - "Content-Disposition" response header
OK - "Content-Length" response header
Passed
Test case: Fetch missing [email protected] for package release [email protected]
OK - HTTP request: GET http://localhost:9229/test-rhs1cp/package-rhs1cp/1.0.0/Package.swift?swift-version=4.30
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Response body
OK - "Content-Disposition" response header
OK - "Content-Length" response header
Passed
Test case: Fetch Package.swift for unknown package release [email protected]
OK - HTTP request: GET http://localhost:9229/test-bveboo/package-bveboo/1.0.0/Package.swift
OK - HTTP response status
OK - Response body
Passed
------------------------------------------------------------
Download Source Archive
------------------------------------------------------------
- Package registry URL: http://localhost:9229
- API version: 1
Test case: Download source archive for package release [email protected]
OK - HTTP request: GET http://localhost:9229/test-c1dz00/package-c1dz00/1.0.0.zip
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - "Content-Disposition" response header
OK - Response body
OK - "Content-Length" response header
OK - Parse "Digest" response header
OK - Digest response header
OK - Get checksum for integrity check at http://localhost:9229/test-c1dz00/package-c1dz00/1.0.0
OK - Run 'compute-checksum' tool on downloaded archive
OK - Integrity of downloaded archive
Passed
Test case: Download source archive for package release [email protected]
OK - HTTP request: GET http://localhost:9229/TEST-C1DZ00/PACKAGE-C1DZ00/1.0.0.zip
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - "Content-Disposition" response header
OK - Response body
OK - "Content-Length" response header
OK - Parse "Digest" response header
OK - Digest response header
OK - Get checksum for integrity check at http://localhost:9229/TEST-C1DZ00/PACKAGE-C1DZ00/1.0.0
OK - Run 'compute-checksum' tool on downloaded archive
OK - Integrity of downloaded archive
Passed
...
Test case: Fetch source archive for unknown package release [email protected]
OK - HTTP request: GET http://localhost:9229/test-bveboo/package-bveboo/1.0.0.zip
OK - HTTP response status
OK - Response body
Passed
------------------------------------------------------------
Lookup Package Identifiers
------------------------------------------------------------
- Package registry URL: http://localhost:9229
- API version: 1
Test case: Lookup package identifiers for URL https://github.com/test-yc9jwg/package-yc9jwg
OK - HTTP request: GET http://localhost:9229/identifiers?url=https://github.com/test-yc9jwg/package-yc9jwg
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Parse response body
OK - Package identifiers
Passed
Test case: Lookup package identifiers for URL HTTPS://GITHUB.COM/TEST-YC9JWG/PACKAGE-YC9JWG
OK - HTTP request: GET http://localhost:9229/identifiers?url=HTTPS://GITHUB.COM/TEST-YC9JWG/PACKAGE-YC9JWG
OK - HTTP response status
OK - "Content-Type" response header
OK - "Content-Version" response header
OK - Parse response body
OK - Package identifiers
Passed
...
Test case: Lookup package identifiers for unknown URL https://repos.test/test-6iait6/package-6iait6
OK - HTTP request: GET http://localhost:9229/identifiers?url=https://repos.test/test-6iait6/package-6iait6
OK - HTTP response status
OK - Response body
Passed
Test summary:
Create Package Release - All tests passed.
List Package Releases - All tests passed.
Fetch Package Release Information - All tests passed.
Fetch Package Release Manifest - All tests passed.
Download Source Archive - All tests passed.
Lookup Package Identifiers - All tests passed.