hoot.services.controllers.job.JobResourceTest.java Source code

Java tutorial

Introduction

Here is the source code for hoot.services.controllers.job.JobResourceTest.java

Source

/*
 * This file is part of Hootenanny.
 *
 * Hootenanny is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * --------------------------------------------------------------------
 *
 * The following copyright notices are generated automatically. If you
 * have a new notice to add, please use the format:
 * " * @copyright Copyright ..."
 * This will properly maintain the copyright information. DigitalGlobe
 * copyrights will be updated automatically.
 *
 * @copyright Copyright (C) 2015, 2016 DigitalGlobe (http://www.digitalglobe.com/)
 */
package hoot.services.controllers.job;

import static hoot.services.HootProperties.HOME_FOLDER;

import java.io.File;
import java.net.URL;
import java.sql.Connection;
import java.util.List;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;

import org.apache.commons.io.FileUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Matchers;
import org.mockito.Mockito;

import hoot.services.UnitTest;
import hoot.services.job.JobStatusManager;
import hoot.services.utils.HootCustomPropertiesSetter;

public class JobResourceTest {
    private static final File homeFolder;
    private static final String original_HOME_FOLDER;

    static {
        try {
            original_HOME_FOLDER = HOME_FOLDER;
            homeFolder = new File(FileUtils.getTempDirectory(), "RasterToTilesResourceTest");
            FileUtils.forceMkdir(homeFolder);
            Assert.assertTrue(homeFolder.exists());
            HootCustomPropertiesSetter.setProperty("HOME_FOLDER", homeFolder.getAbsolutePath());

            URL inputUrl = JobResourceTest.class
                    .getResource("/hoot/services/validators/job/services_fields_metadata.json");
            File dest = new File(new File(homeFolder, "scripts"), "services_fields_metadata.json");
            FileUtils.copyURLToFile(inputUrl, dest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @BeforeClass
    public static void beforeClass() throws Exception {
    }

    @AfterClass
    public static void afterClass() throws Exception {
        FileUtils.deleteDirectory(homeFolder);
        HootCustomPropertiesSetter.setProperty("HOME_FOLDER", original_HOME_FOLDER);
    }

    /**
     * Tests processChainJob in happy route
     *
     * @throws Exception
     */
    @Test
    @Category(UnitTest.class)
    public void testProcessChainJob() throws Exception {
        // Create Mock JobStatusManager Class
        JobStatusManager mockJobStatusManager = Mockito.mock(JobStatusManager.class);
        Mockito.doNothing().when(mockJobStatusManager).addJob(Matchers.anyString());
        Mockito.doNothing().when(mockJobStatusManager).updateJob(Matchers.anyString(), Matchers.anyString());
        Mockito.doNothing().when(mockJobStatusManager).setComplete(Matchers.anyString(), Matchers.anyString());
        Mockito.doNothing().when(mockJobStatusManager).setFailed(Matchers.anyString(), Matchers.anyString());

        // Mock child info
        JSONObject mockChild = new JSONObject();
        mockChild.put("id", "test_child_123");
        mockChild.put("detail", "processing");
        mockChild.put("status", "running");

        JobResource real = new JobResource();
        JobResource spy = Mockito.spy(real);

        Mockito.doReturn(Response.ok().build()).when(spy).processJob(Matchers.anyString(),
                Matchers.any(String.class));
        Mockito.doReturn(mockJobStatusManager).when(spy).createJobStatusMananger(Matchers.any(Connection.class));
        Mockito.doReturn(mockChild).when(spy).execReflection(Matchers.anyString(), Matchers.any(JSONObject.class),
                Matchers.any(JobStatusManager.class));

        String jobStr = "[{\"caller\":\"FileUploadResource\",\"exec\":\"makeetl\","
                + "\"params\":[{\"INPUT\":\"upload\\/81898818-2ca3-4a15-9421-50eb91952586\\/GroundPhotos.shp\"},"
                + "{\"INPUT_TYPE\":\"OGR\"},{\"TRANSLATION\":\"translations\\/UTP.js\"},{\"INPUT_NAME\":\"GroundPhotos\"}],"
                + "\"exectype\":\"make\"},{\"class\":\"hoot.services.controllers.ingest.RasterToTilesService\","
                + "\"method\":\"ingestOSMResource\",\"params\":[{\"isprimitivetype\":\"false\",\"value\":\"GroundPhotos\","
                + "\"paramtype\":\"java.lang.String\"}],\"exectype\":\"reflection\"}]";

        spy.processChainJob("test_job_id_1234", jobStr);

        // sleep for a couple of secs to make sure that all threads spawned by the call to spy.processChainJob() finish
        Thread.sleep(2000);

        class validParam2Matcher extends ArgumentMatcher<JSONObject> {

            @Override
            public boolean matches(Object argument) {
                JSONObject param = (JSONObject) argument;
                boolean val1 = param.get("class").toString()
                        .equals("hoot.services.controllers.ingest.RasterToTilesService");
                boolean val2 = param.get("method").toString().equals("ingestOSMResource");
                boolean val3 = param.get("exectype").toString().equals("reflection");

                JSONArray params = (JSONArray) param.get("params");
                JSONObject innerParam = (JSONObject) params.get(0);
                boolean val4 = innerParam.get("isprimitivetype").toString().equals("false");
                boolean val5 = innerParam.get("value").toString().equals("GroundPhotos");
                boolean val6 = innerParam.get("paramtype").toString().equals("java.lang.String");

                return val1 && val2 && val3 && val4 && val5 && val6;
            }
        }

        Mockito.verify(spy).execReflection(Matchers.matches("test_job_id_1234"),
                Matchers.argThat(new validParam2Matcher()), Matchers.any(JobStatusManager.class));

        ArgumentCaptor<String> argCaptor = ArgumentCaptor.forClass(String.class);

        Mockito.verify(mockJobStatusManager, Mockito.times(3)).updateJob(Matchers.anyString(), argCaptor.capture());

        JSONParser parser = new JSONParser();

        List<String> args = argCaptor.getAllValues();
        JSONObject status = (JSONObject) parser.parse(args.get(0));
        JSONArray children = (JSONArray) status.get("children");
        JSONObject child = (JSONObject) children.get(0);

        Assert.assertEquals("processing", child.get("detail").toString());
        Assert.assertEquals("running", child.get("status").toString());

        status = (JSONObject) parser.parse(args.get(1));
        children = (JSONArray) status.get("children");
        Assert.assertEquals(1, children.size());

        child = (JSONObject) children.get(0);
        Assert.assertEquals("success", child.get("detail").toString());
        Assert.assertEquals("complete", child.get("status").toString());

        status = (JSONObject) parser.parse(args.get(2));
        children = (JSONArray) status.get("children");
        Assert.assertEquals(2, children.size());

        child = (JSONObject) children.get(0);
        Assert.assertEquals("success", child.get("detail").toString());
        Assert.assertEquals("complete", child.get("status").toString());

        child = (JSONObject) children.get(1);
        Assert.assertEquals("success", child.get("detail").toString());
        Assert.assertEquals("complete", child.get("status").toString());

        ArgumentCaptor<String> setCompleteArgCaptor = ArgumentCaptor.forClass(String.class);

        Mockito.verify(mockJobStatusManager, Mockito.times(1)).setComplete(Matchers.anyString(),
                setCompleteArgCaptor.capture());

        args = setCompleteArgCaptor.getAllValues();
        status = (JSONObject) parser.parse(args.get(0));
        children = (JSONArray) status.get("children");

        Assert.assertEquals(2, children.size());

        child = (JSONObject) children.get(0);
        Assert.assertEquals("success", child.get("detail").toString());
        Assert.assertEquals("complete", child.get("status").toString());

        child = (JSONObject) children.get(1);
        Assert.assertEquals("success", child.get("detail").toString());
        Assert.assertEquals("complete", child.get("status").toString());
    }

    /**
     * Tests the processChainJob failure by _execReflection
     *
     * @throws Exception
     */
    @Test
    @Category(UnitTest.class)
    public void testProcessChainJobFailure() throws Exception {
        // Create Mock JobStatusManager Class
        JobStatusManager mockJobStatusManager = Mockito.mock(JobStatusManager.class);
        Mockito.doNothing().when(mockJobStatusManager).addJob(Matchers.anyString());
        Mockito.doNothing().when(mockJobStatusManager).updateJob(Matchers.anyString(), Matchers.anyString());
        Mockito.doNothing().when(mockJobStatusManager).setComplete(Matchers.anyString(), Matchers.anyString());
        Mockito.doNothing().when(mockJobStatusManager).setFailed(Matchers.anyString(), Matchers.anyString());

        // Mock child info
        JSONObject mockChild = new JSONObject();
        mockChild.put("id", "test_child_123_FAIL");
        mockChild.put("detail", "processing");
        mockChild.put("status", "running");

        JobResource real = new JobResource();
        JobResource spy = Mockito.spy(real);

        // so I use this to avoid actual call
        Mockito.doReturn(Response.ok().build()).when(spy).processJob(Matchers.anyString(), Matchers.anyString());
        Mockito.doReturn(mockJobStatusManager).when(spy).createJobStatusMananger(Matchers.any(Connection.class));

        // failure point
        Mockito.doThrow(new Exception("Mock failure for testing Process Chain Job failure. (Not real failure!!!)"))
                .when(spy).execReflection(Matchers.anyString(), Matchers.any(JSONObject.class),
                        Matchers.any(JobStatusManager.class));

        try {
            String jobStr = "[{\"caller\":\"FileUploadResource\",\"exec\":\"makeetl\","
                    + "\"params\":[{\"INPUT\":\"upload\\/81898818-2ca3-4a15-9421-50eb91952586\\/GroundPhotos.shp\"},"
                    + "{\"INPUT_TYPE\":\"OGR\"},{\"TRANSLATION\":\"translations\\/UTP.js\"},{\"INPUT_NAME\":\"GroundPhotos\"}],"
                    + "\"exectype\":\"make\"},{\"class\":\"hoot.services.controllers.ingest.RasterToTilesService\","
                    + "\"method\":\"ingestOSMResource\",\"params\":[{\"isprimitivetype\":\"false\",\"value\":\"GroundPhotos\","
                    + "\"paramtype\":\"java.lang.String\"}],\"exectype\":\"reflection\"}]";

            spy.processChainJob("test_job_id_1234_FAIL", jobStr);

            // sleep for a couple of secs to make sure that all threads spawned by the the call to spy.processChainJob() finish
            Thread.sleep(2000);
        } catch (WebApplicationException wex) {
            Response res = wex.getResponse();
            Assert.assertEquals(500, res.getStatus());
        }

        // There should be one success for first part being completed. Second
        // would be setFailed which updates db directly so update is not called.
        ArgumentCaptor<String> argCaptor = ArgumentCaptor.forClass(String.class);

        Mockito.verify(mockJobStatusManager, Mockito.times(2)).updateJob(Matchers.anyString(), argCaptor.capture());

        JSONParser parser = new JSONParser();

        List<String> args = argCaptor.getAllValues();
        JSONObject status = (JSONObject) parser.parse(args.get(0));
        JSONArray children = (JSONArray) status.get("children");
        JSONObject child = (JSONObject) children.get(0);

        Assert.assertEquals("processing", child.get("detail").toString());
        Assert.assertEquals("running", child.get("status").toString());

        status = (JSONObject) parser.parse(args.get(1));
        children = (JSONArray) status.get("children");
        Assert.assertEquals(1, children.size());

        child = (JSONObject) children.get(0);
        Assert.assertEquals("success", child.get("detail").toString());
        Assert.assertEquals("complete", child.get("status").toString());

        // Check for setFailed invocation
        ArgumentCaptor<String> setFailedArgCaptor = ArgumentCaptor.forClass(String.class);

        Mockito.verify(mockJobStatusManager, Mockito.times(1)).setFailed(Matchers.anyString(),
                setFailedArgCaptor.capture());

        args = setFailedArgCaptor.getAllValues();
        status = (JSONObject) parser.parse(args.get(0));
        children = (JSONArray) status.get("children");

        Assert.assertEquals(1, children.size());

        child = (JSONObject) children.get(0);
        Assert.assertEquals("Mock failure for testing Process Chain Job failure. (Not real failure!!!)",
                child.get("detail").toString());
        Assert.assertEquals("failed", child.get("status").toString());
    }
}