Skip to content

Commit e348e76

Browse files
CLOUDSTACK-8607 - Improving unit tests
- Adding more unit tests as suggested by Daan and Rajani. - Mocking SshHelper and the Script classes, used by Citrix and Libvirt resources respectively.
1 parent 86297e7 commit e348e76

7 files changed

Lines changed: 228 additions & 28 deletions

File tree

plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpdateHostPasswordCommandWrapper.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919

2020
package com.cloud.hypervisor.kvm.resource.wrapper;
2121

22-
import org.apache.log4j.Logger;
23-
2422
import com.cloud.agent.api.Answer;
2523
import com.cloud.agent.api.UpdateHostPasswordCommand;
2624
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
@@ -31,15 +29,14 @@
3129
@ResourceWrapper(handles = UpdateHostPasswordCommand.class)
3230
public final class LibvirtUpdateHostPasswordCommandWrapper extends CommandWrapper<UpdateHostPasswordCommand, Answer, LibvirtComputingResource> {
3331

34-
private static final Logger s_logger = Logger.getLogger(LibvirtUpdateHostPasswordCommandWrapper.class);
35-
private static final int TIMEOUT = 10000;
36-
3732
@Override
3833
public Answer execute(final UpdateHostPasswordCommand command, final LibvirtComputingResource libvirtComputingResource) {
34+
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
35+
3936
final String username = command.getUsername();
4037
final String newPassword = command.getNewPassword();
4138

42-
final Script script = new Script(libvirtComputingResource.getUpdateHostPasswdPath(), TIMEOUT, s_logger);
39+
final Script script = libvirtUtilitiesHelper.buildScript(libvirtComputingResource.getUpdateHostPasswdPath());
4340
script.add(username, newPassword);
4441
final String result = script.execute();
4542

plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,16 @@
3131
import com.cloud.storage.template.Processor;
3232
import com.cloud.storage.template.QCOW2Processor;
3333
import com.cloud.storage.template.TemplateLocation;
34+
import com.cloud.utils.script.Script;
3435

3536
/**
3637
* This class is used to wrap the calls to several static methods. By doing so, we make easier to mock this class
3738
* and the methods wrapped here.
38-
*
39-
* Please do not instantiate this class directly, but inject it using the {@code @Inject} annotation.
4039
*/
4140
public class LibvirtUtilitiesHelper {
4241

42+
public static final int TIMEOUT = 10000;
43+
4344
public Connect getConnectionByVmName(final String vmName) throws LibvirtException {
4445
return LibvirtConnection.getConnectionByVmName(vmName);
4546
}
@@ -90,4 +91,9 @@ public String retrieveBashScriptPath() {
9091
public Connect retrieveQemuConnection(final String qemuURI) throws LibvirtException {
9192
return new Connect(qemuURI);
9293
}
94+
95+
public Script buildScript(final String scriptPath) {
96+
final Script script = new Script(scriptPath, TIMEOUT);
97+
return script;
98+
}
9399
}

plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
169169
import com.cloud.utils.Pair;
170170
import com.cloud.utils.exception.CloudRuntimeException;
171+
import com.cloud.utils.script.Script;
171172
import com.cloud.vm.DiskProfile;
172173
import com.cloud.vm.VirtualMachine;
173174
import com.cloud.vm.VirtualMachine.PowerState;
@@ -5076,12 +5077,45 @@ public void testStartCommandIsolationEc2() {
50765077

50775078
@Test
50785079
public void testUpdateHostPasswordCommand() {
5080+
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
5081+
final Script script = Mockito.mock(Script.class);
5082+
5083+
final String hostIp = "127.0.0.1";
5084+
final String username = "root";
5085+
final String newPassword = "password";
5086+
5087+
final UpdateHostPasswordCommand command = new UpdateHostPasswordCommand(username, newPassword, hostIp);
5088+
5089+
when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
5090+
when(libvirtComputingResource.getUpdateHostPasswdPath()).thenReturn("/tmp");
5091+
when(libvirtUtilitiesHelper.buildScript(libvirtComputingResource.getUpdateHostPasswdPath())).thenReturn(script);
5092+
5093+
when(script.execute()).thenReturn(null);
5094+
5095+
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
5096+
assertNotNull(wrapper);
5097+
5098+
final Answer answer = wrapper.execute(command, libvirtComputingResource);
5099+
5100+
assertTrue(answer.getResult());
5101+
}
5102+
5103+
@Test
5104+
public void testUpdateHostPasswordCommandFail() {
5105+
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
5106+
final Script script = Mockito.mock(Script.class);
5107+
50795108
final String hostIp = "127.0.0.1";
50805109
final String username = "root";
50815110
final String newPassword = "password";
5111+
50825112
final UpdateHostPasswordCommand command = new UpdateHostPasswordCommand(username, newPassword, hostIp);
50835113

5114+
when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
50845115
when(libvirtComputingResource.getUpdateHostPasswdPath()).thenReturn("/tmp");
5116+
when(libvirtUtilitiesHelper.buildScript(libvirtComputingResource.getUpdateHostPasswdPath())).thenReturn(script);
5117+
5118+
when(script.execute()).thenReturn("#FAIL");
50855119

50865120
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
50875121
assertNotNull(wrapper);

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
import com.cloud.host.Host.Type;
104104
import com.cloud.hypervisor.Hypervisor.HypervisorType;
105105
import com.cloud.hypervisor.xenserver.resource.wrapper.xenbase.CitrixRequestWrapper;
106+
import com.cloud.hypervisor.xenserver.resource.wrapper.xenbase.XenServerUtilitiesHelper;
106107
import com.cloud.network.Networks;
107108
import com.cloud.network.Networks.BroadcastDomainType;
108109
import com.cloud.network.Networks.TrafficType;
@@ -259,6 +260,8 @@ private static boolean isAlienVm(final VM vm, final Connection conn) throws XenA
259260
protected String _configDriveSRName = "ConfigDriveISOs";
260261
protected String _attachIsoDeviceNum = "3";
261262

263+
protected XenServerUtilitiesHelper xenServerUtilitiesHelper = new XenServerUtilitiesHelper();
264+
262265
protected int _wait;
263266
// Hypervisor specific params with generic value, may need to be overridden
264267
// for specific versions
@@ -288,6 +291,10 @@ public String getPwdFromQueue() {
288291
return _password.peek();
289292
}
290293

294+
public XenServerUtilitiesHelper getXenServerUtilitiesHelper() {
295+
return xenServerUtilitiesHelper;
296+
}
297+
291298
protected StorageSubsystemCommandHandler buildStorageHandler() {
292299
final XenServerStorageProcessor processor = new XenServerStorageProcessor(this);
293300
return new StorageSubsystemCommandHandlerBase(processor);
@@ -5266,7 +5273,6 @@ public SR createLocalIsoSR(final Connection conn, final String srName) throws Xe
52665273

52675274
}
52685275

5269-
52705276
public void deleteLocalFolder(final String directory) throws Exception {
52715277
if (directory == null || directory.isEmpty()) {
52725278
final String msg = "Invalid directory path (null/empty) detected. Cannot delete specified directory.";
@@ -5283,4 +5289,4 @@ public void deleteLocalFolder(final String directory) throws Exception {
52835289
}
52845290
}
52855291

5286-
}
5292+
}

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUpdateHostPasswordCommandWrapper.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
package com.cloud.hypervisor.xenserver.resource.wrapper.xenbase;
2121

22+
import static com.cloud.hypervisor.xenserver.resource.wrapper.xenbase.XenServerUtilitiesHelper.SCRIPT_CMD_PATH;
23+
2224
import org.apache.log4j.Logger;
2325

2426
import com.cloud.agent.api.Answer;
@@ -28,33 +30,26 @@
2830
import com.cloud.resource.CommandWrapper;
2931
import com.cloud.resource.ResourceWrapper;
3032
import com.cloud.utils.Pair;
31-
import com.cloud.utils.ssh.SshHelper;
3233

3334
@ResourceWrapper(handles = UpdateHostPasswordCommand.class)
3435
public final class CitrixUpdateHostPasswordCommandWrapper extends CommandWrapper<UpdateHostPasswordCommand, Answer, CitrixResourceBase> {
3536

3637
private static final Logger s_logger = Logger.getLogger(CitrixUpdateHostPasswordCommandWrapper.class);
37-
private static final int TIMEOUT = 10000;
3838

3939
@Override
4040
public Answer execute(final UpdateHostPasswordCommand command, final CitrixResourceBase citrixResourceBase) {
4141
final String hostIp = command.getHostIp();
4242
final String username = command.getUsername();
4343
final String newPassword = command.getNewPassword();
4444

45-
final StringBuffer cmdLine = new StringBuffer();
46-
cmdLine.append("sh /opt/cloud/bin/");
47-
cmdLine.append(VRScripts.UPDATE_HOST_PASSWD);
48-
cmdLine.append(' ');
49-
cmdLine.append(username);
50-
cmdLine.append(' ');
51-
cmdLine.append(newPassword);
45+
final XenServerUtilitiesHelper xenServerUtilitiesHelper = citrixResourceBase.getXenServerUtilitiesHelper();
46+
final String cmdLine = xenServerUtilitiesHelper.buildCommandLine(SCRIPT_CMD_PATH, VRScripts.UPDATE_HOST_PASSWD, username, newPassword);
5247

5348
Pair<Boolean, String> result;
54-
5549
try {
5650
s_logger.debug("Executing command in Host: " + cmdLine);
57-
result = SshHelper.sshExecute(hostIp, 22, username, null, citrixResourceBase.getPwdFromQueue(), cmdLine.toString(), 60000, 60000, TIMEOUT);
51+
final String hostPassword = citrixResourceBase.getPwdFromQueue();
52+
result = xenServerUtilitiesHelper.executeSshWrapper(hostIp, 22, username, null, hostPassword, cmdLine.toString());
5853
} catch (final Exception e) {
5954
return new Answer(command, false, e.getMessage());
6055
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.hypervisor.xenserver.resource.wrapper.xenbase;
18+
19+
import java.io.File;
20+
21+
import com.cloud.utils.Pair;
22+
import com.cloud.utils.ssh.SshHelper;
23+
24+
25+
/**
26+
* This class is used to wrap the calls to several static methods. By doing so, we make easier to mock this class
27+
* and the methods wrapped here.
28+
*/
29+
public class XenServerUtilitiesHelper {
30+
31+
public static final int TIMEOUT = 10000;
32+
public static final String SCRIPT_CMD_PATH = "sh /opt/cloud/bin/";
33+
34+
public Pair<Boolean, String> executeSshWrapper(final String hostIp, final int port, final String username, final File pemFile, final String hostPasswd, final String command) throws Exception {
35+
final Pair<Boolean, String> result = SshHelper.sshExecute(hostIp, port, username, pemFile, hostPasswd, command, 60000, 60000, TIMEOUT);
36+
return result;
37+
}
38+
39+
public String buildCommandLine(final String scriptPath, final String script, final String username, final String newPassword) {
40+
final StringBuilder cmdLine = new StringBuilder();
41+
cmdLine.append(scriptPath).append(script).append(' ').append(username).append(' ').append(newPassword);
42+
43+
return cmdLine.toString();
44+
}
45+
}

0 commit comments

Comments
 (0)