import pytest import os from datetime import datetime, timedelta from netCDF4 import Dataset import numpy as np import random import string from tests.TestUtils import TestUtils from SDToolBox.data_acquisition import InputData class Test_CreateDataAcquisition: @pytest.mark.unittest def test_when_create_empty_dataacquistion_no_exception_risen(self): try: InputData() except Exception as e_info: err_mssg = 'Error while creating DataAquisition object.' + \ '{}'.format(str(e_info)) pytest.fail(err_mssg) class Test_ValidateDataAcquisition: @pytest.mark.unittest def test_when_no_dataset_then_returns_false(self): data = InputData() validation_result = data.validate(None) assert validation_result is False class Test_ValidateInputDates: @pytest.mark.unittest def test_when_from_is_greater_than_to_returns_error(self): # 1. Given date_to = datetime.now() date_from = date_to + timedelta(days=1) # 2. When validation_result = InputData.validate_input_dates( date_from, date_to) # 3. Then assert not validation_result @pytest.mark.unittest def test_when_from_is_less_than_to_returns_true(self): # 1. Given date_from = datetime.now() date_to = date_from + timedelta(days=1) # 2. When validation_result = InputData.validate_input_dates( date_from, date_to) # 3. Then assert validation_result class Test_ValidateInputCoordinates: @pytest.mark.unittest @pytest.mark.parametrize( 'coord_list', [ pytest.param([], id='Empty list'), pytest.param(None, id='None list'), ] ) def test_when_no_coordinates_given_returns_false(self, coord_list): # 1. Given data_acq = InputData() dataset = None # 2. When validation_result = data_acq.validate_input_coordinates(dataset) # 3. Then assert not validation_result @pytest.mark.unittest def test_when_no_dataset_is_given_returns_false(self): # 1. Given data_acq = InputData() data_acq.coord_list = [(2.4, 4.2)] dataset = None # 2. When validation_result = data_acq.validate_input_coordinates(dataset) # 3. Then assert not validation_result @pytest.mark.unittest @pytest.mark.parametrize( 'lon_key, lat_key', [ pytest.param(None, None, id='No keys'), pytest.param(None, 'lat_key', id='Only lat key'), pytest.param('lon_key', None, id='Only lon key'), ] ) def test_when_dataset_without_keys_given_returns_false( self, lon_key: str, lat_key: str): # 1. Given data_acq = InputData() data_acq.lon_key = lon_key data_acq.lat_key = lat_key data_acq.coord_list = [(2.4, 4.2)] dataset_name = self.__get_random_dataset_name() test_dataset = self.__create_empty_test_dataset( dataset_name, lon_key, lat_key) # 2. When validation_result = data_acq.validate_input_coordinates(test_dataset) try: os.remove(dataset_name) except OSError: pass # 3. Then assert not validation_result @pytest.mark.unittest def test_given_one_coordinate_when_dataset_has_keys_returns_true(self): test_dataset_name = '' + \ 'test_' + \ 'validate_input_coordinates_' + \ 'given_one_coordinate.nc' # 1. Given data_acq = InputData() data_acq.lon_key = 'Longitude' data_acq.lat_key = 'Latitude' data_acq.coord_list = [(2.4, 4.2)] test_dataset = self.__create_test_dataset(test_dataset_name) # 2. When validation_result = data_acq.validate_input_coordinates(test_dataset) # 3. Then assert validation_result def __get_random_dataset_name(self): dataset_name = ''.join( random.choice(string.ascii_lowercase) for i in range(10)) return dataset_name + '.nc' def __create_test_dataset(self, dataset_name: str): """Extracted from http://pyhogs.github.io/intro_netcdf4.html Arguments: dataset_name {str} -- Name for the dataset. Returns: Dataset -- NetCDF4 Dataset """ # 1. Create some data. lon = np.arange(0, 56, 2) lat = np.arange(-30, 25, 2.5) z = np.arange(0, 200, 10) x = np.random.randint(10, 25, size=(len(lon), len(lat), len(z))) noise = np.random.rand(len(lon), len(lat), len(z)) temp_data = x+noise # 2. Create dataset dataset_file = Dataset(dataset_name, 'w', format='NETCDF4') dataset_group = dataset_file.createGroup('Temp_data') # 3. Specify dimensions dataset_group.createDimension('lon', len(lon)) dataset_group.createDimension('lat', len(lat)) dataset_group.createDimension('z', len(z)) dataset_group.createDimension('time', None) # 4. Build variables longitude = dataset_group.createVariable('Longitude', 'f4', 'lon') latitude = dataset_group.createVariable('Latitude', 'f4', 'lat') levels = dataset_group.createVariable('Levels', 'i4', 'z') temp = dataset_group.createVariable( 'Temperature', 'f4', ('time', 'lon', 'lat', 'z')) time = dataset_group.createVariable('Time', 'i4', 'time') # 5. Pass data into variables # The "[:]" at the end of the variable instance is necessary longitude[:] = lon latitude[:] = lat levels[:] = z temp[0, :, :, :] = temp_data # get time in days since Jan 01,01 today = datetime.today() time_num = today.toordinal() time[0] = time_num # 6. Add attributes # Add global attributes dataset_file.description = "Example dataset containing one group" dataset_file.history = "Created " + today.strftime("%d/%m/%y") # Add local attributes to variable instances longitude.units = 'degrees east' latitude.units = 'degrees north' time.units = 'days since Jan 01, 0001' temp.units = 'Kelvin' levels.units = 'meters' temp.warning = 'This data is not real!' # 5. Save dataset # dataset_file.close() apparently there's a problem saving the variables # (something regarding the ID) return dataset_group def __create_empty_test_dataset( self, dataset_name: str, lon_key: str, lat_key: str): dataset = Dataset(dataset_name, 'w', format='NETCDF4') dataset.createDimension('lon', None) dataset.createDimension('lat', None) if lon_key is not None: dataset.createVariable(lon_key, "f4", ('lon')) if lat_key is not None: dataset.createVariable(lat_key, "f4", ('lat')) dataset.close() return dataset