view gwt-client/src/test/java/test/AbstractModuleRunner.java @ 9570:531a60b7af95

failed tests will be saved to disk
author gernotbelger
date Mon, 05 Nov 2018 17:15:30 +0100
parents 86e522bc7f36
children
line wrap: on
line source
package test;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
import org.dive4elements.artifacts.common.utils.ClientProtocolUtils;
import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
import org.dive4elements.artifacts.httpclient.http.HttpClient;
import org.dive4elements.artifacts.httpclient.http.HttpClientImpl;
import org.dive4elements.artifacts.httpclient.http.response.DocumentResponseHandler;
import org.dive4elements.artifacts.httpclient.utils.XMLUtils;
import org.dive4elements.river.client.server.AdvanceServiceImpl;
import org.dive4elements.river.client.server.ArtifactHelper;
import org.dive4elements.river.client.server.CollectionHelper;
import org.dive4elements.river.client.server.CreateCollectionServiceImpl;
import org.dive4elements.river.client.server.FLYSArtifactCreator;
import org.dive4elements.river.client.server.FeedServiceImpl;
import org.dive4elements.river.client.server.auth.DefaultUser;
import org.dive4elements.river.client.server.auth.User;
import org.dive4elements.river.client.server.auth.UserClient;
import org.dive4elements.river.client.shared.exceptions.ServerException;
import org.dive4elements.river.client.shared.model.Artifact;
import org.dive4elements.river.client.shared.model.Collection;
import org.dive4elements.river.client.shared.model.Data;
import org.dive4elements.river.client.shared.model.DataItem;
import org.dive4elements.river.client.shared.model.DefaultCollection;
import org.dive4elements.river.client.shared.model.DefaultData;
import org.dive4elements.river.client.shared.model.DefaultDataItem;
import org.dive4elements.river.client.shared.model.OutputMode;
import org.dive4elements.river.client.shared.model.StringOptionsData;
import org.junit.Assert;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import test.AbstractBerechnungsartenTester.River;

/**
 * @author Domenico Nardi Tironi
 *
 */
public abstract class AbstractModuleRunner {

    public enum Infotype {
        sinfo, uinfo, bundu
    }

    private final static String USERNAME = "belger";

    private final static String PASSWORD = "belger";

    private final String serverUrl = "http://localhost:8181";
    private final String locale = "de";
    private final HttpClient client;

    private final Infotype infotype;
    private static String userUuid;
    private Collection collection;
    private Artifact artifact;

    // common attributes
    private final ICalcMode iCalcMode;
    private final double from;
    private final double to;
    private final River river;
    private final List<ModuleRunnerOutput> outputList;

    protected final File testFolder;

    public AbstractModuleRunner(final File testFolder, final Infotype infotype, final ICalcMode calcmode, final double from, final double to,
            final River beispielfluss) throws ConnectionException, ServerException {
        // common attributes (evtl. doch in subklassen, evtl. Zwischenhierarchiestufe einführen
        this.outputList = new ArrayList<ModuleRunnerOutput>();
        this.iCalcMode = calcmode;
        this.river = beispielfluss;
        this.from = from;
        this.to = to;
        this.testFolder = testFolder;

        this.infotype = infotype;

        // init
        this.client = new HttpClientImpl(this.serverUrl, this.locale);
        if (AbstractModuleRunner.userUuid == null)
            AbstractModuleRunner.userUuid = makeUserUuid(this.serverUrl);
        this.collection = getCollection();
        this.artifact = getArtifact();
    }

    private static String makeUserUuid(final String serverUrl) throws ConnectionException {
        final User user = new DefaultUser(USERNAME, PASSWORD, null, false, new ArrayList<String>(), new ArrayList<String>(), null);
        final UserClient userClient = new UserClient(serverUrl);
        Element userElement;

        userElement = userClient.findUser(user);
        return userElement.getAttributeNS(ArtifactNamespaceContext.NAMESPACE_URI, "uuid");

    }

    protected final Artifact getArtifact() throws ServerException, ConnectionException {
        if (this.artifact == null) {
            this.artifact = ArtifactHelper.createArtifact(this.serverUrl, this.locale, this.infotype.name(), null);
            setCollection(CollectionHelper.addArtifact(getCollection(), this.artifact, this.serverUrl, this.locale)); // wichtig; sorgt für Persistenz
        }
        return this.artifact;
    }

    protected Collection getCollection() throws ConnectionException {

        if (this.collection == null) {
            // lazy-Loading
            final Document create = ClientProtocolUtils.newCreateCollectionDocument(null);
            final Document doc = (Document) this.client.createCollection(create, userUuid, new DocumentResponseHandler());
            final String uuid = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_UUID, ArtifactNamespaceContext.INSTANCE);
            final String ttlStr = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_TTL, ArtifactNamespaceContext.INSTANCE);
            this.collection = new DefaultCollection(uuid, Long.valueOf(ttlStr), uuid);
        }
        return this.collection;

    }

    private final void setCollection(final Collection collection) {
        this.collection = collection;
    }

    private final void setArtifact(final Artifact artifact) {
        this.artifact = artifact;
    }

    public abstract void runTest() throws ConnectionException, ServerException, IOException;

    protected final void describeCollection() throws ConnectionException {

        final String uuid = getCollection().identifier();
        final Document describe = ClientProtocolUtils.newDescribeCollectionDocument(uuid);
        final Document response = (Document) this.client.doCollectionAction(describe, uuid, new DocumentResponseHandler());
        final Collection c = CollectionHelper.parseCollection(response);
        setCollection(c);

    }

    protected final void feedAndGo(final Data[] data, final int reachableStateIndex) throws ConnectionException, ServerException {
        feed(data);
        advance(getReachableStateByIndex(getArtifact(), reachableStateIndex)); // reachablestate könnte auch String sein.
    }

    protected final String getReachableStateByIndex(final Artifact artifact, final int index) {

        final String[] states = artifact.getArtifactDescription().getReachableStates();
        if (states != null) {

            if (states.length > index)
                return states[index];

            return states[0];
        }

        return "";
    }

    protected final void feed(final Data[] data) throws ServerException, ConnectionException {
        final Document feed = ClientProtocolUtils.newFeedDocument(getArtifact().getUuid(), getArtifact().getHash(), createKVP(data));
        final Document description = (Document) this.client.feed(
                new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), feed,
                new DocumentResponseHandler());

        final String result = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE);

        if (result == null || !result.equals(FeedServiceImpl.OPERATION_FAILURE)) {
            setArtifact((Artifact) new FLYSArtifactCreator().create(description));
        } else if (result != null && result.equals(FeedServiceImpl.OPERATION_FAILURE)) {
            final String msg = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT_MSG, ArtifactNamespaceContext.INSTANCE);
            throw new ServerException(msg);
        }
    }

    protected final Data[] extractPairData(final List<String> pairIds, final String dataName) {
        final DataItem[] items = new DataItem[pairIds.size()];
        int i = 0;
        final StringBuilder builder = new StringBuilder();
        for (final String pairId : pairIds) {
            builder.append(pairId).append("#");
            i++;
        }
        final String allPairIds = builder.delete(builder.length() - 1, builder.length()).toString(); // letztes Gatter entfernen
        final DataItem[] item = new DataItem[] { new DefaultDataItem(allPairIds, allPairIds, allPairIds) };
        return new Data[] { new StringOptionsData(dataName, dataName, item) };
    }

    private final String[][] createKVP(final Data[] data) {
        if (data != null) {
            final String[][] kvp = new String[data.length][];

            int i = 0;

            for (final Data d : data) {
                final String key = d.getLabel();
                final String value = d.getStringValue();

                kvp[i++] = new String[] { key, value };
            }

            return kvp;
        }
        return null;
    }

    protected final void advance(final String target) throws ConnectionException, ServerException {
        final Document advance = ClientProtocolUtils.newAdvanceDocument(getArtifact().getUuid(), getArtifact().getHash(), target);
        final Document description = (Document) this.client.advance(
                new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), advance,
                new DocumentResponseHandler());

        if (description == null) {
            throw new ServerException(AdvanceServiceImpl.ERROR_ADVANCE_ARTIFACT);
        }

        final String result = XMLUtils.xpathString(description, AdvanceServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE);

        if (result == null || !result.equals(AdvanceServiceImpl.OPERATION_FAILURE)) {
            setArtifact((Artifact) new FLYSArtifactCreator().create(description));
        }
    }

    /// ExportServiceImpl

    protected final void selectCalcMode() throws ConnectionException, ServerException {

        /* Select ICalcMode */
        final String calcmodeStr = this.iCalcMode.toString();
        final Data dataCalcMode = new StringOptionsData("calculation_mode", "calculation_mode",
                new DataItem[] { new DefaultDataItem(calcmodeStr, calcmodeStr, calcmodeStr) });
        feedAndGo(new Data[] { dataCalcMode }, 0);
    }

    protected final void selectRange() throws ConnectionException, ServerException {
        makeKmRange(this.getFrom(), this.getTo(), "ld_from", "ld_to");

    }

    protected final void makeKmRange(final double from, final double to, final String from_key, final String to_key)
            throws ConnectionException, ServerException {
        feedAndGo(makeFromToData(from_key, to_key, from, to), 0);
    }

    protected final Data[] makeFromToData(final String from_key, final String to_key, final double _from, final double _to) {
        final String fromStr = String.valueOf(_from);
        final String toStr = String.valueOf(_to);
        final Data dataFrom = new StringOptionsData(from_key, from_key, new DataItem[] { new DefaultDataItem(fromStr, fromStr, fromStr) });
        final Data dataTo = new StringOptionsData(to_key, to_key, new DataItem[] { new DefaultDataItem(toStr, toStr, toStr) });
        return new Data[] { dataFrom, dataTo };
    }

    protected final void selectRiver() throws ConnectionException, ServerException {
        final String riverStr = this.river.name();
        final Data data = new StringOptionsData("river", "river", new DataItem[] { new DefaultDataItem(riverStr, riverStr, riverStr) });
        feedAndGo(new Data[] { data }, 0);
    }

    public final void runTests() throws IOException, ServerException {
        for (final ModuleRunnerOutput output : this.outputList) {
            final String name = output.getOutputModename();
            if (!stateHasRequiredOutputMode(name)) {
                Assert.fail("Unbekannter outputmode " + name);
            }
            output.assertAndWriteToFile(this.client, this.collection.identifier(), this.testFolder);
        }
    }

    private final boolean stateHasRequiredOutputMode(final String outputMode) throws ConnectionException, ServerException {
        final OutputMode[] modes = getArtifact().getArtifactDescription().getOutputModes();
        if (modes != null) {
            for (final OutputMode mode : modes) {
                if (mode.getName().toLowerCase().equals(outputMode))
                    return true;
            }
        }
        return false;
    }

    protected final String getRecommendationPairString(final SimpleRecommendation rec1, final SimpleRecommendation rec2)
            throws ConnectionException, ServerException {

        return rec1.getRecommendationPairString(rec2, getCollection(), this.serverUrl, this.locale);
    }

    protected final void feedAndGoData(final Data[] data) throws ConnectionException, ServerException {
        feedAndGo(data, 0);
    }

    protected final void feedAndGoSimpleTextInput(final String key, final String value) throws ConnectionException, ServerException {
        feedAndGo(new Data[] { getSimpleTextInput(key, value) }, 0);
    }

    protected Data getSimpleTextInput(final String key, final String value) throws ConnectionException, ServerException {
        return new DefaultData(key, key, key, new DataItem[] { new DefaultDataItem(value, value, value) });
    }

    protected final Data[] addItemToExistingData(final Data[] existing, final Data add) {
        final Data[] data = new Data[existing.length + 1];
        for (int i = 0; i < existing.length; i++) {
            data[i] = existing[i];
        }
        data[existing.length] = add;
        return data;
    }

    public double getTo() {
        return this.to;
    }

    public double getFrom() {
        return this.from;
    }

    public final AbstractModuleRunner addOutputTest(final FilenameSupplier filename, final String outputModeName, final String currentKm)
            throws ConnectionException {
        this.outputList.add(new ModuleRunnerOutput(filename, outputModeName, currentKm));
        return this;
    }

}

http://dive4elements.wald.intevation.org