/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation: version 3 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package functionaltests; import java.io.File; import java.util.concurrent.TimeUnit; import javax.ws.rs.core.MediaType; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.ByteArrayBody; import org.apache.http.entity.mime.content.FileBody; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.ow2.proactive.authentication.crypto.Credentials; import org.ow2.proactive.scheduler.common.Scheduler; import org.ow2.proactive.scheduler.common.SchedulerState; import org.ow2.proactive.scheduler.common.exception.NotConnectedException; import org.ow2.proactive.scheduler.common.exception.PermissionException; import org.ow2.proactive.scheduler.common.exception.UnknownJobException; import org.ow2.proactive.scheduler.common.job.JobId; import org.ow2.proactive.scheduler.common.job.JobState; import org.ow2.proactive.scheduler.common.job.JobStatus; import com.google.common.collect.Iterables; import functionaltests.utils.RestFuncTUtils; public class RestSchedulerJobTaskTest extends AbstractRestFuncTestCase { @BeforeClass public static void setUp() throws Exception { init(); cleanScheduler(); } private static void cleanScheduler() throws NotConnectedException, PermissionException, UnknownJobException { Scheduler scheduler = RestFuncTHelper.getScheduler(); SchedulerState state = scheduler.getState(); Iterable<JobState> jobs = Iterables.concat(state.getPendingJobs(), state.getRunningJobs(), state.getFinishedJobs()); for (JobState jobState : jobs) { JobId jobId = jobState.getId(); scheduler.killJob(jobId); scheduler.removeJob(jobId); } } @AfterClass public static void tearDown() { RestFuncTHelper.stopRestfulSchedulerWebapp(); } @Test public void testLogin() throws Exception { RestFuncTestConfig config = RestFuncTestConfig.getInstance(); String url = getResourceUrl("login"); HttpPost httpPost = new HttpPost(url); StringEntity entity = new StringEntity("username=" + config.getLogin() + "&password=" + config.getPassword()); entity.setContentType(MediaType.APPLICATION_FORM_URLENCODED); httpPost.setEntity(entity); HttpResponse response = executeUriRequest(httpPost); assertHttpStatusOK(response); assertContentNotEmpty(response); } @Test public void testLoginWithCredentials() throws Exception { RestFuncTestConfig config = RestFuncTestConfig.getInstance(); Credentials credentials = RestFuncTUtils.createCredentials(config.getLogin(), config.getPassword(), RestFuncTHelper.getSchedulerPublicKey()); String schedulerUrl = getResourceUrl("login"); HttpPost httpPost = new HttpPost(schedulerUrl); MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create() .addPart("credential", new ByteArrayBody(credentials.getBase64(), ContentType.APPLICATION_OCTET_STREAM, null)); httpPost.setEntity(multipartEntityBuilder.build()); HttpResponse response = executeUriRequest(httpPost); assertHttpStatusOK(response); String sessionId = assertContentNotEmpty(response); String currentUserUrl = getResourceUrl("logins/sessionid/" + sessionId); HttpGet httpGet = new HttpGet(currentUserUrl); response = executeUriRequest(httpGet); assertHttpStatusOK(response); String userName = assertContentNotEmpty(response); Assert.assertEquals(config.getLogin(), userName); } @Test public void testSubmit() throws Exception { String schedulerUrl = getResourceUrl("submit"); HttpPost httpPost = new HttpPost(schedulerUrl); setSessionHeader(httpPost); File jobFile = RestFuncTHelper.getDefaultJobXmlfile(); MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create() .addPart("file", new FileBody(jobFile, ContentType.APPLICATION_XML)); httpPost.setEntity(multipartEntityBuilder.build()); HttpResponse response = executeUriRequest(httpPost); assertHttpStatusOK(response); JSONObject jsonObj = toJsonObject(response); assertNotNull(jsonObj.get("id").toString()); } @Test public void testUrlMatrixParamsShouldReplaceJobVariables() throws Exception { File jobFile = new File(RestSchedulerJobTaskTest.class.getResource("config/job_matrix_params.xml").toURI()); String schedulerUrl = getResourceUrl("submit;var=matrix_param_val"); HttpPost httpPost = new HttpPost(schedulerUrl); setSessionHeader(httpPost); MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create() .addPart("file", new FileBody(jobFile, ContentType.APPLICATION_XML)); httpPost.setEntity(multipartEntityBuilder.build()); HttpResponse response = executeUriRequest(httpPost); assertHttpStatusOK(response); JSONObject jsonObj = toJsonObject(response); final String jobId = jsonObj.get("id").toString(); assertNotNull(jobId); waitJobState(jobId, JobStatus.FINISHED, TimeUnit.MINUTES.toMillis(1)); } @Test public void testListJobs() throws Exception { String jobId = submitDefaultJob().value(); String schedulerUrl = getResourceUrl("jobs/" + jobId); HttpGet httpGet = new HttpGet(schedulerUrl); setSessionHeader(httpGet); HttpResponse response = executeUriRequest(httpGet); assertHttpStatusOK(response); JSONObject jsonObject = toJsonObject(response); assertJobId(jobId, jsonObject); } @Test public void testJobResult() throws Exception { String jobId = submitFinishedJob(); String resource = "jobs/" + jobId + "/result"; String schedulerUrl = getResourceUrl(resource); HttpGet httpGet = new HttpGet(schedulerUrl); setSessionHeader(httpGet); HttpResponse response = executeUriRequest(httpGet); assertHttpStatusOK(response); JSONObject jsonObject = toJsonObject(response); String taskResult = getTaskResult(jsonObject, getDefaultTaskName()); assertNotNull(taskResult); } @Test public void testGetNoJob() throws Exception { cleanScheduler(); String resourceUrl = getResourceUrl("jobs"); HttpGet httpGet = new HttpGet(resourceUrl); setSessionHeader(httpGet); HttpResponse response = executeUriRequest(httpGet); assertHttpStatusOK(response); JSONObject jsonObject = toJsonObject(response); JSONArray jsonArray = (JSONArray) jsonObject.get("list"); assertTrue(jsonArray.isEmpty()); } @Test public void testJobResultValue() throws Exception { String jobId = submitFinishedJob(); String resource = getResourceUrl("jobs/" + jobId + "/result/value"); HttpGet httpGet = new HttpGet(resource); setSessionHeader(httpGet); HttpResponse response = executeUriRequest(httpGet); assertHttpStatusOK(response); JSONObject jsonObject = toJsonObject(response); assertEquals("TEST-JOB", jsonObject.get(getDefaultTaskName()).toString()); } @Test(expected = UnknownJobException.class) public void testRemoveJob() throws Exception { String jobId = submitDefaultJob().value(); String resource = "jobs/" + jobId; String schedulerUrl = getResourceUrl(resource); HttpDelete delete = new HttpDelete(schedulerUrl); setSessionHeader(delete); HttpResponse response = executeUriRequest(delete); assertHttpStatusOK(response); assertTrue(Boolean.valueOf(getContent(response))); RestFuncTHelper.getScheduler().getJobState(jobId); fail("UnknownJobException should be thrown"); } @Test public void testKillJob() throws Exception { String jobId = submitPendingJobId(); String resource = "jobs/" + jobId + "/kill"; String schedulerUrl = getResourceUrl(resource); HttpPut httpPut = new HttpPut(schedulerUrl); setSessionHeader(httpPut); HttpResponse response = executeUriRequest(httpPut); assertHttpStatusOK(response); JobState jobState = getScheduler().getJobState(jobId); assertEquals(JobStatus.KILLED, jobState.getStatus()); } @Test public void testGetJobTaskIds() throws Exception { String jobId = submitDefaultJob().value(); String resource = "jobs/" + jobId + "/tasks"; String schedulerUrl = getResourceUrl(resource); HttpGet httpGet = new HttpGet(schedulerUrl); setSessionHeader(httpGet); HttpResponse response = executeUriRequest(httpGet); assertHttpStatusOK(response); JSONObject jsonObject = toJsonObject(response); JSONArray jsonArray = (JSONArray) jsonObject.get("list"); assertEquals(getDefaultTaskName(), jsonArray.get(0).toString()); } @Test public void testJobTaskStates() throws Exception { String jobId = submitDefaultJob().value(); String resource = "jobs/" + jobId + "/taskstates"; String schedulerUrl = getResourceUrl(resource); HttpGet httpGet = new HttpGet(schedulerUrl); setSessionHeader(httpGet); HttpResponse response = executeUriRequest(httpGet); assertHttpStatusOK(response); JSONObject jsonObject = toJsonObject(response); JSONArray jsonArray = (JSONArray) jsonObject.get("list"); assertTrue(jsonArray.size() > 0); } private void assertJobId(String expected, JSONObject job) { JSONObject jobInfo = (JSONObject) job.get("jobInfo"); JSONObject jobId = (JSONObject) jobInfo.get("jobId"); String actual = jobId.get("id").toString(); assertEquals(expected, actual); } private String getTaskResult(JSONObject job, String taskName) { Object allResults = job.get("allResults"); Object result = ((JSONObject) allResults).get(taskName); return ((JSONObject) result).get("serializedValue").toString(); } }