initial commit
This commit is contained in:
243
src/runner_test.v
Normal file
243
src/runner_test.v
Normal file
@@ -0,0 +1,243 @@
|
||||
module runner
|
||||
|
||||
import freeflowuniverse.herolib.core.redisclient
|
||||
import freeflowuniverse.herolib.core.playbook {PlayBook}
|
||||
import freeflowuniverse.herolib.baobab.engine { Engine, Context }
|
||||
|
||||
__global (
|
||||
entries shared map[string]string
|
||||
)
|
||||
|
||||
// Mock actor implementation for testing
|
||||
struct TestActor implements Actor {
|
||||
pub:
|
||||
name string = 'test_actor'
|
||||
pub mut:
|
||||
redis_conn redisclient.Redis
|
||||
}
|
||||
|
||||
// Implement the Actor interface
|
||||
pub fn (mut actor TestActor) process_job(j job.Job) ! {
|
||||
mut redis_conn := actor.redis_conn()!
|
||||
// Update job status to started
|
||||
job.update_status(mut redis_conn, j.id, .started) or {
|
||||
return error('Failed to update job status to started: ${err}')
|
||||
}
|
||||
|
||||
// Run the job using the engine
|
||||
result := actor.engine.run_in_context(j.script,
|
||||
db_path: actor.db_path
|
||||
caller_id: j.caller_id
|
||||
context_id: j.context_id
|
||||
) or {
|
||||
// Handle execution error
|
||||
job.update_status(mut redis_conn, j.id, .error)!
|
||||
job.set_error(mut redis_conn, j.id, '${err}')!
|
||||
return err
|
||||
}
|
||||
|
||||
// Update job status to finished and set result
|
||||
job.update_status(mut redis_conn, j.id, .finished) or {
|
||||
return error('Failed to update job status to finished: ${err}')
|
||||
}
|
||||
job.set_result(mut redis_conn, j.id, result) or {
|
||||
return error('Failed to set job result: ${err}')
|
||||
}
|
||||
}
|
||||
|
||||
fn test_actor_interface_defaults() {
|
||||
actor := TestActor{
|
||||
name: 'test_actor'
|
||||
}
|
||||
|
||||
// Test default values from interface
|
||||
assert actor.name == 'test_actor'
|
||||
}
|
||||
|
||||
fn test_actor_queue_key() {
|
||||
actor := TestActor{
|
||||
name: 'test_actor'
|
||||
}
|
||||
|
||||
assert actor.queue_key()! == 'runner:test_actor'
|
||||
}
|
||||
|
||||
// Mock player function for testing
|
||||
fn mock_player(mut plbook PlayBook) ! {
|
||||
// Simple test player that adds some content
|
||||
action := plbook.get(filter:'entry.define')!
|
||||
entries['entry'] = action.params.get!('entry')!
|
||||
}
|
||||
|
||||
|
||||
fn test_actor_run_job() {
|
||||
mut e := Engine{
|
||||
players: []
|
||||
}
|
||||
|
||||
// Register a simple test player
|
||||
e.register_player(mock_player) or { panic('Failed to register player: ${err}') }
|
||||
|
||||
actor := TestActor{
|
||||
id: 'test_runner'
|
||||
db_path: '/tmp/test_run.db'
|
||||
engine: e
|
||||
}
|
||||
|
||||
// Create a test job
|
||||
test_job := job.new(
|
||||
caller_id: 'test_caller',
|
||||
context_id: 'test_context',
|
||||
script: 'test script',
|
||||
script_type: .v
|
||||
)
|
||||
|
||||
// Run the job
|
||||
result := actor.run_job(test_job) or { panic('Failed to run job: ${err}') }
|
||||
|
||||
assert result.len > 0
|
||||
}
|
||||
|
||||
fn test_actor_run_job_with_context() {
|
||||
mut engine := Engine{
|
||||
players: []
|
||||
}
|
||||
|
||||
// Register a player that uses context
|
||||
engine.register_player(fn (mut plbook playbook.PlayBook) ! {
|
||||
// This player might access context variables
|
||||
plbook.add_result('Context-aware execution')
|
||||
}) or { panic('Failed to register context player: ${err}') }
|
||||
|
||||
actor := TestActor{
|
||||
id: 'context_actor'
|
||||
db_path: '/tmp/context_test.db'
|
||||
engine: engine
|
||||
}
|
||||
|
||||
// Create a job with specific context
|
||||
test_job := job.Job{
|
||||
id: 'context_job_1'
|
||||
caller_id: 'context_caller'
|
||||
context_id: 'context_123'
|
||||
script: 'context_script'
|
||||
script_type: .osis
|
||||
status: .dispatched
|
||||
// ... other fields with defaults
|
||||
}
|
||||
|
||||
result := actor.run_job(test_job) or { panic('Failed to run context job: ${err}') }
|
||||
|
||||
assert result.len > 0
|
||||
}
|
||||
|
||||
fn test_actor_process_job_success() {
|
||||
mut e := Engine{
|
||||
players: []
|
||||
}
|
||||
|
||||
// Register a successful player
|
||||
e.register_player(fn (mut plbook playbook.PlayBook) ! {
|
||||
plbook.add_result('Success!')
|
||||
}) or { panic('Failed to register success player: ${err}') }
|
||||
|
||||
actor := TestActor{
|
||||
id: 'success_actor'
|
||||
engine: e
|
||||
}
|
||||
|
||||
// Create test job
|
||||
test_job := job.new_job('success_caller', 'success_context', 'success script', .v)
|
||||
|
||||
// Process the job
|
||||
actor.process_job(test_job) or { panic('Failed to process job: ${err}') }
|
||||
|
||||
// Process the job
|
||||
actor.process_job(test_job, mut mock_redis) or { panic('Failed to process job: ${err}') }
|
||||
|
||||
// Verify Redis operations were called
|
||||
assert mock_redis.operations.len > 0
|
||||
|
||||
// Check that status was updated to started and then finished
|
||||
job_key := 'hero:job:${test_job.id}'
|
||||
assert mock_redis.job_status[job_key] == 'finished'
|
||||
assert mock_redis.job_results[job_key].len > 0
|
||||
}
|
||||
|
||||
fn test_actor_process_job_error() {
|
||||
mut engine := Engine{
|
||||
players: []
|
||||
}
|
||||
|
||||
// Register a failing player
|
||||
engine.register_player(fn (mut plbook playbook.PlayBook) ! {
|
||||
return error('Test error')
|
||||
}) or { panic('Failed to register failing player: ${err}') }
|
||||
|
||||
actor := TestActor{
|
||||
id: 'error_actor'
|
||||
engine: engine
|
||||
}
|
||||
|
||||
// Create test job
|
||||
test_job := job.new_job('error_caller', 'error_context', 'error script', .v)
|
||||
|
||||
// Mock Redis connection
|
||||
mut mock_redis := MockRedisConn{
|
||||
operations: []
|
||||
job_status: map[string]string{}
|
||||
job_results: map[string]string{}
|
||||
job_errors: map[string]string{}
|
||||
}
|
||||
|
||||
// Process the job (should handle error gracefully)
|
||||
if result := actor.process_job(test_job, mut mock_redis) {
|
||||
panic('Expected job processing to fail')
|
||||
}
|
||||
|
||||
// Verify error was recorded
|
||||
job_key := 'hero:job:${test_job.id}'
|
||||
assert mock_redis.job_status[job_key] == 'error'
|
||||
assert mock_redis.job_errors[job_key].len > 0
|
||||
}
|
||||
|
||||
fn test_multiple_actors() {
|
||||
mut engine1 := Engine{ players: [] }
|
||||
mut engine2 := Engine{ players: [] }
|
||||
|
||||
engine1.register_player(fn (mut plbook playbook.PlayBook) ! {
|
||||
plbook.add_result('Actor 1 result')
|
||||
}) or { panic('Failed to register player 1: ${err}') }
|
||||
|
||||
engine2.register_player(fn (mut plbook playbook.PlayBook) ! {
|
||||
plbook.add_result('Actor 2 result')
|
||||
}) or { panic('Failed to register player 2: ${err}') }
|
||||
|
||||
actor1 := TestActor{
|
||||
id: 'actor_1'
|
||||
engine: engine1
|
||||
}
|
||||
|
||||
actor2 := TestActor{
|
||||
id: 'actor_2'
|
||||
engine: engine2
|
||||
}
|
||||
|
||||
// Test that actors have different queue keys
|
||||
queue1 := actor1.queue_key() or { panic('Failed to get queue key 1: ${err}') }
|
||||
queue2 := actor2.queue_key() or { panic('Failed to get queue key 2: ${err}') }
|
||||
|
||||
assert queue1 != queue2
|
||||
assert queue1.contains('actor_1')
|
||||
assert queue2.contains('actor_2')
|
||||
|
||||
// Test that actors can run jobs independently
|
||||
job1 := job.new_job('caller1', 'context1', 'script1', .v)
|
||||
job2 := job.new_job('caller2', 'context2', 'script2', .osis)
|
||||
|
||||
result1 := actor1.run_job(job1) or { panic('Failed to run job 1: ${err}') }
|
||||
result2 := actor2.run_job(job2) or { panic('Failed to run job 2: ${err}') }
|
||||
|
||||
assert result1.len > 0
|
||||
assert result2.len > 0
|
||||
}
|
Reference in New Issue
Block a user