github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/osutil/udev/netlink/uevent_test.go (about)

     1  package netlink
     2  
     3  import (
     4  	"runtime"
     5  	"testing"
     6  )
     7  
     8  type testingWrapper struct {
     9  	*testing.T
    10  }
    11  
    12  func (t *testingWrapper) FatalfIf(cond bool, msg string, args ...interface{}) {
    13  	if cond {
    14  		if len(args) == 0 {
    15  			t.Fatal(msg)
    16  		}
    17  		t.Fatalf(msg, args...)
    18  	}
    19  }
    20  
    21  // TestParseUEvent parse uevent bytes msg but fatal if needed
    22  func TestParseUEvent(testing *testing.T) {
    23  	t := testingWrapper{testing}
    24  
    25  	samples := []UEvent{
    26  		{
    27  			Action: ADD,
    28  			KObj:   "/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.2/0003:04F2:0976.0008/hidraw/hidraw4",
    29  			Env: map[string]string{
    30  				"ACTION":    "add",
    31  				"DEVPATH":   "/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.2/0003:04F2:0976.0008/hidraw/hidraw4",
    32  				"SUBSYSTEM": "hidraw",
    33  				"MAJOR":     "247",
    34  				"MINOR":     "4",
    35  				"DEVNAME":   "hidraw4",
    36  				"SEQNUM":    "2569",
    37  			},
    38  		},
    39  		{
    40  			Action: REMOVE,
    41  			KObj:   "mykobj",
    42  			Env: map[string]string{
    43  				"bla": "bla",
    44  				"abl": "abl",
    45  				"lab": "lab",
    46  			},
    47  		},
    48  	}
    49  	for _, s := range samples {
    50  		raw := s.Bytes()
    51  		uevent, err := ParseUEvent(raw)
    52  		t.FatalfIf(err != nil, "Unable to parse uevent (got: %s)", s.String())
    53  		t.FatalfIf(uevent == nil, "Uevent can't be nil (with: %s)", s.String())
    54  
    55  		ok, err := uevent.Equal(s)
    56  		t.FatalfIf(!ok || err != nil, "Uevent should be equal: bijectivity fail")
    57  	}
    58  
    59  	raw := samples[0].Bytes()
    60  	raw[3] = 0x00 // remove @ to fake rawdata
    61  
    62  	uevent, err := ParseUEvent(raw)
    63  	t.FatalfIf(err == nil && uevent != nil, "Event parsed successfully but it should be invalid, err: %s", err.Error())
    64  
    65  }
    66  
    67  func TestParseUdevEvent(testing *testing.T) {
    68  	if runtime.GOARCH == "s390x" || runtime.GOARCH == "ppc" {
    69  		testing.Skip("This test assumes little-endian architecture")
    70  	}
    71  
    72  	t := testingWrapper{testing}
    73  
    74  	// Input samples obtained by running the main testing binary in monitor mode
    75  	// and having fmt.Printf("%q\n", raw) in the ParseUEvent method.
    76  	samples := []struct {
    77  		Input    []byte
    78  		Expected UEvent
    79  	}{{
    80  		Input: []byte("libudev\x00\xfe\xed\xca\xfe(\x00\x00\x00(\x00\x00\x00\xd5\x03\x00\x00\x8a\xfa\x90\xc8\x00\x00\x00\x00\x02\x00\x04\x00\x10\x80\x00\x00" +
    81  			"ACTION=remove\x00DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/ttyUSB0/tty/ttyUSB0\x00SUBSYSTEM=tty\x00" +
    82  			"DEVNAME=/dev/ttyUSB0\x00SEQNUM=4344\x00MAJOR=188\x00MINOR=0\x00USEC_INITIALIZED=75223543693\x00ID_BUS=usb\x00" +
    83  			"ID_VENDOR_ID=0403\x00ID_MODEL_ID=6001\x00ID_PCI_CLASS_FROM_DATABASE=Serial bus controller\x00" +
    84  			"ID_PCI_SUBCLASS_FROM_DATABASE=USB controller\x00ID_PCI_INTERFACE_FROM_DATABASE=XHCI\x00" +
    85  			"ID_VENDOR_FROM_DATABASE=Future Technology Devices International, Ltd\x00ID_MODEL_FROM_DATABASE=FT232 Serial (UART) IC\x00" +
    86  			"ID_VENDOR=FTDI\x00ID_VENDOR_ENC=FTDI\x00ID_MODEL=FT232R_USB_UART\x00ID_MODEL_ENC=FT232R\\x20USB\\x20UART\x00" +
    87  			"ID_REVISION=0600\x00ID_SERIAL=FTDI_FT232R_USB_UART_AH06W0EQ\x00ID_SERIAL_SHORT=AH06W0EQ\x00ID_TYPE=generic\x00" +
    88  			"ID_USB_INTERFACES=:ffffff:\x00ID_USB_INTERFACE_NUM=00\x00ID_USB_DRIVER=ftdi_sio\x00" +
    89  			"ID_PATH=pci-0000:00:14.0-usb-0:2:1.0\x00ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_1_0\x00ID_MM_CANDIDATE=1\x00" +
    90  			"DEVLINKS=/dev/serial/by-path/pci-0000:00:14.0-usb-0:2:1.0-port0 /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AH06W0EQ-if00-port0\x00TAGS=:systemd:\x00"),
    91  		Expected: UEvent{
    92  			Action: REMOVE,
    93  			KObj:   "/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/ttyUSB0/tty/ttyUSB0",
    94  			Env: map[string]string{
    95  				"MINOR": "0",
    96  				"ID_PCI_CLASS_FROM_DATABASE":     "Serial bus controller",
    97  				"ID_PCI_SUBCLASS_FROM_DATABASE":  "USB controller",
    98  				"ID_VENDOR_FROM_DATABASE":        "Future Technology Devices International, Ltd",
    99  				"ID_MODEL_ENC":                   "FT232R\\x20USB\\x20UART",
   100  				"ID_USB_INTERFACES":              ":ffffff:",
   101  				"ID_PATH":                        "pci-0000:00:14.0-usb-0:2:1.0",
   102  				"ID_MODEL":                       "FT232R_USB_UART",
   103  				"ID_TYPE":                        "generic",
   104  				"DEVLINKS":                       "/dev/serial/by-path/pci-0000:00:14.0-usb-0:2:1.0-port0 /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AH06W0EQ-if00-port0",
   105  				"ID_MODEL_ID":                    "6001",
   106  				"ID_USB_INTERFACE_NUM":           "00",
   107  				"ID_PATH_TAG":                    "pci-0000_00_14_0-usb-0_2_1_0",
   108  				"TAGS":                           ":systemd:",
   109  				"ACTION":                         "remove",
   110  				"DEVNAME":                        "/dev/ttyUSB0",
   111  				"ID_REVISION":                    "0600",
   112  				"ID_VENDOR_ENC":                  "FTDI",
   113  				"ID_USB_DRIVER":                  "ftdi_sio",
   114  				"ID_MM_CANDIDATE":                "1",
   115  				"SEQNUM":                         "4344",
   116  				"ID_VENDOR":                      "FTDI",
   117  				"SUBSYSTEM":                      "tty",
   118  				"MAJOR":                          "188",
   119  				"ID_BUS":                         "usb",
   120  				"ID_VENDOR_ID":                   "0403",
   121  				"ID_MODEL_FROM_DATABASE":         "FT232 Serial (UART) IC",
   122  				"ID_SERIAL":                      "FTDI_FT232R_USB_UART_AH06W0EQ",
   123  				"DEVPATH":                        "/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/ttyUSB0/tty/ttyUSB0",
   124  				"USEC_INITIALIZED":               "75223543693",
   125  				"ID_PCI_INTERFACE_FROM_DATABASE": "XHCI",
   126  				"ID_SERIAL_SHORT":                "AH06W0EQ",
   127  			}}}, {
   128  		Input: []byte("libudev\x00\xfe\xed\xca\xfe(\x00\x00\x00(\x00\x00\x00\xf2\x02\x00\x00\x05w\xc5\xe5'\xf8\xf5\f\x00\x00\x00\x00\x00\x00\x00\x00" +
   129  			"ACTION=add\x00DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-2\x00SUBSYSTEM=usb\x00DEVNAME=/dev/bus/usb/001/033\x00DEVTYPE=usb_device\x00" +
   130  			"PRODUCT=10c4/ea60/100\x00TYPE=0/0/0\x00BUSNUM=001\x00DEVNUM=033\x00SEQNUM=4410\x00MAJOR=189\x00MINOR=32\x00USEC_INITIALIZED=77155422759\x00" +
   131  			"ID_VENDOR=Silicon_Labs\x00ID_VENDOR_ENC=Silicon\\x20Labs\x00ID_VENDOR_ID=10c4\x00ID_MODEL=CP2102_USB_to_UART_Bridge_Controller\x00" +
   132  			"ID_MODEL_ENC=CP2102\\x20USB\\x20to\\x20UART\\x20Bridge\\x20Controller\x00ID_MODEL_ID=ea60\x00ID_REVISION=0100\x00" +
   133  			"ID_SERIAL=Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001\x00ID_SERIAL_SHORT=0001\x00ID_BUS=usb\x00ID_USB_INTERFACES=:ff0000:\x00" +
   134  			"ID_VENDOR_FROM_DATABASE=Cygnal Integrated Products, Inc.\x00ID_MODEL_FROM_DATABASE=CP2102/CP2109 UART Bridge Controller [CP210x family]\x00" +
   135  			"DRIVER=usb\x00ID_MM_DEVICE_MANUAL_SCAN_ONLY=1\x00"),
   136  		Expected: UEvent{
   137  			Action: ADD,
   138  			KObj:   "/devices/pci0000:00/0000:00:14.0/usb1/1-2",
   139  			Env: map[string]string{
   140  				"DEVTYPE":                "usb_device",
   141  				"SEQNUM":                 "4410",
   142  				"DRIVER":                 "usb",
   143  				"DEVPATH":                "/devices/pci0000:00/0000:00:14.0/usb1/1-2",
   144  				"SUBSYSTEM":              "usb",
   145  				"BUSNUM":                 "001",
   146  				"ID_USB_INTERFACES":      ":ff0000:",
   147  				"USEC_INITIALIZED":       "77155422759",
   148  				"ID_VENDOR_ENC":          "Silicon\\x20Labs",
   149  				"ID_VENDOR_ID":           "10c4",
   150  				"ID_SERIAL":              "Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001",
   151  				"ACTION":                 "add",
   152  				"DEVNAME":                "/dev/bus/usb/001/033",
   153  				"MAJOR":                  "189",
   154  				"ID_MODEL_FROM_DATABASE": "CP2102/CP2109 UART Bridge Controller [CP210x family]",
   155  				"TYPE":                          "0/0/0",
   156  				"ID_REVISION":                   "0100",
   157  				"ID_BUS":                        "usb",
   158  				"PRODUCT":                       "10c4/ea60/100",
   159  				"DEVNUM":                        "033",
   160  				"MINOR":                         "32",
   161  				"ID_MODEL_ENC":                  "CP2102\\x20USB\\x20to\\x20UART\\x20Bridge\\x20Controller",
   162  				"ID_MM_DEVICE_MANUAL_SCAN_ONLY": "1",
   163  				"ID_VENDOR":                     "Silicon_Labs",
   164  				"ID_MODEL":                      "CP2102_USB_to_UART_Bridge_Controller",
   165  				"ID_MODEL_ID":                   "ea60",
   166  				"ID_SERIAL_SHORT":               "0001",
   167  				"ID_VENDOR_FROM_DATABASE":       "Cygnal Integrated Products, Inc.",
   168  			},
   169  		},
   170  	}}
   171  
   172  	for _, s := range samples {
   173  		uevent, err := ParseUEvent(s.Input)
   174  		t.FatalfIf(err != nil, "Unable to parse uevent: %s", err)
   175  		ok, err := uevent.Equal(s.Expected)
   176  		t.FatalfIf(!ok || err != nil, "Uevent should be equal: bijectivity fail,\n%s", err)
   177  	}
   178  
   179  	invalidMagic := []byte("libudev\x00\xfe\xed\xca\xff(\x00\x00\x00(\x00\x00\x00\xd5\x03\x00\x00\x8a\xfa\x90\xc8\x00\x00\x00\x00\x02\x00\x04\x00\x10\x80\x00\x00ACTION=remove\x00DEVPATH=foo\x00")
   180  	uevent, err := ParseUEvent(invalidMagic)
   181  	t.FatalfIf(err == nil && uevent != nil, "Event parsed successfully but it should be invalid, err: %s", err)
   182  	t.FatalfIf(err.Error() != "cannot parse libudev event: magic number mismatch", "Expecting magic number error, got %s", err)
   183  
   184  	invalidOffset := []byte("libudev\x00\xfe\xed\xca\xfe(\xff\xff\xff(\xff\xff\xff\xd5\xf3\xff\xff\x8a\xfa\x90\xc8\x00\x00\x00\x00\x02\x00\x04\x00\x10\x80\x00\x00ACTION=remove\x00DEVPATH=foo\x00")
   185  	uevent, err = ParseUEvent(invalidOffset)
   186  	t.FatalfIf(err == nil && uevent != nil, "Event parsed successfully but it should be invalid, err: %s", err)
   187  	t.FatalfIf(err.Error() != "cannot parse libudev event: invalid data offset", "Expecting invalud offset error, got %s", err)
   188  }