Skip to content

Commit e0e63e5

Browse files
Copilotalvarolopez
andcommitted
Fix AttributeError when user is None in nova extractor
Co-authored-by: alvarolopez <468751+alvarolopez@users.noreply.github.com>
1 parent ddd5ef9 commit e0e63e5

File tree

2 files changed

+67
-3
lines changed

2 files changed

+67
-3
lines changed

caso/extract/openstack/nova.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ def _build_record(self, server):
227227
# Filter out non-ascii characters for APEL compatibility.
228228
vm_name = server.name.encode("ascii", errors="ignore")
229229
local_user_id = server.user_id.encode("ascii", errors="ignore")
230-
global_username = user.encode("ascii", errors="ignore")
230+
global_username = user.encode("ascii", errors="ignore") if user else None
231231

232232
r = record.CloudRecord(
233233
uuid=server.id,

caso/tests/extract/test_nova.py

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414

1515
"""Tests for the OpenStack nova extractor."""
1616

17-
from caso.extract.openstack import nova
18-
17+
import datetime
1918
import unittest
19+
from unittest import mock
20+
21+
from caso.extract.openstack import nova
2022

2123

2224
class 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

Comments
 (0)