github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/mount/scuzz/sg_linux_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  // +build amd64
     6  
     7  package scuzz
     8  
     9  import (
    10  	"testing"
    11  	"unsafe"
    12  )
    13  
    14  // check checks the packetHeader, cdb, and sb.
    15  // The packetHeader check is a bit complex as it contains
    16  // pointers. The pointer values for the original executiion of hdparm
    17  // will not match the values we get for this test. We therefore skip any uintptrs.
    18  func check(t *testing.T, got *packet, want *packet) {
    19  	if got.interfaceID != want.interfaceID {
    20  		t.Errorf("interfaceID: got %v, want %v", got.interfaceID, want.interfaceID)
    21  	}
    22  	if got.direction != want.direction {
    23  		t.Errorf("direction: got %v, want %v", got.direction, want.direction)
    24  	}
    25  	if got.cmdLen != want.cmdLen {
    26  		t.Errorf("cmdLen: got %v, want %v", got.cmdLen, want.cmdLen)
    27  	}
    28  	if got.maxStatusBlockLen != want.maxStatusBlockLen {
    29  		t.Errorf("maxStatusBlockLen: got %v, want %v", got.maxStatusBlockLen, want.maxStatusBlockLen)
    30  	}
    31  	if got.iovCount != want.iovCount {
    32  		t.Errorf("iovCount: got %v, want %v", got.iovCount, want.iovCount)
    33  	}
    34  	if got.dataLen != want.dataLen {
    35  		t.Errorf("dataLen: got %v, want %v", got.dataLen, want.dataLen)
    36  	}
    37  	if got.timeout != want.timeout {
    38  		t.Errorf("timeout: got %v, want %v", got.timeout, want.timeout)
    39  	}
    40  	if got.flags != want.flags {
    41  		t.Errorf("flags: got %v, want %v", got.flags, want.flags)
    42  	}
    43  	if got.packID != want.packID {
    44  		t.Errorf("packID: got %v, want %v", got.packID, want.packID)
    45  	}
    46  	if got.status != want.status {
    47  		t.Errorf("status: got %v, want %v", got.status, want.status)
    48  	}
    49  	if got.maskedStatus != want.maskedStatus {
    50  		t.Errorf("maskedStatus: got %v, want %v", got.maskedStatus, want.maskedStatus)
    51  	}
    52  	if got.msgStatus != want.msgStatus {
    53  		t.Errorf("msgStatus: got %v, want %v", got.msgStatus, want.msgStatus)
    54  	}
    55  	if got.sbLen != want.sbLen {
    56  		t.Errorf("sbLen: got %v, want %v", got.sbLen, want.sbLen)
    57  	}
    58  	if got.hostStatus != want.hostStatus {
    59  		t.Errorf("hostStatus: got %v, want %v", got.hostStatus, want.hostStatus)
    60  	}
    61  	if got.driverStatus != want.driverStatus {
    62  		t.Errorf("driverStatus: got %v, want %v", got.driverStatus, want.driverStatus)
    63  	}
    64  	if got.resID != want.resID {
    65  		t.Errorf("resID: got %v, want %v", got.resID, want.resID)
    66  	}
    67  	if got.duration != want.duration {
    68  		t.Errorf("duration: got %v, want %v", got.duration, want.duration)
    69  	}
    70  	if got.info != want.info {
    71  		t.Errorf("info: got %v, want %v", got.info, want.info)
    72  	}
    73  
    74  	for i := range got.command {
    75  		if got.command[i] != want.command[i] {
    76  			t.Errorf("command[%d]: got %#02x, want %#02x", i, got.command[i], want.command[i])
    77  		}
    78  	}
    79  
    80  	for i := range got.block {
    81  		if got.block[i] != want.block[i] {
    82  			t.Errorf("cblock[%d]: got %#02x, want %#02x", i, got.block[i], want.block[i])
    83  		}
    84  	}
    85  }
    86  
    87  // TestSizes makes sure that everything marshals to the right size.
    88  // The sizes are magic numbers from Linux. Thanks to the compatibility
    89  // guarantee, we know they don't change.
    90  func TestSizes(t *testing.T) {
    91  	hs := unsafe.Sizeof(packetHeader{})
    92  	if hs != hdrSize {
    93  		t.Errorf("PacketHeader.Marshal(): got %d, want %d", hs, hdrSize)
    94  	}
    95  	l := len(&commandDataBlock{})
    96  	if l != cdbSize {
    97  		t.Errorf("commandDataBlock.Marshal(): got %d, want %d", l, cdbSize)
    98  	}
    99  	l = len(&statusBlock{})
   100  	if l != maxStatusBlockLen {
   101  		t.Errorf("sbsize: got %d, want %d", l, maxStatusBlockLen)
   102  	}
   103  }
   104  
   105  func TestUnlock(t *testing.T) {
   106  	Debug = t.Logf
   107  	// This command: ./hdparm --security-unlock 12345678901234567890123456789012 /dev/null
   108  	// yields this header and data to ioctl(fd, SECURITY_UNLOCK, ...)
   109  	// The 'want' data is derived from a modified version of hdparm (github.com/rminnich/hdparmm)
   110  	// which prints the ioctl parameters as initialized go structs.
   111  	var (
   112  		want = &packet{
   113  			packetHeader: packetHeader{
   114  				interfaceID:       'S',
   115  				direction:         -2,
   116  				cmdLen:            16,
   117  				maxStatusBlockLen: 32,
   118  				iovCount:          0,
   119  				dataLen:           512,
   120  				data:              0,
   121  				cdb:               0,
   122  				sb:                0,
   123  				timeout:           15000,
   124  				flags:             0,
   125  				packID:            0,
   126  				usrPtr:            0,
   127  				status:            0,
   128  				maskedStatus:      0,
   129  				msgStatus:         0,
   130  				sbLen:             0,
   131  				hostStatus:        0,
   132  				driverStatus:      0,
   133  				resID:             0,
   134  				duration:          0,
   135  				info:              0,
   136  			},
   137  			command: commandDataBlock{0x85, 0xb, 0x6, 00, 00, 00, 0x1, 00, 00, 00, 00, 00, 00, 0x40, 0xf2, 00},
   138  			block: dataBlock{
   139  				0x00, 0x01, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
   140  				0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
   141  				0x31, 0x32,
   142  			},
   143  		}
   144  		//sb statusBlock
   145  	)
   146  	d := &SGDisk{dev: 0x40, Timeout: DefaultTimeout}
   147  	p := d.unlockPacket("12345678901234567890123456789012", true)
   148  	check(t, p, want)
   149  }
   150  
   151  func TestIdentify(t *testing.T) {
   152  	Debug = t.Logf
   153  	// The 'want' data is derived from a modified version of hdparm (github.com/rminnich/hdparmm)
   154  	// which prints the ioctl parameters as initialized go structs.
   155  	var (
   156  		want = &packet{
   157  			packetHeader: packetHeader{
   158  				interfaceID:       'S',
   159  				direction:         -3,
   160  				cmdLen:            16,
   161  				maxStatusBlockLen: 32,
   162  				iovCount:          0,
   163  				dataLen:           512,
   164  				data:              0,
   165  				cdb:               0,
   166  				sb:                0,
   167  				timeout:           15000,
   168  				flags:             0,
   169  				packID:            0,
   170  				usrPtr:            0,
   171  				status:            0,
   172  				maskedStatus:      0,
   173  				msgStatus:         0,
   174  				sbLen:             0,
   175  				hostStatus:        0,
   176  				driverStatus:      0,
   177  				resID:             0,
   178  				duration:          0,
   179  				info:              0,
   180  			},
   181  			command: commandDataBlock{0x85, 0x08, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xec, 0x00},
   182  		}
   183  		// TODO: check status block. Requires a qemu device that supports these operations.
   184  		//sb = statusBlock{0x70, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
   185  	)
   186  	p := (&SGDisk{dev: 0x40, Timeout: DefaultTimeout}).identifyPacket()
   187  	check(t, p, want)
   188  }