You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2014/01/04 02:18:54 UTC

git commit: updated refs/heads/rbac to d374cd5

Updated Branches:
  refs/heads/rbac 04a0d12a6 -> d374cd5a2


Add Unit Testcases for AclApiService.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d374cd5a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d374cd5a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d374cd5a

Branch: refs/heads/rbac
Commit: d374cd5a2c16536da60a28f236bb341f2dec72db
Parents: 04a0d12
Author: Min Chen <mi...@citrix.com>
Authored: Fri Jan 3 17:18:27 2014 -0800
Committer: Min Chen <mi...@citrix.com>
Committed: Fri Jan 3 17:18:44 2014 -0800

----------------------------------------------------------------------
 server/src/com/cloud/api/ApiServerService.java  |   2 +-
 services/iam/plugin/pom.xml                     |  11 +-
 .../cloudstack/acl/api/AclApiServiceImpl.java   |  82 +----
 .../acl/api/response/AclGroupResponse.java      |  24 ++
 .../acl/api/response/AclPolicyResponse.java     |  20 ++
 .../cloudstack/acl/AclApiServiceTest.java       | 344 +++++++++++++++++++
 .../iam/plugin/test/resources/db.properties     |  75 ++++
 7 files changed, 474 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d374cd5a/server/src/com/cloud/api/ApiServerService.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServerService.java b/server/src/com/cloud/api/ApiServerService.java
index 4a4ae1e..2d6eba5 100644
--- a/server/src/com/cloud/api/ApiServerService.java
+++ b/server/src/com/cloud/api/ApiServerService.java
@@ -36,5 +36,5 @@ public interface ApiServerService {
 
     public String handleRequest(Map params, String responseType, StringBuffer auditTrailSb) throws ServerApiException;
 
-    public Class<?> getCmdClass(String cmdName);
+    public Class getCmdClass(String cmdName);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d374cd5a/services/iam/plugin/pom.xml
----------------------------------------------------------------------
diff --git a/services/iam/plugin/pom.xml b/services/iam/plugin/pom.xml
index e674100..92dcd8c 100644
--- a/services/iam/plugin/pom.xml
+++ b/services/iam/plugin/pom.xml
@@ -36,7 +36,7 @@
       <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-engine-schema</artifactId>
       <version>${project.version}</version>    
-    </dependency>   
+    </dependency> 
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-server</artifactId>
@@ -46,6 +46,13 @@
       <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-iam</artifactId>
       <version>${project.version}</version>    
-    </dependency>            
+    </dependency>  
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-api</artifactId>
+      <version>${project.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>              
   </dependencies> 
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d374cd5a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
index 8e09501..02d015c 100644
--- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
+++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
@@ -17,7 +17,6 @@
 package org.apache.cloudstack.acl.api;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 
 import javax.ejb.Local;
@@ -48,14 +47,10 @@ import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
 import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Volume;
-import com.cloud.template.VirtualMachineTemplate;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.AccountVO;
 import com.cloud.user.dao.AccountDao;
-import com.cloud.uservm.UserVm;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.Manager;
 import com.cloud.utils.component.ManagerBase;
@@ -82,17 +77,6 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
     @Inject
     AccountManager _accountMgr;
 
-
-    public static HashMap<String, Class> entityClassMap = new HashMap<String, Class>();
-
-    static {
-        entityClassMap.put("VirtualMachine", UserVm.class);
-        entityClassMap.put("Volume", Volume.class);
-        entityClassMap.put("Template", VirtualMachineTemplate.class);
-        entityClassMap.put("Snapshot", Snapshot.class);
-        // To be filled in later depending on the entity permission grant scope
-    }
-
     @DB
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_ACL_GROUP_CREATE, eventDescription = "Creating Acl Group", create = true)
@@ -165,70 +149,6 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
         return _iamSrv.removeAclPoliciesFromGroup(policyIds, groupId);
     }
 
