/**
* Copyright (C) 2015 Orange
* Licensed 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 com.francetelecom.clara.cloud.paas.activation.v1;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.engine.ManagementService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.Job;
import org.activiti.engine.runtime.ProcessInstance;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import com.francetelecom.clara.cloud.commons.tasks.PollTaskStateInterface;
import com.francetelecom.clara.cloud.commons.tasks.TaskStatus;
import com.francetelecom.clara.cloud.commons.tasks.TaskStatusEnum;
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class PollingConsumerTest {
@Autowired
RuntimeService runtimeService;
@Autowired
RepositoryService repositoryService;
@Autowired
ManagementService managementService;
// myBackend is a mock
@Autowired
PollTaskStateInterface<TaskStatus> myBackend;
@Before
public void setup() {
// deploy the process
repositoryService
.createDeployment()
.addClasspathResource(
"com/francetelecom/clara/cloud/paas/activation/v1/polling-consumer.bpmn20.xml")
.deploy();
}
@After
public void teardown() {
// reset mock
reset(myBackend);
}
@Test
@Transactional
public void processExecutionWaitsBeforePollingBackendTest()
throws InterruptedException {
/* GIVEN */
// Given polled task is not completed yet
TaskStatus isNotCompleteTaskStatus = new TaskStatus(0);
isNotCompleteTaskStatus.setTaskStatus(TaskStatusEnum.STARTED);
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("taskStatus", isNotCompleteTaskStatus);
// and max polling attempts is 2
variables.put("maxAttempts", 2);
// and delay between 2 polling attempts is PT5M
variables.put("backOffPeriod", "PT5M");
/* WHEN */
// when a new polling process instance is started
ProcessInstance pi = runtimeService.startProcessInstanceByKey(
"polling-consumer", variables);
/* THEN */
// then polling process instance should be pending and should wait for
// a timer event to be thrown
List<Job> jobs = managementService.createJobQuery().list();
assertNotNull("job list should not be null!!!!", jobs);
assertEquals("there should be 1 pending job !!!!", 1, jobs.size());
}
@Test
@Transactional
public void taskIsCompleteWhenFirstPollTest() {
/* GIVEN */
// Given polled task is completed
TaskStatus isCompleteTaskStatus = new TaskStatus(0);
isCompleteTaskStatus.setTaskStatus(TaskStatusEnum.FINISHED_OK);
given(myBackend.giveCurrentTaskStatus(any(TaskStatus.class)))
.willReturn(isCompleteTaskStatus);
// and a process execution is waiting for a timer event to be thrown
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("taskStatus", new TaskStatus(0));
// and max polling attempts is 2
variables.put("maxAttempts", 2);
// and delay between 2 polling attempts is PT5M
variables.put("backOffPeriod", "PT5M");
ProcessInstance pi = runtimeService.startProcessInstanceByKey(
"polling-consumer", variables);
/* WHEN */
// when polling process execution catches timer event
List<Job> jobs = managementService.createJobQuery().list();
managementService.executeJob(jobs.get(0).getId());
/* THEN */
// then myBackend.giveCurrentTaskStatus(...) must have been called once
verify(myBackend, times(1))
.giveCurrentTaskStatus(any(TaskStatus.class));
// and no job must be pending
jobs = managementService.createJobQuery().list();
assertEquals("there should be 0 pending job !!!!", 0, jobs.size());
}
@Test
@Transactional
public void taskIsCompleteWhenSecondPollTest() {
/* GIVEN */
// Given polled task is no completed after first poll and is completed
// after second poll
TaskStatus isCompleteTaskStatus = new TaskStatus(0);
isCompleteTaskStatus.setTaskStatus(TaskStatusEnum.FINISHED_OK);
TaskStatus isNotCompleteTaskStatus = new TaskStatus(0);
isNotCompleteTaskStatus.setTaskStatus(TaskStatusEnum.STARTED);
given(myBackend.giveCurrentTaskStatus(any(TaskStatus.class)))
.willReturn(isNotCompleteTaskStatus).willReturn(
isCompleteTaskStatus);
// and a process execution is waiting for a timer event to be thrown
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("taskStatus", new TaskStatus(0));
// and max polling attempts is 2
variables.put("maxAttempts", 2);
// and delay between 2 polling attempts is PT5M
variables.put("backOffPeriod", "PT5M");
ProcessInstance pi = runtimeService.startProcessInstanceByKey(
"polling-consumer", variables);
/* WHEN */
// when polling process execution catches timer event
List<Job> jobs = managementService.createJobQuery().list();
managementService.executeJob(jobs.get(0).getId());
// and polling process execution catches timer event
jobs = managementService.createJobQuery().list();
managementService.executeJob(jobs.get(0).getId());
/* THEN */
// assert that myBackend.giveCurrentTaskStatus(...) has been called
// twice
verify(myBackend, times(2))
.giveCurrentTaskStatus(any(TaskStatus.class));
// assert that no job is pending
jobs = managementService.createJobQuery().list();
assertEquals("there should be 0 pending job !!!!", 0, jobs.size());
}
@Test
@Transactional
public void taskIsNeverCompleteTest() {
/* GIVEN */
// Given polled task is never completed
TaskStatus isNeverCompleteTaskStatus = new TaskStatus(0);
isNeverCompleteTaskStatus.setTaskStatus(TaskStatusEnum.STARTED);
given(myBackend.giveCurrentTaskStatus(any(TaskStatus.class)))
.willReturn(isNeverCompleteTaskStatus);
// and a process execution is waiting for a timer event to be thrown
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("taskStatus", new TaskStatus(0));
variables.put("maxAttempts", 2);
// and delay between 2 polling attempts is PT5M
variables.put("backOffPeriod", "PT5M");
ProcessInstance pi = runtimeService.startProcessInstanceByKey(
"polling-consumer", variables);
/* WHEN */
// when polling process execution catches timer event
List<Job> jobs = managementService.createJobQuery().list();
managementService.executeJob(jobs.get(0).getId());
// and polling process execution catches timer event
jobs = managementService.createJobQuery().list();
managementService.executeJob(jobs.get(0).getId());
/* THEN */
// assert that myBackend.giveCurrentTaskStatus(...) has been called
// twice
verify(myBackend, times(2))
.giveCurrentTaskStatus(any(TaskStatus.class));
// assert that no job is pending
jobs = managementService.createJobQuery().list();
assertEquals("there should be 0 pending job !!!!", 0, jobs.size());
}
}