es.upv.grycap.coreutils.fiber.test.FetchTest.java Source code

Java tutorial

Introduction

Here is the source code for es.upv.grycap.coreutils.fiber.test.FetchTest.java

Source

/*
 * Core Utils - Fiber-enabled clients.
 * Copyright 2015-2016 GRyCAP (Universitat Politecnica de Valencia)
 * 
 * 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.
 * 
 * This product combines work with different licenses. See the "NOTICE" text
 * file for details on the various modules and licenses.
 * 
 * The "NOTICE" text file is part of the distribution. Any derivative works
 * that you distribute must include a readable copy of the "NOTICE" text file.
 */

package es.upv.grycap.coreutils.fiber.test;

import static es.upv.grycap.coreutils.fiber.test.mockserver.FiberExpectationInitializer.MOCK_SERVER_BASE_URL;
import static es.upv.grycap.coreutils.fiber.test.mockserver.ObjectResponseValidator.validateJson;
import static es.upv.grycap.coreutils.fiber.test.mockserver.ObjectResponseValidator.validateXml;
import static java.util.Collections.emptyList;
import static org.apache.commons.collections.ListUtils.union;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.number.OrderingComparison.greaterThan;

import java.io.File;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

import com.google.common.collect.ImmutableList;

import co.paralleluniverse.fibers.futures.AsyncCompletionStage;
import es.upv.grycap.coreutils.fiber.http.HttpDataFetcher;
import es.upv.grycap.coreutils.fiber.http.HttpDataFetcher.FecthFuture;
import es.upv.grycap.coreutils.fiber.http.HttpDataFetcher.FetchStatus;
import es.upv.grycap.coreutils.test.category.IntegrationTests;
import es.upv.grycap.coreutils.test.rules.TestPrinter;
import es.upv.grycap.coreutils.test.rules.TestWatcher2;

/**
 * Tests data fetching.
 * @author Erik Torres
 * @since 0.1.0
 */
@RunWith(Parameterized.class)
@Category(IntegrationTests.class)
public class FetchTest {

    @Rule
    public TemporaryFolder tmpFolder = new TemporaryFolder();

    @Rule
    public TestPrinter pw = new TestPrinter();

    @Rule
    public TestRule watchman = new TestWatcher2(pw);

    /**
     * Provides an input dataset with different data formats (JSON, XML) and different access methods (URL fragment, 
     * query parameter). Some tests will surpass the concurrency level. Invalid identifiers are included to test that
     * the fetcher handles 404 status responses.
     * @return Parameters for the different test scenarios.
     */
    @Parameters(name = "{index}: path={0}, queryParam={1}, validIds={2}, invalidIds={3}, concurrencyLevel={4}, useFiber={5}")
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {
                /*0*/ { "/test/json", null, ImmutableList.of("1", "2"), emptyList(), 4, true },
                /*1*/ { "/test/xml", "q", ImmutableList.of("1", "2"), emptyList(), 8, true },
                /*2*/ { "/test/json", null, emptyList(), ImmutableList.of("3", "4"), 4, true },
                /*3*/ { "/test/json", null, ImmutableList.of("1", "2"), ImmutableList.of("3", "4"), 4, true },
                /*4*/ { "/test/xml", "q", ImmutableList.of("1", "2"), ImmutableList.of("5", "6", "7"), 2, true },
                /*5*/ { "/test/json", null, ImmutableList.of("1", "2"), emptyList(), 8, false } });
    }

    @Parameter(value = 0)
    public String path;
    @Parameter(value = 1)
    public String queryParam;
    @Parameter(value = 2)
    public List<String> validIds;
    @Parameter(value = 3)
    public List<String> invalidIds;
    @Parameter(value = 4)
    public int concurrencyLevel;
    @Parameter(value = 5)
    public boolean useFiber;

    @Test
    public void testFetch() throws Exception {
        // create fetcher
        final HttpDataFetcher fetcher = new HttpDataFetcher(concurrencyLevel);
        assertThat("Fetcher was created", fetcher, notNullValue());

        // create output folder
        final File outDir = tmpFolder.newFolder(randomAlphanumeric(12));
        assertThat("Output dir was created", outDir, notNullValue());
        assertThat("Output dir is writable", outDir.canWrite());

        // create test dataset
        @SuppressWarnings("unchecked")
        final List<String> ids = union(validIds, invalidIds);
        final URL url = new URL(MOCK_SERVER_BASE_URL + path);

        // fetch from server
        Map<String, FetchStatus> results = null;
        if (useFiber) {
            results = AsyncCompletionStage.get(fetcher.fetchToDir(url, queryParam, ids, "file-", ".tmp", outDir),
                    30l, TimeUnit.SECONDS);
        } else {
            final FecthFuture toBeCompleted = fetcher.fetchToDir(url, queryParam, ids, null, null, outDir);
            assertThat("Fetch task was created", toBeCompleted, notNullValue());
            results = toBeCompleted.get(30l, TimeUnit.SECONDS);
        }
        assertThat("Results are available", results, notNullValue());
        assertThat("Result count coincides with expected", results.size(), equalTo(ids.size()));
        assertThat("Ids coincides with expected", results.keySet(), hasItems(ids.toArray(new String[ids.size()])));
        pw.println(" >> Results: " + results);
        if (!validIds.isEmpty()) {
            assertThat("Status coincides with expected", results.values(), allOf(hasItem(FetchStatus.COMPLETED),
                    not(hasItems(FetchStatus.PENDING, FetchStatus.CANCELLED))));
        }
        if (!invalidIds.isEmpty()) {
            assertThat("Status coincides with expected", results.values(),
                    allOf(hasItem(FetchStatus.FAILED), not(hasItems(FetchStatus.PENDING, FetchStatus.CANCELLED))));
        }

        // check files in the output directory
        for (final String id : validIds) {
            final File outFile = new File(outDir,
                    useFiber ? new StringBuilder("file-").append(id).append(".tmp").toString() : id);
            assertThat("Output file was created", outDir, notNullValue());
            assertThat("Output file file exists and is redable", outFile.canRead(), equalTo(true));
            assertThat("Output file file is not empty", outFile.length(), greaterThan(0l));
            if (path.contains("xml")) {
                validateXml(outFile, id);
            } else if (path.contains("json")) {
                validateJson(outFile, id);
            }
        }
    }

}