From e1e7ef59c6bdb0dff81268e6442235292f28a6b8 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Fri, 15 Jan 2021 09:54:38 +0000 Subject: [PATCH] Measure code coverage from in-game tests More importantly, `./gradlew check' actually runs the in-game tests, which makes the CI steps look a little more sensible again. Somewhat depressing that one of the longest files (15th) in CC:T is the build script. --- .github/workflows/main-ci.yml | 9 ++-- build.gradle | 60 ++++++++++++++++++++++--- doc/events/key.md | 2 +- src/test/server-files/server.properties | 3 +- 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml index 196c65915..66f06fba0 100644 --- a/.github/workflows/main-ci.yml +++ b/.github/workflows/main-ci.yml @@ -24,13 +24,10 @@ jobs: ${{ runner.os }}-gradle- - name: Build with Gradle - run: ./gradlew build --no-daemon || ./gradlew build --no-daemon - - - name: Run in-game tests run: | - ./gradlew setupServer --no-daemon - ./gradlew prepareRunTestServerRun --no-daemon || ./gradlew prepareRunTestServerRun --no-daemon - ./gradlew runTestServerRun --no-daemon + ./gradlew assemble --no-daemon || ./gradlew assemble --no-daemon + ./gradlew downloadAssets --no-daemon || ./gradlew downloadAssets --no-daemon + ./gradlew build - name: Upload Jar uses: actions/upload-artifact@v1 diff --git a/build.gradle b/build.gradle index f0df19a88..856a8173b 100644 --- a/build.gradle +++ b/build.gradle @@ -86,13 +86,6 @@ } } } - - testServerRun { - parent runs.testServer - property 'forge.logging.console.level', 'info' - property 'cctest.run', 'true' - forceExit false - } } mappings channel: 'official', version: project.mc_version @@ -392,6 +385,7 @@ task docWebsite(type: Copy, dependsOn: [illuaminateDocs]) { } jacocoTestReport { + dependsOn('test') reports { xml.enabled true html.enabled true @@ -440,6 +434,9 @@ header file('config/license/api.txt') } task setupServer(type: Copy) { + group "test server" + description "Sets up the environment for the test server." + from("src/test/server-files") { include "eula.txt" include "server.properties" @@ -447,6 +444,55 @@ task setupServer(type: Copy) { into "test-files/server" } +tasks.register('testInGame', JavaExec.class).configure { + it.group('test server') + it.description("Runs tests on a temporary Minecraft server.") + it.dependsOn(setupServer, 'prepareRunTestServer') + + // Copy from runTestServer. We do it in this slightly odd way as runTestServer + // isn't created until the task is configured (which is no good for us). + JavaExec exec = tasks.getByName('runTestServer') + it.setWorkingDir(exec.getWorkingDir()) + it.setSystemProperties(exec.getSystemProperties()) + it.setBootstrapClasspath(exec.getBootstrapClasspath()) + it.setClasspath(exec.getClasspath()) + it.setMain(exec.getMain()) + it.setEnvironment(exec.getEnvironment()) + it.setArgs(exec.getArgs()) + it.setJvmArgs(exec.getJvmArgs()) + + it.systemProperty('forge.logging.console.level', 'info') + it.systemProperty('cctest.run', 'true') + + // Jacoco and modlauncher don't play well together as the classes loaded in-game don't + // match up with those written to disk. We get Jacoco to dump all classes to disk, and + // use that when generating the report. + def coverageOut = new File(buildDir, 'jacocoClassDump/testInGame') + jacoco.applyTo(it) + it.jacoco.setIncludes(["dan200.computercraft.*"]) + it.jacoco.setClassDumpDir(coverageOut) + // Older versions of modlauncher don't include a protection domain (and thus no code + // source). Jacoco skips such classes by default, so we need to explicitly include them. + it.jacoco.setIncludeNoLocationClasses(true) +} + +tasks.register('jacocoTestInGameReport', JacocoReport.class).configure { + it.group('test server') + it.description('Generate coverage reports for in-game tests (testInGame)') + it.dependsOn('testInGame') + + it.executionData(new File(buildDir, 'jacoco/testInGame.exec')) + it.setSourceDirectories(project.files(sourceSets.main.allJava.srcDirs)) + it.setClassDirectories(project.files(new File(buildDir, 'jacocoClassDump/testInGame'))) + + it.reports { + xml.enabled true + html.enabled true + } +} +check.dependsOn('jacocoTestInGameReport') + + // Upload tasks task checkRelease { diff --git a/doc/events/key.md b/doc/events/key.md index 839dc553f..2b4b5aa22 100644 --- a/doc/events/key.md +++ b/doc/events/key.md @@ -21,6 +21,6 @@ ## Example ```lua while true do local event, key, is_held = os.pullEvent("key") - print(("%s held=%b"):format(keys.getName(key), is_held)) + print(("%s held=%s"):format(keys.getName(key), is_held)) end ``` diff --git a/src/test/server-files/server.properties b/src/test/server-files/server.properties index c7efd2230..46446b36a 100644 --- a/src/test/server-files/server.properties +++ b/src/test/server-files/server.properties @@ -1,5 +1,4 @@ -#Minecraft server properties -#Fri Jan 08 18:54:30 GMT 2021 +# Minecraft server properties allow-flight=false allow-nether=true broadcast-console-to-ops=true