diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..e873f1a --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,34 @@ +name: test + +on: + pull_request: + push: + branches: ["main"] + +jobs: + test: + name: Integration tests + runs-on: ubuntu-latest + + steps: + - name: Check out the repository + uses: actions/checkout@v4 + + - name: Build container image + run: docker build -t nexus_allowlist:latest . + + - name: Start service + run: docker compose up -d + + - name: Wait for Nexus to start + run: sleep 120 + + - name: Show nexus allowlist container logs + run: docker compose logs allowlist + + - name: Show nexus container logs + run: docker compose logs nexus + + - name: Run tests + working-directory: integration_tests + run: ./test.sh diff --git a/allowlists/cran.allowlist b/allowlists/cran.allowlist index 904fe72..2d92333 100644 --- a/allowlists/cran.allowlist +++ b/allowlists/cran.allowlist @@ -1,2 +1,3 @@ cli data.table +remotes diff --git a/docker-compose.yaml b/docker-compose.yaml index 3dccb1b..731c141 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,5 +1,4 @@ --- -version: "3" services: nexus: container_name: nexus @@ -7,7 +6,7 @@ services: volumes: - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro - - ./nexus-data:/nexus-data + - nexus-data:/nexus-data restart: always allowlist: container_name: allowlist @@ -21,7 +20,7 @@ services: # ENTR_FALLBACK: "yes" volumes: - ./allowlists:/allowlists - - ./nexus-data:/nexus-data + - nexus-data:/nexus-data restart: always reverse-proxy: container_name: reverse-proxy @@ -30,3 +29,5 @@ services: - "8080:80" volumes: - ./Caddyfile:/etc/caddy/Caddyfile +volumes: + nexus-data: diff --git a/integration_tests/Dockerfile b/integration_tests/Dockerfile new file mode 100644 index 0000000..69190bd --- /dev/null +++ b/integration_tests/Dockerfile @@ -0,0 +1,6 @@ +FROM bats/bats + +RUN apk add --no-cache --update python3 py3-pip R +RUN mkdir -p /root/.config/pip +COPY pip.conf /root/.config/pip/pip.conf +COPY Rprofile /root/.Rprofile diff --git a/integration_tests/Rprofile b/integration_tests/Rprofile new file mode 100644 index 0000000..8ac4dd2 --- /dev/null +++ b/integration_tests/Rprofile @@ -0,0 +1,9 @@ +.First <- function(){ + .libPaths("/root/rpackages") +} + +local({ + r <- getOption("repos") + r["CRAN"] <- "http://localhost:8080/repository/cran-proxy" + options(repos=r) +}) diff --git a/integration_tests/pip.conf b/integration_tests/pip.conf new file mode 100644 index 0000000..813fa8c --- /dev/null +++ b/integration_tests/pip.conf @@ -0,0 +1,3 @@ +[global] +index = http://localhost:8080/repository/pypi-proxy/pypi +index-url = http://localhost:8080/repository/pypi-proxy/simple diff --git a/integration_tests/test.sh b/integration_tests/test.sh new file mode 100755 index 0000000..1263a0e --- /dev/null +++ b/integration_tests/test.sh @@ -0,0 +1,8 @@ +#! /usr/bin/env bash +docker build -t nexus_allowlist_bats:latest . +docker run \ + --rm \ + -v "$PWD/tests:/code" \ + --network host \ + nexus_allowlist_bats:latest \ + /code diff --git a/integration_tests/tests/cran.bats b/integration_tests/tests/cran.bats new file mode 100644 index 0000000..ad42d81 --- /dev/null +++ b/integration_tests/tests/cran.bats @@ -0,0 +1,35 @@ +setup() { + mkdir /root/rpackages +} + +teardown() { + rm -rf /root/rpackages +} + +@test "Install data.table" { + run Rscript -e 'install.packages("data.table")' + [[ "$output" == *"package ‘data.table’ successfully unpacked and MD5 sums checked"* ]] +} + +@test "Install archived version of data.table" { + run Rscript -e 'packagename <- "data.table" + version <- "1.13.0" # or 1.12.0 + packageurl <- paste0(contrib.url(getOption("repos")), "/Archive/", packagename, "/", packagename, "_", version, ".tar.gz") + install.packages(packageurl, repos=NULL, type="source") + ' + [[ "$output" == *"package ‘data.table’ successfully unpacked and MD5 sums checked"* ]] +} + +@test "Install archived version of data.table using remotes" { + run Rscript -e ' + install.packages("remotes") + remotes::install_version("data.table", version = "1.13.0") + ' + [[ "$output" == *"package ‘data.table’ successfully unpacked and MD5 sums checked"* ]] +} + +@test "Install ggplot2" { + run Rscript -e 'install.packages("ggplot2")' + [[ "$output" == *"download of package ‘ggplot2’ failed"* ]] + [[ "$output" == *"HTTP status was '403 Forbidden'"* ]] +} diff --git a/integration_tests/tests/pypi.bats b/integration_tests/tests/pypi.bats new file mode 100644 index 0000000..9188d73 --- /dev/null +++ b/integration_tests/tests/pypi.bats @@ -0,0 +1,20 @@ +setup () { + python3 -m venv /root/venv + . /root/venv/bin/activate +} + +teardown() { + deactivate + rm -rf /root/venv +} + +@test "Install numpy" { + pip install numpy +} + +@test "Install mkdocs" { + bats_require_minimum_version 1.5.0 + run ! pip install mkdocs + [ "$status" -eq 1 ] + [[ "$output" == *"HTTP error 403"* ]] +}