diff --git a/.github/workflows/ruby-unit-tests.yml b/.github/workflows/ruby-unit-tests.yml deleted file mode 100644 index f2d562b..0000000 --- a/.github/workflows/ruby-unit-tests.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Ruby Unit Tests - -on: - push: - pull_request: - -jobs: - test: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - backend: ['ruby', 'ruby-agraph'] # api runs tests with 4store backend and api-agraph runs with AllegroGraph backend - steps: - - uses: actions/checkout@v4 - - name: copy config file - run: cp config/config.test.rb config/config.rb - - name: Build docker compose - run: docker compose build - - name: Run unit tests - # unit tests are run inside a container - # http://docs.codecov.io/docs/testing-with-docker - run: | - ci_env=`bash <(curl -s https://codecov.io/env)` - docker compose run $ci_env -e CI ${{ matrix.backend }} bundle exec rake test TESTOPTS='-v' - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - flags: unittests - verbose: true - fail_ci_if_error: false # optional (default = false) diff --git a/.github/workflows/testkit-unit-tests.yml b/.github/workflows/testkit-unit-tests.yml new file mode 100644 index 0000000..d763837 --- /dev/null +++ b/.github/workflows/testkit-unit-tests.yml @@ -0,0 +1,87 @@ +name: Docker Unit Tests + +on: + push: + branches: + - '**' + tags-ignore: + - '**' + pull_request: + +env: + # CI execution mode for backend tests: + # - container: run `test:docker::container` (default) + # - native: run `test:docker:` on host Ruby + # OPTK_CI_RUN_MODE: ${{ vars.OPTK_CI_RUN_MODE || 'container' }} + # Example override to force native mode in this workflow file: + OPTK_CI_RUN_MODE: native + +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + backends: ${{ steps.cfg.outputs.backends }} + steps: + - uses: actions/checkout@v4 + + - id: cfg + name: Read backend matrix from .ontoportal-testkit.yml + run: | + BACKENDS=$(ruby -ryaml -rjson -e 'c=YAML.safe_load_file(".ontoportal-testkit.yml") || {}; b=c["backends"] || %w[fs ag vo gd]; puts JSON.generate(b)') + echo "backends=$BACKENDS" >> "$GITHUB_OUTPUT" + + test: + needs: prepare + runs-on: ubuntu-latest + timeout-minutes: 45 + strategy: + fail-fast: false + matrix: + backend: ${{ fromJson(needs.prepare.outputs.backends) }} + + steps: + - uses: actions/checkout@v4 + + - name: Set up Ruby from .ruby-version + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Set up Java 11 (native mode) + if: env.OPTK_CI_RUN_MODE == 'native' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '11' + + - name: Install native system dependencies + if: env.OPTK_CI_RUN_MODE == 'native' + run: | + sudo apt-get update + sudo apt-get install -y raptor2-utils + + - name: Run unit tests + env: + CI: "true" + TESTOPTS: "-v" + BACKEND: ${{ matrix.backend }} + run: | + MODE="${OPTK_CI_RUN_MODE:-container}" + TASK="test:docker:${BACKEND}" + if [ "$MODE" = "container" ]; then + TASK="${TASK}:container" + elif [ "$MODE" != "native" ]; then + echo "Invalid OPTK_CI_RUN_MODE=$MODE (expected container or native)" + exit 1 + fi + + bundle exec rake "$TASK" + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + flags: unittests,${{ matrix.backend }} + verbose: true + fail_ci_if_error: false diff --git a/.ontoportal-testkit.yml b/.ontoportal-testkit.yml new file mode 100644 index 0000000..161f930 --- /dev/null +++ b/.ontoportal-testkit.yml @@ -0,0 +1,9 @@ +component_name: ncbo_annotator +app_service: test-container +backends: + - fs + - ag + - vo + - gd +dependency_services: + - mgrep diff --git a/.ruby-version b/.ruby-version index be94e6f..f15386a 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.2 +3.2.10 diff --git a/Dockerfile b/Dockerfile index c585383..6c56623 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,38 +1,18 @@ -ARG RUBY_VERSION=3.1 +ARG RUBY_VERSION=3.2 ARG DISTRO=bullseye - -FROM ruby:$RUBY_VERSION-$DISTRO - -RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential \ - git \ - libxml2 \ - libxslt-dev \ - openjdk-11-jre-headless \ - raptor2-utils \ - && rm -rf /var/lib/apt/lists/* +ARG TESTKIT_BASE_IMAGE=ontoportal/testkit-base:ruby${RUBY_VERSION}-${DISTRO} +FROM ${TESTKIT_BASE_IMAGE} WORKDIR /app -# Use a dedicated bundle path -ENV BUNDLE_PATH=/usr/local/bundle -ENV GEM_HOME=/usr/local/bundle -ENV PATH="$BUNDLE_PATH/bin:$PATH" - COPY Gemfile* *.gemspec ./ -RUN gem update --system - -#I nstall the exact Bundler version from Gemfile.lock (if it exists) +# Respect the project's Bundler lock when present. RUN if [ -f Gemfile.lock ]; then \ BUNDLER_VERSION=$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n 1 | tr -d ' '); \ gem install bundler -v "$BUNDLER_VERSION"; \ - else \ - gem install bundler; \ fi -RUN bundle config set --local path '/usr/local/bundle' -RUN bundle config set --global no-document 'true' RUN bundle install --jobs 4 --retry 3 COPY . ./ diff --git a/Gemfile b/Gemfile index 9be1a91..ac829ed 100644 --- a/Gemfile +++ b/Gemfile @@ -14,6 +14,7 @@ gem 'activesupport' group :test do gem 'minitest' gem 'minitest-reporters' + gem 'ontoportal_testkit', github: 'alexskr/ontoportal_testkit', branch: 'main' gem 'pry' gem 'simplecov' gem 'simplecov-cobertura' # for codecov.io diff --git a/Gemfile.lock b/Gemfile.lock index c28ad4b..8af47ee 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,11 @@ +GIT + remote: https://github.com/alexskr/ontoportal_testkit.git + revision: 5138aa94c028ec97adeaf1f7a5ed9f1c40b12950 + branch: main + specs: + ontoportal_testkit (0.1.0) + rake (>= 13.0) + GIT remote: https://github.com/ncbo/goo.git revision: 13a8559a2346cc8320d7d36046646907bfa8a27c @@ -263,6 +271,7 @@ DEPENDENCIES minitest-reporters oj (~> 3.0) ontologies_linked_data! + ontoportal_testkit! parallel pry rake @@ -335,6 +344,7 @@ CHECKSUMS oj (3.16.15) sha256=4d3324cac3e8fef54c0fa250b2af26a16dadd9f9788a1d6b1b2098b793a1b2cd omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e ontologies_linked_data (0.0.1) + ontoportal_testkit (0.1.0) ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130 pony (1.13.1) sha256=ab507c8ade8b35de96f1e75c0ae4566a3c40ac8a0d5101433969b6fd29c718a7 @@ -374,4 +384,4 @@ CHECKSUMS uuid (2.3.9) sha256=aec0cf592053cd6e07c13c1ef94c440aba705f22eb1ee767b39631f2760124d7 BUNDLED WITH - 4.0.5 + 4.0.7 diff --git a/config/config.test.rb b/config/config.test.rb index c33e281..afdfa2c 100644 --- a/config/config.test.rb +++ b/config/config.test.rb @@ -16,21 +16,23 @@ SOLR_TERM_SEARCH_URL = ENV.include?("SOLR_TERM_SEARCH_URL") ? ENV["SOLR_TERM_SEARCH_URL"] : "http://localhost:8983/solr" SOLR_PROP_SEARCH_URL = ENV.include?("SOLR_PROP_SEARCH_URL") ? ENV["SOLR_PROP_SEARCH_URL"] : "http://localhost:8983/solr" - LinkedData.config do |config| - config.goo_backend_name = GOO_BACKEND_NAME.to_s - config.goo_host = GOO_HOST.to_s - config.goo_port = GOO_PORT.to_i - config.goo_path_query = GOO_PATH_QUERY.to_s - config.goo_path_data = GOO_PATH_DATA.to_s - config.goo_path_update = GOO_PATH_UPDATE.to_s - config.search_server_url = SOLR_TERM_SEARCH_URL.to_s - config.property_search_server_url = SOLR_PROP_SEARCH_URL.to_s + config.goo_backend_name = GOO_BACKEND_NAME.to_s + config.goo_host = GOO_HOST.to_s + config.goo_port = GOO_PORT.to_s + config.goo_path_query = GOO_PATH_QUERY.to_s + config.goo_path_data = GOO_PATH_DATA.to_s + config.goo_path_update = GOO_PATH_UPDATE.to_s + config.search_server_url = SOLR_TERM_SEARCH_URL.to_s + config.property_search_server_url = SOLR_PROP_SEARCH_URL.to_s end + Annotator.config do |config| config.mgrep_host = MGREP_HOST.to_s - config.mgrep_port = MGREP_PORT.to_i + config.mgrep_port = MGREP_PORT.to_s + config.mgrep_alt_host = MGREP_HOST.to_s + config.mgrep_alt_port = MGREP_PORT.to_s config.mgrep_dictionary_file = './test/data/dictionary.txt' config.annotator_redis_host = REDIS_HOST.to_s - config.annotator_redis_port = REDIS_PORT.to_i + config.annotator_redis_port = REDIS_PORT.to_s end diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index c643b99..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,121 +0,0 @@ -x-app: &app - image: ncbo_annotator:0.0.3 - build: - context: . - args: - RUBY_VERSION: '3.2' - environment: &env - COVERAGE: 'true' # enable simplecov code coverage - REDIS_HOST: redis-ut - REDIS_PORT: 6379 - MGREP_HOST: mgrep-ut - MGREP_PORT: 55556 - SOLR_TERM_SEARCH_URL: http://solr-ut:8983/solr - SOLR_PROP_SEARCH_URL: http://solr-ut:8983/solr - volumes: - - .:/app - - bundle:/usr/local/bundle - stdin_open: true - tty: true - command: "bundle exec rake test TESTOPTS='-v'" - depends_on: &depends_on - solr-ut: - condition: service_healthy - redis-ut: - condition: service_healthy - mgrep-ut: - condition: service_healthy - -services: - ruby: - <<: *app - environment: - <<: *env - GOO_BACKEND_NAME: 4store - GOO_PORT: 9000 - GOO_HOST: 4store-ut - depends_on: - <<: *depends_on - 4store-ut: - condition: service_started - profiles: - - 4store - - ruby-agraph: - <<: *app - environment: - <<: *env - GOO_BACKEND_NAME: ag - GOO_PORT: 10035 - GOO_HOST: agraph-ut - GOO_PATH_QUERY: /repositories/ontoportal_test - GOO_PATH_DATA: /repositories/ontoportal_test/statements - GOO_PATH_UPDATE: /repositories/ontoportal_test/statements - depends_on: - <<: *depends_on - agraph-ut: - condition: service_healthy - profiles: - - agraph - - solr-ut: - image: ontoportal/solr-ut:0.2.0 - healthcheck: - test: ["CMD-SHELL", "curl -sf http://localhost:8983/solr/term_search_core1/admin/ping?wt=json | grep -iq '\"status\":\"OK\"}' || exit 1"] - start_period: 3s - interval: 10s - timeout: 5s - retries: 5 - - redis-ut: - image: redis - healthcheck: - test: redis-cli ping - interval: 10s - timeout: 3s - retries: 10 - - mgrep-ut: - image: ontoportal/mgrep:0.0.3 - platform: linux/amd64 - healthcheck: - test: ["CMD", "nc", "-z", "-v", "127.0.0.1", "55556"] - start_period: 3s - interval: 10s - timeout: 5s - retries: 5 - - 4store-ut: - image: bde2020/4store - platform: linux/amd64 - command: > - bash -c "4s-backend-setup --segments 4 ontoportal_kb - && 4s-backend ontoportal_kb - && 4s-httpd -D -s-1 -p 9000 ontoportal_kb" - profiles: - - 4store - - agraph-ut: - image: franzinc/agraph:v8.3.1 - platform: linux/amd64 - environment: - - AGRAPH_SUPER_USER=test - - AGRAPH_SUPER_PASSWORD=xyzzy - shm_size: 1g - command: > - bash -c "/agraph/bin/agraph-control --config /agraph/etc/agraph.cfg start - ; agtool repos create --supersede ontoportal_test - ; agtool users add anonymous - ; agtool users grant anonymous root:ontoportal_test:rw - ; tail -f /agraph/data/agraph.log" - healthcheck: - test: ["CMD-SHELL", "agtool storage-report ontoportal_test || exit 1"] - start_period: 30s - interval: 10s - timeout: 5s - retries: 5 - profiles: - - agraph - -volumes: - bundle: diff --git a/rakelib/ontoportal_testkit.rake b/rakelib/ontoportal_testkit.rake new file mode 100644 index 0000000..7f04305 --- /dev/null +++ b/rakelib/ontoportal_testkit.rake @@ -0,0 +1,2 @@ +# Loads shared OntoPortal testkit rake tasks into this component. +require "ontoportal/testkit/tasks" diff --git a/run-unit-tests.sh b/run-unit-tests.sh deleted file mode 100755 index e25a7a8..0000000 --- a/run-unit-tests.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# sample script for running unit tests in docker. This functionality should be moved to a rake task -# -# add config for unit testing -[ -f config/config.rb ] || cp config/config.test.rb config/config.rb -docker-compose build - -docker compose run --rm ruby bundle exec rake test TESTOPTS='-v' -#docker compose run --rm ruby-agraph bundle exec rake test TESTOPTS='-v' -docker compose --profile agraph --profile 4store stop diff --git a/test/test_case.rb b/test/test_case.rb index 443693d..e638438 100644 --- a/test/test_case.rb +++ b/test/test_case.rb @@ -16,10 +16,10 @@ end require_relative '../lib/ncbo_annotator' -require_relative '../config/config' +require_relative '../config/config.test' # Check to make sure you want to run if not pointed at localhost -safe_host = Regexp.new(/localhost|-ut|ncbo-dev*|ncbo-unittest*/) +safe_host = Regexp.new(/localhost|-ut*/) unless LinkedData.settings.goo_host.match(safe_host) && LinkedData.settings.search_server_url.match(safe_host) && Annotator.settings.annotator_redis_host.match(safe_host) print '\n\n================================== WARNING ==================================\n' print '** TESTS CAN BE DESTRUCTIVE -- YOU ARE POINTING TO A POTENTIAL PRODUCTION/STAGE SERVER **\n' diff --git a/test/test_mgrep_client.rb b/test/test_mgrep_client.rb index 7a70ca6..0369abe 100644 --- a/test/test_mgrep_client.rb +++ b/test/test_mgrep_client.rb @@ -1,8 +1,7 @@ -require "pry" require "minitest/autorun" -require_relative "../lib/ncbo_annotator.rb" -require_relative "../config/config.rb" +require_relative "../lib/ncbo_annotator" +require_relative "../config/config.test" class TestMgrepClient < Minitest::Test