github.com/hashicorp/go-plugin@v1.6.0/client_posix_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 //go:build !windows 5 // +build !windows 6 7 package plugin 8 9 import ( 10 "os" 11 "reflect" 12 "syscall" 13 "testing" 14 "time" 15 ) 16 17 func TestClient_testInterfaceReattach(t *testing.T) { 18 // Setup the process for daemonization 19 process := helperProcess("test-interface-daemon") 20 if process.SysProcAttr == nil { 21 process.SysProcAttr = &syscall.SysProcAttr{} 22 } 23 process.SysProcAttr.Setsid = true 24 syscall.Umask(0) 25 26 c := NewClient(&ClientConfig{ 27 Cmd: process, 28 HandshakeConfig: testHandshake, 29 Plugins: testPluginMap, 30 }) 31 32 // Start it so we can get the reattach info 33 if _, err := c.Start(); err != nil { 34 t.Fatalf("err should be nil, got %s", err) 35 } 36 37 // New client with reattach info 38 reattach := c.ReattachConfig() 39 if reattach == nil { 40 c.Kill() 41 t.Fatal("reattach config should be non-nil") 42 } 43 44 // Find the process and defer a kill so we know it is gone 45 p, err := os.FindProcess(reattach.Pid) 46 if err != nil { 47 c.Kill() 48 t.Fatalf("couldn't find process: %s", err) 49 } 50 defer p.Kill() 51 52 // Reattach 53 c = NewClient(&ClientConfig{ 54 Reattach: reattach, 55 HandshakeConfig: testHandshake, 56 Plugins: testPluginMap, 57 }) 58 59 // Start shouldn't error 60 if _, err := c.Start(); err != nil { 61 t.Fatalf("err: %s", err) 62 } 63 64 // It should still be alive 65 time.Sleep(1 * time.Second) 66 if c.Exited() { 67 t.Fatal("should not be exited") 68 } 69 70 // Grab the RPC client 71 client, err := c.Client() 72 if err != nil { 73 t.Fatalf("err should be nil, got %s", err) 74 } 75 76 // Grab the impl 77 raw, err := client.Dispense("test") 78 if err != nil { 79 t.Fatalf("err should be nil, got %s", err) 80 } 81 82 impl, ok := raw.(testInterface) 83 if !ok { 84 t.Fatalf("bad: %#v", raw) 85 } 86 87 result := impl.Double(21) 88 if result != 42 { 89 t.Fatalf("bad: %#v", result) 90 } 91 92 // Test the resulting reattach config 93 reattach2 := c.ReattachConfig() 94 if reattach2 == nil { 95 t.Fatal("reattach from reattached should not be nil") 96 } 97 if !reflect.DeepEqual(reattach, reattach2) { 98 t.Fatalf("bad: %#v", reattach) 99 } 100 101 // Kill it 102 c.Kill() 103 104 // Test that it knows it is exited 105 if !c.Exited() { 106 t.Fatal("should say client has exited") 107 } 108 }