Skip to content

Fix nine failing tests on main (regressor forecasting on pandas 2.2+, swallowed CLI messages, task-run 500, task-run timestamps)#2303

Merged
Flix6x merged 2 commits into
mainfrom
fix/pre-existing-test-failures
Jul 12, 2026
Merged

Fix nine failing tests on main (regressor forecasting on pandas 2.2+, swallowed CLI messages, task-run 500, task-run timestamps)#2303
Flix6x merged 2 commits into
mainfrom
fix/pre-existing-test-failures

Conversation

@Flix6x

@Flix6x Flix6x commented Jul 12, 2026

Copy link
Copy Markdown
Member

Description

Fixes the nine tests that fail on a clean main (see #2302). None was a stale assertion — they were masking four distinct defects, one of which breaks a production feature.

# Defect Impact
1 _slice_closed() uses deprecated Series.view("int64") and .loc[:, col] = <ndarray> Forecasting with regressors is broken on pandas ≥ 2.2
2 MarshmallowClickMixin.__call__ raises ValueError Every CLI validation message is swallowed
3 get_task_run() retries without rolling back Any DB error becomes an opaque 500
4 LatestTaskRun.datetime default evaluated at import time Task runs stamped with process start time

1. Forecasting with regressors is broken on pandas ≥ 2.2 (4 tests)

BasePipeline.split_data_all_beliefs() raised TypeError: value should be a 'Timestamp', 'NaT', or array of those. Got 'ndarray' instead. This is not test-only — the regressor split path itself fails, so past/future-regressor forecasting is broken on the pandas version we allow.

Two pandas-version problems in four lines of _slice_closed():

  • Series.view("int64") — deprecated in pandas 2.2, removed in 3.0. The int64 detour is unnecessary: np.searchsorted works on datetime64 directly.
  • out.loc[:, "event_start"] = <ndarray>.loc[:, col] = sets values into the existing column's dtype rather than replacing the column.

2. Every CLI validation message was swallowed (1 test)

--account 9999 reported the offending value but never the reason — across every marshmallow-typed option (--asset, --sensor, --source, …), not just --account.

Cause: the click 8.2 upgrade (#2219) removed the click.ParamType base from MarshmallowClickMixin (fixing a Python 3.10 MRO conflict), so click wraps these fields in FuncParamType, whose convert() does self.fail(value, ...) — reporting the value and discarding the message. MarshmallowClickMixin.convert() became dead code.

Fix: raise click.BadParameter carrying the validation message. The ParamType base stays off, so #2219's MRO fix remains intact.

# before
$ flexmeasures monitor last-seen --maximum-minutes-since-last-seen 30 --account 9999
Error: Invalid value for '--account': 9999

# after
$ flexmeasures monitor last-seen --maximum-minutes-since-last-seen 30 --account 9999
Error: Invalid value for '--account': No account found with id 9999.

The option hint is preserved: click's augment_usage_errors() attaches the offending parameter to any BadParameter raised while that parameter is processed. So we gain the reason without losing the hint.

3. GET /api/ops/getLatestTaskRun turns any DB error into an opaque 500 (1 test)

get_task_run() retries its query on a DatabaseError — but does not roll back first. A failed statement leaves the transaction aborted, so the retry is rejected with InFailedSqlTransaction, masking the original error. As written, the retry could never succeed. Now it rolls back before retrying.

(The accompanying test also never declared the fixture that seeds its data, so it queried a database where latest_task_run did not exist — which is what aborted the transaction in the first place.)

4. LatestTaskRun was stamped with the process start time (1 test)

datetime = db.Column(db.DateTime(timezone=True), default=datetime.now(timezone.utc))

The default is evaluated once, at import time, so every task run created without an explicit timestamp got the time the process started — the wrong answer for a table whose only purpose is "when did this task last run?". Both production call sites happen to overwrite .datetime immediately, so the impact was latent, but the default was still wrong. Now a callable.

This is also what made test_api_task_run_get_recent_entry order-dependent: in a long test session, "import time" drifts past the test's 2-minute freshness window.

Plus: two order-dependent tests (2 tests)

test_build_asset_jobs_data and test_get_job_status_requires_read_access asserted on job counts and job identity without flushing the Redis job cache — and @job_cache silently reuses a cached job for an identical scheduling request. Both now use the existing clean_redis fixture. (This is why identical full-suite runs previously produced different failure counts.)

Testing

pytest flexmeasures/data/tests/ flexmeasures/api/ flexmeasures/cli/tests/ flexmeasures/ui/tests/
# 739 passed, 1 xfailed, 0 failed

Baseline on clean main for the same scope: 9 failed. Verified like-for-like (same selection, same machine) that this branch introduces no regressions.

Fixes #2302

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX

- Forecasting with past/future regressors raised a TypeError on pandas 2.2+:
  _slice_closed used the deprecated Series.view("int64") detour and then
  set values into an existing column with .loc[:, col], which validates
  against that column's dtype. Search the datetime64 values directly, and
  replace the column instead of setting into it.
- CLI validation messages were swallowed for every marshmallow-typed option:
  since the click 8.2 upgrade (#2219) removed the click.ParamType base,
  click wraps these fields in FuncParamType, whose convert() reports the
  offending *value* and discards the reason. Raise a click error carrying the
  validation message instead (the ParamType base stays off, to keep the
  Python 3.10 MRO fix intact).
- The task detail page returned a 500 for jobs whose meta data is not
  JSON-serializable, because rq-dashboard serializes meta with a bare
  json.dumps(). Give it a tolerant default (see rq-dashboard#510).

Fixes #2302

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
Flix6x added a commit that referenced this pull request Jul 12, 2026
…essage format

PR #2303 makes click report the validation message rather than the offending
value, which changes the exact wording of this error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
@read-the-docs-community

read-the-docs-community Bot commented Jul 12, 2026

Copy link
Copy Markdown

- [GET] /api/ops/getLatestTaskRun turned any database error into an opaque
  500: the retry in get_task_run() ran on the still-aborted transaction,
  so it was rejected with InFailedSqlTransaction and the original error was
  never surfaced. Roll back before retrying.
- test_api_task_run_get_recent_entry did not declare the fixture seeding its
  data, so it queried a database without the latest_task_run table at all
  (which is what aborted the transaction above).
- test_build_asset_jobs_data and test_get_job_status_requires_read_access
  asserted on job counts and job identity without flushing the Redis job
  cache, so leftover jobs from earlier tests (which @job_cache also reuses
  for identical requests) made them fail depending on test order. Both now
  use the existing clean_redis fixture.

Fixes #2302

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
@Flix6x Flix6x merged commit aac4837 into main Jul 12, 2026
12 of 13 checks passed
@Flix6x Flix6x deleted the fix/pre-existing-test-failures branch July 12, 2026 07:47
@Flix6x Flix6x added this to the 1.0.0 milestone Jul 12, 2026
@Flix6x Flix6x added the bug Something isn't working label Jul 12, 2026
@Flix6x Flix6x self-assigned this Jul 12, 2026
@Flix6x Flix6x changed the title Fix three long-standing failures on main (regressor splits on pandas 2.2+, swallowed CLI validation messages, task page 500) Fix nine failing tests on main (regressor forecasting on pandas 2.2+, swallowed CLI messages, task-run 500, task-run timestamps) Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Six tests fail on main (CLI validation messages swallowed, rq-dashboard 500 on non-JSON job meta, regressor splits broken on pandas >= 2.2)

1 participant