mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Allow password definition during VM deploy (#6947)
Co-authored-by: Stephan Krug <stephan.krug@scclouds.com.br> Co-authored-by: dahn <daan.hoogland@gmail.com> Co-authored-by: GaOrtiga <49285692+GaOrtiga@users.noreply.github.com> Co-authored-by: Gabriel Pordeus Santos <gabrielpordeus@gmail.com> Co-authored-by: Gabriel <gabriel.fernandes@scclouds.com.br>
This commit is contained in:
		
							parent
							
								
									9df580cef4
								
							
						
					
					
						commit
						0c14e4603d
					
				| @ -105,6 +105,10 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG | |||||||
|     @Parameter(name = ApiConstants.DISPLAY_NAME, type = CommandType.STRING, description = "an optional user generated name for the virtual machine") |     @Parameter(name = ApiConstants.DISPLAY_NAME, type = CommandType.STRING, description = "an optional user generated name for the virtual machine") | ||||||
|     private String displayName; |     private String displayName; | ||||||
| 
 | 
 | ||||||
|  |     @Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, description="The password of the virtual machine. If null, a random password will be generated for the VM.", | ||||||
|  |             since="4.19.0.0") | ||||||
|  |     protected String password; | ||||||
|  | 
 | ||||||
|     //Owner information |     //Owner information | ||||||
|     @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account for the virtual machine. Must be used with domainId.") |     @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account for the virtual machine. Must be used with domainId.") | ||||||
|     private String accountName; |     private String accountName; | ||||||
| @ -464,6 +468,10 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG | |||||||
|         return zoneId; |         return zoneId; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public String getPassword() { | ||||||
|  |         return password; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public List<Long> getNetworkIds() { |     public List<Long> getNetworkIds() { | ||||||
|         if (MapUtils.isNotEmpty(vAppNetworks)) { |         if (MapUtils.isNotEmpty(vAppNetworks)) { | ||||||
|             if (CollectionUtils.isNotEmpty(networkIds) || ipAddress != null || getIp6Address() != null || MapUtils.isNotEmpty(ipToNetworkList)) { |             if (CollectionUtils.isNotEmpty(networkIds) || ipAddress != null || getIp6Address() != null || MapUtils.isNotEmpty(ipToNetworkList)) { | ||||||
|  | |||||||
| @ -1964,7 +1964,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage | |||||||
|     private boolean startNewVM(long vmId) { |     private boolean startNewVM(long vmId) { | ||||||
|         try { |         try { | ||||||
|             CallContext.current().setEventDetails("Vm Id: " + vmId); |             CallContext.current().setEventDetails("Vm Id: " + vmId); | ||||||
|             userVmMgr.startVirtualMachine(vmId, null, null, null); |             userVmMgr.startVirtualMachine(vmId, null, new HashMap<>(), null); | ||||||
|         } catch (final ResourceUnavailableException ex) { |         } catch (final ResourceUnavailableException ex) { | ||||||
|             s_logger.warn("Exception: ", ex); |             s_logger.warn("Exception: ", ex); | ||||||
|             throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); |             throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); | ||||||
|  | |||||||
| @ -135,6 +135,7 @@ import org.apache.commons.lang3.StringUtils; | |||||||
| import org.apache.commons.lang3.builder.ToStringBuilder; | import org.apache.commons.lang3.builder.ToStringBuilder; | ||||||
| import org.apache.commons.lang3.builder.ToStringStyle; | import org.apache.commons.lang3.builder.ToStringStyle; | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
|  | import org.jetbrains.annotations.NotNull; | ||||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||||
| import org.springframework.beans.factory.annotation.Qualifier; | import org.springframework.beans.factory.annotation.Qualifier; | ||||||
| import org.w3c.dom.Document; | import org.w3c.dom.Document; | ||||||
| @ -1174,9 +1175,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|     private UserVm forceRebootVirtualMachine(long vmId, long hostId, boolean enterSetup) { |     private UserVm forceRebootVirtualMachine(long vmId, long hostId, boolean enterSetup) { | ||||||
|         try { |         try { | ||||||
|             if (stopVirtualMachine(vmId, false) != null) { |             if (stopVirtualMachine(vmId, false) != null) { | ||||||
|                 Map<VirtualMachineProfile.Param,Object> params = null; |                 Map<VirtualMachineProfile.Param,Object> params = new HashMap<>(); | ||||||
|                 if (enterSetup) { |                 if (enterSetup) { | ||||||
|                     params = new HashMap(); |  | ||||||
|                     params.put(VirtualMachineProfile.Param.BootIntoSetup, Boolean.TRUE); |                     params.put(VirtualMachineProfile.Param.BootIntoSetup, Boolean.TRUE); | ||||||
|                 } |                 } | ||||||
|                 return startVirtualMachine(vmId, null, null, hostId, params, null, false).first(); |                 return startVirtualMachine(vmId, null, null, hostId, params, null, false).first(); | ||||||
| @ -4878,6 +4878,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|         if (cmd.getBootIntoSetup() != null) { |         if (cmd.getBootIntoSetup() != null) { | ||||||
|             additionalParams.put(VirtualMachineProfile.Param.BootIntoSetup, cmd.getBootIntoSetup()); |             additionalParams.put(VirtualMachineProfile.Param.BootIntoSetup, cmd.getBootIntoSetup()); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         if (StringUtils.isNotBlank(cmd.getPassword())) { | ||||||
|  |             additionalParams.put(VirtualMachineProfile.Param.VmPassword, cmd.getPassword()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         return startVirtualMachine(vmId, podId, clusterId, hostId, diskOfferingMap, additionalParams, cmd.getDeploymentPlanner()); |         return startVirtualMachine(vmId, podId, clusterId, hostId, diskOfferingMap, additionalParams, cmd.getDeploymentPlanner()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -5268,21 +5273,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse) |     public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, @NotNull Map<VirtualMachineProfile.Param, Object> additionalParams, | ||||||
|             throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { |             String deploymentPlannerToUse) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { | ||||||
|         return startVirtualMachine(vmId, null, null, hostId, additionalParams, deploymentPlannerToUse); |         return startVirtualMachine(vmId, null, null, hostId, additionalParams, deploymentPlannerToUse); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, |     public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, | ||||||
|             Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse) |             @NotNull Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse) | ||||||
|             throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { |             throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { | ||||||
|         return startVirtualMachine(vmId, podId, clusterId, hostId, additionalParams, deploymentPlannerToUse, true); |         return startVirtualMachine(vmId, podId, clusterId, hostId, additionalParams, deploymentPlannerToUse, true); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, |     public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, | ||||||
|             Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse, boolean isExplicitHost) |             @NotNull Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse, boolean isExplicitHost) | ||||||
|             throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { |             throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { | ||||||
|         // Input validation |         // Input validation | ||||||
|         final Account callerAccount = CallContext.current().getCallingAccount(); |         final Account callerAccount = CallContext.current().getCallingAccount(); | ||||||
| @ -5381,15 +5386,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|             // Check that the password was passed in and is valid |             // Check that the password was passed in and is valid | ||||||
|             template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId()); |             template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId()); | ||||||
| 
 | 
 | ||||||
|             String password = "saved_password"; |             String password = getCurrentVmPasswordOrDefineNewPassword(String.valueOf(additionalParams.getOrDefault(VirtualMachineProfile.Param.VmPassword, "")), vm, template); | ||||||
|             if (template.isEnablePassword()) { |  | ||||||
|                 if (vm.getDetail("password") != null) { |  | ||||||
|                     password = DBEncryptionUtil.decrypt(vm.getDetail("password")); |  | ||||||
|                 } else { |  | ||||||
|                     password = _mgr.generateRandomPassword(); |  | ||||||
|                     vm.setPassword(password); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             if (!validPassword(password)) { |             if (!validPassword(password)) { | ||||||
|                 throw new InvalidParameterValueException("A valid password for this virtual machine was not provided."); |                 throw new InvalidParameterValueException("A valid password for this virtual machine was not provided."); | ||||||
| @ -5402,7 +5399,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|             params = createParameterInParameterMap(params, additionalParams, VirtualMachineProfile.Param.VmPassword, password); |             params = createParameterInParameterMap(params, additionalParams, VirtualMachineProfile.Param.VmPassword, password); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if(null != additionalParams && additionalParams.containsKey(VirtualMachineProfile.Param.BootIntoSetup)) { |         if(additionalParams.containsKey(VirtualMachineProfile.Param.BootIntoSetup)) { | ||||||
|             if (! HypervisorType.VMware.equals(vm.getHypervisorType())) { |             if (! HypervisorType.VMware.equals(vm.getHypervisorType())) { | ||||||
|                 throw new InvalidParameterValueException(ApiConstants.BOOT_INTO_SETUP + " makes no sense for " + vm.getHypervisorType()); |                 throw new InvalidParameterValueException(ApiConstants.BOOT_INTO_SETUP + " makes no sense for " + vm.getHypervisorType()); | ||||||
|             } |             } | ||||||
| @ -5445,6 +5442,39 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|         return vmParamPair; |         return vmParamPair; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * If the template is password enabled and the VM already has a password, returns it. | ||||||
|  |      * If the template is password enabled and the VM does not have a password, sets the password to the password defined by the user and returns it. If no password is informed, | ||||||
|  |      * sets it to a random password and returns it. | ||||||
|  |      * If the template is not password enabled, returns saved_password. | ||||||
|  |      * @param newPassword The new password informed by the user in order to set the password of the VM. | ||||||
|  |      * @param vm The VM to retrieve the password from. | ||||||
|  |      * @param template The template to be checked if the password is enabled or not. | ||||||
|  |      * @return The password of the VM or saved_password. | ||||||
|  |      */ | ||||||
|  |     protected String getCurrentVmPasswordOrDefineNewPassword(String newPassword, UserVmVO vm, VMTemplateVO template) { | ||||||
|  |         String password = "saved_password"; | ||||||
|  | 
 | ||||||
|  |         if (template.isEnablePassword()) { | ||||||
|  |             if (vm.getDetail("password") != null) { | ||||||
|  |                 s_logger.debug(String.format("Decrypting VM [%s] current password.", vm)); | ||||||
|  |                 password = DBEncryptionUtil.decrypt(vm.getDetail("password")); | ||||||
|  |             } else if (StringUtils.isNotBlank(newPassword)) { | ||||||
|  |                 s_logger.debug(String.format("A password for VM [%s] was informed. Setting VM password to value defined by user.", vm)); | ||||||
|  |                 password = newPassword; | ||||||
|  |                 vm.setPassword(password); | ||||||
|  |             } else { | ||||||
|  |                 s_logger.debug(String.format("Setting VM [%s] password to a randomly generated password.", vm)); | ||||||
|  |                 password = _mgr.generateRandomPassword(); | ||||||
|  |                 vm.setPassword(password); | ||||||
|  |             } | ||||||
|  |         } else if (StringUtils.isNotBlank(newPassword)) { | ||||||
|  |             s_logger.debug(String.format("A password was informed; however, the template [%s] is not password enabled. Ignoring the parameter.", template)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return password; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private Map<VirtualMachineProfile.Param, Object> createParameterInParameterMap(Map<VirtualMachineProfile.Param, Object> params, Map<VirtualMachineProfile.Param, Object> parameterMap, VirtualMachineProfile.Param parameter, |     private Map<VirtualMachineProfile.Param, Object> createParameterInParameterMap(Map<VirtualMachineProfile.Param, Object> params, Map<VirtualMachineProfile.Param, Object> parameterMap, VirtualMachineProfile.Param parameter, | ||||||
|             Object parameterValue) { |             Object parameterValue) { | ||||||
|         if (s_logger.isTraceEnabled()) { |         if (s_logger.isTraceEnabled()) { | ||||||
|  | |||||||
| @ -99,7 +99,6 @@ import com.cloud.vm.UserVmService; | |||||||
| import com.cloud.vm.UserVmVO; | import com.cloud.vm.UserVmVO; | ||||||
| import com.cloud.vm.VirtualMachine; | import com.cloud.vm.VirtualMachine; | ||||||
| import com.cloud.vm.VirtualMachineManager; | import com.cloud.vm.VirtualMachineManager; | ||||||
| import com.cloud.vm.VirtualMachineProfile; |  | ||||||
| import com.cloud.vm.VmStats; | import com.cloud.vm.VmStats; | ||||||
| import com.cloud.vm.dao.DomainRouterDao; | import com.cloud.vm.dao.DomainRouterDao; | ||||||
| import com.cloud.vm.dao.UserVmDao; | import com.cloud.vm.dao.UserVmDao; | ||||||
| @ -1495,8 +1494,6 @@ public class AutoScaleManagerImplTest { | |||||||
|             when(autoScaleVmGroupDao.updateState(vmGroupId, AutoScaleVmGroup.State.ENABLED, AutoScaleVmGroup.State.SCALING)).thenReturn(true); |             when(autoScaleVmGroupDao.updateState(vmGroupId, AutoScaleVmGroup.State.ENABLED, AutoScaleVmGroup.State.SCALING)).thenReturn(true); | ||||||
|             when(autoScaleVmGroupDao.updateState(vmGroupId, AutoScaleVmGroup.State.SCALING, AutoScaleVmGroup.State.ENABLED)).thenReturn(true); |             when(autoScaleVmGroupDao.updateState(vmGroupId, AutoScaleVmGroup.State.SCALING, AutoScaleVmGroup.State.ENABLED)).thenReturn(true); | ||||||
|             Mockito.doReturn(virtualMachineId).when(autoScaleManagerImplSpy).createNewVM(asVmGroupMock); |             Mockito.doReturn(virtualMachineId).when(autoScaleManagerImplSpy).createNewVM(asVmGroupMock); | ||||||
|             Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVm = Mockito.mock(Pair.class); |  | ||||||
|             when(userVmMgr.startVirtualMachine(virtualMachineId, null, null, null)).thenReturn(startVm); |  | ||||||
| 
 | 
 | ||||||
|             when(asVmGroupMock.getLoadBalancerId()).thenReturn(loadBalancerId); |             when(asVmGroupMock.getLoadBalancerId()).thenReturn(loadBalancerId); | ||||||
|             when(lbVmMapDao.listByLoadBalancerId(loadBalancerId)).thenReturn(Arrays.asList(loadBalancerVMMapMock)); |             when(lbVmMapDao.listByLoadBalancerId(loadBalancerId)).thenReturn(Arrays.asList(loadBalancerVMMapMock)); | ||||||
|  | |||||||
| @ -38,6 +38,7 @@ import com.cloud.network.NetworkModel; | |||||||
| import com.cloud.network.dao.NetworkDao; | import com.cloud.network.dao.NetworkDao; | ||||||
| import com.cloud.network.dao.NetworkVO; | import com.cloud.network.dao.NetworkVO; | ||||||
| import com.cloud.offering.ServiceOffering; | import com.cloud.offering.ServiceOffering; | ||||||
|  | import com.cloud.server.ManagementService; | ||||||
| import com.cloud.service.ServiceOfferingVO; | import com.cloud.service.ServiceOfferingVO; | ||||||
| import com.cloud.service.dao.ServiceOfferingDao; | import com.cloud.service.dao.ServiceOfferingDao; | ||||||
| import com.cloud.storage.DiskOfferingVO; | import com.cloud.storage.DiskOfferingVO; | ||||||
| @ -213,6 +214,12 @@ public class UserVmManagerImplTest { | |||||||
|     @Mock |     @Mock | ||||||
|     AccountVO account; |     AccountVO account; | ||||||
| 
 | 
 | ||||||
|  |     @Mock | ||||||
|  |     VMTemplateVO vmTemplateVoMock; | ||||||
|  | 
 | ||||||
|  |     @Mock | ||||||
|  |     ManagementService managementServiceMock; | ||||||
|  | 
 | ||||||
|     @Mock |     @Mock | ||||||
|     private ServiceOfferingVO serviceOffering; |     private ServiceOfferingVO serviceOffering; | ||||||
| 
 | 
 | ||||||
| @ -1068,4 +1075,58 @@ public class UserVmManagerImplTest { | |||||||
|         Mockito.verify(userVmDao).findById(vmId); |         Mockito.verify(userVmDao).findById(vmId); | ||||||
|         Mockito.verify(userVmDao).update(vmId, userVmVoMock); |         Mockito.verify(userVmDao).update(vmId, userVmVoMock); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getCurrentVmPasswordOrDefineNewPasswordTestTemplateIsNotPasswordEnabledReturnPreDefinedString() { | ||||||
|  |         String expected = "saved_password"; | ||||||
|  | 
 | ||||||
|  |         Mockito.doReturn(false).when(vmTemplateVoMock).isEnablePassword(); | ||||||
|  | 
 | ||||||
|  |         String result = userVmManagerImpl.getCurrentVmPasswordOrDefineNewPassword("", userVmVoMock, vmTemplateVoMock); | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals(expected, result); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getCurrentVmPasswordOrDefineNewPasswordTestVmHasPasswordReturnCurrentPassword() { | ||||||
|  |         String expected = "current_password"; | ||||||
|  | 
 | ||||||
|  |         Mockito.doReturn(true).when(vmTemplateVoMock).isEnablePassword(); | ||||||
|  |         Mockito.doReturn(expected).when(userVmVoMock).getDetail("password"); | ||||||
|  | 
 | ||||||
|  |         String result = userVmManagerImpl.getCurrentVmPasswordOrDefineNewPassword("", userVmVoMock, vmTemplateVoMock); | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals(expected, result); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getCurrentVmPasswordOrDefineNewPasswordTestUserDefinedPasswordReturnNewPasswordAndSetVmPassword() { | ||||||
|  |         String expected = "new_password"; | ||||||
|  | 
 | ||||||
|  |         Mockito.doReturn(true).when(vmTemplateVoMock).isEnablePassword(); | ||||||
|  |         Mockito.doReturn(null).when(userVmVoMock).getDetail("password"); | ||||||
|  |         Mockito.doCallRealMethod().when(userVmVoMock).setPassword(Mockito.any()); | ||||||
|  |         Mockito.doCallRealMethod().when(userVmVoMock).getPassword(); | ||||||
|  | 
 | ||||||
|  |         String result = userVmManagerImpl.getCurrentVmPasswordOrDefineNewPassword(expected, userVmVoMock, vmTemplateVoMock); | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals(expected, result); | ||||||
|  |         Assert.assertEquals(expected, userVmVoMock.getPassword()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getCurrentVmPasswordOrDefineNewPasswordTestUserDefinedPasswordReturnRandomPasswordAndSetVmPassword() { | ||||||
|  |         String expected = "random_password"; | ||||||
|  | 
 | ||||||
|  |         Mockito.doReturn(true).when(vmTemplateVoMock).isEnablePassword(); | ||||||
|  |         Mockito.doReturn(null).when(userVmVoMock).getDetail("password"); | ||||||
|  |         Mockito.doReturn(expected).when(managementServiceMock).generateRandomPassword(); | ||||||
|  |         Mockito.doCallRealMethod().when(userVmVoMock).setPassword(Mockito.any()); | ||||||
|  |         Mockito.doCallRealMethod().when(userVmVoMock).getPassword(); | ||||||
|  | 
 | ||||||
|  |         String result = userVmManagerImpl.getCurrentVmPasswordOrDefineNewPassword("", userVmVoMock, vmTemplateVoMock); | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals(expected, result); | ||||||
|  |         Assert.assertEquals(expected, userVmVoMock.getPassword()); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user