mirror of https://gitlab.com/ita1024/waf.git
javatest: manage environment also for non-java dependencies (ie. JNI / JEP)
This commit is contained in:
parent
68bf3867df
commit
02c3711e2e
|
@ -0,0 +1,27 @@
|
|||
public final class StringUtils
|
||||
{
|
||||
|
||||
public static final String LIBRARY_NAME = "stringUtils";
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary(LIBRARY_NAME);
|
||||
}
|
||||
|
||||
private StringUtils()
|
||||
{
|
||||
}
|
||||
|
||||
public static native boolean isAlpha(String string);
|
||||
|
||||
public static native boolean isEmpty(String string);
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
System.out.println(StringUtils.isAlpha("sureIs"));
|
||||
System.out.println(StringUtils.isAlpha("nope!"));
|
||||
System.out.println(StringUtils.isEmpty(" "));
|
||||
System.out.println(StringUtils.isEmpty("nope"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class StringUtils */
|
||||
|
||||
#ifndef _Included_StringUtils
|
||||
#define _Included_StringUtils
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: StringUtils
|
||||
* Method: isAlpha
|
||||
* Signature: (Ljava/lang/String;)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_StringUtils_isAlpha
|
||||
(JNIEnv *, jclass, jstring);
|
||||
|
||||
/*
|
||||
* Class: StringUtils
|
||||
* Method: isEmpty
|
||||
* Signature: (Ljava/lang/String;)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_StringUtils_isEmpty
|
||||
(JNIEnv *, jclass, jstring);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
#include "StringUtils.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_StringUtils_isAlpha(JNIEnv *env, jclass clazz,
|
||||
jstring jStr)
|
||||
{
|
||||
jboolean ret = JNI_TRUE;
|
||||
char *sp = NULL, *s = NULL;
|
||||
|
||||
if (!jStr)
|
||||
return JNI_FALSE;
|
||||
|
||||
s = (char*)(*env)->GetStringUTFChars(env, jStr, 0);
|
||||
sp = s + strlen(s);
|
||||
if (sp <= s)
|
||||
ret = JNI_FALSE;
|
||||
do
|
||||
{
|
||||
if (!isalpha(*(--sp)))
|
||||
ret = JNI_FALSE;
|
||||
}
|
||||
while (sp > s);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, jStr, s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_StringUtils_isEmpty(JNIEnv *env, jclass clazz,
|
||||
jstring jStr)
|
||||
{
|
||||
jboolean ret = JNI_TRUE;
|
||||
char *sp = NULL, *s = NULL;
|
||||
|
||||
if (!jStr)
|
||||
return JNI_TRUE;
|
||||
|
||||
s = (char*)(*env)->GetStringUTFChars(env, jStr, 0);
|
||||
sp = s + strlen(s);
|
||||
if (sp <= s)
|
||||
ret = JNI_TRUE;
|
||||
do
|
||||
{
|
||||
if (!isspace(*(--sp)))
|
||||
ret = JNI_FALSE;
|
||||
}
|
||||
while (sp > s);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, jStr, s);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class TestJni {
|
||||
|
||||
@Test
|
||||
public void testTrue() {
|
||||
Assert.assertEquals(true, StringUtils.isAlpha("myfootest"), "'myfootest' is alpha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFalse() {
|
||||
Assert.assertEquals(false, StringUtils.isAlpha("my f00 t3$t"), "'my f00 t3$t' is not alpha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsEmpty() {
|
||||
Assert.assertEquals(false, StringUtils.isEmpty("emptyNOT"), "'emptyNOT' is not empty");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
|
||||
|
||||
<suite name="SuiteForJni">
|
||||
<test name="testJni">
|
||||
<classes>
|
||||
<class name="TestJni"/>
|
||||
</classes>
|
||||
</test>
|
||||
</suite>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
# Federico Pellegrin, 2017 (fedepell)
|
||||
# Federico Pellegrin, 2019 (fedepell)
|
||||
|
||||
#
|
||||
# Simple script to demonstrate integration of Java Unit testing inside
|
||||
|
@ -21,9 +21,12 @@ def test_results(bld):
|
|||
|
||||
def options(opt):
|
||||
opt.load('java waf_unit_test javatest')
|
||||
opt.load('compiler_c')
|
||||
|
||||
def configure(conf):
|
||||
conf.load('java javatest')
|
||||
conf.load('compiler_c')
|
||||
conf.check_jni_headers()
|
||||
|
||||
def build(bld):
|
||||
bld(features = 'javac',
|
||||
|
@ -39,7 +42,7 @@ def build(bld):
|
|||
srcdir = 'test/', # folder containing the sources to compile
|
||||
outdir = 'test', # folder where to output the classes (in the build directory)
|
||||
sourcepath = ['test'],
|
||||
classpath = [ 'src' ],
|
||||
classpath = [ 'src' ],
|
||||
basedir = 'test', # folder containing the classes and other files to package (must match outdir)
|
||||
use = ['JAVATEST', 'mainprog'],
|
||||
ut_str = 'java -cp ${CLASSPATH} ${JTRUNNER} ${SRC}',
|
||||
|
@ -49,5 +52,25 @@ def build(bld):
|
|||
)
|
||||
|
||||
|
||||
# Demonstrate correct handling also of dependency to non-java tasks (see !2257)
|
||||
bld(name='stjni', features='javac jar', srcdir='jni/java', outdir='jni/java', basedir='jni/java', destfile='stringUtils.jar')
|
||||
|
||||
bld.shlib(source = 'jni/jni/source/StringUtils.c',
|
||||
includes = 'jni/jni/include',
|
||||
target = 'jni/stringUtils',
|
||||
uselib = 'JAVA')
|
||||
|
||||
bld(features = 'javac javatest',
|
||||
srcdir = 'jni/test/', # folder containing the sources to compile
|
||||
outdir = 'jni/test', # folder where to output the classes (in the build directory)
|
||||
sourcepath = ['jni/test'],
|
||||
classpath = [ 'jni/src' ],
|
||||
basedir = 'jni/test', # folder containing the classes and other files to package (must match outdir)
|
||||
use = ['JAVATEST', 'stjni', 'jni/stringUtils'],
|
||||
ut_str = 'java -cp ${CLASSPATH} ${JTRUNNER} ${SRC}',
|
||||
jtest_source = bld.path.ant_glob('jni/test/*.xml'),
|
||||
)
|
||||
|
||||
|
||||
bld.add_post_fun(test_results)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
# Federico Pellegrin, 2017 (fedepell)
|
||||
# Federico Pellegrin, 2019 (fedepell)
|
||||
|
||||
"""
|
||||
Provides Java Unit test support using :py:class:`waflib.Tools.waf_unit_test.utest`
|
||||
|
@ -11,6 +11,10 @@ standard waf unit test environment. It has been tested with TestNG and JUnit
|
|||
but should be easily expandable to other frameworks given the flexibility of
|
||||
ut_str provided by the standard waf unit test environment.
|
||||
|
||||
The extra takes care also of managing non-java dependencies (ie. C/C++ libraries
|
||||
using JNI or Python modules via JEP) and setting up the environment needed to run
|
||||
them.
|
||||
|
||||
Example usage:
|
||||
|
||||
def options(opt):
|
||||
|
@ -20,15 +24,15 @@ def configure(conf):
|
|||
conf.load('java javatest')
|
||||
|
||||
def build(bld):
|
||||
|
||||
|
||||
[ ... mainprog is built here ... ]
|
||||
|
||||
bld(features = 'javac javatest',
|
||||
srcdir = 'test/',
|
||||
outdir = 'test',
|
||||
srcdir = 'test/',
|
||||
outdir = 'test',
|
||||
sourcepath = ['test'],
|
||||
classpath = [ 'src' ],
|
||||
basedir = 'test',
|
||||
classpath = [ 'src' ],
|
||||
basedir = 'test',
|
||||
use = ['JAVATEST', 'mainprog'], # mainprog is the program being tested in src/
|
||||
ut_str = 'java -cp ${CLASSPATH} ${JTRUNNER} ${SRC}',
|
||||
jtest_source = bld.path.ant_glob('test/*.xml'),
|
||||
|
@ -53,10 +57,91 @@ The runner class presence on the system is checked for at configuration stage.
|
|||
"""
|
||||
|
||||
import os
|
||||
from waflib import Task, TaskGen, Options
|
||||
from waflib import Task, TaskGen, Options, Errors, Utils, Logs
|
||||
from waflib.Tools import ccroot
|
||||
|
||||
def _process_use_rec(self, name):
|
||||
"""
|
||||
Recursively process ``use`` for task generator with name ``name``..
|
||||
Used by javatest_process_use.
|
||||
"""
|
||||
if name in self.javatest_use_not or name in self.javatest_use_seen:
|
||||
return
|
||||
try:
|
||||
tg = self.bld.get_tgen_by_name(name)
|
||||
except Errors.WafError:
|
||||
self.javatest_use_not.add(name)
|
||||
return
|
||||
|
||||
self.javatest_use_seen.append(name)
|
||||
tg.post()
|
||||
|
||||
for n in self.to_list(getattr(tg, 'use', [])):
|
||||
_process_use_rec(self, n)
|
||||
|
||||
@TaskGen.feature('javatest')
|
||||
@TaskGen.after_method('apply_java', 'use_javac_files', 'set_classpath')
|
||||
@TaskGen.after_method('process_source', 'apply_link', 'use_javac_files')
|
||||
def javatest_process_use(self):
|
||||
"""
|
||||
Process the ``use`` attribute which contains a list of task generator names and store
|
||||
paths that later is used to populate the unit test runtime environment.
|
||||
"""
|
||||
self.javatest_use_not = set()
|
||||
self.javatest_use_seen = []
|
||||
self.javatest_libpaths = [] # strings or Nodes
|
||||
self.javatest_pypaths = [] # strings or Nodes
|
||||
self.javatest_dep_nodes = []
|
||||
|
||||
names = self.to_list(getattr(self, 'use', []))
|
||||
for name in names:
|
||||
_process_use_rec(self, name)
|
||||
|
||||
def extend_unique(lst, varlst):
|
||||
ext = []
|
||||
for x in varlst:
|
||||
if x not in lst:
|
||||
ext.append(x)
|
||||
lst.extend(ext)
|
||||
|
||||
# Collect type specific info needed to construct a valid runtime environment
|
||||
# for the test.
|
||||
for name in self.javatest_use_seen:
|
||||
tg = self.bld.get_tgen_by_name(name)
|
||||
|
||||
# Python-Java embedding crosstools such as JEP
|
||||
if 'py' in tg.features:
|
||||
# Python dependencies are added to PYTHONPATH
|
||||
pypath = getattr(tg, 'install_from', tg.path)
|
||||
|
||||
if 'buildcopy' in tg.features:
|
||||
# Since buildcopy is used we assume that PYTHONPATH in build should be used,
|
||||
# not source
|
||||
extend_unique(self.javatest_pypaths, [pypath.get_bld().abspath()])
|
||||
|
||||
# Add buildcopy output nodes to dependencies
|
||||
extend_unique(self.javatest_dep_nodes, [o for task in getattr(tg, 'tasks', []) for o in getattr(task, 'outputs', [])])
|
||||
else:
|
||||
# If buildcopy is not used, depend on sources instead
|
||||
extend_unique(self.javatest_dep_nodes, tg.source)
|
||||
extend_unique(self.javatest_pypaths, [pypath.abspath()])
|
||||
|
||||
|
||||
if getattr(tg, 'link_task', None):
|
||||
# For tasks with a link_task (C, C++, D et.c.) include their library paths:
|
||||
if not isinstance(tg.link_task, ccroot.stlink_task):
|
||||
extend_unique(self.javatest_dep_nodes, tg.link_task.outputs)
|
||||
extend_unique(self.javatest_libpaths, tg.link_task.env.LIBPATH)
|
||||
|
||||
if 'pyext' in tg.features:
|
||||
# If the taskgen is extending Python we also want to add the interpreter libpath.
|
||||
extend_unique(self.javatest_libpaths, tg.link_task.env.LIBPATH_PYEXT)
|
||||
else:
|
||||
# Only add to libpath if the link task is not a Python extension
|
||||
extend_unique(self.javatest_libpaths, [tg.link_task.outputs[0].parent.abspath()])
|
||||
|
||||
|
||||
@TaskGen.feature('javatest')
|
||||
@TaskGen.after_method('apply_java', 'use_javac_files', 'set_classpath', 'javatest_process_use')
|
||||
def make_javatest(self):
|
||||
"""
|
||||
Creates a ``utest`` task with a populated environment for Java Unit test execution
|
||||
|
@ -65,6 +150,9 @@ def make_javatest(self):
|
|||
tsk = self.create_task('utest')
|
||||
tsk.set_run_after(self.javac_task)
|
||||
|
||||
# Dependencies from recursive use analysis
|
||||
tsk.dep_nodes.extend(self.javatest_dep_nodes)
|
||||
|
||||
# Put test input files as waf_unit_test relies on that for some prints and log generation
|
||||
# If jtest_source is there, this is specially useful for passing XML for TestNG
|
||||
# that contain test specification, use that as inputs, otherwise test sources
|
||||
|
@ -97,6 +185,21 @@ def make_javatest(self):
|
|||
|
||||
if not hasattr(self, 'ut_env'):
|
||||
self.ut_env = dict(os.environ)
|
||||
def add_paths(var, lst):
|
||||
# Add list of paths to a variable, lst can contain strings or nodes
|
||||
lst = [ str(n) for n in lst ]
|
||||
Logs.debug("ut: %s: Adding paths %s=%s", self, var, lst)
|
||||
self.ut_env[var] = os.pathsep.join(lst) + os.pathsep + self.ut_env.get(var, '')
|
||||
|
||||
add_paths('PYTHONPATH', self.javatest_pypaths)
|
||||
|
||||
if Utils.is_win32:
|
||||
add_paths('PATH', self.javatest_libpaths)
|
||||
elif Utils.unversioned_sys_platform() == 'darwin':
|
||||
add_paths('DYLD_LIBRARY_PATH', self.javatest_libpaths)
|
||||
add_paths('LD_LIBRARY_PATH', self.javatest_libpaths)
|
||||
else:
|
||||
add_paths('LD_LIBRARY_PATH', self.javatest_libpaths)
|
||||
|
||||
def configure(ctx):
|
||||
cp = ctx.env.CLASSPATH or '.'
|
||||
|
|
Loading…
Reference in New Issue