Solo para leer y verificar. No puedes copiar, usar, modificar ni redistribuir este código. Aviso completo en la página principal.
tunnel/nodeproc_test.go
| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "bufio" |
| 5 | "bytes" |
| 6 | "crypto/ed25519" |
| 7 | "crypto/rand" |
| 8 | "crypto/x509" |
| 9 | "encoding/json" |
| 10 | "os" |
| 11 | "os/exec" |
| 12 | "path/filepath" |
| 13 | "testing" |
| 14 | "time" |
| 15 | ) |
| 16 | |
| 17 | // nodeProc is the test-node binary running as a process, with a device the fake control plane knows. |
| 18 | type nodeProc struct { |
| 19 | e *testEnv |
| 20 | d *testDevice |
| 21 | cmd *exec.Cmd |
| 22 | exited chan error |
| 23 | logs *syncBuf |
| 24 | control string |
| 25 | feed string |
| 26 | ready map[string]any // the node's ready line |
| 27 | } |
| 28 | |
| 29 | // launchTestNode starts the test node with one paid device (valid for validFor seconds) and the extra flags, and waits for its ready line. |
| 30 | func launchTestNode(t *testing.T, validFor int, extra ...string) *nodeProc { |
| 31 | t.Helper() |
| 32 | bin := testNodeBinary(t) |
| 33 | dir := t.TempDir() |
| 34 | pub, priv, _ := ed25519.GenerateKey(rand.Reader) |
| 35 | jwks, control, certOut := filepath.Join(dir, "jwks.json"), filepath.Join(dir, "control.json"), filepath.Join(dir, "node.pem") |
| 36 | jwksFile(t, jwks, testKID, pub) |
| 37 | e := &testEnv{t: t, cpKey: priv, tapByID: map[string]*bytes.Buffer{}} |
| 38 | e.srv = &Server{nodeURL: nodeProofURL(testNodeHost, 443)} |
| 39 | d := e.newDeviceNoPlan() |
| 40 | writeControl(t, control, map[string]any{d.id: map[string]any{"host": d.host, "status": "active", "plan": "paid", "valid_for_s": validFor}}) |
| 41 | args := append([]string{"-https-addr", "127.0.0.1:0", "-http-addr", "127.0.0.1:0", "-node-id", testNodeID, "-node-host", testNodeHost, |
| 42 | "-test-jwks", jwks, "-test-control", control, "-test-cert-out", certOut, "-log-level", "info"}, extra...) |
| 43 | cmd := exec.Command(bin, args...) |
| 44 | stdout, _ := cmd.StdoutPipe() |
| 45 | p := &nodeProc{e: e, d: d, cmd: cmd, exited: make(chan error, 1), logs: &syncBuf{}, control: control} |
| 46 | cmd.Stderr = p.logs |
| 47 | if err := cmd.Start(); err != nil { |
| 48 | t.Fatal(err) |
| 49 | } |
| 50 | go func() { p.exited <- cmd.Wait() }() |
| 51 | t.Cleanup(func() { _ = cmd.Process.Kill() }) |
| 52 | ready := make(chan map[string]any, 1) |
| 53 | go func() { |
| 54 | line, _ := bufio.NewReader(stdout).ReadString('\n') |
| 55 | var m map[string]any |
| 56 | if json.Unmarshal([]byte(line), &m) == nil { |
| 57 | ready <- m |
| 58 | } |
| 59 | }() |
| 60 | select { |
| 61 | case info := <-ready: |
| 62 | e.httpsAddr = info["https"].(string) |
| 63 | p.ready = info |
| 64 | case <-time.After(20 * time.Second): |
| 65 | t.Fatalf("the test node did not announce itself:\n%s", p.logs.String()) |
| 66 | } |
| 67 | certPEM, err := os.ReadFile(certOut) |
| 68 | if err != nil { |
| 69 | t.Fatal(err) |
| 70 | } |
| 71 | e.nodePool = x509.NewCertPool() |
| 72 | e.nodePool.AppendCertsFromPEM(certPEM) |
| 73 | return p |
| 74 | } |