-
Notifications
You must be signed in to change notification settings - Fork 241
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: assert metrics in network tests (#10215)
Break out alert checker, and use it from the "gating-passive" and "smoke" spartan tests.
- Loading branch information
1 parent
10d3f6f
commit 9380c0f
Showing
9 changed files
with
199 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 0 additions & 88 deletions
88
yarn-project/end-to-end/src/quality_of_service/alert_checker.test.ts
This file was deleted.
Oops, something went wrong.
105 changes: 105 additions & 0 deletions
105
yarn-project/end-to-end/src/quality_of_service/alert_checker.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { type DebugLogger } from '@aztec/aztec.js'; | ||
|
||
import * as fs from 'fs'; | ||
import * as yaml from 'js-yaml'; | ||
|
||
export interface AlertConfig { | ||
alert: string; | ||
expr: string; | ||
for: string; | ||
labels: Record<string, string>; | ||
annotations: Record<string, string>; | ||
} | ||
|
||
export interface AlertCheckerConfig { | ||
grafanaEndpoint: string; | ||
grafanaCredentials: string; | ||
} | ||
|
||
// This config is good if you're running the otel-lgtm stack locally | ||
const DEFAULT_CONFIG: AlertCheckerConfig = { | ||
grafanaEndpoint: 'http://localhost:3000/api/datasources/proxy/uid/prometheus/api/v1/query', | ||
grafanaCredentials: 'admin:admin', | ||
}; | ||
|
||
export class AlertChecker { | ||
private config: AlertCheckerConfig; | ||
private logger: DebugLogger; | ||
|
||
constructor(logger: DebugLogger, config: Partial<AlertCheckerConfig> = {}) { | ||
this.config = { ...DEFAULT_CONFIG, ...config }; | ||
this.logger = logger; | ||
} | ||
|
||
/** | ||
* Load the alerts config from a file path. | ||
* @param filePath - The absolute path to the alerts file. | ||
*/ | ||
private loadAlertsConfig(filePath: string): AlertConfig[] { | ||
const fileContents = fs.readFileSync(filePath, 'utf8'); | ||
const data = yaml.load(fileContents) as { alerts: AlertConfig[] }; | ||
return data.alerts; | ||
} | ||
|
||
private async queryGrafana(expr: string): Promise<number> { | ||
const credentials = Buffer.from(this.config.grafanaCredentials).toString('base64'); | ||
|
||
const response = await fetch(`${this.config.grafanaEndpoint}?query=${encodeURIComponent(expr)}`, { | ||
headers: { | ||
Authorization: `Basic ${credentials}`, | ||
}, | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error(`Failed to fetch data from Grafana: ${response.statusText}`); | ||
} | ||
|
||
const data = await response.json(); | ||
const result = data.data.result; | ||
return result.length > 0 ? parseFloat(result[0].value[1]) : 0; | ||
} | ||
|
||
private async checkAlerts(alerts: AlertConfig[]): Promise<void> { | ||
let alertTriggered = false; | ||
|
||
for (const alert of alerts) { | ||
this.logger.info(`Checking alert: ${JSON.stringify(alert)}`); | ||
|
||
const metricValue = await this.queryGrafana(alert.expr); | ||
this.logger.info(`Metric value: ${metricValue}`); | ||
if (metricValue > 0) { | ||
this.logger.error(`Alert ${alert.alert} triggered! Value: ${metricValue}`); | ||
alertTriggered = true; | ||
} else { | ||
this.logger.info(`Alert ${alert.alert} passed.`); | ||
} | ||
} | ||
|
||
if (alertTriggered) { | ||
throw new Error('Test failed due to triggered alert'); | ||
} | ||
} | ||
|
||
/** | ||
* Run the alert check based on the alerts defined in an array. | ||
* @param alerts - The alerts to check. | ||
*/ | ||
public async runAlertCheck(alerts: AlertConfig[]): Promise<void> { | ||
try { | ||
await this.checkAlerts(alerts); | ||
this.logger.info('All alerts passed.'); | ||
} catch (error) { | ||
this.logger.error(error instanceof Error ? error.message : String(error)); | ||
throw error; | ||
} | ||
} | ||
|
||
/** | ||
* Run the alert check based on the alerts defined in a yaml file. | ||
* @param filePath - The absolute path to the alerts file. | ||
*/ | ||
public async runAlertCheckFromFilePath(filePath: string): Promise<void> { | ||
const alerts = this.loadAlertsConfig(filePath); | ||
await this.checkAlerts(alerts); | ||
} | ||
} |
10 changes: 0 additions & 10 deletions
10
yarn-project/end-to-end/src/quality_of_service/alerts.yaml
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.