Debug and Extend a Device Registry: Status Validation, Active Counts, Bulk Updates

Quick Overview

A progressive coding exercise on a device registry: find the bug behind a failing test where a device's status must be allowed for its type, then add validated registration, per-type counts of active devices that omit zeros, and a bulk status update based on maintenance time and failure count. It tests code reading and business logic.

Debug and Extend a Device Registry: Status Validation, Active Counts, Bulk Updates

Company: Onepay

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

You are handed a small existing Python module that manages a registry of devices, together with its tests. The exercise has several small steps that build on each other: read the existing code, use a failing test to find a bug, then add follow-up features. It is business-logic implementation rather than algorithm design, so clear structure, validation and tests matter more than clever data structures. The original code was not shared. The module below is a representative reconstruction of the reported bug: a device may be stored only if its status is one that a configuration map allows for that device's type. ```python ALLOWED_STATUSES = { "sensor": {"ACTIVE", "INACTIVE", "MAINTENANCE"}, "camera": {"ACTIVE", "INACTIVE", "FAULTY"}, "gateway": {"ACTIVE", "MAINTENANCE", "FAULTY"}, } class Device: def __init__(self, device_id, device_type, status, registered_at): self.device_id = device_id self.device_type = device_type self.status = status self.registered_at = registered_at self.last_maintenance_at = registered_at self.failure_count = 0 class DeviceRegistry: def __init__(self): self.devices = {} # device_id -> Device def is_valid_status(self, device_type, status): for statuses in ALLOWED_STATUSES.values(): if status in statuses: return True return False def add_device(self, device): if not self.is_valid_status(device.device_type, device.status): return False self.devices[device.device_id] = device return True ``` The failing test: ```python def test_add_device_rejects_status_not_allowed_for_type(): registry = DeviceRegistry() camera = Device("cam-1", "camera", "MAINTENANCE", 100) assert registry.add_device(camera) is False assert "cam-1" not in registry.devices ``` Assume other code, not shown, updates `last_maintenance_at` and `failure_count` as maintenance and failures are recorded. ### Clarifying Questions - Should invalid input be reported by returning `False`, by raising an exception, or by returning an error that names the failed check? - Are device types and statuses case-sensitive, and can the allowed-status map change while the registry is running? - Is the registry used from more than one thread? - Do callers or tests depend on any ordering of returned collections? ### Part 1 — Find and fix the bug Explain why the test fails, fix the bug with a minimal change, and describe which other invalid inputs the same bug lets through. ```hint Follow the unused argument Compare what `is_valid_status` does with its `device_type` argument with the way `ALLOWED_STATUSES` is keyed. ``` #### What This Part Should Cover - The root cause, traced from the failing assertion back to the check - A minimal fix and the other invalid inputs the defect accepted - Regression tests for the fixed behavior ### Part 2 — Register a new device Add `register_device(device_id, device_type, status, registered_at)`. At minimum it must reject a device ID that is already registered, a device type that is not in the map, a status that the map does not allow for that type, and a negative registration time. Otherwise it creates and stores the device. Decide what it returns or raises on each failure, and what else it should validate. ```hint A rejection leaves no trace Think about the order of the checks so that a rejected call never modifies the registry, and about inputs that could raise inside your own validation before it reports anything. ``` #### Clarifying Questions for this Part - Should a duplicate ID whose fields are identical to the stored device count as a harmless retry or as an error? - Is the registration time an integer timestamp, and is a time in the future acceptable? #### What This Part Should Cover - Every reported check (duplicate ID, legal type, status allowed for the type, non-negative time) and the order they run in - Atomicity: a rejected call leaves the registry unchanged - An error-reporting contract that callers and tests can rely on ### Part 3 — Count active devices by type Add `count_active_by_type()`, which returns a mapping from device type to the number of devices whose status is `ACTIVE`. A type with no active devices must not appear in the result. ```hint Where the keys come from Decide whether to start from the list of known types or from the devices themselves, given that zero counts must be left out. ``` #### What This Part Should Cover - Correct omission of types with zero active devices - Time complexity, and whether maintaining live counters is worth it - Deterministic output that tests can compare ### Part 4 — Bulk status update Add a method that updates the status of every device that matches rules based on its last maintenance time and its failure count, and returns how many devices it updated. The exact thresholds, target statuses and precedence were not reported, so settle them through the clarifying questions below before implementing. ```hint Collisions between rules Consider a device that matches both conditions, and a device whose target status is not allowed for its type by `ALLOWED_STATUSES`. ``` #### Clarifying Questions for this Part - What are the thresholds (time since last maintenance, number of failures), and are they parameters or constants? - Which status does each condition move a device to, and which condition wins when both apply? - Does a device that is already in its target status count as updated? - Which current statuses are eligible; for example, should an `INACTIVE` device be touched at all? #### What This Part Should Cover - Explicit, testable rules, including the precedence between the two conditions - Respecting the allowed statuses per type during the update - An updated count that includes only real changes ### What a Strong Answer Covers - Reading the unfamiliar code and the test before editing anything - One validation path reused by every write, so the original bug cannot reappear elsewhere - Edge cases such as an empty registry, unknown types and repeated IDs - Small, incremental changes, each backed by tests - Business questions raised with the interviewer instead of silently guessed ### Follow-up Questions - How would you make `register_device` safe if two threads register the same ID at the same moment? - If the allowed-status map is loaded from configuration and a status is removed, what should happen to devices that currently hold it? - How would you keep an audit history of status changes, including those made by the bulk update?

