Skip to content
ssardina edited this page Nov 1, 2020 · 2 revisions

The JPL package includes unit testing for the cases when Java calls Prolog (using Java JUNIT4) as well as when Prolog calls Java (using SWIPL PLUNIT library).

Both are integrated into CMAKE with the id jpl and be run, from the build directory, as follows:

$ ctest -R  jpl
Test project /home/ssardina/git/soft/prolog/swipl-devel.git/build
    Start 63: jpl:prolog_in_java
1/2 Test #63: jpl:prolog_in_java ...............   Passed    0.87 sec
    Start 64: jpl:java_in_prolog
2/2 Test #64: jpl:java_in_prolog ...............   Passed    0.44 sec

100% tests passed, 0 tests failed out of 2

Total Test time (real) =   1.35 sec

Use ctest -V -R jpl to have the verbose version (long!).

Below we cover both testing cases as well as how to do static checks on the Prolog API code using check/0 nad gxref/0.

Java calls Prolog via JUNIT4

As of April 2020 most tests have been ported to JUNIT4.

  • The set of JUNIT test class are in package org.jpl7.junit, but there is a test suit org.jpl7.JPLTestSuite to wrap them all.
  • There are also standalone tests in org.jpl7.standalone.*
    • Each of these testing classes can be run individually and are not part of the test suite.

IMPORTANT: All unit test cases are sub-classes of org.jpl7.junit.JPLTest, which provides a method setUpClass to initialize the Prolog engine with the correct SWIPL in the source development tree. Such class will gather a few environment variables that point to the development tree of SWIPL. While those variables are already set by CMAKE, if one wants to develop and run the tests within an IDE and outside CMAKE for the Java component, one has to set those variables (see below for more details).

There are 3 ways one can run the unit testing (or an application that wants to use the development SWI+JPL):

Using CMAKE from anywhere in the build/ structure:

$ ctest -V  -R jpl:prolog_in_java

In CLI, the tests needs to be run from build/package/jpl.

This is the command to run the prolog_in_java test (which uses SWIPL plunit and a test_lib script defined in packages/cmake/PrologPackage.cmake to collect all test_xxx.pl unit testing files):

$ /usr/bin/env "CLASSPATH=src/main/java/jpl.jar" "SWI_HOME_DIR=../../home" "SWIPL_BOOT_FILE=../../home/boot.prc" java "-Djava.library.path=." "-classpath" "/usr/share/java/junit4.jar:src/main/java/jpl.jar:src/test/java/jpltest.jar" org.jpl7.junit.Test_Atom
JUnit version 4.12
.Starting test: testAtomToString1 (Test_Atom)
.Starting test: testAtomToString2 (Test_Atom)
.Starting test: testAtomToString3 (Test_Atom)
.Starting test: testAtomEquality1 (Test_Atom)
.Starting test: testAtomEquality2 (Test_Atom)
.Starting test: testAtomIdentity (Test_Atom)
.Starting test: testAtom1 (Test_Atom)
.Starting test: testAtomHasFunctorWrongName (Test_Atom)
.Starting test: testAtomHasFunctorNameZero (Test_Atom)
.Starting test: testAtomArity (Test_Atom)
.Starting test: testAtomName1 (Test_Atom)
.Starting test: testAtomName2 (Test_Atom)
.Starting test: testAtomName3 (Test_Atom)
.Starting test: testAtomHasFunctorWrongArity (Test_Atom)

Time: 0.044

OK (14 tests)

Running JUNIT cases from IDE

Most often one will develop the Java side of JPL from an IDE (e.g., ECLIPSE or IntelliJ) and one would like to run the unit testing directly from there, rather than via CMAKE.

Assuming we are develping JPL in its usual location (packages/jpl) with SWIPL source tree and the SWIPL non-installed build is in build/, we would set-up the following environment variables:

SWI_HOME_DIR=../../build/home/
SWIPL_BOOT_FILE=../../build/home/boot.prc   # to setup SWIPL engine
LD_LIBRARY_PATH=../../build/packages/jpl    # to find libjpl.so
CLASSPATH=target/classes/	        # for calls from Prolog to Java
LD_PRELOAD=../../build/src/libswipl.so	    # avoid run-time errors

