com.torodb.integration.mongo.v3m0.jstests.AbstractIntegrationTest.java Source code

Java tutorial

Introduction

Here is the source code for com.torodb.integration.mongo.v3m0.jstests.AbstractIntegrationTest.java

Source

/*
 *     This file is part of ToroDB.
 *
 *     ToroDB 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, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     ToroDB 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 ToroDB. If not, see <http://www.gnu.org/licenses/>.
 *
 *     Copyright (c) 2014, 8Kdata Technology
 *     
 */

package com.torodb.integration.mongo.v3m0.jstests;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;

import org.apache.commons.lang.ArrayUtils;
import org.junit.AssumptionViolatedException;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runners.Parameterized.Parameter;
import org.slf4j.Logger;

import com.google.common.base.Charsets;
import com.google.common.collect.Multimap;
import com.torodb.config.model.Config;
import com.torodb.integration.IntegrationTestEnvironment;
import com.torodb.integration.TestCategory;
import com.torodb.integration.ToroRunnerClassRule;
import com.torodb.torod.core.exceptions.ToroRuntimeException;

public abstract class AbstractIntegrationTest {

    @ClassRule
    public final static ToroRunnerClassRule TORO_RUNNER_CLASS_RULE = new ToroRunnerClassRule();

    protected final Logger logger;

    @Parameter(0)
    public TestCategory category;
    @Parameter(1)
    public Script script;

    public AbstractIntegrationTest(Logger logger) {
        this.logger = logger;
    }

    @Test
    @SuppressWarnings("fallthrough")
    public void runJstest() throws Exception {
        boolean expectedZeroResult;
        boolean exceptionsExpected;
        switch (category) {
        case FAILING:
            expectedZeroResult = false;
            exceptionsExpected = false;
            break;
        case WORKING:
            expectedZeroResult = true;
            exceptionsExpected = false;
            break;
        case CATASTROPHIC:
            logger.warn("Ignoring the known problematic script: {}", script);
        default:
            throw new AssumptionViolatedException(
                    "Test " + script + " is ignored because its category is " + category);
        }

        Config config = TORO_RUNNER_CLASS_RULE.getConfig();

        String toroConnectionString = config.getProtocol().getMongo().getNet().getBindIp() + ":"
                + config.getProtocol().getMongo().getNet().getPort() + "/";
        if (config.getBackend().isPostgresLike()) {
            toroConnectionString = toroConnectionString + config.getBackend().asPostgres().getDatabase();
        } else if (config.getBackend().isMySQLLike()) {
            toroConnectionString = toroConnectionString + config.getBackend().asMySQL().getDatabase();
        } else {
            throw new ToroRuntimeException(
                    "Backend " + config.getBackend().getBackendImplementation() + " is not supported");
        }

        URL mongoMocksUrl = AbstractIntegrationTest.class.getResource("mongo_mocks.js");

        logger.info("Testing {}", script);

        runMongoTest(toroConnectionString, mongoMocksUrl, expectedZeroResult, exceptionsExpected);
    }

    protected void runMongoTest(String toroConnectionString, URL mongoMocksUrl, boolean expectedZeroResult,
            boolean exceptionsExpected, String... parameters)
            throws IOException, InterruptedException, UnsupportedEncodingException, AssertionError {
        Process mongoProcess = runMongoProcess(toroConnectionString, mongoMocksUrl, parameters);

        int result = mongoProcess.waitFor();

        List<Throwable> uncaughtExceptions = TORO_RUNNER_CLASS_RULE.getUcaughtExceptions();

        ByteArrayOutputStream byteArrayOutputStream = readOutput(result, mongoProcess);

        checkResults(expectedZeroResult, exceptionsExpected, result, uncaughtExceptions, byteArrayOutputStream);
    }

    protected Process runMongoProcess(String toroConnectionString, URL mongoMocksUrl, String... parameters)
            throws IOException {
        Process mongoProcess = Runtime.getRuntime().exec((String[]) ArrayUtils.addAll(
                new String[] { "mongo", toroConnectionString, mongoMocksUrl.getPath(), script.getURL().getPath(), },
                parameters));
        return mongoProcess;
    }

    protected ByteArrayOutputStream readOutput(int result, Process mongoProcess) throws IOException {
        InputStream inputStream = mongoProcess.getInputStream();
        InputStream erroStream = mongoProcess.getErrorStream();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        if (result != 0) {
            int read;

            while ((read = inputStream.read()) != -1) {
                byteArrayOutputStream.write(read);
            }

            while ((read = erroStream.read()) != -1) {
                byteArrayOutputStream.write(read);
            }
        }
        return byteArrayOutputStream;
    }

    protected void checkResults(boolean expectedZeroResult, boolean exceptionsExpected, int result,
            List<Throwable> uncaughtExceptions, ByteArrayOutputStream byteArrayOutputStream)
            throws UnsupportedEncodingException, AssertionError {
        if (!uncaughtExceptions.isEmpty()) {
            PrintStream printStream = new PrintStream(byteArrayOutputStream, true, Charsets.UTF_8.name());

            for (Throwable throwable : uncaughtExceptions) {
                throwable.printStackTrace(printStream);
            }
        }

        if (expectedZeroResult) {
            if (result != 0) {
                String reason = new String(byteArrayOutputStream.toByteArray(), Charsets.UTF_8);
                throw new AssertionError("Test " + script + " failed:\n" + reason);
            }
        } else {
            if (result == 0) {
                throw new AssertionError("Test " + script + " should fail, but it didn't");
            }
        }

        if (!exceptionsExpected && !uncaughtExceptions.isEmpty()) {
            String reason = new String(byteArrayOutputStream.toByteArray(), Charsets.UTF_8);
            throw new AssertionError(
                    "Test " + script + " did not failed but " + "following exception where received:\n" + reason);
        }
    }

    protected static Collection<Object[]> parameters(ScriptClassifier classifier) {
        IntegrationTestEnvironment ite = IntegrationTestEnvironment.CURRENT_INTEGRATION_TEST_ENVIRONMENT;

        Multimap<TestCategory, Script> scriptFor = classifier.getScriptFor(ite);

        Collection<Object[]> result = new ArrayList<>(scriptFor.size());

        for (Entry<TestCategory, Script> entry : scriptFor.entries()) {
            result.add(new Object[] { entry.getKey(), entry.getValue() });
        }

        return result;
    }

}