Skip to content

Commit 555d7df

Browse files
authored
Remove S101 Ruff Rule in tests (#29)
* Ignore: S101 ruff rule in tests * Remove: unused variable * Apply: ruff check
1 parent 88d11c1 commit 555d7df

File tree

7 files changed

+115
-61
lines changed

7 files changed

+115
-61
lines changed

pyproject.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ python_functions = ["test_*"]
3939
[tool.ruff]
4040
line-length = 79
4141
exclude = [
42-
"tests",
4342
"docs",
4443
]
4544

@@ -57,5 +56,10 @@ ignore = ["C901", "E501"]
5756
lines-after-imports = 2
5857
no-sections = true
5958

59+
[tool.ruff.lint.per-file-ignores]
60+
"tests/*" = [
61+
"S101",
62+
]
63+
6064
[tool.ruff.lint.pydocstyle]
6165
convention = "google"

src/openstack_mcp_server/tools/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ def register_tool(mcp: FastMCP):
66
Register Openstack MCP tools.
77
"""
88
from .glance_tools import GlanceTools
9-
from .nova_tools import NovaTools
109
from .keystone_tools import KeystoneTools
10+
from .nova_tools import NovaTools
1111

1212
NovaTools().register_tools(mcp)
1313
GlanceTools().register_tools(mcp)

src/openstack_mcp_server/tools/keystone_tools.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
from .base import get_openstack_conn
12
from fastmcp import FastMCP
23
from pydantic import BaseModel
3-
from .base import get_openstack_conn
4+
45

56
# NOTE: In openstacksdk, all of the fields are optional.
67
# In this case, we are only using description field as optional.
78
class Region(BaseModel):
89
id: str
910
description: str | None = None
1011

12+
1113
class KeystoneTools:
1214
"""
1315
A class to encapsulate Keystone-related tools and utilities.
@@ -24,29 +26,30 @@ def register_tools(self, mcp: FastMCP):
2426
def get_regions(self) -> list[Region]:
2527
"""
2628
Get the list of Keystone regions.
27-
29+
2830
:return: A list of Region objects representing the regions.
2931
"""
3032
conn = get_openstack_conn()
3133

3234
region_list = []
3335
for region in conn.identity.regions():
34-
region_list.append(Region(id=region.id, description=region.description))
35-
36+
region_list.append(
37+
Region(id=region.id, description=region.description)
38+
)
39+
3640
return region_list
37-
41+
3842
def create_region(self, id: str, description: str | None = None) -> Region:
3943
"""
4044
Create a new region.
41-
45+
4246
:param id: The ID of the region.
4347
:param description: The description of the region. It can be None.
44-
48+
4549
:return: The created Region object.
4650
"""
4751
conn = get_openstack_conn()
4852

4953
region = conn.identity.create_region(id=id, description=description)
5054

5155
return Region(id=region.id, description=region.description)
52-

tests/conftest.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def mock_get_openstack_conn():
1010
with patch(
1111
"openstack_mcp_server.tools.nova_tools.get_openstack_conn",
1212
return_value=mock_conn
13-
) as mock_func:
13+
):
1414
yield mock_conn
1515

1616

@@ -22,7 +22,7 @@ def mock_get_openstack_conn_glance():
2222
with patch(
2323
"openstack_mcp_server.tools.glance_tools.get_openstack_conn",
2424
return_value=mock_conn
25-
) as mock_func:
25+
):
2626
yield mock_conn
2727

2828
@pytest.fixture
@@ -33,7 +33,7 @@ def mock_get_openstack_conn_keystone():
3333
with patch(
3434
"openstack_mcp_server.tools.keystone_tools.get_openstack_conn",
3535
return_value=mock_conn
36-
) as mock_func:
36+
):
3737
yield mock_conn
3838

3939
@pytest.fixture
@@ -44,5 +44,5 @@ def mock_openstack_base():
4444
with patch(
4545
"openstack_mcp_server.tools.base.get_openstack_conn",
4646
return_value=mock_conn
47-
) as mock_func:
47+
):
4848
yield mock_conn

tests/tools/test_glance_tools.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import pytest
2-
from unittest.mock import Mock
31
from openstack_mcp_server.tools.glance_tools import GlanceTools
2+
from unittest.mock import Mock
43

54

65
class TestGlanceTools:
@@ -38,7 +37,9 @@ def test_get_glance_images_success(self, mock_get_openstack_conn_glance):
3837
# Verify mock calls
3938
mock_conn.image.images.assert_called_once()
4039

41-
def test_get_glance_images_empty_list(self, mock_get_openstack_conn_glance):
40+
def test_get_glance_images_empty_list(
41+
self, mock_get_openstack_conn_glance
42+
):
4243
"""Test getting glance images when no images exist."""
4344
mock_conn = mock_get_openstack_conn_glance
4445

@@ -53,7 +54,9 @@ def test_get_glance_images_empty_list(self, mock_get_openstack_conn_glance):
5354

5455
mock_conn.image.images.assert_called_once()
5556

56-
def test_get_glance_images_with_empty_name(self, mock_get_openstack_conn_glance):
57+
def test_get_glance_images_with_empty_name(
58+
self, mock_get_openstack_conn_glance
59+
):
5760
"""Test images with empty or None names."""
5861
mock_conn = mock_get_openstack_conn_glance
5962

@@ -76,4 +79,4 @@ def test_get_glance_images_with_empty_name(self, mock_get_openstack_conn_glance)
7679
assert "normal-image (img-normal) - Status: active" in result
7780
assert " (img-empty-name) - Status: active" in result # Empty name
7881

79-
mock_conn.image.images.assert_called_once()
82+
mock_conn.image.images.assert_called_once()

