github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/dt/fdt_test.go (about) 1 // Copyright 2019 the u-root 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 dt 6 7 import ( 8 "bytes" 9 "encoding/json" 10 "errors" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "reflect" 15 "strings" 16 "testing" 17 ) 18 19 func TestLoadFDT(t *testing.T) { 20 jsonData, err := os.ReadFile("testdata/fdt.json") 21 if err != nil { 22 t.Fatal(err) 23 } 24 testData := &FDT{} 25 if err := json.Unmarshal(jsonData, testData); err != nil { 26 t.Fatal(err) 27 } 28 29 // 1. Load by path given and succeed. 30 dtb, err := os.Open("testdata/fdt.dtb") 31 if err != nil { 32 t.Fatal(err) 33 } 34 fdt, err := LoadFDT(dtb) 35 if err != nil { 36 t.Fatal(err) 37 } 38 if !reflect.DeepEqual(fdt, testData) { 39 got, err := json.MarshalIndent(fdt, "", " ") 40 if err != nil { 41 t.Fatal(err) 42 } 43 t.Errorf(`Read("fdt.dtb") = %s \n, want %s`, got, jsonData) 44 } 45 46 dir := t.TempDir() 47 nonexistDTB := filepath.Join(dir, "xxx") 48 // 2. Fallback to read from sys fs, and sys fs reading also failed. 49 if _, err = LoadFDT(nil, nonexistDTB); !errors.Is(err, ErrNoValidReaders) { 50 t.Errorf("LoadFDT(%s) got %v, want %v", nonexistDTB, err, ErrNoValidReaders) 51 } 52 53 // 3. Fallback to read from sys fs, and succeed. 54 fdt, err = LoadFDT(nil, "testdata/fdt.dtb") 55 if err != nil { 56 t.Fatal(err) 57 } 58 if !reflect.DeepEqual(fdt, testData) { 59 got, err := json.MarshalIndent(fdt, "", " ") 60 if err != nil { 61 t.Fatal(err) 62 } 63 t.Errorf(`Read("fdt.dtb") = %s \n, want %s`, got, jsonData) 64 } 65 } 66 67 func TestRead(t *testing.T) { 68 f, err := os.Open("testdata/fdt.dtb") 69 if err != nil { 70 t.Fatal(err) 71 } 72 defer f.Close() 73 74 jsonData, err := os.ReadFile("testdata/fdt.json") 75 if err != nil { 76 t.Fatal(err) 77 } 78 testData := &FDT{} 79 if err := json.Unmarshal(jsonData, testData); err != nil { 80 t.Fatal(err) 81 } 82 83 fdt, err := ReadFDT(f) 84 if err != nil { 85 t.Fatal(err) 86 } 87 88 if !reflect.DeepEqual(fdt, testData) { 89 got, err := json.MarshalIndent(fdt, "", " ") 90 if err != nil { 91 t.Fatal(err) 92 } 93 t.Errorf(`Read("fdt.dtb") = %s`, got) 94 t.Errorf(`want %s`, jsonData) 95 } 96 } 97 98 // TestParity tests that the fdt Read+Write operations are compatible with your 99 // system's fdtdump command. 100 func TestParity(t *testing.T) { 101 // TODO: I'm convinced my system's fdtdump command is broken. 102 t.Skip() 103 104 // Read and write the fdt. 105 fdt, err := New(WithFileName("testdata/fdt.dtb")) 106 if err != nil { 107 t.Fatal(err) 108 } 109 dir := t.TempDir() 110 dtb := filepath.Join(dir, "fdt2.dtb") 111 f, err := os.Create(dtb) 112 if err != nil { 113 t.Fatal(err) 114 } 115 _, err = fdt.Write(f) 116 f.Close() 117 if err != nil { 118 t.Fatal(err) 119 } 120 121 // Run your system's fdtdump command. 122 dts := filepath.Join(dir, "fdt2.dts") 123 f, err = os.Create(dts) 124 if err != nil { 125 t.Fatal(err) 126 } 127 cmd := exec.Command("fdtdump", dtb) 128 cmd.Stdout = f 129 err = cmd.Run() 130 f.Close() 131 if err != nil { 132 t.Fatal(err) // TODO: skip if system does not have fdtdump 133 } 134 135 // This used to run diff, has to be done better. It's not even working now so. 136 if false { 137 cmd = exec.Command("diff", "testdata/fdt.dts", "testdata/fdt2.dts") 138 cmd.Stdout = os.Stdout 139 cmd.Stderr = os.Stderr 140 cmd.Run() 141 } 142 } 143 144 func TestFindNode(t *testing.T) { 145 f, err := os.Open("testdata/fdt.dtb") 146 if err != nil { 147 t.Fatal(err) 148 } 149 150 fdt, err := ReadFDT(f) 151 f.Close() 152 if err != nil { 153 t.Fatal(err) 154 } 155 156 n, ok := fdt.NodeByName("psci") 157 if !ok { 158 t.Fatalf("Finding psci in %s: got false, want true", fdt) 159 } 160 t.Logf("Got the node: %s", n) 161 } 162 163 func TestFindAllNode(t *testing.T) { 164 f, err := os.Open("testdata/fdt.dtb") 165 if err != nil { 166 t.Fatal(err) 167 } 168 169 fdt, err := ReadFDT(f) 170 f.Close() 171 if err != nil { 172 t.Fatal(err) 173 } 174 const expectedVirtNodes = 32 175 nodes, err := fdt.Root().FindAll(func(n *Node) bool { 176 return strings.HasPrefix(n.Name, "virtio_mmio") 177 }) 178 if err != nil { 179 t.Fatalf("Finding all virtio_mmio in %s: got err %v, want nil", fdt, err) 180 } 181 182 if len(nodes) != expectedVirtNodes { 183 t.Fatalf("Finding all virtio_mmio in %s: got returned %d nodes, want %d", fdt, len(nodes), expectedVirtNodes) 184 } 185 } 186 187 func TestFindProperty(t *testing.T) { 188 f, err := os.Open("testdata/fdt.dtb") 189 if err != nil { 190 t.Fatal(err) 191 } 192 fdt, err := ReadFDT(f) 193 f.Close() 194 if err != nil { 195 t.Fatal(err) 196 } 197 198 n, ok := fdt.NodeByName("psci") 199 if !ok { 200 t.Fatalf("Finding psci in %s: got false, want true", fdt) 201 } 202 t.Logf("Got the node: %s", n) 203 l := "migrate" 204 p, ok := n.LookProperty(l) 205 if !ok { 206 t.Fatalf("Find property %q in %s: got false, want true", l, n) 207 } 208 v := []byte{0x84, 0, 0, 0x5} 209 if !bytes.Equal(p.Value, v) { 210 t.Fatalf("Checking value of %s: got %q, want %q", p.Name, p.Value, v) 211 } 212 l = "bogosity" 213 p, ok = n.LookProperty(l) 214 if ok { 215 t.Fatalf("Find property %q in %s: got true, want false", l, n) 216 } 217 } 218 219 func TestWalk(t *testing.T) { 220 f, err := os.Open("testdata/fdt.dtb") 221 if err != nil { 222 t.Fatal(err) 223 } 224 fdt, err := ReadFDT(f) 225 f.Close() 226 if err != nil { 227 t.Fatal(err) 228 } 229 230 b, err := fdt.Root().Walk("psci").Property("migrate").AsBytes() 231 if err != nil { 232 t.Fatalf("Walk to psci/migrate: got %v, want nil", err) 233 } 234 v := []byte{0x84, 0, 0, 0x5} 235 if !bytes.Equal(b, v) { 236 t.Fatalf("Checking value of psci/migrate: got %q, want %q", b, v) 237 } 238 }