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 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 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 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 HostDevice createHostDevice(Guid vmId) {
   HostDevice hostDevice = new HostDevice();
   hostDevice.setHostId(HOST_ID);
   hostDevice.setVmId(vmId);
   return hostDevice;
 }