2026-09-02 19:21:30 -07:00
// +build integration
package tests
import (
"context"
"os"
"testing"
"time"
"github.com/rockliang/poimen/workflows/internal/routing"
2026-09-05 23:59:13 -07:00
"github.com/rockliang/poimen/workflows/workflow"
2026-09-02 19:21:30 -07:00
"github.com/stretchr/testify/require"
"go.temporal.io/sdk/client"
)
// TestTemporalRoutingWorkflow tests full flow against real Temporal cluster
// Run with: TEMPORAL_HOSTPORT=temporal.riotpiao.com:7233 RUN_INTEGRATION_TESTS=1 go test -tags=integration -v -run TestTemporalRoutingWorkflow ./tests/...
func TestTemporalRoutingWorkflow ( t * testing . T ) {
if os . Getenv ( "RUN_INTEGRATION_TESTS" ) != "1" {
t . Skip ( "Skipping integration test. Set RUN_INTEGRATION_TESTS=1 to run." )
}
hostPort := os . Getenv ( "TEMPORAL_HOSTPORT" )
if hostPort == "" {
hostPort = "temporal.riotpiao.com:7233"
}
namespace := os . Getenv ( "TEMPORAL_NAMESPACE" )
if namespace == "" {
namespace = "poimen-harness"
}
t . Logf ( "Connecting to Temporal at %s (namespace: %s)" , hostPort , namespace )
// Connect to Temporal
c , err := client . Dial ( client . Options {
HostPort : hostPort ,
Namespace : namespace ,
})
if err != nil {
t . Skipf ( "Skipping - cannot connect to Temporal: %v" , err )
}
defer c . Close ()
t . Log ( "Connected to Temporal successfully" )
// Test 1: Generate spec via LLM and submit
t . Run ( "LLM_Route_And_Submit" , func ( t * testing . T ) {
// Load KB and create router
kb , err := routing . LoadKnowledgeBaseFromDefaultPath ()
require . NoError ( t , err )
router , err := routing . NewLLMRouter ( kb )
require . NoError ( t , err )
// Generate workflow spec
ctx , cancel := context . WithTimeout ( context . Background (), 60 * time . Second )
defer cancel ()
output , err := router . Route ( ctx , routing . LLMRouterInput {
Message : "Clone and analyze https://github.com/rockliang/poimen" ,
})
require . NoError ( t , err )
require . False ( t , output . IsCron )
require . NotNil ( t , output . Spec )
t . Logf ( "Generated spec: %s with %d states" , output . Spec . Name , len ( output . Spec . States ))
// Submit to Temporal
workflowID := "test-routing-" + time . Now (). Format ( "20060102-150405" )
2026-09-05 23:59:13 -07:00
input := workflow . RoutingWorkflowInput { Spec : output . Spec }
2026-09-02 19:21:30 -07:00
run , err := c . ExecuteWorkflow ( ctx , client . StartWorkflowOptions {
ID : workflowID ,
TaskQueue : "poimen-taskqueue" ,
2026-09-05 23:59:13 -07:00
}, workflow . RoutingWorkflow , input )
2026-09-02 19:21:30 -07:00
require . NoError ( t , err )
t . Logf ( "Workflow submitted: ID=%s, RunID=%s" , run . GetID (), run . GetRunID ())
// Check workflow started (don't wait for completion - activities may not be registered)
desc , err := c . DescribeWorkflowExecution ( ctx , workflowID , "" )
require . NoError ( t , err )
t . Logf ( "Workflow status: %s" , desc . WorkflowExecutionInfo . Status . String ())
// Cancel the workflow (since activities may not be running)
err = c . CancelWorkflow ( ctx , workflowID , "" )
if err != nil {
t . Logf ( "Cancel failed (may already be done): %v" , err )
} else {
t . Log ( "Workflow cancelled" )
}
})
// Test 2: Submit simple Pass-only workflow (no activities needed)
t . Run ( "PassOnly_Workflow" , func ( t * testing . T ) {
ctx , cancel := context . WithTimeout ( context . Background (), 30 * time . Second )
defer cancel ()
spec := & routing . WorkflowSpec {
Name : "pass-only-test" ,
Input : map [ string ] interface {}{ "test" : true },
States : [] routing . State {
{
Name : "Step1" ,
Type : routing . StateTypePass ,
Result : map [ string ] interface {}{ "status" : "step1-done" },
Next : "Step2" ,
},
{
Name : "Step2" ,
Type : routing . StateTypePass ,
Result : map [ string ] interface {}{ "status" : "step2-done" , "final" : true },
End : true ,
},
},
}
workflowID := "test-pass-only-" + time . Now (). Format ( "20060102-150405" )
2026-09-05 23:59:13 -07:00
input := workflow . RoutingWorkflowInput { Spec : spec }
2026-09-02 19:21:30 -07:00
run , err := c . ExecuteWorkflow ( ctx , client . StartWorkflowOptions {
ID : workflowID ,
TaskQueue : "poimen-taskqueue" ,
2026-09-05 23:59:13 -07:00
}, workflow . RoutingWorkflow , input )
2026-09-02 19:21:30 -07:00
require . NoError ( t , err )
t . Logf ( "Pass-only workflow submitted: ID=%s" , run . GetID ())
// Wait for result (Pass states don't need workers)
2026-09-05 23:59:13 -07:00
var result workflow . RoutingWorkflowOutput
2026-09-02 19:21:30 -07:00
err = run . Get ( ctx , & result )
require . NoError ( t , err )
t . Logf ( "Workflow result: status=%s" , result . Status )
require . Equal ( t , "COMPLETED" , result . Status )
require . Contains ( t , result . StepResults , "Step1" )
require . Contains ( t , result . StepResults , "Step2" )
})
}