From 983e5f667a9425ffb0d1e4da65815bede31079b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 00:08:10 +0000 Subject: [PATCH 1/6] Initial plan From 8b931fe988ddc34fa313fbaff1339fa7ea58f71c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 00:11:11 +0000 Subject: [PATCH 2/6] Merge PR #1155 changes Agent-Logs-Url: https://github.com/open-edge-platform/scenescape/sessions/b01747ad-5665-488d-9575-5f6498edd0f5 Co-authored-by: saratpoluri <1325325+saratpoluri@users.noreply.github.com> --- controller/src/controller/ilabs_tracking.py | 26 +++++++++++++++---- controller/src/controller/uuid_manager.py | 7 ++++- .../rv/tracking/MultipleObjectTracker.hpp | 10 +++++++ .../src/robot_vision/extensions/tracking.cpp | 6 +++++ 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/controller/src/controller/ilabs_tracking.py b/controller/src/controller/ilabs_tracking.py index 58b604b376..b49f0dbb14 100644 --- a/controller/src/controller/ilabs_tracking.py +++ b/controller/src/controller/ilabs_tracking.py @@ -129,7 +129,13 @@ def from_tracked_object(self, tracked_object, objects): sscape_object.inferRotationFromVelocity() break if not found: - sscape_object.setGID(uuid) + # Check if UUID manager already has a mapping for this rv_id + with self.uuid_manager.active_ids_lock: + existing_gid = self.uuid_manager.active_ids.get(sscape_object.rv_id, [None])[0] + if existing_gid is None: + sscape_object.setGID(uuid) + else: + sscape_object.setGID(existing_gid) self.uuid_manager.assignID(sscape_object) @@ -176,8 +182,13 @@ def trackCategory(self, objects, when, already_tracked_objects): """Create reliable tracks for objects detected and tracks detected""" when = datetime.fromtimestamp(when) self.update_tracks(objects, when) - tracked_objects = self.tracker.get_reliable_tracks() - self.uuid_manager.pruneInactiveTracks(tracked_objects) + reliable_tracks = self.tracker.get_reliable_tracks() + # Include ALL active C++ tracks to preserve UUID mappings + all_active_tracks = set(reliable_tracks + + self.tracker.get_unreliable_tracks() + + self.tracker.get_suspended_tracks()) + tracked_objects = reliable_tracks + self.uuid_manager.pruneInactiveTracks(all_active_tracks) tracks_from_detections = [self.from_tracked_object(tracked_object, objects) for tracked_object in tracked_objects] @@ -190,8 +201,13 @@ def trackCategoryBatched(self, objects_per_camera, when, already_tracked_objects """Create reliable tracks for objects from multiple cameras using batched tracking""" when = datetime.fromtimestamp(when) self.update_tracks_batched(objects_per_camera, when) - tracked_objects = self.tracker.get_reliable_tracks() - self.uuid_manager.pruneInactiveTracks(tracked_objects) + reliable_tracks = self.tracker.get_reliable_tracks() + # Include ALL active C++ tracks to preserve UUID mappings + all_active_tracks = set(reliable_tracks + + self.tracker.get_unreliable_tracks() + + self.tracker.get_suspended_tracks()) + tracked_objects = reliable_tracks + self.uuid_manager.pruneInactiveTracks(all_active_tracks) # Flatten all objects for from_tracked_object lookup all_objects = [obj for camera_objects in objects_per_camera for obj in camera_objects] diff --git a/controller/src/controller/uuid_manager.py b/controller/src/controller/uuid_manager.py index 5102c2da1a..9ab61caa22 100644 --- a/controller/src/controller/uuid_manager.py +++ b/controller/src/controller/uuid_manager.py @@ -46,7 +46,7 @@ def pruneInactiveTracks(self, tracked_objects): @param tracked_objects The objects currently tracked by the tracker """ - active_tracks = [tracked_object.id for tracked_object in tracked_objects] + active_tracks = {tracked_object.id for tracked_object in tracked_objects} inactive_tracks = [] new_active_ids = {} with self.active_ids_lock: @@ -290,6 +290,11 @@ def assignID(self, sscape_object): if sscape_object.rv_id not in self.active_query: self.active_query[sscape_object.rv_id] = True self.pool.submit(self.querySimilarity, sscape_object) + else: + # Re-ID is disabled or we don't have enough features; fall back to using the generated GID + with self.active_ids_lock: + if self.active_ids.get(sscape_object.rv_id, [None])[0] is None: + self.active_ids[sscape_object.rv_id] = [sscape_object.gid, None] else: self.pickBestID(sscape_object) return diff --git a/controller/src/robot_vision/include/rv/tracking/MultipleObjectTracker.hpp b/controller/src/robot_vision/include/rv/tracking/MultipleObjectTracker.hpp index de3d52d260..0d9a943885 100644 --- a/controller/src/robot_vision/include/rv/tracking/MultipleObjectTracker.hpp +++ b/controller/src/robot_vision/include/rv/tracking/MultipleObjectTracker.hpp @@ -82,6 +82,16 @@ class MultipleObjectTracker return mTrackManager.getReliableTracks(); } + inline std::vector getSuspendedTracks() + { + return mTrackManager.getSuspendedTracks(); + } + + inline std::vector getUnreliableTracks() + { + return mTrackManager.getUnreliableTracks(); + } + /** * @brief Returns a the list of all active tracked objects * diff --git a/controller/src/robot_vision/python/src/robot_vision/extensions/tracking.cpp b/controller/src/robot_vision/python/src/robot_vision/extensions/tracking.cpp index 8d1df4720d..629edaa279 100644 --- a/controller/src/robot_vision/python/src/robot_vision/extensions/tracking.cpp +++ b/controller/src/robot_vision/python/src/robot_vision/extensions/tracking.cpp @@ -325,6 +325,12 @@ py::class_(tracking, "Classification", "Classifica .def("get_reliable_tracks", &rv::tracking::MultipleObjectTracker::getReliableTracks, "Returns a list of all active reliable tracks.") + .def("get_suspended_tracks", + &rv::tracking::MultipleObjectTracker::getSuspendedTracks, + "Returns a list of all suspended tracks.") + .def("get_unreliable_tracks", + &rv::tracking::MultipleObjectTracker::getUnreliableTracks, + "Returns a list of all active unreliable tracks.") .def("update_tracker_params", &rv::tracking::MultipleObjectTracker::updateTrackerParams, "Updates tracker frame based parameters."); From 695e8cb2b36871898e33f0a4cfc689fca13f46b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 00:13:21 +0000 Subject: [PATCH 3/6] Fix: change else to elif not self.reid_enabled in assignID fallback Agent-Logs-Url: https://github.com/open-edge-platform/scenescape/sessions/b01747ad-5665-488d-9575-5f6498edd0f5 Co-authored-by: saratpoluri <1325325+saratpoluri@users.noreply.github.com> --- controller/src/controller/uuid_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controller/src/controller/uuid_manager.py b/controller/src/controller/uuid_manager.py index 9ab61caa22..26b66f147f 100644 --- a/controller/src/controller/uuid_manager.py +++ b/controller/src/controller/uuid_manager.py @@ -290,8 +290,8 @@ def assignID(self, sscape_object): if sscape_object.rv_id not in self.active_query: self.active_query[sscape_object.rv_id] = True self.pool.submit(self.querySimilarity, sscape_object) - else: - # Re-ID is disabled or we don't have enough features; fall back to using the generated GID + elif not self.reid_enabled: + # Re-ID is disabled; fall back to using the generated GID with self.active_ids_lock: if self.active_ids.get(sscape_object.rv_id, [None])[0] is None: self.active_ids[sscape_object.rv_id] = [sscape_object.gid, None] From a68e92807361d1a3830968bac89af87e4cf49fc5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 21 May 2026 00:14:54 +0000 Subject: [PATCH 4/6] test(controller): add unit tests for UUIDManager (PR #1155 and Re-ID fallback fix) Agent-Logs-Url: https://github.com/open-edge-platform/scenescape/sessions/2c08cbd9-3c79-4c79-a87d-7d620301877d Co-authored-by: saratpoluri <1325325+saratpoluri@users.noreply.github.com> --- tests/sscape_tests/uuid_manager/__init__.py | 2 + tests/sscape_tests/uuid_manager/conftest.py | 26 ++ .../uuid_manager/test_uuid_manager.py | 361 ++++++++++++++++++ 3 files changed, 389 insertions(+) create mode 100644 tests/sscape_tests/uuid_manager/__init__.py create mode 100644 tests/sscape_tests/uuid_manager/conftest.py create mode 100644 tests/sscape_tests/uuid_manager/test_uuid_manager.py diff --git a/tests/sscape_tests/uuid_manager/__init__.py b/tests/sscape_tests/uuid_manager/__init__.py new file mode 100644 index 0000000000..78bbdf41b1 --- /dev/null +++ b/tests/sscape_tests/uuid_manager/__init__.py @@ -0,0 +1,2 @@ +# SPDX-FileCopyrightText: (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 diff --git a/tests/sscape_tests/uuid_manager/conftest.py b/tests/sscape_tests/uuid_manager/conftest.py new file mode 100644 index 0000000000..81be4a147e --- /dev/null +++ b/tests/sscape_tests/uuid_manager/conftest.py @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import sys +from unittest.mock import MagicMock + +import tests.common_test_utils as common + +TEST_NAME = "NEX-T10700" + +# Mock the vdms module before importing controller modules that depend on it. +sys.modules.setdefault('vdms', MagicMock()) + + +def pytest_sessionstart(): + """! Executes at the beginning of the session. """ + + print(f"Executing: {TEST_NAME}") + return + + +def pytest_sessionfinish(exitstatus): + """! Executes at the end of the session. """ + + common.record_test_result(TEST_NAME, exitstatus) + return diff --git a/tests/sscape_tests/uuid_manager/test_uuid_manager.py b/tests/sscape_tests/uuid_manager/test_uuid_manager.py new file mode 100644 index 0000000000..e6d0613081 --- /dev/null +++ b/tests/sscape_tests/uuid_manager/test_uuid_manager.py @@ -0,0 +1,361 @@ +# SPDX-FileCopyrightText: (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +"""Unit tests for controller.UUIDManager. + +Covers: + - PR #1155: preserve UUID for static objects after occlusion + * pruneInactiveTracks correctly prunes only truly inactive tracks when + given a set of all active C++ tracker objects (reliable + unreliable + + suspended). + * pickBestID restores a previously assigned GID from active_ids so a + reappearing static object keeps its original identity. + - Current PR fix: prevent Re-ID fallback from firing while features are + still being gathered + * When Re-ID is enabled but the feature count has not yet reached the + minimum, active_ids[rv_id] stays [None, None] (no premature lock-in). + * When Re-ID is explicitly disabled the GID fallback fires immediately. + * When Re-ID is enabled and sufficient features exist the similarity + query is submitted to the thread pool. +""" + +import collections +import sys +import threading +from unittest.mock import MagicMock + +import numpy as np +import pytest + +# Ensure the vdms stub is present before any controller import +sys.modules.setdefault('vdms', MagicMock()) + +from controller.uuid_manager import (DEFAULT_MINIMUM_FEATURE_COUNT, + DEFAULT_MINIMUM_BBOX_AREA, + UUIDManager) + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + +def _make_uuid_manager(): + """Create a UUIDManager with all external dependencies mocked out.""" + um = UUIDManager.__new__(UUIDManager) + um.active_ids = {} + um.active_ids_lock = threading.Lock() + um.active_query = {} + um.features_for_database = {} + um.quality_features = {} + um.unique_id_count = 0 + um.reid_database = MagicMock() + um.pool = MagicMock() + um.similarity_query_times = collections.deque(maxlen=10) + um.similarity_query_times_lock = threading.Lock() + um.reid_enabled = True + return um + + +def _make_sscape_object(rv_id=1, gid='test-gid', reid_vector=None, + bbox_area=10000, category='person'): + """Create a minimal mock Scenescape object.""" + obj = MagicMock() + obj.rv_id = rv_id + obj.gid = gid + obj.reidVector = reid_vector if reid_vector is not None else np.ones((1, 256)) + obj.boundingBoxPixels = MagicMock() + obj.boundingBoxPixels.area = bbox_area + obj.category = category + obj.similarity = None + return obj + + +def _populate_features(uuid_manager, rv_id, count): + """Insert *count* dummy ReID vectors for *rv_id* into quality_features.""" + uuid_manager.quality_features[rv_id] = [np.ones((1, 256)) for _ in range(count)] + + +# =========================================================================== +# PR #1155 – preserve UUID for static objects after occlusion +# =========================================================================== + +class TestPruneInactiveTracks: + """pruneInactiveTracks must accept a *set* of tracked objects and remove + only the tracks whose IDs are absent from that set.""" + + def test_preserves_tracks_present_in_active_set(self, uuid_manager): + """! Tracks still present in the active set are kept in active_ids. + + Verifies that a track ID found in the supplied set is NOT removed. + """ + uuid_manager.active_ids = {1: ['gid-1', None], 2: ['gid-2', 0.3]} + + active_obj = _make_tracked_obj(1) + uuid_manager.pruneInactiveTracks({active_obj}) + + assert 1 in uuid_manager.active_ids + + def test_removes_tracks_absent_from_active_set(self, uuid_manager): + """! Tracks absent from the active set are removed from active_ids. + + Verifies that a track ID NOT found in the supplied set IS removed. + """ + uuid_manager.active_ids = {1: ['gid-1', None], 2: ['gid-2', None]} + + active_obj = _make_tracked_obj(1) + uuid_manager.pruneInactiveTracks({active_obj}) + + assert 2 not in uuid_manager.active_ids + + def test_accepts_set_containing_suspended_tracks(self, uuid_manager): + """! Passing a mixed set of reliable, unreliable, and suspended track + objects preserves all their IDs (mirrors the PR #1155 change that passes + set(reliable + unreliable + suspended) to pruneInactiveTracks). + """ + uuid_manager.active_ids = { + 10: ['gid-reliable', 0.2], + 20: ['gid-unreliable', None], + 30: ['gid-suspended', None], + } + + reliable = _make_tracked_obj(10) + unreliable = _make_tracked_obj(20) + suspended = _make_tracked_obj(30) + + all_active = {reliable, unreliable, suspended} + uuid_manager.pruneInactiveTracks(all_active) + + assert 10 in uuid_manager.active_ids + assert 20 in uuid_manager.active_ids + assert 30 in uuid_manager.active_ids + + def test_increments_unique_id_count_for_unmatched_tracks(self, uuid_manager): + """! When an inactive track has similarity==None, unique_id_count + is incremented because no database match was found for that object. + """ + uuid_manager.active_ids = {5: ['gid-5', None]} # similarity is None → new object + uuid_manager.unique_id_count = 0 + + uuid_manager.pruneInactiveTracks(set()) # empty → track 5 is inactive + + assert uuid_manager.unique_id_count == 1 + + def test_does_not_increment_unique_id_count_for_matched_tracks(self, uuid_manager): + """! When an inactive track has a non-None similarity score, it was + matched to an existing database entry and unique_id_count must NOT + be incremented. + """ + uuid_manager.active_ids = {5: ['gid-5', 12.3]} # similarity is not None → matched + uuid_manager.unique_id_count = 0 + + uuid_manager.pruneInactiveTracks(set()) + + assert uuid_manager.unique_id_count == 0 + + def test_suspended_track_uuid_survives_occlusion(self, uuid_manager): + """! Simulates an object becoming occluded (moving to suspended state) + and reappearing. + + When the object's rv_id is included in all_active_tracks (because the + C++ tracker keeps the suspended track alive), its GID must not be + removed from active_ids, so when it reappears pickBestID can restore + the original GID. + """ + rv_id = 42 + original_gid = 'original-gid' + uuid_manager.active_ids = {rv_id: [original_gid, None]} + + # Object is suspended – its ID IS in the all_active set + suspended_track = _make_tracked_obj(rv_id) + uuid_manager.pruneInactiveTracks({suspended_track}) + + # GID must still be present + assert rv_id in uuid_manager.active_ids + assert uuid_manager.active_ids[rv_id][0] == original_gid + + +# =========================================================================== +# PR #1155 – pickBestID restores GID for reappearing static objects +# =========================================================================== + +class TestPickBestID: + """pickBestID must restore the database GID (and similarity) from + active_ids onto the sscape_object when an existing mapping exists.""" + + def test_restores_gid_from_active_ids(self, uuid_manager, sscape_object): + """! When active_ids contains a non-None GID for the track, pickBestID + sets that GID on the object so the original identity is preserved. + """ + stored_gid = 'database-uuid' + stored_similarity = 5.2 + uuid_manager.active_ids[sscape_object.rv_id] = [stored_gid, stored_similarity] + + uuid_manager.pickBestID(sscape_object) + + assert sscape_object.gid == stored_gid + assert sscape_object.similarity == stored_similarity + + def test_sets_similarity_none_when_no_mapping(self, uuid_manager, sscape_object): + """! When active_ids has no entry for the track, similarity is set to + None and the object's gid is left unchanged. + """ + uuid_manager.active_ids = {} + sscape_object.gid = 'original-gid' + + uuid_manager.pickBestID(sscape_object) + + assert sscape_object.similarity is None + + def test_accumulates_reid_vectors_for_known_track(self, uuid_manager, sscape_object): + """! Once a GID is locked in active_ids and the object has reid + vectors, subsequent calls to pickBestID append them to + features_for_database so the track can be indexed on departure. + """ + stored_gid = 'database-uuid' + uuid_manager.active_ids[sscape_object.rv_id] = [stored_gid, None] + uuid_manager.features_for_database[sscape_object.rv_id] = { + 'gid': stored_gid, + 'category': sscape_object.category, + 'reid_vectors': [], + } + reid_vector = np.ones((1, 256)) + sscape_object.reidVector = reid_vector + + uuid_manager.pickBestID(sscape_object) + + assert len(uuid_manager.features_for_database[sscape_object.rv_id]['reid_vectors']) == 1 + + +# =========================================================================== +# Current PR fix – elif not self.reid_enabled +# =========================================================================== + +class TestAssignIDFallbackBehavior: + """The GID fallback in assignID must fire ONLY when re-id is explicitly + disabled, never while feature collection is still in progress.""" + + def test_reid_enabled_insufficient_features_does_not_lock_gid( + self, uuid_manager, sscape_object): + """! Core bug-fix regression test: with re-id enabled and fewer than + DEFAULT_MINIMUM_FEATURE_COUNT features gathered, active_ids must stay + [None, None] so that feature collection continues on subsequent frames. + + Before the fix the 'else' branch would set active_ids[rv_id] to + [gid, None] on the very first frame, causing isNewTrackerID() to return + False on subsequent frames and permanently skipping + gatherQualityVisualFeatures(). + """ + uuid_manager.reid_enabled = True + # Seed fewer features than the minimum + _populate_features(uuid_manager, sscape_object.rv_id, + DEFAULT_MINIMUM_FEATURE_COUNT - 1) + + uuid_manager.assignID(sscape_object) + + # active_ids should remain [None, None] – GID must NOT be locked in yet + assert uuid_manager.active_ids.get(sscape_object.rv_id) == [None, None] + + def test_reid_enabled_gid_not_locked_across_multiple_frames( + self, uuid_manager, sscape_object): + """! Calling assignID repeatedly while features are still accumulating + must keep active_ids[rv_id] == [None, None] on every call (not + prematurely lock the GID after the first call). + """ + uuid_manager.reid_enabled = True + + for _ in range(DEFAULT_MINIMUM_FEATURE_COUNT - 1): + uuid_manager.assignID(sscape_object) + assert uuid_manager.active_ids.get(sscape_object.rv_id) == [None, None], \ + "GID was locked before sufficient features were collected" + + def test_reid_disabled_locks_gid_immediately(self, uuid_manager, sscape_object): + """! When re-id is disabled the GID fallback must fire on the first + call to assignID, setting active_ids[rv_id] to [gid, None]. + """ + uuid_manager.reid_enabled = False + + uuid_manager.assignID(sscape_object) + + result = uuid_manager.active_ids.get(sscape_object.rv_id) + assert result == [sscape_object.gid, None] + + def test_reid_enabled_sufficient_features_submits_query( + self, uuid_manager, sscape_object): + """! When re-id is enabled and the feature count reaches + DEFAULT_MINIMUM_FEATURE_COUNT, a similarity query must be submitted + to the thread pool exactly once. + """ + uuid_manager.reid_enabled = True + _populate_features(uuid_manager, sscape_object.rv_id, + DEFAULT_MINIMUM_FEATURE_COUNT) + + uuid_manager.assignID(sscape_object) + + uuid_manager.pool.submit.assert_called_once() + + def test_reid_enabled_sufficient_features_query_submitted_only_once( + self, uuid_manager, sscape_object): + """! Once the similarity query has been submitted (active_query[rv_id] + is set), subsequent frames must not submit it again even if the feature + count remains above the minimum. + """ + uuid_manager.reid_enabled = True + _populate_features(uuid_manager, sscape_object.rv_id, + DEFAULT_MINIMUM_FEATURE_COUNT) + + uuid_manager.assignID(sscape_object) # first call – query submitted + uuid_manager.assignID(sscape_object) # second call – should not re-submit + + assert uuid_manager.pool.submit.call_count == 1 + + def test_assign_id_known_tracker_id_calls_pick_best_id( + self, uuid_manager, sscape_object): + """! For a track that already has an entry in active_ids with a non-None + GID (i.e., isNewTrackerID returns False), assignID must call pickBestID + to apply the stored GID to the object. + """ + stored_gid = 'already-resolved-gid' + uuid_manager.active_ids[sscape_object.rv_id] = [stored_gid, 3.1] + + uuid_manager.assignID(sscape_object) + + assert sscape_object.gid == stored_gid + + def test_reid_disabled_no_query_submitted(self, uuid_manager, sscape_object): + """! When re-id is disabled the thread pool must never be asked to run + a similarity query. + """ + uuid_manager.reid_enabled = False + _populate_features(uuid_manager, sscape_object.rv_id, + DEFAULT_MINIMUM_FEATURE_COUNT) + + uuid_manager.assignID(sscape_object) + + uuid_manager.pool.submit.assert_not_called() + + +# =========================================================================== +# Supporting helpers +# =========================================================================== + +def _make_tracked_obj(track_id): + """Return a minimal mock with .id set to *track_id*.""" + obj = MagicMock() + obj.id = track_id + return obj + + +# --------------------------------------------------------------------------- +# Pytest fixtures +# --------------------------------------------------------------------------- + +@pytest.fixture +def uuid_manager(): + """Provide a fresh UUIDManager for each test.""" + return _make_uuid_manager() + + +@pytest.fixture +def sscape_object(): + """Provide a default mock Scenescape object.""" + return _make_sscape_object() From 15fefe16ccc2f8a7bb5df8b482ccdd6746eb303f Mon Sep 17 00:00:00 2001 From: Sarat Poluri Date: Wed, 20 May 2026 17:33:38 -0700 Subject: [PATCH 5/6] Minor fixes --- tests/sscape_tests/uuid_manager/__init__.py | 2 -- tests/sscape_tests/uuid_manager/conftest.py | 4 +-- .../uuid_manager/test_uuid_manager.py | 25 ++----------------- 3 files changed, 4 insertions(+), 27 deletions(-) delete mode 100644 tests/sscape_tests/uuid_manager/__init__.py diff --git a/tests/sscape_tests/uuid_manager/__init__.py b/tests/sscape_tests/uuid_manager/__init__.py deleted file mode 100644 index 78bbdf41b1..0000000000 --- a/tests/sscape_tests/uuid_manager/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-FileCopyrightText: (C) 2025 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 diff --git a/tests/sscape_tests/uuid_manager/conftest.py b/tests/sscape_tests/uuid_manager/conftest.py index 81be4a147e..d73e876ed9 100644 --- a/tests/sscape_tests/uuid_manager/conftest.py +++ b/tests/sscape_tests/uuid_manager/conftest.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: (C) 2025 Intel Corporation +# SPDX-FileCopyrightText: (C) 2026 Intel Corporation # SPDX-License-Identifier: Apache-2.0 import sys @@ -6,7 +6,7 @@ import tests.common_test_utils as common -TEST_NAME = "NEX-T10700" +TEST_NAME = "NEX-T19884" # Mock the vdms module before importing controller modules that depend on it. sys.modules.setdefault('vdms', MagicMock()) diff --git a/tests/sscape_tests/uuid_manager/test_uuid_manager.py b/tests/sscape_tests/uuid_manager/test_uuid_manager.py index e6d0613081..74ebcdd943 100644 --- a/tests/sscape_tests/uuid_manager/test_uuid_manager.py +++ b/tests/sscape_tests/uuid_manager/test_uuid_manager.py @@ -1,23 +1,7 @@ -# SPDX-FileCopyrightText: (C) 2025 Intel Corporation +# SPDX-FileCopyrightText: (C) 2026 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -"""Unit tests for controller.UUIDManager. - -Covers: - - PR #1155: preserve UUID for static objects after occlusion - * pruneInactiveTracks correctly prunes only truly inactive tracks when - given a set of all active C++ tracker objects (reliable + unreliable + - suspended). - * pickBestID restores a previously assigned GID from active_ids so a - reappearing static object keeps its original identity. - - Current PR fix: prevent Re-ID fallback from firing while features are - still being gathered - * When Re-ID is enabled but the feature count has not yet reached the - minimum, active_ids[rv_id] stays [None, None] (no premature lock-in). - * When Re-ID is explicitly disabled the GID fallback fires immediately. - * When Re-ID is enabled and sufficient features exist the similarity - query is submitted to the thread pool. -""" +"""Unit tests for controller.UUIDManager.""" import collections import sys @@ -31,7 +15,6 @@ sys.modules.setdefault('vdms', MagicMock()) from controller.uuid_manager import (DEFAULT_MINIMUM_FEATURE_COUNT, - DEFAULT_MINIMUM_BBOX_AREA, UUIDManager) @@ -226,10 +209,6 @@ def test_accumulates_reid_vectors_for_known_track(self, uuid_manager, sscape_obj assert len(uuid_manager.features_for_database[sscape_object.rv_id]['reid_vectors']) == 1 -# =========================================================================== -# Current PR fix – elif not self.reid_enabled -# =========================================================================== - class TestAssignIDFallbackBehavior: """The GID fallback in assignID must fire ONLY when re-id is explicitly disabled, never while feature collection is still in progress.""" From 8ca275b3da37f1b1a09fa854e7c5317be455ebe8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 05:51:03 +0000 Subject: [PATCH 6/6] test(controller): add uuid-manager-unit Makefile target to BAT unit-tests Agent-Logs-Url: https://github.com/open-edge-platform/scenescape/sessions/fc03c776-3187-4a9c-b2a9-61561ef4fbfc Co-authored-by: saratpoluri <1325325+saratpoluri@users.noreply.github.com> --- tests/Makefile | 1 + tests/Makefile.sscape | 3 +++ 2 files changed, 4 insertions(+) diff --git a/tests/Makefile b/tests/Makefile index f0b0efbc84..3a35a45fd8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -233,6 +233,7 @@ _unit-tests: \ singleton-sensor-unit \ timestamp-unit \ transform-unit \ + uuid-manager-unit \ views-unit \ include Makefile.sscape Makefile.functional Makefile.perf \ diff --git a/tests/Makefile.sscape b/tests/Makefile.sscape index ddddb4d0f6..b698a6fefa 100644 --- a/tests/Makefile.sscape +++ b/tests/Makefile.sscape @@ -79,5 +79,8 @@ timestamp-unit: # NEX-T10480 transform-unit: # NEX-T10512 $(call unit-recipe, transform, $(IMAGE)-manager-test) +uuid-manager-unit: # NEX-T19884 + $(call unit-recipe, uuid_manager, $(IMAGE)-controller-test) + views-unit: # NEX-T10479 $(call unit-recipe, views, $(IMAGE)-manager-test)