Skip to content

Commit

Permalink
test: speed-up tests by mocking gethostbyaddr
Browse files Browse the repository at this point in the history
Tests that are using mrack outputs are slowed down by
socker.gethostbyaddr for adhoc IP addresses. This resolution mostly
fails and the test is slow (multiple seconds timeout for single IP).

With this, all python tests are executed within 1.5s.

Signed-off-by: Petr Vobornik <[email protected]>
  • Loading branch information
pvoborni committed May 30, 2024
1 parent 587a9c7 commit 6f81e37
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 23 deletions.
18 changes: 18 additions & 0 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import shutil
import socket
import tempfile
from pathlib import Path

Expand Down Expand Up @@ -45,3 +46,20 @@ def cleandir():
yield
os.chdir(old_cwd)
shutil.rmtree(newpath)


@pytest.fixture
def mock_gethostbyaddr(monkeypatch):
"""
Mock gethostbyaddr function from socket module.
It returns only IP address as if the DNS resolution would fail - which it does
for test data anyway.
This is to speed up the tests
"""

def gethostbyaddr(ip_address):
return [ip_address, [], []]

monkeypatch.setattr(socket, "gethostbyaddr", gethostbyaddr)
8 changes: 7 additions & 1 deletion tests/integration/test_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ def global_context_init(provisioning_config_file, mrack_config_file=None, db_fil
class TestStaticProvider:
@pytest.mark.asyncio
async def test_up_action(
self, provisioning_config, metadata, database, setup_providers
self,
provisioning_config,
metadata,
database,
setup_providers,
mock_gethostbyaddr,
):
up_action = UpAction(
config=provisioning_config,
Expand Down Expand Up @@ -88,6 +93,7 @@ async def test_output_action(
cleandir,
config,
files,
mock_gethostbyaddr,
):
workdir = os.getcwd()

Expand Down
18 changes: 18 additions & 0 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import socket
from unittest.mock import MagicMock, PropertyMock

import pytest
Expand Down Expand Up @@ -185,3 +186,20 @@ def host1_osp(metahost1):
@pytest.fixture
def host_win_aws(metahost_win):
return meta_to_host(metahost_win, "aws", "3", "192.168.0.129")


@pytest.fixture
def mock_gethostbyaddr(monkeypatch):
"""
Mock gethostbyaddr function from socket module.
It returns only IP address as if the DNS resolution would fail - which it does
for test data anyway.
This is to speed up the tests
"""

def gethostbyaddr(ip_address):
return [ip_address, [], []]

monkeypatch.setattr(socket, "gethostbyaddr", gethostbyaddr)
36 changes: 17 additions & 19 deletions tests/unit/test_ansible_inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class TestAnsibleInventory:
False,
],
)
def test_layouts(self, layout, db, metadata):
def test_layouts(self, layout, db, metadata, mock_gethostbyaddr):
config = provisioning_config(layout)
ans_inv = AnsibleInventoryOutput(config, db, metadata)
inventory = ans_inv.create_inventory()
Expand All @@ -123,15 +123,15 @@ def test_layouts(self, layout, db, metadata):
(True, False),
],
)
def test_invalid_layouts(self, layout, db, metadata):
def test_invalid_layouts(self, layout, db, metadata, mock_gethostbyaddr):
config = provisioning_config(layout)
ans_inv = AnsibleInventoryOutput(config, db, metadata)

with pytest.raises(ConfigError) as excinfo:
ans_inv.create_inventory()
assert "dictionary" in str(excinfo.value)

