From 8e17725510351a2fa377334aaa3c3ac7a6ab58e1 Mon Sep 17 00:00:00 2001 From: Erick Daniszewski Date: Fri, 10 Sep 2021 11:52:07 -0400 Subject: [PATCH] bugfix: convert NaN to None when parsing readings [VIO-1369] --- synse_server/cmd/read.py | 12 ++++++++++++ tests/unit/cmd/test_read.py | 31 ++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/synse_server/cmd/read.py b/synse_server/cmd/read.py index 76635d47..94ad6699 100644 --- a/synse_server/cmd/read.py +++ b/synse_server/cmd/read.py @@ -1,5 +1,6 @@ import asyncio +import math import queue import threading from typing import Any, AsyncIterable, Dict, List, Optional, Union @@ -32,6 +33,17 @@ def reading_to_dict(reading: api.V3Reading) -> Dict[str, Any]: if field is not None: value = getattr(reading, field) + # Ensure the value is not NaN, as NaN is not a part of the + # JSON spec and could cause clients to error. + try: + float(value) + except ValueError: + # Not a real number, nothing to do. + pass + else: + if math.isnan(value): + value = None + if not reading.unit or (reading.unit.symbol == '' and reading.unit.name == ''): unit = None else: diff --git a/tests/unit/cmd/test_read.py b/tests/unit/cmd/test_read.py index 0906738d..f92dd473 100644 --- a/tests/unit/cmd/test_read.py +++ b/tests/unit/cmd/test_read.py @@ -2,7 +2,7 @@ import asynctest import pytest -from synse_grpc import client +from synse_grpc import api, client from synse_server import cmd, errors, plugin from synse_server.cmd.read import reading_to_dict @@ -675,3 +675,32 @@ def test_reading_to_dict_3(state_reading): 'unit': None, 'context': {}, } + + +def test_reading_to_dict_4_nan(state_reading): + """Handle NaN when converting the gRPC message to JSON, as NaN is not + part of the JSON spec. NaN should be converted to None. + + Regression for: https://vaporio.atlassian.net/browse/VIO-1369 + """ + + msg = api.V3Reading( + id='ddd', + timestamp='2019-04-22T13:30:00Z', + type='temperature', + deviceType='temperature', + deviceInfo='Example Temperature Device', + float64_value=float('nan'), + ) + + actual = reading_to_dict(msg) + assert actual == { + 'device': 'ddd', + 'timestamp': '2019-04-22T13:30:00Z', + 'type': 'temperature', + 'device_type': 'temperature', + 'device_info': 'Example Temperature Device', + 'value': None, + 'unit': None, + 'context': {}, + }