Skip to main content
Glama
portel-dev

NCP - Natural Context Provider

by portel-dev
SCHEDULER_TESTING_GUIDE.md11.9 kB
## Scheduler Testing Guide Comprehensive guide for testing the NCP scheduler system. --- ## Testing Strategy ### 1. **Unit Tests** (Fast, Isolated) Test individual components in isolation: - JobManager (CRUD operations) - ExecutionRecorder (CSV + JSON storage) - CronManager (validation only, not actual crontab) - NaturalLanguageParser (schedule parsing) - ToolValidator (validation logic) ### 2. **Integration Tests** (Moderate, Mocked) Test component interactions with mocked dependencies: - Job creation → Validation → Storage → Cron entry - Execution flow → Recording → Cleanup - CLI commands → Scheduler → Storage ### 3. **E2E Tests** (Slow, Real System) Test actual system behavior (run manually or in isolated CI): - Real crontab manipulation - Actual tool execution - Real MCP interactions --- ## Running Tests ### **All Tests** ```bash npm test ``` ### **Scheduler Tests Only** ```bash npm test -- test/scheduler ``` ### **Specific Test File** ```bash npm test -- test/scheduler/job-manager.test.ts ``` ### **Watch Mode** ```bash npm test -- --watch test/scheduler ``` --- ## Test Structure ``` test/scheduler/ ├── test-helpers.ts # Shared utilities ├── job-manager.test.ts # JobManager unit tests ├── execution-recorder.test.ts # ExecutionRecorder unit tests ├── cron-manager.test.ts # CronManager unit tests ├── natural-language-parser.test.ts # Parser unit tests ├── tool-validator.test.ts # Validation unit tests ├── scheduler-integration.test.ts # Integration tests └── e2e/ # End-to-end tests ├── real-cron.test.ts # Actual crontab tests └── real-execution.test.ts # Actual tool execution tests ``` --- ## Unit Testing ### **JobManager Tests** Tests CRUD operations on jobs: ```typescript describe('JobManager', () => { it('should create a new job', () => { const job = createMockJob(); jobManager.createJob(job); const retrieved = jobManager.getJob(job.id); expect(retrieved).toEqual(job); }); it('should reject duplicate job IDs', () => { const job = createMockJob(); jobManager.createJob(job); expect(() => jobManager.createJob(job)).toThrow('already exists'); }); }); ``` **Run:** ```bash npm test -- test/scheduler/job-manager.test.ts ``` --- ### **NaturalLanguageParser Tests** Tests schedule parsing: ```typescript describe('NaturalLanguageParser', () => { it('should parse "every day at 9am"', () => { const result = NaturalLanguageParser.parseSchedule('every day at 9am'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 9 * * *'); }); it('should parse "in 5 minutes" as one-time', () => { const result = NaturalLanguageParser.parseSchedule('in 5 minutes'); expect(result.success).toBe(true); expect(result.fireOnce).toBe(true); }); }); ``` **Run:** ```bash npm test -- test/scheduler/natural-language-parser.test.ts ``` --- ### **CronManager Tests** Tests cron expression validation (NOT actual crontab): ```typescript describe('CronManager', () => { it('should validate correct cron expressions', () => { const result = CronManager.validateCronExpression('0 9 * * *'); expect(result.valid).toBe(true); }); it('should reject invalid expressions', () => { const result = CronManager.validateCronExpression('60 * * * *'); expect(result.valid).toBe(false); expect(result.error).toContain('minute'); }); }); ``` **Run:** ```bash npm test -- test/scheduler/cron-manager.test.ts ``` --- ## Integration Testing Tests component interactions with mocked dependencies: ```typescript describe('Scheduler Integration', () => { it('should create job with validation', async () => { // Mock file system const testDir = createTestDirectory(); mockSchedulerEnvironment(testDir); // Create scheduler const scheduler = new Scheduler(); // Create job (validation happens automatically) const job = await scheduler.createJob({ name: 'Test Job', schedule: 'every day at 9am', tool: 'test:tool', parameters: {} }); expect(job.id).toBeDefined(); expect(job.cronExpression).toBe('0 9 * * *'); // Cleanup cleanupTestDirectory(testDir); }); }); ``` **Run:** ```bash npm test -- test/scheduler/scheduler-integration.test.ts ``` --- ## Manual Testing ### **1. Test Job Creation** ```bash # Create a test job ncp schedule create scheduler:validate "in 2 minutes" \ --name "Test Validation Job" \ --params '{"tool": "schedule", "arguments": {"name": "test"}}' \ --fire-once # Verify it was created ncp schedule list # Check crontab (Unix/Linux/macOS only) crontab -l | grep NCP ``` **Expected Output:** ``` # === NCP SCHEDULED JOBS - DO NOT EDIT MANUALLY === # NCP_JOB: <job-id> 42 14 20 1 * ncp _job-run <job-id> # === END NCP SCHEDULED JOBS === ``` --- ### **2. Test Job Execution** ```bash # Create a job that runs in 1 minute ncp schedule create scheduler:validate "in 1 minute" \ --name "Quick Test" \ --params '{"tool": "schedule", "arguments": {}}' \ --fire-once # Wait 1-2 minutes... # Check execution history ncp schedule executions --job-id "Quick Test" ``` **Expected Output:** ``` ✅ Quick Test ID: exec-abc-123 Time: 1/20/2025, 2:42:00 PM Duration: 234ms ``` --- ### **3. Test Validation** ```bash # This should FAIL validation (missing required param) ncp schedule create scheduler:schedule "every day at 9am" \ --name "Bad Job" \ --params '{}' # Expected error: # ❌ Tool validation failed: # Missing required parameter: name # Missing required parameter: schedule # Missing required parameter: tool # Missing required parameter: parameters ``` --- ### **4. Test Natural Language Parsing** ```bash # Test various schedule formats ncp schedule create scheduler:validate "every weekday at 2:30pm" \ --name "Weekday Test" \ --params '{"tool": "schedule", "arguments": {}}' \ --test-run # Check the cron expression ncp schedule get "Weekday Test" # Should show: 30 14 * * 1-5 ``` --- ## End-to-End Testing **⚠️ WARNING:** These tests modify your system crontab. Run in isolated environment! ### **Setup Test Environment** ```bash # Create isolated test user (Linux) sudo useradd -m ncptest sudo su - ncptest # Or use Docker docker run -it --rm node:18 bash npm install -g ncp # Install NCP ``` --- ### **E2E Test 1: Simple Job** ```bash # Create a simple job ncp schedule create scheduler:validate "*/5 * * * *" \ --name "Five Minute Test" \ --params '{"tool": "schedule", "arguments": {}}' \ --max-executions 3 # Wait 15 minutes for 3 executions # Check executions ncp schedule executions --job-id "Five Minute Test" # Should show 3 successful executions # Job should be marked as "completed" ncp schedule get "Five Minute Test" ``` --- ### **E2E Test 2: Error Handling** ```bash # Create job with invalid tool (should fail validation) ncp schedule create nonexistent:tool "every day at 9am" \ --name "Bad Tool" \ --params '{}' # Should fail with validation error ``` --- ### **E2E Test 3: Cleanup** ```bash # Create multiple jobs for i in {1..5}; do ncp schedule create scheduler:validate "every day at ${i}am" \ --name "Test Job $i" \ --params '{"tool": "schedule", "arguments": {}}' done # Generate some executions (run jobs manually) for i in {1..5}; do JOB_ID=$(ncp schedule list | grep "Test Job $i" | awk '{print $4}') ncp _job-run $JOB_ID done # Run cleanup ncp schedule cleanup --max-per-job 2 # Verify old executions were deleted ncp schedule executions ``` --- ## Testing Validation Protocol ### **Test MCP-Native Validation** ```bash # The scheduler MCP implements tools/validate # Test it through the MCP interface: # 1. Via CLI (calls MCP internally) ncp schedule create scheduler:schedule "every day" \ --name "Validation Test" \ --params '{"name": "test"}' # Missing required params # Should show validation errors # 2. Via run command (test validate tool directly) ncp run scheduler:validate --params '{ "tool": "schedule", "arguments": { "name": "test", "schedule": "invalid cron", "tool": "filesystem:backup", "parameters": {} } }' # Should return validation errors in JSON format ``` --- ## CI/CD Testing ### **GitHub Actions Example** ```yaml name: Scheduler Tests on: [push, pull_request] jobs: test: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest] # Skip Windows since cron not supported steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' - name: Install dependencies run: npm ci - name: Run unit tests run: npm test -- test/scheduler - name: Run integration tests run: npm test -- test/scheduler/scheduler-integration.test.ts # E2E tests only on Linux (safe cron manipulation) - name: Run E2E tests if: matrix.os == 'ubuntu-latest' run: npm test -- test/scheduler/e2e ``` --- ## Test Coverage ### **Check Coverage** ```bash npm test -- --coverage test/scheduler ``` **Target Coverage:** - JobManager: 90%+ - ExecutionRecorder: 85%+ - NaturalLanguageParser: 95%+ - CronManager (validation): 90%+ - ToolValidator: 85%+ - Scheduler: 80%+ --- ## Debugging Tests ### **Enable Debug Logging** ```bash # Set debug env var export NCP_DEBUG=true # Run tests npm test -- test/scheduler/job-manager.test.ts # Debug logs will show file paths, operations, etc. ``` --- ### **Inspect Test Artifacts** ```bash # Tests create temp directories, find them: ls /tmp/ncp-scheduler-test-* # Inspect test data cat /tmp/ncp-scheduler-test-*/scheduler/jobs.json cat /tmp/ncp-scheduler-test-*/scheduler/executions/summary.csv ``` --- ## Common Test Failures ### **1. "crontab command not found"** **Cause:** Testing on Windows or system without cron **Solution:** Tests should skip on Windows automatically ```typescript if (process.platform === 'win32') { console.log('Skipping cron test on Windows'); return; } ``` --- ### **2. "Permission denied" on crontab** **Cause:** User doesn't have crontab permissions **Solution:** Run in Docker or add user to cron group ```bash sudo usermod -a -G cron $USER ``` --- ### **3. Test directories not cleaned up** **Cause:** Test interrupted before cleanup **Solution:** Manual cleanup ```bash rm -rf /tmp/ncp-scheduler-test-* ``` --- ## Best Practices 1. **Isolate Tests:** Use temp directories, don't touch real crontab 2. **Mock External Deps:** Mock MCPs, file system, cron when possible 3. **Test Edge Cases:** Empty params, invalid cron, duplicate names 4. **Test Error Paths:** Validation failures, missing files, bad permissions 5. **Clean Up:** Always cleanup test artifacts in `afterEach` 6. **Platform Checks:** Skip Windows-specific tests gracefully 7. **Time Independence:** Don't depend on current time for assertions --- ## Summary ### **Quick Test Commands** ```bash # All tests npm test # Unit tests only npm test -- test/scheduler/*.test.ts # Integration tests npm test -- test/scheduler/*-integration.test.ts # Watch mode for development npm test -- --watch test/scheduler # Coverage report npm test -- --coverage test/scheduler ``` ### **Manual Test Workflow** ```bash # 1. Create test job ncp schedule create scheduler:validate "in 2 minutes" \ --name "Test" --params '{"tool":"schedule","arguments":{}}' --fire-once # 2. Verify in crontab crontab -l | grep NCP # 3. Wait for execution # 4. Check results ncp schedule executions --job-id "Test" # 5. Cleanup ncp schedule delete "Test" -y ``` --- **Remember:** Always test in isolated environments for E2E tests that touch system crontab!

Latest Blog Posts

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/portel-dev/ncp'

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