| // 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) |
| } |
| } |
| } |
| } |