tests/tools/test_keystone_tools.py

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
import pytest
2-
from unittest.mock import Mock
32
from openstack import exceptions
43
from openstack_mcp_server.tools.keystone_tools import KeystoneTools, Region
4+
from unittest.mock import Mock
5+
56

67
class TestKeystoneTools:
78
"""Test cases for KeystoneTools class."""
89

910
def get_keystone_tools(self) -> KeystoneTools:
1011
"""Get an instance of KeystoneTools."""
1112
return KeystoneTools()
12-
13+
1314
def test_get_regions_success(self, mock_get_openstack_conn_keystone):
1415
"""Test getting keystone regions successfully."""
1516
mock_conn = mock_get_openstack_conn_keystone
16-
17+
1718
# Create mock region objects
1819
mock_region1 = Mock()
1920
mock_region1.id = "RegionOne"
@@ -22,32 +23,34 @@ def test_get_regions_success(self, mock_get_openstack_conn_keystone):
2223
mock_region2 = Mock()
2324
mock_region2.id = "RegionTwo"
2425
mock_region2.description = "Region Two description"
25-
26+
2627
# Configure mock region.regions()
2728
mock_conn.identity.regions.return_value = [mock_region1, mock_region2]
2829

2930
# Test get_regions()
3031
keystone_tools = self.get_keystone_tools()
3132
result = keystone_tools.get_regions()
32-
33+
3334
# Verify results
34-
assert result == [Region(id="RegionOne", description="Region One description"),
35-
Region(id="RegionTwo", description="Region Two description")]
35+
assert result == [
36+
Region(id="RegionOne", description="Region One description"),
37+
Region(id="RegionTwo", description="Region Two description"),
38+
]
3639

3740
# Verify mock calls
3841
mock_conn.identity.regions.assert_called_once()
3942

4043
def test_get_regions_empty_list(self, mock_get_openstack_conn_keystone):
4144
"""Test getting keystone regions when there are no regions."""
4245
mock_conn = mock_get_openstack_conn_keystone
43-
46+
4447
# Empty region list
4548
mock_conn.identity.regions.return_value = []
46-
49+
4750
# Test get_regions()
4851
keystone_tools = self.get_keystone_tools()
4952
result = keystone_tools.get_regions()
50-
53+
5154
# Verify results
5255
assert result == []
5356

@@ -57,7 +60,7 @@ def test_get_regions_empty_list(self, mock_get_openstack_conn_keystone):
5760
def test_create_region_success(self, mock_get_openstack_conn_keystone):
5861
"""Test creating a keystone region successfully."""
5962
mock_conn = mock_get_openstack_conn_keystone
60-
63+
6164
# Create mock region object
6265
mock_region = Mock()
6366
mock_region.id = "RegionOne"
@@ -68,15 +71,23 @@ def test_create_region_success(self, mock_get_openstack_conn_keystone):
6871

6972
# Test create_region()
7073
keystone_tools = self.get_keystone_tools()
71-
result = keystone_tools.create_region(id="RegionOne", description="Region One description")
72-
74+
result = keystone_tools.create_region(
75+
id="RegionOne", description="Region One description"
76+
)
77+
7378
# Verify results
74-
assert result == Region(id="RegionOne", description="Region One description")
79+
assert result == Region(
80+
id="RegionOne", description="Region One description"
81+
)
7582

7683
# Verify mock calls
77-
mock_conn.identity.create_region.assert_called_once_with(id="RegionOne", description="Region One description")
78-
79-
def test_create_region_without_description(self, mock_get_openstack_conn_keystone):
84+
mock_conn.identity.create_region.assert_called_once_with(
85+
id="RegionOne", description="Region One description"
86+
)
87+
88+
def test_create_region_without_description(
89+
self, mock_get_openstack_conn_keystone
90+
):
8091
"""Test creating a keystone region without a description."""
8192
mock_conn = mock_get_openstack_conn_keystone
8293

@@ -95,22 +106,32 @@ def test_create_region_without_description(self, mock_get_openstack_conn_keyston
95106
# Verify results
96107
assert result == Region(id="RegionOne")
97108

98-
def test_create_region_invalid_id_format(self, mock_get_openstack_conn_keystone):
109+
def test_create_region_invalid_id_format(
110+
self, mock_get_openstack_conn_keystone
111+
):
99112
"""Test creating a keystone region with an invalid ID format."""
100113
mock_conn = mock_get_openstack_conn_keystone
101114

102115
# Configure mock region.create_region() to raise an exception
103-
mock_conn.identity.create_region.side_effect = exceptions.BadRequestException(
104-
"Invalid input for field 'id': Expected string, got integer"
116+
mock_conn.identity.create_region.side_effect = (
117+
exceptions.BadRequestException(
118+
"Invalid input for field 'id': Expected string, got integer"
119+
)
105120
)
106121

107122
# Test create_region()
108123
keystone_tools = self.get_keystone_tools()
109124

110125
# Verify results
111-
with pytest.raises(exceptions.BadRequestException, match="Invalid input for field 'id': Expected string, got integer"):
112-
keystone_tools.create_region(id=1, description="Region One description")
126+
with pytest.raises(
127+
exceptions.BadRequestException,
128+
match="Invalid input for field 'id': Expected string, got integer",
129+
):
130+
keystone_tools.create_region(
131+
id=1, description="Region One description"
132+
)
113133

114134
# Verify mock calls
115-
mock_conn.identity.create_region.assert_called_once_with(id=1, description="Region One description")
116-
135+
mock_conn.identity.create_region.assert_called_once_with(
136+
id=1, description="Region One description"
137+
)

0 commit comments

Comments
 (0)