-    /*
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ACL_POLICY_GRANT, eventDescription = "Granting permission to Acl Role")
-    public AclP addAclPermissionToAclPolicy(final long aclRoleId, final List<String> apiNames) {
-        Account caller = CallContext.current().getCallingAccount();
-        // get the Acl Role entity
-        AclRole role = _aclPolicyDao.findById(aclRoleId);
-        if (role == null) {
-            throw new InvalidParameterValueException("Unable to find acl role: " + aclRoleId
-                    + "; failed to grant permission to role.");
-        }
-        // check permissions
-        _accountMgr.checkAccess(caller, null, true, role);
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // add entries in acl_api_permission table
-                for (String api : apiNames) {
-                    AclApiPermissionVO perm = _apiPermissionDao.findByRoleAndApi(aclRoleId, api);
-                    if (perm == null) {
-                        // not there already
-                        perm = new AclApiPermissionVO(aclRoleId, api);
-                        _apiPermissionDao.persist(perm);
-                    }
-                }
-            }
-        });
-            
-        return role;
-
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ACL_POLICY_REVOKE, eventDescription = "Revoking permission from Acl Role")
-    public AclRole revokeApiPermissionFromAclRole(final long aclRoleId, final List<String> apiNames) {
-        Account caller = CallContext.current().getCallingAccount();
-        // get the Acl Role entity
-        AclRole role = _aclPolicyDao.findById(aclRoleId);
-        if (role == null) {
-            throw new InvalidParameterValueException("Unable to find acl role: " + aclRoleId
-                    + "; failed to revoke permission from role.");
-        }
-        // check permissions
-        _accountMgr.checkAccess(caller, null, true, role);
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // remove entries from acl_api_permission table
-                for (String api : apiNames) {
-                    AclApiPermissionVO perm = _apiPermissionDao.findByRoleAndApi(aclRoleId, api);
-                    if (perm != null) {
-                        // not removed yet
-                        _apiPermissionDao.remove(perm.getId());
-                    }
-                }
-            }
-        });
-        return role;
-    }
-    */
 
     @DB
     @Override
