custom_column_printer_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. Copyright 2014 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package kubectl
  14. import (
  15. "bytes"
  16. "reflect"
  17. "strings"
  18. "testing"
  19. "k8s.io/kubernetes/pkg/api"
  20. "k8s.io/kubernetes/pkg/api/unversioned"
  21. "k8s.io/kubernetes/pkg/api/v1"
  22. "k8s.io/kubernetes/pkg/runtime"
  23. )
  24. func TestMassageJSONPath(t *testing.T) {
  25. tests := []struct {
  26. input string
  27. expectedOutput string
  28. expectErr bool
  29. }{
  30. {input: "foo.bar", expectedOutput: "{.foo.bar}"},
  31. {input: "{foo.bar}", expectedOutput: "{.foo.bar}"},
  32. {input: ".foo.bar", expectedOutput: "{.foo.bar}"},
  33. {input: "{.foo.bar}", expectedOutput: "{.foo.bar}"},
  34. {input: "", expectedOutput: ""},
  35. {input: "{foo.bar", expectErr: true},
  36. {input: "foo.bar}", expectErr: true},
  37. {input: "{foo.bar}}", expectErr: true},
  38. {input: "{{foo.bar}", expectErr: true},
  39. }
  40. for _, test := range tests {
  41. output, err := massageJSONPath(test.input)
  42. if err != nil && !test.expectErr {
  43. t.Errorf("unexpected error: %v", err)
  44. continue
  45. }
  46. if test.expectErr {
  47. if err == nil {
  48. t.Error("unexpected non-error")
  49. }
  50. continue
  51. }
  52. if output != test.expectedOutput {
  53. t.Errorf("input: %s, expected: %s, saw: %s", test.input, test.expectedOutput, output)
  54. }
  55. }
  56. }
  57. func TestNewColumnPrinterFromSpec(t *testing.T) {
  58. tests := []struct {
  59. spec string
  60. expectedColumns []Column
  61. expectErr bool
  62. name string
  63. noHeaders bool
  64. }{
  65. {
  66. spec: "",
  67. expectErr: true,
  68. name: "empty",
  69. },
  70. {
  71. spec: "invalid",
  72. expectErr: true,
  73. name: "invalid1",
  74. },
  75. {
  76. spec: "invalid=foobar",
  77. expectErr: true,
  78. name: "invalid2",
  79. },
  80. {
  81. spec: "invalid,foobar:blah",
  82. expectErr: true,
  83. name: "invalid3",
  84. },
  85. {
  86. spec: "NAME:metadata.name,API_VERSION:apiVersion",
  87. name: "ok",
  88. expectedColumns: []Column{
  89. {
  90. Header: "NAME",
  91. FieldSpec: "{.metadata.name}",
  92. },
  93. {
  94. Header: "API_VERSION",
  95. FieldSpec: "{.apiVersion}",
  96. },
  97. },
  98. },
  99. {
  100. spec: "API_VERSION:apiVersion",
  101. name: "no-headers",
  102. noHeaders: true,
  103. },
  104. }
  105. for _, test := range tests {
  106. printer, err := NewCustomColumnsPrinterFromSpec(test.spec, api.Codecs.UniversalDecoder(), test.noHeaders)
  107. if test.expectErr {
  108. if err == nil {
  109. t.Errorf("[%s] unexpected non-error", test.name)
  110. }
  111. continue
  112. }
  113. if !test.expectErr && err != nil {
  114. t.Errorf("[%s] unexpected error: %v", test.name, err)
  115. continue
  116. }
  117. if test.noHeaders {
  118. buffer := &bytes.Buffer{}
  119. printer.PrintObj(&api.Pod{}, buffer)
  120. if err != nil {
  121. t.Fatalf("An error occurred printing Pod: %#v", err)
  122. }
  123. if contains(strings.Fields(buffer.String()), "API_VERSION") {
  124. t.Errorf("unexpected header API_VERSION")
  125. }
  126. } else if !reflect.DeepEqual(test.expectedColumns, printer.Columns) {
  127. t.Errorf("[%s]\nexpected:\n%v\nsaw:\n%v\n", test.name, test.expectedColumns, printer.Columns)
  128. }
  129. }
  130. }
  131. const exampleTemplateOne = `NAME API_VERSION
  132. {metadata.name} {apiVersion}`
  133. const exampleTemplateTwo = `NAME API_VERSION
  134. {metadata.name} {apiVersion}`
  135. func TestNewColumnPrinterFromTemplate(t *testing.T) {
  136. tests := []struct {
  137. spec string
  138. expectedColumns []Column
  139. expectErr bool
  140. name string
  141. }{
  142. {
  143. spec: "",
  144. expectErr: true,
  145. name: "empty",
  146. },
  147. {
  148. spec: "invalid",
  149. expectErr: true,
  150. name: "invalid1",
  151. },
  152. {
  153. spec: "invalid=foobar",
  154. expectErr: true,
  155. name: "invalid2",
  156. },
  157. {
  158. spec: "invalid,foobar:blah",
  159. expectErr: true,
  160. name: "invalid3",
  161. },
  162. {
  163. spec: exampleTemplateOne,
  164. name: "ok",
  165. expectedColumns: []Column{
  166. {
  167. Header: "NAME",
  168. FieldSpec: "{.metadata.name}",
  169. },
  170. {
  171. Header: "API_VERSION",
  172. FieldSpec: "{.apiVersion}",
  173. },
  174. },
  175. },
  176. {
  177. spec: exampleTemplateTwo,
  178. name: "ok-2",
  179. expectedColumns: []Column{
  180. {
  181. Header: "NAME",
  182. FieldSpec: "{.metadata.name}",
  183. },
  184. {
  185. Header: "API_VERSION",
  186. FieldSpec: "{.apiVersion}",
  187. },
  188. },
  189. },
  190. }
  191. for _, test := range tests {
  192. reader := bytes.NewBufferString(test.spec)
  193. printer, err := NewCustomColumnsPrinterFromTemplate(reader, api.Codecs.UniversalDecoder())
  194. if test.expectErr {
  195. if err == nil {
  196. t.Errorf("[%s] unexpected non-error", test.name)
  197. }
  198. continue
  199. }
  200. if !test.expectErr && err != nil {
  201. t.Errorf("[%s] unexpected error: %v", test.name, err)
  202. continue
  203. }
  204. if !reflect.DeepEqual(test.expectedColumns, printer.Columns) {
  205. t.Errorf("[%s]\nexpected:\n%v\nsaw:\n%v\n", test.name, test.expectedColumns, printer.Columns)
  206. }
  207. }
  208. }
  209. func TestColumnPrint(t *testing.T) {
  210. tests := []struct {
  211. columns []Column
  212. obj runtime.Object
  213. expectedOutput string
  214. }{
  215. {
  216. columns: []Column{
  217. {
  218. Header: "NAME",
  219. FieldSpec: "{.metadata.name}",
  220. },
  221. },
  222. obj: &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "foo"}},
  223. expectedOutput: `NAME
  224. foo
  225. `,
  226. },
  227. {
  228. columns: []Column{
  229. {
  230. Header: "NAME",
  231. FieldSpec: "{.metadata.name}",
  232. },
  233. },
  234. obj: &v1.PodList{
  235. Items: []v1.Pod{
  236. {ObjectMeta: v1.ObjectMeta{Name: "foo"}},
  237. {ObjectMeta: v1.ObjectMeta{Name: "bar"}},
  238. },
  239. },
  240. expectedOutput: `NAME
  241. foo
  242. bar
  243. `,
  244. },
  245. {
  246. columns: []Column{
  247. {
  248. Header: "NAME",
  249. FieldSpec: "{.metadata.name}",
  250. },
  251. {
  252. Header: "API_VERSION",
  253. FieldSpec: "{.apiVersion}",
  254. },
  255. },
  256. obj: &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "foo"}, TypeMeta: unversioned.TypeMeta{APIVersion: "baz"}},
  257. expectedOutput: `NAME API_VERSION
  258. foo baz
  259. `,
  260. },
  261. }
  262. for _, test := range tests {
  263. printer := &CustomColumnsPrinter{
  264. Columns: test.columns,
  265. Decoder: api.Codecs.UniversalDecoder(),
  266. }
  267. buffer := &bytes.Buffer{}
  268. if err := printer.PrintObj(test.obj, buffer); err != nil {
  269. t.Errorf("unexpected error: %v", err)
  270. }
  271. if buffer.String() != test.expectedOutput {
  272. t.Errorf("\nexpected:\n'%s'\nsaw\n'%s'\n", test.expectedOutput, buffer.String())
  273. }
  274. }
  275. }