/* * RHQ Management Platform * Copyright (C) 2005-2010 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.server.resource.group.test; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.testng.annotations.Test; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.criteria.ResourceCriteria; import org.rhq.core.domain.criteria.ResourceGroupCriteria; import org.rhq.core.domain.resource.InventoryStatus; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.group.ResourceGroup; import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite; import org.rhq.core.domain.util.OrderingField; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; import org.rhq.core.domain.util.PageOrdering; import org.rhq.enterprise.server.authz.AuthorizationManagerLocal; import org.rhq.enterprise.server.resource.ResourceManagerLocal; import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal; import org.rhq.enterprise.server.test.LargeGroupTestBase; import org.rhq.enterprise.server.test.TestServerCommunicationsService; import org.rhq.enterprise.server.test.TransactionCallback; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.util.SessionTestHelper; @Test public class LargeGroupCriteriaTest extends LargeGroupTestBase { private static final boolean TEST_ENABLED = true; private ArrayList<LargeGroupEnvironment> env; private List<ResourceGroup> globalGroups; private class GroupAvailCounts { public final int up; public final int down; public final int unknown; public final int disabled; public final int uncommitted; public final int total; public final int visibleTotal; GroupAvailCounts(int up, int down, int unknown, int disabled) { this(up, down, unknown, disabled, 0); } GroupAvailCounts(int up, int down, int unknown, int disabled, int uncommitted) { this.up = up; this.down = down; this.unknown = unknown; this.disabled = disabled; this.uncommitted = uncommitted; this.total = up + down + unknown + disabled + uncommitted; this.visibleTotal = up + down + unknown + disabled; // uncommitted is not included } } @Override protected void setupMockAgentServices(TestServerCommunicationsService agentServiceContainer) { } /** * Remove the group and all its members. */ @Override protected void afterMethod() throws Exception { tearDownGroups(); super.afterMethod(); } private void tearDownGroups() throws Exception { if (env != null) { System.out.println("Tearing down groups..."); Iterator<LargeGroupEnvironment> iter = env.iterator(); while (iter.hasNext()) { LargeGroupEnvironment doomed = iter.next(); tearDownLargeGroupWithNormalUserRoleAccess(doomed, iter.hasNext()); SessionTestHelper.simulateLogout(doomed.normalSubject); } env = null; } if (globalGroups != null) { Iterator<ResourceGroup> iter = globalGroups.iterator(); while (iter.hasNext()) { resourceGroupManager.deleteResourceGroup(getOverlord(), iter.next().getId()); } globalGroups = null; } } @Test(enabled = TEST_ENABLED) public void testSearchBarAvailabilityQueryUP() throws Exception { GroupAvailCounts gac = new GroupAvailCounts(5, 0, 0, 0); PageList<ResourceGroupComposite> pageList = testGroupQueriesWithSearchBar(gac, "availability=up"); assert pageList.size() == 1; tearDownGroups(); pageList = testGroupQueriesWithSearchBar(gac, "availability != up"); assert pageList.size() == 0; } @Test(enabled = TEST_ENABLED) public void testSearchBarAvailabilityQueryDOWN() throws Exception { GroupAvailCounts gac = new GroupAvailCounts(0, 5, 0, 0); PageList<ResourceGroupComposite> pageList = testGroupQueriesWithSearchBar(gac, "availability=down"); assert pageList.size() == 1; tearDownGroups(); pageList = testGroupQueriesWithSearchBar(gac, "availability != down"); assert pageList.size() == 0; } @Test(enabled = TEST_ENABLED) public void testSearchBarAvailabilityQueryDISABLED() throws Exception { GroupAvailCounts gac = new GroupAvailCounts(0, 0, 0, 5); PageList<ResourceGroupComposite> pageList = testGroupQueriesWithSearchBar(gac, "availability=disabled"); assert pageList.size() == 1; tearDownGroups(); pageList = testGroupQueriesWithSearchBar(gac, "availability != disabled"); assert pageList.size() == 0; } @Test(enabled = TEST_ENABLED) public void testSearchBarAvailabilityQueryMIXED() throws Exception { // when a group has a mix of up/down/disabled resources, it will not be returned with the avail search expression GroupAvailCounts gac = new GroupAvailCounts(2, 2, 0, 2); PageList<ResourceGroupComposite> pageList = testGroupQueriesWithSearchBar(gac, "availability=up"); assert pageList.size() == 0; tearDownGroups(); pageList = testGroupQueriesWithSearchBar(gac, "availability=down"); assert pageList.size() == 0; tearDownGroups(); pageList = testGroupQueriesWithSearchBar(gac, "availability=disabled"); assert pageList.size() == 0; } @Test(enabled = TEST_ENABLED) public void testUncommitted() throws Exception { ArrayList<GroupAvailCounts> gacs = new ArrayList<LargeGroupCriteriaTest.GroupAvailCounts>(); gacs.add(new GroupAvailCounts(1, 1, 1, 1, 1)); testGroupQueries(gacs); } @Test(enabled = TEST_ENABLED) public void testSmallGroupsWithUncommitted() throws Exception { ArrayList<GroupAvailCounts> gacs = new ArrayList<LargeGroupCriteriaTest.GroupAvailCounts>(); gacs.add(new GroupAvailCounts(8, 4, 2, 1, 1)); gacs.add(new GroupAvailCounts(2, 4, 6, 8, 10)); testGroupQueries(gacs); } @Test(enabled = TEST_ENABLED) public void testSmallGroups() throws Exception { ArrayList<GroupAvailCounts> gacs = new ArrayList<LargeGroupCriteriaTest.GroupAvailCounts>(); gacs.add(new GroupAvailCounts(8, 4, 2, 1)); gacs.add(new GroupAvailCounts(2, 4, 6, 8)); testGroupQueries(gacs); } @Test(enabled = TEST_ENABLED) public void testLotsOfSmallGroups() throws Exception { ArrayList<GroupAvailCounts> gacs = new ArrayList<LargeGroupCriteriaTest.GroupAvailCounts>(); for (int i = 0; i < 50; i++) { gacs.add(new GroupAvailCounts(1, 1, 1, 1)); gacs.add(new GroupAvailCounts(2, 2, 2, 2)); } testGroupQueries(gacs); } @Test(enabled = TEST_ENABLED) public void testLargeGroup() throws Exception { ArrayList<GroupAvailCounts> gacs = new ArrayList<LargeGroupCriteriaTest.GroupAvailCounts>(); gacs.add(new GroupAvailCounts(500, 250, 150, 110)); // purposefully over 1,000 testGroupQueries(gacs); } @Test(enabled = TEST_ENABLED) public void testLotsOfLargeGroups() throws Exception { ArrayList<GroupAvailCounts> gacs = new ArrayList<LargeGroupCriteriaTest.GroupAvailCounts>(); for (int i = 0; i < 5; i++) { gacs.add(new GroupAvailCounts(10, 10, 10, 10)); gacs.add(new GroupAvailCounts(20, 20, 20, 20)); } testGroupQueries(gacs); } @Test(enabled = TEST_ENABLED) public void testVariousCriteriaQueries() throws Exception { globalGroups = new ArrayList<ResourceGroup>(); // create 10 empty groups executeInTransaction(false, new TransactionCallback() { @Override public void execute() throws Exception { for (int i = 0; i < 10; i++) { ResourceGroup group = SessionTestHelper.createNewCompatibleGroupForRole(em, null, "LargeGroupTestCompatGroup", null); globalGroups.add(group); } } }); ResourceGroupManagerLocal groupManager = LookupUtil.getResourceGroupManager(); ResourceGroupCriteria criteria = new ResourceGroupCriteria(); // test ordering criteria.addSortName(PageOrdering.DESC); PageList<ResourceGroupComposite> result = groupManager.findResourceGroupCompositesByCriteria(getOverlord(), criteria); assert result.size() == 10 : "Expected to return 10 group composites, but was " + result.size(); // test custom page size criteria = new ResourceGroupCriteria(); criteria.setPageControl(new PageControl(0, 2)); result = groupManager.findResourceGroupCompositesByCriteria(getOverlord(), criteria); assert result.size() == 2 : "Expected to return 2 group composites when paging is enabled"; assert result.getTotalSize() == 10 : "Expected 10 group composites as total pageList size"; // test custom page size and ordering within pageControl criteria = new ResourceGroupCriteria(); criteria.setPageControl(new PageControl(0, 2, new OrderingField("name", PageOrdering.DESC))); result = groupManager.findResourceGroupCompositesByCriteria(getOverlord(), criteria); assert result.size() == 2 : "Expected to return 2 group composites when paging is enabled"; assert result.getTotalSize() == 10 : "Expected 10 group composites as total pageList size"; } // test findResourcesByCriteriaBounded here instead of ResourceGroupManagerBeanTest because we want // to work with a decent # or resources. @Test(enabled = TEST_ENABLED) public void testResourceCriteriaBounded() throws Exception { ArrayList<GroupAvailCounts> gacs = new ArrayList<LargeGroupCriteriaTest.GroupAvailCounts>(); gacs.add(new GroupAvailCounts(1100, 0, 0, 0)); // purposefully over 1,000, avails don't really matter ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); AuthorizationManagerLocal authManager = LookupUtil.getAuthorizationManager(); env = new ArrayList<LargeGroupEnvironment>(gacs.size()); LargeGroupEnvironment lgeWithTypes = null; for (GroupAvailCounts gac : gacs) { env.add(createLargeGroupWithNormalUserRoleAccessWithInventoryStatus(lgeWithTypes, gac.total, gac.down, gac.unknown, gac.disabled, gac.uncommitted, Permission.CONFIGURE_READ)); lgeWithTypes = env.get(0); } ResourceCriteria criteria = new ResourceCriteria(); List<Resource> result; SessionTestHelper.simulateLogin(env.get(0).normalSubject); criteria.addFilterParentResourceId(lgeWithTypes.platformResource.getId()); criteria.setPageControl(PageControl.getUnlimitedInstance()); result = resourceManager.findResourcesByCriteria(env.get(0).normalSubject, criteria); assert null != result; assert result.size() == 1100 : "Expected unbounded query to return all 1100 resources"; result = resourceManager.findResourcesByCriteriaBounded(env.get(0).normalSubject, criteria, 2000, 100); assert null != result; assert result.size() == 1100 : "Expected 2000/100 bounded query to return all 1100 resources"; result = resourceManager.findResourcesByCriteriaBounded(env.get(0).normalSubject, criteria, 1100, 100); assert null != result; assert result.size() == 1100 : "Expected 1100/100 bounded query to return all 1100 resources"; result = resourceManager.findResourcesByCriteriaBounded(env.get(0).normalSubject, criteria, 0, 0); assert null != result; assert result.size() == 200 : "Expected default (1000/200) bounded query to return 200 resources"; result = resourceManager.findResourcesByCriteriaBounded(env.get(0).normalSubject, criteria, 0, 500); assert null != result; assert result.size() == 500 : "Expected default (1000)/500) bounded query to return 500 resources"; result = resourceManager.findResourcesByCriteriaBounded(env.get(0).normalSubject, criteria, 100, 200); assert null != result; assert result.size() == 100 : "Expected 100/200 bounded query to return 100 resources"; } private PageList<ResourceGroupComposite> testGroupQueriesWithSearchBar(GroupAvailCounts gac, String searchExpression) throws Exception { ResourceGroupManagerLocal groupManager = LookupUtil.getResourceGroupManager(); env = new ArrayList<LargeGroupEnvironment>(1); LargeGroupEnvironment lgeWithTypes = null; env.add(createLargeGroupWithNormalUserRoleAccessWithInventoryStatus(lgeWithTypes, gac.total, gac.down, gac.unknown, gac.disabled, gac.uncommitted, Permission.CONFIGURE_READ)); ResourceGroupCriteria criteria; PageList<ResourceGroupComposite> pageList; long start; // test findResourceGroupCompositesByCriteria where the criteria will use the search bar feature SessionTestHelper.simulateLogin(env.get(0).normalSubject); criteria = new ResourceGroupCriteria(); criteria.setSearchExpression(searchExpression); start = System.currentTimeMillis(); pageList = groupManager.findResourceGroupCompositesByCriteria(env.get(0).normalSubject, criteria); System.out.println("criteria with search==>" + (System.currentTimeMillis() - start) + "ms"); return pageList; } private void testGroupQueries(ArrayList<GroupAvailCounts> groupAvailCounts) throws Exception { ResourceGroupManagerLocal groupManager = LookupUtil.getResourceGroupManager(); AuthorizationManagerLocal authManager = LookupUtil.getAuthorizationManager(); env = new ArrayList<LargeGroupEnvironment>(groupAvailCounts.size()); LargeGroupEnvironment lgeWithTypes = null; for (GroupAvailCounts gac : groupAvailCounts) { env.add(createLargeGroupWithNormalUserRoleAccessWithInventoryStatus(lgeWithTypes, gac.total, gac.down, gac.unknown, gac.disabled, gac.uncommitted, Permission.CONFIGURE_READ)); lgeWithTypes = env.get(0); } ResourceGroupCriteria criteria; PageList<ResourceGroupComposite> pageList; ResourceGroupComposite groupComp; long start; // test findResourceGroupCompositesByCriteria for (int i = 0; i < groupAvailCounts.size(); i++) { LargeGroupEnvironment lge = env.get(i); GroupAvailCounts gac = groupAvailCounts.get(i); SessionTestHelper.simulateLogin(lge.normalSubject); criteria = new ResourceGroupCriteria(); start = System.currentTimeMillis(); pageList = groupManager.findResourceGroupCompositesByCriteria(lge.normalSubject, criteria); System.out.println("findResourceGroupCompositesByCriteria #" + i + "==>" + (System.currentTimeMillis() - start) + "ms"); assert pageList.size() == 1 : "the query should only have selected the one group for our user"; groupComp = pageList.get(0); System.out.println("-->" + groupComp); assert groupComp.getExplicitCount() == gac.visibleTotal; assert groupComp.getExplicitCount() == groupComp.getImplicitCount(); // we aren't testing recursive groups assert groupComp.getExplicitUp() == gac.up; assert groupComp.getExplicitDown() == gac.down; assert groupComp.getExplicitUnknown() == gac.unknown; assert groupComp.getExplicitDisabled() == gac.disabled; // mainly to help test when there are uncommitted resources in the group - see BZ 820981 Resource committed = pickAResourceWithInventoryStatus(lge.platformResource, InventoryStatus.COMMITTED); assert true == authManager.hasResourcePermission(lge.normalSubject, Permission.CONFIGURE_READ, Collections.singletonList(committed.getId())); assert false == authManager.hasResourcePermission(lge.normalSubject, Permission.CONTROL, Collections.singletonList(committed.getId())); // we weren't given CONTROL perms on the committed resource Resource uncommitted = pickAResourceWithInventoryStatus(lge.platformResource, InventoryStatus.NEW); if (uncommitted != null) { assert false == authManager.hasResourcePermission(lge.normalSubject, Permission.CONFIGURE_READ, Collections.singletonList(uncommitted.getId())); // no permissions for uncommitted resource } } // test getResourceGroupComposite for (int i = 0; i < groupAvailCounts.size(); i++) { LargeGroupEnvironment lge = env.get(i); GroupAvailCounts gac = groupAvailCounts.get(i); SessionTestHelper.simulateLogin(lge.normalSubject); start = System.currentTimeMillis(); groupComp = groupManager.getResourceGroupComposite(lge.normalSubject, lge.compatibleGroup.getId()); System.out.println("getResourceGroupComposite #" + i + "==>" + (System.currentTimeMillis() - start) + "ms"); System.out.println("-->" + groupComp); assert groupComp.getExplicitCount() == gac.visibleTotal; assert groupComp.getExplicitCount() == groupComp.getImplicitCount(); // we aren't testing recursive groups assert groupComp.getExplicitUp() == gac.up; assert groupComp.getExplicitDown() == gac.down; assert groupComp.getExplicitUnknown() == gac.unknown; assert groupComp.getExplicitDisabled() == gac.disabled; } } private Resource pickAResourceWithInventoryStatus(Resource platformResource, InventoryStatus status) { for (Resource r : platformResource.getChildResources()) { if (r.getInventoryStatus() == status) { return r; } } return null; } }