/**
* Copyright (c) 2009 - 2012 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package org.candlepin.policy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.candlepin.auth.UserPrincipal;
import org.candlepin.common.config.Configuration;
import org.candlepin.config.ConfigProperties;
import org.candlepin.controller.PoolManager;
import org.candlepin.model.Branding;
import org.candlepin.model.Entitlement;
import org.candlepin.model.EntitlementCurator;
import org.candlepin.model.Owner;
import org.candlepin.model.OwnerProductCurator;
import org.candlepin.model.Pool;
import org.candlepin.model.Product;
import org.candlepin.model.ProductCurator;
import org.candlepin.model.Rules;
import org.candlepin.model.RulesCurator;
import org.candlepin.model.dto.ProductData;
import org.candlepin.model.dto.Subscription;
import org.candlepin.policy.js.pool.PoolRules;
import org.candlepin.policy.js.pool.PoolUpdate;
import org.candlepin.test.TestUtil;
import org.candlepin.util.Util;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* JsPoolRulesTest: Tests for the default rules.
*/
@RunWith(MockitoJUnitRunner.class)
public class PoolRulesTest {
private PoolRules poolRules;
private static final String DERIVED_ATTR = "lookformeimderived";
@Mock private RulesCurator rulesCuratorMock;
@Mock private PoolManager poolManagerMock;
@Mock private Configuration configMock;
@Mock private EntitlementCurator entCurMock;
@Mock private OwnerProductCurator ownerProdCuratorMock;
@Mock private ProductCurator productCurator;
private UserPrincipal principal;
private Owner owner;
@Before
public void setUp() {
// Load the default production rules:
InputStream is = this.getClass().getResourceAsStream(RulesCurator.DEFAULT_RULES_FILE);
Rules rules = new Rules(Util.readFile(is));
when(rulesCuratorMock.getUpdated()).thenReturn(new Date());
when(rulesCuratorMock.getRules()).thenReturn(rules);
when(configMock.getInt(eq(ConfigProperties.PRODUCT_CACHE_MAX))).thenReturn(100);
poolRules = new PoolRules(poolManagerMock, configMock, entCurMock, ownerProdCuratorMock,
productCurator);
principal = TestUtil.createOwnerPrincipal();
owner = principal.getOwners().get(0);
}
@Test
public void hostedVirtLimitBadValueDoesntTraceBack() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(false);
Product product = TestUtil.createProduct();
when(this.ownerProdCuratorMock.getProductById(owner, product.getId())).thenReturn(product);
Pool p = TestUtil.createPool(owner, product);
p.getProduct().setAttribute(Product.Attributes.VIRT_LIMIT, "badvalue");
p.setQuantity(10L);
List<Pool> pools = null;
try {
pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
}
catch (Exception e) {
fail(
"Create pools should not have thrown an exception on bad value for virt_limit: " +
e.getMessage()
);
}
assertEquals(1, pools.size());
Pool physicalPool = pools.get(0);
physicalPool.setId("physical");
assertEquals(new Long(10), physicalPool.getQuantity());
assertEquals(0, physicalPool.getAttributes().size());
}
@Test
public void providedProductsChanged() {
// Pool with two provided products:
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
Product product1 = TestUtil.createProduct();
Product product2 = TestUtil.createProduct();
Product product3 = TestUtil.createProduct();
p.getProvidedProducts().add(product1);
p.getProvidedProducts().add(product2);
// Setup a pool with a single (different) provided product:
Pool p1 = TestUtil.clone(p);
p1.getProvidedProducts().clear();
p1.getProvidedProducts().add(product3);
List<Pool> existingPools = new LinkedList<Pool>();
existingPools.add(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(1, updates.size());
PoolUpdate update = updates.get(0);
assertTrue(update.getProductsChanged());
assertFalse(update.getDatesChanged());
assertFalse(update.getQuantityChanged());
}
@Test
public void productNameChanged() {
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
// Setup a pool with a single (different) provided product:
Pool p1 = TestUtil.clone(p);
p1.getProduct().setName("somethingelse");
List<Pool> existingPools = Arrays.asList(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
TestUtil.stubChangedProducts(p.getProduct()));
assertEquals(1, updates.size());
PoolUpdate update = updates.get(0);
assertTrue(update.getProductsChanged());
assertFalse(update.getDatesChanged());
assertFalse(update.getQuantityChanged());
assertEquals(p.getProduct().getName(), update.getPool().getProductName());
}
@Test
public void datesNameChanged() {
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
// Setup a pool with a single (different) provided product:
Pool p1 = TestUtil.clone(p);
p1.setEndDate(new Date());
List<Pool> existingPools = Arrays.asList(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(1, updates.size());
PoolUpdate update = updates.get(0);
assertFalse(update.getProductsChanged());
assertTrue(update.getDatesChanged());
assertFalse(update.getQuantityChanged());
assertEquals(p.getEndDate(), update.getPool().getEndDate());
}
@Test
public void quantityChanged() {
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
// Setup a pool with a single (different) provided product:
Pool p1 = TestUtil.clone(p);
p1.setQuantity(2000L);
List<Pool> existingPools = Arrays.asList(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(1, updates.size());
PoolUpdate update = updates.get(0);
assertFalse(update.getProductsChanged());
assertFalse(update.getDatesChanged());
assertTrue(update.getQuantityChanged());
assertEquals(p.getQuantity(), update.getPool().getQuantity());
}
@Test
public void brandingChanged() {
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
Pool p1 = TestUtil.clone(p);
// Add some branding to the pool and do an update:
Branding b1 = new Branding("8000", "OS", "Awesome OS Branded");
Branding b2 = new Branding("8001", "OS", "Awesome OS Branded 2");
p.getBranding().add(b1);
p.getBranding().add(b2);
List<Pool> existingPools = Arrays.asList(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(1, updates.size());
PoolUpdate update = updates.get(0);
assertFalse(update.getProductsChanged());
assertFalse(update.getDatesChanged());
assertFalse(update.getQuantityChanged());
assertTrue(update.getBrandingChanged());
assertTrue(update.changed());
assertEquals(2, update.getPool().getBranding().size());
assertTrue(update.getPool().getBranding().contains(b1));
assertTrue(update.getPool().getBranding().contains(b2));
}
@Test
public void brandingDidntChange() {
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
// Add some branding to the subscription and do an update:
Branding b1 = new Branding("8000", "OS", "Awesome OS Branded");
Branding b2 = new Branding("8001", "OS", "Awesome OS Branded 2");
p.getBranding().add(b1);
p.getBranding().add(b2);
// Copy the pool with the branding to begin with:
Pool p1 = TestUtil.clone(p);
List<Pool> existingPools = Arrays.asList(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(0, updates.size());
}
@Test
public void virtOnlyQuantityChanged() {
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
p.getProduct().setAttribute(Product.Attributes.VIRT_LIMIT, "5");
p.setQuantity(10L);
// Setup a pool with a single (different) provided product:
Pool p1 = TestUtil.clone(p);
p1.setAttribute(Product.Attributes.VIRT_ONLY, "true");
p1.setAttribute(Pool.Attributes.DERIVED_POOL, "true");
p1.setQuantity(40L);
List<Pool> existingPools = Arrays.asList(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(), null);
assertEquals(1, updates.size());
PoolUpdate update = updates.get(0);
assertFalse(update.getProductsChanged());
assertFalse(update.getDatesChanged());
assertFalse(update.getProductAttributesChanged());
assertTrue(update.getQuantityChanged());
assertEquals(Long.valueOf(50), update.getPool().getQuantity());
}
@Test
public void updatePoolSubProvidedProductsChanged() {
// Pool with two provided products:
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
Product subProd = TestUtil.createProduct();
p.setDerivedProduct(subProd);
Product product1 = TestUtil.createProduct();
Product product2 = TestUtil.createProduct();
Product product3 = TestUtil.createProduct();
p.getDerivedProvidedProducts().add(product1);
p.getDerivedProvidedProducts().add(product2);
// Setup a pool with a single (different) provided product:
Pool p1 = TestUtil.clone(p);
p1.getProvidedProducts().clear();
p1.getProvidedProducts().add(product3);
List<Pool> existingPools = Arrays.asList(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(1, updates.size());
assertEquals(2, updates.get(0).getPool().getDerivedProvidedProducts().size());
}
private Pool createVirtLimitPool(String productId, int quantity, int virtLimit) {
Product product = TestUtil.createProduct(productId, productId);
product.setAttribute(Product.Attributes.VIRT_LIMIT, Integer.toString(virtLimit));
Pool p = TestUtil.createPool(owner, product);
p.setQuantity(new Long(quantity));
return p;
}
/*
* Bonus pools should be created at pool creation time if the
* host_limited attribute is present on the product. A tag will
* be added to the created pool. Host specific bonus pools will
* still be created during binding.
*/
@Test
public void virtLimitWithHostLimitedCreatesTaggedBonusPool() {
Pool p1 = createVirtLimitPool("virtLimitProduct", 10, 10);
p1.getProduct().setAttribute(Product.Attributes.HOST_LIMITED, "true");
List<Pool> pools = poolRules.createAndEnrichPools(p1, new LinkedList<Pool>());
assertEquals(2, pools.size());
for (Pool p : pools) {
if (p.getSourceSubscription().getSubscriptionSubKey().equals("derived")) {
assertTrue(p.hasAttribute(Pool.Attributes.UNMAPPED_GUESTS_ONLY));
assertEquals("true", p.getAttributeValue(Pool.Attributes.UNMAPPED_GUESTS_ONLY));
}
}
}
// Make sure host_limited false is working:
@Test
public void hostedVirtLimitWithHostLimitedFalseCreatesBonusPools() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(false);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
p.getProduct().setAttribute(Product.Attributes.HOST_LIMITED, "false");
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(2, pools.size());
}
@Test
public void hostedVirtLimitSubCreatesBonusVirtOnlyPool() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(false);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(2, pools.size());
Pool physicalPool = pools.get(0);
Pool virtBonusPool = pools.get(1);
assertEquals(new Long(10), physicalPool.getQuantity());
assertEquals(0, physicalPool.getAttributes().size());
// Quantity on bonus pool should be virt limit * sub quantity:
assertEquals(new Long(100), virtBonusPool.getQuantity());
assertEquals("true", virtBonusPool.getAttributeValue(Product.Attributes.VIRT_ONLY));
assertEquals("10", virtBonusPool.getProduct().getAttributeValue(Product.Attributes.VIRT_LIMIT));
}
@Test
public void hostedVirtLimitSubCreatesUnlimitedBonusVirtOnlyPool() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(false);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
p.getProduct().setAttribute(Product.Attributes.VIRT_LIMIT, "unlimited");
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(2, pools.size());
Pool virtBonusPool = pools.get(1);
// Quantity on bonus pool should be unlimited:
assertEquals(new Long(-1), virtBonusPool.getQuantity());
}
@Test
public void hostedVirtLimitSubUpdatesUnlimitedBonusVirtOnlyPool() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(false);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
p.getProduct().setAttribute(Product.Attributes.VIRT_LIMIT, "unlimited");
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(2, pools.size());
Pool virtBonusPool = pools.get(1);
// Quantity on bonus pool should be unlimited:
assertEquals(new Long(-1), virtBonusPool.getQuantity());
// Now we update the sub and see if that unlimited pool gets adjusted:
p.getProduct().setAttribute(Product.Attributes.VIRT_LIMIT, "10");
List<PoolUpdate> updates = poolRules.updatePools(p, pools, p.getQuantity(),
TestUtil.stubChangedProducts(p.getProduct()));
assertEquals(2, updates.size());
PoolUpdate virtUpdate = updates.get(1);
assertEquals(new Long(100), virtUpdate.getPool().getQuantity());
}
@Test
public void hostedVirtLimitRemoved() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(false);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
p.getProduct().setAttribute(Product.Attributes.VIRT_LIMIT, "4");
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(2, pools.size());
// Now we remove virt_limit on the incoming subscription product and see if
// the unlimited pool gets adjusted and flagged for cleanup:
p.setProduct(TestUtil.createProduct(p.getProduct().getId(), p.getProduct().getName()));
List<PoolUpdate> updates = poolRules.updatePools(p, pools, p.getQuantity(),
TestUtil.stubChangedProducts(p.getProduct()));
assertEquals(2, updates.size());
// Regular pool should be in a sane state:
PoolUpdate baseUpdate = updates.get(0);
assertEquals(new Long(10), baseUpdate.getPool().getQuantity());
assertFalse(baseUpdate.getPool().isMarkedForDelete());
// Virt bonus pool should have quantity 0 and be flagged for cleanup:
PoolUpdate virtUpdate = updates.get(1);
assertEquals(new Long(0), virtUpdate.getPool().getQuantity());
assertTrue(virtUpdate.getPool().isMarkedForDelete());
}
@Test
public void hostedVirtLimitSubWithMultiplierCreatesUnlimitedBonusVirtOnlyPool() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(false);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
p.getProduct().setAttribute(Product.Attributes.VIRT_LIMIT, "unlimited");
p.getProduct().setMultiplier(5L);
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(2, pools.size());
Pool virtBonusPool = pools.get(1);
// Quantity on bonus pool should be unlimited:
assertEquals(new Long(-1), virtBonusPool.getQuantity());
}
@Test
public void hostedVirtLimitSubCreateAttributesTest() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(false);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
p.getProduct().setAttribute(Pool.Attributes.PHYSICAL_ONLY, "true");
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
// Should be no virt_only bonus pool:
assertEquals(2, pools.size());
int virtOnlyCount = 0;
for (Pool pool : pools) {
String virtAttr = pool.getAttributeValue(Pool.Attributes.VIRT_ONLY);
if ("true".equals(virtAttr)) {
virtOnlyCount++;
assertEquals("false", pool.getAttributeValue(Pool.Attributes.PHYSICAL_ONLY));
}
}
assertEquals(1, virtOnlyCount);
}
@Test
public void standaloneVirtLimitSubCreate() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(true);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
Product provided1 = TestUtil.createProduct();
Product provided2 = TestUtil.createProduct();
Product derivedProd = TestUtil.createProduct();
Product derivedProvidedProd1 = TestUtil.createProduct();
Product derivedProvidedProd2 = TestUtil.createProduct();
when(ownerProdCuratorMock.getProductById(owner, provided1.getId())).thenReturn(provided1);
when(ownerProdCuratorMock.getProductById(owner, provided2.getId())).thenReturn(provided2);
when(ownerProdCuratorMock.getProductById(owner, derivedProd.getId())).thenReturn(derivedProd);
when(ownerProdCuratorMock.getProductById(owner, derivedProvidedProd1.getId()))
.thenReturn(derivedProvidedProd1);
when(ownerProdCuratorMock.getProductById(owner, derivedProvidedProd2.getId()))
.thenReturn(derivedProvidedProd2);
p.setId("mockPoolRuleTestID");
p.getProvidedProducts().add(provided1);
p.getProvidedProducts().add(provided2);
p.setDerivedProduct(derivedProd);
p.getDerivedProvidedProducts().add(derivedProvidedProd1);
p.getDerivedProvidedProducts().add(derivedProvidedProd2);
when(productCurator.getPoolProvidedProductsCached(p))
.thenReturn(p.getProvidedProducts());
when(productCurator.getPoolDerivedProvidedProductsCached(p))
.thenReturn(p.getDerivedProvidedProducts());
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
// Should be virt_only pool for unmapped guests:
assertEquals(2, pools.size());
Pool physicalPool = pools.get(0);
assertEquals(0, physicalPool.getAttributes().size());
assertProvidedProducts(p.getProvidedProducts(), physicalPool.getProvidedProducts());
assertProvidedProducts(p.getDerivedProvidedProducts(),
physicalPool.getDerivedProvidedProducts());
Pool unmappedVirtPool = pools.get(1);
assert ("true".equals(unmappedVirtPool.getAttributeValue(Product.Attributes.VIRT_ONLY)));
assert ("true".equals(unmappedVirtPool.getAttributeValue(Pool.Attributes.UNMAPPED_GUESTS_ONLY)));
// The derived provided products of the sub should be promoted to provided products
// on the unmappedVirtPool
assertProvidedProducts(p.getDerivedProvidedProducts(), unmappedVirtPool.getProvidedProducts());
assertProvidedProducts(new HashSet<Product>(), unmappedVirtPool.getDerivedProvidedProducts());
// Test for BZ 1204311 - Refreshing pools should not change unmapped guest pools
// Refresh is a no-op in multiorg
// List<PoolUpdate> updates = poolRules.updatePools(s, pools);
// assertTrue(updates.isEmpty());
}
@Test
public void standaloneVirtLimitSubCreateDerived() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(true);
Subscription s = createVirtLimitSubWithDerivedProducts("virtLimitProduct",
"derivedProd", 10, 10);
Pool p = TestUtil.copyFromSub(s);
p.setId("mockVirtLimitSubCreateDerived");
when(productCurator.getPoolDerivedProvidedProductsCached(p))
.thenReturn(p.getDerivedProvidedProducts());
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
// Should be virt_only pool for unmapped guests:
assertEquals(2, pools.size());
Pool physicalPool = pools.get(0);
assertEquals(0, physicalPool.getAttributes().size());
assertFalse(physicalPool.getProduct().hasAttribute(DERIVED_ATTR));
Pool unmappedVirtPool = pools.get(1);
assert ("true".equals(unmappedVirtPool.getAttributeValue(Product.Attributes.VIRT_ONLY)));
assert ("true".equals(unmappedVirtPool.getAttributeValue(Pool.Attributes.UNMAPPED_GUESTS_ONLY)));
assertEquals("derivedProd", unmappedVirtPool.getProductId());
assertProvidedProductsForSub(s.getDerivedProvidedProducts(), unmappedVirtPool.getProvidedProducts());
assertProvidedProducts(new HashSet<Product>(), unmappedVirtPool.getDerivedProvidedProducts());
assertTrue(unmappedVirtPool.getProduct().hasAttribute(DERIVED_ATTR));
}
private void assertProvidedProducts(Set<Product> expectedProducts, Set<Product> providedProducts) {
assertEquals(expectedProducts.size(), providedProducts.size());
for (Product expected : expectedProducts) {
boolean found = false;
for (Product provided : providedProducts) {
if (provided.getId().equals(expected.getId())) {
found = true;
break;
}
}
assertTrue(found);
}
}
private void assertProvidedProductsForSub(Set<ProductData> expectedProducts,
Set<Product> providedProducts) {
assertEquals(expectedProducts.size(), providedProducts.size());
for (ProductData expected : expectedProducts) {
boolean found = false;
for (Product provided : providedProducts) {
if (provided.getId().equals(expected.getId())) {
found = true;
break;
}
}
assertTrue(found);
}
}
private Subscription createVirtLimitSubWithDerivedProducts(String productId,
String derivedProductId, int quantity, int virtLimit) {
Product product = TestUtil.createProduct(productId, productId);
product.setAttribute(Product.Attributes.VIRT_LIMIT, Integer.toString(virtLimit));
when(ownerProdCuratorMock.getProductById(owner, product.getId()))
.thenReturn(product);
Product derivedProd = TestUtil.createProduct(derivedProductId, derivedProductId);
// We'll look for this to make sure it makes it to correct pools:
derivedProd.setAttribute(DERIVED_ATTR, "nobodycares");
when(ownerProdCuratorMock.getProductById(owner, derivedProd.getId()))
.thenReturn(derivedProd);
// Create some provided products:
Product provided1 = TestUtil.createProduct();
when(ownerProdCuratorMock.getProductById(owner, provided1.getId()))
.thenReturn(provided1);
Product provided2 = TestUtil.createProduct();
when(ownerProdCuratorMock.getProductById(owner, provided2.getId()))
.thenReturn(provided2);
// Create some derived provided products:
Product derivedProvided1 = TestUtil.createProduct();
when(ownerProdCuratorMock.getProductById(owner, derivedProvided1.getId()))
.thenReturn(derivedProvided1);
Product derivedProvided2 = TestUtil.createProduct();
when(ownerProdCuratorMock.getProductById(owner, derivedProvided2.getId()))
.thenReturn(derivedProvided2);
Subscription s = TestUtil.createSubscription(owner, product);
s.setQuantity(new Long(quantity));
s.setDerivedProduct(derivedProd.toDTO());
Set<ProductData> derivedProds = Util.newSet();
derivedProds.add(derivedProvided1.toDTO());
derivedProds.add(derivedProvided2.toDTO());
s.setDerivedProvidedProducts(derivedProds);
return s;
}
@Test
public void standaloneVirtLimitSubUpdate() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(true);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
// Should be unmapped virt_only pool:
assertEquals(2, pools.size());
Pool physicalPool = pools.get(0);
assertEquals(0, physicalPool.getAttributes().size());
p = createVirtLimitPool("virtLimitProduct", 10, 10);
p.setQuantity(50L);
List<PoolUpdate> updates = poolRules.updatePools(p, pools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(2, updates.size());
physicalPool = updates.get(0).getPool();
assertEquals(new Long(50), physicalPool.getQuantity());
assertEquals(0, physicalPool.getAttributes().size());
}
private Pool createVirtOnlyPool(String productId, int quantity) {
Product product = TestUtil.createProduct(productId, productId);
product.setAttribute(Product.Attributes.VIRT_ONLY, "true");
Pool p = TestUtil.createPool(owner, product);
p.setQuantity(new Long(quantity));
return p;
}
@Test
public void hostedVirtOnlySubCreate() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(true);
Pool p = createVirtOnlyPool("virtOnlyProduct", 10);
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(1, pools.size());
assertEquals("true", pools.get(0).getProduct().getAttributeValue(Product.Attributes.VIRT_ONLY));
assertEquals(new Long(10), pools.get(0).getQuantity());
}
@Test
public void hostedVirtOnlySubCreateWithMultiplier() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(true);
Pool p = createVirtOnlyPool("virtOnlyProduct", 10);
p.getProduct().setMultiplier(new Long(5));
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(1, pools.size());
assertEquals("true", pools.get(0).getProduct().getAttributeValue(Product.Attributes.VIRT_ONLY));
assertEquals(new Long(50), pools.get(0).getQuantity());
}
@Test
public void hostedVirtOnlySubUpdate() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(true);
Pool p = createVirtOnlyPool("virtOnlyProduct", 10);
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(1, pools.size());
p = createVirtOnlyPool("virtOnlyProduct", 20);
List<PoolUpdate> updates = poolRules.updatePools(p, pools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(1, updates.size());
Pool updated = updates.get(0).getPool();
assertEquals(new Long(20), updated.getQuantity());
}
@Test
public void standaloneVirtSubPoolUpdateNoChanges() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(true);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(2, pools.size());
Entitlement ent = mock(Entitlement.class);
when(ent.getQuantity()).thenReturn(1);
// Now make a pool that would have been created for guests only after a host
// bound to the parent pool:
Pool consumerSpecificPool = TestUtil.clone(p);
consumerSpecificPool.setAttribute(Pool.Attributes.REQUIRES_HOST, "FAKEUUID");
consumerSpecificPool.setAttribute(Pool.Attributes.DERIVED_POOL, "true");
consumerSpecificPool.setAttribute(Product.Attributes.VIRT_ONLY, "true");
consumerSpecificPool.setQuantity(10L);
consumerSpecificPool.setSourceEntitlement(ent);
pools.add(consumerSpecificPool);
List<PoolUpdate> updates = poolRules.updatePools(p, pools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(0, updates.size());
}
@Test
public void standaloneVirtSubPoolUpdateVirtLimitChanged() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(true);
Pool p = createVirtLimitPool("virtLimitProduct", 10, 10);
List<Pool> pools = poolRules.createAndEnrichPools(p, new LinkedList<Pool>());
assertEquals(2, pools.size());
p.setQuantity(new Long(20));
Entitlement ent = mock(Entitlement.class);
when(ent.getQuantity()).thenReturn(4);
// Now make a pool that would have been created for guests only after a host
// bound to the parent pool:
Pool consumerSpecificPool = TestUtil.clone(p);
consumerSpecificPool.setAttribute(Pool.Attributes.REQUIRES_HOST, "FAKEUUID");
consumerSpecificPool.setAttribute(Pool.Attributes.DERIVED_POOL, "true");
consumerSpecificPool.setAttribute(Product.Attributes.VIRT_ONLY, "true");
consumerSpecificPool.setQuantity(10L);
consumerSpecificPool.setSourceEntitlement(ent);
pools.add(consumerSpecificPool);
p.getProduct().setAttribute(Product.Attributes.VIRT_LIMIT, "40");
List<PoolUpdate> updates = poolRules.updatePools(p, pools, p.getQuantity(),
TestUtil.stubChangedProducts(p.getProduct()));
assertEquals(3, updates.size());
Pool regular = updates.get(0).getPool();
Pool unmappedSubPool = updates.get(1).getPool();
Pool subPool = updates.get(2).getPool();
assertEquals("40", regular.getProduct().getAttributeValue(Product.Attributes.VIRT_LIMIT));
assertEquals(new Long(40), subPool.getQuantity());
assertEquals(new Long(800), unmappedSubPool.getQuantity());
}
@Test
public void dontUpdateVirtOnlyNoVirtLimit() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(false);
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
p.setQuantity(10L);
// Setup a pool with a single (different) provided product:
Pool p1 = TestUtil.clone(p);
p1.setAttribute(Product.Attributes.VIRT_ONLY, "true");
p1.setAttribute(Pool.Attributes.DERIVED_POOL, "true");
p1.setQuantity(10L);
List<Pool> existingPools = new LinkedList<Pool>();
existingPools.add(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(0, updates.size());
}
@Test
public void updateVirtOnlyNoVirtLimit() {
when(configMock.getBoolean(ConfigProperties.STANDALONE)).thenReturn(false);
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
p.setQuantity(10L);
// Setup a pool with a single (different) provided product:
Pool p1 = TestUtil.clone(p);
p1.setAttribute(Product.Attributes.VIRT_ONLY, "true");
p1.setAttribute(Pool.Attributes.DERIVED_POOL, "true");
p1.setQuantity(20L);
List<Pool> existingPools = new LinkedList<Pool>();
existingPools.add(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(1, updates.size());
PoolUpdate update = updates.get(0);
assertFalse(update.getProductsChanged());
assertFalse(update.getDatesChanged());
assertTrue(update.getQuantityChanged());
assertEquals(Long.valueOf(10), update.getPool().getQuantity());
}
@Test
public void contractNumberChanged() {
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
p.setContractNumber("123");
// Setup a pool with a single (different) provided product:
Pool p1 = TestUtil.clone(p);
p1.setQuantity(2000L);
p1.setContractNumber("ABC");
List<Pool> existingPools = new LinkedList<Pool>();
existingPools.add(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(1, updates.size());
PoolUpdate update = updates.get(0);
assertTrue(update.getOrderChanged());
assertEquals("123", update.getPool().getContractNumber());
}
@Test
public void orderNumberChanged() {
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
p.setOrderNumber("123");
// Setup a pool with a single (different) order number:
Pool p1 = TestUtil.clone(p);
p1.setQuantity(2000L);
p1.setOrderNumber("ABC");
List<Pool> existingPools = new LinkedList<Pool>();
existingPools.add(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(1, updates.size());
PoolUpdate update = updates.get(0);
assertTrue(update.getOrderChanged());
assertEquals("123", update.getPool().getOrderNumber());
}
@Test
public void accountNumberChanged() {
Pool p = TestUtil.createPool(owner, TestUtil.createProduct());
p.setAccountNumber("123");
// Setup a pool with a single (different) account number:
Pool p1 = TestUtil.clone(p);
p1.setQuantity(2000L);
p1.setAccountNumber("ABC");
List<Pool> existingPools = new LinkedList<Pool>();
existingPools.add(p1);
List<PoolUpdate> updates = this.poolRules.updatePools(p, existingPools, p.getQuantity(),
Collections.<String, Product>emptyMap());
assertEquals(1, updates.size());
PoolUpdate update = updates.get(0);
assertTrue(update.getOrderChanged());
assertEquals("123", update.getPool().getAccountNumber());
}
@Test
public void productNameChangedDevPool() {
Pool p = TestUtil.createPool(TestUtil.createProduct());
p.setSourceSubscription(null);
p.setAttribute(Pool.Attributes.DEVELOPMENT_POOL, "true");
List<Pool> floatingPools = new ArrayList<Pool>();
floatingPools.add(p);
Product changed = p.getProduct();
changed.setName("somethingelse");
List<PoolUpdate> updates = this.poolRules.updatePools(floatingPools,
TestUtil.stubChangedProducts(changed));
assertEquals(0, updates.size());
}
@Test
public void noPoolsCreatedTest() {
Product product = TestUtil.createProduct();
List<Pool> existingPools = new ArrayList<Pool>();
Pool masterPool = TestUtil.createPool(product);
masterPool.setSubscriptionSubKey("master");
existingPools.add(masterPool);
Pool derivedPool = TestUtil.createPool(product);
derivedPool.setSubscriptionSubKey("derived");
existingPools.add(derivedPool);
List<Pool> pools = this.poolRules.createAndEnrichPools(masterPool, existingPools);
assertEquals(0, pools.size());
}
@Test
public void derivedPoolCreateCreatedTest() {
Product product = TestUtil.createProduct();
product.setAttribute(Product.Attributes.VIRT_LIMIT, "4");
List<Pool> existingPools = new ArrayList<Pool>();
Pool masterPool = TestUtil.createPool(product);
masterPool.setSubscriptionSubKey("master");
existingPools.add(masterPool);
List<Pool> pools = this.poolRules.createAndEnrichPools(masterPool, existingPools);
assertEquals(1, pools.size());
assertEquals("derived", pools.get(0).getSubscriptionSubKey());
}
@Test(expected = IllegalStateException.class)
public void cantCreateMasterPoolFromDerivedPoolTest() {
Product product = TestUtil.createProduct();
List<Pool> existingPools = new ArrayList<Pool>();
Pool masterPool = TestUtil.createPool(product);
masterPool.setSubscriptionSubKey("derived");
existingPools.add(masterPool);
List<Pool> pools = this.poolRules.createAndEnrichPools(masterPool, existingPools);
}
}