/**
* 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.resource.util;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import org.candlepin.audit.EventSink;
import org.candlepin.jackson.ProductCachedSerializationModule;
import org.candlepin.model.CandlepinQuery;
import org.candlepin.model.Consumer;
import org.candlepin.model.ConsumerCurator;
import org.candlepin.model.ConsumerInstalledProduct;
import org.candlepin.model.ConsumerType;
import org.candlepin.model.Entitlement;
import org.candlepin.model.EntitlementCurator;
import org.candlepin.model.GuestId;
import org.candlepin.model.Owner;
import org.candlepin.model.OwnerProductCurator;
import org.candlepin.model.Pool;
import org.candlepin.model.PoolCurator;
import org.candlepin.model.Product;
import org.candlepin.model.ProductCurator;
import org.candlepin.model.Rules;
import org.candlepin.model.RulesCurator;
import org.candlepin.policy.js.JsRunnerProvider;
import org.candlepin.policy.js.JsRunnerRequestCache;
import org.candlepin.policy.js.RulesObjectMapper;
import org.candlepin.policy.js.compliance.ComplianceRules;
import org.candlepin.policy.js.compliance.ComplianceStatus;
import org.candlepin.policy.js.compliance.DateRange;
import org.candlepin.policy.js.compliance.StatusReasonMessageGenerator;
import org.candlepin.test.TestUtil;
import org.candlepin.test.MockResultIterator;
import org.candlepin.util.Util;
import com.google.inject.Provider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.xnap.commons.i18n.I18n;
import org.xnap.commons.i18n.I18nFactory;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.Set;
/**
* InstalledProductStatusCalculatorTest
*/
@RunWith(MockitoJUnitRunner.class)
public class InstalledProductStatusCalculatorTest {
private ComplianceRules complianceRules;
@Mock private ConsumerCurator consumerCurator;
@Mock private EntitlementCurator entCurator;
@Mock private RulesCurator rulesCuratorMock;
@Mock private EventSink eventSink;
@Mock private Provider<JsRunnerRequestCache> cacheProvider;
@Mock private JsRunnerRequestCache cache;
@Mock private PoolCurator poolCurator;
@Mock private ProductCurator productCurator;
@Mock private OwnerProductCurator ownerProductCurator;
private JsRunnerProvider provider;
private I18n i18n;
private ConsumerEnricher consumerEnricher;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
// Load the default production rules:
InputStream is = this.getClass().getResourceAsStream(RulesCurator.DEFAULT_RULES_FILE);
Rules rules = new Rules(Util.readFile(is));
Locale locale = new Locale("en_US");
when(rulesCuratorMock.getUpdated()).thenReturn(new Date());
when(rulesCuratorMock.getRules()).thenReturn(rules);
when(cacheProvider.get()).thenReturn(cache);
this.provider = new JsRunnerProvider(rulesCuratorMock, cacheProvider);
i18n = I18nFactory.getI18n(getClass(), "org.candlepin.i18n.Messages", locale, I18nFactory.FALLBACK);
RulesObjectMapper objectMapper =
new RulesObjectMapper(new ProductCachedSerializationModule(productCurator));
this.complianceRules = new ComplianceRules(provider.get(), this.entCurator,
new StatusReasonMessageGenerator(i18n), eventSink, this.consumerCurator, objectMapper);
this.consumerEnricher = new ConsumerEnricher(this.complianceRules, this.ownerProductCurator);
}
@Test
public void validRangeForSingleValidEnitlement() {
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
DateRange range = this.rangeRelativeToDate(new Date(), -6, 6);
Entitlement entitlement = this.mockEntitlement(owner, consumer, product, range, product);
consumer.addEntitlement(entitlement);
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range.getStartDate(), cip.getStartDate());
assertEquals(range.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeForUnmappedGuestEntitlement() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range = this.rangeRelativeToDate(now, -6, 6);
Entitlement entitlement = this.mockUnmappedGuestEntitlement(owner, consumer, product, range, product);
consumer.addEntitlement(entitlement);
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
Date expectedEnd = new Date(now.getTime() + (24 * 60 * 60 * 1000));
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range.getStartDate(), cip.getStartDate());
assertEquals(expectedEnd, cip.getEndDate());
}
@Test
public void validRangeIgnoresExpiredWithNoOverlap() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -6, -3);
DateRange range2 = this.rangeRelativeToDate(now, -1, 6);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range2, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range2.getStartDate(), cip.getStartDate());
assertEquals(range2.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeIgnoresFutureWithNoOverlap() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, 6, 12);
DateRange range2 = this.rangeRelativeToDate(now, -1, 4);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range2, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range2.getStartDate(), cip.getStartDate());
assertEquals(range2.getEndDate(), cip.getEndDate());
}
@Test
public void enricherSetsArchVersion() {
//test that the enricher sets the arch and version when they are null in the CIP
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
DateRange range = this.rangeRelativeToDate(new Date(), -1, 4);
Entitlement entitlement = this.mockEntitlement(owner, consumer, product, range, product);
consumer.addEntitlement(entitlement);
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
ConsumerInstalledProduct cip = new ConsumerInstalledProduct();
cip.setProductId(product.getId());
consumer.addInstalledProduct(cip);
this.mockOwnerProducts(owner, Arrays.asList(product));
product.setAttribute(Product.Attributes.ARCHITECTURE, "candlepin arch");
product.setAttribute(Product.Attributes.VERSION, "candlepin version");
this.consumerEnricher.enrich(consumer);
assertEquals("candlepin arch", cip.getArch());
assertEquals("candlepin version", cip.getVersion());
}
@Test
public void enricherDoesntSetArchVersion() {
//test that the enricher does not set the arch and version when they are populated
// in the CIP
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
DateRange range = this.rangeRelativeToDate(new Date(), -1, 4);
Entitlement entitlement = this.mockEntitlement(owner, consumer, product, range, product);
consumer.addEntitlement(entitlement);
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
ConsumerInstalledProduct cip = new ConsumerInstalledProduct();
cip.setProductId(product.getId());
consumer.addInstalledProduct(cip);
this.mockOwnerProducts(owner, Arrays.asList(product));
// Set these to non-null values to show they aren't overwritten
cip.setArch("original arch");
cip.setVersion("original version");
product.setAttribute(Product.Attributes.ARCHITECTURE, "candlepin arch");
product.setAttribute(Product.Attributes.VERSION, "candlepin version");
this.consumerEnricher.enrich(consumer);
assertEquals("original arch", cip.getArch());
assertEquals("original version", cip.getVersion());
}
@Test
public void validRangeIgnoresFutureWithOverlap() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, 12, 24);
DateRange range2 = this.rangeRelativeToDate(now, 0, 13);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range2, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range2.getStartDate(), cip.getStartDate());
assertEquals(range1.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeIgnoresFutureBackToBack() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, 12, 24);
DateRange range2 = this.rangeRelativeToDate(now, 0, 12);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range2, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range2.getStartDate(), cip.getStartDate());
assertEquals(range1.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeWithMultipleEntsWithOverlap() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 4);
DateRange range2 = this.rangeRelativeToDate(now, 1, 8);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range2, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range1.getStartDate(), cip.getStartDate());
assertEquals(range2.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeWithMultipleWhereOneConsumesTheOthersSpan() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 4);
DateRange range2 = this.rangeRelativeToDate(now, 0, 2);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range2, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range1.getStartDate(), cip.getStartDate());
assertEquals(range1.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeWithMultipleWhereFutureEntitlementOverlaps() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 2);
DateRange range2 = this.rangeRelativeToDate(now, 2, 4);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range2, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range1.getStartDate(), cip.getStartDate());
assertEquals(range2.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeWithMultipleWhereExpiredEntitlementOverlaps() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 2);
DateRange range2 = this.rangeRelativeToDate(now, -7, -3);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range2, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range2.getStartDate(), cip.getStartDate());
assertEquals(range1.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeIsNullWhenOnlyFutureEntitlementExists() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, 4, 2);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(null, cip.getStartDate());
assertEquals(null, cip.getEndDate());
}
@Test
public void validRangeIsNullWhenOnlyExpiredEntitlementExists() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, -2);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(null, cip.getStartDate());
assertEquals(null, cip.getEndDate());
}
// Stacking becomes involved here.
@Test
public void validRangeNotNullWhenOnlyPartialEntitlement() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 4);
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range1.getStartDate(), cip.getStartDate());
assertEquals(range1.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeCorrectPartialEntitlementNoGap() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 4);
DateRange range2 = this.rangeRelativeToDate(now, 4, 9);
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range2, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range1.getStartDate(), cip.getStartDate());
assertEquals(range2.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeCorrectPartialEntitlementGap() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 4);
DateRange range2 = this.rangeRelativeToDate(now, 5, 9);
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range2, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range1.getStartDate(), cip.getStartDate());
assertEquals(range1.getEndDate(), cip.getEndDate());
}
@Test
public void multiEntGreenNowYellowFutureWithOverlap() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 12);
DateRange range2 = this.rangeRelativeToDate(now, 11, 24);
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range2, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range1.getStartDate(), cip.getStartDate());
assertEquals(range1.getEndDate(), cip.getEndDate());
}
@Test
public void multiEntGreenNowInnerDatesYellowFutureWithOverlap() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 12);
DateRange range2 = this.rangeRelativeToDate(now, -3, 10);
DateRange range3 = this.rangeRelativeToDate(now, 11, 24);
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range2, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range3, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range2.getStartDate(), cip.getStartDate());
assertEquals(range2.getEndDate(), cip.getEndDate());
}
// Test valid range with a full stack where one stacked entitlement provides the product
@Test
public void validRangeWhenStackedButOneProvides() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Product product2 = TestUtil.createProduct("p2", "product2");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 4);
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product2, 1, range1, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range1.getStartDate(), cip.getStartDate());
assertEquals(range1.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeEndDateSetToFirstDateOfLosingValidStatus() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 4);
DateRange range2 = this.rangeRelativeToDate(now, -2, 10);
DateRange range3 = this.rangeRelativeToDate(now, -3, -1);
DateRange range4 = this.rangeRelativeToDate(range1.getEndDate(), 0, 10);
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range2, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range3, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range4, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range3.getStartDate(), cip.getStartDate());
assertEquals(range2.getEndDate(), cip.getEndDate());
}
@Test
public void cannotStackFutureSubs() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 12);
DateRange range2 = this.rangeRelativeToDate(range1.getEndDate(), 5, 6);
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range2, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
ComplianceStatus status = complianceRules.getStatus(consumer, now);
assertEquals("partial", status.getStatus());
assertTrue(status.getPartialStacks().containsKey("stack_id_1"));
}
@Test
public void validRangeConsidersInvalidGapBetweenNonStackedAndPartialEntitlement() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, -2);
DateRange range2 = this.rangeRelativeToDate(now, -3, 2);
DateRange range3 = this.rangeRelativeToDate(now, -1, 4);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range2, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 1, range3, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range3.getStartDate(), cip.getStartDate());
assertEquals(range2.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeConsidersInvalidGapBetweenNonStackedEntitlement() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Product stacked = TestUtil.createProduct("p1_stack", "product1-stacked");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, -2);
DateRange range2 = this.rangeRelativeToDate(now, -3, 2);
DateRange range3 = this.rangeRelativeToDate(now, -1, 4);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", stacked, 1, range2, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range3, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range3.getStartDate(), cip.getStartDate());
assertEquals(range3.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeConsidersNonStackingEntNotCoveringMachineSocketsInvalid() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
Product sockets = TestUtil.createProduct("socketed", "socketed_product");
sockets.setAttribute(Product.Attributes.SOCKETS, "2");
Consumer consumer = this.mockConsumer(owner, product);
consumer.setCreated(now);
DateRange range1 = this.rangeRelativeToDate(now, -4, 4);
DateRange range2 = this.rangeRelativeToDate(now, -2, 6);
consumer.addEntitlement(this.mockEntitlement(owner, consumer, sockets, range1, product));
consumer.addEntitlement(this.mockEntitlement(owner, consumer, product, range2, product));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range2.getStartDate(), cip.getStartDate());
assertEquals(range2.getEndDate(), cip.getEndDate());
}
@Test
public void validRangeWhenGuestLimitOverridden() {
Date now = new Date();
Owner owner = TestUtil.createOwner();
Product product = TestUtil.createProduct("p1", "product1");
product.setAttribute(Product.Attributes.GUEST_LIMIT, "2");
Product product2 = TestUtil.createProduct("p2", "product2");
product2.setAttribute(Product.Attributes.GUEST_LIMIT, "-1");
Product product3 = TestUtil.createProduct("p3", "product3");
Consumer consumer = this.mockConsumer(owner, product);
for (int i = 0; i < 5; i++) {
consumer.addGuestId(new GuestId(String.valueOf(i), consumer, this.getActiveGuestAttrs()));
}
DateRange range1 = this.rangeRelativeToDate(now, -4, 4);
DateRange range2 = this.rangeRelativeToDate(now, -2, 2);
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_1", product, 10, range1, product));
consumer.addEntitlement(
this.mockStackedEntitlement(owner, consumer, "stack_id_2", product2, 10, range2, product3));
this.mockConsumerEntitlements(consumer, consumer.getEntitlements());
this.mockOwnerProducts(owner, Arrays.asList(product, product2, product3));
this.consumerEnricher.enrich(consumer);
ConsumerInstalledProduct cip = this.getInstalledProduct(consumer, product);
assertEquals(range2.getStartDate(), cip.getStartDate());
assertEquals(range2.getEndDate(), cip.getEndDate());
}
private static int lastPoolId = 1;
private Entitlement mockEntitlement(Owner owner, Consumer consumer, Product product, DateRange range,
Product... providedProducts) {
Set<Product> provided = new HashSet<Product>();
for (Product pp : providedProducts) {
provided.add(pp);
}
final Pool p = new Pool(
owner,
product,
provided,
new Long(1000),
range.getStartDate(),
range.getEndDate(),
"1000",
"1000",
"1000"
);
p.setId("" + lastPoolId++);
Entitlement e = new Entitlement(p, consumer, 1);
when(poolCurator.provides(p, product.getId())).thenReturn(true);
for (Product pp : providedProducts) {
when(poolCurator.provides(p, pp.getId())).thenReturn(true);
}
Random gen = new Random();
int id = gen.nextInt(Integer.MAX_VALUE);
e.setId(String.valueOf(id));
return e;
}
private Entitlement mockUnmappedGuestEntitlement(Owner owner, Consumer consumer, Product product,
DateRange range, Product ... providedProducts) {
consumer.setFact("virt.is_guest", "True");
Entitlement e = mockEntitlement(owner, consumer, product, range, providedProducts);
Pool p = e.getPool();
Date endDateOverride = new Date(consumer.getCreated().getTime() + (24 * 60 * 60 * 1000));
e.setEndDateOverride(endDateOverride);
// Setup the attributes for stacking:
p.setAttribute("virt_only", "true");
p.setAttribute("unmapped_guests_only", "true");
product.setAttribute("virt_limit", "unlimited");
return e;
}
private Consumer mockConsumer(Owner owner, Product... installedProducts) {
Consumer consumer = new Consumer();
consumer.setType(new ConsumerType(ConsumerType.ConsumerTypeEnum.SYSTEM));
consumer.setOwner(owner);
for (Product product : installedProducts) {
consumer.addInstalledProduct(new ConsumerInstalledProduct(consumer, product));
}
consumer.setFact("cpu.cpu_socket(s)", "4");
return consumer;
}
private Entitlement mockStackedEntitlement(Owner owner, Consumer consumer, String stackId,
Product product, int quantity, DateRange range, Product ... providedProducts) {
Entitlement entitlement = this.mockEntitlement(owner, consumer, product, range, providedProducts);
entitlement.setQuantity(quantity);
Pool pool = entitlement.getPool();
// Setup the attributes for stacking:
pool.getProduct().setAttribute("stacking_id", stackId);
pool.getProduct().setAttribute("sockets", "2");
return entitlement;
}
private DateRange rangeRelativeToDate(Date relativeTo, int startMonths, int endMonths) {
Calendar cal = Calendar.getInstance();
cal.setTime(relativeTo);
cal.add(Calendar.MONTH, startMonths);
Date start = cal.getTime();
cal.setTime(relativeTo);
cal.add(Calendar.MONTH, endMonths);
Date end = cal.getTime();
return new DateRange(start, end);
}
private void mockConsumerEntitlements(Consumer consumer, Collection<Entitlement> entitlements) {
List<Entitlement> entList = new LinkedList(entitlements);
CandlepinQuery mockCPQuery = mock(CandlepinQuery.class);
when(mockCPQuery.list()).thenReturn(entList);
when(mockCPQuery.iterator()).thenReturn(entitlements.iterator());
when(entCurator.listByConsumer(eq(consumer))).thenReturn(entList);
when(entCurator.listByConsumerAndDate(eq(consumer), any(Date.class))).thenReturn(mockCPQuery);
}
private Map<String, String> getActiveGuestAttrs() {
Map<String, String> activeGuestAttrs = new HashMap<String, String>();
activeGuestAttrs.put("virtWhoType", "libvirt");
activeGuestAttrs.put("active", "1");
return activeGuestAttrs;
}
private void mockOwnerProducts(Owner owner, Collection<Product> products) {
final Map<String, Product> productMap = new HashMap<String, Product>();
for (Product product : products) {
productMap.put(product.getId(), product);
}
doAnswer(new Answer<CandlepinQuery<Product>>() {
@Override
public CandlepinQuery<Product> answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
Collection<String> productIds = (Collection<String>) args[1];
Collection<Product> products = new LinkedList<Product>();
for (String productId : productIds) {
Product product = productMap.get(productId);
if (product != null) {
products.add(product);
}
}
CandlepinQuery cqmock = mock(CandlepinQuery.class);
when(cqmock.iterator()).thenReturn(products.iterator());
when(cqmock.iterate()).thenReturn(new MockResultIterator(products.iterator()));
return cqmock;
}
}).when(this.ownerProductCurator).getProductsByIds(eq(owner), anyCollection());
}
private ConsumerInstalledProduct getInstalledProduct(Consumer consumer, Product product) {
for (ConsumerInstalledProduct cip : consumer.getInstalledProducts()) {
if (cip.getProductId().equals(product.getId())) {
return cip;
}
}
return null;
}
}