From 9dbda47acba636151056c6bcfc23ee41dab4a8a2 Mon Sep 17 00:00:00 2001 From: Jordan Simonovski Date: Thu, 16 Jul 2026 11:07:05 +1000 Subject: [PATCH 1/7] test(api): split unit tests out of the integration suite --- packages/api/jest.config.js | 1 + packages/api/jest.int.config.js | 10 ++++++++++ packages/api/package.json | 5 +++-- ...test.ts.snap => renderChartConfig.int.test.ts.snap} | 0 ...artConfig.test.ts => renderChartConfig.int.test.ts} | 0 .../{alertHistory.test.ts => alertHistory.int.test.ts} | 0 .../__tests__/{sources.test.ts => sources.int.test.ts} | 0 .../__tests__/{team.test.ts => team.int.test.ts} | 0 .../__tests__/{alerts.test.ts => alerts.int.test.ts} | 0 ...teDashboard.test.ts => deleteDashboard.int.test.ts} | 0 .../{getDashboard.test.ts => getDashboard.int.test.ts} | 0 ...hboardTile.test.ts => getDashboardTile.int.test.ts} | 0 ...tchDashboard.test.ts => patchDashboard.int.test.ts} | 0 .../{queryTile.test.ts => queryTile.int.test.ts} | 0 ...saveDashboard.test.ts => saveDashboard.int.test.ts} | 0 ...Dashboards.test.ts => searchDashboards.int.test.ts} | 0 .../{deltasTool.test.ts => deltasTool.int.test.ts} | 0 .../{queryTool.test.ts => queryTool.int.test.ts} | 0 ...savedSearches.test.ts => savedSearches.int.test.ts} | 0 .../__tests__/{sources.test.ts => sources.int.test.ts} | 0 .../mcp/__tests__/{trace.test.ts => trace.int.test.ts} | 0 .../__tests__/{index.test.ts => index.int.test.ts} | 0 .../__tests__/{alerts.test.ts => alerts.int.test.ts} | 0 .../{connections.test.ts => connections.int.test.ts} | 0 .../{dashboard.test.ts => dashboard.int.test.ts} | 0 .../{favorites.test.ts => favorites.int.test.ts} | 0 ...pinnedFilters.test.ts => pinnedFilters.int.test.ts} | 0 ...heus.integration.test.ts => prometheus.int.test.ts} | 0 .../{savedSearch.test.ts => savedSearch.int.test.ts} | 0 .../__tests__/{sources.test.ts => sources.int.test.ts} | 0 .../api/__tests__/{team.test.ts => team.int.test.ts} | 0 .../{webhooks.test.ts => webhooks.int.test.ts} | 0 .../__tests__/{alerts.test.ts => alerts.int.test.ts} | 0 .../__tests__/{charts.test.ts => charts.int.test.ts} | 0 .../{connections.test.ts => connections.int.test.ts} | 0 .../{dashboards.test.ts => dashboards.int.test.ts} | 0 ...hes-crud.test.ts => savedSearches-crud.int.test.ts} | 0 .../__tests__/{search.test.ts => search.int.test.ts} | 0 .../{sources-crud.test.ts => sources-crud.int.test.ts} | 0 .../__tests__/{sources.test.ts => sources.int.test.ts} | 0 .../__tests__/{team.test.ts => team.int.test.ts} | 0 .../__tests__/{v2.test.ts => v2.int.test.ts} | 0 .../{webhooks.test.ts => webhooks.int.test.ts} | 0 ...st.ts.snap => renderAlertTemplate.int.test.ts.snap} | 0 .../{checkAlerts.test.ts => checkAlerts.int.test.ts} | 0 ...emplate.test.ts => renderAlertTemplate.int.test.ts} | 0 ...Alert.test.ts => singleInvocationAlert.int.test.ts} | 0 .../__tests__/{default.test.ts => default.int.test.ts} | 0 ...hboards.test.ts => provisionDashboards.int.test.ts} | 0 49 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 packages/api/jest.int.config.js rename packages/api/src/clickhouse/__tests__/__snapshots__/{renderChartConfig.test.ts.snap => renderChartConfig.int.test.ts.snap} (100%) rename packages/api/src/clickhouse/__tests__/{renderChartConfig.test.ts => renderChartConfig.int.test.ts} (100%) rename packages/api/src/controllers/__tests__/{alertHistory.test.ts => alertHistory.int.test.ts} (100%) rename packages/api/src/controllers/__tests__/{sources.test.ts => sources.int.test.ts} (100%) rename packages/api/src/controllers/__tests__/{team.test.ts => team.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/{alerts.test.ts => alerts.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/dashboards/{deleteDashboard.test.ts => deleteDashboard.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/dashboards/{getDashboard.test.ts => getDashboard.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/dashboards/{getDashboardTile.test.ts => getDashboardTile.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/dashboards/{patchDashboard.test.ts => patchDashboard.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/dashboards/{queryTile.test.ts => queryTile.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/dashboards/{saveDashboard.test.ts => saveDashboard.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/dashboards/{searchDashboards.test.ts => searchDashboards.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/{deltasTool.test.ts => deltasTool.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/{queryTool.test.ts => queryTool.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/{savedSearches.test.ts => savedSearches.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/{sources.test.ts => sources.int.test.ts} (100%) rename packages/api/src/mcp/__tests__/{trace.test.ts => trace.int.test.ts} (100%) rename packages/api/src/models/__tests__/{index.test.ts => index.int.test.ts} (100%) rename packages/api/src/routers/api/__tests__/{alerts.test.ts => alerts.int.test.ts} (100%) rename packages/api/src/routers/api/__tests__/{connections.test.ts => connections.int.test.ts} (100%) rename packages/api/src/routers/api/__tests__/{dashboard.test.ts => dashboard.int.test.ts} (100%) rename packages/api/src/routers/api/__tests__/{favorites.test.ts => favorites.int.test.ts} (100%) rename packages/api/src/routers/api/__tests__/{pinnedFilters.test.ts => pinnedFilters.int.test.ts} (100%) rename packages/api/src/routers/api/__tests__/{prometheus.integration.test.ts => prometheus.int.test.ts} (100%) rename packages/api/src/routers/api/__tests__/{savedSearch.test.ts => savedSearch.int.test.ts} (100%) rename packages/api/src/routers/api/__tests__/{sources.test.ts => sources.int.test.ts} (100%) rename packages/api/src/routers/api/__tests__/{team.test.ts => team.int.test.ts} (100%) rename packages/api/src/routers/api/__tests__/{webhooks.test.ts => webhooks.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{alerts.test.ts => alerts.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{charts.test.ts => charts.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{connections.test.ts => connections.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{dashboards.test.ts => dashboards.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{savedSearches-crud.test.ts => savedSearches-crud.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{search.test.ts => search.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{sources-crud.test.ts => sources-crud.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{sources.test.ts => sources.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{team.test.ts => team.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{v2.test.ts => v2.int.test.ts} (100%) rename packages/api/src/routers/external-api/__tests__/{webhooks.test.ts => webhooks.int.test.ts} (100%) rename packages/api/src/tasks/checkAlerts/__tests__/__snapshots__/{renderAlertTemplate.test.ts.snap => renderAlertTemplate.int.test.ts.snap} (100%) rename packages/api/src/tasks/checkAlerts/__tests__/{checkAlerts.test.ts => checkAlerts.int.test.ts} (100%) rename packages/api/src/tasks/checkAlerts/__tests__/{renderAlertTemplate.test.ts => renderAlertTemplate.int.test.ts} (100%) rename packages/api/src/tasks/checkAlerts/__tests__/{singleInvocationAlert.test.ts => singleInvocationAlert.int.test.ts} (100%) rename packages/api/src/tasks/checkAlerts/providers/__tests__/{default.test.ts => default.int.test.ts} (100%) rename packages/api/src/tasks/provisionDashboards/__tests__/{provisionDashboards.test.ts => provisionDashboards.int.test.ts} (100%) diff --git a/packages/api/jest.config.js b/packages/api/jest.config.js index 8b6d0e10fb..d8d938caa1 100644 --- a/packages/api/jest.config.js +++ b/packages/api/jest.config.js @@ -17,6 +17,7 @@ module.exports = { verbose: true, rootDir: './src', testMatch: ['**/__tests__/**/*.test.ts?(x)'], + testPathIgnorePatterns: ['/node_modules/', '.*\\.int\\.test\\.tsx?$'], testTimeout: 30000, moduleNameMapper: { '@/(.*)$': '/$1', diff --git a/packages/api/jest.int.config.js b/packages/api/jest.int.config.js new file mode 100644 index 0000000000..add0482623 --- /dev/null +++ b/packages/api/jest.int.config.js @@ -0,0 +1,10 @@ +const base = require('./jest.config.js'); + +/** @type {import("jest").Config} **/ +module.exports = { + ...base, + testMatch: ['**/__tests__/**/*.int.test.ts?(x)'], + // Override the unit config's ignore list: it excludes `.int.test.ts`, which + // would otherwise hide every integration test from this suite. + testPathIgnorePatterns: ['/node_modules/'], +}; diff --git a/packages/api/package.json b/packages/api/package.json index 312a94c86e..c53bf19a78 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -92,8 +92,9 @@ "lint": "npx eslint --quiet . --ext .ts", "lint:fix": "npx eslint . --ext .ts --fix", "ci:lint": "yarn lint && yarn tsc --noEmit && yarn lint:openapi", - "ci:int": "DOTENV_CONFIG_PATH=.env.test DOTENV_CONFIG_OVERRIDE=true jest --runInBand --ci --forceExit", - "dev:int": "DOTENV_CONFIG_PATH=.env.test DOTENV_CONFIG_OVERRIDE=true jest --runInBand --coverage --forceExit", + "ci:unit": "jest --ci --coverage", + "ci:int": "DOTENV_CONFIG_PATH=.env.test DOTENV_CONFIG_OVERRIDE=true jest --config jest.int.config.js --runInBand --ci --forceExit", + "dev:int": "DOTENV_CONFIG_PATH=.env.test DOTENV_CONFIG_OVERRIDE=true jest --config jest.int.config.js --runInBand --coverage --forceExit", "dev:migrate-db-create": "ts-node node_modules/.bin/migrate-mongo create -f migrate-mongo-config.ts", "dev:migrate-db": "ts-node node_modules/.bin/migrate-mongo up -f migrate-mongo-config.ts", "dev:migrate-ch-create": "migrate create -ext sql -dir ./migrations/ch -seq", diff --git a/packages/api/src/clickhouse/__tests__/__snapshots__/renderChartConfig.test.ts.snap b/packages/api/src/clickhouse/__tests__/__snapshots__/renderChartConfig.int.test.ts.snap similarity index 100% rename from packages/api/src/clickhouse/__tests__/__snapshots__/renderChartConfig.test.ts.snap rename to packages/api/src/clickhouse/__tests__/__snapshots__/renderChartConfig.int.test.ts.snap diff --git a/packages/api/src/clickhouse/__tests__/renderChartConfig.test.ts b/packages/api/src/clickhouse/__tests__/renderChartConfig.int.test.ts similarity index 100% rename from packages/api/src/clickhouse/__tests__/renderChartConfig.test.ts rename to packages/api/src/clickhouse/__tests__/renderChartConfig.int.test.ts diff --git a/packages/api/src/controllers/__tests__/alertHistory.test.ts b/packages/api/src/controllers/__tests__/alertHistory.int.test.ts similarity index 100% rename from packages/api/src/controllers/__tests__/alertHistory.test.ts rename to packages/api/src/controllers/__tests__/alertHistory.int.test.ts diff --git a/packages/api/src/controllers/__tests__/sources.test.ts b/packages/api/src/controllers/__tests__/sources.int.test.ts similarity index 100% rename from packages/api/src/controllers/__tests__/sources.test.ts rename to packages/api/src/controllers/__tests__/sources.int.test.ts diff --git a/packages/api/src/controllers/__tests__/team.test.ts b/packages/api/src/controllers/__tests__/team.int.test.ts similarity index 100% rename from packages/api/src/controllers/__tests__/team.test.ts rename to packages/api/src/controllers/__tests__/team.int.test.ts diff --git a/packages/api/src/mcp/__tests__/alerts.test.ts b/packages/api/src/mcp/__tests__/alerts.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/alerts.test.ts rename to packages/api/src/mcp/__tests__/alerts.int.test.ts diff --git a/packages/api/src/mcp/__tests__/dashboards/deleteDashboard.test.ts b/packages/api/src/mcp/__tests__/dashboards/deleteDashboard.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/dashboards/deleteDashboard.test.ts rename to packages/api/src/mcp/__tests__/dashboards/deleteDashboard.int.test.ts diff --git a/packages/api/src/mcp/__tests__/dashboards/getDashboard.test.ts b/packages/api/src/mcp/__tests__/dashboards/getDashboard.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/dashboards/getDashboard.test.ts rename to packages/api/src/mcp/__tests__/dashboards/getDashboard.int.test.ts diff --git a/packages/api/src/mcp/__tests__/dashboards/getDashboardTile.test.ts b/packages/api/src/mcp/__tests__/dashboards/getDashboardTile.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/dashboards/getDashboardTile.test.ts rename to packages/api/src/mcp/__tests__/dashboards/getDashboardTile.int.test.ts diff --git a/packages/api/src/mcp/__tests__/dashboards/patchDashboard.test.ts b/packages/api/src/mcp/__tests__/dashboards/patchDashboard.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/dashboards/patchDashboard.test.ts rename to packages/api/src/mcp/__tests__/dashboards/patchDashboard.int.test.ts diff --git a/packages/api/src/mcp/__tests__/dashboards/queryTile.test.ts b/packages/api/src/mcp/__tests__/dashboards/queryTile.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/dashboards/queryTile.test.ts rename to packages/api/src/mcp/__tests__/dashboards/queryTile.int.test.ts diff --git a/packages/api/src/mcp/__tests__/dashboards/saveDashboard.test.ts b/packages/api/src/mcp/__tests__/dashboards/saveDashboard.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/dashboards/saveDashboard.test.ts rename to packages/api/src/mcp/__tests__/dashboards/saveDashboard.int.test.ts diff --git a/packages/api/src/mcp/__tests__/dashboards/searchDashboards.test.ts b/packages/api/src/mcp/__tests__/dashboards/searchDashboards.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/dashboards/searchDashboards.test.ts rename to packages/api/src/mcp/__tests__/dashboards/searchDashboards.int.test.ts diff --git a/packages/api/src/mcp/__tests__/deltasTool.test.ts b/packages/api/src/mcp/__tests__/deltasTool.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/deltasTool.test.ts rename to packages/api/src/mcp/__tests__/deltasTool.int.test.ts diff --git a/packages/api/src/mcp/__tests__/queryTool.test.ts b/packages/api/src/mcp/__tests__/queryTool.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/queryTool.test.ts rename to packages/api/src/mcp/__tests__/queryTool.int.test.ts diff --git a/packages/api/src/mcp/__tests__/savedSearches.test.ts b/packages/api/src/mcp/__tests__/savedSearches.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/savedSearches.test.ts rename to packages/api/src/mcp/__tests__/savedSearches.int.test.ts diff --git a/packages/api/src/mcp/__tests__/sources.test.ts b/packages/api/src/mcp/__tests__/sources.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/sources.test.ts rename to packages/api/src/mcp/__tests__/sources.int.test.ts diff --git a/packages/api/src/mcp/__tests__/trace.test.ts b/packages/api/src/mcp/__tests__/trace.int.test.ts similarity index 100% rename from packages/api/src/mcp/__tests__/trace.test.ts rename to packages/api/src/mcp/__tests__/trace.int.test.ts diff --git a/packages/api/src/models/__tests__/index.test.ts b/packages/api/src/models/__tests__/index.int.test.ts similarity index 100% rename from packages/api/src/models/__tests__/index.test.ts rename to packages/api/src/models/__tests__/index.int.test.ts diff --git a/packages/api/src/routers/api/__tests__/alerts.test.ts b/packages/api/src/routers/api/__tests__/alerts.int.test.ts similarity index 100% rename from packages/api/src/routers/api/__tests__/alerts.test.ts rename to packages/api/src/routers/api/__tests__/alerts.int.test.ts diff --git a/packages/api/src/routers/api/__tests__/connections.test.ts b/packages/api/src/routers/api/__tests__/connections.int.test.ts similarity index 100% rename from packages/api/src/routers/api/__tests__/connections.test.ts rename to packages/api/src/routers/api/__tests__/connections.int.test.ts diff --git a/packages/api/src/routers/api/__tests__/dashboard.test.ts b/packages/api/src/routers/api/__tests__/dashboard.int.test.ts similarity index 100% rename from packages/api/src/routers/api/__tests__/dashboard.test.ts rename to packages/api/src/routers/api/__tests__/dashboard.int.test.ts diff --git a/packages/api/src/routers/api/__tests__/favorites.test.ts b/packages/api/src/routers/api/__tests__/favorites.int.test.ts similarity index 100% rename from packages/api/src/routers/api/__tests__/favorites.test.ts rename to packages/api/src/routers/api/__tests__/favorites.int.test.ts diff --git a/packages/api/src/routers/api/__tests__/pinnedFilters.test.ts b/packages/api/src/routers/api/__tests__/pinnedFilters.int.test.ts similarity index 100% rename from packages/api/src/routers/api/__tests__/pinnedFilters.test.ts rename to packages/api/src/routers/api/__tests__/pinnedFilters.int.test.ts diff --git a/packages/api/src/routers/api/__tests__/prometheus.integration.test.ts b/packages/api/src/routers/api/__tests__/prometheus.int.test.ts similarity index 100% rename from packages/api/src/routers/api/__tests__/prometheus.integration.test.ts rename to packages/api/src/routers/api/__tests__/prometheus.int.test.ts diff --git a/packages/api/src/routers/api/__tests__/savedSearch.test.ts b/packages/api/src/routers/api/__tests__/savedSearch.int.test.ts similarity index 100% rename from packages/api/src/routers/api/__tests__/savedSearch.test.ts rename to packages/api/src/routers/api/__tests__/savedSearch.int.test.ts diff --git a/packages/api/src/routers/api/__tests__/sources.test.ts b/packages/api/src/routers/api/__tests__/sources.int.test.ts similarity index 100% rename from packages/api/src/routers/api/__tests__/sources.test.ts rename to packages/api/src/routers/api/__tests__/sources.int.test.ts diff --git a/packages/api/src/routers/api/__tests__/team.test.ts b/packages/api/src/routers/api/__tests__/team.int.test.ts similarity index 100% rename from packages/api/src/routers/api/__tests__/team.test.ts rename to packages/api/src/routers/api/__tests__/team.int.test.ts diff --git a/packages/api/src/routers/api/__tests__/webhooks.test.ts b/packages/api/src/routers/api/__tests__/webhooks.int.test.ts similarity index 100% rename from packages/api/src/routers/api/__tests__/webhooks.test.ts rename to packages/api/src/routers/api/__tests__/webhooks.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/alerts.test.ts b/packages/api/src/routers/external-api/__tests__/alerts.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/alerts.test.ts rename to packages/api/src/routers/external-api/__tests__/alerts.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/charts.test.ts b/packages/api/src/routers/external-api/__tests__/charts.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/charts.test.ts rename to packages/api/src/routers/external-api/__tests__/charts.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/connections.test.ts b/packages/api/src/routers/external-api/__tests__/connections.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/connections.test.ts rename to packages/api/src/routers/external-api/__tests__/connections.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/dashboards.test.ts b/packages/api/src/routers/external-api/__tests__/dashboards.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/dashboards.test.ts rename to packages/api/src/routers/external-api/__tests__/dashboards.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/savedSearches-crud.test.ts b/packages/api/src/routers/external-api/__tests__/savedSearches-crud.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/savedSearches-crud.test.ts rename to packages/api/src/routers/external-api/__tests__/savedSearches-crud.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/search.test.ts b/packages/api/src/routers/external-api/__tests__/search.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/search.test.ts rename to packages/api/src/routers/external-api/__tests__/search.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/sources-crud.test.ts b/packages/api/src/routers/external-api/__tests__/sources-crud.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/sources-crud.test.ts rename to packages/api/src/routers/external-api/__tests__/sources-crud.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/sources.test.ts b/packages/api/src/routers/external-api/__tests__/sources.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/sources.test.ts rename to packages/api/src/routers/external-api/__tests__/sources.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/team.test.ts b/packages/api/src/routers/external-api/__tests__/team.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/team.test.ts rename to packages/api/src/routers/external-api/__tests__/team.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/v2.test.ts b/packages/api/src/routers/external-api/__tests__/v2.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/v2.test.ts rename to packages/api/src/routers/external-api/__tests__/v2.int.test.ts diff --git a/packages/api/src/routers/external-api/__tests__/webhooks.test.ts b/packages/api/src/routers/external-api/__tests__/webhooks.int.test.ts similarity index 100% rename from packages/api/src/routers/external-api/__tests__/webhooks.test.ts rename to packages/api/src/routers/external-api/__tests__/webhooks.int.test.ts diff --git a/packages/api/src/tasks/checkAlerts/__tests__/__snapshots__/renderAlertTemplate.test.ts.snap b/packages/api/src/tasks/checkAlerts/__tests__/__snapshots__/renderAlertTemplate.int.test.ts.snap similarity index 100% rename from packages/api/src/tasks/checkAlerts/__tests__/__snapshots__/renderAlertTemplate.test.ts.snap rename to packages/api/src/tasks/checkAlerts/__tests__/__snapshots__/renderAlertTemplate.int.test.ts.snap diff --git a/packages/api/src/tasks/checkAlerts/__tests__/checkAlerts.test.ts b/packages/api/src/tasks/checkAlerts/__tests__/checkAlerts.int.test.ts similarity index 100% rename from packages/api/src/tasks/checkAlerts/__tests__/checkAlerts.test.ts rename to packages/api/src/tasks/checkAlerts/__tests__/checkAlerts.int.test.ts diff --git a/packages/api/src/tasks/checkAlerts/__tests__/renderAlertTemplate.test.ts b/packages/api/src/tasks/checkAlerts/__tests__/renderAlertTemplate.int.test.ts similarity index 100% rename from packages/api/src/tasks/checkAlerts/__tests__/renderAlertTemplate.test.ts rename to packages/api/src/tasks/checkAlerts/__tests__/renderAlertTemplate.int.test.ts diff --git a/packages/api/src/tasks/checkAlerts/__tests__/singleInvocationAlert.test.ts b/packages/api/src/tasks/checkAlerts/__tests__/singleInvocationAlert.int.test.ts similarity index 100% rename from packages/api/src/tasks/checkAlerts/__tests__/singleInvocationAlert.test.ts rename to packages/api/src/tasks/checkAlerts/__tests__/singleInvocationAlert.int.test.ts diff --git a/packages/api/src/tasks/checkAlerts/providers/__tests__/default.test.ts b/packages/api/src/tasks/checkAlerts/providers/__tests__/default.int.test.ts similarity index 100% rename from packages/api/src/tasks/checkAlerts/providers/__tests__/default.test.ts rename to packages/api/src/tasks/checkAlerts/providers/__tests__/default.int.test.ts diff --git a/packages/api/src/tasks/provisionDashboards/__tests__/provisionDashboards.test.ts b/packages/api/src/tasks/provisionDashboards/__tests__/provisionDashboards.int.test.ts similarity index 100% rename from packages/api/src/tasks/provisionDashboards/__tests__/provisionDashboards.test.ts rename to packages/api/src/tasks/provisionDashboards/__tests__/provisionDashboards.int.test.ts From 08b30351d2847161a542551f429d3ff5bc0f2d24 Mon Sep 17 00:00:00 2001 From: Jordan Simonovski Date: Thu, 16 Jul 2026 12:03:11 +1000 Subject: [PATCH 2/7] docs: document the api unit-test command after the test split --- AGENTS.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 17fa68b54f..6c9afa8393 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -113,11 +113,14 @@ yarn ci:unit # Run unit tests yarn dev:unit # Watch mode for unit tests ``` -**packages/api** (integration tests only): +**packages/api** (unit and integration tests): ```bash -make dev-int-build # Build dependencies (run once before tests) -make dev-int FILE= # Spins up Docker services and runs tests. +cd packages/api +yarn ci:unit # Run unit tests (no services needed) + +make dev-int-build # Build dependencies (run once before integration tests) +make dev-int FILE= # Spins up Docker services and runs integration tests. # Ctrl-C to stop and wait for all services to tear down. ``` From 9c6b58870afa15c41e26962ffe6c67ac0a61bc40 Mon Sep 17 00:00:00 2001 From: Jordan Simonovski Date: Thu, 16 Jul 2026 12:06:21 +1000 Subject: [PATCH 3/7] ci(test): run common-utils unit tests in parallel --- packages/common-utils/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/common-utils/package.json b/packages/common-utils/package.json index 92d7006597..f2676cd646 100644 --- a/packages/common-utils/package.json +++ b/packages/common-utils/package.json @@ -46,8 +46,8 @@ "lint": "npx eslint --quiet . --ext .ts", "lint:fix": "npx eslint . --ext .ts --fix", "ci:lint": "yarn lint && yarn tsc --noEmit", - "ci:unit": "jest --runInBand --ci --coverage", - "dev:unit": "jest --watchAll --runInBand", + "ci:unit": "jest --ci --coverage", + "dev:unit": "jest --watchAll", "ci:int": "DOTENV_CONFIG_PATH=.env.test jest --config jest.int.config.js --runInBand --ci --coverage", "dev:int": "DOTENV_CONFIG_PATH=.env.test jest --config jest.int.config.js --watchAll --runInBand" } From 806f79ee9fb3db0c78509991efcd4a3dd2427038 Mon Sep 17 00:00:00 2001 From: Jordan Simonovski Date: Thu, 16 Jul 2026 12:21:57 +1000 Subject: [PATCH 4/7] ci: shard integration tests across parallel jobs --- .github/workflows/main.yml | 16 +++++++++++++++- packages/api/package.json | 2 +- packages/common-utils/package.json | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7df016c548..e1e1752bb4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,8 +47,13 @@ jobs: - name: Run unit tests run: make ci-unit integration: + name: Integration - Shard ${{ matrix.shard }} timeout-minutes: 16 runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + shard: [1, 2, 3, 4] steps: - name: Checkout uses: actions/checkout@v6 @@ -68,8 +73,17 @@ jobs: docker buildx bake -f ./docker-compose.ci.yml --set *.cache-to="type=gha" --set *.cache-from="type=gha" --load - name: Build dependencies run: make ci-build + # Integration tests boot a MockServer on fixed ports and share a single + # MongoDB/ClickHouse database, so they must stay serial (--runInBand) + # within a runner. We shard ACROSS runners instead: each shard is its own + # VM with its own Docker stack, and jest's --shard splits the test files + # so the shards run in parallel. make ci-int is kept unchanged for local + # unsharded runs; here we start the same Docker stack and forward --shard + # through nx (args after `--` reach the underlying jest invocations). - name: Run integration tests - run: make ci-int + run: | + docker compose -f ./docker-compose.ci.yml up -d --quiet-pull + npx nx run-many -t ci:int --parallel=false --output-style=stream -- --shard=${{ matrix.shard }}/4 otel-unit-test: timeout-minutes: 8 runs-on: ubuntu-24.04 diff --git a/packages/api/package.json b/packages/api/package.json index c53bf19a78..217cd3e39f 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -93,7 +93,7 @@ "lint:fix": "npx eslint . --ext .ts --fix", "ci:lint": "yarn lint && yarn tsc --noEmit && yarn lint:openapi", "ci:unit": "jest --ci --coverage", - "ci:int": "DOTENV_CONFIG_PATH=.env.test DOTENV_CONFIG_OVERRIDE=true jest --config jest.int.config.js --runInBand --ci --forceExit", + "ci:int": "DOTENV_CONFIG_PATH=.env.test DOTENV_CONFIG_OVERRIDE=true jest --config jest.int.config.js --runInBand --ci --forceExit --passWithNoTests", "dev:int": "DOTENV_CONFIG_PATH=.env.test DOTENV_CONFIG_OVERRIDE=true jest --config jest.int.config.js --runInBand --coverage --forceExit", "dev:migrate-db-create": "ts-node node_modules/.bin/migrate-mongo create -f migrate-mongo-config.ts", "dev:migrate-db": "ts-node node_modules/.bin/migrate-mongo up -f migrate-mongo-config.ts", diff --git a/packages/common-utils/package.json b/packages/common-utils/package.json index f2676cd646..358731acc4 100644 --- a/packages/common-utils/package.json +++ b/packages/common-utils/package.json @@ -48,7 +48,7 @@ "ci:lint": "yarn lint && yarn tsc --noEmit", "ci:unit": "jest --ci --coverage", "dev:unit": "jest --watchAll", - "ci:int": "DOTENV_CONFIG_PATH=.env.test jest --config jest.int.config.js --runInBand --ci --coverage", + "ci:int": "DOTENV_CONFIG_PATH=.env.test jest --config jest.int.config.js --runInBand --ci --coverage --passWithNoTests", "dev:int": "DOTENV_CONFIG_PATH=.env.test jest --config jest.int.config.js --watchAll --runInBand" } } From 4cd9f7eee919621f3eadb5551a1abba5a53c70e2 Mon Sep 17 00:00:00 2001 From: Jordan Simonovski Date: Thu, 16 Jul 2026 12:36:02 +1000 Subject: [PATCH 5/7] ci: add stable integration aggregator check for the shard matrix --- .github/workflows/main.yml | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e1e1752bb4..3238b5b1a6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -46,7 +46,7 @@ jobs: run: make ci-build - name: Run unit tests run: make ci-unit - integration: + integration-shards: name: Integration - Shard ${{ matrix.shard }} timeout-minutes: 16 runs-on: ubuntu-24.04 @@ -77,13 +77,32 @@ jobs: # MongoDB/ClickHouse database, so they must stay serial (--runInBand) # within a runner. We shard ACROSS runners instead: each shard is its own # VM with its own Docker stack, and jest's --shard splits the test files - # so the shards run in parallel. make ci-int is kept unchanged for local - # unsharded runs; here we start the same Docker stack and forward --shard - # through nx (args after `--` reach the underlying jest invocations). + # so the shards run in parallel. --shard is forwarded through nx (args + # after `--` reach the underlying jest invocations). + # + # Runs inline (not `make ci-int`) so the compose project stays `hdx-ci` + # (matching the bake step above); make ci-int's `-p int-` is local + # multi-worktree isolation that CI doesn't need, and routing through it + # would reintroduce a project-name mismatch against bake. Teardown and + # log-archival are omitted intentionally — the runner is ephemeral and + # Actions streams stdout. - name: Run integration tests run: | docker compose -f ./docker-compose.ci.yml up -d --quiet-pull npx nx run-many -t ci:int --parallel=false --output-style=stream -- --shard=${{ matrix.shard }}/4 + # Stable aggregator context: `integration` is green only when all four shards + # pass. Merge-queue / required-status checks target this single context, since + # the per-shard contexts (Integration - Shard N) are not stable check names. + integration: + needs: [integration-shards] + if: always() + runs-on: ubuntu-24.04 + steps: + - name: Verify all integration shards passed + if: needs.integration-shards.result != 'success' + run: | + echo "::error::One or more integration shards failed" + exit 1 otel-unit-test: timeout-minutes: 8 runs-on: ubuntu-24.04 From cad8d2cebd6f3426b512570f390c7f8a694f4064 Mon Sep 17 00:00:00 2001 From: Jordan Simonovski Date: Thu, 16 Jul 2026 15:56:09 +1000 Subject: [PATCH 6/7] ci: DRY shard divisor via strategy.job-total; aggregator timeout; api dev:unit --- .github/workflows/main.yml | 3 ++- packages/api/package.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3238b5b1a6..e0a5735d29 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -89,7 +89,7 @@ jobs: - name: Run integration tests run: | docker compose -f ./docker-compose.ci.yml up -d --quiet-pull - npx nx run-many -t ci:int --parallel=false --output-style=stream -- --shard=${{ matrix.shard }}/4 + npx nx run-many -t ci:int --parallel=false --output-style=stream -- --shard=${{ matrix.shard }}/${{ strategy.job-total }} # Stable aggregator context: `integration` is green only when all four shards # pass. Merge-queue / required-status checks target this single context, since # the per-shard contexts (Integration - Shard N) are not stable check names. @@ -97,6 +97,7 @@ jobs: needs: [integration-shards] if: always() runs-on: ubuntu-24.04 + timeout-minutes: 5 steps: - name: Verify all integration shards passed if: needs.integration-shards.result != 'success' diff --git a/packages/api/package.json b/packages/api/package.json index 217cd3e39f..c028ad6174 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -93,6 +93,7 @@ "lint:fix": "npx eslint . --ext .ts --fix", "ci:lint": "yarn lint && yarn tsc --noEmit && yarn lint:openapi", "ci:unit": "jest --ci --coverage", + "dev:unit": "jest --watch", "ci:int": "DOTENV_CONFIG_PATH=.env.test DOTENV_CONFIG_OVERRIDE=true jest --config jest.int.config.js --runInBand --ci --forceExit --passWithNoTests", "dev:int": "DOTENV_CONFIG_PATH=.env.test DOTENV_CONFIG_OVERRIDE=true jest --config jest.int.config.js --runInBand --coverage --forceExit", "dev:migrate-db-create": "ts-node node_modules/.bin/migrate-mongo create -f migrate-mongo-config.ts", From e86e6ad0f7fd5f69194c5bd36f115538d0b929fe Mon Sep 17 00:00:00 2001 From: Jordan Simonovski Date: Thu, 16 Jul 2026 16:13:56 +1000 Subject: [PATCH 7/7] ci: immutable installs + scoped integration bake cache (folded from #2662) --- .github/workflows/knip.yml | 2 +- .github/workflows/main.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/knip.yml b/.github/workflows/knip.yml index ff782ed03d..0e8c55b1c5 100644 --- a/.github/workflows/knip.yml +++ b/.github/workflows/knip.yml @@ -26,7 +26,7 @@ jobs: cache: 'yarn' - name: Install dependencies - run: yarn install + run: yarn install --immutable - name: Run Knip run: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e0a5735d29..68202d94ae 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -41,7 +41,7 @@ jobs: cache-dependency-path: 'yarn.lock' cache: 'yarn' - name: Install root dependencies - run: yarn install + run: yarn install --immutable - name: Build dependencies run: make ci-build - name: Run unit tests @@ -64,13 +64,13 @@ jobs: cache-dependency-path: 'yarn.lock' cache: 'yarn' - name: Install root dependencies - run: yarn install + run: yarn install --immutable - name: Expose GitHub Runtime uses: crazy-max/ghaction-github-runtime@v4 - name: Spin up docker services run: | docker buildx create --use --driver=docker-container - docker buildx bake -f ./docker-compose.ci.yml --set *.cache-to="type=gha" --set *.cache-from="type=gha" --load + docker buildx bake -f ./docker-compose.ci.yml --set *.cache-to="type=gha,mode=max,scope=ci-integration" --set *.cache-from="type=gha,scope=ci-integration" --load - name: Build dependencies run: make ci-build # Integration tests boot a MockServer on fixed ports and share a single @@ -298,7 +298,7 @@ jobs: cache: 'yarn' - name: Install dependencies - run: yarn install + run: yarn install --immutable - name: Build App run: yarn build:clickhouse