Skip to content

fix: restore shadowed test_discovery_http_is_closed test - #2801

Open
skippdot wants to merge 2 commits into
googleapis:mainfrom
skippdot:fix-shadowed-discovery-test
Open

fix: restore shadowed test_discovery_http_is_closed test#2801
skippdot wants to merge 2 commits into
googleapis:mainfrom
skippdot:fix-shadowed-discovery-test

Conversation

@skippdot

@skippdot skippdot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #2757

tests/test_discovery.py has contained two class Discovery(unittest.TestCase) definitions since September 2020 (#1038). The second definition silently shadows the first, so its only test, test_discovery_http_is_closed, has never been collected — pytest picks up 0 instances of it on main. The dead test also could not have passed if it ever ran: it calls assert_called_once() on HttpMock.close, a plain method, which raises AttributeError.

Changes

  • Remove the shadowed duplicate class.
  • Re-add test_discovery_http_is_closed inside the surviving Discovery class, rewritten to patch httplib2.Http so the assertion targets a real mock. It verifies that build() closes the temporary http client it creates to fetch the discovery document (discovery.py, the discovery_http.close() call).
  • Pass cache_discovery=False in addition to static_discovery=False, so the discovery document is always fetched through the mocked client — a discovery-cache hit cannot bypass the code path under test.

One file, +14/−7.

Verification

  • Collected tests in tests/test_discovery.py: 173 → 174.
  • Mutation check: with the discovery_http.close() call removed from googleapiclient/discovery.py, the restored test fails; with it in place, the test passes — so it genuinely guards the close behavior.
  • Full tests/ folder on Python 3.14: 339 passed, 1 skipped.
  • black --check clean; flake8 --select=E9,F63,F7,F82 (the set CI enforces) clean.

Note: running tests/test_discovery.py in isolation shows one pre-existing failure, DiscoveryErrors::test_tests_should_be_run_with_strict_positional_enforcement — that is #2755, reproducible on an unmodified main, and untouched by this PR.

- Remove the duplicate `class Discovery(unittest.TestCase)` definition that
  has shadowed the active class of the same name since 2020, leaving its only
  test permanently uncollected by the test runner
- Re-add `test_discovery_http_is_closed` inside the surviving class, rewritten
  to patch `httplib2.Http`: the original asserted on `HttpMock.close`, a plain
  method that would raise AttributeError if the test ever ran
- Pass `cache_discovery=False` so the discovery document is always fetched
  through the mocked client and the close assertion cannot be bypassed by a
  cache hit; the test fails if `build()` stops closing its temporary client

Fixes googleapis#2757
@skippdot
skippdot requested a review from a team as a code owner September 1, 2026 10:20
@product-auto-label product-auto-label Bot added the size: s Pull request size is small. label Sep 1, 2026

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

Copy link
Copy Markdown

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 refactors the test_discovery_http_is_closed test in tests/test_discovery.py. The test was moved to the Discovery test class and updated to use @mock.patch on httplib2.Http to verify that the temporary HTTP client created during service discovery is properly closed, preventing connection leaks. There are no review comments, so I have no feedback to provide.

@skippdot

Copy link
Copy Markdown
Contributor Author

Noting for reviewers: #2758, opened earlier, addresses the same issue (#2757) with a similar approach (remove the shadowed class, re-add the test with httplib2.Http patched). Differences in this PR:

  • passes cache_discovery=False in addition to static_discovery=False, so a discovery-cache hit cannot bypass the mocked client and make the test fail spuriously;
  • patches via http_class.return_value instead of a two-mock side_effect, so the test does not depend on build() constructing exactly two Http instances in a particular order;
  • mutation-checked: with the discovery_http.close() call removed from discovery.py, the test fails.

#2758 additionally asserts that the caller-facing http client is not closed, which is a nice extra check. Happy to fold that assertion in here, or to defer to #2758 if maintainers prefer it — flagging the overlap so both are not reviewed in parallel unknowingly.

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

Labels

size: s Pull request size is small.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: connection leak test test_discovery_http_is_closed is shadowed and syntactically invalid

1 participant