Skip to content

Commit 55424ca

Browse files
Merge pull request #17 from FabrizioSandri/custom-harness
Custom test harness
2 parents b2f6a06 + 06776e0 commit 55424ca

File tree

3 files changed

+89
-54
lines changed

3 files changed

+89
-54
lines changed

R/fun_harness_create.R

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ deepstate_fun_create<-function(package_path, function_name, sep="infun"){
1616
functions.list <- deepstate_get_function_body(package_path)
1717
functions.list$argument.type <- gsub("Rcpp::","",functions.list$argument.type)
1818
prototypes_calls <- deepstate_get_prototype_calls(package_path)
19-
19+
fun_path <- file.path(package_path, "inst", "testfiles", function_name)
20+
2021
if(sep == "generation" || sep == "checks"){
2122
if(is.null(functions.list) || length(functions.list) < 1){
2223
stop("No Rcpp Function to test in the package")
@@ -51,10 +52,22 @@ deepstate_fun_create<-function(package_path, function_name, sep="infun"){
5152
params <- gsub("arma::","",params)
5253
params <- gsub("std::","",params)
5354

55+
filename <- if(sep == "generation" || sep == "checks"){
56+
paste0(function_name,"_DeepState_TestHarness_",sep,".cpp")
57+
}else{
58+
paste0(function_name,"_DeepState_TestHarness.cpp")
59+
}
60+
5461
# check if the parameters are allowed or not
5562
matched <- params %in% types_table$ctype
5663
unsupported_datatypes <- params[!matched]
57-
if(length(unsupported_datatypes) > 0){
64+
if(file.exists(file.path(fun_path, filename))){
65+
deepstate_create_makefile(package_path,function_name)
66+
warn_msg <- paste0("Test harness already exists for the function - ",
67+
function_name, " - using the existing one\n")
68+
message(warn_msg)
69+
return(filename)
70+
}else if(length(unsupported_datatypes) > 0){
5871
unsupported_datatypes <- paste(unsupported_datatypes, collapse=",")
5972
error_msg <- paste0("We can't test the function - ", function_name,
6073
" - due to the following datatypes falling out of the ",
@@ -64,13 +77,7 @@ deepstate_fun_create<-function(package_path, function_name, sep="infun"){
6477
}
6578

6679
pt <- prototypes_calls[prototypes_calls$funName == function_name,]
67-
filename <- if(sep == "generation" || sep == "checks"){
68-
paste0(function_name,"_DeepState_TestHarness_",sep,".cpp")
69-
}else{
70-
paste0(function_name,"_DeepState_TestHarness.cpp")
71-
}
7280

73-
fun_path <- file.path(package_path, "inst", "testfiles", function_name)
7481
if(!dir.exists(fun_path)){
7582
dir.create(fun_path, showWarnings = FALSE, recursive = TRUE)
7683
}

R/fun_makefile_create.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ deepstate_create_makefile <-function(package,fun_name){
6868

6969
# Makefile rules : compile lines
7070
write_to_file<-paste0(write_to_file, "\n\n", test_harness_path, " : ", test_harness.o_path)
71-
write_to_file<-paste0(write_to_file, "\n\t", "clang++ -g ", test_harness.o_path, " ${CPPFLAGS} ", " ${LDFLAGS} ", " ${LDLIBS} ", obj.file.path, " -o ", test_harness_path) #," ",objs.add)
71+
write_to_file<-paste0(write_to_file, "\n\t", "clang++ -g -gdwarf-4 ", test_harness.o_path, " ${CPPFLAGS} ", " ${LDFLAGS} ", " ${LDLIBS} ", obj.file.path, " -o ", test_harness_path) #," ",objs.add)
7272
write_to_file<-paste0(write_to_file, "\n\n", test_harness.o_path, " : ", test_harness.cpp_path)
73-
write_to_file<-paste0(write_to_file, "\n\t", "clang++ -g -c ", " ${CPPFLAGS} ", test_harness.cpp_path, " -o ", test_harness.o_path)
73+
write_to_file<-paste0(write_to_file, "\n\t", "clang++ -g -gdwarf-4 -c ", " ${CPPFLAGS} ", test_harness.cpp_path, " -o ", test_harness.o_path)
7474

7575
write(write_to_file, makefile_path, append=TRUE)
7676

R/pkg_harness_create.R

Lines changed: 72 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,117 @@
11
##' @title TestHarness for the package
22
##' @param package_path path to the test package
33
##' @param verbose used to deliver more in depth information
4-
##' @description Creates Testharness for all the functions in the package that you want to test
4+
##' @description Creates Testharness for all the functions in the package that
5+
##' you want to test
56
##' using RcppDeepState.
6-
##' @examples
7+
##' @examples
78
##' path <- system.file("testpkgs/testSAN", package = "RcppDeepState")
89
##' harness.list <- deepstate_pkg_create(path)
910
##' print(harness.list)
1011
##' @import RcppArmadillo
1112
##' @return A character vector of TestHarness files that are generated
1213
##' @export
13-
deepstate_pkg_create<-function(package_path, verbose=getOption("verbose")){
14-
package_path <-normalizePath(package_path, mustWork=TRUE)
15-
package_path <- sub("/$","",package_path)
16-
inst_path <- file.path(package_path, "inst")
17-
test_path <- file.path(inst_path,"testfiles")
14+
deepstate_pkg_create <- function(package_path, verbose=getOption("verbose")) {
15+
package_path <- normalizePath(package_path, mustWork=TRUE)
16+
package_path <- sub("/$", "", package_path)
17+
test_path <- file.path(package_path, "inst", "testfiles")
1818

1919
# Test directory structure initialization
20-
unlink(test_path, recursive = TRUE)
21-
if(!dir.exists(inst_path)) {
22-
dir.create(inst_path)
20+
if (!dir.exists(test_path)) {
21+
dir.create(test_path, showWarnings=FALSE, recursive=TRUE)
22+
}else {
23+
# delete all the existing files except for the harness
24+
for (function_name in list.files(test_path)) {
25+
fun_path <- file.path(test_path, function_name)
26+
filename <- paste0(function_name, "_DeepState_TestHarness", ".cpp")
27+
harness_path <- file.path(fun_path, filename)
28+
29+
# delete all the files and directories except the harness file
30+
if (file.exists(harness_path)) {
31+
delete_content <- setdiff(list.files(fun_path), filename)
32+
unlink(file.path(fun_path, delete_content), recursive=TRUE)
33+
}
34+
}
2335
}
24-
dir.create(test_path,showWarnings = FALSE)
2536

26-
if(!file.exists(file.path(package_path,"src/*.so"))) {
27-
# ensure that the debugging symbols are embedded in the resulting shared object
37+
if (!file.exists(file.path(package_path, "src/*.so"))) {
38+
# ensure that the debugging symbols are embedded in the shared object
2839
makevars_file <- file.path(package_path, "src", "Makevars")
29-
if (dir.exists(file.path(package_path, "src"))){
40+
if (dir.exists(file.path(package_path, "src"))) {
3041
makevars_content <- "PKG_CXXFLAGS += -g "
3142
write(makevars_content, makevars_file, append=FALSE)
3243
}
3344

34-
system(paste0("R CMD INSTALL ",package_path),intern = FALSE, ignore.stdout=!verbose, ignore.stderr=!verbose)
45+
system(paste0("R CMD INSTALL ", package_path), intern=FALSE,
46+
ignore.stdout=!verbose, ignore.stderr=!verbose)
3547
unlink(makevars_file, recursive = FALSE)
3648
}
3749

38-
if(!(file.exists("~/.RcppDeepState/deepstate-master/build/libdeepstate32.a") &&
39-
file.exists("~/.RcppDeepState/deepstate-master/build/libdeepstate.a")))
40-
{
50+
# download and build deepstate
51+
libdeepstate32 <- "~/.RcppDeepState/deepstate-master/build/libdeepstate32.a"
52+
libdeepstate <- "~/.RcppDeepState/deepstate-master/build/libdeepstate.a"
53+
if (!(file.exists(libdeepstate32) && file.exists(libdeepstate))) {
4154
deepstate_make_run(verbose)
4255
}
56+
4357
Rcpp::compileAttributes(package_path)
4458
harness <- list()
4559
failed.harness <- list()
4660

4761
functions.list <- deepstate_get_function_body(package_path)
48-
if(!is.null(functions.list) && length(functions.list) > 1){
49-
functions.list$argument.type<-gsub("Rcpp::","",functions.list$argument.type)
62+
if (!is.null(functions.list) && length(functions.list) > 1) {
63+
functions.list$argument.type <- gsub("Rcpp::", "",
64+
functions.list$argument.type)
5065
match_count <- 0
5166
mismatch_count <- 0
5267

5368
fun_names <- unique(functions.list$funName)
54-
for(function_name.i in fun_names) {
55-
functions.rows <- functions.list [functions.list$funName == function_name.i,]
56-
params <- c(functions.rows$argument.type)
57-
filepath <-deepstate_fun_create(package_path,function_name.i)
58-
filename <- paste0(function_name.i,"_DeepState_TestHarness",".cpp")
69+
for (function_name in fun_names) {
70+
fun_path <- file.path(test_path, function_name)
71+
filename <- paste0(function_name, "_DeepState_TestHarness", ".cpp")
72+
harness_path <- file.path(fun_path, filename)
5973

60-
if(!is.na(filepath) && basename(filepath) == filename ){
61-
match_count = match_count + 1
62-
harness <- c(harness,filename)
74+
functions.rows <- functions.list[functions.list$funName == function_name,]
75+
params <- c(functions.rows$argument.type)
76+
filepath <- deepstate_fun_create(package_path, function_name)
77+
78+
if (!is.na(filepath) && basename(filepath) == filename) {
79+
match_count <- match_count + 1
80+
harness <- c(harness, filename)
6381
}else {
64-
mismatch_count = mismatch_count + 1
65-
failed.harness <- c(failed.harness,function_name.i)
82+
mismatch_count <- mismatch_count + 1
83+
failed.harness <- c(failed.harness, function_name)
6684
}
6785

6886
}
6987

70-
if(match_count > 0 && match_count == length(fun_names)){
71-
message(sprintf("Testharness created for %d functions in the package\n",match_count))
88+
89+
# harness generated for all of the functions
90+
if (match_count > 0 && match_count == length(fun_names)) {
91+
message(paste0("Testharness created for ", match_count,
92+
" functions in the package\n"))
7293
return(as.character(harness))
7394
}
74-
else{
75-
if(mismatch_count < length(fun_names) && length(failed.harness) > 0 && match_count != 0){
76-
message(sprintf("Failed to create testharness for %d functions in the package - %s\n",mismatch_count,paste(failed.harness, collapse=", ")))
77-
message(sprintf("Testharness created for %d functions in the package\n",match_count))
78-
return(as.character(harness))
79-
}
95+
96+
# harness generated for some function
97+
if (mismatch_count < length(fun_names) && length(failed.harness) > 0
98+
&& match_count != 0) {
99+
failed_str <- paste(failed.harness, collapse=", ")
100+
message(paste0("Failed to create testharness for ", mismatch_count,
101+
" functions in the package - ", failed_str))
102+
103+
message(paste0("Testharness created for ", match_count,
104+
" functions in the package\n"))
105+
return(as.character(harness))
80106
}
81-
if(mismatch_count == length(fun_names)){
82-
stop("Testharnesses cannot be created for the package - datatypes fall out of specified list!!")
107+
108+
# harness not generated for any function
109+
if (mismatch_count == length(fun_names)) {
110+
stop("Testharnesses cannot be created for the package")
83111
return(as.character(failed.harness))
84112
}
113+
114+
}else {
115+
stop("No Rcpp function to test in the package")
85116
}
86-
else{
87-
stop("No Rcpp Functions to test in the package")
88-
}
89-
}
117+
}

0 commit comments

Comments
 (0)