Skip to main content
Glama

mcp-server-circleci

Official
findUnderusedResourceClasses.test.ts4.03 kB
import { describe, it, expect, vi, type Mock } from 'vitest'; import { readAndParseCSV, validateCSVColumns, groupRecordsByJob, analyzeJobGroups, generateReport, } from './findUnderusedResourceClasses.js'; import * as fs from 'fs'; vi.mock('fs'); describe('findUnderusedResourceClasses library functions', () => { const CSV_HEADERS = 'project_name,workflow_name,job_name,resource_class,median_cpu_utilization_pct,max_cpu_utilization_pct,median_ram_utilization_pct,max_ram_utilization_pct,compute_credits'; const CSV_ROW_UNDER = 'proj,flow,build,medium,10,20,15,18,100'; const CSV_ROW_OVER = 'proj,flow,test,large,50,60,55,58,200'; const CSV_CONTENT = `${CSV_HEADERS}\n${CSV_ROW_UNDER}\n${CSV_ROW_OVER}`; const mockRecords = [ { project_name: 'proj', workflow_name: 'flow', job_name: 'build', resource_class: 'medium', median_cpu_utilization_pct: '10', max_cpu_utilization_pct: '20', median_ram_utilization_pct: '15', max_ram_utilization_pct: '18', compute_credits: '100' }, { project_name: 'proj', workflow_name: 'flow', job_name: 'test', resource_class: 'large', median_cpu_utilization_pct: '50', max_cpu_utilization_pct: '60', median_ram_utilization_pct: '55', max_ram_utilization_pct: '58', compute_credits: '200' } ]; describe('readAndParseCSV', () => { it('should read and parse a CSV file correctly', () => { (fs.readFileSync as Mock).mockReturnValue(CSV_CONTENT); const records = readAndParseCSV('dummy/path.csv'); expect(records).toHaveLength(2); expect(records[0].project_name).toBe('proj'); }); it('should throw an error if file read fails', () => { (fs.readFileSync as Mock).mockImplementation(() => { throw new Error('File not found'); }); expect(() => readAndParseCSV('bad/path.csv')).toThrow('Could not read CSV file'); }); }); describe('validateCSVColumns', () => { it('should not throw an error for valid records', () => { expect(() => validateCSVColumns(mockRecords)).not.toThrow(); }); it('should throw an error for missing required columns', () => { const invalidRecords = [{ project_name: 'proj' }]; expect(() => validateCSVColumns(invalidRecords)).toThrow('CSV is missing required columns'); }); }); describe('groupRecordsByJob', () => { it('should group records by job identifier', () => { const grouped = groupRecordsByJob(mockRecords); expect(grouped.size).toBe(2); expect(grouped.has('proj|||flow|||build|||medium')).toBe(true); }); }); describe('analyzeJobGroups', () => { it('should identify underused jobs', () => { const grouped = groupRecordsByJob(mockRecords); const underused = analyzeJobGroups(grouped, 40); expect(underused).toHaveLength(1); expect(underused[0].job).toBe('build'); }); it('should return an empty array if no jobs are underused', () => { const grouped = groupRecordsByJob([mockRecords[1]]); const underused = analyzeJobGroups(grouped, 40); expect(underused).toHaveLength(0); }); }); describe('generateReport', () => { it('should generate a report for underused jobs', () => { const underusedJobs = [{ projectName: 'proj', workflowName: 'flow', job: 'build', resourceClass: 'medium', avgCpu: 10, maxCpu: 20, avgRam: 15, maxRam: 18, count: 1, totalComputeCredits: 100 }]; const report = generateReport(underusedJobs, 40); expect(report).toContain('Underused resource classes'); expect(report).toContain('Project: proj'); }); it('should generate a message when no jobs are underused', () => { const report = generateReport([], 40); expect(report).toBe('No underused resource classes found (threshold: 40%).'); }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/CircleCI-Public/mcp-server-circleci'

If you have feedback or need assistance with the MCP directory API, please join our Discord server