aboutsummaryrefslogtreecommitdiff
path: root/tests/integration
diff options
context:
space:
mode:
Diffstat (limited to 'tests/integration')
-rw-r--r--tests/integration/conftest.py24
-rw-r--r--tests/integration/test_correlation.py8
-rw-r--r--tests/integration/test_gemma.py14
-rw-r--r--tests/integration/test_general.py8
-rw-r--r--tests/integration/test_partial_correlations.py225
-rw-r--r--tests/integration/test_wgcna.py3
6 files changed, 280 insertions, 2 deletions
diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py
new file mode 100644
index 0000000..be927a4
--- /dev/null
+++ b/tests/integration/conftest.py
@@ -0,0 +1,24 @@
+"""Module that holds fixtures for integration tests"""
+import pytest
+
+from gn3.app import create_app
+from gn3.db_utils import database_connector
+
+@pytest.fixture(scope="session")
+def client():
+ """Create a test client fixture for tests"""
+ # Do some setup
+ app = create_app()
+ app.config.update({"TESTING": True})
+ app.testing = True
+ yield app.test_client()
+ # Do some teardown/cleanup
+
+
+@pytest.fixture
+def db_conn():
+ """Create a db connection fixture for tests"""
+ ## Update this to use temp db once that is in place
+ conn = database_connector()
+ yield conn
+ conn.close()
diff --git a/tests/integration/test_correlation.py b/tests/integration/test_correlation.py
index bdd9bce..d52ab01 100644
--- a/tests/integration/test_correlation.py
+++ b/tests/integration/test_correlation.py
@@ -1,6 +1,7 @@
"""module contains integration tests for correlation"""
from unittest import TestCase
from unittest import mock
+import pytest
from gn3.app import create_app
@@ -10,6 +11,7 @@ class CorrelationIntegrationTest(TestCase):
def setUp(self):
self.app = create_app().test_client()
+ @pytest.mark.integration_test
@mock.patch("gn3.api.correlation.compute_all_sample_correlation")
def test_sample_r_correlation(self, mock_compute_samples):
"""Test /api/correlation/sample_r/{method}"""
@@ -61,6 +63,7 @@ class CorrelationIntegrationTest(TestCase):
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get_json(), api_response)
+ @pytest.mark.integration_test
@mock.patch("gn3.api.correlation.compute_all_lit_correlation")
@mock.patch("gn3.api.correlation.database_connector")
def test_lit_correlation(self, database_connector, mock_compute_corr):
@@ -68,7 +71,9 @@ class CorrelationIntegrationTest(TestCase):
mock_compute_corr.return_value = []
- database_connector.return_value = (mock.Mock(), mock.Mock())
+ database_connector.return_value = mock.Mock()
+ database_connector.return_value.__enter__ = mock.Mock()
+ database_connector.return_value.__exit__ = mock.Mock()
post_data = {"1426678_at": "68031",
"1426679_at": "68036",
@@ -80,6 +85,7 @@ class CorrelationIntegrationTest(TestCase):
self.assertEqual(mock_compute_corr.call_count, 1)
self.assertEqual(response.status_code, 200)
+ @pytest.mark.integration_test
@mock.patch("gn3.api.correlation.compute_tissue_correlation")
def test_tissue_correlation(self, mock_tissue_corr):
"""Test api/correlation/tissue_corr/{corr_method}"""
diff --git a/tests/integration/test_gemma.py b/tests/integration/test_gemma.py
index f871173..0515539 100644
--- a/tests/integration/test_gemma.py
+++ b/tests/integration/test_gemma.py
@@ -7,6 +7,8 @@ from dataclasses import dataclass
from typing import Callable
from unittest import mock
+import pytest
+
from gn3.app import create_app
@@ -30,6 +32,7 @@ class GemmaAPITest(unittest.TestCase):
"TMPDIR": "/tmp"
}).test_client()
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.run_cmd")
def test_get_version(self, mock_run_cmd):
"""Test that the correct response is returned"""
@@ -38,6 +41,7 @@ class GemmaAPITest(unittest.TestCase):
self.assertEqual(response.get_json(), {"status": 0, "output": "v1.9"})
self.assertEqual(response.status_code, 200)
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.redis.Redis")
def test_check_cmd_status(self, mock_redis):
"""Test that you can check the status of a given command"""
@@ -52,6 +56,7 @@ class GemmaAPITest(unittest.TestCase):
name="cmd::2021-02-1217-3224-3224-1234", key="status")
self.assertEqual(response.get_json(), {"status": "test"})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.queue_cmd")
@mock.patch("gn3.computations.gemma.get_hash_of_files")
@mock.patch("gn3.api.gemma.jsonfile_to_dict")
@@ -94,6 +99,7 @@ class GemmaAPITest(unittest.TestCase):
"unique_id": "my-unique-id"
})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.queue_cmd")
@mock.patch("gn3.computations.gemma.get_hash_of_files")
@mock.patch("gn3.api.gemma.jsonfile_to_dict")
@@ -137,6 +143,7 @@ class GemmaAPITest(unittest.TestCase):
"unique_id": "my-unique-id"
})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.queue_cmd")
@mock.patch("gn3.computations.gemma.get_hash_of_files")
@mock.patch("gn3.api.gemma.jsonfile_to_dict")
@@ -187,6 +194,7 @@ class GemmaAPITest(unittest.TestCase):
"output_file": "hash-output.json"
})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.queue_cmd")
@mock.patch("gn3.computations.gemma.get_hash_of_files")
@mock.patch("gn3.api.gemma.jsonfile_to_dict")
@@ -240,6 +248,7 @@ class GemmaAPITest(unittest.TestCase):
"output_file": "hash-output.json"
})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.queue_cmd")
@mock.patch("gn3.computations.gemma.get_hash_of_files")
@mock.patch("gn3.api.gemma.jsonfile_to_dict")
@@ -292,6 +301,7 @@ class GemmaAPITest(unittest.TestCase):
"output_file": "hash-output.json"
})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.queue_cmd")
@mock.patch("gn3.computations.gemma.get_hash_of_files")
@mock.patch("gn3.api.gemma.jsonfile_to_dict")
@@ -346,6 +356,7 @@ class GemmaAPITest(unittest.TestCase):
"output_file": "hash-output.json"
})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.queue_cmd")
@mock.patch("gn3.computations.gemma.get_hash_of_files")
@mock.patch("gn3.api.gemma.jsonfile_to_dict")
@@ -401,6 +412,7 @@ class GemmaAPITest(unittest.TestCase):
"output_file": "hash-output.json"
})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.queue_cmd")
@mock.patch("gn3.computations.gemma.get_hash_of_files")
@mock.patch("gn3.api.gemma.jsonfile_to_dict")
@@ -465,6 +477,7 @@ class GemmaAPITest(unittest.TestCase):
"output_file": "hash-output.json"
})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.queue_cmd")
@mock.patch("gn3.computations.gemma.get_hash_of_files")
@mock.patch("gn3.api.gemma.jsonfile_to_dict")
@@ -530,6 +543,7 @@ class GemmaAPITest(unittest.TestCase):
"output_file": "hash-output.json"
})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.gemma.queue_cmd")
@mock.patch("gn3.computations.gemma.get_hash_of_files")
@mock.patch("gn3.api.gemma.jsonfile_to_dict")
diff --git a/tests/integration/test_general.py b/tests/integration/test_general.py
index 8fc2b43..9d87449 100644
--- a/tests/integration/test_general.py
+++ b/tests/integration/test_general.py
@@ -1,8 +1,10 @@
"""Integration tests for some 'general' API endpoints"""
import os
import unittest
-
from unittest import mock
+
+import pytest
+
from gn3.app import create_app
@@ -11,6 +13,7 @@ class GeneralAPITest(unittest.TestCase):
def setUp(self):
self.app = create_app().test_client()
+ @pytest.mark.integration_test
def test_metadata_endpoint_exists(self):
"""Test that /metadata/upload exists"""
response = self.app.post("/api/metadata/upload/d41d86-e4ceEo")
@@ -19,6 +22,7 @@ class GeneralAPITest(unittest.TestCase):
{"status": 128,
"error": "Please provide a file!"})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.general.extract_uploaded_file")
def test_metadata_file_upload(self, mock_extract_upload):
"""Test correct upload of file"""
@@ -37,6 +41,7 @@ class GeneralAPITest(unittest.TestCase):
{"status": 0,
"token": "d41d86-e4ceEo"})
+ @pytest.mark.integration_test
def test_metadata_file_wrong_upload(self):
"""Test that incorrect upload return correct status code"""
response = self.app.post("/api/metadata/upload/d41d86-e4ceEo",
@@ -47,6 +52,7 @@ class GeneralAPITest(unittest.TestCase):
{"status": 128,
"error": "gzip failed to unpack file"})
+ @pytest.mark.integration_test
@mock.patch("gn3.api.general.run_cmd")
def test_run_r_qtl(self, mock_run_cmd):
"""Test correct upload of file"""
diff --git a/tests/integration/test_partial_correlations.py b/tests/integration/test_partial_correlations.py
new file mode 100644
index 0000000..4bf352a
--- /dev/null
+++ b/tests/integration/test_partial_correlations.py
@@ -0,0 +1,225 @@
+"""Test partial correlations"""
+from unittest import mock
+
+import pytest
+
+from gn3.computations.partial_correlations import partial_correlations_entry
+
+@pytest.mark.integration_test
+@pytest.mark.parametrize(
+ "post_data", (
+ None, {}, {
+ "primary_trait": None,
+ "control_traits": None,
+ "method": None,
+ "target_db": None
+ }, {
+ "primary_trait": None,
+ "control_traits": None,
+ "method": None,
+ "target_db": "a_db"
+ }, {
+ "primary_trait": None,
+ "control_traits": None,
+ "method": "a_method",
+ "target_db": None
+ }, {
+ "primary_trait": None,
+ "control_traits": None,
+ "method": "a_method",
+ "target_db": "a_db"
+ }, {
+ "primary_trait": None,
+ "control_traits": ["a_trait", "another"],
+ "method": None,
+ "target_db": None
+ }, {
+ "primary_trait": None,
+ "control_traits": ["a_trait", "another"],
+ "method": None,
+ "target_db": "a_db"
+ }, {
+ "primary_trait": None,
+ "control_traits": ["a_trait", "another"],
+ "method": "a_method",
+ "target_db": None
+ }, {
+ "primary_trait": None,
+ "control_traits": ["a_trait", "another"],
+ "method": "a_method",
+ "target_db": "a_db"
+ }, {
+ "primary_trait": "a_trait",
+ "control_traits": None,
+ "method": None,
+ "target_db": None
+ }, {
+ "primary_trait": "a_trait",
+ "control_traits": None,
+ "method": None,
+ "target_db": "a_db"
+ }, {
+ "primary_trait": "a_trait",
+ "control_traits": None,
+ "method": "a_method",
+ "target_db": None
+ }, {
+ "primary_trait": "a_trait",
+ "control_traits": None,
+ "method": "a_method",
+ "target_db": "a_db"
+ }, {
+ "primary_trait": "a_trait",
+ "control_traits": ["a_trait", "another"],
+ "method": None,
+ "target_db": None
+ }, {
+ "primary_trait": "a_trait",
+ "control_traits": ["a_trait", "another"],
+ "method": None,
+ "target_db": "a_db"
+ }, {
+ "primary_trait": "a_trait",
+ "control_traits": ["a_trait", "another"],
+ "method": "a_method",
+ "target_db": None
+ }))
+def test_partial_correlation_api_with_missing_request_data(client, post_data):
+ """
+ Test /api/correlations/partial endpoint with various expected request data
+ missing.
+ """
+ response = client.post("/api/correlation/partial", json=post_data)
+ assert (
+ response.status_code == 400 and response.is_json and
+ response.json.get("status") == "error")
+
+@pytest.mark.integration_test
+@pytest.mark.slow
+@pytest.mark.parametrize(
+ "post_data",
+ ({# ProbeSet
+ "primary_trait": {"dataset": "a_dataset", "trait_name": "a_name"},
+ "control_traits": [
+ {"dataset": "a_dataset", "trait_name": "a_name"},
+ {"dataset": "a_dataset2", "trait_name": "a_name2"}],
+ "method": "a_method",
+ "target_db": "a_db"
+ }, {# Publish
+ "primary_trait": {
+ "dataset": "a_Publish_dataset", "trait_name": "a_name"},
+ "control_traits": [
+ {"dataset": "a_dataset", "trait_name": "a_name"},
+ {"dataset": "a_dataset2", "trait_name": "a_name2"}],
+ "method": "a_method",
+ "target_db": "a_db"
+ }, {# Geno
+ "primary_trait": {"dataset": "a_Geno_dataset", "trait_name": "a_name"},
+ "control_traits": [
+ {"dataset": "a_dataset", "trait_name": "a_name"},
+ {"dataset": "a_dataset2", "trait_name": "a_name2"}],
+ "method": "a_method",
+ "target_db": "a_db"
+ }, {# Temp
+ "primary_trait": {"dataset": "a_Temp_dataset", "trait_name": "a_name"},
+ "control_traits": [
+ {"dataset": "a_dataset", "trait_name": "a_name"},
+ {"dataset": "a_dataset2", "trait_name": "a_name2"}],
+ "method": "a_method",
+ "target_db": "a_db"
+ }))
+def test_partial_correlation_api_with_non_existent_primary_traits(
+ client, post_data, mocker):
+ """
+ Check that the system responds appropriately in the case where the user
+ makes a request with a non-existent primary trait.
+ """
+ mocker.patch("gn3.api.correlation.redis.Redis", mock.MagicMock())
+ response = client.post("/api/correlation/partial", json=post_data)
+ assert (
+ response.status_code == 200 and response.is_json and
+ response.json.get("status") == "success")
+
+@pytest.mark.integration_test
+@pytest.mark.slow
+@pytest.mark.parametrize(
+ "post_data",
+ ({# ProbeSet
+ "primary_trait": {
+ "dataset": "UCLA_BXDBXH_CARTILAGE_V2",
+ "trait_name": "ILM103710672"},
+ "control_traits": [
+ {"dataset": "a_dataset", "trait_name": "a_name"},
+ {"dataset": "a_dataset2", "trait_name": "a_name2"}],
+ "method": "a_method",
+ "target_db": "a_db"
+ }, {# Publish
+ "primary_trait": {"dataset": "BXDPublish", "trait_name": "BXD_12557"},
+ "control_traits": [
+ {"dataset": "a_dataset", "trait_name": "a_name"},
+ {"dataset": "a_dataset2", "trait_name": "a_name2"}],
+ "method": "a_method",
+ "target_db": "a_db"
+ }, {# Geno
+ "primary_trait": {"dataset": "AKXDGeno", "trait_name": "D4Mit16"},
+ "control_traits": [
+ {"dataset": "a_dataset", "trait_name": "a_name"},
+ {"dataset": "a_dataset2", "trait_name": "a_name2"}],
+ "method": "a_method",
+ "target_db": "a_db"
+ }
+ # Temp -- the data in the database for these is ephemeral, making it
+ # difficult to test for this
+ ))
+def test_partial_correlation_api_with_non_existent_control_traits(client, post_data, mocker):
+ """
+ Check that the system responds appropriately in the case where the user
+ makes a request with a non-existent control traits.
+
+ The code repetition here is on purpose - valuing clarity over succinctness.
+ """
+ mocker.patch("gn3.api.correlation.redis.Redis", mock.MagicMock())
+ response = client.post("/api/correlation/partial", json=post_data)
+ assert (
+ response.status_code == 200 and response.is_json and
+ response.json.get("status") == "success")
+
+@pytest.mark.integration_test
+@pytest.mark.slow
+@pytest.mark.parametrize(
+ "primary,controls,method,target", (
+ (# Probeset
+ "UCLA_BXDBXH_CARTILAGE_V2::ILM103710672", (
+ "UCLA_BXDBXH_CARTILAGE_V2::nonExisting01",
+ "UCLA_BXDBXH_CARTILAGE_V2::nonExisting02",
+ "UCLA_BXDBXH_CARTILAGE_V2::ILM380019"),
+ "Genetic Correlation, Pearson's r", "BXDPublish"),
+ (# Publish
+ "BXDPublish::17937", (
+ "BXDPublish::17940",
+ "BXDPublish::nonExisting03"),
+ "Genetic Correlation, Spearman's rho", "BXDPublish"),
+ (# Geno
+ "AKXDGeno::D4Mit16", (
+ "AKXDGeno::D1Mit170",
+ "AKXDGeno::nonExisting04",
+ "AKXDGeno::D1Mit135",
+ "AKXDGeno::nonExisting05",
+ "AKXDGeno::nonExisting06"),
+ "SGO Literature Correlation", "BXDPublish")
+ )
+ # Temp -- the data in the database for these is ephemeral, making it
+ # difficult to test for these without a temp database with the temp
+ # traits data set to something we are in control of
+ )
+
+def test_part_corr_api_with_mix_of_existing_and_non_existing_control_traits(
+ db_conn, primary, controls, method, target):
+ """
+ Check that calling the function with a mix of existing and missing control
+ traits raises an warning.
+ """
+ criteria = 10
+ with pytest.warns(UserWarning):
+ partial_correlations_entry(
+ db_conn, primary, controls, method, criteria, target)
diff --git a/tests/integration/test_wgcna.py b/tests/integration/test_wgcna.py
index 078449d..5880b40 100644
--- a/tests/integration/test_wgcna.py
+++ b/tests/integration/test_wgcna.py
@@ -3,6 +3,8 @@
from unittest import TestCase
from unittest import mock
+import pytest
+
from gn3.app import create_app
@@ -12,6 +14,7 @@ class WgcnaIntegrationTest(TestCase):
def setUp(self):
self.app = create_app().test_client()
+ @pytest.mark.integration_test
@mock.patch("gn3.api.wgcna.call_wgcna_script")
def test_wgcna_endpoint(self, mock_wgcna_script):
"""test /api/wgcna/run_wgcna endpoint"""