diff --git a/.CI-setup.sh b/.CI-setup.sh new file mode 100644 index 0000000000000000000000000000000000000000..b14c0ced4c5e66ef22754ea248b85acbd4d49ba0 --- /dev/null +++ b/.CI-setup.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +### Setup singularity ### +# adapted from: https://sylabs.io/guides/3.0/user-guide/installation.html +# install dependencies +apt-get update +apt-get install -y \ + build-essential \ + libssl-dev \ + uuid-dev \ + libgpgme11-dev \ + squashfs-tools \ + libseccomp-dev \ + pkg-config \ + wget +# yum update -y && \ +# yum groupinstall -y 'Development Tools' && \ +# yum install -y \ +# openssl-devel \ +# libuuid-devel \ +# libseccomp-devel \ +# wget \ +# squashfs-tools + + + +# install go +export GOVERSION=1.15.6 OS=linux ARCH=amd64 +wget https://dl.google.com/go/go$GOVERSION.$OS-$ARCH.tar.gz +tar -C /usr/local -xzvf go$GOVERSION.$OS-$ARCH.tar.gz +rm go$GOVERSION.$OS-$ARCH.tar.gz + +# install singularity +export VERSION=3.9.1 +mkdir -p $GOPATH/src/github.com/sylabs +cd $GOPATH/src/github.com/sylabs +wget https://github.com/sylabs/singularity/releases/download/v${VERSION}/singularity-ce-${VERSION}.tar.gz +tar -xzf singularity-ce-${VERSION}.tar.gz +cd ./singularity +./mconfig +make -C ./builddir +make -C ./builddir install \ No newline at end of file diff --git a/.Rbuildignore b/.Rbuildignore index 509fef60bd8d852f15534cf4a3bb08b13f3ca015..ba2a974ee7d689362cc20de5de6e7a3fb0fc70b7 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -10,3 +10,4 @@ ^doc$ ^Meta$ ^data-raw$ +^ci$ \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ac098d20b56cab50641ae82c2a6ad2f9eccb135a..731820c2747987e1de002035d443b4d5538d33ba 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,13 @@ -image: rocker/tidyverse +# helpful Links: +# https://docs.gitlab.com/ee/ci/variables/predefined_variables.html +# https://www.youtube.com/watch?v=7I6tHw68DMQ + +stages: + - test + - test-benchmarks test: + image: $CI_REGISTRY_IMAGE stage: test tags: - envinf2 @@ -8,16 +15,13 @@ test: R_LIBS_USER: "$CI_PROJECT_DIR/ci/lib/" RETICULATE_MINICONDA_PATH: "/root/.local/share/r-miniconda/" #default path RETICULATE_PYTHON_ENV: "/root/.local/share/r-miniconda/envs/r-reticulate/" - # RETICULATE_PYTHON: "$CI_PROJECT_DIR/ci/r-miniconda/envs/r-reticulate/bin/python3" script: - if [ ! -d "$R_LIBS_USER" ]; then mkdir -p "$R_LIBS_USER"; fi - R -e 'withr::with_libpaths(new = Sys.getenv("R_LIBS_USER"), devtools::install_deps(dependencies = T))' # checks if the packages from the Imports, Suggests, LinkinTo field # are already installed in the cache - R -e '.libPaths(new = Sys.getenv("R_LIBS_USER"))' - # python dependencies - - if [ ! -d "$RETICULATE_MINICONDA_PATH" ]; then R -e 'reticulate::install_miniconda()'; fi - - R -e 'if(tryCatch(reticulate::import("vtk"), error = function(e) return(TRUE))) reticulate::py_install("vtk")' + # Build and Check r2ogs6 - R CMD build . --no-build-vignettes --no-manual - R CMD check $(ls -1t *.tar.gz | head -n 1) --no-build-vignettes --no-manual cache: @@ -25,8 +29,79 @@ test: untracked: true paths: - "$R_LIBS_USER" - - "$RETICULATE_MINICONDA_PATH" - - "$RETICULATE_PYTHON_ENV" - # script will only run then attempting to merge/push to master - only: - - merge_requests \ No newline at end of file + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event" || $CI_PIPELINE_SOURCE == "web"' + - if: '$CI_COMMIT_BRANCH == "master"' +benchmark:ref: + stage: test-benchmarks + tags: + - envinf1 + image: "$CI_REGISTRY_IMAGE" + variables: + R_LIBS_USER: "$CI_PROJECT_DIR/ci/lib/" + # change this as needed + OGS_VERSION: "6.4.1" + rules: + - if: '$CI_PIPELINE_SOURCE == "web"' + when: on_success + script: + - if [ ! -d "$R_LIBS_USER" ]; then mkdir -p "$R_LIBS_USER"; fi + - R -e 'withr::with_libpaths(new = Sys.getenv("R_LIBS_USER"), devtools::install_deps(dependencies = T))' + - R -e '.libPaths(new = Sys.getenv("R_LIBS_USER"))' + - Rscript ./ci/test_bm_script.R "$OGS_VERSION" "ref" + cache: + key: "$CI_COMMIT_REF_SLUG" + untracked: true + paths: + - "$R_LIBS_USER" + artifacts: + name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME" + expire_in: 4 hrs + paths: + - ref_exit.rda + - out_ref/logfiles/ + +benchmark:r2ogs6: + stage: test-benchmarks + tags: + - envinf1 + image: "$CI_REGISTRY_IMAGE" + variables: + R_LIBS_USER: "$CI_PROJECT_DIR/ci/lib/" + # change this as needed + OGS_VERSION: "6.4.1" + rules: + - if: '$CI_PIPELINE_SOURCE == "web"' + when: on_success + script: + - if [ ! -d "$R_LIBS_USER" ]; then mkdir -p "$R_LIBS_USER"; fi + - R -e 'withr::with_libpaths(new = Sys.getenv("R_LIBS_USER"), devtools::install_deps(dependencies = T))' + - R -e '.libPaths(new = Sys.getenv("R_LIBS_USER"))' + - Rscript ./ci/test_bm_script.R "$OGS_VERSION" "r2ogs6" + cache: + key: "$CI_COMMIT_REF_SLUG" + untracked: true + paths: + - "$R_LIBS_USER" + artifacts: + name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME" + expire_in: 4 hrs + paths: + - test_exit.rda + - out_test/logfiles/ + +compare-benchmarks: + needs: ["benchmark:ref", "benchmark:r2ogs6"] + stage: test-benchmarks + tags: + - envinf1 + image: "$CI_REGISTRY_IMAGE" + rules: + - if: '$CI_PIPELINE_SOURCE == "web"' + when: on_success + dependencies: + - benchmark:ref + - benchmark:r2ogs6 + script: + - Rscript ./ci/test_bm_script.R "$OGS_VERSION" "test" + diff --git a/R/analyse_xml.R b/R/analyse_xml.R index 80b4eeaa9ecd82e42333e82296e947e4f857c361..333224923a1eeea8e8d246876b5f8dff57e3e3b4 100644 --- a/R/analyse_xml.R +++ b/R/analyse_xml.R @@ -271,11 +271,11 @@ get_required <- function(names, occurence_probabilities){ for(i in seq_len(length(names))) { if(occurence_probabilities[[i]] < 1) { - required[[names[[i]]]] <- FALSE + required[[paste0(names[[i]])]] <- FALSE }else{ - required[[names[[i]]]] <- TRUE + required[[paste0(names[[i]])]] <- TRUE } } - return(invisible(required)) + return(required) } diff --git a/ci/test_bm_script.R b/ci/test_bm_script.R new file mode 100644 index 0000000000000000000000000000000000000000..35a5df6678842c619d80377f4ae5c83e0563d5b0 --- /dev/null +++ b/ci/test_bm_script.R @@ -0,0 +1,146 @@ + +# git clone --depth 1 --branch 6.4.1 https://gitlab.opengeosys.org/ogs/ogs +# wget https://ogsstorage.blob.core.windows.net/binaries/ogs6/6.4.1/ogs-6.4.1-serial.sif + +# Setup ------------------------------------------------------------------- +if (commandArgs(trailingOnly=TRUE)[2] == "ref" | + commandArgs(trailingOnly=TRUE)[2 ]== "r2ogs6") { + + ogs_version <- commandArgs(trailingOnly=TRUE)[1] + + if (!dir.exists("/root/ogs")) { + system2( + command = c( + "git", + "clone", + "--depth", + "1", + "--branch", + ogs_version, + "https://gitlab.opengeosys.org/ogs/ogs.git/", + "/root/ogs" + ) + ) + } + if (!file.exists(paste0("/root/ogs-", ogs_version, "-serial.sif"))) { + system2( + command = c( + "wget", + "-nv", # no verbose + "-P", + "/root", + paste0("https://ogsstorage.blob.core.windows.net/binaries/ogs6/", + ogs_version, "/ogs-", ogs_version, "-serial.sif") + ) + ) + } + devtools::load_all(".") + library(dplyr) + + ogs_repo <- "/root/ogs/" + prjs <- r2ogs6:::get_benchmark_paths(paste0(ogs_repo, "ProcessLib")) + # prjs <- prjs[c(6, 45, 46, 47, 249, 250, 251, 252)] # for testing + + #### Exceptions ##### + # exclude some prj files + prjs <- prjs[-grep("\\.xml$", prjs)] + prjs <- prjs[-grep("TH2M/THM/slab/THM_1d_dirichlet.prj", prjs)] + prjs <- prjs[-grep("InvalidProjectFiles/", prjs)] + ##################### + + ogs6_container <- paste0("/root/ogs-", ogs_version, "-serial.sif") + + # include call with --app ogs flag for ogs < 6.4.1 + if (as.numeric(gsub("[.]", "", ogs_version)) <= 640) { + ogs6_command_str <- c("singularity", "exec", "--app", "ogs", + ogs6_container, "ogs") + } else { + ogs6_command_str <- c("singularity", "exec", ogs6_container, "ogs") + } + +} + +# reference run ----------------------------------------------------------- +if (commandArgs(trailingOnly=TRUE)[2] == "ref") { + + out_ref <- "-o /root/out_ref" + dir.create("/root/out_ref") + dir.create("/root/out_ref/logfiles/") + + ref_exit <- tibble(benchmark = character(), + ref = numeric()) + + for (prj in prjs) { + + print(paste0("Running benchmark ", prj)) + prj_path <- paste0(ogs_repo, "Tests/Data/", prj) + + log_ref <- paste0("> /root/out_ref/logfiles/", + sub(".prj",".txt", basename(prj))) + + out <- system2(command = ogs6_command_str, + args = c(prj_path, out_ref, log_ref)) + + ref_exit <- add_row(ref_exit, + benchmark = prj, + ref = out) + } + + save(ref_exit, file = "ref_exit.rda") + dir.create("out_ref") + file.copy("/root/out_ref/logfiles", to = "out_ref", recursive = TRUE) +} + +# test run with r2ogs6 ---------------------------------------------------- +if (commandArgs(trailingOnly=TRUE)[2] == "r2ogs6") { + + test_exit <- tibble(benchmark = character(), + test = numeric()) + out_test <- "/root/out_test" + dir.create(out_test) + for (prj in prjs) { + print(paste0("Attempting to run benchmark ", prj)) + prj_path <- paste0(ogs_repo, "Tests/Data/", prj) + out <- tryCatch({ + r2ogs6:::run_benchmark( + prj_path = prj_path, + ogs6_bin_path = ogs6_container, + sim_path = out_test + ) + }, + error = function(e) { + message("\nrun_benchmark() failed!\nOriginal error message:") + message(e) + }) + + test_exit <- add_row(test_exit, + benchmark = prj, + test = out) + } + test_exit$test[which(is.na(test_exit$test))] <- 99 + save(test_exit, file = "test_exit.rda") + + dir.create("out_test") + file.copy("/root/out_test/logfiles", to = "out_test", recursive = TRUE) +} + +if (commandArgs(trailingOnly=TRUE)[2] == "test") { + + install.packages("dplyr") + load("ref_exit.rda") + load("test_exit.rda") + test_exit <- dplyr::full_join(ref_exit, test_exit, by = "benchmark") + + print(test_exit, n = nrow(test_exit)) + + # benchmarks that passed with & without r2ogs6 + r2ogs6_passed <- test_exit$test[which(test_exit$ref == 0)] == 0 + + if(!all(r2ogs6_passed)) { + cat(paste0(test_exit$benchmark[!r2ogs6_passed], + collapse = "\n")) + stop("Exit codes for r2ogs6 were nonzero for above benchmarks!") + } +} + +