def test_layout_nested_groups(self, db, metadata):
def test_layout_nested_groups(self, db, metadata, mock_gethostbyaddr):
layout = {
"all": {
"children": {
Expand All @@ -145,10 +145,6 @@ def test_layout_nested_groups(self, db, metadata):
ans_inv = AnsibleInventoryOutput(config, db, metadata)
inventory = ans_inv.create_inventory()

import yaml

print(yaml.dump(inventory))

assert "all" in inventory
assert "children" in inventory["all"]

Expand Down Expand Up @@ -176,7 +172,7 @@ def test_layout_nested_groups(self, db, metadata):
in inventory["all"]["children"]["server"]["children"]["ipaserver"]["hosts"]
)

def test_layout_overwrite(self, db, metadata):
def test_layout_overwrite(self, db, metadata, mock_gethostbyaddr):
metadata["config"] = {
"ansible": {
"layout": {
Expand All @@ -198,7 +194,7 @@ def test_layout_overwrite(self, db, metadata):
assert "windows" not in inventory["all"]["children"]
assert "mylayout" in inventory["all"]["children"]

def test_meta_extra(self, db_meta_extra, metadata):
def test_meta_extra(self, db_meta_extra, metadata, mock_gethostbyaddr):
config = provisioning_config()
ans_inv = AnsibleInventoryOutput(config, db_meta_extra, metadata)
inventory = ans_inv.create_inventory()
Expand All @@ -211,7 +207,7 @@ def test_meta_extra(self, db_meta_extra, metadata):
), "Host must have 'meta_compose_url' field"
assert "meta_compose_id" in first_host, "Host must have 'meta_compose_id' field"

def test_not_meta_extra(self, db, metadata):
def test_not_meta_extra(self, db, metadata, mock_gethostbyaddr):
"""
Because some images (such as Windows images) don't have extra meta data fields
like meta_compose_id and meta_compose_url, inventory shouldn't output them
Expand All @@ -232,7 +228,7 @@ def test_not_meta_extra(self, db, metadata):
"meta_compose_id" not in first_host
), "Host must NOT have 'meta_compose_id' field"

def test_arbitrary_meta_attrs(self):
def test_arbitrary_meta_attrs(self, mock_gethostbyaddr):
"""
Test that inventory has meta_$something attribute if user defined it in job
metadata file. Also test that they override the default meta attrs, e.g.,
Expand All @@ -259,7 +255,7 @@ def test_arbitrary_meta_attrs(self):
assert srv2["meta_readonly_dc"] == "no"
assert srv2["meta_os"] == "fedora-32"

def test_arbitrary_attrs(self):
def test_arbitrary_attrs(self, mock_gethostbyaddr):
"""
Test that values defined in `ansible_inventory` dictionary in host part
of job metadata file gets into host attributes in generated ansible
Expand Down Expand Up @@ -296,7 +292,7 @@ def test_arbitrary_attrs(self):
assert srv2["no_ca"] == "yes"
assert srv2["something_else"] == "for_fun"

def test_domain_arbitrary_attrs(self):
def test_domain_arbitrary_attrs(self, mock_gethostbyaddr):
"""
Test that values defined in `ansible_inventory` dictionary in domain
section of job metadata file gets into host attributes in generated ansible
Expand Down Expand Up @@ -327,7 +323,7 @@ def test_domain_arbitrary_attrs(self):
assert srv2["no_ca"] == "no"
assert srv2["something_else"] == "not_funny"

def test_domain_arbitrary_attrs_override(self):
def test_domain_arbitrary_attrs_override(self, mock_gethostbyaddr):
"""
Test that values defined in `ansible_inventory` dictionary in domain
section of job metadata file gets into host attributes in generated ansible
Expand Down Expand Up @@ -368,7 +364,7 @@ def test_domain_arbitrary_attrs_override(self):
assert srv2["no_ca"] == "yes"
assert srv2["something_else"] == "for_fun"

def test_global_arbitrary_attrs(self):
def test_global_arbitrary_attrs(self, mock_gethostbyaddr):
"""
Test that values defined in `ansible_inventory` dictionary in global
section of job metadata file gets into host attributes in generated ansible
Expand Down Expand Up @@ -399,7 +395,7 @@ def test_global_arbitrary_attrs(self):
assert srv2["no_ca"] == "no"
assert srv2["something_else"] == "not_funny"

def test_global_arbitrary_attrs_domain_override(self):
def test_global_arbitrary_attrs_domain_override(self, mock_gethostbyaddr):
"""
Test that values defined in `ansible_inventory` dictionary in global
section of job metadata file gets into host attributes in generated ansible
Expand Down Expand Up @@ -434,7 +430,7 @@ def test_global_arbitrary_attrs_domain_override(self):
assert srv2["no_ca"] == "yes"
assert srv2["something_else"] == "not_funny"

def test_global_arbitrary_attrs_host_override(self):
def test_global_arbitrary_attrs_host_override(self, mock_gethostbyaddr):
"""
Test that values defined in `ansible_inventory` dictionary in global
section of job metadata file gets into host attributes in generated ansible
Expand Down Expand Up @@ -481,7 +477,9 @@ def test_global_arbitrary_attrs_host_override(self):
assert srv2["no_ca"] == "whatever"
assert srv2["something_else"] == "host_value"

def test_global_arbitrary_attrs_host_override_multiple_domains(self):
def test_global_arbitrary_attrs_host_override_multiple_domains(
self, mock_gethostbyaddr
):
"""
Test that values defined in `ansible_inventory` dictionary in global
section of job metadata file gets into host attributes in generated ansible
Expand Down Expand Up @@ -547,7 +545,7 @@ def test_global_arbitrary_attrs_host_override_multiple_domains(self):
assert d1_srv2["no_ca"] == "no"
assert d1_srv2["something_else"] == "default_global"

def test_host_ssh_options(self, metadata, db):
def test_host_ssh_options(self, metadata, db, mock_gethostbyaddr):
prov_config = provisioning_config()
ans_inv = AnsibleInventoryOutput(prov_config, db, metadata)

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_pytest_mh.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def mock_metadata():


class TestPytestMhOutput:
def test_output(self, mock_metadata):
def test_output(self, mock_metadata, mock_gethostbyaddr):
config = provisioning_config()
db = get_db_from_metadata(mock_metadata)

Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_pytest_multihost.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


class TestPytestMultihostOutput:
def test_arbitrary_attrs(self):
def test_arbitrary_attrs(self, mock_gethostbyaddr):
"""
Test that values defined in `pytest_multihost` dictionary in host part
of job metadata file gets into host attributes in generated pytest-multihost
Expand Down Expand Up @@ -40,7 +40,7 @@ def test_arbitrary_attrs(self):
assert srv2["no_ca"] == "yes"
assert srv2["something_else"] == "for_fun"

def test_config_section_deleted(self):
def test_config_section_deleted(self, mock_gethostbyaddr):
"""
Test that config section from metadata is not included in mhc.yaml.
"""
Expand Down

0 comments on commit 6f81e37

Please sign in to comment.