Skip to content

Commit caafa1e

Browse files
committed
Enhance test framework and conversation handling for audio persistence
- Updated the Makefile to introduce new test commands for running tests with and without API keys, improving CI integration. - Refactored integration tests to replace static sleep calls with polling mechanisms for conversation creation, enhancing reliability and reducing flakiness. - Added a new keyword to wait for conversations by client ID, streamlining test logic and improving readability. - Updated documentation in the Makefile to reflect changes in test commands and configurations.
1 parent 0e73576 commit caafa1e

File tree

3 files changed

+84
-51
lines changed

3 files changed

+84
-51
lines changed

tests/Makefile

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
containers-start containers-stop containers-restart containers-rebuild \
66
containers-start-rebuild containers-clean containers-status containers-logs \
77
start stop restart rebuild start-rebuild status logs \
8-
test test-quick test-slow test-sdk test-all-with-slow-and-sdk clean-all \
8+
test test-quick test-slow test-sdk test-no-api test-with-api-keys test-all-with-slow-and-sdk clean-all \
99
results results-path results-detailed
1010

1111
# Default output directory
@@ -27,14 +27,15 @@ ifdef CONFIG
2727
export TEST_CONFIG_FILE = $(CONFIG)
2828
endif
2929
else
30-
export TEST_CONFIG_FILE ?= /app/test-configs/mock-services.yml
30+
export TEST_CONFIG_FILE ?= /app/test-configs/deepgram-openai.yml
3131
endif
3232

3333
help:
3434
@echo "Chronicle Test Targets:"
3535
@echo ""
3636
@echo "Quick Commands:"
37-
@echo " make test - Start containers + run tests (excludes slow/sdk/API)"
37+
@echo " make test - Start containers + run tests (uses real APIs)"
38+
@echo " make test-no-api - Run tests without API keys (CI mode)"
3839
@echo " make test-quick - Run tests on existing containers"
3940
@echo " make start - Start test containers"
4041
@echo " make stop - Stop containers (keep volumes)"
@@ -44,15 +45,15 @@ help:
4445
@echo " make status - Show container status"
4546
@echo ""
4647
@echo "Running Tests:"
47-
@echo " make all - Run all tests (excludes slow/sdk/API)"
48+
@echo " make all - Run all tests (excludes slow/sdk)"
4849
@echo " make endpoints - Run only endpoint tests"
4950
@echo " make integration - Run only integration tests"
5051
@echo " make infra - Run only infrastructure tests"
5152
@echo ""
5253
@echo "Special Test Tags:"
5354
@echo " make test-slow - Run ONLY slow tests (backend restarts)"
5455
@echo " make test-sdk - Run ONLY SDK tests (unreleased)"
55-
@echo " make test-with-api-keys - Run ONLY tests requiring API keys"
56+
@echo " make test-no-api - Run tests without API keys (CI mode)"
5657
@echo " make test-all-with-slow-and-sdk - Run ALL tests including excluded"
5758
@echo ""
5859
@echo "Container Management:"
@@ -80,30 +81,29 @@ help:
8081
@echo " CONFIG - Config file to use (e.g., deepgram-openai.yml or full path)"
8182
@echo ""
8283
@echo "Config Options:"
83-
@echo " mock-services.yml - No API keys (default, excludes API tests)"
84-
@echo " deepgram-openai.yml - Real API keys (required for API tests)"
84+
@echo " deepgram-openai.yml - Real API keys (default)"
85+
@echo " mock-services.yml - No API keys (for CI)"
8586
@echo " mock-transcription-failure.yml - Test transcription failure scenarios"
8687
@echo ""
8788
@echo "Examples:"
88-
@echo " make test # Default (no API keys)"
89-
@echo " make test-with-api-keys # Auto-switches to deepgram config"
90-
@echo " make test CONFIG=deepgram-openai.yml # Custom config"
89+
@echo " make test # Default (uses real APIs)"
90+
@echo " make test-no-api # CI mode (no API keys)"
91+
@echo " make test CONFIG=mock-services.yml # Custom config"
9192
@echo " make endpoints CONFIG=mock-services.yml # Endpoint tests with mock"
9293
@echo " make start-rebuild CONFIG=custom.yml # Rebuild with custom config"
9394
@echo " make containers-logs SERVICE=workers-test # View worker logs"
9495
@echo " make show-config # Show current config"
9596

