Skip to content

Commit a0ade96

Browse files
authored
fix dockerfiles, playwright tests and bugs (opea-project#71)
Signed-off-by: wwanarif <wan.abdul.hakim.b.wan.arif@intel.com>
1 parent 42b7dc2 commit a0ade96

File tree

7 files changed

+92
-58
lines changed

7 files changed

+92
-58
lines changed

app-backend/Dockerfile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
FROM python:3.11-slim
22

33
RUN apt-get update -y && apt-get install -y --no-install-recommends --fix-missing \
4-
libsqlite3-0=3.40.1-2+deb12u1 \
5-
libgl1-mesa-glx=22.3.6-1+deb12u1 \
6-
libjemalloc-dev=5.3.0-1 \
4+
libsqlite3-0 \
5+
libjemalloc-dev \
76
git && \
87
rm -rf /var/lib/apt/lists/*
98

app-frontend/react/src/components/File_Input/FileInput.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,16 +232,23 @@ const FileInput: React.FC<FileInputProps> = ({
232232
const uploadFiles = async () => {
233233
dispatch(setUploadInProgress(true));
234234

235-
const responses = await Promise.all(
236-
filesToUpload.map((file: any) => {
237-
dispatch(uploadFile({ file: file.file }));
238-
}),
239-
);
235+
try {
236+
const responses = await Promise.all(
237+
filesToUpload.map((file: any) => {
238+
return dispatch(uploadFile({ file: file.file }));
239+
}),
240+
);
240241

241-
dispatch(setUploadInProgress(false));
242+
// Wait a brief moment to ensure notifications are displayed
243+
await new Promise(resolve => setTimeout(resolve, 100));
242244

243-
setConfirmUpload(false);
244-
setFilesToUpload([]);
245+
dispatch(setUploadInProgress(false));
246+
setConfirmUpload(false);
247+
setFilesToUpload([]);
248+
} catch (error) {
249+
dispatch(setUploadInProgress(false));
250+
setConfirmUpload(false);
251+
}
245252
};
246253

247254
const showConfirmUpload = () => {

studio-backend/app/routers/debuglog_router.py

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,6 @@ async def get_all_pods_in_namespace(namespace: str):
218218
except Exception as e:
219219
pass
220220

221-
# Analyze pod dependencies
222-
dependencies = []
223-
if services:
224-
try:
225-
dependencies = find_pod_dependencies(pod, pods, services, namespace, core_v1_api)
226-
# print(f"Pod {pod_name} dependencies: {dependencies}")
227-
except Exception as e:
228-
pass
229-
230221
# Analyze pod dependencies
231222
dependencies = []
232223
if services:
@@ -260,41 +251,71 @@ async def get_all_pods_in_namespace(namespace: str):
260251
total_count = len(pod.status.container_statuses)
261252
ready_status = f"{ready_count}/{total_count}"
262253

263-
# Only check for error conditions if not already terminating or in terminal state
264-
has_error = False
254+
# Determine detailed pod status based on current container states
255+
has_current_error = False
256+
is_running = False
257+
is_pending = False
258+
265259
if not is_terminating and pod.status.phase not in ["Failed", "Succeeded"]:
266-
# Check init container statuses for errors
260+
# Check init container statuses for current errors (not historical)
267261
if pod.status.init_container_statuses:
268262
for status in pod.status.init_container_statuses:
269263
if status.state and status.state.waiting and status.state.waiting.reason in ['ImagePullBackOff', 'ErrImagePull', 'CrashLoopBackOff', 'Error']:
270-
has_error = True
264+
has_current_error = True
271265
break
272266
elif status.state and status.state.terminated and status.state.terminated.reason == 'Error':
273-
has_error = True
267+
has_current_error = True
274268
break
275269

276-
# Check main container statuses for errors
277-
if pod.status.container_statuses:
270+
# Check main container statuses for current state - prioritize running state
271+
if pod.status.container_statuses and not has_current_error:
272+
containers_running = 0
273+
containers_with_current_errors = 0
274+
containers_with_high_restarts = 0
275+
total_containers = len(pod.status.container_statuses)
276+
278277
for status in pod.status.container_statuses:
279-
if status.state and status.state.waiting and status.state.waiting.reason in ['ImagePullBackOff', 'ErrImagePull', 'CrashLoopBackOff', 'Error']:
280-
has_error = True
281-
break
278+
# Priority 1: Check if container is currently running (this overrides restart history)
279+
if status.state and status.state.running:
280+
containers_running += 1
281+
# Even if running, check if it has excessive restarts (indicates instability)
282+
if status.restart_count and status.restart_count > 1:
283+
containers_with_high_restarts += 1
284+
# Priority 2: Check for current error states only if not running
285+
elif status.state and status.state.waiting:
286+
if status.state.waiting.reason in ['ImagePullBackOff', 'ErrImagePull', 'CrashLoopBackOff']:
287+
# These are current errors only if container is not running
288+
containers_with_current_errors += 1
289+
elif status.state.waiting.reason in ['ContainerCreating', 'PodInitializing']:
290+
is_pending = True
291+
# Other waiting reasons are treated as pending, not errors
282292
elif status.state and status.state.terminated and status.state.terminated.reason == 'Error':
283-
has_error = True
284-
break
285-
elif status.restart_count and status.restart_count > 0:
286-
# Check if the pod is restarting frequently (possible error condition)
287-
if status.state and status.state.waiting and status.state.waiting.reason == 'CrashLoopBackOff':
288-
has_error = True
289-
break
290-
has_error = True
291-
break
293+
# Only count as error if container is currently terminated with error
294+
containers_with_current_errors += 1
295+
296+
# Determine overall status based on current state (ignore restart history if currently running)
297+
if containers_running == total_containers:
298+
# All containers running - but check if any have high restart counts
299+
if containers_with_high_restarts > 0:
300+
# Containers are running but unstable (high restarts)
301+
has_current_error = True # This will show as "Error" status
302+
else:
303+
is_running = True
304+
elif containers_with_current_errors > 0:
305+
has_current_error = True
306+
elif containers_running > 0:
307+
# Some containers running, some pending - consider it as pending/starting
308+
is_pending = True
292309

293-
# Set pod status based on conditions
294-
if has_error:
295-
pod_status = "Error"
296-
elif pod.metadata.deletion_timestamp:
310+
# Set pod status based on current conditions (prioritize current state over history)
311+
if pod.metadata.deletion_timestamp:
297312
pod_status = "Terminating"
313+
elif has_current_error:
314+
pod_status = "Error"
315+
elif is_running:
316+
pod_status = "Running"
317+
elif is_pending:
318+
pod_status = "Pending"
298319
elif pod.status.init_container_statuses:
299320
ready_count = sum(1 for status in pod.status.init_container_statuses if status.ready)
300321
total_count = len(pod.status.init_container_statuses)

studio-frontend/packages/ui/src/ui-component/table/FlowListTable.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ export const FlowListTable = ({ data, images, isLoading, filterFunction, updateF
515515
justifyContent='center'
516516
alignItems='center'
517517
>
518-
{row.sandboxStatus === "Getting Ready" || row.sandboxStatus === "Stopping" || row.sandboxStatus === "Deleting existing namespace" ? (
518+
{row.sandboxStatus === "Getting Ready" || row.sandboxStatus === "Stopping" || row.sandboxStatus === "Deleting existing namespace" || row.sandboxStatus === "Sending Request" ? (
519519
<CircularProgress size={20} />
520520
) : null
521521
}
@@ -549,7 +549,7 @@ export const FlowListTable = ({ data, images, isLoading, filterFunction, updateF
549549
window.open(`/debuglogs/sandbox-${row.id}`, '_blank');
550550
handleRunSandbox(row.id);
551551
}}
552-
disabled={row.sandboxStatus === 'Stopping'}
552+
disabled={row.sandboxStatus === 'Stopping' || row.sandboxStatus === 'Sending Request'}
553553
>
554554
</Button>
555555
</Tooltip>

tests/playwright/studio-e2e/002_test_sandbox_chatqna.spec.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ async function setupResponseListener(page, apiResponse) {
2525
const lines = event.split('\n');
2626
for (const line of lines) {
2727
if (line.startsWith('data: ')) {
28-
const cleanedData = line.slice(6, -1).trim(); // Remove 'data: ' prefix
29-
apiResponse.value += cleanedData + " ";
28+
const cleanedData = line.slice(6).trim(); // Remove 'data: ' prefix only
29+
if (cleanedData && cleanedData !== '[DONE]') {
30+
apiResponse.value += cleanedData;
31+
}
3032
}
3133
}
3234
}
@@ -212,31 +214,36 @@ test('002_test_sandbox_chatqna', async ({ browser, baseURL }) => {
212214
// }
213215
// }
214216
console.log ('Chat Attempt 2-------------------');
217+
apiResponse.value = ""; // Clear the response listener buffer
215218
await page2.getByRole('button', { name: 'New Chat' }).click();
216219
await page2.getByRole('textbox', { name: 'Enter your message' }).fill(question);
217220
await page2.getByRole('button').filter({ hasText: /^$/ }).nth(2).click();
218-
await page2.waitForTimeout(30000);
221+
222+
// Wait for the Copy button to appear, indicating response is complete
223+
await page2.getByRole('button', { name: 'Copy' }).waitFor({ state: 'visible'});
219224
responseContainsKeyword = apiResponse && containsAnyKeyword(apiResponse.value, keywords);
220225
console.log ('response:', apiResponse.value);
221226
console.log ("responseContainsKeyword:", responseContainsKeyword);
222-
223227
if (!responseContainsKeyword) {
224228
console.log('First attempt failed. Asking a follow-up question...');
225229
apiResponse.value = ""; // Clear the response listener buffer
226-
227230
// Ask another question
228231
const followUpQuestion = "How is Intel performing in Q3 2024?";
229232
await page2.getByRole('textbox', { name: 'Enter your message' }).fill(followUpQuestion);
230-
await page2.getByRole('button').filter({ hasText: /^$/ }).nth(2).click();
231-
await page2.waitForTimeout(30000);
233+
await page2.locator('.MuiButtonBase-root.MuiButton-root').click();
234+
235+
// Wait for the second Copy button to appear, indicating follow-up response is complete
236+
await page2.getByRole('button', { name: 'Copy' }).nth(1).waitFor({ state: 'visible'});
232237

233238
responseContainsKeyword = apiResponse && containsAnyKeyword(apiResponse.value, keywords);
234-
console.log ('response:', apiResponse.value);
235-
console.log ("responseContainsKeyword:", responseContainsKeyword);
239+
console.log ('Follow-up response:', apiResponse.value);
240+
console.log ("Follow-up responseContainsKeyword:", responseContainsKeyword);
236241

237242
if (!responseContainsKeyword) {
238243
throw new Error('RAG failed after follow-up question');
239244
}
245+
} else {
246+
console.log('First attempt succeeded - RAG is working correctly');
240247
}
241248
await page2.screenshot({ path: 'screenshot_chat_attempt2.png' });
242249

tests/playwright/studio-e2e/003_test_sandbox_docsum.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test';
22
import { waitForStatusText } from '../utils';
33
import path from 'path';
44

5-
const sampleWorkflow = path.resolve(__dirname, '../../../sample-workflows/sample_workflow_docsum.json');//this workflow consists of Hugging Face token! cannot deploy as off now.
5+
const sampleWorkflow = path.resolve(__dirname, '../../../sample-workflows/sample_docsum.json');
66
const uploadtxt1 = path.resolve(__dirname, '../../test-files/Little Red Riding Hood.txt');
77

88
const keywords = ["Little Red Riding Hood", "sick grandmother", "wolf", "woodcutter", "hunter", "closet", "food"]; // more keywords needed
@@ -90,7 +90,7 @@ test('003_test_sandbox_docsum', async ({ browser, baseURL }) => {
9090
//Summarization Generation and Response Validation
9191
await page2.waitForTimeout(60000);
9292
let responseContainsKeyword = apiResponse && containsAnyKeyword(apiResponse.value, keywords);
93-
console.log ('response:', apiResponse.value);
93+
// console.log ('response:', apiResponse.value);
9494
await page2.screenshot({ path: 'screenshot_docsum_attempt1.png' });
9595

9696
if (!responseContainsKeyword) {

tests/playwright/studio-e2e/004_test_sandbox_codegen.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test';
22
import { waitForStatusText } from '../utils';
33
import path from 'path';
44

5-
const sampleWorkflow = path.resolve(__dirname, '../../../sample-workflows/sample_workflow_codegen.json');
5+
const sampleWorkflow = path.resolve(__dirname, '../../../sample-workflows/sample_codegen.json');
66
const question = "write me a python function for fibonacci loop";
77
const keywords = ["Python", "Fibonacci", "iterative", "if", "<=", "=", "(", ")", "[", "]"]; // more keywords needed
88

@@ -81,7 +81,7 @@ test('004_test_sandbox_codegen', async ({ browser, baseURL }) => {
8181
await page2.getByRole('button').filter({ hasText: /^$/ }).nth(2).click(); //end here
8282
await page2.waitForTimeout(60000);
8383
let responseContainsKeyword = apiResponse && containsAnyKeyword(apiResponse.value, keywords);
84-
console.log ('response:', apiResponse.value);
84+
// console.log ('response:', apiResponse.value);
8585
await page2.screenshot({ path: 'screenshot_codegen_attempt1.png' });
8686

8787
if (!responseContainsKeyword) {

0 commit comments

Comments
 (0)