From 231893a794bbf64d15d5f8af100767defe8fb5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 10 Mar 2022 19:31:36 +0100 Subject: [PATCH] feat: shed: ItestD --- cmd/lotus-shed/itestd.go | 104 +++++++++++++++++++++++++++++++++++++++ cmd/lotus-shed/main.go | 1 + itests/kit/itestd.go | 36 ++++++++++++++ itests/kit/rpc.go | 2 + 4 files changed, 143 insertions(+) create mode 100644 cmd/lotus-shed/itestd.go create mode 100644 itests/kit/itestd.go diff --git a/cmd/lotus-shed/itestd.go b/cmd/lotus-shed/itestd.go new file mode 100644 index 00000000000..3ac542d2728 --- /dev/null +++ b/cmd/lotus-shed/itestd.go @@ -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") + } + } + }, +} diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index 45fd24e18a6..c1facfe7b94 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -69,6 +69,7 @@ func main() { terminationsCmd, migrationsCmd, diffCmd, + itestdCmd, } app := &cli.App{ diff --git a/itests/kit/itestd.go b/itests/kit/itestd.go new file mode 100644 index 00000000000..5911a20310c --- /dev/null +++ b/itests/kit/itestd.go @@ -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 + } +} diff --git a/itests/kit/rpc.go b/itests/kit/rpc.go index 61c8a7b2330..1abab8005c6 100644 --- a/itests/kit/rpc.go +++ b/itests/kit/rpc.go @@ -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)