
Audio System Enhancements: - Complete PipeWire configuration with WirePlumber session management - AI-powered noise suppression using RNNoise plugin - GUI applications: EasyEffects, pavucontrol, Helvum, qpwgraph, pwvucontrol - Pre-configured audio presets for microphone noise suppression - Desktop integration with auto-start and helper scripts - Validation tools and interactive audio management utilities - Real-time audio processing with RTKit optimization - Cross-application compatibility (Discord, Zoom, OBS, etc.) MCP (Model Context Protocol) Implementation in Guile Scheme: - Modular MCP server architecture with clean separation of concerns - JSON-RPC transport layer with WebSocket and stdio support - Protocol compliance with MCP specification - Comprehensive error handling and validation - Router system for tool and resource management - Integration layer for NixOS Home Lab management - Full test suite with unit and integration tests - Documentation and usage examples Technical Details: - Removed conflicting ALSA udev rules while maintaining compatibility - Fixed package dependencies and service configurations - Successfully deployed and tested on congenital-optimist machine - Functional programming approach using Guile Scheme modules - Type-safe protocol implementation with validation - Async/await pattern support for concurrent operations This represents a significant enhancement to the Home Lab infrastructure, providing both professional-grade audio capabilities and a robust MCP server implementation for AI assistant integration.
189 lines
6.9 KiB
Scheme
189 lines
6.9 KiB
Scheme
;; Unit Tests for JSON-RPC 2.0 Module
|
|
;; Tests the foundational JSON-RPC protocol implementation
|
|
|
|
(define-module (tests jsonrpc-tests)
|
|
#:use-module (srfi srfi-64)
|
|
#:use-module (json)
|
|
#:use-module (mcp server jsonrpc)
|
|
#:export (run-jsonrpc-tests))
|
|
|
|
(define (run-jsonrpc-tests)
|
|
"Run all JSON-RPC module tests"
|
|
(test-begin "JSON-RPC Tests")
|
|
|
|
;; Test JSON-RPC request parsing
|
|
(test-group "Request Parsing"
|
|
(test-jsonrpc-request-parsing))
|
|
|
|
;; Test JSON-RPC response creation
|
|
(test-group "Response Creation"
|
|
(test-jsonrpc-response-creation))
|
|
|
|
;; Test JSON-RPC error handling
|
|
(test-group "Error Handling"
|
|
(test-jsonrpc-error-handling))
|
|
|
|
;; Test JSON-RPC notifications
|
|
(test-group "Notifications"
|
|
(test-jsonrpc-notifications))
|
|
|
|
;; Test batch requests
|
|
(test-group "Batch Requests"
|
|
(test-jsonrpc-batch-requests))
|
|
|
|
;; Test message validation
|
|
(test-group "Message Validation"
|
|
(test-jsonrpc-validation))
|
|
|
|
(test-end "JSON-RPC Tests"))
|
|
|
|
(define (test-jsonrpc-request-parsing)
|
|
"Test JSON-RPC request parsing functionality"
|
|
|
|
;; Test valid request parsing
|
|
(test-assert "Parse valid JSON-RPC request"
|
|
(let* ((json-request "{\"jsonrpc\":\"2.0\",\"method\":\"test\",\"params\":{\"foo\":\"bar\"},\"id\":1}")
|
|
(parsed (parse-jsonrpc-message json-request)))
|
|
(and (jsonrpc-request? parsed)
|
|
(equal? (jsonrpc-request-method parsed) "test")
|
|
(equal? (jsonrpc-request-id parsed) 1))))
|
|
|
|
;; Test request without params
|
|
(test-assert "Parse request without params"
|
|
(let* ((json-request "{\"jsonrpc\":\"2.0\",\"method\":\"test\",\"id\":1}")
|
|
(parsed (parse-jsonrpc-message json-request)))
|
|
(and (jsonrpc-request? parsed)
|
|
(equal? (jsonrpc-request-method parsed) "test")
|
|
(equal? (jsonrpc-request-params parsed) #f))))
|
|
|
|
;; Test request with string ID
|
|
(test-assert "Parse request with string ID"
|
|
(let* ((json-request "{\"jsonrpc\":\"2.0\",\"method\":\"test\",\"id\":\"abc123\"}")
|
|
(parsed (parse-jsonrpc-message json-request)))
|
|
(and (jsonrpc-request? parsed)
|
|
(equal? (jsonrpc-request-id parsed) "abc123"))))
|
|
|
|
;; Test invalid version
|
|
(test-assert "Reject invalid JSON-RPC version"
|
|
(let* ((json-request "{\"jsonrpc\":\"1.0\",\"method\":\"test\",\"id\":1}")
|
|
(parsed (parse-jsonrpc-message json-request)))
|
|
(jsonrpc-error? parsed))))
|
|
|
|
(define (test-jsonrpc-response-creation)
|
|
"Test JSON-RPC response creation functionality"
|
|
|
|
;; Test successful response
|
|
(test-assert "Create successful response"
|
|
(let ((response (make-jsonrpc-response 1 "result-data")))
|
|
(and (jsonrpc-response? response)
|
|
(equal? (jsonrpc-response-id response) 1)
|
|
(equal? (jsonrpc-response-result response) "result-data"))))
|
|
|
|
;; Test response serialization
|
|
(test-assert "Serialize response to JSON"
|
|
(let* ((response (make-jsonrpc-response 1 "test-result"))
|
|
(json-str (jsonrpc-message->json response))
|
|
(parsed (json-string->scm json-str)))
|
|
(and (list? parsed)
|
|
(equal? (assoc-ref parsed "jsonrpc") "2.0")
|
|
(equal? (assoc-ref parsed "id") 1)
|
|
(equal? (assoc-ref parsed "result") "test-result")))))
|
|
|
|
(define (test-jsonrpc-error-handling)
|
|
"Test JSON-RPC error handling functionality"
|
|
|
|
;; Test error creation
|
|
(test-assert "Create JSON-RPC error"
|
|
(let ((error (make-jsonrpc-error 1 -32600 "Invalid Request" #f)))
|
|
(and (jsonrpc-error? error)
|
|
(equal? (jsonrpc-error-id error) 1)
|
|
(equal? (jsonrpc-error-code error) -32600)
|
|
(equal? (jsonrpc-error-message error) "Invalid Request"))))
|
|
|
|
;; Test parse error handling
|
|
(test-assert "Handle parse error"
|
|
(let ((parsed (parse-jsonrpc-message "invalid json")))
|
|
(and (jsonrpc-error? parsed)
|
|
(equal? (jsonrpc-error-code parsed) -32700))))
|
|
|
|
;; Test error with data
|
|
(test-assert "Create error with additional data"
|
|
(let ((error (make-jsonrpc-error 1 -32603 "Internal error" '("extra" "data"))))
|
|
(and (jsonrpc-error? error)
|
|
(equal? (jsonrpc-error-data error) '("extra" "data"))))))
|
|
|
|
(define (test-jsonrpc-notifications)
|
|
"Test JSON-RPC notification functionality"
|
|
|
|
;; Test notification parsing
|
|
(test-assert "Parse JSON-RPC notification"
|
|
(let* ((json-notif "{\"jsonrpc\":\"2.0\",\"method\":\"notify\",\"params\":{\"data\":\"value\"}}")
|
|
(parsed (parse-jsonrpc-message json-notif)))
|
|
(and (jsonrpc-notification? parsed)
|
|
(equal? (jsonrpc-notification-method parsed) "notify"))))
|
|
|
|
;; Test notification without params
|
|
(test-assert "Parse notification without params"
|
|
(let* ((json-notif "{\"jsonrpc\":\"2.0\",\"method\":\"notify\"}")
|
|
(parsed (parse-jsonrpc-message json-notif)))
|
|
(and (jsonrpc-notification? parsed)
|
|
(equal? (jsonrpc-notification-params parsed) #f)))))
|
|
|
|
(define (test-jsonrpc-batch-requests)
|
|
"Test JSON-RPC batch request functionality"
|
|
|
|
;; Test batch parsing
|
|
(test-assert "Parse batch requests"
|
|
(let* ((batch-msgs '("{\"jsonrpc\":\"2.0\",\"method\":\"test1\",\"id\":1}"
|
|
"{\"jsonrpc\":\"2.0\",\"method\":\"test2\",\"id\":2}"))
|
|
(results (handle-jsonrpc-batch batch-msgs)))
|
|
(and (list? results)
|
|
(= (length results) 2)
|
|
(jsonrpc-request? (car results))
|
|
(jsonrpc-request? (cadr results))
|
|
(equal? (jsonrpc-request-method (car results)) "test1")
|
|
(equal? (jsonrpc-request-method (cadr results)) "test2"))))
|
|
|
|
;; Test empty batch error
|
|
(test-assert "Reject empty batch"
|
|
(let ((result (handle-jsonrpc-batch '())))
|
|
(and (list? result)
|
|
(= (length result) 1)
|
|
(jsonrpc-error? (car result))))))
|
|
|
|
(define (test-jsonrpc-validation)
|
|
"Test JSON-RPC message validation"
|
|
|
|
;; Test valid message validation
|
|
(test-assert "Validate correct message structure"
|
|
(let* ((json-request "{\"jsonrpc\":\"2.0\",\"method\":\"test\",\"id\":1}")
|
|
(parsed (parse-jsonrpc-message json-request)))
|
|
(jsonrpc-request? parsed)))
|
|
|
|
;; Test invalid method name
|
|
(test-assert "Reject invalid method names"
|
|
(let* ((json-request "{\"jsonrpc\":\"2.0\",\"method\":\"rpc.invalid\",\"id\":1}")
|
|
(parsed (parse-jsonrpc-message json-request)))
|
|
(jsonrpc-error? parsed)))
|
|
|
|
;; Test missing required fields
|
|
(test-assert "Reject missing jsonrpc field"
|
|
(let* ((json-request "{\"method\":\"test\",\"id\":1}")
|
|
(parsed (parse-jsonrpc-message json-request)))
|
|
(jsonrpc-error? parsed))))
|
|
|
|
;; Helper functions for testing
|
|
(define (create-test-request method params id)
|
|
"Create a test JSON-RPC request"
|
|
(scm->json-string
|
|
`(("jsonrpc" . "2.0")
|
|
("method" . ,method)
|
|
,@(if params `(("params" . ,params)) '())
|
|
("id" . ,id))))
|
|
|
|
(define (create-test-notification method params)
|
|
"Create a test JSON-RPC notification"
|
|
(scm->json-string
|
|
`(("jsonrpc" . "2.0")
|
|
("method" . ,method)
|
|
,@(if params `(("params" . ,params)) '()))))
|