client_test.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. package ftp
  2. import (
  3. "bytes"
  4. "io/ioutil"
  5. "net/textproto"
  6. "strings"
  7. "testing"
  8. "time"
  9. )
  10. const (
  11. testData = "Just some text"
  12. testDir = "mydir"
  13. )
  14. func TestConnPASV(t *testing.T) {
  15. testConn(t, true)
  16. }
  17. func TestConnEPSV(t *testing.T) {
  18. testConn(t, false)
  19. }
  20. func testConn(t *testing.T, disableEPSV bool) {
  21. mock, c := openConn(t, "127.0.0.1", DialWithTimeout(5*time.Second), DialWithDisabledEPSV(disableEPSV))
  22. err := c.Login("anonymous", "anonymous")
  23. if err != nil {
  24. t.Fatal(err)
  25. }
  26. err = c.NoOp()
  27. if err != nil {
  28. t.Error(err)
  29. }
  30. err = c.ChangeDir("incoming")
  31. if err != nil {
  32. t.Error(err)
  33. }
  34. dir, err := c.CurrentDir()
  35. if err != nil {
  36. t.Error(err)
  37. } else {
  38. if dir != "/incoming" {
  39. t.Error("Wrong dir: " + dir)
  40. }
  41. }
  42. data := bytes.NewBufferString(testData)
  43. err = c.Stor("test", data)
  44. if err != nil {
  45. t.Error(err)
  46. }
  47. _, err = c.List(".")
  48. if err != nil {
  49. t.Error(err)
  50. }
  51. err = c.Rename("test", "tset")
  52. if err != nil {
  53. t.Error(err)
  54. }
  55. // Read without deadline
  56. r, err := c.Retr("tset")
  57. if err != nil {
  58. t.Error(err)
  59. } else {
  60. buf, err := ioutil.ReadAll(r)
  61. if err != nil {
  62. t.Error(err)
  63. }
  64. if string(buf) != testData {
  65. t.Errorf("'%s'", buf)
  66. }
  67. r.Close()
  68. r.Close() // test we can close two times
  69. }
  70. // Read with deadline
  71. r, err = c.Retr("tset")
  72. if err != nil {
  73. t.Error(err)
  74. } else {
  75. r.SetDeadline(time.Now())
  76. _, err := ioutil.ReadAll(r)
  77. if err == nil {
  78. t.Error("deadline should have caused error")
  79. } else if !strings.HasSuffix(err.Error(), "i/o timeout") {
  80. t.Error(err)
  81. }
  82. r.Close()
  83. }
  84. // Read with offset
  85. r, err = c.RetrFrom("tset", 5)
  86. if err != nil {
  87. t.Error(err)
  88. } else {
  89. buf, err := ioutil.ReadAll(r)
  90. if err != nil {
  91. t.Error(err)
  92. }
  93. expected := testData[5:]
  94. if string(buf) != expected {
  95. t.Errorf("read %q, expected %q", buf, expected)
  96. }
  97. r.Close()
  98. }
  99. data2 := bytes.NewBufferString(testData)
  100. err = c.Append("tset", data2)
  101. if err != nil {
  102. t.Error(err)
  103. }
  104. // Read without deadline, after append
  105. r, err = c.Retr("tset")
  106. if err != nil {
  107. t.Error(err)
  108. } else {
  109. buf, err := ioutil.ReadAll(r)
  110. if err != nil {
  111. t.Error(err)
  112. }
  113. if string(buf) != testData+testData {
  114. t.Errorf("'%s'", buf)
  115. }
  116. r.Close()
  117. }
  118. fileSize, err := c.FileSize("magic-file")
  119. if err != nil {
  120. t.Error(err)
  121. }
  122. if fileSize != 42 {
  123. t.Errorf("file size %q, expected %q", fileSize, 42)
  124. }
  125. _, err = c.FileSize("not-found")
  126. if err == nil {
  127. t.Fatal("expected error, got nil")
  128. }
  129. err = c.Delete("tset")
  130. if err != nil {
  131. t.Error(err)
  132. }
  133. err = c.MakeDir(testDir)
  134. if err != nil {
  135. t.Error(err)
  136. }
  137. err = c.ChangeDir(testDir)
  138. if err != nil {
  139. t.Error(err)
  140. }
  141. err = c.ChangeDirToParent()
  142. if err != nil {
  143. t.Error(err)
  144. }
  145. entries, err := c.NameList("/")
  146. if err != nil {
  147. t.Error(err)
  148. }
  149. if len(entries) != 1 || entries[0] != "/incoming" {
  150. t.Errorf("Unexpected entries: %v", entries)
  151. }
  152. err = c.RemoveDir(testDir)
  153. if err != nil {
  154. t.Error(err)
  155. }
  156. err = c.Logout()
  157. if err != nil {
  158. if protoErr := err.(*textproto.Error); protoErr != nil {
  159. if protoErr.Code != StatusNotImplemented {
  160. t.Error(err)
  161. }
  162. } else {
  163. t.Error(err)
  164. }
  165. }
  166. if err := c.Quit(); err != nil {
  167. t.Fatal(err)
  168. }
  169. // Wait for the connection to close
  170. mock.Wait()
  171. err = c.NoOp()
  172. if err == nil {
  173. t.Error("Expected error")
  174. }
  175. }
  176. // TestConnect tests the legacy Connect function
  177. func TestConnect(t *testing.T) {
  178. mock, err := newFtpMock(t, "127.0.0.1")
  179. if err != nil {
  180. t.Fatal(err)
  181. }
  182. defer mock.Close()
  183. c, err := Connect(mock.Addr())
  184. if err != nil {
  185. t.Fatal(err)
  186. }
  187. if err := c.Quit(); err != nil {
  188. t.Fatal(err)
  189. }
  190. mock.Wait()
  191. }
  192. func TestTimeout(t *testing.T) {
  193. if testing.Short() {
  194. t.Skip("skipping test in short mode.")
  195. }
  196. c, err := DialTimeout("localhost:2121", 1*time.Second)
  197. if err == nil {
  198. t.Fatal("expected timeout, got nil error")
  199. c.Quit()
  200. }
  201. }
  202. func TestWrongLogin(t *testing.T) {
  203. mock, err := newFtpMock(t, "127.0.0.1")
  204. if err != nil {
  205. t.Fatal(err)
  206. }
  207. defer mock.Close()
  208. c, err := DialTimeout(mock.Addr(), 5*time.Second)
  209. if err != nil {
  210. t.Fatal(err)
  211. }
  212. defer c.Quit()
  213. err = c.Login("zoo2Shia", "fei5Yix9")
  214. if err == nil {
  215. t.Fatal("expected error, got nil")
  216. }
  217. }
  218. func TestDeleteDirRecur(t *testing.T) {
  219. mock, c := openConn(t, "127.0.0.1")
  220. err := c.RemoveDirRecur("testDir")
  221. if err != nil {
  222. t.Error(err)
  223. }
  224. if err := c.Quit(); err != nil {
  225. t.Fatal(err)
  226. }
  227. // Wait for the connection to close
  228. mock.Wait()
  229. }
  230. // func TestFileDeleteDirRecur(t *testing.T) {
  231. // mock, c := openConn(t, "127.0.0.1")
  232. // err := c.RemoveDirRecur("testFile")
  233. // if err == nil {
  234. // t.Fatal("expected error got nil")
  235. // }
  236. // if err := c.Quit(); err != nil {
  237. // t.Fatal(err)
  238. // }
  239. // // Wait for the connection to close
  240. // mock.Wait()
  241. // }
  242. func TestMissingFolderDeleteDirRecur(t *testing.T) {
  243. mock, c := openConn(t, "127.0.0.1")
  244. err := c.RemoveDirRecur("missing-dir")
  245. if err == nil {
  246. t.Fatal("expected error got nil")
  247. }
  248. if err := c.Quit(); err != nil {
  249. t.Fatal(err)
  250. }
  251. // Wait for the connection to close
  252. mock.Wait()
  253. }