fediverse-devnet / feditest

A testing framework for distributed, heterogeneous systems communicating with complex protocols, such as the Fediverse
https://feditest.org/
MIT License
27 stars 4 forks source link

AttributeError: 'NoneType' object has no attribute 'is_valid_link_subset' #165

Closed jernst closed 4 weeks ago

jernst commented 1 month ago

This can apparently happen:

2024-05-31T16:47:23Z [ERROR] feditest: Ended TestRunFunction webfinger.server.4__1_accepts_all_link_rels_in_query::accepts_combined_link_rels_in_query with Exception:
Traceback (most recent call last):
  File "/Users/jernst/git/github.com/jernst/feditest/venv.darwin.develop/lib/python3.12/site-packages/feditest/testrun.py", line 158, in run
    self.test_from_test_function.test_function(**args)
  File "/Users/jernst/git/github.com/jernst/feditest-tests-fediverse/tests/webfinger/server/4__1_accepts_all_link_rels_in_query.py", line 134, in accepts_combined_link_rels_in_query
    hard_assert_that(
  File "/Users/jernst/git/github.com/jernst/feditest/venv.darwin.develop/lib/python3.12/site-packages/feditest/__init__.py", line 250, in hard_assert_that
    feditest_assert_that(actual_or_assertion, HardAssertionFailure, matcher, reason)
  File "/Users/jernst/git/github.com/jernst/feditest/venv.darwin.develop/lib/python3.12/site-packages/feditest/__init__.py", line 193, in feditest_assert_that
    _feditest_assert_match(actual=actual_or_assertion, exception_factory=exception_factory, matcher=matcher, reason=reason)
  File "/Users/jernst/git/github.com/jernst/feditest/venv.darwin.develop/lib/python3.12/site-packages/feditest/__init__.py", line 201, in _feditest_assert_match
    if not matcher.matches(actual):
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jernst/git/github.com/jernst/feditest/venv.darwin.develop/lib/python3.12/site-packages/hamcrest/core/base_matcher.py", line 39, in matches
    match_result = self._matches(item)
                   ^^^^^^^^^^^^^^^^^^^
  File "/Users/jernst/git/github.com/jernst/feditest/venv.darwin.develop/lib/python3.12/site-packages/feditest/protocols/webfinger/utils.py", line 72, in _matches
    return jrd_with_subset.is_valid_link_subset(self._jrd_with_superset, self._rels)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'is_valid_link_subset'

This was when accessing misskey.io. It may be because it is behind cloudflare and cloudflare said it blocked me (apparently after most of the tests were run).

steve-bate commented 1 month ago

(Followup to PR #170)

The cause of the problem is that Imp is returning an ExceptionGroup that contains an exception accepted by the none_except assertion predicate. For example, the accepts_known_link_rels_in_query receives the following exception group for MissKey:

0: Wrong HTTP status code.
 -> 403
1: Wrong HTTP content type.
 -> "text/html; charset=UTF-8"
2: Expecting value: line 1 column 1 (char 0)
Expected: No exception other than: WrongContentTypeError,InvalidMediaTypeError,InvalidRelError
     but: was <Multiple WebFinger errors (3 sub-exceptions)>

and the assertion is:

    hard_assert_that(
            response_without_rel.exc,
            none_except(WebClient.WrongContentTypeError, ClaimedJrd.InvalidMediaTypeError, ClaimedJrd.InvalidRelError),
            wf_error(response_without_rel))

The wrong content type is allowed by none_except and so the assertion is satisfied. The other two exceptions indicate there will be JRD to check for validity but the tests tries to do so anyway.

I think you want an assertion to check for a missing JRD prior to trying to validate it (?). In other words, there seems to be an implicit (incorrect) assumption that a JRD will be present if any of the allowed exceptions are present in the ExceptionGroup.

jernst commented 1 month ago

Cannot reproduce. My test plan:

{
    "sessions": [
        {
            "constellation": {
                "roles": {
                    "client": {
                        "nodedriver": "imp.ImpInProcessNodeDriver",
                        "parameters": null
                    },
                    "server": {
                        "nodedriver": "saas.SaasFediverseNodeDriver",
                        "parameters": {
                            "app": "Misskey",
                            "hostname": "misskey.io",
                            "existing-account-uri": "acct:syuilo@misskey.io",
                            "nonexisting-account-uri": "acct:does-not-exist@misskey.io"
                        }
                    }
                },
                "name": "Misskey"
            },
            "tests": [
                {
                    "name": "webfinger.server.4__1_accepts_all_link_rels_in_query::accepts_combined_link_rels_in_query",
                    "rolemapping": {
                        "server": "server",
                        "client": "client"
                    },
                    "skip": null
                }
            ],
            "name": "Misskey"
        }
    ],
    "name": null
}

My result:

../feditest/venv.darwin.develop/bin/feditest run --testplan foo/testplan.json 
2024-06-07T15:44:32Z [ERROR] feditest: Ended test webfinger.server.4__1_accepts_all_link_rels_in_query::accepts_combined_link_rels_in_query in Misskey with Exception:
Traceback (most recent call last):
  File "/Users/jernst/git/github.com/jernst/feditest/venv.darwin.develop/lib/python3.12/site-packages/feditest/testrun.py", line 162, in run
    self.test_from_test_function.test_function(**args)
  File "/Users/jernst/git/github.com/jernst/feditest-tests-fediverse/tests/webfinger/server/4__1_accepts_all_link_rels_in_query.py", line 134, in accepts_combined_link_rels_in_query
    hard_assert_that(
  File "/Users/jernst/git/github.com/jernst/feditest/venv.darwin.develop/lib/python3.12/site-packages/feditest/__init__.py", line 250, in hard_assert_that
    feditest_assert_that(actual_or_assertion, HardAssertionFailure, matcher, reason)
  File "/Users/jernst/git/github.com/jernst/feditest/venv.darwin.develop/lib/python3.12/site-packages/feditest/__init__.py", line 193, in feditest_assert_that
    _feditest_assert_match(actual=actual_or_assertion, exception_factory=exception_factory, matcher=matcher, reason=reason)
  File "/Users/jernst/git/github.com/jernst/feditest/venv.darwin.develop/lib/python3.12/site-packages/feditest/__init__.py", line 208, in _feditest_assert_match
    raise exception_factory(description)
feditest.HardAssertionFailure: Not same or subset of links.
Accessed URI: "https://misskey.io/.well-known/webfinger?resource=acct%3Asyuilo%40misskey.io&rel=something-else&rel=http%3A//webfinger.net/rel/profile-page" with rels something-else and http://webfinger.net/rel/profile-page vs none.
Expected: Links must be the same or a subset.JRD: {"subject": "acct:syuilo@misskey.io", "links": [{"rel": "self", "type": "application/activity+json", "href": "https://misskey.io/users/7rkrarq81i"}, {"rel": "http://webfinger.net/rel/profile-page", "type": "text/html", "href": "https://misskey.io/@syuilo"}, {"rel": "http://ostatus.org/schema/1.0/subscribe", "template": "https://misskey.io/authorize-follow?acct={uri}"}]}
     but: was <None>

Test summary: total=1, passed=0, failed=1 (hard=1, soft=0, degrade=0), skipped=0, errors=0.
FAILED.
steve-bate commented 1 month ago

That's what I'd expect and why I merged the PR. In #170, I said "this addresses the symptom, but not the cause of the problem." In the related comments in this issue, I suggested that fixing the test that caused the symptoms would be a better solution. We can close this issue if that's not something worth doing.

jernst commented 4 weeks ago

I don't see what else there is to do. If there is, please open a new issue