Skip to content

Commit

Permalink
cmds/cbfs: add smoke tests to CLI command
Browse files Browse the repository at this point in the history
Signed-off-by: Siarhiej Siemianczuk <[email protected]>
  • Loading branch information
binjip978 authored and orangecms committed Sep 22, 2024
1 parent 54e4adf commit d9260b5
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 20 deletions.
51 changes: 31 additions & 20 deletions cmds/cbfs/cbfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ package main

import (
"encoding/json"
"errors"
"fmt"
"io"
"log"
"os"
"path/filepath"
Expand All @@ -18,41 +20,42 @@ import (

var debug = flag.BoolP("debug", "d", false, "enable debug prints")

func main() {
flag.Parse()
var errUsage = errors.New("usage: cbfs <firmware-file> <json,list,extract <directory-name>>")
var errMissingDirectory = errors.New("provide a directory name")

if *debug {
func run(stdout io.Writer, debug bool, args []string) error {
if debug {
cbfs.Debug = log.Printf
}

a := flag.Args()
if len(a) < 2 {
log.Fatal("Usage: cbfs <firmware-file> <json,list,extract <directory-name>>")
if len(args) < 2 {
return errUsage
}

i, err := cbfs.Open(a[0])
i, err := cbfs.Open(args[0])
if err != nil {
log.Fatal(err)
return err
}

switch a[1] {
switch args[1] {
case "list":
fmt.Printf("%s", i.String())
fmt.Fprintf(stdout, "%s", i.String())
case "json":
j, err := json.MarshalIndent(i, " ", " ")
if err != nil {
log.Fatal(err)
return err
}
fmt.Printf("%s", string(j))
fmt.Fprintf(stdout, "%s", string(j))
case "extract":
if len(a) != 3 {
log.Fatal("provide a directory name")
if len(args) != 3 {
return errMissingDirectory
}
dir := filepath.Join(".", a[2])
dir := filepath.Join(".", args[2])
err := os.MkdirAll(dir, os.ModePerm)
if err != nil {
log.Fatal(err)
return err
}

base := i.Area.Offset
log.Printf("FMAP base at %x", base)
for s := range i.Segs {
Expand All @@ -64,19 +67,27 @@ func main() {
log.Printf("Skipping empty/deleted file at 0x%x", o)
} else {
log.Printf("Extracting %v from 0x%x, compression: %v", n, o, c)
fpath := filepath.Join(dir, strings.Replace(n, "/", "_", -1))
fpath := filepath.Join(dir, strings.ReplaceAll(n, "/", "_"))
d, err := f.Decompress()
if err != nil {
log.Fatal(err)
return err
}
err = os.WriteFile(fpath, d, 0644)
if err != nil {
log.Fatal(err)
return err
}
}
}
default:
log.Fatal("?")
return errUsage
}

return nil
}

func main() {
flag.Parse()
if err := run(os.Stdout, *debug, flag.Args()); err != nil {
log.Fatal(err)
}
}
88 changes: 88 additions & 0 deletions cmds/cbfs/cbfs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2024 the LinuxBoot 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 main

import (
"bytes"
"encoding/json"
"errors"
"io"
"os"
"path/filepath"
"strings"
"testing"
)

func TestCBFS(t *testing.T) {
t.Run("usage error", func(t *testing.T) {
err := run(io.Discard, false, []string{"list"})
if !errors.Is(err, errUsage) {
t.Errorf("expected %v, got nil", errUsage)
}
})

t.Run("unknown command", func(t *testing.T) {
err := run(io.Discard, false, []string{"testdata/coreboot.rom", "unknown"})
if !errors.Is(err, errUsage) {
t.Errorf("expected %v, got nil", errUsage)
}
})

t.Run("list command", func(t *testing.T) {
stdout := &bytes.Buffer{}
err := run(stdout, false, []string{"testdata/coreboot.rom", "list"})
if err != nil {
t.Fatalf("expected nil got %v", err)
}

if !strings.Contains(stdout.String(), "fallback/ramstage") {
t.Errorf("output doesn't contain `fallback/ramstage`, %s", stdout.String())
}
})

t.Run("list json", func(t *testing.T) {
stdout := &bytes.Buffer{}
err := run(stdout, false, []string{"testdata/coreboot.rom", "json"})
if err != nil {
t.Fatalf("expected nil got %v", err)
}

if !strings.Contains(stdout.String(), "fallback/ramstage") {
t.Errorf("output doesn't contain `fallback/ramstage`, %s", stdout.String())
}

j := make(map[string]any)
err = json.Unmarshal(stdout.Bytes(), &j)
if err != nil {
t.Errorf("expected json output, got unmarshal error: %v", err)
}
})

t.Run("extract missing dir", func(t *testing.T) {
err := run(io.Discard, false, []string{"testdata/coreboot.rom", "extract"})
if !errors.Is(err, errMissingDirectory) {
t.Errorf("expected %v, got nil", errMissingDirectory)
}
})

t.Run("extract", func(t *testing.T) {
dir := t.TempDir()
// save local path
romPath, err := filepath.Abs("testdata/coreboot.rom")
if err != nil {
t.Fatal(err)
}

err = os.Chdir(dir)
if err != nil {
t.Fatal(err)
}

err = run(io.Discard, false, []string{romPath, "extract", "firmware"})
if err != nil {
t.Fatalf("expected nil, got %v", err)
}
})
}
Binary file added cmds/cbfs/testdata/coreboot.rom
Binary file not shown.

0 comments on commit d9260b5

Please sign in to comment.