blob: ee4426e3f7c9043c23e0c311700c2a49e2eb9c49 [file] [log] [blame]
/*
* Copyright 1999-2015 dangdang.com.
* <p>
* 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.
* </p>
*/
package io.elasticjob.cloud.scheduler.restful;
import io.elasticjob.cloud.scheduler.config.job.CloudJobExecutionType;
import io.elasticjob.cloud.scheduler.fixture.TaskNode;
import io.elasticjob.cloud.scheduler.state.running.RunningService;
import io.elasticjob.cloud.context.ExecutionType;
import io.elasticjob.cloud.event.rdb.JobEventRdbSearch;
import io.elasticjob.cloud.event.type.JobExecutionEvent;
import io.elasticjob.cloud.scheduler.fixture.CloudAppJsonConstants;
import io.elasticjob.cloud.scheduler.fixture.CloudJsonConstants;
import io.elasticjob.cloud.scheduler.state.failover.FailoverTaskInfo;
import io.elasticjob.cloud.statistics.type.task.TaskResultStatistics;
import io.elasticjob.cloud.util.json.GsonFactory;
import io.elasticjob.cloud.context.TaskContext;
import io.elasticjob.cloud.context.TaskContext.MetaInfo;
import io.elasticjob.cloud.event.type.JobStatusTraceEvent;
import io.elasticjob.cloud.event.type.JobStatusTraceEvent.Source;
import io.elasticjob.cloud.event.type.JobStatusTraceEvent.State;
import io.elasticjob.cloud.statistics.type.job.JobExecutionTypeStatistics;
import io.elasticjob.cloud.statistics.type.job.JobTypeStatistics;
import com.google.common.collect.Lists;
import org.hamcrest.core.Is;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.unitils.util.ReflectionUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import static io.elasticjob.cloud.scheduler.restful.RestfulTestsUtil.sentGetRequest;
import static io.elasticjob.cloud.scheduler.restful.RestfulTestsUtil.sentRequest;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public final class CloudJobRestfulApiTest extends AbstractCloudRestfulApiTest {
@Test
public void assertRegister() throws Exception {
when(getRegCenter().get("/config/app/test_app")).thenReturn(CloudAppJsonConstants.getAppJson("test_app"));
when(getRegCenter().isExisted("/config/job/test_job")).thenReturn(false);
assertThat(sentRequest("http://127.0.0.1:19000/api/job/register", "POST", CloudJsonConstants.getJobJson()), is(204));
verify(getRegCenter()).persist("/config/job/test_job", CloudJsonConstants.getJobJson());
sentRequest("http://127.0.0.1:19000/api/job/deregister", "DELETE", "test_job");
}
@Test
public void assertRegisterWithoutApp() throws Exception {
when(getRegCenter().isExisted("/config/job/test_job")).thenReturn(false);
assertThat(sentRequest("http://127.0.0.1:19000/api/job/register", "POST", CloudJsonConstants.getJobJson()), is(500));
}
@Test
public void assertRegisterWithExistedName() throws Exception {
when(getRegCenter().get("/config/app/test_app")).thenReturn(CloudAppJsonConstants.getAppJson("test_app"));
when(getRegCenter().isExisted("/config/test_job")).thenReturn(false);
assertThat(sentRequest("http://127.0.0.1:19000/api/job/register", "POST", CloudJsonConstants.getJobJson()), is(204));
when(getRegCenter().get("/config/job/test_job")).thenReturn(CloudJsonConstants.getJobJson());
assertThat(sentRequest("http://127.0.0.1:19000/api/job/register", "POST", CloudJsonConstants.getJobJson()), is(500));
sentRequest("http://127.0.0.1:19000/api/job/deregister", "DELETE", "test_job");
}
@Test
public void assertRegisterWithBadRequest() throws Exception {
when(getRegCenter().get("/config/app/test_app")).thenReturn(CloudAppJsonConstants.getAppJson("test_app"));
assertThat(sentRequest("http://127.0.0.1:19000/api/job/register", "POST", "\"{\"jobName\":\"wrong_job\"}"), is(500));
}
@Test
public void assertUpdate() throws Exception {
when(getRegCenter().isExisted("/config/job/test_job")).thenReturn(true);
when(getRegCenter().get("/config/job/test_job")).thenReturn(CloudJsonConstants.getJobJson());
assertThat(sentRequest("http://127.0.0.1:19000/api/job/update", "PUT", CloudJsonConstants.getJobJson()), is(204));
verify(getRegCenter()).update("/config/job/test_job", CloudJsonConstants.getJobJson());
sentRequest("http://127.0.0.1:19000/api/job/deregister", "DELETE", "test_job");
}
@Test
public void assertDeregister() throws Exception {
when(getRegCenter().isExisted("/config/job/test_job")).thenReturn(false);
assertThat(sentRequest("http://127.0.0.1:19000/api/job/deregister", "DELETE", "test_job"), is(204));
verify(getRegCenter(), times(3)).get("/config/job/test_job");
}
@Test
public void assertTriggerWithDaemonJob() throws Exception {
when(getRegCenter().get("/config/job/test_job")).thenReturn(CloudJsonConstants.getJobJson(CloudJobExecutionType.DAEMON));
assertThat(sentRequest("http://127.0.0.1:19000/api/job/trigger", "POST", "test_job"), is(500));
}
@Test
public void assertTriggerWithTransientJob() throws Exception {
when(getRegCenter().get("/config/job/test_job")).thenReturn(CloudJsonConstants.getJobJson());
assertThat(sentRequest("http://127.0.0.1:19000/api/job/trigger", "POST", "test_job"), is(204));
}
@Test
public void assertDetail() throws Exception {
when(getRegCenter().get("/config/job/test_job")).thenReturn(CloudJsonConstants.getJobJson());
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/jobs/test_job"), is(CloudJsonConstants.getJobJson()));
verify(getRegCenter()).get("/config/job/test_job");
}
@Test
public void assertDetailWithNotExistedJob() throws Exception {
assertThat(sentRequest("http://127.0.0.1:19000/api/job/jobs/notExistedJobName", "GET", ""), is(404));
}
@Test
public void assertFindAllJobs() throws Exception {
when(getRegCenter().isExisted("/config/job")).thenReturn(true);
when(getRegCenter().getChildrenKeys("/config/job")).thenReturn(Lists.newArrayList("test_job"));
when(getRegCenter().get("/config/job/test_job")).thenReturn(CloudJsonConstants.getJobJson());
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/jobs"), is("[" + CloudJsonConstants.getJobJson() + "]"));
verify(getRegCenter()).isExisted("/config/job");
verify(getRegCenter()).getChildrenKeys("/config/job");
verify(getRegCenter()).get("/config/job/test_job");
}
@Test
public void assertFindAllRunningTasks() throws Exception {
RunningService runningService = new RunningService(getRegCenter());
TaskContext actualTaskContext = TaskContext.from(TaskNode.builder().build().getTaskNodeValue());
when(getRegCenter().get("/config/job/" + actualTaskContext.getMetaInfo().getJobName())).thenReturn(CloudJsonConstants.getJobJson());
runningService.add(actualTaskContext);
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/tasks/running"), Is.is(GsonFactory.getGson().toJson(Lists.newArrayList(actualTaskContext))));
}
@Test
public void assertFindAllReadyTasks() throws Exception {
when(getRegCenter().isExisted("/state/ready")).thenReturn(true);
when(getRegCenter().getChildrenKeys("/state/ready")).thenReturn(Lists.newArrayList("test_job"));
when(getRegCenter().get("/state/ready/test_job")).thenReturn("1");
Map<String, String> expectedMap = new HashMap<>();
expectedMap.put("jobName", "test_job");
expectedMap.put("times", "1");
@SuppressWarnings("unchecked")
Collection<Map<String, String>> expectedResult = Lists.newArrayList(expectedMap);
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/tasks/ready"), is(GsonFactory.getGson().toJson(expectedResult)));
verify(getRegCenter()).isExisted("/state/ready");
verify(getRegCenter()).getChildrenKeys("/state/ready");
verify(getRegCenter()).get("/state/ready/test_job");
}
@Test
public void assertFindAllFailoverTasks() throws Exception {
when(getRegCenter().isExisted("/state/failover")).thenReturn(true);
when(getRegCenter().getChildrenKeys("/state/failover")).thenReturn(Lists.newArrayList("test_job"));
when(getRegCenter().getChildrenKeys("/state/failover/test_job")).thenReturn(Lists.newArrayList("test_job@-@0"));
String originalTaskId = UUID.randomUUID().toString();
when(getRegCenter().get("/state/failover/test_job/test_job@-@0")).thenReturn(originalTaskId);
FailoverTaskInfo expectedFailoverTask = new FailoverTaskInfo(MetaInfo.from("test_job@-@0"), originalTaskId);
Collection<FailoverTaskInfo> expectedResult = Lists.newArrayList(expectedFailoverTask);
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/tasks/failover"), is(GsonFactory.getGson().toJson(expectedResult)));
verify(getRegCenter()).isExisted("/state/failover");
verify(getRegCenter()).getChildrenKeys("/state/failover");
verify(getRegCenter()).getChildrenKeys("/state/failover/test_job");
verify(getRegCenter()).get("/state/failover/test_job/test_job@-@0");
}
@Test
public void assertFindJobExecutionEventsWhenNotConfigRDB() throws Exception {
ReflectionUtils.setFieldValue(CloudJobRestfulApi.class, CloudJobRestfulApi.class.getDeclaredField("jobEventRdbSearch"), null);
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/events/executions"), is(GsonFactory.getGson().toJson(new JobEventRdbSearch.Result<>(0, Collections.<JobExecutionEvent>emptyList()))));
}
@Test
public void assertFindJobExecutionEvents() throws Exception {
ReflectionUtils.setFieldValue(CloudJobRestfulApi.class, CloudJobRestfulApi.class.getDeclaredField("jobEventRdbSearch"), getJobEventRdbSearch());
JobExecutionEvent jobExecutionEvent = new JobExecutionEvent("fake_task_id", "test_job", JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER, 0);
when(getJobEventRdbSearch().findJobExecutionEvents(any(JobEventRdbSearch.Condition.class))).thenReturn(new JobEventRdbSearch.Result<>(0, Lists.newArrayList(jobExecutionEvent)));
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/events/executions?" + buildFindJobEventsQueryParameter()),
is(GsonFactory.getGson().toJson(new JobEventRdbSearch.Result<>(0, Lists.newArrayList(jobExecutionEvent)))));
verify(getJobEventRdbSearch()).findJobExecutionEvents(any(JobEventRdbSearch.Condition.class));
}
@Test
public void assertFindJobStatusTraceEventEventsWhenNotConfigRDB() throws Exception {
ReflectionUtils.setFieldValue(CloudJobRestfulApi.class, CloudJobRestfulApi.class.getDeclaredField("jobEventRdbSearch"), null);
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/events/statusTraces"), is(GsonFactory.getGson().toJson(new JobEventRdbSearch.Result<>(0, Collections.<JobExecutionEvent>emptyList()))));
}
@Test
public void assertFindJobStatusTraceEvent() throws Exception {
ReflectionUtils.setFieldValue(CloudJobRestfulApi.class, CloudJobRestfulApi.class.getDeclaredField("jobEventRdbSearch"), getJobEventRdbSearch());
JobStatusTraceEvent jobStatusTraceEvent = new JobStatusTraceEvent(
"test-job", "fake_task_id", "fake_slave_id", Source.LITE_EXECUTOR, ExecutionType.READY, "0", State.TASK_RUNNING, "message is empty.");
when(getJobEventRdbSearch().findJobStatusTraceEvents(any(JobEventRdbSearch.Condition.class))).thenReturn(new JobEventRdbSearch.Result<>(0, Lists.newArrayList(jobStatusTraceEvent)));
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/events/statusTraces?" + buildFindJobEventsQueryParameter()),
is(GsonFactory.getGson().toJson(new JobEventRdbSearch.Result<>(0, Lists.newArrayList(jobStatusTraceEvent)))));
verify(getJobEventRdbSearch()).findJobStatusTraceEvents(any(JobEventRdbSearch.Condition.class));
}
private String buildFindJobEventsQueryParameter() throws UnsupportedEncodingException {
return "per_page=10&page=1&sort=jobName&order=DESC&jobName=test_job"
+ "&startTime=" + URLEncoder.encode("2016-12-26 10:00:00", "UTF-8") + "&endTime=" + URLEncoder.encode("2016-12-26 10:00:00", "UTF-8");
}
@Test
public void assertGetTaskResultStatistics() throws Exception {
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/statistics/tasks/results"),
is(GsonFactory.getGson().toJson(Collections.emptyList())));
}
@Test
public void assertGetTaskResultStatisticsWithSinceParameter() throws Exception {
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/statistics/tasks/results?since=last24hours"),
is(GsonFactory.getGson().toJson(Collections.emptyList())));
}
@Test
public void assertGetTaskResultStatisticsWithPathParameter() throws Exception {
String[] parameters = {"online", "lastWeek", "lastHour", "lastMinute"};
for (String each : parameters) {
String result = sentGetRequest("http://127.0.0.1:19000/api/job/statistics/tasks/results/" + each);
TaskResultStatistics taskResultStatistics = GsonFactory.getGson().fromJson(result, TaskResultStatistics.class);
assertThat(taskResultStatistics.getSuccessCount(), is(0));
assertThat(taskResultStatistics.getFailedCount(), is(0));
}
}
@Test
public void assertGetTaskResultStatisticsWithErrorPathParameter() throws Exception {
String result = sentGetRequest("http://127.0.0.1:19000/api/job/statistics/tasks/results/errorPath");
TaskResultStatistics taskResultStatistics = GsonFactory.getGson().fromJson(result, TaskResultStatistics.class);
assertThat(taskResultStatistics.getSuccessCount(), is(0));
assertThat(taskResultStatistics.getFailedCount(), is(0));
}
@Test
public void assertGetJobTypeStatistics() throws Exception {
String result = sentGetRequest("http://127.0.0.1:19000/api/job/statistics/jobs/type");
JobTypeStatistics jobTypeStatistics = GsonFactory.getGson().fromJson(result, JobTypeStatistics.class);
assertThat(jobTypeStatistics.getSimpleJobCount(), is(0));
assertThat(jobTypeStatistics.getDataflowJobCount(), is(0));
assertThat(jobTypeStatistics.getScriptJobCount(), is(0));
}
@Test
public void assertGetJobExecutionTypeStatistics() throws Exception {
String result = sentGetRequest("http://127.0.0.1:19000/api/job/statistics/jobs/executionType");
JobExecutionTypeStatistics jobExecutionTypeStatistics = GsonFactory.getGson().fromJson(result, JobExecutionTypeStatistics.class);
assertThat(jobExecutionTypeStatistics.getDaemonJobCount(), is(0));
assertThat(jobExecutionTypeStatistics.getTransientJobCount(), is(0));
}
@Test
public void assertFindTaskRunningStatistics() throws Exception {
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/statistics/tasks/running"),
is(GsonFactory.getGson().toJson(Collections.emptyList())));
}
@Test
public void assertFindTaskRunningStatisticsWeekly() throws Exception {
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/statistics/tasks/running?since=lastWeek"),
is(GsonFactory.getGson().toJson(Collections.emptyList())));
}
@Test
public void assertFindJobRunningStatistics() throws Exception {
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/statistics/jobs/running"),
is(GsonFactory.getGson().toJson(Collections.emptyList())));
}
@Test
public void assertFindJobRunningStatisticsWeekly() throws Exception {
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/statistics/jobs/running?since=lastWeek"),
is(GsonFactory.getGson().toJson(Collections.emptyList())));
}
@Test
public void assertFindJobRegisterStatisticsSinceOnline() throws Exception {
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/statistics/jobs/register"),
is(GsonFactory.getGson().toJson(Collections.emptyList())));
}
@Test
public void assertIsDisabled() throws Exception {
when(getRegCenter().isExisted("/state/disable/job/test_job")).thenReturn(true);
assertThat(sentGetRequest("http://127.0.0.1:19000/api/job/test_job/disable"), is("true"));
}
@Test
public void assertDisable() throws Exception {
when(getRegCenter().isExisted("/config/job")).thenReturn(true);
when(getRegCenter().getChildrenKeys("/config/job")).thenReturn(Lists.newArrayList("test_job"));
when(getRegCenter().get("/config/app/test_app")).thenReturn(CloudAppJsonConstants.getAppJson("test_app"));
when(getRegCenter().get("/config/job/test_job")).thenReturn(CloudJsonConstants.getJobJson());
assertThat(sentRequest("http://127.0.0.1:19000/api/job/test_job/disable", "POST"), is(204));
verify(getRegCenter()).persist("/state/disable/job/test_job", "test_job");
}
@Test
public void assertEnable() throws Exception {
when(getRegCenter().isExisted("/config/job")).thenReturn(true);
when(getRegCenter().getChildrenKeys("/config/job")).thenReturn(Lists.newArrayList("test_job"));
when(getRegCenter().get("/config/app/test_app")).thenReturn(CloudAppJsonConstants.getAppJson("test_app"));
when(getRegCenter().get("/config/job/test_job")).thenReturn(CloudJsonConstants.getJobJson());
assertThat(sentRequest("http://127.0.0.1:19000/api/job/test_job/disable", "DELETE", "test_job"), is(204));
verify(getRegCenter()).remove("/state/disable/job/test_job");
}
}