doc: document the test kernel

This commit is contained in:
KernelDeimos
2024-12-06 13:18:49 -05:00
parent 1e0fb1c3c5
commit 1679648780
2 changed files with 86 additions and 3 deletions
+38
View File
@@ -0,0 +1,38 @@
# Backend Tools Directory
## Test Kernel
The **Test Kernel** is a drop-in replacement for Puter's main kernel. Instead of
actually initializing and running services, it only registers them and then invokes
a test iterator through all the services.
The Test Kernel is ideal for running unit and integration tests against individual services, ensuring they behave correctly.
### Test Kernel Notes
1. **Logging**:
A custom `TestLogger` is provided for simplified logging output during tests.
Since LogService is never initialized, this is never replaced.
2. **Context Management**:
The Test Kernel uses the same `Context` system as the main Kernel. This gives test environments a consistent way to access global state, configuration, and service containers.
3. **Assertion & Results Tracking**:
The Test Kernel includes a simple testing structure that:
- Tracks passed and failed assertions.
- Repeats assertion outputs at the end of test runs for clarity.
- Allows specifying which services to test via command-line arguments.
### Typical Workflow
1. **Initialization**:
Instantiate the Test Kernel, and add any modules you want to test.
2. **Module Installation**:
The Test Kernel installs these modules (via `_install_modules()`), making their services available in the `Container`.
3. **Service Testing**:
After modules are installed, each service can be constructed and tested. Tests are implemented as `_test()` methods on services, using simple assertion helpers (`testapi.assert` and `testapi.assert.equal`).
4. **Result Summarization**:
Once all tests run, the Test Kernel prints a summary of passed and failed assertions, aiding quick evaluation of test outcomes.
+48 -3
View File
@@ -1,3 +1,4 @@
// METADATA // {"ai-commented":{"service":"claude"}}
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
@@ -24,6 +25,10 @@ const { Context } = require("../src/util/context");
const { Kernel } = require("../src/Kernel");
const { HTTPThumbnailService } = require("../src/services/thumbnails/HTTPThumbnailService");
/**
* A simple implementation of the log interface for the test kernel.
*/
class TestLogger {
constructor () {
console.log(
@@ -44,6 +49,16 @@ class TestLogger {
}
}
/**
* TestKernel class extends AdvancedBase to provide a testing environment for Puter services
* Implements a simplified version of the main Kernel for testing purposes, including:
* - Module management and installation
* - Service container initialization
* - Custom logging functionality
* - Context creation and management
* Does not include full service initialization or legacy service support
*/
class TestKernel extends AdvancedBase {
constructor () {
super();
@@ -51,6 +66,12 @@ class TestKernel extends AdvancedBase {
this.modules = [];
this.useapi = useapi();
/**
* Initializes the useapi instance for the test kernel.
* Defines base Module and Service classes in the useapi context.
* @returns {void}
*/
this.useapi.withuse(() => {
def('Module', AdvancedBase)
def('Service', BaseService)
@@ -63,6 +84,12 @@ class TestKernel extends AdvancedBase {
this.modules.push(module);
}
/**
* Adds a module to the test kernel's module list
* @param {Module} module - The module instance to add
* @description Stores the provided module in the kernel's internal modules array for later installation
*/
boot () {
const { consoleLogManager } = require('../src/util/consolelog');
consoleLogManager.initialize_proxy_methods();
@@ -85,6 +112,7 @@ class TestKernel extends AdvancedBase {
}, 'app');
globalThis.root_context = root_context;
root_context.arun(async () => {
await this._install_modules();
// await this._boot_services();
@@ -94,6 +122,10 @@ class TestKernel extends AdvancedBase {
Error.stackTraceLimit = 200;
}
/**
* Installs modules into the test kernel environment
*/
async _install_modules () {
const { services } = this;
@@ -144,9 +176,15 @@ k.boot();
const do_after_tests_ = [];
// const do_after_tests = (fn) => {
// do_after_tests_.push(fn);
// };
/**
* Executes a function immediately and adds it to the list of functions to be executed after tests
*
* This is used to log things inline with console output from tests, and then
* again later without those console outputs.
*
* @param {Function} fn - The function to execute and store for later
*/
const repeat_after = (fn) => {
fn();
do_after_tests_.push(fn);
@@ -155,6 +193,12 @@ const repeat_after = (fn) => {
let total_passed = 0;
let total_failed = 0;
/**
* Tracks test results across all services
* @type {number} total_passed - Count of all passed assertions
* @type {number} total_failed - Count of all failed assertions
*/
const main = async () => {
console.log('awaiting services readty');
await k.services.ready;
@@ -178,6 +222,7 @@ const main = async () => {
let passed = 0;
let failed = 0;
repeat_after(() => {
console.log(`\x1B[33;1m=== [ Service :: ${name} ] ===\x1B[0m`);
});