@@ -350,7 +270,7 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
         List<Long> members = _iamSrv.listAccountsByGroup(group.getId());
         if (members != null && members.size() > 0) {
             for (Long member : members) {
-                AccountVO mem = _accountDao.findById(accountId);
+                AccountVO mem = _accountDao.findById(member);
                 if (mem != null) {
                     response.addMemberAccount(mem.getAccountName());
                 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d374cd5a/services/iam/plugin/src/org/apache/cloudstack/acl/api/response/AclGroupResponse.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/response/AclGroupResponse.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/response/AclGroupResponse.java
index 209aa7a..14f7fd2 100644
--- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/response/AclGroupResponse.java
+++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/response/AclGroupResponse.java
@@ -121,6 +121,30 @@ public class AclGroupResponse extends BaseResponse implements ControlledViewEnti
 
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public String getDomainName() {
+        return domainName;
+    }
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public Set<String> getAccountNameList() {
+        return accountNameList;
+    }
+
     public void setMemberAccounts(Set<String> accts) {
         accountNameList = accts;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d374cd5a/services/iam/plugin/src/org/apache/cloudstack/acl/api/response/AclPolicyResponse.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/response/AclPolicyResponse.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/response/AclPolicyResponse.java
index 5a6db0c..83014ac 100644
--- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/response/AclPolicyResponse.java
+++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/response/AclPolicyResponse.java
@@ -127,6 +127,26 @@ public class AclPolicyResponse extends BaseResponse implements ControlledViewEnt
 
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public String getDomainName() {
+        return domainName;
+    }
+
+    public String getAccountName() {
+        return accountName;
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d374cd5a/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java b/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
new file mode 100644
index 0000000..9604e01
--- /dev/null
+++ b/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
@@ -0,0 +1,344 @@
+package org.apache.cloudstack.acl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.acl.api.AclApiService;
+import org.apache.cloudstack.acl.api.AclApiServiceImpl;
+import org.apache.cloudstack.acl.api.response.AclGroupResponse;
+import org.apache.cloudstack.acl.api.response.AclPermissionResponse;
+import org.apache.cloudstack.acl.api.response.AclPolicyResponse;
+import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.iam.api.AclGroup;
+import org.apache.cloudstack.iam.api.AclPolicy;
+import org.apache.cloudstack.iam.api.AclPolicyPermission;
+import org.apache.cloudstack.iam.api.AclPolicyPermission.Permission;
+import org.apache.cloudstack.iam.api.IAMService;
+import org.apache.cloudstack.iam.server.AclGroupVO;
+import org.apache.cloudstack.iam.server.AclPolicyPermissionVO;
+import org.apache.cloudstack.iam.server.AclPolicyVO;
+import org.apache.cloudstack.test.utils.SpringUtils;
+
+import com.cloud.api.ApiServerService;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ComponentContext;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class AclApiServiceTest {
+
+    @Inject
+    IAMService _iamSrv;
+
+    @Inject
+    DomainDao _domainDao;
+
+    @Inject
+    AclApiService _aclSrv;
+
+    @Inject
+    AccountManager _accountMgr;
+
+    @Inject
+    AccountDao _accountDao;
+
+    @Inject
+    ApiServerService _apiServer;
+
+    private static Account caller;
+    private static Long callerId;
+    private static String callerAccountName = "tester";
+    private static Long callerDomainId = 3L;
+    private static String callerDomainPath = "/root/testdomain";
+    private static DomainVO callerDomain;
+
+    @BeforeClass
+    public static void setUpClass() throws ConfigurationException {
+    }
+
+    @Before
+    public void setUp() {
+        ComponentContext.initComponentsLifeCycle();
+        caller = new AccountVO(callerAccountName, callerDomainId, null, Account.ACCOUNT_TYPE_ADMIN, UUID.randomUUID().toString());
+        callerId = caller.getId();
+        callerDomain = new DomainVO();
+        callerDomain.setPath(callerDomainPath);
+        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
+        CallContext.register(user, caller);
+
+        when(_domainDao.findById(callerDomainId)).thenReturn(callerDomain);
+        doNothing().when(_accountMgr).checkAccess(caller, callerDomain);
+    }
+
+    @Test
+    public void createAclGroupTest() {
+        AclGroup group = new AclGroupVO("group1", "tester group1");
+        List<AclGroup> groups = new ArrayList<AclGroup>();
+        groups.add(group);
+        Pair<List<AclGroup>, Integer> grpList = new Pair<List<AclGroup>, Integer>(groups, 1);
+        when(_iamSrv.createAclGroup("group1", "tester group1", callerDomainPath)).thenReturn(group);
+        when(_iamSrv.listAclGroups(null, null, callerDomainPath, 0L, 20L)).thenReturn(grpList);
+
+        AclGroup createdGrp = _aclSrv.createAclGroup(caller, "group1", "tester group1");
+        assertNotNull("Acl group 'group1' failed to create ", createdGrp);
+        ListResponse<AclGroupResponse> grpResp = _aclSrv.listAclGroups(null, null, callerDomainId, 0L, 20L);
+        assertTrue("No. of response items should be one", grpResp.getCount() == 1);
+        AclGroupResponse resp = grpResp.getResponses().get(0);
+        assertEquals("Error in created group name", "group1", resp.getName());
+    }
+
+    @Test
+    public void deleteAclGroupTest() {
+        when(_iamSrv.deleteAclGroup(1L)).thenReturn(true);
+        assertTrue("failed to delete acl group 1", _aclSrv.deleteAclGroup(1L));
+    }
+
+    @Test
+    public void listAclGroupTest() {
+        AclGroup group = new AclGroupVO("group1", "tester group1");
+        List<AclGroup> groups = new ArrayList<AclGroup>();
+        groups.add(group);
+        when(_iamSrv.listAclGroups(callerId)).thenReturn(groups);
+        List<AclGroup> grps = _aclSrv.listAclGroups(callerId);
+        assertTrue(grps != null && grps.size() == 1);
+        AclGroup grp = grps.get(0);
+        assertEquals("Error to retrieve group", "group1", grp.getName());
+    }
+
+    @Test
+    public void addRemoveAccountToGroupTest() {
+        AclGroup group = new AclGroupVO("group1", "tester group1");
+        List<AclGroup> groups = new ArrayList<AclGroup>();
+        groups.add(group);
+        Long groupId = group.getId();
+        List<Long> acctIds = new ArrayList<Long>();
+        AccountVO acct1 = new AccountVO(100L);
+        acct1.setAccountName("account1");
+        AccountVO acct2 = new AccountVO(200L);
+        acct2.setAccountName("account2");
+        acctIds.add(acct1.getId());
+        acctIds.add(acct2.getId());
+        when(_accountDao.findById(acct1.getId())).thenReturn(acct1);
+        when(_accountDao.findById(acct2.getId())).thenReturn(acct2);
+        when(_iamSrv.addAccountsToGroup(acctIds, groupId)).thenReturn(group);
+        when(_iamSrv.listAccountsByGroup(groupId)).thenReturn(acctIds);
+        Pair<List<AclGroup>, Integer> grpList = new Pair<List<AclGroup>, Integer>(groups, 1);
+        when(_iamSrv.listAclGroups(null, "group1", callerDomainPath, 0L, 20L)).thenReturn(grpList);
+        _aclSrv.addAccountsToGroup(acctIds, groupId);
+        ListResponse<AclGroupResponse> grpResp = _aclSrv.listAclGroups(null, "group1", callerDomainId, 0L, 20L);
+        assertTrue("No. of response items should be one", grpResp.getCount() == 1);
+        AclGroupResponse resp = grpResp.getResponses().get(0);
+        Set<String> acctNames = resp.getAccountNameList();
+        assertEquals("There should be 2 accounts in the group", 2, acctNames.size());
+        assertTrue("account1 should be assigned to the group", acctNames.contains("account1"));
+        assertTrue("account2 should be assigned to the group", acctNames.contains("account2"));
+        // remove "account2" from group1
+        acctIds.remove(1);
+        List<Long> rmAccts = new ArrayList<Long>();
+        rmAccts.add(acct2.getId());
+        when(_iamSrv.removeAccountsFromGroup(rmAccts, groupId)).thenReturn(group);
+        _aclSrv.removeAccountsFromGroup(acctIds, groupId);
+        grpResp = _aclSrv.listAclGroups(null, "group1", callerDomainId, 0L, 20L);
+        assertTrue("No. of response items should be one", grpResp.getCount() == 1);
+        resp = grpResp.getResponses().get(0);
+        acctNames = resp.getAccountNameList();
+        assertEquals("There should be 1 accounts in the group", 1, acctNames.size());
+        assertFalse("account2 should not belong to the group anymore", acctNames.contains("account2"));
+    }
+
+    @Test
+    public void createAclPolicyTest() {
+        AclPolicy policy = new AclPolicyVO("policy1", "tester policy1");
+        List<AclPolicy> policies = new ArrayList<AclPolicy>();
+        policies.add(policy);
+        Pair<List<AclPolicy>, Integer> policyList = new Pair<List<AclPolicy>, Integer>(policies, 1);
+        when(_iamSrv.createAclPolicy("policy1", "tester policy1", null)).thenReturn(policy);
+        when(_iamSrv.listAclPolicies(null, null, callerDomainPath, 0L, 20L)).thenReturn(policyList);
+
+        AclPolicy createdPolicy = _aclSrv.createAclPolicy(caller, "policy1", "tester policy1", null);
+        assertNotNull("Acl policy 'policy1' failed to create ", createdPolicy);
+        ListResponse<AclPolicyResponse> policyResp = _aclSrv.listAclPolicies(null, null, callerDomainId, 0L, 20L);
+        assertTrue("No. of response items should be one", policyResp.getCount() == 1);
+        AclPolicyResponse resp = policyResp.getResponses().get(0);
+        assertEquals("Error in created group name", "policy1", resp.getName());
+    }
+
+    @Test
+    public void deleteAclPolicyTest() {
+        when(_iamSrv.deleteAclPolicy(1L)).thenReturn(true);
+        assertTrue("failed to delete acl policy 1", _aclSrv.deleteAclPolicy(1L));
+    }
+
+    @Test
+    public void listAclPolicyTest() {
+        AclPolicy policy = new AclPolicyVO("policy1", "tester policy1");
+        List<AclPolicy> policies = new ArrayList<AclPolicy>();
+        policies.add(policy);
+        when(_iamSrv.listAclPolicies(callerId)).thenReturn(policies);
+        List<AclPolicy> polys = _aclSrv.listAclPolicies(callerId);
+        assertTrue(polys != null && polys.size() == 1);
+        AclPolicy p = polys.get(0);
+        assertEquals("Error to retrieve group", "policy1", p.getName());
+    }
+
+    @Test
+    public void addRemovePolicyToGroupTest() {
+        AclGroup group = new AclGroupVO("group1", "tester group1");
+        List<AclGroup> groups = new ArrayList<AclGroup>();
+        groups.add(group);
+        Long groupId = group.getId();
+        List<Long> policyIds = new ArrayList<Long>();
+        policyIds.add(100L);
+        policyIds.add(200L);
+        AclPolicy policy1 = new AclPolicyVO("policy1", "my first policy");
+        AclPolicy policy2 = new AclPolicyVO("policy2", "my second policy");
+        List<AclPolicy> policies = new ArrayList<AclPolicy>();
+        policies.add(policy1);
+        policies.add(policy2);
+        when(_iamSrv.attachAclPoliciesToGroup(policyIds, groupId)).thenReturn(group);
+        when(_iamSrv.listAclPoliciesByGroup(groupId)).thenReturn(policies);
+        Pair<List<AclGroup>, Integer> grpList = new Pair<List<AclGroup>, Integer>(groups, 1);
+        when(_iamSrv.listAclGroups(null, "group1", callerDomainPath, 0L, 20L)).thenReturn(grpList);
+        _aclSrv.attachAclPoliciesToGroup(policyIds, groupId);
+        ListResponse<AclGroupResponse> grpResp = _aclSrv.listAclGroups(null, "group1", callerDomainId, 0L, 20L);
+        assertTrue("No. of response items should be one", grpResp.getCount() == 1);
+        AclGroupResponse resp = grpResp.getResponses().get(0);
+        Set<String> policyNames = resp.getPolicyList();
+        assertEquals("There should be 2 policies in the group", 2, policyNames.size());
+        assertTrue("policy1 should be assigned to the group", policyNames.contains("policy1"));
+        assertTrue("policy2 should be assigned to the group", policyNames.contains("policy2"));
+        // remove "policy2" from group1
+        policyIds.remove(1);
+        policies.remove(policy2);
+        when(_iamSrv.removeAclPoliciesFromGroup(policyIds, groupId)).thenReturn(group);
+        _aclSrv.removeAclPoliciesFromGroup(policyIds, groupId);
+        grpResp = _aclSrv.listAclGroups(null, "group1", callerDomainId, 0L, 20L);
+        assertTrue("No. of response items should be one", grpResp.getCount() == 1);
+        resp = grpResp.getResponses().get(0);
+        policyNames = resp.getPolicyList();
+        assertEquals("There should be 1 policy attached to the group", 1, policyNames.size());
+        assertFalse("policy2 should not belong to the group anymore", policyNames.contains("policy2"));
+    }
+
+    @Test
+    public void addRemovePermissionToPolicyTest() {
+        AclPolicy policy = new AclPolicyVO("policy1", "tester policy1");
+        List<AclPolicy> policies = new ArrayList<AclPolicy>();
+        policies.add(policy);
+        Long policyId = policy.getId();
+        Long resId = 200L;
+        when(_apiServer.getCmdClass("listVirtualMachines")).thenReturn(ListVMsCmd.class);
+        when(
+                _iamSrv.addAclPermissionToAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE.toString(), resId, "listVirtualMachines",
+                        AccessType.ListEntry.toString(), Permission.Allow)).thenReturn(policy);
+        _aclSrv.addAclPermissionToAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE, resId, "listVirtualMachines", Permission.Allow);
+        Pair<List<AclPolicy>, Integer> policyList = new Pair<List<AclPolicy>, Integer>(policies, 1);
+        List<AclPolicyPermission> policyPerms = new ArrayList<AclPolicyPermission>();
+        AclPolicyPermission perm = new AclPolicyPermissionVO(policyId, "listVirtualMachines", AclEntityType.VirtualMachine.toString(), AccessType.ListEntry.toString(),
+                PermissionScope.RESOURCE.toString(),
+                resId, Permission.Allow);
+        policyPerms.add(perm);
+        when(_iamSrv.listAclPolicies(null, "policy1", callerDomainPath, 0L, 20L)).thenReturn(policyList);
+        when(_iamSrv.listPolicyPermissions(policyId)).thenReturn(policyPerms);
+        ListResponse<AclPolicyResponse> policyResp = _aclSrv.listAclPolicies(null, "policy1", callerDomainId, 0L, 20L);
+        assertTrue("No. of response items should be one", policyResp.getCount() == 1);
+        AclPolicyResponse resp = policyResp.getResponses().get(0);
+        Set<AclPermissionResponse> permList = resp.getPermissionList();
+        assertTrue("Permission list should not be empty", permList != null && permList.size() > 0);
+        AclPermissionResponse permResp = permList.iterator().next();
+        assertEquals("There should be one permission for listVirtualMachines", "listVirtualMachines", permResp.getAction());
+
+        //remove permission from policy
+        policyPerms.remove(perm);
+        _aclSrv.removeAclPermissionFromAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE, resId, "listVirtualMachines");
+        policyResp = _aclSrv.listAclPolicies(null, "policy1", callerDomainId, 0L, 20L);
+        assertTrue("No. of response items should be one", policyResp.getCount() == 1);
+        resp = policyResp.getResponses().get(0);
+        permList = resp.getPermissionList();
+        assertTrue("Permission list should be empty", permList != null && permList.size() == 0);
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Configuration
+    @ComponentScan(basePackageClasses = {AclApiServiceImpl.class}, includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
+    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
+
+        @Bean
+        public DomainDao domainDao() {
+            return Mockito.mock(DomainDao.class);
+        }
+
+        @Bean
+        public IAMService iamService() {
+            return Mockito.mock(IAMService.class);
+        }
+
+        @Bean
+        public AccountDao accountDao() {
+            return Mockito.mock(AccountDao.class);
+        }
+
+        @Bean
+        public AccountManager accountManager() {
+            return Mockito.mock(AccountManager.class);
+        }
+
+        @Bean
+        public ApiServerService apiServerService() {
+            return Mockito.mock(ApiServerService.class);
+        }
+
+        public static class Library implements TypeFilter {
+
+            @Override
+            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
+                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
+                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d374cd5a/services/iam/plugin/test/resources/db.properties
----------------------------------------------------------------------
diff --git a/services/iam/plugin/test/resources/db.properties b/services/iam/plugin/test/resources/db.properties
new file mode 100644
index 0000000..e1b5fe9
--- /dev/null
+++ b/services/iam/plugin/test/resources/db.properties
@@ -0,0 +1,75 @@
+# 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.
+
+
+# management server clustering parameters, change cluster.node.IP to the machine IP address
+# in which the management server(Tomcat) is running
+cluster.node.IP=127.0.0.1
+cluster.servlet.port=9090
+region.id=1
+
+# CloudStack database settings
+db.cloud.username=cloud
+db.cloud.password=cloud
+db.root.password=
+db.cloud.host=localhost
+db.cloud.port=3306
+db.cloud.name=cloud
+
+# CloudStack database tuning parameters
+db.cloud.maxActive=250
+db.cloud.maxIdle=30
+db.cloud.maxWait=10000
+db.cloud.autoReconnect=true
+db.cloud.validationQuery=SELECT 1
+db.cloud.testOnBorrow=true
+db.cloud.testWhileIdle=true
+db.cloud.timeBetweenEvictionRunsMillis=40000
+db.cloud.minEvictableIdleTimeMillis=240000
+db.cloud.poolPreparedStatements=false
+db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true&prepStmtCacheSqlLimit=4096
+
+# usage database settings
+db.usage.username=cloud
+db.usage.password=cloud
+db.usage.host=localhost
+db.usage.port=3306
+db.usage.name=cloud_usage
+
+# usage database tuning parameters
+db.usage.maxActive=100
+db.usage.maxIdle=30
+db.usage.maxWait=10000
+db.usage.autoReconnect=true
+
+# awsapi database settings
+db.awsapi.username=cloud
+db.awsapi.password=cloud
+db.awsapi.host=localhost
+db.awsapi.port=3306
+db.awsapi.name=cloudbridge
+
+# Simulator database settings
+db.simulator.username=cloud
+db.simulator.password=cloud
+db.simulator.host=localhost
+db.simulator.port=3306
+db.simulator.name=simulator
+db.simulator.maxActive=250
+db.simulator.maxIdle=30
+db.simulator.maxWait=10000
+db.simulator.autoReconnect=true