Merge pull request #1497 from nvazquez/addidsparam

CLOUDSTACK-9351: Add ids parameter to resource listing API calls## General behaviour
A new parameter is added in each method, its type a list of IDs of the entity, it will be mutually exclusive with id. (Similar to <code>id</code> and <code>ids</code> parameters in <code>listVirtualMachines</code> method)

### API Methods affected
* <code>listTemplates</code>: new parameter **<code>ids</code>**, mutually exclusive with <code>id</code>
* <code>listVolumes</code>: new parameter **<code>ids</code>**, mutually exclusive with <code>id</code>
* <code>listSnapshots</code>: new parameter **<code>ids</code>**, mutually exclusive with <code>id</code>
* <code>listVMSnapshots</code>: new parameter **<code>vmsnapshotids</code>**, mutually exclusive with <code>vmsnapshotid</code>

* pr/1497:
  CLOUDSTACK-9351: Add marvin test and add it to travis file
  CLOUDSTACK-9351: Add ids parameter to resource listing API calls

Signed-off-by: Will Stevens <williamstevens@gmail.com>
This commit is contained in:
Will Stevens 2016-05-10 23:49:55 -04:00
commit de582a41c0
12 changed files with 521 additions and 10 deletions

View File

@ -37,7 +37,7 @@ env:
- PATH=$HOME/.local/bin:$PATH
matrix:
- TESTS="smoke/test_affinity_groups smoke/test_affinity_groups_projects smoke/test_deploy_vgpu_enabled_vm smoke/test_deploy_vm_iso smoke/test_deploy_vm_root_resize smoke/test_deploy_vm_with_userdata smoke/test_deploy_vms_with_varied_deploymentplanners smoke/test_disk_offerings smoke/test_global_settings smoke/test_guest_vlan_range"
- TESTS="smoke/test_hosts smoke/test_internal_lb smoke/test_iso smoke/test_loadbalance smoke/test_multipleips_per_nic smoke/test_network smoke/test_network_acl smoke/test_nic smoke/test_nic_adapter_type smoke/test_non_contigiousvlan"
- TESTS="smoke/test_hosts smoke/test_internal_lb smoke/test_iso smoke/test_list_ids_parameter smoke/test_loadbalance smoke/test_multipleips_per_nic smoke/test_network smoke/test_network_acl smoke/test_nic smoke/test_nic_adapter_type smoke/test_non_contigiousvlan"
- TESTS="smoke/test_over_provisioning smoke/test_password_server smoke/test_portable_publicip smoke/test_primary_storage smoke/test_privategw_acl smoke/test_public_ip_range smoke/test_pvlan smoke/test_regions smoke/test_reset_vm_on_reboot smoke/test_resource_detail"
- TESTS="smoke/test_router_dhcphosts smoke/test_routers smoke/test_routers_iptables_default_policy smoke/test_routers_network_ops smoke/test_scale_vm smoke/test_secondary_storage smoke/test_service_offerings smoke/test_snapshots smoke/test_ssvm smoke/test_templates"
- TESTS="smoke/test_usage_events smoke/test_vm_life_cycle smoke/test_vm_snapshots smoke/test_volumes smoke/test_vpc_redundant smoke/test_vpc_router_nics smoke/test_vpc_vpn smoke/misc/test_deploy_vm smoke/misc/test_vm_ha smoke/misc/test_escalations_templates smoke/misc/test_vm_sync"

View File

@ -551,6 +551,7 @@ public class ApiConstants {
public static final String VM_SNAPSHOT_DESCRIPTION = "description";
public static final String VM_SNAPSHOT_DISPLAYNAME = "name";
public static final String VM_SNAPSHOT_ID = "vmsnapshotid";
public static final String VM_SNAPSHOT_IDS = "vmsnapshotids";
public static final String VM_SNAPSHOT_DISK_IDS = "vmsnapshotdiskids";
public static final String VM_SNAPSHOT_MEMORY = "snapshotmemory";
public static final String VM_SNAPSHOT_QUIESCEVM = "quiescevm";

View File

@ -48,6 +48,9 @@ public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = SnapshotResponse.class, description = "lists snapshot by snapshot ID")
private Long id;
@Parameter(name=ApiConstants.IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType=SnapshotResponse.class, description="the IDs of the snapshots, mutually exclusive with id", since = "4.9")
private List<Long> ids;
@Parameter(name = ApiConstants.INTERVAL_TYPE, type = CommandType.STRING, description = "valid values are HOURLY, DAILY, WEEKLY, and MONTHLY.")
private String intervalType;
@ -120,4 +123,8 @@ public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd {
setResponseObject(response);
}
public List<Long> getIds() {
return ids;
}
}

