Skip to content

Commit 092dd2b

Browse files
committed
feat: add polyglot integration test for JS plugin deployment
- Create minimal test JS plugins (hello service + interceptor) in polyglot test resources - Enable js-plugins-test.feature with @requires-graalvm tag - RunnerIT conditionally excludes @requires-graalvm on non-GraalVM runtimes - Verifies Source.findLanguage classloader fix and commonjs option removal
1 parent cb06545 commit 092dd2b

5 files changed

Lines changed: 69 additions & 60 deletions

File tree

core/src/test/java/karate/RunnerIT.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222

2323
import static org.junit.jupiter.api.Assertions.assertEquals;
2424

25+
import java.util.ArrayList;
26+
import java.util.List;
27+
2528
import org.junit.jupiter.api.Test;
2629
import org.restheart.test.integration.AbstactIT;
2730

@@ -36,10 +39,26 @@
3639
public class RunnerIT extends AbstactIT {
3740
@Test
3841
public void run() {
42+
List<String> tags = new ArrayList<>(List.of("~@ignore", "~@helper"));
43+
44+
if (!isGraalVMRuntime()) {
45+
// Skip polyglot tests on non-GraalVM runtimes (JS plugins won't load)
46+
tags.add("~@requires-graalvm");
47+
}
48+
3949
var results = Runner.path("classpath:karate")
40-
.tags("~@ignore", "~@helper")
50+
.tags(tags.toArray(new String[0]))
4151
.parallel(1);
4252

4353
assertEquals(0, results.getFailCount());
4454
}
55+
56+
private static boolean isGraalVMRuntime() {
57+
try {
58+
Class.forName("org.graalvm.home.Version");
59+
return true;
60+
} catch (ClassNotFoundException e) {
61+
return false;
62+
}
63+
}
4564
}
Lines changed: 16 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@ignore
1+
@requires-graalvm
22
Feature: Test javascript plugins
33

44
Background:
@@ -14,18 +14,7 @@ Background:
1414
}
1515
"""
1616

17-
18-
* def basic =
19-
"""
20-
function(creds) {
21-
var temp = creds.username + ':' + creds.password;
22-
var Base64 = Java.type('java.util.Base64');
23-
var encoded = Base64.getEncoder().encodeToString(temp.toString().getBytes());
24-
return 'Basic ' + encoded;
25-
}
26-
"""
27-
28-
* def copyJsPluginDir =
17+
* def copyJsPluginDir =
2918
"""
3019
function() {
3120
var CopyFolderRecursively = Java.type('karate.CopyFolderRecursively');
@@ -34,58 +23,26 @@ Background:
3423
}
3524
"""
3625

37-
* def admin = basic({username: 'admin', password: 'secret'})
26+
* def basic =
27+
"""
28+
function(creds) {
29+
var temp = creds.username + ':' + creds.password;
30+
var Base64 = Java.type('java.util.Base64');
31+
var encoded = Base64.getEncoder().encodeToString(temp.toString().getBytes());
32+
return 'Basic ' + encoded;
33+
}
34+
"""
3835

36+
* def admin = basic({username: 'admin', password: 'secret'})
3937

40-
Scenario: Test hello
38+
Scenario: Load JS plugins and test hello service
4139
* call copyJsPluginDir
4240
* call sleep 10
43-
Given path '/hello'
44-
When method GET
45-
Then status 200
46-
And match response == {"msg":"Hello World from Italy with Love","note":"'from Italy with Love' was added by 'helloWorldInterceptor' that modifies the response of 'helloWorldService'"}
47-
48-
49-
Scenario: Test sub hello
50-
51-
Given path '/sub/hello'
52-
When method GET
53-
Then status 200
54-
55-
56-
Scenario: Test http client
57-
58-
Given path '/httpClient'
59-
When method GET
60-
Then status 200
61-
62-
63-
Scenario: Test mclient-service
64-
65-
# create test-db
6641
* header Authorization = admin
67-
Given path '/test-db'
68-
When method PUT
69-
* def ETAG = responseHeaders['ETag'][0]
70-
71-
72-
# create collection coll
73-
* header Authorization = admin
74-
Given path '/test-db/coll'
75-
When method PUT
76-
77-
78-
# send request
79-
* header Authorization = admin
80-
Given path '/mclientService'
42+
Given path '/hello'
8143
When method GET
8244
Then status 200
83-
84-
85-
# delete test-db
86-
* headers { "Authorization" : '#(admin)', "If-Match" : "#(ETAG)" }
87-
Given path '/test-db'
88-
When method DELETE
89-
And status 204
45+
And match response.msg == 'Hello World!'
46+
And match response.note == 'modified by helloWorldInterceptor'
9047

9148

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export const options = {
2+
name: "helloWorldInterceptor",
3+
description: "modifies the response of helloWorldService",
4+
interceptPoint: "RESPONSE"
5+
}
6+
7+
export function handle(req, res) {
8+
var body = JSON.parse(res.getContent());
9+
body.note = "modified by helloWorldInterceptor";
10+
res.setContent(JSON.stringify(body));
11+
}
12+
13+
export function resolve(req) {
14+
return req.isHandledBy("helloWorldService") && req.isGet();
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export const options = {
2+
name: "helloWorldService",
3+
description: "just another Hello World",
4+
uri: "/hello",
5+
secured: false,
6+
matchPolicy: "EXACT"
7+
}
8+
9+
export function handle(req, res) {
10+
if (req.isGet()) {
11+
res.setContent(JSON.stringify({ msg: "Hello World!" }));
12+
res.setContentTypeAsJson();
13+
}
14+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"rh:services": ["hello.mjs"],
3+
"rh:interceptors": ["hello-interceptor.mjs"]
4+
}

0 commit comments

Comments
 (0)