You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
7.0 KiB

  1. /*
  2. * Minio Cloud Storage, (C) 2016 Minio, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package cmd
  17. import (
  18. "fmt"
  19. "net"
  20. "net/http"
  21. "net/url"
  22. "reflect"
  23. "runtime"
  24. "testing"
  25. )
  26. // Tests http.Header clone.
  27. func TestCloneHeader(t *testing.T) {
  28. headers := []http.Header{
  29. {
  30. "Content-Type": {"text/html; charset=UTF-8"},
  31. "Content-Length": {"0"},
  32. },
  33. {
  34. "Content-Length": {"0", "1", "2"},
  35. },
  36. {
  37. "Expires": {"-1"},
  38. "Content-Length": {"0"},
  39. "Content-Encoding": {"gzip"},
  40. },
  41. }
  42. for i, header := range headers {
  43. clonedHeader := cloneHeader(header)
  44. if !reflect.DeepEqual(header, clonedHeader) {
  45. t.Errorf("Test %d failed", i+1)
  46. }
  47. }
  48. }
  49. // Tests check duplicates function.
  50. func TestCheckDuplicates(t *testing.T) {
  51. tests := []struct {
  52. list []string
  53. err error
  54. shouldPass bool
  55. }{
  56. // Test 1 - for '/tmp/1' repeated twice.
  57. {
  58. list: []string{"/tmp/1", "/tmp/1", "/tmp/2", "/tmp/3"},
  59. err: fmt.Errorf("Duplicate key: \"/tmp/1\" found of count: \"2\""),
  60. shouldPass: false,
  61. },
  62. // Test 2 - for '/tmp/1' repeated thrice.
  63. {
  64. list: []string{"/tmp/1", "/tmp/1", "/tmp/1", "/tmp/3"},
  65. err: fmt.Errorf("Duplicate key: \"/tmp/1\" found of count: \"3\""),
  66. shouldPass: false,
  67. },
  68. // Test 3 - empty string.
  69. {
  70. list: []string{""},
  71. err: errInvalidArgument,
  72. shouldPass: false,
  73. },
  74. // Test 4 - empty string.
  75. {
  76. list: nil,
  77. err: errInvalidArgument,
  78. shouldPass: false,
  79. },
  80. // Test 5 - non repeated strings.
  81. {
  82. list: []string{"/tmp/1", "/tmp/2", "/tmp/3"},
  83. err: nil,
  84. shouldPass: true,
  85. },
  86. }
  87. // Validate if function runs as expected.
  88. for i, test := range tests {
  89. err := checkDuplicateStrings(test.list)
  90. if test.shouldPass && err != test.err {
  91. t.Errorf("Test: %d, Expected %s got %s", i+1, test.err, err)
  92. }
  93. if !test.shouldPass && err.Error() != test.err.Error() {
  94. t.Errorf("Test: %d, Expected %s got %s", i+1, test.err, err)
  95. }
  96. }
  97. }
  98. // Tests maximum object size.
  99. func TestMaxObjectSize(t *testing.T) {
  100. sizes := []struct {
  101. isMax bool
  102. size int64
  103. }{
  104. // Test - 1 - maximum object size.
  105. {
  106. true,
  107. maxObjectSize + 1,
  108. },
  109. // Test - 2 - not maximum object size.
  110. {
  111. false,
  112. maxObjectSize - 1,
  113. },
  114. }
  115. for i, s := range sizes {
  116. isMax := isMaxObjectSize(s.size)
  117. if isMax != s.isMax {
  118. t.Errorf("Test %d: Expected %t, got %t", i+1, s.isMax, isMax)
  119. }
  120. }
  121. }
  122. // Test urlPathSplit.
  123. func TestURLPathSplit(t *testing.T) {
  124. type test struct {
  125. urlPath string
  126. bucketName string
  127. prefixName string
  128. }
  129. testCases := []test{
  130. {
  131. urlPath: "/b/c/",
  132. bucketName: "b",
  133. prefixName: "c/",
  134. },
  135. {
  136. urlPath: "c/aa",
  137. bucketName: "c",
  138. prefixName: "aa",
  139. },
  140. {
  141. urlPath: "",
  142. bucketName: "",
  143. prefixName: "",
  144. },
  145. {
  146. urlPath: "/b",
  147. bucketName: "b",
  148. prefixName: "",
  149. },
  150. }
  151. for i, testCase := range testCases {
  152. bucketName, prefixName := urlPathSplit(testCase.urlPath)
  153. if bucketName != testCase.bucketName {
  154. t.Errorf("Tets %d: Expected %s, %s", i+1, testCase.bucketName, bucketName)
  155. }
  156. if prefixName != testCase.prefixName {
  157. t.Errorf("Tets %d: Expected %s, %s", i+1, testCase.bucketName, bucketName)
  158. }
  159. }
  160. }
  161. // Tests minimum allowed part size.
  162. func TestMinAllowedPartSize(t *testing.T) {
  163. sizes := []struct {
  164. isMin bool
  165. size int64
  166. }{
  167. // Test - 1 - within minimum part size.
  168. {
  169. true,
  170. minPartSize + 1,
  171. },
  172. // Test - 2 - smaller than minimum part size.
  173. {
  174. false,
  175. minPartSize - 1,
  176. },
  177. }
  178. for i, s := range sizes {
  179. isMin := isMinAllowedPartSize(s.size)
  180. if isMin != s.isMin {
  181. t.Errorf("Test %d: Expected %t, got %t", i+1, s.isMin, isMin)
  182. }
  183. }
  184. }
  185. // Tests maximum allowed part number.
  186. func TestMaxPartID(t *testing.T) {
  187. sizes := []struct {
  188. isMax bool
  189. partN int
  190. }{
  191. // Test - 1 part number within max part number.
  192. {
  193. false,
  194. maxPartID - 1,
  195. },
  196. // Test - 2 part number bigger than max part number.
  197. {
  198. true,
  199. maxPartID + 1,
  200. },
  201. }
  202. for i, s := range sizes {
  203. isMax := isMaxPartID(s.partN)
  204. if isMax != s.isMax {
  205. t.Errorf("Test %d: Expected %t, got %t", i+1, s.isMax, isMax)
  206. }
  207. }
  208. }
  209. // Tests fetch local address.
  210. func TestLocalAddress(t *testing.T) {
  211. if runtime.GOOS == "windows" {
  212. return
  213. }
  214. // need to set this to avoid stale values from other tests.
  215. globalMinioPort = "9000"
  216. globalMinioHost = ""
  217. testCases := []struct {
  218. isDistXL bool
  219. srvCmdConfig serverCmdConfig
  220. localAddr string
  221. }{
  222. // Test 1 - local address is found.
  223. {
  224. isDistXL: true,
  225. srvCmdConfig: serverCmdConfig{
  226. endpoints: []*url.URL{{
  227. Scheme: "http",
  228. Host: "localhost:9000",
  229. Path: "/mnt/disk1",
  230. }, {
  231. Scheme: "http",
  232. Host: "1.1.1.2:9000",
  233. Path: "/mnt/disk2",
  234. }, {
  235. Scheme: "http",
  236. Host: "1.1.2.1:9000",
  237. Path: "/mnt/disk3",
  238. }, {
  239. Scheme: "http",
  240. Host: "1.1.2.2:9000",
  241. Path: "/mnt/disk4",
  242. }},
  243. },
  244. localAddr: net.JoinHostPort("localhost", globalMinioPort),
  245. },
  246. // Test 2 - local address is everything.
  247. {
  248. isDistXL: false,
  249. srvCmdConfig: serverCmdConfig{
  250. serverAddr: net.JoinHostPort("", globalMinioPort),
  251. endpoints: []*url.URL{{
  252. Path: "/mnt/disk1",
  253. }, {
  254. Path: "/mnt/disk2",
  255. }, {
  256. Path: "/mnt/disk3",
  257. }, {
  258. Path: "/mnt/disk4",
  259. }},
  260. },
  261. localAddr: net.JoinHostPort("", globalMinioPort),
  262. },
  263. // Test 3 - local address is not found.
  264. {
  265. isDistXL: true,
  266. srvCmdConfig: serverCmdConfig{
  267. endpoints: []*url.URL{{
  268. Scheme: "http",
  269. Host: "1.1.1.1:9000",
  270. Path: "/mnt/disk2",
  271. }, {
  272. Scheme: "http",
  273. Host: "1.1.1.2:9000",
  274. Path: "/mnt/disk2",
  275. }, {
  276. Scheme: "http",
  277. Host: "1.1.2.1:9000",
  278. Path: "/mnt/disk3",
  279. }, {
  280. Scheme: "http",
  281. Host: "1.1.2.2:9000",
  282. Path: "/mnt/disk4",
  283. }},
  284. },
  285. localAddr: "",
  286. },
  287. // Test 4 - in case of FS mode, with SSL, the host
  288. // name is specified in the --address option on the
  289. // server command line.
  290. {
  291. isDistXL: false,
  292. srvCmdConfig: serverCmdConfig{
  293. serverAddr: "play.minio.io:9000",
  294. endpoints: []*url.URL{{
  295. Path: "/mnt/disk1",
  296. }, {
  297. Path: "/mnt/disk2",
  298. }, {
  299. Path: "/mnt/disk3",
  300. }, {
  301. Path: "/mnt/disk4",
  302. }},
  303. },
  304. localAddr: "play.minio.io:9000",
  305. },
  306. }
  307. // Validates fetching local address.
  308. for i, testCase := range testCases {
  309. globalIsDistXL = testCase.isDistXL
  310. localAddr := getLocalAddress(testCase.srvCmdConfig)
  311. if localAddr != testCase.localAddr {
  312. t.Fatalf("Test %d: Expected %s, got %s", i+1, testCase.localAddr, localAddr)
  313. }
  314. }
  315. }