cpcc.ros.sim.osm.CameraTest.java Source code

Java tutorial

Introduction

Here is the source code for cpcc.ros.sim.osm.CameraTest.java

Source

// This code is part of the CPCC-NG project.
//
// Copyright (c) 2013 Clemens Krainer <clemens.krainer@gmail.com>
//
// This program 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 2 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, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

package cpcc.ros.sim.osm;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.MethodNotSupportedException;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpProcessorBuilder;
import org.apache.http.protocol.HttpRequestHandler;
import org.apache.http.protocol.HttpService;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
import org.apache.http.protocol.UriHttpRequestHandlerMapper;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import cpcc.core.entities.PolarCoordinate;
import cpcc.core.utils.GeodeticSystem;
import cpcc.core.utils.WGS84;
import cpcc.ros.sim.osm.Camera;
import cpcc.ros.sim.osm.Configuration;
import cpcc.ros.test.RequestListenerThread;

/**
 * CameraTest
 */
public class CameraTest {
    private static final String BLACK_TILE = "data/black_tile.png";
    private static final String BLUE_TILE = "data/blue_tile.png";
    private static final String CYAN_TILE = "data/cyan_tile.png";
    private static final String GREEN_TILE = "data/green_tile.png";
    private static final String PURPLE_TILE = "data/purple_tile.png";
    private static final String RED_TILE = "data/red_tile.png";
    private static final String WHITE_TILE = "data/white_tile.png";

    private static final String HEIGHT_0 = "data/height-0.png";
    private static final String HEIGHT_10 = "data/height-10.png";
    private static final String HEIGHT_20 = "data/height-20.png";
    private static final String HEIGHT_40 = "data/height-40.png";
    private static final String HEIGHT_90 = "data/height-90.png";
    private static final String HEIGHT_120 = "data/height-120.png";
    private static final String HEIGHT_150 = "data/height-150.png";
    private static final String HEIGHT_200 = "data/height-200.png";

    private static final File blackTileFile = new File(CameraTest.class.getResource(BLACK_TILE).getFile());
    private static final File blueTileFile = new File(CameraTest.class.getResource(BLUE_TILE).getFile());
    private static final File cyanTileFile = new File(CameraTest.class.getResource(CYAN_TILE).getFile());
    private static final File greenTileFile = new File(CameraTest.class.getResource(GREEN_TILE).getFile());
    private static final File purpleTileFile = new File(CameraTest.class.getResource(PURPLE_TILE).getFile());
    private static final File redTileFile = new File(CameraTest.class.getResource(RED_TILE).getFile());
    private static final File whiteTileFile = new File(CameraTest.class.getResource(WHITE_TILE).getFile());

    private static final String height0 = CameraTest.class.getResource(HEIGHT_0).getFile();
    private static final String height10 = CameraTest.class.getResource(HEIGHT_10).getFile();
    private static final String height20 = CameraTest.class.getResource(HEIGHT_20).getFile();
    private static final String height40 = CameraTest.class.getResource(HEIGHT_40).getFile();
    private static final String height90 = CameraTest.class.getResource(HEIGHT_90).getFile();
    private static final String height120 = CameraTest.class.getResource(HEIGHT_120).getFile();
    private static final String height150 = CameraTest.class.getResource(HEIGHT_150).getFile();
    private static final String height200 = CameraTest.class.getResource(HEIGHT_200).getFile();

    private Configuration config;
    private Camera camera;
    private GeodeticSystem gs;
    private RequestListenerThread requestListenerThread;
    private MyHttpFileHandler testFileHandler;
    private File tempDir;

