Skip to content

Commit d9260b5

Browse files
binjip978orangecms
authored andcommitted
cmds/cbfs: add smoke tests to CLI command
Signed-off-by: Siarhiej Siemianczuk <pdp.eleven11@gmail.com>
1 parent 54e4adf commit d9260b5

3 files changed

Lines changed: 119 additions & 20 deletions

File tree

cmds/cbfs/cbfs.go

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ package main
66

77
import (
88
"encoding/json"
9+
"errors"
910
"fmt"
11+
"io"
1012
"log"
1113
"os"
1214
"path/filepath"
@@ -18,41 +20,42 @@ import (
1820

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

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

24-
if *debug {
26+
func run(stdout io.Writer, debug bool, args []string) error {
27+
if debug {
2528
cbfs.Debug = log.Printf
2629
}
2730

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

33-
i, err := cbfs.Open(a[0])
35+
i, err := cbfs.Open(args[0])
3436
if err != nil {
35-
log.Fatal(err)
37+
return err
3638
}
3739

38-
switch a[1] {
40+
switch args[1] {
3941
case "list":
40-
fmt.Printf("%s", i.String())
42+
fmt.Fprintf(stdout, "%s", i.String())
4143
case "json":
4244
j, err := json.MarshalIndent(i, " ", " ")
4345
if err != nil {
44-
log.Fatal(err)
46+
return err
4547
}
46-
fmt.Printf("%s", string(j))
48+
fmt.Fprintf(stdout, "%s", string(j))
4749
case "extract":
48-
if len(a) != 3 {
49-
log.Fatal("provide a directory name")
50+
if len(args) != 3 {
51+
return errMissingDirectory
5052
}
51-
dir := filepath.Join(".", a[2])
53+
dir := filepath.Join(".", args[2])
5254
err := os.MkdirAll(dir, os.ModePerm)
5355
if err != nil {
54-
log.Fatal(err)
56+
return err
5557
}
58+
5659
base := i.Area.Offset
5760
log.Printf("FMAP base at %x", base)
5861
for s := range i.Segs {
@@ -64,19 +67,27 @@ func main() {
6467
log.Printf("Skipping empty/deleted file at 0x%x", o)
6568
} else {
6669
log.Printf("Extracting %v from 0x%x, compression: %v", n, o, c)
67-
fpath := filepath.Join(dir, strings.Replace(n, "/", "_", -1))
70+
fpath := filepath.Join(dir, strings.ReplaceAll(n, "/", "_"))
6871
d, err := f.Decompress()
6972
if err != nil {
70-
log.Fatal(err)
73+
return err
7174
}
7275
err = os.WriteFile(fpath, d, 0644)
7376
if err != nil {
74-
log.Fatal(err)
77+
return err
7578
}
7679
}
7780
}
7881
default:
79-
log.Fatal("?")
82+
return errUsage
8083
}
8184

85+
return nil
86+
}
87+
88+
func main() {
89+
flag.Parse()
90+
if err := run(os.Stdout, *debug, flag.Args()); err != nil {
91+
log.Fatal(err)
92+
}
8293
}

cmds/cbfs/cbfs_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2024 the LinuxBoot Authors. All rights reserved
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package main
6+
7+
import (
8+
"bytes"
9+
"encoding/json"
10+
"errors"
11+
"io"
12+
"os"
13+
"path/filepath"
14+
"strings"
15+
"testing"
16+
)
17+
18+
func TestCBFS(t *testing.T) {
19+
t.Run("usage error", func(t *testing.T) {
20+
err := run(io.Discard, false, []string{"list"})
21+
if !errors.Is(err, errUsage) {
22+
t.Errorf("expected %v, got nil", errUsage)
23+
}
24+
})
25+
26+
t.Run("unknown command", func(t *testing.T) {
27+
err := run(io.Discard, false, []string{"testdata/coreboot.rom", "unknown"})
28+
if !errors.Is(err, errUsage) {
29+
t.Errorf("expected %v, got nil", errUsage)
30+
}
31+
})
32+
33+
t.Run("list command", func(t *testing.T) {
34+
stdout := &bytes.Buffer{}
35+
err := run(stdout, false, []string{"testdata/coreboot.rom", "list"})
36+
if err != nil {
37+
t.Fatalf("expected nil got %v", err)
38+
}
39+
40+
if !strings.Contains(stdout.String(), "fallback/ramstage") {
41+
t.Errorf("output doesn't contain `fallback/ramstage`, %s", stdout.String())
42+
}
43+
})
44+
45+
t.Run("list json", func(t *testing.T) {
46+
stdout := &bytes.Buffer{}
47+
err := run(stdout, false, []string{"testdata/coreboot.rom", "json"})
48+
if err != nil {
49+
t.Fatalf("expected nil got %v", err)
50+
}
51+
52+
if !strings.Contains(stdout.String(), "fallback/ramstage") {
53+
t.Errorf("output doesn't contain `fallback/ramstage`, %s", stdout.String())
54+
}
55+
56+
j := make(map[string]any)
57+
err = json.Unmarshal(stdout.Bytes(), &j)
58+
if err != nil {
59+
t.Errorf("expected json output, got unmarshal error: %v", err)
60+
}
61+
})
62+
63+
t.Run("extract missing dir", func(t *testing.T) {
64+
err := run(io.Discard, false, []string{"testdata/coreboot.rom", "extract"})
65+
if !errors.Is(err, errMissingDirectory) {
66+
t.Errorf("expected %v, got nil", errMissingDirectory)
67+
}
68+
})
69+
70+
t.Run("extract", func(t *testing.T) {
71+
dir := t.TempDir()
72+
// save local path
73+
romPath, err := filepath.Abs("testdata/coreboot.rom")
74+
if err != nil {
75+
t.Fatal(err)
76+
}
77+
78+
err = os.Chdir(dir)
79+
if err != nil {
80+
t.Fatal(err)
81+
}
82+
83+
err = run(io.Discard, false, []string{romPath, "extract", "firmware"})
84+
if err != nil {
85+
t.Fatalf("expected nil, got %v", err)
86+
}
87+
})
88+
}

cmds/cbfs/testdata/coreboot.rom

256 KB
Binary file not shown.

0 commit comments

Comments
 (0)