blob: 6d1d7b7fd73b5a6726f13fa17a730458e27301ce [file] [log] [blame]
// 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 util
import (
"bytes"
"fmt"
"strings"
"testing"
"go.fuchsia.dev/fuchsia/src/sys/pkg/bin/pm/build"
)
const (
merkleA = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
merkleB = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
)
func pkgURL(name, hash string) string {
return fmt.Sprintf("fuchsia-pkg://host/%s?hash=%s", name, hash)
}
type pkgMerkle struct {
name string
hash build.MerkleRoot
}
func TestParsePackagesJSON(t *testing.T) {
tests := []struct {
id string
json []byte
pkgs []pkgMerkle
expectErr bool
}{
{
id: "invalid json fails",
json: []byte("abcd"),
expectErr: true,
},
{
id: "empty object fails",
json: []byte("{}"),
expectErr: true,
},
{
id: "invalid version fails",
json: []byte(`{"version":"42","content":[]}`),
expectErr: true,
},
{
id: "numeric 1 succeeds",
json: []byte(`{"version":1,"content":[]}`),
expectErr: false,
},
{
id: "numeric 2 fails",
json: []byte(`{"version":2,"content":[]}`),
expectErr: true,
},
{
id: "contentless version succeeds",
json: []byte(`{"version":"1"}`),
expectErr: false,
},
{
id: "variant-less package succeeds",
json: []byte(fmt.Sprintf(`{"version":"1","content":["%s"]}`, pkgURL("pkg", merkleA))),
pkgs: []pkgMerkle{{"pkg", build.MustDecodeMerkleRoot(merkleA)}},
expectErr: false,
},
{
id: "variant package succeeds",
json: []byte(fmt.Sprintf(`{"version":"1","content":["%s"]}`, pkgURL("pkg/0", merkleA))),
pkgs: []pkgMerkle{{"pkg/0", build.MustDecodeMerkleRoot(merkleA)}},
expectErr: false,
},
{
id: "multiple packages succeed",
json: []byte(fmt.Sprintf(
`{"version":"1","content":["%s","%s"]}`,
pkgURL("pkg/0", merkleA),
pkgURL("another/0", merkleB)),
),
pkgs: []pkgMerkle{
{"pkg/0", build.MustDecodeMerkleRoot(merkleA)},
{"another/0", build.MustDecodeMerkleRoot(merkleB)},
},
expectErr: false,
},
}
for _, test := range tests {
r := bytes.NewBuffer(test.json)
pkgs, err := ParsePackagesJSON(r)
gotErr := (err != nil)
if test.expectErr && !gotErr {
t.Errorf("test %s: want error; got none", test.id)
} else if !test.expectErr && gotErr {
t.Errorf("test %s: want no error; got %v", test.id, err)
}
if len(pkgs) != len(test.pkgs) {
t.Errorf("test %s: got %d packages; want %d", test.id, len(pkgs), len(test.pkgs))
}
if test.pkgs != nil {
for _, pv := range test.pkgs {
h, ok := pkgs[pv.name]
if !ok {
t.Errorf("test %s: key not found; want %s", test.id, pv.name)
}
if h != pv.hash {
t.Errorf("test %s for package %s: got hash %s; want %s", test.id, pv.name, h, pv.hash)
}
}
}
}
}
func TestRehostPackagesJSON(t *testing.T) {
tests := []struct {
id string
json []byte
expected string
}{
{
id: "regular update package",
json: []byte(fmt.Sprintf(`{"version":"1","content":["%s","%s"]}`, pkgURL("pkg/0", "abc"), pkgURL("another/0", "def"))),
expected: `{"version":"1","content":["fuchsia-pkg://new/pkg/0?hash=abc","fuchsia-pkg://new/another/0?hash=def"]}`,
},
{
id: "numeric version 1 converted to string",
json: []byte(`{"version":1,"content":[]}`),
expected: `{"version":"1","content":[]}`,
},
}
for _, test := range tests {
r := bytes.NewBuffer(test.json)
var b bytes.Buffer
err := RehostPackagesJSON(r, &b, "new")
if err != nil {
t.Errorf("test %s: RehostPackagesJSON failed: %v", test.id, err)
}
actual := strings.TrimSpace(b.String())
if actual != test.expected {
t.Errorf("test %s: packages.json does not match, expected '%s', got '%s'", test.id, test.expected, actual)
}
}
}