Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
* Metrics Collection Orchestrator Tests
*/

const fs = require('fs');
const path = require('path');
const { MetricsCollectionOrchestrator } = require('../metrics-collection-orchestrator');
const fs = require("fs");
const path = require("path");
const {
MetricsCollectionOrchestrator,
} = require("../metrics-collection-orchestrator");

describe('MetricsCollectionOrchestrator', () => {
describe("MetricsCollectionOrchestrator", () => {
let orchestrator;
let configPath;
let testConfig;
Expand All @@ -15,9 +17,9 @@ describe('MetricsCollectionOrchestrator', () => {
// Create test configuration
testConfig = {
schedule: {
cron: '0 2 * * *',
timezone: 'UTC',
description: 'Daily metrics collection at 2 AM UTC',
cron: "0 2 * * *",
timezone: "UTC",
description: "Daily metrics collection at 2 AM UTC",
},
execution: {
parallelJobs: 1,
Expand All @@ -27,16 +29,16 @@ describe('MetricsCollectionOrchestrator', () => {
},
repositories: [
{
owner: 'lightspeedwp',
repo: '.github',
context: 'github-control-plane',
owner: "lightspeedwp",
repo: ".github",
context: "github-control-plane",
enabled: true,
},
],
storage: {
basePath: '.github/reports/metrics',
format: 'json',
timestampFormat: 'ISO8601',
basePath: ".github/reports/metrics",
format: "json",
timestampFormat: "ISO8601",
retention: {
days: 365,
maxFiles: 366,
Expand All @@ -45,17 +47,17 @@ describe('MetricsCollectionOrchestrator', () => {
notifications: {
onFailure: true,
onSuccess: false,
channels: ['github-issues'],
channels: ["github-issues"],
},
logging: {
level: 'info',
level: "info",
verbose: false,
outputPath: '.github/reports/metrics/logs',
outputPath: ".github/reports/metrics/logs",
},
};

// Write test configuration to temporary file
configPath = path.join(__dirname, 'test-metrics-config.json');
configPath = path.join(__dirname, "test-metrics-config.json");
fs.writeFileSync(configPath, JSON.stringify(testConfig, null, 2));
});

Expand All @@ -66,40 +68,40 @@ describe('MetricsCollectionOrchestrator', () => {
}
});

test('should load configuration successfully', () => {
test("should load configuration successfully", () => {
orchestrator = new MetricsCollectionOrchestrator(configPath);
expect(orchestrator.config).toBeDefined();
expect(orchestrator.config.repositories).toHaveLength(1);
expect(orchestrator.config.schedule.cron).toBe('0 2 * * *');
expect(orchestrator.config.schedule.cron).toBe("0 2 * * *");
});

test('should throw error when configuration file not found', () => {
const invalidPath = path.join(__dirname, 'nonexistent-config.json');
test("should throw error when configuration file not found", () => {
const invalidPath = path.join(__dirname, "nonexistent-config.json");
expect(() => {
new MetricsCollectionOrchestrator(invalidPath);
}).toThrow('Configuration file not found');
}).toThrow("Configuration file not found");
});

test('should throw error when repositories array is empty', () => {
test("should throw error when repositories array is empty", () => {
testConfig.repositories = [];
fs.writeFileSync(configPath, JSON.stringify(testConfig, null, 2));

expect(() => {
new MetricsCollectionOrchestrator(configPath);
}).toThrow('No repositories configured');
}).toThrow("No repositories configured");
});

test('should initialize storage and analyzers', () => {
test("should initialize storage and analyzers", () => {
orchestrator = new MetricsCollectionOrchestrator(configPath);
expect(orchestrator.storage).toBeDefined();
expect(orchestrator.trendAnalyzer).toBeDefined();
expect(orchestrator.anomalyDetector).toBeDefined();
});

test('should handle disabled repositories', async () => {
test("should handle disabled repositories", async () => {
testConfig.repositories = [
{ owner: 'org', repo: 'repo1', context: 'test', enabled: true },
{ owner: 'org', repo: 'repo2', context: 'test', enabled: false },
{ owner: "org", repo: "repo1", context: "test", enabled: true },
{ owner: "org", repo: "repo2", context: "test", enabled: false },
];
fs.writeFileSync(configPath, JSON.stringify(testConfig, null, 2));

Expand All @@ -111,15 +113,15 @@ describe('MetricsCollectionOrchestrator', () => {
expect(orchestrator.config.repositories).toHaveLength(2);
});

test('should generate summary with correct structure', async () => {
test("should generate summary with correct structure", async () => {
orchestrator = new MetricsCollectionOrchestrator(configPath);
orchestrator.startTime = Date.now();

// Add mock results
orchestrator.results = [
{
repository: 'lightspeedwp/.github',
status: 'success',
repository: "lightspeedwp/.github",
status: "success",
metricsCount: 15,
timestamp: new Date().toISOString(),
collectionTime: 2500,
Expand All @@ -139,14 +141,14 @@ describe('MetricsCollectionOrchestrator', () => {
expect(summary.results).toHaveLength(1);
});

test('should handle mixed success and error results', async () => {
test("should handle mixed success and error results", async () => {
orchestrator = new MetricsCollectionOrchestrator(configPath);
orchestrator.startTime = Date.now();

orchestrator.results = [
{
repository: 'lightspeedwp/.github',
status: 'success',
repository: "lightspeedwp/.github",
status: "success",
metricsCount: 15,
timestamp: new Date().toISOString(),
collectionTime: 2500,
Expand All @@ -157,9 +159,9 @@ describe('MetricsCollectionOrchestrator', () => {

orchestrator.errors = [
{
repository: 'lightspeedwp/plugin',
status: 'error',
error: 'GitHub API rate limit exceeded',
repository: "lightspeedwp/plugin",
status: "error",
error: "GitHub API rate limit exceeded",
timestamp: new Date().toISOString(),
},
];
Expand All @@ -169,17 +171,17 @@ describe('MetricsCollectionOrchestrator', () => {
expect(summary.execution.repositories.total).toBe(2);
expect(summary.execution.repositories.successful).toBe(1);
expect(summary.execution.repositories.failed).toBe(1);
expect(summary.execution.repositories.percentage).toBe('50.00');
expect(summary.execution.repositories.percentage).toBe("50.00");
});

test('should save summary report to disk', async () => {
test("should save summary report to disk", async () => {
orchestrator = new MetricsCollectionOrchestrator(configPath);
orchestrator.startTime = Date.now();

orchestrator.results = [
{
repository: 'lightspeedwp/.github',
status: 'success',
repository: "lightspeedwp/.github",
status: "success",
metricsCount: 15,
timestamp: new Date().toISOString(),
collectionTime: 2500,
Expand All @@ -192,12 +194,12 @@ describe('MetricsCollectionOrchestrator', () => {

// Verify summary file exists
const expectedPath = path.join(
'.github/reports/metrics',
`collection-summary-${new Date().toISOString().split('T')[0]}.json`
".github/reports/metrics",
`collection-summary-${new Date().toISOString().split("T")[0]}.json`,
);

if (fs.existsSync(expectedPath)) {
const savedSummary = JSON.parse(fs.readFileSync(expectedPath, 'utf8'));
const savedSummary = JSON.parse(fs.readFileSync(expectedPath, "utf8"));
expect(savedSummary.timestamp).toBeDefined();
expect(savedSummary.results).toHaveLength(1);

Expand All @@ -206,7 +208,7 @@ describe('MetricsCollectionOrchestrator', () => {
}
});

test('should track collection duration', async () => {
test("should track collection duration", async () => {
orchestrator = new MetricsCollectionOrchestrator(configPath);
const startTime = Date.now();
orchestrator.startTime = startTime;
Expand All @@ -216,8 +218,8 @@ describe('MetricsCollectionOrchestrator', () => {

orchestrator.results = [
{
repository: 'lightspeedwp/.github',
status: 'success',
repository: "lightspeedwp/.github",
status: "success",
metricsCount: 15,
timestamp: new Date().toISOString(),
collectionTime: 2500,
Expand All @@ -232,7 +234,7 @@ describe('MetricsCollectionOrchestrator', () => {
expect(summary.execution.duration).toBeGreaterThan(0);
});

test('should handle parallel vs sequential execution configuration', () => {
test("should handle parallel vs sequential execution configuration", () => {
testConfig.execution.parallelJobs = 4;
fs.writeFileSync(configPath, JSON.stringify(testConfig, null, 2));

Expand All @@ -241,7 +243,7 @@ describe('MetricsCollectionOrchestrator', () => {
expect(orchestrator.config.execution.parallelJobs).toBe(4);
});

test('should validate configuration structure', () => {
test("should validate configuration structure", () => {
orchestrator = new MetricsCollectionOrchestrator(configPath);

expect(orchestrator.config.schedule).toBeDefined();
Expand Down
Loading
Loading