Skip to content

Commit d4b2fa2

Browse files
committed
Improved tests of scala port and java loader.
1 parent 60cbe68 commit d4b2fa2

File tree

5 files changed

+63
-33
lines changed

5 files changed

+63
-33
lines changed

source/loaders/java_loader/source/java_loader_impl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ loader_impl_data java_loader_impl_initialize(loader_impl impl, configuration con
129129
if (java_impl != nullptr)
130130
{
131131
#define TEST_CLASS_PATH \
132-
"ADD HERE YOUR CLASSPATH"
132+
"$(sbt 'export test:fullClasspath')"
133133

134134
static const size_t options_size = 2;
135135

@@ -186,7 +186,8 @@ loader_handle java_loader_impl_load_from_file(loader_impl impl, const loader_nam
186186
std::cout << "ffffffffffffffffffffffffffff" << std::endl;
187187
}
188188

189-
jclass cls2 = java_impl->env->FindClass("metacall/MetaCallSpecRunner");
189+
// jclass cls2 = java_impl->env->FindClass("metacall/MetaCallSpecRunner");
190+
jclass cls2 = java_impl->env->FindClass("metacall/CallerSpecRunner");
190191

191192
if (cls2 == nullptr)
192193
{

source/ports/scala_port/src/main/scala/Caller.scala

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import scala.concurrent.ExecutionContext
66

77
import com.sun.jna._, ptr.PointerByReference
88
import java.util.concurrent.{ConcurrentLinkedQueue, ConcurrentHashMap}
9+
import java.util.concurrent.locks.{ReentrantLock}
910
import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger}
1011

1112
/** `Caller` creates a new thread on which:
@@ -41,32 +42,46 @@ object Caller {
4142
if (!runningInMetacall)
4243
Bindings.instance.metacall_initialize()
4344

44-
while (!closed.get) try {
45+
while (!closed.get) {
4546
if (!scriptsQueue.isEmpty()) {
46-
val LoadCommand(namespace, runtime, paths) = scriptsQueue.poll()
47-
val handleRef = namespace.map(_ => new PointerByReference())
48-
Loader.loadFilesUnsafe(runtime, paths, handleRef)
49-
handleRef.zip(namespace) match {
50-
case Some((handleRef, namespace)) =>
51-
namespaceHandles.put(
52-
namespace,
53-
handleRef
54-
)
55-
case None => ()
47+
try {
48+
scriptsLock.lock()
49+
val LoadCommand(namespace, runtime, paths) = scriptsQueue.poll()
50+
val handleRef = namespace.map(_ => new PointerByReference())
51+
Loader.loadFilesUnsafe(runtime, paths, handleRef)
52+
handleRef.zip(namespace) match {
53+
case Some((handleRef, namespace)) =>
54+
namespaceHandles.put(
55+
namespace,
56+
handleRef
57+
)
58+
case None => ()
59+
}
60+
// TODO: We may need to set up the result or the error in a monad
61+
} catch {
62+
// TODO: We may need to set up the result or the error in a monad
63+
case e: Throwable => Console.err.println(e)
64+
} finally {
65+
scriptsReady.signal()
66+
scriptsLock.unlock()
5667
}
5768
} else if (!callQueue.isEmpty()) {
58-
val UniqueCall(Call(namespace, fnName, args), id) = callQueue.poll()
59-
val result = callUnsafe(namespace, fnName, args)
60-
callResultMap.put(id, result)
69+
try {
70+
val UniqueCall(Call(namespace, fnName, args), id) = callQueue.poll()
71+
val result = callUnsafe(namespace, fnName, args)
72+
callResultMap.put(id, result)
73+
} catch {
74+
case e: Throwable => Console.err.println(e)
75+
}
6176
}
62-
} catch {
63-
case e: Throwable => Console.err.println(e)
6477
}
6578

6679
if (!runningInMetacall)
6780
Bindings.instance.metacall_destroy()
6881
}
6982

83+
private val scriptsLock = new ReentrantLock()
84+
private val scriptsReady = scriptsLock.newCondition()
7085
private val closed = new AtomicBoolean(false)
7186
private val callQueue = new ConcurrentLinkedQueue[UniqueCall]()
7287
private val callResultMap = new ConcurrentHashMap[Int, Value]()
@@ -90,7 +105,13 @@ object Caller {
90105
}
91106

92107
scriptsQueue.add(LoadCommand(namespace, runtime, filePaths))
93-
while (!scriptsQueue.isEmpty()) ()
108+
109+
scriptsLock.lock()
110+
111+
while (!scriptsQueue.isEmpty())
112+
scriptsReady.await()
113+
114+
scriptsLock.unlock()
94115
}
95116

96117
def loadFile(
@@ -106,10 +127,7 @@ object Caller {
106127
loadFile(runtime, filePath, None)
107128

108129
def start(): Unit = {
109-
if (!runningInMetacall)
110-
new Thread(() => callLoop()).start()
111-
else
112-
callLoop()
130+
new Thread(() => callLoop()).start()
113131
}
114132

115133
def destroy(): Unit = closed.set(true)

source/ports/scala_port/src/test/scala/CallerSpec.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ package metacall
33
import metacall.instances._
44
import org.scalatest.flatspec.AnyFlatSpec
55

6+
class CallerSpecRunner {
7+
def run() = {
8+
println("Executing CallerSpec Tests")
9+
(new CallerSpec()).execute()
10+
}
11+
}
12+
613
class CallerSpec extends AnyFlatSpec {
7-
// TODO: This won't work with NodeJS, it is not tolerant a reinitialization.
8-
// Probably we should split this into two tests, one for the caller (event loop based),
9-
// and another for MetaCall without event loop. So each test suite runs in a different process.
1014
"Caller" should "start successfully" in {
1115
Caller.start()
1216
}

source/ports/scala_port/src/test/scala/MetaCallSpec.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,21 @@ class MetaCallSpec extends AnyFlatSpec {
2121
"MetaCall" should "initialize successfully" in {
2222
// TODO: Remove this if we drop support for executing Scala outside of MetaCall
2323
// TODO: Create a destroy method wrapping this functionality
24-
if (System.getProperty("java.polyglot.name") != "metacall") {
24+
if (System.getProperty("metacall.polyglot.name") != "core") {
2525
assert(
2626
metacall.metacall_initialize() == 0,
2727
"MetaCall was not successfully initialized"
2828
)
2929
}
3030
}
3131

32-
/*
3332
"MetaCall" should "load node script successsfully" in {
33+
// NodeJS requires to set the library path environment variable
34+
assert(
35+
sys.env("LOADER_LIBRARY_PATH") != "",
36+
"For running NodeJS tests you must define the loader library path"
37+
)
38+
3439
val scriptPaths = Array(
3540
Paths.get("./src/test/scala/scripts/main.js").toAbsolutePath.toString()
3641
)
@@ -46,7 +51,6 @@ class MetaCallSpec extends AnyFlatSpec {
4651
s"MetaCall failed to load the script with code $retCode"
4752
)
4853
}
49-
*/
5054

5155
"MetaCall" should "load python script successsfully" in {
5256
val scriptPaths = Array(
@@ -83,7 +87,7 @@ class MetaCallSpec extends AnyFlatSpec {
8387
s"MetaCall failed to load the script with code $retCode"
8488
)
8589

86-
val ret = Bindings.instance.metacallhv_s(
90+
val ret = metacall.metacallhv_s(
8791
handleRef.getValue(),
8892
"fn_in_s1",
8993
Array(),
@@ -440,7 +444,7 @@ class MetaCallSpec extends AnyFlatSpec {
440444
argValues match {
441445
case StringValue(s) :: Nil =>
442446
Ptr.fromValueUnsafe(StringValue("Hello, " + s)).ptr
443-
case _ => Bindings.instance.metacall_value_create_null()
447+
case _ => metacall.metacall_value_create_null()
444448
}
445449
}
446450
}
@@ -456,7 +460,7 @@ class MetaCallSpec extends AnyFlatSpec {
456460
"MetaCall" should "be destroyed successfully" in {
457461
// TODO: Remove this if we drop support for executing Scala outside of MetaCall
458462
// TODO: Create a destroy method wrapping this functionality
459-
if (System.getProperty("java.polyglot.name") != "metacall") {
463+
if (System.getProperty("metacall.polyglot.name") != "core") {
460464
assert(
461465
metacall.metacall_destroy() == 0,
462466
"MetaCall was not successfully destroyed"

source/tests/java_loader_test/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,11 @@ target_link_libraries(${target}
126126
#
127127

128128
add_test(NAME ${target}
129-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
129+
# WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
130130
COMMAND $<TARGET_FILE:${target}>
131+
132+
# TODO: Remove this
133+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/source/ports/scala_port
131134
)
132135

133136
#

0 commit comments

Comments
 (0)