package testing
import (
"context"
"errors"
"os"
"strings"
"testing"
"time"
"github.com/gdamore/tcell/v2"
"github.com/pancsta/asyncmachine-go/internal/testing/utils"
amhelp "github.com/pancsta/asyncmachine-go/pkg/helpers"
amhelpt "github.com/pancsta/asyncmachine-go/pkg/helpers/testing"
am "github.com/pancsta/asyncmachine-go/pkg/machine"
"github.com/pancsta/asyncmachine-go/pkg/rpc"
ssrpc "github.com/pancsta/asyncmachine-go/pkg/rpc/states"
"github.com/pancsta/asyncmachine-go/pkg/telemetry"
"github.com/pancsta/asyncmachine-go/tools/debugger"
"github.com/pancsta/asyncmachine-go/tools/debugger/server"
ssdbg "github.com/pancsta/asyncmachine-go/tools/debugger/states"
"github.com/pancsta/asyncmachine-go/tools/debugger/types"
)
var (
WorkerRpcAddr = "localhost:53480"
WorkerTelemetryAddr = "localhost:53470"
EnvAmDbgWorkerRpcAddr = "AM_DBG_WORKER_RPC_ADDR"
EnvAmDbgWorkerTelemetryAddr = "AM_DBG_WORKER_TELEMETRY_ADDR"
)
func NewRpcTest (
t *testing .T , ctx context .Context , netSrc *am .Machine ,
consumer *am .Machine ,
) (*am .Machine , *rpc .Server , *rpc .Client ) {
utils .ConnInit .Lock ()
defer utils .ConnInit .Unlock ()
amDbgAddr := os .Getenv (telemetry .EnvAmDbgAddr )
stdout := os .Getenv (am .EnvAmDebug ) == "2"
logLvl := am .EnvLogLevel ("" )
listener := utils .RandListener ("localhost" )
addr := listener .Addr ().String ()
if netSrc == nil {
t .Fatal ("worker is nil" )
}
s , err := rpc .NewServer (ctx , addr , t .Name (), netSrc , &rpc .ServerOpts {
Parent : netSrc ,
})
if err != nil {
t .Fatal (err )
}
s .Listener .Store (&listener )
amhelpt .MachDebug (t , s .Mach , amDbgAddr , logLvl , stdout )
time .Sleep (10 * time .Millisecond )
c , err := rpc .NewClient (ctx , addr , t .Name (), netSrc .Schema (), &rpc .ClientOpts {
Consumer : consumer ,
Parent : netSrc ,
})
if err != nil {
t .Fatal (err )
}
amhelpt .MachDebug (t , c .Mach , amDbgAddr , logLvl , stdout )
t .Cleanup (func () {
<-s .Mach .WhenDisposed ()
<-c .Mach .WhenDisposed ()
if amDbgAddr != "" {
time .Sleep (100 * time .Millisecond )
}
})
timeout := 3 * time .Second
if amhelp .IsDebug () {
timeout = 100 * time .Second
}
s .Start ()
amhelpt .WaitForErrAll (t , "server RpcReady" , ctx , s .Mach , timeout ,
s .Mach .When1 (ssrpc .ServerStates .RpcReady , nil ))
amhelpt .WaitForErrAll (t , "client Ready" , ctx , s .Mach , timeout ,
c .Mach .When1 (ssrpc .ClientStates .Ready , nil ))
amhelpt .WaitForErrAll (t , "server Ready" , ctx , s .Mach , timeout ,
s .Mach .When1 (ssrpc .ServerStates .Ready , nil ))
return netSrc , s , c
}
func NewDbgWorker (
realTty bool , opts debugger .Opts ,
) (*debugger .Debugger , error ) {
var screen tcell .Screen
if !realTty {
screen = tcell .NewSimulationScreen ("utf8" )
screen .SetSize (100 , 50 )
_ = screen .Init ()
screen .Clear ()
}
if opts .ImportData == "" {
dirPrefix := ""
wd , err := os .Getwd ()
if err != nil {
return nil , err
}
if strings .HasSuffix (wd , "tools/debugger/test" ) {
dirPrefix = "../../../"
}
opts .ImportData = dirPrefix + "tools/debugger/testdata/am-dbg-sim.gob.br"
}
opts .DbgLogLevel = am .EnvLogLevel ("" )
if opts .DbgLogLevel > 0 && os .Getenv (amhelp .EnvAmLogFile ) != "" {
opts .DbgLogger = types .GetLogger (&types .Params {
LogLevel : opts .DbgLogLevel ,
}, "" )
}
if opts .Screen == nil {
opts .Screen = screen
}
if opts .Id == "" {
opts .Id = "rem-worker"
}
opts .SelectConnected = true
dbg , err := debugger .New (context .TODO (), opts )
if err != nil {
return nil , err
}
_ = amhelp .MachDebugEnv (dbg .Mach )
res := dbg .Mach .Add1 (ssdbg .Start , am .A {
"Client.id" : "ps-2" ,
"Client.cursorTx" : 20 ,
})
if res == am .Canceled {
return nil , errors .New ("failed to start am-dbg" )
}
<-dbg .Mach .When1 (ssdbg .Ready , nil )
<-dbg .Mach .WhenNot1 (ssdbg .ScrollToTx , nil )
dbg .Mach .Log ("NewDbgWorker ready" )
return dbg , nil
}
func NewRpcClient (
t *testing .T , ctx context .Context , addr string , netSrcSchema am .Schema ,
consumer *am .Machine ,
) *rpc .Client {
c , err := rpc .NewClient (ctx , addr , t .Name (), netSrcSchema ,
&rpc .ClientOpts {Consumer : consumer })
if err != nil {
t .Fatal (err )
}
amhelpt .MachDebugEnv (t , c .Mach )
t .Cleanup (func () {
<-c .Mach .WhenDisposed ()
if os .Getenv (telemetry .EnvAmDbgAddr ) != "" {
time .Sleep (100 * time .Millisecond )
}
})
timeout := 3 * time .Second
if os .Getenv ("AM_DEBUG" ) != "" {
timeout = 100 * time .Second
}
readyCtx , cancel := context .WithTimeout (ctx , timeout )
defer cancel ()
c .Start ()
select {
case <- c .Mach .WhenErr (readyCtx ):
err := c .Mach .Err ()
if readyCtx .Err () != nil {
err = readyCtx .Err ()
}
t .Fatal (err )
case <- c .Mach .When1 (ssrpc .ClientStates .Ready , readyCtx ):
}
return c
}
func RpcShutdown (ctx context .Context , c *rpc .Client , s *rpc .Server ) {
c .Mach .Remove1 (ssrpc .ClientStates .Start , nil )
if s != nil {
s .Mach .Remove1 (ssrpc .ServerStates .Start , nil )
}
<-c .Mach .When1 (ssrpc .ClientStates .Disconnected , ctx )
}
func RpcGet [G any ](
t *testing .T , c *rpc .Client , name server .GetField , defVal G ,
) G {
panic ("not implemented" )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .