private VdsNetworkInterface mockNicForNetDevice(HostDevice netDeviceParam) {
    VdsNetworkInterface nic = new VdsNetworkInterface();
    nic.setVdsId(netDeviceParam.getHostId());
    nic.setName(netDeviceParam.getNetworkInterfaceName());

    return nic;
  }
  @Test
  public void isNonNetworkDeviceNetworkFree() {
    HostDevice device = new HostDevice();
    device.setHostId(HOST_ID);
    device.setDeviceName(PCI_DEVICE_NAME_2);

    assertTrue(networkDeviceHelper.isDeviceNetworkFree(device));
  }
  private List<HostDevice> freeVfCommon(
      int numOfFreeVfs,
      int numOfVfsAttachedToVm,
      int numOfVfsHasNoNic,
      int numOfVfsHasNetworkAttached,
      int numOfVfsHasVlanDeviceAttached,
      int numOfVfsArePartOfBond) {
    networkDeviceHelper =
        spy(new NetworkDeviceHelperImpl(interfaceDao, hostDeviceDao, hostNicVfsConfigDao, vdsDao));

    List<HostDevice> devices = new ArrayList<>();
    List<HostDevice> freeVfs = new ArrayList<>();

    int numOfVfs =
        numOfFreeVfs
            + numOfVfsAttachedToVm
            + numOfVfsHasNoNic
            + numOfVfsHasNetworkAttached
            + numOfVfsHasVlanDeviceAttached
            + numOfVfsArePartOfBond;
    List<HostDevice> vfs = mockVfsOnNetDevice(numOfVfs);
    List<VdsNetworkInterface> nics = new ArrayList<>();
    devices.addAll(vfs);

    for (HostDevice vfPciDevice : vfs) {
      HostDevice vfNetDevice = mockNetworkDeviceForPciDevice(vfPciDevice);
      devices.add(vfNetDevice);

      if (numOfVfsHasNoNic != 0) {
        --numOfVfsHasNoNic;
      } else {
        VdsNetworkInterface vfNic = mockNicForNetDevice(vfNetDevice);
        nics.add(vfNic);
        if (numOfVfsAttachedToVm != 0) {
          --numOfVfsAttachedToVm;
          vfPciDevice.setVmId(Guid.newGuid());
        } else if (numOfVfsHasNetworkAttached != 0) {
          --numOfVfsHasNetworkAttached;
          vfNic.setNetworkName("netName");
        } else if (numOfVfsHasVlanDeviceAttached != 0) {
          --numOfVfsHasVlanDeviceAttached;
          doReturn(true).when(networkDeviceHelper).isVlanDeviceAttached(vfNic);
        } else if (numOfVfsArePartOfBond != 0) {
          --numOfVfsArePartOfBond;
          vfNic.setBondName("bondName");
        } else {
          doReturn(false).when(networkDeviceHelper).isVlanDeviceAttached(vfNic);
          freeVfs.add(vfPciDevice);
        }
      }
    }

    mockHostDevices(devices);
    mockNics(nics, true);

    return freeVfs;
  }
  private HostDevice mockNetworkDeviceForPciDevice(HostDevice pciDeviceParam) {
    HostDevice mockedNetDevice = new HostDevice();
    mockedNetDevice.setParentDeviceName(pciDeviceParam.getDeviceName());
    mockedNetDevice.setHostId(pciDeviceParam.getHostId());
    mockedNetDevice.setDeviceName(pciDeviceParam.getDeviceName() + "netDevice");
    mockedNetDevice.setNetworkInterfaceName(mockedNetDevice.getDeviceName() + "iface");

    return mockedNetDevice;
  }
  @Before
  public void setUp() {
    networkDeviceHelper =
        new NetworkDeviceHelperImpl(interfaceDao, hostDeviceDao, hostNicVfsConfigDao, vdsDao);

    when(netDevice.getHostId()).thenReturn(HOST_ID);
    when(netDevice.getDeviceName()).thenReturn(NET_DEVICE_NAME);
    when(netDevice.getName()).thenReturn(NET_DEVICE_NAME);
    when(netDevice.getNetworkInterfaceName()).thenReturn(NIC_NAME);
    when(netDevice.getParentDeviceName()).thenReturn(PCI_DEVICE_NAME);

    when(pciDevice.getHostId()).thenReturn(HOST_ID);
    when(pciDevice.getDeviceName()).thenReturn(PCI_DEVICE_NAME);
    when(pciDevice.getName()).thenReturn(PCI_DEVICE_NAME);

    List<HostDevice> devices = new ArrayList<>();
    devices.add(netDevice);
    devices.add(pciDevice);
    mockHostDevices(devices);

    when(nic.getId()).thenReturn(NIC_ID);
    when(nic.getName()).thenReturn(NIC_NAME);
    when(nic.getVdsId()).thenReturn(HOST_ID);
    when(interfaceDao.get(NIC_ID)).thenReturn(nic);
    when(nic.getName()).thenReturn(NIC_NAME);

    when(hostNicVfsConfig.getNicId()).thenReturn(NIC_ID);
    when(hostNicVfsConfigDao.getByNicId(NIC_ID)).thenReturn(hostNicVfsConfig);
  }
  @Test
  public void getNicByNetDeviceNoNic() {
    VdsNetworkInterface newNic = new VdsNetworkInterface();
    newNic.setName(netDevice.getNetworkInterfaceName() + "not");
    mockNics(Collections.singletonList(newNic), false);

    assertNull(networkDeviceHelper.getNicByPciDevice(pciDevice));
  }
  @Test
  public void setVmIdOnVfs() {
    List<HostDevice> vfs = mockVfsOnNetDevice(1);
    mockHostDevices(vfs);

    HostDevice vf = vfs.get(0);
    Guid vmId = Guid.newGuid();
    vf.setVmId(vmId);
    networkDeviceHelper.setVmIdOnVfs(HOST_ID, vmId, Collections.singleton(vf.getDeviceName()));

    verify(hostDeviceDao).setVmIdOnHostDevice(hostDeviceIdCaptor.capture(), vmIdCaptor.capture());

    HostDeviceId capturedDeviceId = hostDeviceIdCaptor.getValue();
    Guid capturedVmId = vmIdCaptor.getValue();

    assertEquals(vf.getId(), capturedDeviceId);
    assertEquals(vmId, capturedVmId);
  }
  private void commonUpdateHostNicVfsConfigWithNumVfsData(int numOfVfs) {
    when(pciDevice.getTotalVirtualFunctions()).thenReturn(TOTAL_NUM_OF_VFS);
    List<HostDevice> vfs = mockVfsOnNetDevice(numOfVfs);
    mockHostDevices(vfs);

    networkDeviceHelper.updateHostNicVfsConfigWithNumVfsData(hostNicVfsConfig);

    verify(hostNicVfsConfig).setMaxNumOfVfs(TOTAL_NUM_OF_VFS);
    verify(hostNicVfsConfig).setNumOfVfs(numOfVfs);
  }
  @Test
  public void testGetVfMap() {
    final HostDevice pfNetDevice = new HostDevice();
    final HostDevice pfPciDevice = new HostDevice();

    final Guid pfNicId = Guid.newGuid();
    final String pfNicName = "pf" + NIC_NAME;
    final String pfPciDeviceName = "pf" + PCI_DEVICE_NAME;

    pfNetDevice.setHostId(HOST_ID);
    pfNetDevice.setDeviceName("pf" + NET_DEVICE_NAME);
    pfNetDevice.setNetworkInterfaceName(pfNicName);
    pfNetDevice.setParentDeviceName(pfPciDeviceName);

    pfPciDevice.setHostId(HOST_ID);
    pfPciDevice.setDeviceName(pfPciDeviceName);
    pfPciDevice.setDeviceName(pfPciDeviceName);

    when(pciDevice.getParentPhysicalFunction()).thenReturn(pfPciDeviceName);
    mockHostDevices(Arrays.asList(pfNetDevice, pfPciDevice, new HostDevice()));

    when(nic.getVlanId()).thenReturn(null);
    final VdsNetworkInterface pfNic = new VdsNetworkInterface();
    pfNic.setId(pfNicId);
    pfNic.setName(pfNetDevice.getNetworkInterfaceName());
    final VdsNetworkInterface bondNic = new VdsNetworkInterface();
    bondNic.setBonded(true);
    final VdsNetworkInterface vlanNic = new VdsNetworkInterface();
    vlanNic.setVlanId(666);
    mockNics(Arrays.asList(pfNic, bondNic, vlanNic), true);

    mockHostSupportsSriov(true);

    final Map<Guid, Guid> actual = networkDeviceHelper.getVfMap(HOST_ID);

    assertEquals(1, actual.size());
    assertThat(actual, hasEntry(NIC_ID, pfNicId));
  }
  private void removeVmIdFromVfsCommonTest(int numOfVfWithVmId, int numOfOtherDeviceWithVmId) {
    List<HostDevice> allDevices = new ArrayList<>();
    List<HostDevice> otherDeviceWithVmId = new ArrayList<>();

    Guid vmId = Guid.newGuid();
    List<HostDevice> vfs = mockVfsOnNetDevice(numOfVfWithVmId, vmId);
    allDevices.addAll(vfs);

    for (int i = 0; i <= numOfOtherDeviceWithVmId; ++i) {
      HostDevice hostDevice = createHostDevice(vmId);
      otherDeviceWithVmId.add(hostDevice);
    }

    allDevices.addAll(otherDeviceWithVmId);
    mockHostDevices(allDevices);

    for (HostDevice vf : vfs) {
      assertEquals(vmId, vf.getVmId());
    }

    networkDeviceHelper.removeVmIdFromVfs(vmId);

    for (HostDevice vf : vfs) {
      vf.setVmId(null);
    }

    if (numOfVfWithVmId == 0) {
      verify(hostDeviceDao, never()).setVmIdOnHostDevice(any(HostDeviceId.class), any(Guid.class));
    } else {
      verify(hostDeviceDao, times(numOfVfWithVmId))
          .setVmIdOnHostDevice(hostDeviceIdCaptor.capture(), vmIdCaptor.capture());

      List<HostDeviceId> capturedDeviceIds = hostDeviceIdCaptor.getAllValues();
      List<Guid> capturedVmIds = vmIdCaptor.getAllValues();

      for (HostDevice vf : vfs) {
        assertTrue(capturedDeviceIds.contains(vf.getId()));
      }

      for (HostDevice hostDevice : otherDeviceWithVmId) {
        assertFalse(capturedDeviceIds.contains(hostDevice.getId()));
      }

      for (Guid capturedVmId : capturedVmIds) {
        assertEquals(null, capturedVmId);
      }
    }
  }
  @Test
  public void getHostNicVfsConfigsWithNumVfsDataByHostId() {
    when(hostNicVfsConfigDao.getAllVfsConfigByHostId(HOST_ID))
        .thenReturn(Collections.singletonList(hostNicVfsConfig));

    when(pciDevice.getTotalVirtualFunctions()).thenReturn(TOTAL_NUM_OF_VFS);
    List<HostDevice> vfs = mockVfsOnNetDevice(2);
    mockHostDevices(vfs);

    List<HostNicVfsConfig> vfsConfigList =
        networkDeviceHelper.getHostNicVfsConfigsWithNumVfsDataByHostId(HOST_ID);

    assertEquals(1, vfsConfigList.size());
    assertEquals(hostNicVfsConfig, vfsConfigList.get(0));

    verify(hostNicVfsConfig).setMaxNumOfVfs(TOTAL_NUM_OF_VFS);
    verify(hostNicVfsConfig).setNumOfVfs(2);
  }
  private List<HostDevice> mockVfsOnNetDevice(int numOfVfs, Guid vmId) {
    List<HostDevice> vfs = new ArrayList<>();

    for (int i = 0; i < numOfVfs; ++i) {
      HostDevice vfPciDevice = new HostDevice();
      vfPciDevice.setParentPhysicalFunction(pciDevice.getDeviceName());
      vfPciDevice.setDeviceName(String.valueOf(i));
      vfPciDevice.setHostId(HOST_ID);
      vfPciDevice.setVmId(vmId);
      vfs.add(vfPciDevice);
    }

    return vfs;
  }
 private HostDevice createHostDevice(Guid vmId) {
   HostDevice hostDevice = new HostDevice();
   hostDevice.setHostId(HOST_ID);
   hostDevice.setVmId(vmId);
   return hostDevice;
 }
  private void commonIsSriovDevice(boolean isSriov) {
    when(pciDevice.getTotalVirtualFunctions()).thenReturn(isSriov ? TOTAL_NUM_OF_VFS : null);

    assertEquals(isSriov, networkDeviceHelper.isSriovDevice(pciDevice));
  }