github.com/shaardie/u-root@v4.0.1-0.20190127173353-f24a1c26aa2e+incompatible/pkg/kexec/memory_linux_test.go (about)

     1  // Copyright 2018-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 kexec
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"os"
    12  	"path"
    13  	"reflect"
    14  	"testing"
    15  )
    16  
    17  func TestParseMemoryMap(t *testing.T) {
    18  	var mem Memory
    19  	root, err := ioutil.TempDir("", "memmap")
    20  	if err != nil {
    21  		t.Fatalf("Cannot create test dir: %v", err)
    22  	}
    23  	defer os.RemoveAll(root)
    24  
    25  	old := memoryMapRoot
    26  	memoryMapRoot = root
    27  	defer func() { memoryMapRoot = old }()
    28  
    29  	create := func(dir string, start, end uintptr, typ RangeType) error {
    30  		p := path.Join(root, dir)
    31  		if err := os.Mkdir(p, 0755); err != nil {
    32  			return err
    33  		}
    34  		if err := ioutil.WriteFile(path.Join(p, "start"), []byte(fmt.Sprintf("%#x\n", start)), 0655); err != nil {
    35  			return err
    36  		}
    37  		if err := ioutil.WriteFile(path.Join(p, "end"), []byte(fmt.Sprintf("%#x\n", end)), 0655); err != nil {
    38  			return err
    39  		}
    40  		return ioutil.WriteFile(path.Join(p, "type"), append([]byte(typ), '\n'), 0655)
    41  	}
    42  
    43  	if err := create("0", 0, 50, RangeRAM); err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	if err := create("1", 100, 150, RangeNVACPI); err != nil {
    47  		t.Fatal(err)
    48  	}
    49  	if err := create("2", 200, 250, RangeACPI); err != nil {
    50  		t.Fatal(err)
    51  	}
    52  	if err := create("3", 300, 350, RangeNVS); err != nil {
    53  		t.Fatal(err)
    54  	}
    55  
    56  	want := []TypedAddressRange{
    57  		{Range: Range{Start: 0, Size: 50}, Type: RangeRAM},
    58  		{Range: Range{Start: 100, Size: 50}, Type: RangeNVACPI},
    59  		{Range: Range{Start: 200, Size: 50}, Type: RangeACPI},
    60  		{Range: Range{Start: 300, Size: 50}, Type: RangeNVS},
    61  	}
    62  
    63  	if err := mem.ParseMemoryMap(); err != nil {
    64  		t.Fatalf("ParseMemoryMap() error: %v", err)
    65  	}
    66  	if !reflect.DeepEqual(mem.Phys, want) {
    67  		t.Errorf("ParseMemoryMap() got %v, want %v", mem.Phys, want)
    68  	}
    69  }
    70  
    71  func TestAvailableRAM(t *testing.T) {
    72  	old := pageMask
    73  	defer func() {
    74  		pageMask = old
    75  	}()
    76  	// suppose we have 4K pages.
    77  	pageMask = 4095
    78  
    79  	var mem Memory
    80  	mem.Phys = []TypedAddressRange{
    81  		TypedAddressRange{Range: Range{Start: 0, Size: 8192}, Type: RangeRAM},
    82  		TypedAddressRange{Range: Range{Start: 8192, Size: 8000}, Type: RangeRAM},
    83  		TypedAddressRange{Range: Range{Start: 20480, Size: 1000}, Type: RangeRAM},
    84  		TypedAddressRange{Range: Range{Start: 24576, Size: 1000}, Type: RangeRAM},
    85  		TypedAddressRange{Range: Range{Start: 28672, Size: 1000}, Type: RangeRAM},
    86  	}
    87  
    88  	mem.Segments = []Segment{
    89  		Segment{Phys: Range{Start: 40, Size: 50}},
    90  		Segment{Phys: Range{Start: 8000, Size: 200}},
    91  		Segment{Phys: Range{Start: 18000, Size: 1000}},
    92  		Segment{Phys: Range{Start: 24600, Size: 1000}},
    93  		Segment{Phys: Range{Start: 28000, Size: 10000}},
    94  	}
    95  
    96  	want := []TypedAddressRange{
    97  		TypedAddressRange{Range: Range{Start: 0, Size: 40}, Type: RangeRAM},
    98  		TypedAddressRange{Range: Range{Start: 4096, Size: 8000 - 4096}, Type: RangeRAM},
    99  		TypedAddressRange{Range: Range{Start: 12288, Size: 8192 + 8000 - 12288}, Type: RangeRAM},
   100  		TypedAddressRange{Range: Range{Start: 20480, Size: 1000}, Type: RangeRAM},
   101  		TypedAddressRange{Range: Range{Start: 24576, Size: 24}, Type: RangeRAM},
   102  	}
   103  
   104  	got := mem.availableRAM()
   105  	if !reflect.DeepEqual(got, want) {
   106  		t.Errorf("availableRAM() got %+v, want %+v", got, want)
   107  	}
   108  }
   109  
   110  func TestAlignPhys(t *testing.T) {
   111  	for _, test := range []struct {
   112  		name      string
   113  		seg, want Segment
   114  	}{
   115  		{
   116  			name: "aligned",
   117  			seg: Segment{
   118  				Buf:  Range{Start: 0x1000, Size: 0x1000},
   119  				Phys: Range{Start: 0x2000, Size: 0x1000},
   120  			},
   121  			want: Segment{
   122  				Buf:  Range{Start: 0x1000, Size: 0x1000},
   123  				Phys: Range{Start: 0x2000, Size: 0x1000},
   124  			},
   125  		},
   126  		{
   127  			name: "unaligned",
   128  			seg: Segment{
   129  				Buf:  Range{Start: 0x1011, Size: 0x1022},
   130  				Phys: Range{Start: 0x2011, Size: 0x1022},
   131  			},
   132  			want: Segment{
   133  				Buf:  Range{Start: 0x1000, Size: 0x1033},
   134  				Phys: Range{Start: 0x2000, Size: 0x2000},
   135  			},
   136  		},
   137  		{
   138  			name: "empty_buf",
   139  			seg: Segment{
   140  				Buf:  Range{Start: 0x1011, Size: 0},
   141  				Phys: Range{Start: 0x2011, Size: 0},
   142  			},
   143  			want: Segment{
   144  				Buf:  Range{Start: 0x1000, Size: 0},
   145  				Phys: Range{Start: 0x2000, Size: 0x1000},
   146  			},
   147  		},
   148  	} {
   149  		t.Run(test.name, func(t *testing.T) {
   150  			got := AlignPhys(test.seg)
   151  			if got != test.want {
   152  				t.Errorf("AlignPhys() got %v, want %v", got, test.want)
   153  			}
   154  		})
   155  	}
   156  }
   157  
   158  func TestTryMerge(t *testing.T) {
   159  	for _, test := range []struct {
   160  		name   string
   161  		phys   Range
   162  		merged bool
   163  		want   Range
   164  	}{
   165  		{
   166  			name:   "disjunct",
   167  			phys:   Range{Start: 100, Size: 150},
   168  			merged: false,
   169  		},
   170  		{
   171  			name:   "superset",
   172  			phys:   Range{Start: 0, Size: 80},
   173  			merged: true,
   174  			want:   Range{Start: 0, Size: 100},
   175  		},
   176  		{
   177  			name:   "superset",
   178  			phys:   Range{Start: 10, Size: 80},
   179  			merged: true,
   180  			want:   Range{Start: 0, Size: 100},
   181  		},
   182  		{
   183  			name:   "superset",
   184  			phys:   Range{Start: 10, Size: 90},
   185  			merged: true,
   186  			want:   Range{Start: 0, Size: 100},
   187  		},
   188  		{
   189  			name:   "superset",
   190  			phys:   Range{Start: 0, Size: 100},
   191  			merged: true,
   192  			want:   Range{Start: 0, Size: 100},
   193  		},
   194  		{
   195  			name:   "overlap",
   196  			phys:   Range{Start: 0, Size: 150},
   197  			merged: true,
   198  			want:   Range{Start: 0, Size: 150},
   199  		},
   200  		{
   201  			name:   "overlap",
   202  			phys:   Range{Start: 50, Size: 100},
   203  			merged: true,
   204  			want:   Range{Start: 0, Size: 150},
   205  		},
   206  		{
   207  			name:   "overlap",
   208  			phys:   Range{Start: 99, Size: 51},
   209  			merged: true,
   210  			want:   Range{Start: 0, Size: 150},
   211  		},
   212  	} {
   213  		t.Run(test.name, func(t *testing.T) {
   214  			a := NewSegment([]byte("aaaa"), Range{Start: 0, Size: 100})
   215  			b := NewSegment([]byte("bbbb"), test.phys)
   216  
   217  			merged := a.tryMerge(b)
   218  			if merged != test.merged {
   219  				t.Fatalf("tryMerge() got %v, want %v", merged, test.merged)
   220  			}
   221  			if !merged {
   222  				return
   223  			}
   224  			if a.Phys != test.want {
   225  				t.Fatalf("Wrong merge result: got %+v, want %+v", a.Phys, test.want)
   226  			}
   227  
   228  			got := a.Buf.toSlice()
   229  			want := []byte("aaaabbbb")
   230  			if !bytes.Equal(got, want) {
   231  				t.Errorf("Wrong buf: got %s, want %s", got, want)
   232  			}
   233  		})
   234  	}
   235  }
   236  
   237  func TestDedup(t *testing.T) {
   238  	s := []Segment{
   239  		NewSegment([]byte("test"), Range{Start: 0, Size: 100}),
   240  		NewSegment([]byte("test"), Range{Start: 100, Size: 100}),
   241  		NewSegment([]byte("test"), Range{Start: 200, Size: 100}),
   242  		NewSegment([]byte("test"), Range{Start: 250, Size: 50}),
   243  		NewSegment([]byte("test"), Range{Start: 300, Size: 100}),
   244  		NewSegment([]byte("test"), Range{Start: 350, Size: 100}),
   245  	}
   246  	want := []Range{
   247  		Range{Start: 0, Size: 100},
   248  		Range{Start: 100, Size: 100},
   249  		Range{Start: 200, Size: 100},
   250  		Range{Start: 300, Size: 150},
   251  	}
   252  
   253  	got := Dedup(s)
   254  	for i := range got {
   255  		if got[i].Phys != want[i] {
   256  			t.Errorf("Dedup() got %v, want %v", got[i].Phys, want[i])
   257  		}
   258  	}
   259  
   260  }