[MIRROR: https://git.mills.io/prologic/go-gopher] Gopher (RFC 1436) protocol library for the Go (Golang) programming language supporting both client and server
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

191 Zeilen
4.3 KiB

  1. package gopher_test
  2. import (
  3. "fmt"
  4. "log"
  5. "net"
  6. "os"
  7. "testing"
  8. "time"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. "code.as/writefreely/go-gopher"
  12. )
  13. var (
  14. testHost string = "localhost"
  15. testPort int
  16. )
  17. func pickUnusedPort() (int, error) {
  18. addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0")
  19. if err != nil {
  20. return 0, err
  21. }
  22. l, err := net.ListenTCP("tcp", addr)
  23. if err != nil {
  24. return 0, err
  25. }
  26. port := l.Addr().(*net.TCPAddr).Port
  27. if err := l.Close(); err != nil {
  28. return 0, err
  29. }
  30. return port, nil
  31. }
  32. func TestMain(m *testing.M) {
  33. port, err := pickUnusedPort()
  34. if err != nil {
  35. log.Fatalf("error finding a free port: %s", err)
  36. }
  37. testPort = port
  38. go func() {
  39. gopher.Handle("/", gopher.FileServer(gopher.Dir("./testdata")))
  40. gopher.HandleFunc("/hello", hello)
  41. log.Printf("Test server starting on :%d\n", testPort)
  42. log.Fatal(gopher.ListenAndServe(fmt.Sprintf(":%d", testPort), nil))
  43. }()
  44. // Because it can take some time for the server to spin up
  45. // the tests are inconsistent - they'll fail if the server isn't
  46. // ready, but pass otherwise. This problem seems more pronounced
  47. // when running via the makefile.
  48. //
  49. // It seems like there should be a better way to do this
  50. for attempts := 3; attempts > 0; attempts-- {
  51. _, err := gopher.Get(fmt.Sprintf("gopher://%s:%d", testHost, testPort))
  52. if err == nil {
  53. log.Println("Server ready")
  54. break
  55. }
  56. log.Printf("Server not ready, going to try again in a sec. %v\n", err)
  57. time.Sleep(1 * time.Second)
  58. }
  59. code := m.Run()
  60. os.Exit(code)
  61. }
  62. func hello(w gopher.ResponseWriter, r *gopher.Request) {
  63. w.WriteInfo("Hello World!")
  64. }
  65. func Example_client() {
  66. res, err := gopher.Get("gopher://gopher.floodgap.com")
  67. if err != nil {
  68. log.Fatal(err)
  69. }
  70. fmt.Print(res.Dir.ToText())
  71. }
  72. func Example_server() {
  73. gopher.HandleFunc("/hello", hello)
  74. log.Fatal(gopher.ListenAndServe("localhost:7000", nil))
  75. }
  76. func Example_fileserver() {
  77. gopher.Handle("/", gopher.FileServer(gopher.Dir("/tmp")))
  78. log.Fatal(gopher.ListenAndServe("localhost:7000", nil))
  79. }
  80. func TestGet(t *testing.T) {
  81. assert := assert.New(t)
  82. require := require.New(t)
  83. res, err := gopher.Get(fmt.Sprintf("gopher://%s:%d/1hello", testHost, testPort))
  84. require.NoError(err)
  85. assert.Len(res.Dir.Items, 1)
  86. assert.Equal(res.Dir.Items[0].Type, gopher.INFO)
  87. assert.Equal(res.Dir.Items[0].Description, "Hello World!")
  88. out, err := res.Dir.ToText()
  89. require.NoError(err)
  90. assert.Equal(string(out), "iHello World!\t\terror.host\t1\r\n")
  91. }
  92. func TestFileServer(t *testing.T) {
  93. assert := assert.New(t)
  94. require := require.New(t)
  95. res, err := gopher.Get(fmt.Sprintf("gopher://%s:%d/", testHost, testPort))
  96. require.NoError(err)
  97. assert.Len(res.Dir.Items, 1)
  98. json, err := res.Dir.ToJSON()
  99. require.NoError(err)
  100. log.Println(string(json))
  101. assert.JSONEq(
  102. `{"items":[{"type":"0","description":"hello.txt","selector":"/hello.txt","host":"127.0.0.1","port":7000,"extras":[]}]}`,
  103. string(json))
  104. }
  105. func TestParseItemNull(t *testing.T) {
  106. assert := assert.New(t)
  107. item, err := gopher.ParseItem("")
  108. assert.Nil(item)
  109. assert.Error(err)
  110. }
  111. func TestParseItem(t *testing.T) {
  112. assert := assert.New(t)
  113. require := require.New(t)
  114. item, err := gopher.ParseItem("0foo\t/foo\tlocalhost\t70\r\n")
  115. require.NoError(err)
  116. assert.NotNil(item)
  117. assert.Equal(item, &gopher.Item{
  118. Type: gopher.FILE,
  119. Description: "foo",
  120. Selector: "/foo",
  121. Host: "localhost",
  122. Port: 70,
  123. Extras: []string{},
  124. })
  125. }
  126. func TestParseItemMarshal(t *testing.T) {
  127. assert := assert.New(t)
  128. require := require.New(t)
  129. data := "0foo\t/foo\tlocalhost\t70\r\n"
  130. item, err := gopher.ParseItem(data)
  131. require.NoError(err)
  132. assert.NotNil(item)
  133. assert.Equal(item, &gopher.Item{
  134. Type: gopher.FILE,
  135. Description: "foo",
  136. Selector: "/foo",
  137. Host: "localhost",
  138. Port: 70,
  139. Extras: []string{},
  140. })
  141. data1, err := item.MarshalText()
  142. assert.Nil(err)
  143. assert.Equal(data, string(data1))
  144. }
  145. func TestParseItemMarshalIdempotency(t *testing.T) {
  146. assert := assert.New(t)
  147. require := require.New(t)
  148. data := "0"
  149. item, err := gopher.ParseItem(data)
  150. require.NoError(err)
  151. assert.NotNil(item)
  152. data1, err := item.MarshalText()
  153. assert.Nil(err)
  154. item1, err := gopher.ParseItem(string(data1))
  155. assert.NoError(err)
  156. assert.NotNil(item1)
  157. assert.Equal(item, item1)
  158. }