From 48b606eee6836512168fb6f2bbd0c3de2892b231 Mon Sep 17 00:00:00 2001 From: Alice Jacques Date: Tue, 12 Mar 2024 14:39:29 -0700 Subject: [PATCH 1/8] Start of adding auth client tests --- tests/expected_pat.py | 40 +++++++++++ tests/tests_api.py | 153 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) diff --git a/tests/expected_pat.py b/tests/expected_pat.py index 55c7979..f0ed82a 100644 --- a/tests/expected_pat.py +++ b/tests/expected_pat.py @@ -168,3 +168,43 @@ #reorder_2b = [1254334738051655680, 1254335012929562624, None] reorder_2b = [39627926995470031, 39627920993422590, None] + +authorized_1 = {'Loggedin_As': 'test_user_1@noirlab.edu', + 'Authorized_Datasets': {'BOSS-DR16', + 'DESI-EDR', + 'SDSS-DR16', + 'SDSS-DR17-test'}} + +authorized_2 = {'Loggedin_As': 'test_user_2@noirlab.edu', + 'Authorized_Datasets': {'BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'}} + +authorized_3 = {'Loggedin_As': 'Anonymous', + 'Authorized_Datasets': {'BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'}} + +auth_find_1 = ['84452fad-dbe7-11ee-a970-525400aad0aa', '847e0be4-dbe7-11ee-b095-525400aad0aa'] + +auth_find_2 = ['00769ec9-9931-11ee-97de-525400aad0aa', + '00b0904d-992f-11ee-b7f9-525400aad0aa', + '00c6d798-9931-11ee-af11-525400aad0aa'] + +auth_find_4 = ['00769ec9-9931-11ee-97de-525400aad0aa', + '00b0904d-992f-11ee-b7f9-525400aad0aa', + '00c6d798-9931-11ee-af11-525400aad0aa', + '010eb4d0-992f-11ee-89de-525400aad0aa', + '014ac8ea-9931-11ee-b693-525400aad0aa', + '01c9187a-9931-11ee-bbbc-525400aad0aa', + '01db0ea0-9930-11ee-a576-525400aad0aa', + '020ed77c-992f-11ee-aefb-525400aad0aa', + '022ab30b-9931-11ee-a372-525400aad0aa', + '024c9ba1-9930-11ee-aa56-525400aad0aa'] + +auth_find_6 = ['00769ec9-9931-11ee-97de-525400aad0aa', + '00b0904d-992f-11ee-b7f9-525400aad0aa', + '00c6d798-9931-11ee-af11-525400aad0aa', + '010eb4d0-992f-11ee-89de-525400aad0aa', + '014ac8ea-9931-11ee-b693-525400aad0aa', + '01c9187a-9931-11ee-bbbc-525400aad0aa', + '01db0ea0-9930-11ee-a576-525400aad0aa', + '020ed77c-992f-11ee-aefb-525400aad0aa', + '022ab30b-9931-11ee-a372-525400aad0aa', + '024c9ba1-9930-11ee-aa56-525400aad0aa'] diff --git a/tests/tests_api.py b/tests/tests_api.py index c102a50..ad59629 100755 --- a/tests/tests_api.py +++ b/tests/tests_api.py @@ -666,3 +666,156 @@ def test_align_7(self): with self.assertRaises(Exception, msg=msg): ar_dict, grid = sg.align_records(got.records, precision=11) # shape = ar_dict['flux'].shape + +class AuthTest(unittest.TestCase): + """Test authorization and authentication features""" + + @classmethod + def setUpClass(cls): + if clverb: + print( + f"\n# Running AuthTest:setUpClass() " + "{str(datetime.datetime.now())}" + ) + + cls.client = sparcl.client.SparclClient( + url=serverurl, verbose=clverb, show_curl=showcurl + ) + + # Test users + cls.auth_user = 'test_user_1@noirlab.edu' + cls.unauth_user = 'test_user_2@noirlab.edu' + cls.non_user = 'test_user_3@noirlab.edu' + cls.usrpw = 'pass123word' + + out = ['sparcl_id', 'data_release'] + cons = {'spectype': ['GALAXY'], + 'redshift': [0.5, 0.9], + 'data_release': ['BOSS-DR16', 'SDSS-DR16']} + found = cls.client.find(outfields=out, constraints=cons, + limit=10) + + cls.uuid_list4 = [ + "00001ebf-d030-4d59-97e5-060c47202897", + "ff1e9a12-f21a-4050-bada-a1e67a265885", + ] + if clverb: + print( + f"\n# Completed AuthTest:setUpClass() " + f"{str(datetime.datetime.now())}\n" + ) + + @classmethod + def tearDownClass(cls): + pass + + def test_authorized_1(self): + """Test authorized method with authorized user signed in""" + self.client.login(self.auth_user, self.usrpw) + actual = self.client.authorized + if showact: + print(f"authorized_1: actual={actual}") + + self.assertEqual(actual, exp.authorized_1, msg="Actual to Expected") + self.client.logout() + + def test_authorized_2(self): + """Test authorized method with unauthorized user signed in""" + self.client.login(self.unauth_user, self.usrpw) + actual = self.client.authorized + if showact: + print(f"authorized_2: actual={actual}") + + self.assertEqual(actual, exp.authorized_2, msg="Actual to Expected") + self.client.logout() + + def test_authorized_3(self): + """Test authorized method on anonymous user not signed in""" + actual = self.client.authorized + if showact: + print(f"authorized_3: actual={actual}") + + self.assertEqual(actual, exp.authorized_3, msg="Actual to Expected") + + def test_auth_find_1(self): + """Test find method with authorized user; private data set + specified""" + self.client.login(self.auth_user, self.usrpw) + out = ['sparcl_id', 'data_release'] + cons = {'spectype': ['GALAXY'], + 'redshift': [0.5, 0.9], + 'data_release': ['SDSS-DR17-test']} + found = self.client.find(outfields=out, constraints=cons, + limit=2, sort='sparcl_id') + actual = sorted(found.ids) + if showact: + print(f"auth_find_1: actual={pf(actual)}") + self.assertEqual(actual, sorted(exp.auth_find_1), msg="Actual to Expected") + self.client.logout() + + def test_auth_find_2(self): + """Test find method with authorized user; no data sets specified""" + self.client.login(self.auth_user, self.usrpw) + out = ['sparcl_id', 'data_release'] + cons = {'spectype': ['GALAXY'], + 'redshift': [0.5, 0.9]} + found = self.client.find(outfields=out, constraints=cons, + limit=3, sort='sparcl_id') + actual = sorted(found.ids) + if showact: + print(f"auth_find_2: actual={pf(actual)}") + self.assertEqual(actual, sorted(exp.auth_find_2), msg="Actual to Expected") + self.client.logout() + + def test_auth_find_3(self): + """Test find method with unauthorized user; private data set + specified""" + self.client.login(self.unauth_user, self.usrpw) + out = ['sparcl_id', 'data_release'] + cons = {'spectype': ['GALAXY'], + 'redshift': [0.5, 0.9], + 'data_release': ['SDSS-DR17-test', 'SDSS-DR16']} + ### Replace exception name below once real one is created + with self.assertRaises(ex.UnknownServerError): + self.client.find(outfields=out, constraints=cons, + limit=3, sort='sparcl_id') + self.client.logout() + + def test_auth_find_4(self): + """Test find method with unauthorized user; no data sets specified""" + self.client.login(self.unauth_user, self.usrpw) + out = ['sparcl_id', 'data_release'] + cons = {'spectype': ['GALAXY'], + 'redshift': [0.5, 0.9]} + found = self.client.find(outfields=out, constraints=cons, + limit=10, sort='sparcl_id') + actual = sorted(found.ids) + if showact: + print(f"auth_find_4: actual={pf(actual)}") + self.assertEqual(actual, sorted(exp.auth_find_4), msg="Actual to Expected") + self.client.logout() + + def test_auth_find_5(self): + """Test find method with anonymous user; private data set + specified""" + out = ['sparcl_id', 'data_release'] + cons = {'spectype': ['GALAXY'], + 'redshift': [0.5, 0.9], + 'data_release': ['SDSS-DR17-test', 'SDSS-DR16']} + ### Replace exception name below once real one is created + with self.assertRaises(ex.UnknownServerError): + self.client.find(outfields=out, constraints=cons, + limit=3, sort='sparcl_id') + + def test_auth_find_6(self): + """Test find method with anonymous user; no data sets specified""" + out = ['sparcl_id', 'data_release'] + cons = {'spectype': ['GALAXY'], + 'redshift': [0.5, 0.9]} + found = self.client.find(outfields=out, constraints=cons, + limit=10, sort='sparcl_id') + actual = sorted(found.ids) + if showact: + print(f"auth_find_6: actual={pf(actual)}") + self.assertEqual(actual, sorted(exp.auth_find_6), msg="Actual to Expected") + From ac2a1f357af63f5732241a1003d7c6094e7b1aea Mon Sep 17 00:00:00 2001 From: Alice Jacques Date: Tue, 12 Mar 2024 15:01:14 -0700 Subject: [PATCH 2/8] Use getpass --- tests/tests_api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/tests_api.py b/tests/tests_api.py index ad59629..b294932 100755 --- a/tests/tests_api.py +++ b/tests/tests_api.py @@ -32,6 +32,7 @@ import unittest from unittest import skip import datetime +from getpass import getpass #! from unittest mock, skipIf, skipUnless #!import warnings @@ -686,7 +687,7 @@ def setUpClass(cls): cls.auth_user = 'test_user_1@noirlab.edu' cls.unauth_user = 'test_user_2@noirlab.edu' cls.non_user = 'test_user_3@noirlab.edu' - cls.usrpw = 'pass123word' + cls.usrpw = getpass() out = ['sparcl_id', 'data_release'] cons = {'spectype': ['GALAXY'], From 31678516d2c021656da68cd5287f49ed36efddc0 Mon Sep 17 00:00:00 2001 From: Alice Jacques Date: Wed, 13 Mar 2024 12:45:50 -0700 Subject: [PATCH 3/8] Add auth retrieve tests --- tests/expected_pat.py | 17 +++- tests/tests_api.py | 177 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 172 insertions(+), 22 deletions(-) diff --git a/tests/expected_pat.py b/tests/expected_pat.py index f0ed82a..0cac3a3 100644 --- a/tests/expected_pat.py +++ b/tests/expected_pat.py @@ -181,7 +181,8 @@ authorized_3 = {'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'}} -auth_find_1 = ['84452fad-dbe7-11ee-a970-525400aad0aa', '847e0be4-dbe7-11ee-b095-525400aad0aa'] +auth_find_1 = ['84452fad-dbe7-11ee-a970-525400aad0aa', + '847e0be4-dbe7-11ee-b095-525400aad0aa'] auth_find_2 = ['00769ec9-9931-11ee-97de-525400aad0aa', '00b0904d-992f-11ee-b7f9-525400aad0aa', @@ -208,3 +209,17 @@ '020ed77c-992f-11ee-aefb-525400aad0aa', '022ab30b-9931-11ee-a372-525400aad0aa', '024c9ba1-9930-11ee-aa56-525400aad0aa'] + +auth_retrieve_1 = ('SDSS-DR16, 3878 ; SDSS-DR16, 3878 ; ' + 'SDSS-DR17-test, 3859 ; SDSS-DR17-test, 3859 ; ') + +auth_retrieve_2 = ('BOSS-DR16, 4615 ; BOSS-DR16, 4615 ; ' + 'SDSS-DR16, 3878 ; SDSS-DR16, 3878 ; ' + 'DESI-EDR, 7781 ; DESI-EDR, 7781 ; ' + 'SDSS-DR17-test, 3859 ; SDSS-DR17-test, 3859 ; ') + +auth_retrieve_5 = ('SDSS-DR16, 3878 ; SDSS-DR16, 3878 ; ' + 'DESI-EDR, 7781 ; DESI-EDR, 7781 ; ') + +auth_retrieve_8 = ('BOSS-DR16, 4615 ; BOSS-DR16, 4615 ; ' + 'SDSS-DR16, 3878 ; SDSS-DR16, 3878 ; ') diff --git a/tests/tests_api.py b/tests/tests_api.py index b294932..237bb77 100755 --- a/tests/tests_api.py +++ b/tests/tests_api.py @@ -686,20 +686,28 @@ def setUpClass(cls): # Test users cls.auth_user = 'test_user_1@noirlab.edu' cls.unauth_user = 'test_user_2@noirlab.edu' - cls.non_user = 'test_user_3@noirlab.edu' cls.usrpw = getpass() - out = ['sparcl_id', 'data_release'] - cons = {'spectype': ['GALAXY'], - 'redshift': [0.5, 0.9], - 'data_release': ['BOSS-DR16', 'SDSS-DR16']} - found = cls.client.find(outfields=out, constraints=cons, - limit=10) + # Sample list of sparcl_ids from each data set + cls.uuid_priv = [ + '84452fad-dbe7-11ee-a970-525400aad0aa', + '847e0be4-dbe7-11ee-b095-525400aad0aa'] + + cls.uuid_bossdr16 = [ + '00b0904d-992f-11ee-b7f9-525400aad0aa', + '010eb4d0-992f-11ee-89de-525400aad0aa'] + + cls.uuid_sdssdr16 = [ + '0fad3e28-992f-11ee-a9e7-525400aad0aa', + '12ec49f6-992f-11ee-8003-525400aad0aa'] + + cls.uuid_desiedr = [ + '00769ec9-9931-11ee-97de-525400aad0aa', + '00c6d798-9931-11ee-af11-525400aad0aa'] + + cls.uuid_all = (cls.uuid_priv + cls.uuid_bossdr16 + + cls.uuid_sdssdr16 + cls.uuid_desiedr) - cls.uuid_list4 = [ - "00001ebf-d030-4d59-97e5-060c47202897", - "ff1e9a12-f21a-4050-bada-a1e67a265885", - ] if clverb: print( f"\n# Completed AuthTest:setUpClass() " @@ -747,11 +755,12 @@ def test_auth_find_1(self): 'redshift': [0.5, 0.9], 'data_release': ['SDSS-DR17-test']} found = self.client.find(outfields=out, constraints=cons, - limit=2, sort='sparcl_id') + limit=2, sort='sparcl_id') actual = sorted(found.ids) if showact: print(f"auth_find_1: actual={pf(actual)}") - self.assertEqual(actual, sorted(exp.auth_find_1), msg="Actual to Expected") + self.assertEqual(actual, sorted(exp.auth_find_1), + msg="Actual to Expected") self.client.logout() def test_auth_find_2(self): @@ -761,11 +770,12 @@ def test_auth_find_2(self): cons = {'spectype': ['GALAXY'], 'redshift': [0.5, 0.9]} found = self.client.find(outfields=out, constraints=cons, - limit=3, sort='sparcl_id') + limit=3, sort='sparcl_id') actual = sorted(found.ids) if showact: print(f"auth_find_2: actual={pf(actual)}") - self.assertEqual(actual, sorted(exp.auth_find_2), msg="Actual to Expected") + self.assertEqual(actual, sorted(exp.auth_find_2), + msg="Actual to Expected") self.client.logout() def test_auth_find_3(self): @@ -776,7 +786,7 @@ def test_auth_find_3(self): cons = {'spectype': ['GALAXY'], 'redshift': [0.5, 0.9], 'data_release': ['SDSS-DR17-test', 'SDSS-DR16']} - ### Replace exception name below once real one is created + # Replace exception name below once real one is created with self.assertRaises(ex.UnknownServerError): self.client.find(outfields=out, constraints=cons, limit=3, sort='sparcl_id') @@ -789,11 +799,12 @@ def test_auth_find_4(self): cons = {'spectype': ['GALAXY'], 'redshift': [0.5, 0.9]} found = self.client.find(outfields=out, constraints=cons, - limit=10, sort='sparcl_id') + limit=10, sort='sparcl_id') actual = sorted(found.ids) if showact: print(f"auth_find_4: actual={pf(actual)}") - self.assertEqual(actual, sorted(exp.auth_find_4), msg="Actual to Expected") + self.assertEqual(actual, sorted(exp.auth_find_4), + msg="Actual to Expected") self.client.logout() def test_auth_find_5(self): @@ -803,7 +814,7 @@ def test_auth_find_5(self): cons = {'spectype': ['GALAXY'], 'redshift': [0.5, 0.9], 'data_release': ['SDSS-DR17-test', 'SDSS-DR16']} - ### Replace exception name below once real one is created + # Replace exception name below once real one is created with self.assertRaises(ex.UnknownServerError): self.client.find(outfields=out, constraints=cons, limit=3, sort='sparcl_id') @@ -814,9 +825,133 @@ def test_auth_find_6(self): cons = {'spectype': ['GALAXY'], 'redshift': [0.5, 0.9]} found = self.client.find(outfields=out, constraints=cons, - limit=10, sort='sparcl_id') + limit=10, sort='sparcl_id') actual = sorted(found.ids) if showact: print(f"auth_find_6: actual={pf(actual)}") - self.assertEqual(actual, sorted(exp.auth_find_6), msg="Actual to Expected") + self.assertEqual(actual, sorted(exp.auth_find_6), + msg="Actual to Expected") + + def test_auth_retrieve_1(self): + """Test retrieve method with authorized user; private data + set specified""" + self.client.login(self.auth_user, self.usrpw) + inc = ['data_release', 'flux'] + drs = ['SDSS-DR16', 'SDSS-DR17-test'] + uuids = self.uuid_priv + self.uuid_sdssdr16 + got = self.client.retrieve(uuid_list=uuids, + include=inc, + dataset_list=drs) + actual = '' + for rec in got.records: + actual1 = rec.data_release + ', ' + str(len(rec.flux)) + ' ; ' + actual = actual + actual1 + if showact: + print(f"auth_retrieve_1: actual={pf(actual)}") + self.assertEqual(actual, exp.auth_retrieve_1, + msg="Actual to Expected") + self.client.logout() + + def test_auth_retrieve_2(self): + """Test retrieve method with authorized user; no data + sets specified""" + self.client.login(self.auth_user, self.usrpw) + inc = ['data_release', 'wavelength'] + got = self.client.retrieve(uuid_list=self.uuid_all, + include=inc) + actual = '' + for rec in got.records: + actual1 = (rec.data_release + ', ' + + str(len(rec.wavelength)) + ' ; ') + actual = actual + actual1 + if showact: + print(f"auth_retrieve_2: actual={pf(actual)}") + self.assertEqual(actual, exp.auth_retrieve_2, + msg="Actual to Expected") + self.client.logout() + def test_auth_retrieve_3(self): + """Test retrieve method with unauthorized user; private data + set specified""" + self.client.login(self.unauth_user, self.usrpw) + inc = ['data_release', 'ivar'] + drs = ['DESI-EDR', 'SDSS-DR17-test'] + uuids = self.uuid_desiedr + self.uuid_priv + # Replace exception name below once real one is created + with self.assertRaises(ex.UnknownServerError): + self.client.retrieve(uuid_list=uuids, + include=inc, + dataset_list=drs) + self.client.logout() + + def test_auth_retrieve_4(self): + """Test retrieve method with unauthorized user; no data + sets specified""" + self.client.login(self.unauth_user, self.usrpw) + inc = ['data_release', 'wave_sigma'] + # Replace exception name below once real one is created + with self.assertRaises(ex.UnknownServerError): + self.client.retrieve(uuid_list=self.uuid_all, + include=inc) + self.client.logout() + + def test_auth_retrieve_5(self): + """Test retrieve method with unauthorized user; public data + sets specified""" + self.client.login(self.unauth_user, self.usrpw) + inc = ['data_release', 'wave_sigma'] + drs = ['SDSS-DR16', 'DESI-EDR'] + uuids = self.uuid_sdssdr16 + self.uuid_desiedr + got = self.client.retrieve(uuid_list=uuids, + include=inc, + dataset_list=drs) + actual = '' + for rec in got.records: + actual1 = (rec.data_release + ', ' + + str(len(rec.wave_sigma)) + ' ; ') + actual = actual + actual1 + if showact: + print(f"auth_retrieve_5: actual={pf(actual)}") + self.assertEqual(actual, exp.auth_retrieve_5, + msg="Actual to Expected") + self.client.logout() + + def test_auth_retrieve_6(self): + """Test retrieve method with anonymous user; private data + set specified""" + inc = ['data_release', 'flux'] + drs = ['SDSS-DR17-test', 'BOSS-DR16'] + uuids = self.uuid_priv + self.uuid_bossdr16 + # Replace exception name below once real one is created + with self.assertRaises(ex.UnknownServerError): + self.client.retrieve(uuid_list=uuids, + include=inc, + dataset_list=drs) + + def test_auth_retrieve_7(self): + """Test retrieve method with anonymous user; no data + sets specified""" + inc = ['data_release', 'model'] + # Replace exception name below once real one is created + with self.assertRaises(ex.UnknownServerError): + self.client.retrieve(uuid_list=self.uuid_all, + include=inc) + + def test_auth_retrieve_8(self): + """Test retrieve method with anonymous user; public data + sets specified""" + inc = ['data_release', 'model'] + drs = ['SDSS-DR16', 'BOSS-DR16'] + uuids = self.uuid_sdssdr16 + self.uuid_bossdr16 + got = self.client.retrieve(uuid_list=uuids, + include=inc, + dataset_list=drs) + actual = '' + for rec in got.records: + actual1 = (rec.data_release + ', ' + + str(len(rec.model)) + ' ; ') + actual = actual + actual1 + if showact: + print(f"auth_retrieve_8: actual={pf(actual)}") + self.assertEqual(actual, exp.auth_retrieve_8, + msg="Actual to Expected") From f991af28e36f9b11b64a1cf0355ce8930e059c40 Mon Sep 17 00:00:00 2001 From: Alice Jacques Date: Wed, 13 Mar 2024 13:12:27 -0700 Subject: [PATCH 4/8] Fix all other tests to be compliant with auth features --- tests/expected_pat.py | 41 ++++++++++++++++++++++++++++++++++------- tests/tests_api.py | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/tests/expected_pat.py b/tests/expected_pat.py index 0cac3a3..710c0de 100644 --- a/tests/expected_pat.py +++ b/tests/expected_pat.py @@ -110,6 +110,20 @@ # }, #] +# OLD as of March 13, 2024 +#find_3 = [{'_dr': 'DESI-EDR', +# 'dec': 5.662937176455572, +# 'ra': 208.7076645721256, +# 'sparcl_id': '00063e73-992e-11ee-ad57-525400aad0aa'}, +# {'_dr': 'DESI-EDR', +# 'dec': 5.492057016906403, +# 'ra': 209.52823969727436, +# 'sparcl_id': '000d4892-9931-11ee-9e4d-525400aad0aa'}, +# {'_dr': 'SDSS-DR17', +# 'dec': 34.863511, +# 'ra': 194.86904, +# 'sparcl_id': '000e388f-992d-11ee-a373-525400aad0aa'}] + find_3 = [{'_dr': 'DESI-EDR', 'dec': 5.662937176455572, 'ra': 208.7076645721256, @@ -118,10 +132,10 @@ 'dec': 5.492057016906403, 'ra': 209.52823969727436, 'sparcl_id': '000d4892-9931-11ee-9e4d-525400aad0aa'}, - {'_dr': 'SDSS-DR17', - 'dec': 34.863511, - 'ra': 194.86904, - 'sparcl_id': '000e388f-992d-11ee-a373-525400aad0aa'}] + {'_dr': 'BOSS-DR16', + 'dec': 27.461703, + 'ra': 141.95067, + 'sparcl_id': '001b11a6-992f-11ee-993c-525400aad0aa'}] # OLD as of Dec 14, 2023 #find_4 = [ @@ -130,9 +144,14 @@ # "0018f253-75d7-11ee-8253-525400aad0aa", #] +# OLD as of March 13, 2024 +#find_4 = ['00063e73-992e-11ee-ad57-525400aad0aa', +# '000d4892-9931-11ee-9e4d-525400aad0aa', +# '000e388f-992d-11ee-a373-525400aad0aa'] + find_4 = ['00063e73-992e-11ee-ad57-525400aad0aa', '000d4892-9931-11ee-9e4d-525400aad0aa', - '000e388f-992d-11ee-a373-525400aad0aa'] + '001b11a6-992f-11ee-993c-525400aad0aa'] find_5a = [ {"_dr": "BOSS-DR16", "data_release": "BOSS-DR16", "mjd": 55689}, @@ -148,14 +167,22 @@ # "fbb22144-25c5-4330-9b0b-8b2eac83079c", #] +# OLD as of March 13, 2024 +#reorder_1a = ['00063e73-992e-11ee-ad57-525400aad0aa', +# '000d4892-9931-11ee-9e4d-525400aad0aa', +# '000e388f-992d-11ee-a373-525400aad0aa'] + reorder_1a = ['00063e73-992e-11ee-ad57-525400aad0aa', '000d4892-9931-11ee-9e4d-525400aad0aa', - '000e388f-992d-11ee-a373-525400aad0aa'] + '001b11a6-992f-11ee-993c-525400aad0aa'] # OLD as of Dec 14, 2023 #reorder_1b = [1254334738051655680, 1254335012929562624, 1254335287807469568] -reorder_1b = [39627926995470031, 39627920993422590, 2258670445286942720] +# OLD as of March 13, 2024 +#reorder_1b = [39627926995470031, 39627920993422590, 2258670445286942720] + +reorder_1b = [39627926995470031, 39627920993422590, -5672180510041550848] # OLD as of Dec 14, 2023 #reorder_2a = [1254334738051655680, 1254335012929562624, None] diff --git a/tests/tests_api.py b/tests/tests_api.py index 237bb77..1c545ce 100755 --- a/tests/tests_api.py +++ b/tests/tests_api.py @@ -269,8 +269,10 @@ def test_missing_specids_1(self): def test_retrieve_0(self): """Get spectra using small list of SPECIDS.""" + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] res = self.client.retrieve_by_specid( - self.specid_list0, include=["sparcl_id", "specid"] + self.specid_list0, include=["sparcl_id", "specid"], + dataset_list=drs ) actual = sorted([r["specid"] for r in res.records]) if showact: @@ -282,9 +284,10 @@ def test_retrieve_0b(self): """Get spectra using small list of uuids.""" name = "retrieve_0b" uuids = self.uuid_list0 + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] tic() - res = self.client.retrieve(uuids) + res = self.client.retrieve(uuids, dataset_list=drs) self.timing[name] = toc() actual = sorted(res.records[0].keys()) @@ -319,13 +322,16 @@ def test_retrieve_1(self): def test_retrieve_3(self): """Issue warning when some sids do not exist.""" uuids = self.uuid_list0 + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] with self.assertWarns(Warning): - self.client.retrieve(uuids + [999]) + self.client.retrieve(uuids + [999], dataset_list=drs) def test_retrieve_5(self): """Limit number of records returned by retrieve_by_specid.""" + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] res = self.client.retrieve_by_specid( - self.specid_list5, include=["specid"], limit=2 + self.specid_list5, include=["specid"], dataset_list=drs, + limit=2 ) actual = sorted([r["specid"] for r in res.records]) if showact: @@ -447,7 +453,8 @@ def test_reorder_1a(self): print(f"ids: {ids}") tic() - res = self.client.retrieve(ids) + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] + res = self.client.retrieve(ids, dataset_list=drs) res_ids = [r["sparcl_id"] for r in res.records] print(f"retrieved: {res_ids}") self.timing[name] = toc() @@ -463,7 +470,8 @@ def test_reorder_1b(self): specids = self.specid_list2 tic() - res = self.client.retrieve_by_specid(specids) + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] + res = self.client.retrieve_by_specid(specids, dataset_list=drs) self.timing[name] = toc() res_reorder = res.reorder(specids) actual = [f["specid"] for f in res_reorder.records] @@ -478,8 +486,9 @@ def test_reorder_2a(self): ids = self.uuid_list3 tic() + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] with self.assertWarns(Warning): - res = self.client.retrieve(ids) + res = self.client.retrieve(ids, dataset_list=drs) self.timing[name] = toc() with self.assertWarns(Warning): res_reorder = res.reorder(ids) @@ -495,7 +504,8 @@ def test_reorder_2b(self): specids = self.specid_list3 tic() - res = self.client.retrieve_by_specid(specids) + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] + res = self.client.retrieve_by_specid(specids, dataset_list=drs) self.timing[name] = toc() with self.assertWarns(Warning): res_reorder = res.reorder(specids) @@ -512,7 +522,8 @@ def test_reorder_3a(self): og_ids = [] tic() - res = self.client.retrieve(ids) + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] + res = self.client.retrieve(ids, dataset_list=drs) self.timing[name] = toc() with self.assertRaises(ex.NoIDs): res.reorder(og_ids) @@ -525,7 +536,8 @@ def test_reorder_3b(self): og_specids = [] tic() - res = self.client.retrieve_by_specid(specids) + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] + res = self.client.retrieve_by_specid(specids, dataset_list=drs) self.timing[name] = toc() with self.assertRaises(ex.NoIDs): res.reorder(og_specids) @@ -537,8 +549,9 @@ def test_reorder_4a(self): ids = self.uuid_list4 tic() + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] with self.assertWarns(Warning): - res = self.client.retrieve(ids) + res = self.client.retrieve(ids, dataset_list=drs) self.timing[name] = toc() with self.assertRaises(ex.NoRecords): res.reorder(ids) @@ -550,7 +563,8 @@ def test_reorder_4b(self): specids = self.specid_list4 tic() - res = self.client.retrieve_by_specid(specids) + drs = ['SDSS-DR16', 'BOSS-DR16', 'DESI-EDR'] + res = self.client.retrieve_by_specid(specids, dataset_list=drs) self.timing[name] = toc() with self.assertRaises(ex.NoRecords): res.reorder(specids) @@ -560,7 +574,8 @@ def test_dls_468(self): constraints={"data_release": ["SDSS-DR16"]}, limit=1 ).ids re = self.client.retrieve( - uuid_list=idss, include=["ra", "dec"], verbose=True + uuid_list=idss, include=["ra", "dec"], dataset_list=['SDSS-DR16'], + verbose=True ) self.assertEqual(1, re.count) From 0922721875791963e86fcbfbefcdd8dd02dae43f Mon Sep 17 00:00:00 2001 From: Alice Jacques Date: Wed, 13 Mar 2024 14:28:25 -0700 Subject: [PATCH 5/8] Pass usrpw as an environment variable --- tests/tests_api.py | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/tests/tests_api.py b/tests/tests_api.py index 1c545ce..b88e4ef 100755 --- a/tests/tests_api.py +++ b/tests/tests_api.py @@ -1,38 +1,41 @@ # Unit tests for the NOIRLab SPARCL API Client # EXAMPLES: (do after activating venv, in sandbox/sparclclient/) -# python -m unittest tests.tests_api +# usrpw (User Password) is intentionally left blank in these examples. +# When actually running tests, the User Password should be included. +# +# usrpw='' python -m unittest tests.tests_api # # ### Run Against DEV Server. -# serverurl=http://localhost:8050 python -m unittest tests.tests_api -# showact=1 serverurl=http://localhost:8050 python -m unittest tests.tests_api +# usrpw='' serverurl=http://localhost:8050 python -m unittest tests.tests_api +# showact=1 usrpw='' serverurl=http://localhost:8050 python -m unittest tests.tests_api # noqa: E501 # # python -m unittest -v tests.tests_api # VERBOSE # python -m unittest tests.tests_api.SparclClientTest # python -m unittest tests.tests_api.SparclClientTest.test_find_3 # python3 -m unittest tests.tests_api.AlignRecordsTest +# usrpw='' python3 -m unittest tests.tests_api.AuthTest # # showact=1 python -m unittest -k test_find_5 tests.tests_api # # ### Run Against DEV Server. -# serverurl=http://localhost:8050 python -m unittest tests.tests_api +# usrpw='' serverurl=http://localhost:8050 python -m unittest tests.tests_api # # ### Run tests Against PAT Server. # export serverurl=https://sparc1.datalab.noirlab.edu/ -# python -m unittest tests.tests_api +# usrpw='' python -m unittest tests.tests_api # # ### Run Against STAGE Server. # serverurl=https://sparclstage.datalab.noirlab.edu/ -# python -m unittest tests.tests_api +# usrpw='' python -m unittest tests.tests_api # # ### Run Against PROD Server. -# serverurl=https://astrosparcl.datalab.noirlab.edu/ python -m unittest tests.tests_api # noqa: E501 +# usrpw='' serverurl=https://astrosparcl.datalab.noirlab.edu/ python -m unittest tests.tests_api # noqa: E501 # Python library from contextlib import contextmanager import unittest from unittest import skip import datetime -from getpass import getpass #! from unittest mock, skipIf, skipUnless #!import warnings @@ -87,6 +90,7 @@ clverb = False +usrpw = os.environ.get("usrpw") @contextmanager def streamhandler_to_console(lggr): @@ -701,7 +705,6 @@ def setUpClass(cls): # Test users cls.auth_user = 'test_user_1@noirlab.edu' cls.unauth_user = 'test_user_2@noirlab.edu' - cls.usrpw = getpass() # Sample list of sparcl_ids from each data set cls.uuid_priv = [ @@ -735,7 +738,7 @@ def tearDownClass(cls): def test_authorized_1(self): """Test authorized method with authorized user signed in""" - self.client.login(self.auth_user, self.usrpw) + self.client.login(self.auth_user, usrpw) actual = self.client.authorized if showact: print(f"authorized_1: actual={actual}") @@ -745,7 +748,7 @@ def test_authorized_1(self): def test_authorized_2(self): """Test authorized method with unauthorized user signed in""" - self.client.login(self.unauth_user, self.usrpw) + self.client.login(self.unauth_user, usrpw) actual = self.client.authorized if showact: print(f"authorized_2: actual={actual}") @@ -764,7 +767,7 @@ def test_authorized_3(self): def test_auth_find_1(self): """Test find method with authorized user; private data set specified""" - self.client.login(self.auth_user, self.usrpw) + self.client.login(self.auth_user, usrpw) out = ['sparcl_id', 'data_release'] cons = {'spectype': ['GALAXY'], 'redshift': [0.5, 0.9], @@ -780,7 +783,7 @@ def test_auth_find_1(self): def test_auth_find_2(self): """Test find method with authorized user; no data sets specified""" - self.client.login(self.auth_user, self.usrpw) + self.client.login(self.auth_user, usrpw) out = ['sparcl_id', 'data_release'] cons = {'spectype': ['GALAXY'], 'redshift': [0.5, 0.9]} @@ -796,7 +799,7 @@ def test_auth_find_2(self): def test_auth_find_3(self): """Test find method with unauthorized user; private data set specified""" - self.client.login(self.unauth_user, self.usrpw) + self.client.login(self.unauth_user, usrpw) out = ['sparcl_id', 'data_release'] cons = {'spectype': ['GALAXY'], 'redshift': [0.5, 0.9], @@ -809,7 +812,7 @@ def test_auth_find_3(self): def test_auth_find_4(self): """Test find method with unauthorized user; no data sets specified""" - self.client.login(self.unauth_user, self.usrpw) + self.client.login(self.unauth_user, usrpw) out = ['sparcl_id', 'data_release'] cons = {'spectype': ['GALAXY'], 'redshift': [0.5, 0.9]} @@ -850,7 +853,7 @@ def test_auth_find_6(self): def test_auth_retrieve_1(self): """Test retrieve method with authorized user; private data set specified""" - self.client.login(self.auth_user, self.usrpw) + self.client.login(self.auth_user, usrpw) inc = ['data_release', 'flux'] drs = ['SDSS-DR16', 'SDSS-DR17-test'] uuids = self.uuid_priv + self.uuid_sdssdr16 @@ -870,7 +873,7 @@ def test_auth_retrieve_1(self): def test_auth_retrieve_2(self): """Test retrieve method with authorized user; no data sets specified""" - self.client.login(self.auth_user, self.usrpw) + self.client.login(self.auth_user, usrpw) inc = ['data_release', 'wavelength'] got = self.client.retrieve(uuid_list=self.uuid_all, include=inc) @@ -888,7 +891,7 @@ def test_auth_retrieve_2(self): def test_auth_retrieve_3(self): """Test retrieve method with unauthorized user; private data set specified""" - self.client.login(self.unauth_user, self.usrpw) + self.client.login(self.unauth_user, usrpw) inc = ['data_release', 'ivar'] drs = ['DESI-EDR', 'SDSS-DR17-test'] uuids = self.uuid_desiedr + self.uuid_priv @@ -902,7 +905,7 @@ def test_auth_retrieve_3(self): def test_auth_retrieve_4(self): """Test retrieve method with unauthorized user; no data sets specified""" - self.client.login(self.unauth_user, self.usrpw) + self.client.login(self.unauth_user, usrpw) inc = ['data_release', 'wave_sigma'] # Replace exception name below once real one is created with self.assertRaises(ex.UnknownServerError): @@ -913,7 +916,7 @@ def test_auth_retrieve_4(self): def test_auth_retrieve_5(self): """Test retrieve method with unauthorized user; public data sets specified""" - self.client.login(self.unauth_user, self.usrpw) + self.client.login(self.unauth_user, usrpw) inc = ['data_release', 'wave_sigma'] drs = ['SDSS-DR16', 'DESI-EDR'] uuids = self.uuid_sdssdr16 + self.uuid_desiedr From ac861ff41496ff055c00b99d6db4e4867666b8f5 Mon Sep 17 00:00:00 2001 From: Alice Jacques Date: Wed, 13 Mar 2024 14:51:07 -0700 Subject: [PATCH 6/8] Add skipUnless for Auth tests --- tests/tests_api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/tests_api.py b/tests/tests_api.py index b88e4ef..ae2a471 100755 --- a/tests/tests_api.py +++ b/tests/tests_api.py @@ -34,7 +34,7 @@ # Python library from contextlib import contextmanager import unittest -from unittest import skip +from unittest import skip, skipUnless import datetime #! from unittest mock, skipIf, skipUnless @@ -687,6 +687,7 @@ def test_align_7(self): ar_dict, grid = sg.align_records(got.records, precision=11) # shape = ar_dict['flux'].shape +@skipUnless('usrpw' in os.environ, 'Password is required to test auth') class AuthTest(unittest.TestCase): """Test authorization and authentication features""" From b42c441e95bdffb6a038cd40cb25b93441d8e225 Mon Sep 17 00:00:00 2001 From: Alice Jacques Date: Wed, 13 Mar 2024 15:54:27 -0700 Subject: [PATCH 7/8] Replace hardcoded UUIDs --- tests/expected_pat.py | 14 +++++++------- tests/tests_api.py | 43 ++++++++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/tests/expected_pat.py b/tests/expected_pat.py index 710c0de..04b4549 100644 --- a/tests/expected_pat.py +++ b/tests/expected_pat.py @@ -237,16 +237,16 @@ '022ab30b-9931-11ee-a372-525400aad0aa', '024c9ba1-9930-11ee-aa56-525400aad0aa'] -auth_retrieve_1 = ('SDSS-DR16, 3878 ; SDSS-DR16, 3878 ; ' +auth_retrieve_1 = ('SDSS-DR16, 3848 ; SDSS-DR16, 3848 ; ' 'SDSS-DR17-test, 3859 ; SDSS-DR17-test, 3859 ; ') -auth_retrieve_2 = ('BOSS-DR16, 4615 ; BOSS-DR16, 4615 ; ' - 'SDSS-DR16, 3878 ; SDSS-DR16, 3878 ; ' - 'DESI-EDR, 7781 ; DESI-EDR, 7781 ; ' +auth_retrieve_2 = ('DESI-EDR, 7781 ; BOSS-DR16, 4615 ; ' + 'BOSS-DR16, 4615 ; SDSS-DR16, 3848 ; ' + 'SDSS-DR16, 3848 ; DESI-EDR, 7781 ; ' 'SDSS-DR17-test, 3859 ; SDSS-DR17-test, 3859 ; ') -auth_retrieve_5 = ('SDSS-DR16, 3878 ; SDSS-DR16, 3878 ; ' - 'DESI-EDR, 7781 ; DESI-EDR, 7781 ; ') +auth_retrieve_5 = ('DESI-EDR, 7781 ; SDSS-DR16, 3848 ; ' + 'SDSS-DR16, 3848 ; DESI-EDR, 7781 ; ') auth_retrieve_8 = ('BOSS-DR16, 4615 ; BOSS-DR16, 4615 ; ' - 'SDSS-DR16, 3878 ; SDSS-DR16, 3878 ; ') + 'SDSS-DR16, 3848 ; SDSS-DR16, 3848 ; ') diff --git a/tests/tests_api.py b/tests/tests_api.py index ae2a471..04605ef 100755 --- a/tests/tests_api.py +++ b/tests/tests_api.py @@ -708,21 +708,34 @@ def setUpClass(cls): cls.unauth_user = 'test_user_2@noirlab.edu' # Sample list of sparcl_ids from each data set - cls.uuid_priv = [ - '84452fad-dbe7-11ee-a970-525400aad0aa', - '847e0be4-dbe7-11ee-b095-525400aad0aa'] - - cls.uuid_bossdr16 = [ - '00b0904d-992f-11ee-b7f9-525400aad0aa', - '010eb4d0-992f-11ee-89de-525400aad0aa'] - - cls.uuid_sdssdr16 = [ - '0fad3e28-992f-11ee-a9e7-525400aad0aa', - '12ec49f6-992f-11ee-8003-525400aad0aa'] - - cls.uuid_desiedr = [ - '00769ec9-9931-11ee-97de-525400aad0aa', - '00c6d798-9931-11ee-af11-525400aad0aa'] + out = ['sparcl_id'] + cons1 = {'data_release': ['DESI-EDR']} + cons2 = {'data_release': ['BOSS-DR16']} + cons3 = {'data_release': ['SDSS-DR16']} + cons4 = {'data_release': ['SDSS-DR17-test']} + cls.client.login(cls.auth_user, usrpw) + cls.uuid_desiedr = (cls.client.find(outfields=out, + constraints=cons1, + limit=2, + sort='sparcl_id') + ).ids + cls.uuid_bossdr16 = (cls.client.find(outfields=out, + constraints=cons2, + limit=2, + sort='sparcl_id') + ).ids + cls.uuid_sdssdr16 = (cls.client.find(outfields=out, + constraints=cons3, + limit=2, + sort='sparcl_id') + ).ids + cls.uuid_priv = (cls.client.find(outfields=out, + constraints=cons4, + limit=2, + sort='sparcl_id') + ).ids + + cls.client.logout() cls.uuid_all = (cls.uuid_priv + cls.uuid_bossdr16 + cls.uuid_sdssdr16 + cls.uuid_desiedr) From 96583feb612a864176493fcbc29429a88569d922 Mon Sep 17 00:00:00 2001 From: Alice Jacques Date: Wed, 13 Mar 2024 16:10:36 -0700 Subject: [PATCH 8/8] Silence output from login/logout --- tests/tests_api.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/tests_api.py b/tests/tests_api.py index 04605ef..83f2399 100755 --- a/tests/tests_api.py +++ b/tests/tests_api.py @@ -46,6 +46,7 @@ #!from unittest.mock import MagicMock, create_autospec import os +import io # External Packages import numpy @@ -713,6 +714,8 @@ def setUpClass(cls): cons2 = {'data_release': ['BOSS-DR16']} cons3 = {'data_release': ['SDSS-DR16']} cons4 = {'data_release': ['SDSS-DR17-test']} + # Silence output from login/logout + sys.stdout = io.StringIO() cls.client.login(cls.auth_user, usrpw) cls.uuid_desiedr = (cls.client.find(outfields=out, constraints=cons1,