    @BeforeMethod
    public void setUp() throws Exception {
        int port = RandomUtils.nextInt(30000, 50000);

        gs = new WGS84();

        tempDir = File.createTempFile("camera", "");
        tempDir.delete();
        FileUtils.forceMkdir(tempDir);

        config = mock(Configuration.class);
        when(config.getCameraHeight()).thenReturn(240);
        when(config.getCameraWidth()).thenReturn(320);
        when(config.getTileHeight()).thenReturn(256);
        when(config.getTileWidth()).thenReturn(256);
        when(config.getOriginPosition()).thenReturn(null);
        when(config.getCameraApertureAngle()).thenReturn(2.0);
        when(config.getTileServerUrl()).thenReturn("http://localhost:" + port + "/%1$d/%2$d/%3$d.png");
        when(config.getZoomLevel()).thenReturn(18);
        when(config.getGeodeticSystem()).thenReturn(gs);
        when(config.getTileCacheBaseDir()).thenReturn(tempDir.getAbsolutePath());

        camera = new Camera(config);

        testFileHandler = new MyHttpFileHandler();
        testFileHandler.getResponses().put("/18/41920/101290.png", new Object[] { "image/png", blackTileFile });
        testFileHandler.getResponses().put("/18/41920/101291.png", new Object[] { "image/png", blueTileFile });
        testFileHandler.getResponses().put("/18/41920/101292.png", new Object[] { "image/png", cyanTileFile });
        testFileHandler.getResponses().put("/18/41920/101293.png", new Object[] { "image/png", greenTileFile });
        testFileHandler.getResponses().put("/18/41920/101294.png", new Object[] { "image/png", purpleTileFile });

        testFileHandler.getResponses().put("/18/41921/101290.png", new Object[] { "image/png", redTileFile });
        testFileHandler.getResponses().put("/18/41921/101291.png", new Object[] { "image/png", whiteTileFile });
        testFileHandler.getResponses().put("/18/41921/101292.png", new Object[] { "image/png", blackTileFile });
        testFileHandler.getResponses().put("/18/41921/101293.png", new Object[] { "image/png", blueTileFile });
        testFileHandler.getResponses().put("/18/41921/101294.png", new Object[] { "image/png", cyanTileFile });

        testFileHandler.getResponses().put("/18/41922/101290.png", new Object[] { "image/png", greenTileFile });
        testFileHandler.getResponses().put("/18/41922/101291.png", new Object[] { "image/png", purpleTileFile });
        testFileHandler.getResponses().put("/18/41922/101292.png", new Object[] { "image/png", redTileFile });
        testFileHandler.getResponses().put("/18/41922/101293.png", new Object[] { "image/png", whiteTileFile });
        testFileHandler.getResponses().put("/18/41922/101294.png", new Object[] { "image/png", blackTileFile });

        testFileHandler.getResponses().put("/18/41923/101290.png", new Object[] { "image/png", blueTileFile });
        testFileHandler.getResponses().put("/18/41923/101291.png", new Object[] { "image/png", cyanTileFile });
        testFileHandler.getResponses().put("/18/41923/101292.png", new Object[] { "image/png", greenTileFile });
        testFileHandler.getResponses().put("/18/41923/101293.png", new Object[] { "image/png", purpleTileFile });
        testFileHandler.getResponses().put("/18/41923/101294.png", new Object[] { "image/png", redTileFile });

        testFileHandler.getResponses().put("/18/41924/101290.png", new Object[] { "image/png", whiteTileFile });
        testFileHandler.getResponses().put("/18/41924/101291.png", new Object[] { "image/png", blackTileFile });
        testFileHandler.getResponses().put("/18/41924/101292.png", new Object[] { "image/png", blueTileFile });
        testFileHandler.getResponses().put("/18/41924/101293.png", new Object[] { "image/png", cyanTileFile });
        testFileHandler.getResponses().put("/18/41924/101294.png", new Object[] { "image/png", greenTileFile });
        // whiteTileFile
        testFileHandler.getResponses().put("/18/41925/101290.png", new Object[] { "image/png", purpleTileFile });
        testFileHandler.getResponses().put("/18/41925/101291.png", new Object[] { "image/png", redTileFile });
        testFileHandler.getResponses().put("/18/41925/101292.png", new Object[] { "image/png", whiteTileFile });
        testFileHandler.getResponses().put("/18/41925/101293.png", new Object[] { "image/png", blackTileFile });
        testFileHandler.getResponses().put("/18/41925/101294.png", new Object[] { "image/png", blueTileFile });

        testFileHandler.getResponses().put("/18/41926/101290.png", new Object[] { "image/png", cyanTileFile });
        testFileHandler.getResponses().put("/18/41926/101291.png", new Object[] { "image/png", greenTileFile });
        testFileHandler.getResponses().put("/18/41926/101292.png", new Object[] { "image/png", purpleTileFile });
        testFileHandler.getResponses().put("/18/41926/101293.png", new Object[] { "image/png", redTileFile });
        testFileHandler.getResponses().put("/18/41926/101294.png", new Object[] { "image/png", whiteTileFile });

        HttpProcessor httpproc = HttpProcessorBuilder.create().add(new ResponseDate())
                .add(new ResponseServer("Test/1.1")).add(new ResponseContent()).add(new ResponseConnControl())
                .build();

        UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
        reqistry.register("*", testFileHandler);

        HttpService httpService = new HttpService(httpproc, reqistry);

        requestListenerThread = new RequestListenerThread(port, httpService);
        requestListenerThread.setDaemon(false);
        requestListenerThread.start();
    }

    /**
     * Tear down the test setup.
     * 
     * @throws IOException
     */
    @AfterMethod
    public void teadDown() throws IOException {
        requestListenerThread.interrupt();
        FileUtils.deleteDirectory(tempDir);
    }

    /**
     * MyHttpFileHandler
     */
    static class MyHttpFileHandler implements HttpRequestHandler {
        private Map<String, Object[]> responses = new HashMap<String, Object[]>();

        /**
         * {@inheritDoc}
         */
        @Override
        public void handle(HttpRequest request, HttpResponse response, HttpContext context)
                throws HttpException, IOException {
            String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH);
            if (!"GET".equalsIgnoreCase(method)) {
                throw new MethodNotSupportedException(method + " method not supported");
            }

            String target = URLDecoder.decode(request.getRequestLine().getUri(), "UTF-8");

            if (responses.containsKey(target)) {
                Object[] responseContent = responses.get(target);
                ContentType contentType = ContentType.create((String) responseContent[0], (Charset) null);
                response.setStatusCode(HttpStatus.SC_OK);
                FileEntity body = new FileEntity((File) responseContent[1], contentType);
                response.setEntity(body);
                //System.out.println("Serving: url=" + target + ", file="
                //    + ((File) (responseContent[1])).getAbsolutePath());
            } else {
                response.setStatusCode(HttpStatus.SC_FORBIDDEN);
                StringEntity entity = new StringEntity("<html><body><h1>Access denied</h1></body></html>",
                        ContentType.create("text/html", "UTF-8"));
                response.setEntity(entity);
                // System.out.println("Cannot deliver file " + target);
            }
        }

        /**
         * @return the responses
         */
        public Map<String, Object[]> getResponses() {
            return responses;
        }
    }

    @DataProvider
    public static Object[][] imageDataProvider() {
        return new Object[][] {
                new Object[] { new PolarCoordinate(37.80881, -122.42669, 0.0), 320, 240, "PNG", height0 },
                new Object[] { new PolarCoordinate(37.80881, -122.42669, 10.0), 320, 240, "PNG", height10 },
                new Object[] { new PolarCoordinate(37.80881, -122.42669, 20.0), 320, 240, "PNG", height20 },
                new Object[] { new PolarCoordinate(37.80881, -122.42669, 40.0), 320, 240, "PNG", height40 },
                new Object[] { new PolarCoordinate(37.80881, -122.42669, 90.0), 320, 240, "PNG", height90 },
                new Object[] { new PolarCoordinate(37.80881, -122.42669, 120.0), 320, 240, "PNG", height120 },
                new Object[] { new PolarCoordinate(37.80881, -122.42669, 150.0), 320, 240, "PNG", height150 },
                new Object[] { new PolarCoordinate(37.80881, -122.42669, 200.0), 320, 240, "PNG", height200 },
                new Object[] { new PolarCoordinate(37.80881, -122.42669, 200.1), 320, 240, "PNG", height200 },
                new Object[] { new PolarCoordinate(37.80881, -122.42669, 250.0), 320, 240, "PNG", height200 }, };
    }

    @Test(dataProvider = "imageDataProvider")
    public void shouldGetImageForGivenPositionAndHeight(PolarCoordinate position, int width, int height,
            String imageFormat, String imageName) throws IOException {
        byte[] buffer = camera.getImage(position);
        BufferedImage image = ImageIO.read(new ByteArrayInputStream(buffer));
        assertThat(image.getHeight()).isEqualTo(height);
        assertThat(image.getWidth()).isEqualTo(width);

        byte[] reference = FileUtils.readFileToByteArray(new File(imageName));
        assertThat(buffer).isEqualTo(reference);
    }

    @Test
    public void shouldReturnNullImageOnNullPosition() throws IOException {
        byte[] buffer = camera.getImage(null);
        assertThat(buffer).isNotNull().hasSize(0);
    }

}