/** * 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.core; import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import static org.quartz.JobKey.*; import org.candlepin.auth.Principal; import org.candlepin.model.JobCurator; import org.candlepin.pinsetter.core.model.JobStatus; import org.candlepin.pinsetter.core.model.JobStatus.JobState; import com.google.inject.persist.UnitOfWork; import org.apache.commons.lang.RandomStringUtils; import org.junit.Before; import org.junit.Test; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * PinsetterJobListenerTest */ public class PinsetterJobListenerTest { private PinsetterJobListener listener; private JobCurator jcurator; private UnitOfWork unitOfWork; private JobExecutionContext ctx; @Before public void init() { jcurator = mock(JobCurator.class); unitOfWork = mock(UnitOfWork.class); listener = new PinsetterJobListener(jcurator, unitOfWork); ctx = mock(JobExecutionContext.class); } @Test public void name() { assertEquals(PinsetterJobListener.LISTENER_NAME, listener.getName()); } @Test public void tobeExecuted() { Principal principal = mock(Principal.class); JobDataMap map = new JobDataMap(); JobDetail detail = mock(JobDetail.class); JobStatus status = mock(JobStatus.class); map.put(PinsetterJobListener.PRINCIPAL_KEY, principal); when(ctx.getMergedJobDataMap()).thenReturn(map); when(detail.getKey()).thenReturn(jobKey("foo")); when(ctx.getJobDetail()).thenReturn(detail); when(jcurator.find(eq("foo"))).thenReturn(status); listener.jobToBeExecuted(ctx); verify(status).update(eq(ctx)); verify(jcurator).merge(eq(status)); } @Test public void vetoed() { listener.jobExecutionVetoed(ctx); verifyZeroInteractions(ctx); verifyZeroInteractions(jcurator); } @Test public void executed() { JobDetail detail = mock(JobDetail.class); JobStatus status = mock(JobStatus.class); when(detail.getKey()).thenReturn(jobKey("foo")); when(ctx.getJobDetail()).thenReturn(detail); when(jcurator.find(eq("foo"))).thenReturn(status); listener.jobWasExecuted(ctx, null); verify(status).update(eq(ctx)); verify(jcurator).merge(eq(status)); } @Test public void executedNullStatus() { JobExecutionException e = mock(JobExecutionException.class); JobDetail detail = mock(JobDetail.class); JobStatus status = mock(JobStatus.class); when(detail.getKey()).thenReturn(jobKey("foo")); when(ctx.getJobDetail()).thenReturn(detail); when(jcurator.find(eq("foo"))).thenReturn(null); listener.jobWasExecuted(ctx, e); verifyZeroInteractions(status); verify(jcurator, never()).merge(eq(status)); verifyZeroInteractions(e); } @Test public void tobeExecutedNull() { Principal principal = mock(Principal.class); JobDataMap map = new JobDataMap(); JobDetail detail = mock(JobDetail.class); JobStatus status = mock(JobStatus.class); map.put(PinsetterJobListener.PRINCIPAL_KEY, principal); when(ctx.getMergedJobDataMap()).thenReturn(map); when(detail.getKey()).thenReturn(jobKey("foo")); when(ctx.getJobDetail()).thenReturn(detail); when(jcurator.find(eq("foo"))).thenReturn(null); listener.jobToBeExecuted(ctx); verifyZeroInteractions(status); verify(jcurator, never()).merge(eq(status)); } @Test public void handleNullException() { JobStatus status = mock(JobStatus.class); JobDetail detail = mock(JobDetail.class); when(detail.getKey()).thenReturn(jobKey("foo")); when(ctx.getJobDetail()).thenReturn(detail); when(jcurator.find(eq("foo"))).thenReturn(status); listener.jobWasExecuted(ctx, null); verify(status).update(eq(ctx)); verify(jcurator).merge(eq(status)); } @Test public void handleException() { JobExecutionException e = mock(JobExecutionException.class); JobDetail detail = mock(JobDetail.class); JobStatus status = mock(JobStatus.class); when(detail.getKey()).thenReturn(jobKey("foo")); when(ctx.getJobDetail()).thenReturn(detail); when(jcurator.find(eq("foo"))).thenReturn(status); when(e.getMessage()).thenReturn("job errored"); listener.jobWasExecuted(ctx, e); verify(status).setState(eq(JobState.FAILED)); verify(status).setResult(eq("job errored")); verify(status, never()).update(eq(ctx)); verify(jcurator).merge(eq(status)); } @Test public void bug863518WasExecuted() { JobDetail detail = mock(JobDetail.class); when(detail.getKey()).thenReturn(jobKey("foo")); when(ctx.getJobDetail()).thenReturn(detail); when(jcurator.find(any(String.class))).thenThrow(new RuntimeException()); try { listener.jobWasExecuted(ctx, null); } catch (RuntimeException re) { // do nothing, we're really trying to verify end is called } verify(unitOfWork, atLeastOnce()).end(); } @Test public void bug863518ToBeExecuted() { Principal principal = mock(Principal.class); JobDataMap map = new JobDataMap(); JobDetail detail = mock(JobDetail.class); map.put(PinsetterJobListener.PRINCIPAL_KEY, principal); when(ctx.getMergedJobDataMap()).thenReturn(map); when(detail.getKey()).thenReturn(jobKey("foo")); when(ctx.getJobDetail()).thenReturn(detail); when(jcurator.find(any(String.class))).thenThrow(new RuntimeException()); try { listener.jobToBeExecuted(ctx); } catch (RuntimeException re) { // do nothing, we're really trying to verify end is called } verify(unitOfWork, atLeastOnce()).end(); } @Test public void ensureProperLengthOfResult() { JobExecutionException e = mock(JobExecutionException.class); JobDetail detail = mock(JobDetail.class); JobStatus status = mock(JobStatus.class); when(detail.getKey()).thenReturn(jobKey("foo")); when(ctx.getJobDetail()).thenReturn(detail); when(jcurator.find(eq("foo"))).thenReturn(status); String longstr = RandomStringUtils.randomAlphanumeric( JobStatus.RESULT_COL_LENGTH); when(e.getMessage()).thenReturn(longstr); listener.jobWasExecuted(ctx, e); verify(status).setState(eq(JobState.FAILED)); verify(status).setResult(eq(longstr)); verify(status, never()).update(eq(ctx)); verify(jcurator).merge(eq(status)); } @Test public void handleResultTooLong() { JobExecutionException e = mock(JobExecutionException.class); JobDetail detail = mock(JobDetail.class); JobDataMap map = new JobDataMap(); map.put(JobStatus.TARGET_TYPE, JobStatus.TargetType.OWNER); when(detail.getKey()).thenReturn(jobKey("name", "group")); when(detail.getJobDataMap()).thenReturn(map); when(ctx.getJobDetail()).thenReturn(detail); JobStatus status = new JobStatus(detail); when(jcurator.find(eq("name"))).thenReturn(status); String longstr = RandomStringUtils.randomAlphanumeric(300); when(e.getMessage()).thenReturn(longstr); listener.jobWasExecuted(ctx, e); assertEquals(longstr.substring(0, JobStatus.RESULT_COL_LENGTH), status.getResult()); assertEquals(JobState.FAILED, status.getState()); verify(jcurator).merge(eq(status)); } }