From 602e69f5293a30fd71bd6abe93df08ff662d0401 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Thu, 1 Jun 2023 09:12:43 -0700 Subject: [PATCH 01/13] Fix sensor data test --- tests/test_sofar_api_class.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/test_sofar_api_class.py b/tests/test_sofar_api_class.py index 8d41070..c6a2255 100644 --- a/tests/test_sofar_api_class.py +++ b/tests/test_sofar_api_class.py @@ -1,12 +1,13 @@ """ -This file is part of pysofar: A client for interfacing with Sofar Oceans Spotter API +This file is part of pysofar: +A client for interfacing with Sofar Ocean Technologies Spotter API Contents: Tests for device endpoints -Copyright (C) 2019 +Copyright (C) 2019-2023 Sofar Ocean Technologies -Authors: Mike Sosa +Authors: Mike Sosa et al """ from pysofar import wavefleet_exceptions from pysofar.sofar import SofarApi @@ -112,12 +113,13 @@ def test_get_all_data(): def test_get_sensor_data(): # Test that getting sensor data in a time range works - spotter_id = 'SPOT-9999' - st = '2021-07-18' - end = '2021-07-19' + spotter_id = 'SPOT-30081D' + st = '2022-08-01' + end = '2022-08-02' dat = api.get_sensor_data(spotter_id, start_date=st, end_date=end) assert dat is not None + print(dat) assert 'sensorPosition' in dat[-1] From 8364773f18fb81e66df2fd5af7293a4bcb25a847 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Thu, 1 Jun 2023 10:43:51 -0700 Subject: [PATCH 02/13] Allow for limited number of processes during testing --- src/pysofar/sofar.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pysofar/sofar.py b/src/pysofar/sofar.py index 2673022..35ef2e7 100644 --- a/src/pysofar/sofar.py +++ b/src/pysofar/sofar.py @@ -574,19 +574,20 @@ def __str__(self): # ---------------------------------- Util Functions -------------------------------------- # -def get_and_update_spotters(_api=None): +def get_and_update_spotters(_api=None, _processes=None): """ :return: A list of the Spotter objects associated with this account """ from itertools import repeat api = _api or SofarApi() + processes = _processes or 16 # grab device id's and query for device data # initialize Spotter objects spot_data = api.devices - pool = ThreadPool(processes=16) + pool = ThreadPool(processes=processes) spotters = pool.starmap(_spot_worker, zip(spot_data, repeat(api))) pool.close() From 140b98413ee849203c697bcfb537e7df1ced12e5 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Thu, 1 Jun 2023 10:45:03 -0700 Subject: [PATCH 03/13] Change selected Spotter to be API trial Spotter --- tests/test_wave_query_class.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_wave_query_class.py b/tests/test_wave_query_class.py index 930f8a5..ef3989b 100644 --- a/tests/test_wave_query_class.py +++ b/tests/test_wave_query_class.py @@ -10,9 +10,9 @@ """ from pysofar.sofar import WaveDataQuery -st = '2019-05-02' -end = '2019-05-10' -q = WaveDataQuery('SPOT-0350', limit=100, start_date=st, end_date=end) +st = '2023-05-02' +end = '2023-05-10' +q = WaveDataQuery('SPOT-30344R', limit=100, start_date=st, end_date=end) q.wind(True) @@ -28,7 +28,7 @@ def test_query_execute(): def test_query_no_dates(): - # resturned latest data first + # returned latest data first q.limit(10) q.clear_start_date() q.clear_end_date() @@ -42,7 +42,7 @@ def test_query_no_dates(): def test_query_no_start(): - # resturned + # returned q.limit(10) q.clear_start_date() From d0119ad57dfda8614a9f02ad51851a3220c267c6 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Thu, 1 Jun 2023 10:46:00 -0700 Subject: [PATCH 04/13] Uncomment SST test --- tests/test_wave_query_class.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/tests/test_wave_query_class.py b/tests/test_wave_query_class.py index ef3989b..0fb28e6 100644 --- a/tests/test_wave_query_class.py +++ b/tests/test_wave_query_class.py @@ -3,10 +3,10 @@ Contents: Tests for device endpoints -Copyright (C) 2019 +Copyright (C) 2019-2023 Sofar Ocean Technologies -Authors: Mike Sosa +Authors: Mike Sosa et al """ from pysofar.sofar import WaveDataQuery @@ -70,18 +70,17 @@ def test_query_no_end(): assert 'waves' in response assert 'wind' in response -# TODO: need to get a viable spotter for testing -# def test_query_surface_temp(): -# q.surface_temp(True) -# q.limit = 10 -# -# q.clear_end_date() -# response = q.execute() -# q.set_start_date(st) -# -# assert response is not None -# assert isinstance(response, dict) -# -# assert 'waves' in response -# assert 'wind' in response -# assert 'surfaceTemp' in response +def test_query_surface_temp(): + q.surface_temp(True) + q.limit = 10 + + q.clear_end_date() + response = q.execute() + q.set_start_date(st) + + assert response is not None + assert isinstance(response, dict) + + assert 'waves' in response + assert 'wind' in response + assert 'surfaceTemp' in response From 1088138deffee3ec8e95083d8f6e0bdfc7d5561f Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Thu, 1 Jun 2023 10:47:41 -0700 Subject: [PATCH 05/13] Change Spotter to be the API trial Spotter --- tests/test_sofar_api_class.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_sofar_api_class.py b/tests/test_sofar_api_class.py index c6a2255..83e06a0 100644 --- a/tests/test_sofar_api_class.py +++ b/tests/test_sofar_api_class.py @@ -24,7 +24,7 @@ def test_custom_api(): api = SofarApi() -latest_dat = api.get_latest_data('SPOT-0350', include_wind_data=True) +latest_dat = api.get_latest_data('SPOT-30344R', include_wind_data=True) def test_get_latest_data(): @@ -42,7 +42,7 @@ def test_get_and_update_spotters(): from pysofar.spotter import Spotter from pysofar.sofar import get_and_update_spotters - sptrs = get_and_update_spotters(_api=api) + sptrs = get_and_update_spotters(_api=api, _processes=2) assert sptrs is not None assert all(map(lambda x: isinstance(x, Spotter), sptrs)) From b94091722edc5acc89a7b0f841f76f6bad714e84 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Thu, 1 Jun 2023 11:04:54 -0700 Subject: [PATCH 06/13] Reuse API instance in worker --- src/pysofar/sofar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pysofar/sofar.py b/src/pysofar/sofar.py index 35ef2e7..024128a 100644 --- a/src/pysofar/sofar.py +++ b/src/pysofar/sofar.py @@ -595,7 +595,7 @@ def get_and_update_spotters(_api=None, _processes=None): # ---------------------------------- Workers -------------------------------------- # -def _spot_worker(device: dict, api: SofarApi): +def _spot_worker(device: dict, api: None): """ Worker to grab Spotter data @@ -607,7 +607,7 @@ def _spot_worker(device: dict, api: SofarApi): _id = device['spotterId'] _name = device['name'] - _api = api + _api = api or SofarApi() sptr = Spotter(_id, _name, _api) sptr.update() From 72d7e730548f460d6d954fb50ffdc9ca7624f910 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Thu, 1 Jun 2023 11:20:30 -0700 Subject: [PATCH 07/13] Mark grab data with limit as expected failure --- tests/test_spotter_class.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/test_spotter_class.py b/tests/test_spotter_class.py index 4754c91..3b8ad04 100644 --- a/tests/test_spotter_class.py +++ b/tests/test_spotter_class.py @@ -1,23 +1,25 @@ """ -This file is part of pysofar: A client for interfacing with Sofar Oceans Spotter API +This file is part of pysofar: +A client for interfacing with Sofar Ocean Technologies Spotter API Contents: Tests for device endpoints -Copyright (C) 2019 +Copyright (C) 2019-2023 Sofar Ocean Technologies -Authors: Mike Sosa +Authors: Mike Sosa et al """ from pysofar.sofar import SofarApi from pysofar.spotter import Spotter -api = SofarApi() +import pytest -device = Spotter('SPOT-0350', '') +api = SofarApi() +device = Spotter('SPOT-30344R', '') def test_spotter_update(): - # tests the spotter updates correctly + # tests the Spotter updates correctly device.update() assert device.mode is not None @@ -67,18 +69,18 @@ def test_spotter_edit(): def test_spotter_mode(): - # test the spotter mode property is set correctly + # test the Spotter mode property is set correctly device.mode = 'track' assert device.mode == 'tracking' device.mode = 'full' assert device.mode == 'waves_spectrum' - -def test_spotter_grab_data(): - # test spotter can correctly grab data +@pytest.mark.xfail() +def test_spotter_grab_data_with_limit(): + # test Spotter can correctly grab data with limit + # will fail if device is not owned by the token making the request dat = device.grab_data(limit=20) - print(dat) assert 'waves' in dat assert len(dat['waves']) <= 20 From e1d8ceb58639d8a6f067a63353ea082464ba1a28 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Thu, 1 Jun 2023 11:21:38 -0700 Subject: [PATCH 08/13] Fix wrong import order --- tests/test_spotter_class.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_spotter_class.py b/tests/test_spotter_class.py index 3b8ad04..8624c46 100644 --- a/tests/test_spotter_class.py +++ b/tests/test_spotter_class.py @@ -9,11 +9,11 @@ Authors: Mike Sosa et al """ +import pytest + from pysofar.sofar import SofarApi from pysofar.spotter import Spotter -import pytest - api = SofarApi() device = Spotter('SPOT-30344R', '') From 1e4d4aaa6efddd9223dc886bca5ee4454ebf4a39 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Mon, 5 Jun 2023 10:42:51 -0700 Subject: [PATCH 09/13] Update dates for track data test (ineffectual) --- tests/test_sofar_api_class.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_sofar_api_class.py b/tests/test_sofar_api_class.py index 83e06a0..3a20310 100644 --- a/tests/test_sofar_api_class.py +++ b/tests/test_sofar_api_class.py @@ -74,8 +74,8 @@ def test_get_all_wind_data(): def test_get_all_tracking_data(): # Test that all tracking data is able to be queried in a time range - st = '2021-05-02' - end = '2021-06-10' + st = '2023-05-02' + end = '2023-05-10' dat = api.get_track_data(start_date=st, end_date=end) assert dat is not None From 39e7e7875ecadeafd35df04c527e54219d86b727 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Mon, 5 Jun 2023 10:43:41 -0700 Subject: [PATCH 10/13] Revert "Reuse API instance in worker" This reverts commit b94091722edc5acc89a7b0f841f76f6bad714e84. --- src/pysofar/sofar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pysofar/sofar.py b/src/pysofar/sofar.py index 024128a..35ef2e7 100644 --- a/src/pysofar/sofar.py +++ b/src/pysofar/sofar.py @@ -595,7 +595,7 @@ def get_and_update_spotters(_api=None, _processes=None): # ---------------------------------- Workers -------------------------------------- # -def _spot_worker(device: dict, api: None): +def _spot_worker(device: dict, api: SofarApi): """ Worker to grab Spotter data @@ -607,7 +607,7 @@ def _spot_worker(device: dict, api: None): _id = device['spotterId'] _name = device['name'] - _api = api or SofarApi() + _api = api sptr = Spotter(_id, _name, _api) sptr.update() From af7abe056fa3277474b049e1337c03d97eda0906 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Mon, 5 Jun 2023 10:50:03 -0700 Subject: [PATCH 11/13] Update dates in API test --- tests/test_sofar_api_class.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_sofar_api_class.py b/tests/test_sofar_api_class.py index 3a20310..00d9092 100644 --- a/tests/test_sofar_api_class.py +++ b/tests/test_sofar_api_class.py @@ -50,8 +50,8 @@ def test_get_and_update_spotters(): def test_get_all_wave_data(): # Test that all wave data is able to be queried in a time range - st = '2019-05-02' - end = '2019-07-10' + st = '2023-05-02' + end = '2023-05-10' dat = api.get_wave_data(start_date=st, end_date=end) assert dat is not None @@ -62,8 +62,8 @@ def test_get_all_wave_data(): def test_get_all_wind_data(): # Test that all wind data over all time is able to be queried - st = '2021-05-02' - end = '2021-07-10' + st = '2023-05-02' + end = '2023-05-10' dat = api.get_wind_data(start_date=st, end_date=end) assert dat is not None From 3e86fd7cb6894c07da9b5406cbb02913cdb9db14 Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Mon, 5 Jun 2023 10:57:47 -0700 Subject: [PATCH 12/13] Add possibility to really use custom token (if custom tokens work) --- tests/test_sofar_api_class.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/test_sofar_api_class.py b/tests/test_sofar_api_class.py index 00d9092..f9164b2 100644 --- a/tests/test_sofar_api_class.py +++ b/tests/test_sofar_api_class.py @@ -9,24 +9,28 @@ Authors: Mike Sosa et al """ +import os + from pysofar import wavefleet_exceptions from pysofar.sofar import SofarApi from unittest.mock import patch +# try to read custom token from environment. +# if absent, default to hard-coded value in this source module +custom_token = os.getenv('PYSOFAR_CUSTOM_TOKEN', 'custom_api_token_here') # The custom token will fail to authenticate so use a mock to bypass the `_sync step` with patch.object(SofarApi, '_sync', return_value=None) as mock_method: - custom_api = SofarApi(custom_token='custom_api_token_here') + custom_token = os.getenv('PYSOFAR_CUSTOM_TOKEN', 'custom_api_token_here') + custom_api = SofarApi(custom_token=custom_token) def test_custom_api(): # test that custom api token is set - assert custom_api.token == 'custom_api_token_here' - + assert custom_api.token == custom_token api = SofarApi() latest_dat = api.get_latest_data('SPOT-30344R', include_wind_data=True) - def test_get_latest_data(): # test basic that latest_data is able to be queried assert latest_dat is not None From b9b352c62be4cf25ad5babb3daa679da6b693b5e Mon Sep 17 00:00:00 2001 From: Tim Johnson <2293335+tcj@users.noreply.github.com> Date: Mon, 5 Jun 2023 11:45:05 -0700 Subject: [PATCH 13/13] Allow overriding the Spot ID being used for tests. --- tests/test_sofar_api_class.py | 15 ++++++++------- tests/test_spotter_class.py | 6 +++--- tests/test_wave_query_class.py | 4 +++- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/test_sofar_api_class.py b/tests/test_sofar_api_class.py index f9164b2..5ec5d60 100644 --- a/tests/test_sofar_api_class.py +++ b/tests/test_sofar_api_class.py @@ -10,6 +10,7 @@ Authors: Mike Sosa et al """ import os +import pytest from pysofar import wavefleet_exceptions from pysofar.sofar import SofarApi @@ -18,6 +19,7 @@ # try to read custom token from environment. # if absent, default to hard-coded value in this source module custom_token = os.getenv('PYSOFAR_CUSTOM_TOKEN', 'custom_api_token_here') +custom_spotter_id = os.getenv('PYSOFAR_TEST_SPOTTER_ID', 'SPOT-30344R') # The custom token will fail to authenticate so use a mock to bypass the `_sync step` with patch.object(SofarApi, '_sync', return_value=None) as mock_method: @@ -29,7 +31,7 @@ def test_custom_api(): assert custom_api.token == custom_token api = SofarApi() -latest_dat = api.get_latest_data('SPOT-30344R', include_wind_data=True) +latest_dat = api.get_latest_data(custom_spotter_id, include_wind_data=True) def test_get_latest_data(): # test basic that latest_data is able to be queried @@ -75,7 +77,6 @@ def test_get_all_wind_data(): assert 'wind' in dat assert len(dat['wind']) > 0 - def test_get_all_tracking_data(): # Test that all tracking data is able to be queried in a time range st = '2023-05-02' @@ -87,13 +88,13 @@ def test_get_all_tracking_data(): assert 'track' in dat assert len(dat['track']) > 0 - +@pytest.mark.xfail(reason="A Spotter will return no frequency data if it was not in Waves:Spectrum") def test_get_all_frequency_data(): # Test that all frequency data is able to be queried in a time range - st = '2021-06-08' - end = '2021-06-10' + st = '2022-07-26' + end = '2022-08-04' dat = api.get_frequency_data(start_date=st, end_date=end) - + print(dat.keys()) assert dat is not None assert isinstance(dat, dict) assert 'frequency' in dat @@ -101,7 +102,7 @@ def test_get_all_frequency_data(): def test_get_all_data(): - # Test that grabbing data from all spotters from all data types works + # Test that grabbing data from all Spotters from all data types works st = '2019-01-18' end = '2019-01-25' diff --git a/tests/test_spotter_class.py b/tests/test_spotter_class.py index 8624c46..92b1d6b 100644 --- a/tests/test_spotter_class.py +++ b/tests/test_spotter_class.py @@ -9,6 +9,7 @@ Authors: Mike Sosa et al """ +import os import pytest from pysofar.sofar import SofarApi @@ -16,7 +17,7 @@ api = SofarApi() -device = Spotter('SPOT-30344R', '') +device = Spotter(os.getenv('PYSOFAR_TEST_SPOTTER_ID', 'SPOT-30344R'), '', session = api) def test_spotter_update(): # tests the Spotter updates correctly @@ -76,10 +77,9 @@ def test_spotter_mode(): device.mode = 'full' assert device.mode == 'waves_spectrum' -@pytest.mark.xfail() +@pytest.mark.xfail(reason="will fail if device is not owned by the token making the request") def test_spotter_grab_data_with_limit(): # test Spotter can correctly grab data with limit - # will fail if device is not owned by the token making the request dat = device.grab_data(limit=20) assert 'waves' in dat diff --git a/tests/test_wave_query_class.py b/tests/test_wave_query_class.py index 0fb28e6..4bc9808 100644 --- a/tests/test_wave_query_class.py +++ b/tests/test_wave_query_class.py @@ -8,11 +8,13 @@ Authors: Mike Sosa et al """ +import os + from pysofar.sofar import WaveDataQuery st = '2023-05-02' end = '2023-05-10' -q = WaveDataQuery('SPOT-30344R', limit=100, start_date=st, end_date=end) +q = WaveDataQuery(os.getenv('PYSOFAR_TEST_SPOTTER_ID', 'SPOT-30344R'), limit=100, start_date=st, end_date=end) q.wind(True)