fix: per-variant API to avoid Azure 240s timeout
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
7415a96e65
commit
e4eee9fb0d
3 changed files with 64 additions and 12 deletions
4
.github/workflows/build-deploy.yml
vendored
4
.github/workflows/build-deploy.yml
vendored
|
|
@ -49,10 +49,6 @@ jobs:
|
||||||
--name ${{ env.CONTAINER_APP_NAME }} \
|
--name ${{ env.CONTAINER_APP_NAME }} \
|
||||||
--resource-group ${{ env.RESOURCE_GROUP }} \
|
--resource-group ${{ env.RESOURCE_GROUP }} \
|
||||||
--image ${{ secrets.ACR_LOGIN_SERVER }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
|
--image ${{ secrets.ACR_LOGIN_SERVER }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
|
||||||
az containerapp ingress update \
|
|
||||||
--name ${{ env.CONTAINER_APP_NAME }} \
|
|
||||||
--resource-group ${{ env.RESOURCE_GROUP }} \
|
|
||||||
--request-timeout 900
|
|
||||||
|
|
||||||
- name: Summary
|
- name: Summary
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
|
|
@ -112,15 +112,50 @@ const _BROWSER_ARGS_MINIMAL = [
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run auth tests: 5 browser configs, all running the "Join a meeting" flow.
|
* Return the list of available variant IDs for the frontend to iterate over.
|
||||||
* Each variant: MS login → Teams landing page → "Join a meeting" → enter meeting ID + passcode → Join → screenshot.
|
*/
|
||||||
|
export function getVariantIds(): { id: string; name: string; description: string }[] {
|
||||||
|
return _VARIANTS.map(v => ({ id: v.id, name: v.name, description: v.description }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a SINGLE variant by ID. Called once per variant to stay within Azure's 240s timeout.
|
||||||
|
*/
|
||||||
|
export async function runSingleVariant(
|
||||||
|
variantId: string,
|
||||||
|
meetingUrl: string,
|
||||||
|
botAccountEmail?: string,
|
||||||
|
botAccountPassword?: string,
|
||||||
|
): Promise<AuthTestResult> {
|
||||||
|
const variant = _VARIANTS.find(v => v.id === variantId);
|
||||||
|
if (!variant) {
|
||||||
|
throw new Error(`Unknown variant ID: ${variantId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!botAccountEmail || !botAccountPassword) {
|
||||||
|
return _createSkippedResult(variant, 'Keine Credentials angegeben');
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(`[AuthTest] Running single variant: ${variant.name}`);
|
||||||
|
try {
|
||||||
|
const result = await _runVariant(variant, meetingUrl, botAccountEmail, botAccountPassword);
|
||||||
|
logger.info(`[AuthTest] Variant ${variant.name}: finalUrl=${result.finalUrl.substring(0, 80)}`);
|
||||||
|
return result;
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(`[AuthTest] Variant ${variant.name} failed:`, err);
|
||||||
|
return _createErrorResult(variant, String(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run ALL variants sequentially (legacy — may timeout on Azure).
|
||||||
*/
|
*/
|
||||||
export async function runAuthTests(
|
export async function runAuthTests(
|
||||||
meetingUrl: string,
|
meetingUrl: string,
|
||||||
botAccountEmail?: string,
|
botAccountEmail?: string,
|
||||||
botAccountPassword?: string,
|
botAccountPassword?: string,
|
||||||
): Promise<AuthTestResults> {
|
): Promise<AuthTestResults> {
|
||||||
logger.info(`[AuthTest] Starting auth tests for: ${meetingUrl} (email=${!!botAccountEmail})`);
|
logger.info(`[AuthTest] Starting all auth tests for: ${meetingUrl} (email=${!!botAccountEmail})`);
|
||||||
|
|
||||||
const results: AuthTestResult[] = [];
|
const results: AuthTestResult[] = [];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import express, { Express, Request, Response } from 'express';
|
||||||
import { Server } from 'http';
|
import { Server } from 'http';
|
||||||
import { logger } from '../utils/logger';
|
import { logger } from '../utils/logger';
|
||||||
import { config } from '../config';
|
import { config } from '../config';
|
||||||
import { runAuthTests } from '../bot/authTestProcedure';
|
import { runAuthTests, runSingleVariant, getVariantIds } from '../bot/authTestProcedure';
|
||||||
|
|
||||||
export interface HttpServerCallbacks {
|
export interface HttpServerCallbacks {
|
||||||
onJoinRequest: (sessionId: string, meetingUrl: string, botName?: string, instanceId?: string, gatewayWsUrl?: string, language?: string, botAccountEmail?: string, botAccountPassword?: string, backgroundImageUrl?: string) => Promise<void>;
|
onJoinRequest: (sessionId: string, meetingUrl: string, botName?: string, instanceId?: string, gatewayWsUrl?: string, language?: string, botAccountEmail?: string, botAccountPassword?: string, backgroundImageUrl?: string) => Promise<void>;
|
||||||
|
|
@ -138,7 +138,31 @@ export class HttpServer {
|
||||||
res.json({ message: 'Not implemented' });
|
res.json({ message: 'Not implemented' });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Run auth detection tests against a Teams meeting URL
|
// Get list of available test variants
|
||||||
|
this._app.get('/api/bot/test-auth/variants', (_req: Request, res: Response) => {
|
||||||
|
res.json(getVariantIds());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run a SINGLE test variant (stays within Azure 240s timeout)
|
||||||
|
this._app.post('/api/bot/test-auth/variant', async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
const { variantId, meetingUrl, botAccountEmail, botAccountPassword } = req.body;
|
||||||
|
|
||||||
|
if (!meetingUrl || !variantId) {
|
||||||
|
res.status(400).json({ error: 'Missing required fields: variantId, meetingUrl' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(`Running single auth test variant: ${variantId} for ${meetingUrl}`);
|
||||||
|
const result = await runSingleVariant(variantId, meetingUrl, botAccountEmail, botAccountPassword);
|
||||||
|
res.json(result);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Error running single variant:', error);
|
||||||
|
res.status(500).json({ error: (error as Error).message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run ALL auth detection tests (legacy — may timeout on Azure with many variants)
|
||||||
this._app.post('/api/bot/test-auth', async (req: Request, res: Response) => {
|
this._app.post('/api/bot/test-auth', async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { meetingUrl, botAccountEmail, botAccountPassword } = req.body;
|
const { meetingUrl, botAccountEmail, botAccountPassword } = req.body;
|
||||||
|
|
@ -153,10 +177,7 @@ export class HttpServer {
|
||||||
logger.info(`Starting auth detection tests for: ${meetingUrl} (credentials: email=${hasEmail}, password=${hasPassword})`);
|
logger.info(`Starting auth detection tests for: ${meetingUrl} (credentials: email=${hasEmail}, password=${hasPassword})`);
|
||||||
|
|
||||||
const results = await runAuthTests(meetingUrl, botAccountEmail, botAccountPassword);
|
const results = await runAuthTests(meetingUrl, botAccountEmail, botAccountPassword);
|
||||||
|
|
||||||
// Attach credential debug info so UI can show it
|
|
||||||
(results as any).credentialsReceived = { hasEmail, hasPassword };
|
(results as any).credentialsReceived = { hasEmail, hasPassword };
|
||||||
|
|
||||||
res.json(results);
|
res.json(results);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Error running auth tests:', error);
|
logger.error('Error running auth tests:', error);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue