Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.

Commit 19a0dba

Browse files
authored
Merge pull request #415 from pibi/groovyserv
Groovyserv POC for develop branch
2 parents 7e7badb + fae4489 commit 19a0dba

File tree

7 files changed

+218
-65
lines changed

7 files changed

+218
-65
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ env:
2323
- TEST_IMG=ruby
2424
- TEST_IMG=alt
2525
- TEST_IMG=rust
26-
- TEST_IMG=julia
26+
# - TEST_IMG=julia
2727
- TEST_IMG=systems
2828
- TEST_IMG=dart
2929
- TEST_IMG=crystal
@@ -33,6 +33,7 @@ env:
3333
- TEST_IMG=objc
3434
- TEST_IMG=go
3535
- TEST_IMG=lua
36+
- TEST_IMG=java
3637

3738
script:
3839
- eslint '**/*.js'

Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
HOSTNAME=codewars
22

33
# Building erlang images have been suspended (frozen) until they are able to be repaired
4-
CONTAINERS=node dotnet jvm python ruby alt rust julia systems dart crystal ocaml swift haskell objc go lua
4+
CONTAINERS=node dotnet jvm java python ruby alt rust systems dart crystal ocaml swift haskell objc go lua
55

66
# recent containers should be updated when adding or modifying a language, so that
77
# the travis build process will test it. The process cant test all languages
88
# without timing out so this is required to get passed that issue.
9-
RECENT_CONTAINERS=node
9+
RECENT_CONTAINERS=java
1010

1111
ALL_CONTAINERS=${CONTAINERS} base
1212

@@ -44,6 +44,7 @@ push:
4444
docker push codewars/python-runner
4545
docker push codewars/dotnet-runner
4646
docker push codewars/jvm-runner
47+
docker push codewars/java-runner
4748
docker push codewars/haskell-runner
4849
docker push codewars/systems-runner
4950
docker push codewars/erlang-runner
@@ -62,6 +63,7 @@ pull:
6263
docker pull codewars/python-runner
6364
docker pull codewars/dotnet-runner
6465
docker pull codewars/jvm-runner
66+
docker pull codewars/java-runner
6567
docker pull codewars/haskell-runner
6668
docker pull codewars/systems-runner
6769
docker pull codewars/erlang-runner

docker/java.docker

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# BUILD-USING: docker build -t codewars/runner-jvm .
2+
# EXAMPLE USAGE: (Hello world): docker run --rm --name=runner-jvm codewars/runner-jvm run -l java -c $'class Solution {\npublic static void main(String[] args){\nSystem.out.println("Hello world");\n}}'
3+
4+
# Pull base image.
5+
FROM codewars/base-runner
6+
7+
# Needed to run add-apt-repository
8+
RUN apt-get -y install software-properties-common
9+
10+
# Install Java 8
11+
# RUN apt-get install -y default-jre-headless default-jdk # default is OpenJDK6
12+
RUN add-apt-repository ppa:webupd8team/java
13+
RUN apt-get update
14+
# http://askubuntu.com/a/190674
15+
RUN echo debconf shared/accepted-oracle-license-v1-1 select true | debconf-set-selections && \
16+
echo debconf shared/accepted-oracle-license-v1-1 seen true | debconf-set-selections
17+
RUN apt-get install -y oracle-java8-installer
18+
19+
RUN apt-get install -y unzip
20+
21+
# Install dependencies binaries
22+
RUN mkdir -p /usr/local
23+
WORKDIR /usr/local
24+
25+
# Checkout binaries
26+
RUN wget -q https://dl.bintray.com/groovy/maven/apache-groovy-binary-2.4.10.zip && unzip apache-groovy-binary-2.4.10.zip
27+
RUN wget -q https://bitbucket.org/kobo/groovyserv-mirror/downloads/groovyserv-1.1.0-bin.zip && unzip groovyserv-1.1.0-bin.zip
28+
29+
# Setup Groovy
30+
RUN mv groovy-2.4.10 groovy
31+
ENV GROOVY_HOME /usr/local/groovy/
32+
ENV PATH /usr/local/groovy/bin:${PATH}
33+
34+
# Setup GroovyServ
35+
RUN mv groovyserv-1.1.0 groovyserv
36+
ENV PATH /usr/local/groovyserv/bin:${PATH}
37+
38+
# add the package json first to a tmp directory and build, copy over so that we dont rebuild every time
39+
ADD package.json /tmp/package.json
40+
RUN cd /tmp && npm install --production
41+
RUN mkdir -p /runner && cp -a /tmp/node_modules /runner
42+
43+
# ADD cli-runner and install node deps
44+
ADD . /runner
45+
46+
RUN ln -s /home/codewarrior /workspace
47+
WORKDIR /runner
48+
RUN npm install
49+
50+
RUN /usr/local/groovyserv/bin/setup.sh
51+
RUN groovyserver -t 20 --debug || echo "server connection error"; groovyclient -Ct 120 -Cdebug -e "println 'Hello from GroovyServ'"
52+
53+
# Run the test suite to make sure this thing works
54+
USER codewarrior
55+
56+
# Set environment variables
57+
ENV TIMEOUT 120000
58+
ENV USER codewarrior
59+
ENV HOME /home/codewarrior
60+
RUN groovyserver -t 20 --debug || echo "server connection error"; mocha -t ${TIMEOUT} test/runners/java_spec.js
61+
62+
USER root
63+
RUN echo '#!/bin/bash\ngroovyserver -t 10 -q || echo ""\n timeout 15 node "$@"'>/runner/entrypoint.sh ; chmod +x /runner/entrypoint.sh
64+
65+
USER codewarrior
66+
#timeout is a fallback in case an error with node
67+
#prevents it from exiting properly
68+
ENTRYPOINT ["/runner/entrypoint.sh"]
69+

docker/jvm.docker

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ USER codewarrior
5858
ENV TIMEOUT 10000
5959
ENV USER codewarrior
6060
ENV HOME /home/codewarrior
61-
RUN mocha -t 10000 test/runners/{java,clojure,groovy,scala,kotlin}_spec.js
61+
RUN mocha -t 10000 test/runners/{clojure,groovy,scala,kotlin}_spec.js
6262

6363
#timeout is a fallback in case an error with node
6464
#prevents it from exiting properly

frameworks/java/CwRunListener.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import org.junit.runner.notification.Failure;
2+
import org.junit.runner.notification.RunListener;
3+
import org.junit.runner.Description;
4+
import java.io.StringWriter;
5+
import java.io.PrintWriter;
6+
7+
public class CwRunListener extends RunListener
8+
{
9+
private boolean failed;
10+
public void testFailure(final Failure failure)
11+
{
12+
failed = true;
13+
final String msg = failure.getMessage();
14+
final boolean hasMessage = msg != null && msg.length() > 0;
15+
System.out.println(String.format("\n<FAILED::>%s<:LF:>", formatMessage(hasMessage ? msg : "Runtime Error Occurred")));
16+
if(!hasMessage && failure.getException() != null) {
17+
System.out.println(formatException(failure.getException()));
18+
}
19+
}
20+
public void testStarted(final Description description)
21+
{
22+
System.out.println(String.format("\n<DESCRIBE::>%s<:LF:>", formatMessage(description.getDisplayName())));
23+
failed = false;
24+
}
25+
public void testFinished(final Description description)
26+
{
27+
if(!failed)
28+
{
29+
System.out.println("\n<PASSED::>Test Passed<:LF:>");
30+
}
31+
System.out.println("\n<COMPLETEDIN::>");
32+
}
33+
private static String formatException(final Throwable ex)
34+
{
35+
if(ex == null){
36+
return "";
37+
}
38+
StringWriter sw = new StringWriter();
39+
PrintWriter pw = new PrintWriter(sw);
40+
ex.printStackTrace(pw);
41+
return sw.toString();
42+
}
43+
private static String formatMessage(final String s)
44+
{
45+
if(s == null){
46+
return "";
47+
}
48+
return s.replaceAll("\n", "<:LF:>");
49+
}
50+
}

lib/runners/java.js

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,51 @@
11
var shovel = require('../shovel'),
2-
path = require('path');
2+
exec = require('child_process').exec,
3+
util = require('../util');
4+
5+
6+
var groovyTestRunner = `
7+
import org.junit.runner.JUnitCore;
8+
import CwRunListener;
9+
import TestFixture;
10+
11+
def runner = new JUnitCore();
12+
runner.addListener(new CwRunListener());
13+
runner.run(TestFixture.class);
14+
`;
315

416
module.exports.run = function run(opts, cb) {
5-
var uberJar = path.resolve(__dirname, '../../jvm-runner/target/jvm-runner-0.1.3-standalone.jar');
17+
18+
function compile(args, cb) {
19+
args.unshift('javac', '-verbose','-cp', opts.dir, '-d', opts.dir, '-sourcepath', opts.dir);
20+
exec(args.join(' '), cb);
21+
}
22+
623
shovel.start(opts, cb, {
7-
solutionOnly: function(runCode) {
8-
runCode({
9-
name: 'java',
10-
args: ['-jar', uberJar],
11-
stdin: JSON.stringify(opts)
24+
solutionOnly: function(runCode, fail) {
25+
var solutionFile = util.codeWriteSync('javac', opts.solution, opts.dir, 'Solution.java');
26+
27+
compile([solutionFile], function(error, stdout, stderr) {
28+
if (error) return fail(error, stdout, stderr);
29+
opts.publish('stdout', stdout);
30+
runCode({
31+
name: 'groovyclient',
32+
args: ['-cp', opts.dir, '-e', 'import Solution; Solution.main(null);']
33+
});
1234
});
1335
},
14-
testIntegration: function(runCode) {
15-
runCode({
16-
name: 'java',
17-
args: ['-jar', uberJar],
18-
stdin: JSON.stringify(opts)
36+
testIntegration: function(runCode, fail) {
37+
var solutionFile = util.codeWriteSync('javac', opts.solution, opts.dir, 'Solution.java');
38+
39+
var fixtureFile = util.codeWriteSync('javac', opts.fixture, opts.dir, 'TestFixture.java');
40+
var runner = util.codeWriteSync('groovy', groovyTestRunner, opts.dir, 'testRunner.groovy');
41+
42+
compile(['-cp', '/usr/local/groovy/lib/junit-4.12.jar', solutionFile, fixtureFile, './frameworks/java/CwRunListener.java'], function(error, stdout, stderr) {
43+
if (error) return fail(error, stdout, stderr);
44+
opts.publish('stdout', stdout);
45+
runCode({
46+
name: 'groovyclient',
47+
args: ['-cp', opts.dir, '-cp', '/usr/local/groovy/lib/', runner]
48+
});
1949
});
2050
}
2151
});

test/runners/java_spec.js

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ describe('java runner', function() {
77
it('should handle basic code evaluation', function(done) {
88
runner.run({
99
language: 'java',
10-
code: [
11-
'class Solution {',
12-
' static void main(String[] args){',
13-
' System.out.println("42");',
14-
' }',
15-
'}'].join('\n')
10+
code:`
11+
class Solution {
12+
public static void main(String[] args){
13+
System.out.println("42");
14+
}
15+
}`
1616
}, function(buffer) {
17+
console.log(buffer);
1718
expect(buffer.stdout).to.contain('42\n');
1819
done();
1920
});
@@ -23,21 +24,21 @@ describe('java runner', function() {
2324
it('should handle basic junit tests', function(done) {
2425
runner.run({
2526
language: 'java',
26-
code: 'public class Solution {\n'
27-
+ ' public Solution(){}\n'
28-
+ ' public int testthing(){return 3;}\n'
29-
+ '}\n',
30-
fixture: 'import static org.junit.Assert.assertEquals;\n'
31-
+ 'import org.junit.Test;\n'
32-
+ 'import org.junit.runners.JUnit4;\n'
33-
+ 'public class TestFixture {\n'
34-
+ ' public TestFixture(){}'
35-
+ ' @Test\n'
36-
+ ' public void myTestFunction(){\n'
37-
+ ' Solution s = new Solution();\n'
38-
+ ' assertEquals("wow", 3, s.testthing());\n'
39-
+ ' System.out.println("test out");\n'
40-
+ '}}'
27+
code: `public class Solution {
28+
public Solution(){}
29+
public int testthing(){return 3;}
30+
}`,
31+
fixture: `import static org.junit.Assert.assertEquals;
32+
import org.junit.Test;
33+
import org.junit.runners.JUnit4;
34+
public class TestFixture {
35+
public TestFixture(){}
36+
@Test
37+
public void myTestFunction(){
38+
Solution s = new Solution();
39+
assertEquals("wow", 3, s.testthing());
40+
System.out.println("test out");
41+
}}`
4142
}, function(buffer) {
4243
expect(buffer.stdout).to.contain('<DESCRIBE::>myTestFunction(TestFixture)<:LF:>\ntest out\n\n<PASSED::>Test Passed<:LF:>\n');
4344
done();
@@ -46,21 +47,21 @@ describe('java runner', function() {
4647
it('should handle junit tests failing', function(done) {
4748
runner.run({
4849
language: 'java',
49-
code: 'public class Solution {\n'
50-
+ ' public Solution(){}\n'
51-
+ ' public int testthing(){return 3;}\n'
52-
+ '}\n',
53-
fixture: 'import static org.junit.Assert.assertEquals;\n'
54-
+ 'import org.junit.Test;\n'
55-
+ 'import org.junit.runners.JUnit4;\n'
56-
+ 'public class TestFixture {\n'
57-
+ ' public TestFixture(){}'
58-
+ ' @Test\n'
59-
+ ' public void myTestFunction(){\n'
60-
+ ' Solution s = new Solution();\n'
61-
+ ' assertEquals("Failed Message", 5, s.testthing());\n'
62-
+ ' System.out.println("test out");\n'
63-
+ '}}'
50+
code: `public class Solution {
51+
public Solution(){}
52+
public int testthing(){return 3;}
53+
}`,
54+
fixture: `import static org.junit.Assert.assertEquals;
55+
import org.junit.Test;
56+
import org.junit.runners.JUnit4;
57+
public class TestFixture {
58+
public TestFixture(){}
59+
@Test
60+
public void myTestFunction(){
61+
Solution s = new Solution();
62+
assertEquals("Failed Message", 5, s.testthing());
63+
System.out.println("test out");
64+
}}`
6465
}, function(buffer) {
6566
expect(buffer.stdout).to.contain('<DESCRIBE::>myTestFunction(TestFixture)<:LF:>\n\n<FAILED::>Failed Message expected:<5> but was:<3><:LF:>\n');
6667
done();
@@ -69,19 +70,19 @@ describe('java runner', function() {
6970
it('should report junit messages', function(done) {
7071
runner.run({
7172
language: 'java',
72-
code: 'public class Solution {\n'
73-
+ ' public Solution(){}\n'
74-
+ ' public String testthing(){ return null; }\n'
75-
+ '}\n',
76-
fixture: 'import static org.junit.Assert.assertEquals;\n'
77-
+ 'import org.junit.Test;\n'
78-
+ 'import org.junit.runners.JUnit4;\n'
79-
+ 'public class TestFixture {\n'
80-
+ ' @Test\n'
81-
+ ' public void myTestFunction(){\n'
82-
+ ' Solution s = new Solution();\n'
83-
+ ' assertEquals("Failed Message", 1, s.testthing().length());\n'
84-
+ '}}'
73+
code: `public class Solution {
74+
public Solution(){}
75+
public String testthing(){ return null; }
76+
}`,
77+
fixture: `import static org.junit.Assert.assertEquals;
78+
import org.junit.Test;
79+
import org.junit.runners.JUnit4;
80+
public class TestFixture {
81+
@Test
82+
public void myTestFunction(){
83+
Solution s = new Solution();
84+
assertEquals("Failed Message", 1, s.testthing().length());
85+
}}`
8586
}, function(buffer) {
8687
expect(buffer.stdout).to.contain('<FAILED::>Runtime Error Occurred');
8788
expect(buffer.stdout).to.contain('NullPointerException');

0 commit comments

Comments
 (0)