[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 kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

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