diff --git a/.github/workflows/ALL-PHPUnit.yml b/.github/workflows/ALL-PHPUnit.yml new file mode 100644 index 0000000..c8e4919 --- /dev/null +++ b/.github/workflows/ALL-PHPUnit.yml @@ -0,0 +1,43 @@ + +name: PHPUnit +on: [push] + +env: + PKG_NAME: tripal_blast + MODULES: "tripal_blast" + +jobs: + run-tests: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php-version: + - "8.0" + - "8.1" + pgsql-version: + - "13" + drupal-version: + - "9.3.x-dev" + - "9.4.x-dev" + - "9.5.x-dev" + # - "10.0.x-dev" +# exclude: +# - php-version: "8.0" +# pgsql-version: "13" +# drupal-version: "10.0.x-dev" + + steps: + # Check out the repo + - name: Checkout Repository + uses: actions/checkout@v3 + # Here we pull the development tripaldocker image for this combo in our matrix + - name: Run Automated testing + uses: tripal/test-tripal-action@v1.0 + with: + directory-name: $PKG_NAME + modules: $MODULES + php-version: ${{ matrix.php-version }} + pgsql-version: ${{ matrix.pgsql-version }} + drupal-version: ${{ matrix.drupal-version }} diff --git a/.github/workflows/ALL-testCoverage-codeclimate.yml b/.github/workflows/ALL-testCoverage-codeclimate.yml new file mode 100644 index 0000000..c2ded45 --- /dev/null +++ b/.github/workflows/ALL-testCoverage-codeclimate.yml @@ -0,0 +1,74 @@ +# Run some PHPUnit tests +name: Test Coverage +on: [push] + +env: + PKG_NAME: tripal_blast + MODULES: "tripal_blast" + IMAGE_TAG: drupal9.5.x-dev-php8.1-pgsql13 + SIMPLETEST_BASE_URL: "http://localhost" + SIMPLETEST_DB: "pgsql://drupaladmin:drupal9developmentonlylocal@localhost/sitedb" + BROWSER_OUTPUT_DIRECTORY: "/var/www/drupal9/web/sites/default/files/simpletest" + +jobs: + # Job 1: 'build' + run-tests: + # Runner type + runs-on: ubuntu-latest + name: Test Coverage + + steps: + # Check out the repo + - name: Checkout Repository + uses: actions/checkout@v3 + # Here we pull the development tripaldocker image for this combo in our matrix + - name: Pull TripalDocker Image + run: | + docker pull tripalproject/tripaldocker:$IMAGE_TAG + # Just spin up docker the good ol' fashion way + # mounting our currently checked out package inside the docker container. + - name: Spin up Docker locally + run: | + docker run --publish=80:80 --name=tripaldocker -tid \ + --volume=`pwd`:/var/www/drupal9/web/modules/contrib/$PKG_NAME tripalproject/tripaldocker:$IMAGE_TAG + # Install the modules + - name: Install our package in Docker + run: | + docker exec tripaldocker service postgresql restart + docker exec tripaldocker drush en $MODULES --yes + # Ensure we have the variables we need. + - name: Inject slug/short variables + uses: rlespinasse/github-slug-action@v3.x + # Prepare for code coverage. + - name: Prepare for Code Coverage + run: | + curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + docker cp cc-test-reporter tripaldocker:/var/www/drupal9/web/modules/contrib/$PKG_NAME + docker exec tripaldocker chmod a+x /var/www/drupal9/web/modules/contrib/$PKG_NAME/cc-test-reporter + docker exec --workdir=/var/www/drupal9/web/modules/contrib/$PKG_NAME tripaldocker ./cc-test-reporter before-build --debug + # Runs the PHPUnit tests. + # https://github.com/mheap/phpunit-github-actions-printer is used + # to report PHPUnit fails in a meaningful way to github in PRs. + # Stopped using mheap due to warning w/ phpunit8->9 + - name: Run Tests for Coverage + env: + SIMPLETEST_BASE_URL: "http://localhost" + SIMPLETEST_DB: "pgsql://drupaladmin:drupal9developmentonlylocal@localhost/sitedb" + BROWSER_OUTPUT_DIRECTORY: "/var/www/drupal9/web/sites/default/files/simpletest" + run: | + docker exec tripaldocker service postgresql restart + docker exec -e SIMPLETEST_BASE_URL=$SIMPLETEST_BASE_URL \ + -e SIMPLETEST_DB=$SIMPLETEST_DB \ + -e BROWSER_OUTPUT_DIRECTORY=$BROWSER_OUTPUT_DIRECTORY \ + --workdir=/var/www/drupal9/web/modules/contrib/$PKG_NAME \ + tripaldocker phpunit --coverage-text \ + --coverage-clover /var/www/drupal9/web/modules/contrib/$PKG_NAME/clover.xml + docker exec tripaldocker ls /var/www/drupal9/web/modules/contrib/$PKG_NAME + - name: Publish code coverage to Code Climate + run: | + docker exec --workdir=/var/www/drupal9/web/modules/contrib/$PKG_NAME tripaldocker \ + git config --global --add safe.directory /var/www/drupal9/web/modules/contrib/$PKG_NAME + docker exec --workdir=/var/www/drupal9/web/modules/contrib/$PKG_NAME \ + tripaldocker ./cc-test-reporter after-build clover.xml \ + --id ${{ secrets.CODECLIMATE_TEST_REPORTER_ID }} \ + --debug -t clover -p /var/www/drupal9/web/modules/contrib/$PKG_NAME diff --git a/.github/workflows/MAIN-phpunit-Grid1A.yml b/.github/workflows/MAIN-phpunit-Grid1A.yml new file mode 100644 index 0000000..9a3af46 --- /dev/null +++ b/.github/workflows/MAIN-phpunit-Grid1A.yml @@ -0,0 +1,19 @@ +name: PHPUnit +on: + push: + branches: + - 2.x +jobs: + run-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Run Automated testing + uses: tripal/test-tripal-action@v1.0 + with: + directory-name: 'tripal_blast' + modules: 'tripal_blast' + php-version: '8.0' + pgsql-version: '13' + drupal-version: '9.3.x-dev' diff --git a/.github/workflows/MAIN-phpunit-Grid1B.yml b/.github/workflows/MAIN-phpunit-Grid1B.yml new file mode 100644 index 0000000..fb0c80d --- /dev/null +++ b/.github/workflows/MAIN-phpunit-Grid1B.yml @@ -0,0 +1,19 @@ +name: PHPUnit +on: + push: + branches: + - 2.x +jobs: + run-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Run Automated testing + uses: tripal/test-tripal-action@v1.0 + with: + directory-name: 'tripal_blast' + modules: 'tripal_blast' + php-version: '8.0' + pgsql-version: '13' + drupal-version: '9.4.x-dev' diff --git a/.github/workflows/MAIN-phpunit-Grid1C.yml b/.github/workflows/MAIN-phpunit-Grid1C.yml new file mode 100644 index 0000000..d22ac59 --- /dev/null +++ b/.github/workflows/MAIN-phpunit-Grid1C.yml @@ -0,0 +1,19 @@ +name: PHPUnit +on: + push: + branches: + - 2.x +jobs: + run-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Run Automated testing + uses: tripal/test-tripal-action@v1.0 + with: + directory-name: 'tripal_blast' + modules: 'tripal_blast' + php-version: '8.0' + pgsql-version: '13' + drupal-version: '9.5.x-dev' diff --git a/.github/workflows/MAIN-phpunit-Grid2A.yml b/.github/workflows/MAIN-phpunit-Grid2A.yml new file mode 100644 index 0000000..dfefec0 --- /dev/null +++ b/.github/workflows/MAIN-phpunit-Grid2A.yml @@ -0,0 +1,19 @@ +name: PHPUnit +on: + push: + branches: + - 2.x +jobs: + run-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Run Automated testing + uses: tripal/test-tripal-action@v1.0 + with: + directory-name: 'tripal_blast' + modules: 'tripal_blast' + php-version: '8.1' + pgsql-version: '13' + drupal-version: '9.3.x-dev' diff --git a/.github/workflows/MAIN-phpunit-Grid2B.yml b/.github/workflows/MAIN-phpunit-Grid2B.yml new file mode 100644 index 0000000..74daa24 --- /dev/null +++ b/.github/workflows/MAIN-phpunit-Grid2B.yml @@ -0,0 +1,19 @@ +name: PHPUnit +on: + push: + branches: + - 2.x +jobs: + run-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Run Automated testing + uses: tripal/test-tripal-action@v1.0 + with: + directory-name: 'tripal_blast' + modules: 'tripal_blast' + php-version: '8.1' + pgsql-version: '13' + drupal-version: '9.4.x-dev' diff --git a/.github/workflows/MAIN-phpunit-Grid2C.yml b/.github/workflows/MAIN-phpunit-Grid2C.yml new file mode 100644 index 0000000..33da52b --- /dev/null +++ b/.github/workflows/MAIN-phpunit-Grid2C.yml @@ -0,0 +1,19 @@ +name: PHPUnit +on: + push: + branches: + - 2.x +jobs: + run-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Run Automated testing + uses: tripal/test-tripal-action@v1.0 + with: + directory-name: 'tripal_blast' + modules: 'tripal_blast' + php-version: '8.1' + pgsql-version: '13' + drupal-version: '9.5.x-dev' diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..2d20413 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,19 @@ + +GitHub Actions +================= + +This directory contains automated workflows executed by GitHub Actions. + +Naming Conventions +-------------------- + +### File Name: [scope]-[purpose]-[extra_info].yml + + - [scope] should be one of the following: + - MAIN for only against the master branch + - ALL for against all branches + - PR if specific to pull requests + - [purpose] should be a one word description of the purpose (e.g. phpunit, coverage) + - use snake-case if you must use more then one word (e.g. buildDocker) + - [extra_info] should be any additional information needed to make the file + name unique. For multiple words, separate words using an underscore. diff --git a/.gitignore b/.gitignore index cb53fe2..25c2248 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -supervisord* \ No newline at end of file +supervisord* +.phpunit.* diff --git a/README.md b/README.md new file mode 100644 index 0000000..53d2a15 --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +![Tripal Dependency](https://img.shields.io/badge/Tripal-4.0--alpha1-brightgreen) +![Development Status](https://img.shields.io/badge/Status-Active%20Development-orange) + +**Developed by the University of Saskatchewan, Pulse Crop Bioinformatics team.** + +## Introduction + +This module provides a basic interface to allow your users to utilize your +server's NCBI BLAST+. + +Specifically it provides blast program-specific forms (blastn, blastp, tblastn, +blastx are supported). In the future, there will be a single form where you +will be able to select either a nucleotide or a protein database to BLAST +against regardless of the type of query and it will decide which BLAST +program to use based on the combination of query/database type (ie: if you +selected a protein database on the nucleotide BLAST form then blastx would +be used). + +BLAST submissions result in the creation of Tripal jobs which then need to run +from the command-line. This ensures that long running BLASTs will not cause +page time-outs but does add some management overhead and might result in longer +waits for users depending on how often you have cron set to run Tripal jobs. + +The BLAST results page is an expandable summary table with each hit being +listed as a row in the table with query/hit/e-value information. The row can +then be expanded to include additional information including the alignment. +Download formats are allow users to download these results in the familiar +tabular, GFF3 or HTML NCBI formats. + +## Automated Testing + +This package is dedicated to a high standard of automated testing. We use +PHPUnit for testing and CodeClimate to ensure good test coverage and maintainability. +There are more details on [our CodeClimate project page] describing our specific +maintainability issues and test coverage. + +![MaintainabilityBadge] +![TestCoverageBadge] + +The following compatibility is proven via automated testing workflows. + +![Tripal Version for following tests](https://img.shields.io/badge/Tripal-4.x--dev-green) + +| Drupal | 9.3.x | 9.4.x | 9.5.x | 10.0.x | +|--------|-------|-------|-------|--------| +| **PHP 8.0** | ![Grid1A-Badge] | ![Grid1B-Badge] | ![Grid1C-Badge] | | +| **PHP 8.1** | ![Grid2A-Badge] | ![Grid2B-Badge] | ![Grid2C-Badge] | | + +[our CodeClimate project page]: https://codeclimate.com/github/tripal/tripal_blast +[MaintainabilityBadge]: https://api.codeclimate.com/v1/badges/5071f91a02a3fcafc275/maintainability +[TestCoverageBadge]: https://api.codeclimate.com/v1/badges/5071f91a02a3fcafc275/test_coverage + +[Grid1A-Badge]: https://github.com/tripal/tripal_blast/actions/workflows/MAIN-phpunit-Grid1A.yml/badge.svg +[Grid1B-Badge]: https://github.com/tripal/tripal_blast/actions/workflows/MAIN-phpunit-Grid1B.yml/badge.svg +[Grid1C-Badge]: https://github.com/tripal/tripal_blast/actions/workflows/MAIN-phpunit-Grid1C.yml/badge.svg + +[Grid2A-Badge]: https://github.com/tripal/tripal_blast/actions/workflows/MAIN-phpunit-Grid2A.yml/badge.svg +[Grid2B-Badge]: https://github.com/tripal/tripal_blast/actions/workflows/MAIN-phpunit-Grid2B.yml/badge.svg +[Grid2C-Badge]: https://github.com/tripal/tripal_blast/actions/workflows/MAIN-phpunit-Grid2C.yml/badge.svg +[Grid2D-Badge]: https://github.com/tripal/tripal_blast/actions/workflows/MAIN-phpunit-Grid2D.yml/badge.svg + +## Docker + +``` +git clone https://github.com/tripal/tripal_blast.git +cd tripal_blast +docker build --tag=tripal/tripal_blast:latest . +docker run --publish=80:80 -tid --volume=`pwd`:/var/www/drupal9/web/modules/contrib/tripal_blast tripal/tripal_blast:latest +``` diff --git a/config/schema/tripal_blast.settings.schema.yml b/config/schema/tripal_blast.settings.schema.yml new file mode 100644 index 0000000..3aafb58 --- /dev/null +++ b/config/schema/tripal_blast.settings.schema.yml @@ -0,0 +1,61 @@ +# @file +# Tripal Blast module variables/configuration. + +tripal_blast.settings: + type: config_object + mapping: + + # GENERAL CONFIGURATIONS: + tripal_blast_config_general: + type: mapping + mapping: + path: + type: string + label: 'Path to BLAST executables' + threads: + type: integer + label: 'Processor Threads for Blast' + eval: + type: float + label: 'E-value Threshold' + qrange: + type: integer + label: 'Max Matches in a Query Range' + + # UPLOAD CONFIGURATIONS: + tripal_blast_config_upload: + type: mapping + mapping: + allow_query: + type: boolean + label: 'Allow Query Sequence Upload' + allow_target: + type: boolean + label: 'Allow Target Database Upload' + + # SEQUENCE CONFIGURATIONS: + tripal_blast_config_sequence: + type: mapping + mapping: + nucleotide: + type: text + label: 'Nucleotide Example Fasta Record' + protein: + type: text + label: 'Protein Example Fasta Record' + + # LARGE JOBS CONFIGURATIONS: + tripal_blast_config_jobs: + type: mapping + mapping: + max_result: + type: integer + label: 'Max Results to Display' + + # NOTIFICATION CONFIGURATIONS + tripal_blast_config_notification: + type: mapping + mapping: + warning_text: + type: text + label: 'Warning Text on Blast Page' diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..35f1f3e --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,59 @@ + + + + + + + src + trpcultivate_genetics.module + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tests + + + + + + + diff --git a/tests/src/Functional/InstallTest.php b/tests/src/Functional/InstallTest.php new file mode 100644 index 0000000..4f7b852 --- /dev/null +++ b/tests/src/Functional/InstallTest.php @@ -0,0 +1,49 @@ +getSession(); + + // Ensure we have an admin user. + $user = $this->drupalCreateUser(['access administration pages', 'administer modules']); + $this->drupalLogin($user); + + $context = '(modules installed: ' . implode(',', self::$modules) . ')'; + + // Front Page. + $this->drupalGet(Url::fromRoute('')); + $status_code = $session->getStatusCode(); + $this->assertEquals(200, $status_code, "The front page should be able to load $context."); + + // Extend Admin page. + $this->drupalGet('admin/modules'); + $status_code = $session->getStatusCode(); + $this->assertEquals(200, $status_code, "The module install page should be able to load $context."); + $this->assertSession()->pageTextContains( 'Tripal BLAST' ); + + } +} diff --git a/tests/src/Functional/README.md b/tests/src/Functional/README.md new file mode 100644 index 0000000..6fe42ff --- /dev/null +++ b/tests/src/Functional/README.md @@ -0,0 +1,44 @@ + +All PHPUnit-based tests requiring a fully bootstrapped/functioning +Drupal/Tripal instance for effective testing should be included in this +directory. Each one should extend one of the following base classes: + +- `Drupal\Tests\tripal_chado\Functional\ChadoTestBrowserBase` + For any test which needs a chado instance either directly or indirectly. + +- `Drupal\Tests\tripal\Functional\TripalTestBrowserBase` + For any test which needs a Tripal site but will not use Chado in any way. + +- `Drupal\Tests\BrowserTestBase` + For any test which does not use Tripal in any way. If this is the case, + you may want to think about the design of your module to ensure that + it is effectively using all Tripal APIs available. + +NOTE: The above list of classes each inherit from those listed below them in +the list. As such, you have all the functionality from the TripalTestBrowserBase +and the Drupal BrowserTestBase available to you when you extend the +ChadoTestBrowserBase. + +NOTE: Javascript-focused tests should NOT BE in this directory. Instead they +should be in a FunctionalJavscript directory as they use WebDriver and a +different set of base classes. + +## Directory Structure + +Only tests which apply to the module as a whole should be directly in this folder. + +In most cases you will create a folder to indicate a category of tests. For example, +you will create a folder labelled `ChadoFields` to contain all tests relating +to ChadoField implementations (testing type, widget and formatter). + +Rule of Thumb: +- All plugin types should have a folder named the same as the plugin type that + contains all tests for implementations, base classes, and the plugin manager + for that plugin type. +- All services should have its own folder named the same as the service class. + This folder can also include tests for forms, controllers, etc which provide + a user or administrative interface for this service. +- Beyond this, create folders focused on common functionality. + - For example, if this module creates an entity, you may create a folder + named the same as the entity that contains tests related to the entity + classes, forms, list builders, etc. diff --git a/tripal_blast.install b/tripal_blast.install index 529b66a..f7fa544 100755 --- a/tripal_blast.install +++ b/tripal_blast.install @@ -16,12 +16,12 @@ use Drupal\tripal_blast\TripalBlastDatabaseInterface; /** * Implements hook_install(). - * + * * @see tripal.info */ function tripal_blast_install() { // Retreives the Drupal relative directory for a Tripal module. - tripal_create_files_dir('tripal_blast'); + // @upgrade tripal_create_files_dir('tripal_blast'); } /** @@ -35,12 +35,12 @@ function tripal_blast_uninstall() { $blast_db = $entity_query ->condition('id', '>', 0) ->execute(); - + // Load multiples or single item load($id) $db = $database_entity->loadMultiple($blast_db); foreach($db as $id => $db_obj) { $db_id = $db_obj->getId(); - + $databae_entity->load($db_id) ->delete(); } @@ -50,7 +50,7 @@ function tripal_blast_uninstall() { * Implements hook_schema(). * Create the blast job database table for storing blast job requests. */ -function tripal_blast_schema() { +function tripal_blast_schema() { // BLAST JOBS // ------------------------ // Keeps track of additional information related to tripal blast jobs. @@ -101,6 +101,6 @@ function tripal_blast_schema() { ), ), ); - + return $schema; -} \ No newline at end of file +}