github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/dt/node_test.go (about)

     1  // Copyright 2022 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  	"errors"
     9  	"reflect"
    10  	"testing"
    11  )
    12  
    13  func TestRemoveProperty(t *testing.T) {
    14  	for _, tc := range []struct {
    15  		name     string
    16  		node     *Node
    17  		remove   string
    18  		want     *Node
    19  		wantBool bool
    20  	}{
    21  		{
    22  			name: "empty property list",
    23  			node: &Node{
    24  				Name:       "test node",
    25  				Properties: []Property{},
    26  			},
    27  			remove: "linux,initrd-end",
    28  			want: &Node{
    29  				Name:       "test node",
    30  				Properties: []Property{},
    31  			},
    32  			wantBool: false,
    33  		},
    34  		{
    35  			name: "remove non-exist property",
    36  			node: &Node{
    37  				Name: "test node",
    38  				Properties: []Property{
    39  					{Name: "linux,elfcorehdr", Value: []byte{1, 2, 3}},
    40  					{Name: "linux,usable-memory-range", Value: []byte{1, 2, 3}},
    41  				},
    42  			},
    43  			remove: "linux,initrd-end",
    44  			want: &Node{
    45  				Name: "test node",
    46  				Properties: []Property{
    47  					{Name: "linux,elfcorehdr", Value: []byte{1, 2, 3}},
    48  					{Name: "linux,usable-memory-range", Value: []byte{1, 2, 3}},
    49  				},
    50  			},
    51  			wantBool: false,
    52  		},
    53  		{
    54  			name: "remove middle property, success",
    55  			node: &Node{
    56  				Name: "test node",
    57  				Properties: []Property{
    58  					{Name: "linux,elfcorehdr", Value: []byte{1, 2, 3}},
    59  					{Name: "linux,usable-memory-range", Value: []byte{1, 2, 3}},
    60  					{Name: "kaslr-seed", Value: []byte{1, 2, 3}},
    61  					{Name: "rng-seed", Value: []byte{1, 2, 3}},
    62  					{Name: "linux,initrd-start", Value: []byte{1, 2, 3}},
    63  					{Name: "linux,initrd-end", Value: []byte{1, 2, 3}},
    64  				},
    65  			},
    66  			remove: "linux,initrd-start",
    67  			want: &Node{
    68  				Name: "test node",
    69  				Properties: []Property{
    70  					{Name: "linux,elfcorehdr", Value: []byte{1, 2, 3}},
    71  					{Name: "linux,usable-memory-range", Value: []byte{1, 2, 3}},
    72  					{Name: "kaslr-seed", Value: []byte{1, 2, 3}},
    73  					{Name: "rng-seed", Value: []byte{1, 2, 3}},
    74  					{Name: "linux,initrd-end", Value: []byte{1, 2, 3}},
    75  				},
    76  			},
    77  			wantBool: true,
    78  		},
    79  		{
    80  			name: "remove last property, success",
    81  			node: &Node{
    82  				Name: "test node",
    83  				Properties: []Property{
    84  					{Name: "linux,elfcorehdr", Value: []byte{1, 2, 3}},
    85  					{Name: "linux,usable-memory-range", Value: []byte{1, 2, 3}},
    86  					{Name: "kaslr-seed", Value: []byte{1, 2, 3}},
    87  					{Name: "rng-seed", Value: []byte{1, 2, 3}},
    88  					{Name: "linux,initrd-start", Value: []byte{1, 2, 3}},
    89  					{Name: "linux,initrd-end", Value: []byte{1, 2, 3}},
    90  				},
    91  			},
    92  			remove: "linux,initrd-end",
    93  			want: &Node{
    94  				Name: "test node",
    95  				Properties: []Property{
    96  					{Name: "linux,elfcorehdr", Value: []byte{1, 2, 3}},
    97  					{Name: "linux,usable-memory-range", Value: []byte{1, 2, 3}},
    98  					{Name: "kaslr-seed", Value: []byte{1, 2, 3}},
    99  					{Name: "rng-seed", Value: []byte{1, 2, 3}},
   100  					{Name: "linux,initrd-start", Value: []byte{1, 2, 3}},
   101  				},
   102  			},
   103  			wantBool: true,
   104  		},
   105  	} {
   106  		t.Run(tc.name, func(t *testing.T) {
   107  			if got := tc.node.RemoveProperty(tc.remove); got != tc.wantBool {
   108  				t.Errorf("tc.node.RemoveProperty(%s) = %t, want %t", tc.remove, got, tc.wantBool)
   109  			}
   110  			if !reflect.DeepEqual(tc.node, tc.want) {
   111  				t.Errorf("after removing %s got %+v, want %+v", tc.remove, tc.node, tc.want)
   112  			}
   113  		})
   114  	}
   115  }
   116  
   117  func TestUpdateProperty(t *testing.T) {
   118  	node := &Node{
   119  		Name: "test node",
   120  		Properties: []Property{
   121  			{Name: "linux,elfcorehdr", Value: []byte{1, 2, 3}},
   122  			{Name: "linux,usable-memory-range", Value: []byte{1, 2, 3}},
   123  			{Name: "kaslr-seed", Value: []byte{1, 2, 3}},
   124  		},
   125  	}
   126  
   127  	// Try update an existing property.
   128  	if got := node.UpdateProperty("kaslr-seed", []byte{3, 4, 5}); !got {
   129  		t.Errorf("node.UpdateProperty(\"kaslr-seed\", []byte{3, 4,5}) = %t, want true", got)
   130  	}
   131  	want1 := &Node{
   132  		Name: "test node",
   133  		Properties: []Property{
   134  			{Name: "linux,elfcorehdr", Value: []byte{1, 2, 3}},
   135  			{Name: "linux,usable-memory-range", Value: []byte{1, 2, 3}},
   136  			{Name: "kaslr-seed", Value: []byte{3, 4, 5}},
   137  		},
   138  	}
   139  	if !reflect.DeepEqual(node, want1) {
   140  		t.Errorf("after updating %s got %+v, want %+v", "kaslr-seed", node, want1)
   141  	}
   142  
   143  	// Update an non-existent property.
   144  	if got := node.UpdateProperty("rng-seed", []byte{3, 4, 5}); got {
   145  		t.Errorf("node.UpdateProperty(\"rng-seed\", []byte{3, 4,5}) = %t, want false", got)
   146  	}
   147  	want2 := &Node{
   148  		Name: "test node",
   149  		Properties: []Property{
   150  			{Name: "linux,elfcorehdr", Value: []byte{1, 2, 3}},
   151  			{Name: "linux,usable-memory-range", Value: []byte{1, 2, 3}},
   152  			{Name: "kaslr-seed", Value: []byte{3, 4, 5}},
   153  			{Name: "rng-seed", Value: []byte{3, 4, 5}},
   154  		},
   155  	}
   156  	if !reflect.DeepEqual(node, want2) {
   157  		t.Errorf("after updating %s got %+v, want %+v", "kaslr-seed", node, want2)
   158  	}
   159  }
   160  
   161  func TestAsRegion(t *testing.T) {
   162  	for _, tc := range []struct {
   163  		name    string
   164  		p       *Property
   165  		want    *Region
   166  		wantErr error
   167  	}{
   168  		{
   169  			name: "invalid value",
   170  			p: &Property{
   171  				Name:  "linux,initrd-start",
   172  				Value: []byte{},
   173  			},
   174  			want:    &Region{},
   175  			wantErr: errPropertyRegionInvalid,
   176  		},
   177  		{
   178  			name: "read start and size, success",
   179  			p: &Property{
   180  				Name:  "linux,initrd-start",
   181  				Value: []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xf},
   182  			},
   183  			want: &Region{
   184  				Start: 0x0001020304050607,
   185  				Size:  0x08090a0b0c0d0e0f,
   186  			},
   187  			wantErr: nil,
   188  		},
   189  		// Given value is of type []byte, and we check length equal to 16
   190  		// at the beginning, it is nearly impossible for binary.Read for
   191  		// 2 uint64 from a fixed size bytes slice of size 16 to go wrong.
   192  	} {
   193  		t.Run(tc.name, func(t *testing.T) {
   194  			got, err := tc.p.AsRegion()
   195  			if !errors.Is(err, tc.wantErr) {
   196  				t.Errorf("tc.p.AsRegion() returned error %v, want error %v", err, tc.wantErr)
   197  			}
   198  			if err == nil && tc.wantErr == nil {
   199  				if got.Start != tc.want.Start || got.Size != tc.want.Size {
   200  					t.Errorf("got region %v, want region %v", got, tc.want)
   201  				}
   202  			}
   203  		})
   204  	}
   205  }