From 8ba49a6a7f66c2756f2c26ddae517c2fd34da558 Mon Sep 17 00:00:00 2001 From: jhoffner Date: Fri, 1 Sep 2017 16:01:21 -0700 Subject: [PATCH] Gradle Optimization Improvements - when-prewarmed utility added to ensure we wait until the starting daemon is ready - cleaned up test cases - improved test case prewarm integration - increased jvm memory --- .gitignore | 2 + docker-compose.yml | 11 ++++- docker/gradle.docker | 5 +- frameworks/gradle/build.gradle | 2 +- frameworks/gradle/gradle.properties | 1 - frameworks/gradle/prewarm.sh | 7 +++ frameworks/java/prewarm.sh | 2 - lib/runners/groovy.js | 36 ++++++++------ lib/runners/java.js | 28 ++--------- lib/runners/kotlin.js | 35 ++++++++------ lib/runners/scala.js | 36 ++++++++------ lib/utils/when-prewarmed.js | 53 ++++++++++++++++++++ test/runners/groovy_spec.js | 60 +++-------------------- test/runners/kotlin_spec.js | 75 +++++++++-------------------- test/runners/scala_spec.js | 71 ++++++++------------------- 15 files changed, 190 insertions(+), 234 deletions(-) delete mode 100644 frameworks/gradle/gradle.properties create mode 100644 lib/utils/when-prewarmed.js diff --git a/.gitignore b/.gitignore index 7676f8ba..4bb780c0 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ frameworks/java/.gradle frameworks/java/4.0 frameworks/java/build frameworks/java/buildOutputCleanup +frameworks/gradle/.gradle +frameworks/gradle/build diff --git a/docker-compose.yml b/docker-compose.yml index 3fde66e6..113d24ad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -47,7 +47,16 @@ services: - ./examples:/runner/examples - ./frameworks:/runner/frameworks - ./test:/runner/test - - ./listen.js:/runner/listen.js + entrypoint: '' + command: bash + + gradle-runner: + image: codewars/gradle-runner + volumes: + - ./lib:/runner/lib + - ./examples:/runner/examples + - ./frameworks:/runner/frameworks + - ./test:/runner/test entrypoint: '' command: bash diff --git a/docker/gradle.docker b/docker/gradle.docker index 99cf755c..f55ced68 100644 --- a/docker/gradle.docker +++ b/docker/gradle.docker @@ -29,7 +29,8 @@ WORKDIR /runner COPY package.json package.json RUN npm install --production -COPY frameworks/gradle frameworks/gradle +COPY frameworks/gradle/build.gradle frameworks/gradle/build.gradle +COPY frameworks/gradle/src frameworks/gradle/src RUN chown -R codewarrior:codewarrior frameworks/gradle COPY entrypoint.sh entrypoint.sh @@ -39,7 +40,7 @@ USER codewarrior ENV USER=codewarrior HOME=/home/codewarrior # JVM flags to control memory usage. org.gradle.jvmargs applies to forked JVM process -ENV GRADLE_OPTS="-Xmx64m -Dorg.gradle.jvmargs='-Xmx256m'" +ENV GRADLE_OPTS="-Xmx64m -Dorg.gradle.jvmargs='-Xmx512m'" RUN cd /runner/frameworks/gradle \ # download dependencies diff --git a/frameworks/gradle/build.gradle b/frameworks/gradle/build.gradle index 4c803b16..d291adf9 100644 --- a/frameworks/gradle/build.gradle +++ b/frameworks/gradle/build.gradle @@ -103,7 +103,7 @@ test { task run(type: JavaExec, dependsOn: classes) { // use gradle -D? main = System.getenv("MAIN_CLASS_NAME") - jvmArgs '-Xmx256m' + jvmArgs '-Xmx512m' classpath sourceSets.main.runtimeClasspath classpath configurations.runtime } diff --git a/frameworks/gradle/gradle.properties b/frameworks/gradle/gradle.properties deleted file mode 100644 index 2fd662e5..00000000 --- a/frameworks/gradle/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -#kotlin.incremental=false diff --git a/frameworks/gradle/prewarm.sh b/frameworks/gradle/prewarm.sh index 5a9ba726..738874a4 100644 --- a/frameworks/gradle/prewarm.sh +++ b/frameworks/gradle/prewarm.sh @@ -1,3 +1,10 @@ #!/bin/bash +echo "loading" > /workspace/prewarm.status + +# prewarm by starting the gradle daemon. Running an initial test build will also speed things up a bit cd /runner/frameworks/gradle && gradle --daemon --offline test + +echo "loaded" > /workspace/prewarm.status + +echo "prewarmed" diff --git a/frameworks/java/prewarm.sh b/frameworks/java/prewarm.sh index cb05e35c..4065c439 100644 --- a/frameworks/java/prewarm.sh +++ b/frameworks/java/prewarm.sh @@ -7,5 +7,3 @@ cd /runner/frameworks/java && gradle --daemon --offline test echo "loaded" > /workspace/prewarm.status -# node run -l java -c "public class Solution {}" -f "import org.junit.Test;public class TestFixture{}" - diff --git a/lib/runners/groovy.js b/lib/runners/groovy.js index 8e8dce35..66b7c558 100644 --- a/lib/runners/groovy.js +++ b/lib/runners/groovy.js @@ -3,6 +3,7 @@ const path = require('path'); const fs = require('fs-extra'); +const whenPrewarmed = require('../utils/when-prewarmed'); module.exports = { solutionOnly(opts, runCode) { @@ -40,22 +41,25 @@ module.exports = { fs.outputFileSync(path.join(dir, 'src', 'main', 'groovy', 'Setup.groovy'), opts.setup); fs.outputFileSync(path.join(dir, 'src', 'main', 'groovy', 'Solution.groovy'), opts.solution); fs.outputFileSync(path.join(dir, 'src', 'test', 'groovy', 'Fixture.groovy'), opts.fixture); - runCode({ - name: 'gradle', - args: [ - '--daemon', - '--no-search-upward', - '--offline', - '--exclude-task', 'compileScala', - '--exclude-task', 'compileKotlin', - '--exclude-task', 'compileTestScala', - '--exclude-task', 'compileTestKotlin', - '--quiet', - 'test', - ], - options: { - cwd: dir, - } + + whenPrewarmed(opts, prewarmed => { + runCode({ + name: 'gradle', + args: [ + prewarmed ? '--daemon' : '--no-daemon', // if not prewarmed don't bother + '--no-search-upward', + '--offline', + '--exclude-task', 'compileScala', + '--exclude-task', 'compileKotlin', + '--exclude-task', 'compileTestScala', + '--exclude-task', 'compileTestKotlin', + '--quiet', + 'test', + ], + options: { + cwd: dir, + } + }); }); }, diff --git a/lib/runners/java.js b/lib/runners/java.js index abeb5885..1a54d0b4 100644 --- a/lib/runners/java.js +++ b/lib/runners/java.js @@ -4,6 +4,7 @@ const fs = require('fs-extra'); const tagHelpers = require('../utils/tag-helpers'); const manipulateFileSync = require('../utils/manipulate-file-sync'); +const whenPrewarmed = require('../utils/when-prewarmed'); // we will cache the contents of this file so that we can process it later. var buildGradle = ''; @@ -102,29 +103,6 @@ module.exports = { } }; -/** - * If the prewarming process is in-process, we want to wait until it finishes, otherwise two builds happen and that - * will kill performance and the process will likely fail due to a timeout. - * multiple - * @param cb Function callback. True will be passed to the callback if the prewarm happened, which - * will indicate that the deamon should have been started. - */ -function whenReady(cb, notified, opts) { - const path = "/workspace/prewarm.status"; - if (!fs.pathExistsSync(path)) { - cb(false); - } - else if (fs.readFileSync(path).toString().indexOf('loaded') === 0) { - cb(true); - } - else { - if (!notified) { - opts.publish('status', 'Waiting for Gradle daemon to start...'); - } - setTimeout(() => whenReady(cb, true, opts), 200); - } -} - // we always build and test code with the gradle test task, even if we are not actually testing anything. // Currently this is because we have test mode setup to embed its output within the build output. function buildAndTest(opts, runCode) { @@ -140,7 +118,7 @@ function buildAndTest(opts, runCode) { buildGradle = manipulateFileSync(`/runner/frameworks/java/build.gradle`, `${opts.dir}/build.gradle`, templateOptions); - whenReady(prewarmed => { + whenPrewarmed(opts, prewarmed => { runCode({ name: 'gradle', // reuse the java dir cache since thats where we originally built from @@ -159,7 +137,7 @@ function buildAndTest(opts, runCode) { cwd: opts.dir } }); - }, false, opts); + }); } // checks if the spring-boot reference is loaded and adds additional settings diff --git a/lib/runners/kotlin.js b/lib/runners/kotlin.js index 630c98ec..f891c0d4 100644 --- a/lib/runners/kotlin.js +++ b/lib/runners/kotlin.js @@ -3,6 +3,7 @@ const path = require('path'); const fs = require('fs-extra'); +const whenPrewarmed = require('../utils/when-prewarmed'); module.exports = { solutionOnly(opts, runCode) { @@ -41,22 +42,24 @@ module.exports = { fs.outputFileSync(path.join(dir, 'src', 'main', 'kotlin', 'setup.kt'), opts.setup); fs.outputFileSync(path.join(dir, 'src', 'main', 'kotlin', 'solution.kt'), opts.solution); fs.outputFileSync(path.join(dir, 'src', 'test', 'kotlin', 'fixture.kt'), opts.fixture); - runCode({ - name: 'gradle', - args: [ - '--daemon', - '--no-search-upward', - '--offline', - '--exclude-task', 'compileScala', - '--exclude-task', 'compileGroovy', - '--exclude-task', 'compileTestScala', - '--exclude-task', 'compileTestGroovy', - '--quiet', - 'test', - ], - options: { - cwd: dir, - } + whenPrewarmed(opts, prewarmed => { + runCode({ + name: 'gradle', + args: [ + prewarmed ? '--daemon' : '--no-daemon', // if not prewarmed don't bother + '--no-search-upward', + '--offline', + '--exclude-task', 'compileScala', + '--exclude-task', 'compileGroovy', + '--exclude-task', 'compileTestScala', + '--exclude-task', 'compileTestGroovy', + '--quiet', + 'test', + ], + options: { + cwd: dir, + } + }); }); }, diff --git a/lib/runners/scala.js b/lib/runners/scala.js index 41dca9f5..1e9e0b62 100644 --- a/lib/runners/scala.js +++ b/lib/runners/scala.js @@ -3,6 +3,7 @@ const path = require('path'); const fs = require('fs-extra'); +const whenPrewarmed = require('../utils/when-prewarmed'); module.exports = { solutionOnly(opts, runCode) { @@ -40,22 +41,25 @@ module.exports = { fs.outputFileSync(path.join(dir, 'src', 'main', 'scala', 'Setup.scala'), opts.setup); fs.outputFileSync(path.join(dir, 'src', 'main', 'scala', 'Solution.scala'), opts.solution); fs.outputFileSync(path.join(dir, 'src', 'test', 'scala', 'Fixture.scala'), opts.fixture); - runCode({ - name: 'gradle', - args: [ - '--daemon', - '--no-search-upward', - '--offline', - '--exclude-task', 'compileGroovy', - '--exclude-task', 'compileKotlin', - '--exclude-task', 'compileTestGroovy', - '--exclude-task', 'compileTestKotlin', - '--quiet', - 'test', - ], - options: { - cwd: dir, - } + + whenPrewarmed(opts, prewarmed => { + runCode({ + name: 'gradle', + args: [ + prewarmed ? '--daemon' : '--no-daemon', // if not prewarmed don't bother + '--no-search-upward', + '--offline', + '--exclude-task', 'compileGroovy', + '--exclude-task', 'compileKotlin', + '--exclude-task', 'compileTestGroovy', + '--exclude-task', 'compileTestKotlin', + '--quiet', + 'test', + ], + options: { + cwd: dir, + } + }); }); }, diff --git a/lib/utils/when-prewarmed.js b/lib/utils/when-prewarmed.js new file mode 100644 index 00000000..e6012ec1 --- /dev/null +++ b/lib/utils/when-prewarmed.js @@ -0,0 +1,53 @@ +const fs = require('fs-extra'); +const execSync = require('child_process').execSync; + +const statusPath = "/home/codewarrior/prewarm.status"; + +/** + * If the prewarming process is in-process, we want to wait until it finishes, otherwise in the case of things like waiting + * for Gradle, two builds happen and that will kill performance and the process will likely fail due to a timeout. + + * @param cb Function callback. True will be passed to the callback if the prewarm happened, which + * will indicate that the deamon should have been started. + */ +function whenPrewarmed(opts, cb, notified) { + if (!fs.pathExistsSync(statusPath)) { + cb(false); + } + else if (fs.readFileSync(statusPath).toString().indexOf('loaded') === 0) { + cb(true); + } + else { + if (!notified && opts.publish) { + opts.publish('status', 'Waiting for prewarming to finish...'); + } + setTimeout(() => whenPrewarmed(opts, cb, true), 200); + } +} + +// used by specs to ensure the daemon is prewarmed +function ensure(done, shPath = "/runner/prewarm.sh") { + if (!fs.pathExistsSync(statusPath)) { + console.log("Starting daemon with test run to ensure tests run within their allowed time..."); + console.log(execSync(`sh ${shPath}`).toString()); + done(); + } + else { + whenPrewarmed({}, done); + } +} + +function clean() { + execSync(`rm -rf ${statusPath}`); + execSync(`gradle --stop`); +} + +module.exports = whenPrewarmed; +module.exports.ensure = ensure; +module.exports.clean = clean; + +// sets up mocha, also ensures that done never gets called with an argument +module.exports.setupMocha = function() { + before(done => ensure(_ => done())); + after(done => clean(_ => done())); +} diff --git a/test/runners/groovy_spec.js b/test/runners/groovy_spec.js index 866e8cbd..1a65a053 100644 --- a/test/runners/groovy_spec.js +++ b/test/runners/groovy_spec.js @@ -6,29 +6,23 @@ const fs = require('fs'); const path = require('path'); const yaml = require('js-yaml'); const exec = require('child_process').exec; +const prewarm = require('../../lib/utils/when-prewarmed').setupMocha; describe('groovy-runner', function() { - before(function startDaemon(done) { - this.timeout(0); - exec('gradle --daemon --offline test', { - cwd: '/runner/frameworks/gradle', - }, (err) => { + this.timeout(0); + + prewarm(); + + afterEach(function cleanup(done) { + exec('rm -rf /home/codewarrior/project', function(err) { if (err) return done(err); - console.log('Started Gradle daemon'); done(); }); }); describe('running', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); it('should handle basic code evaluation (script)', function(done) { - this.timeout(0); runner.run({ language: 'groovy', solution: [ @@ -42,7 +36,6 @@ describe('groovy-runner', function() { it('should handle basic code evaluation (static void main)', function(done) { // class needs to be `Main` - this.timeout(0); runner.run({ language: 'groovy', solution: [ @@ -59,7 +52,6 @@ describe('groovy-runner', function() { }); it('should handle setup code', function(done) { - this.timeout(0); runner.run({ language: 'groovy', setup: [ @@ -79,7 +71,6 @@ describe('groovy-runner', function() { }); it('should handle setup code with package declaration', function(done) { - this.timeout(0); runner.run({ language: 'groovy', setup: [ @@ -100,7 +91,6 @@ describe('groovy-runner', function() { }); it('should handle setup code with arbitrary package declaration', function(done) { - this.timeout(0); runner.run({ language: 'groovy', setup: [ @@ -122,15 +112,7 @@ describe('groovy-runner', function() { }); describe('testing with JUnit', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - it('should handle basic assertion', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'junit4', @@ -156,7 +138,6 @@ describe('groovy-runner', function() { }); it('should handle basic assertion with package declared', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'junit4', @@ -184,7 +165,6 @@ describe('groovy-runner', function() { }); it('should handle basic assertion failure', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'junit4', @@ -210,7 +190,6 @@ describe('groovy-runner', function() { }); it('should handle basic assertion failure by error', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'junit4', @@ -237,7 +216,6 @@ describe('groovy-runner', function() { it('should handle basic assertion failure with message', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'junit4', @@ -265,7 +243,6 @@ describe('groovy-runner', function() { it('can have multiple suites', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'junit4', @@ -306,7 +283,6 @@ describe('groovy-runner', function() { it('should allow logging', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'junit4', @@ -337,15 +313,7 @@ describe('groovy-runner', function() { }); describe('testing with Spock', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - it('should handle basic assertion', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'spock', @@ -371,7 +339,6 @@ describe('groovy-runner', function() { }); it('should handle basic assertion with package declared', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'spock', @@ -399,7 +366,6 @@ describe('groovy-runner', function() { }); it('should handle basic assertion failure', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'spock', @@ -425,7 +391,6 @@ describe('groovy-runner', function() { }); it('should handle basic assertion failure by error', function(done) { // No - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'spock', @@ -453,7 +418,6 @@ describe('groovy-runner', function() { }); it('can have multiple suites', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'spock', @@ -493,7 +457,6 @@ describe('groovy-runner', function() { }); it('should allow logging', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'spock', @@ -523,7 +486,6 @@ describe('groovy-runner', function() { }); it('should support @Unroll', function(done) { - this.timeout(0); runner.run({ language: 'groovy', testFramework: 'spock', @@ -568,13 +530,6 @@ describe('groovy-runner', function() { }); describe('Example Challenges', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - forEachExamples(function(framework, name, example) { describe(`${framework}: "${name}" example`, function() { it('should define an initial code block', function() { @@ -582,7 +537,6 @@ describe('groovy-runner', function() { }); it('should have a passing solution', function(done) { - this.timeout(0); runner.run({ language: 'groovy', setup: example.setup, diff --git a/test/runners/kotlin_spec.js b/test/runners/kotlin_spec.js index 0a1804cb..731f37cc 100644 --- a/test/runners/kotlin_spec.js +++ b/test/runners/kotlin_spec.js @@ -6,29 +6,23 @@ const fs = require('fs'); const path = require('path'); const yaml = require('js-yaml'); const exec = require('child_process').exec; +const prewarm = require('../../lib/utils/when-prewarmed').setupMocha; describe('kotlin-runner', function() { - before(function startDaemon(done) { - this.timeout(0); - exec('gradle --daemon --offline test', { - cwd: '/runner/frameworks/gradle', - }, (err) => { + this.timeout(0); + + prewarm(); + + afterEach(function cleanup(done) { + exec('rm -rf /home/codewarrior/project', function(err) { if (err) return done(err); - console.log('Started Gradle daemon'); done(); }); }); describe('running', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - it('should handle basic code evaluation', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', solution: [ @@ -43,7 +37,7 @@ describe('kotlin-runner', function() { }); it('should handle setup code', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', setup: [ @@ -63,7 +57,7 @@ describe('kotlin-runner', function() { }); it('can have package declaration', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', setup: [ @@ -86,15 +80,8 @@ describe('kotlin-runner', function() { }); describe('testing with JUnit', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - it('should handle basic assertion', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'junit4', @@ -119,7 +106,7 @@ describe('kotlin-runner', function() { }); it('should handle basic assertion with named package', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'junit4', @@ -148,7 +135,7 @@ describe('kotlin-runner', function() { }); it('should handle basic assertion failure', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'junit4', @@ -178,7 +165,7 @@ describe('kotlin-runner', function() { }); it('should handle basic assertion failure by error', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'junit4', @@ -208,7 +195,7 @@ describe('kotlin-runner', function() { }); it('should handle basic assertion failure with message', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'junit4', @@ -239,7 +226,7 @@ describe('kotlin-runner', function() { }); it('can have multiple suites', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'junit4', @@ -281,7 +268,7 @@ describe('kotlin-runner', function() { }); it('should allow logging', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'junit4', @@ -315,15 +302,8 @@ describe('kotlin-runner', function() { }); describe('testing with KotlinTest', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - it('should handle basic assertion', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'kotlintest', @@ -349,7 +329,7 @@ describe('kotlin-runner', function() { }); it('should handle basic assertion with named package', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'kotlintest', @@ -379,7 +359,7 @@ describe('kotlin-runner', function() { }); it('should handle basic assertion failure', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'kotlintest', @@ -405,7 +385,7 @@ describe('kotlin-runner', function() { }); it('should handle basic assertion failure by error', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'kotlintest', @@ -432,7 +412,7 @@ describe('kotlin-runner', function() { it('can have multiple suites', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'kotlintest', @@ -478,7 +458,7 @@ describe('kotlin-runner', function() { }); it('should allow logging', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', testFramework: 'kotlintest', @@ -513,13 +493,6 @@ describe('kotlin-runner', function() { }); describe('Example Challenges', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - forEachExamples(function(framework, name, example) { describe(`${framework}: "${name}" example`, function() { it('should define an initial code block', function() { @@ -527,7 +500,7 @@ describe('kotlin-runner', function() { }); it('should have a passing solution', function(done) { - this.timeout(0); + runner.run({ language: 'kotlin', setup: example.setup, diff --git a/test/runners/scala_spec.js b/test/runners/scala_spec.js index d7706590..6ad61c37 100644 --- a/test/runners/scala_spec.js +++ b/test/runners/scala_spec.js @@ -6,29 +6,22 @@ const fs = require('fs'); const path = require('path'); const yaml = require('js-yaml'); const exec = require('child_process').exec; +const prewarm = require('../../lib/utils/when-prewarmed').setupMocha; describe('scala-runner', function() { - before(function startDaemon(done) { - this.timeout(0); - exec('gradle --daemon --offline test', { - cwd: '/runner/frameworks/gradle', - }, (err) => { + this.timeout(0); + + prewarm(); + + afterEach(function cleanup(done) { + exec('rm -rf /home/codewarrior/project', function(err) { if (err) return done(err); - console.log('Started Gradle daemon'); done(); }); }); describe('running', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - it('should handle basic code evaluation', function(done) { - this.timeout(0); runner.run({ language: 'scala', solution: [ @@ -43,7 +36,7 @@ describe('scala-runner', function() { }); it('should handle setup code', function(done) { - this.timeout(0); + runner.run({ language: 'scala', setup: [ @@ -66,7 +59,7 @@ describe('scala-runner', function() { }); it('should handle setup code in arbitrary package', function(done) { - this.timeout(0); + runner.run({ language: 'scala', setup: [ @@ -90,15 +83,8 @@ describe('scala-runner', function() { }); describe('testing with ScalaTest', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - it('should handle basic assertion', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'scalatest', @@ -130,7 +116,7 @@ describe('scala-runner', function() { }); it('should handle basic assertion failure', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'scalatest', @@ -162,7 +148,7 @@ describe('scala-runner', function() { }); it('should handle basic assertion failure by error', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'scalatest', @@ -194,7 +180,7 @@ describe('scala-runner', function() { }); it('can have multiple suites', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'scalatest', @@ -241,7 +227,7 @@ describe('scala-runner', function() { }); it('should allow logging', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'scalatest', @@ -278,15 +264,8 @@ describe('scala-runner', function() { }); describe('testing with JUnit', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - it('should handle basic assertion', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'junit4', @@ -315,7 +294,7 @@ describe('scala-runner', function() { }); it('should handle basic assertion failure', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'junit4', @@ -344,7 +323,7 @@ describe('scala-runner', function() { }); it('should handle basic assertion failure by error', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'junit4', @@ -373,7 +352,7 @@ describe('scala-runner', function() { }); it('should handle basic assertion failure with message', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'junit4', @@ -403,7 +382,7 @@ describe('scala-runner', function() { }); it('can have multiple suites', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'junit4', @@ -445,7 +424,7 @@ describe('scala-runner', function() { }); it('should allow logging', function(done) { - this.timeout(0); + runner.run({ language: 'scala', testFramework: 'junit4', @@ -478,15 +457,7 @@ describe('scala-runner', function() { }); }); - describe('Example Challenges', function() { - afterEach(function cleanup(done) { - exec('rm -rf /home/codewarrior/project', function(err) { - if (err) return done(err); - done(); - }); - }); - forEachExamples(function(framework, name, example) { describe(`${framework}: "${name}" example`, function() { it('should define an initial code block', function() { @@ -494,7 +465,7 @@ describe('scala-runner', function() { }); it('should have a passing solution', function(done) { - this.timeout(0); + runner.run({ language: 'scala', setup: example.setup,