diff --git a/.github/workflows/sapporo.yml b/.github/workflows/sapporo.yml new file mode 100644 index 0000000000..9a266bfec9 --- /dev/null +++ b/.github/workflows/sapporo.yml @@ -0,0 +1,78 @@ +name: Sapporo CI + +on: + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + test: + timeout-minutes: 10 + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:14.6 + env: + POSTGRES_DB: irida_next_test + POSTGRES_PASSWORD: test + POSTGRES_USER: test + POSTGRES_HOST: postgres + ports: + - 5432:5432 + # Set health checks to wait until postgres has started + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - name: Check out code + uses: actions/checkout@v3 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + - name: Set up PNPM + uses: pnpm/action-setup@v2 + with: + version: 7 + - name: Use Node.js 19 + uses: actions/setup-node@v3 + with: + node-version: 19 + cache: "pnpm" + - name: Install dependencies + run: pnpm install + - name: Install Sapporo dependencies + uses: actions/setup-java@v4 + with: + distribution: adopt + java-version: 16 + - name: Download Sapporo + uses: actions/checkout@v3 + with: + repository: phac-nml/sapporo-service + ref: irida-next + path: ./sapporo + - name: Build Sapporo + run: | + cd sapporo + IRIDA_NEXT_PATH=${GITHUB_WORKSPACE}/tmp MYUID="$(id -u)" MYGID="$(id -g)" docker compose -f compose.irida-next.yml up -d --build + cd .. + - name: Run Sapporo + uses: JarvusInnovations/background-action@v1 + with: + run: | + IRIDA_NEXT_PATH=${GITHUB_WORKSPACE}/tmp MYUID="$(id -u)" MYGID="$(id -g)" docker compose -f compose.irida-next.yml exec app bash -c "sapporo" + wait-on: + http://localhost:1122/service-info + wait-for: 2m + working-directory: sapporo + - name: Update permissions + run: sudo chmod -R 777 ${GITHUB_WORKSPACE} + - name: Run tests + run: | + bin/rails test test/integration/sapporo.rb diff --git a/Gemfile b/Gemfile index 1f5d5191ad..2fe3a2f48c 100644 --- a/Gemfile +++ b/Gemfile @@ -117,6 +117,9 @@ gem 'zip_kit' gem 'business_time' gem 'holidays' +# csv +gem 'csv' + group :development, :test do # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem gem 'debug', platforms: %i[mri mingw x64_mingw] @@ -141,6 +144,9 @@ group :development do gem 'actioncable' gem 'listen' gem 'lookbook', '~> 2.1', '>= 2.1.1' + + # Solargraph + gem 'solargraph' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 7c76560109..27708a2941 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -123,8 +123,10 @@ GEM aws-sigv4 (~> 1.8) aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) + backport (1.2.0) base64 (0.2.0) bcrypt (3.1.20) + benchmark (0.3.0) bigdecimal (3.1.8) bindex (0.8.1) bootsnap (1.18.3) @@ -155,6 +157,7 @@ GEM crass (1.0.6) css_parser (1.17.1) addressable + csv (3.2.8) cuprite (0.15) capybara (~> 3.0) ferrum (~> 0.14.0) @@ -169,10 +172,12 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) + diff-lcs (1.5.1) digest-crc (0.6.5) rake (>= 12.0.0, < 14.0.0) docile (1.4.0) drb (2.2.1) + e2mmap (0.1.0) erb-formatter (0.7.2) syntax_tree (~> 6.0) erubi (1.12.0) @@ -267,6 +272,7 @@ GEM irb (1.13.1) rdoc (>= 4.0.0) reline (>= 0.4.2) + jaro_winkler (1.5.6) jbuilder (2.12.0) actionview (>= 5.0.0) activesupport (>= 5.0.0) @@ -280,6 +286,10 @@ GEM simpleidn (~> 0.2) jwt (2.8.1) base64 + kramdown (2.4.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) language_server-protocol (3.17.0.3) listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) @@ -427,8 +437,9 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rdoc (6.7.0) + rbs (2.8.4) psych (>= 4.0.0) + rdoc (6.7.0) redcarpet (3.6.0) regexp_parser (2.9.2) reline (0.5.8) @@ -441,6 +452,8 @@ GEM actionpack (>= 5.2) railties (>= 5.2) retriable (3.1.2) + reverse_markdown (2.1.1) + nokogiri rexml (3.2.8) strscan (>= 3.0.9) roo (2.10.1) @@ -499,6 +512,22 @@ GEM snaky_hash (2.0.1) hashie version_gem (~> 1.1, >= 1.1.1) + solargraph (0.50.0) + backport (~> 1.2) + benchmark + bundler (~> 2.0) + diff-lcs (~> 1.4) + e2mmap + jaro_winkler (~> 1.5) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.1) + parser (~> 3.0) + rbs (~> 2.0) + reverse_markdown (~> 2.0) + rubocop (~> 1.38) + thor (~> 1.0) + tilt (~> 2.0) + yard (~> 0.9, >= 0.9.24) spreadsheet (1.3.1) bigdecimal ruby-ole @@ -522,6 +551,7 @@ GEM tailwindcss-rails (2.6.0-x86_64-linux) railties (>= 7.0.0) thor (1.3.1) + tilt (2.3.0) timecop (0.9.8) timeout (0.4.1) trailblazer-option (0.1.2) @@ -579,6 +609,7 @@ DEPENDENCIES business_time capybara capybara-lockstep + csv cuprite debug devise (~> 4.9.4) @@ -614,6 +645,7 @@ DEPENDENCIES rubocop-graphql rubocop-rails simplecov + solargraph sprockets-rails stimulus-rails tailwindcss-rails (~> 2.6) diff --git a/config/application.rb b/config/application.rb index 4b22208c17..c2b03676fe 100644 --- a/config/application.rb +++ b/config/application.rb @@ -84,5 +84,12 @@ class Application < Rails::Application # Omniauth Configuration config.auth_config = config_for(Rails.root.join('config/authentication/auth_config.yml')) + + # GA4GH WES Configuration + config.ga4gh_wes_server_endpoint = if Rails.application.credentials.ga4gh_wes.nil? + nil + else + Rails.application.credentials.dig(:ga4gh_wes, :server_url_endpoint) + end end end diff --git a/lib/integrations/ga4gh_wes_api/v1/api_connection.rb b/lib/integrations/ga4gh_wes_api/v1/api_connection.rb index f246f5c8cf..73499efea5 100644 --- a/lib/integrations/ga4gh_wes_api/v1/api_connection.rb +++ b/lib/integrations/ga4gh_wes_api/v1/api_connection.rb @@ -19,14 +19,14 @@ class ApiConnection # Path is then generated by REST versioning standard. ex: 'http://localhost:7500/' # Default: server url with endpoint is set from credentials file as ga4gh_wes:server_url_endpoint def initialize(api_server_url = nil) - @api_endpoint = if api_server_url.nil? && Rails.application.credentials.ga4gh_wes.nil? - "http://www.example.com/#{Ga4ghWesApi::API_SERVER_ENDPOINT_PATH}#{V1::API_SERVER_ENDPOINT_VERSION}" - elsif api_server_url.nil? && Rails.application.credentials.ga4gh_wes.present? - Rails.application.credentials.dig(:ga4gh_wes, :server_url_endpoint) - else - # Endpoint with path and version - api_server_url + Ga4ghWesApi::API_SERVER_ENDPOINT_PATH + V1::API_SERVER_ENDPOINT_VERSION - end + @api_endpoint = + if api_server_url.present? + "#{api_server_url}#{Ga4ghWesApi::API_SERVER_ENDPOINT_PATH}#{V1::API_SERVER_ENDPOINT_VERSION}" + elsif Rails.configuration.ga4gh_wes_server_endpoint.present? + Rails.configuration.ga4gh_wes_server_endpoint + else + "http://www.example.com/#{Ga4ghWesApi::API_SERVER_ENDPOINT_PATH}#{V1::API_SERVER_ENDPOINT_VERSION}" + end Rails.logger.info @api_endpoint end diff --git a/scripts/clean_dev.sh b/scripts/clean_dev.sh index 2033d6e819..c564f90148 100755 --- a/scripts/clean_dev.sh +++ b/scripts/clean_dev.sh @@ -1,5 +1,6 @@ # clean storage rm -rf storage/* +rm -rf tmp/storage/* # grab any new gems bundle # delete, create and migrate databases diff --git a/test/integration/sapporo.rb b/test/integration/sapporo.rb new file mode 100644 index 0000000000..9bb23036f7 --- /dev/null +++ b/test/integration/sapporo.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'test_helper' +require 'active_job_test_case' + +class IntegrationSapporoTest < ActiveJobTestCase + def setup + @workflow_execution = workflow_executions(:irida_next_example_end_to_end) + Rails.configuration.ga4gh_wes_server_endpoint = 'http://localhost:1122/' + end + + def teardown + Rails.configuration.ga4gh_wes_server_endpoint = nil + end + + test 'integration sapporo end to end' do + # Before starting test, check if Sapporo Integration is running. + begin + ga4gh_client = Integrations::Ga4ghWesApi::V1::Client.new + ga4gh_client.service_info + rescue Integrations::ApiExceptions::ConnectionError + skip 'Sapporo server is not running' + end + + assert_equal 'initial', @workflow_execution.state + assert_not @workflow_execution.cleaned? + + WorkflowExecutionPreparationJob.perform_later(@workflow_execution) + + perform_enqueued_jobs_sequentially(except: WorkflowExecutionSubmissionJob) + assert_equal 'prepared', @workflow_execution.reload.state + + perform_enqueued_jobs_sequentially(except: WorkflowExecutionStatusJob) + assert_equal 'submitted', @workflow_execution.reload.state + + perform_enqueued_jobs_sequentially(delay_seconds: 10, except: WorkflowExecutionCompletionJob) + assert_equal 'completing', @workflow_execution.reload.state + + perform_enqueued_jobs_sequentially(except: WorkflowExecutionCleanupJob) + assert_equal 'completed', @workflow_execution.reload.state + + perform_enqueued_jobs_sequentially + + assert_equal 'completed', @workflow_execution.reload.state + assert @workflow_execution.cleaned? + end +end