96-
# Run all tests (excludes slow, sdk, and requires-api-keys tests for faster feedback)
97+
# Run all tests (excludes slow and sdk tests for faster feedback)
9798
# Creates a persistent fixture conversation that won't be deleted between suites
9899
all:
99-
@echo "Running all tests (excluding slow, sdk, and requires-api-keys tests)..."
100+
@echo "Running all tests (excluding slow and sdk tests)..."
100101
CREATE_FIXTURE=true uv run --with-requirements test-requirements.txt robot --outputdir $(OUTPUTDIR) \
101102
--name "All Tests" \
102103
--console verbose \
103104
--loglevel INFO:INFO \
104105
--exclude slow \
105106
--exclude sdk \
106-
--exclude requires-api-keys \
107107
$(TEST_DIR)
108108

109109
# Run only endpoint tests
@@ -242,26 +242,39 @@ test-sdk:
242242
$(TEST_DIR)
243243

244244
# Run ONLY tests that require API keys (Deepgram + OpenAI)
245-
# Automatically switches to deepgram-openai.yml config
245+
# Uses default deepgram-openai.yml config
246246
test-with-api-keys:
247-
@echo "🔄 Switching to deepgram-openai.yml config..."
247+
@echo "🧪 Running tests that require API keys..."
248248
@if [ -z "$$DEEPGRAM_API_KEY" ] || [ -z "$$OPENAI_API_KEY" ]; then \
249249
echo "❌ Error: DEEPGRAM_API_KEY and OPENAI_API_KEY must be set"; \
250250
echo " export DEEPGRAM_API_KEY='your-key-here'"; \
251251
echo " export OPENAI_API_KEY='your-key-here'"; \
252252
exit 1; \
253253
fi
254-
@$(MAKE) containers-stop
255-
@TEST_CONFIG_FILE=/app/test-configs/deepgram-openai.yml $(MAKE) containers-start
256-
@echo "✅ Containers running with deepgram-openai.yml"
257-
@echo "🧪 Running API key tests..."
258254
CREATE_FIXTURE=true uv run --with-requirements test-requirements.txt robot --outputdir $(OUTPUTDIR) \
259255
--name "API Key Tests" \
260256
--console verbose \
261257
--loglevel INFO:INFO \
262258
--include requires-api-keys \
263259
$(TEST_DIR)
264260

261+
# Run tests without API keys (CI mode)
262+
# Switches to mock-services.yml config and excludes requires-api-keys tests
263+
test-no-api:
264+
@echo "🔄 Running tests without API keys (CI mode)..."
265+
@$(MAKE) containers-stop
266+
@TEST_CONFIG_FILE=/app/test-configs/mock-services.yml $(MAKE) containers-start
267+
@echo "✅ Containers running with mock-services.yml"
268+
@echo "🧪 Running tests (excluding requires-api-keys)..."
269+
CREATE_FIXTURE=true uv run --with-requirements test-requirements.txt robot --outputdir $(OUTPUTDIR) \
270+
--name "No API Tests" \
271+
--console verbose \
272+
--loglevel INFO:INFO \
273+
--exclude slow \
274+
--exclude sdk \
275+
--exclude requires-api-keys \
276+
$(TEST_DIR)
277+
265278
# Run ALL tests including slow and SDK tests
266279
test-all-with-slow-and-sdk:
267280
@echo "Running ALL tests including slow and SDK tests..."

tests/integration/always_persist_audio_tests.robot

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,19 @@ Placeholder Conversation Created Immediately With Always Persist
5858
# Get baseline conversation count for THIS client_id only
5959
${convs_before}= Get Conversations By Client ID ${client_id}
6060
${count_before}= Get Length ${convs_before}
61+
${expected_count}= Evaluate ${count_before} + 1
6162

6263
# Start stream with always_persist=true
6364
${stream_id}= Open Audio Stream With Always Persist device_name=${device_name}
6465

65-
# Conversation created by audio persistence job (takes 3-5s to start)
66-
Sleep 5s # Wait for audio persistence job to create placeholder
67-
${convs_after}= Get Conversations By Client ID ${client_id}
66+
# Poll for conversation to be created by audio persistence job (may take 10-15s to start)
67+
${convs_after}= Wait Until Keyword Succeeds 30s 2s
68+
... Wait For Conversation By Client ID ${client_id} ${expected_count}
6869
${count_after}= Get Length ${convs_after}
6970

