Skip to content

feat: expand integration tests with new input types and mode transitions#2274

Merged
openminddev merged 15 commits intoOpenMind:mainfrom
0xbyt4:feature/integration-test-expansion
Feb 15, 2026
Merged

feat: expand integration tests with new input types and mode transitions#2274
openminddev merged 15 commits intoOpenMind:mainfrom
0xbyt4:feature/integration-test-expansion

Conversation

@0xbyt4
Copy link
Collaborator

@0xbyt4 0xbyt4 commented Feb 15, 2026

Summary

  • Add integration tests for 5 new input types: ASR (greeting, question), battery (low), odometry (moving), GPS (outdoor location)
  • Add multi-input combination test: VLM + ASR simultaneous processing
  • Add 4 mode transition tests: input-triggered, negative (no transition), time-based timeout, and cooldown prevention
  • Add mock implementations: MockGoogleASR, MockUnitreeGo2Battery, MockUnitreeGo2Odom, MockGps with data providers (MockTextProvider, MockStateProvider)
  • Fix upstream test runner issues: typo in fixture name, DRY violations (normalize_expected_value, _extract_emotion, _detect_input_type), dead code removal, mutable default argument fix, rating_description deduplication

New Test Cases

Test Case Input Type What It Tests
asr_greeting_test ASR Robot responds to voice greeting
asr_question_test ASR Robot responds to voice question
battery_low_test Battery + VLM Low battery triggers warning behavior
odometry_awareness_test Odometry + VLM Robot aware of movement state
gps_location_test GPS + VLM Robot aware of geographic location
multi_input_vlm_asr_test VLM + ASR Combined visual and audio processing
mode_transition_test ASR (mode) Input-triggered calm -> alert transition
mode_no_transition_test ASR (mode) No transition when keywords absent
mode_time_based_test ASR (mode) Time-based patrol -> idle transition
mode_cooldown_test ASR (mode) Cooldown prevents repeated transitions

File Structure

tests/integration/
├── test_case_runner.py                          # MODIFIED - new runners + refactoring
├── data/
│   ├── images/
│   │   ├── indoor_1.jpg                         # existing
│   │   └── indoor_2.jpg                         # existing
│   ├── lidar/
│   │   └── sample_scan.json                     # existing
│   ├── asr/                                     # NEW directory
│   │   ├── emergency.json                       # new
│   │   ├── greeting.json                        # new
│   │   └── weather_question.json                # new
│   ├── gps/                                     # NEW directory
│   │   └── outdoor_location.json                # new
│   ├── state/                                   # NEW directory
│   │   ├── battery_low.json                     # new
│   │   └── odometry_moving.json                 # new
│   └── test_cases/
│       ├── coco_indoor_test.json5               # existing
│       ├── gemini_indoor_test.json5             # existing
│       ├── open_ai_indoor_test.json5            # existing
│       ├── rplidar_test.json5                   # existing
│       ├── vila_indoor_test.json5               # existing
│       ├── asr_greeting_test.json5              # new
│       ├── asr_question_test.json5              # new
│       ├── battery_low_test.json5               # new
│       ├── gps_location_test.json5              # new
│       ├── odometry_awareness_test.json5        # new
│       ├── multi_input_vlm_asr_test.json5       # new
│       ├── mode_transition_test.json5           # new
│       ├── mode_no_transition_test.json5        # new
│       ├── mode_time_based_test.json5           # new
│       └── mode_cooldown_test.json5             # new
└── mock_inputs/
    ├── __init__.py                              # existing
    ├── input_registry.py                        # MODIFIED - dict-based restoration
    ├── mock_vlm_coco.py                         # existing
    ├── mock_vlm_gemini.py                       # existing
    ├── mock_vlm_openai.py                       # existing
    ├── mock_vlm_vila.py                         # existing
    ├── mock_unitree_go2_rplidar.py              # existing
    ├── mock_google_asr.py                       # new
    ├── mock_battery.py                          # new
    ├── mock_gps.py                              # new
    ├── mock_odometry.py                         # new
    └── data_providers/
        ├── __init__.py                          # new
        ├── mock_image_provider.py               # existing
        ├── mock_lidar_scan_provider.py          # existing
        ├── mock_text_provider.py                # new
        └── mock_state_provider.py               # new

Add ASR, battery, odometry, GPS mock inputs and test cases.
Add mode transition integration test verifying input-triggered
transitions through the full cortex runtime pipeline.
Replace no-op transition callback with real _on_mode_transition.
Only mock _start_orchestrators to prevent infinite loops. This
tests the actual transition: stop orchestrators, reinitialize
mode components, and verify new config is loaded.
Add three new integration test scenarios for mode transitions:
- Negative case: verify no transition when input lacks trigger keywords
- Time-based: verify timeout-triggered mode transition
- Cooldown: verify cooldown prevents repeated transitions

Also fix missing timeout_seconds in build_multi_mode_config.
Filter cooldown and time-based configs in discover_mode_transition_test_cases()
instead of skipping them inside test_mode_transition(). Discovery should only
return configs that will actually be run.
Keywords are checked against the fused prompt (raw_response), not the
LLM output. Original keywords included words not present in the prompt
(e.g. "forecast", "temperature", "power", "location"). Replaced with
keywords verified to exist in system_prompt or mock input output.
- Move `import json` to top-level (maintainer convention)
- Remove unused MockTextProvider.text_count, remaining_texts properties
- Remove unused MockStateProvider.reset_all() method
- Remove unused load_test_texts() wrapper function
- Remove redundant section comments in mock_state_provider.py
The -k flag filters by test ID, not file name. Parametrized test IDs
use numeric indices (test_case_path0, test_case_path1) so -k "asr"
or -k "battery" would match nothing.
- Fix typo: mock_confige_provider -> mock_config_provider
- Extract normalize_expected_value, _detect_input_type, _extract_emotion
  to module-level to eliminate duplicate definitions
- Remove dead code: pass inside try/except that can never raise
- Collapse 3 identical rating_description branches into one
- Add GPS-only case to get_movement_types_for_config
- Fix mutable default argument (= [] -> = None) in mock_llm_ask
- Replace if/elif chain with dict-based class restoration in input_registry
Match upstream convention where empty config objects are omitted
from agent_inputs in JSON5 config files.
… conversation provider mock

- Fix load_test_state_data to collect all entries before loading,
  preventing data overwrite when multiple files are specified
- Extract _setup_mode_transition_mocks and _cleanup_mode_transition_test
  helpers to eliminate repeated setup/teardown code
- Add _MockConversationProvider to MockGoogleASR to match upstream
  formatted_latest_buffer behavior (store_user_message call)
- Remove unused battery_full.json (no test uses it, battery mock only
  reports for low levels)
@0xbyt4 0xbyt4 requested a review from a team as a code owner February 15, 2026 19:40
@github-actions github-actions bot added python Python code tests Test files config Configuration files labels Feb 15, 2026
@codecov
Copy link

codecov bot commented Feb 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@openminddev
Copy link
Contributor

Great PR! Thank you.

@openminddev openminddev merged commit 4003f32 into OpenMind:main Feb 15, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Configuration files python Python code tests Test files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants