Files
cleveragents-core/features/repo_indexing.feature
T
aditya 4e64544aae
CI / benchmark-publish (pull_request) Has been skipped
CI / quality (pull_request) Successful in 48s
CI / build (pull_request) Successful in 31s
CI / helm (pull_request) Successful in 21s
CI / lint (pull_request) Successful in 3m15s
CI / typecheck (pull_request) Successful in 4m4s
CI / security (pull_request) Successful in 4m13s
CI / unit_tests (pull_request) Successful in 4m28s
CI / docker (pull_request) Successful in 1m52s
CI / integration_tests (pull_request) Successful in 7m14s
CI / coverage (pull_request) Successful in 12m49s
CI / e2e_tests (pull_request) Successful in 22m8s
CI / status-check (pull_request) Successful in 2s
CI / benchmark-regression (pull_request) Successful in 57m27s
feat(acms): projects with 10,000+ files index without timeout
Add explicit indexing timeout bounds and propagate timeout_seconds through the repo indexing service, utility walker, and CLI entrypoint so large repositories fail predictably instead of hanging.

Add 10K-scale Behave/Robot verification and a dedicated benchmark path to validate that large-project indexing completes, persists status correctly, and remains measurable for regressions.

Address review feedback by splitting oversized Behave and Robot support files into focused modules, trimming repo_indexing_service.py back under the 500-line limit, and rebasing the branch onto current master.

ISSUES CLOSED: #851

# Conflicts:
#	CHANGELOG.md
#	robot/helper_m5_e2e_verification.py
2026-03-30 10:18:19 +00:00

280 lines
13 KiB
Gherkin