7071
# Verify new conversation created for this client
71-
Should Be True ${count_after} == ${count_before} + 1
72-
... Expected 1 new conversation for client ${client_id}, found ${count_after} - ${count_before}
72+
Should Be True ${count_after} >= ${expected_count}
73+
... Expected at least ${expected_count} conversation(s) for client ${client_id}, found ${count_after}
7374

7475
# Find the new conversation (most recent)
7576
${new_conv}= Set Variable ${convs_after}[0]
@@ -141,21 +142,22 @@ Redis Key Set Immediately With Always Persist
141142
# Get baseline conversation count for THIS client_id only
142143
${convs_before}= Get Conversations By Client ID ${client_id}
143144
${count_before}= Get Length ${convs_before}
145+
${expected_count}= Evaluate ${count_before} + 1
144146

145147
# Start stream with always_persist=true
146148
${stream_id}= Open Audio Stream With Always Persist device_name=${device_name}
147149

148150
# session_id == client_id for streaming mode (not stream_id!)
149151
${session_id}= Set Variable ${client_id}
150152

151-
# Get conversation (created by audio persistence job)
152-
Sleep 5s # Wait for audio persistence job to create placeholder
153-
${convs_after}= Get Conversations By Client ID ${client_id}
153+
# Poll for conversation to be created by audio persistence job
154+
${convs_after}= Wait Until Keyword Succeeds 30s 2s
155+
... Wait For Conversation By Client ID ${client_id} ${expected_count}
154156
${count_after}= Get Length ${convs_after}
155157

156158
# Verify new conversation created for this client
157-
Should Be True ${count_after} == ${count_before} + 1
158-
... Expected 1 new conversation for client ${client_id}, found ${count_after} - ${count_before}
159+
Should Be True ${count_after} >= ${expected_count}
160+
... Expected at least ${expected_count} conversation(s) for client ${client_id}, found ${count_after}
159161

160162
# Get the new conversation (most recent)
161163
${conversation}= Set Variable ${convs_after}[0]
@@ -192,33 +194,36 @@ Multiple Sessions Create Separate Conversations
192194
${count_before_1}= Get Length ${convs_before_1}
193195
${count_before_2}= Get Length ${convs_before_2}
194196
${count_before_3}= Get Length ${convs_before_3}
197+
${expected_count_1}= Evaluate ${count_before_1} + 1
198+
${expected_count_2}= Evaluate ${count_before_2} + 1
199+
${expected_count_3}= Evaluate ${count_before_3} + 1
195200

196201
# Start 3 separate sessions
197202
${stream_1}= Open Audio Stream With Always Persist device_name=${device_name}-1
198203
Sleep 1s
199204
${stream_2}= Open Audio Stream With Always Persist device_name=${device_name}-2
200205
Sleep 1s
201206
${stream_3}= Open Audio Stream With Always Persist device_name=${device_name}-3
202-
Sleep 5s # Wait for all audio persistence jobs to create placeholders
203207

204-
# Verify each client has exactly 1 new conversation
205-
${convs_after_1}= Get Conversations By Client ID ${client_id_1}
206-
${convs_after_2}= Get Conversations By Client ID ${client_id_2}
207-
${convs_after_3}= Get Conversations By Client ID ${client_id_3}
208+
# Poll for each conversation to be created (audio persistence jobs may take 10-15s)
209+
${convs_after_1}= Wait Until Keyword Succeeds 30s 2s
210+
... Wait For Conversation By Client ID ${client_id_1} ${expected_count_1}
211+
${convs_after_2}= Wait Until Keyword Succeeds 30s 2s
212+
... Wait For Conversation By Client ID ${client_id_2} ${expected_count_2}
213+
${convs_after_3}= Wait Until Keyword Succeeds 30s 2s
214+
... Wait For Conversation By Client ID ${client_id_3} ${expected_count_3}
215+
208216
${count_after_1}= Get Length ${convs_after_1}
209217
${count_after_2}= Get Length ${convs_after_2}
210218
${count_after_3}= Get Length ${convs_after_3}
211219

