| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package pmhttp |
| |
| import ( |
| "encoding/json" |
| "errors" |
| "math" |
| "os" |
| "path/filepath" |
| "testing" |
| |
| tuf_data "github.com/theupdateframework/go-tuf/data" |
| |
| "go.fuchsia.dev/fuchsia/src/sys/pkg/bin/pm/repo" |
| |
| repo_structs "go.fuchsia.dev/fuchsia/src/sys/pkg/lib/repo" |
| ) |
| |
| func TestConfigV2(t *testing.T) { |
| repoDir := t.TempDir() |
| |
| repository, err := repo.New(repoDir, t.TempDir()) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| if err := repository.Init(); err != nil { |
| t.Fatal(err) |
| } |
| |
| if err := repository.AddTargets([]string{}, json.RawMessage{}); err != nil { |
| t.Fatal(err) |
| } |
| |
| if err := repository.CommitUpdates(false); err != nil { |
| t.Fatal(err) |
| } |
| |
| rootBytes, err := os.ReadFile(filepath.Join(repoDir, "repository", "root.json")) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| t.Run("parse config", func(t *testing.T) { |
| var signed tuf_data.Signed |
| var root tuf_data.Root |
| if err := json.Unmarshal(rootBytes, &signed); err != nil { |
| t.Fatal(err) |
| } |
| if err := json.Unmarshal(signed.Signed, &root); err != nil { |
| t.Fatal(err) |
| } |
| |
| server := NewConfigServerV2(func() []byte { return rootBytes }, false) |
| config, err := server.parseConfig("http://localhost") |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| if root.Version != int(config.RootVersion) { |
| t.Fatalf("expected root version to be %v, not %v", root.Version, config.RootVersion) |
| } |
| |
| rootRole, ok := root.Roles["root"] |
| if !ok { |
| t.Fatalf("root does not have root role") |
| } |
| |
| if rootRole.Threshold != int(config.RootThreshold) { |
| t.Fatalf("expected root version to be %v, not %v", root.Version, config.RootThreshold) |
| } |
| }) |
| |
| t.Run("parse config with persistency flag set", func(t *testing.T) { |
| var signed tuf_data.Signed |
| var root tuf_data.Root |
| if err := json.Unmarshal(rootBytes, &signed); err != nil { |
| t.Fatal(err) |
| } |
| if err := json.Unmarshal(signed.Signed, &root); err != nil { |
| t.Fatal(err) |
| } |
| |
| server := NewConfigServerV2(func() []byte { return rootBytes }, true) |
| config, err := server.parseConfig("http://localhost") |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| if root.Version != int(config.RootVersion) { |
| t.Fatalf("expected root version to be %v, not %v", root.Version, config.RootVersion) |
| } |
| |
| rootRole, ok := root.Roles["root"] |
| if !ok { |
| t.Fatalf("root does not have root role") |
| } |
| |
| if rootRole.Threshold != int(config.RootThreshold) { |
| t.Fatalf("expected root version to be %v, not %v", root.Version, config.RootThreshold) |
| } |
| |
| if config.StorageType != repo_structs.Persistent { |
| t.Fatalf("expected storage type to be %v, not %v", repo_structs.Persistent, config.StorageType) |
| } |
| }) |
| |
| t.Run("parse config errs with underflow root version", func(t *testing.T) { |
| var signed tuf_data.Signed |
| var root tuf_data.Root |
| if err := json.Unmarshal(rootBytes, &signed); err != nil { |
| t.Fatal(err) |
| } |
| if err := json.Unmarshal(signed.Signed, &root); err != nil { |
| t.Fatal(err) |
| } |
| |
| root.Version = -1 |
| signed.Signed, err = json.Marshal(root) |
| if err != nil { |
| t.Fatal(err) |
| } |
| badRootBytes, err := json.Marshal(signed) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| server := NewConfigServerV2(func() []byte { return badRootBytes }, false) |
| if _, err := server.parseConfig("http://localhost"); !errors.Is(err, OutOfRangeError) { |
| t.Fatalf("expected error to be out of range, not %v", err) |
| } |
| }) |
| |
| t.Run("parse config errs with overflow root version", func(t *testing.T) { |
| var signed tuf_data.Signed |
| var root tuf_data.Root |
| if err := json.Unmarshal(rootBytes, &signed); err != nil { |
| t.Fatal(err) |
| } |
| if err := json.Unmarshal(signed.Signed, &root); err != nil { |
| t.Fatal(err) |
| } |
| |
| root.Version = math.MaxUint32 + 1 |
| signed.Signed, err = json.Marshal(root) |
| if err != nil { |
| t.Fatal(err) |
| } |
| badRootBytes, err := json.Marshal(signed) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| server := NewConfigServerV2(func() []byte { return badRootBytes }, false) |
| if _, err := server.parseConfig("http://localhost"); !errors.Is(err, OutOfRangeError) { |
| t.Fatalf("expected error to be out of range, not %v", err) |
| } |
| }) |
| |
| t.Run("parse config errs with underflow root threshold", func(t *testing.T) { |
| var signed tuf_data.Signed |
| var root tuf_data.Root |
| if err := json.Unmarshal(rootBytes, &signed); err != nil { |
| t.Fatal(err) |
| } |
| if err := json.Unmarshal(signed.Signed, &root); err != nil { |
| t.Fatal(err) |
| } |
| |
| root.Roles["root"].Threshold = -1 |
| signed.Signed, err = json.Marshal(root) |
| if err != nil { |
| t.Fatal(err) |
| } |
| badRootBytes, err := json.Marshal(signed) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| server := NewConfigServerV2(func() []byte { return badRootBytes }, false) |
| if _, err := server.parseConfig("http://localhost"); !errors.Is(err, OutOfRangeError) { |
| t.Fatalf("expected error to be out of range, not %v", err) |
| } |
| }) |
| |
| t.Run("parse config errs with overrflow root threshold", func(t *testing.T) { |
| var signed tuf_data.Signed |
| var root tuf_data.Root |
| if err := json.Unmarshal(rootBytes, &signed); err != nil { |
| t.Fatal(err) |
| } |
| if err := json.Unmarshal(signed.Signed, &root); err != nil { |
| t.Fatal(err) |
| } |
| |
| root.Roles["root"].Threshold = math.MaxUint32 + 1 |
| signed.Signed, err = json.Marshal(root) |
| if err != nil { |
| t.Fatal(err) |
| } |
| badRootBytes, err := json.Marshal(signed) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| server := NewConfigServerV2(func() []byte { return badRootBytes }, false) |
| if _, err := server.parseConfig("http://localhost"); !errors.Is(err, OutOfRangeError) { |
| t.Fatalf("expected error to be out of range, not %v", err) |
| } |
| }) |
| } |
| |
| func TestBuildRepoUrl(t *testing.T) { |
| testCases := []struct { |
| url string |
| want string |
| }{ |
| { |
| url: "fuchsia-pkg://devhost", |
| want: "fuchsia-pkg://devhost", |
| }, |
| { |
| url: "fuchsia-pkg://DEVHOST", |
| want: "fuchsia-pkg://devhost", |
| }, |
| { |
| url: "http://fuchsia.com", |
| want: "fuchsia-pkg://fuchsia.com", |
| }, |
| { |
| url: "https://fuchsia.com/packages", |
| want: "fuchsia-pkg://fuchsia.com-packages", |
| }, |
| } |
| |
| for _, tc := range testCases { |
| got := buildRepoUrl(tc.url) |
| if got != tc.want { |
| t.Errorf("buildRepoUrl(%v) returned %v, wanted %v", tc.url, got, tc.want) |
| } |
| } |
| } |