Merge pull request #8290 from filecoin-project/feat/itestd
feat: shed: ItestD
This commit is contained in:
commit
e1ac3f641b
104
cmd/lotus-shed/itestd.go
Normal file
104
cmd/lotus-shed/itestd.go
Normal file
@ -0,0 +1,104 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/chzyer/readline"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/itests/kit"
|
||||
)
|
||||
|
||||
var itestdCmd = &cli.Command{
|
||||
Name: "itestd",
|
||||
Description: "Integration test debug env",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "listen",
|
||||
Value: "127.0.0.1:5674",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
var nodes []kit.ItestdNotif
|
||||
|
||||
m := http.NewServeMux()
|
||||
m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
var notif kit.ItestdNotif
|
||||
if err := json.NewDecoder(r.Body).Decode(¬if); err != nil {
|
||||
fmt.Printf("!! Decode itest notif: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d @%s '%s=%s'\n", len(nodes), notif.TestName, notif.NodeType, notif.Api)
|
||||
nodes = append(nodes, notif)
|
||||
})
|
||||
l, err := net.Listen("tcp", cctx.String("listen"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("net listen: %w", err)
|
||||
}
|
||||
s := &httptest.Server{
|
||||
Listener: l,
|
||||
Config: &http.Server{Handler: m},
|
||||
}
|
||||
s.Start()
|
||||
fmt.Printf("ITest env:\n\nLOTUS_ITESTD=%s\n\nSay 'sh' to spawn a shell connected to test nodes\n--- waiting for clients\n", s.URL)
|
||||
|
||||
cs := readline.NewCancelableStdin(os.Stdin)
|
||||
go func() {
|
||||
<-cctx.Done()
|
||||
cs.Close() // nolint:errcheck
|
||||
}()
|
||||
|
||||
rl := bufio.NewReader(cs)
|
||||
|
||||
for {
|
||||
cmd, _, err := rl.ReadLine()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("readline: %w", err)
|
||||
}
|
||||
|
||||
switch string(cmd) {
|
||||
case "sh":
|
||||
shell := "/bin/sh"
|
||||
if os.Getenv("SHELL") != "" {
|
||||
shell = os.Getenv("SHELL")
|
||||
}
|
||||
|
||||
p := exec.Command(shell, "-i")
|
||||
p.Env = append(p.Env, os.Environ()...)
|
||||
lastNodes := map[string]string{}
|
||||
for _, node := range nodes {
|
||||
lastNodes[node.NodeType] = node.Api
|
||||
}
|
||||
if _, found := lastNodes["MARKETS_API_INFO"]; !found {
|
||||
lastNodes["MARKETS_API_INFO"] = lastNodes["MINER_API_INFO"]
|
||||
}
|
||||
for typ, api := range lastNodes {
|
||||
p.Env = append(p.Env, fmt.Sprintf("%s=%s", typ, api))
|
||||
}
|
||||
|
||||
p.Stdout = os.Stdout
|
||||
p.Stderr = os.Stderr
|
||||
p.Stdin = os.Stdin
|
||||
if err := p.Start(); err != nil {
|
||||
return xerrors.Errorf("start shell: %w", err)
|
||||
}
|
||||
if err := p.Wait(); err != nil {
|
||||
fmt.Printf("wait for shell: %s\n", err)
|
||||
}
|
||||
fmt.Println("\n--- shell quit")
|
||||
|
||||
default:
|
||||
fmt.Println("!! Unknown command")
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
@ -69,6 +69,7 @@ func main() {
|
||||
terminationsCmd,
|
||||
migrationsCmd,
|
||||
diffCmd,
|
||||
itestdCmd,
|
||||
}
|
||||
|
||||
app := &cli.App{
|
||||
|
36
itests/kit/itestd.go
Normal file
36
itests/kit/itestd.go
Normal file
@ -0,0 +1,36 @@
|
||||
package kit
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type ItestdNotif struct {
|
||||
NodeType string // api env var name
|
||||
TestName string
|
||||
Api string
|
||||
}
|
||||
|
||||
func sendItestdNotif(nodeType, testName, apiAddr string) {
|
||||
td := os.Getenv("LOTUS_ITESTD")
|
||||
if td == "" {
|
||||
// not running
|
||||
return
|
||||
}
|
||||
|
||||
notif := ItestdNotif{
|
||||
NodeType: nodeType,
|
||||
TestName: testName,
|
||||
Api: apiAddr,
|
||||
}
|
||||
nb, err := json.Marshal(¬if)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := http.Post(td, "application/json", bytes.NewReader(nb)); err != nil { // nolint:gosec
|
||||
return
|
||||
}
|
||||
}
|
@ -40,6 +40,7 @@ func fullRpc(t *testing.T, f *TestFullNode) *TestFullNode {
|
||||
|
||||
srv, maddr := CreateRPCServer(t, handler, l)
|
||||
fmt.Printf("FULLNODE RPC ENV FOR CLI DEBUGGING `export FULLNODE_API_INFO=%s`\n", "ws://"+srv.Listener.Addr().String())
|
||||
sendItestdNotif("FULLNODE_API_INFO", t.Name(), "ws://"+srv.Listener.Addr().String())
|
||||
|
||||
cl, stop, err := client.NewFullNodeRPCV1(context.Background(), "ws://"+srv.Listener.Addr().String()+"/rpc/v1", nil)
|
||||
require.NoError(t, err)
|
||||
@ -57,6 +58,7 @@ func minerRpc(t *testing.T, m *TestMiner) *TestMiner {
|
||||
|
||||
fmt.Printf("creating RPC server for %s at %s\n", m.ActorAddr, srv.Listener.Addr().String())
|
||||
fmt.Printf("SP RPC ENV FOR CLI DEBUGGING `export MINER_API_INFO=%s`\n", "ws://"+srv.Listener.Addr().String())
|
||||
sendItestdNotif("MINER_API_INFO", t.Name(), "ws://"+srv.Listener.Addr().String())
|
||||
|
||||
url := "ws://" + srv.Listener.Addr().String() + "/rpc/v0"
|
||||
cl, stop, err := client.NewStorageMinerRPCV0(context.Background(), url, nil)
|
||||
|
Loading…
Reference in New Issue
Block a user