github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/socket_windows_test.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 //go:build windows 5 // +build windows 6 7 package libkb 8 9 import ( 10 "bufio" 11 "errors" 12 "fmt" 13 "os" 14 "os/exec" 15 "path/filepath" 16 "sync" 17 "testing" 18 "time" 19 ) 20 21 func setupTest(t *testing.T, nm string) *TestContext { 22 tc := SetupTest(t, nm, 1) 23 tc.SetRuntimeDir(filepath.Join(tc.Tp.Home, "socket_windows_test")) 24 if err := tc.G.ConfigureSocketInfo(); err != nil { 25 t.Fatal(err) 26 } 27 return &tc 28 } 29 30 // It would be better to test across process boundaries, but this is better 31 // than nothing: across gofuncs. We start a server func, then send it a string, 32 // then synchronize with the server func. 33 // 34 // Another property of named pipes that is NOT tested here is security: 35 // only processes in the same user account are supposed to be able to 36 // open each other's named pipes. 37 func TestWindowsNamedPipe(t *testing.T) { 38 tc := setupTest(t, "socket_windows_test") 39 defer tc.Cleanup() 40 41 listenSocket, err := NewSocket(tc.G) 42 if err != nil { 43 t.Fatal(err) 44 } 45 46 l, err := listenSocket.BindToSocket() 47 if err != nil { 48 t.Fatal(err) 49 } 50 51 // Do the server listening in a separate gofunc, which we synchronize 52 // with later after it has gotten a string 53 var wg sync.WaitGroup 54 wg.Add(1) 55 go func() { 56 defer wg.Done() 57 conn, err := l.Accept() 58 if err != nil { 59 t.Fatal(err) 60 } 61 answer, err := bufio.NewReader(conn).ReadString('\n') 62 if err != nil { 63 t.Fatal(err) 64 } 65 if answer != "Hi server!\n" { 66 t.Fatalf("Bad response over pipe: -%s-", answer) 67 } 68 }() 69 70 sendSocket, err := NewSocket(tc.G) 71 namedPipeClient(sendSocket, t) 72 wg.Wait() 73 } 74 75 // Dial the server over the pipe and send a string 76 func namedPipeClient(sendSocket Socket, t *testing.T) { 77 conn, err := sendSocket.DialSocket() 78 if err != nil { 79 t.Fatal(err) 80 } 81 if _, err := fmt.Fprintln(conn, "Hi server!"); err != nil { 82 t.Fatal(err) 83 } 84 } 85 86 func TestWindowsPipeOwner(t *testing.T) { 87 88 if os.Getenv("JENKINS_URL") != "" { 89 t.Skip("Skipping pipeowner test - doesn't work on CI, works locally") 90 } 91 92 tc := setupTest(t, "socket_windows_test") 93 defer tc.Cleanup() 94 95 testPipeName := "\\\\.\\pipe\\kbservice\\test_pipe" 96 serverCmd := exec.Command("go", "run", "testfixtures\\kb_pipetest_server\\main.go", testPipeName) 97 err := serverCmd.Start() 98 if err != nil { 99 t.Fatal(err) 100 } 101 defer serverCmd.Process.Kill() 102 103 for i := 0; i < 20; i++ { 104 // Give the server time to open the pipe 105 time.Sleep(500 * time.Millisecond) 106 107 // Test existing pipe 108 owner, err := IsPipeowner(tc.G.Log, testPipeName) 109 if err != nil { 110 if i < 19 { 111 continue 112 } 113 t.Fatal(err) 114 } 115 if !owner.IsOwner { 116 t.Fatal(errors.New("Expected true getting owner of test pipe")) 117 } 118 } 119 120 // Test nonexisting 121 owner, err := IsPipeowner(tc.G.Log, testPipeName+"_nonexistent") 122 if err == nil { 123 t.Fatal(errors.New("Expected error getting owner of nonexistent pipe")) 124 } 125 if owner.IsOwner { 126 t.Fatal(errors.New("Expected false getting owner of nonexistent pipe")) 127 } 128 }