mirror of
https://github.com/Unidata/python-awips.git
synced 2025-02-23 14:57:56 -05:00
Merge branch 'master-python2'
This commit is contained in:
commit
69427a6ac0
64 changed files with 5091 additions and 107 deletions
|
@ -1,7 +1,7 @@
|
||||||
##
|
##
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
# This software was developed and / or modified by Raytheon Company,
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
#
|
#
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
# This software product contains export-restricted data whose
|
# This software product contains export-restricted data whose
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
# Mail Stop B8
|
# Mail Stop B8
|
||||||
# Omaha, NE 68106
|
# Omaha, NE 68106
|
||||||
# 402.291.0100
|
# 402.291.0100
|
||||||
#
|
#
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
# further licensing information.
|
# further licensing information.
|
||||||
##
|
##
|
||||||
|
@ -47,6 +47,8 @@ from dynamicserialize import DynamicSerializationManager
|
||||||
# 01/07/11 5645 cjeanbap Added audio file to Status Message.
|
# 01/07/11 5645 cjeanbap Added audio file to Status Message.
|
||||||
# 05/27/11 3050 cjeanbap Added if-statement to check Priority
|
# 05/27/11 3050 cjeanbap Added if-statement to check Priority
|
||||||
# value
|
# value
|
||||||
|
# 07/27/15 4654 skorolev Added filters
|
||||||
|
# 11/11/15 5120 rferrel Cannot serialize empty filters.
|
||||||
#
|
#
|
||||||
class NotificationMessage:
|
class NotificationMessage:
|
||||||
|
|
||||||
|
@ -58,13 +60,14 @@ class NotificationMessage:
|
||||||
4: 'EVENTB',
|
4: 'EVENTB',
|
||||||
5: 'VERBOSE'}
|
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.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
self.message = message
|
self.message = message
|
||||||
self.audioFile = audioFile
|
self.audioFile = audioFile
|
||||||
self.source = source
|
self.source = source
|
||||||
self.category = category
|
self.category = category
|
||||||
|
self.filters = filters
|
||||||
|
|
||||||
priorityInt = None
|
priorityInt = None
|
||||||
|
|
||||||
|
@ -113,9 +116,9 @@ class NotificationMessage:
|
||||||
# of the message to AlertViz
|
# of the message to AlertViz
|
||||||
# 9581 is global distribution thru ThriftClient to Edex
|
# 9581 is global distribution thru ThriftClient to Edex
|
||||||
# 61999 is local distribution
|
# 61999 is local distribution
|
||||||
if (self.port == 61999):
|
if (int(self.port) == 61999):
|
||||||
# use stomp.py
|
# 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])
|
timeout = threading.Timer(5.0, self.connection_timeout, [conn])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -132,6 +135,8 @@ class NotificationMessage:
|
||||||
sm.set("category", self.category)
|
sm.set("category", self.category)
|
||||||
sm.set("sourceKey", self.source)
|
sm.set("sourceKey", self.source)
|
||||||
sm.set("audioFile", self.audioFile)
|
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 = ET.SubElement(sm, "message")
|
||||||
msg.text = self.message
|
msg.text = self.message
|
||||||
details = ET.SubElement(sm, "details")
|
details = ET.SubElement(sm, "details")
|
||||||
|
@ -144,7 +149,7 @@ class NotificationMessage:
|
||||||
conn.stop()
|
conn.stop()
|
||||||
else:
|
else:
|
||||||
# use ThriftClient
|
# 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")
|
thriftClient = ThriftClient.ThriftClient(self.host, self.port, "/services")
|
||||||
|
|
||||||
serverResponse = None
|
serverResponse = None
|
||||||
|
@ -159,7 +164,7 @@ class NotificationMessage:
|
||||||
else:
|
else:
|
||||||
print("Response: " + str(serverResponse))
|
print("Response: " + str(serverResponse))
|
||||||
|
|
||||||
def createRequest(message, priority, source, category, audioFile):
|
def createRequest(message, priority, source, category, audioFile, filters):
|
||||||
obj = AlertVizRequest()
|
obj = AlertVizRequest()
|
||||||
|
|
||||||
obj.setMachine(socket.gethostname())
|
obj.setMachine(socket.gethostname())
|
||||||
|
@ -171,7 +176,7 @@ def createRequest(message, priority, source, category, audioFile):
|
||||||
obj.setAudioFile(audioFile)
|
obj.setAudioFile(audioFile)
|
||||||
else:
|
else:
|
||||||
obj.setAudioFile('\0')
|
obj.setAudioFile('\0')
|
||||||
|
obj.setFilters(filters)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
99
awips/dataaccess/CombinedTimeQuery.py
Normal file
99
awips/dataaccess/CombinedTimeQuery.py
Normal 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())
|
|
@ -30,12 +30,17 @@
|
||||||
# 12/10/12 njensen Initial Creation.
|
# 12/10/12 njensen Initial Creation.
|
||||||
# Feb 14, 2013 1614 bsteffen refactor data access framework
|
# Feb 14, 2013 1614 bsteffen refactor data access framework
|
||||||
# to use single request.
|
# to use single request.
|
||||||
# 04/10/13 1871 mnash move getLatLonCoords to JGridData and add default args
|
# 04/10/13 1871 mnash move getLatLonCoords to JGridData and add default args
|
||||||
# 05/29/13 2023 dgilling Hook up ThriftClientRouter.
|
# 05/29/13 2023 dgilling Hook up ThriftClientRouter.
|
||||||
# 03/03/14 2673 bsteffen Add ability to query only ref times.
|
# 03/03/14 2673 bsteffen Add ability to query only ref times.
|
||||||
# 07/22/14 3185 njensen Added optional/default args to newDataRequest
|
# 07/22/14 3185 njensen Added optional/default args to newDataRequest
|
||||||
# 07/30/14 3185 njensen Renamed valid identifiers to optional
|
# 07/30/14 3185 njensen Renamed valid identifiers to optional
|
||||||
# Apr 26, 2015 4259 njensen Updated for new JEP API
|
# 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 sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import warnings
|
||||||
|
|
||||||
THRIFT_HOST = "edex"
|
THRIFT_HOST = "edex"
|
||||||
USING_NATIVE_THRIFT = False
|
USING_NATIVE_THRIFT = False
|
||||||
|
@ -58,17 +64,17 @@ else:
|
||||||
router = ThriftClientRouter.ThriftClientRouter(THRIFT_HOST)
|
router = ThriftClientRouter.ThriftClientRouter(THRIFT_HOST)
|
||||||
USING_NATIVE_THRIFT = True
|
USING_NATIVE_THRIFT = True
|
||||||
|
|
||||||
def getForecastCycle(cycle, times):
|
def getForecastRun(cycle, times):
|
||||||
"""
|
"""
|
||||||
:param cycle: Forecast cycle reference time
|
:param cycle: Forecast cycle reference time
|
||||||
:param times: All available times/cycles
|
:param times: All available times/cycles
|
||||||
:return: DataTime array for a single forecast run
|
:return: DataTime array for a single forecast run
|
||||||
"""
|
"""
|
||||||
forecast_run = []
|
fcstRun = []
|
||||||
for time in times:
|
for t in times:
|
||||||
if time.getRefTime() == cycle.getRefTime():
|
if str(t)[:19] == str(cycle):
|
||||||
forecast_run.append(time)
|
fcstRun.append(t)
|
||||||
return forecast_run
|
return fcstRun
|
||||||
|
|
||||||
def getAvailableTimes(request, refTimeOnly=False):
|
def getAvailableTimes(request, refTimeOnly=False):
|
||||||
"""
|
"""
|
||||||
|
@ -81,6 +87,7 @@ def getAvailableTimes(request, refTimeOnly=False):
|
||||||
"""
|
"""
|
||||||
return router.getAvailableTimes(request, refTimeOnly)
|
return router.getAvailableTimes(request, refTimeOnly)
|
||||||
|
|
||||||
|
|
||||||
def getGridData(request, times=[]):
|
def getGridData(request, times=[]):
|
||||||
"""
|
"""
|
||||||
Gets the grid data that matches the request at the specified times. Each
|
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)
|
return router.getGridData(request, times)
|
||||||
|
|
||||||
|
|
||||||
def getGeometryData(request, times=[]):
|
def getGeometryData(request, times=[]):
|
||||||
"""
|
"""
|
||||||
Gets the geometry data that matches the request at the specified 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)
|
return router.getGeometryData(request, times)
|
||||||
|
|
||||||
|
|
||||||
def getAvailableLocationNames(request):
|
def getAvailableLocationNames(request):
|
||||||
"""
|
"""
|
||||||
Gets the available location names that match the request without actually
|
Gets the available location names that match the request without actually
|
||||||
|
@ -118,6 +127,7 @@ def getAvailableLocationNames(request):
|
||||||
"""
|
"""
|
||||||
return router.getAvailableLocationNames(request)
|
return router.getAvailableLocationNames(request)
|
||||||
|
|
||||||
|
|
||||||
def getAvailableParameters(request):
|
def getAvailableParameters(request):
|
||||||
"""
|
"""
|
||||||
Gets the available parameters names that match the request without actually
|
Gets the available parameters names that match the request without actually
|
||||||
|
@ -129,6 +139,7 @@ def getAvailableParameters(request):
|
||||||
"""
|
"""
|
||||||
return router.getAvailableParameters(request)
|
return router.getAvailableParameters(request)
|
||||||
|
|
||||||
|
|
||||||
def getAvailableLevels(request):
|
def getAvailableLevels(request):
|
||||||
"""
|
"""
|
||||||
Gets the available levels that match the request without actually
|
Gets the available levels that match the request without actually
|
||||||
|
@ -140,26 +151,46 @@ def getAvailableLevels(request):
|
||||||
"""
|
"""
|
||||||
return router.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.
|
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
|
: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
|
: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):
|
def newDataRequest(datatype=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -28,10 +28,11 @@
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# 06/03/13 dgilling Initial Creation.
|
# 06/03/13 dgilling Initial Creation.
|
||||||
# 01/06/14 #2537 bsteffen Share geometry WKT.
|
# 01/06/14 2537 bsteffen Share geometry WKT.
|
||||||
# 03/19/14 #2882 dgilling Raise an exception when getNumber()
|
# 03/19/14 2882 dgilling Raise an exception when getNumber()
|
||||||
# is called for data that is not a
|
# is called for data that is not a
|
||||||
# numeric Type.
|
# 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):
|
def getNumber(self, param):
|
||||||
value = self.__dataMap[param][0]
|
value = self.__dataMap[param][0]
|
||||||
t = self.getType(param)
|
t = self.getType(param)
|
||||||
if t == 'INT':
|
if t == 'INT' or t == 'SHORT':
|
||||||
return int(value)
|
return int(value)
|
||||||
elif t == 'LONG':
|
elif t == 'LONG':
|
||||||
return int(value)
|
return int(value)
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# 06/03/13 #2023 dgilling Initial Creation.
|
# 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
|
ny = ny
|
||||||
self.__parameter = gridDataRecord.getParameter()
|
self.__parameter = gridDataRecord.getParameter()
|
||||||
self.__unit = gridDataRecord.getUnit()
|
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
|
self.__latLonGrid = latLonGrid
|
||||||
|
|
||||||
def getParameter(self):
|
def getParameter(self):
|
||||||
|
|
|
@ -23,17 +23,22 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# SOFTWARE HISTORY
|
# SOFTWARE HISTORY
|
||||||
#
|
#
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# 05/21/13 #2023 dgilling Initial Creation.
|
# 05/21/13 2023 dgilling Initial Creation.
|
||||||
# 01/06/14 #2537 bsteffen Share geometry WKT.
|
# 01/06/14 2537 bsteffen Share geometry WKT.
|
||||||
# 03/03/14 #2673 bsteffen Add ability to query only ref times.
|
# 03/03/14 2673 bsteffen Add ability to query only ref times.
|
||||||
# 07/22/14 #3185 njensen Added optional/default args to newDataRequest
|
# 07/22/14 3185 njensen Added optional/default args to newDataRequest
|
||||||
# 07/23/14 #3185 njensen Added new methods
|
# 07/23/14 3185 njensen Added new methods
|
||||||
# 07/30/14 #3185 njensen Renamed valid identifiers to optional
|
# 07/30/14 3185 njensen Renamed valid identifiers to optional
|
||||||
# 06/30/15 #4569 nabowle Use hex WKB for geometries.
|
# 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 GetAvailableLevelsRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetRequiredIdentifiersRequest
|
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 GetOptionalIdentifiersRequest
|
||||||
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetIdentifierValuesRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetSupportedDatatypesRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetSupportedDatatypesRequest
|
||||||
|
|
||||||
from awips import ThriftClient
|
from awips import ThriftClient
|
||||||
|
@ -87,8 +93,8 @@ class ThriftClientRouter(object):
|
||||||
for location in locNames:
|
for location in locNames:
|
||||||
nx = response.getSiteNxValues()[location]
|
nx = response.getSiteNxValues()[location]
|
||||||
ny = response.getSiteNyValues()[location]
|
ny = response.getSiteNyValues()[location]
|
||||||
latData = numpy.reshape(numpy.array(response.getSiteLatGrids()[location]), (nx, ny))
|
latData = numpy.reshape(numpy.array(response.getSiteLatGrids()[location]), (ny, nx))
|
||||||
lonData = numpy.reshape(numpy.array(response.getSiteLonGrids()[location]), (nx, ny))
|
lonData = numpy.reshape(numpy.array(response.getSiteLonGrids()[location]), (ny, nx))
|
||||||
locSpecificData[location] = (nx, ny, (lonData, latData))
|
locSpecificData[location] = (nx, ny, (lonData, latData))
|
||||||
|
|
||||||
retVal = []
|
retVal = []
|
||||||
|
@ -143,18 +149,31 @@ class ThriftClientRouter(object):
|
||||||
response = self._client.sendRequest(levelReq)
|
response = self._client.sendRequest(levelReq)
|
||||||
return response
|
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 = GetRequiredIdentifiersRequest()
|
||||||
idReq.setDatatype(datatype)
|
idReq.setRequest(request)
|
||||||
response = self._client.sendRequest(idReq)
|
response = self._client.sendRequest(idReq)
|
||||||
return response
|
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 = GetOptionalIdentifiersRequest()
|
||||||
idReq.setDatatype(datatype)
|
idReq.setRequest(request)
|
||||||
response = self._client.sendRequest(idReq)
|
response = self._client.sendRequest(idReq)
|
||||||
return response
|
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):
|
def newDataRequest(self, datatype, parameters=[], levels=[], locationNames = [], envelope=None, **kwargs):
|
||||||
req = DefaultDataRequest()
|
req = DefaultDataRequest()
|
||||||
if datatype:
|
if datatype:
|
||||||
|
|
36
awips/test/dafTests/__init__.py
Normal file
36
awips/test/dafTests/__init__.py
Normal 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__ = []
|
59
awips/test/dafTests/baseBufrMosTestCase.py
Normal file
59
awips/test/dafTests/baseBufrMosTestCase.py
Normal 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)
|
218
awips/test/dafTests/baseDafTestCase.py
Normal file
218
awips/test/dafTests/baseDafTestCase.py
Normal 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
|
61
awips/test/dafTests/testAcars.py
Normal file
61
awips/test/dafTests/testAcars.py
Normal 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)
|
165
awips/test/dafTests/testAirep.py
Normal file
165
awips/test/dafTests/testAirep.py
Normal 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)
|
192
awips/test/dafTests/testBinLightning.py
Normal file
192
awips/test/dafTests/testBinLightning.py
Normal 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', [])
|
45
awips/test/dafTests/testBufrMosAvn.py
Normal file
45
awips/test/dafTests/testBufrMosAvn.py
Normal 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
|
45
awips/test/dafTests/testBufrMosEta.py
Normal file
45
awips/test/dafTests/testBufrMosEta.py
Normal 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
|
45
awips/test/dafTests/testBufrMosGfs.py
Normal file
45
awips/test/dafTests/testBufrMosGfs.py
Normal 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
|
52
awips/test/dafTests/testBufrMosHpc.py
Normal file
52
awips/test/dafTests/testBufrMosHpc.py
Normal 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)
|
45
awips/test/dafTests/testBufrMosLamp.py
Normal file
45
awips/test/dafTests/testBufrMosLamp.py
Normal 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
|
52
awips/test/dafTests/testBufrMosMrf.py
Normal file
52
awips/test/dafTests/testBufrMosMrf.py
Normal 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)
|
205
awips/test/dafTests/testBufrUa.py
Normal file
205
awips/test/dafTests/testBufrUa.py
Normal 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)
|
413
awips/test/dafTests/testClimate.py
Normal file
413
awips/test/dafTests/testClimate.py
Normal 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)
|
||||||
|
|
67
awips/test/dafTests/testCombinedTimeQuery.py
Normal file
67
awips/test/dafTests/testCombinedTimeQuery.py
Normal 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)
|
179
awips/test/dafTests/testCommonObsSpatial.py
Normal file
179
awips/test/dafTests/testCommonObsSpatial.py
Normal 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', [])
|
98
awips/test/dafTests/testFfmp.py
Normal file
98
awips/test/dafTests/testFfmp.py
Normal 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()
|
196
awips/test/dafTests/testGfe.py
Normal file
196
awips/test/dafTests/testGfe.py
Normal 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', [])
|
123
awips/test/dafTests/testGrid.py
Normal file
123
awips/test/dafTests/testGrid.py
Normal 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])))
|
||||||
|
|
261
awips/test/dafTests/testHydro.py
Normal file
261
awips/test/dafTests/testHydro.py
Normal 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)
|
77
awips/test/dafTests/testLdadMesonet.py
Normal file
77
awips/test/dafTests/testLdadMesonet.py
Normal 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)
|
227
awips/test/dafTests/testMaps.py
Normal file
227
awips/test/dafTests/testMaps.py
Normal 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', [])
|
209
awips/test/dafTests/testModelSounding.py
Normal file
209
awips/test/dafTests/testModelSounding.py
Normal 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)
|
168
awips/test/dafTests/testObs.py
Normal file
168
awips/test/dafTests/testObs.py
Normal 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)
|
83
awips/test/dafTests/testPirep.py
Normal file
83
awips/test/dafTests/testPirep.py
Normal 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")
|
||||||
|
|
49
awips/test/dafTests/testPracticeWarning.py
Normal file
49
awips/test/dafTests/testPracticeWarning.py
Normal 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
|
80
awips/test/dafTests/testProfiler.py
Normal file
80
awips/test/dafTests/testProfiler.py
Normal 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")
|
197
awips/test/dafTests/testRadar.py
Normal file
197
awips/test/dafTests/testRadar.py
Normal 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', [])
|
175
awips/test/dafTests/testRadarSpatial.py
Normal file
175
awips/test/dafTests/testRadarSpatial.py
Normal 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', [])
|
186
awips/test/dafTests/testSatellite.py
Normal file
186
awips/test/dafTests/testSatellite.py
Normal 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)
|
177
awips/test/dafTests/testSfcObs.py
Normal file
177
awips/test/dafTests/testSfcObs.py
Normal 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)
|
96
awips/test/dafTests/testTopo.py
Normal file
96
awips/test/dafTests/testTopo.py
Normal 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()
|
228
awips/test/dafTests/testWarning.py
Normal file
228
awips/test/dafTests/testWarning.py
Normal 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)
|
|
@ -64,7 +64,7 @@ installations.
|
||||||
Package Version RPM Name
|
Package Version RPM Name
|
||||||
====================== ============== ==============================
|
====================== ============== ==============================
|
||||||
Python 2.7.10 awips2-python
|
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
|
cartopy 0.14.2 awips2-python-cartopy
|
||||||
cherrypy 3.1.2 awips2-python-cherrypy
|
cherrypy 3.1.2 awips2-python-cherrypy
|
||||||
cycler 0.10.0 awips2-python-cycler
|
cycler 0.10.0 awips2-python-cycler
|
||||||
|
|
|
@ -65,7 +65,7 @@ author = 'Unidata'
|
||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '0.9.7'
|
version = '0.9.8'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
|
|
|
@ -66,4 +66,4 @@ class DynamicSerializationManager:
|
||||||
return self.transport.getvalue()
|
return self.transport.getvalue()
|
||||||
|
|
||||||
def _serialize(self, ctx, obj):
|
def _serialize(self, ctx, obj):
|
||||||
ctx.serializeMessage(obj)
|
ctx.serializeMessage(obj)
|
||||||
|
|
46
dynamicserialize/adapters/CommutativeTimestampAdapter.py
Normal file
46
dynamicserialize/adapters/CommutativeTimestampAdapter.py
Normal 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
|
|
@ -1,19 +1,19 @@
|
||||||
##
|
##
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
# This software was developed and / or modified by Raytheon Company,
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
#
|
#
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
# This software product contains export-restricted data whose
|
# This software product contains export-restricted data whose
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
# to non-U.S. persons whether in the United States or abroad requires
|
||||||
# an export license or other authorization.
|
# an export license or other authorization.
|
||||||
#
|
#
|
||||||
# Contractor Name: Raytheon Company
|
# Contractor Name: Raytheon Company
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
# Contractor Address: 6825 Pine Street, Suite 340
|
||||||
# Mail Stop B8
|
# Mail Stop B8
|
||||||
# Omaha, NE 68106
|
# Omaha, NE 68106
|
||||||
# 402.291.0100
|
# 402.291.0100
|
||||||
#
|
#
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
# further licensing information.
|
# further licensing information.
|
||||||
##
|
##
|
||||||
|
@ -21,10 +21,10 @@
|
||||||
|
|
||||||
#
|
#
|
||||||
# __init__.py for Dynamic Serialize adapters.
|
# __init__.py for Dynamic Serialize adapters.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# SOFTWARE HISTORY
|
# SOFTWARE HISTORY
|
||||||
#
|
#
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# 08/31/10 njensen Initial Creation.
|
# 08/31/10 njensen Initial Creation.
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
# 02/06/14 #2672 bsteffen Added JTSEnvelopeAdapter
|
# 02/06/14 #2672 bsteffen Added JTSEnvelopeAdapter
|
||||||
# 06/22/2015 #4573 randerso Added JobProgressAdapter
|
# 06/22/2015 #4573 randerso Added JobProgressAdapter
|
||||||
# 09/21/2015 #4486 rjpeter Added FormattedDateAdapter
|
# 09/21/2015 #4486 rjpeter Added FormattedDateAdapter
|
||||||
|
# 06/23/2016 #5696 rjpeter Added CommutativeTimestampAdapter
|
||||||
#
|
#
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
@ -52,6 +53,7 @@ __all__ = [
|
||||||
'ParmIDAdapter',
|
'ParmIDAdapter',
|
||||||
'DatabaseIDAdapter',
|
'DatabaseIDAdapter',
|
||||||
'TimestampAdapter',
|
'TimestampAdapter',
|
||||||
|
'CommutativeTimestampAdapter',
|
||||||
'EnumSetAdapter',
|
'EnumSetAdapter',
|
||||||
'FloatBufferAdapter',
|
'FloatBufferAdapter',
|
||||||
'ByteBufferAdapter',
|
'ByteBufferAdapter',
|
||||||
|
@ -60,12 +62,12 @@ __all__ = [
|
||||||
'JTSEnvelopeAdapter',
|
'JTSEnvelopeAdapter',
|
||||||
'JobProgressAdapter',
|
'JobProgressAdapter',
|
||||||
]
|
]
|
||||||
|
|
||||||
classAdapterRegistry = {}
|
classAdapterRegistry = {}
|
||||||
|
|
||||||
|
|
||||||
def getAdapterRegistry():
|
def getAdapterRegistry():
|
||||||
import sys
|
import sys
|
||||||
for x in __all__:
|
for x in __all__:
|
||||||
exec('import dynamicserialize.adapters.' + x )
|
exec('import dynamicserialize.adapters.' + x )
|
||||||
m = sys.modules['dynamicserialize.adapters.' + x]
|
m = sys.modules['dynamicserialize.adapters.' + x]
|
||||||
|
@ -80,7 +82,7 @@ def getAdapterRegistry():
|
||||||
else:
|
else:
|
||||||
raise LookupError('Adapter class ' + x + ' has no ClassAdapter field ' + \
|
raise LookupError('Adapter class ' + x + ' has no ClassAdapter field ' + \
|
||||||
'and cannot be registered.')
|
'and cannot be registered.')
|
||||||
|
|
||||||
|
|
||||||
getAdapterRegistry()
|
getAdapterRegistry()
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ __all__ = [
|
||||||
'auth',
|
'auth',
|
||||||
'dataaccess',
|
'dataaccess',
|
||||||
'dataplugin',
|
'dataplugin',
|
||||||
|
'dataquery',
|
||||||
'datastorage',
|
'datastorage',
|
||||||
'localization',
|
'localization',
|
||||||
'management',
|
'management',
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# 05/22/2015 4522 randerso Initial creation
|
# 05/22/2015 4522 randerso Initial creation
|
||||||
# 03/17/2016 5426 randerso Add issueYear to primary key
|
# 03/17/2016 5426 randerso Add issueYear to primary key
|
||||||
|
# 08/03/2016 19213 ryu Add pil to primary key
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
class ActiveTableKey(object):
|
class ActiveTableKey(object):
|
||||||
|
@ -35,6 +36,7 @@ class ActiveTableKey(object):
|
||||||
self.etn = None
|
self.etn = None
|
||||||
self.ugcZone = None
|
self.ugcZone = None
|
||||||
self.issueYear = None
|
self.issueYear = None
|
||||||
|
self.pil = None
|
||||||
|
|
||||||
def getOfficeid(self):
|
def getOfficeid(self):
|
||||||
return self.officeid
|
return self.officeid
|
||||||
|
@ -71,3 +73,9 @@ class ActiveTableKey(object):
|
||||||
|
|
||||||
def setIssueYear(self, issueYear):
|
def setIssueYear(self, issueYear):
|
||||||
self.issueYear = issueYear
|
self.issueYear = issueYear
|
||||||
|
|
||||||
|
def getPil(self):
|
||||||
|
return self.pil
|
||||||
|
|
||||||
|
def setPil(self, pil):
|
||||||
|
self.pil = pil
|
||||||
|
|
|
@ -19,10 +19,11 @@
|
||||||
##
|
##
|
||||||
|
|
||||||
# File generated against equivalent DynamicSerialize Java class
|
# File generated against equivalent DynamicSerialize Java class
|
||||||
|
# Jul 27, 2016 #5769 randerso Fixed __str__ method
|
||||||
|
|
||||||
class ActiveTableMode(object):
|
class ActiveTableMode(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.value = None
|
self.value = None
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.value)
|
return str(self.value)
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# 05/22/2015 4522 randerso Initial creation (hand generated)
|
# 05/22/2015 4522 randerso Initial creation (hand generated)
|
||||||
# 03/17/2016 5426 randerso Add issueYear to primary key
|
# 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.issueTime = None
|
||||||
self.purgeTime = None
|
self.purgeTime = None
|
||||||
self.ufn = None
|
self.ufn = None
|
||||||
self.geometry = None
|
|
||||||
self.forecaster = None
|
self.forecaster = None
|
||||||
self.motdir = None
|
self.motdir = None
|
||||||
self.motspd = None
|
self.motspd = None
|
||||||
|
@ -177,12 +177,6 @@ class ActiveTableRecord(with_metaclass(abc.ABCMeta, object)):
|
||||||
def setUfn(self, ufn):
|
def setUfn(self, ufn):
|
||||||
self.ufn = ufn
|
self.ufn = ufn
|
||||||
|
|
||||||
def getGeometry(self):
|
|
||||||
return self.geometry
|
|
||||||
|
|
||||||
def setGeometry(self, geometry):
|
|
||||||
self.geometry = geometry
|
|
||||||
|
|
||||||
def getForecaster(self):
|
def getForecaster(self):
|
||||||
return self.forecaster
|
return self.forecaster
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# 07/23/14 #3185 njensen Initial Creation.
|
# 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)):
|
class AbstractIdentifierRequest(with_metaclass(abc.ABCMeta, object)):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.datatype = None
|
self.request = None
|
||||||
|
|
||||||
def getDatatype(self):
|
def getRequest(self):
|
||||||
return self.datatype
|
return self.request
|
||||||
|
|
||||||
def setDatatype(self, datatype):
|
def setRequest(self, request):
|
||||||
self.datatype = datatype
|
self.request = request
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -31,7 +31,8 @@ __all__ = [
|
||||||
'GetGridDataRequest',
|
'GetGridDataRequest',
|
||||||
'GetRequiredIdentifiersRequest',
|
'GetRequiredIdentifiersRequest',
|
||||||
'GetSupportedDatatypesRequest',
|
'GetSupportedDatatypesRequest',
|
||||||
'GetOptionalIdentifiersRequest'
|
'GetOptionalIdentifiersRequest',
|
||||||
|
'GetIdentifierValuesRequest'
|
||||||
]
|
]
|
||||||
|
|
||||||
from .AbstractDataAccessRequest import AbstractDataAccessRequest
|
from .AbstractDataAccessRequest import AbstractDataAccessRequest
|
||||||
|
@ -45,4 +46,4 @@ from .GetGridDataRequest import GetGridDataRequest
|
||||||
from .GetRequiredIdentifiersRequest import GetRequiredIdentifiersRequest
|
from .GetRequiredIdentifiersRequest import GetRequiredIdentifiersRequest
|
||||||
from .GetSupportedDatatypesRequest import GetSupportedDatatypesRequest
|
from .GetSupportedDatatypesRequest import GetSupportedDatatypesRequest
|
||||||
from .GetOptionalIdentifiersRequest import GetOptionalIdentifiersRequest
|
from .GetOptionalIdentifiersRequest import GetOptionalIdentifiersRequest
|
||||||
|
from .GetIdentifierValuesRequest import GetIdentifierValuesRequest
|
||||||
|
|
|
@ -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'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
@ -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
|
||||||
|
|
|
@ -26,7 +26,6 @@ class CopyRequest(object):
|
||||||
self.repack = None
|
self.repack = None
|
||||||
self.repackCompression = None
|
self.repackCompression = None
|
||||||
self.outputDir = None
|
self.outputDir = None
|
||||||
self.timestampCheck = None
|
|
||||||
self.minMillisSinceLastChange = None
|
self.minMillisSinceLastChange = None
|
||||||
self.maxMillisSinceLastChange = None
|
self.maxMillisSinceLastChange = None
|
||||||
self.filename = None
|
self.filename = None
|
||||||
|
@ -49,12 +48,6 @@ class CopyRequest(object):
|
||||||
def setOutputDir(self, outputDir):
|
def setOutputDir(self, outputDir):
|
||||||
self.outputDir = outputDir
|
self.outputDir = outputDir
|
||||||
|
|
||||||
def getTimestampCheck(self):
|
|
||||||
return self.timestampCheck
|
|
||||||
|
|
||||||
def setTimestampCheck(self, timestampCheck):
|
|
||||||
self.timestampCheck = timestampCheck
|
|
||||||
|
|
||||||
def getMinMillisSinceLastChange(self):
|
def getMinMillisSinceLastChange(self):
|
||||||
return self.minMillisSinceLastChange
|
return self.minMillisSinceLastChange
|
||||||
|
|
||||||
|
|
|
@ -19,21 +19,29 @@
|
||||||
##
|
##
|
||||||
|
|
||||||
# File auto-generated against equivalent DynamicSerialize Java class
|
# 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):
|
class DeleteOrphansRequest(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.oldestDateMap = None
|
||||||
self.filename = None
|
self.filename = None
|
||||||
self.oldestDate = None
|
|
||||||
|
|
||||||
def getOldestDate(self):
|
def getOldestDateMap(self):
|
||||||
return self.oldestDate
|
return self.oldestDateMap
|
||||||
|
|
||||||
def setOldestDate(self, oldestDate):
|
def setOldestDateMap(self, oldestDateMap):
|
||||||
self.oldestDate = oldestDate
|
self.oldestDateMap = oldestDateMap
|
||||||
|
|
||||||
def getFilename(self):
|
def getFilename(self):
|
||||||
return self.filename
|
return self.filename
|
||||||
|
|
||||||
def setFilename(self, filename):
|
def setFilename(self, filename):
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -24,16 +24,13 @@
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# 09/21/2015 4486 rjpeter Initial creation.
|
# 09/21/2015 4486 rjpeter Initial creation.
|
||||||
#
|
# 06/23/2016 #5696 rjpeter Extend CommutativeTimestamp
|
||||||
##
|
##
|
||||||
|
|
||||||
from time import gmtime, strftime
|
from CommutativeTimestamp import CommutativeTimestamp
|
||||||
from dynamicserialize.dstypes.java.util import Date
|
|
||||||
|
|
||||||
class FormattedDate(Date):
|
# TODO: Remove after 16.4.1 no longer in field
|
||||||
|
class FormattedDate(CommutativeTimestamp):
|
||||||
|
|
||||||
def __init__(self, timeInMillis=None):
|
def __init__(self, timeInMillis=None):
|
||||||
super(FormattedDate, self).__init__(timeInMillis)
|
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)
|
|
||||||
|
|
|
@ -23,10 +23,11 @@
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'DataTime',
|
'DataTime',
|
||||||
'TimeRange',
|
'TimeRange',
|
||||||
'FormattedDate'
|
'FormattedDate',
|
||||||
|
'CommutativeTimestamp'
|
||||||
]
|
]
|
||||||
|
|
||||||
from .DataTime import DataTime
|
from .DataTime import DataTime
|
||||||
from .TimeRange import TimeRange
|
from .TimeRange import TimeRange
|
||||||
from .FormattedDate import FormattedDate
|
from .FormattedDate import FormattedDate
|
||||||
|
from .CommutativeTimestamp import CommutativeTimestamp
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
# File auto-generated against equivalent DynamicSerialize Java class
|
# File auto-generated against equivalent DynamicSerialize Java class
|
||||||
#
|
#
|
||||||
# SOFTWARE HISTORY
|
# SOFTWARE HISTORY
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# May 05, 2016 root Generated
|
# May 05, 2016 root Generated
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
# File auto-generated against equivalent DynamicSerialize Java class
|
# File auto-generated against equivalent DynamicSerialize Java class
|
||||||
#
|
#
|
||||||
# SOFTWARE HISTORY
|
# SOFTWARE HISTORY
|
||||||
#
|
#
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# May 06, 2016 root Generated
|
# May 06, 2016 root Generated
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
# File auto-generated against equivalent DynamicSerialize Java class
|
# File auto-generated against equivalent DynamicSerialize Java class
|
||||||
#
|
#
|
||||||
# SOFTWARE HISTORY
|
# SOFTWARE HISTORY
|
||||||
#
|
#
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# May 06, 2016 root Generated
|
# May 06, 2016 root Generated
|
||||||
|
|
|
@ -20,20 +20,24 @@
|
||||||
|
|
||||||
# File auto-generated against equivalent DynamicSerialize Java class
|
# File auto-generated against equivalent DynamicSerialize Java class
|
||||||
# and then modified post-generation to add additional features to better
|
# 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
|
# SOFTWARE HISTORY
|
||||||
#
|
#
|
||||||
# Date Ticket# Engineer Description
|
# Date Ticket# Engineer Description
|
||||||
# ------------ ---------- ----------- --------------------------
|
# ------------ ---------- ----------- --------------------------
|
||||||
# ??/??/?? xxxxxxxx Initial Creation.
|
# ??/??/?? 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 dynamicserialize.dstypes.java.util import Date
|
||||||
|
from time import gmtime, strftime
|
||||||
|
|
||||||
class Timestamp(Date):
|
class Timestamp(Date):
|
||||||
|
|
||||||
def __init__(self, time=None):
|
def __init__(self, time=None):
|
||||||
super(Timestamp, self).__init__(time)
|
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)
|
||||||
|
|
6
setup.py
6
setup.py
|
@ -3,12 +3,12 @@ from setuptools import find_packages
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='python-awips',
|
name='python-awips',
|
||||||
version='0.9.7',
|
version='0.9.8',
|
||||||
description='A framework for requesting AWIPS meteorological datasets from an EDEX server',
|
description='A framework for requesting AWIPS meteorological datasets from an EDEX server',
|
||||||
packages=find_packages(exclude='data'),
|
packages=find_packages(exclude='data'),
|
||||||
license='Open Source',
|
license='Open Source',
|
||||||
url='http://www.unidata.ucar.edu/software/awips2',
|
url='http://python-awips.readthedocs.io',
|
||||||
download_url='https://github.com/Unidata/python-awips/tarball/0.9.7',
|
download_url='https://github.com/Unidata/python-awips/tarball/0.9.8',
|
||||||
author='Unidata',
|
author='Unidata',
|
||||||
author_email='mjames@ucar.edu',
|
author_email='mjames@ucar.edu',
|
||||||
requires=['argparse','shapely','numpy','six']
|
requires=['argparse','shapely','numpy','six']
|
||||||
|
|
Loading…
Add table
Reference in a new issue