Skip to content

rewriting memcache tests#8485

Open
danlavu wants to merge 2 commits intoSSSD:masterfrom
danlavu:tests-rm-memcache
Open

rewriting memcache tests#8485
danlavu wants to merge 2 commits intoSSSD:masterfrom
danlavu:tests-rm-memcache

Conversation

@danlavu
Copy link
Copy Markdown

@danlavu danlavu commented Feb 27, 2026

No description provided.

@danlavu danlavu added the Tests label Feb 27, 2026
@danlavu danlavu marked this pull request as draft February 27, 2026 07:57
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a significant refactoring of the memcache tests, aiming to reduce code duplication by introducing helper functions and parametrizing tests. While this is a great improvement for maintainability, the new implementation introduces several critical and high-severity issues, including a syntax error, flawed test logic that would cause failures, and several inconsistencies between test names, docstrings, and their implementations. I've detailed these issues in the review comments.

@danlavu danlavu force-pushed the tests-rm-memcache branch from 4164a67 to 92e2433 Compare March 1, 2026 00:20
@danlavu danlavu force-pushed the tests-rm-memcache branch 4 times, most recently from 800149e to 79780ef Compare March 2, 2026 22:48
@danlavu danlavu force-pushed the tests-rm-memcache branch 2 times, most recently from 36e1b79 to 757722f Compare March 3, 2026 01:32
@danlavu danlavu force-pushed the tests-rm-memcache branch 2 times, most recently from bc7b7a2 to b484bad Compare March 3, 2026 03:41
@danlavu danlavu marked this pull request as ready for review March 3, 2026 04:33
@madhuriupadhye
Copy link
Copy Markdown
Contributor

@danlavu, can you please check,
ValueError: Required field 'customerscenario' is missing for 'tests/test_memcache.py::test_memcache__lookup_objects_by_name[users] (ldap)'

@danlavu
Copy link
Copy Markdown
Author

danlavu commented Mar 12, 2026

@madhuriupadhye @andreboscatto I suggest reviewing this PR using the split diff view and not the unified diff.

@andreboscatto
Copy link
Copy Markdown
Contributor

@madhuriupadhye @andreboscatto I suggest reviewing this PR using the split diff view and not the unified diff.

Indeed, I started reviewing the old document, understanding each case and looking at yours. Doing that side by side is helpful.

@danlavu
Copy link
Copy Markdown
Author

danlavu commented Mar 13, 2026

@danlavu, can you please check, ValueError: Required field 'customerscenario' is missing for 'tests/test_memcache.py::test_memcache__lookup_objects_by_name[users] (ldap)'

fixed.

Check the existence of objects, either users, groups, or initgroups.

This is a helper function to parameterize the memcache test. The assertions for each
cache time are different. Looking up 'users, will use 'id', groups will use 'getent group',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update to Looking up 'users', will use

cache time or cache type?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace Looking up 'users, will use to Looking up **'users'**, will use

@madhuriupadhye
Copy link
Copy Markdown
Contributor

madhuriupadhye commented Mar 16, 2026

please check,
ValueError: Number of steps and results do not match in idm-sssd-tc::tests/test_memcache.py::test_memcache__lookup_objects_by_id[users] (ldap)

289: 2: Group membership is correct -> 2. Group membership is correct

@danlavu danlavu force-pushed the tests-rm-memcache branch 2 times, most recently from f45a3e2 to 3ab0a1e Compare March 17, 2026 05:24
@danlavu danlavu force-pushed the tests-rm-memcache branch from 3ab0a1e to c3b49a7 Compare March 26, 2026 16:48
def test_memcache__invalidate_user_cache_after_stop(client: Client, provider: GenericProvider):
@pytest.mark.parametrize(
"cache",
["users", "groups", "initgroups", "all"],
Copy link
Copy Markdown
Contributor

@madhuriupadhye madhuriupadhye Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert_objects and assert_objects_not_found only handle "users", "groups", and "initgroups". There is no branch for cache == "all", so for "all" both functions return without asserting anything.
When cache is "all", those two lines invoke the helpers with "all", which matches none of the if cache == ... branches, so no assertions run there.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is an awesome catch, thank you. Created a new test to cover all cache types disabled.

Dan Lavu added 2 commits April 1, 2026 13:36
* parametrized test cases
* added colliding hash test case
* remove poor test scenarios
def test_memcache__invalidate_groups_cache_after_stop(client: Client, provider: GenericProvider):
@pytest.mark.parametrize(
"cache",
["users", "groups", "initgroups", "all"],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pytest.mark.parametrize(
    "cache",
    ["users", "groups", "initgroups", "all"],
)
...
    assert_objects(client, objects, cache)
    invalidate_cache_stop_sssd(client, order, cache)

    assert_objects_not_found(client, objects, cache)

assert_objects / assert_objects_not_found only handle "users", "groups", and "initgroups". For "all" they do nothing, so those subtests do not assert warm-up or post-conditions. invalidate_cache_stop_sssd does hit cache_expire(everything=True) in the else branch, but the test body is still incomplete.

Drop "all" and add a dedicated test that loops the three cache kinds, or teach the helpers to treat "all" as “run all three branches.”, WDYT?

gresult = client.tools.getent.group("group1")
assert gresult is not None, "Group group1 is not found using getent"
assert gresult.gid == 10001, f"Group gid {gresult.gid} is incorrect, 10001 expected"
colliding_user = client.host.conn.run(f"python {script}").stdout
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use something like colliding_user = client.host.conn.run(...).stdout.strip() and assert non-empty. A trailing newline can become part of the username and break lookups.

assert result_user is not None, f"User '{user.name}' was not found!"
assert (
result_user.groups[-1].name == expected_groups[-1]
), f"User '{user.name}' is member of incorrect groups!"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

            assert (
                result_user.groups[-1].name == expected_groups[-1]
            ), f"User '{user.name}' is member of incorrect groups!"

This only compares the last group name. NSS/id group order may not match user_map list order. Safer: compare sets of names (or sorted lists) for user2 / user3.
Something like this,

            assert result_user is not None, f"User '{user.name}' was not found!"
            expected_names = set(expected_groups)
            actual_names = {g.name for g in result_user.groups if g.name is not None}
            assert actual_names == expected_names, (
                f"User '{user.name}' group names from id {sorted(actual_names)!r} "
                f"!= expected {sorted(expected_names)!r}"
            )

assert result.user.name == user, f"Username {result.user.name} is incorrect, {user} expected"
assert result.user.id == id, f"User id {result.user.id} is incorrect, {id} expected"
The word objects is used because it may add 'users' or 'groups'. It returns a dict of lists of objects,
so they can be used to retrieve uidNUmber and gidNumbers.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in docstrings: uidNUmberuidNumber

client.sssd.domain["ldap_id_mapping"] = "false"
script = client.fs.mktmp("""
#!/usr/bin/env python3
import argparse
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

argparse is imported but unused.

assert client.tools.getent.group(202020) is None, "Group with gid 202020 was found which is not expected"

assert_objects_not_found(client, objects, cache)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP 8: Missing a blank line between functions at ~401–402.

assert_objects_not_found(client, objects, cache)

@pytest.mark.importance("critical")
@pytest.mark.cache
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of these tests use @pytest.mark.cache, are we dropping this marker?

@madhuriupadhye
Copy link
Copy Markdown
Contributor

Please make sure it will be green in IDM-CI also.

Copy link
Copy Markdown
Contributor

@andreboscatto andreboscatto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Dan! LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants