testutil.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. /*
  10. Package testutil contains common datastructures and functions for testing.
  11. */
  12. package testutil
  13. import (
  14. "bytes"
  15. "errors"
  16. "fmt"
  17. "net"
  18. "runtime"
  19. "time"
  20. )
  21. /*
  22. GetCaller returns the calling function of the function which called it and the
  23. code location which called the calling function. Can optionally go further back
  24. depending on the level parameter.
  25. For example testfile.go:
  26. 20: foo() {
  27. 21: x := GetCaller(0)
  28. 22: }
  29. 23:
  30. 24: bar() {
  31. 25: foo()
  32. 26: }
  33. In the example x would be set to "bar" and location would be testfile.go 25.
  34. */
  35. func GetCaller(level int) (string, string) {
  36. name := "n/a"
  37. loc := "n/a"
  38. // Get callers as uintptr
  39. fpcs := make([]uintptr, 1)
  40. // Skip 3 levels to get the caller's caller
  41. if n := runtime.Callers(3+level, fpcs); n != 0 {
  42. // Get the function info
  43. if fc := runtime.FuncForPC(fpcs[0] - 1); fc != nil {
  44. name = fc.Name()
  45. file, line := fc.FileLine(fpcs[0] - 1)
  46. loc = fmt.Sprintf("%v:%v", file, line)
  47. }
  48. }
  49. return name, loc
  50. }
  51. /*
  52. ErrorTestingConnection testing object for connection errors.
  53. */
  54. type ErrorTestingConnection struct {
  55. In bytes.Buffer
  56. Out bytes.Buffer
  57. rc int
  58. InErr int
  59. wc int
  60. OutErr int
  61. OutClose bool
  62. }
  63. /*
  64. Read reads from the test connection in buffer.
  65. */
  66. func (c *ErrorTestingConnection) Read(b []byte) (n int, err error) {
  67. c.rc += len(b)
  68. if c.InErr != 0 && c.rc > c.InErr {
  69. return 0, errors.New("Test reading error")
  70. }
  71. return c.In.Read(b)
  72. }
  73. /*
  74. Write write to the test connections buffer.
  75. */
  76. func (c *ErrorTestingConnection) Write(b []byte) (n int, err error) {
  77. c.wc += len(b)
  78. if c.OutErr != 0 && c.wc > c.OutErr {
  79. return 0, errors.New("Test writing error")
  80. }
  81. if c.OutClose {
  82. return 0, nil
  83. }
  84. return c.Out.Write(b)
  85. }
  86. /*
  87. Close is a method stub to satisfy the net.Conn interface.
  88. */
  89. func (c *ErrorTestingConnection) Close() error {
  90. return nil
  91. }
  92. /*
  93. LocalAddr is a method stub to satisfy the net.Conn interface.
  94. */
  95. func (c *ErrorTestingConnection) LocalAddr() net.Addr {
  96. return nil
  97. }
  98. /*
  99. RemoteAddr is a method stub to satisfy the net.Conn interface.
  100. */
  101. func (c *ErrorTestingConnection) RemoteAddr() net.Addr {
  102. return nil
  103. }
  104. /*
  105. SetDeadline is a method stub to satisfy the net.Conn interface.
  106. */
  107. func (c *ErrorTestingConnection) SetDeadline(t time.Time) error {
  108. return nil
  109. }
  110. /*
  111. SetReadDeadline is a method stub to satisfy the net.Conn interface.
  112. */
  113. func (c *ErrorTestingConnection) SetReadDeadline(t time.Time) error {
  114. return nil
  115. }
  116. /*
  117. SetWriteDeadline is a method stub to satisfy the net.Conn interface.
  118. */
  119. func (c *ErrorTestingConnection) SetWriteDeadline(t time.Time) error {
  120. return nil
  121. }
  122. /*
  123. GobTestObject testing object for gob errors.
  124. */
  125. type GobTestObject struct {
  126. Name string
  127. EncErr bool
  128. DecErr bool
  129. }
  130. /*
  131. GobEncode returns a test encoded byte array or an error.
  132. */
  133. func (t *GobTestObject) GobEncode() ([]byte, error) {
  134. if t.EncErr {
  135. return nil, errors.New("Encode error")
  136. }
  137. return []byte(t.Name), nil
  138. }
  139. /*
  140. GobDecode decodes the given byte array are returns an error.
  141. */
  142. func (t *GobTestObject) GobDecode(b []byte) error {
  143. if t.DecErr {
  144. return errors.New("Decode error")
  145. }
  146. t.Name = string(b)
  147. return nil
  148. }
  149. /*
  150. ErrorTestingBuffer is a testing buffer to test error handling for writing operations.
  151. */
  152. type ErrorTestingBuffer struct {
  153. RemainingSize int
  154. WrittenSize int
  155. }
  156. /*
  157. Write simulates writing to the test buffer. Returns error if it is full.
  158. */
  159. func (etb *ErrorTestingBuffer) Write(p []byte) (n int, err error) {
  160. if len(p) > etb.RemainingSize {
  161. return 0, *etb
  162. }
  163. written := len(p)
  164. etb.WrittenSize += written
  165. etb.RemainingSize -= written
  166. return written, nil
  167. }
  168. /*
  169. Error returns buffer errors. For simplicity the buffer itself implements the error interface.
  170. */
  171. func (etb ErrorTestingBuffer) Error() string {
  172. return fmt.Sprintf("Buffer is full at: %v", etb.WrittenSize+etb.RemainingSize)
  173. }
  174. /*
  175. ErrorTestingFile is a testing buffer which can be used as an io.File like object.
  176. */
  177. type ErrorTestingFile struct {
  178. Buf *ErrorTestingBuffer
  179. }
  180. /*
  181. NewTestingFile creates a new test file.
  182. */
  183. func NewTestingFile(size int) *ErrorTestingFile {
  184. return &ErrorTestingFile{&ErrorTestingBuffer{size, 0}}
  185. }
  186. /*
  187. Write writes to the file.
  188. */
  189. func (etf ErrorTestingFile) Write(p []byte) (n int, err error) {
  190. return etf.Buf.Write(p)
  191. }
  192. /*
  193. Close does nothing (there to satisfy interfaces)
  194. */
  195. func (etf ErrorTestingFile) Close() error {
  196. return nil
  197. }
  198. /*
  199. Sync does nothing (there to satisfy interfaces)
  200. */
  201. func (etf ErrorTestingFile) Sync() error {
  202. return nil
  203. }