212-
${new_count_1}= Evaluate ${count_after_1} - ${count_before_1}
213-
${new_count_2}= Evaluate ${count_after_2} - ${count_before_2}
214-
${new_count_3}= Evaluate ${count_after_3} - ${count_before_3}
215-
216-
Should Be Equal As Integers ${new_count_1} 1
217-
... Expected 1 new conversation for client ${client_id_1}, found ${new_count_1}
218-
Should Be Equal As Integers ${new_count_2} 1
219-
... Expected 1 new conversation for client ${client_id_2}, found ${new_count_2}
220-
Should Be Equal As Integers ${new_count_3} 1
221-
... Expected 1 new conversation for client ${client_id_3}, found ${new_count_3}
220+
# Verify each client has at least 1 new conversation
221+
Should Be True ${count_after_1} >= ${expected_count_1}
222+
... Expected at least ${expected_count_1} conversation(s) for client ${client_id_1}, found ${count_after_1}
223+
Should Be True ${count_after_2} >= ${expected_count_2}
224+
... Expected at least ${expected_count_2} conversation(s) for client ${client_id_2}, found ${count_after_2}
225+
Should Be True ${count_after_3} >= ${expected_count_3}
226+
... Expected at least ${expected_count_3} conversation(s) for client ${client_id_3}, found ${count_after_3}
222227

223228
# Verify each conversation has unique conversation_id
224229
${conv_id_1}= Set Variable ${convs_after_1}[0][conversation_id]
@@ -255,8 +260,9 @@ Audio Chunks Persisted Despite Transcription Failure
255260
# Start stream with always_persist=true
256261
${stream_id}= Open Audio Stream With Always Persist device_name=${device_name}
257262

258-
# Wait for audio persistence job to start consuming from Redis Stream
259-
Sleep 2s
263+
# Poll for conversation to be created by audio persistence job
264+
${conversations}= Wait Until Keyword Succeeds 30s 2s
265+
... Wait For Conversation By Client ID ${client_id} 1
260266

261267
# Send audio chunks (transcription will fail due to invalid API key in config)
262268
# Use realtime pacing to ensure chunks arrive while persistence job is running
@@ -266,8 +272,7 @@ Audio Chunks Persisted Despite Transcription Failure
266272
${total_chunks}= Close Audio Stream ${stream_id}
267273
Log Sent ${total_chunks} total chunks
268274

269-
# Get the conversation for this client - already created by audio persistence job
270-
${conversations}= Get Conversations By Client ID ${client_id}
275+
# Get the conversation for this client
271276
${conversation}= Set Variable ${conversations}[0]
272277
${conversation_id}= Set Variable ${conversation}[conversation_id]
273278

@@ -307,13 +312,14 @@ Conversation Updates To Completed When Transcription Succeeds
307312
# Get baseline conversation count for THIS client_id only
308313
${convs_before}= Get Conversations By Client ID ${client_id}
309314
${count_before}= Get Length ${convs_before}
315+
${expected_count}= Evaluate ${count_before} + 1
310316

311317
# Start stream with always_persist=true
312318
${stream_id}= Open Audio Stream With Always Persist device_name=${device_name}
313319

314-
# Verify placeholder conversation exists (created by audio persistence job)
315-
Sleep 5s
316-
${convs_after}= Get Conversations By Client ID ${client_id}
320+
# Poll for placeholder conversation to be created by audio persistence job
321+
${convs_after}= Wait Until Keyword Succeeds 30s 2s
322+
... Wait For Conversation By Client ID ${client_id} ${expected_count}
317323
${conversation}= Set Variable ${convs_after}[0]
318324
${conversation_id}= Set Variable ${conversation}[conversation_id]
319325

tests/resources/conversation_keywords.robot

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ Get Conversations By Client ID
3333

3434
RETURN ${filtered}
3535

36+
Wait For Conversation By Client ID
37+
[Documentation] Wait for at least one conversation to exist for the given client_id.
38+
... Polls until a conversation is found or timeout is reached.
39+
... Returns the list of conversations for that client.
40+
[Arguments] ${client_id} ${expected_count}=1
41+
42+
${conversations}= Get Conversations By Client ID ${client_id}
43+
${count}= Get Length ${conversations}
44+
45+
Should Be True ${count} >= ${expected_count}
46+
... Expected at least ${expected_count} conversation(s) for client ${client_id}, found ${count}
47+
48+
RETURN ${conversations}
49+
3650
Get Conversation By ID
3751
[Documentation] Get a specific conversation by ID
3852
[Arguments] ${conversation_id}

0 commit comments

Comments
 (0)