Merge branch 'master-python2'

This commit is contained in:
Michael James 2017-02-01 21:09:01 -07:00
commit 69427a6ac0
64 changed files with 5091 additions and 107 deletions

View file

@ -1,7 +1,7 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
@ -13,7 +13,7 @@
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
@ -47,6 +47,8 @@ from dynamicserialize import DynamicSerializationManager
# 01/07/11 5645 cjeanbap Added audio file to Status Message.
# 05/27/11 3050 cjeanbap Added if-statement to check Priority
# value
# 07/27/15 4654 skorolev Added filters
# 11/11/15 5120 rferrel Cannot serialize empty filters.
#
class NotificationMessage:
@ -58,13 +60,14 @@ class NotificationMessage:
4: 'EVENTB',
5: 'VERBOSE'}
def __init__(self, host='localhost', port=61999, message='', priority='PROBLEM', category="LOCAL", source="ANNOUNCER", audioFile="NONE"):
def __init__(self, host='localhost', port=61999, message='', priority='PROBLEM', category="LOCAL", source="ANNOUNCER", audioFile="NONE", filters=None):
self.host = host
self.port = port
self.message = message
self.audioFile = audioFile
self.source = source
self.category = category
self.filters = filters
priorityInt = None
@ -113,9 +116,9 @@ class NotificationMessage:
# of the message to AlertViz
# 9581 is global distribution thru ThriftClient to Edex
# 61999 is local distribution
if (self.port == 61999):
if (int(self.port) == 61999):
# use stomp.py
conn = stomp.Connection(host_and_ports=[(self.host, self.port)])
conn = stomp.Connection(host_and_ports=[(self.host, 61999)])
timeout = threading.Timer(5.0, self.connection_timeout, [conn])
try:
@ -132,6 +135,8 @@ class NotificationMessage:
sm.set("category", self.category)
sm.set("sourceKey", self.source)
sm.set("audioFile", self.audioFile)
if self.filters is not None and len(self.filters) > 0:
sm.set("filters", self.filters)
msg = ET.SubElement(sm, "message")
msg.text = self.message
details = ET.SubElement(sm, "details")
@ -144,7 +149,7 @@ class NotificationMessage:
conn.stop()
else:
# use ThriftClient
alertVizRequest = createRequest(self.message, self.priority, self.source, self.category, self.audioFile)
alertVizRequest = createRequest(self.message, self.priority, self.source, self.category, self.audioFile, self.filters)
thriftClient = ThriftClient.ThriftClient(self.host, self.port, "/services")
serverResponse = None
@ -159,7 +164,7 @@ class NotificationMessage:
else:
print("Response: " + str(serverResponse))
def createRequest(message, priority, source, category, audioFile):
def createRequest(message, priority, source, category, audioFile, filters):
obj = AlertVizRequest()
obj.setMachine(socket.gethostname())
@ -171,7 +176,7 @@ def createRequest(message, priority, source, category, audioFile):
obj.setAudioFile(audioFile)
else:
obj.setAudioFile('\0')
obj.setFilters(filters)
return obj
if __name__ == '__main__':

View file

@ -0,0 +1,99 @@
# #
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
# #
#
# Method for performing a DAF time query where all parameter/level/location
# combinations must be available at the same time.
#
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 06/22/16 #5591 bsteffen Initial Creation.
#
from awips.dataaccess import DataAccessLayer
def getAvailableTimes(request, refTimeOnly=False):
return __getAvailableTimesForEachParameter(request, refTimeOnly)
def __getAvailableTimesForEachParameter(request, refTimeOnly=False):
parameters = request.getParameters()
if parameters:
times = None
for parameter in parameters:
specificRequest = __cloneRequest(request)
specificRequest.setParameters(parameter)
specificTimes = __getAvailableTimesForEachLevel(specificRequest, refTimeOnly)
if times is None:
times = specificTimes
else:
times.intersection_update(specificTimes)
if not times:
break
return times
else:
return __getAvailableTimesForEachLevel(request, refTimeOnly)
def __getAvailableTimesForEachLevel(request, refTimeOnly=False):
levels = request.getLevels()
if levels:
times = None
for level in levels:
specificRequest = __cloneRequest(request)
specificRequest.setLevels(level)
specificTimes = __getAvailableTimesForEachLocation(specificRequest, refTimeOnly)
if times is None:
times = specificTimes
else:
times.intersection_update(specificTimes)
if not times:
break
return times
else:
return __getAvailableTimesForEachLocation(request, refTimeOnly)
def __getAvailableTimesForEachLocation(request, refTimeOnly=False):
locations = request.getLocationNames()
if locations:
times = None
for location in locations:
specificRequest = __cloneRequest(request)
specificRequest.setLocationNames(location)
specificTimes = DataAccessLayer.getAvailableTimes(specificRequest, refTimeOnly)
if times is None:
times = set(specificTimes)
else:
times.intersection_update(specificTimes)
if not times:
break
return times
else:
return DataAccessLayer.getAvailableTimes(request, refTimeOnly)
def __cloneRequest(request):
return DataAccessLayer.newDataRequest(datatype = request.getDatatype(),
parameters = request.getParameters(),
levels = request.getLevels(),
locationNames = request.getLocationNames(),
envelope = request.getEnvelope(),
**request.getIdentifiers())

View file

