fix(pi): isolate resolved package builds
This commit is contained in:
@@ -53,6 +53,7 @@ func TestNPMRegistryClientRejectsInvalidResponses(t *testing.T) {
|
||||
}{
|
||||
{name: "prerelease only", status: http.StatusOK, body: `{"versions":{"1.0.0-rc.1":{}}}`, wantText: "no stable"},
|
||||
{name: "malformed JSON", status: http.StatusOK, body: `{`, wantText: "invalid"},
|
||||
{name: "malformed semantic version key", status: http.StatusOK, body: `{"versions":{"0.81.0":{},"latest":{}}}`, wantText: "invalid"},
|
||||
{name: "no version data", status: http.StatusOK, body: `{"versions":{}}`, wantText: "no stable"},
|
||||
{name: "package not found", status: http.StatusNotFound, body: `{"error":"not_found"}`, wantText: "not found"},
|
||||
} {
|
||||
@@ -68,6 +69,31 @@ func TestNPMRegistryClientRejectsInvalidResponses(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNPMRegistryClientRejectsRedirectsOutsideTheAuthoritativePackageURL(t *testing.T) {
|
||||
for _, destination := range []string{
|
||||
"http://registry.npmjs.org/@earendil-works%2Fpi-coding-agent",
|
||||
"https://mirror.example.invalid/@earendil-works%2Fpi-coding-agent",
|
||||
} {
|
||||
t.Run(destination, func(t *testing.T) {
|
||||
calls := 0
|
||||
client := newNPMRegistryClient(&http.Client{Transport: roundTripFunc(func(request *http.Request) (*http.Response, error) {
|
||||
calls++
|
||||
response := registryResponse(http.StatusFound, "")
|
||||
response.Header.Set("Location", destination)
|
||||
response.Request = request
|
||||
return response, nil
|
||||
})})
|
||||
_, err := client.LatestStable(context.Background(), "@earendil-works/pi-coding-agent")
|
||||
if err == nil || !strings.Contains(strings.ToLower(err.Error()), "redirect") {
|
||||
t.Fatalf("LatestStable() redirect error = %v, want rejected redirect", err)
|
||||
}
|
||||
if calls != 1 {
|
||||
t.Fatalf("LatestStable() followed rejected redirect %d times", calls-1)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNPMRegistryClientRejectsAnOversizedResponse(t *testing.T) {
|
||||
client := newNPMRegistryClient(&http.Client{Transport: roundTripFunc(func(*http.Request) (*http.Response, error) {
|
||||
return registryResponse(http.StatusOK, `{"versions":{"1.2.3":{}}}`+strings.Repeat(" ", registryBodyLimit+1)), nil
|
||||
@@ -124,6 +150,7 @@ func TestUpdateWithResolvedVersionDoesNotMutateWhenDiscoveryFails(t *testing.T)
|
||||
{name: "package missing", err: errors.New("package not found")},
|
||||
{name: "malformed", err: errors.New("registry response is invalid")},
|
||||
{name: "no stable version", err: errors.New("registry contains no stable version")},
|
||||
{name: "malformed semantic version key", err: errors.New("registry version key is invalid")},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fake := newFakeRunner()
|
||||
@@ -144,6 +171,24 @@ func TestUpdateWithResolvedVersionDoesNotMutateWhenDiscoveryFails(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateWithResolvedVersionDoesNotMutateForMalformedRegistryVersionKeys(t *testing.T) {
|
||||
fake := newFakeRunner()
|
||||
statePath := t.TempDir() + "/state/update.json"
|
||||
registry := newNPMRegistryClient(&http.Client{Transport: roundTripFunc(func(*http.Request) (*http.Response, error) {
|
||||
return registryResponse(http.StatusOK, `{"versions":{"0.81.0":{},"not-a-semver":{}}}`), nil
|
||||
})})
|
||||
_, err := UpdateWithResolvedVersion(context.Background(), fake, Request{StatePath: statePath, Source: BuildSource, Confirm: true, Drain: true}, "@earendil-works/pi-coding-agent", registry)
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid") {
|
||||
t.Fatalf("UpdateWithResolvedVersion() error = %v, want malformed registry version rejection", err)
|
||||
}
|
||||
if len(fake.calls) != 0 {
|
||||
t.Fatalf("malformed registry version invoked Docker or lifecycle commands: %v", fake.calls)
|
||||
}
|
||||
if _, statErr := os.Stat(filepath.Dir(statePath)); !errors.Is(statErr, os.ErrNotExist) {
|
||||
t.Fatalf("malformed registry version created update state directory: %v", statErr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadRuntimePackageNameReadsThePiDependency(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
path := filepath.Join(root, "docker", "pi-runtime")
|
||||
|
||||
Reference in New Issue
Block a user