opts_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. package opts
  2. import (
  3. "fmt"
  4. "os"
  5. "strings"
  6. "testing"
  7. )
  8. func TestValidateIPAddress(t *testing.T) {
  9. if ret, err := ValidateIPAddress(`1.2.3.4`); err != nil || ret == "" {
  10. t.Fatalf("ValidateIPAddress(`1.2.3.4`) got %s %s", ret, err)
  11. }
  12. if ret, err := ValidateIPAddress(`127.0.0.1`); err != nil || ret == "" {
  13. t.Fatalf("ValidateIPAddress(`127.0.0.1`) got %s %s", ret, err)
  14. }
  15. if ret, err := ValidateIPAddress(`::1`); err != nil || ret == "" {
  16. t.Fatalf("ValidateIPAddress(`::1`) got %s %s", ret, err)
  17. }
  18. if ret, err := ValidateIPAddress(`127`); err == nil || ret != "" {
  19. t.Fatalf("ValidateIPAddress(`127`) got %s %s", ret, err)
  20. }
  21. if ret, err := ValidateIPAddress(`random invalid string`); err == nil || ret != "" {
  22. t.Fatalf("ValidateIPAddress(`random invalid string`) got %s %s", ret, err)
  23. }
  24. }
  25. func TestMapOpts(t *testing.T) {
  26. tmpMap := make(map[string]string)
  27. o := NewMapOpts(tmpMap, logOptsValidator)
  28. o.Set("max-size=1")
  29. if o.String() != "map[max-size:1]" {
  30. t.Errorf("%s != [map[max-size:1]", o.String())
  31. }
  32. o.Set("max-file=2")
  33. if len(tmpMap) != 2 {
  34. t.Errorf("map length %d != 2", len(tmpMap))
  35. }
  36. if tmpMap["max-file"] != "2" {
  37. t.Errorf("max-file = %s != 2", tmpMap["max-file"])
  38. }
  39. if tmpMap["max-size"] != "1" {
  40. t.Errorf("max-size = %s != 1", tmpMap["max-size"])
  41. }
  42. if o.Set("dummy-val=3") == nil {
  43. t.Errorf("validator is not being called")
  44. }
  45. }
  46. func TestValidateMACAddress(t *testing.T) {
  47. if _, err := ValidateMACAddress(`92:d0:c6:0a:29:33`); err != nil {
  48. t.Fatalf("ValidateMACAddress(`92:d0:c6:0a:29:33`) got %s", err)
  49. }
  50. if _, err := ValidateMACAddress(`92:d0:c6:0a:33`); err == nil {
  51. t.Fatalf("ValidateMACAddress(`92:d0:c6:0a:33`) succeeded; expected failure on invalid MAC")
  52. }
  53. if _, err := ValidateMACAddress(`random invalid string`); err == nil {
  54. t.Fatalf("ValidateMACAddress(`random invalid string`) succeeded; expected failure on invalid MAC")
  55. }
  56. }
  57. func TestListOptsWithoutValidator(t *testing.T) {
  58. o := NewListOpts(nil)
  59. o.Set("foo")
  60. if o.String() != "[foo]" {
  61. t.Errorf("%s != [foo]", o.String())
  62. }
  63. o.Set("bar")
  64. if o.Len() != 2 {
  65. t.Errorf("%d != 2", o.Len())
  66. }
  67. o.Set("bar")
  68. if o.Len() != 3 {
  69. t.Errorf("%d != 3", o.Len())
  70. }
  71. if !o.Get("bar") {
  72. t.Error("o.Get(\"bar\") == false")
  73. }
  74. if o.Get("baz") {
  75. t.Error("o.Get(\"baz\") == true")
  76. }
  77. o.Delete("foo")
  78. if o.String() != "[bar bar]" {
  79. t.Errorf("%s != [bar bar]", o.String())
  80. }
  81. listOpts := o.GetAll()
  82. if len(listOpts) != 2 || listOpts[0] != "bar" || listOpts[1] != "bar" {
  83. t.Errorf("Expected [[bar bar]], got [%v]", listOpts)
  84. }
  85. mapListOpts := o.GetMap()
  86. if len(mapListOpts) != 1 {
  87. t.Errorf("Expected [map[bar:{}]], got [%v]", mapListOpts)
  88. }
  89. }
  90. func TestListOptsWithValidator(t *testing.T) {
  91. // Re-using logOptsvalidator (used by MapOpts)
  92. o := NewListOpts(logOptsValidator)
  93. o.Set("foo")
  94. if o.String() != "[]" {
  95. t.Errorf("%s != []", o.String())
  96. }
  97. o.Set("foo=bar")
  98. if o.String() != "[]" {
  99. t.Errorf("%s != []", o.String())
  100. }
  101. o.Set("max-file=2")
  102. if o.Len() != 1 {
  103. t.Errorf("%d != 1", o.Len())
  104. }
  105. if !o.Get("max-file=2") {
  106. t.Error("o.Get(\"max-file=2\") == false")
  107. }
  108. if o.Get("baz") {
  109. t.Error("o.Get(\"baz\") == true")
  110. }
  111. o.Delete("max-file=2")
  112. if o.String() != "[]" {
  113. t.Errorf("%s != []", o.String())
  114. }
  115. }
  116. func TestValidateDNSSearch(t *testing.T) {
  117. valid := []string{
  118. `.`,
  119. `a`,
  120. `a.`,
  121. `1.foo`,
  122. `17.foo`,
  123. `foo.bar`,
  124. `foo.bar.baz`,
  125. `foo.bar.`,
  126. `foo.bar.baz`,
  127. `foo1.bar2`,
  128. `foo1.bar2.baz`,
  129. `1foo.2bar.`,
  130. `1foo.2bar.baz`,
  131. `foo-1.bar-2`,
  132. `foo-1.bar-2.baz`,
  133. `foo-1.bar-2.`,
  134. `foo-1.bar-2.baz`,
  135. `1-foo.2-bar`,
  136. `1-foo.2-bar.baz`,
  137. `1-foo.2-bar.`,
  138. `1-foo.2-bar.baz`,
  139. }
  140. invalid := []string{
  141. ``,
  142. ` `,
  143. ` `,
  144. `17`,
  145. `17.`,
  146. `.17`,
  147. `17-.`,
  148. `17-.foo`,
  149. `.foo`,
  150. `foo-.bar`,
  151. `-foo.bar`,
  152. `foo.bar-`,
  153. `foo.bar-.baz`,
  154. `foo.-bar`,
  155. `foo.-bar.baz`,
  156. `foo.bar.baz.this.should.fail.on.long.name.beause.it.is.longer.thanisshouldbethis.should.fail.on.long.name.beause.it.is.longer.thanisshouldbethis.should.fail.on.long.name.beause.it.is.longer.thanisshouldbethis.should.fail.on.long.name.beause.it.is.longer.thanisshouldbe`,
  157. }
  158. for _, domain := range valid {
  159. if ret, err := ValidateDNSSearch(domain); err != nil || ret == "" {
  160. t.Fatalf("ValidateDNSSearch(`"+domain+"`) got %s %s", ret, err)
  161. }
  162. }
  163. for _, domain := range invalid {
  164. if ret, err := ValidateDNSSearch(domain); err == nil || ret != "" {
  165. t.Fatalf("ValidateDNSSearch(`"+domain+"`) got %s %s", ret, err)
  166. }
  167. }
  168. }
  169. func TestValidateExtraHosts(t *testing.T) {
  170. valid := []string{
  171. `myhost:192.168.0.1`,
  172. `thathost:10.0.2.1`,
  173. `anipv6host:2003:ab34:e::1`,
  174. `ipv6local:::1`,
  175. }
  176. invalid := map[string]string{
  177. `myhost:192.notanipaddress.1`: `invalid IP`,
  178. `thathost-nosemicolon10.0.0.1`: `bad format`,
  179. `anipv6host:::::1`: `invalid IP`,
  180. `ipv6local:::0::`: `invalid IP`,
  181. }
  182. for _, extrahost := range valid {
  183. if _, err := ValidateExtraHost(extrahost); err != nil {
  184. t.Fatalf("ValidateExtraHost(`"+extrahost+"`) should succeed: error %v", err)
  185. }
  186. }
  187. for extraHost, expectedError := range invalid {
  188. if _, err := ValidateExtraHost(extraHost); err == nil {
  189. t.Fatalf("ValidateExtraHost(`%q`) should have failed validation", extraHost)
  190. } else {
  191. if !strings.Contains(err.Error(), expectedError) {
  192. t.Fatalf("ValidateExtraHost(`%q`) error should contain %q", extraHost, expectedError)
  193. }
  194. }
  195. }
  196. }
  197. func TestValidateAttach(t *testing.T) {
  198. valid := []string{
  199. "stdin",
  200. "stdout",
  201. "stderr",
  202. "STDIN",
  203. "STDOUT",
  204. "STDERR",
  205. }
  206. if _, err := ValidateAttach("invalid"); err == nil {
  207. t.Fatalf("Expected error with [valid streams are STDIN, STDOUT and STDERR], got nothing")
  208. }
  209. for _, attach := range valid {
  210. value, err := ValidateAttach(attach)
  211. if err != nil {
  212. t.Fatal(err)
  213. }
  214. if value != strings.ToLower(attach) {
  215. t.Fatalf("Expected [%v], got [%v]", attach, value)
  216. }
  217. }
  218. }
  219. func TestValidateLink(t *testing.T) {
  220. valid := []string{
  221. "name",
  222. "dcdfbe62ecd0:alias",
  223. "7a67485460b7642516a4ad82ecefe7f57d0c4916f530561b71a50a3f9c4e33da",
  224. "angry_torvalds:linus",
  225. }
  226. invalid := map[string]string{
  227. "": "empty string specified for links",
  228. "too:much:of:it": "bad format for links: too:much:of:it",
  229. }
  230. for _, link := range valid {
  231. if _, err := ValidateLink(link); err != nil {
  232. t.Fatalf("ValidateLink(`%q`) should succeed: error %q", link, err)
  233. }
  234. }
  235. for link, expectedError := range invalid {
  236. if _, err := ValidateLink(link); err == nil {
  237. t.Fatalf("ValidateLink(`%q`) should have failed validation", link)
  238. } else {
  239. if !strings.Contains(err.Error(), expectedError) {
  240. t.Fatalf("ValidateLink(`%q`) error should contain %q", link, expectedError)
  241. }
  242. }
  243. }
  244. }
  245. func TestValidateDevice(t *testing.T) {
  246. valid := []string{
  247. "/home",
  248. "/home:/home",
  249. "/home:/something/else",
  250. "/with space",
  251. "/home:/with space",
  252. "relative:/absolute-path",
  253. "hostPath:/containerPath:r",
  254. "/hostPath:/containerPath:rw",
  255. "/hostPath:/containerPath:mrw",
  256. }
  257. invalid := map[string]string{
  258. "": "bad format for path: ",
  259. "./": "./ is not an absolute path",
  260. "../": "../ is not an absolute path",
  261. "/:../": "../ is not an absolute path",
  262. "/:path": "path is not an absolute path",
  263. ":": "bad format for path: :",
  264. "/tmp:": " is not an absolute path",
  265. ":test": "bad format for path: :test",
  266. ":/test": "bad format for path: :/test",
  267. "tmp:": " is not an absolute path",
  268. ":test:": "bad format for path: :test:",
  269. "::": "bad format for path: ::",
  270. ":::": "bad format for path: :::",
  271. "/tmp:::": "bad format for path: /tmp:::",
  272. ":/tmp::": "bad format for path: :/tmp::",
  273. "path:ro": "ro is not an absolute path",
  274. "path:rr": "rr is not an absolute path",
  275. "a:/b:ro": "bad mode specified: ro",
  276. "a:/b:rr": "bad mode specified: rr",
  277. }
  278. for _, path := range valid {
  279. if _, err := ValidateDevice(path); err != nil {
  280. t.Fatalf("ValidateDevice(`%q`) should succeed: error %q", path, err)
  281. }
  282. }
  283. for path, expectedError := range invalid {
  284. if _, err := ValidateDevice(path); err == nil {
  285. t.Fatalf("ValidateDevice(`%q`) should have failed validation", path)
  286. } else {
  287. if err.Error() != expectedError {
  288. t.Fatalf("ValidateDevice(`%q`) error should contain %q, got %q", path, expectedError, err.Error())
  289. }
  290. }
  291. }
  292. }
  293. func TestValidateEnv(t *testing.T) {
  294. valids := map[string]string{
  295. "a": "a",
  296. "something": "something",
  297. "_=a": "_=a",
  298. "env1=value1": "env1=value1",
  299. "_env1=value1": "_env1=value1",
  300. "env2=value2=value3": "env2=value2=value3",
  301. "env3=abc!qwe": "env3=abc!qwe",
  302. "env_4=value 4": "env_4=value 4",
  303. "PATH": fmt.Sprintf("PATH=%v", os.Getenv("PATH")),
  304. "PATH=something": "PATH=something",
  305. "asd!qwe": "asd!qwe",
  306. "1asd": "1asd",
  307. "123": "123",
  308. "some space": "some space",
  309. " some space before": " some space before",
  310. "some space after ": "some space after ",
  311. }
  312. for value, expected := range valids {
  313. actual, err := ValidateEnv(value)
  314. if err != nil {
  315. t.Fatal(err)
  316. }
  317. if actual != expected {
  318. t.Fatalf("Expected [%v], got [%v]", expected, actual)
  319. }
  320. }
  321. }
  322. func TestValidateLabel(t *testing.T) {
  323. if _, err := ValidateLabel("label"); err == nil || err.Error() != "bad attribute format: label" {
  324. t.Fatalf("Expected an error [bad attribute format: label], go %v", err)
  325. }
  326. if actual, err := ValidateLabel("key1=value1"); err != nil || actual != "key1=value1" {
  327. t.Fatalf("Expected [key1=value1], got [%v,%v]", actual, err)
  328. }
  329. // Validate it's working with more than one =
  330. if actual, err := ValidateLabel("key1=value1=value2"); err != nil {
  331. t.Fatalf("Expected [key1=value1=value2], got [%v,%v]", actual, err)
  332. }
  333. // Validate it's working with one more
  334. if actual, err := ValidateLabel("key1=value1=value2=value3"); err != nil {
  335. t.Fatalf("Expected [key1=value1=value2=value2], got [%v,%v]", actual, err)
  336. }
  337. }
  338. func logOptsValidator(val string) (string, error) {
  339. allowedKeys := map[string]string{"max-size": "1", "max-file": "2"}
  340. vals := strings.Split(val, "=")
  341. if allowedKeys[vals[0]] != "" {
  342. return val, nil
  343. }
  344. return "", fmt.Errorf("invalid key %s", vals[0])
  345. }