Tests/r (#275)
* Added install R * Added devtools build * devtools build and test * Clean up rscript * Added line breaks * Added devtools('.') * Added testthat package * Added roxygen * Replaced rscript * Test live * Added environment variables to test * Fixed test * Removed * Fixed tests * makeClusters to makeCluster * Error handling to stop exit * Added params to setup function * Removed pool names * Get / Get Cluster List * Added utility R source * Fixed tests * Fixed remove error handling with combine test * Forgot \ lines
This commit is contained in:
Родитель
008b0ad46d
Коммит
4983fb120e
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/bash
|
||||||
|
sudo echo "deb http://cran.rstudio.com/bin/linux/ubuntu trusty/" | sudo tee -a /etc/apt/sources.list
|
||||||
|
|
||||||
|
gpg --keyserver keyserver.ubuntu.com --recv-key E084DAB9
|
||||||
|
gpg -a --export E084DAB9 | sudo apt-key add -
|
||||||
|
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y r-base r-base-dev libcurl4-openssl-dev
|
||||||
|
sudo apt-get install -y libssl-dev libxml2-dev libgdal-dev libproj-dev libgsl-dev
|
||||||
|
|
||||||
|
sudo R \
|
||||||
|
-e "Sys.setenv(BATCH_ACCOUNT_NAME = '$BATCH_ACCOUNT_NAME')" \
|
||||||
|
-e "Sys.setenv(BATCH_ACCOUNT_KEY = '$BATCH_ACCOUNT_KEY')" \
|
||||||
|
-e "Sys.setenv(BATCH_ACCOUNT_URL = '$BATCH_ACCOUNT_URL')" \
|
||||||
|
-e "Sys.setenv(STORAGE_ACCOUNT_NAME = '$STORAGE_ACCOUNT_NAME')" \
|
||||||
|
-e "Sys.setenv(STORAGE_ACCOUNT_KEY = '$STORAGE_ACCOUNT_KEY')" \
|
||||||
|
-e "getwd();" \
|
||||||
|
-e "install.packages(c('devtools', 'remotes', 'testthat', 'roxygen2'));" \
|
||||||
|
-e "devtools::install();" \
|
||||||
|
-e "devtools::build();" \
|
||||||
|
-e "res <- devtools::test(reporter='summary');" \
|
||||||
|
-e "df <- as.data.frame(res);" \
|
||||||
|
-e "if(sum(df[['failed']]) > 0 || any(df[['error']])) { q(status=1) }"
|
|
@ -1,38 +1,27 @@
|
||||||
# Run this test for users to make sure the async cluster creation features
|
context("Cluster Management Test")
|
||||||
# of doAzureParallel are still working
|
test_that("Get Cluster List / Get Cluster test", {
|
||||||
context("async cluster scenario test")
|
|
||||||
test_that("Async cluster scenario test", {
|
|
||||||
testthat::skip("Live test")
|
|
||||||
testthat::skip_on_travis()
|
testthat::skip_on_travis()
|
||||||
credentialsFileName <- "credentials.json"
|
source("utility.R")
|
||||||
clusterFileName <- "cluster.json"
|
|
||||||
|
|
||||||
doAzureParallel::generateCredentialsConfig(credentialsFileName)
|
settings <- getSettings()
|
||||||
doAzureParallel::generateClusterConfig(clusterFileName)
|
|
||||||
|
|
||||||
# set your credentials
|
# set your credentials
|
||||||
doAzureParallel::setCredentials(credentialsFileName)
|
doAzureParallel::setCredentials(settings$credentials)
|
||||||
|
|
||||||
cluster <-
|
cluster <-
|
||||||
doAzureParallel::makeCluster(clusterSetting = clusterFileName, wait = FALSE)
|
doAzureParallel::makeCluster(settings$clusterConfig, wait = FALSE)
|
||||||
|
|
||||||
cluster <- getCluster(cluster$poolId)
|
cluster <- getCluster(cluster$poolId)
|
||||||
getClusterList()
|
clusterList <- getClusterList()
|
||||||
filter <- filter <- list()
|
filter <- list()
|
||||||
filter$state <- c("active", "deleting")
|
filter$state <- c("active", "deleting")
|
||||||
getClusterList(filter)
|
|
||||||
doAzureParallel::registerDoAzureParallel(cluster)
|
|
||||||
|
|
||||||
'%dopar%' <- foreach::'%dopar%'
|
testthat::expect_true('test-pool' %in% clusterList$Id)
|
||||||
res <-
|
|
||||||
foreach::foreach(i = 1:4) %dopar% {
|
|
||||||
mean(1:3)
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
clusterList <- getClusterList(filter)
|
||||||
|
|
||||||
testthat::expect_equal(length(res), 4)
|
for (i in 1:length(clusterList$State)) {
|
||||||
testthat::expect_equal(res, list(2, 2, 2, 2))
|
testthat::expect_true(clusterList$State[i] == 'active' ||
|
||||||
|
clusterList$State[i] == 'deleting')
|
||||||
stopCluster(cluster)
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
context("error handling test")
|
context("error handling test")
|
||||||
test_that("Remove error handling with combine test", {
|
test_that("Remove error handling with combine test", {
|
||||||
testthat::skip("Live test")
|
|
||||||
testthat::skip_on_travis()
|
testthat::skip_on_travis()
|
||||||
credentialsFileName <- "credentials.json"
|
source("utility.R")
|
||||||
clusterFileName <- "cluster.json"
|
settings <- getSettings()
|
||||||
|
|
||||||
doAzureParallel::generateCredentialsConfig(credentialsFileName)
|
|
||||||
doAzureParallel::generateClusterConfig(clusterFileName)
|
|
||||||
|
|
||||||
# set your credentials
|
# set your credentials
|
||||||
doAzureParallel::setCredentials(credentialsFileName)
|
doAzureParallel::setCredentials(settings$credentials)
|
||||||
cluster <- doAzureParallel::makeCluster(clusterFileName)
|
|
||||||
|
cluster <- doAzureParallel::makeCluster(settings$clusterConfig)
|
||||||
doAzureParallel::registerDoAzureParallel(cluster)
|
doAzureParallel::registerDoAzureParallel(cluster)
|
||||||
|
|
||||||
'%dopar%' <- foreach::'%dopar%'
|
'%dopar%' <- foreach::'%dopar%'
|
||||||
|
@ -23,28 +20,27 @@ test_that("Remove error handling with combine test", {
|
||||||
sqrt(i)
|
sqrt(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res <- unname(res)
|
||||||
|
|
||||||
testthat::expect_equal(length(res), 2)
|
testthat::expect_equal(length(res), 3)
|
||||||
|
testthat::expect_equal(res, c(sqrt(1), sqrt(2), sqrt(5)))
|
||||||
})
|
})
|
||||||
|
|
||||||
test_that("Remove error handling test", {
|
test_that("Remove error handling test", {
|
||||||
testthat::skip("Live test")
|
|
||||||
testthat::skip_on_travis()
|
testthat::skip_on_travis()
|
||||||
credentialsFileName <- "credentials.json"
|
source("utility.R")
|
||||||
clusterFileName <- "cluster.json"
|
settings <- getSettings()
|
||||||
|
|
||||||
doAzureParallel::generateCredentialsConfig(credentialsFileName)
|
|
||||||
doAzureParallel::generateClusterConfig(clusterFileName)
|
|
||||||
|
|
||||||
# set your credentials
|
# set your credentials
|
||||||
doAzureParallel::setCredentials(credentialsFileName)
|
doAzureParallel::setCredentials(settings$credentials)
|
||||||
cluster <- doAzureParallel::makeCluster(clusterFileName)
|
|
||||||
|
settings$clusterConfig$poolId <- "error-handling-test"
|
||||||
|
cluster <- doAzureParallel::makeCluster(settings$clusterConfig)
|
||||||
doAzureParallel::registerDoAzureParallel(cluster)
|
doAzureParallel::registerDoAzureParallel(cluster)
|
||||||
|
|
||||||
'%dopar%' <- foreach::'%dopar%'
|
'%dopar%' <- foreach::'%dopar%'
|
||||||
res <-
|
res <-
|
||||||
foreach::foreach(i = 1:4, .errorhandling = "remove") %dopar% {
|
foreach::foreach(i = 1:5, .errorhandling = "remove") %dopar% {
|
||||||
if (i == 3 || i == 4) {
|
if (i == 3 || i == 4) {
|
||||||
randomObject
|
randomObject
|
||||||
}
|
}
|
||||||
|
@ -52,23 +48,21 @@ test_that("Remove error handling test", {
|
||||||
i
|
i
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res <- unname(res)
|
||||||
|
|
||||||
testthat::expect_equal(length(res), 2)
|
testthat::expect_equal(res, list(1, 2, 5))
|
||||||
})
|
})
|
||||||
|
|
||||||
test_that("Pass error handling test", {
|
test_that("Pass error handling test", {
|
||||||
testthat::skip("Live test")
|
|
||||||
testthat::skip_on_travis()
|
testthat::skip_on_travis()
|
||||||
credentialsFileName <- "credentials.json"
|
source("utility.R")
|
||||||
clusterFileName <- "cluster.json"
|
settings <- getSettings()
|
||||||
|
|
||||||
doAzureParallel::generateCredentialsConfig(credentialsFileName)
|
|
||||||
doAzureParallel::generateClusterConfig(clusterFileName)
|
|
||||||
|
|
||||||
# set your credentials
|
# set your credentials
|
||||||
doAzureParallel::setCredentials(credentialsFileName)
|
doAzureParallel::setCredentials(settings$credentials)
|
||||||
cluster <- doAzureParallel::makeCluster(clusterFileName)
|
|
||||||
|
settings$clusterConfig$poolId <- "error-handling-test"
|
||||||
|
cluster <- doAzureParallel::makeCluster(settings$clusterConfig)
|
||||||
doAzureParallel::registerDoAzureParallel(cluster)
|
doAzureParallel::registerDoAzureParallel(cluster)
|
||||||
|
|
||||||
'%dopar%' <- foreach::'%dopar%'
|
'%dopar%' <- foreach::'%dopar%'
|
||||||
|
@ -88,17 +82,16 @@ test_that("Pass error handling test", {
|
||||||
})
|
})
|
||||||
|
|
||||||
test_that("Stop error handling test", {
|
test_that("Stop error handling test", {
|
||||||
testthat::skip("Live test")
|
testthat::skip("Manual Test")
|
||||||
testthat::skip_on_travis()
|
testthat::skip_on_travis()
|
||||||
credentialsFileName <- "credentials.json"
|
source("utility.R")
|
||||||
clusterFileName <- "cluster.json"
|
settings <- getSettings()
|
||||||
|
|
||||||
doAzureParallel::generateCredentialsConfig(credentialsFileName)
|
|
||||||
doAzureParallel::generateClusterConfig(clusterFileName)
|
|
||||||
|
|
||||||
# set your credentials
|
# set your credentials
|
||||||
doAzureParallel::setCredentials(credentialsFileName)
|
doAzureParallel::setCredentials(settings$credentials)
|
||||||
cluster <- doAzureParallel::makeCluster(clusterFileName)
|
|
||||||
|
settings$clusterConfig$poolId <- "error-handling-test"
|
||||||
|
cluster <- doAzureParallel::makeCluster(settings$clusterConfig)
|
||||||
doAzureParallel::registerDoAzureParallel(cluster)
|
doAzureParallel::registerDoAzureParallel(cluster)
|
||||||
|
|
||||||
'%dopar%' <- foreach::'%dopar%'
|
'%dopar%' <- foreach::'%dopar%'
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
context("foreach options test")
|
||||||
|
test_that("chunksize", {
|
||||||
|
testthat::skip_on_travis()
|
||||||
|
source("utility.R")
|
||||||
|
settings <- getSettings()
|
||||||
|
|
||||||
|
# set your credentials
|
||||||
|
doAzureParallel::setCredentials(settings$credentials)
|
||||||
|
|
||||||
|
cluster <- doAzureParallel::makeCluster(settings$clusterConfig)
|
||||||
|
doAzureParallel::registerDoAzureParallel(cluster)
|
||||||
|
|
||||||
|
'%dopar%' <- foreach::'%dopar%'
|
||||||
|
res <-
|
||||||
|
foreach::foreach(i = 1:10,
|
||||||
|
.options.azure = list(chunkSize = 3)) %dopar% {
|
||||||
|
i
|
||||||
|
}
|
||||||
|
|
||||||
|
testthat::expect_equal(length(res),
|
||||||
|
10)
|
||||||
|
|
||||||
|
for (index in 1:10) {
|
||||||
|
testthat::expect_equal(res[[index]],
|
||||||
|
index)
|
||||||
|
}
|
||||||
|
|
||||||
|
res <-
|
||||||
|
foreach::foreach(i = 1:2,
|
||||||
|
.options.azure = list(chunkSize = 2)) %dopar% {
|
||||||
|
i
|
||||||
|
}
|
||||||
|
|
||||||
|
testthat::expect_equal(length(res),
|
||||||
|
2)
|
||||||
|
|
||||||
|
for (index in 1:2) {
|
||||||
|
testthat::expect_equal(res[[index]],
|
||||||
|
index)
|
||||||
|
}
|
||||||
|
})
|
|
@ -1,18 +1,16 @@
|
||||||
|
context("Integration Test")
|
||||||
|
|
||||||
# Run this test for users to make sure the core features
|
# Run this test for users to make sure the core features
|
||||||
# of doAzureParallel are still working
|
# of doAzureParallel are still working
|
||||||
context("live scenario test")
|
test_that("simple foreach 1 to 4", {
|
||||||
test_that("Basic scenario test", {
|
|
||||||
testthat::skip("Live test")
|
|
||||||
testthat::skip_on_travis()
|
testthat::skip_on_travis()
|
||||||
credentialsFileName <- "credentials.json"
|
source("utility.R")
|
||||||
clusterFileName <- "cluster.json"
|
settings <- getSettings()
|
||||||
|
|
||||||
doAzureParallel::generateCredentialsConfig(credentialsFileName)
|
|
||||||
doAzureParallel::generateClusterConfig(clusterFileName)
|
|
||||||
|
|
||||||
# set your credentials
|
# set your credentials
|
||||||
doAzureParallel::setCredentials(credentialsFileName)
|
doAzureParallel::setCredentials(settings$credentials)
|
||||||
cluster <- doAzureParallel::makeCluster(clusterFileName)
|
|
||||||
|
cluster <- doAzureParallel::makeCluster(settings$clusterConfig)
|
||||||
doAzureParallel::registerDoAzureParallel(cluster)
|
doAzureParallel::registerDoAzureParallel(cluster)
|
||||||
|
|
||||||
'%dopar%' <- foreach::'%dopar%'
|
'%dopar%' <- foreach::'%dopar%'
|
||||||
|
@ -21,37 +19,8 @@ test_that("Basic scenario test", {
|
||||||
i
|
i
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res <- unname(res)
|
||||||
|
|
||||||
testthat::expect_equal(length(res), 4)
|
testthat::expect_equal(length(res), 4)
|
||||||
testthat::expect_equal(res, list(2, 2, 2, 2))
|
testthat::expect_equal(res, list(1, 2, 3, 4))
|
||||||
})
|
|
||||||
|
|
||||||
test_that("Chunksize Test", {
|
|
||||||
testthat::skip("Live test")
|
|
||||||
testthat::skip_on_travis()
|
|
||||||
credentialsFileName <- "credentials.json"
|
|
||||||
clusterFileName <- "cluster.json"
|
|
||||||
|
|
||||||
doAzureParallel::generateCredentialsConfig(credentialsFileName)
|
|
||||||
doAzureParallel::generateClusterConfig(clusterFileName)
|
|
||||||
|
|
||||||
doAzureParallel::setCredentials(credentialsFileName)
|
|
||||||
cluster <- doAzureParallel::makeCluster(clusterFileName)
|
|
||||||
doAzureParallel::registerDoAzureParallel(cluster)
|
|
||||||
|
|
||||||
'%dopar%' <- foreach::'%dopar%'
|
|
||||||
res <-
|
|
||||||
foreach::foreach(i = 1:10,
|
|
||||||
.options.azure = list(chunkSize = 3)) %dopar% {
|
|
||||||
i
|
|
||||||
}
|
|
||||||
|
|
||||||
testthat::expect_equal(length(res),
|
|
||||||
10)
|
|
||||||
|
|
||||||
for (i in 1:10) {
|
|
||||||
testthat::expect_equal(res[[i]],
|
|
||||||
i)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
# of doAzureParallel are still working
|
# of doAzureParallel are still working
|
||||||
context("merge job result locally test")
|
context("merge job result locally test")
|
||||||
test_that("merge job result locally test", {
|
test_that("merge job result locally test", {
|
||||||
testthat::skip("merge job result locally test")
|
|
||||||
testthat::skip_on_travis()
|
testthat::skip_on_travis()
|
||||||
credentialsFileName <- "credentials.json"
|
testthat::skip("Skipping merge job locally")
|
||||||
clusterFileName <- "cluster.json"
|
source("utility.R")
|
||||||
|
settings <- gettingSettings()
|
||||||
|
settings <- getSettings()
|
||||||
|
|
||||||
doAzureParallel::generateCredentialsConfig(credentialsFileName)
|
# set your credentials
|
||||||
doAzureParallel::generateClusterConfig(clusterFileName)
|
doAzureParallel::setCredentials(settings$credentials)
|
||||||
|
|
||||||
doAzureParallel::setCredentials(credentialsFileName)
|
cluster <- doAzureParallel::makeCluster(settings$clusterConfig)
|
||||||
cluster <- doAzureParallel::makeCluster(clusterFileName)
|
|
||||||
doAzureParallel::registerDoAzureParallel(cluster)
|
doAzureParallel::registerDoAzureParallel(cluster)
|
||||||
|
|
||||||
setChunkSize(2)
|
setChunkSize(2)
|
||||||
|
@ -37,6 +37,4 @@ test_that("merge job result locally test", {
|
||||||
testthat::expect_equal(res[[i]],
|
testthat::expect_equal(res[[i]],
|
||||||
i)
|
i)
|
||||||
}
|
}
|
||||||
|
|
||||||
stopCluster(cluster)
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -43,7 +43,6 @@ test_that("Long Running Job Test", {
|
||||||
|
|
||||||
# get job result
|
# get job result
|
||||||
jobResult <- doAzureParallel::getJobResult(jobId)
|
jobResult <- doAzureParallel::getJobResult(jobId)
|
||||||
doAzureParallel::stopCluster(cluster)
|
|
||||||
|
|
||||||
# verify the job result is correct
|
# verify the job result is correct
|
||||||
testthat::expect_equal(length(jobResult),
|
testthat::expect_equal(length(jobResult),
|
||||||
|
|
|
@ -113,6 +113,4 @@ test_that("pool multiple bioconductor package install Test", {
|
||||||
list(
|
list(
|
||||||
c(TRUE, TRUE, TRUE),
|
c(TRUE, TRUE, TRUE),
|
||||||
c(TRUE, TRUE, TRUE)))
|
c(TRUE, TRUE, TRUE)))
|
||||||
|
|
||||||
doAzureParallel::stopCluster(cluster)
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -116,6 +116,4 @@ test_that("pool multiple github package install Test", {
|
||||||
list(c(TRUE, TRUE, TRUE),
|
list(c(TRUE, TRUE, TRUE),
|
||||||
c(TRUE, TRUE, TRUE),
|
c(TRUE, TRUE, TRUE),
|
||||||
c(TRUE, TRUE, TRUE)))
|
c(TRUE, TRUE, TRUE)))
|
||||||
|
|
||||||
doAzureParallel::stopCluster(cluster)
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
context("package installation")
|
context("Package Command Line Tests")
|
||||||
test_that("successfully create cran job package command line", {
|
test_that("successfully create cran job package command line", {
|
||||||
jobInstallation <-
|
jobInstallation <-
|
||||||
getJobPackageInstallationCommand("cran", c("hts", "lubridate", "tidyr", "dplyr"))
|
getJobPackageInstallationCommand("cran", c("hts", "lubridate", "tidyr", "dplyr"))
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
|
context("Unit Tests")
|
||||||
if (requireNamespace("nycflights13", quietly = TRUE)) {
|
if (requireNamespace("nycflights13", quietly = TRUE)) {
|
||||||
context("hasDataSet function")
|
test_that("hasDataSet Test - Contains Data", {
|
||||||
|
|
||||||
test_that("Arguments contains data set", {
|
|
||||||
byCarrierList <- split(nycflights13::flights, nycflights13::flights$carrier)
|
byCarrierList <- split(nycflights13::flights, nycflights13::flights$carrier)
|
||||||
it <- iterators::iter(byCarrierList)
|
it <- iterators::iter(byCarrierList)
|
||||||
argsList <- as.list(it)
|
argsList <- as.list(it)
|
||||||
|
@ -11,7 +10,7 @@ if (requireNamespace("nycflights13", quietly = TRUE)) {
|
||||||
expect_equal(hasDataSet, TRUE)
|
expect_equal(hasDataSet, TRUE)
|
||||||
})
|
})
|
||||||
|
|
||||||
test_that("Arguments does not contain data set", {
|
test_that("hasDataSet Test - Contains no Data Set", {
|
||||||
args <- seq(1:10)
|
args <- seq(1:10)
|
||||||
it <- iterators::iter(args)
|
it <- iterators::iter(args)
|
||||||
argsList <- as.list(it)
|
argsList <- as.list(it)
|
||||||
|
@ -20,5 +19,4 @@ if (requireNamespace("nycflights13", quietly = TRUE)) {
|
||||||
|
|
||||||
expect_equal(hasDataSet, FALSE)
|
expect_equal(hasDataSet, FALSE)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
getSettings <- function(dedicatedMin = 2,
|
||||||
|
dedicatedMax = 2,
|
||||||
|
lowPriorityMin = 2,
|
||||||
|
lowPriorityMax = 2,
|
||||||
|
poolName = "test-pool"){
|
||||||
|
list(
|
||||||
|
credentials = list(
|
||||||
|
"sharedKey" = list(
|
||||||
|
"batchAccount" = list(
|
||||||
|
"name" = Sys.getenv("BATCH_ACCOUNT_NAME"),
|
||||||
|
"key" = Sys.getenv("BATCH_ACCOUNT_KEY"),
|
||||||
|
"url" = Sys.getenv("BATCH_ACCOUNT_URL")
|
||||||
|
),
|
||||||
|
"storageAccount" = list(
|
||||||
|
"name" = Sys.getenv("STORAGE_ACCOUNT_NAME"),
|
||||||
|
"key" = Sys.getenv("STORAGE_ACCOUNT_KEY"),
|
||||||
|
"endpointSuffix" = "core.windows.net"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"githubAuthenticationToken" = "",
|
||||||
|
"dockerAuthentication" = list("username" = "",
|
||||||
|
"password" = "",
|
||||||
|
"registry" = "")
|
||||||
|
),
|
||||||
|
clusterConfig = list(
|
||||||
|
"name" = poolName,
|
||||||
|
"vmSize" = "Standard_D2_v2",
|
||||||
|
"maxTasksPerNode" = 1,
|
||||||
|
"poolSize" = list(
|
||||||
|
"dedicatedNodes" = list(
|
||||||
|
"min" = dedicatedMin,
|
||||||
|
"max" = dedicatedMax
|
||||||
|
),
|
||||||
|
"lowPriorityNodes" = list(
|
||||||
|
"min" = lowPriorityMin,
|
||||||
|
"max" = lowPriorityMax
|
||||||
|
),
|
||||||
|
"autoscaleFormula" = "QUEUE"
|
||||||
|
),
|
||||||
|
"containerImage" = "rocker/tidyverse:latest",
|
||||||
|
"rPackages" = list(
|
||||||
|
"cran" = list(),
|
||||||
|
"github" = list(),
|
||||||
|
"bioconductor" = list()
|
||||||
|
),
|
||||||
|
"commandLine" = list()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче