blob: 3158d1002e000c2eb3c9bf0b6bed4866ebfc5016 [file] [log] [blame] [edit]
// Copyright 2019 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 bootserver
import (
"context"
"io"
"io/ioutil"
"path/filepath"
"reflect"
"testing"
)
func assertEqual(t *testing.T, actual, expected []string) {
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("unexpected output:\nactual:%v\nexpected:%v\n", actual, expected)
}
}
func TestGetImages(t *testing.T) {
var mockManifest = `[
{
"bootserver_pave": [
"--bootloader"
],
"name": "bootloader",
"path": "bootloader",
"type": "blk"
},
{
"bootserver_pave": [
"--zirconr"
],
"name": "zircon-r",
"path": "zedboot.zbi",
"type": "zbi"
},
{
"bootserver_netboot": [
"--boot"
],
"name": "netboot",
"path": "netboot.zbi",
"type": "zbi"
},
{
"name": "non-existent",
"path": "non-existent.zbi",
"type": "zbi"
}
]`
tmpDir := t.TempDir()
imgManifest := filepath.Join(tmpDir, "images.json")
if err := ioutil.WriteFile(imgManifest, []byte(mockManifest), 0o600); err != nil {
t.Fatalf("failed to write image manifest: %v", err)
}
type testImage struct {
name string
args []string
path string
contents string
bootMode Mode
}
bootloaderImage := testImage{
name: "blk_bootloader",
args: []string{"--bootloader"},
path: filepath.Join(tmpDir, "bootloader"),
contents: "bootloader contents",
bootMode: ModePave,
}
zedbootImage := testImage{
name: "zbi_zircon-r",
args: []string{"--zirconr"},
path: filepath.Join(tmpDir, "zedboot.zbi"),
contents: "zedboot contents",
bootMode: ModePave,
}
netbootImage := testImage{
name: "zbi_netboot",
args: []string{"--boot"},
path: filepath.Join(tmpDir, "netboot.zbi"),
contents: "netboot contents",
bootMode: ModeNetboot,
}
allImages := make(map[string]testImage)
for _, img := range []testImage{bootloaderImage, zedbootImage, netbootImage} {
if err := ioutil.WriteFile(img.path, []byte(img.contents), 0o600); err != nil {
t.Fatal(err)
}
allImages[img.name] = img
}
tests := []struct {
name string
bootMode Mode
}{
{"NetbootImgs", ModeNetboot},
{"UnknownBootMode", -1},
}
for _, test := range tests {
imgs, closeFunc, err := GetImages(context.Background(), imgManifest, test.bootMode)
if err != nil {
t.Fatalf("Test%s: failed to get images: %v", test.name, err)
}
// The images returned should be all existing images.
if len(imgs) != 3 {
t.Errorf("Test%s: got %d images, expected 3", test.name, len(imgs))
}
for _, img := range imgs {
expectedImg := allImages[img.Name]
if expectedImg.bootMode == test.bootMode {
assertEqual(t, img.Args, expectedImg.args)
} else {
assertEqual(t, img.Args, nil)
}
buf := make([]byte, img.Size)
_, err := img.Reader.ReadAt(buf, 0)
if err != nil {
t.Fatalf("Test%s: failed to read img %s: %v", test.name, img.Path, err)
}
if string(buf) != expectedImg.contents {
t.Fatalf("Test%s: unexpected image contents: expected: %s, actual: %v", test.name, expectedImg.contents, buf)
}
}
closeFunc()
for _, img := range imgs {
buf := make([]byte, 1)
if _, err := img.Reader.ReadAt(buf, 0); err == nil || err == io.EOF {
t.Fatalf("Test%s: reader is not closed for %s", test.name, img.Name)
}
}
}
}