All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opendaylight.odlparent.featuretest.PerRepoTestRunner Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.odlparent.featuretest;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.bind.JAXBException;
import org.apache.karaf.features.internal.model.Features;
import org.apache.karaf.features.internal.model.JaxbUtil;
import org.junit.runner.Description;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.ParentRunner;
import org.junit.runners.model.InitializationError;
import org.opendaylight.odlparent.karafutil.CustomBundleUrlStreamHandlerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Deprecated(since = "13.1.0", forRemoval = true)
public class PerRepoTestRunner extends ParentRunner {
    private static final Logger LOG = LoggerFactory.getLogger(PerRepoTestRunner.class);

    private static final String REPO_RECURSE = "repo.recurse";
    private static final String[] FEATURES_FILENAMES = new String[] { "features.xml", "feature.xml" };

    private static boolean isURLStreamHandlerFactorySet = false;
    // Do NOT static {@code { URL.setURLStreamHandlerFactory(new CustomBundleUrlStreamHandlerFactory()); }}
    // This is VERY BAD practice, because it leads to VERY HARD TO TRACK errors in case ANYTHING goes wrong in this.
    // For example, we had a case where (following an upgrade of PAX Exam) a dependency was missing. This appeared
    // as a confusing error because the root cause of static initialization errors is typically lost in Java; so best is
    // NOT to use it!
    // ("NoClassDefFoundError: Could not initialize class ...PerRepoTestRunner")

    private final List children = new ArrayList<>();

    /**
     * Create a runner.
     *
     * @param testClass The test class.
     * @throws InitializationError if an error occurs.
     */
    public PerRepoTestRunner(final Class testClass) throws InitializationError {
        super(testClass);
        setURLStreamHandlerFactory();
        try {
            for (String filename : FEATURES_FILENAMES) {
                final URL repoUrl = getClass().getClassLoader().getResource(filename);
                if (repoUrl != null) {
                    final boolean recursive = Boolean.getBoolean(REPO_RECURSE);
                    LOG.info("Creating test runners for repoUrl {} recursive {}", repoUrl, recursive);
                    children.addAll(runnersFromRepoUrl(repoUrl, testClass, recursive));
                }
            }
            if (children.isEmpty()) {
                LOG.error("No features found to test; looked for {}", Arrays.toString(FEATURES_FILENAMES));
            }
        } catch (final IOException | JAXBException e) {
            throw new InitializationError(e);
        }
    }

    // We have to exceptionally suppress IllegalCatch just because URL.setURLStreamHandlerFactory stupidly throws Error
    @SuppressWarnings("checkstyle:IllegalCatch")
    // see doc on isURLStreamHandlerFactorySet for why we do NOT want to do this in a static block
    private static synchronized void setURLStreamHandlerFactory() {
        if (!isURLStreamHandlerFactorySet) {
            try {
                URL.setURLStreamHandlerFactory(new CustomBundleUrlStreamHandlerFactory());
                isURLStreamHandlerFactorySet = true;
            } catch (Error e) {
                LOG.warn("""
                    Failed to setURLStreamHandlerFactory to CustomBundleUrlStreamHandlerFactory (depending on which is
                    already set, this may or may not actually be a problem; e.g. Karaf 4 already registers
                    the neccessary handlers, so OK to ignore)""", e);
            }
        }
    }

    protected List runnersFromRepoUrl(
            final URL repoUrl, final Class testClass, final boolean recursive)
            throws JAXBException, IOException, InitializationError {
        if (recursive) {
            return recursiveRunnersFromRepoUrl(repoUrl, testClass);
        } else {
            return runnersFromRepoUrl(repoUrl, testClass);
        }
    }

    protected List runnersFromRepoUrl(final URL repoUrl, final Class testClass)
            throws JAXBException, IOException, InitializationError {
        return runnersFromFeatures(repoUrl, getFeatures(repoUrl), testClass);
    }

    protected List recursiveRunnersFromRepoUrl(final URL repoUrl, final Class testClass)
            throws JAXBException, IOException, InitializationError {
        final List runners = new ArrayList<>();
        final Features features = getFeatures(repoUrl);
        runners.addAll(runnersFromRepoUrl(repoUrl, testClass));
        for (final String repoString : features.getRepository()) {
            final URL subRepoUrl = new URL(repoString);
            runners.addAll(recursiveRunnersFromRepoUrl(subRepoUrl, testClass));
        }
        return runners;
    }

    protected List runnersFromFeatures(
            final URL repoUrl, final Features features, final Class testClass) throws InitializationError {
        final var runners = new ArrayList();
        final var featureList = features.getFeature();
        for (var f : featureList) {
            // If the features have more than one feature, ignore any feature with the same name as the
            // repository — these are the aggregator features generated by the Karaf Maven plugin, and
            // which are expensive to test
            if (featureList.size() == 1 || !f.getName().equals(features.getName())) {
                runners.add(new PerFeatureRunner(repoUrl, f.getName(), f.getVersion(), testClass));
            } else {
                LOG.warn("Skipping {}, it's an aggregator feature", f.getName());
            }
        }
        return runners;
    }

    protected Features getFeatures(final URL repoUrl) throws JAXBException, IOException {
        return JaxbUtil.unmarshal(repoUrl.toExternalForm(), false);
    }

    @Override
    protected List getChildren() {
        return children;
    }

    @Override
    protected Description describeChild(final PerFeatureRunner child) {
        return child.getDescription();
    }

    @Override
    @SuppressWarnings("checkstyle:RegexpSinglelineJava")
    protected void runChild(final PerFeatureRunner child, final RunNotifier notifier) {
        LOG.info("[LOG] About to run test: {}", child.getDescription());
        System.out.println("[sys.out] About to run test: " + child.getDescription());
        child.run(notifier);
    }

    @Override
    public int testCount() {
        return super.testCount() * children.size();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy