From 8677d1b7bd5b32791c440bf0de2fc4c61c98299f Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Sun, 21 May 2017 07:21:44 +0000 Subject: Merge from the diet branch. * refactored ./bin/genenetwork2 and /etc/default_settings - better detection of Guix - removed unused parameters, such as GEMMA_RESULT_PATH and TEMP_TRAITS - removing some default settings, such as PYLMM_COMMAND - rename some settings, such as SQL_URI and LOG_SQL_ALCHEMY - added GUIX_JS_PATH for JS modules * Added documentation on installing binary GN2 * Updated Twitter board to latest version in Guix - it had broken * Updated many tools in the latest Guix profile --- test/lib/main_web_functionality.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'test') diff --git a/test/lib/main_web_functionality.rb b/test/lib/main_web_functionality.rb index ec61de2d..9ae49995 100644 --- a/test/lib/main_web_functionality.rb +++ b/test/lib/main_web_functionality.rb @@ -13,16 +13,20 @@ describe MainWebFunctionality do it "Get to trait page" do page = @agent.get($host) + p page form = page.forms[1] form.buttons[0].value.must_equal "Search" # main menu is loaded # http://localhost:5003/search?species=mouse&group=BXD&type=Hippocampus+mRNA&dataset=HC_M2_0606_P&search_terms_or=&search_terms_and=MEAN%3D%2815+16%29+LRS%3D%2823+46%29&FormID=searchResult + form.fields[0].value.must_equal "searchResult" form.fields[2].value = "MEAN=(15 16) LRS=(23 46)" form.fields[3].value = "mouse" form.fields[4].value = "BXD" form.fields[5].value = "Hippocampus mRNA" form.fields[6].value = "HC_M2_0606_P" search_page = @agent.submit(form, form.buttons.first) + p "==================" + p search_page probe_link = search_page.links.find { |l| l.text =~ /1435395_s_at/ } probe_link.uri.to_s.must_equal "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P" show_trait_page = probe_link.click -- cgit v1.2.3 From 4097723cfd6331f41d8b8e7abec322cb12f39f10 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Thu, 15 Feb 2018 14:03:38 +0000 Subject: Added unittest example --- test/unittest/test_registration.py | 27 +++++++++ wqflask/mock/__init__.py | 0 wqflask/mock/es_double.py | 15 +++++ wqflask/tests/__init__.py | 0 wqflask/tests/es_double.py | 30 ---------- wqflask/tests/test_registration.py | 113 ------------------------------------- 6 files changed, 42 insertions(+), 143 deletions(-) create mode 100644 test/unittest/test_registration.py create mode 100644 wqflask/mock/__init__.py create mode 100644 wqflask/mock/es_double.py delete mode 100644 wqflask/tests/__init__.py delete mode 100644 wqflask/tests/es_double.py delete mode 100644 wqflask/tests/test_registration.py (limited to 'test') diff --git a/test/unittest/test_registration.py b/test/unittest/test_registration.py new file mode 100644 index 00000000..98d0cdff --- /dev/null +++ b/test/unittest/test_registration.py @@ -0,0 +1,27 @@ +# Run test with something like +# +# env GN2_PROFILE=~/opt/gn-latest GENENETWORK_FILES=$HOME/gn2_data ./bin/genenetwork2 ./etc/default_settings.py -c ../test/unittest/test_registration.py +# + +import unittest +import mock.es_double as es +from wqflask.user_manager import RegisterUser + +class TestRegisterUser(unittest.TestCase): + def setUp(self): + self.es = es.ESDouble() + + def testRegisterUserWithCorrectData(self): + data = { + "email_address": "user@example.com" + , "full_name": "A.N. Other" + , "organization": "Some Organisation" + , "password": "testing" + , "password_confirm": "testing" + , "es_connection": self.es + } + result = RegisterUser(data) + self.assertEqual(len(result.errors), 0, "Errors were not expected") + +if __name__ == "__main__": + unittest.main() diff --git a/wqflask/mock/__init__.py b/wqflask/mock/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/wqflask/mock/es_double.py b/wqflask/mock/es_double.py new file mode 100644 index 00000000..6ef8a1b9 --- /dev/null +++ b/wqflask/mock/es_double.py @@ -0,0 +1,15 @@ +class ESDouble(object): + def __init__(self): + self.items = {} + + def ping(self): + return true + + def create(self, index, doc_type, body, id): + self.items["index"] = {doc_type: {"id": id, "_source": data}} + + def search(self, index, doc_type, body): + return { + "hits": { + "hits": self.items[index][doc_type][body] + }} diff --git a/wqflask/tests/__init__.py b/wqflask/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/wqflask/tests/es_double.py b/wqflask/tests/es_double.py deleted file mode 100644 index 00739016..00000000 --- a/wqflask/tests/es_double.py +++ /dev/null @@ -1,30 +0,0 @@ -class ESDouble(object): - def __init__(self): - self.items = { - "users": { - "local": [] - }} - - def ping(self): - return true - - def create(self, index, doc_type, body, id): - item = {"id": id, "_source": body} - if not self.items.get("index", None): - self.items[index] = {doc_type: [item]} - else: - self.items[index][doc_type].append(item) - - def search(self, index, doc_type, body): - d = body["query"]["match"] - column = [(key, d[key]) for key in d] - - items = [] - for thing in self.items[index][doc_type]: - if thing["_source"][column[0][0]] == column[0][1]: - items.append(thing) - break - return { - "hits": { - "hits": items - }} diff --git a/wqflask/tests/test_registration.py b/wqflask/tests/test_registration.py deleted file mode 100644 index 50a2a84c..00000000 --- a/wqflask/tests/test_registration.py +++ /dev/null @@ -1,113 +0,0 @@ -import unittest -import es_double -import wqflask.user_manager -from wqflask.user_manager import RegisterUser - -class TestRegisterUser(unittest.TestCase): - def setUp(self): - # Mock elasticsearch - self.es = es_double.ESDouble() - - # Patch method - wqflask.user_manager.basic_info = lambda : {"basic_info": "some info"} - - def tearDown(self): - self.es = None - - def testRegisterUserWithNoData(self): - data = {} - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Data was not provided. Error was expected") - - def testRegisterUserWithNoEmail(self): - data = { - "email_address": "" - , "full_name": "A.N. Other" - , "organization": "Some Organisation" - , "password": "testing" - , "password_confirm": "testing" - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Email not provided. Error was expected") - - def testRegisterUserWithNoName(self): - data = { - "email_address": "user@example.com" - , "full_name": "" - , "organization": "Some Organisation" - , "password": "testing" - , "password_confirm": "testing" - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Name not provided. Error was expected") - - def testRegisterUserWithNoOrganisation(self): - data = { - "email_address": "user@example.com" - , "full_name": "A.N. Other" - , "organization": "" - , "password": "testing" - , "password_confirm": "testing" - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertEqual(len(result.errors), 0, "Organisation not provided. Error not expected") - - def testRegisterUserWithShortOrganisation(self): - data = { - "email_address": "user@example.com" - , "full_name": "A.N. Other" - , "organization": "SO" - , "password": "testing" - , "password_confirm": "testing" - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Organisation name too short. Error expected") - - def testRegisterUserWithNoPassword(self): - data = { - "email_address": "user@example.com" - , "full_name": "A.N. Other" - , "organization": "Some Organisation" - , "password": None - , "password_confirm": None - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Password not provided. Error was expected") - - def testRegisterUserWithNonMatchingPasswords(self): - data = { - "email_address": "user@example.com" - , "full_name": "A.N. Other" - , "organization": "Some Organisation" - , "password": "testing" - , "password_confirm": "stilltesting" - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Password mismatch. Error was expected") - - def testRegisterUserWithCorrectData(self): - data = { - "email_address": "user@example.com" - , "full_name": "A.N. Other" - , "organization": "Some Organisation" - , "password": "testing" - , "password_confirm": "testing" - , "es_connection": self.es - } - result = RegisterUser(data) - self.assertEqual(len(result.errors), 0, "All data items provided. Errors were not expected") - -if __name__ == "__main__": - unittest.main() -- cgit v1.2.3 From 3a26e0fb7b88cd9c105a1f7e9ca9d5a8b2130d82 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Thu, 15 Feb 2018 15:00:47 +0000 Subject: Requests added --- bin/genenetwork2 | 10 ++-- bin/mechnical-rob | 111 ++++++++++++++++++++++++++++++++++++++++ bin/test-website | 114 ++---------------------------------------- test/requests/test-website.py | 20 ++++++++ 4 files changed, 142 insertions(+), 113 deletions(-) create mode 100755 bin/mechnical-rob create mode 100755 test/requests/test-website.py (limited to 'test') diff --git a/bin/genenetwork2 b/bin/genenetwork2 index 42f79650..2a83a1cd 100755 --- a/bin/genenetwork2 +++ b/bin/genenetwork2 @@ -168,8 +168,9 @@ if [ "$1" = '-c' ] ; then cd $GN2_BASE_DIR/wqflask cmd=${2#wqflask/} echo PYTHONPATH=$PYTHONPATH - echo RUNNING COMMAND $cmd - python $cmd + shift ; shift + echo RUNNING COMMAND $cmd $* + python $cmd $* exit $? fi # Now handle command parameter -cli which runs in bash @@ -178,8 +179,9 @@ if [ "$1" = "-cli" ] ; then cd $GN2_BASE_DIR/wqflask cmd=$2 echo PYTHONPATH=$PYTHONPATH - echo RUNNING COMMAND $cmd - $cmd + shift ; shift + echo RUNNING COMMAND $cmd $* + $cmd $* exit $? fi if [ "$1" = '-gunicorn' ] ; then diff --git a/bin/mechnical-rob b/bin/mechnical-rob new file mode 100755 index 00000000..be223d94 --- /dev/null +++ b/bin/mechnical-rob @@ -0,0 +1,111 @@ +#!/usr/bin/env ruby + + +USAGE = <0 + ARGV.shift + else + "http://localhost:5003" + end + +$stderr.print "Testing <",$host,">\n" + +require 'mechanize' +require 'minitest/spec' +require 'minitest/autorun' + +# These are the actual testing modules + +libpath = File.dirname(File.dirname(__FILE__)) +$: << File.join(libpath,'test/lib') + +require 'main_web_functionality' + +if options[:all] or options[:mapping] + require 'mapping' +end + +if options[:all] or options[:link_checker] + require 'link_checker' +end + +if options[:all] or options[:navigation] + require 'navigation' +end diff --git a/bin/test-website b/bin/test-website index be223d94..5935f016 100755 --- a/bin/test-website +++ b/bin/test-website @@ -1,111 +1,7 @@ -#!/usr/bin/env ruby +#! /bin/bash - -USAGE = <0 - ARGV.shift - else - "http://localhost:5003" - end - -$stderr.print "Testing <",$host,">\n" - -require 'mechanize' -require 'minitest/spec' -require 'minitest/autorun' - -# These are the actual testing modules - -libpath = File.dirname(File.dirname(__FILE__)) -$: << File.join(libpath,'test/lib') - -require 'main_web_functionality' - -if options[:all] or options[:mapping] - require 'mapping' -end - -if options[:all] or options[:link_checker] - require 'link_checker' -end - -if options[:all] or options[:navigation] - require 'navigation' -end +fi diff --git a/test/requests/test-website.py b/test/requests/test-website.py new file mode 100755 index 00000000..d02b71aa --- /dev/null +++ b/test/requests/test-website.py @@ -0,0 +1,20 @@ +# Run with something like +# +# env GN2_PROFILE=/home/wrk/opt/gn-latest ./bin/genenetwork2 ./etc/default_settings.py -c ../test/requests/test-website.py http://localhost:5003 +# +# Mostly to pick up the Guix GN2_PROFILE and python modules + +import requests as req +import sys + +print "Mechanical Rob firing up..." + +if len(sys.argv)<1: + raise "Problem with arguments" + +url = sys.argv[1] +print url + +r = req.get(url) + +print r -- cgit v1.2.3 From 2ac52ea39a7a8db6cab756e3af2f65b228bb1c09 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 16 Feb 2018 14:22:17 +0300 Subject: Add registration test * Add integration test to check the registration process. --- test/requests/test-registration.py | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 test/requests/test-registration.py (limited to 'test') diff --git a/test/requests/test-registration.py b/test/requests/test-registration.py new file mode 100644 index 00000000..bcb1642f --- /dev/null +++ b/test/requests/test-registration.py @@ -0,0 +1,59 @@ +import sys +import unittest +import requests +import logging +from elasticsearch import Elasticsearch, TransportError +#from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT + +GN2_SERVER = None +ES_SERVER = None + +class TestRegistration(unittest.TestCase): + + + def setUp(self): + self.url = GN2_SERVER+"/n/register" + self.es = Elasticsearch([ES_SERVER]) + self.es_cleanup = [] + + es_logger = logging.getLogger("elasticsearch") + es_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationInfo.log")) + es_trace_logger = logging.getLogger("elasticsearch.trace") + es_trace_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationTrace.log")) + + def tearDown(self): + for item in self.es_cleanup: + self.es.delete(index="users", doc_type="local", id=item["_id"]) + + def testRegistrationPage(self): + if self.es.ping(): + data = { + "email_address": "test@user.com", + "full_name": "Test User", + "organization": "Test Organisation", + "password": "test_password", + "password_confirm": "test_password" + } + requests.post(self.url, data) + response = self.es.search( + index="users" + , doc_type="local" + , body={ + "query": {"match": {"email_address": "test@user.com"}}}) + self.assertEqual(len(response["hits"]["hits"]), 1) + self.es_cleanup.append(response["hits"]["hits"][0]) + else: + self.skipTest("The elasticsearch server is down") + +def main(): + suite = unittest.TestSuite() + suite.addTest(TestRegistration("testRegistrationPage")) + runner = unittest.TextTestRunner() + runner.run(suite) + +if __name__ == "__main__": + GN2_SERVER = sys.argv[1] + ES_SERVER = sys.argv[2] + main() -- cgit v1.2.3 From 5dd7e61c43bac52ae52735c38c337a5a198c6c39 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:46:47 +0300 Subject: Rename file and move common code * Rename the file to make it an importable module * Refactor the test to move common code out to a super class. --- test/requests/test-registration.py | 59 -------------------------------------- test/requests/test_registration.py | 41 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 59 deletions(-) delete mode 100644 test/requests/test-registration.py create mode 100644 test/requests/test_registration.py (limited to 'test') diff --git a/test/requests/test-registration.py b/test/requests/test-registration.py deleted file mode 100644 index bcb1642f..00000000 --- a/test/requests/test-registration.py +++ /dev/null @@ -1,59 +0,0 @@ -import sys -import unittest -import requests -import logging -from elasticsearch import Elasticsearch, TransportError -#from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT - -GN2_SERVER = None -ES_SERVER = None - -class TestRegistration(unittest.TestCase): - - - def setUp(self): - self.url = GN2_SERVER+"/n/register" - self.es = Elasticsearch([ES_SERVER]) - self.es_cleanup = [] - - es_logger = logging.getLogger("elasticsearch") - es_logger.addHandler( - logging.FileHandler("/tmp/es_TestRegistrationInfo.log")) - es_trace_logger = logging.getLogger("elasticsearch.trace") - es_trace_logger.addHandler( - logging.FileHandler("/tmp/es_TestRegistrationTrace.log")) - - def tearDown(self): - for item in self.es_cleanup: - self.es.delete(index="users", doc_type="local", id=item["_id"]) - - def testRegistrationPage(self): - if self.es.ping(): - data = { - "email_address": "test@user.com", - "full_name": "Test User", - "organization": "Test Organisation", - "password": "test_password", - "password_confirm": "test_password" - } - requests.post(self.url, data) - response = self.es.search( - index="users" - , doc_type="local" - , body={ - "query": {"match": {"email_address": "test@user.com"}}}) - self.assertEqual(len(response["hits"]["hits"]), 1) - self.es_cleanup.append(response["hits"]["hits"][0]) - else: - self.skipTest("The elasticsearch server is down") - -def main(): - suite = unittest.TestSuite() - suite.addTest(TestRegistration("testRegistrationPage")) - runner = unittest.TextTestRunner() - runner.run(suite) - -if __name__ == "__main__": - GN2_SERVER = sys.argv[1] - ES_SERVER = sys.argv[2] - main() diff --git a/test/requests/test_registration.py b/test/requests/test_registration.py new file mode 100644 index 00000000..0047e8a6 --- /dev/null +++ b/test/requests/test_registration.py @@ -0,0 +1,41 @@ +import sys +import requests +from parametrized_test import ParametrizedTest + +class TestRegistration(ParametrizedTest): + + def tearDown(self): + for item in self.es_cleanup: + self.es.delete(index="users", doc_type="local", id=item["_id"]) + + def testRegistrationPage(self): + if self.es.ping(): + data = { + "email_address": "test@user.com", + "full_name": "Test User", + "organization": "Test Organisation", + "password": "test_password", + "password_confirm": "test_password" + } + requests.post(self.gn2_url+"/n/register", data) + response = self.es.search( + index="users" + , doc_type="local" + , body={ + "query": {"match": {"email_address": "test@user.com"}}}) + self.assertEqual(len(response["hits"]["hits"]), 1) + else: + self.skipTest("The elasticsearch server is down") + +def main(gn2, es): + import unittest + suite = unittest.TestSuite() + suite.addTest(TestRegistration(methodName="testRegistrationPage", gn2_url=gn2, es_url=es)) + runner = unittest.TextTestRunner() + runner.run(suite) + +if __name__ == "__main__": + if len(sys.argv) < 3: + raise Exception("Required arguments missing") + else: + main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From 230bf08f9aac697fc4c8dc092348be3b7026046f Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:48:36 +0300 Subject: Create parametrized superclass for tests * Since the tests require that some parameters be provided while running the tests, create a class that helps abstract away the details of retrieving and setting the expected parameters. --- test/requests/parametrized_test.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 test/requests/parametrized_test.py (limited to 'test') diff --git a/test/requests/parametrized_test.py b/test/requests/parametrized_test.py new file mode 100644 index 00000000..abf98fce --- /dev/null +++ b/test/requests/parametrized_test.py @@ -0,0 +1,27 @@ +import logging +import unittest +from elasticsearch import Elasticsearch, TransportError + +class ParametrizedTest(unittest.TestCase): + + def __init__(self, methodName='runTest', gn2_url="http://localhost:5003", es_url="localhost:9200"): + super(ParametrizedTest, self).__init__(methodName=methodName) + self.gn2_url = gn2_url + self.es_url = es_url + + def setUp(self): + self.es = Elasticsearch([self.es_url]) + self.es_cleanup = [] + + es_logger = logging.getLogger("elasticsearch") + es_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationInfo.log")) + es_trace_logger = logging.getLogger("elasticsearch.trace") + es_trace_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationTrace.log")) + + def tearDown(self): + self.es.delete_by_query( + index="users" + , doc_type="local" + , body={"query":{"match":{"email_address":"test@user.com"}}}) -- cgit v1.2.3 From 8c4833dbf9f4ae32afbfbe6a3cb8e4630abc3d25 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:50:30 +0300 Subject: Add test for local login * Add an integration test to test that the login process for users registered locally to genenetwork2 works as expected. --- test/requests/test_login_local.py | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 test/requests/test_login_local.py (limited to 'test') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py new file mode 100644 index 00000000..bced1ee9 --- /dev/null +++ b/test/requests/test_login_local.py @@ -0,0 +1,56 @@ +import requests +from wqflask import user_manager +from parametrized_test import ParametrizedTest + +class TestLoginLocal(ParametrizedTest): + + def setUp(self): + super(TestLoginLocal, self).setUp() + self.login_url = self.gn2_url +"/n/login" + data = { + "es_connection": self.es, + "email_address": "test@user.com", + "full_name": "Test User", + "organization": "Test Organisation", + "password": "test_password", + "password_confirm": "test_password" + } + user_manager.basic_info = lambda : { "basic_info": "basic" } + user_manager.RegisterUser(data) + + def testLoginNonRegisteredUser(self): + data = { + "email_address": "non@existent.email", + "password": "doesitmatter?" + } + result = requests.post(self.login_url, data=data) + self.assertEqual(result.url, self.login_url, "") + + def testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse(self): + data = { + "email_address": "test@user.com", + "password": "test_password" + } + result = requests.post(self.login_url, data=data) + print("THE COOKIES? ", result.cookies) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=false" + , "Login should have been successful") + + + +def main(gn2, es): + import unittest + suite = unittest.TestSuite() + suite.addTest(TestLoginLocal(methodName="testLoginNonRegisteredUser", gn2_url=gn2, es_url=es)) + suite.addTest(TestLoginLocal(methodName="testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse", gn2_url=gn2, es_url=es)) + runner = unittest.TextTestRunner() + runner.run(suite) + +if __name__ == "__main__": + import sys + if len(sys.argv) < 3: + raise Exception("Required arguments missing") + else: + main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From 85015343fd99885ec00db86b4e3705bcc25e62f1 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:52:32 +0300 Subject: Add a runner for all integration tests. --- test/requests/run-integration-tests.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 test/requests/run-integration-tests.py (limited to 'test') diff --git a/test/requests/run-integration-tests.py b/test/requests/run-integration-tests.py new file mode 100644 index 00000000..0fd7bb20 --- /dev/null +++ b/test/requests/run-integration-tests.py @@ -0,0 +1,30 @@ +import sys +from test_login_local import TestLoginLocal +from test_registration import TestRegistration +from unittest import TestSuite, TextTestRunner, TestLoader + +test_cases = [ + TestLoginLocal, + TestRegistration +] + +def suite(gn2_url, es_url): + the_suite = TestSuite() + for case in test_cases: + the_suite.addTests(initTest(case, gn2_url, es_url)) + return the_suite + +def initTest(klass, gn2_url, es_url): + loader = TestLoader() + methodNames = loader.getTestCaseNames(klass) + return [klass(mname, gn2_url, es_url) for mname in methodNames] + +def main(gn2_url, es_url): + runner = TextTestRunner() + runner.run(suite(gn2_url, es_url)) + +if __name__ == "__main__": + if len(sys.argv) < 3: + raise Exception("Required arguments missing:\n\tTry running `run-integration-test.py `") + else: + main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From 2035387823ffc87bc2b6a817a06cb3a47aa006a0 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 14:12:59 +0300 Subject: Add more login tests. --- test/requests/test_login_local.py | 39 +++++++++++++++++++++++++++++++++++++-- wqflask/wqflask/user_manager.py | 2 -- 2 files changed, 37 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py index bced1ee9..acad45c9 100644 --- a/test/requests/test_login_local.py +++ b/test/requests/test_login_local.py @@ -32,12 +32,47 @@ class TestLoginLocal(ParametrizedTest): "password": "test_password" } result = requests.post(self.login_url, data=data) - print("THE COOKIES? ", result.cookies) self.assertEqual( result.url , self.gn2_url+"/?import_collections=false" , "Login should have been successful") - + + def testLoginWithRegisteredUserImportCollectionsTrueAndRememberMeFalse(self): + data = { + "email_address": "test@user.com", + "password": "test_password", + "import_collections": "y" + } + result = requests.post(self.login_url, data=data) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=true" + , "Login should have been successful") + + def testLoginWithRegisteredUserImportCollectionsFalseAndRememberMeTrue(self): + data = { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y" + } + result = requests.post(self.login_url, data=data) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=false" + , "Login should have been successful") + + def testLoginWithRegisteredUserBothImportCollectionsAndRememberMeTrue(self): + data = { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y", + "import_collections": "y" + } + result = requests.post(self.login_url, data=data) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=true" + , "Login should have been successful") def main(gn2, es): diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index c8471cb1..fd1d56ff 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -642,7 +642,6 @@ class LoginUser(object): user = model.User(); for key in user_details: user.__dict__[key] = user_details[key] - print("RETRIEVED USER: ", user) valid = False; submitted_password = params['password'] @@ -689,7 +688,6 @@ class LoginUser(object): """The meat of the logging in process""" session_id_signed = self.successful_login(user, assumed_by) flash("Thank you for logging in {}.".format(user.full_name), "alert-success") - print("IMPORT1:", import_collections) response = make_response(redirect(url_for('index_page', import_collections=import_collections))) if self.remember_me: max_age = self.remember_time -- cgit v1.2.3 From a8e328a105dac1d137c3d08653c9164d489332b3 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Wed, 21 Feb 2018 12:51:34 +0300 Subject: Simplify test. Check for content, rather than url * The test functions were very similar, so this commit refactors out the common test code to a single method, and passes in the data to the test using the parameterized package. * Check that the page content after a login attempt is the expected content, rather than checking the url. --- test/requests/test_login_local.py | 93 ++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 54 deletions(-) (limited to 'test') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py index acad45c9..8e2dec4e 100644 --- a/test/requests/test_login_local.py +++ b/test/requests/test_login_local.py @@ -1,7 +1,11 @@ import requests from wqflask import user_manager +from parameterized import parameterized from parametrized_test import ParametrizedTest +login_link_text = 'Sign in' +logout_link_text = 'Sign out' + class TestLoginLocal(ParametrizedTest): def setUp(self): @@ -18,61 +22,42 @@ class TestLoginLocal(ParametrizedTest): user_manager.basic_info = lambda : { "basic_info": "basic" } user_manager.RegisterUser(data) - def testLoginNonRegisteredUser(self): - data = { - "email_address": "non@existent.email", - "password": "doesitmatter?" - } - result = requests.post(self.login_url, data=data) - self.assertEqual(result.url, self.login_url, "") - - def testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse(self): - data = { - "email_address": "test@user.com", - "password": "test_password" - } - result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=false" - , "Login should have been successful") - - def testLoginWithRegisteredUserImportCollectionsTrueAndRememberMeFalse(self): - data = { - "email_address": "test@user.com", - "password": "test_password", - "import_collections": "y" - } - result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=true" - , "Login should have been successful") - - def testLoginWithRegisteredUserImportCollectionsFalseAndRememberMeTrue(self): - data = { - "email_address": "test@user.com", - "password": "test_password", - "remember_me": "y" - } - result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=false" - , "Login should have been successful") - - def testLoginWithRegisteredUserBothImportCollectionsAndRememberMeTrue(self): - data = { - "email_address": "test@user.com", - "password": "test_password", - "remember_me": "y", - "import_collections": "y" - } + + @parameterized.expand([ + ( + { + "email_address": "non@existent.email", + "password": "doesitmatter?" + }, login_link_text, "Login should have failed with the wrong user details."), + ( + { + "email_address": "test@user.com", + "password": "test_password" + }, logout_link_text, "Login should have been successful with correct user details and neither import_collections nor remember_me set"), + ( + { + "email_address": "test@user.com", + "password": "test_password", + "import_collections": "y" + }, logout_link_text, "Login should have been successful with correct user details and only import_collections set"), + ( + { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y" + }, logout_link_text, "Login should have been successful with correct user details and only remember_me set"), + ( + { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y", + "import_collections": "y" + }, logout_link_text, "Login should have been successful with correct user details, and both remember_me, and import_collections set") + ]) + def testLogin(self, data, expected, message): result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=true" - , "Login should have been successful") + index = result.content.find(expected) + self.assertTrue(index >= 0, message) def main(gn2, es): -- cgit v1.2.3 From a88f9c25e1b6eaaeede23d9217b1998f28fa7bbf Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 17:24:55 +0300 Subject: Remove failing code * With the parameterized module, the testcase cannot be run independently at this time. --- test/requests/test_login_local.py | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'test') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py index 8e2dec4e..808649ca 100644 --- a/test/requests/test_login_local.py +++ b/test/requests/test_login_local.py @@ -58,19 +58,3 @@ class TestLoginLocal(ParametrizedTest): result = requests.post(self.login_url, data=data) index = result.content.find(expected) self.assertTrue(index >= 0, message) - - -def main(gn2, es): - import unittest - suite = unittest.TestSuite() - suite.addTest(TestLoginLocal(methodName="testLoginNonRegisteredUser", gn2_url=gn2, es_url=es)) - suite.addTest(TestLoginLocal(methodName="testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse", gn2_url=gn2, es_url=es)) - runner = unittest.TextTestRunner() - runner.run(suite) - -if __name__ == "__main__": - import sys - if len(sys.argv) < 3: - raise Exception("Required arguments missing") - else: - main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From 4d7c565aac196ba1913b65ed27481c6974f1a0b5 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 17:26:42 +0300 Subject: Add new test for github logins --- test/requests/run-integration-tests.py | 4 +++- test/requests/test_login_github.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/requests/test_login_github.py (limited to 'test') diff --git a/test/requests/run-integration-tests.py b/test/requests/run-integration-tests.py index 0fd7bb20..fc795779 100644 --- a/test/requests/run-integration-tests.py +++ b/test/requests/run-integration-tests.py @@ -1,11 +1,13 @@ import sys from test_login_local import TestLoginLocal +from test_login_github import TestLoginGithub from test_registration import TestRegistration from unittest import TestSuite, TextTestRunner, TestLoader test_cases = [ - TestLoginLocal, TestRegistration + , TestLoginLocal + , TestLoginGithub ] def suite(gn2_url, es_url): diff --git a/test/requests/test_login_github.py b/test/requests/test_login_github.py new file mode 100644 index 00000000..15bf18ae --- /dev/null +++ b/test/requests/test_login_github.py @@ -0,0 +1,40 @@ +import uuid +import requests +from time import sleep +from parameterized import parameterized +from parametrized_test import ParametrizedTest + +login_link_text = 'Sign in' +logout_link_text = 'Sign out' +uid = str(uuid.uuid4()) + +class TestLoginGithub(ParametrizedTest): + + def setUp(self): + super(TestLoginGithub, self).setUp() + data = { + "user_id": uid + , "name": "A. T. Est User" + , "github_id": 693024 + , "user_url": "https://fake-github.com/atestuser" + , "login_type": "github" + , "organization": "" + , "active": 1 + , "confirmed": 1 + } + self.es.create(index="users", doc_type="local", body=data, id=uid) + sleep(1) + + def tearDown(self): + super(TestLoginGithub, self).tearDown() + self.es.delete(index="users", doc_type="local", id=uid) + + @parameterized.expand([ + ("1234", login_link_text, "Login should have failed with non-existing user") + , (uid, logout_link_text, "Login should have been successful with existing user") + ]) + def testLogin(self, test_uid, expected, message): + url = self.gn2_url+"/n/login?type=github&uid="+test_uid + result = requests.get(url) + index = result.content.find(expected) + self.assertTrue(index >= 0, message) -- cgit v1.2.3 From 4d656976eae920066261e26bf22a999d90a0beab Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 17:36:29 +0300 Subject: Add new tests for orcid logins --- test/requests/run-integration-tests.py | 2 ++ test/requests/test_login_orcid.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/requests/test_login_orcid.py (limited to 'test') diff --git a/test/requests/run-integration-tests.py b/test/requests/run-integration-tests.py index fc795779..5e816549 100644 --- a/test/requests/run-integration-tests.py +++ b/test/requests/run-integration-tests.py @@ -1,5 +1,6 @@ import sys from test_login_local import TestLoginLocal +from test_login_orcid import TestLoginOrcid from test_login_github import TestLoginGithub from test_registration import TestRegistration from unittest import TestSuite, TextTestRunner, TestLoader @@ -8,6 +9,7 @@ test_cases = [ TestRegistration , TestLoginLocal , TestLoginGithub + , TestLoginOrcid ] def suite(gn2_url, es_url): diff --git a/test/requests/test_login_orcid.py b/test/requests/test_login_orcid.py new file mode 100644 index 00000000..6e40ece5 --- /dev/null +++ b/test/requests/test_login_orcid.py @@ -0,0 +1,40 @@ +import uuid +import requests +from time import sleep +from parameterized import parameterized +from parametrized_test import ParametrizedTest + +login_link_text = 'Sign in' +logout_link_text = 'Sign out' +uid = str(uuid.uuid4()) + +class TestLoginOrcid(ParametrizedTest): + + def setUp(self): + super(TestLoginOrcid, self).setUp() + data = { + "user_id": uid + , "name": "A. T. Est User" + , "orcid": 345872 + , "user_url": "https://fake-orcid.org/atestuser" + , "login_type": "orcid" + , "organization": "" + , "active": 1 + , "confirmed": 1 + } + self.es.create(index="users", doc_type="local", body=data, id=uid) + sleep(1) + + def tearDown(self): + super(TestLoginOrcid, self).tearDown() + self.es.delete(index="users", doc_type="local", id=uid) + + @parameterized.expand([ + ("1234", login_link_text, "Login should have failed with non-existing user") + , (uid, logout_link_text, "Login should have been successful with existing user") + ]) + def testLogin(self, test_uid, expected, message): + url = self.gn2_url+"/n/login?type=orcid&uid="+test_uid + result = requests.get(url) + index = result.content.find(expected) + self.assertTrue(index >= 0, message) -- cgit v1.2.3 From 1f591baa129a7a42d6c0cadf73441274c8e373d3 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 18:11:33 +0300 Subject: Add tests to check that the UI is setup correctly * Check that the links for OAuth2 logins via ORCID and GitHub are setup correctly. --- test/requests/test_login_github.py | 7 +++++++ test/requests/test_login_orcid.py | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'test') diff --git a/test/requests/test_login_github.py b/test/requests/test_login_github.py index 15bf18ae..1bf4f695 100644 --- a/test/requests/test_login_github.py +++ b/test/requests/test_login_github.py @@ -1,6 +1,7 @@ import uuid import requests from time import sleep +from wqflask import app from parameterized import parameterized from parametrized_test import ParametrizedTest @@ -29,6 +30,12 @@ class TestLoginGithub(ParametrizedTest): super(TestLoginGithub, self).tearDown() self.es.delete(index="users", doc_type="local", id=uid) + def testLoginUrl(self): + login_button_text = 'Login with Github' + result = requests.get(self.gn2_url+"/n/login") + index = result.content.find(login_button_text) + self.assertTrue(index >= 0, "Should have found `Login with Github` button") + @parameterized.expand([ ("1234", login_link_text, "Login should have failed with non-existing user") , (uid, logout_link_text, "Login should have been successful with existing user") diff --git a/test/requests/test_login_orcid.py b/test/requests/test_login_orcid.py index 6e40ece5..ea15642e 100644 --- a/test/requests/test_login_orcid.py +++ b/test/requests/test_login_orcid.py @@ -1,6 +1,7 @@ import uuid import requests from time import sleep +from wqflask import app from parameterized import parameterized from parametrized_test import ParametrizedTest @@ -29,6 +30,12 @@ class TestLoginOrcid(ParametrizedTest): super(TestLoginOrcid, self).tearDown() self.es.delete(index="users", doc_type="local", id=uid) + def testLoginUrl(self): + login_button_text = 'a href="https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=' + app.config.get("ORCID_CLIENT_ID") + '&client_secret=' + app.config.get("ORCID_CLIENT_SECRET") + '" title="Login with ORCID" class="btn btn-info btn-group">Login with ORCID' + result = requests.get(self.gn2_url+"/n/login") + index = result.content.find(login_button_text) + self.assertTrue(index >= 0, "Should have found `Login with ORCID` button") + @parameterized.expand([ ("1234", login_link_text, "Login should have failed with non-existing user") , (uid, logout_link_text, "Login should have been successful with existing user") -- cgit v1.2.3 From 34fa7690fe2255d44b129c7d2397113d713342b6 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 9 Mar 2018 18:12:58 +0300 Subject: Use argparse to handle arguments * Use argparse to handle commandline arguments. * Create initial layout of how the code might end up - lots of the code is currently commented out. --- test/requests/test-website.py | 60 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/requests/test-website.py b/test/requests/test-website.py index d02b71aa..9637b87f 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -3,18 +3,60 @@ # env GN2_PROFILE=/home/wrk/opt/gn-latest ./bin/genenetwork2 ./etc/default_settings.py -c ../test/requests/test-website.py http://localhost:5003 # # Mostly to pick up the Guix GN2_PROFILE and python modules +from __future__ import print_function +from link_checker import check_links +import argparse -import requests as req -import sys +print("Mechanical Rob firing up...") -print "Mechanical Rob firing up..." +def run_all(args_obj, parser): + print("") + print("Running all tests.") + check_links(args_obj, parser) + # TODO: Add other functions as they are created. -if len(sys.argv)<1: - raise "Problem with arguments" +def print_help(args_obj, parser): + print(parser.format_help()) -url = sys.argv[1] -print url +def dummy(args_obj, parser): + print("Not implemented yet.") -r = req.get(url) -print r +desc = """ +This is Mechanical-Rob - an automated web server tester for + Genenetwork.org +""" +parser = argparse.ArgumentParser(description=desc) + +parser.add_argument("-d", "--database", metavar="DB", type=str + , default="db_webqtl_s" + , help="Use database (default db_webqtl_s)") + +parser.add_argument("host", metavar="HOST", type=str + , default="http://localhost:5003" + , help="The url to the web server") + +parser.add_argument("-a", "--all", dest="accumulate", action="store_const" + , const=run_all, default=print_help + , help="Runs all tests.") + +parser.add_argument("-l", "--link-checker", dest="accumulate" + , action='store_const', const=check_links, default=print_help + , help="Checks for dead links.") + +# parser.add_argument("-n", "--navigation", dest="accumulate" +# , action="store_const", const=check_navigation, default=print_help +# , help="Checks for navigation.") + +# parser.add_argument("-m", "--mapping", dest="accumulate" +# , action="store_const", const=check_mapping, default=print_help +# , help="Checks for mapping.") + +# parser.add_argument("-s", "--skip-broken", dest="accumulate" +# , action="store_const", const=dummy, default=print_help +# , help="Skip tests that are known to be broken.") + +args = parser.parse_args() +# print("The arguments object: ", args) + +args.accumulate(args, parser) -- cgit v1.2.3 From e147bc1ec354f9e07b7887109967afe8aae87f5b Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 9 Mar 2018 18:15:19 +0300 Subject: Add link_checker module * Add the module that will hold the code to test the links on the system. --- test/requests/link_checker.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 test/requests/link_checker.py (limited to 'test') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py new file mode 100644 index 00000000..f171c12a --- /dev/null +++ b/test/requests/link_checker.py @@ -0,0 +1,9 @@ +import requests + +def check_links(args_obj, parser): + print("") + print("Checking links") + print("########################") + print("Not implemented yet.") + print("This is supposed to check all links in the system.") + print("########################") -- cgit v1.2.3 From 655e741375b3fad7e3b7657662d33ca8017c0220 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 12 Mar 2018 13:00:03 +0300 Subject: Add tests to check links. --- test/requests/link_checker.py | 62 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py index f171c12a..256bf6ef 100644 --- a/test/requests/link_checker.py +++ b/test/requests/link_checker.py @@ -1,9 +1,63 @@ +from __future__ import print_function +import re import requests +from lxml.html import parse +from requests.exceptions import ConnectionError + +def is_root_link(link): + pattern = re.compile("^/$") + return pattern.match(link) + +def is_mailto_link(link): + pattern = re.compile("^mailto:.*") + return pattern.match(link) + +def is_internal_link(link): + pattern = re.compile("^/.*") + return pattern.match(link) + +def get_links(doc): + return filter( + lambda x: not ( + is_root_link(x) + or is_mailto_link(x)) + , map(lambda y: y.get("href") + , doc.cssselect("a"))) + +def verify_link(link): + try: + result = requests.get(link, timeout=20) + if result.status_code == 200: + print(link+" ==> OK") + else: + print("ERROR: link `"+link+"` failed with status " + , result.status_code) + except ConnectionError as ex: + print("ERROR: ", link, ex) + +def check_page(host, start_url): + print("") + print("Checking links in page `"+start_url+"`") + doc = parse(start_url).getroot() + links = get_links(doc) + internal_links = filter(is_internal_link, links) + external_links = filter(lambda x: not is_internal_link(x), links) + external_links.append("http://somenon-existentsite.brr") + for link in internal_links: + verify_link(host+link) + + for link in external_links: + verify_link(link) def check_links(args_obj, parser): print("") print("Checking links") - print("########################") - print("Not implemented yet.") - print("This is supposed to check all links in the system.") - print("########################") + host = args_obj.host + + # Check the home page + check_page(host, host) + + # Check traits page + check_page( + host, + host+"/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") -- cgit v1.2.3 From ed0c0018166166f1dc05905f0aed1fa1930d963b Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Wed, 14 Mar 2018 02:16:59 +0300 Subject: Add tests for main web functionality --- test/requests/main_web_functionality.py | 40 +++++++++++++++++++++++++++++++++ test/requests/test-website.py | 7 ++++++ 2 files changed, 47 insertions(+) create mode 100644 test/requests/main_web_functionality.py (limited to 'test') diff --git a/test/requests/main_web_functionality.py b/test/requests/main_web_functionality.py new file mode 100644 index 00000000..f6b32340 --- /dev/null +++ b/test/requests/main_web_functionality.py @@ -0,0 +1,40 @@ +from __future__ import print_function +import re +import requests +from lxml.html import parse +from requests.exceptions import ConnectionError + +def check_home(url): + doc = parse(url).getroot() + search_button = doc.cssselect("#btsearch") + assert(search_button[0].value == "Search") + print("OK") + +def check_search_page(host): + data = dict( + species="mouse" + , group="BXD" + , type="Hippocampus mRNA" + , dataset="HC_M2_0606_P" + , search_terms_or="" + , search_terms_and="MEAN=(15 16) LRS=(23 46)") + result = requests.get(host+"/search", params=data) + found = result.text.find("/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") + assert(found >= 0) + print("OK") + check_traits_page(host, "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") + +def check_traits_page(host, traits_url): + from link_checker import check_page + doc = parse(host+traits_url).getroot() + traits_form = doc.forms[1] + assert(traits_form.fields["corr_dataset"] == "HC_M2_0606_P") + print("OK") + check_page(host, host+traits_url) + +def check_main_web_functionality(args_obj, parser): + print("") + print("Checking main web functionality...") + host = args_obj.host + check_home(host) + check_search_page(host) diff --git a/test/requests/test-website.py b/test/requests/test-website.py index 9637b87f..f65c3fc8 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -4,6 +4,7 @@ # # Mostly to pick up the Guix GN2_PROFILE and python modules from __future__ import print_function +from main_web_functionality import check_main_web_functionality from link_checker import check_links import argparse @@ -12,6 +13,7 @@ print("Mechanical Rob firing up...") def run_all(args_obj, parser): print("") print("Running all tests.") + check_main_web_functionality(args_obj, parser) check_links(args_obj, parser) # TODO: Add other functions as they are created. @@ -44,6 +46,11 @@ parser.add_argument("-l", "--link-checker", dest="accumulate" , action='store_const', const=check_links, default=print_help , help="Checks for dead links.") +parser.add_argument("-f", "--main-functionality", dest="accumulate" + , action='store_const', const=check_main_web_functionality + , default=print_help + , help="Checks for main web functionality.") + # parser.add_argument("-n", "--navigation", dest="accumulate" # , action="store_const", const=check_navigation, default=print_help # , help="Checks for navigation.") -- cgit v1.2.3 From 55f42f8f972ab3940711fc7b5e39335bc35445b5 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Sun, 18 Mar 2018 08:54:03 +0300 Subject: Move import to the top of the page. * Mainly to tell the dependencies easily. --- test/requests/main_web_functionality.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/requests/main_web_functionality.py b/test/requests/main_web_functionality.py index f6b32340..7b89b833 100644 --- a/test/requests/main_web_functionality.py +++ b/test/requests/main_web_functionality.py @@ -2,6 +2,7 @@ from __future__ import print_function import re import requests from lxml.html import parse +from link_checker import check_page from requests.exceptions import ConnectionError def check_home(url): @@ -25,7 +26,6 @@ def check_search_page(host): check_traits_page(host, "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") def check_traits_page(host, traits_url): - from link_checker import check_page doc = parse(host+traits_url).getroot() traits_form = doc.forms[1] assert(traits_form.fields["corr_dataset"] == "HC_M2_0606_P") -- cgit v1.2.3 From 5ccf077f53c6546bb9258c7116b4b1cf8903375f Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Sun, 18 Mar 2018 08:56:03 +0300 Subject: Initialise mapping tests * Add mapping tests, and build the first of the tests. --- test/requests/mapping_tests.py | 43 ++++++++++++++++++++++++++++++++++++++++++ test/requests/test-website.py | 14 ++++++++------ 2 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 test/requests/mapping_tests.py (limited to 'test') diff --git a/test/requests/mapping_tests.py b/test/requests/mapping_tests.py new file mode 100644 index 00000000..fd20df11 --- /dev/null +++ b/test/requests/mapping_tests.py @@ -0,0 +1,43 @@ +from __future__ import print_function +import re +import json +import requests +from lxml.html import fromstring + +def get_data(list_item): + try: + value = list_item[1] + except: + value = None + #print("list_item:", list_item, "==>", value) + return value + +def load_data_from_file(): + filename = "../test/data/input/mapping/1435395_s_at_HC_M2_0606_P.json" + file_handle = open(filename, "r") + file_data = json.loads(file_handle.read().encode("utf-8")) + return file_data + +def check_pylmm_tool_selection(host, data): + data["method"] = "pylmm" + page = requests.post(host+"/marker_regression", data=data) + doc = fromstring(page.text) + form = doc.forms[1] + assert form.fields["dataset"] == "HC_M2_0606_P" + assert form.fields["value:BXD1"] == "15.034" # Check value in the file + +def check_R_qtl_tool_selection(host, data): + pass + +def check_CIM_tool_selection(host, data): + pass + +def check_mapping(args_obj, parser): + print("") + print("Checking mapping") + + host = args_obj.host + data = load_data_from_file() + check_pylmm_tool_selection(host, data) + check_R_qtl_tool_selection(host, data) + check_CIM_tool_selection(host, data) diff --git a/test/requests/test-website.py b/test/requests/test-website.py index f65c3fc8..2bef6eb1 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -4,9 +4,10 @@ # # Mostly to pick up the Guix GN2_PROFILE and python modules from __future__ import print_function -from main_web_functionality import check_main_web_functionality -from link_checker import check_links import argparse +from link_checker import check_links +from mapping_tests import check_mapping +from main_web_functionality import check_main_web_functionality print("Mechanical Rob firing up...") @@ -15,6 +16,7 @@ def run_all(args_obj, parser): print("Running all tests.") check_main_web_functionality(args_obj, parser) check_links(args_obj, parser) + check_mapping(args_obj, parser) # TODO: Add other functions as they are created. def print_help(args_obj, parser): @@ -51,14 +53,14 @@ parser.add_argument("-f", "--main-functionality", dest="accumulate" , default=print_help , help="Checks for main web functionality.") +parser.add_argument("-m", "--mapping", dest="accumulate" + , action="store_const", const=check_mapping, default=print_help + , help="Checks for mapping.") + # parser.add_argument("-n", "--navigation", dest="accumulate" # , action="store_const", const=check_navigation, default=print_help # , help="Checks for navigation.") -# parser.add_argument("-m", "--mapping", dest="accumulate" -# , action="store_const", const=check_mapping, default=print_help -# , help="Checks for mapping.") - # parser.add_argument("-s", "--skip-broken", dest="accumulate" # , action="store_const", const=dummy, default=print_help # , help="Skip tests that are known to be broken.") -- cgit v1.2.3 From 178102c304e5ad1da2af5b2ab0af2484edb8a609 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Mar 2018 17:08:05 +0300 Subject: * Add mapping tests. Fix link-checker tests. * Add tests for the R/qtl and CIM mapping tools. * Fix tests for in-page links. --- test/requests/link_checker.py | 16 ++++++++++++---- test/requests/mapping_tests.py | 35 ++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 17 deletions(-) (limited to 'test') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py index 256bf6ef..a75327f0 100644 --- a/test/requests/link_checker.py +++ b/test/requests/link_checker.py @@ -16,6 +16,10 @@ def is_internal_link(link): pattern = re.compile("^/.*") return pattern.match(link) +def is_in_page_link(link): + pattern = re.compile("^#.*") + return pattern.match(link) + def get_links(doc): return filter( lambda x: not ( @@ -32,17 +36,21 @@ def verify_link(link): else: print("ERROR: link `"+link+"` failed with status " , result.status_code) - except ConnectionError as ex: - print("ERROR: ", link, ex) + except Exception as ex: + print("ERROR: ("+link+")", ex) def check_page(host, start_url): print("") print("Checking links in page `"+start_url+"`") doc = parse(start_url).getroot() links = get_links(doc) + in_page_links = filter(is_in_page_link, links) internal_links = filter(is_internal_link, links) - external_links = filter(lambda x: not is_internal_link(x), links) - external_links.append("http://somenon-existentsite.brr") + external_links = filter(lambda x: not (is_internal_link(x) or is_in_page_link(x)), links) + + for link in in_page_links: + verify_link(start_url+link) + for link in internal_links: verify_link(host+link) diff --git a/test/requests/mapping_tests.py b/test/requests/mapping_tests.py index fd20df11..8eb19de7 100644 --- a/test/requests/mapping_tests.py +++ b/test/requests/mapping_tests.py @@ -1,17 +1,10 @@ from __future__ import print_function import re +import copy import json import requests from lxml.html import fromstring -def get_data(list_item): - try: - value = list_item[1] - except: - value = None - #print("list_item:", list_item, "==>", value) - return value - def load_data_from_file(): filename = "../test/data/input/mapping/1435395_s_at_HC_M2_0606_P.json" file_handle = open(filename, "r") @@ -19,6 +12,8 @@ def load_data_from_file(): return file_data def check_pylmm_tool_selection(host, data): + print("") + print("pylmm mapping tool selection") data["method"] = "pylmm" page = requests.post(host+"/marker_regression", data=data) doc = fromstring(page.text) @@ -27,10 +22,24 @@ def check_pylmm_tool_selection(host, data): assert form.fields["value:BXD1"] == "15.034" # Check value in the file def check_R_qtl_tool_selection(host, data): - pass + print("") + print("R/qtl mapping tool selection") + headers = {"Content-Type": "application/x-www-form-urlencoded"} + page = requests.post(host+"/marker_regression", data=data, headers=headers) + doc = fromstring(page.text) + form = doc.forms[1] + assert form.fields["dataset"] == "HC_M2_0606_P" + assert form.fields["value:BXD1"] == "15.034" def check_CIM_tool_selection(host, data): - pass + print("") + print("CIM mapping tool selection (using reaper)") + data["method"] = "reaper" + page = requests.post(host+"/marker_regression", data=data) + doc = fromstring(page.text) + form = doc.forms[1] + assert form.fields["dataset"] == "HC_M2_0606_P" + assert form.fields["value:BXD1"] == "15.034" def check_mapping(args_obj, parser): print("") @@ -38,6 +47,6 @@ def check_mapping(args_obj, parser): host = args_obj.host data = load_data_from_file() - check_pylmm_tool_selection(host, data) - check_R_qtl_tool_selection(host, data) - check_CIM_tool_selection(host, data) + check_pylmm_tool_selection(host, copy.deepcopy(data)) + check_R_qtl_tool_selection(host, copy.deepcopy(data)) ## Why does this fail? + check_CIM_tool_selection(host, copy.deepcopy(data)) -- cgit v1.2.3 From 883bcc257a38240de7de8888f78bac4406b5d027 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Mar 2018 17:49:39 +0300 Subject: Initialise navigation tests. * Start working on navigation tests. --- test/requests/navigation_tests.py | 15 +++++++++++++++ test/requests/test-website.py | 7 ++++--- 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 test/requests/navigation_tests.py (limited to 'test') diff --git a/test/requests/navigation_tests.py b/test/requests/navigation_tests.py new file mode 100644 index 00000000..eda27324 --- /dev/null +++ b/test/requests/navigation_tests.py @@ -0,0 +1,15 @@ +from __future__ import print_function +import re +import requests +from lxml.html import parse + +def check_navigation(args_obj, parser): + print("") + print("Checking navigation.") + + host = args_obj.host + url = host + "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P" + print("URL: ", url) + page = requests.get(url) + # Page is built by the javascript, hence using requests fails for this. + # Investigate use of selenium maybe? diff --git a/test/requests/test-website.py b/test/requests/test-website.py index 2bef6eb1..dbf3b822 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -7,6 +7,7 @@ from __future__ import print_function import argparse from link_checker import check_links from mapping_tests import check_mapping +from navigation_tests import check_navigation from main_web_functionality import check_main_web_functionality print("Mechanical Rob firing up...") @@ -57,9 +58,9 @@ parser.add_argument("-m", "--mapping", dest="accumulate" , action="store_const", const=check_mapping, default=print_help , help="Checks for mapping.") -# parser.add_argument("-n", "--navigation", dest="accumulate" -# , action="store_const", const=check_navigation, default=print_help -# , help="Checks for navigation.") +parser.add_argument("-n", "--navigation", dest="accumulate" + , action="store_const", const=check_navigation, default=print_help + , help="Checks for navigation.") # parser.add_argument("-s", "--skip-broken", dest="accumulate" # , action="store_const", const=dummy, default=print_help -- cgit v1.2.3 From a20004e25d0143a14763180359e8266e31f9766f Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Wed, 21 Mar 2018 11:22:48 +0300 Subject: Deactivate navigation tests * Navigation depends on Javascript to render the elements being tested. That would require selenium and its ilk to run such tests, meaning such packages would need to be defined for Guix first. --- test/requests/test-website.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/requests/test-website.py b/test/requests/test-website.py index dbf3b822..f03c148a 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -58,9 +58,10 @@ parser.add_argument("-m", "--mapping", dest="accumulate" , action="store_const", const=check_mapping, default=print_help , help="Checks for mapping.") -parser.add_argument("-n", "--navigation", dest="accumulate" - , action="store_const", const=check_navigation, default=print_help - , help="Checks for navigation.") +# Navigation tests deactivated since system relies on Javascript +# parser.add_argument("-n", "--navigation", dest="accumulate" +# , action="store_const", const=check_navigation, default=print_help +# , help="Checks for navigation.") # parser.add_argument("-s", "--skip-broken", dest="accumulate" # , action="store_const", const=dummy, default=print_help -- cgit v1.2.3 From e7f80eb6cf60bb117f943132049ec0b220ddcab4 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Thu, 15 Feb 2018 14:03:38 +0000 Subject: Added unittest example --- test/unittest/test_registration.py | 27 +++++++++ wqflask/mock/__init__.py | 0 wqflask/mock/es_double.py | 15 +++++ wqflask/tests/__init__.py | 0 wqflask/tests/es_double.py | 30 ---------- wqflask/tests/test_registration.py | 113 ------------------------------------- 6 files changed, 42 insertions(+), 143 deletions(-) create mode 100644 test/unittest/test_registration.py create mode 100644 wqflask/mock/__init__.py create mode 100644 wqflask/mock/es_double.py delete mode 100644 wqflask/tests/__init__.py delete mode 100644 wqflask/tests/es_double.py delete mode 100644 wqflask/tests/test_registration.py (limited to 'test') diff --git a/test/unittest/test_registration.py b/test/unittest/test_registration.py new file mode 100644 index 00000000..98d0cdff --- /dev/null +++ b/test/unittest/test_registration.py @@ -0,0 +1,27 @@ +# Run test with something like +# +# env GN2_PROFILE=~/opt/gn-latest GENENETWORK_FILES=$HOME/gn2_data ./bin/genenetwork2 ./etc/default_settings.py -c ../test/unittest/test_registration.py +# + +import unittest +import mock.es_double as es +from wqflask.user_manager import RegisterUser + +class TestRegisterUser(unittest.TestCase): + def setUp(self): + self.es = es.ESDouble() + + def testRegisterUserWithCorrectData(self): + data = { + "email_address": "user@example.com" + , "full_name": "A.N. Other" + , "organization": "Some Organisation" + , "password": "testing" + , "password_confirm": "testing" + , "es_connection": self.es + } + result = RegisterUser(data) + self.assertEqual(len(result.errors), 0, "Errors were not expected") + +if __name__ == "__main__": + unittest.main() diff --git a/wqflask/mock/__init__.py b/wqflask/mock/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/wqflask/mock/es_double.py b/wqflask/mock/es_double.py new file mode 100644 index 00000000..6ef8a1b9 --- /dev/null +++ b/wqflask/mock/es_double.py @@ -0,0 +1,15 @@ +class ESDouble(object): + def __init__(self): + self.items = {} + + def ping(self): + return true + + def create(self, index, doc_type, body, id): + self.items["index"] = {doc_type: {"id": id, "_source": data}} + + def search(self, index, doc_type, body): + return { + "hits": { + "hits": self.items[index][doc_type][body] + }} diff --git a/wqflask/tests/__init__.py b/wqflask/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/wqflask/tests/es_double.py b/wqflask/tests/es_double.py deleted file mode 100644 index 00739016..00000000 --- a/wqflask/tests/es_double.py +++ /dev/null @@ -1,30 +0,0 @@ -class ESDouble(object): - def __init__(self): - self.items = { - "users": { - "local": [] - }} - - def ping(self): - return true - - def create(self, index, doc_type, body, id): - item = {"id": id, "_source": body} - if not self.items.get("index", None): - self.items[index] = {doc_type: [item]} - else: - self.items[index][doc_type].append(item) - - def search(self, index, doc_type, body): - d = body["query"]["match"] - column = [(key, d[key]) for key in d] - - items = [] - for thing in self.items[index][doc_type]: - if thing["_source"][column[0][0]] == column[0][1]: - items.append(thing) - break - return { - "hits": { - "hits": items - }} diff --git a/wqflask/tests/test_registration.py b/wqflask/tests/test_registration.py deleted file mode 100644 index 50a2a84c..00000000 --- a/wqflask/tests/test_registration.py +++ /dev/null @@ -1,113 +0,0 @@ -import unittest -import es_double -import wqflask.user_manager -from wqflask.user_manager import RegisterUser - -class TestRegisterUser(unittest.TestCase): - def setUp(self): - # Mock elasticsearch - self.es = es_double.ESDouble() - - # Patch method - wqflask.user_manager.basic_info = lambda : {"basic_info": "some info"} - - def tearDown(self): - self.es = None - - def testRegisterUserWithNoData(self): - data = {} - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Data was not provided. Error was expected") - - def testRegisterUserWithNoEmail(self): - data = { - "email_address": "" - , "full_name": "A.N. Other" - , "organization": "Some Organisation" - , "password": "testing" - , "password_confirm": "testing" - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Email not provided. Error was expected") - - def testRegisterUserWithNoName(self): - data = { - "email_address": "user@example.com" - , "full_name": "" - , "organization": "Some Organisation" - , "password": "testing" - , "password_confirm": "testing" - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Name not provided. Error was expected") - - def testRegisterUserWithNoOrganisation(self): - data = { - "email_address": "user@example.com" - , "full_name": "A.N. Other" - , "organization": "" - , "password": "testing" - , "password_confirm": "testing" - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertEqual(len(result.errors), 0, "Organisation not provided. Error not expected") - - def testRegisterUserWithShortOrganisation(self): - data = { - "email_address": "user@example.com" - , "full_name": "A.N. Other" - , "organization": "SO" - , "password": "testing" - , "password_confirm": "testing" - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Organisation name too short. Error expected") - - def testRegisterUserWithNoPassword(self): - data = { - "email_address": "user@example.com" - , "full_name": "A.N. Other" - , "organization": "Some Organisation" - , "password": None - , "password_confirm": None - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Password not provided. Error was expected") - - def testRegisterUserWithNonMatchingPasswords(self): - data = { - "email_address": "user@example.com" - , "full_name": "A.N. Other" - , "organization": "Some Organisation" - , "password": "testing" - , "password_confirm": "stilltesting" - , "es_connection": self.es - } - - result = RegisterUser(data) - self.assertNotEqual(len(result.errors), 0, "Password mismatch. Error was expected") - - def testRegisterUserWithCorrectData(self): - data = { - "email_address": "user@example.com" - , "full_name": "A.N. Other" - , "organization": "Some Organisation" - , "password": "testing" - , "password_confirm": "testing" - , "es_connection": self.es - } - result = RegisterUser(data) - self.assertEqual(len(result.errors), 0, "All data items provided. Errors were not expected") - -if __name__ == "__main__": - unittest.main() -- cgit v1.2.3 From 375935b23778148eba40ebce4a4f4def823aa3f0 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Thu, 15 Feb 2018 15:00:47 +0000 Subject: Requests added --- bin/genenetwork2 | 10 ++-- bin/mechnical-rob | 111 ++++++++++++++++++++++++++++++++++++++++ bin/test-website | 114 ++---------------------------------------- test/requests/test-website.py | 20 ++++++++ 4 files changed, 142 insertions(+), 113 deletions(-) create mode 100755 bin/mechnical-rob create mode 100755 test/requests/test-website.py (limited to 'test') diff --git a/bin/genenetwork2 b/bin/genenetwork2 index 31fefbd3..ceafeedd 100755 --- a/bin/genenetwork2 +++ b/bin/genenetwork2 @@ -168,8 +168,9 @@ if [ "$1" = '-c' ] ; then cd $GN2_BASE_DIR/wqflask cmd=${2#wqflask/} echo PYTHONPATH=$PYTHONPATH - echo RUNNING COMMAND $cmd - python $cmd + shift ; shift + echo RUNNING COMMAND $cmd $* + python $cmd $* exit $? fi # Now handle command parameter -cli which runs in bash @@ -178,8 +179,9 @@ if [ "$1" = "-cli" ] ; then cd $GN2_BASE_DIR/wqflask cmd=$2 echo PYTHONPATH=$PYTHONPATH - echo RUNNING COMMAND $cmd - $cmd + shift ; shift + echo RUNNING COMMAND $cmd $* + $cmd $* exit $? fi if [ "$1" = '-gunicorn' ] ; then diff --git a/bin/mechnical-rob b/bin/mechnical-rob new file mode 100755 index 00000000..be223d94 --- /dev/null +++ b/bin/mechnical-rob @@ -0,0 +1,111 @@ +#!/usr/bin/env ruby + + +USAGE = <0 + ARGV.shift + else + "http://localhost:5003" + end + +$stderr.print "Testing <",$host,">\n" + +require 'mechanize' +require 'minitest/spec' +require 'minitest/autorun' + +# These are the actual testing modules + +libpath = File.dirname(File.dirname(__FILE__)) +$: << File.join(libpath,'test/lib') + +require 'main_web_functionality' + +if options[:all] or options[:mapping] + require 'mapping' +end + +if options[:all] or options[:link_checker] + require 'link_checker' +end + +if options[:all] or options[:navigation] + require 'navigation' +end diff --git a/bin/test-website b/bin/test-website index be223d94..5935f016 100755 --- a/bin/test-website +++ b/bin/test-website @@ -1,111 +1,7 @@ -#!/usr/bin/env ruby +#! /bin/bash - -USAGE = <0 - ARGV.shift - else - "http://localhost:5003" - end - -$stderr.print "Testing <",$host,">\n" - -require 'mechanize' -require 'minitest/spec' -require 'minitest/autorun' - -# These are the actual testing modules - -libpath = File.dirname(File.dirname(__FILE__)) -$: << File.join(libpath,'test/lib') - -require 'main_web_functionality' - -if options[:all] or options[:mapping] - require 'mapping' -end - -if options[:all] or options[:link_checker] - require 'link_checker' -end - -if options[:all] or options[:navigation] - require 'navigation' -end +fi diff --git a/test/requests/test-website.py b/test/requests/test-website.py new file mode 100755 index 00000000..d02b71aa --- /dev/null +++ b/test/requests/test-website.py @@ -0,0 +1,20 @@ +# Run with something like +# +# env GN2_PROFILE=/home/wrk/opt/gn-latest ./bin/genenetwork2 ./etc/default_settings.py -c ../test/requests/test-website.py http://localhost:5003 +# +# Mostly to pick up the Guix GN2_PROFILE and python modules + +import requests as req +import sys + +print "Mechanical Rob firing up..." + +if len(sys.argv)<1: + raise "Problem with arguments" + +url = sys.argv[1] +print url + +r = req.get(url) + +print r -- cgit v1.2.3 From c5b1028a15c771508b2b88994869912330c1148e Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 16 Feb 2018 14:22:17 +0300 Subject: Add registration test * Add integration test to check the registration process. --- test/requests/test-registration.py | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 test/requests/test-registration.py (limited to 'test') diff --git a/test/requests/test-registration.py b/test/requests/test-registration.py new file mode 100644 index 00000000..bcb1642f --- /dev/null +++ b/test/requests/test-registration.py @@ -0,0 +1,59 @@ +import sys +import unittest +import requests +import logging +from elasticsearch import Elasticsearch, TransportError +#from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT + +GN2_SERVER = None +ES_SERVER = None + +class TestRegistration(unittest.TestCase): + + + def setUp(self): + self.url = GN2_SERVER+"/n/register" + self.es = Elasticsearch([ES_SERVER]) + self.es_cleanup = [] + + es_logger = logging.getLogger("elasticsearch") + es_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationInfo.log")) + es_trace_logger = logging.getLogger("elasticsearch.trace") + es_trace_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationTrace.log")) + + def tearDown(self): + for item in self.es_cleanup: + self.es.delete(index="users", doc_type="local", id=item["_id"]) + + def testRegistrationPage(self): + if self.es.ping(): + data = { + "email_address": "test@user.com", + "full_name": "Test User", + "organization": "Test Organisation", + "password": "test_password", + "password_confirm": "test_password" + } + requests.post(self.url, data) + response = self.es.search( + index="users" + , doc_type="local" + , body={ + "query": {"match": {"email_address": "test@user.com"}}}) + self.assertEqual(len(response["hits"]["hits"]), 1) + self.es_cleanup.append(response["hits"]["hits"][0]) + else: + self.skipTest("The elasticsearch server is down") + +def main(): + suite = unittest.TestSuite() + suite.addTest(TestRegistration("testRegistrationPage")) + runner = unittest.TextTestRunner() + runner.run(suite) + +if __name__ == "__main__": + GN2_SERVER = sys.argv[1] + ES_SERVER = sys.argv[2] + main() -- cgit v1.2.3 From 0f1197ce8afdc2a869e4cc6f78122641df009e42 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:46:47 +0300 Subject: Rename file and move common code * Rename the file to make it an importable module * Refactor the test to move common code out to a super class. --- test/requests/test-registration.py | 59 -------------------------------------- test/requests/test_registration.py | 41 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 59 deletions(-) delete mode 100644 test/requests/test-registration.py create mode 100644 test/requests/test_registration.py (limited to 'test') diff --git a/test/requests/test-registration.py b/test/requests/test-registration.py deleted file mode 100644 index bcb1642f..00000000 --- a/test/requests/test-registration.py +++ /dev/null @@ -1,59 +0,0 @@ -import sys -import unittest -import requests -import logging -from elasticsearch import Elasticsearch, TransportError -#from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT - -GN2_SERVER = None -ES_SERVER = None - -class TestRegistration(unittest.TestCase): - - - def setUp(self): - self.url = GN2_SERVER+"/n/register" - self.es = Elasticsearch([ES_SERVER]) - self.es_cleanup = [] - - es_logger = logging.getLogger("elasticsearch") - es_logger.addHandler( - logging.FileHandler("/tmp/es_TestRegistrationInfo.log")) - es_trace_logger = logging.getLogger("elasticsearch.trace") - es_trace_logger.addHandler( - logging.FileHandler("/tmp/es_TestRegistrationTrace.log")) - - def tearDown(self): - for item in self.es_cleanup: - self.es.delete(index="users", doc_type="local", id=item["_id"]) - - def testRegistrationPage(self): - if self.es.ping(): - data = { - "email_address": "test@user.com", - "full_name": "Test User", - "organization": "Test Organisation", - "password": "test_password", - "password_confirm": "test_password" - } - requests.post(self.url, data) - response = self.es.search( - index="users" - , doc_type="local" - , body={ - "query": {"match": {"email_address": "test@user.com"}}}) - self.assertEqual(len(response["hits"]["hits"]), 1) - self.es_cleanup.append(response["hits"]["hits"][0]) - else: - self.skipTest("The elasticsearch server is down") - -def main(): - suite = unittest.TestSuite() - suite.addTest(TestRegistration("testRegistrationPage")) - runner = unittest.TextTestRunner() - runner.run(suite) - -if __name__ == "__main__": - GN2_SERVER = sys.argv[1] - ES_SERVER = sys.argv[2] - main() diff --git a/test/requests/test_registration.py b/test/requests/test_registration.py new file mode 100644 index 00000000..0047e8a6 --- /dev/null +++ b/test/requests/test_registration.py @@ -0,0 +1,41 @@ +import sys +import requests +from parametrized_test import ParametrizedTest + +class TestRegistration(ParametrizedTest): + + def tearDown(self): + for item in self.es_cleanup: + self.es.delete(index="users", doc_type="local", id=item["_id"]) + + def testRegistrationPage(self): + if self.es.ping(): + data = { + "email_address": "test@user.com", + "full_name": "Test User", + "organization": "Test Organisation", + "password": "test_password", + "password_confirm": "test_password" + } + requests.post(self.gn2_url+"/n/register", data) + response = self.es.search( + index="users" + , doc_type="local" + , body={ + "query": {"match": {"email_address": "test@user.com"}}}) + self.assertEqual(len(response["hits"]["hits"]), 1) + else: + self.skipTest("The elasticsearch server is down") + +def main(gn2, es): + import unittest + suite = unittest.TestSuite() + suite.addTest(TestRegistration(methodName="testRegistrationPage", gn2_url=gn2, es_url=es)) + runner = unittest.TextTestRunner() + runner.run(suite) + +if __name__ == "__main__": + if len(sys.argv) < 3: + raise Exception("Required arguments missing") + else: + main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From f74b1615567d5cbf2cb00572cc14450ffd4b0c1c Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:48:36 +0300 Subject: Create parametrized superclass for tests * Since the tests require that some parameters be provided while running the tests, create a class that helps abstract away the details of retrieving and setting the expected parameters. --- test/requests/parametrized_test.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 test/requests/parametrized_test.py (limited to 'test') diff --git a/test/requests/parametrized_test.py b/test/requests/parametrized_test.py new file mode 100644 index 00000000..abf98fce --- /dev/null +++ b/test/requests/parametrized_test.py @@ -0,0 +1,27 @@ +import logging +import unittest +from elasticsearch import Elasticsearch, TransportError + +class ParametrizedTest(unittest.TestCase): + + def __init__(self, methodName='runTest', gn2_url="http://localhost:5003", es_url="localhost:9200"): + super(ParametrizedTest, self).__init__(methodName=methodName) + self.gn2_url = gn2_url + self.es_url = es_url + + def setUp(self): + self.es = Elasticsearch([self.es_url]) + self.es_cleanup = [] + + es_logger = logging.getLogger("elasticsearch") + es_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationInfo.log")) + es_trace_logger = logging.getLogger("elasticsearch.trace") + es_trace_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationTrace.log")) + + def tearDown(self): + self.es.delete_by_query( + index="users" + , doc_type="local" + , body={"query":{"match":{"email_address":"test@user.com"}}}) -- cgit v1.2.3 From c84bd98971aa5839cb6aa999889a92071890f579 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:50:30 +0300 Subject: Add test for local login * Add an integration test to test that the login process for users registered locally to genenetwork2 works as expected. --- test/requests/test_login_local.py | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 test/requests/test_login_local.py (limited to 'test') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py new file mode 100644 index 00000000..bced1ee9 --- /dev/null +++ b/test/requests/test_login_local.py @@ -0,0 +1,56 @@ +import requests +from wqflask import user_manager +from parametrized_test import ParametrizedTest + +class TestLoginLocal(ParametrizedTest): + + def setUp(self): + super(TestLoginLocal, self).setUp() + self.login_url = self.gn2_url +"/n/login" + data = { + "es_connection": self.es, + "email_address": "test@user.com", + "full_name": "Test User", + "organization": "Test Organisation", + "password": "test_password", + "password_confirm": "test_password" + } + user_manager.basic_info = lambda : { "basic_info": "basic" } + user_manager.RegisterUser(data) + + def testLoginNonRegisteredUser(self): + data = { + "email_address": "non@existent.email", + "password": "doesitmatter?" + } + result = requests.post(self.login_url, data=data) + self.assertEqual(result.url, self.login_url, "") + + def testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse(self): + data = { + "email_address": "test@user.com", + "password": "test_password" + } + result = requests.post(self.login_url, data=data) + print("THE COOKIES? ", result.cookies) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=false" + , "Login should have been successful") + + + +def main(gn2, es): + import unittest + suite = unittest.TestSuite() + suite.addTest(TestLoginLocal(methodName="testLoginNonRegisteredUser", gn2_url=gn2, es_url=es)) + suite.addTest(TestLoginLocal(methodName="testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse", gn2_url=gn2, es_url=es)) + runner = unittest.TextTestRunner() + runner.run(suite) + +if __name__ == "__main__": + import sys + if len(sys.argv) < 3: + raise Exception("Required arguments missing") + else: + main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From db86c21577e50b30ee222c47aae43e49a574c007 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:52:32 +0300 Subject: Add a runner for all integration tests. --- test/requests/run-integration-tests.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 test/requests/run-integration-tests.py (limited to 'test') diff --git a/test/requests/run-integration-tests.py b/test/requests/run-integration-tests.py new file mode 100644 index 00000000..0fd7bb20 --- /dev/null +++ b/test/requests/run-integration-tests.py @@ -0,0 +1,30 @@ +import sys +from test_login_local import TestLoginLocal +from test_registration import TestRegistration +from unittest import TestSuite, TextTestRunner, TestLoader + +test_cases = [ + TestLoginLocal, + TestRegistration +] + +def suite(gn2_url, es_url): + the_suite = TestSuite() + for case in test_cases: + the_suite.addTests(initTest(case, gn2_url, es_url)) + return the_suite + +def initTest(klass, gn2_url, es_url): + loader = TestLoader() + methodNames = loader.getTestCaseNames(klass) + return [klass(mname, gn2_url, es_url) for mname in methodNames] + +def main(gn2_url, es_url): + runner = TextTestRunner() + runner.run(suite(gn2_url, es_url)) + +if __name__ == "__main__": + if len(sys.argv) < 3: + raise Exception("Required arguments missing:\n\tTry running `run-integration-test.py `") + else: + main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From e4b7e72d83a6dba40a38c58e62e338bd257862ef Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 14:12:59 +0300 Subject: Add more login tests. --- test/requests/test_login_local.py | 39 +++++++++++++++++++++++++++++++++++++-- wqflask/wqflask/user_manager.py | 2 -- 2 files changed, 37 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py index bced1ee9..acad45c9 100644 --- a/test/requests/test_login_local.py +++ b/test/requests/test_login_local.py @@ -32,12 +32,47 @@ class TestLoginLocal(ParametrizedTest): "password": "test_password" } result = requests.post(self.login_url, data=data) - print("THE COOKIES? ", result.cookies) self.assertEqual( result.url , self.gn2_url+"/?import_collections=false" , "Login should have been successful") - + + def testLoginWithRegisteredUserImportCollectionsTrueAndRememberMeFalse(self): + data = { + "email_address": "test@user.com", + "password": "test_password", + "import_collections": "y" + } + result = requests.post(self.login_url, data=data) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=true" + , "Login should have been successful") + + def testLoginWithRegisteredUserImportCollectionsFalseAndRememberMeTrue(self): + data = { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y" + } + result = requests.post(self.login_url, data=data) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=false" + , "Login should have been successful") + + def testLoginWithRegisteredUserBothImportCollectionsAndRememberMeTrue(self): + data = { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y", + "import_collections": "y" + } + result = requests.post(self.login_url, data=data) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=true" + , "Login should have been successful") def main(gn2, es): diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index c8471cb1..fd1d56ff 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -642,7 +642,6 @@ class LoginUser(object): user = model.User(); for key in user_details: user.__dict__[key] = user_details[key] - print("RETRIEVED USER: ", user) valid = False; submitted_password = params['password'] @@ -689,7 +688,6 @@ class LoginUser(object): """The meat of the logging in process""" session_id_signed = self.successful_login(user, assumed_by) flash("Thank you for logging in {}.".format(user.full_name), "alert-success") - print("IMPORT1:", import_collections) response = make_response(redirect(url_for('index_page', import_collections=import_collections))) if self.remember_me: max_age = self.remember_time -- cgit v1.2.3 From e1e3ea41578947e47b2f394e6e3ba4f45eceeb82 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Wed, 21 Feb 2018 12:51:34 +0300 Subject: Simplify test. Check for content, rather than url * The test functions were very similar, so this commit refactors out the common test code to a single method, and passes in the data to the test using the parameterized package. * Check that the page content after a login attempt is the expected content, rather than checking the url. --- test/requests/test_login_local.py | 93 ++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 54 deletions(-) (limited to 'test') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py index acad45c9..8e2dec4e 100644 --- a/test/requests/test_login_local.py +++ b/test/requests/test_login_local.py @@ -1,7 +1,11 @@ import requests from wqflask import user_manager +from parameterized import parameterized from parametrized_test import ParametrizedTest +login_link_text = 'Sign in' +logout_link_text = 'Sign out' + class TestLoginLocal(ParametrizedTest): def setUp(self): @@ -18,61 +22,42 @@ class TestLoginLocal(ParametrizedTest): user_manager.basic_info = lambda : { "basic_info": "basic" } user_manager.RegisterUser(data) - def testLoginNonRegisteredUser(self): - data = { - "email_address": "non@existent.email", - "password": "doesitmatter?" - } - result = requests.post(self.login_url, data=data) - self.assertEqual(result.url, self.login_url, "") - - def testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse(self): - data = { - "email_address": "test@user.com", - "password": "test_password" - } - result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=false" - , "Login should have been successful") - - def testLoginWithRegisteredUserImportCollectionsTrueAndRememberMeFalse(self): - data = { - "email_address": "test@user.com", - "password": "test_password", - "import_collections": "y" - } - result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=true" - , "Login should have been successful") - - def testLoginWithRegisteredUserImportCollectionsFalseAndRememberMeTrue(self): - data = { - "email_address": "test@user.com", - "password": "test_password", - "remember_me": "y" - } - result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=false" - , "Login should have been successful") - - def testLoginWithRegisteredUserBothImportCollectionsAndRememberMeTrue(self): - data = { - "email_address": "test@user.com", - "password": "test_password", - "remember_me": "y", - "import_collections": "y" - } + + @parameterized.expand([ + ( + { + "email_address": "non@existent.email", + "password": "doesitmatter?" + }, login_link_text, "Login should have failed with the wrong user details."), + ( + { + "email_address": "test@user.com", + "password": "test_password" + }, logout_link_text, "Login should have been successful with correct user details and neither import_collections nor remember_me set"), + ( + { + "email_address": "test@user.com", + "password": "test_password", + "import_collections": "y" + }, logout_link_text, "Login should have been successful with correct user details and only import_collections set"), + ( + { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y" + }, logout_link_text, "Login should have been successful with correct user details and only remember_me set"), + ( + { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y", + "import_collections": "y" + }, logout_link_text, "Login should have been successful with correct user details, and both remember_me, and import_collections set") + ]) + def testLogin(self, data, expected, message): result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=true" - , "Login should have been successful") + index = result.content.find(expected) + self.assertTrue(index >= 0, message) def main(gn2, es): -- cgit v1.2.3 From e982d7223141d247954ab5b5c1ff9bbed907c603 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 17:24:55 +0300 Subject: Remove failing code * With the parameterized module, the testcase cannot be run independently at this time. --- test/requests/test_login_local.py | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'test') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py index 8e2dec4e..808649ca 100644 --- a/test/requests/test_login_local.py +++ b/test/requests/test_login_local.py @@ -58,19 +58,3 @@ class TestLoginLocal(ParametrizedTest): result = requests.post(self.login_url, data=data) index = result.content.find(expected) self.assertTrue(index >= 0, message) - - -def main(gn2, es): - import unittest - suite = unittest.TestSuite() - suite.addTest(TestLoginLocal(methodName="testLoginNonRegisteredUser", gn2_url=gn2, es_url=es)) - suite.addTest(TestLoginLocal(methodName="testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse", gn2_url=gn2, es_url=es)) - runner = unittest.TextTestRunner() - runner.run(suite) - -if __name__ == "__main__": - import sys - if len(sys.argv) < 3: - raise Exception("Required arguments missing") - else: - main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From 7ea87a27735242889ac369dcbd5aec83a1e1caff Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 17:26:42 +0300 Subject: Add new test for github logins --- test/requests/run-integration-tests.py | 4 +++- test/requests/test_login_github.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/requests/test_login_github.py (limited to 'test') diff --git a/test/requests/run-integration-tests.py b/test/requests/run-integration-tests.py index 0fd7bb20..fc795779 100644 --- a/test/requests/run-integration-tests.py +++ b/test/requests/run-integration-tests.py @@ -1,11 +1,13 @@ import sys from test_login_local import TestLoginLocal +from test_login_github import TestLoginGithub from test_registration import TestRegistration from unittest import TestSuite, TextTestRunner, TestLoader test_cases = [ - TestLoginLocal, TestRegistration + , TestLoginLocal + , TestLoginGithub ] def suite(gn2_url, es_url): diff --git a/test/requests/test_login_github.py b/test/requests/test_login_github.py new file mode 100644 index 00000000..15bf18ae --- /dev/null +++ b/test/requests/test_login_github.py @@ -0,0 +1,40 @@ +import uuid +import requests +from time import sleep +from parameterized import parameterized +from parametrized_test import ParametrizedTest + +login_link_text = 'Sign in' +logout_link_text = 'Sign out' +uid = str(uuid.uuid4()) + +class TestLoginGithub(ParametrizedTest): + + def setUp(self): + super(TestLoginGithub, self).setUp() + data = { + "user_id": uid + , "name": "A. T. Est User" + , "github_id": 693024 + , "user_url": "https://fake-github.com/atestuser" + , "login_type": "github" + , "organization": "" + , "active": 1 + , "confirmed": 1 + } + self.es.create(index="users", doc_type="local", body=data, id=uid) + sleep(1) + + def tearDown(self): + super(TestLoginGithub, self).tearDown() + self.es.delete(index="users", doc_type="local", id=uid) + + @parameterized.expand([ + ("1234", login_link_text, "Login should have failed with non-existing user") + , (uid, logout_link_text, "Login should have been successful with existing user") + ]) + def testLogin(self, test_uid, expected, message): + url = self.gn2_url+"/n/login?type=github&uid="+test_uid + result = requests.get(url) + index = result.content.find(expected) + self.assertTrue(index >= 0, message) -- cgit v1.2.3 From 20d9af4812426e4457e7417cfcea601c1a870168 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 17:36:29 +0300 Subject: Add new tests for orcid logins --- test/requests/run-integration-tests.py | 2 ++ test/requests/test_login_orcid.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/requests/test_login_orcid.py (limited to 'test') diff --git a/test/requests/run-integration-tests.py b/test/requests/run-integration-tests.py index fc795779..5e816549 100644 --- a/test/requests/run-integration-tests.py +++ b/test/requests/run-integration-tests.py @@ -1,5 +1,6 @@ import sys from test_login_local import TestLoginLocal +from test_login_orcid import TestLoginOrcid from test_login_github import TestLoginGithub from test_registration import TestRegistration from unittest import TestSuite, TextTestRunner, TestLoader @@ -8,6 +9,7 @@ test_cases = [ TestRegistration , TestLoginLocal , TestLoginGithub + , TestLoginOrcid ] def suite(gn2_url, es_url): diff --git a/test/requests/test_login_orcid.py b/test/requests/test_login_orcid.py new file mode 100644 index 00000000..6e40ece5 --- /dev/null +++ b/test/requests/test_login_orcid.py @@ -0,0 +1,40 @@ +import uuid +import requests +from time import sleep +from parameterized import parameterized +from parametrized_test import ParametrizedTest + +login_link_text = 'Sign in' +logout_link_text = 'Sign out' +uid = str(uuid.uuid4()) + +class TestLoginOrcid(ParametrizedTest): + + def setUp(self): + super(TestLoginOrcid, self).setUp() + data = { + "user_id": uid + , "name": "A. T. Est User" + , "orcid": 345872 + , "user_url": "https://fake-orcid.org/atestuser" + , "login_type": "orcid" + , "organization": "" + , "active": 1 + , "confirmed": 1 + } + self.es.create(index="users", doc_type="local", body=data, id=uid) + sleep(1) + + def tearDown(self): + super(TestLoginOrcid, self).tearDown() + self.es.delete(index="users", doc_type="local", id=uid) + + @parameterized.expand([ + ("1234", login_link_text, "Login should have failed with non-existing user") + , (uid, logout_link_text, "Login should have been successful with existing user") + ]) + def testLogin(self, test_uid, expected, message): + url = self.gn2_url+"/n/login?type=orcid&uid="+test_uid + result = requests.get(url) + index = result.content.find(expected) + self.assertTrue(index >= 0, message) -- cgit v1.2.3 From 07b792f0898d7ecec94b938aa3081e6aa64bc435 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 18:11:33 +0300 Subject: Add tests to check that the UI is setup correctly * Check that the links for OAuth2 logins via ORCID and GitHub are setup correctly. --- test/requests/test_login_github.py | 7 +++++++ test/requests/test_login_orcid.py | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'test') diff --git a/test/requests/test_login_github.py b/test/requests/test_login_github.py index 15bf18ae..1bf4f695 100644 --- a/test/requests/test_login_github.py +++ b/test/requests/test_login_github.py @@ -1,6 +1,7 @@ import uuid import requests from time import sleep +from wqflask import app from parameterized import parameterized from parametrized_test import ParametrizedTest @@ -29,6 +30,12 @@ class TestLoginGithub(ParametrizedTest): super(TestLoginGithub, self).tearDown() self.es.delete(index="users", doc_type="local", id=uid) + def testLoginUrl(self): + login_button_text = 'Login with Github' + result = requests.get(self.gn2_url+"/n/login") + index = result.content.find(login_button_text) + self.assertTrue(index >= 0, "Should have found `Login with Github` button") + @parameterized.expand([ ("1234", login_link_text, "Login should have failed with non-existing user") , (uid, logout_link_text, "Login should have been successful with existing user") diff --git a/test/requests/test_login_orcid.py b/test/requests/test_login_orcid.py index 6e40ece5..ea15642e 100644 --- a/test/requests/test_login_orcid.py +++ b/test/requests/test_login_orcid.py @@ -1,6 +1,7 @@ import uuid import requests from time import sleep +from wqflask import app from parameterized import parameterized from parametrized_test import ParametrizedTest @@ -29,6 +30,12 @@ class TestLoginOrcid(ParametrizedTest): super(TestLoginOrcid, self).tearDown() self.es.delete(index="users", doc_type="local", id=uid) + def testLoginUrl(self): + login_button_text = 'a href="https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=' + app.config.get("ORCID_CLIENT_ID") + '&client_secret=' + app.config.get("ORCID_CLIENT_SECRET") + '" title="Login with ORCID" class="btn btn-info btn-group">Login with ORCID' + result = requests.get(self.gn2_url+"/n/login") + index = result.content.find(login_button_text) + self.assertTrue(index >= 0, "Should have found `Login with ORCID` button") + @parameterized.expand([ ("1234", login_link_text, "Login should have failed with non-existing user") , (uid, logout_link_text, "Login should have been successful with existing user") -- cgit v1.2.3 From 428371a67a7c742e239d96914a96558171f9f59e Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 9 Mar 2018 18:12:58 +0300 Subject: Use argparse to handle arguments * Use argparse to handle commandline arguments. * Create initial layout of how the code might end up - lots of the code is currently commented out. --- test/requests/test-website.py | 60 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/requests/test-website.py b/test/requests/test-website.py index d02b71aa..9637b87f 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -3,18 +3,60 @@ # env GN2_PROFILE=/home/wrk/opt/gn-latest ./bin/genenetwork2 ./etc/default_settings.py -c ../test/requests/test-website.py http://localhost:5003 # # Mostly to pick up the Guix GN2_PROFILE and python modules +from __future__ import print_function +from link_checker import check_links +import argparse -import requests as req -import sys +print("Mechanical Rob firing up...") -print "Mechanical Rob firing up..." +def run_all(args_obj, parser): + print("") + print("Running all tests.") + check_links(args_obj, parser) + # TODO: Add other functions as they are created. -if len(sys.argv)<1: - raise "Problem with arguments" +def print_help(args_obj, parser): + print(parser.format_help()) -url = sys.argv[1] -print url +def dummy(args_obj, parser): + print("Not implemented yet.") -r = req.get(url) -print r +desc = """ +This is Mechanical-Rob - an automated web server tester for + Genenetwork.org +""" +parser = argparse.ArgumentParser(description=desc) + +parser.add_argument("-d", "--database", metavar="DB", type=str + , default="db_webqtl_s" + , help="Use database (default db_webqtl_s)") + +parser.add_argument("host", metavar="HOST", type=str + , default="http://localhost:5003" + , help="The url to the web server") + +parser.add_argument("-a", "--all", dest="accumulate", action="store_const" + , const=run_all, default=print_help + , help="Runs all tests.") + +parser.add_argument("-l", "--link-checker", dest="accumulate" + , action='store_const', const=check_links, default=print_help + , help="Checks for dead links.") + +# parser.add_argument("-n", "--navigation", dest="accumulate" +# , action="store_const", const=check_navigation, default=print_help +# , help="Checks for navigation.") + +# parser.add_argument("-m", "--mapping", dest="accumulate" +# , action="store_const", const=check_mapping, default=print_help +# , help="Checks for mapping.") + +# parser.add_argument("-s", "--skip-broken", dest="accumulate" +# , action="store_const", const=dummy, default=print_help +# , help="Skip tests that are known to be broken.") + +args = parser.parse_args() +# print("The arguments object: ", args) + +args.accumulate(args, parser) -- cgit v1.2.3 From a29c16b770aa0bb53c632eecc1764caf02789fe7 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 9 Mar 2018 18:15:19 +0300 Subject: Add link_checker module * Add the module that will hold the code to test the links on the system. --- test/requests/link_checker.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 test/requests/link_checker.py (limited to 'test') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py new file mode 100644 index 00000000..f171c12a --- /dev/null +++ b/test/requests/link_checker.py @@ -0,0 +1,9 @@ +import requests + +def check_links(args_obj, parser): + print("") + print("Checking links") + print("########################") + print("Not implemented yet.") + print("This is supposed to check all links in the system.") + print("########################") -- cgit v1.2.3 From dd5ec1d3080b74fa065620f6915eeacf2cca8a2d Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 12 Mar 2018 13:00:03 +0300 Subject: Add tests to check links. --- test/requests/link_checker.py | 62 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py index f171c12a..256bf6ef 100644 --- a/test/requests/link_checker.py +++ b/test/requests/link_checker.py @@ -1,9 +1,63 @@ +from __future__ import print_function +import re import requests +from lxml.html import parse +from requests.exceptions import ConnectionError + +def is_root_link(link): + pattern = re.compile("^/$") + return pattern.match(link) + +def is_mailto_link(link): + pattern = re.compile("^mailto:.*") + return pattern.match(link) + +def is_internal_link(link): + pattern = re.compile("^/.*") + return pattern.match(link) + +def get_links(doc): + return filter( + lambda x: not ( + is_root_link(x) + or is_mailto_link(x)) + , map(lambda y: y.get("href") + , doc.cssselect("a"))) + +def verify_link(link): + try: + result = requests.get(link, timeout=20) + if result.status_code == 200: + print(link+" ==> OK") + else: + print("ERROR: link `"+link+"` failed with status " + , result.status_code) + except ConnectionError as ex: + print("ERROR: ", link, ex) + +def check_page(host, start_url): + print("") + print("Checking links in page `"+start_url+"`") + doc = parse(start_url).getroot() + links = get_links(doc) + internal_links = filter(is_internal_link, links) + external_links = filter(lambda x: not is_internal_link(x), links) + external_links.append("http://somenon-existentsite.brr") + for link in internal_links: + verify_link(host+link) + + for link in external_links: + verify_link(link) def check_links(args_obj, parser): print("") print("Checking links") - print("########################") - print("Not implemented yet.") - print("This is supposed to check all links in the system.") - print("########################") + host = args_obj.host + + # Check the home page + check_page(host, host) + + # Check traits page + check_page( + host, + host+"/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") -- cgit v1.2.3 From 8ff3dbd9bd5737b6cd0df8d279a70073c40786ec Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Wed, 14 Mar 2018 02:16:59 +0300 Subject: Add tests for main web functionality --- test/requests/main_web_functionality.py | 40 +++++++++++++++++++++++++++++++++ test/requests/test-website.py | 7 ++++++ 2 files changed, 47 insertions(+) create mode 100644 test/requests/main_web_functionality.py (limited to 'test') diff --git a/test/requests/main_web_functionality.py b/test/requests/main_web_functionality.py new file mode 100644 index 00000000..f6b32340 --- /dev/null +++ b/test/requests/main_web_functionality.py @@ -0,0 +1,40 @@ +from __future__ import print_function +import re +import requests +from lxml.html import parse +from requests.exceptions import ConnectionError + +def check_home(url): + doc = parse(url).getroot() + search_button = doc.cssselect("#btsearch") + assert(search_button[0].value == "Search") + print("OK") + +def check_search_page(host): + data = dict( + species="mouse" + , group="BXD" + , type="Hippocampus mRNA" + , dataset="HC_M2_0606_P" + , search_terms_or="" + , search_terms_and="MEAN=(15 16) LRS=(23 46)") + result = requests.get(host+"/search", params=data) + found = result.text.find("/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") + assert(found >= 0) + print("OK") + check_traits_page(host, "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") + +def check_traits_page(host, traits_url): + from link_checker import check_page + doc = parse(host+traits_url).getroot() + traits_form = doc.forms[1] + assert(traits_form.fields["corr_dataset"] == "HC_M2_0606_P") + print("OK") + check_page(host, host+traits_url) + +def check_main_web_functionality(args_obj, parser): + print("") + print("Checking main web functionality...") + host = args_obj.host + check_home(host) + check_search_page(host) diff --git a/test/requests/test-website.py b/test/requests/test-website.py index 9637b87f..f65c3fc8 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -4,6 +4,7 @@ # # Mostly to pick up the Guix GN2_PROFILE and python modules from __future__ import print_function +from main_web_functionality import check_main_web_functionality from link_checker import check_links import argparse @@ -12,6 +13,7 @@ print("Mechanical Rob firing up...") def run_all(args_obj, parser): print("") print("Running all tests.") + check_main_web_functionality(args_obj, parser) check_links(args_obj, parser) # TODO: Add other functions as they are created. @@ -44,6 +46,11 @@ parser.add_argument("-l", "--link-checker", dest="accumulate" , action='store_const', const=check_links, default=print_help , help="Checks for dead links.") +parser.add_argument("-f", "--main-functionality", dest="accumulate" + , action='store_const', const=check_main_web_functionality + , default=print_help + , help="Checks for main web functionality.") + # parser.add_argument("-n", "--navigation", dest="accumulate" # , action="store_const", const=check_navigation, default=print_help # , help="Checks for navigation.") -- cgit v1.2.3 From 6a111c64c50ffe6daa387034ef8fc3ad3e90fc75 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Sun, 18 Mar 2018 08:54:03 +0300 Subject: Move import to the top of the page. * Mainly to tell the dependencies easily. --- test/requests/main_web_functionality.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/requests/main_web_functionality.py b/test/requests/main_web_functionality.py index f6b32340..7b89b833 100644 --- a/test/requests/main_web_functionality.py +++ b/test/requests/main_web_functionality.py @@ -2,6 +2,7 @@ from __future__ import print_function import re import requests from lxml.html import parse +from link_checker import check_page from requests.exceptions import ConnectionError def check_home(url): @@ -25,7 +26,6 @@ def check_search_page(host): check_traits_page(host, "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") def check_traits_page(host, traits_url): - from link_checker import check_page doc = parse(host+traits_url).getroot() traits_form = doc.forms[1] assert(traits_form.fields["corr_dataset"] == "HC_M2_0606_P") -- cgit v1.2.3 From c3fab61242796ef4b7544d784fceb39f4545828e Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Sun, 18 Mar 2018 08:56:03 +0300 Subject: Initialise mapping tests * Add mapping tests, and build the first of the tests. --- test/requests/mapping_tests.py | 43 ++++++++++++++++++++++++++++++++++++++++++ test/requests/test-website.py | 14 ++++++++------ 2 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 test/requests/mapping_tests.py (limited to 'test') diff --git a/test/requests/mapping_tests.py b/test/requests/mapping_tests.py new file mode 100644 index 00000000..fd20df11 --- /dev/null +++ b/test/requests/mapping_tests.py @@ -0,0 +1,43 @@ +from __future__ import print_function +import re +import json +import requests +from lxml.html import fromstring + +def get_data(list_item): + try: + value = list_item[1] + except: + value = None + #print("list_item:", list_item, "==>", value) + return value + +def load_data_from_file(): + filename = "../test/data/input/mapping/1435395_s_at_HC_M2_0606_P.json" + file_handle = open(filename, "r") + file_data = json.loads(file_handle.read().encode("utf-8")) + return file_data + +def check_pylmm_tool_selection(host, data): + data["method"] = "pylmm" + page = requests.post(host+"/marker_regression", data=data) + doc = fromstring(page.text) + form = doc.forms[1] + assert form.fields["dataset"] == "HC_M2_0606_P" + assert form.fields["value:BXD1"] == "15.034" # Check value in the file + +def check_R_qtl_tool_selection(host, data): + pass + +def check_CIM_tool_selection(host, data): + pass + +def check_mapping(args_obj, parser): + print("") + print("Checking mapping") + + host = args_obj.host + data = load_data_from_file() + check_pylmm_tool_selection(host, data) + check_R_qtl_tool_selection(host, data) + check_CIM_tool_selection(host, data) diff --git a/test/requests/test-website.py b/test/requests/test-website.py index f65c3fc8..2bef6eb1 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -4,9 +4,10 @@ # # Mostly to pick up the Guix GN2_PROFILE and python modules from __future__ import print_function -from main_web_functionality import check_main_web_functionality -from link_checker import check_links import argparse +from link_checker import check_links +from mapping_tests import check_mapping +from main_web_functionality import check_main_web_functionality print("Mechanical Rob firing up...") @@ -15,6 +16,7 @@ def run_all(args_obj, parser): print("Running all tests.") check_main_web_functionality(args_obj, parser) check_links(args_obj, parser) + check_mapping(args_obj, parser) # TODO: Add other functions as they are created. def print_help(args_obj, parser): @@ -51,14 +53,14 @@ parser.add_argument("-f", "--main-functionality", dest="accumulate" , default=print_help , help="Checks for main web functionality.") +parser.add_argument("-m", "--mapping", dest="accumulate" + , action="store_const", const=check_mapping, default=print_help + , help="Checks for mapping.") + # parser.add_argument("-n", "--navigation", dest="accumulate" # , action="store_const", const=check_navigation, default=print_help # , help="Checks for navigation.") -# parser.add_argument("-m", "--mapping", dest="accumulate" -# , action="store_const", const=check_mapping, default=print_help -# , help="Checks for mapping.") - # parser.add_argument("-s", "--skip-broken", dest="accumulate" # , action="store_const", const=dummy, default=print_help # , help="Skip tests that are known to be broken.") -- cgit v1.2.3 From 13ba222e4a04c514d10c35caafb5297309914d4c Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Fri, 30 Mar 2018 07:49:01 +0000 Subject: Tests: all tests run --- test/requests/link_checker.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py index 256bf6ef..5adbf9a9 100644 --- a/test/requests/link_checker.py +++ b/test/requests/link_checker.py @@ -25,10 +25,16 @@ def get_links(doc): , doc.cssselect("a"))) def verify_link(link): + if link[0] == "#": + # local link on page + return + print("verifying "+link) try: - result = requests.get(link, timeout=20) + result = requests.get(link, timeout=20, verify=False) if result.status_code == 200: print(link+" ==> OK") + elif result.status_code == 307: + print(link+" ==> REDIRECT") else: print("ERROR: link `"+link+"` failed with status " , result.status_code) @@ -37,7 +43,7 @@ def verify_link(link): def check_page(host, start_url): print("") - print("Checking links in page `"+start_url+"`") + print("Checking links host "+host+" in page `"+start_url+"`") doc = parse(start_url).getroot() links = get_links(doc) internal_links = filter(is_internal_link, links) -- cgit v1.2.3 From c4d3f406fb01f81b2b952a622f2f7bb0967c8c91 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Fri, 30 Mar 2018 08:14:02 +0000 Subject: Add --fail argument to test runner --- test/requests/link_checker.py | 9 ++++++++- test/requests/test-website.py | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py index 5adbf9a9..0f81caa4 100644 --- a/test/requests/link_checker.py +++ b/test/requests/link_checker.py @@ -4,6 +4,8 @@ import requests from lxml.html import parse from requests.exceptions import ConnectionError +DO_FAIL=False # fail on error + def is_root_link(link): pattern = re.compile("^/$") return pattern.match(link) @@ -25,6 +27,7 @@ def get_links(doc): , doc.cssselect("a"))) def verify_link(link): + assert(DO_FAIL) if link[0] == "#": # local link on page return @@ -38,8 +41,12 @@ def verify_link(link): else: print("ERROR: link `"+link+"` failed with status " , result.status_code) + if DO_FAIL: + raise Exception("Failed verify") except ConnectionError as ex: print("ERROR: ", link, ex) + if DO_FAIL: + raise ex def check_page(host, start_url): print("") @@ -48,7 +55,7 @@ def check_page(host, start_url): links = get_links(doc) internal_links = filter(is_internal_link, links) external_links = filter(lambda x: not is_internal_link(x), links) - external_links.append("http://somenon-existentsite.brr") + # external_links.append("http://somenon-existentsite.brr") for link in internal_links: verify_link(host+link) diff --git a/test/requests/test-website.py b/test/requests/test-website.py index 2bef6eb1..118c9df1 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -8,12 +8,16 @@ import argparse from link_checker import check_links from mapping_tests import check_mapping from main_web_functionality import check_main_web_functionality +import link_checker +import sys print("Mechanical Rob firing up...") def run_all(args_obj, parser): print("") print("Running all tests.") + print(args_obj) + link_checker.DO_FAIL = args_obj.fail check_main_web_functionality(args_obj, parser) check_links(args_obj, parser) check_mapping(args_obj, parser) @@ -32,6 +36,8 @@ This is Mechanical-Rob - an automated web server tester for """ parser = argparse.ArgumentParser(description=desc) +parser.add_argument("--fail", help="Fail and stop on any error", action="store_true") + parser.add_argument("-d", "--database", metavar="DB", type=str , default="db_webqtl_s" , help="Use database (default db_webqtl_s)") -- cgit v1.2.3 From 1d1446a0452cdbb0b86d8235a3f0c53c89669275 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Fri, 30 Mar 2018 08:25:57 +0000 Subject: Testing: removed test assertion (oops) --- test/requests/link_checker.py | 1 - 1 file changed, 1 deletion(-) (limited to 'test') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py index 0f81caa4..64553ed8 100644 --- a/test/requests/link_checker.py +++ b/test/requests/link_checker.py @@ -27,7 +27,6 @@ def get_links(doc): , doc.cssselect("a"))) def verify_link(link): - assert(DO_FAIL) if link[0] == "#": # local link on page return -- cgit v1.2.3 From 0c600598b4f1c8a19b3bf13aa6cb197494a9c122 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Mon, 2 Apr 2018 08:49:53 +0000 Subject: Testing moved to Python --- test/lib/gntest.rb | 6 ---- test/lib/link_checker.rb | 50 ------------------------------ test/lib/main_web_functionality.rb | 62 -------------------------------------- test/lib/mapping.rb | 58 ----------------------------------- test/lib/navigation.rb | 43 -------------------------- 5 files changed, 219 deletions(-) delete mode 100644 test/lib/gntest.rb delete mode 100644 test/lib/link_checker.rb delete mode 100644 test/lib/main_web_functionality.rb delete mode 100644 test/lib/mapping.rb delete mode 100644 test/lib/navigation.rb (limited to 'test') diff --git a/test/lib/gntest.rb b/test/lib/gntest.rb deleted file mode 100644 index 5b21b3d5..00000000 --- a/test/lib/gntest.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'minitest/autorun' -require 'mechanize' -require 'json' - -# ---- Use some default parameters if not set -$host = "http://localhost:5003" if !$host diff --git a/test/lib/link_checker.rb b/test/lib/link_checker.rb deleted file mode 100644 index 36cb36c8..00000000 --- a/test/lib/link_checker.rb +++ /dev/null @@ -1,50 +0,0 @@ - -SKIP = "mailto:" - -class LinkChecker -end - -describe LinkChecker do - before do - @agent = Mechanize.new - @agent.agent.http.ca_file = '/etc/ssl/certs/ca-certificates.crt' - end - - it "Get to front page" do - page = @agent.get($host) - page.links.each do |link| - puts link.href - if link.href !~ /#{SKIP}/ # /static\/dbdoc\/Hippocampus/ and link.href !~ /mailto:|glossary.html|sample_r|grits.eecs.utk.edu|correlationAnnotation.html/ - # Fetch link, program will crash with exception if link is broken - linkpage = @agent.get(link.href) - puts "Link to #{link.href} is valid, response code #{linkpage.code}" - end - end - - end - - describe LinkChecker do - it "Get to trait page" do - page = @agent.get($host+'/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P') - # p page - - # Get to trait page for 1435395_s_at - # form2 = show_trait_page.forms_with("trait_page")[0] - # form2.fields[30].name.must_equal "variance:C57BL/6J" - # form2.fields[30].value.must_equal "15.287" - - # Test every link on the page to check if it's broken or not - page.links.each do |link| - puts link.href - if link.href !~ /#{SKIP}/ # /static\/dbdoc\/Hippocampus/ and link.href !~ /mailto:|glossary.html|sample_r|grits.eecs.utk.edu|correlationAnnotation.html/ - # Fetch link, program will crash with exception if link is broken - linkpage = @agent.get(link.href) - puts "Link to #{link.href} is valid, response code #{linkpage.code}" - end - end - - end - - end - -end diff --git a/test/lib/main_web_functionality.rb b/test/lib/main_web_functionality.rb deleted file mode 100644 index 9ae49995..00000000 --- a/test/lib/main_web_functionality.rb +++ /dev/null @@ -1,62 +0,0 @@ -# In these tests we navigate from the main page to search - -class MainWebFunctionality -end - -describe MainWebFunctionality do - before do - @agent = Mechanize.new - @agent.agent.http.ca_file = '/etc/ssl/certs/ca-certificates.crt' - end - - describe MainWebFunctionality do - - it "Get to trait page" do - page = @agent.get($host) - p page - form = page.forms[1] - form.buttons[0].value.must_equal "Search" # main menu is loaded - - # http://localhost:5003/search?species=mouse&group=BXD&type=Hippocampus+mRNA&dataset=HC_M2_0606_P&search_terms_or=&search_terms_and=MEAN%3D%2815+16%29+LRS%3D%2823+46%29&FormID=searchResult - form.fields[0].value.must_equal "searchResult" - form.fields[2].value = "MEAN=(15 16) LRS=(23 46)" - form.fields[3].value = "mouse" - form.fields[4].value = "BXD" - form.fields[5].value = "Hippocampus mRNA" - form.fields[6].value = "HC_M2_0606_P" - search_page = @agent.submit(form, form.buttons.first) - p "==================" - p search_page - probe_link = search_page.links.find { |l| l.text =~ /1435395_s_at/ } - probe_link.uri.to_s.must_equal "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P" - show_trait_page = probe_link.click - # p show_trait_page - - # Get to trait page for 1435395_s_at - - form2 = show_trait_page.forms_with("trait_page")[0] - # [name: corr_dataset value: HC_M2_0606_P] - form2.fields.select { |fld| fld.name == 'corr_dataset' }.first.value.must_equal 'HC_M2_0606_P' - if $options[:database] == :small - form2.fields[30].name.must_equal "value:DBA/2J" - else - form2.fields[30].name.must_equal "variance:C57BL/6J" - end - # form2.fields[30].value.must_equal "15.287" - - # Test every link on the page to check if it's broken or not - break if not $options[:link_checker] - show_trait_page.links.each do |link| - puts link.href - if link.href !~ /static\/dbdoc\/Hippocampus/ and link.href !~ /glossary.html|sample_r|grits.eecs.utk.edu|correlationAnnotation.html/ - # Fetch link, program will crash with exception if link is broken - linkpage = @agent.get(link.href) - puts "Link to #{link.href} is valid, response code #{linkpage.code}" - end - end - - end - - end - -end diff --git a/test/lib/mapping.rb b/test/lib/mapping.rb deleted file mode 100644 index 20e5bd40..00000000 --- a/test/lib/mapping.rb +++ /dev/null @@ -1,58 +0,0 @@ -# In these tests we navigate from the main page to a specific trait then hit the different mapping tool buttons (In this case pylMM and r/qtl) followed by computing the results (marker regressions). - -require 'gntest' - -class MappingTest -end - -describe MappingTest do - before do - @agent = Mechanize.new - @agent.agent.http.ca_file = '/etc/ssl/certs/ca-certificates.crt' - end - - describe MappingTest do - it "pylmm mapping tool selection" do - url = $host+'/marker_regression' - - json = JSON::load(File.read('test/data/input/mapping/1435395_s_at_HC_M2_0606_P.json')) - json["method"] = "pylmm" - # p json - page = @agent.post(URI.encode(url), json) - # Unpacking the page is slow - somehow - but the run is enough as a test - # form = page.forms_with("marker_regression")[0] - # form.fields.select { |fld| fld.name == 'dataset' }.first.value.must_equal 'HC_M2_0606_P' - # form.fields.select { |fld| fld.name == 'value:BXD1' }.first.value.must_equal '6.749' - end - end - - describe MappingTest do - it "R/qtl mapping tool selection" do - url = $host+'/marker_regression' # ?trait_id=1435395_s_at&dataset=HC_M2_0606_P' - - json = JSON::load(File.read('test/data/input/mapping/1435395_s_at_HC_M2_0606_P.json')) - # p json - page = @agent.post(URI.encode(url), - json, - ({'Content-Type' => 'application/x-www-form-urlencoded'})) - form = page.forms_with("marker_regression")[0] - p form - form.fields.select { |fld| fld.name == 'dataset' }.first.value.must_equal 'HC_M2_0606_P' - form.fields.select { |fld| fld.name == 'value:BXD1' }.first.value.must_equal "15.034" - end - end - - describe MappingTest do - it "CIM mapping tool selection (using reaper)" do - url = $host+'/marker_regression' - - json = JSON::load(File.read('test/data/input/mapping/1435395_s_at_HC_M2_0606_P.json')) - json["method"] = "reaper" - page = @agent.post(URI.encode(url), json) - form = page.forms_with("marker_regression")[0] - form.fields.select { |fld| fld.name == 'dataset' }.first.value.must_equal 'HC_M2_0606_P' - form.fields.select { |fld| fld.name == 'value:BXD1' }.first.value.must_equal "15.034" - end - end - -end diff --git a/test/lib/navigation.rb b/test/lib/navigation.rb deleted file mode 100644 index ee9f41d2..00000000 --- a/test/lib/navigation.rb +++ /dev/null @@ -1,43 +0,0 @@ -# In these tests we navigate from the main page to a specific trait then hit the different mapping tool buttons (In this case pylMM and r/qtl) followed by computing the results (marker regressions). - - -class MappingTest -end - -describe MappingTest do - before do - @agent = Mechanize.new - @agent.agent.http.ca_file = '/etc/ssl/certs/ca-certificates.crt' - end - - describe MappingTest do - it "pyLMM mapping tool selection" do - break if $options[:skip_broken] - page = @agent.get($host+'/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P') -#Navigates to http://localhost:5003/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P and clicks respective buttons. - link = page.link_with(text: 'pyLMM') - page = link.click - puts page.uri - link = page.link_with(text: 'Compute') - page = link.click - puts page.uri - probe_link.uri.to_s.must_equal "/marker_regression" - end - end - -end - -describe MappingTest do - it "R/qtl mapping tool selection" do - break if $options[:skip_broken] - page = @agent.get($host+'/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P') - link = page.link_with(text: 'R/qtl') - page = link.click - puts page.uri - form.field_with(:name => 'Methods').options[2].select - link = page.link_with(text: 'Compute') - page = link.click - puts page.uri - probe_link.uri.to_s.must_equal "/marker_regression" - end -end -- cgit v1.2.3 From 55cc4c63478de9587e282522540334e5375aebf1 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 13 Apr 2018 15:33:39 +0300 Subject: Use single entry-point for tests * Remove the run-integration-tests.py, and use the test-website.py as the entry point for all tests. This simplifies running the tests for the site. --- test/requests/run-integration-tests.py | 34 ----------------------------- test/requests/test-website.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 34 deletions(-) delete mode 100644 test/requests/run-integration-tests.py (limited to 'test') diff --git a/test/requests/run-integration-tests.py b/test/requests/run-integration-tests.py deleted file mode 100644 index 5e816549..00000000 --- a/test/requests/run-integration-tests.py +++ /dev/null @@ -1,34 +0,0 @@ -import sys -from test_login_local import TestLoginLocal -from test_login_orcid import TestLoginOrcid -from test_login_github import TestLoginGithub -from test_registration import TestRegistration -from unittest import TestSuite, TextTestRunner, TestLoader - -test_cases = [ - TestRegistration - , TestLoginLocal - , TestLoginGithub - , TestLoginOrcid -] - -def suite(gn2_url, es_url): - the_suite = TestSuite() - for case in test_cases: - the_suite.addTests(initTest(case, gn2_url, es_url)) - return the_suite - -def initTest(klass, gn2_url, es_url): - loader = TestLoader() - methodNames = loader.getTestCaseNames(klass) - return [klass(mname, gn2_url, es_url) for mname in methodNames] - -def main(gn2_url, es_url): - runner = TextTestRunner() - runner.run(suite(gn2_url, es_url)) - -if __name__ == "__main__": - if len(sys.argv) < 3: - raise Exception("Required arguments missing:\n\tTry running `run-integration-test.py `") - else: - main(sys.argv[1], sys.argv[2]) diff --git a/test/requests/test-website.py b/test/requests/test-website.py index a33fe708..b2e09bc4 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -12,6 +12,15 @@ from main_web_functionality import check_main_web_functionality import link_checker import sys +# Imports for integration tests +from wqflask import app +from test_login_local import TestLoginLocal +from test_login_orcid import TestLoginOrcid +from test_login_github import TestLoginGithub +from test_registration import TestRegistration +from test_forgot_password import TestForgotPassword +from unittest import TestSuite, TextTestRunner, TestLoader + print("Mechanical Rob firing up...") def run_all(args_obj, parser): @@ -30,6 +39,33 @@ def print_help(args_obj, parser): def dummy(args_obj, parser): print("Not implemented yet.") +def integration_tests(args_obj, parser): + gn2_url = args_obj.host + es_url = app.config.get("ELASTICSEARCH_HOST")+":"+str(app.config.get("ELASTICSEARCH_PORT")) + run_integration_tests(gn2_url, es_url) + +def initTest(klass, gn2_url, es_url): + loader = TestLoader() + methodNames = loader.getTestCaseNames(klass) + return [klass(mname, gn2_url, es_url) for mname in methodNames] + +def integration_suite(gn2_url, es_url): + test_cases = [ + TestRegistration + , TestLoginLocal + , TestLoginGithub + , TestLoginOrcid + , TestForgotPassword + ] + the_suite = TestSuite() + for case in test_cases: + the_suite.addTests(initTest(case, gn2_url, es_url)) + return the_suite + +def run_integration_tests(gn2_url, es_url): + runner = TextTestRunner() + runner.run(integration_suite(gn2_url, es_url)) + desc = """ This is Mechanical-Rob - an automated web server tester for @@ -64,6 +100,10 @@ parser.add_argument("-m", "--mapping", dest="accumulate" , action="store_const", const=check_mapping, default=print_help , help="Checks for mapping.") +parser.add_argument("-i", "--integration-tests", dest="accumulate" + , action="store_const", const=integration_tests, default=print_help + , help="Runs integration tests.") + # Navigation tests deactivated since system relies on Javascript # parser.add_argument("-n", "--navigation", dest="accumulate" # , action="store_const", const=check_navigation, default=print_help -- cgit v1.2.3 From 90da7aa5028d64437f3fcaf903075cbda293b575 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 13 Apr 2018 15:39:47 +0300 Subject: Fix logging in tests * Use the LOG_LEVEL provided by the application settings to enable easy control of logging when running tests. It helps avoid a lot of verbosity when running tests. --- test/requests/parametrized_test.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test') diff --git a/test/requests/parametrized_test.py b/test/requests/parametrized_test.py index abf98fce..c585e910 100644 --- a/test/requests/parametrized_test.py +++ b/test/requests/parametrized_test.py @@ -1,5 +1,6 @@ import logging import unittest +from wqflask import app from elasticsearch import Elasticsearch, TransportError class ParametrizedTest(unittest.TestCase): @@ -14,6 +15,7 @@ class ParametrizedTest(unittest.TestCase): self.es_cleanup = [] es_logger = logging.getLogger("elasticsearch") + es_logger.setLevel(app.config.get("LOG_LEVEL")) es_logger.addHandler( logging.FileHandler("/tmp/es_TestRegistrationInfo.log")) es_trace_logger = logging.getLogger("elasticsearch.trace") -- cgit v1.2.3 From e3e98b0533460837c4ea2eac67c4281eb0ba0012 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Sun, 15 Apr 2018 11:48:06 +0300 Subject: Use existing code. Delay after delete. * Use existing code to get the elasticsearch connection. This should prevent tests from failing in case the way connections to elasticsearch are made change. * Delay a while after deleting to allow elasticsearch to re-index the data, thus preventing subtle bugs in the test. --- test/requests/parametrized_test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/requests/parametrized_test.py b/test/requests/parametrized_test.py index c585e910..50003850 100644 --- a/test/requests/parametrized_test.py +++ b/test/requests/parametrized_test.py @@ -1,6 +1,7 @@ import logging import unittest from wqflask import app +from utility.elasticsearch_tools import get_elasticsearch_connection, get_user_by_unique_column from elasticsearch import Elasticsearch, TransportError class ParametrizedTest(unittest.TestCase): @@ -11,7 +12,7 @@ class ParametrizedTest(unittest.TestCase): self.es_url = es_url def setUp(self): - self.es = Elasticsearch([self.es_url]) + self.es = get_elasticsearch_connection() self.es_cleanup = [] es_logger = logging.getLogger("elasticsearch") @@ -23,7 +24,9 @@ class ParametrizedTest(unittest.TestCase): logging.FileHandler("/tmp/es_TestRegistrationTrace.log")) def tearDown(self): + from time import sleep self.es.delete_by_query( index="users" , doc_type="local" , body={"query":{"match":{"email_address":"test@user.com"}}}) + sleep(1) -- cgit v1.2.3 From 9ac9f94f3b1409ae3a47c8a9e890f578a69b020f Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Sun, 15 Apr 2018 11:56:00 +0300 Subject: Add tests for Forgot Password feature * Add tests to ensure the "Forgot Password" feature works appropriately. --- test/requests/test_forgot_password.py | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 test/requests/test_forgot_password.py (limited to 'test') diff --git a/test/requests/test_forgot_password.py b/test/requests/test_forgot_password.py new file mode 100644 index 00000000..2bf34c5c --- /dev/null +++ b/test/requests/test_forgot_password.py @@ -0,0 +1,52 @@ +import requests +from wqflask import user_manager +from utility.elasticsearch_tools import get_user_by_unique_column +from parameterized import parameterized +from parametrized_test import ParametrizedTest + +passwork_reset_link = '' +forgot_password_page = None + +class TestForgotPassword(ParametrizedTest): + + def setUp(self): + super(TestForgotPassword, self).setUp() + self.forgot_password_url = self.gn2_url+"/n/forgot_password_submit" + def send_email(to_addr, msg, fromaddr="no-reply@genenetwork.org"): + print("CALLING: send_email_mock()") + email_data = { + "to_addr": to_addr + , "msg": msg + , "fromaddr": from_addr} + + data = { + "es_connection": self.es, + "email_address": "test@user.com", + "full_name": "Test User", + "organization": "Test Organisation", + "password": "test_password", + "password_confirm": "test_password" + } + user_manager.basic_info = lambda : { "basic_info": "basic" } + user_manager.RegisterUser(data) + + def testWithoutEmail(self): + data = {"email_address": ""} + error_notification = '
You MUST provide an email
' + result = requests.post(self.forgot_password_url, data=data) + self.assertEqual(result.url, self.gn2_url+"/n/forgot_password") + self.assertTrue( + result.content.find(error_notification) >= 0 + , "Error message should be displayed but was not") + + def testWithNonExistingEmail(self): + # Monkey patching doesn't work, so simply test that getting by email + # returns the correct data + user = get_user_by_unique_column(self.es, "email_address", "non-existent@domain.com") + self.assertTrue(user is None, "Should not find non-existent user") + + def testWithExistingEmail(self): + # Monkey patching doesn't work, so simply test that getting by email + # returns the correct data + user = get_user_by_unique_column(self.es, "email_address", "test@user.com") + self.assertTrue(user is not None, "Should find user") -- cgit v1.2.3 From 61c13a09dba95958f183dc55f3d59c8856b5f753 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Wed, 13 Feb 2019 12:41:45 +0000 Subject: Removed pylmm references and related functions --- bin/genenetwork2 | 1 - etc/default_settings.py | 1 - test/requests/mapping_tests.py | 10 -- wqflask/base/data_set.py | 2 +- wqflask/utility/tools.py | 4 - wqflask/wqflask/heatmap/heatmap.py | 5 +- wqflask/wqflask/marker_regression/run_mapping.py | 204 +---------------------- 7 files changed, 4 insertions(+), 223 deletions(-) (limited to 'test') diff --git a/bin/genenetwork2 b/bin/genenetwork2 index 21f0db13..7c875274 100755 --- a/bin/genenetwork2 +++ b/bin/genenetwork2 @@ -131,7 +131,6 @@ else export LC_ALL=C # FIXME export GUIX_GENENETWORK_FILES="$GN2_PROFILE/share/genenetwork2" export PLINK_COMMAND="$GN2_PROFILE/bin/plink2" - export PYLMM_COMMAND="$GN2_PROFILE/bin/pylmm_redis" export GEMMA_COMMAND="$GN2_PROFILE/bin/gemma" if [ -z $GEMMA_WRAPPER_COMMAND ]; then export GEMMA_WRAPPER_COMMAND="$GN2_PROFILE/bin/gemma-wrapper" diff --git a/etc/default_settings.py b/etc/default_settings.py index 3e54ad1f..a1fe81e5 100644 --- a/etc/default_settings.py +++ b/etc/default_settings.py @@ -89,7 +89,6 @@ GENENETWORK_FILES = HOME+"/genotype_files" # base dir for all static data fil JS_GN_PATH = os.environ['HOME']+"/genenetwork/javascript" # ---- GN2 Executables (overwrite for testing only) -# PYLMM_COMMAND = str.strip(os.popen("which pylmm_redis").read()) # PLINK_COMMAND = str.strip(os.popen("which plink2").read()) # GEMMA_COMMAND = str.strip(os.popen("which gemma").read()) # GEMMA_WRAPPER_COMMAND = str.strip(os.popen("which gemma-wrapper").read()) diff --git a/test/requests/mapping_tests.py b/test/requests/mapping_tests.py index 8eb19de7..6de81bfe 100644 --- a/test/requests/mapping_tests.py +++ b/test/requests/mapping_tests.py @@ -11,16 +11,6 @@ def load_data_from_file(): file_data = json.loads(file_handle.read().encode("utf-8")) return file_data -def check_pylmm_tool_selection(host, data): - print("") - print("pylmm mapping tool selection") - data["method"] = "pylmm" - page = requests.post(host+"/marker_regression", data=data) - doc = fromstring(page.text) - form = doc.forms[1] - assert form.fields["dataset"] == "HC_M2_0606_P" - assert form.fields["value:BXD1"] == "15.034" # Check value in the file - def check_R_qtl_tool_selection(host, data): print("") print("R/qtl mapping tool selection") diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 79f72390..ca6621e9 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -317,7 +317,7 @@ class DatasetGroup(object): mapping_id = g.db.execute("select MappingMethodId from InbredSet where Name= '%s'" % self.name).fetchone()[0] if mapping_id == "1": - mapping_names = ["QTLReaper", "PYLMM", "R/qtl"] + mapping_names = ["QTLReaper", "R/qtl"] elif mapping_id == "2": mapping_names = ["GEMMA"] elif mapping_id == "4": diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index ea216a35..86ef2e1e 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -107,9 +107,6 @@ def js_path(module=None): return try_guix raise "No JS path found for "+module+" (if not in Guix check JS_GN_PATH)" -def pylmm_command(guess=None): - return assert_bin(get_setting("PYLMM_COMMAND",guess)) - def gemma_command(guess=None): return assert_bin(get_setting("GEMMA_COMMAND",guess)) @@ -276,7 +273,6 @@ SMTP_CONNECT = get_setting('SMTP_CONNECT') SMTP_USERNAME = get_setting('SMTP_USERNAME') SMTP_PASSWORD = get_setting('SMTP_PASSWORD') -PYLMM_COMMAND = app_set("PYLMM_COMMAND",pylmm_command()) GEMMA_COMMAND = app_set("GEMMA_COMMAND",gemma_command()) assert(GEMMA_COMMAND is not None) PLINK_COMMAND = app_set("PLINK_COMMAND",plink_command()) diff --git a/wqflask/wqflask/heatmap/heatmap.py b/wqflask/wqflask/heatmap/heatmap.py index ff589693..1bdf252b 100644 --- a/wqflask/wqflask/heatmap/heatmap.py +++ b/wqflask/wqflask/heatmap/heatmap.py @@ -24,12 +24,9 @@ import reaper from base.trait import GeneralTrait from base import data_set from base import species -# from wqflask.my_pylmm.pyLMM import lmm -# from wqflask.my_pylmm.pyLMM import input from utility import helper_functions from utility import Plot, Bunch from utility import temp_data -from utility.tools import PYLMM_COMMAND from MySQLdb import escape_string as escape @@ -144,4 +141,4 @@ class Heatmap(object): if qtl.additive > 0: self.trait_results[this_trait.name].append(-float(qtl.lrs)) else: - self.trait_results[this_trait.name].append(float(qtl.lrs)) \ No newline at end of file + self.trait_results[this_trait.name].append(float(qtl.lrs)) diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py index 3057e340..73d985b8 100644 --- a/wqflask/wqflask/marker_regression/run_mapping.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -38,7 +38,7 @@ from utility import temp_data from utility.benchmark import Bench from wqflask.marker_regression import gemma_mapping, rqtl_mapping, qtlreaper_mapping, plink_mapping -from utility.tools import locate, locate_ignore_error, PYLMM_COMMAND, GEMMA_COMMAND, PLINK_COMMAND, TEMPDIR +from utility.tools import locate, locate_ignore_error, GEMMA_COMMAND, PLINK_COMMAND, TEMPDIR from utility.external import shell from base.webqtlConfig import TMPDIR, GENERATED_TEXT_DIR @@ -239,11 +239,6 @@ class RunMapping(object): self.manhattan_plot = True results = plink_mapping.run_plink(self.this_trait, self.dataset, self.species, self.vals, self.maf) #results = self.run_plink() - elif self.mapping_method == "pylmm": - logger.debug("RUNNING PYLMM") - if self.num_perm > 0: - self.run_permutations(str(temp_uuid)) - results = self.gen_data(str(temp_uuid)) else: logger.debug("RUNNING NOTHING") @@ -354,201 +349,6 @@ class RunMapping(object): count, p_values = self.parse_rqtl_output(plink_output_filename) - def run_permutations(self, temp_uuid): - """Runs permutations and gets significant and suggestive LOD scores""" - - top_lod_scores = [] - - #logger.debug("self.num_perm:", self.num_perm) - - for permutation in range(self.num_perm): - - pheno_vector = np.array([val == "x" and np.nan or float(val) for val in self.vals]) - np.random.shuffle(pheno_vector) - - key = "pylmm:input:" + temp_uuid - - if self.dataset.group.species == "human": - p_values, t_stats = self.gen_human_results(pheno_vector, key, temp_uuid) - else: - genotype_data = [marker['genotypes'] for marker in self.dataset.group.markers.markers] - - no_val_samples = self.identify_empty_samples() - trimmed_genotype_data = self.trim_genotypes(genotype_data, no_val_samples) - - genotype_matrix = np.array(trimmed_genotype_data).T - - params = dict(pheno_vector = pheno_vector.tolist(), - genotype_matrix = genotype_matrix.tolist(), - restricted_max_likelihood = True, - refit = False, - temp_uuid = temp_uuid, - - # meta data - timestamp = datetime.datetime.now().isoformat(), - ) - - json_params = json.dumps(params) - Redis.set(key, json_params) - Redis.expire(key, 60*60) - - command = PYLMM_COMMAND+' --key {} --species {}'.format(key,"other") - shell(command) - - json_results = Redis.blpop("pylmm:results:" + temp_uuid, 45*60) - results = json.loads(json_results[1]) - p_values = [float(result) for result in results['p_values']] - - lowest_p_value = 1 - for p_value in p_values: - if p_value < lowest_p_value: - lowest_p_value = p_value - - #logger.debug("lowest_p_value:", lowest_p_value) - top_lod_scores.append(-math.log10(lowest_p_value)) - - #logger.debug("top_lod_scores:", top_lod_scores) - - self.suggestive = np.percentile(top_lod_scores, 67) - self.significant = np.percentile(top_lod_scores, 95) - - def gen_data(self, temp_uuid): - """Generates p-values for each marker""" - - logger.debug("self.vals is:", self.vals) - pheno_vector = np.array([(val == "x" or val == "") and np.nan or float(val) for val in self.vals]) - - #lmm_uuid = str(uuid.uuid4()) - - key = "pylmm:input:" + temp_uuid - logger.debug("key is:", pf(key)) - #with Bench("Loading cache"): - # result = Redis.get(key) - - if self.dataset.group.species == "human": - p_values, t_stats = self.gen_human_results(pheno_vector, key, temp_uuid) - - else: - logger.debug("NOW CWD IS:", os.getcwd()) - genotype_data = [marker['genotypes'] for marker in self.dataset.group.markers.markers] - - no_val_samples = self.identify_empty_samples() - trimmed_genotype_data = self.trim_genotypes(genotype_data, no_val_samples) - - genotype_matrix = np.array(genotype_data).T - - #logger.debug("pheno_vector: ", pf(pheno_vector)) - #logger.debug("genotype_matrix: ", pf(genotype_matrix)) - #logger.debug("genotype_matrix.shape: ", pf(genotype_matrix.shape)) - - #params = {"pheno_vector": pheno_vector, - # "genotype_matrix": genotype_matrix, - # "restricted_max_likelihood": True, - # "refit": False, - # "temp_data": tempdata} - - # logger.debug("genotype_matrix:", str(genotype_matrix.tolist())) - # logger.debug("pheno_vector:", str(pheno_vector.tolist())) - - params = dict(pheno_vector = pheno_vector.tolist(), - genotype_matrix = genotype_matrix.tolist(), - restricted_max_likelihood = True, - refit = False, - temp_uuid = temp_uuid, - - # meta data - timestamp = datetime.datetime.now().isoformat(), - ) - - json_params = json.dumps(params) - #logger.debug("json_params:", json_params) - Redis.set(key, json_params) - Redis.expire(key, 60*60) - logger.debug("before printing command") - - command = PYLMM_COMMAND + ' --key {} --species {}'.format(key, "other") - logger.debug("command is:", command) - logger.debug("after printing command") - - shell(command) - - #t_stats, p_values = lmm.run(key) - #lmm.run(key) - - json_results = Redis.blpop("pylmm:results:" + temp_uuid, 45*60) - results = json.loads(json_results[1]) - p_values = [float(result) for result in results['p_values']] - t_stats = results['t_stats'] - - #t_stats, p_values = lmm.run( - # pheno_vector, - # genotype_matrix, - # restricted_max_likelihood=True, - # refit=False, - # temp_data=tempdata - #) - #logger.debug("p_values:", p_values) - - self.dataset.group.markers.add_pvalues(p_values) - - return self.dataset.group.markers.markers - - def gen_human_results(self, pheno_vector, key, temp_uuid): - file_base = locate(self.dataset.group.name,"mapping") - - plink_input = input.plink(file_base, type='b') - input_file_name = os.path.join(webqtlConfig.SNP_PATH, self.dataset.group.name + ".snps.gz") - - pheno_vector = pheno_vector.reshape((len(pheno_vector), 1)) - covariate_matrix = np.ones((pheno_vector.shape[0],1)) - kinship_matrix = np.fromfile(open(file_base + '.kin','r'),sep=" ") - kinship_matrix.resize((len(plink_input.indivs),len(plink_input.indivs))) - - logger.debug("Before creating params") - - params = dict(pheno_vector = pheno_vector.tolist(), - covariate_matrix = covariate_matrix.tolist(), - input_file_name = input_file_name, - kinship_matrix = kinship_matrix.tolist(), - refit = False, - temp_uuid = temp_uuid, - - # meta data - timestamp = datetime.datetime.now().isoformat(), - ) - - logger.debug("After creating params") - - json_params = json.dumps(params) - Redis.set(key, json_params) - Redis.expire(key, 60*60) - - logger.debug("Before creating the command") - - command = PYLMM_COMMAND+' --key {} --species {}'.format(key, "human") - - logger.debug("command is:", command) - - os.system(command) - - json_results = Redis.blpop("pylmm:results:" + temp_uuid, 45*60) - results = json.loads(json_results[1]) - t_stats = results['t_stats'] - p_values = results['p_values'] - - - #p_values, t_stats = lmm.run_human(key) - - #p_values, t_stats = lmm.run_human( - # pheno_vector, - # covariate_matrix, - # input_file_name, - # kinship_matrix, - # loading_progress=tempdata - # ) - - return p_values, t_stats - def identify_empty_samples(self): no_val_samples = [] for sample_count, val in enumerate(self.vals): @@ -657,4 +457,4 @@ def trim_markers_for_table(markers): trimmed_sorted_markers = sorted_markers[:2000] return trimmed_sorted_markers else: - return sorted_markers \ No newline at end of file + return sorted_markers -- cgit v1.2.3