[MIRROR: https://git.mills.io/prologic/go-gopher] Gopher (RFC 1436) protocol library for the Go (Golang) programming language supporting both client and server
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

191 lignes
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. }