blob: fa3e8458b12c5a6b458ad441de2b358249d7b866 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sling.jobs.impl;
import org.apache.sling.jobs.*;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
/**
*/
public class JobImplTest {
private Job job;
private String jobId;
@Mock
private JobController jobController;
private final long before = System.currentTimeMillis();
private long after = System.currentTimeMillis();
private boolean jobAborted;
private boolean jobStopped;
public JobImplTest() {
MockitoAnnotations.initMocks(this);
}
@Before
public void setUp() throws Exception {
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
jobAborted = true;
return null;
}
}).when(jobController).abort();
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
jobStopped = true;
return null;
}
}).when(jobController).stop();
Thread.sleep(1);
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("job.name", "Jobname");
jobId = Utils.generateId();
job = new JobImpl(Types.jobQueue("testtopic"), jobId, Types.jobType("testtype"), properties);
Thread.sleep(1);
after = System.currentTimeMillis();
}
@Test
public void testGetTopic() throws Exception {
assertEquals(Types.jobQueue("testtopic"), job.getQueue());
}
@Test
public void testGetId() throws Exception {
assertEquals(jobId, job.getId());
}
@Test
public void testGetProperties() throws Exception {
assertEquals(1, job.getProperties().size());
assertEquals("Jobname", job.getProperties().get("job.name"));
}
@Test
public void testGetRetryCount() throws Exception {
assertEquals(0,job.getRetryCount());
}
@Test
public void testGetNumberOfRetries() throws Exception {
assertEquals(0,job.getNumberOfRetries());
}
@Test
public void testGetStarted() throws Exception {
assertEquals(0, job.getStarted());
}
@Test
public void testGetCreated() throws Exception {
long created = job.getCreated();
assertTrue(created > before && created < after);
}
@Test
public void testGetJobState() throws Exception {
assertEquals(Job.JobState.CREATED, job.getJobState());
}
@Test
public void testSetState() throws Exception {
assertEquals(Job.JobState.CREATED,job.getJobState());
job.setState(Job.JobState.STOPPED);
assertEquals(Job.JobState.STOPPED, job.getJobState());
}
@Test
public void testGetFinished() throws Exception {
assertEquals(0,job.getFinished());
}
@Test
public void testGetResultMessage() throws Exception {
assertEquals("",job.getResultMessage());
}
@Test
public void testGetController() throws Exception {
assertEquals(null,job.getController());
}
@Test
public void testSetJobController() throws Exception {
assertEquals(null,job.getController());
job.setJobController(jobController);
assertEquals(jobController,job.getController());
}
@Test
public void testRemoveJobController() throws Exception {
assertEquals(null,job.getController());
job.setJobController(jobController);
assertEquals(jobController, job.getController());
job.removeJobController();
assertEquals(null, job.getController());
}
@Test
public void testUpdate() throws Exception {
JobImpl jobImpl = (JobImpl) job;
JobUpdateBuilder jobUpdateBuilder = jobImpl.newJobUpdateBuilder();
assertNotNull(jobUpdateBuilder);
Map<String,Object> updateProperties = new HashMap<String, Object>();
updateProperties.put("updateprop", "updatevalue");
JobUpdate jobUpdate = jobUpdateBuilder
.command(JobUpdate.JobUpdateCommand.START_JOB)
.putAll(updateProperties)
.put("extra", "extravalue")
.build();
jobImpl.update(jobUpdate);
// Job update does not change the job state even if the command says so.
// the state change comes from a job starter.
assertEquals(Job.JobState.CREATED, job.getJobState());
assertEquals(3, job.getProperties().size());
assertEquals("Jobname", job.getProperties().get("job.name"));
assertEquals("extravalue", job.getProperties().get("extra"));
assertEquals("updatevalue", job.getProperties().get("updateprop"));
JobImpl jobImp = new JobImpl(jobUpdate);
assertEquals(job.getId(), jobImp.getId());
// update with some, but not all the new properties.
updateProperties = new HashMap<String, Object>();
updateProperties.put("updateprop", "updatevalue2");
jobImpl.update(jobImpl.newJobUpdateBuilder()
.command(JobUpdate.JobUpdateCommand.UPDATE_JOB)
.putAll(updateProperties)
.put("extra", "extravalue")
.build());
assertEquals(Job.JobState.CREATED, job.getJobState());
assertEquals(3, job.getProperties().size());
assertEquals("Jobname", job.getProperties().get("job.name"));
assertEquals("extravalue", job.getProperties().get("extra"));
assertEquals("updatevalue2", job.getProperties().get("updateprop"));
// remove a property.
jobImpl.update(jobImpl.newJobUpdateBuilder()
.command(JobUpdate.JobUpdateCommand.UPDATE_JOB)
.put("extra", JobUpdate.JobPropertyAction.REMOVE)
.build());
assertEquals(Job.JobState.CREATED, job.getJobState());
assertEquals(2, job.getProperties().size());
assertEquals("Jobname", job.getProperties().get("job.name"));
assertEquals("updatevalue2", job.getProperties().get("updateprop"));
// remove a property.
JobUpdate retryUpdate = jobImpl.newJobUpdateBuilder()
.command(JobUpdate.JobUpdateCommand.RETRY_JOB)
.put("updateprop", "updatevalue2")
.build();
set(retryUpdate, "numberOfRetries", 10);
set(retryUpdate, "retryCount", 10);
jobImpl.update(retryUpdate);
assertEquals(Job.JobState.CREATED, job.getJobState());
assertEquals(2, job.getProperties().size());
assertEquals("Jobname", job.getProperties().get("job.name"));
assertEquals("updatevalue2", job.getProperties().get("updateprop"));
assertEquals(20, job.getNumberOfRetries());
assertEquals(10,job.getRetryCount());
// Abort the job without a controller present.
jobAborted = false;
jobStopped = false;
jobImpl.update(jobImpl.newJobUpdateBuilder()
.command(JobUpdate.JobUpdateCommand.ABORT_JOB)
.put("extra2", "newextra2")
.build());
assertEquals(Job.JobState.CREATED, job.getJobState());
assertEquals(2, job.getProperties().size());
assertEquals("Jobname", job.getProperties().get("job.name"));
assertEquals("updatevalue2", job.getProperties().get("updateprop"));
assertFalse(jobAborted);
assertFalse(jobStopped);
// set a controller as if the job was stated.
job.setJobController(jobController);
jobAborted = false;
jobStopped = false;
// abort the job
jobImpl.update(jobImpl.newJobUpdateBuilder()
.command(JobUpdate.JobUpdateCommand.ABORT_JOB)
.put("extra2", "newextra3")
.build());
assertEquals(Job.JobState.CREATED, job.getJobState());
// abort does not update properties.
assertEquals(2, job.getProperties().size());
assertEquals("Jobname", job.getProperties().get("job.name"));
assertEquals("updatevalue2", job.getProperties().get("updateprop"));
assertTrue(jobAborted);
assertFalse(jobStopped);
jobAborted = false;
jobStopped = false;
JobUpdate wrongOrder = jobImpl.newJobUpdateBuilder()
.command(JobUpdate.JobUpdateCommand.UPDATE_JOB)
.put("extra2", "newextra4")
.build();
Thread.sleep(2);
// abort the job
jobImpl.update(jobImpl.newJobUpdateBuilder()
.command(JobUpdate.JobUpdateCommand.STOP_JOB)
.put("extra2", "newextra4")
.build());
assertEquals(Job.JobState.CREATED, job.getJobState());
assertEquals(2, job.getProperties().size());
assertEquals("Jobname", job.getProperties().get("job.name"));
assertEquals("updatevalue2", job.getProperties().get("updateprop"));
assertFalse(jobAborted);
assertTrue(jobStopped);
try {
jobImpl.update(wrongOrder);
fail("Update should have been rejected due to out of sequence");
} catch ( IllegalStateException e) {
// ok
}
JobUpdate wrongId = new JobUpdateImpl(Utils.generateId(), JobUpdate.JobUpdateCommand.UPDATE_JOB);
try {
jobImpl.update(wrongId);
fail("Update should have been rejected due wrong Id");
} catch ( IllegalArgumentException e) {
// ok
}
JobUpdate expired = jobImpl.newJobUpdateBuilder()
.command(JobUpdate.JobUpdateCommand.STOP_JOB)
.put("extra2", "newextra4")
.build();
set(expired, "expires", System.currentTimeMillis());
Thread.sleep(1);
try {
jobImpl.update(expired);
fail("Update should have expired");
} catch ( IllegalStateException e) {
// ok
}
try {
JobUpdate failJobUpdate = new JobUpdateBuilderImpl(job.getId()).command(JobUpdate.JobUpdateCommand.START_JOB).build();
fail("should not be able to build a job by ID only");
} catch ( IllegalStateException e) {
// ok
JobUpdate stopJob = new JobUpdateBuilderImpl(job.getId()).command(JobUpdate.JobUpdateCommand.STOP_JOB).build();
JobUpdate abortJob = new JobUpdateBuilderImpl(job.getId()).command(JobUpdate.JobUpdateCommand.ABORT_JOB).build();
}
}
private void set(Object obj, String name, Object v) throws NoSuchFieldException, IllegalAccessException {
Field f = obj.getClass().getDeclaredField(name);
f.setAccessible(true);
f.set(obj, v);
}
@Test
public void testNewJobUpdateBuilder() throws Exception {
long updateBefore = System.currentTimeMillis();
Thread.sleep(1);
JobImpl jobImpl = (JobImpl) job;
JobUpdateBuilder jobUpdateBuilder = jobImpl.newJobUpdateBuilder();
assertNotNull(jobUpdateBuilder);
Map<String,Object> updateProperties = new HashMap<String, Object>();
updateProperties.put("updateprop", "updatevalue");
JobUpdate jobUpdate = jobUpdateBuilder
.command(JobUpdate.JobUpdateCommand.START_JOB)
.putAll(updateProperties)
.put("extra", "extravalue")
.build();
Thread.sleep(1);
long updateAfter = System.currentTimeMillis();
assertNotNull(jobUpdate);
assertEquals(jobId, jobUpdate.getId());
assertEquals(Types.jobQueue("testtopic"), jobUpdate.getQueue());
assertEquals("", jobUpdate.getResultMessage());
assertTrue(jobUpdate.expires() > updateAfter);
assertTrue(jobUpdate.updateTimestamp() > updateBefore && jobUpdate.updateTimestamp() < updateAfter);
assertTrue(jobUpdate.getCreated() > before && jobUpdate.getCreated() < after);
assertEquals(JobUpdate.JobUpdateCommand.START_JOB, jobUpdate.getCommand());
assertEquals(Job.JobState.CREATED, jobUpdate.getState());
assertEquals(0, jobUpdate.getStarted());
assertEquals(0,jobUpdate.getFinished());
assertEquals(0,jobUpdate.getRetryCount());
assertEquals(0,jobUpdate.getNumberOfRetries());
assertEquals(2,jobUpdate.getProperties().size());
assertEquals("extravalue", jobUpdate.getProperties().get("extra"));
assertEquals("updatevalue",jobUpdate.getProperties().get("updateprop"));
}
}