SIENTIAPDE-1445
Invert startTime and endTime parameters in PIWebAPIClient to ensure descending order results. Update tests to verify parameter handling and use pytest.approx for floating-point comparisons.
This commit is contained in:
@@ -287,14 +287,17 @@ class PIWebAPIClient(SientiaMonitoring):
|
|||||||
|
|
||||||
# Build query parameters with WebIds (filtering out None values)
|
# Build query parameters with WebIds (filtering out None values)
|
||||||
params: list[tuple[str, str]] = [('webid', web_id['webid']) for web_id in web_ids.values()]
|
params: list[tuple[str, str]] = [('webid', web_id['webid']) for web_id in web_ids.values()]
|
||||||
|
# Invert startTime and endTime to get descending order (most recent first)
|
||||||
|
# PI Web API returns descending order when endTime < startTime
|
||||||
params.extend(
|
params.extend(
|
||||||
[
|
[
|
||||||
('startTime', start_time),
|
('startTime', end_time), # Use end_time as startTime (inverted)
|
||||||
('endtime', end_time),
|
('endtime', start_time), # Use start_time as endTime (inverted)
|
||||||
('selectedFields', 'Items.Name;Items.Items.Timestamp;Items.Items.Value'),
|
('selectedFields', 'Items.Name;Items.Items.Timestamp;Items.Items.Value'),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if max_count is not None:
|
||||||
params.append(('maxCount', str(max_count)))
|
params.append(('maxCount', str(max_count)))
|
||||||
|
|
||||||
data = await self._curl_get_json(
|
data = await self._curl_get_json(
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ async def test_get_tag_values_success(api_activity):
|
|||||||
|
|
||||||
assert len(result) == 3
|
assert len(result) == 3
|
||||||
assert result[0]['name'] == 'tag1'
|
assert result[0]['name'] == 'tag1'
|
||||||
assert result[0]['value'] == 10.5
|
assert result[0]['value'] == pytest.approx(10.5)
|
||||||
assert result[1]['name'] == 'tag2'
|
assert result[1]['name'] == 'tag2'
|
||||||
assert result[2]['name'] == 'tag3'
|
assert result[2]['name'] == 'tag3'
|
||||||
assert result[0]['timestamp'] == '2023-01-01 12:02:00+0000'
|
assert result[0]['timestamp'] == '2023-01-01 12:02:00+0000'
|
||||||
@@ -332,6 +332,6 @@ async def test_get_tag_values_with_nan_values(api_activity):
|
|||||||
|
|
||||||
# Verify
|
# Verify
|
||||||
assert len(result) == 2
|
assert len(result) == 2
|
||||||
assert result[0]['value'] == 10.0
|
assert result[0]['value'] == pytest.approx(10.0)
|
||||||
# NaN should be preserved in the result
|
# NaN should be preserved in the result
|
||||||
assert pd.isna(result[1]['value'])
|
assert pd.isna(result[1]['value'])
|
||||||
|
|||||||
@@ -164,28 +164,28 @@ def test_extract_numeric_with_float(pi_client):
|
|||||||
"""Test extracting numeric value from float"""
|
"""Test extracting numeric value from float"""
|
||||||
result = pi_client._extract_numeric(42.5)
|
result = pi_client._extract_numeric(42.5)
|
||||||
|
|
||||||
assert result == 42.5
|
assert result == pytest.approx(42.5)
|
||||||
|
|
||||||
|
|
||||||
def test_extract_numeric_with_int(pi_client):
|
def test_extract_numeric_with_int(pi_client):
|
||||||
"""Test extracting numeric value from int"""
|
"""Test extracting numeric value from int"""
|
||||||
result = pi_client._extract_numeric(42)
|
result = pi_client._extract_numeric(42)
|
||||||
|
|
||||||
assert result == 42.0
|
assert result == pytest.approx(42.0)
|
||||||
|
|
||||||
|
|
||||||
def test_extract_numeric_with_string(pi_client):
|
def test_extract_numeric_with_string(pi_client):
|
||||||
"""Test extracting numeric value from string"""
|
"""Test extracting numeric value from string"""
|
||||||
result = pi_client._extract_numeric('123.45')
|
result = pi_client._extract_numeric('123.45')
|
||||||
|
|
||||||
assert result == 123.45
|
assert result == pytest.approx(123.45)
|
||||||
|
|
||||||
|
|
||||||
def test_extract_numeric_with_dict(pi_client):
|
def test_extract_numeric_with_dict(pi_client):
|
||||||
"""Test extracting numeric value from dictionary"""
|
"""Test extracting numeric value from dictionary"""
|
||||||
result = pi_client._extract_numeric({'Value': 99.9})
|
result = pi_client._extract_numeric({'Value': 99.9})
|
||||||
|
|
||||||
assert result == 99.9
|
assert result == pytest.approx(99.9)
|
||||||
|
|
||||||
|
|
||||||
def test_extract_numeric_with_invalid_value(pi_client):
|
def test_extract_numeric_with_invalid_value(pi_client):
|
||||||
@@ -436,9 +436,9 @@ async def test_get_latest_values_df_with_custom_params(mock_curl_get_json, pi_cl
|
|||||||
call_args = mock_curl_get_json.call_args
|
call_args = mock_curl_get_json.call_args
|
||||||
params = call_args[1]['params']
|
params = call_args[1]['params']
|
||||||
|
|
||||||
# Verify parameters
|
# Verify parameters (inverted: startTime uses end_time, endTime uses start_time)
|
||||||
assert ('startTime', '*-7d') in params
|
assert ('startTime', '*-1d') in params
|
||||||
assert ('endtime', '*-1d') in params
|
assert ('endtime', '*-7d') in params
|
||||||
assert ('maxCount', '100') in params
|
assert ('maxCount', '100') in params
|
||||||
assert call_args[1]['timeout'] == 60
|
assert call_args[1]['timeout'] == 60
|
||||||
assert call_args[1]['metadata'] == metadata
|
assert call_args[1]['metadata'] == metadata
|
||||||
@@ -558,3 +558,31 @@ async def test_get_latest_values_df_default_max_count(mock_curl_get_json, pi_cli
|
|||||||
params = call_args[1]['params']
|
params = call_args[1]['params']
|
||||||
|
|
||||||
assert ('maxCount', '1') in params
|
assert ('maxCount', '1') in params
|
||||||
|
# Verify default time parameters are inverted (startTime uses end_time default, endTime uses start_time default)
|
||||||
|
assert ('startTime', '*') in params # Default end_time
|
||||||
|
assert ('endtime', '*-1d') in params # Default start_time
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@patch.object(PIWebAPIClient, '_curl_get_json', new_callable=AsyncMock)
|
||||||
|
async def test_get_latest_values_df_with_none_max_count(mock_curl_get_json, pi_client):
|
||||||
|
"""Test get_latest_values_df does not send maxCount parameter when max_count is None"""
|
||||||
|
mock_curl_get_json.return_value = {'Items': []}
|
||||||
|
|
||||||
|
web_ids = {'tag1': {'webid': 'webid1'}}
|
||||||
|
|
||||||
|
await pi_client.get_latest_values_df(
|
||||||
|
web_ids=web_ids,
|
||||||
|
endpoint='/streamsets/recorded',
|
||||||
|
max_count=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
call_args = mock_curl_get_json.call_args
|
||||||
|
params = call_args[1]['params']
|
||||||
|
|
||||||
|
# Verify maxCount parameter is not present when max_count is None
|
||||||
|
assert ('maxCount', '1') not in params
|
||||||
|
assert ('maxCount', None) not in params
|
||||||
|
# Verify time parameters are still present
|
||||||
|
assert ('startTime', '*') in params
|
||||||
|
assert ('endtime', '*-1d') in params
|
||||||
|
|||||||
Reference in New Issue
Block a user