25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

97 lines
2.2 KiB

  1. /*
  2. *
  3. * Copyright 2018 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. // Package testutils contains testing helpers.
  19. package testutils
  20. import (
  21. "errors"
  22. "net"
  23. "time"
  24. )
  25. var errClosed = errors.New("closed")
  26. type pipeAddr struct{}
  27. func (p pipeAddr) Network() string { return "pipe" }
  28. func (p pipeAddr) String() string { return "pipe" }
  29. // PipeListener is a listener with an unbuffered pipe. Each write will complete only once the other side reads. It
  30. // should only be created using NewPipeListener.
  31. type PipeListener struct {
  32. c chan chan<- net.Conn
  33. done chan struct{}
  34. }
  35. // NewPipeListener creates a new pipe listener.
  36. func NewPipeListener() *PipeListener {
  37. return &PipeListener{
  38. c: make(chan chan<- net.Conn),
  39. done: make(chan struct{}),
  40. }
  41. }
  42. // Accept accepts a connection.
  43. func (p *PipeListener) Accept() (net.Conn, error) {
  44. var connChan chan<- net.Conn
  45. select {
  46. case <-p.done:
  47. return nil, errClosed
  48. case connChan = <-p.c:
  49. select {
  50. case <-p.done:
  51. close(connChan)
  52. return nil, errClosed
  53. default:
  54. }
  55. }
  56. c1, c2 := net.Pipe()
  57. connChan <- c1
  58. close(connChan)
  59. return c2, nil
  60. }
  61. // Close closes the listener.
  62. func (p *PipeListener) Close() error {
  63. close(p.done)
  64. return nil
  65. }
  66. // Addr returns a pipe addr.
  67. func (p *PipeListener) Addr() net.Addr {
  68. return pipeAddr{}
  69. }
  70. // Dialer dials a connection.
  71. func (p *PipeListener) Dialer() func(string, time.Duration) (net.Conn, error) {
  72. return func(string, time.Duration) (net.Conn, error) {
  73. connChan := make(chan net.Conn)
  74. select {
  75. case p.c <- connChan:
  76. case <-p.done:
  77. return nil, errClosed
  78. }
  79. conn, ok := <-connChan
  80. if !ok {
  81. return nil, errClosed
  82. }
  83. return conn, nil
  84. }
  85. }