@@ -59,6 +59,12 @@ def sample_data():
5959 }
6060
6161
62+ @pytest .fixture
63+ def sample_metadata ():
64+ """Sample metadata for testing ingestion."""
65+ return {"policy_name" : "test-policy" , "hostname" : "router1" }
66+
67+
6268@pytest .fixture
6369def mock_version_semver ():
6470 """Mock the version_semver function."""
@@ -73,6 +79,13 @@ def mock_diode_client_class():
7379 yield mock
7480
7581
82+ @pytest .fixture
83+ def mock_diode_otlp_client_class ():
84+ """Mock the DiodeOTLPClient class."""
85+ with patch ("device_discovery.client.DiodeOTLPClient" ) as mock :
86+ yield mock
87+
88+
7689def test_init_client (mock_diode_client_class , mock_version_semver ):
7790 """Test the initialization of the Diode client."""
7891 client = Client ()
@@ -92,7 +105,7 @@ def test_init_client(mock_diode_client_class, mock_version_semver):
92105 )
93106
94107
95- def test_ingest_success (mock_diode_client_class , sample_data ):
108+ def test_ingest_success (mock_diode_client_class , sample_data , sample_metadata ):
96109 """Test successful data ingestion."""
97110 client = Client ()
98111 client .init_client (
@@ -101,18 +114,20 @@ def test_ingest_success(mock_diode_client_class, sample_data):
101114
102115 mock_diode_instance = mock_diode_client_class .return_value
103116 mock_diode_instance .ingest .return_value .errors = []
104- hostname = sample_data ["device" ]["hostname" ]
105-
117+ metadata = sample_metadata
106118 with patch (
107119 "device_discovery.client.translate_data" ,
108120 return_value = translate_data (sample_data ),
109121 ) as mock_translate_data :
110- client .ingest (hostname , sample_data )
122+ client .ingest (metadata , sample_data )
111123 mock_translate_data .assert_called_once_with (sample_data )
112- mock_diode_instance .ingest .assert_called_once ()
124+ mock_diode_instance .ingest .assert_called_once_with (
125+ entities = mock_translate_data .return_value ,
126+ metadata = metadata ,
127+ )
113128
114129
115- def test_ingest_failure (mock_diode_client_class , sample_data ):
130+ def test_ingest_failure (mock_diode_client_class , sample_data , sample_metadata ):
116131 """Test data ingestion with errors."""
117132 client = Client ()
118133 client .init_client (
@@ -124,25 +139,27 @@ def test_ingest_failure(mock_diode_client_class, sample_data):
124139
125140 mock_diode_instance = mock_diode_client_class .return_value
126141 mock_diode_instance .ingest .return_value .errors = ["Error1" , "Error2" ]
127- hostname = sample_data ["device" ]["hostname" ]
128-
142+ metadata = sample_metadata
129143 with patch (
130144 "device_discovery.client.translate_data" ,
131145 return_value = translate_data (sample_data ),
132146 ) as mock_translate_data :
133- client .ingest (hostname , sample_data )
147+ client .ingest (metadata , sample_data )
134148 mock_translate_data .assert_called_once_with (sample_data )
135- mock_diode_instance .ingest .assert_called_once ()
149+ mock_diode_instance .ingest .assert_called_once_with (
150+ entities = mock_translate_data .return_value ,
151+ metadata = metadata ,
152+ )
136153
137154 assert len (mock_diode_instance .ingest .return_value .errors ) > 0
138155
139156
140- def test_ingest_without_initialization ():
157+ def test_ingest_without_initialization (sample_metadata ):
141158 """Test ingestion without client initialization raises ValueError."""
142159 Client ._instance = None # Reset the Client singleton instance
143160 client = Client ()
144161 with pytest .raises (ValueError , match = "Diode client not initialized" ):
145- client .ingest ("" , {})
162+ client .ingest (sample_metadata , {})
146163
147164
148165def test_client_dry_run (tmp_path , sample_data ):
@@ -154,7 +171,8 @@ def test_client_dry_run(tmp_path, sample_data):
154171 dry_run_output_dir = tmp_path ,
155172 )
156173 hostname = sample_data ["device" ]["hostname" ]
157- client .ingest (hostname , sample_data )
174+ metadata = {"policy_name" : "dry-run-policy" , "hostname" : hostname }
175+ client .ingest (metadata , sample_data )
158176 files = list (tmp_path .glob ("prefix_device-discovery*.json" ))
159177
160178 assert len (files ) == 1
@@ -174,8 +192,24 @@ def test_client_dry_run_stdout(capsys, sample_data):
174192 )
175193
176194 hostname = sample_data ["device" ]["hostname" ]
177- client .ingest (hostname , sample_data )
195+ metadata = {"policy_name" : "dry-run-policy" , "hostname" : hostname }
196+ client .ingest (metadata , sample_data )
178197
179198 captured = capsys .readouterr ()
180199 assert sample_data ["device" ]["hostname" ] in captured .out
181200 assert sample_data ["interface" ]["GigabitEthernet0/0" ]["mac_address" ] in captured .out
201+
202+
203+ def test_init_client_uses_otlp_when_credentials_missing (
204+ mock_diode_client_class , mock_diode_otlp_client_class , mock_version_semver
205+ ):
206+ """Ensure init_client falls back to DiodeOTLPClient when credentials are not provided."""
207+ client = Client ()
208+ client .init_client (prefix = "prefix" , target = "https://example.com" )
209+
210+ assert not mock_diode_client_class .called
211+ mock_diode_otlp_client_class .assert_called_once_with (
212+ target = "https://example.com" ,
213+ app_name = "prefix/device-discovery" ,
214+ app_version = mock_version_semver (),
215+ )
0 commit comments