Skip to content

Commit

Permalink
Increase Cloudadapter unit test coverage back to 90 percent
Browse files Browse the repository at this point in the history
  • Loading branch information
nmgaston committed Oct 1, 2024
1 parent 2bd9a5e commit 48ffb31
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
import json
import unittest
import mock
from unittest.mock import MagicMock
Expand All @@ -11,6 +12,36 @@
from cloudadapter.cloud.adapters.azure_adapter import AzureAdapter
from time import time

#class TestAzureAdapterFailures(unittest.TestCase):
# @mock.patch('cloudadapter.cloud.adapters.azure_adapter.requests.put')
# @mock.patch('cloudadapter.cloud.adapters.azure_adapter.requests.get')
# def test_configure_json_decode_error(self, mock_get, mock_put):
# # Set up the AzureAdapter with some dummy configs
# configs = {
# "scope_id": "test_scope_id",
# "device_id": "test_device_id",
# "device_sas_key": "test_device_sas_key"
# }
# adapter = AzureAdapter(configs)

# # Mock the put request to return a response with invalid JSON content
# mock_put_response = MagicMock()
# mock_put_response.ok = True
# mock_put_response.text = "Invalid JSON"
# mock_put.return_value = mock_put_response

# # Mock the get request to return a response with valid JSON content
# # This is necessary because the configure method may call get after put
# mock_get_response = MagicMock()
# mock_get_response.ok = True
# mock_get_response.text = json.dumps({"status": "assigned", "registrationState": {"assignedHub": "test_hub"}})
# mock_get.return_value = mock_get_response

# with self.assertRaises(AdapterConfigureError) as context:
# adapter.configure(configs)

# # Check that the exception message contains the expected text
# self.assertIn("Error retrieving hostname", str(context.exception))

class TestAzureAdapter(unittest.TestCase):

