1414
1515"""Tests for the OpenStack nova extractor."""
1616
17- from caso .extract .openstack import nova
18-
17+ import datetime
1918import unittest
19+ from unittest import mock
20+
21+ from caso .extract .openstack import nova
2022
2123
2224class TestCasoManager (unittest .TestCase ):
@@ -33,3 +35,65 @@ def tearDown(self):
3335 self .reset_flags ()
3436
3537 super (TestCasoManager , self ).tearDown ()
38+
39+
40+ class TestNovaBuildRecord (unittest .TestCase ):
41+ """Test case for Nova _build_record method."""
42+
43+ @mock .patch ("caso.extract.openstack.nova.CONF" )
44+ def test_build_record_with_none_user (self , mock_conf ):
45+ """Test that _build_record handles None user without AttributeError."""
46+ # Setup mocks
47+ mock_conf .site_name = "test-site"
48+ mock_conf .service_name = "test-service"
49+ mock_conf .benchmark .name_key = "benchmark_name"
50+ mock_conf .benchmark .value_key = "benchmark_value"
51+
52+ # Create a mock extractor with None user
53+ with mock .patch .object (nova .NovaExtractor , "__init__" , lambda x , y , z : None ):
54+ extractor = nova .NovaExtractor (None , None )
55+ extractor .vo = "test-vo"
56+
57+ # Mock the users dictionary to return None
58+ extractor .users = {"test-user-id" : None }
59+
60+ # Mock flavors and images
61+ extractor .flavors = {
62+ "test-flavor-id" : {
63+ "ram" : 2048 ,
64+ "vcpus" : 2 ,
65+ "disk" : 20 ,
66+ "OS-FLV-EXT-DATA:ephemeral" : 0 ,
67+ "extra" : {},
68+ }
69+ }
70+ extractor .images = {}
71+
72+ # Create a mock server object
73+ mock_server = mock .MagicMock ()
74+ mock_server .id = "550e8400-e29b-41d4-a716-446655440000"
75+ mock_server .name = "test-server"
76+ mock_server .user_id = "test-user-id"
77+ mock_server .tenant_id = "test-tenant-id"
78+ mock_server .status = "ACTIVE"
79+ mock_server .image = {"id" : "test-image-id" }
80+ mock_server .flavor = {"id" : "test-flavor-id" }
81+ mock_server .created = "2023-01-01T00:00:00.000000"
82+
83+ # Mock methods
84+ start_dt = datetime .datetime (2023 , 1 , 1 )
85+ end_dt = datetime .datetime (2023 , 1 , 2 )
86+ with mock .patch .object (
87+ extractor , "_get_server_start" , return_value = start_dt
88+ ):
89+ with mock .patch .object (
90+ extractor , "_get_server_end" , return_value = end_dt
91+ ):
92+ with mock .patch .object (
93+ extractor , "_count_ips_on_server" , return_value = 0
94+ ):
95+ # This should not raise AttributeError
96+ record = extractor ._build_record (mock_server )
97+
98+ # Verify the record was created with user_dn=None
99+ self .assertIsNone (record .user_dn )
0 commit comments