blob: 73765b3e385953c4c0efe4b686ad57c2f3b606fd [file] [log] [blame]
clargs <- commandArgs(trailing=TRUE)
source(file.path(clargs[1], "unittest.R"))
#source("unittest.R")
dyn.load(paste("li_boost_shared_ptr", .Platform$dynlib.ext, sep=""))
source("li_boost_shared_ptr.R")
cacheMetaData(1)
# simple shared_ptr usage - created in C++
invisible(debug_shared(TRUE))
unittest(debug_shared(), TRUE)
# Expect 1 instance - the one global variable (GlobalValue)
unittest(Klass_getTotal_count(), 1)
# Change loop count to run for a long time to monitor memory
unittest(shared_ptr_wrapper_count(), NOT_COUNTING())
#
# test suite to be run in a loop
#
testSuite_verifyCount <- function(expected, k) {
got = use_count(k)
unittest(expected, got);
}
testSuite <- function() {
#
# Reference Implementation is li_boost_shared_ptr_runme.py
#
# simple shared_ptr usage - created in C++
{
k = Klass("me oh my")
val = k$getValue()
unittest("me oh my", val)
testSuite_verifyCount(1, k)
}
# simple shared_ptr usage - not created in C++
{
k = factorycreate()
val = k$getValue()
unittest("factorycreate", val)
testSuite_verifyCount(1, k)
}
# pass by shared_ptr
{
k = Klass("me oh my")
kret = smartpointertest(k)
val = kret$getValue()
unittest("me oh my smartpointertest", val)
testSuite_verifyCount(2, k)
testSuite_verifyCount(2, kret)
}
# pass by shared_ptr pointer
{
k = Klass("me oh my")
kret = smartpointerpointertest(k)
val = kret$getValue()
unittest("me oh my smartpointerpointertest", val)
testSuite_verifyCount(2, k)
testSuite_verifyCount(2, kret)
}
# pass by shared_ptr reference
{
k = Klass("me oh my")
kret = smartpointerreftest(k)
val = kret$getValue()
unittest("me oh my smartpointerreftest", val)
testSuite_verifyCount(2, k)
testSuite_verifyCount(2, kret)
}
{
# pass by shared_ptr pointer reference
k = Klass("me oh my")
kret = smartpointerpointerreftest(k)
val = kret$getValue()
unittest("me oh my smartpointerpointerreftest", val)
testSuite_verifyCount(2, k)
testSuite_verifyCount(2, kret)
}
{
# pass by shared_ptr pointer reference
k = Klass("me oh my");
kret = smartpointerpointerreftest(k);
val = kret$getValue()
unittest("me oh my smartpointerpointerreftest", val);
testSuite_verifyCount(2, k);
testSuite_verifyCount(2, kret);
}
# const pass by shared_ptr
{
k = Klass("me oh my");
kret = constsmartpointertest(k);
val = Klass_getValue(kret);
unittest("me oh my", val);
testSuite_verifyCount(2, k);
testSuite_verifyCount(2, kret);
}
# const pass by shared_ptr pointer
{
k = Klass("me oh my")
kret = constsmartpointerpointertest(k)
val = Klass_getValue(kret)
unittest("me oh my", val)
testSuite_verifyCount(2, k)
testSuite_verifyCount(2, kret)
}
# const pass by shared_ptr reference
{
k = Klass("me oh my")
kret = constsmartpointerreftest(k)
val = Klass_getValue(kret)
unittest("me oh my", val)
testSuite_verifyCount(2, k)
testSuite_verifyCount(2, kret)
}
# pass by value
{
k = Klass("me oh my");
kret = valuetest(k);
val = kret$getValue();
unittest("me oh my valuetest", val);
testSuite_verifyCount(1, k);
testSuite_verifyCount(1, kret);
}
# pass by pointer
{
k = Klass("me oh my");
kret = pointertest(k);
val = kret$getValue();
unittest("me oh my pointertest", val);
testSuite_verifyCount(1, k);
testSuite_verifyCount(1, kret);
}
# pass by reference
{
k = Klass("me oh my");
kret = reftest(k);
val = kret$getValue();
unittest("me oh my reftest", val);
testSuite_verifyCount(1, k);
testSuite_verifyCount(1, kret);
}
# pass by pointer reference
{
k = Klass("me oh my");
kret = pointerreftest(k);
val = kret$getValue();
unittest("me oh my pointerreftest", val);
testSuite_verifyCount(1, k);
testSuite_verifyCount(1, kret);
}
# null tests
{
k = NULL
if (!is.null(smartpointertest(k))) {
stop("return was not null");
}
if (!is.null(smartpointerpointertest(k))) {
stop("return was not null");
}
if (!is.null(smartpointerreftest(k))) {
stop("return was not null");
}
if (!is.null(smartpointerpointerreftest(k))) {
stop("return was not null");
}
if (nullsmartpointerpointertest(k) != "null pointer") {
stop("not null smartpointer pointer");
}
bNotCatched = F
try({
valuetest(k);
bNotCatched = T
}, silent = T)
if (bNotCatched) {
stop("Failed to catch null pointer");
}
if (!is.null(pointertest(k))) {
stop("return was not null");
}
bNotCatched = F
try({
reftest(k);
bNotCatched = T
}, silent = T)
if (bNotCatched) {
stop("Failed to catch null pointer");
}
# test null pointers emitted from C++
k = sp_pointer_null()
if (!is.null(k)) {
stop("return was not null")
}
k = null_sp_pointer()
if (!is.null(k)) {
stop("return was not null")
}
k = sp_value_null()
if (!is.null(k)) {
stop("return was not null")
}
}
# $owner
{
k = pointerownertest();
val = k$getValue();
unittest("pointerownertest", val);
testSuite_verifyCount(1, k);
}
{
k = smartpointerpointerownertest();
val = k$getValue();
unittest("smartpointerpointerownertest", val);
testSuite_verifyCount(1, k);
}
#
# ###################### Derived and base class mixed ######################
#
# pass by shared_ptr (mixed)
{
k = KlassDerived("me oh my");
kret = derivedsmartptrtest(k);
val = kret$getValue();
unittest("me oh my derivedsmartptrtest-Derived", val);
testSuite_verifyCount(2, k);
testSuite_verifyCount(2, kret);
}
# pass by shared_ptr pointer (mixed)
{
k = KlassDerived("me oh my");
kret = derivedsmartptrpointertest(k);
val = kret$getValue();
unittest("me oh my derivedsmartptrpointertest-Derived", val);
testSuite_verifyCount(2, k);
testSuite_verifyCount(2, kret);
}
# pass by shared_ptr ref (mixed)
{
k = KlassDerived("me oh my");
kret = derivedsmartptrreftest(k);
val = kret$getValue();
unittest("me oh my derivedsmartptrreftest-Derived", val);
testSuite_verifyCount(2, k);
testSuite_verifyCount(2, kret);
}
# pass by shared_ptr pointer reference (mixed)
{
k = KlassDerived("me oh my");
kret = smartpointerpointerreftest(k);
val = kret$getValue();
unittest("me oh my smartpointerpointerreftest-Derived", val);
#testSuite_verifyCount(2, k); # includes two extra references for upcasts in the proxy classes
#testSuite_verifyCount(2, kret);
}
# pass by value (mixed)
{
k = KlassDerived("me oh my")
kret = valuetest(k)
val = kret$getValue()
unittest("me oh my valuetest", val) # note slicing
testSuite_verifyCount(2, k)
testSuite_verifyCount(1, kret)
# --> these are the python expected counting
# testSuite_verifyCount(1, k)
# testSuite_verifyCount(1, kret)
}
# pass by pointer (mixed)
{
k = KlassDerived("me oh my");
kret = derivedpointertest(k);
val = kret$getValue();
unittest("me oh my derivedpointertest-Derived", val);
testSuite_verifyCount(1, k);
testSuite_verifyCount(1, kret);
}
# pass by ref (mixed)
{
k = KlassDerived("me oh my");
kret = reftest(k);
val = kret$getValue();
unittest("me oh my reftest-Derived", val);
testSuite_verifyCount(2, k);
testSuite_verifyCount(1, kret);
# --> these are the python expected counting
#testSuite_verifyCount(1, k);
#testSuite_verifyCount(1, kret);
}
#
# ################# Overloading tests ##################
#
# Base class
{
k = Klass("me oh my");
unittest(overload_rawbyval(k), "rawbyval")
unittest(overload_rawbyref(k), "rawbyref")
unittest(overload_rawbyptr(k), "rawbyptr")
unittest(overload_rawbyptrref(k), "rawbyptrref")
unittest(overload_smartbyval(k), "smartbyval")
unittest(overload_smartbyref(k), "smartbyref")
unittest(overload_smartbyptr(k), "smartbyptr")
unittest(overload_smartbyptrref(k), "smartbyptrref")
}
# Derived class
{
k = KlassDerived("me oh my")
unittest(overload_rawbyval(k), "rawbyval")
unittest(overload_rawbyref(k), "rawbyref")
unittest(overload_rawbyptr(k), "rawbyptr")
unittest(overload_rawbyptrref(k), "rawbyptrref")
unittest(overload_smartbyval(k), "smartbyval")
unittest(overload_smartbyref(k), "smartbyref")
unittest(overload_smartbyptr(k), "smartbyptr")
unittest(overload_smartbyptrref(k), "smartbyptrref")
}
# 3rd derived class
{
k = Klass3rdDerived("me oh my")
unittest(overload_rawbyval(k), "rawbyval")
unittest(overload_rawbyref(k), "rawbyref")
unittest(overload_rawbyptr(k), "rawbyptr")
unittest(overload_rawbyptrref(k), "rawbyptrref")
unittest(overload_smartbyval(k), "smartbyval")
unittest(overload_smartbyref(k), "smartbyref")
unittest(overload_smartbyptr(k), "smartbyptr")
unittest(overload_smartbyptrref(k), "smartbyptrref")
}
#
# ################ Member variables ####################
#
# smart pointer by value
{
m = MemberVariables();
k = Klass("smart member value");
m$SmartMemberValue = k;
val = k$getValue();
unittest("smart member value", val);
testSuite_verifyCount(2, k);
kmember = m$SmartMemberPointer;
val = kmember$getValue();
unittest("smart member value", val);
testSuite_verifyCount(3, kmember);
testSuite_verifyCount(3, k);
delete_MemberVariables(m)
testSuite_verifyCount(2, kmember);
testSuite_verifyCount(2, k);
}
# smart pointer by pointer
{
m = MemberVariables();
k = Klass("smart member pointer");
m$SmartMemberPointer = k;
val = k$getValue();
unittest("smart member pointer", val);
testSuite_verifyCount(1, k);
kmember = m$SmartMemberPointer;
val = kmember$getValue();
unittest("smart member pointer", val);
testSuite_verifyCount(2, kmember);
testSuite_verifyCount(2, k);
delete_MemberVariables(m);
testSuite_verifyCount(2, kmember);
testSuite_verifyCount(2, k);
}
# smart pointer by reference
{
m = MemberVariables();
k = Klass("smart member reference");
m$SmartMemberReference = k;
val = k$getValue();
unittest("smart member reference", val);
testSuite_verifyCount(2, k);
kmember = m$SmartMemberPointer;
val = kmember$getValue();
unittest("smart member reference", val);
testSuite_verifyCount(3, kmember);
testSuite_verifyCount(3, k);
# The C++ reference refers to SmartMemberValue...
kmemberVal = m$SmartMemberReference;
val = kmember$getValue();
unittest("smart member reference", val);
testSuite_verifyCount(4, kmemberVal);
testSuite_verifyCount(4, kmember);
testSuite_verifyCount(4, k);
delete_MemberVariables(m);
testSuite_verifyCount(3, kmemberVal);
testSuite_verifyCount(3, kmember);
testSuite_verifyCount(3, k);
}
# plain by value
{
m = MemberVariables();
k = Klass("plain member value");
m$MemberValue = k;
val = k$getValue();
unittest("plain member value", val);
testSuite_verifyCount(1, k);
kmember = m$MemberValue;
val = kmember$getValue();
unittest("plain member value", val);
testSuite_verifyCount(1, kmember);
testSuite_verifyCount(1, k);
delete_MemberVariables(m); # m.delete();
testSuite_verifyCount(1, kmember);
testSuite_verifyCount(1, k);
}
# plain by pointer
{
m = MemberVariables();
k = Klass("plain member pointer");
m$MemberPointer = k;
val = k$getValue();
unittest("plain member pointer", val);
testSuite_verifyCount(1, k);
kmember = m$MemberPointer;
val = kmember$getValue();
unittest("plain member pointer", val);
testSuite_verifyCount(1, kmember);
testSuite_verifyCount(1, k);
delete_MemberVariables(m); # m.delete();
testSuite_verifyCount(1, kmember);
testSuite_verifyCount(1, k);
}
# plain by reference
{
m = MemberVariables();
k = Klass("plain member reference");
m$MemberReference = k;
val = k$getValue();
unittest("plain member reference", val);
testSuite_verifyCount(1, k);
kmember = m$MemberReference;
val = kmember$getValue();
unittest("plain member reference", val);
testSuite_verifyCount(1, kmember);
testSuite_verifyCount(1, k);
delete_MemberVariables(m); # m.delete();
testSuite_verifyCount(1, kmember);
testSuite_verifyCount(1, k);
}
# null member variables
{
m = MemberVariables();
# shared_ptr by value
k = m$SmartMemberValue;
if (!is.null(k))
stop("expected null");
m$SmartMemberValue = NULL;
k = m$SmartMemberValue;
if (!is.null(k))
stop("expected null");
#testSuite_verifyCount(0, k); # this does not work for nulls
# plain by value
bNotCatched = F
try({
m$MemberValue = NULL
bNotCatched = T
}, silent = T)
if (bNotCatched) {
stop("Failed to catch null pointer")
}
}
#
# ################ Global variables ####################
#
# smart pointer
{
kglobal = GlobalSmartValue_get();
if (!is.null(kglobal))
stop("expected null");
k = Klass("smart global value");
GlobalSmartValue_set(k);
testSuite_verifyCount(2, k);
kglobal = GlobalSmartValue_get();
val = kglobal$getValue();
unittest("smart global value", val);
testSuite_verifyCount(3, kglobal);
testSuite_verifyCount(3, k);
unittest("smart global value", GlobalSmartValue_get()$getValue());
GlobalSmartValue_set(NULL);
}
# plain value
{
k = Klass("global value");
GlobalValue_set(k);
testSuite_verifyCount(1, k);
kglobal = GlobalValue_get();
val = kglobal$getValue();
unittest("global value", val);
testSuite_verifyCount(1, kglobal);
testSuite_verifyCount(1, k);
unittest("global value", GlobalValue_get()$getValue());
bNotCatched = F
try({
GlobalValue_set(NULL)
bNotCatched = T
}, silent = T)
if (bNotCatched) {
stop("Failed to catch null pointer")
}
}
# plain pointer
{
kglobal = GlobalPointer_get();
if (!is.null(kglobal))
stop("expected null");
k = Klass("global pointer");
GlobalPointer_set(k);
testSuite_verifyCount(1, k);
kglobal = GlobalPointer_get();
val = kglobal$getValue();
unittest("global pointer", val);
testSuite_verifyCount(1, kglobal);
testSuite_verifyCount(1, k);
GlobalPointer_set(NULL);
}
# plain reference
{
k = Klass("global reference");
GlobalReference_set(k);
testSuite_verifyCount(1, k);
kglobal = GlobalReference_get();
val = kglobal$getValue();
unittest("global reference", val);
testSuite_verifyCount(1, kglobal);
testSuite_verifyCount(1, k);
bNotCatched = F
try({
GlobalReference_set(NULL)
bNotCatched = T
}, silent = T)
if (bNotCatched) {
stop("Failed to catch null pointer")
}
}
#
# ###################### Templates ######################
#
{
pid = PairIntDouble(10, 20.2);
if (BaseIntDouble_baseVal1_get(pid) != 20 || BaseIntDouble_baseVal2_get(pid) != 40.4)
stop("Base values wrong");
if (PairIntDouble_val1_get(pid) != 10 || PairIntDouble_val2_get(pid) != 20.2)
stop("Derived Values wrong");
}
}
# actually do the tests
for (i in 1:10) {
print(paste("Start Loop: ", i))
testSuite()
print(paste("End Loop: ", i))
}
# wait for the GC to collect unused objects
#for (i in 1:10) {
# invisible(gc(verbose = F, full = T))
#
# if (Klass_getTotal_count() == 1) {
# break
# }
#
# print(paste("Still waiting for GC to collect ", Klass_getTotal_count()-1, " objects, ", i))
# Sys.sleep(1)
#}
# Expect
unittest(shared_ptr_wrapper_count(), NOT_COUNTING())
# Expect 1 instance - the one global variable (GlobalValue)
# -> documented bug - gc does not work on some objects - https://www.swig.org/Doc4.0/SWIGDocumentation.html#R_nn2
if (FALSE) {
unittest(Klass_getTotal_count(), 1)
}
q(save="no")