Overview: A progressive coding exercise on a device registry: find the bug behind a failing test where a device's status must be allowed for its type, then add validated registration, per-type counts of active devices that omit zeros, and a bulk status update based on maintenance time and failure count. It tests code reading and business logic.

|Home/Software Engineering Fundamentals/Onepay
Onepay logo
Onepay
Sep 17, 2026
mediumSoftware EngineerTechnical ScreenSoftware Engineering Fundamentals
0
0

You are handed a small existing Python module that manages a registry of devices, together with its tests. The exercise has several small steps that build on each other: read the existing code, use a failing test to find a bug, then add follow-up features. It is business-logic implementation rather than algorithm design, so clear structure, validation and tests matter more than clever data structures.

The original code was not shared. The module below is a representative reconstruction of the reported bug: a device may be stored only if its status is one that a configuration map allows for that device's type.

ALLOWED_STATUSES = {
    "sensor": {"ACTIVE", "INACTIVE", "MAINTENANCE"},
    "camera": {"ACTIVE", "INACTIVE", "FAULTY"},
    "gateway": {"ACTIVE", "MAINTENANCE", "FAULTY"},
}


class Device:
    def __init__(self, device_id, device_type, status, registered_at):
        self.device_id = device_id
        self.device_type = device_type
        self.status = status
        self.registered_at = registered_at
        self.last_maintenance_at = registered_at
        self.failure_count = 0


class DeviceRegistry:
    def __init__(self):
        self.devices = {}  # device_id -> Device

    def is_valid_status(self, device_type, status):
        for statuses in ALLOWED_STATUSES.values():
            if status in statuses:
                return True
        return False

    def add_device(self, device):
        if not self.is_valid_status(device.device_type, device.status):
            return False
        self.devices[device.device_id] = device
        return True

The failing test:

def test_add_device_rejects_status_not_allowed_for_type():
    registry = DeviceRegistry()
    camera = Device("cam-1", "camera", "MAINTENANCE", 100)
    assert registry.add_device(camera) is False
    assert "cam-1" not in registry.devices

Assume other code, not shown, updates last_maintenance_at and failure_count as maintenance and failures are recorded.

Clarifying Questions Guidance

  • Should invalid input be reported by returning False , by raising an exception, or by returning an error that names the failed check?
  • Are device types and statuses case-sensitive, and can the allowed-status map change while the registry is running?
  • Is the registry used from more than one thread?
  • Do callers or tests depend on any ordering of returned collections?

Part 1 — Find and fix the bug

Explain why the test fails, fix the bug with a minimal change, and describe which other invalid inputs the same bug lets through.

What This Part Should Cover Guidance

  • The root cause, traced from the failing assertion back to the check
  • A minimal fix and the other invalid inputs the defect accepted
  • Regression tests for the fixed behavior

Part 2 — Register a new device

Add register_device(device_id, device_type, status, registered_at). At minimum it must reject a device ID that is already registered, a device type that is not in the map, a status that the map does not allow for that type, and a negative registration time. Otherwise it creates and stores the device. Decide what it returns or raises on each failure, and what else it should validate.

Clarifying Questions for this Part Guidance

  • Should a duplicate ID whose fields are identical to the stored device count as a harmless retry or as an error?
  • Is the registration time an integer timestamp, and is a time in the future acceptable?

What This Part Should Cover Guidance

  • Every reported check (duplicate ID, legal type, status allowed for the type, non-negative time) and the order they run in
  • Atomicity: a rejected call leaves the registry unchanged
  • An error-reporting contract that callers and tests can rely on

Part 3 — Count active devices by type

Add count_active_by_type(), which returns a mapping from device type to the number of devices whose status is ACTIVE. A type with no active devices must not appear in the result.

What This Part Should Cover Guidance

  • Correct omission of types with zero active devices
  • Time complexity, and whether maintaining live counters is worth it
  • Deterministic output that tests can compare

Part 4 — Bulk status update

Add a method that updates the status of every device that matches rules based on its last maintenance time and its failure count, and returns how many devices it updated. The exact thresholds, target statuses and precedence were not reported, so settle them through the clarifying questions below before implementing.

Clarifying Questions for this Part Guidance

  • What are the thresholds (time since last maintenance, number of failures), and are they parameters or constants?
  • Which status does each condition move a device to, and which condition wins when both apply?
  • Does a device that is already in its target status count as updated?
  • Which current statuses are eligible; for example, should an INACTIVE device be touched at all?

What This Part Should Cover Guidance

  • Explicit, testable rules, including the precedence between the two conditions
  • Respecting the allowed statuses per type during the update
  • An updated count that includes only real changes

What a Strong Answer Covers Guidance

  • Reading the unfamiliar code and the test before editing anything
  • One validation path reused by every write, so the original bug cannot reappear elsewhere
  • Edge cases such as an empty registry, unknown types and repeated IDs
  • Small, incremental changes, each backed by tests
  • Business questions raised with the interviewer instead of silently guessed

Follow-up Questions Guidance

  • How would you make register_device safe if two threads register the same ID at the same moment?
  • If the allowed-status map is loaded from configuration and a status is removed, what should happen to devices that currently hold it?
  • How would you keep an audit history of status changes, including those made by the bulk update?
Loading comments...