Skip to content

test(spp_dci_client): assert outgoing-log integration at the log-service seam (#443) - #546

Open
gonzalesedwin1123 wants to merge 3 commits into
19.0from
fix-443-dci-client-outgoing-log-tests
Open

gonzalesedwin1123 wants to merge 3 commits into
19.0from
fix-443-dci-client-outgoing-log-tests

Conversation

@gonzalesedwin1123

Copy link
Copy Markdown
Member

Part of #443 (weekly ci-full red). Test-only; 8 tests in the SP-MIS stack, the largest single cluster.

Causes

The class had never run. TestOutgoingLogIntegration.setUpClass skips without spp.api.outgoing.log, and spp_dci_client's dependency closure (base, spp_dci) does not reach spp_api_v2, so per-module CI always skipped it. The SP-MIS stack is the first database with both installed.

Seven test_make_request_logs_* tests'success' != 'connection_error' etc., and duration_ms 0 not greater than 0. _log_outgoing_call writes the audit row through registry.cursor(), a separate connection that really commits (by design: the row must survive the request's UserError rollback). In Odoo 19 a plain TransactionCase is not in registry test mode (only HttpCase is), and the test transaction runs at REPEATABLE READ, so rows committed after its snapshot are invisible while rows committed by earlier classes are visible. _find_latest_log filtered only on url like "crvs.example.org", so every test found TestClientService.test_make_request_with_oauth2's committed success row from a sub-millisecond mocked call, which explains every asserted value.

test_401_retry_creates_two_log_entries — never satisfiable: it built an OAuth2 data source without token URL / client id / secret, so _check_oauth2_fields refused the create (the constraint predates the test). Once fixed, get_headers() would have fetched the OAuth2 token through the same patched httpx.Client and consumed the canned 401.

Fix (test-only)

  • Assert at the seam: setUp patches OutgoingApiLogService.log_call (autospec) and each test asserts the kwargs of the call(s) made — status, response code, endpoint, url, origin, error detail. The soft-dependency check, cursor open and service construction still run for real. duration_ms is asserted >= 0 (a mocked round trip is sub-millisecond).
  • One test still proves the real write: it lets the service run, then reads the row back through a fresh registry.cursor() (a new snapshot), scoped by a per-test unique service_code, and removes it the same way.
  • A test asserts the service is constructed with the client's identity (service_name, service_code, user_id).
  • The 401 test builds a valid OAuth2 source, patches get_headers (the token flow is not under test) and clear_oauth2_token_cache, and asserts the two log calls in call order (inner retried success first, outer 401 second) rather than by row id.
  • The no-op @unittest.skipUnless(True, ...) decorator is removed; the real guard is in setUpClass.

Evidence

  • Stack run -i spp_dci_client,spp_api_v2 --test-tags /spp_dci_client:TestOutgoingLogIntegration: before 7 failed, 1 error(s) of 9; after 0 failed, 0 error(s) of 11.
  • Module suite green (the class skips there, as before). All pre-commit hooks pass.

spp_dci_client 19.0.2.0.1 → 19.0.2.0.2 + HISTORY (note: the module has no HISTORY entry for 2.0.1; pre-existing). README/index.html left for CI's generator.

Noted, not changed

Every mocked _make_request in any TransactionCase on a database with spp_api_v2 leaves a committed spp.api.outgoing.log row behind (harmless in a throwaway CI database; makes "latest row" assertions order-dependent anywhere). Production behaviour is correct and intended.

…ice seam

TestOutgoingLogIntegration skips without spp_api_v2, so it had never run
before the full-stack CI. The client writes the audit row through a
separate, committed cursor on purpose (the row must survive the
request's rollback); a TransactionCase at REPEATABLE READ cannot see
that row and its latest-row query found an earlier class's committed
success entry instead, so every status assertion failed against a stale
row. test_401_retry also built an OAuth2 source without the fields its
own constraint requires.

The tests now patch OutgoingApiLogService.log_call and assert the kwargs
of each call; one test lets the real write happen and reads the row
back through a fresh cursor, scoped by a per-test service code, and
removes it; the 401 test builds a valid OAuth2 source, keeps the token
flow out of the patched HTTP client, and asserts the two calls in the
order the code guarantees.

Refs #443
@codecov

codecov Bot commented Sep 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.49%. Comparing base (1a3c591) to head (262d45d).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             19.0     #546      +/-   ##
==========================================
+ Coverage   76.91%   77.49%   +0.58%     
==========================================
  Files         704      740      +36     
  Lines       45774    47416    +1642     
==========================================
+ Hits        35205    36745    +1540     
- Misses      10569    10671     +102     
Flag Coverage Δ
spp_base_common 91.07% <ø> (ø)
spp_dci_client 89.25% <ø> (ø)
spp_dci_client_compliance 99.25% <ø> (ø)
spp_dci_client_crvs 92.51% <ø> (ø)
spp_dci_client_dr 85.77% <ø> (ø)
spp_dci_client_ibr 92.47% <ø> (?)
spp_dci_client_sr 98.10% <ø> (?)
spp_dci_compliance 93.01% <ø> (ø)
spp_dci_demo 94.28% <ø> (ø)
spp_dci_indicators 96.23% <ø> (?)
spp_dci_server 90.24% <ø> (ø)
spp_dci_server_social 89.57% <ø> (?)
spp_farmer_registry_demo 63.39% <ø> (ø)
spp_mis_demo_v2 70.41% <ø> (ø)
spp_programs 67.58% <ø> (ø)
spp_registry 89.00% <ø> (ø)
spp_starter_sp_mis 86.84% <ø> (-2.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.
see 37 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gonzalesedwin1123

Copy link
Copy Markdown
Member Author

Full-stack evidence: SP-MIS ci-full dispatched on this branch (run 35566505354) vs the 2026-09-20 weekly baseline (run 35499069639).

  • Result line: 4 failed, 10 error(s) of 7399 tests vs baseline 11 failed, 11 error(s) of 7397 tests.
  • Failing-test set diff: gone TestOutgoingLogIntegration.test_401_retry_creates_two_log_entries, TestOutgoingLogIntegration.test_make_request_logs_connection_error, TestOutgoingLogIntegration.test_make_request_logs_dns_error, TestOutgoingLogIntegration.test_make_request_logs_generic_exception, TestOutgoingLogIntegration.test_make_request_logs_http_error, TestOutgoingLogIntegration.test_make_request_logs_ssl_error, TestOutgoingLogIntegration.test_make_request_logs_success, TestOutgoingLogIntegration.test_make_request_logs_timeout; new: none. The remaining failures are the other ci-full: 23 tests red under the full demo stacks (2 production bugs + 9 test-isolation causes); originally the spp_registry unlink tests since #411 #443 causes, each with its own PR.

@gonzalesedwin1123
gonzalesedwin1123 marked this pull request as ready for review September 21, 2026 06:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant