github.com/mirantis/virtlet@v1.5.2-0.20191204181327-1659b8a48e9b/pkg/libvirttools/diskdriver_test.go (about)

     1  /*
     2  Copyright 2017 Mirantis
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package libvirttools
    18  
    19  import (
    20  	"testing"
    21  
    22  	libvirtxml "github.com/libvirt/libvirt-go-xml"
    23  
    24  	"github.com/Mirantis/virtlet/pkg/metadata/types"
    25  )
    26  
    27  func TestDiskPath(t *testing.T) {
    28  	for _, tc := range []struct {
    29  		name       string
    30  		driverName types.DiskDriverName
    31  		diskCount  int
    32  		devList    libvirtxml.DomainDeviceList
    33  		diskPaths  []diskPath
    34  	}{
    35  		{
    36  			name:       "scsi driver",
    37  			driverName: types.DiskDriverScsi,
    38  			diskCount:  3,
    39  			devList: libvirtxml.DomainDeviceList{
    40  				Disks: []libvirtxml.DomainDisk{
    41  					{
    42  						Device: "disk",
    43  						// NOTE: Source & Driver aren't used here, so omitting them for the sake of simplicity
    44  						Target: &libvirtxml.DomainDiskTarget{
    45  							Dev: "sda",
    46  							Bus: "scsi",
    47  						},
    48  						Address: scsiAddress(0, 0, 0, 0),
    49  					},
    50  					{
    51  						Device: "disk",
    52  						Target: &libvirtxml.DomainDiskTarget{
    53  							Dev: "sdb",
    54  							Bus: "scsi",
    55  						},
    56  						Address: scsiAddress(0, 0, 0, 1),
    57  					},
    58  					{
    59  						Device: "cdrom",
    60  						Target: &libvirtxml.DomainDiskTarget{
    61  							// this one is usually sr0 in the VM,
    62  							// but it doesn't matter here
    63  							Dev: "sdc",
    64  							Bus: "scsi",
    65  						},
    66  						Address:  scsiAddress(0, 0, 0, 2),
    67  						ReadOnly: &libvirtxml.DomainDiskReadOnly{},
    68  					},
    69  				},
    70  				Controllers: []libvirtxml.DomainController{
    71  					{
    72  						Type:  "pci",
    73  						Model: "pci-root",
    74  					},
    75  					{
    76  						Type:    "scsi",
    77  						Index:   puint(0),
    78  						Model:   "virtio-scsi",
    79  						Address: pciAddress(0, 0, 3, 0),
    80  					},
    81  				},
    82  			},
    83  			diskPaths: []diskPath{
    84  				{
    85  					"/dev/disk/by-path/virtio-pci-0000:00:03.0-scsi-0:0:0:0",
    86  					"/sys/devices/pci0000:00/0000:00:03.0/virtio*/host*/target*:0:0/*:0:0:0/block/",
    87  				},
    88  				{
    89  					"/dev/disk/by-path/virtio-pci-0000:00:03.0-scsi-0:0:0:1",
    90  					"/sys/devices/pci0000:00/0000:00:03.0/virtio*/host*/target*:0:0/*:0:0:1/block/",
    91  				},
    92  				{
    93  					"/dev/disk/by-path/virtio-pci-0000:00:03.0-scsi-0:0:0:2",
    94  					"/sys/devices/pci0000:00/0000:00:03.0/virtio*/host*/target*:0:0/*:0:0:2/block/",
    95  				},
    96  			},
    97  		},
    98  		{
    99  			name:       "virtio driver",
   100  			driverName: types.DiskDriverVirtio,
   101  			diskCount:  3,
   102  			devList: libvirtxml.DomainDeviceList{
   103  				Disks: []libvirtxml.DomainDisk{
   104  					{
   105  						Device: "disk",
   106  						Target: &libvirtxml.DomainDiskTarget{
   107  							Dev: "vda",
   108  							Bus: "virtio",
   109  						},
   110  						Address: pciAddress(0, 1, 1, 0),
   111  					},
   112  					{
   113  						Device: "disk",
   114  						Target: &libvirtxml.DomainDiskTarget{
   115  							Dev: "vdb",
   116  							Bus: "virtio",
   117  						},
   118  						Address: pciAddress(0, 1, 2, 0),
   119  					},
   120  					{
   121  						Device: "cdrom",
   122  						Target: &libvirtxml.DomainDiskTarget{
   123  							Dev: "vdc",
   124  							Bus: "virtio",
   125  						},
   126  						Address:  pciAddress(0, 1, 3, 0),
   127  						ReadOnly: &libvirtxml.DomainDiskReadOnly{},
   128  					},
   129  				},
   130  				Controllers: []libvirtxml.DomainController{
   131  					{
   132  						Type:  "pci",
   133  						Model: "pci-root",
   134  					},
   135  					{
   136  						Type:    "pci",
   137  						Index:   puint(1),
   138  						Model:   "pci-bridge",
   139  						Address: pciAddress(0, 0, 3, 0),
   140  					},
   141  				},
   142  			},
   143  			diskPaths: []diskPath{
   144  				{
   145  					"/dev/disk/by-path/pci-0000:00:03.0-virtio-pci-0000:01:01.0",
   146  					"/sys/devices/pci0000:00/0000:00:03.0/0000:01:01.0/virtio*/block/",
   147  				},
   148  				{
   149  					"/dev/disk/by-path/pci-0000:00:03.0-virtio-pci-0000:01:02.0",
   150  					"/sys/devices/pci0000:00/0000:00:03.0/0000:01:02.0/virtio*/block/",
   151  				},
   152  				{
   153  					"/dev/disk/by-path/pci-0000:00:03.0-virtio-pci-0000:01:03.0",
   154  					"/sys/devices/pci0000:00/0000:00:03.0/0000:01:03.0/virtio*/block/",
   155  				},
   156  			},
   157  		},
   158  	} {
   159  		t.Run(tc.name, func(t *testing.T) {
   160  			factory, err := getDiskDriverFactory(tc.driverName)
   161  			if err != nil {
   162  				t.Fatalf("creating factory %q: %v", tc.driverName, err)
   163  			}
   164  			domain := &libvirtxml.Domain{Devices: &tc.devList}
   165  			for n := 0; n < tc.diskCount; n++ {
   166  				driver, err := factory(n)
   167  				if err != nil {
   168  					t.Errorf("error making driver #%d: %v", n, err)
   169  					continue
   170  				}
   171  				diskPath, err := driver.diskPath(domain)
   172  				if err != nil {
   173  					t.Errorf("diskPath() #%d: %v", n, err)
   174  					continue
   175  				}
   176  				if diskPath.devPath != tc.diskPaths[n].devPath {
   177  					t.Errorf("bad devPath #%d: expected %q, got %q", n, tc.diskPaths[n].devPath, diskPath.devPath)
   178  				}
   179  				if diskPath.sysfsPath != tc.diskPaths[n].sysfsPath {
   180  					t.Errorf("bad sysfsPath #%d: expected %q, got %q", n, tc.diskPaths[n].sysfsPath, diskPath.sysfsPath)
   181  				}
   182  			}
   183  		})
   184  	}
   185  }
   186  
   187  func puint(n uint) *uint { return &n }
   188  
   189  func scsiAddress(controller, bus, target, unit uint) *libvirtxml.DomainAddress {
   190  	return &libvirtxml.DomainAddress{
   191  		Drive: &libvirtxml.DomainAddressDrive{
   192  			Controller: &controller,
   193  			Bus:        &bus,
   194  			Target:     &target,
   195  			Unit:       &unit,
   196  		},
   197  	}
   198  }
   199  
   200  func pciAddress(domain, bus, slot, function uint) *libvirtxml.DomainAddress {
   201  	return &libvirtxml.DomainAddress{
   202  		PCI: &libvirtxml.DomainAddressPCI{
   203  			Domain:   &domain,
   204  			Bus:      &bus,
   205  			Slot:     &slot,
   206  			Function: &function,
   207  		},
   208  	}
   209  }
   210  
   211  // TODO: sort pci-bridge controllers by index !!!