Expand Down Expand Up @@ -50,6 +81,66 @@ def setUp(self, mock_build_client_with_config, MockCloudClient, _mock_retrieve_h
self.azure_adapter = AzureAdapter(self.CONFIG)
self.azure_adapter.configure(self.CONFIG)

@mock.patch('cloudadapter.cloud.adapters.azure_adapter.requests.put')
@mock.patch('cloudadapter.cloud.adapters.azure_adapter.requests.get')
def test_configure_json_decode_error(self, mock_get, mock_put):
# Mock the put request to return a response with invalid JSON content
mock_put_response = MagicMock()
mock_put_response.ok = True
mock_put_response.text = "Invalid JSON"
mock_put.return_value = mock_put_response

# Mock the get request to return a response with valid JSON content
# This is necessary because the configure method may call get after put
mock_get_response = MagicMock()
mock_get_response.ok = True
mock_get_response.text = json.dumps({"status": "assigned", "registrationState": {"assignedHub": "test_hub"}})
mock_get.return_value = mock_get_response

with self.assertRaises(AdapterConfigureError) as context:
self.azure_adapter.configure(self.CONFIG)

# Check that the exception message contains the expected text
self.assertIn("Error retrieving hostname", str(context.exception))

@mock.patch('cloudadapter.cloud.adapters.azure_adapter.requests.put')
@mock.patch('cloudadapter.cloud.adapters.azure_adapter.requests.get')
def test_retrieve_hostname_while_loop(self, mock_get, mock_put):
# Mock the put request to return a response indicating the device is being assigned
assigning_response = {
"status": "assigning",
"operationId": "test_operation_id"
}
mock_put_response = MagicMock()
mock_put_response.ok = True
mock_put_response.text = json.dumps(assigning_response)
mock_put.return_value = mock_put_response

# Mock the get request to return "assigning" status twice, then "assigned"
assigning_get_response = MagicMock()
assigning_get_response.ok = True
assigning_get_response.text = json.dumps(assigning_response)

assigned_response = {
"status": "assigned",
"registrationState": {"assignedHub": "test_hub"}
}
assigned_get_response = MagicMock()
assigned_get_response.ok = True
assigned_get_response.text = json.dumps(assigned_response)

# Set up the side_effect for the get mock to return "assigning" twice, then "assigned"
mock_get.side_effect = [assigning_get_response, assigning_get_response, assigned_get_response]

# Call the _retrieve_hostname method
hostname = self.azure_adapter._retrieve_hostname(self.CONFIG['scope_id'], self.CONFIG['device_id'], {'sas_key': self.CONFIG['device_sas_key']}, None)

# Assert that the hostname is as expected
self.assertEqual(hostname, "test_hub")

# Assert that the get request was called three times
self.assertEqual(mock_get.call_count, 3)

@mock.patch.object(AzureAdapter, '_retrieve_hostname', autospec=True)
@mock.patch('cloudadapter.cloud.client.cloud_client.CloudClient', autospec=True)
@mock.patch(
Expand All @@ -71,7 +162,7 @@ def test_sas_configure_succeeds(
self.azure_adapter.configure(self.SAS_CONFIG)
assert mock_get_sas_token.call_count == 1
assert mock_build_client_with_config.call_count == 1

@mock.patch('base64.b64encode', autospec=True)
@mock.patch('future.moves.urllib.request.quote', autospec=True)
def test_generate_sas_token(self, mock_quote, mock_base64encode) -> None:
Expand Down
19 changes: 19 additions & 0 deletions inbm/cloudadapter-agent/tests/unit/cloud/test_adapter_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""


import json
import unittest
import mock

Expand Down Expand Up @@ -35,6 +36,24 @@ def test_islink_error(self, mock_islink) -> None:
str(context.exception),
)

@mock.patch('cloudadapter.cloud.adapter_factory.load_adapter_config')
def test_get_adapter_config_filepaths_with_auxiliary_files(self, mock_load):
mock_load.return_value = {
"auxiliary_files": ["aux_file_1.json", "aux_file_2.json"]
}
filepaths = adapter_factory.get_adapter_config_filepaths()
self.assertIn("aux_file_1.json", filepaths)
self.assertIn("aux_file_2.json", filepaths)
self.assertIn(ADAPTER_CONFIG_PATH, filepaths)

@mock.patch("os.path.islink", return_value=False)
@mock.patch("builtins.open")
def test_load_adapter_config_success(self, mock_open, mock_islink) -> None:
mock_data = json.dumps({'key': 'value'})
mock_open.return_value.__enter__.return_value.read.return_value = mock_data
result = load_adapter_config()
self.assertEqual(result, {'key': 'value'})

@mock.patch('cloudadapter.cloud.adapter_factory.AzureAdapter')
@mock.patch('cloudadapter.cloud.adapter_factory.load_adapter_config', autospec=True)
def test_get_adapter_azure_succeeds(self, mock_load_adapter_config, MockAzureAdapter) -> None:
Expand Down
2 changes: 1 addition & 1 deletion inbm/dispatcher-agent/dispatcher/dispatcher_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ def _on_cloud_request(self, topic: str, payload: str, qos: int) -> None:
request_type = topic.split('/')[2]
request_id = topic.split('/')[3] if len(topic.split('/')) > 3 else None
manifest = payload
self._add_cmd_to_queue(request_type, manifest, request_id)
self._add_request_to_queue(request_type, manifest, request_id)

def _on_message(self, topic: str, payload: Any, qos: int) -> None:
"""Called when a message is received from _telemetry-agent
Expand Down
2 changes: 1 addition & 1 deletion inbm/dockerfiles/Dockerfile-check.m4
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ RUN source /venv-py3/bin/activate && \
mkdir -p /output/coverage && \
set -o pipefail && \
export PYTHONPATH=$PYTHONPATH:$(pwd) && \
pytest --timeout=10 -n 10 --cov=cloudadapter --cov-report=term-missing --cov-fail-under=89 tests/unit 2>&1 | tee /output/coverage/cloudadapter-coverage.txt
pytest --timeout=10 -n 10 --cov=cloudadapter --cov-report=term-missing --cov-fail-under=90 tests/unit 2>&1 | tee /output/coverage/cloudadapter-coverage.txt

# ---telemetry agent---

Expand Down

0 comments on commit 48ffb31

Please sign in to comment.