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