View File

@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command.user.template;
import org.apache.log4j.Logger;
import java.util.List;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.ApiConstants;
@ -50,6 +51,9 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, description = "the template ID")
private Long id;
@Parameter(name=ApiConstants.IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType=TemplateResponse.class, description="the IDs of the templates, mutually exclusive with id", since = "4.9")
private List<Long> ids;
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the template name")
private String templateName;
@ -132,4 +136,8 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd {
response.setResponseName(getCommandName());
setResponseObject(response);
}
public List<Long> getIds() {
return ids;
}
}

View File

@ -39,6 +39,9 @@ public class ListVMSnapshotCmd extends BaseListTaggedResourcesCmd {
@Parameter(name = ApiConstants.VM_SNAPSHOT_ID, type = CommandType.UUID, entityType = VMSnapshotResponse.class, description = "The ID of the VM snapshot")
private Long id;
@Parameter(name=ApiConstants.VM_SNAPSHOT_IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType=VMSnapshotResponse.class, description="the IDs of the vm snapshots, mutually exclusive with vmsnapshotid", since = "4.9")
private List<Long> ids;
@Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "state of the virtual machine snapshot")
private String state;
@ -84,4 +87,8 @@ public class ListVMSnapshotCmd extends BaseListTaggedResourcesCmd {
return s_name;
}
public List<Long> getIds() {
return ids;
}
}

View File

@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command.user.volume;
import org.apache.log4j.Logger;
import java.util.List;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandJobType;
@ -53,6 +54,9 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VolumeResponse.class, description = "the ID of the disk volume")
private Long id;
@Parameter(name=ApiConstants.IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType=VolumeResponse.class, description="the IDs of the volumes, mutually exclusive with id", since = "4.9")
private List<Long> ids;
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the disk volume")
private String volumeName;
@ -153,4 +157,8 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd {
response.setResponseName(getCommandName());
setResponseObject(response);
}
public List<Long> getIds() {
return ids;
}
}

View File

@ -0,0 +1,62 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.api.query;
import java.util.ArrayList;
import java.util.List;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.SearchCriteria;
public class MutualExclusiveIdsManagerBase extends ManagerBase {
/***
* Include ids list in query criteria if ids is not null
* @param sc search criteria, class type SearchCriteria<Z>
* @param ids ids list, class type List<T>
*/
protected <Z,T> void setIdsListToSearchCriteria(SearchCriteria<Z> sc, List<T> ids){
if (ids != null && !ids.isEmpty()) {
sc.setParameters("idIN", ids.toArray());
}
}
/***
* Mutually exclusive parameters id and ids for API calls.<br/>
* Retrieve a list of ids or a list containing id depending on which of them is not null, or null if both are null
* @param id entity id, class type T
* @param ids entities ids, class type List<T>
* @return if id is not null return a list containing id else return ids, if both parameters are null -> return null
* @throws InvalidParameterValueException - if id and ids are both not null
*/
protected <T> List<T> getIdsListFromCmd(T id, List<T> ids){
List<T> idsList = null;
if (id != null) {
if (ids != null && !ids.isEmpty()) {
throw new InvalidParameterValueException("Specify either id or ids but not both parameters");
}
idsList = new ArrayList<T>();
idsList.add(id);
} else {
idsList = ids;
}
return idsList;
}
}

View File

@ -205,7 +205,6 @@ import com.cloud.utils.DateUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
@ -222,7 +221,7 @@ import com.cloud.vm.dao.UserVmDetailsDao;
import com.cloud.vm.dao.VMInstanceDao;
@Component
public class QueryManagerImpl extends ManagerBase implements QueryService, Configurable {
public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements QueryService, Configurable {
public static final Logger s_logger = Logger.getLogger(QueryManagerImpl.class);
@ -1731,6 +1730,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
Long zoneId = cmd.getZoneId();
Long podId = cmd.getPodId();
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
cmd.getDomainId(), cmd.isRecursive(), null);
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts,
@ -1754,6 +1755,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE);
sb.and("instanceId", sb.entity().getVmId(), SearchCriteria.Op.EQ);
sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
@ -1790,6 +1792,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
sc.setParameters("display", display);
}
setIdsListToSearchCriteria(sc, ids);
sc.setParameters("systemUse", 1);
if (tags != null && !tags.isEmpty()) {
@ -3077,14 +3081,15 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
return searchForTemplatesInternal(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null,
cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, showDomr,
cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedTmpl);
cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedTmpl,
cmd.getIds());
}
private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long templateId, String name,
String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize,
Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady,
List<Account> permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria,
Map<String, String> tags, boolean showRemovedTmpl) {
Map<String, String> tags, boolean showRemovedTmpl, List<Long> ids) {
// check if zone is configured, if not, just return empty list
List<HypervisorType> hypers = null;
@ -3104,6 +3109,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
SearchBuilder<TemplateJoinVO> sb = _templateJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getTempZonePair()); // select distinct (templateId, zoneId) pair
if (ids != null && !ids.isEmpty()){
sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
}
SearchCriteria<TemplateJoinVO> sc = sb.create();
// verify templateId parameter and specially handle it
@ -3149,6 +3157,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
// hypers = _resourceMgr.listAvailHypervisorInZone(null, null);
// }
setIdsListToSearchCriteria(sc, ids);
// add criteria for project or not
if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) {
sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT);
@ -3386,7 +3396,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
return searchForTemplatesInternal(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true,
cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, true,
cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO);
cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO,
null);
}
@Override