# Repository indexing service tests targeting issue #195.
@feature195
Feature: Repository indexing with incremental refresh and language detection
As a CleverAgents user with a large project
I want the system to index my repository files with language detection
So that context assembly can efficiently retrieve relevant code fragments
# -- Full index ----------------------------------------------------------
@feature195
Scenario: Full index of a repository with mixed file types
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
When I run repo-index full index on the sample directory
Then the repo-index result status should be "ready"
And the repo-index result file count should be 6
And the repo-index primary language should be "python"
And the repo-index token estimate should be positive
@feature195
Scenario: Indexed files have correct language detection
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
When I run repo-index full index on the sample directory
Then the repo-index file "main.py" should have language "python"
And the repo-index file "index.ts" should have language "typescript"
And the repo-index file "README.md" should have language "markdown"
And the repo-index file "config.json" should have language "json"
And the repo-index file "Makefile" should have language "makefile"
@feature195
Scenario: Index is persisted and can be retrieved
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
When I run repo-index full index on the sample directory
And I query repo-index for the indexed resource
Then the repo-index retrieved index should match the original
And the repo-index retrieved file hashes should match the original
# -- Incremental refresh -------------------------------------------------
@feature195
Scenario: Incremental refresh detects changed files
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
And I run repo-index full index on the sample directory
When I modify repo-index file "main.py" with new content
And I run repo-index incremental refresh
Then the repo-index file "main.py" content hash should differ from original
And the repo-index file "index.ts" content hash should match original
@feature195
Scenario: Refresh on non-existent index falls back to full index
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
When I run repo-index incremental refresh
Then the repo-index result status should be "ready"
And the repo-index result file count should be 6
# -- Policy enforcement --------------------------------------------------
@feature195
Scenario: Max file size excludes large files
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files and a 2MB file
When I run repo-index full index with max file size 1000000 bytes
Then the repo-index result should not include file "big_file.dat"
And the repo-index result file count should be 6
@feature195
Scenario: Include globs filter to matching files only
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
When I run repo-index full index with include globs "*.py"
Then the repo-index result file count should be 2
And the repo-index primary language should be "python"
@feature195
Scenario: Exclude globs remove matching files
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
When I run repo-index full index with exclude globs "*.md,*.json"
Then the repo-index result should not include file "README.md"
And the repo-index result should not include file "config.json"
@feature195
Scenario: Max total size truncates indexing
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files and a 2MB file
When I run repo-index full index with max total size 100 bytes
Then the repo-index result file count should be less than 6
@feature195
Scenario: Indexing 10,000 files completes within timeout bound
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with 10000 python files
When I run repo-index full index with timeout of 120 seconds
Then the repo-index result status should be "ready"
And the repo-index result file count should be 10000
And the repo-index indexing elapsed seconds should be less than 120
# -- Removal -------------------------------------------------------------
@feature195
Scenario: Remove index cleans up all records
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
And I run repo-index full index on the sample directory
When I remove the repo-index for the resource
Then querying repo-index for the resource should return nothing
@feature195
Scenario: Remove non-existent index returns false
Given a repo-index fresh in-memory indexing service
When I remove the repo-index for a non-existent resource
Then the repo-index removal result should be false
# -- Error handling ------------------------------------------------------
@feature195
Scenario: Index with empty resource ID raises error
Given a repo-index fresh in-memory indexing service
When I attempt repo-index with empty resource ID
Then a repo-index ValueError should be raised mentioning "non-empty"
@feature195
Scenario: Index with non-existent path raises error
Given a repo-index fresh in-memory indexing service
When I attempt repo-index with non-existent path "/nonexistent/xyz"
Then a repo-index FileNotFoundError should be raised
@feature195
Scenario: Index with invalid ULID resource ID raises error
Given a repo-index fresh in-memory indexing service
When I attempt repo-index with invalid ULID resource ID
Then a repo-index ValueError should be raised mentioning "valid ULID"
# -- Status query ---------------------------------------------------------
@feature195
Scenario: Get index status returns metadata without file records
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
And I run repo-index full index on the sample directory
When I query repo-index status for the indexed resource
Then the repo-index status metadata should have status "ready"
And the repo-index status metadata file count should be 6
# -- Additional edge cases -----------------------------------------------
@feature195
Scenario: Index with file path as root raises error
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
When I attempt repo-index with a file path as root
Then a repo-index ValueError should be raised mentioning "not a directory"
@feature195
Scenario: Index on empty directory returns zero files with ready status
Given a repo-index fresh in-memory indexing service
And a repo-index empty temporary directory
When I run repo-index full index on the sample directory
Then the repo-index result status should be "ready"
And the repo-index result file count should be 0
And the repo-index primary language should be "unknown"
# -- Refresh error paths -------------------------------------------------
@feature195
Scenario: Refresh with non-existent path raises error
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
And I run repo-index full index on the sample directory
When I attempt repo-index refresh with non-existent path "/nonexistent/xyz"
Then a repo-index FileNotFoundError should be raised
@feature195
Scenario: Refresh with file path as root raises error
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
And I run repo-index full index on the sample directory
When I attempt repo-index refresh with a file path as root
Then a repo-index ValueError should be raised mentioning "not a directory"
# -- Fault tolerance paths -----------------------------------------------
@feature195
Scenario: Walk failure on fresh resource persists ERROR status
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
When repo-index walk is mocked to fail and I index a fresh resource
Then a repo-index error should be raised
And querying repo-index status for the resource should show "error"
@feature195
Scenario: Walk failure on existing resource preserves previous index
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
And I run repo-index full index on the sample directory
When repo-index walk is mocked to fail and I re-index
Then a repo-index error should be raised
And the repo-index previous index should still be retrievable with 6 files
@feature195
Scenario: Refresh walk failure preserves previous good index
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
And I run repo-index full index on the sample directory
When repo-index walk is mocked to fail and I refresh
Then a repo-index error should be raised
And the repo-index previous index should still be retrievable with 6 files
# -- Stale indexing cleanup ------------------------------------------------
@feature195
Scenario: Cleanup stale indexing removes orphan INDEXING rows
Given a repo-index fresh in-memory indexing service
And a repo-index stale INDEXING row is inserted for a resource
When I call repo-index cleanup stale indexing
Then the repo-index cleanup should report 1 stale row removed
And querying repo-index for the stale resource should return nothing
# -- Edge cases: unreadable files, naive datetimes -----------------------
@feature195
Scenario: Unreadable file is skipped without crashing index
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with a file that fails hashing
When I run repo-index full index with hash failure on "secret.dat"
Then the repo-index result status should be "ready"
And the repo-index result should not include file "secret.dat"
@feature195
Scenario: Re-index replaces existing index completely
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
And I run repo-index full index on the sample directory
When I add a new file "extra.py" and re-index
Then the repo-index result file count should be 7
And the repo-index result status should be "ready"
@feature195
Scenario: Naive datetime is coerced to UTC in FileRecord
Given a repo-index fresh in-memory indexing service
When I create a FileRecord with a naive datetime
Then the FileRecord last_modified should have UTC timezone
@feature195
Scenario: Naive datetime is coerced to UTC in IndexMetadata
Given a repo-index fresh in-memory indexing service
When I create an IndexMetadata with a naive datetime
Then the IndexMetadata indexed_at should have UTC timezone
# -- Domain model structural assertions ----------------------------------
@feature195
Scenario: IndexMetadata has all spec-required fields
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
When I run repo-index full index on the sample directory
Then the repo-index metadata should have field "index_id"
And the repo-index metadata should have field "resource_id"
And the repo-index metadata should have field "indexed_at"
And the repo-index metadata should have field "file_count"
And the repo-index metadata should have field "token_estimate"
And the repo-index metadata should have field "primary_language"
And the repo-index metadata should have field "status"
@feature195
Scenario: FileRecord has all spec-required fields
Given a repo-index fresh in-memory indexing service
And a repo-index temporary directory with sample project files
When I run repo-index full index on the sample directory
Then each repo-index file record should have field "path"
And each repo-index file record should have field "content_hash"
And each repo-index file record should have field "token_count"
And each repo-index file record should have field "language"
And each repo-index file record should have field "size_bytes"
And each repo-index file record should have field "last_modified"