@ -30,12 +30,17 @@
# 12/10/12 njensen Initial Creation.
# Feb 14, 2013 1614 bsteffen refactor data access framework
# to use single request.
# 04/10/13 1871 mnash move getLatLonCoords to JGridData and add default args
# 05/29/13 2023 dgilling Hook up ThriftClientRouter.
# 03/03/14 2673 bsteffen Add ability to query only ref times.
# 07/22/14 3185 njensen Added optional/default args to newDataRequest
# 07/30/14 3185 njensen Renamed valid identifiers to optional
# Apr 26, 2015 4259 njensen Updated for new JEP API
# 04/10/13 1871 mnash move getLatLonCoords to JGridData and add default args
# 05/29/13 2023 dgilling Hook up ThriftClientRouter.
# 03/03/14 2673 bsteffen Add ability to query only ref times.
# 07/22/14 3185 njensen Added optional/default args to newDataRequest
# 07/30/14 3185 njensen Renamed valid identifiers to optional
# Apr 26, 2015 4259 njensen Updated for new JEP API
# Apr 13, 2016 5379 tgurney Add getIdentifierValues()
# Jun 01, 2016 5587 tgurney Add new signatures for
# getRequiredIdentifiers() and
# getOptionalIdentifiers()
# 10/07/16 ---- mjames@ucar Added getForecastRun
#
#
#
@ -43,6 +48,7 @@
import sys
import subprocess
import warnings
THRIFT_HOST = "edex"
USING_NATIVE_THRIFT = False
@ -58,17 +64,17 @@ else:
router = ThriftClientRouter.ThriftClientRouter(THRIFT_HOST)
USING_NATIVE_THRIFT = True
def getForecastCycle(cycle, times):
def getForecastRun(cycle, times):
"""
:param cycle: Forecast cycle reference time
:param times: All available times/cycles
:return: DataTime array for a single forecast run
"""
forecast_run = []
for time in times:
if time.getRefTime() == cycle.getRefTime():
forecast_run.append(time)
return forecast_run
fcstRun = []
for t in times:
if str(t)[:19] == str(cycle):
fcstRun.append(t)
return fcstRun
def getAvailableTimes(request, refTimeOnly=False):
"""
@ -81,6 +87,7 @@ def getAvailableTimes(request, refTimeOnly=False):
"""
return router.getAvailableTimes(request, refTimeOnly)
def getGridData(request, times=[]):
"""
Gets the grid data that matches the request at the specified times. Each
@ -94,6 +101,7 @@ def getGridData(request, times=[]):
"""
return router.getGridData(request, times)
def getGeometryData(request, times=[]):
"""
Gets the geometry data that matches the request at the specified times.
@ -107,6 +115,7 @@ def getGeometryData(request, times=[]):
"""
return router.getGeometryData(request, times)
def getAvailableLocationNames(request):
"""
Gets the available location names that match the request without actually
@ -118,6 +127,7 @@ def getAvailableLocationNames(request):
"""
return router.getAvailableLocationNames(request)
def getAvailableParameters(request):
"""
Gets the available parameters names that match the request without actually
@ -129,6 +139,7 @@ def getAvailableParameters(request):
"""
return router.getAvailableParameters(request)
def getAvailableLevels(request):
"""
Gets the available levels that match the request without actually
@ -140,26 +151,46 @@ def getAvailableLevels(request):
"""
return router.getAvailableLevels(request)
def getRequiredIdentifiers(datatype):
def getRequiredIdentifiers(request):
"""
Gets the required identifiers for this datatype. These identifiers
Gets the required identifiers for this request. These identifiers
must be set on a request for the request of this datatype to succeed.
:param datatype: the datatype to find required identifiers for
:param request: the request to find required identifiers
:returns: a list of strings of required identifiers
"""
return router.getRequiredIdentifiers(datatype)
if str(request) == request:
warnings.warn("Use getRequiredIdentifiers(IDataRequest) instead",
DeprecationWarning)
return router.getRequiredIdentifiers(request)
def getOptionalIdentifiers(datatype):
def getOptionalIdentifiers(request):
"""
Gets the optional identifiers for this datatype.
Gets the optional identifiers for this request.
:param datatype: the datatype to find optional identifiers for
:param request: the reuqest to find optional identifiers for
:returns: a list of strings of optional identifiers
"""
return router.getOptionalIdentifiers(datatype)
if str(request) == request:
warnings.warn("Use getOptionalIdentifiers(IDataRequest) instead",
DeprecationWarning)
return router.getOptionalIdentifiers(request)
def getIdentifierValues(request, identifierKey):
"""
Gets the allowed values for a particular identifier on this datatype.
:param request: the request to find identifier values for
:praram identifierKey: the identifier to find values for
:returns: a list of strings of allowed values for the specified identifier
"""
return router.getIdentifierValues(request, identifierKey)
def newDataRequest(datatype=None, **kwargs):
"""

View file

@ -28,10 +28,11 @@
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 06/03/13 dgilling Initial Creation.
# 01/06/14 #2537 bsteffen Share geometry WKT.
# 03/19/14 #2882 dgilling Raise an exception when getNumber()
# 01/06/14 2537 bsteffen Share geometry WKT.
# 03/19/14 2882 dgilling Raise an exception when getNumber()
# is called for data that is not a
# numeric Type.
# 06/09/16 5574 mapeters Handle 'SHORT' type in getNumber().
#
#
@ -61,7 +62,7 @@ class PyGeometryData(IGeometryData, PyData.PyData):
def getNumber(self, param):
value = self.__dataMap[param][0]
t = self.getType(param)
if t == 'INT':
if t == 'INT' or t == 'SHORT':
return int(value)
elif t == 'LONG':
return int(value)

View file

@ -28,6 +28,7 @@
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 06/03/13 #2023 dgilling Initial Creation.
# 11/10/16 #5900 bsteffen Correct grid shape
#
#
@ -51,7 +52,7 @@ class PyGridData(IGridData, PyData.PyData):
ny = ny
self.__parameter = gridDataRecord.getParameter()
self.__unit = gridDataRecord.getUnit()
self.__gridData = numpy.reshape(numpy.array(gridDataRecord.getGridData()), (nx, ny))
self.__gridData = numpy.reshape(numpy.array(gridDataRecord.getGridData()), (ny, nx))
self.__latLonGrid = latLonGrid
def getParameter(self):

View file

@ -23,17 +23,22 @@
#
#
#
# SOFTWARE HISTORY
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 05/21/13 #2023 dgilling Initial Creation.
# 01/06/14 #2537 bsteffen Share geometry WKT.
# 03/03/14 #2673 bsteffen Add ability to query only ref times.
# 07/22/14 #3185 njensen Added optional/default args to newDataRequest
# 07/23/14 #3185 njensen Added new methods
# 07/30/14 #3185 njensen Renamed valid identifiers to optional
# 06/30/15 #4569 nabowle Use hex WKB for geometries.
# 05/21/13 2023 dgilling Initial Creation.
# 01/06/14 2537 bsteffen Share geometry WKT.
# 03/03/14 2673 bsteffen Add ability to query only ref times.
# 07/22/14 3185 njensen Added optional/default args to newDataRequest
# 07/23/14 3185 njensen Added new methods
# 07/30/14 3185 njensen Renamed valid identifiers to optional
# 06/30/15 4569 nabowle Use hex WKB for geometries.
# 04/13/15 5379 tgurney Add getIdentifierValues()
# 06/01/16 5587 tgurney Add new signatures for
# getRequiredIdentifiers() and
# getOptionalIdentifiers()
# 11/10/16 5900 bsteffen Correct grid shape
#
@ -49,6 +54,7 @@ from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import G
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetAvailableLevelsRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetRequiredIdentifiersRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetOptionalIdentifiersRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetIdentifierValuesRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetSupportedDatatypesRequest
from awips import ThriftClient
@ -87,8 +93,8 @@ class ThriftClientRouter(object):
for location in locNames:
nx = response.getSiteNxValues()[location]
ny = response.getSiteNyValues()[location]
latData = numpy.reshape(numpy.array(response.getSiteLatGrids()[location]), (nx, ny))
lonData = numpy.reshape(numpy.array(response.getSiteLonGrids()[location]), (nx, ny))
latData = numpy.reshape(numpy.array(response.getSiteLatGrids()[location]), (ny, nx))
lonData = numpy.reshape(numpy.array(response.getSiteLonGrids()[location]), (ny, nx))
locSpecificData[location] = (nx, ny, (lonData, latData))
retVal = []
@ -143,18 +149,31 @@ class ThriftClientRouter(object):
response = self._client.sendRequest(levelReq)
return response
def getRequiredIdentifiers(self, datatype):
def getRequiredIdentifiers(self, request):
if str(request) == request:
# Handle old version getRequiredIdentifiers(str)
request = self.newDataRequest(request)
idReq = GetRequiredIdentifiersRequest()
idReq.setDatatype(datatype)
idReq.setRequest(request)
response = self._client.sendRequest(idReq)
return response
def getOptionalIdentifiers(self, datatype):
def getOptionalIdentifiers(self, request):
if str(request) == request:
# Handle old version getOptionalIdentifiers(str)
request = self.newDataRequest(request)
idReq = GetOptionalIdentifiersRequest()
idReq.setDatatype(datatype)
idReq.setRequest(request)
response = self._client.sendRequest(idReq)
return response
def getIdentifierValues(self, request, identifierKey):
idValReq = GetIdentifierValuesRequest()
idValReq.setIdentifierKey(identifierKey)
idValReq.setRequestParameters(request)
response = self._client.sendRequest(idValReq)
return response
def newDataRequest(self, datatype, parameters=[], levels=[], locationNames = [], envelope=None, **kwargs):
req = DefaultDataRequest()
if datatype:

View file

@ -0,0 +1,36 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
#
# __init__.py for awips.test.dafTests package
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 02/09/2016 4795 mapeters Initial creation.
# 04/12/2016 5548 tgurney Cleanup
#
#
#
__all__ = []

View file

@ -0,0 +1,59 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from awips.dataaccess import DataAccessLayer as DAL
import baseDafTestCase
#
# Base TestCase for BufrMos* tests.
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
#
#
#
class BufrMosTestCase(baseDafTestCase.DafTestCase):
"""Base class for testing DAF support of bufrmos data"""
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames("KOMA")
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames("KOMA")
req.setParameters("temperature", "dewpoint")
self.runGeometryDataTest(req)

View file

@ -0,0 +1,218 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
from awips.ThriftClient import ThriftRequestException
import os
import unittest
#
# Base TestCase for DAF tests. This class provides helper methods and
# tests common to all DAF test cases.
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/13/16 5379 tgurney Add identifier values tests
# 04/18/16 5548 tgurney More cleanup, plus new tests
# 04/26/16 5587 tgurney Move identifier values tests
# to subclasses
# 06/01/16 5587 tgurney Add testGet*Identifiers
# 06/07/16 5574 tgurney Make geometry/grid data tests
# return the retrieved data
# 06/10/16 5548 tgurney Make testDatatypeIsSupported
# case-insensitive
# 10/05/16 5926 dgilling Better checks in runGeometryDataTest.
# 11/08/16 5985 tgurney Do not check data times on
# time-agnostic data
#
#
class DafTestCase(unittest.TestCase):
sampleDataLimit = 5
"""
Maximum number of levels, locations, times, and geometry/grid data to
display
"""
numTimesToLimit = 3
"""
When limiting geometry/grid data requests with times, only retrieve data
for this many times
"""
datatype = None
"""Name of the datatype"""
@classmethod
def setUp(cls):
host = os.environ.get('DAF_TEST_HOST')
if host is None:
host = 'localhost'
DAL.changeEDEXHost(host)
@staticmethod
def getTimesIfSupported(req):
"""Return available times for req. If req refers to a time-agnostic
datatype, return an empty list instead.
"""
times = []
try:
times = DAL.getAvailableTimes(req)
except ThriftRequestException as e:
if not 'TimeAgnosticDataException' in str(e):
raise
return times
def testDatatypeIsSupported(self):
allSupported = (item.lower() for item in DAL.getSupportedDatatypes())
self.assertIn(self.datatype.lower(), allSupported)
def testGetRequiredIdentifiers(self):
req = DAL.newDataRequest(self.datatype)
required = DAL.getRequiredIdentifiers(req)
self.assertIsNotNone(required)
print("Required identifiers:", required)
def testGetOptionalIdentifiers(self):
req = DAL.newDataRequest(self.datatype)
optional = DAL.getOptionalIdentifiers(req)
self.assertIsNotNone(optional)
print("Optional identifiers:", optional)
def runGetIdValuesTest(self, identifiers):
for id in identifiers:
req = DAL.newDataRequest(self.datatype)
idValues = DAL.getIdentifierValues(req, id)
self.assertTrue(hasattr(idValues, '__iter__'))
def runInvalidIdValuesTest(self):
badString = 'id from ' + self.datatype + '; select 1;'
with self.assertRaises(ThriftRequestException) as cm:
req = DAL.newDataRequest(self.datatype)
idValues = DAL.getIdentifierValues(req, badString)
def runNonexistentIdValuesTest(self):
with self.assertRaises(ThriftRequestException) as cm:
req = DAL.newDataRequest(self.datatype)
idValues = DAL.getIdentifierValues(req, 'idthatdoesnotexist')
def runParametersTest(self, req):
params = DAL.getAvailableParameters(req)
self.assertIsNotNone(params)
print(params)
def runLevelsTest(self, req):
levels = DAL.getAvailableLevels(req)
self.assertIsNotNone(levels)
print("Number of levels: " + str(len(levels)))
strLevels = [str(t) for t in levels[:self.sampleDataLimit]]
print("Sample levels:\n" + str(strLevels))
def runLocationsTest(self, req):
locs = DAL.getAvailableLocationNames(req)
self.assertIsNotNone(locs)
print("Number of location names: " + str(len(locs)))
print("Sample location names:\n" + str(locs[:self.sampleDataLimit]))
def runTimesTest(self, req):
times = DAL.getAvailableTimes(req)
self.assertIsNotNone(times)
print("Number of times: " + str(len(times)))
strTimes = [str(t) for t in times[:self.sampleDataLimit]]
print("Sample times:\n" + str(strTimes))
def runTimeAgnosticTest(self, req):
with self.assertRaises(ThriftRequestException) as cm:
times = DAL.getAvailableTimes(req)
self.assertIn('TimeAgnosticDataException', str(cm.exception))
def runGeometryDataTest(self, req, checkDataTimes=True):
"""
Test that we are able to successfully retrieve geometry data for the
given request.
"""
times = DafTestCase.getTimesIfSupported(req)
geomData = DAL.getGeometryData(req, times[:self.numTimesToLimit])
self.assertIsNotNone(geomData)
if times:
self.assertNotEqual(len(geomData), 0)
print("Number of geometry records: " + str(len(geomData)))
print("Sample geometry data:")
for record in geomData[:self.sampleDataLimit]:
if checkDataTimes and times:
self.assertIn(record.getDataTime(), times[:self.numTimesToLimit])
print("geometry=" + str(record.getGeometry()), end="")
for p in req.getParameters():
print(" " + p + "=" + record.getString(p), end="")
print()
return geomData
def runGeometryDataTestWithTimeRange(self, req, timeRange):
"""
Test that we are able to successfully retrieve geometry data for the
given request.
"""
geomData = DAL.getGeometryData(req, timeRange)
self.assertIsNotNone(geomData)
print("Number of geometry records: " + str(len(geomData)))
print("Sample geometry data:")
for record in geomData[:self.sampleDataLimit]:
self.assertGreaterEqual(record.getDataTime().getRefTime().getTime(), timeRange.getStartInMillis())
self.assertLessEqual(record.getDataTime().getRefTime().getTime(), timeRange.getEndInMillis())
print("geometry=" + str(record.getGeometry()), end="")
for p in req.getParameters():
print(" " + p + "=" + record.getString(p), end="")
print()
return geomData
def runGridDataTest(self, req, testSameShape=True):
"""
Test that we are able to successfully retrieve grid data for the given
request.
Args:
testSameShape: whether or not to verify that all the retrieved data
have the same shape (most data don't change shape)
"""
times = DafTestCase.getTimesIfSupported(req)
gridData = DAL.getGridData(req, times[:self.numTimesToLimit])
self.assertIsNotNone(gridData)
print("Number of grid records: " + str(len(gridData)))
if len(gridData) > 0:
print("Sample grid data shape:\n" + str(gridData[0].getRawData().shape) + "\n")
print("Sample grid data:\n" + str(gridData[0].getRawData()) + "\n")
print("Sample lat-lon data:\n" + str(gridData[0].getLatLonCoords()) + "\n")
if testSameShape:
correctGridShape = gridData[0].getLatLonCoords()[0].shape
for record in gridData:
rawData = record.getRawData()
self.assertIsNotNone(rawData)
self.assertEqual(rawData.shape, correctGridShape)
return gridData

View file

@ -0,0 +1,61 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
import baseDafTestCase
import unittest
#
# Test DAF support for ACARS data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
#
#
class AcarsTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for ACARS data"""
datatype = "acars"
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setParameters("flightLevel", "tailNumber")
self.runGeometryDataTest(req)

View file

@ -0,0 +1,165 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
import baseDafTestCase
import unittest
#
# Test DAF support for airep data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 06/09/16 5587 bsteffen Add getIdentifierValues tests
# 06/13/16 5574 tgurney Add advanced query tests
#
#
class AirepTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for airep data"""
datatype = "airep"
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setParameters("flightLevel", "reportType")
self.runGeometryDataTest(req)
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
self.runGetIdValuesTest(optionalIds)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.setParameters("flightLevel", "reportType")
req.addIdentifier(key, constraint)
return self.runGeometryDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('reportType', '=', 'AIREP')
for record in geometryData:
self.assertEqual(record.getString('reportType'), 'AIREP')
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('reportType', '=', u'AIREP')
for record in geometryData:
self.assertEqual(record.getString('reportType'), 'AIREP')
# No numeric tests since no numeric identifiers are available.
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('reportType', '=', None)
for record in geometryData:
self.assertEqual(record.getType('reportType'), 'NULL')
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('reportType', '!=', 'AIREP')
for record in geometryData:
self.assertNotEqual(record.getString('reportType'), 'AIREP')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('reportType', '!=', None)
for record in geometryData:
self.assertNotEqual(record.getType('reportType'), 'NULL')
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('reportType', '>', 'AIREP')
for record in geometryData:
self.assertGreater(record.getString('reportType'), 'AIREP')
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('reportType', '<', 'AIREP')
for record in geometryData:
self.assertLess(record.getString('reportType'), 'AIREP')
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('reportType', '>=', 'AIREP')
for record in geometryData:
self.assertGreaterEqual(record.getString('reportType'), 'AIREP')
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('reportType', '<=', 'AIREP')
for record in geometryData:
self.assertLessEqual(record.getString('reportType'), 'AIREP')
def testGetDataWithInTuple(self):
collection = ('AIREP', 'AMDAR')
geometryData = self._runConstraintTest('reportType', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('reportType'), collection)
def testGetDataWithInList(self):
collection = ['AIREP', 'AMDAR']
geometryData = self._runConstraintTest('reportType', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('reportType'), collection)
def testGetDataWithInGenerator(self):
collection = ('AIREP', 'AMDAR')
generator = (item for item in collection)
geometryData = self._runConstraintTest('reportType', 'in', generator)
for record in geometryData:
self.assertIn(record.getString('reportType'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('reportType', 'junk', 'AIREP')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('reportType', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('reportType', 'in', [])
def testGetDataWithNestedInConstraintThrowsException(self):
collection = ('AIREP', 'AMDAR', ())
with self.assertRaises(TypeError):
self._runConstraintTest('reportType', 'in', collection)

View file

@ -0,0 +1,192 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
from awips.ThriftClient import ThriftRequestException
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
import baseDafTestCase
import unittest
#
# Test DAF support for binlightning data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 04/21/16 5551 tgurney Add tests to verify #5551
# 04/25/16 5587 tgurney Enable skipped test added in
# #5551
# 04/26/16 5587 tgurney Move identifier values tests
# out of base class
# 06/01/16 5587 tgurney Update testGetIdentifierValues
# 06/03/16 5574 tgurney Add advanced query tests
# 06/13/16 5574 tgurney Typo
# 11/08/16 5985 tgurney Do not check data times
#
#
class BinLightningTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for binlightning data"""
datatype = "binlightning"
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("source", "NLDN")
self.runTimesTest(req)
def testGetGeometryDataSingleSourceSingleParameter(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("source", "NLDN")
req.setParameters('intensity')
self.runGeometryDataTest(req, checkDataTimes=False)
def testGetGeometryDataInvalidParamRaisesIncompatibleRequestException(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("source", "NLDN")
req.setParameters('blahblahblah')
with self.assertRaises(ThriftRequestException) as cm:
self.runGeometryDataTest(req)
self.assertIn('IncompatibleRequestException', str(cm.exception))
def testGetGeometryDataSingleSourceAllParameters(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("source", "NLDN")
req.setParameters(*DAL.getAvailableParameters(req))
self.runGeometryDataTest(req, checkDataTimes=False)
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
requiredIds = set(DAL.getRequiredIdentifiers(req))
self.runGetIdValuesTest(optionalIds | requiredIds)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.setParameters('intensity')
return self.runGeometryDataTest(req, checkDataTimes=False)
def testGetDataWithEqualsString(self):
geomData = self._runConstraintTest('source', '=', 'NLDN')
for record in geomData:
self.assertEqual(record.getAttribute('source'), 'NLDN')
def testGetDataWithEqualsUnicode(self):
geomData = self._runConstraintTest('source', '=', u'NLDN')
for record in geomData:
self.assertEqual(record.getAttribute('source'), 'NLDN')
def testGetDataWithEqualsInt(self):
geomData = self._runConstraintTest('source', '=', 1000)
for record in geomData:
self.assertEqual(record.getAttribute('source'), 1000)
def testGetDataWithEqualsLong(self):
geomData = self._runConstraintTest('source', '=', 1000L)
for record in geomData:
self.assertEqual(record.getAttribute('source'), 1000)
def testGetDataWithEqualsFloat(self):
geomData = self._runConstraintTest('source', '=', 1.0)
for record in geomData:
self.assertEqual(round(record.getAttribute('source'), 1), 1.0)
def testGetDataWithEqualsNone(self):
geomData = self._runConstraintTest('source', '=', None)
for record in geomData:
self.assertIsNone(record.getAttribute('source'))
def testGetDataWithNotEquals(self):
geomData = self._runConstraintTest('source', '!=', 'NLDN')
for record in geomData:
self.assertNotEqual(record.getAttribute('source'), 'NLDN')
def testGetDataWithNotEqualsNone(self):
geomData = self._runConstraintTest('source', '!=', None)
for record in geomData:
self.assertIsNotNone(record.getAttribute('source'))
def testGetDataWithGreaterThan(self):
geomData = self._runConstraintTest('source', '>', 'NLDN')
for record in geomData:
self.assertGreater(record.getAttribute('source'), 'NLDN')
def testGetDataWithLessThan(self):
geomData = self._runConstraintTest('source', '<', 'NLDN')
for record in geomData:
self.assertLess(record.getAttribute('source'), 'NLDN')
def testGetDataWithGreaterThanEquals(self):
geomData = self._runConstraintTest('source', '>=', 'NLDN')
for record in geomData:
self.assertGreaterEqual(record.getAttribute('source'), 'NLDN')
def testGetDataWithLessThanEquals(self):
geomData = self._runConstraintTest('source', '<=', 'NLDN')
for record in geomData:
self.assertLessEqual(record.getAttribute('source'), 'NLDN')
def testGetDataWithInTuple(self):
geomData = self._runConstraintTest('source', 'in', ('NLDN', 'ENTLN'))
for record in geomData:
self.assertIn(record.getAttribute('source'), ('NLDN', 'ENTLN'))
def testGetDataWithInList(self):
geomData = self._runConstraintTest('source', 'in', ['NLDN', 'ENTLN'])
for record in geomData:
self.assertIn(record.getAttribute('source'), ('NLDN', 'ENTLN'))
def testGetDataWithInGenerator(self):
generator = (item for item in ('NLDN', 'ENTLN'))
geomData = self._runConstraintTest('source', 'in', generator)
for record in geomData:
self.assertIn(record.getAttribute('source'), ('NLDN', 'ENTLN'))
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('source', 'junk', 'NLDN')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('source', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('source', 'in', [])

View file

@ -0,0 +1,45 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
import baseBufrMosTestCase
import unittest
#
# Test DAF support for bufrmosAVN data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
#
#
class BufrMosAvnTestCase(baseBufrMosTestCase.BufrMosTestCase):
"""Test DAF support for bufrmosAVN data"""
datatype = "bufrmosAVN"
# All tests inherited from superclass

View file

@ -0,0 +1,45 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
import baseBufrMosTestCase
import unittest
#
# Test DAF support for bufrmosETA data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
#
#
class BufrMosEtaTestCase(baseBufrMosTestCase.BufrMosTestCase):
"""Test DAF support for bufrmosETA data"""
datatype = "bufrmosETA"
# All tests inherited from superclass

View file

@ -0,0 +1,45 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
import baseBufrMosTestCase
import unittest
#
# Test DAF support for bufrmosGFS data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
#
#
class BufrMosGfsTestCase(baseBufrMosTestCase.BufrMosTestCase):
"""Test DAF support for bufrmosGFS data"""
datatype = "bufrmosGFS"
# All tests inherited from superclass

View file

@ -0,0 +1,52 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
import baseBufrMosTestCase
import unittest
#
# Test DAF support for bufrmosHPC data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
#
#
class BufrMosHpcTestCase(baseBufrMosTestCase.BufrMosTestCase):
"""Test DAF support for bufrmosHPC data"""
datatype = "bufrmosHPC"
# Most tests inherited from superclass
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames("KOMA")
req.setParameters("forecastHr", "maxTemp24Hour")
self.runGeometryDataTest(req)

View file

@ -0,0 +1,45 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
import baseBufrMosTestCase
import unittest
#
# Test DAF support for bufrmosLAMP data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
#
#
class BufrMosLampTestCase(baseBufrMosTestCase.BufrMosTestCase):
"""Test DAF support for bufrmosLAMP data"""
datatype = "bufrmosLAMP"
# All tests inherited from superclass

View file

@ -0,0 +1,52 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
import baseBufrMosTestCase
import unittest
#
# Test DAF support for bufrmosMRF data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
#
#
class BufrMosMrfTestCase(baseBufrMosTestCase.BufrMosTestCase):
"""Test DAF support for bufrmosMRF data"""
datatype = "bufrmosMRF"
# Most tests inherited from superclass
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames("KOMA")
req.setParameters("forecastHr", "maxTempDay")
self.runGeometryDataTest(req)

View file

@ -0,0 +1,205 @@
# #
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
# #
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
import baseDafTestCase
import unittest
#
# Test DAF support for bufrua data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 06/09/16 5587 bsteffen Add getIdentifierValues tests
# 06/13/16 5574 tgurney Add advanced query tests
#
#
class BufrUaTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for bufrua data"""
datatype = "bufrua"
location = "72558"
"""stationid corresponding to KOAX"""
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("reportType", "2020")
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames(self.location)
req.addIdentifier("reportType", "2020")
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames(self.location)
req.addIdentifier("reportType", "2020")
req.setParameters("sfcPressure", "staName", "rptType", "tdMan")
print("Testing getGeometryData()")
geomData = DAL.getGeometryData(req)
self.assertIsNotNone(geomData)
print("Number of geometry records: " + str(len(geomData)))
print("Sample geometry data:")
for record in geomData[:self.sampleDataLimit]:
print("level=", record.getLevel(), end="")
# One dimensional parameters are reported on the 0.0UNKNOWN level.
# 2D parameters are reported on MB levels from pressure.
if record.getLevel() == "0.0UNKNOWN":
print(" sfcPressure=" + record.getString("sfcPressure") + record.getUnit("sfcPressure"), end="")
print(" staName=" + record.getString("staName"), end="")
print(" rptType=" + record.getString("rptType") + record.getUnit("rptType"), end="")
else:
print(" tdMan=" + str(record.getNumber("tdMan")) + record.getUnit("tdMan"), end="")
print(" geometry=", record.getGeometry())
print("getGeometryData() complete\n\n")
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
self.runGetIdValuesTest(optionalIds)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
# As an identifier it is "reportType" but as a parameter it is
# "rptType"... this is weird...
req.setParameters("staName", "rptType")
return self.runGeometryDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('reportType', '=', '2022')
for record in geometryData:
self.assertEqual(record.getString('rptType'), '2022')
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('reportType', '=', u'2022')
for record in geometryData:
self.assertEqual(record.getString('rptType'), '2022')
def testGetDataWithEqualsInt(self):
geometryData = self._runConstraintTest('reportType', '=', 2022)
for record in geometryData:
self.assertEqual(record.getString('rptType'), '2022')
def testGetDataWithEqualsLong(self):
geometryData = self._runConstraintTest('reportType', '=', 2022L)
for record in geometryData:
self.assertEqual(record.getString('rptType'), '2022')
# No float test because no float identifiers are available
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('reportType', '=', None)
for record in geometryData:
self.assertEqual(record.getType('rptType'), 'NULL')
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('reportType', '!=', 2022)
for record in geometryData:
self.assertNotEqual(record.getString('rptType'), '2022')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('reportType', '!=', None)
for record in geometryData:
self.assertNotEqual(record.getType('rptType'), 'NULL')
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('reportType', '>', 2022)
for record in geometryData:
self.assertGreater(record.getString('rptType'), '2022')
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('reportType', '<', 2022)
for record in geometryData:
self.assertLess(record.getString('rptType'), '2022')
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('reportType', '>=', 2022)
for record in geometryData:
self.assertGreaterEqual(record.getString('rptType'), '2022')
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('reportType', '<=', 2022)
for record in geometryData:
self.assertLessEqual(record.getString('rptType'), '2022')
def testGetDataWithInTuple(self):
collection = ('2022', '2032')
geometryData = self._runConstraintTest('reportType', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('rptType'), collection)
def testGetDataWithInList(self):
collection = ['2022', '2032']
geometryData = self._runConstraintTest('reportType', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('rptType'), collection)
def testGetDataWithInGenerator(self):
collection = ('2022', '2032')
generator = (item for item in collection)
geometryData = self._runConstraintTest('reportType', 'in', generator)
for record in geometryData:
self.assertIn(record.getString('rptType'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('reportType', 'junk', '2022')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('reportType', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('rptType', 'in', [])
def testGetDataWithNestedInConstraintThrowsException(self):
collection = ('2022', '2032', ())
with self.assertRaises(TypeError):
self._runConstraintTest('rptType', 'in', collection)

View file

@ -0,0 +1,413 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
import datetime
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
from awips.dataaccess import DataAccessLayer as DAL
from awips.ThriftClient import ThriftRequestException
import baseDafTestCase
import unittest
#
# Test DAF support for climate data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 04/26/16 5587 tgurney Add identifier values tests
# 06/09/16 5574 mapeters Add advanced query tests, Short parameter test
# 06/13/16 5574 tgurney Fix checks for None
# 06/21/16 5548 tgurney Skip tests that cause errors
# 10/06/16 5926 dgilling Add additional time and location tests.
#
#
class ClimateTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for climate data"""
datatype = 'climate'
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
self.runLocationsTest(req)
def testGetAvailableLocationsForRptTable(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.rpt')
self.runLocationsTest(req)
def testGetAvailableLocationsForStationId(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.day_climate_norm')
self.runLocationsTest(req)
def testGetAvailableLocationsForInformId(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_mon_season_yr')
self.runLocationsTest(req)
def testGetAvailableLocationsWithConstraints(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
req.addIdentifier('maxtemp_mon', RequestConstraint.new('>', 95))
self.runLocationsTest(req)
def testGetAvailableLocationsWithInvalidTable(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.boolean_values')
with self.assertRaises(ThriftRequestException) as cm:
DAL.getAvailableLocationNames(req)
self.assertIn('IncompatibleRequestException', str(cm.exception))
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
req.setParameters('maxtemp_mon', 'min_sea_press')
self.runTimesTest(req)
def testGetAvailableTimesWithLocationNamesForYearMonth(self):
"""
Test retrieval of times for a climo table that uses year and
month columns to build DataTimes.
"""
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
req.setLocationNames('KOMA', 'KABR', 'KDMO')
req.setParameters('maxtemp_mon', 'min_sea_press')
self.runTimesTest(req)
def testGetAvailableTimesWithLocationNamesForYearDayOfYear(self):
"""
Test retrieval of times for a climo table that uses year and
day_of_year columns to build DataTimes.
"""
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_daily')
req.setLocationNames('KOMA', 'KABR', 'KDMO')
req.setParameters('maxtemp_cal', 'min_press')
self.runTimesTest(req)
def testGetAvailableTimesWithLocationNamesForPeriod(self):
"""
Test retrieval of times for a climo table that uses
period_start and period_end columns to build DataTimes.
"""
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_mon_season_yr')
req.setLocationNames('KOMA', 'KABR', 'KDMO')
req.setParameters('max_temp', 'precip_total')
self.runTimesTest(req)
def testGetAvailableTimesWithLocationNamesForDate(self):
"""
Test retrieval of times for a climo table that uses a date
column to build DataTimes.
"""
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.daily_climate')
req.setLocationNames('KOMA', 'KABR', 'KDMO')
req.setParameters('max_temp', 'precip', 'avg_wind_speed')
self.runTimesTest(req)
def testGetAvailableTimesWithConstraint(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
req.addIdentifier('maxtemp_mon', RequestConstraint.new('<', 75))
req.setParameters('maxtemp_mon', 'min_sea_press')
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
req.setLocationNames('KFNB')
req.setParameters('maxtemp_mon', 'min_sea_press')
self.runGeometryDataTest(req)
def testGetGeometryDataForYearAndDayOfYearTable(self):
"""
Test retrieval of data for a climo table that uses year and
day_of_year columns to build DataTimes.
"""
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_daily')
req.setLocationNames('KFNB')
req.setParameters('maxtemp_cal', 'min_press')
self.runGeometryDataTest(req)
def testGetGeometryDataForPeriodTable(self):
"""
Test retrieval of data for a climo table that uses a period_start and
period_end columns to build DataTimes.
"""
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_mon_season_yr')
req.setLocationNames('KFNB')
req.setParameters('max_temp', 'precip_total')
self.runGeometryDataTest(req)
def testGetGeometryDataForDateTable(self):
"""
Test retrieval of data for a climo table that uses a date column to
build DataTimes.
"""
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.daily_climate')
req.setLocationNames('KFNB')
req.setParameters('max_temp', 'precip', 'avg_wind_speed')
self.runGeometryDataTest(req)
def testGetGeometryDataWithShortParameter(self):
"""
Test that a parameter that is stored in Java as a Short is correctly
retrieved as a number.
"""
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'cli_asos_monthly')
req.setParameters('month')
geometryData = self.runGeometryDataTest(req)
for record in geometryData:
self.assertIsNotNone(record.getNumber('month'))
def testGetTableIdentifierValues(self):
self.runGetIdValuesTest(['table'])
def testGetColumnIdValuesWithTable(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
idValues = DAL.getIdentifierValues(req, 'year')
self.assertTrue(hasattr(idValues, '__iter__'))
def testGetColumnIdValuesWithoutTableThrowsException(self):
req = DAL.newDataRequest(self.datatype)
with self.assertRaises(ThriftRequestException):
idValues = DAL.getIdentifierValues(req, 'year')
@unittest.skip('avoid EDEX error')
def testGetColumnIdValuesWithNonexistentTableThrowsException(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'nonexistentjunk')
with self.assertRaises(ThriftRequestException):
idValues = DAL.getIdentifierValues(req, 'year')
@unittest.skip('avoid EDEX error')
def testGetNonexistentColumnIdValuesThrowsException(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
with self.assertRaises(ThriftRequestException):
idValues = DAL.getIdentifierValues(req, 'nonexistentjunk')
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'cli_asos_monthly')
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.setParameters('station_code', 'avg_daily_max')
return self.runGeometryDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('station_code', '=', 'KOMA')
for record in geometryData:
self.assertEqual(record.getString('station_code'), 'KOMA')
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('station_code', '=', u'KOMA')
for record in geometryData:
self.assertEqual(record.getString('station_code'), 'KOMA')
def testGetDataWithEqualsInt(self):
geometryData = self._runConstraintTest('avg_daily_max', '=', 70)
for record in geometryData:
self.assertEqual(record.getNumber('avg_daily_max'), 70)
def testGetDataWithEqualsLong(self):
geometryData = self._runConstraintTest('avg_daily_max', '=', 70L)
for record in geometryData:
self.assertEqual(record.getNumber('avg_daily_max'), 70)
def testGetDataWithEqualsFloat(self):
geometryData = self._runConstraintTest('avg_daily_max', '=', 69.2)
for record in geometryData:
self.assertEqual(round(record.getNumber('avg_daily_max'), 1), 69.2)
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('station_code', '=', None)
self.assertEqual(len(geometryData), 0)
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('station_code', '!=', 'KOMA')
for record in geometryData:
self.assertNotEqual(record.getString('station_code'), 'KOMA')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('station_code', '!=', None)
for record in geometryData:
self.assertNotEqual(record.getType('station_code'), 'NULL')
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('avg_daily_max', '>', 70)
for record in geometryData:
self.assertGreater(record.getNumber('avg_daily_max'), 70)
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('avg_daily_max', '<', 70)
for record in geometryData:
self.assertLess(record.getNumber('avg_daily_max'), 70)
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('avg_daily_max', '>=', 70)
for record in geometryData:
self.assertGreaterEqual(record.getNumber('avg_daily_max'), 70)
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('avg_daily_max', '<=', 70)
for record in geometryData:
self.assertLessEqual(record.getNumber('avg_daily_max'), 70)
def testGetDataWithInTuple(self):
collection = ('KOMA', 'KABR')
geometryData = self._runConstraintTest('station_code', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('station_code'), collection)
def testGetDataWithInList(self):
collection = ['KOMA', 'KABR']
geometryData = self._runConstraintTest('station_code', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('station_code'), collection)
def testGetDataWithInGenerator(self):
collection = ('KOMA', 'KABR')
generator = (item for item in collection)
geometryData = self._runConstraintTest('station_code', 'in', generator)
for record in geometryData:
self.assertIn(record.getString('station_code'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('station_code', 'junk', 'KOMA')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('station_code', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('station_code', 'in', [])
def testGetDataWithTimeRangeWithYearAndMonth1(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
req.setLocationNames('KFNB')
req.setParameters('maxtemp_mon', 'min_sea_press')
startTime = datetime.datetime(2009, 1, 1)
endTime = datetime.datetime(2009, 12, 31)
tr = TimeRange(startTime, endTime)
self.runGeometryDataTestWithTimeRange(req, tr)
def testGetDataWithTimeRangeWithYearAndMonth2(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
req.setLocationNames('KFNB')
req.setParameters('maxtemp_mon', 'min_sea_press')
startTime = datetime.datetime(2008, 1, 1)
endTime = datetime.datetime(2009, 3, 31)
tr = TimeRange(startTime, endTime)
self.runGeometryDataTestWithTimeRange(req, tr)
def testGetDataWithTimeRangeWithYearAndMonth3(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_monthly')
req.setLocationNames('KFNB')
req.setParameters('maxtemp_mon', 'min_sea_press')
startTime = datetime.datetime(2007, 7, 1)
endTime = datetime.datetime(2009, 3, 31)
tr = TimeRange(startTime, endTime)
self.runGeometryDataTestWithTimeRange(req, tr)
def testGetDataWithTimeRangeWithYearAndDayOfYear1(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_daily')
req.setLocationNames('KFNB')
req.setParameters('maxtemp_cal', 'min_press')
startTime = datetime.datetime(2009, 1, 1)
endTime = datetime.datetime(2009, 7, 31)
tr = TimeRange(startTime, endTime)
self.runGeometryDataTestWithTimeRange(req, tr)
def testGetDataWithTimeRangeWithYearAndDayOfYear2(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_daily')
req.setLocationNames('KFNB')
req.setParameters('maxtemp_cal', 'min_press')
startTime = datetime.datetime(2008, 7, 1)
endTime = datetime.datetime(2009, 3, 31)
tr = TimeRange(startTime, endTime)
self.runGeometryDataTestWithTimeRange(req, tr)
def testGetDataWithTimeRangeWithYearAndDayOfYear3(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_asos_daily')
req.setLocationNames('KFNB')
req.setParameters('maxtemp_cal', 'min_press')
startTime = datetime.datetime(2007, 7, 1)
endTime = datetime.datetime(2009, 3, 31)
tr = TimeRange(startTime, endTime)
self.runGeometryDataTestWithTimeRange(req, tr)
def testGetDataWithTimeRangeWithPeriodTable(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.cli_mon_season_yr')
req.setLocationNames('KFNB')
req.setParameters('max_temp', 'precip_total')
startTime = datetime.datetime(2007, 7, 1)
endTime = datetime.datetime(2009, 3, 31)
tr = TimeRange(startTime, endTime)
self.runGeometryDataTestWithTimeRange(req, tr)
def testGetDataWithTimeRangeWithForDateTable(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.daily_climate')
req.setLocationNames('KFNB')
req.setParameters('max_temp', 'precip', 'avg_wind_speed')
startTime = datetime.datetime(2007, 7, 1)
endTime = datetime.datetime(2009, 3, 31)
tr = TimeRange(startTime, endTime)
self.runGeometryDataTestWithTimeRange(req, tr)

View file

@ -0,0 +1,67 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from awips.dataaccess import DataAccessLayer as DAL
from awips.dataaccess import CombinedTimeQuery as CTQ
import unittest
import os
#
# Test the CombinedTimedQuery module
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 06/24/16 5591 bsteffen Initial Creation.
# 11/08/16 5895 tgurney Change grid model
#
#
#
class CombinedTimeQueryTestCase(unittest.TestCase):
@classmethod
def setUp(cls):
host = os.environ.get('DAF_TEST_HOST')
if host is None:
host = 'localhost'
DAL.changeEDEXHost(host)
def testSuccessfulQuery(self):
req = DAL.newDataRequest('grid')
req.setLocationNames('RUC130')
req.setParameters('T','GH')
req.setLevels('300MB', '500MB','700MB')
times = CTQ.getAvailableTimes(req);
self.assertNotEqual(len(times), 0)
def testNonIntersectingQuery(self):
"""
Test that when a parameter is only available on one of the levels that no times are returned.
"""
req = DAL.newDataRequest('grid')
req.setLocationNames('RUC130')
req.setParameters('T','GH', 'LgSP1hr')
req.setLevels('300MB', '500MB','700MB','0.0SFC')
times = CTQ.getAvailableTimes(req);
self.assertEqual(len(times), 0)

View file

@ -0,0 +1,179 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from shapely.geometry import box
from awips.dataaccess import DataAccessLayer as DAL
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
import baseDafTestCase
import unittest
#
# Test DAF support for common_obs_spatial data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 05/26/16 5587 njensen Added testGetIdentifierValues()
# 06/01/16 5587 tgurney Move testIdentifiers() to
# superclass
# 06/13/16 5574 tgurney Add advanced query tests
# 06/21/16 5548 tgurney Skip tests that cause errors
#
class CommonObsSpatialTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for common_obs_spatial data"""
datatype = "common_obs_spatial"
envelope = box(-97.0, 41.0, -96.0, 42.0)
"""Default request area (box around KOAX)"""
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("country", ["US", "CN"])
self.runLocationsTest(req)
def testGetIdentifierValues(self):
self.runGetIdValuesTest(['country'])
@unittest.skip('avoid EDEX error')
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
@unittest.skip('avoid EDEX error')
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setEnvelope(self.envelope)
req.setParameters("name", "stationid")
self.runGeometryDataTest(req)
def testRequestingTimesThrowsTimeAgnosticDataException(self):
req = DAL.newDataRequest(self.datatype)
self.runTimeAgnosticTest(req)
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.setParameters('catalogtype', 'elevation', 'state')
return self.runGeometryDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('state', '=', 'NE')
for record in geometryData:
self.assertEqual(record.getString('state'), 'NE')
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('state', '=', u'NE')
for record in geometryData:
self.assertEqual(record.getString('state'), 'NE')
def testGetDataWithEqualsInt(self):
geometryData = self._runConstraintTest('catalogtype', '=', 32)
for record in geometryData:
self.assertEqual(record.getNumber('catalogtype'), 32)
def testGetDataWithEqualsLong(self):
geometryData = self._runConstraintTest('elevation', '=', 0L)
for record in geometryData:
self.assertEqual(record.getNumber('elevation'), 0)
# No float test since there are no float identifiers available. Attempting
# to filter a non-float identifier on a float value raises an exception.
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('state', '=', None)
for record in geometryData:
self.assertEqual(record.getType('state'), 'NULL')
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('state', '!=', 'NE')
for record in geometryData:
self.assertNotEqual(record.getString('state'), 'NE')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('state', '!=', None)
for record in geometryData:
self.assertNotEqual(record.getType('state'), 'NULL')
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('elevation', '>', 500)
for record in geometryData:
self.assertGreater(record.getNumber('elevation'), 500)
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('elevation', '<', 100)
for record in geometryData:
self.assertLess(record.getNumber('elevation'), 100)
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('elevation', '>=', 500)
for record in geometryData:
self.assertGreaterEqual(record.getNumber('elevation'), 500)
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('elevation', '<=', 100)
for record in geometryData:
self.assertLessEqual(record.getNumber('elevation'), 100)
def testGetDataWithInTuple(self):
collection = ('NE', 'TX')
geometryData = self._runConstraintTest('state', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('state'), collection)
def testGetDataWithInList(self):
collection = ['NE', 'TX']
geometryData = self._runConstraintTest('state', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('state'), collection)
def testGetDataWithInGenerator(self):
collection = ('NE', 'TX')
generator = (item for item in collection)
geometryData = self._runConstraintTest('state', 'in', generator)
for record in geometryData:
self.assertIn(record.getString('state'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('state', 'junk', 'NE')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('state', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('state', 'in', [])

View file

@ -0,0 +1,98 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
import baseDafTestCase
import unittest
#
# Test DAF support for ffmp data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 04/18/16 5587 tgurney Add test for sane handling of
# zero records returned
# 06/20/16 5587 tgurney Add identifier values tests
# 11/08/16 5985 tgurney Do not check data times
#
#
class FfmpTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for ffmp data"""
datatype = "ffmp"
@staticmethod
def addIdentifiers(req):
req.addIdentifier("wfo", "OAX")
req.addIdentifier("siteKey", "hpe")
req.addIdentifier("dataKey", "hpe")
req.addIdentifier("huc", "ALL")
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.addIdentifiers(req)
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
self.addIdentifiers(req)
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
self.addIdentifiers(req)
req.setParameters("PRTM")
self.runGeometryDataTest(req, checkDataTimes=False)
def testGetGeometryDataEmptyResult(self):
req = DAL.newDataRequest(self.datatype)
self.addIdentifiers(req)
req.setParameters("blah blah blah") # force 0 records returned
result = self.runGeometryDataTest(req, checkDataTimes=False)
self.assertEqual(len(result), 0)
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
requiredIds = set(DAL.getRequiredIdentifiers(req))
ids = requiredIds | optionalIds
# These two not yet supported
ids.remove('huc')
ids.remove('accumHrs')
self.runGetIdValuesTest(ids)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()

View file

@ -0,0 +1,196 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
from awips.dataaccess import DataAccessLayer as DAL
import baseDafTestCase
import unittest
#
# Test DAF support for GFE data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 05/23/16 5637 bsteffen Test vectors
# 05/31/16 5587 tgurney Add getIdentifierValues tests
# 06/01/16 5587 tgurney Update testGetIdentifierValues
# 06/17/16 5574 mapeters Add advanced query tests
# 11/07/16 5991 bsteffen Improve vector tests
#
#
class GfeTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for GFE data"""
datatype = 'gfe'
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('modelName', 'Fcst')
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('modelName', 'Fcst')
req.addIdentifier('siteId', 'OAX')
self.runTimesTest(req)
def testGetGridData(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('modelName', 'Fcst')
req.addIdentifier('siteId', 'OAX')
req.setParameters('T')
self.runGridDataTest(req)
def testGetVectorGridData(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('modelName', 'Fcst')
req.addIdentifier('siteId', 'OAX')
req.setParameters('Wind')
times = DAL.getAvailableTimes(req)
if not(times):
raise unittest.SkipTest('No Wind Data available for testing')
gridData = DAL.getGridData(req, [times[0]])
rawWind = None
rawDir = None
for grid in gridData:
if grid.getParameter() == 'Wind':
self.assertEqual(grid.getUnit(),'kts')
rawWind = grid.getRawData()
elif grid.getParameter() == 'WindDirection':
self.assertEqual(grid.getUnit(),'deg')
rawDir = grid.getRawData()
self.assertIsNotNone(rawWind, 'Wind Magnitude grid is not present')
self.assertIsNotNone(rawDir, 'Wind Direction grid is not present')
# rawWind and rawDir are numpy.ndarrays so comparison will result in boolean ndarrays.
self.assertTrue((rawWind >= 0).all(), 'Wind Speed should not contain negative values')
self.assertTrue((rawDir >= 0).all(), 'Wind Direction should not contain negative values')
self.assertTrue((rawDir <= 360).all(), 'Wind Direction should be less than or equal to 360')
self.assertFalse((rawDir == rawWind).all(), 'Wind Direction should be different from Wind Speed')
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
requiredIds = set(DAL.getRequiredIdentifiers(req))
self.runGetIdValuesTest(optionalIds | requiredIds)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.setLocationNames('OAX')
req.setParameters('T')
return self.runGridDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('modelName', '=', 'Fcst')
for record in geometryData:
self.assertEqual(record.getAttribute('modelName'), 'Fcst')
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('modelName', '=', u'Fcst')
for record in geometryData:
self.assertEqual(record.getAttribute('modelName'), 'Fcst')
# No numeric tests since no numeric identifiers are available.
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('modelName', '=', None)
for record in geometryData:
self.assertIsNone(record.getAttribute('modelName'))
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('modelName', '!=', 'Fcst')
for record in geometryData:
self.assertNotEqual(record.getAttribute('modelName'), 'Fcst')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('modelName', '!=', None)
for record in geometryData:
self.assertIsNotNone(record.getAttribute('modelName'))
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('modelName', '>', 'Fcst')
for record in geometryData:
self.assertGreater(record.getAttribute('modelName'), 'Fcst')
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('modelName', '<', 'Fcst')
for record in geometryData:
self.assertLess(record.getAttribute('modelName'), 'Fcst')
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('modelName', '>=', 'Fcst')
for record in geometryData:
self.assertGreaterEqual(record.getAttribute('modelName'), 'Fcst')
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('modelName', '<=', 'Fcst')
for record in geometryData:
self.assertLessEqual(record.getAttribute('modelName'), 'Fcst')
def testGetDataWithInTuple(self):
collection = ('Fcst', 'SAT')
geometryData = self._runConstraintTest('modelName', 'in', collection)
for record in geometryData:
self.assertIn(record.getAttribute('modelName'), collection)
def testGetDataWithInList(self):
collection = ['Fcst', 'SAT']
geometryData = self._runConstraintTest('modelName', 'in', collection)
for record in geometryData:
self.assertIn(record.getAttribute('modelName'), collection)
def testGetDataWithInGenerator(self):
collection = ('Fcst', 'SAT')
generator = (item for item in collection)
geometryData = self._runConstraintTest('modelName', 'in', generator)
for record in geometryData:
self.assertIn(record.getAttribute('modelName'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('modelName', 'junk', 'Fcst')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('modelName', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('modelName', 'in', [])

View file

@ -0,0 +1,123 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from shapely.geometry import box, Point
from awips.dataaccess import DataAccessLayer as DAL
import baseDafTestCase
import unittest
#
# Test DAF support for grid data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 06/09/16 5587 tgurney Typo in id values test
# 10/13/16 5942 bsteffen Test envelopes
# 11/08/16 5985 tgurney Skip certain tests when no
# data is available
#
class GridTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for grid data"""
datatype = "grid"
model = "GFS160"
envelope = box(-97.0, 41.0, -96.0, 42.0)
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("info.datasetId", self.model)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("info.datasetId", self.model)
self.runLocationsTest(req)
def testGetAvailableLevels(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("info.datasetId", self.model)
self.runLevelsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("info.datasetId", self.model)
req.setLevels("2FHAG")
self.runTimesTest(req)
def testGetGridData(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("info.datasetId", self.model)
req.setLevels("2FHAG")
req.setParameters("T")
self.runGridDataTest(req)
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("info.datasetId", 'ENSEMBLE')
req.setLevels("2FHAG")
req.setParameters("T")
idValues = DAL.getIdentifierValues(req, 'info.ensembleId')
self.assertTrue(hasattr(idValues, '__iter__'))
if idValues:
self.assertIn('ctl1', idValues)
self.assertIn('p1', idValues)
self.assertIn('n1', idValues)
else:
raise unittest.SkipTest("no data available")
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def testGetDataWithEnvelope(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('info.datasetId', self.model)
req.setLevels('2FHAG')
req.setParameters('T')
req.setEnvelope(self.envelope)
gridData = self.runGridDataTest(req)
if not gridData:
raise unittest.SkipTest('no data available')
lons, lats = gridData[0].getLatLonCoords()
lons = lons.reshape(-1)
lats = lats.reshape(-1)
# Ensure all points are within one degree of the original box
# to allow slight margin of error for reprojection distortion.
testEnv = box(self.envelope.bounds[0] - 1, self.envelope.bounds[1] - 1,
self.envelope.bounds[2] + 1, self.envelope.bounds[3] + 1 )
for i in range(len(lons)):
self.assertTrue(testEnv.contains(Point(lons[i], lats[i])))

View file

@ -0,0 +1,261 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
import datetime
from awips.dataaccess import DataAccessLayer as DAL
from awips.ThriftClient import ThriftRequestException
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
import baseDafTestCase
import unittest
#
# Test DAF support for hydro data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 04/21/16 5596 tgurney Add tests to verify #5596
# 04/26/16 5587 tgurney Add identifier values tests
# 06/09/16 5574 tgurney Add advanced query tests
# 06/13/16 5574 tgurney Fix checks for None
# 06/21/16 5548 tgurney Skip tests that cause errors
# 10/06/16 5926 dgilling Add additional location tests.
#
#
class HydroTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for hydro data"""
datatype = 'hydro'
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'height')
self.runParametersTest(req)
def testGetAvailableParametersFullyQualifiedTable(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'public.height')
self.runParametersTest(req)
def testGetAvailableParamsNoTableThrowsInvalidIdentifiersException(self):
req = DAL.newDataRequest(self.datatype)
with self.assertRaises(ThriftRequestException) as cm:
self.runParametersTest(req)
self.assertIn('InvalidIdentifiersException', str(cm.exception))
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'height')
self.runLocationsTest(req)
def testGetAvailableLocationsWithConstraint(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'height')
req.addIdentifier('value', RequestConstraint.new('>', 5.0))
self.runLocationsTest(req)
def testGetAvailableLocationsWithInvalidTable(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'city')
with self.assertRaises(ThriftRequestException) as cm:
DAL.getAvailableLocationNames(req)
self.assertIn('IncompatibleRequestException', str(cm.exception))
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'height')
req.setParameters('lid', 'quality_code')
self.runTimesTest(req)
def testGetGeometryDataWithoutLocationSpecified(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'height')
req.setParameters('lid', 'quality_code')
self.runGeometryDataTest(req)
def testGetGeometryDataWithLocationSpecified(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'fcstheight')
locs = DAL.getAvailableLocationNames(req)
if locs:
req.setLocationNames(locs[0])
req.setParameters('probability', 'value')
data = self.runGeometryDataTest(req)
self.assertNotEqual(len(data), 0)
def testGetTableIdentifierValues(self):
self.runGetIdValuesTest(['table'])
def testGetColumnIdValuesWithTable(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'height')
idValues = DAL.getIdentifierValues(req, 'lid')
self.assertTrue(hasattr(idValues, '__iter__'))
@unittest.skip('avoid EDEX error')
def testGetColumnIdValuesWithNonexistentTableThrowsException(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'nonexistentjunk')
with self.assertRaises(ThriftRequestException):
idValues = DAL.getIdentifierValues(req, 'lid')
def testGetColumnIdValuesWithoutTableThrowsException(self):
req = DAL.newDataRequest(self.datatype)
with self.assertRaises(ThriftRequestException):
idValues = DAL.getIdentifierValues(req, 'lid')
@unittest.skip('avoid EDEX error')
def testGetNonexistentColumnIdValuesThrowsException(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'height')
with self.assertRaises(ThriftRequestException):
idValues = DAL.getIdentifierValues(req, 'nonexistentjunk')
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.addIdentifier('table', 'height')
req.addIdentifier('ts', 'RG')
req.setParameters('value', 'lid', 'quality_code')
return self.runGeometryDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('value', '=', '3')
for record in geometryData:
self.assertEqual(record.getNumber('value'), 3)
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('value', '=', u'3')
for record in geometryData:
self.assertEqual(record.getNumber('value'), 3)
def testGetDataWithEqualsInt(self):
geometryData = self._runConstraintTest('value', '=', 3)
for record in geometryData:
self.assertEqual(record.getNumber('value'), 3)
def testGetDataWithEqualsLong(self):
geometryData = self._runConstraintTest('value', '=', 3L)
for record in geometryData:
self.assertEqual(record.getNumber('value'), 3L)
def testGetDataWithEqualsFloat(self):
geometryData = self._runConstraintTest('value', '=', 3.0)
for record in geometryData:
self.assertEqual(round(record.getNumber('value'), 1), 3.0)
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('value', '=', None)
self.assertEqual(len(geometryData), 0)
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('value', '!=', 3)
for record in geometryData:
self.assertNotEqual(record.getNumber('value'), '3')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('value', '!=', None)
self.assertNotEqual(len(geometryData), 0)
for record in geometryData:
self.assertNotEqual(record.getType('value'), 'NULL')
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('value', '>', 3)
for record in geometryData:
self.assertGreater(record.getNumber('value'), 3)
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('value', '<', 3)
for record in geometryData:
self.assertLess(record.getNumber('value'), 3)
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('value', '>=', 3)
for record in geometryData:
self.assertGreaterEqual(record.getNumber('value'), 3)
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('value', '<=', 3)
for record in geometryData:
self.assertLessEqual(record.getNumber('value'), 3)
def testGetDataWithInTuple(self):
collection = (3, 4)
geometryData = self._runConstraintTest('value', 'in', collection)
for record in geometryData:
self.assertIn(record.getNumber('value'), collection)
def testGetDataWithInList(self):
collection = [3, 4]
geometryData = self._runConstraintTest('value', 'in', collection)
for record in geometryData:
self.assertIn(record.getNumber('value'), collection)
def testGetDataWithInGenerator(self):
collection = (3, 4)
generator = (item for item in collection)
geometryData = self._runConstraintTest('value', 'in', generator)
for record in geometryData:
self.assertIn(record.getNumber('value'), collection)
def testGetDataWithTimeRange(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'height')
req.addIdentifier('ts', 'RG')
req.setParameters('value', 'lid', 'quality_code')
times = DAL.getAvailableTimes(req)
limitTimes = times[-self.numTimesToLimit:]
startTime = datetime.datetime.utcfromtimestamp(limitTimes[0].getRefTime().getTime()/1000)
endTime = datetime.datetime.utcnow()
tr = TimeRange(startTime, endTime)
self.runGeometryDataTestWithTimeRange(req, tr)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('value', 'junk', 3)
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('value', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('value', 'in', [])
def testGetDataWithNestedInConstraintThrowsException(self):
collection = ('3', '4', ())
with self.assertRaises(TypeError):
self._runConstraintTest('value', 'in', collection)

View file

@ -0,0 +1,77 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from shapely.geometry import Polygon
from awips.dataaccess import DataAccessLayer as DAL
import baseDafTestCase
import unittest
#
# Test DAF support for ldadmesonet data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
#
#
class LdadMesonetTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for ldadmesonet data"""
datatype = "ldadmesonet"
envelope = None
@classmethod
def getReqEnvelope(cls):
# Restrict the output to only records with latitude and
# longitude between -30 and 30.
if not cls.envelope:
vertices = [(-30, -30), (-30, 30), (30, 30), (30, -30)]
polygon = Polygon(vertices)
cls.envelope = polygon.envelope
return cls.envelope
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
req.setEnvelope(self.getReqEnvelope())
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.setEnvelope(self.getReqEnvelope())
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setParameters("highLevelCloud", "pressure")
req.setEnvelope(self.getReqEnvelope())
self.runGeometryDataTest(req)

View file

@ -0,0 +1,227 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
from awips.dataaccess import DataAccessLayer as DAL
from awips.ThriftClient import ThriftRequestException
import baseDafTestCase
import unittest
#
# Test DAF support for maps data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 04/26/16 5587 tgurney Add identifier values tests
# 06/13/16 5574 mapeters Add advanced query tests
# 06/21/16 5548 tgurney Skip tests that cause errors
#
#
class MapsTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for maps data"""
datatype = 'maps'
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'mapdata.county')
req.addIdentifier('geomField', 'the_geom')
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'mapdata.county')
req.addIdentifier('geomField', 'the_geom')
req.addIdentifier('locationField', 'cwa')
self.runLocationsTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'mapdata.county')
req.addIdentifier('geomField', 'the_geom')
req.addIdentifier('inLocation', 'true')
req.addIdentifier('locationField', 'cwa')
req.setLocationNames('OAX')
req.addIdentifier('cwa', 'OAX')
req.setParameters('countyname', 'state', 'fips')
self.runGeometryDataTest(req)
def testRequestingTimesThrowsTimeAgnosticDataException(self):
req = DAL.newDataRequest(self.datatype)
self.runTimeAgnosticTest(req)
def testGetTableIdentifierValues(self):
self.runGetIdValuesTest(['table'])
def testGetGeomFieldIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'mapdata.county')
idValues = DAL.getIdentifierValues(req, 'geomField')
for idValue in idValues:
self.assertTrue(idValue.startswith('the_geom'))
def testGetGeomFieldIdValuesWithoutTableThrowsException(self):
with self.assertRaises(ThriftRequestException):
self.runGetIdValuesTest(['geomField'])
def testGetColumnIdValuesWithTable(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'mapdata.county')
req.addIdentifier('geomField', 'the_geom')
idValues = DAL.getIdentifierValues(req, 'state')
self.assertIn('NE', idValues)
def testGetColumnIdValuesWithoutTableThrowsException(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('geomField', 'the_geom')
with self.assertRaises(ThriftRequestException):
idValues = DAL.getIdentifierValues(req, 'state')
@unittest.skip('avoid EDEX error')
def testGetColumnIdValuesWithNonexistentTableThrowsException(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'mapdata.nonexistentjunk')
req.addIdentifier('geomField', 'the_geom')
with self.assertRaises(ThriftRequestException):
idValues = DAL.getIdentifierValues(req, 'state')
@unittest.skip('avoid EDEX error')
def testGetNonexistentColumnIdValuesThrowsException(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'mapdata.county')
req.addIdentifier('geomField', 'the_geom')
with self.assertRaises(ThriftRequestException):
idValues = DAL.getIdentifierValues(req, 'nonexistentjunk')
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('table', 'mapdata.ffmp_basins')
req.addIdentifier('geomField', 'the_geom')
req.addIdentifier('cwa', 'OAX')
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.setParameters('state', 'reservoir', 'area_sq_mi')
return self.runGeometryDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('state', '=', 'NE')
for record in geometryData:
self.assertEqual(record.getString('state'), 'NE')
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('state', '=', u'NE')
for record in geometryData:
self.assertEqual(record.getString('state'), 'NE')
def testGetDataWithEqualsInt(self):
geometryData = self._runConstraintTest('reservoir', '=', 1)
for record in geometryData:
self.assertEqual(record.getNumber('reservoir'), 1)
def testGetDataWithEqualsLong(self):
geometryData = self._runConstraintTest('reservoir', '=', 1L)
for record in geometryData:
self.assertEqual(record.getNumber('reservoir'), 1)
def testGetDataWithEqualsFloat(self):
geometryData = self._runConstraintTest('area_sq_mi', '=', 5.00)
for record in geometryData:
self.assertEqual(round(record.getNumber('area_sq_mi'), 2), 5.00)
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('state', '=', None)
for record in geometryData:
self.assertEqual(record.getType('state'), 'NULL')
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('state', '!=', 'NE')
for record in geometryData:
self.assertNotEqual(record.getString('state'), 'NE')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('state', '!=', None)
for record in geometryData:
self.assertNotEqual(record.getType('state'), 'NULL')
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('area_sq_mi', '>', 5)
for record in geometryData:
self.assertGreater(record.getNumber('area_sq_mi'), 5)
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('area_sq_mi', '<', 5)
for record in geometryData:
self.assertLess(record.getNumber('area_sq_mi'), 5)
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('area_sq_mi', '>=', 5)
for record in geometryData:
self.assertGreaterEqual(record.getNumber('area_sq_mi'), 5)
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('area_sq_mi', '<=', 5)
for record in geometryData:
self.assertLessEqual(record.getNumber('area_sq_mi'), 5)
def testGetDataWithInTuple(self):
collection = ('NE', 'TX')
geometryData = self._runConstraintTest('state', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('state'), collection)
def testGetDataWithInList(self):
collection = ['NE', 'TX']
geometryData = self._runConstraintTest('state', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('state'), collection)
def testGetDataWithInGenerator(self):
collection = ('NE', 'TX')
generator = (item for item in collection)
geometryData = self._runConstraintTest('state', 'in', generator)
for record in geometryData:
self.assertIn(record.getString('state'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('state', 'junk', 'NE')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('state', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('state', 'in', [])

View file

@ -0,0 +1,209 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
import baseDafTestCase
import unittest
#
# Test DAF support for modelsounding data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 06/09/16 5587 bsteffen Add getIdentifierValues tests
# 06/13/16 5574 tgurney Add advanced query tests
# 11/10/16 5985 tgurney Mark expected failures prior
# to 17.3.1
#
#
class ModelSoundingTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for modelsounding data"""
datatype = "modelsounding"
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("reportType", "ETA")
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("reportType", "ETA")
req.setLocationNames("KOMA")
self.runTimesTest(req)
@unittest.expectedFailure
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("reportType", "ETA")
req.setLocationNames("KOMA")
req.setParameters("temperature", "pressure", "specHum", "sfcPress", "temp2", "q2")
print("Testing getGeometryData()")
geomData = DAL.getGeometryData(req)
print("Number of geometry records: " + str(len(geomData)))
print("Sample geometry data:")
for record in geomData[:self.sampleDataLimit]:
print("level=" + record.getLevel(), end="")
# One dimensional parameters are reported on the 0.0UNKNOWN level.
# 2D parameters are reported on MB levels from pressure.
if record.getLevel() == "0.0UNKNOWN":
print(" sfcPress=" + record.getString("sfcPress") + record.getUnit("sfcPress"), end="")
print(" temp2=" + record.getString("temp2") + record.getUnit("temp2"), end="")
print(" q2=" + record.getString("q2") + record.getUnit("q2"), end="")
else:
print(" pressure=" + record.getString("pressure") + record.getUnit("pressure"), end="")
print(" temperature=" + record.getString("temperature") + record.getUnit("temperature"), end="")
print(" specHum=" + record.getString("specHum") + record.getUnit("specHum"), end="")
print(" geometry=" + str(record.getGeometry()))
print("getGeometryData() complete\n\n")
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
self.runGetIdValuesTest(optionalIds)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.setParameters('dataURI')
req.setLocationNames('KOMA', 'KORD', 'KOFK', 'KLNK')
req.addIdentifier(key, constraint)
return self.runGeometryDataTest(req)
# We can filter on reportType but it is not possible to retrieve the value
# of reportType directly. We can look inside the dataURI instead.
#
# For cases like '<=' and '>' the best we can do is send the request and
# see if it throws back an exception.
#
# Can also eyeball the number of returned records.
@unittest.expectedFailure
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('reportType', '=', 'ETA')
for record in geometryData:
self.assertIn('/ETA/', record.getString('dataURI'))
@unittest.expectedFailure
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('reportType', '=', u'ETA')
for record in geometryData:
self.assertIn('/ETA/', record.getString('dataURI'))
# No numeric tests since no numeric identifiers are available.
@unittest.expectedFailure
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('reportType', '=', None)
@unittest.expectedFailure
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('reportType', '!=', 'ETA')
for record in geometryData:
self.assertNotIn('/ETA/', record.getString('dataURI'))
@unittest.expectedFailure
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('reportType', '!=', None)
@unittest.expectedFailure
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('reportType', '>', 'ETA')
@unittest.expectedFailure
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('reportType', '<', 'ETA')
@unittest.expectedFailure
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('reportType', '>=', 'ETA')
@unittest.expectedFailure
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('reportType', '<=', 'ETA')
@unittest.expectedFailure
def testGetDataWithInTuple(self):
collection = ('ETA', 'GFS')
geometryData = self._runConstraintTest('reportType', 'in', collection)
for record in geometryData:
dataURI = record.getString('dataURI')
self.assertTrue('/ETA/' in dataURI or '/GFS/' in dataURI)
@unittest.expectedFailure
def testGetDataWithInList(self):
collection = ['ETA', 'GFS']
geometryData = self._runConstraintTest('reportType', 'in', collection)
for record in geometryData:
dataURI = record.getString('dataURI')
self.assertTrue('/ETA/' in dataURI or '/GFS/' in dataURI)
@unittest.expectedFailure
def testGetDataWithInGenerator(self):
collection = ('ETA', 'GFS')
generator = (item for item in collection)
geometryData = self._runConstraintTest('reportType', 'in', generator)
for record in geometryData:
dataURI = record.getString('dataURI')
self.assertTrue('/ETA/' in dataURI or '/GFS/' in dataURI)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('reportType', 'junk', 'ETA')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('reportType', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('reportType', 'in', [])
def testGetDataWithNestedInConstraintThrowsException(self):
collection = ('ETA', 'GFS', ())
with self.assertRaises(TypeError):
self._runConstraintTest('reportType', 'in', collection)

View file

@ -0,0 +1,168 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
import baseDafTestCase
import unittest
#
# Test DAF support for obs data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 06/09/16 5587 bsteffen Add getIdentifierValues tests
# 06/13/16 5574 tgurney Add advanced query tests
#
#
class ObsTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for obs data"""
datatype = "obs"
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames("KOMA")
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames("KOMA")
req.setParameters("temperature", "seaLevelPress", "dewpoint")
self.runGeometryDataTest(req)
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
self.runGetIdValuesTest(optionalIds)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.setParameters("temperature", "reportType")
req.setLocationNames("KOMA")
req.addIdentifier(key, constraint)
return self.runGeometryDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('reportType', '=', 'METAR')
for record in geometryData:
self.assertEqual(record.getString('reportType'), 'METAR')
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('reportType', '=', u'METAR')
for record in geometryData:
self.assertEqual(record.getString('reportType'), 'METAR')
# No numeric tests since no numeric identifiers are available.
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('reportType', '=', None)
for record in geometryData:
self.assertEqual(record.getType('reportType'), 'NULL')
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('reportType', '!=', 'METAR')
for record in geometryData:
self.assertNotEqual(record.getString('reportType'), 'METAR')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('reportType', '!=', None)
for record in geometryData:
self.assertNotEqual(record.getType('reportType'), 'NULL')
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('reportType', '>', 'METAR')
for record in geometryData:
self.assertGreater(record.getString('reportType'), 'METAR')
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('reportType', '<', 'METAR')
for record in geometryData:
self.assertLess(record.getString('reportType'), 'METAR')
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('reportType', '>=', 'METAR')
for record in geometryData:
self.assertGreaterEqual(record.getString('reportType'), 'METAR')
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('reportType', '<=', 'METAR')
for record in geometryData:
self.assertLessEqual(record.getString('reportType'), 'METAR')
def testGetDataWithInTuple(self):
collection = ('METAR', 'SPECI')
geometryData = self._runConstraintTest('reportType', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('reportType'), collection)
def testGetDataWithInList(self):
collection = ['METAR', 'SPECI']
geometryData = self._runConstraintTest('reportType', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('reportType'), collection)
def testGetDataWithInGenerator(self):
collection = ('METAR', 'SPECI')
generator = (item for item in collection)
geometryData = self._runConstraintTest('reportType', 'in', generator)
for record in geometryData:
self.assertIn(record.getString('reportType'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('reportType', 'junk', 'METAR')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('reportType', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('reportType', 'in', [])
def testGetDataWithNestedInConstraintThrowsException(self):
collection = ('METAR', 'SPECI', ())
with self.assertRaises(TypeError):
self._runConstraintTest('reportType', 'in', collection)

View file

@ -0,0 +1,83 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
import baseDafTestCase
import unittest
#
# Test DAF support for pirep data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
#
#
class PirepTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for pirep data"""
datatype = "pirep"
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames('OMA')
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames('OMA')
req.setParameters("temperature", "windSpeed", "hazardType", "turbType")
print("Testing getGeometryData()")
geomData = DAL.getGeometryData(req)
self.assertIsNotNone(geomData)
print("Number of geometry records: " + str(len(geomData)))
print("Sample geometry data:")
for record in geomData[:self.sampleDataLimit]:
print("level=", record.getLevel(), end="")
# One dimensional parameters are reported on the 0.0UNKNOWN level.
# 2D parameters are reported on MB levels from pressure.
if record.getLevel() == "0.0UNKNOWN":
print(" temperature=" + record.getString("temperature") + record.getUnit("temperature"), end="")
print(" windSpeed=" + record.getString("windSpeed") + record.getUnit("windSpeed"), end="")
else:
print(" hazardType=" + record.getString("hazardType"), end="")
print(" turbType=" + record.getString("turbType"), end="")
print(" geometry=", record.getGeometry())
print("getGeometryData() complete\n")

View file

@ -0,0 +1,49 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
import baseDafTestCase
import testWarning
import unittest
#
# Test DAF support for practicewarning data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 06/10/16 5548 tgurney Inherit all tests from
# warning
#
class PracticeWarningTestCase(testWarning.WarningTestCase):
"""Test DAF support for practicewarning data"""
datatype = "practicewarning"
# All tests taken from testWarning

View file

@ -0,0 +1,80 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
import baseDafTestCase
import unittest
#
# Test DAF support for profiler data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
#
#
class ProfilerTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for profiler data"""
datatype = "profiler"
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setParameters("temperature", "pressure", "uComponent", "vComponent")
print("Testing getGeometryData()")
geomData = DAL.getGeometryData(req)
self.assertIsNotNone(geomData)
print("Number of geometry records: " + str(len(geomData)))
print("Sample geometry data:")
for record in geomData[:self.sampleDataLimit]:
print("level:", record.getLevel(), end="")
# One dimensional parameters are reported on the 0.0UNKNOWN level.
# 2D parameters are reported on MB levels from pressure.
if record.getLevel() == "0.0UNKNOWN":
print(" temperature=" + record.getString("temperature") + record.getUnit("temperature"), end="")
print(" pressure=" + record.getString("pressure") + record.getUnit("pressure"), end="")
else:
print(" uComponent=" + record.getString("uComponent") + record.getUnit("uComponent"), end="")
print(" vComponent=" + record.getString("vComponent") + record.getUnit("vComponent"), end="")
print(" geometry:", record.getGeometry())
print("getGeometryData() complete\n\n")

View file

@ -0,0 +1,197 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
from shapely.geometry import box
from awips.dataaccess import DataAccessLayer as DAL
from awips.ThriftClient import ThriftRequestException
import baseDafTestCase
import unittest
#
# Test DAF support for radar data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 04/26/16 5587 tgurney Move identifier values tests
# out of base class
# 06/01/16 5587 tgurney Update testGetIdentifierValues
# 06/08/16 5574 mapeters Add advanced query tests
# 06/13/16 5574 tgurney Fix checks for None
# 06/14/16 5548 tgurney Undo previous change (broke
# test)
#
#
class RadarTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for radar data"""
datatype = 'radar'
envelope = box(-97.0, 41.0, -96.0, 42.0)
"""Request area (box around KOAX)"""
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.runLocationsTest(req)
def testGetAvailableLevels(self):
req = DAL.newDataRequest(self.datatype)
self.runLevelsTest(req)
def testGetAvailableLevelsWithInvalidLevelIdentifierThrowsException(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier('level.one.field', 'invalidLevelField')
with self.assertRaises(ThriftRequestException) as cm:
self.runLevelsTest(req)
self.assertIn('IncompatibleRequestException', str(cm.exception))
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.setEnvelope(self.envelope)
self.runTimesTest(req)
def testGetGridData(self):
req = DAL.newDataRequest(self.datatype)
req.setEnvelope(self.envelope)
req.setLocationNames('koax')
req.setParameters('94')
# Don't test shapes since they may differ.
self.runGridDataTest(req, testSameShape=False)
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
requiredIds = set(DAL.getRequiredIdentifiers(req))
self.runGetIdValuesTest(optionalIds | requiredIds)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.setParameters('94')
# Don't test shapes since they may differ.
return self.runGridDataTest(req, testSameShape=False)
def testGetDataWithEqualsString(self):
gridData = self._runConstraintTest('icao', '=', 'koax')
for record in gridData:
self.assertEqual(record.getAttribute('icao'), 'koax')
def testGetDataWithEqualsUnicode(self):
gridData = self._runConstraintTest('icao', '=', u'koax')
for record in gridData:
self.assertEqual(record.getAttribute('icao'), 'koax')
def testGetDataWithEqualsInt(self):
gridData = self._runConstraintTest('icao', '=', 1000)
for record in gridData:
self.assertEqual(record.getAttribute('icao'), 1000)
def testGetDataWithEqualsLong(self):
gridData = self._runConstraintTest('icao', '=', 1000L)
for record in gridData:
self.assertEqual(record.getAttribute('icao'), 1000)
def testGetDataWithEqualsFloat(self):
gridData = self._runConstraintTest('icao', '=', 1.0)
for record in gridData:
self.assertEqual(round(record.getAttribute('icao'), 1), 1.0)
def testGetDataWithEqualsNone(self):
gridData = self._runConstraintTest('icao', '=', None)
for record in gridData:
self.assertIsNone(record.getAttribute('icao'))
def testGetDataWithNotEquals(self):
gridData = self._runConstraintTest('icao', '!=', 'koax')
for record in gridData:
self.assertNotEqual(record.getAttribute('icao'), 'koax')
def testGetDataWithNotEqualsNone(self):
gridData = self._runConstraintTest('icao', '!=', None)
for record in gridData:
self.assertIsNotNone(record.getAttribute('icao'))
def testGetDataWithGreaterThan(self):
gridData = self._runConstraintTest('icao', '>', 'koax')
for record in gridData:
self.assertGreater(record.getAttribute('icao'), 'koax')
def testGetDataWithLessThan(self):
gridData = self._runConstraintTest('icao', '<', 'koax')
for record in gridData:
self.assertLess(record.getAttribute('icao'), 'koax')
def testGetDataWithGreaterThanEquals(self):
gridData = self._runConstraintTest('icao', '>=', 'koax')
for record in gridData:
self.assertGreaterEqual(record.getAttribute('icao'), 'koax')
def testGetDataWithLessThanEquals(self):
gridData = self._runConstraintTest('icao', '<=', 'koax')
for record in gridData:
self.assertLessEqual(record.getAttribute('icao'), 'koax')
def testGetDataWithInTuple(self):
gridData = self._runConstraintTest('icao', 'in', ('koax', 'tpbi'))
for record in gridData:
self.assertIn(record.getAttribute('icao'), ('koax', 'tpbi'))
def testGetDataWithInList(self):
gridData = self._runConstraintTest('icao', 'in', ['koax', 'tpbi'])
for record in gridData:
self.assertIn(record.getAttribute('icao'), ('koax', 'tpbi'))
def testGetDataWithInGenerator(self):
generator = (item for item in ('koax', 'tpbi'))
gridData = self._runConstraintTest('icao', 'in', generator)
for record in gridData:
self.assertIn(record.getAttribute('icao'), ('koax', 'tpbi'))
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('icao', 'junk', 'koax')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('icao', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('icao', 'in', [])

View file

@ -0,0 +1,175 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from shapely.geometry import box
from awips.dataaccess import DataAccessLayer as DAL
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
import baseDafTestCase
import unittest
#
# Test DAF support for radar_spatial data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 05/26/16 5587 njensen Added testGetIdentifierValues()
# 06/01/16 5587 tgurney Move testIdentifiers() to
# superclass
# 06/13/16 5574 tgurney Add advanced query tests
#
#
class RadarSpatialTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for radar_spatial data"""
datatype = "radar_spatial"
envelope = box(-97.0, 41.0, -96.0, 42.0)
"""
Default request area (box around KOAX)
"""
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
req.setEnvelope(self.envelope)
self.runLocationsTest(req)
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetIdentifierValues(self):
self.runGetIdValuesTest(['wfo_id'])
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames("TORD", "TMDW")
req.setParameters("wfo_id", "name", "elevmeter")
self.runGeometryDataTest(req)
def testRequestingTimesThrowsTimeAgnosticDataException(self):
req = DAL.newDataRequest(self.datatype)
self.runTimeAgnosticTest(req)
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.setParameters('elevmeter', 'eqp_elv', 'wfo_id', 'immutablex')
return self.runGeometryDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('wfo_id', '=', 'OAX')
for record in geometryData:
self.assertEqual(record.getString('wfo_id'), 'OAX')
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('wfo_id', '=', u'OAX')
for record in geometryData:
self.assertEqual(record.getString('wfo_id'), 'OAX')
def testGetDataWithEqualsInt(self):
geometryData = self._runConstraintTest('immutablex', '=', 57)
for record in geometryData:
self.assertEqual(record.getNumber('immutablex'), 57)
def testGetDataWithEqualsLong(self):
geometryData = self._runConstraintTest('immutablex', '=', 57L)
for record in geometryData:
self.assertEqual(record.getNumber('immutablex'), 57)
def testGetDataWithEqualsFloat(self):
geometryData = self._runConstraintTest('immutablex', '=', 57.0)
for record in geometryData:
self.assertEqual(round(record.getNumber('immutablex'), 1), 57.0)
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('wfo_id', '=', None)
for record in geometryData:
self.assertEqual(record.getType('wfo_id'), 'NULL')
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('wfo_id', '!=', 'OAX')
for record in geometryData:
self.assertNotEquals(record.getString('wfo_id'), 'OAX')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('wfo_id', '!=', None)
for record in geometryData:
self.assertNotEqual(record.getType('wfo_id'), 'NULL')
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('elevmeter', '>', 1000)
for record in geometryData:
self.assertGreater(record.getNumber('elevmeter'), 1000)
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('elevmeter', '<', 1000)
for record in geometryData:
self.assertLess(record.getNumber('elevmeter'), 1000)
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('eqp_elv', '>=', 1295)
for record in geometryData:
self.assertGreaterEqual(record.getNumber('eqp_elv'), 1295)
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('eqp_elv', '<=', 138)
for record in geometryData:
self.assertLessEqual(record.getNumber('eqp_elv'), 138)
def testGetDataWithInTuple(self):
collection = ('OAX', 'GID')
geometryData = self._runConstraintTest('wfo_id', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('wfo_id'), collection)
def testGetDataWithInList(self):
collection = ['OAX', 'GID']
geometryData = self._runConstraintTest('wfo_id', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('wfo_id'), collection)
def testGetDataWithInGenerator(self):
collection = ('OAX', 'GID')
generator = (item for item in collection)
geometryData = self._runConstraintTest('wfo_id', 'in', generator)
for record in geometryData:
self.assertIn(record.getString('wfo_id'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('wfo_id', 'junk', 'OAX')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('wfo_id', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('wfo_id', 'in', [])

View file

@ -0,0 +1,186 @@
#!/usr/bin/env python
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
import baseDafTestCase
import unittest
#
# Test DAF support for satellite data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 04/26/16 5587 tgurney Move identifier values tests
# out of base class
# 06/01/16 5587 tgurney Update testGetIdentifierValues
# 06/07/16 5574 tgurney Add advanced query tests
# 06/13/16 5574 tgurney Typo
#
#
class SatelliteTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for satellite data"""
datatype = "satellite"
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames("West CONUS")
self.runTimesTest(req)
def testGetGridData(self):
req = DAL.newDataRequest(self.datatype)
req.setParameters("Imager 11 micron IR")
req.setLocationNames("West CONUS")
self.runGridDataTest(req)
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
requiredIds = set(DAL.getRequiredIdentifiers(req))
self.runGetIdValuesTest(optionalIds | requiredIds)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.setParameters("Imager 11 micron IR")
req.setLocationNames("West CONUS")
return self.runGridDataTest(req)
def testGetDataWithEqualsString(self):
gridData = self._runConstraintTest('creatingEntity', '=', 'Composite')
for record in gridData:
self.assertEqual(record.getAttribute('creatingEntity'), 'Composite')
def testGetDataWithEqualsUnicode(self):
gridData = self._runConstraintTest('creatingEntity', '=', u'Composite')
for record in gridData:
self.assertEqual(record.getAttribute('creatingEntity'), 'Composite')
def testGetDataWithEqualsInt(self):
gridData = self._runConstraintTest('creatingEntity', '=', 1000)
for record in gridData:
self.assertEqual(record.getAttribute('creatingEntity'), 1000)
def testGetDataWithEqualsLong(self):
gridData = self._runConstraintTest('creatingEntity', '=', 1000L)
for record in gridData:
self.assertEqual(record.getAttribute('creatingEntity'), 1000)
def testGetDataWithEqualsFloat(self):
gridData = self._runConstraintTest('creatingEntity', '=', 1.0)
for record in gridData:
self.assertEqual(round(record.getAttribute('creatingEntity'), 1), 1.0)
def testGetDataWithEqualsNone(self):
gridData = self._runConstraintTest('creatingEntity', '=', None)
for record in gridData:
self.assertIsNone(record.getAttribute('creatingEntity'))
def testGetDataWithNotEquals(self):
gridData = self._runConstraintTest('creatingEntity', '!=', 'Composite')
for record in gridData:
self.assertNotEqual(record.getAttribute('creatingEntity'), 'Composite')
def testGetDataWithNotEqualsNone(self):
gridData = self._runConstraintTest('creatingEntity', '!=', None)
for record in gridData:
self.assertIsNotNone(record.getAttribute('creatingEntity'))
def testGetDataWithGreaterThan(self):
gridData = self._runConstraintTest('creatingEntity', '>', 'Composite')
for record in gridData:
self.assertGreater(record.getAttribute('creatingEntity'), 'Composite')
def testGetDataWithLessThan(self):
gridData = self._runConstraintTest('creatingEntity', '<', 'Composite')
for record in gridData:
self.assertLess(record.getAttribute('creatingEntity'), 'Composite')
def testGetDataWithGreaterThanEquals(self):
gridData = self._runConstraintTest('creatingEntity', '>=', 'Composite')
for record in gridData:
self.assertGreaterEqual(record.getAttribute('creatingEntity'), 'Composite')
def testGetDataWithLessThanEquals(self):
gridData = self._runConstraintTest('creatingEntity', '<=', 'Composite')
for record in gridData:
self.assertLessEqual(record.getAttribute('creatingEntity'), 'Composite')
def testGetDataWithInTuple(self):
collection = ('Composite', 'Miscellaneous')
gridData = self._runConstraintTest('creatingEntity', 'in', collection)
for record in gridData:
self.assertIn(record.getAttribute('creatingEntity'), collection)
def testGetDataWithInList(self):
collection = ('Composite', 'Miscellaneous')
gridData = self._runConstraintTest('creatingEntity', 'in', collection)
for record in gridData:
self.assertIn(record.getAttribute('creatingEntity'), collection)
def testGetDataWithInGenerator(self):
collection = ('Composite', 'Miscellaneous')
generator = (item for item in collection)
gridData = self._runConstraintTest('creatingEntity', 'in', generator)
for record in gridData:
self.assertIn(record.getAttribute('creatingEntity'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('creatingEntity', 'junk', 'Composite')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('creatingEntity', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('creatingEntity', 'in', [])
def testGetDataWithNestedInConstraintThrowsException(self):
collection = ('Composite', 'Miscellaneous', ())
with self.assertRaises(TypeError):
self._runConstraintTest('creatingEntity', 'in', collection)

View file

@ -0,0 +1,177 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
import baseDafTestCase
import unittest
#
# Test DAF support for sfcobs data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 06/09/16 5587 bsteffen Add getIdentifierValues tests
# 06/13/16 5574 tgurney Add advanced query tests
#
#
class SfcObsTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for sfcobs data"""
datatype = "sfcobs"
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames("14547")
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setLocationNames("14547")
req.setParameters("temperature", "seaLevelPress", "dewpoint")
self.runGeometryDataTest(req)
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
self.runGetIdValuesTest(optionalIds)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.setParameters("temperature", "reportType")
return self.runGeometryDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('reportType', '=', '1004')
for record in geometryData:
self.assertEqual(record.getString('reportType'), '1004')
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('reportType', '=', u'1004')
for record in geometryData:
self.assertEqual(record.getString('reportType'), '1004')
def testGetDataWithEqualsInt(self):
geometryData = self._runConstraintTest('reportType', '=', 1004)
for record in geometryData:
self.assertEqual(record.getString('reportType'), '1004')
def testGetDataWithEqualsLong(self):
geometryData = self._runConstraintTest('reportType', '=', 1004L)
for record in geometryData:
self.assertEqual(record.getString('reportType'), '1004')
# No float test because no float identifiers are available
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('reportType', '=', None)
for record in geometryData:
self.assertEqual(record.getType('reportType'), 'NULL')
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('reportType', '!=', 1004)
for record in geometryData:
self.assertNotEqual(record.getString('reportType'), '1004')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('reportType', '!=', None)
for record in geometryData:
self.assertNotEqual(record.getType('reportType'), 'NULL')
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('reportType', '>', 1004)
for record in geometryData:
self.assertGreater(record.getString('reportType'), '1004')
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('reportType', '<', 1004)
for record in geometryData:
self.assertLess(record.getString('reportType'), '1004')
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('reportType', '>=', 1004)
for record in geometryData:
self.assertGreaterEqual(record.getString('reportType'), '1004')
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('reportType', '<=', 1004)
for record in geometryData:
self.assertLessEqual(record.getString('reportType'), '1004')
def testGetDataWithInTuple(self):
collection = ('1004', '1005')
geometryData = self._runConstraintTest('reportType', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('reportType'), collection)
def testGetDataWithInList(self):
collection = ['1004', '1005']
geometryData = self._runConstraintTest('reportType', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('reportType'), collection)
def testGetDataWithInGenerator(self):
collection = ('1004', '1005')
generator = (item for item in collection)
geometryData = self._runConstraintTest('reportType', 'in', generator)
for record in geometryData:
self.assertIn(record.getString('reportType'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('reportType', 'junk', '1004')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('reportType', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('reportType', 'in', [])
def testGetDataWithNestedInConstraintThrowsException(self):
collection = ('1004', '1005', ())
with self.assertRaises(TypeError):
self._runConstraintTest('reportType', 'in', collection)

View file

@ -0,0 +1,96 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
from awips.ThriftClient import ThriftRequestException
import baseDafTestCase
import shapely.geometry
import unittest
#
# Test DAF support for topo data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 05/26/16 5587 tgurney Add test for
# getIdentifierValues()
# 06/01/16 5587 tgurney Update testGetIdentifierValues
#
#
class TopoTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for topo data"""
datatype = "topo"
def testGetGridData(self):
print("defaultTopo")
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("group", "/")
req.addIdentifier("dataset", "full")
poly = shapely.geometry.LinearRing(((-70, 40), (-71, 40), (-71, 42), (-70, 42)))
req.setEnvelope(poly)
gridData = DAL.getGridData(req)
self.assertIsNotNone(gridData)
print("Number of grid records: " + str(len(gridData)))
print("Sample grid data shape:\n" + str(gridData[0].getRawData().shape) + "\n")
print("Sample grid data:\n" + str(gridData[0].getRawData()) + "\n")
for topoFile in ["gmted2010", "gtopo30"]:
print("\n" + topoFile)
req.addIdentifier("topoFile", topoFile)
gridData = DAL.getGridData(req)
self.assertIsNotNone(gridData)
print("Number of grid records: " + str(len(gridData)))
print("Sample grid data shape:\n" + str(gridData[0].getRawData().shape) + "\n")
print("Sample grid data:\n" + str(gridData[0].getRawData()) + "\n")
def testRequestingTooMuchDataThrowsResponseTooLargeException(self):
req = DAL.newDataRequest(self.datatype)
req.addIdentifier("group", "/")
req.addIdentifier("dataset", "full")
points = ((-180, 90), (180, 90), (180, -90), (-180, -90))
poly = shapely.geometry.LinearRing(points)
req.setEnvelope(poly)
with self.assertRaises(ThriftRequestException) as cm:
DAL.getGridData(req)
self.assertIn('ResponseTooLargeException', str(cm.exception))
def testGetIdentifierValues(self):
req = DAL.newDataRequest(self.datatype)
optionalIds = set(DAL.getOptionalIdentifiers(req))
requiredIds = set(DAL.getRequiredIdentifiers(req))
self.runGetIdValuesTest(optionalIds | requiredIds)
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()

View file

@ -0,0 +1,228 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
from __future__ import print_function
from awips.dataaccess import DataAccessLayer as DAL
from dynamicserialize.dstypes.com.raytheon.uf.common.dataquery.requests import RequestConstraint
import baseDafTestCase
import unittest
#
# Test DAF support for warning data
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/19/16 4795 mapeters Initial Creation.
# 04/11/16 5548 tgurney Cleanup
# 04/18/16 5548 tgurney More cleanup
# 04/26/16 5587 tgurney Add identifier values tests
# 06/08/16 5574 tgurney Add advanced query tests
# 06/10/16 5548 tgurney Clean up references to name
# of data type
# 06/13/16 5574 tgurney Fix checks for None
# 06/21/16 5548 tgurney Skip tests that cause errors
#
#
class WarningTestCase(baseDafTestCase.DafTestCase):
"""Test DAF support for warning data"""
datatype = "warning"
def _getLocationNames(self):
req = DAL.newDataRequest()
req.setDatatype(self.datatype)
return DAL.getAvailableLocationNames(req)
def _getAllRecords(self):
req = DAL.newDataRequest()
req.setDatatype(self.datatype)
req.setParameters('id')
return DAL.getGeometryData(req)
def testGetAvailableParameters(self):
req = DAL.newDataRequest(self.datatype)
self.runParametersTest(req)
def testGetAvailableLocations(self):
req = DAL.newDataRequest(self.datatype)
self.runLocationsTest(req)
def testGetAvailableTimes(self):
req = DAL.newDataRequest(self.datatype)
req.setParameters("etn", "wmoid")
self.runTimesTest(req)
def testGetGeometryData(self):
req = DAL.newDataRequest(self.datatype)
req.setParameters("etn", "wmoid")
self.runGeometryDataTest(req)
def testFilterOnLocationName(self):
allRecordsCount = len(self._getAllRecords())
allLocationNames = self._getLocationNames()
if allRecordsCount == 0:
errmsg = "No {0} data exists on {1}. Try again with {0} data."
raise unittest.SkipTest(errmsg.format(self.datatype, DAL.THRIFT_HOST))
if len(allLocationNames) != 1:
testCount = 3 # number of different location names to test
for locationName in allLocationNames[:testCount]:
req = DAL.newDataRequest()
req.setDatatype(self.datatype)
req.setParameters('id')
req.setLocationNames(locationName)
geomData = DAL.getGeometryData(req)
self.assertLess(len(geomData), allRecordsCount)
for geom in geomData:
self.assertEqual(geom.getLocationName(), locationName)
def testFilterOnNonexistentLocationReturnsEmpty(self):
req = DAL.newDataRequest()
req.setDatatype(self.datatype)
req.setParameters('id')
req.setLocationNames('ZZZZ')
self.assertEqual(len(DAL.getGeometryData(req)), 0)
def testFilterOnInvalidLocationThrowsIncompatibleRequestException(self):
req = DAL.newDataRequest()
req.setDatatype(self.datatype)
req.setParameters('id')
req.setLocationNames(') and 0=1')
with self.assertRaises(Exception) as cm:
DAL.getGeometryData(req)
self.assertIn('IncompatibleRequestException', str(cm.exception))
def testGetColumnIdentifierValues(self):
self.runGetIdValuesTest(['act'])
@unittest.skip('avoid EDEX error')
def testGetInvalidIdentifierValuesThrowsException(self):
self.runInvalidIdValuesTest()
@unittest.skip('avoid EDEX error')
def testGetNonexistentIdentifierValuesThrowsException(self):
self.runNonexistentIdValuesTest()
def _runConstraintTest(self, key, operator, value):
req = DAL.newDataRequest(self.datatype)
constraint = RequestConstraint.new(operator, value)
req.addIdentifier(key, constraint)
req.setParameters("etn", "wmoid", "sig")
return self.runGeometryDataTest(req)
def testGetDataWithEqualsString(self):
geometryData = self._runConstraintTest('sig', '=', 'Y')
for record in geometryData:
self.assertEqual(record.getString('sig'), 'Y')
def testGetDataWithEqualsUnicode(self):
geometryData = self._runConstraintTest('sig', '=', u'Y')
for record in geometryData:
self.assertEqual(record.getString('sig'), 'Y')
def testGetDataWithEqualsInt(self):
geometryData = self._runConstraintTest('etn', '=', 1000)
for record in geometryData:
self.assertEqual(record.getString('etn'), '1000')
def testGetDataWithEqualsLong(self):
geometryData = self._runConstraintTest('etn', '=', 1000L)
for record in geometryData:
self.assertEqual(record.getString('etn'), '1000')
def testGetDataWithEqualsFloat(self):
geometryData = self._runConstraintTest('etn', '=', 1.0)
for record in geometryData:
self.assertEqual(round(float(record.getString('etn')), 1), 1.0)
def testGetDataWithEqualsNone(self):
geometryData = self._runConstraintTest('sig', '=', None)
for record in geometryData:
self.assertEqual(record.getType('sig'), 'NULL')
def testGetDataWithNotEquals(self):
geometryData = self._runConstraintTest('sig', '!=', 'Y')
for record in geometryData:
self.assertNotEqual(record.getString('sig'), 'Y')
def testGetDataWithNotEqualsNone(self):
geometryData = self._runConstraintTest('sig', '!=', None)
for record in geometryData:
self.assertNotEqual(record.getType('sig'), 'NULL')
def testGetDataWithGreaterThan(self):
geometryData = self._runConstraintTest('sig', '>', 'Y')
for record in geometryData:
self.assertGreater(record.getString('sig'), 'Y')
def testGetDataWithLessThan(self):
geometryData = self._runConstraintTest('sig', '<', 'Y')
for record in geometryData:
self.assertLess(record.getString('sig'), 'Y')
def testGetDataWithGreaterThanEquals(self):
geometryData = self._runConstraintTest('sig', '>=', 'Y')
for record in geometryData:
self.assertGreaterEqual(record.getString('sig'), 'Y')
def testGetDataWithLessThanEquals(self):
geometryData = self._runConstraintTest('sig', '<=', 'Y')
for record in geometryData:
self.assertLessEqual(record.getString('sig'), 'Y')
def testGetDataWithInTuple(self):
collection = ('Y', 'A')
geometryData = self._runConstraintTest('sig', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('sig'), collection)
def testGetDataWithInList(self):
collection = ['Y', 'A']
geometryData = self._runConstraintTest('sig', 'in', collection)
for record in geometryData:
self.assertIn(record.getString('sig'), collection)
def testGetDataWithInGenerator(self):
collection = ('Y', 'A')
generator = (item for item in collection)
geometryData = self._runConstraintTest('sig', 'in', generator)
for record in geometryData:
self.assertIn(record.getString('sig'), collection)
def testGetDataWithInvalidConstraintTypeThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('sig', 'junk', 'Y')
def testGetDataWithInvalidConstraintValueThrowsException(self):
with self.assertRaises(TypeError):
self._runConstraintTest('sig', '=', {})
def testGetDataWithEmptyInConstraintThrowsException(self):
with self.assertRaises(ValueError):
self._runConstraintTest('sig', 'in', [])
def testGetDataWithNestedInConstraintThrowsException(self):
collection = ('Y', 'A', ())
with self.assertRaises(TypeError):
self._runConstraintTest('sig', 'in', collection)

View file

@ -64,7 +64,7 @@ installations.
Package Version RPM Name
====================== ============== ==============================
Python 2.7.10 awips2-python
**awips** **0.9.7** **awips2-python-awips**
**awips** **0.9.8** **awips2-python-awips**
cartopy 0.14.2 awips2-python-cartopy
cherrypy 3.1.2 awips2-python-cherrypy
cycler 0.10.0 awips2-python-cycler

View file

@ -65,7 +65,7 @@ author = 'Unidata'
# built documents.
#
# The short X.Y version.
version = '0.9.7'
version = '0.9.8'
# The full version, including alpha/beta/rc tags.
# The language for content autogenerated by Sphinx. Refer to documentation

View file

@ -66,4 +66,4 @@ class DynamicSerializationManager:
return self.transport.getvalue()
def _serialize(self, ctx, obj):
ctx.serializeMessage(obj)
ctx.serializeMessage(obj)

View file

@ -0,0 +1,46 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
#
# Adapter for CommutativeTimestamp
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 9/21/2015 4486 rjpeter Initial creation.
# Jun 23, 2016 5696 rjpeter Handle CommutativeTimestamp.
#
#
from dynamicserialize.dstypes.com.raytheon.uf.common.time import CommutativeTimestamp
ClassAdapter = 'com.raytheon.uf.common.time.CommutativeTimestamp'
def serialize(context, date):
context.writeI64(date.getTime())
def deserialize(context):
result = CommutativeTimestamp()
result.setTime(context.readI64())
return result

View file

@ -1,19 +1,19 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
@ -21,10 +21,10 @@
#
# __init__.py for Dynamic Serialize adapters.
#
#
#
#
# SOFTWARE HISTORY
#
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 08/31/10 njensen Initial Creation.
@ -33,6 +33,7 @@
# 02/06/14 #2672 bsteffen Added JTSEnvelopeAdapter
# 06/22/2015 #4573 randerso Added JobProgressAdapter
# 09/21/2015 #4486 rjpeter Added FormattedDateAdapter
# 06/23/2016 #5696 rjpeter Added CommutativeTimestampAdapter
#
__all__ = [
@ -52,6 +53,7 @@ __all__ = [
'ParmIDAdapter',
'DatabaseIDAdapter',
'TimestampAdapter',
'CommutativeTimestampAdapter',
'EnumSetAdapter',
'FloatBufferAdapter',
'ByteBufferAdapter',
@ -60,12 +62,12 @@ __all__ = [
'JTSEnvelopeAdapter',
'JobProgressAdapter',
]
classAdapterRegistry = {}
def getAdapterRegistry():
import sys
import sys
for x in __all__:
exec('import dynamicserialize.adapters.' + x )
m = sys.modules['dynamicserialize.adapters.' + x]
@ -80,7 +82,7 @@ def getAdapterRegistry():
else:
raise LookupError('Adapter class ' + x + ' has no ClassAdapter field ' + \
'and cannot be registered.')
getAdapterRegistry()

View file

@ -26,6 +26,7 @@ __all__ = [
'auth',
'dataaccess',
'dataplugin',
'dataquery',
'datastorage',
'localization',
'management',

View file

@ -24,6 +24,7 @@
# ------------ ---------- ----------- --------------------------
# 05/22/2015 4522 randerso Initial creation
# 03/17/2016 5426 randerso Add issueYear to primary key
# 08/03/2016 19213 ryu Add pil to primary key
#
##
class ActiveTableKey(object):
@ -35,6 +36,7 @@ class ActiveTableKey(object):
self.etn = None
self.ugcZone = None
self.issueYear = None
self.pil = None
def getOfficeid(self):
return self.officeid
@ -71,3 +73,9 @@ class ActiveTableKey(object):
def setIssueYear(self, issueYear):
self.issueYear = issueYear
def getPil(self):
return self.pil
def setPil(self, pil):
self.pil = pil

View file

@ -19,10 +19,11 @@
##
# File generated against equivalent DynamicSerialize Java class
# Jul 27, 2016 #5769 randerso Fixed __str__ method
class ActiveTableMode(object):
def __init__(self):
self.value = None
def __str__(self):
return repr(self.value)
return str(self.value)

View file

@ -24,6 +24,7 @@
# ------------ ---------- ----------- --------------------------
# 05/22/2015 4522 randerso Initial creation (hand generated)
# 03/17/2016 5426 randerso Add issueYear to primary key
# 06/27/2016 5707 nabowle Remove geometry
#
##
@ -46,7 +47,6 @@ class ActiveTableRecord(with_metaclass(abc.ABCMeta, object)):
self.issueTime = None
self.purgeTime = None
self.ufn = None
self.geometry = None
self.forecaster = None
self.motdir = None
self.motspd = None
@ -177,12 +177,6 @@ class ActiveTableRecord(with_metaclass(abc.ABCMeta, object)):
def setUfn(self, ufn):
self.ufn = ufn
def getGeometry(self):
return self.geometry
def setGeometry(self, geometry):
self.geometry = geometry
def getForecaster(self):
return self.forecaster

View file

@ -26,6 +26,8 @@
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 07/23/14 #3185 njensen Initial Creation.
# Jun 01, 2016 5587 tgurney Change self.datatype to
# self.request
#
#
@ -34,11 +36,11 @@ from six import with_metaclass
class AbstractIdentifierRequest(with_metaclass(abc.ABCMeta, object)):
def __init__(self):
self.datatype = None
self.request = None
def getDatatype(self):
return self.datatype
def getRequest(self):
return self.request
def setDatatype(self, datatype):
self.datatype = datatype
def setRequest(self, request):
self.request = request

View file

@ -0,0 +1,45 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
# File auto-generated against equivalent DynamicSerialize Java class
# and then modified post-generation to make it subclass
# AbstractDataAccessRequest.
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 04/15/2016 5379 tgurney Initial creation
#
#
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import AbstractDataAccessRequest
class GetIdentifierValuesRequest(AbstractDataAccessRequest):
def __init__(self):
super(GetIdentifierValuesRequest, self).__init__()
self.identifierKey = None
def getIdentifierKey(self):
return self.identifierKey
def setIdentifierKey(self, identifierKey):
self.identifierKey = identifierKey

View file

@ -31,7 +31,8 @@ __all__ = [
'GetGridDataRequest',
'GetRequiredIdentifiersRequest',
'GetSupportedDatatypesRequest',
'GetOptionalIdentifiersRequest'
'GetOptionalIdentifiersRequest',
'GetIdentifierValuesRequest'
]
from .AbstractDataAccessRequest import AbstractDataAccessRequest
@ -45,4 +46,4 @@ from .GetGridDataRequest import GetGridDataRequest
from .GetRequiredIdentifiersRequest import GetRequiredIdentifiersRequest
from .GetSupportedDatatypesRequest import GetSupportedDatatypesRequest
from .GetOptionalIdentifiersRequest import GetOptionalIdentifiersRequest
from .GetIdentifierValuesRequest import GetIdentifierValuesRequest

View file

@ -0,0 +1,27 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
# File auto-generated by PythonFileGenerator
__all__ = [
'requests'
]

View file

@ -0,0 +1,124 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# Jun 01, 2016 5574 tgurney Initial creation
#
#
class RequestConstraint(object):
def __init__(self):
self.constraintValue = None
self.constraintType = None
def getConstraintValue(self):
return self.constraintValue
def setConstraintValue(self, constraintValue):
self.constraintValue = constraintValue
def getConstraintType(self):
return self.constraintType
def setConstraintType(self, constraintType):
self.constraintType = constraintType
# DAF-specific stuff begins here ##########################################
CONSTRAINT_MAP = {'=': 'EQUALS',
'!=': 'NOT_EQUALS',
'>': 'GREATER_THAN',
'>=': 'GREATER_THAN_EQUALS',
'<': 'LESS_THAN',
'<=': 'LESS_THAN_EQUALS',
'IN': 'IN',
#'NOT IN': 'NOT_IN'
}
@staticmethod
def _stringify(value):
if type(value) in {str, int, long, bool, float, unicode}:
return str(value)
else:
# Collections are not allowed; they are handled separately.
# Arbitrary objects are not allowed because the string
# representation may not be sufficient to reconstruct the object.
raise TypeError('Constraint values of type ' + repr(type(value)) +
'are not allowed')
@classmethod
def _construct_in(cls, constraintType, constraintValue):
"""Build a new "IN" constraint from an iterable."""
try:
iterator = iter(constraintValue)
except TypeError:
raise TypeError("value for IN constraint must be an iterable")
stringValue = ', '.join(cls._stringify(item) for item in iterator)
if len(stringValue) == 0:
raise ValueError('cannot use IN with empty collection')
obj = cls()
obj.setConstraintType(constraintType)
obj.setConstraintValue(stringValue)
return obj
@classmethod
def _construct_eq_not_eq(cls, constraintType, constraintValue):
"""Build a new = or != constraint. Handle None specially by making an
"is null" or "is not null" instead.
"""
obj = cls()
if constraintValue is None:
if constraintType == 'EQUALS':
obj.setConstraintType('ISNULL')
elif constraintType == 'NOT_EQUALS':
obj.setConstraintType('ISNOTNULL')
else:
obj = cls._construct(constraintType, constraintValue)
return obj
@classmethod
def _construct(cls, constraintType, constraintValue):
"""Build a new constraint."""
stringValue = cls._stringify(constraintValue)
obj = cls()
obj.setConstraintType(constraintType)
obj.setConstraintValue(stringValue)
return obj
@classmethod
def new(cls, operator, constraintValue):
"""Build a new RequestConstraint."""
try:
constraintType = cls.CONSTRAINT_MAP[operator.upper()]
except KeyError, AttributeError:
errmsg = '{} is not a valid operator. Valid operators are: {}'
validOperators = list(sorted(cls.CONSTRAINT_MAP.keys()))
raise ValueError(errmsg.format(operator, validOperators))
if constraintType == 'IN':
return cls._construct_in(constraintType, constraintValue)
elif constraintType in {'EQUALS', 'NOT_EQUALS'}:
return cls._construct_eq_not_eq(constraintType, constraintValue)
else:
return cls._construct(constraintType, constraintValue)

View file

@ -0,0 +1,28 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
# File auto-generated by PythonFileGenerator
__all__ = [
'RequestConstraint'
]
from RequestConstraint import RequestConstraint

View file

@ -26,7 +26,6 @@ class CopyRequest(object):
self.repack = None
self.repackCompression = None
self.outputDir = None
self.timestampCheck = None
self.minMillisSinceLastChange = None
self.maxMillisSinceLastChange = None
self.filename = None
@ -49,12 +48,6 @@ class CopyRequest(object):
def setOutputDir(self, outputDir):
self.outputDir = outputDir
def getTimestampCheck(self):
return self.timestampCheck
def setTimestampCheck(self, timestampCheck):
self.timestampCheck = timestampCheck
def getMinMillisSinceLastChange(self):
return self.minMillisSinceLastChange

View file

@ -19,21 +19,29 @@
##
# File auto-generated against equivalent DynamicSerialize Java class
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# Jul 27, 2015 1574 nabowle Generated
# Feb 23, 2016 5389 nabowle Regenerated
class DeleteOrphansRequest(object):
def __init__(self):
self.oldestDateMap = None
self.filename = None
self.oldestDate = None
def getOldestDate(self):
return self.oldestDate
def getOldestDateMap(self):
return self.oldestDateMap
def setOldestDate(self, oldestDate):
self.oldestDate = oldestDate
def setOldestDateMap(self, oldestDateMap):
self.oldestDateMap = oldestDateMap
def getFilename(self):
return self.filename
def setFilename(self, filename):
self.filename = filename

View file

@ -0,0 +1,37 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
# ----------------------------------------------------------------------------
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 06/23/2016 #5696 rjpeter Initial creation.
#
##
from time import gmtime, strftime
from dynamicserialize.dstypes.java.sql import Timestamp
class CommutativeTimestamp(Timestamp):
def __init__(self, timeInMillis=None):
super(CommutativeTimestamp, self).__init__(timeInMillis)

View file

@ -24,16 +24,13 @@
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 09/21/2015 4486 rjpeter Initial creation.
#
# 06/23/2016 #5696 rjpeter Extend CommutativeTimestamp
##
from time import gmtime, strftime
from dynamicserialize.dstypes.java.util import Date
from CommutativeTimestamp import CommutativeTimestamp
class FormattedDate(Date):
# TODO: Remove after 16.4.1 no longer in field
class FormattedDate(CommutativeTimestamp):
def __init__(self, timeInMillis=None):
super(FormattedDate, self).__init__(timeInMillis)
def __repr__(self):
return strftime("%Y-%m-%d %H:%M:%S.", gmtime(self.time/1000.0)) + '{:03d}'.format(self.time%1000)

View file

@ -23,10 +23,11 @@
__all__ = [
'DataTime',
'TimeRange',
'FormattedDate'
'FormattedDate',
'CommutativeTimestamp'
]
from .DataTime import DataTime
from .TimeRange import TimeRange
from .FormattedDate import FormattedDate
from .CommutativeTimestamp import CommutativeTimestamp

View file

@ -1,8 +1,8 @@
# File auto-generated against equivalent DynamicSerialize Java class
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# May 05, 2016 root Generated

View file

@ -1,8 +1,8 @@
# File auto-generated against equivalent DynamicSerialize Java class
#
#
# SOFTWARE HISTORY
#
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# May 06, 2016 root Generated

View file

@ -1,8 +1,8 @@
# File auto-generated against equivalent DynamicSerialize Java class
#
#
# SOFTWARE HISTORY
#
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# May 06, 2016 root Generated

View file

@ -20,20 +20,24 @@
# File auto-generated against equivalent DynamicSerialize Java class
# and then modified post-generation to add additional features to better
# match Java implementation.
# match Java implementation. Unlike real timestamp, does not support nanos precision.
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# ??/??/?? xxxxxxxx Initial Creation.
# 06/24/15 4480 dgilling implement based on Date class.
# 06/24/15 4480 dgilling implement based on Date class.
# Jun 23, 2016 5696 rjpeter Make String version match java.
#
from dynamicserialize.dstypes.java.util import Date
from time import gmtime, strftime
class Timestamp(Date):
def __init__(self, time=None):
super(Timestamp, self).__init__(time)
def __repr__(self):
return strftime("%Y-%m-%d %H:%M:%S.", gmtime(self.time/1000.0)) + '{:03d}'.format(self.time%1000)

View file

@ -3,12 +3,12 @@ from setuptools import find_packages
setup(
name='python-awips',
version='0.9.7',
version='0.9.8',
description='A framework for requesting AWIPS meteorological datasets from an EDEX server',
packages=find_packages(exclude='data'),
license='Open Source',
url='http://www.unidata.ucar.edu/software/awips2',
download_url='https://github.com/Unidata/python-awips/tarball/0.9.7',
url='http://python-awips.readthedocs.io',
download_url='https://github.com/Unidata/python-awips/tarball/0.9.8',
author='Unidata',
author_email='mjames@ucar.edu',
requires=['argparse','shapely','numpy','six']