Back to Repositories

Testing Alert Duration Management Implementation in OpenPilot

This test suite validates the AlertManager component in the OpenPilot self-driving system, focusing on alert duration handling and timing mechanisms. It ensures alerts are properly managed and displayed for the correct duration periods.

Test Coverage Overview

The test suite provides comprehensive coverage of the AlertManager’s duration handling capabilities.

Key areas tested include:
  • Alert duration enforcement for various time periods
  • Alert persistence when duration exceeds add time
  • Alert extension behavior when re-added before expiration
  • Edge cases with random durations from 1-100 frames

Implementation Analysis

The implementation uses a systematic approach to test alert duration behavior through randomized testing. It leverages Python’s random module to generate test cases, with explicit validation of alert states across different timing scenarios.

The testing pattern includes:
  • Random alert selection from EVENTS dictionary
  • Multiple duration test cases (shorter/longer than alert duration)
  • Frame-by-frame state verification

Technical Details

Testing tools and configuration:
  • Python unit testing framework
  • AlertManager class from selfdrive.selfdrived.alertmanager
  • Alert and EmptyAlert classes from events module
  • Random test data generation
  • Frame-based timing simulation

Best Practices Demonstrated

The test implementation showcases several testing best practices.

Notable practices include:
  • Comprehensive edge case coverage
  • Randomized test data generation
  • Clear assertion messages with detailed state information
  • Systematic testing of multiple scenarios
  • Explicit state verification at each step

commaai/openpilot

selfdrive/selfdrived/tests/test_alertmanager.py

            
import random

from openpilot.selfdrive.selfdrived.events import Alert, EmptyAlert, EVENTS
from openpilot.selfdrive.selfdrived.alertmanager import AlertManager


class TestAlertManager:

  def test_duration(self):
    """
      Enforce that an alert lasts for max(alert duration, duration the alert is added)
    """
    for duration in range(1, 100):
      alert = None
      while not isinstance(alert, Alert):
        event = random.choice([e for e in EVENTS.values() if len(e)])
        alert = random.choice(list(event.values()))

      alert.duration = duration

      # check two cases:
      # - alert is added to AM for <= the alert's duration
      # - alert is added to AM for > alert's duration
      for greater in (True, False):
        if greater:
          add_duration = duration + random.randint(1, 10)
        else:
          add_duration = random.randint(1, duration)
        show_duration = max(duration, add_duration)

        AM = AlertManager()
        for frame in range(duration+10):
          if frame < add_duration:
            AM.add_many(frame, [alert, ])
          AM.process_alerts(frame, set())

          shown = AM.current_alert != EmptyAlert
          should_show = frame <= show_duration
          assert shown == should_show, f"{frame=} {add_duration=} {duration=}"

      # check one case:
      # - if alert is re-added to AM before it ends the duration is extended
      if duration > 1:
        AM = AlertManager()
        show_duration = duration * 2
        for frame in range(duration * 2 + 10):
          if frame == 0:
            AM.add_many(frame, [alert, ])

          if frame == duration:
            # add alert one frame before it ends
            assert AM.current_alert == alert
            AM.add_many(frame, [alert, ])
          AM.process_alerts(frame, set())

          shown = AM.current_alert != EmptyAlert
          should_show = frame <= show_duration
          assert shown == should_show, f"{frame=} {duration=}"