In IntelliJ, for example, this is done by modifying the Java/JUnit Template in "Run/Debug Configuration" to include the environment variables.

Note this assumes your IDE will compile the JPL classes into target/classes dir, as default in a Maven project.

For instance, modify the JUNIT template by just enter this string in "Environment variables":

LD_LIBRARY_PATH=../../build/packages/jpl;SWI_HOME_DIR=../../build/home;SWIPL_BOOT_FILE=../../build/home/boot.prc;CLASSPATH=target/classes;LD_PRELOAD=../../build/src/libswipl.so

Prolog calls Java via PLUNIT

The unit testing of Prolog code calling Java is implemented via the SWI plunit library.

The unit tests are located in file test_jpl.pl at the root of the JPL source tree, that is, <swi-src>/package/jpl/test_jpl.pl within the whole SWIPL source tree.

To run the unit test via CMAKE:

$ ctest -V  -R jpl:java_in_prolog

To run it manually via CLI from build/package/jpl:

$ /home/ssardina/git/soft/prolog/swipl-devel.git/build/src/swipl "-p" "foreign=:/home/ssardina/git/soft/prolog/swipl-devel.git/build/packages/plunit" "-f" "none" "--no-packs" "-s" "/home/ssardina/git/soft/prolog/swipl-devel.git/packages/jpl/test_jpl.pl" "-g" "test_jpl" "-t" "halt"
% PL-Unit: jpl .......................................................................................... done
% 3 tests are blocked:
% /home/ssardina/git/soft/prolog/swipl-devel.git/packages/jpl/test_jpl.pl:610:
	test method_static_echo_float_4: we do not yet widen unbounded integers to floats or doubles
% /home/ssardina/git/soft/prolog/swipl-devel.git/packages/jpl/test_jpl.pl:914:
	test set_field_static_shadow_1: we do not yet resolve same-named shadowed fields
% /home/ssardina/git/soft/prolog/swipl-devel.git/packages/jpl/test_jpl.pl:1193:
	test throw_java_exception_1: part of the error term is nondeterministic: we need to match with _
% 90 tests passed

Checking jpl.pl code

If changes are done to the Prolog API, in file jpl.pl, then one can use check/0 and gxref/0 to run some basic static checks:

$ echo $SWI_BUILD 
/home/ssardina/git/soft/prolog/swipl-devel.git/build/

$ $SWI_BUILD/src/swipl -x $SWI_BUILD/home/boot.prc -F swipl --home=$SWI_BUILD/home 

Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.1-34-g9adbe8ff1-DIRTY)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

    CMake built from "/home/ssardina/git/soft/prolog/swipl-devel.git/build"

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).


?- use_module(library(jpl)).
true.

?- check.
% Checking undefined predicates ...
% Checking trivial failures ...
% Checking format/2,3 and debug/3 templates ...
% Checking redefined system and global predicates ...
% Checking predicates with declarations but without clauses ...
% Checking predicates that need autoloading ...
% Disabled autoloading (loaded 98 files)
true.

Note how we are running the SWIPL development framework that is compiled but still not installed system wide.

Testing in deployment environment

If the system was installed from a built using the CMAKE -DINSTALL_TESTS=ON flag, then tests will be installed. This is mostly intended for cross-compilation where you cannot run the test suite on the build host or you want tor some other reason to test the system in the deployment environment.

To run the tests, issue the goal ? - test_installation.

[ssardina@Thinkpad-X1 swipl-devel.git]$ /usr/local/swipl-git/bin/swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.3-2-ga5e08cf2e-DIRTY)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- test_installation.
% SWI-Prolog test suite.
% To run all tests run ?- test.
% 
Running test set "syntax" ............................... done.
Running test set "write_test" .............. done.
Running test set "format_test" ......... done.
Running test set "unify" .. done.
Running test set "occurs_check" ...... done.
Running test set "unifiable" ... done.
Running test set "arithmetic" ...................................... done.
Running test set "arithmetic_functions"  done.
Running test set "floattest" ........ done.
Running test set "gmp" ........................................................... done.
Running test set "chars" .. done.
Running test set "wchars" .. done.
Running test set "depth_limit" .... done. 
....