View File

@ -58,6 +58,7 @@ import com.cloud.agent.api.Command;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.alert.AlertManager;
import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd;
import com.cloud.api.query.MutualExclusiveIdsManagerBase;
import com.cloud.configuration.Config;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.dc.ClusterVO;
@ -112,7 +113,6 @@ import com.cloud.utils.DateUtil.IntervalType;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.JoinBuilder;
@ -129,7 +129,7 @@ import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
@Component
public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, SnapshotApiService {
public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implements SnapshotManager, SnapshotApiService {
private static final Logger s_logger = Logger.getLogger(SnapshotManagerImpl.class);
@Inject
VMTemplateDao _templateDao;
@ -512,6 +512,8 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
}
}
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
Long domainId = domainIdRecursiveListProject.first();
@ -526,6 +528,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ);
sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
sb.and("snapshotTypeEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.IN);
sb.and("snapshotTypeNEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.NEQ);
sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
@ -565,6 +568,8 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
sc.setParameters("dataCenterId", zoneId);
}
setIdsListToSearchCriteria(sc, ids);
if (name != null) {
sc.setParameters("name", "%" + name + "%");
}

View File

@ -46,6 +46,7 @@ import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO;
import org.apache.cloudstack.jobs.JobInfo;
import org.apache.cloudstack.utils.identity.ManagementServerNode;
import com.cloud.api.query.MutualExclusiveIdsManagerBase;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
@ -77,7 +78,6 @@ import com.cloud.utils.Pair;
import com.cloud.utils.Predicate;
import com.cloud.utils.ReflectionUse;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.SearchBuilder;
@ -99,7 +99,7 @@ import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
@Component
public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotManager, VMSnapshotService, VmWorkJobHandler {
public class VMSnapshotManagerImpl extends MutualExclusiveIdsManagerBase implements VMSnapshotManager, VMSnapshotService, VmWorkJobHandler {
private static final Logger s_logger = Logger.getLogger(VMSnapshotManagerImpl.class);
public static final String VM_WORK_JOB_HANDLER = VMSnapshotManagerImpl.class.getSimpleName();
@ -176,6 +176,8 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
String name = cmd.getVmSnapshotName();
String accountName = cmd.getAccountName();
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
cmd.getDomainId(), cmd.isRecursive(), null);
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll,
@ -193,6 +195,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
sb.and("status", sb.entity().getState(), SearchCriteria.Op.IN);
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
sb.and("display_name", sb.entity().getDisplayName(), SearchCriteria.Op.EQ);
sb.and("account_id", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
sb.done();
@ -209,6 +212,8 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
sc.setParameters("vm_id", vmId);
}
setIdsListToSearchCriteria(sc, ids);
if (domainId != null) {
sc.setParameters("domain_id", domainId);
}

View File

@ -0,0 +1,102 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.api.query;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.never;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.db.SearchCriteria;
@RunWith(MockitoJUnitRunner.class)
public class MutualExclusiveIdsManagerBaseTest {
@Mock
SearchCriteria<String> sc;
private static Long id1 = 1L;
private static Long id2 = 2L;
private List<Long> idsList;
private List<Long> idsEmptyList;
private List<Long> expectedListId;
private List<Long> expectedListIds;
private MutualExclusiveIdsManagerBase mgr = new MutualExclusiveIdsManagerBase();
@Before
public void setup() {
idsList = Arrays.asList(id1, id2);
idsEmptyList = Arrays.asList();
expectedListId = Arrays.asList(id1);
expectedListIds = Arrays.asList(id1, id2);
}
@Test
public void testSetIdsListToSearchCriteria(){
mgr.setIdsListToSearchCriteria(sc, idsList);
Mockito.verify(sc).setParameters(Mockito.same("idIN"), Mockito.same(id1), Mockito.same(id2));
}
@Test
public void testSetIdsListToSearchCriteriaEmptyList(){
mgr.setIdsListToSearchCriteria(sc, idsEmptyList);
Mockito.verify(sc, never()).setParameters(Mockito.anyString(), Mockito.any());
}
@Test
public void testGetIdsListId(){
List<Long> result = mgr.getIdsListFromCmd(id1, idsEmptyList);
assertEquals(expectedListId, result);
}
@Test
public void testGetIdsListProvideList(){
List<Long> result = mgr.getIdsListFromCmd(null, idsList);
assertEquals(expectedListIds, result);
}
@Test(expected=InvalidParameterValueException.class)
public void testGetIdsListBothNotNull(){
mgr.getIdsListFromCmd(id1, idsList);
}
@Test
public void testGetIdsListBothNull(){
List<Long> result = mgr.getIdsListFromCmd(null, null);
assertNull(result);
}
@Test
public void testGetIdsEmptyListIdNull(){
List<Long> result = mgr.getIdsListFromCmd(null, idsEmptyList);
assertEquals(idsEmptyList, result);
}
}

View File

@ -0,0 +1,295 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
""" Tests for API listing methods using 'ids' parameter
"""
#Import Local Modules
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.utils import (cleanup_resources,
validateList)
from marvin.lib.base import (Account,
Volume,
DiskOffering,
Template,
ServiceOffering,
Snapshot,
VmSnapshot,
VirtualMachine)
from marvin.lib.common import (get_domain,
get_zone, get_template)
from marvin.codes import FAILED, PASS
from nose.plugins.attrib import attr
#Import System modules
import time
_multiprocess_shared_ = True
class TestListIdsParams(cloudstackTestCase):
@classmethod
def setUpClass(cls):
testClient = super(TestListIdsParams, cls).getClsTestClient()
cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig()
cls.hypervisor = testClient.getHypervisorInfo()
cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.disk_offering = DiskOffering.create(
cls.apiclient,
cls.services["disk_offering"]
)
cls.account = Account.create(
cls.apiclient,
cls.services["account"],
domainid=cls.domain.id
)
cls.service_offering = ServiceOffering.create(
cls.apiclient,
cls.services["service_offerings"]["tiny"]
)
template = get_template(
cls.apiclient,
cls.zone.id,
cls.services["ostype"]
)
if template == FAILED:
assert False, "get_template() failed to return template with description %s" % cls.services["ostype"]
cls.services["template"]["ostypeid"] = template.ostypeid
cls.services["template_2"]["ostypeid"] = template.ostypeid
cls.services["ostypeid"] = template.ostypeid
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
cls.services["mode"] = cls.zone.networktype
#Create 3 VMs
cls.virtual_machine_1 = VirtualMachine.create(
cls.apiclient,
cls.services["virtual_machine"],
templateid=template.id,
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.service_offering.id,
mode=cls.services["mode"]
)
cls.virtual_machine_2 = VirtualMachine.create(
cls.apiclient,
cls.services["virtual_machine"],
templateid=template.id,
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.service_offering.id,
mode=cls.services["mode"]
)
cls.virtual_machine_3 = VirtualMachine.create(
cls.apiclient,
cls.services["virtual_machine"],
templateid=template.id,
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.service_offering.id,
mode=cls.services["mode"]
)
#Take 3 VM1 Snapshots
#PLEASE UNCOMMENT ONCE VM SNAPSHOT DELAY BUG AFTER VM CREATION IS FIXED
"""cls.vmsnapshot_1 = VmSnapshot.create(
cls.apiclient,
cls.virtual_machine_1.id
)
cls.vmsnapshot_2 = VmSnapshot.create(
cls.apiclient,
cls.virtual_machine_1.id
)
cls.vmsnapshot_3 = VmSnapshot.create(
cls.apiclient,
cls.virtual_machine_1.id
)"""
#Stop VMs
cls.virtual_machine_1.stop(cls.apiclient)
cls.virtual_machine_2.stop(cls.apiclient)
cls.virtual_machine_3.stop(cls.apiclient)
#Get ROOT volumes of 3 VMs
vm1RootVolumeResponse = Volume.list(
cls.apiclient,
virtualmachineid=cls.virtual_machine_1.id,
type='ROOT',
listall=True
)
vm2RootVolumeResponse = Volume.list(
cls.apiclient,
virtualmachineid=cls.virtual_machine_2.id,
type='ROOT',
listall=True
)
vm3RootVolumeResponse = Volume.list(
cls.apiclient,
virtualmachineid=cls.virtual_machine_3.id,
type='ROOT',
listall=True
)
cls.vm1_root_volume = vm1RootVolumeResponse[0]
cls.vm2_root_volume = vm2RootVolumeResponse[0]
cls.vm3_root_volume = vm3RootVolumeResponse[0]
#Take 3 snapshots of VM2's ROOT volume
cls.snapshot_1 = Snapshot.create(
cls.apiclient,
cls.vm2_root_volume.id,
account=cls.account.name,
domainid=cls.account.domainid
)
cls.snapshot_2 = Snapshot.create(
cls.apiclient,
cls.vm2_root_volume.id,
account=cls.account.name,
domainid=cls.account.domainid
)
cls.snapshot_3 = Snapshot.create(
cls.apiclient,
cls.vm2_root_volume.id,
account=cls.account.name,
domainid=cls.account.domainid
)
#Create 3 templates
cls.template_1 = Template.create(
cls.apiclient,
cls.services["template"],
cls.vm3_root_volume.id,
account=cls.account.name,
domainid=cls.account.domainid
)
cls.template_2 = Template.create(
cls.apiclient,
cls.services["template_2"],
cls.vm3_root_volume.id,
account=cls.account.name,
domainid=cls.account.domainid
)
cls.template_3 = Template.create(
cls.apiclient,
cls.services["template_2"],
cls.vm3_root_volume.id,
account=cls.account.name,
domainid=cls.account.domainid
)
cls._cleanup = [
cls.disk_offering,
cls.account,
cls.service_offering,
cls.snapshot_1,
cls.snapshot_2,
cls.snapshot_3
]
@classmethod
def tearDownClass(cls):
cls.apiclient = super(TestListIdsParams, cls).getClsTestClient().getApiClient()
try:
cleanup_resources(cls.apiclient, cls._cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
def test_01_list_volumes(self):
"""Test listing Volumes using 'ids' parameter
"""
list_volume_response = Volume.list(
self.apiclient,
ids=[self.vm1_root_volume.id, self.vm2_root_volume.id, self.vm3_root_volume.id],
type='ROOT',
listAll=True
)
self.assertEqual(
isinstance(list_volume_response, list),
True,
"List Volume response was not a valid list"
)
self.assertEqual(
len(list_volume_response),
3,
"ListVolumes response expected 3 Volumes, received %s" % len(list_volume_response)
)
@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
def test_02_list_templates(self):
"""Test listing Templates using 'ids' parameter
"""
list_template_response = Template.list(
self.apiclient,
templatefilter='all',
ids=[self.template_1.id, self.template_2.id, self.template_3.id],
account=self.account.name,
domainid=self.account.domainid,
listAll=True
)
self.assertEqual(
isinstance(list_template_response, list),
True,
"ListTemplates response was not a valid list"
)
self.assertEqual(
len(list_template_response),
3,
"ListTemplates response expected 3 Templates, received %s" % len(list_template_response)
)
@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
def test_03_list_snapshots(self):
"""Test listing Snapshots using 'ids' parameter
"""
list_snapshot_response = Snapshot.list(
self.apiclient,
ids=[self.snapshot_1.id, self.snapshot_2.id, self.snapshot_3.id],
listAll=True
)
self.assertEqual(
isinstance(list_snapshot_response, list),
True,
"ListSnapshots response was not a valid list"
)
self.assertEqual(
len(list_snapshot_response),
3,
"ListSnapshots response expected 3 Snapshots, received %s" % len(list_snapshot_response)
)
#PLEASE UNCOMMENT ONCE VM SNAPSHOT DELAY BUG AFTER VM CREATION IS FIXED
#@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
#def test_04_list_vm_snapshots(self):
"""Test listing VMSnapshots using 'vmsnapshotids' parameter
"""
"""list_vm_snapshot_response = VmSnapshot.list(
self.apiclient,
vmsnapshotids=[self.vmsnapshot_1.id, self.vmsnapshot_2.id, self.vmsnapshot_3.id],
listall=True
)
self.assertEqual(
isinstance(list_vm_snapshot_response, list),
True,
"ListVMSnapshots response was not a valid list"
)
self.assertEqual(
len(list_vm_snapshot_response),
3,
"ListVMSnapshots response expected 3 VMSnapshots, received %s" % len(list_vm_snapshot_response)
)"""