diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c7d42cdb85ddc55d98908db8e313e36c47c5e3b5..a4809bd6690274cea3db131f6ed49289898027cb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,10 +12,13 @@ variables: # # Improve performance with overlayfs. # DOCKER_DRIVER: overlay2 GRADLE_OPTS: "-Dorg.gradle.daemon=false" - TEST_REPORTS: "/builds/OpenLicht/eraser/eraser-base/build/reports/tests/test/" - TEST_LOG: "/builds/OpenLicht/eraser/eraser-base/logs/eraser-test.log" - JACOCO_REPORT: "/builds/OpenLicht/eraser/eraser-base/build/reports/jacoco/test/jacocoTestReport.xml" - TESTCONTAINERS_RYUK_DISABLED: "true" + TEST_REPORTS: "eraser-base/build/reports/tests/" + TEST_LOG: "eraser-base/logs/eraser-test.log" + JACOCO_REPORT: "*/build/reports/jacoco/all-tests/jacoco*Report.xml" + # settings for influxdb + INFLUXDB_DB: "jastaddHistory" + INFLUXDB_USER: "root" + INFLUXDB_USER_PASSWORD: "root" before_script: - export GRADLE_USER_HOME=`pwd`/.gradle @@ -29,7 +32,7 @@ build: image: openjdk:8 stage: build script: - - ./gradlew --console=plain --build-cache assemble + - ./gradlew --console=plain assemble artifacts: paths: - "eraser-base/src/gen" @@ -39,10 +42,15 @@ test: tags: - docker stage: test + services: + - name: "eclipse-mosquitto:1.6.12" + alias: "mqtt" + - name: "influxdb:1.8.4" + alias: "influx" needs: - build script: - - ./gradlew --continue --console=plain --info check jacocoTestReport + - ./gradlew --console=plain --info allTests artifacts: when: always paths: @@ -56,7 +64,6 @@ coverage: needs: - test script: -# - ./gradlew --continue --console=plain -x test jacocoTestReport - pip install --user untangle - python print-coverage.py coverage: "/Covered (\\d{1,3}\\.\\d{2}%) of instructions for all projects\\./" diff --git a/buildSrc/src/main/groovy/eraser.java-common-conventions.gradle b/buildSrc/src/main/groovy/eraser.java-common-conventions.gradle index 21077d8d8a54b9e6bee47df5b45df1ca96142a1f..35d106e2f655c9e9d6b627913c4e9d68ba82480f 100644 --- a/buildSrc/src/main/groovy/eraser.java-common-conventions.gradle +++ b/buildSrc/src/main/groovy/eraser.java-common-conventions.gradle @@ -2,6 +2,7 @@ plugins { id 'java' id 'idea' id 'com.github.ben-manes.versions' + id 'jacoco' } repositories { @@ -17,5 +18,31 @@ dependencies { } tasks.named('test') { - useJUnitPlatform() + useJUnitPlatform { + excludeTags 'mqtt | influx' + } +} + +task allTests(type: Test, dependsOn: testClasses) { + description = 'Run every test' + group = 'verification' + + useJUnitPlatform { + } +} + +// extension for all Test tasks similar to https://stackoverflow.com/a/57330075/2493208 +jacocoTestReport { + executionData tasks.withType(Test).findAll { it.state.executed } + getExecutionData().setFrom(fileTree(buildDir).include("/jacoco/*.exec")) + + reports { + xml.enabled true + xml.destination(file("${jacoco.reportsDir}/all-tests/jacocoAllTestReport.xml")) + html.enabled false + } +} + +tasks.withType(Test) { + finalizedBy jacocoTestReport } diff --git a/eraser-base/build.gradle b/eraser-base/build.gradle index 7b5aa8060bbd083c4e05b41fa9bc77a85c6642ff..75c4c27c466bb8f89a14b9174e4e8d29af2dc4dd 100644 --- a/eraser-base/build.gradle +++ b/eraser-base/build.gradle @@ -9,7 +9,6 @@ buildscript { plugins { id 'eraser.java-application-conventions' id 'eraser.java-jastadd-conventions' - id 'jacoco' } apply plugin: 'jastadd' @@ -29,31 +28,6 @@ dependencies { application { mainClass = 'de.tudresden.inf.st.eraser.Main' } -// -//test { -// testLogging { -// events "passed", "skipped", "failed" -// exceptionFormat "full" -// } -//} - -//jacoco { -// toolVersion = '0.7.9' -// applyTo junitPlatformTest -//} - -jacocoTestReport { - reports { - xml.enabled true - html.enabled false - } -} - -//junitPlatformTest { -// jacoco { -// destinationFile = file("${buildDir}/jacoco/test.exec") -// } -//} def relastFiles = fileTree('src/main/jastadd/') { include '**/*.relast' }.toList().toArray() diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/InfluxTest.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/InfluxTest.java index 8d9d5a4c50382b63b0e43324dad3968219903f63..a5647fe4ee23ee8825a17ec5d59de80fb94dd9c7 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/InfluxTest.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/InfluxTest.java @@ -3,16 +3,10 @@ package de.tudresden.inf.st.eraser; import de.tudresden.inf.st.eraser.jastadd.model.*; import de.tudresden.inf.st.eraser.util.TestUtils; import de.tudresden.inf.st.eraser.util.TestUtils.ModelAndItem; -import org.junit.ClassRule; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import org.testcontainers.containers.InfluxDBContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; -import org.testcontainers.utility.DockerImageName; import java.time.Instant; import java.util.ArrayList; @@ -29,9 +23,19 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; * * @author rschoene - Initial contribution */ -@Testcontainers +@Tag("influx") public class InfluxTest { + public static String getInfluxHost() { + if (System.getenv("GITLAB_CI") != null) { + // we are in the CI, so use "influx" as host + return "influx"; + } { + // else assume a locally running influx container + return "localhost"; + } + } + private static final double DELTA = 0.001; private final List<DoubleStatePoint> points = new ArrayList<>(); private static final double firstState = 2.0; @@ -40,16 +44,6 @@ public class InfluxTest { private ModelAndItem mai; - @Container - private static final InfluxDBContainer<?> influxDbContainer = - new InfluxDBContainer<>( - DockerImageName - .parse("influxdb") - .withTag("1.8.3")) - .withDatabase(InfluxRoot.createDefault().getDbName()) - .withAdmin(InfluxRoot.createDefault().getUser()) - .withAdminPassword(InfluxRoot.createDefault().getPassword()); - @ParameterizedTest @ValueSource(booleans = {true, false}) public void oneItem(boolean useStub) { @@ -176,8 +170,7 @@ public class InfluxTest { influxRoot = InfluxRoot.createDefault(); // use container running influx influxRoot.setDbName(InfluxTest.class.getSimpleName()); - System.out.println("ports: " + influxDbContainer.getPortBindings() + " url: '" + influxDbContainer.getUrl() + "'"); - influxRoot.setHostByName(influxDbContainer.getUrl().replaceAll("^http://", "")); + influxRoot.setHostByName(getInfluxHost()); } mai.model.getRoot().setInfluxRoot(influxRoot); assumeTrue(influxRoot.influxAdapter().isConnected()); diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/MqttTests.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/MqttTests.java index cca050f08b6065e208ccd9c6732c03eae251724b..9b6a4ab492036278416ef1d2e2ff8d435a68d39e 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/MqttTests.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/MqttTests.java @@ -5,12 +5,9 @@ import de.tudresden.inf.st.eraser.util.MqttReceiver; import de.tudresden.inf.st.eraser.util.TestUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import java.io.IOException; import java.util.ArrayList; @@ -29,9 +26,19 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; * * @author rschoene - Initial contribution */ -@Testcontainers +@Tag("mqtt") public class MqttTests { + public static String getMqttHost() { + if (System.getenv("GITLAB_CI") != null) { + // we are in the CI, so use "mqtt" as host + return "mqtt"; + } { + // else assume a locally running mqtt broker + return "localhost"; + } + } + private static final String outgoingPrefix = "out"; private static final String firstPart = "a"; private static final String alternativeFirstPart = "x"; @@ -43,10 +50,6 @@ public class MqttTests { private final List<String> messages = new ArrayList<>(); private static final Logger logger = LogManager.getLogger(MqttTests.class); - @Container - public static GenericContainer<?> mqttBroker = new GenericContainer<>("eclipse-mosquitto:1.5") - .withExposedPorts(1883); - @ParameterizedTest @ValueSource(booleans = {true, false}) public void resolve1(boolean useStub) { @@ -137,7 +140,6 @@ public class MqttTests { private void assertSenderConnected(ModelItemAndTwoTopics modelAB) { MqttRoot mqttRoot = modelAB.model.getRoot().getMqttRoot(); - mqttBroker.waitingFor(Wait.forHealthcheck()); if (!mqttRoot.getMqttSender().isConnected()) { try { Thread.sleep(1000); @@ -156,8 +158,7 @@ public class MqttTests { } MqttReceiver receiver = new MqttReceiver(); List<String> expectedTopicList = Arrays.asList(expectedTopics); -// receiver.setHost("localhost", 1883); - receiver.setHost(mqttBroker.getContainerIpAddress(), mqttBroker.getFirstMappedPort()); + receiver.setHost(getMqttHost(), 1883); receiver.setTopicsForSubscription(expectedTopics); receiver.setOnMessage((topic, message) -> { assertThat(expectedTopicList).contains(topic); @@ -178,8 +179,7 @@ public class MqttTests { // now a SenderStub is being used ((MQTTSenderStub) mqttRoot.getMqttSender()).setCallback(((topic, message, qos) -> messages.add(message))); } else { -// mqttRoot.setHostByName("localhost"); - mqttRoot.setHost(ExternalHost.of(mqttBroker.getContainerIpAddress(), mqttBroker.getFirstMappedPort())); + mqttRoot.setHost(ExternalHost.of(getMqttHost(), 1883)); } MqttTopic a = createAndAddMqttTopic(mqttRoot, firstPart); MqttTopic ab = createAndAddMqttTopic(mqttRoot, firstPart + "/" + secondPart); diff --git a/print-coverage.py b/print-coverage.py index 30ee86794382a8e055ce3fa0e0746cd872981b34..951043a82b101393a0486c342a12c7b619f4338e 100644 --- a/print-coverage.py +++ b/print-coverage.py @@ -1,8 +1,16 @@ +import glob import os import untangle -print('Current path: ' + os.path.abspath(os.curdir)) -obj = untangle.parse('eraser-base/build/reports/jacoco/test/jacocoTestReport.xml') -instructions = [o for o in obj.report.counter if o['type'] == 'INSTRUCTION'][0] -missed, covered = int(instructions['missed']), int(instructions['covered']) + +print(f'Current path: {os.path.abspath(os.curdir)}') +missed, covered = 0, 0 +for f in glob.iglob(os.getenv('JACOCO_REPORT')): + print(f'Checking {f}') + obj = untangle.parse(f) + instructions = [o for o in obj.report.counter if o['type'] == 'INSTRUCTION'][0] + missed += int(instructions['missed']) + covered += int(instructions['covered']) # print missed / (missed + covered) -print('Covered %.2f%% of instructions for all projects.' % (missed * 100.0 / (missed + covered))) +if missed == covered == 0: + covered = 1 +print('Covered %.2f%% of instructions for all projects.' % (covered * 100.0 / (missed + covered)))