001/*
002 * Copyright 2015-2024 the original author or authors
003 *
004 * This software is licensed under the Apache License, Version 2.0,
005 * the GNU Lesser General Public License version 2 or later ("LGPL")
006 * and the WTFPL.
007 * You may choose either license to govern your use of this software only
008 * upon the condition that you accept all of the terms of either
009 * the Apache License 2.0, the LGPL 2.1+ or the WTFPL.
010 */
011package org.minidns.integrationtest;
012
013import java.lang.reflect.InvocationTargetException;
014import java.lang.reflect.Method;
015import java.util.ArrayList;
016import java.util.HashSet;
017import java.util.List;
018import java.util.Properties;
019import java.util.Set;
020import java.util.logging.Level;
021import java.util.logging.Logger;
022
023import org.junit.Ignore;
024import org.minidns.dnsname.DnsName;
025import org.minidns.jul.MiniDnsJul;
026import org.minidns.record.Record.TYPE;
027
028public class IntegrationTestHelper {
029
030    public static final DnsName DNSSEC_DOMAIN = DnsName.from("verteiltesysteme.net");
031    public static final TYPE RR_TYPE = TYPE.A;
032
033    private static Set<Class<?>> testClasses = new HashSet<>();
034    private static Logger LOGGER = Logger.getLogger(IntegrationTestHelper.class.getName());
035
036    enum TestResult {
037        Success,
038        Failure,
039    }
040
041    static {
042        testClasses.add(CoreTest.class);
043        testClasses.add(DnssecTest.class);
044        testClasses.add(DaneTest.class);
045        testClasses.add(HlaTest.class);
046        testClasses.add(NsidTest.class);
047        testClasses.add(IterativeDnssecTest.class);
048    }
049
050    private static final String MINTTEST = "minttest.";
051
052    public static void main(String[] args) {
053        Properties systemProperties = System.getProperties();
054        String debugString = systemProperties.getProperty(MINTTEST + "debug", Boolean.toString(false));
055        boolean debug = Boolean.parseBoolean(debugString);
056        if (debug) {
057            LOGGER.info("Enabling debug and trace output");
058            MiniDnsJul.enableMiniDnsTrace();
059        }
060
061        int testsRun = 0;
062        List<Method> successfulTests = new ArrayList<>();
063        List<Method> failedTests = new ArrayList<>();
064        List<Method> ignoredTests = new ArrayList<>();
065        for (final Class<?> aClass : testClasses) {
066            for (final Method method : aClass.getDeclaredMethods()) {
067                if (!method.isAnnotationPresent(IntegrationTest.class)) {
068                    continue;
069                }
070                if (method.isAnnotationPresent(Ignore.class)) {
071                    ignoredTests.add(method);
072                    continue;
073                }
074                TestResult result = invokeTest(method, aClass);
075                testsRun++;
076                switch (result) {
077                case Success:
078                    successfulTests.add(method);
079                    break;
080                case Failure:
081                    failedTests.add(method);
082                    break;
083                }
084            }
085        }
086        StringBuilder resultMessage = new StringBuilder();
087        resultMessage.append("MiniDNS Integration Test Result: [").append(successfulTests.size()).append('/').append(testsRun).append("] ");
088        if (!ignoredTests.isEmpty()) {
089            resultMessage.append("(Ignored: ").append(ignoredTests.size()).append(") ");
090        }
091        int exitStatus = 0;
092        if (failedTests.isEmpty()) {
093            resultMessage.append("SUCCESS \\o/");
094        } else {
095            resultMessage.append("FAILURE :(");
096            exitStatus = 2;
097        }
098        LOGGER.info(resultMessage.toString());
099        System.exit(exitStatus);
100    }
101
102    public static TestResult invokeTest(Method method, Class<?> aClass) {
103        Class<?> expected = method.getAnnotation(IntegrationTest.class).expected();
104        if (!Exception.class.isAssignableFrom(expected)) expected = null;
105
106        String testClassName = method.getDeclaringClass().getSimpleName();
107        String testMethodName = method.getName();
108
109        LOGGER.logp(Level.INFO, testClassName, testMethodName, "Test start.");
110        try {
111            method.invoke(null);
112
113            if (expected != null) {
114                LOGGER.logp(Level.WARNING, testClassName, testMethodName, "Test failed: expected exception " + expected + " was not thrown!");
115                return TestResult.Failure;
116            } else {
117                LOGGER.logp(Level.INFO, testClassName, testMethodName, "Test suceeded.");
118                return TestResult.Success;
119            }
120        } catch (InvocationTargetException e) {
121            if (expected != null && expected.isAssignableFrom(e.getTargetException().getClass())) {
122                LOGGER.logp(Level.INFO, testClassName, testMethodName, "Test suceeded.");
123                return TestResult.Success;
124            } else {
125                LOGGER.logp(Level.WARNING, testClassName, testMethodName, "Test failed: unexpected exception was thrown: ", e.getTargetException());
126                return TestResult.Failure;
127            }
128        } catch (IllegalAccessException | NullPointerException e) {
129            LOGGER.logp(Level.SEVERE, testClassName, testMethodName, "Test failed: could not invoke test, is it public static?");
130            return TestResult.Failure;
131        }
132    }
133}