/** * 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.pinsetter.tasks; import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import org.candlepin.common.exceptions.ForbiddenException; import org.candlepin.controller.Entitler; import org.candlepin.model.CandlepinQuery; import org.candlepin.model.Consumer; import org.candlepin.model.ConsumerType; import org.candlepin.model.Entitlement; import org.candlepin.model.Owner; import org.candlepin.model.Pool; import org.candlepin.model.PoolCurator; import org.candlepin.model.dto.PoolIdAndErrors; import org.candlepin.model.dto.PoolIdAndQuantity; import org.candlepin.pinsetter.core.model.JobStatus; import org.candlepin.policy.EntitlementRefusedException; import org.candlepin.policy.ValidationResult; import org.hibernate.mapping.Map; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.xnap.commons.i18n.I18n; import org.xnap.commons.i18n.I18nFactory; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; /** * EntitlerJobTest */ public class EntitlerJobTest { private String consumerUuid; private Consumer consumer; private Entitler e; private PoolCurator pC; private I18n i18n; @Before public void init() { consumerUuid = "49bd6a8f-e9f8-40cc-b8d7-86cafd687a0e"; consumer = new Consumer("Test Consumer", "test-consumer", new Owner("test-owner"), new ConsumerType("system")); consumer.setUuid(consumerUuid); e = mock(Entitler.class); pC = mock(PoolCurator.class); i18n = I18nFactory.getI18n(getClass(), Locale.US, I18nFactory.FALLBACK); } @Test public void bindByPoolSetup() { String pool = "pool10"; PoolIdAndQuantity[] pQs = new PoolIdAndQuantity[1]; pQs[0] = new PoolIdAndQuantity(pool, 1); JobDetail detail = EntitlerJob.bindByPoolAndQuantities(consumer, pQs); assertNotNull(detail); PoolIdAndQuantity[] resultPools = (PoolIdAndQuantity[]) detail.getJobDataMap().get( "pool_and_quantities"); assertEquals("pool10", resultPools[0].getPoolId()); assertEquals(1, resultPools[0].getQuantity().intValue()); assertEquals(consumerUuid, detail.getJobDataMap().get(JobStatus.TARGET_ID)); assertTrue(detail.getKey().getName().startsWith("bind_by_pool_")); } @Test public void bindByPoolExec() throws JobExecutionException, EntitlementRefusedException { String pool = "pool10"; PoolIdAndQuantity[] pQs = new PoolIdAndQuantity[1]; pQs[0] = new PoolIdAndQuantity(pool, 1); JobDetail detail = EntitlerJob.bindByPoolAndQuantities(consumer, pQs); JobExecutionContext ctx = mock(JobExecutionContext.class); when(ctx.getMergedJobDataMap()).thenReturn(detail.getJobDataMap()); List<Entitlement> ents = new ArrayList<Entitlement>(); Pool p = new Pool(); p.setId(pool); Entitlement ent = new Entitlement(); ent.setPool(p); ent.setQuantity(100); ents.add(ent); when(e.bindByPoolQuantities(eq(consumerUuid), anyMapOf(String.class, Integer.class))) .thenReturn(ents); EntitlerJob job = new EntitlerJob(e, null, pC, null); job.execute(ctx); verify(e).bindByPoolQuantities(eq(consumerUuid), anyMapOf(String.class, Integer.class)); verify(e).sendEvents(eq(ents)); ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class); verify(ctx).setResult(argumentCaptor.capture()); PoolIdAndQuantity[] result = (PoolIdAndQuantity[]) argumentCaptor.getValue(); assertEquals(1, result.length); assertEquals(pool, result[0].getPoolId()); assertEquals(100, result[0].getQuantity().intValue()); } /** * At first glance this seems like a stupid test of Quartz functionality, * but its intent is to ensure that what we put into the JobDataMap can * be serialized to the database for Quartz clustering. If this test fails * 9/10 times one of the objects added does not implement the Serializable * interface. * @throws IOException */ @Test public void serializeJobDataMapForPool() throws IOException { PoolIdAndQuantity[] pQs = new PoolIdAndQuantity[1]; pQs[0] = new PoolIdAndQuantity("pool10", 1); JobDetail detail = EntitlerJob.bindByPoolAndQuantities(consumer, pQs); serialize(detail.getJobDataMap()); } @Test public void recoveryIsFalse() { PoolIdAndQuantity[] pQs = new PoolIdAndQuantity[1]; pQs[0] = new PoolIdAndQuantity("pool10", 1); JobDetail detail = EntitlerJob.bindByPoolAndQuantities(consumer, pQs); assertFalse(detail.requestsRecovery()); assertTrue(detail.isDurable()); } private void serialize(Object obj) throws IOException { ObjectOutput out = new ObjectOutputStream(new FileOutputStream("obj.ser")); out.writeObject(obj); out.close(); } @Test(expected = JobExecutionException.class) public void handleException() throws JobExecutionException, EntitlementRefusedException { PoolIdAndQuantity[] pQs = new PoolIdAndQuantity[1]; pQs[0] = new PoolIdAndQuantity("pool10", 1); JobDetail detail = EntitlerJob.bindByPoolAndQuantities(consumer, pQs); JobExecutionContext ctx = mock(JobExecutionContext.class); when(ctx.getMergedJobDataMap()).thenReturn(detail.getJobDataMap()); Class<HashMap<String, Integer>> className = (Class<HashMap<String, Integer>>) (Class) Map.class; ArgumentCaptor<HashMap<String, Integer>> pqMapCaptor = ArgumentCaptor.forClass(className); when(e.bindByPoolQuantities(eq(consumerUuid), pqMapCaptor.capture())) .thenThrow(new ForbiddenException("job should fail")); EntitlerJob job = new EntitlerJob(e, null, null, null); job.execute(ctx); } @Test public void respondWithValidationErrors() throws JobExecutionException, EntitlementRefusedException { PoolIdAndQuantity[] pQs = new PoolIdAndQuantity[1]; pQs[0] = new PoolIdAndQuantity("pool10", 1); JobDetail detail = EntitlerJob.bindByPoolAndQuantities(consumer, pQs); JobExecutionContext ctx = mock(JobExecutionContext.class); when(ctx.getMergedJobDataMap()).thenReturn(detail.getJobDataMap()); HashMap<String, ValidationResult> mapResult = new HashMap<String, ValidationResult>(); ValidationResult result = new ValidationResult(); result.addError("rulefailed.no.entitlements.available"); mapResult.put("hello", result); when(e.bindByPoolQuantities(eq(consumerUuid), anyMapOf(String.class, Integer.class))) .thenThrow(new EntitlementRefusedException(mapResult)); EntitlerJob job = new EntitlerJob(e, null, pC, i18n); Pool p = new Pool(); p.setId("hello"); CandlepinQuery cqmock = mock(CandlepinQuery.class); when(cqmock.iterator()).thenReturn(Arrays.asList(p).iterator()); when(pC.listAllByIds(anyListOf(String.class))).thenReturn(cqmock); job.execute(ctx); ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class); verify(ctx).setResult(argumentCaptor.capture()); List<PoolIdAndErrors> resultErrors = (List<PoolIdAndErrors>) argumentCaptor.getValue(); assertEquals(1, resultErrors.size()); assertEquals("hello", resultErrors.get(0).getPoolId()); assertEquals(1, resultErrors.get(0).getErrors().size()); assertEquals("No subscriptions are available from the pool with ID 'hello'.", resultErrors.get(0) .getErrors().get(0)); } @After public void cleanup() { new File("obj.ser").delete(); } }