2014-10-06 01:24:19 +00:00
/ *
2016-06-03 00:25:58 +00:00
Copyright 2014 The Kubernetes Authors .
2014-10-06 01:24:19 +00:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2017-02-19 03:40:38 +00:00
package internalversion
2014-10-06 01:24:19 +00:00
import (
"bytes"
"encoding/json"
"fmt"
"io"
"reflect"
2017-06-25 19:43:05 +00:00
"regexp"
2017-05-26 23:00:01 +00:00
"strconv"
2015-01-15 01:11:34 +00:00
"strings"
2014-10-06 01:24:19 +00:00
"testing"
2014-12-16 22:20:51 +00:00
"time"
2014-10-06 01:24:19 +00:00
2017-02-19 22:37:24 +00:00
"github.com/ghodss/yaml"
2017-06-22 18:24:23 +00:00
"k8s.io/api/core/v1"
2016-11-30 20:58:58 +00:00
"k8s.io/apimachinery/pkg/api/resource"
2017-01-11 14:09:48 +00:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2017-02-19 22:37:24 +00:00
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2017-05-26 23:00:01 +00:00
metav1alpha1 "k8s.io/apimachinery/pkg/apis/meta/v1alpha1"
2017-01-11 14:09:48 +00:00
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
yamlserializer "k8s.io/apimachinery/pkg/runtime/serializer/yaml"
"k8s.io/apimachinery/pkg/util/diff"
2017-01-27 20:42:17 +00:00
"k8s.io/apimachinery/pkg/util/intstr"
2017-01-11 14:09:48 +00:00
"k8s.io/apimachinery/pkg/util/sets"
2017-10-16 11:41:50 +00:00
"k8s.io/kubernetes/pkg/api/legacyscheme"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/api/testapi"
2017-05-30 23:10:56 +00:00
"k8s.io/kubernetes/pkg/apis/apps"
2016-11-30 20:58:58 +00:00
"k8s.io/kubernetes/pkg/apis/autoscaling"
2016-04-18 15:44:19 +00:00
"k8s.io/kubernetes/pkg/apis/batch"
2017-11-08 22:34:54 +00:00
api "k8s.io/kubernetes/pkg/apis/core"
2015-10-09 22:04:41 +00:00
"k8s.io/kubernetes/pkg/apis/extensions"
2016-11-09 12:39:16 +00:00
"k8s.io/kubernetes/pkg/apis/policy"
2017-09-15 09:55:40 +00:00
"k8s.io/kubernetes/pkg/apis/storage"
2017-02-19 22:37:24 +00:00
"k8s.io/kubernetes/pkg/printers"
2014-10-06 01:24:19 +00:00
)
2014-11-11 23:29:01 +00:00
func init ( ) {
2017-12-08 07:24:25 +00:00
legacyscheme . Scheme . AddKnownTypes ( testapi . Default . InternalGroupVersion ( ) , & TestPrintType { } )
legacyscheme . Scheme . AddKnownTypes ( legacyscheme . Registry . GroupOrDie ( api . GroupName ) . GroupVersion , & TestPrintType { } )
2014-11-11 23:29:01 +00:00
}
2017-12-08 07:24:25 +00:00
var testData = TestStruct {
2014-11-11 23:29:01 +00:00
Key : "testValue" ,
Map : map [ string ] int { "TestSubkey" : 1 } ,
StringList : [ ] string { "a" , "b" , "c" } ,
IntList : [ ] int { 1 , 2 , 3 } ,
2014-10-06 01:24:19 +00:00
}
2017-12-08 07:24:25 +00:00
type TestStruct struct {
metav1 . TypeMeta ` json:",inline" `
metav1 . ObjectMeta ` json:"metadata,omitempty" `
Key string ` json:"Key" `
Map map [ string ] int ` json:"Map" `
StringList [ ] string ` json:"StringList" `
IntList [ ] int ` json:"IntList" `
}
func ( in * TestStruct ) DeepCopyObject ( ) runtime . Object {
panic ( "never called" )
}
2014-12-31 00:42:55 +00:00
func TestVersionedPrinter ( t * testing . T ) {
2017-12-08 07:24:25 +00:00
original := & TestPrintType { Data : "value" }
2017-02-19 22:37:24 +00:00
p := printers . NewVersionedPrinter (
printers . ResourcePrinterFunc ( func ( obj runtime . Object , w io . Writer ) error {
2014-12-31 00:42:55 +00:00
if obj == original {
t . Fatalf ( "object should not be identical: %#v" , obj )
}
2017-12-08 07:24:25 +00:00
if obj . ( * TestPrintType ) . Data != "value" {
2014-12-31 00:42:55 +00:00
t . Fatalf ( "object was not converted: %#v" , obj )
}
return nil
} ) ,
2017-10-16 11:41:50 +00:00
legacyscheme . Scheme ,
legacyscheme . Registry . GroupOrDie ( api . GroupName ) . GroupVersion ,
2014-12-31 00:42:55 +00:00
)
if err := p . PrintObj ( original , nil ) ; err != nil {
t . Errorf ( "unexpected error: %v" , err )
}
}
func TestPrintDefault ( t * testing . T ) {
2017-05-23 02:47:20 +00:00
printerTests := [ ] struct {
Name string
Format string
} {
{ "test wide" , "wide" } ,
{ "test blank format" , "" } ,
2014-12-31 00:42:55 +00:00
}
2017-05-23 02:47:20 +00:00
for _ , test := range printerTests {
2017-10-30 19:54:44 +00:00
printer , err := printers . GetStandardPrinter ( nil , nil , legacyscheme . Codecs . LegacyCodec ( legacyscheme . Registry . EnabledVersions ( ) ... ) , [ ] runtime . Decoder { legacyscheme . Codecs . UniversalDecoder ( ) , unstructured . UnstructuredJSONScheme } , printers . PrintOptions { AllowMissingKeys : false } )
2017-05-23 02:47:20 +00:00
if err != nil {
t . Errorf ( "in %s, unexpected error: %#v" , test . Name , err )
}
if printer . IsGeneric ( ) {
t . Errorf ( "in %s, printer should not be generic: %#v" , test . Name , printer )
}
2014-12-31 00:42:55 +00:00
}
2014-11-18 18:04:10 +00:00
}
2017-06-25 19:43:05 +00:00
func TestPrintUnstructuredObject ( t * testing . T ) {
obj := & unstructured . Unstructured {
Object : map [ string ] interface { } {
"apiVersion" : "v1" ,
"kind" : "Test" ,
"dummy1" : "present" ,
"dummy2" : "present" ,
"metadata" : map [ string ] interface { } {
"name" : "MyName" ,
"namespace" : "MyNamespace" ,
"creationTimestamp" : "2017-04-01T00:00:00Z" ,
"resourceVersion" : 123 ,
"uid" : "00000000-0000-0000-0000-000000000001" ,
"dummy3" : "present" ,
"labels" : map [ string ] interface { } { "test" : "other" } ,
} ,
/ * "items" : [ ] interface { } {
map [ string ] interface { } {
"itemBool" : true ,
"itemInt" : 42 ,
} ,
} , * /
"url" : "http://localhost" ,
"status" : "ok" ,
} ,
}
tests := [ ] struct {
expected string
options printers . PrintOptions
object runtime . Object
} {
{
expected : "NAME\\s+AGE\nMyName\\s+\\d+" ,
object : obj ,
} ,
{
options : printers . PrintOptions {
WithNamespace : true ,
} ,
expected : "NAMESPACE\\s+NAME\\s+AGE\nMyNamespace\\s+MyName\\s+\\d+" ,
object : obj ,
} ,
{
options : printers . PrintOptions {
ShowLabels : true ,
WithNamespace : true ,
} ,
expected : "NAMESPACE\\s+NAME\\s+AGE\\s+LABELS\nMyNamespace\\s+MyName\\s+\\d+\\w+\\s+test\\=other" ,
object : obj ,
} ,
{
expected : "NAME\\s+AGE\nMyName\\s+\\d+\\w+\nMyName2\\s+\\d+" ,
object : & unstructured . Unstructured {
Object : map [ string ] interface { } {
"apiVersion" : "v1" ,
"kind" : "Test" ,
"dummy1" : "present" ,
"dummy2" : "present" ,
"items" : [ ] interface { } {
map [ string ] interface { } {
"metadata" : map [ string ] interface { } {
"name" : "MyName" ,
"namespace" : "MyNamespace" ,
"creationTimestamp" : "2017-04-01T00:00:00Z" ,
"resourceVersion" : 123 ,
"uid" : "00000000-0000-0000-0000-000000000001" ,
"dummy3" : "present" ,
"labels" : map [ string ] interface { } { "test" : "other" } ,
} ,
} ,
map [ string ] interface { } {
"metadata" : map [ string ] interface { } {
"name" : "MyName2" ,
"namespace" : "MyNamespace" ,
"creationTimestamp" : "2017-04-01T00:00:00Z" ,
"resourceVersion" : 123 ,
"uid" : "00000000-0000-0000-0000-000000000001" ,
"dummy3" : "present" ,
"labels" : "badlabel" ,
} ,
} ,
} ,
"url" : "http://localhost" ,
"status" : "ok" ,
} ,
} ,
} ,
}
out := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
out . Reset ( )
printer := printers . NewHumanReadablePrinter ( nil , nil , test . options ) . With ( AddDefaultHandlers )
printer . PrintObj ( test . object , out )
matches , err := regexp . MatchString ( test . expected , out . String ( ) )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
if ! matches {
t . Errorf ( "wanted:\n%s\ngot:\n%s" , test . expected , out )
}
}
}
2015-08-13 08:31:38 +00:00
type TestPrintType struct {
Data string
2014-11-18 18:04:10 +00:00
}
2016-11-21 02:55:31 +00:00
func ( obj * TestPrintType ) GetObjectKind ( ) schema . ObjectKind { return schema . EmptyObjectKind }
2017-07-06 08:59:05 +00:00
func ( obj * TestPrintType ) DeepCopyObject ( ) runtime . Object {
if obj == nil {
return nil
}
clone := * obj
return & clone
}
2014-11-18 18:04:10 +00:00
2015-08-13 08:31:38 +00:00
type TestUnknownType struct { }
2014-10-30 02:32:25 +00:00
2016-11-21 02:55:31 +00:00
func ( obj * TestUnknownType ) GetObjectKind ( ) schema . ObjectKind { return schema . EmptyObjectKind }
2017-07-06 08:59:05 +00:00
func ( obj * TestUnknownType ) DeepCopyObject ( ) runtime . Object {
if obj == nil {
return nil
}
clone := * obj
return & clone
}
2014-10-30 02:32:25 +00:00
2015-08-13 08:31:38 +00:00
func TestPrinter ( t * testing . T ) {
//test inputs
simpleTest := & TestPrintType { "foo" }
2017-01-17 03:38:19 +00:00
podTest := & api . Pod { ObjectMeta : metav1 . ObjectMeta { Name : "foo" } }
2015-08-13 21:11:23 +00:00
podListTest := & api . PodList {
Items : [ ] api . Pod {
2017-01-17 03:38:19 +00:00
{ ObjectMeta : metav1 . ObjectMeta { Name : "foo" } } ,
{ ObjectMeta : metav1 . ObjectMeta { Name : "bar" } } ,
2015-08-13 21:11:23 +00:00
} ,
}
emptyListTest := & api . PodList { }
2017-10-16 11:41:50 +00:00
testapi , err := legacyscheme . Scheme . ConvertToVersion ( podTest , legacyscheme . Registry . GroupOrDie ( api . GroupName ) . GroupVersion )
2014-11-07 22:41:59 +00:00
if err != nil {
2015-08-13 08:31:38 +00:00
t . Fatalf ( "unexpected error: %v" , err )
2014-10-30 02:32:25 +00:00
}
2015-08-13 08:31:38 +00:00
printerTests := [ ] struct {
Name string
2017-10-30 19:54:44 +00:00
PrintOpts * printers . PrintOptions
2015-08-13 08:31:38 +00:00
Input runtime . Object
2016-12-09 18:38:44 +00:00
OutputVersions [ ] schema . GroupVersion
2015-08-13 08:31:38 +00:00
Expect string
} {
2017-10-30 19:54:44 +00:00
{ "test json" , & printers . PrintOptions { OutputFormatType : "json" , AllowMissingKeys : true } , simpleTest , nil , "{\n \"Data\": \"foo\"\n}\n" } ,
{ "test yaml" , & printers . PrintOptions { OutputFormatType : "yaml" , AllowMissingKeys : true } , simpleTest , nil , "Data: foo\n" } ,
{ "test template" , & printers . PrintOptions { OutputFormatType : "template" , OutputFormatArgument : "{{if .id}}{{.id}}{{end}}{{if .metadata.name}}{{.metadata.name}}{{end}}" , AllowMissingKeys : true } ,
2016-12-09 18:38:44 +00:00
podTest , [ ] schema . GroupVersion { v1 . SchemeGroupVersion } , "foo" } ,
2017-10-30 19:54:44 +00:00
{ "test jsonpath" , & printers . PrintOptions { OutputFormatType : "jsonpath" , OutputFormatArgument : "{.metadata.name}" , AllowMissingKeys : true } , podTest , [ ] schema . GroupVersion { v1 . SchemeGroupVersion } , "foo" } ,
{ "test jsonpath list" , & printers . PrintOptions { OutputFormatType : "jsonpath" , OutputFormatArgument : "{.items[*].metadata.name}" , AllowMissingKeys : true } , podListTest , [ ] schema . GroupVersion { v1 . SchemeGroupVersion } , "foo bar" } ,
{ "test jsonpath empty list" , & printers . PrintOptions { OutputFormatType : "jsonpath" , OutputFormatArgument : "{.items[*].metadata.name}" , AllowMissingKeys : true } , emptyListTest , [ ] schema . GroupVersion { v1 . SchemeGroupVersion } , "" } ,
{ "test name" , & printers . PrintOptions { OutputFormatType : "name" , AllowMissingKeys : true } , podTest , [ ] schema . GroupVersion { v1 . SchemeGroupVersion } , "pods/foo\n" } ,
{ "emits versioned objects" , & printers . PrintOptions { OutputFormatType : "template" , OutputFormatArgument : "{{.kind}}" , AllowMissingKeys : true } , testapi , [ ] schema . GroupVersion { v1 . SchemeGroupVersion } , "Pod" } ,
2015-08-13 08:31:38 +00:00
}
for _ , test := range printerTests {
buf := bytes . NewBuffer ( [ ] byte { } )
2017-10-30 19:54:44 +00:00
printer , err := printers . GetStandardPrinter ( legacyscheme . Registry . RESTMapper ( legacyscheme . Registry . EnabledVersions ( ) ... ) , legacyscheme . Scheme , legacyscheme . Codecs . LegacyCodec ( legacyscheme . Registry . EnabledVersions ( ) ... ) , [ ] runtime . Decoder { legacyscheme . Codecs . UniversalDecoder ( ) , unstructured . UnstructuredJSONScheme } , * test . PrintOpts )
2016-12-09 18:38:44 +00:00
if err != nil {
2015-12-21 05:34:11 +00:00
t . Errorf ( "in %s, unexpected error: %#v" , test . Name , err )
2015-08-13 08:31:38 +00:00
}
2017-05-23 02:47:20 +00:00
if printer . IsGeneric ( ) && len ( test . OutputVersions ) > 0 {
2017-10-16 11:41:50 +00:00
printer = printers . NewVersionedPrinter ( printer , legacyscheme . Scheme , test . OutputVersions ... )
2016-12-09 18:38:44 +00:00
}
2015-08-13 08:31:38 +00:00
if err := printer . PrintObj ( test . Input , buf ) ; err != nil {
2015-12-21 05:34:11 +00:00
t . Errorf ( "in %s, unexpected error: %#v" , test . Name , err )
2015-08-13 08:31:38 +00:00
}
if buf . String ( ) != test . Expect {
2015-08-13 21:11:23 +00:00
t . Errorf ( "in %s, expect %q, got %q" , test . Name , test . Expect , buf . String ( ) )
2015-08-13 08:31:38 +00:00
}
2014-10-30 02:32:25 +00:00
}
}
2015-08-13 08:31:38 +00:00
func TestBadPrinter ( t * testing . T ) {
badPrinterTests := [ ] struct {
2017-10-30 19:54:44 +00:00
Name string
PrintOpts * printers . PrintOptions
Error error
2015-08-13 08:31:38 +00:00
} {
2017-10-30 19:54:44 +00:00
{ "empty template" , & printers . PrintOptions { OutputFormatType : "template" , AllowMissingKeys : false } , fmt . Errorf ( "template format specified but no template given" ) } ,
{ "bad template" , & printers . PrintOptions { OutputFormatType : "template" , OutputFormatArgument : "{{ .Name" , AllowMissingKeys : false } , fmt . Errorf ( "error parsing template {{ .Name, template: output:1: unclosed action\n" ) } ,
{ "bad templatefile" , & printers . PrintOptions { OutputFormatType : "templatefile" , AllowMissingKeys : false } , fmt . Errorf ( "templatefile format specified but no template file given" ) } ,
{ "bad jsonpath" , & printers . PrintOptions { OutputFormatType : "jsonpath" , OutputFormatArgument : "{.Name" , AllowMissingKeys : false } , fmt . Errorf ( "error parsing jsonpath {.Name, unclosed action\n" ) } ,
{ "unknown format" , & printers . PrintOptions { OutputFormatType : "anUnknownFormat" , OutputFormatArgument : "" , AllowMissingKeys : false } , fmt . Errorf ( "output format \"anUnknownFormat\" not recognized" ) } ,
2015-08-13 08:31:38 +00:00
}
for _ , test := range badPrinterTests {
2017-10-30 19:54:44 +00:00
_ , err := printers . GetStandardPrinter ( legacyscheme . Registry . RESTMapper ( legacyscheme . Registry . EnabledVersions ( ) ... ) , legacyscheme . Scheme , legacyscheme . Codecs . LegacyCodec ( legacyscheme . Registry . EnabledVersions ( ) ... ) , [ ] runtime . Decoder { legacyscheme . Codecs . UniversalDecoder ( ) , unstructured . UnstructuredJSONScheme } , * test . PrintOpts )
2015-08-13 08:31:38 +00:00
if err == nil || err . Error ( ) != test . Error . Error ( ) {
t . Errorf ( "in %s, expect %s, got %s" , test . Name , test . Error , err )
}
2014-10-30 02:32:25 +00:00
}
}
2017-02-19 22:37:24 +00:00
func testPrinter ( t * testing . T , printer printers . ResourcePrinter , unmarshalFunc func ( data [ ] byte , v interface { } ) error ) {
2014-10-06 01:24:19 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
err := printer . PrintObj ( & testData , buf )
if err != nil {
t . Fatal ( err )
}
2017-12-08 07:24:25 +00:00
var poutput TestStruct
2014-11-11 23:29:01 +00:00
// Verify that given function runs without error.
err = unmarshalFunc ( buf . Bytes ( ) , & poutput )
if err != nil {
t . Fatal ( err )
}
// Use real decode function to undo the versioning process.
2017-12-08 07:24:25 +00:00
poutput = TestStruct { }
2015-12-21 05:34:11 +00:00
s := yamlserializer . NewDecodingSerializer ( testapi . Default . Codec ( ) )
if err := runtime . DecodeInto ( s , buf . Bytes ( ) , & poutput ) ; err != nil {
2014-10-06 01:24:19 +00:00
t . Fatal ( err )
}
if ! reflect . DeepEqual ( testData , poutput ) {
2016-03-11 02:43:55 +00:00
t . Errorf ( "Test data and unmarshaled data are not equal: %v" , diff . ObjectDiff ( poutput , testData ) )
2014-10-06 01:24:19 +00:00
}
obj := & api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo" } ,
2014-10-06 01:24:19 +00:00
}
buf . Reset ( )
printer . PrintObj ( obj , buf )
var objOut api . Pod
2014-11-11 23:29:01 +00:00
// Verify that given function runs without error.
err = unmarshalFunc ( buf . Bytes ( ) , & objOut )
2014-10-06 01:24:19 +00:00
if err != nil {
2014-11-18 18:04:10 +00:00
t . Fatalf ( "unexpected error: %#v" , err )
2014-10-06 01:24:19 +00:00
}
2014-11-11 23:29:01 +00:00
// Use real decode function to undo the versioning process.
objOut = api . Pod { }
2015-12-21 05:34:11 +00:00
if err := runtime . DecodeInto ( s , buf . Bytes ( ) , & objOut ) ; err != nil {
2014-11-11 23:29:01 +00:00
t . Fatal ( err )
}
2014-10-06 01:24:19 +00:00
if ! reflect . DeepEqual ( obj , & objOut ) {
2016-03-11 02:43:55 +00:00
t . Errorf ( "Unexpected inequality:\n%v" , diff . ObjectDiff ( obj , & objOut ) )
2014-10-06 01:24:19 +00:00
}
}
2015-08-13 08:31:38 +00:00
func TestYAMLPrinter ( t * testing . T ) {
2017-02-19 22:37:24 +00:00
testPrinter ( t , & printers . YAMLPrinter { } , yaml . Unmarshal )
2014-10-06 01:24:19 +00:00
}
2015-08-13 08:31:38 +00:00
func TestJSONPrinter ( t * testing . T ) {
2017-02-19 22:37:24 +00:00
testPrinter ( t , & printers . JSONPrinter { } , json . Unmarshal )
2015-08-13 08:31:38 +00:00
}
2014-10-06 01:24:19 +00:00
2016-07-22 22:01:59 +00:00
func TestFormatResourceName ( t * testing . T ) {
tests := [ ] struct {
kind , name string
want string
} {
{ "" , "" , "" } ,
{ "" , "name" , "name" } ,
{ "kind" , "" , "kind/" } , // should not happen in practice
{ "kind" , "name" , "kind/name" } ,
}
for _ , tt := range tests {
2017-03-14 09:11:51 +00:00
if got := printers . FormatResourceName ( tt . kind , tt . name , true ) ; got != tt . want {
2016-07-22 22:01:59 +00:00
t . Errorf ( "formatResourceName(%q, %q) = %q, want %q" , tt . kind , tt . name , got , tt . want )
}
}
}
2017-02-19 22:37:24 +00:00
func PrintCustomType ( obj * TestPrintType , w io . Writer , options printers . PrintOptions ) error {
2016-06-29 22:02:08 +00:00
data := obj . Data
2016-07-22 22:01:59 +00:00
kind := options . Kind
2016-06-29 22:02:08 +00:00
if options . WithKind {
data = kind + "/" + data
}
_ , err := fmt . Fprintf ( w , "%s" , data )
2014-10-06 01:24:19 +00:00
return err
}
2017-02-19 22:37:24 +00:00
func ErrorPrintHandler ( obj * TestPrintType , w io . Writer , options printers . PrintOptions ) error {
2014-10-06 01:24:19 +00:00
return fmt . Errorf ( "ErrorPrintHandler error" )
}
func TestCustomTypePrinting ( t * testing . T ) {
columns := [ ] string { "Data" }
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions { } )
2017-01-04 16:32:14 +00:00
printer . Handler ( columns , nil , PrintCustomType )
2014-10-06 01:24:19 +00:00
obj := TestPrintType { "test object" }
buffer := & bytes . Buffer { }
err := printer . PrintObj ( & obj , buffer )
if err != nil {
2014-11-18 18:04:10 +00:00
t . Fatalf ( "An error occurred printing the custom type: %#v" , err )
2014-10-06 01:24:19 +00:00
}
2017-05-26 23:00:01 +00:00
expectedOutput := "DATA\ntest object"
2014-10-06 01:24:19 +00:00
if buffer . String ( ) != expectedOutput {
t . Errorf ( "The data was not printed as expected. Expected:\n%s\nGot:\n%s" , expectedOutput , buffer . String ( ) )
}
}
2016-06-29 22:02:08 +00:00
func TestCustomTypePrintingWithKind ( t * testing . T ) {
columns := [ ] string { "Data" }
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions { } )
2017-01-04 16:32:14 +00:00
printer . Handler ( columns , nil , PrintCustomType )
2016-07-22 22:01:59 +00:00
printer . EnsurePrintWithKind ( "test" )
2016-06-29 22:02:08 +00:00
obj := TestPrintType { "test object" }
buffer := & bytes . Buffer { }
err := printer . PrintObj ( & obj , buffer )
if err != nil {
t . Fatalf ( "An error occurred printing the custom type: %#v" , err )
}
2017-05-26 23:00:01 +00:00
expectedOutput := "DATA\ntest/test object"
2016-06-29 22:02:08 +00:00
if buffer . String ( ) != expectedOutput {
t . Errorf ( "The data was not printed as expected. Expected:\n%s\nGot:\n%s" , expectedOutput , buffer . String ( ) )
}
}
2014-10-06 01:24:19 +00:00
func TestPrintHandlerError ( t * testing . T ) {
columns := [ ] string { "Data" }
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions { } )
2017-01-04 16:32:14 +00:00
printer . Handler ( columns , nil , ErrorPrintHandler )
2014-10-06 01:24:19 +00:00
obj := TestPrintType { "test object" }
buffer := & bytes . Buffer { }
err := printer . PrintObj ( & obj , buffer )
if err == nil || err . Error ( ) != "ErrorPrintHandler error" {
t . Errorf ( "Did not get the expected error: %#v" , err )
}
}
func TestUnknownTypePrinting ( t * testing . T ) {
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions { } )
2014-10-06 01:24:19 +00:00
buffer := & bytes . Buffer { }
err := printer . PrintObj ( & TestUnknownType { } , buffer )
if err == nil {
t . Errorf ( "An error was expected from printing unknown type" )
}
}
2014-11-07 22:41:59 +00:00
2014-12-23 19:21:38 +00:00
func TestTemplatePanic ( t * testing . T ) {
2015-01-28 18:13:02 +00:00
tmpl := ` {{ and ( ( index .currentState .info "foo" ) .state .running .startedAt ) .currentState .info .net .state .running .startedAt }} `
2017-02-19 22:37:24 +00:00
printer , err := printers . NewTemplatePrinter ( [ ] byte ( tmpl ) )
2014-12-23 19:21:38 +00:00
if err != nil {
t . Fatalf ( "tmpl fail: %v" , err )
}
buffer := & bytes . Buffer { }
err = printer . PrintObj ( & api . Pod { } , buffer )
if err == nil {
t . Fatalf ( "expected that template to crash" )
}
if buffer . String ( ) == "" {
t . Errorf ( "no debugging info was printed" )
}
}
2015-08-18 07:35:35 +00:00
func TestNamePrinter ( t * testing . T ) {
tests := map [ string ] struct {
obj runtime . Object
expect string
} {
"singleObject" : {
& api . Pod {
2016-12-03 18:57:26 +00:00
TypeMeta : metav1 . TypeMeta {
2015-08-18 07:35:35 +00:00
Kind : "Pod" ,
} ,
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2015-08-18 07:35:35 +00:00
Name : "foo" ,
} ,
} ,
2017-02-19 22:37:48 +00:00
"pods/foo\n" } ,
2015-08-18 07:35:35 +00:00
"List" : {
& v1 . List {
2016-12-03 18:57:26 +00:00
TypeMeta : metav1 . TypeMeta {
2015-08-18 07:35:35 +00:00
Kind : "List" ,
} ,
Items : [ ] runtime . RawExtension {
{
2016-03-17 10:32:14 +00:00
Raw : [ ] byte ( ` { "kind": "Pod", "apiVersion": "v1", "metadata": { "name": "foo"}} ` ) ,
2015-08-18 07:35:35 +00:00
} ,
{
2016-03-17 10:32:14 +00:00
Raw : [ ] byte ( ` { "kind": "Pod", "apiVersion": "v1", "metadata": { "name": "bar"}} ` ) ,
2015-08-18 07:35:35 +00:00
} ,
} ,
} ,
2017-02-19 22:37:48 +00:00
"pods/foo\npods/bar\n" } ,
2015-08-18 07:35:35 +00:00
}
2017-10-30 19:54:44 +00:00
printOpts := & printers . PrintOptions { OutputFormatType : "name" , AllowMissingKeys : false }
printer , _ := printers . GetStandardPrinter ( legacyscheme . Registry . RESTMapper ( legacyscheme . Registry . EnabledVersions ( ) ... ) , legacyscheme . Scheme , legacyscheme . Codecs . LegacyCodec ( legacyscheme . Registry . EnabledVersions ( ) ... ) , [ ] runtime . Decoder { legacyscheme . Codecs . UniversalDecoder ( ) , unstructured . UnstructuredJSONScheme } , * printOpts )
2015-08-18 07:35:35 +00:00
for name , item := range tests {
buff := & bytes . Buffer { }
err := printer . PrintObj ( item . obj , buff )
if err != nil {
t . Errorf ( "%v: unexpected err: %v" , name , err )
continue
}
got := buff . String ( )
if item . expect != got {
t . Errorf ( "%v: expected %v, got %v" , name , item . expect , got )
}
}
}
2014-12-23 22:05:26 +00:00
func TestTemplateStrings ( t * testing . T ) {
// This unit tests the "exists" function as well as the template from update.sh
table := map [ string ] struct {
pod api . Pod
expect string
} {
"nilInfo" : { api . Pod { } , "false" } ,
2015-03-25 11:09:35 +00:00
"emptyInfo" : { api . Pod { Status : api . PodStatus { ContainerStatuses : [ ] api . ContainerStatus { } } } , "false" } ,
2015-01-28 18:13:02 +00:00
"fooExists" : {
2014-12-23 22:05:26 +00:00
api . Pod {
Status : api . PodStatus {
2015-03-25 11:09:35 +00:00
ContainerStatuses : [ ] api . ContainerStatus {
{
Name : "foo" ,
} ,
} ,
2014-12-23 22:05:26 +00:00
} ,
} ,
"false" ,
} ,
2015-01-28 18:13:02 +00:00
"barExists" : {
2014-12-23 22:05:26 +00:00
api . Pod {
Status : api . PodStatus {
2015-03-25 11:09:35 +00:00
ContainerStatuses : [ ] api . ContainerStatus {
{
Name : "bar" ,
} ,
} ,
2014-12-23 22:05:26 +00:00
} ,
} ,
"false" ,
} ,
"bothExist" : {
api . Pod {
Status : api . PodStatus {
2015-03-25 11:09:35 +00:00
ContainerStatuses : [ ] api . ContainerStatus {
{
Name : "foo" ,
} ,
{
Name : "bar" ,
} ,
2014-12-23 22:05:26 +00:00
} ,
} ,
} ,
"false" ,
} ,
2015-04-08 17:22:33 +00:00
"barValid" : {
2014-12-23 22:05:26 +00:00
api . Pod {
Status : api . PodStatus {
2015-03-25 11:09:35 +00:00
ContainerStatuses : [ ] api . ContainerStatus {
{
Name : "foo" ,
} ,
{
Name : "bar" ,
2014-12-23 22:05:26 +00:00
State : api . ContainerState {
Running : & api . ContainerStateRunning {
2016-12-03 18:57:26 +00:00
StartedAt : metav1 . Time { } ,
2014-12-23 22:05:26 +00:00
} ,
} ,
} ,
} ,
} ,
} ,
"false" ,
} ,
"bothValid" : {
api . Pod {
Status : api . PodStatus {
2015-03-25 11:09:35 +00:00
ContainerStatuses : [ ] api . ContainerStatus {
{
Name : "foo" ,
2014-12-23 22:05:26 +00:00
State : api . ContainerState {
Running : & api . ContainerStateRunning {
2016-12-03 18:57:26 +00:00
StartedAt : metav1 . Time { } ,
2014-12-23 22:05:26 +00:00
} ,
} ,
} ,
2015-03-25 11:09:35 +00:00
{
Name : "bar" ,
2014-12-23 22:05:26 +00:00
State : api . ContainerState {
Running : & api . ContainerStateRunning {
2016-12-03 18:57:26 +00:00
StartedAt : metav1 . Time { } ,
2014-12-23 22:05:26 +00:00
} ,
} ,
} ,
} ,
} ,
} ,
"true" ,
} ,
}
2015-07-28 14:59:28 +00:00
// The point of this test is to verify that the below template works.
2015-06-04 03:09:03 +00:00
tmpl := ` {{ if ( exists . "status" "containerStatuses" ) }} {{ range .status .containerStatuses }} {{ if ( and ( eq .name "foo" ) ( exists . "state" "running" ) ) }} true {{ end }} {{ end }} {{ end }} `
2017-02-19 22:37:24 +00:00
p , err := printers . NewTemplatePrinter ( [ ] byte ( tmpl ) )
2014-12-23 22:05:26 +00:00
if err != nil {
t . Fatalf ( "tmpl fail: %v" , err )
}
2017-10-16 11:41:50 +00:00
printer := printers . NewVersionedPrinter ( p , legacyscheme . Scheme , legacyscheme . Registry . GroupOrDie ( api . GroupName ) . GroupVersion )
2014-12-31 00:42:55 +00:00
2014-12-23 22:05:26 +00:00
for name , item := range table {
buffer := & bytes . Buffer { }
err = printer . PrintObj ( & item . pod , buffer )
if err != nil {
t . Errorf ( "%v: unexpected err: %v" , name , err )
continue
}
2015-04-08 17:22:33 +00:00
actual := buffer . String ( )
if len ( actual ) == 0 {
actual = "false"
}
if e := item . expect ; e != actual {
t . Errorf ( "%v: expected %v, got %v" , name , e , actual )
2014-12-23 22:05:26 +00:00
}
}
}
2014-11-20 22:09:59 +00:00
func TestPrinters ( t * testing . T ) {
2017-01-17 03:38:19 +00:00
om := func ( name string ) metav1 . ObjectMeta { return metav1 . ObjectMeta { Name : name } }
2016-12-09 18:38:44 +00:00
var (
err error
2017-02-19 22:37:24 +00:00
templatePrinter printers . ResourcePrinter
templatePrinter2 printers . ResourcePrinter
jsonpathPrinter printers . ResourcePrinter
2016-12-09 18:38:44 +00:00
)
2017-02-19 22:37:24 +00:00
templatePrinter , err = printers . NewTemplatePrinter ( [ ] byte ( "{{.name}}" ) )
2014-11-20 22:09:59 +00:00
if err != nil {
t . Fatal ( err )
}
2017-10-16 11:41:50 +00:00
templatePrinter = printers . NewVersionedPrinter ( templatePrinter , legacyscheme . Scheme , v1 . SchemeGroupVersion )
2016-12-09 18:38:44 +00:00
2017-02-19 22:37:24 +00:00
templatePrinter2 , err = printers . NewTemplatePrinter ( [ ] byte ( "{{len .items}}" ) )
2014-11-20 22:09:59 +00:00
if err != nil {
t . Fatal ( err )
}
2017-10-16 11:41:50 +00:00
templatePrinter2 = printers . NewVersionedPrinter ( templatePrinter2 , legacyscheme . Scheme , v1 . SchemeGroupVersion )
2016-12-09 18:38:44 +00:00
2017-02-19 22:37:24 +00:00
jsonpathPrinter , err = printers . NewJSONPathPrinter ( "{.metadata.name}" )
2015-08-04 08:14:31 +00:00
if err != nil {
t . Fatal ( err )
}
2017-10-16 11:41:50 +00:00
jsonpathPrinter = printers . NewVersionedPrinter ( jsonpathPrinter , legacyscheme . Scheme , v1 . SchemeGroupVersion )
2016-12-09 18:38:44 +00:00
2017-02-19 22:37:24 +00:00
allPrinters := map [ string ] printers . ResourcePrinter {
2017-02-28 22:45:09 +00:00
"humanReadable" : printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions {
2016-12-27 04:10:05 +00:00
NoHeaders : true ,
2016-06-23 14:49:31 +00:00
} ) ,
2017-02-28 22:45:09 +00:00
"humanReadableHeaders" : printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions { } ) ,
2017-02-19 22:37:24 +00:00
"json" : & printers . JSONPrinter { } ,
"yaml" : & printers . YAMLPrinter { } ,
2016-12-27 04:10:05 +00:00
"template" : templatePrinter ,
"template2" : templatePrinter2 ,
"jsonpath" : jsonpathPrinter ,
2017-02-19 22:37:24 +00:00
"name" : & printers . NamePrinter {
2017-10-16 11:41:50 +00:00
Typer : legacyscheme . Scheme ,
Decoders : [ ] runtime . Decoder { legacyscheme . Codecs . UniversalDecoder ( ) , unstructured . UnstructuredJSONScheme } ,
Mapper : legacyscheme . Registry . RESTMapper ( legacyscheme . Registry . EnabledVersions ( ) ... ) ,
2015-12-21 05:34:11 +00:00
} ,
2014-11-20 22:09:59 +00:00
}
2017-02-19 22:37:24 +00:00
AddHandlers ( ( allPrinters [ "humanReadable" ] ) . ( * printers . HumanReadablePrinter ) )
AddHandlers ( ( allPrinters [ "humanReadableHeaders" ] ) . ( * printers . HumanReadablePrinter ) )
2014-11-20 22:09:59 +00:00
objects := map [ string ] runtime . Object {
"pod" : & api . Pod { ObjectMeta : om ( "pod" ) } ,
"emptyPodList" : & api . PodList { } ,
"nonEmptyPodList" : & api . PodList { Items : [ ] api . Pod { { } } } ,
2015-03-20 21:24:43 +00:00
"endpoints" : & api . Endpoints {
Subsets : [ ] api . EndpointSubset { {
Addresses : [ ] api . EndpointAddress { { IP : "127.0.0.1" } , { IP : "localhost" } } ,
Ports : [ ] api . EndpointPort { { Port : 8080 } } ,
} } } ,
2014-11-20 22:09:59 +00:00
}
// map of printer name to set of objects it should fail on.
2015-09-09 17:45:01 +00:00
expectedErrors := map [ string ] sets . String {
"template2" : sets . NewString ( "pod" , "emptyPodList" , "endpoints" ) ,
"jsonpath" : sets . NewString ( "emptyPodList" , "nonEmptyPodList" , "endpoints" ) ,
2014-11-20 22:09:59 +00:00
}
2017-02-19 22:37:24 +00:00
for pName , p := range allPrinters {
2014-11-20 22:09:59 +00:00
for oName , obj := range objects {
b := & bytes . Buffer { }
if err := p . PrintObj ( obj , b ) ; err != nil {
if set , found := expectedErrors [ pName ] ; found && set . Has ( oName ) {
// expected error
continue
}
t . Errorf ( "printer '%v', object '%v'; error: '%v'" , pName , oName , err )
}
}
}
}
2014-12-16 22:20:51 +00:00
func TestPrintEventsResultSorted ( t * testing . T ) {
// Arrange
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions { } )
2017-02-19 22:37:24 +00:00
AddHandlers ( printer )
2014-12-16 22:20:51 +00:00
obj := api . EventList {
Items : [ ] api . Event {
{
2015-02-06 02:21:01 +00:00
Source : api . EventSource { Component : "kubelet" } ,
Message : "Item 1" ,
2016-12-03 18:57:26 +00:00
FirstTimestamp : metav1 . NewTime ( time . Date ( 2014 , time . January , 15 , 0 , 0 , 0 , 0 , time . UTC ) ) ,
LastTimestamp : metav1 . NewTime ( time . Date ( 2014 , time . January , 15 , 0 , 0 , 0 , 0 , time . UTC ) ) ,
2015-02-06 02:21:01 +00:00
Count : 1 ,
2015-11-13 22:30:45 +00:00
Type : api . EventTypeNormal ,
2014-12-16 22:20:51 +00:00
} ,
{
2015-02-06 02:21:01 +00:00
Source : api . EventSource { Component : "scheduler" } ,
Message : "Item 2" ,
2016-12-03 18:57:26 +00:00
FirstTimestamp : metav1 . NewTime ( time . Date ( 1987 , time . June , 17 , 0 , 0 , 0 , 0 , time . UTC ) ) ,
LastTimestamp : metav1 . NewTime ( time . Date ( 1987 , time . June , 17 , 0 , 0 , 0 , 0 , time . UTC ) ) ,
2015-02-06 02:21:01 +00:00
Count : 1 ,
2015-11-13 22:30:45 +00:00
Type : api . EventTypeNormal ,
2014-12-16 22:20:51 +00:00
} ,
{
2015-02-06 02:21:01 +00:00
Source : api . EventSource { Component : "kubelet" } ,
Message : "Item 3" ,
2016-12-03 18:57:26 +00:00
FirstTimestamp : metav1 . NewTime ( time . Date ( 2002 , time . December , 25 , 0 , 0 , 0 , 0 , time . UTC ) ) ,
LastTimestamp : metav1 . NewTime ( time . Date ( 2002 , time . December , 25 , 0 , 0 , 0 , 0 , time . UTC ) ) ,
2015-02-06 02:21:01 +00:00
Count : 1 ,
2015-11-13 22:30:45 +00:00
Type : api . EventTypeNormal ,
2014-12-16 22:20:51 +00:00
} ,
} ,
}
buffer := & bytes . Buffer { }
// Act
err := printer . PrintObj ( & obj , buffer )
// Assert
if err != nil {
t . Fatalf ( "An error occurred printing the EventList: %#v" , err )
}
out := buffer . String ( )
VerifyDatesInOrder ( out , "\n" /* rowDelimiter */ , " " /* columnDelimiter */ , t )
}
2015-01-15 01:11:34 +00:00
2015-09-09 14:18:17 +00:00
func TestPrintNodeStatus ( t * testing . T ) {
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions { } )
2017-02-19 22:37:24 +00:00
AddHandlers ( printer )
2015-01-15 01:11:34 +00:00
table := [ ] struct {
2015-09-09 14:18:17 +00:00
node api . Node
2015-01-15 01:11:34 +00:00
status string
} {
{
2015-09-09 14:18:17 +00:00
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo1" } ,
2015-03-23 18:33:55 +00:00
Status : api . NodeStatus { Conditions : [ ] api . NodeCondition { { Type : api . NodeReady , Status : api . ConditionTrue } } } ,
2015-01-15 01:11:34 +00:00
} ,
status : "Ready" ,
} ,
2015-04-16 01:53:03 +00:00
{
2015-09-09 14:18:17 +00:00
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo2" } ,
2015-04-16 01:53:03 +00:00
Spec : api . NodeSpec { Unschedulable : true } ,
Status : api . NodeStatus { Conditions : [ ] api . NodeCondition { { Type : api . NodeReady , Status : api . ConditionTrue } } } ,
} ,
status : "Ready,SchedulingDisabled" ,
} ,
2015-01-15 01:11:34 +00:00
{
2015-09-09 14:18:17 +00:00
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo3" } ,
2015-01-15 01:11:34 +00:00
Status : api . NodeStatus { Conditions : [ ] api . NodeCondition {
2015-03-23 18:33:55 +00:00
{ Type : api . NodeReady , Status : api . ConditionTrue } ,
{ Type : api . NodeReady , Status : api . ConditionTrue } } } ,
2015-01-15 01:11:34 +00:00
} ,
status : "Ready" ,
} ,
{
2015-09-09 14:18:17 +00:00
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo4" } ,
2015-03-23 18:33:55 +00:00
Status : api . NodeStatus { Conditions : [ ] api . NodeCondition { { Type : api . NodeReady , Status : api . ConditionFalse } } } ,
2015-01-15 01:11:34 +00:00
} ,
status : "NotReady" ,
} ,
{
2015-09-09 14:18:17 +00:00
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo5" } ,
2015-04-16 01:53:03 +00:00
Spec : api . NodeSpec { Unschedulable : true } ,
Status : api . NodeStatus { Conditions : [ ] api . NodeCondition { { Type : api . NodeReady , Status : api . ConditionFalse } } } ,
} ,
status : "NotReady,SchedulingDisabled" ,
} ,
{
2015-09-09 14:18:17 +00:00
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo6" } ,
2015-03-23 18:33:55 +00:00
Status : api . NodeStatus { Conditions : [ ] api . NodeCondition { { Type : "InvalidValue" , Status : api . ConditionTrue } } } ,
2015-01-15 01:11:34 +00:00
} ,
status : "Unknown" ,
} ,
{
2015-09-09 14:18:17 +00:00
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo7" } ,
2015-01-15 01:11:34 +00:00
Status : api . NodeStatus { Conditions : [ ] api . NodeCondition { { } } } ,
} ,
status : "Unknown" ,
} ,
2015-04-16 01:53:03 +00:00
{
2015-09-09 14:18:17 +00:00
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo8" } ,
2015-04-16 01:53:03 +00:00
Spec : api . NodeSpec { Unschedulable : true } ,
Status : api . NodeStatus { Conditions : [ ] api . NodeCondition { { Type : "InvalidValue" , Status : api . ConditionTrue } } } ,
} ,
status : "Unknown,SchedulingDisabled" ,
} ,
{
2015-09-09 14:18:17 +00:00
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo9" } ,
2015-04-16 01:53:03 +00:00
Spec : api . NodeSpec { Unschedulable : true } ,
Status : api . NodeStatus { Conditions : [ ] api . NodeCondition { { } } } ,
} ,
status : "Unknown,SchedulingDisabled" ,
} ,
2017-08-23 04:48:59 +00:00
}
for _ , test := range table {
buffer := & bytes . Buffer { }
err := printer . PrintObj ( & test . node , buffer )
if err != nil {
t . Fatalf ( "An error occurred printing Node: %#v" , err )
}
if ! contains ( strings . Fields ( buffer . String ( ) ) , test . status ) {
t . Fatalf ( "Expect printing node %s with status %#v, got: %#v" , test . node . Name , test . status , buffer . String ( ) )
}
}
}
func TestPrintNodeRole ( t * testing . T ) {
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions { } )
AddHandlers ( printer )
table := [ ] struct {
node api . Node
expected string
} {
2017-08-10 08:19:13 +00:00
{
node : api . Node {
2017-08-23 04:48:59 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo9" } ,
2017-08-10 08:19:13 +00:00
} ,
2017-08-23 04:48:59 +00:00
expected : "<none>" ,
2017-08-10 08:19:13 +00:00
} ,
{
node : api . Node {
ObjectMeta : metav1 . ObjectMeta {
2017-08-23 04:48:59 +00:00
Name : "foo10" ,
Labels : map [ string ] string { "node-role.kubernetes.io/master" : "" , "node-role.kubernetes.io/proxy" : "" , "kubernetes.io/role" : "node" } ,
2017-08-10 08:19:13 +00:00
} ,
} ,
2017-08-23 04:48:59 +00:00
expected : "master,node,proxy" ,
2017-08-10 08:19:13 +00:00
} ,
2017-07-18 20:43:47 +00:00
{
node : api . Node {
ObjectMeta : metav1 . ObjectMeta {
2017-08-23 04:48:59 +00:00
Name : "foo11" ,
Labels : map [ string ] string { "kubernetes.io/role" : "node" } ,
2017-07-18 20:43:47 +00:00
} ,
} ,
2017-08-23 04:48:59 +00:00
expected : "node" ,
2017-07-18 20:43:47 +00:00
} ,
2015-01-15 01:11:34 +00:00
}
for _ , test := range table {
buffer := & bytes . Buffer { }
2015-09-09 14:18:17 +00:00
err := printer . PrintObj ( & test . node , buffer )
2015-01-15 01:11:34 +00:00
if err != nil {
2015-09-09 14:18:17 +00:00
t . Fatalf ( "An error occurred printing Node: %#v" , err )
2015-01-15 01:11:34 +00:00
}
2017-08-23 04:48:59 +00:00
if ! contains ( strings . Fields ( buffer . String ( ) ) , test . expected ) {
t . Fatalf ( "Expect printing node %s with role %#v, got: %#v" , test . node . Name , test . expected , buffer . String ( ) )
2015-01-15 01:11:34 +00:00
}
}
}
2016-12-16 05:42:59 +00:00
func TestPrintNodeOSImage ( t * testing . T ) {
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions {
2016-12-16 05:42:59 +00:00
ColumnLabels : [ ] string { } ,
Wide : true ,
} )
2017-02-19 22:37:24 +00:00
AddHandlers ( printer )
2016-12-16 05:42:59 +00:00
table := [ ] struct {
node api . Node
osImage string
} {
{
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo1" } ,
2016-12-16 05:42:59 +00:00
Status : api . NodeStatus {
NodeInfo : api . NodeSystemInfo { OSImage : "fake-os-image" } ,
Addresses : [ ] api . NodeAddress { { Type : api . NodeExternalIP , Address : "1.1.1.1" } } ,
} ,
} ,
osImage : "fake-os-image" ,
} ,
{
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo2" } ,
2016-12-16 05:42:59 +00:00
Status : api . NodeStatus {
NodeInfo : api . NodeSystemInfo { KernelVersion : "fake-kernel-version" } ,
Addresses : [ ] api . NodeAddress { { Type : api . NodeExternalIP , Address : "1.1.1.1" } } ,
} ,
} ,
osImage : "<unknown>" ,
} ,
}
for _ , test := range table {
buffer := & bytes . Buffer { }
err := printer . PrintObj ( & test . node , buffer )
if err != nil {
t . Fatalf ( "An error occurred printing Node: %#v" , err )
}
if ! contains ( strings . Fields ( buffer . String ( ) ) , test . osImage ) {
t . Fatalf ( "Expect printing node %s with os image %#v, got: %#v" , test . node . Name , test . osImage , buffer . String ( ) )
}
}
}
func TestPrintNodeKernelVersion ( t * testing . T ) {
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions {
2016-12-16 05:42:59 +00:00
ColumnLabels : [ ] string { } ,
Wide : true ,
} )
2017-02-19 22:37:24 +00:00
AddHandlers ( printer )
2016-12-16 05:42:59 +00:00
table := [ ] struct {
node api . Node
kernelVersion string
} {
{
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo1" } ,
2016-12-16 05:42:59 +00:00
Status : api . NodeStatus {
NodeInfo : api . NodeSystemInfo { KernelVersion : "fake-kernel-version" } ,
Addresses : [ ] api . NodeAddress { { Type : api . NodeExternalIP , Address : "1.1.1.1" } } ,
} ,
} ,
kernelVersion : "fake-kernel-version" ,
} ,
{
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo2" } ,
2016-12-16 05:42:59 +00:00
Status : api . NodeStatus {
NodeInfo : api . NodeSystemInfo { OSImage : "fake-os-image" } ,
Addresses : [ ] api . NodeAddress { { Type : api . NodeExternalIP , Address : "1.1.1.1" } } ,
} ,
} ,
kernelVersion : "<unknown>" ,
} ,
}
for _ , test := range table {
buffer := & bytes . Buffer { }
err := printer . PrintObj ( & test . node , buffer )
if err != nil {
t . Fatalf ( "An error occurred printing Node: %#v" , err )
}
if ! contains ( strings . Fields ( buffer . String ( ) ) , test . kernelVersion ) {
t . Fatalf ( "Expect printing node %s with kernel version %#v, got: %#v" , test . node . Name , test . kernelVersion , buffer . String ( ) )
}
}
}
2017-05-30 20:14:04 +00:00
func TestPrintNodeContainerRuntimeVersion ( t * testing . T ) {
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions {
ColumnLabels : [ ] string { } ,
Wide : true ,
} )
AddHandlers ( printer )
table := [ ] struct {
node api . Node
containerRuntimeVersion string
} {
{
node : api . Node {
ObjectMeta : metav1 . ObjectMeta { Name : "foo1" } ,
Status : api . NodeStatus {
NodeInfo : api . NodeSystemInfo { ContainerRuntimeVersion : "foo://1.2.3" } ,
Addresses : [ ] api . NodeAddress { { Type : api . NodeExternalIP , Address : "1.1.1.1" } } ,
} ,
} ,
containerRuntimeVersion : "foo://1.2.3" ,
} ,
{
node : api . Node {
ObjectMeta : metav1 . ObjectMeta { Name : "foo2" } ,
Status : api . NodeStatus {
NodeInfo : api . NodeSystemInfo { } ,
Addresses : [ ] api . NodeAddress { { Type : api . NodeExternalIP , Address : "1.1.1.1" } } ,
} ,
} ,
containerRuntimeVersion : "<unknown>" ,
} ,
}
for _ , test := range table {
buffer := & bytes . Buffer { }
err := printer . PrintObj ( & test . node , buffer )
if err != nil {
t . Fatalf ( "An error occurred printing Node: %#v" , err )
}
if ! contains ( strings . Fields ( buffer . String ( ) ) , test . containerRuntimeVersion ) {
t . Fatalf ( "Expect printing node %s with kernel version %#v, got: %#v" , test . node . Name , test . containerRuntimeVersion , buffer . String ( ) )
}
}
}
2017-05-12 12:43:44 +00:00
func TestPrintNodeName ( t * testing . T ) {
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions {
Wide : true ,
} )
AddHandlers ( printer )
table := [ ] struct {
node api . Node
Name string
} {
{
node : api . Node {
ObjectMeta : metav1 . ObjectMeta { Name : "127.0.0.1" } ,
Status : api . NodeStatus { } ,
} ,
Name : "127.0.0.1" ,
} ,
{
node : api . Node {
ObjectMeta : metav1 . ObjectMeta { Name : "" } ,
Status : api . NodeStatus { } ,
} ,
Name : "<unknown>" ,
} ,
}
for _ , test := range table {
buffer := & bytes . Buffer { }
err := printer . PrintObj ( & test . node , buffer )
if err != nil {
t . Fatalf ( "An error occurred printing Node: %#v" , err )
}
if ! contains ( strings . Fields ( buffer . String ( ) ) , test . Name ) {
t . Fatalf ( "Expect printing node %s with node name %#v, got: %#v" , test . node . Name , test . Name , buffer . String ( ) )
}
}
}
2016-09-27 10:31:37 +00:00
func TestPrintNodeExternalIP ( t * testing . T ) {
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions {
2016-12-27 04:10:05 +00:00
Wide : true ,
2016-09-27 10:31:37 +00:00
} )
2017-02-19 22:37:24 +00:00
AddHandlers ( printer )
2016-09-27 10:31:37 +00:00
table := [ ] struct {
node api . Node
externalIP string
} {
{
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo1" } ,
2016-09-27 10:31:37 +00:00
Status : api . NodeStatus { Addresses : [ ] api . NodeAddress { { Type : api . NodeExternalIP , Address : "1.1.1.1" } } } ,
} ,
externalIP : "1.1.1.1" ,
} ,
{
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo2" } ,
2016-09-27 10:31:37 +00:00
Status : api . NodeStatus { Addresses : [ ] api . NodeAddress { { Type : api . NodeInternalIP , Address : "1.1.1.1" } } } ,
} ,
externalIP : "<none>" ,
} ,
{
node : api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo3" } ,
2016-09-27 10:31:37 +00:00
Status : api . NodeStatus { Addresses : [ ] api . NodeAddress {
{ Type : api . NodeExternalIP , Address : "2.2.2.2" } ,
{ Type : api . NodeInternalIP , Address : "3.3.3.3" } ,
{ Type : api . NodeExternalIP , Address : "4.4.4.4" } ,
} } ,
} ,
externalIP : "2.2.2.2" ,
} ,
}
for _ , test := range table {
buffer := & bytes . Buffer { }
err := printer . PrintObj ( & test . node , buffer )
if err != nil {
t . Fatalf ( "An error occurred printing Node: %#v" , err )
}
if ! contains ( strings . Fields ( buffer . String ( ) ) , test . externalIP ) {
t . Fatalf ( "Expect printing node %s with external ip %#v, got: %#v" , test . node . Name , test . externalIP , buffer . String ( ) )
}
}
}
2015-01-15 01:11:34 +00:00
func contains ( fields [ ] string , field string ) bool {
for _ , v := range fields {
if v == field {
return true
}
}
return false
}
2015-04-01 21:46:33 +00:00
2016-02-14 09:28:44 +00:00
func TestPrintHunmanReadableIngressWithColumnLabels ( t * testing . T ) {
ingress := extensions . Ingress {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2016-02-14 09:28:44 +00:00
Name : "test1" ,
2016-12-03 18:57:26 +00:00
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . AddDate ( - 10 , 0 , 0 ) } ,
2016-02-14 09:28:44 +00:00
Labels : map [ string ] string {
"app_name" : "kubectl_test_ingress" ,
} ,
} ,
Spec : extensions . IngressSpec {
Backend : & extensions . IngressBackend {
ServiceName : "svc" ,
ServicePort : intstr . FromInt ( 93 ) ,
} ,
} ,
Status : extensions . IngressStatus {
LoadBalancer : api . LoadBalancerStatus {
Ingress : [ ] api . LoadBalancerIngress {
{
IP : "2.3.4.5" ,
Hostname : "localhost.localdomain" ,
} ,
} ,
} ,
} ,
}
2017-07-25 02:05:10 +00:00
buff := bytes . NewBuffer ( [ ] byte { } )
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & ingress , printers . PrintOptions { ColumnLabels : [ ] string { "app_name" } } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buff , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
2016-02-14 09:28:44 +00:00
output := string ( buff . Bytes ( ) )
appName := ingress . ObjectMeta . Labels [ "app_name" ]
if ! strings . Contains ( output , appName ) {
t . Errorf ( "expected to container app_name label value %s, but doesn't %s" , appName , output )
}
}
2015-04-01 21:46:33 +00:00
func TestPrintHumanReadableService ( t * testing . T ) {
tests := [ ] api . Service {
{
Spec : api . ServiceSpec {
2015-05-23 20:41:11 +00:00
ClusterIP : "1.2.3.4" ,
2015-08-08 04:08:43 +00:00
Type : "LoadBalancer" ,
2015-04-01 21:46:33 +00:00
Ports : [ ] api . ServicePort {
{
Port : 80 ,
Protocol : "TCP" ,
} ,
} ,
} ,
2015-05-22 21:33:29 +00:00
Status : api . ServiceStatus {
LoadBalancer : api . LoadBalancerStatus {
Ingress : [ ] api . LoadBalancerIngress {
{
IP : "2.3.4.5" ,
} ,
{
IP : "3.4.5.6" ,
} ,
} ,
} ,
} ,
2015-04-01 21:46:33 +00:00
} ,
{
Spec : api . ServiceSpec {
2016-06-02 23:09:51 +00:00
ClusterIP : "1.3.4.5" ,
2015-04-01 21:46:33 +00:00
Ports : [ ] api . ServicePort {
{
Port : 80 ,
Protocol : "TCP" ,
} ,
{
Port : 8090 ,
Protocol : "UDP" ,
} ,
{
Port : 8000 ,
Protocol : "TCP" ,
} ,
} ,
} ,
} ,
{
Spec : api . ServiceSpec {
2016-06-02 23:09:51 +00:00
ClusterIP : "1.4.5.6" ,
2015-08-08 04:08:43 +00:00
Type : "LoadBalancer" ,
2015-04-01 21:46:33 +00:00
Ports : [ ] api . ServicePort {
{
Port : 80 ,
Protocol : "TCP" ,
} ,
{
Port : 8090 ,
Protocol : "UDP" ,
} ,
{
Port : 8000 ,
Protocol : "TCP" ,
} ,
} ,
} ,
2015-05-22 21:33:29 +00:00
Status : api . ServiceStatus {
LoadBalancer : api . LoadBalancerStatus {
Ingress : [ ] api . LoadBalancerIngress {
{
IP : "2.3.4.5" ,
} ,
} ,
} ,
} ,
2015-04-01 21:46:33 +00:00
} ,
{
Spec : api . ServiceSpec {
2016-06-02 23:09:51 +00:00
ClusterIP : "1.5.6.7" ,
2015-08-08 04:08:43 +00:00
Type : "LoadBalancer" ,
2015-04-01 21:46:33 +00:00
Ports : [ ] api . ServicePort {
{
Port : 80 ,
Protocol : "TCP" ,
} ,
{
Port : 8090 ,
Protocol : "UDP" ,
} ,
{
Port : 8000 ,
Protocol : "TCP" ,
} ,
} ,
} ,
2015-05-22 21:33:29 +00:00
Status : api . ServiceStatus {
LoadBalancer : api . LoadBalancerStatus {
Ingress : [ ] api . LoadBalancerIngress {
{
IP : "2.3.4.5" ,
} ,
{
IP : "3.4.5.6" ,
} ,
{
IP : "5.6.7.8" ,
Hostname : "host5678" ,
} ,
} ,
} ,
} ,
2015-04-01 21:46:33 +00:00
} ,
}
for _ , svc := range tests {
2016-06-02 23:09:51 +00:00
for _ , wide := range [ ] bool { false , true } {
2017-07-21 07:42:30 +00:00
buff := bytes . NewBuffer ( [ ] byte { } )
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & svc , printers . PrintOptions { Wide : wide } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buff , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
2016-06-02 23:09:51 +00:00
output := string ( buff . Bytes ( ) )
ip := svc . Spec . ClusterIP
2015-04-01 21:46:33 +00:00
if ! strings . Contains ( output , ip ) {
2016-06-02 23:09:51 +00:00
t . Errorf ( "expected to contain ClusterIP %s, but doesn't: %s" , ip , output )
2015-04-01 21:46:33 +00:00
}
2016-06-02 23:09:51 +00:00
for n , ingress := range svc . Status . LoadBalancer . Ingress {
ip = ingress . IP
// For non-wide output, we only guarantee the first IP to be printed
if ( n == 0 || wide ) && ! strings . Contains ( output , ip ) {
t . Errorf ( "expected to contain ingress ip %s with wide=%v, but doesn't: %s" , ip , wide , output )
}
}
for _ , port := range svc . Spec . Ports {
portSpec := fmt . Sprintf ( "%d/%s" , port . Port , port . Protocol )
if ! strings . Contains ( output , portSpec ) {
t . Errorf ( "expected to contain port: %s, but doesn't: %s" , portSpec , output )
}
}
// Each service should print on one line
if 1 != strings . Count ( output , "\n" ) {
t . Errorf ( "expected a single newline, found %d" , strings . Count ( output , "\n" ) )
2015-04-01 21:46:33 +00:00
}
}
}
}
2015-05-15 19:24:41 +00:00
2015-05-20 19:51:35 +00:00
func TestPrintHumanReadableWithNamespace ( t * testing . T ) {
namespaceName := "testnamespace"
name := "test"
table := [ ] struct {
2015-07-01 20:41:54 +00:00
obj runtime . Object
isNamespaced bool
2015-05-20 19:51:35 +00:00
} {
{
obj : & api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : true ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . ReplicationController {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
Spec : api . ReplicationControllerSpec {
Replicas : 2 ,
Template : & api . PodTemplateSpec {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2015-05-20 19:51:35 +00:00
Labels : map [ string ] string {
"name" : "foo" ,
"type" : "production" ,
} ,
} ,
Spec : api . PodSpec {
Containers : [ ] api . Container {
{
Image : "foo/bar" ,
TerminationMessagePath : api . TerminationMessagePathDefault ,
ImagePullPolicy : api . PullIfNotPresent ,
} ,
} ,
RestartPolicy : api . RestartPolicyAlways ,
DNSPolicy : api . DNSDefault ,
NodeSelector : map [ string ] string {
"baz" : "blah" ,
} ,
} ,
} ,
} ,
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : true ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . Service {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
Spec : api . ServiceSpec {
2015-05-23 20:41:11 +00:00
ClusterIP : "1.2.3.4" ,
2015-05-20 19:51:35 +00:00
Ports : [ ] api . ServicePort {
{
Port : 80 ,
Protocol : "TCP" ,
} ,
} ,
} ,
2015-05-22 22:12:46 +00:00
Status : api . ServiceStatus {
LoadBalancer : api . LoadBalancerStatus {
Ingress : [ ] api . LoadBalancerIngress {
{
IP : "2.3.4.5" ,
} ,
} ,
} ,
} ,
2015-05-20 19:51:35 +00:00
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : true ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . Endpoints {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
Subsets : [ ] api . EndpointSubset { {
Addresses : [ ] api . EndpointAddress { { IP : "127.0.0.1" } , { IP : "localhost" } } ,
Ports : [ ] api . EndpointPort { { Port : 8080 } } ,
} ,
} } ,
2015-07-01 20:41:54 +00:00
isNamespaced : true ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . Namespace {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name } ,
2015-05-20 19:51:35 +00:00
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : false ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . Secret {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : true ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . ServiceAccount {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
Secrets : [ ] api . ObjectReference { } ,
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : true ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name } ,
2015-05-20 19:51:35 +00:00
Status : api . NodeStatus { } ,
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : false ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . PersistentVolume {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
Spec : api . PersistentVolumeSpec { } ,
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : false ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . PersistentVolumeClaim {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
Spec : api . PersistentVolumeClaimSpec { } ,
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : true ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . Event {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
Source : api . EventSource { Component : "kubelet" } ,
Message : "Item 1" ,
2016-12-03 18:57:26 +00:00
FirstTimestamp : metav1 . NewTime ( time . Date ( 2014 , time . January , 15 , 0 , 0 , 0 , 0 , time . UTC ) ) ,
LastTimestamp : metav1 . NewTime ( time . Date ( 2014 , time . January , 15 , 0 , 0 , 0 , 0 , time . UTC ) ) ,
2015-05-20 19:51:35 +00:00
Count : 1 ,
2015-11-13 22:30:45 +00:00
Type : api . EventTypeNormal ,
2015-05-20 19:51:35 +00:00
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : true ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . LimitRange {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : true ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . ResourceQuota {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : name , Namespace : namespaceName } ,
2015-05-20 19:51:35 +00:00
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : true ,
2015-05-20 19:51:35 +00:00
} ,
{
obj : & api . ComponentStatus {
Conditions : [ ] api . ComponentCondition {
{ Type : api . ComponentHealthy , Status : api . ConditionTrue , Message : "ok" , Error : "" } ,
} ,
} ,
2015-07-01 20:41:54 +00:00
isNamespaced : false ,
2015-05-20 19:51:35 +00:00
} ,
}
2017-05-26 23:00:01 +00:00
for i , test := range table {
2015-07-01 20:41:54 +00:00
if test . isNamespaced {
// Expect output to include namespace when requested.
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions {
2016-06-23 14:49:31 +00:00
WithNamespace : true ,
} )
2017-02-19 22:37:24 +00:00
AddHandlers ( printer )
2015-07-01 20:41:54 +00:00
buffer := & bytes . Buffer { }
err := printer . PrintObj ( test . obj , buffer )
if err != nil {
t . Fatalf ( "An error occurred printing object: %#v" , err )
}
2015-07-01 20:56:31 +00:00
matched := contains ( strings . Fields ( buffer . String ( ) ) , fmt . Sprintf ( "%s" , namespaceName ) )
2015-07-01 20:41:54 +00:00
if ! matched {
2017-05-26 23:00:01 +00:00
t . Errorf ( "%d: Expect printing object to contain namespace: %#v" , i , test . obj )
2015-07-01 20:41:54 +00:00
}
} else {
// Expect error when trying to get all namespaces for un-namespaced object.
2017-02-28 22:45:09 +00:00
printer := printers . NewHumanReadablePrinter ( nil , nil , printers . PrintOptions {
2016-06-23 14:49:31 +00:00
WithNamespace : true ,
} )
2015-07-01 20:41:54 +00:00
buffer := & bytes . Buffer { }
err := printer . PrintObj ( test . obj , buffer )
if err == nil {
t . Errorf ( "Expected error when printing un-namespaced type" )
}
2015-05-20 19:51:35 +00:00
}
2015-05-15 19:24:41 +00:00
}
}
2015-05-30 01:42:44 +00:00
2017-05-26 23:00:01 +00:00
func TestPrintPodTable ( t * testing . T ) {
runningPod := & api . Pod {
ObjectMeta : metav1 . ObjectMeta { Name : "test1" , Labels : map [ string ] string { "a" : "1" , "b" : "2" } } ,
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "Running" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
}
failedPod := & api . Pod {
ObjectMeta : metav1 . ObjectMeta { Name : "test2" , Labels : map [ string ] string { "b" : "2" } } ,
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "Failed" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
}
tests := [ ] struct {
obj runtime . Object
opts printers . PrintOptions
expect string
ignoreLegacy bool
} {
{
obj : runningPod , opts : printers . PrintOptions { } ,
expect : "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\ntest1\t1/2\tRunning\t6\t<unknown>\n" ,
} ,
{
obj : runningPod , opts : printers . PrintOptions { WithKind : true , Kind : "pods" } ,
expect : "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\npods/test1\t1/2\tRunning\t6\t<unknown>\n" ,
} ,
{
obj : runningPod , opts : printers . PrintOptions { ShowLabels : true } ,
expect : "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\tLABELS\ntest1\t1/2\tRunning\t6\t<unknown>\ta=1,b=2\n" ,
} ,
{
obj : & api . PodList { Items : [ ] api . Pod { * runningPod , * failedPod } } , opts : printers . PrintOptions { ShowAll : true , ColumnLabels : [ ] string { "a" } } ,
expect : "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\tA\ntest1\t1/2\tRunning\t6\t<unknown>\t1\ntest2\t1/2\tFailed\t6\t<unknown>\t\n" ,
} ,
{
obj : runningPod , opts : printers . PrintOptions { NoHeaders : true } ,
expect : "test1\t1/2\tRunning\t6\t<unknown>\n" ,
} ,
{
obj : failedPod , opts : printers . PrintOptions { } ,
expect : "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\n" ,
ignoreLegacy : true , // filtering is not done by the printer in the legacy path
} ,
{
obj : failedPod , opts : printers . PrintOptions { ShowAll : true } ,
expect : "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\ntest2\t1/2\tFailed\t6\t<unknown>\n" ,
} ,
}
for i , test := range tests {
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( test . obj , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
buf := & bytes . Buffer { }
2017-06-06 01:29:43 +00:00
p := printers . NewHumanReadablePrinter ( nil , nil , test . opts ) . With ( AddHandlers ) . AddTabWriter ( false )
2017-05-26 23:00:01 +00:00
if err := p . PrintObj ( table , buf ) ; err != nil {
t . Fatal ( err )
}
if test . expect != buf . String ( ) {
t . Errorf ( "%d mismatch:\n%s\n%s" , i , strconv . Quote ( test . expect ) , strconv . Quote ( buf . String ( ) ) )
}
if test . ignoreLegacy {
continue
}
buf . Reset ( )
if err := p . PrintObj ( test . obj , buf ) ; err != nil {
t . Fatal ( err )
}
if test . expect != buf . String ( ) {
t . Errorf ( "%d legacy mismatch:\n%s\n%s" , i , strconv . Quote ( test . expect ) , strconv . Quote ( buf . String ( ) ) )
}
}
}
2017-10-12 05:29:11 +00:00
2015-05-30 01:42:44 +00:00
func TestPrintPod ( t * testing . T ) {
tests := [ ] struct {
pod api . Pod
2017-05-26 23:00:01 +00:00
expect [ ] metav1alpha1 . TableRow
2015-05-30 01:42:44 +00:00
} {
{
// Test name, num of containers, restarts, container ready status
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test1" } ,
2015-05-30 01:42:44 +00:00
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
} ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test1" , "1/2" , "podPhase" , 6 , "<unknown>" } } } ,
2015-05-30 01:42:44 +00:00
} ,
{
// Test container error overwrites pod phase
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test2" } ,
2015-05-30 01:42:44 +00:00
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
2015-06-09 15:58:16 +00:00
{ State : api . ContainerState { Waiting : & api . ContainerStateWaiting { Reason : "ContainerWaitingReason" } } , RestartCount : 3 } ,
2015-05-30 01:42:44 +00:00
} ,
} ,
} ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test2" , "1/2" , "ContainerWaitingReason" , 6 , "<unknown>" } } } ,
2015-05-30 01:42:44 +00:00
} ,
{
// Test the same as the above but with Terminated state and the first container overwrites the rest
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test3" } ,
2015-05-30 01:42:44 +00:00
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
2015-06-09 15:58:16 +00:00
{ State : api . ContainerState { Waiting : & api . ContainerStateWaiting { Reason : "ContainerWaitingReason" } } , RestartCount : 3 } ,
{ State : api . ContainerState { Terminated : & api . ContainerStateTerminated { Reason : "ContainerTerminatedReason" } } , RestartCount : 3 } ,
2015-05-30 01:42:44 +00:00
} ,
} ,
} ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test3" , "0/2" , "ContainerWaitingReason" , 6 , "<unknown>" } } } ,
2015-05-30 01:42:44 +00:00
} ,
{
// Test ready is not enough for reporting running
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test4" } ,
2015-05-30 01:42:44 +00:00
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ Ready : true , RestartCount : 3 } ,
} ,
} ,
} ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test4" , "1/2" , "podPhase" , 6 , "<unknown>" } } } ,
2015-05-30 01:42:44 +00:00
} ,
2015-06-09 15:58:16 +00:00
{
// Test ready is not enough for reporting running
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test5" } ,
2015-06-09 15:58:16 +00:00
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
2017-07-20 20:23:13 +00:00
Reason : "podReason" ,
2015-06-09 15:58:16 +00:00
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ Ready : true , RestartCount : 3 } ,
} ,
} ,
} ,
2017-07-20 20:23:13 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test5" , "1/2" , "podReason" , 6 , "<unknown>" } } } ,
2015-06-09 15:58:16 +00:00
} ,
2015-05-30 01:42:44 +00:00
}
2017-05-26 23:00:01 +00:00
for i , test := range tests {
rows , err := printPod ( & test . pod , printers . PrintOptions { ShowAll : true } )
if err != nil {
t . Fatal ( err )
}
for i := range rows {
rows [ i ] . Object . Object = nil
}
if ! reflect . DeepEqual ( test . expect , rows ) {
t . Errorf ( "%d mismatch: %s" , i , diff . ObjectReflectDiff ( test . expect , rows ) )
2015-07-31 23:42:34 +00:00
}
}
}
2017-10-27 02:39:09 +00:00
func TestPrintPodwide ( t * testing . T ) {
tests := [ ] struct {
pod api . Pod
expect [ ] metav1alpha1 . TableRow
} {
{
// Test when the NodeName and PodIP are not none
api . Pod {
ObjectMeta : metav1 . ObjectMeta { Name : "test1" } ,
Spec : api . PodSpec {
Containers : make ( [ ] api . Container , 2 ) ,
NodeName : "test1" ,
} ,
Status : api . PodStatus {
Phase : "podPhase" ,
PodIP : "1.1.1.1" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
} ,
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test1" , "1/2" , "podPhase" , 6 , "<unknown>" , "1.1.1.1" , "test1" } } } ,
} ,
{
// Test when the NodeName and PodIP are none
api . Pod {
ObjectMeta : metav1 . ObjectMeta { Name : "test2" } ,
Spec : api . PodSpec {
Containers : make ( [ ] api . Container , 2 ) ,
NodeName : "" ,
} ,
Status : api . PodStatus {
Phase : "podPhase" ,
PodIP : "" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ State : api . ContainerState { Waiting : & api . ContainerStateWaiting { Reason : "ContainerWaitingReason" } } , RestartCount : 3 } ,
} ,
} ,
} ,
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test2" , "1/2" , "ContainerWaitingReason" , 6 , "<unknown>" , "<none>" , "<none>" } } } ,
} ,
}
for i , test := range tests {
rows , err := printPod ( & test . pod , printers . PrintOptions { Wide : true } )
if err != nil {
t . Fatal ( err )
}
for i := range rows {
rows [ i ] . Object . Object = nil
}
if ! reflect . DeepEqual ( test . expect , rows ) {
t . Errorf ( "%d mismatch: %s" , i , diff . ObjectReflectDiff ( test . expect , rows ) )
}
}
}
2017-06-05 09:56:34 +00:00
func TestPrintPodList ( t * testing . T ) {
tests := [ ] struct {
pods api . PodList
expect [ ] metav1alpha1 . TableRow
} {
// Test podList's pod: name, num of containers, restarts, container ready status
{
api . PodList {
Items : [ ] api . Pod {
{
ObjectMeta : metav1 . ObjectMeta { Name : "test1" } ,
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
} ,
} ,
} ,
{
ObjectMeta : metav1 . ObjectMeta { Name : "test2" } ,
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 1 ) } ,
Status : api . PodStatus {
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 1 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
} ,
} ,
} ,
} ,
} ,
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test1" , "2/2" , "podPhase" , 6 , "<unknown>" } } , { Cells : [ ] interface { } { "test2" , "1/1" , "podPhase" , 1 , "<unknown>" } } } ,
} ,
}
for _ , test := range tests {
rows , err := printPodList ( & test . pods , printers . PrintOptions { ShowAll : true } )
if err != nil {
t . Fatal ( err )
}
for i := range rows {
rows [ i ] . Object . Object = nil
}
if ! reflect . DeepEqual ( test . expect , rows ) {
t . Errorf ( "mismatch: %s" , diff . ObjectReflectDiff ( test . expect , rows ) )
}
}
}
2015-07-31 23:42:34 +00:00
func TestPrintNonTerminatedPod ( t * testing . T ) {
tests := [ ] struct {
pod api . Pod
2017-05-26 23:00:01 +00:00
expect [ ] metav1alpha1 . TableRow
2015-07-31 23:42:34 +00:00
} {
{
// Test pod phase Running should be printed
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test1" } ,
2015-07-31 23:42:34 +00:00
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : api . PodRunning ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
} ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test1" , "1/2" , "Running" , 6 , "<unknown>" } } } ,
2015-07-31 23:42:34 +00:00
} ,
{
// Test pod phase Pending should be printed
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test2" } ,
2015-07-31 23:42:34 +00:00
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : api . PodPending ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
} ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test2" , "1/2" , "Pending" , 6 , "<unknown>" } } } ,
2015-07-31 23:42:34 +00:00
} ,
{
// Test pod phase Unknown should be printed
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test3" } ,
2015-07-31 23:42:34 +00:00
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : api . PodUnknown ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
} ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test3" , "1/2" , "Unknown" , 6 , "<unknown>" } } } ,
2015-07-31 23:42:34 +00:00
} ,
{
// Test pod phase Succeeded shouldn't be printed
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test4" } ,
2015-07-31 23:42:34 +00:00
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : api . PodSucceeded ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
} ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test4" , "1/2" , "Succeeded" , 6 , "<unknown>" } , Conditions : podSuccessConditions } } ,
2015-07-31 23:42:34 +00:00
} ,
{
// Test pod phase Failed shouldn't be printed
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test5" } ,
2015-07-31 23:42:34 +00:00
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : api . PodFailed ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ Ready : true , RestartCount : 3 } ,
} ,
} ,
} ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test5" , "1/2" , "Failed" , 6 , "<unknown>" } , Conditions : podFailedConditions } } ,
2015-07-31 23:42:34 +00:00
} ,
}
2017-05-26 23:00:01 +00:00
for i , test := range tests {
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . pod , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
rows := table . Rows
for i := range rows {
rows [ i ] . Object . Object = nil
}
if ! reflect . DeepEqual ( test . expect , rows ) {
t . Errorf ( "%d mismatch: %s" , i , diff . ObjectReflectDiff ( test . expect , rows ) )
2015-05-30 01:42:44 +00:00
}
}
}
2015-06-16 16:30:11 +00:00
func TestPrintPodWithLabels ( t * testing . T ) {
tests := [ ] struct {
pod api . Pod
labelColumns [ ] string
2017-05-26 23:00:01 +00:00
expect [ ] metav1alpha1 . TableRow
2015-06-16 16:30:11 +00:00
} {
{
// Test name, num of containers, restarts, container ready status
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2015-06-16 16:30:11 +00:00
Name : "test1" ,
Labels : map [ string ] string { "col1" : "asd" , "COL2" : "zxc" } ,
} ,
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
} ,
[ ] string { "col1" , "COL2" } ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test1" , "1/2" , "podPhase" , 6 , "<unknown>" , "asd" , "zxc" } } } ,
2015-06-16 16:30:11 +00:00
} ,
{
// Test name, num of containers, restarts, container ready status
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2015-06-16 16:30:11 +00:00
Name : "test1" ,
Labels : map [ string ] string { "col1" : "asd" , "COL2" : "zxc" } ,
} ,
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
} ,
[ ] string { } ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test1" , "1/2" , "podPhase" , 6 , "<unknown>" } } } ,
2015-06-16 16:30:11 +00:00
} ,
}
2017-05-26 23:00:01 +00:00
for i , test := range tests {
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . pod , printers . PrintOptions { ColumnLabels : test . labelColumns } )
if err != nil {
t . Fatal ( err )
}
rows := table . Rows
for i := range rows {
rows [ i ] . Object . Object = nil
}
if ! reflect . DeepEqual ( test . expect , rows ) {
t . Errorf ( "%d mismatch: %s" , i , diff . ObjectReflectDiff ( test . expect , rows ) )
2015-06-16 16:30:11 +00:00
}
}
}
2015-08-13 08:23:10 +00:00
type stringTestList [ ] struct {
name , got , exp string
}
func TestTranslateTimestamp ( t * testing . T ) {
tl := stringTestList {
2016-12-03 18:57:26 +00:00
{ "a while from now" , translateTimestamp ( metav1 . Time { Time : time . Now ( ) . Add ( 2.1e9 ) } ) , "<invalid>" } ,
{ "almost now" , translateTimestamp ( metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ) , "0s" } ,
{ "now" , translateTimestamp ( metav1 . Time { Time : time . Now ( ) } ) , "0s" } ,
{ "unknown" , translateTimestamp ( metav1 . Time { } ) , "<unknown>" } ,
{ "30 seconds ago" , translateTimestamp ( metav1 . Time { Time : time . Now ( ) . Add ( - 3e10 ) } ) , "30s" } ,
{ "5 minutes ago" , translateTimestamp ( metav1 . Time { Time : time . Now ( ) . Add ( - 3e11 ) } ) , "5m" } ,
{ "an hour ago" , translateTimestamp ( metav1 . Time { Time : time . Now ( ) . Add ( - 6e12 ) } ) , "1h" } ,
{ "2 days ago" , translateTimestamp ( metav1 . Time { Time : time . Now ( ) . UTC ( ) . AddDate ( 0 , 0 , - 2 ) } ) , "2d" } ,
{ "months ago" , translateTimestamp ( metav1 . Time { Time : time . Now ( ) . UTC ( ) . AddDate ( 0 , 0 , - 90 ) } ) , "90d" } ,
{ "10 years ago" , translateTimestamp ( metav1 . Time { Time : time . Now ( ) . UTC ( ) . AddDate ( - 10 , 0 , 0 ) } ) , "10y" } ,
2015-08-13 08:23:10 +00:00
}
for _ , test := range tl {
if test . got != test . exp {
t . Errorf ( "On %v, expected '%v', but got '%v'" ,
test . name , test . exp , test . got )
}
}
}
2015-08-31 21:43:24 +00:00
func TestPrintDeployment ( t * testing . T ) {
tests := [ ] struct {
2015-10-09 22:49:10 +00:00
deployment extensions . Deployment
2015-08-31 21:43:24 +00:00
expect string
2016-12-27 04:10:05 +00:00
wideExpect string
2015-08-31 21:43:24 +00:00
} {
{
2015-10-09 22:49:10 +00:00
extensions . Deployment {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2015-08-31 21:43:24 +00:00
Name : "test1" ,
2016-12-03 18:57:26 +00:00
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
2015-08-31 21:43:24 +00:00
} ,
2015-10-09 22:49:10 +00:00
Spec : extensions . DeploymentSpec {
2015-08-31 21:43:24 +00:00
Replicas : 5 ,
2015-10-26 23:20:43 +00:00
Template : api . PodTemplateSpec {
2016-12-27 04:10:05 +00:00
Spec : api . PodSpec {
Containers : [ ] api . Container {
{
Name : "fake-container1" ,
Image : "fake-image1" ,
} ,
{
Name : "fake-container2" ,
Image : "fake-image2" ,
} ,
} ,
} ,
2015-08-31 21:43:24 +00:00
} ,
2016-12-27 04:10:05 +00:00
Selector : & metav1 . LabelSelector { MatchLabels : map [ string ] string { "foo" : "bar" } } ,
2015-08-31 21:43:24 +00:00
} ,
2015-10-09 22:49:10 +00:00
Status : extensions . DeploymentStatus {
2016-01-22 18:40:37 +00:00
Replicas : 10 ,
UpdatedReplicas : 2 ,
AvailableReplicas : 1 ,
UnavailableReplicas : 4 ,
2015-08-31 21:43:24 +00:00
} ,
} ,
2016-01-22 18:40:37 +00:00
"test1\t5\t10\t2\t1\t0s\n" ,
2016-12-27 04:10:05 +00:00
"test1\t5\t10\t2\t1\t0s\tfake-container1,fake-container2\tfake-image1,fake-image2\tfoo=bar\n" ,
2015-08-31 21:43:24 +00:00
} ,
}
buf := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
2017-07-27 09:22:48 +00:00
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . deployment , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
2015-08-31 21:43:24 +00:00
if buf . String ( ) != test . expect {
t . Fatalf ( "Expected: %s, got: %s" , test . expect , buf . String ( ) )
}
buf . Reset ( )
2017-07-27 09:22:48 +00:00
table , err = printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . deployment , printers . PrintOptions { Wide : true } )
2016-12-27 04:10:05 +00:00
// print deployment with '-o wide' option
2017-07-27 09:22:48 +00:00
if err := printers . PrintTable ( table , buf , printers . PrintOptions { Wide : true , NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
2016-12-27 04:10:05 +00:00
if buf . String ( ) != test . wideExpect {
t . Fatalf ( "Expected: %s, got: %s" , test . wideExpect , buf . String ( ) )
}
buf . Reset ( )
2015-08-31 21:43:24 +00:00
}
}
2016-02-04 07:08:44 +00:00
2016-02-23 15:11:19 +00:00
func TestPrintDaemonSet ( t * testing . T ) {
tests := [ ] struct {
ds extensions . DaemonSet
startsWith string
} {
{
extensions . DaemonSet {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2016-02-23 15:11:19 +00:00
Name : "test1" ,
2016-12-03 18:57:26 +00:00
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
2016-02-23 15:11:19 +00:00
} ,
Spec : extensions . DaemonSetSpec {
Template : api . PodTemplateSpec {
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
} ,
} ,
Status : extensions . DaemonSetStatus {
CurrentNumberScheduled : 2 ,
DesiredNumberScheduled : 3 ,
2016-10-05 07:16:41 +00:00
NumberReady : 1 ,
2017-03-09 21:24:07 +00:00
UpdatedNumberScheduled : 2 ,
NumberAvailable : 0 ,
2016-02-23 15:11:19 +00:00
} ,
} ,
2017-03-09 21:24:07 +00:00
"test1\t3\t2\t1\t2\t0\t<none>\t0s\n" ,
2016-02-23 15:11:19 +00:00
} ,
}
buf := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
2017-06-25 17:01:14 +00:00
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . ds , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
2016-02-23 15:11:19 +00:00
if ! strings . HasPrefix ( buf . String ( ) , test . startsWith ) {
t . Fatalf ( "Expected to start with %s but got %s" , test . startsWith , buf . String ( ) )
}
buf . Reset ( )
}
}
2016-02-25 15:43:04 +00:00
func TestPrintJob ( t * testing . T ) {
2016-04-27 04:35:14 +00:00
completions := int32 ( 2 )
2016-02-25 15:43:04 +00:00
tests := [ ] struct {
2016-04-18 15:44:19 +00:00
job batch . Job
2016-02-25 15:43:04 +00:00
expect string
} {
{
2016-04-18 15:44:19 +00:00
batch . Job {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2016-02-25 15:43:04 +00:00
Name : "job1" ,
2016-12-03 18:57:26 +00:00
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
2016-02-25 15:43:04 +00:00
} ,
2016-04-18 15:44:19 +00:00
Spec : batch . JobSpec {
2016-02-25 15:43:04 +00:00
Completions : & completions ,
} ,
2016-04-18 15:44:19 +00:00
Status : batch . JobStatus {
2016-02-25 15:43:04 +00:00
Succeeded : 1 ,
} ,
} ,
2016-02-28 05:59:01 +00:00
"job1\t2\t1\t0s\n" ,
2016-02-25 15:43:04 +00:00
} ,
{
2016-04-18 15:44:19 +00:00
batch . Job {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2016-02-25 15:43:04 +00:00
Name : "job2" ,
2016-12-03 18:57:26 +00:00
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . AddDate ( - 10 , 0 , 0 ) } ,
2016-02-25 15:43:04 +00:00
} ,
2016-04-18 15:44:19 +00:00
Spec : batch . JobSpec {
2016-02-25 15:43:04 +00:00
Completions : nil ,
} ,
2016-04-18 15:44:19 +00:00
Status : batch . JobStatus {
2016-02-25 15:43:04 +00:00
Succeeded : 0 ,
} ,
} ,
2016-02-28 05:59:01 +00:00
"job2\t<none>\t0\t10y\n" ,
2016-02-25 15:43:04 +00:00
} ,
}
buf := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
2017-06-24 22:31:36 +00:00
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . job , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
2016-02-25 15:43:04 +00:00
if buf . String ( ) != test . expect {
t . Fatalf ( "Expected: %s, got: %s" , test . expect , buf . String ( ) )
}
buf . Reset ( )
}
}
2016-11-30 20:58:58 +00:00
func TestPrintHPA ( t * testing . T ) {
minReplicasVal := int32 ( 2 )
targetUtilizationVal := int32 ( 80 )
currentUtilizationVal := int32 ( 50 )
tests := [ ] struct {
hpa autoscaling . HorizontalPodAutoscaler
expected string
} {
// minReplicas unset
{
autoscaling . HorizontalPodAutoscaler {
ObjectMeta : metav1 . ObjectMeta { Name : "some-hpa" } ,
Spec : autoscaling . HorizontalPodAutoscalerSpec {
ScaleTargetRef : autoscaling . CrossVersionObjectReference {
Name : "some-rc" ,
Kind : "ReplicationController" ,
} ,
MaxReplicas : 10 ,
} ,
Status : autoscaling . HorizontalPodAutoscalerStatus {
CurrentReplicas : 4 ,
DesiredReplicas : 5 ,
} ,
} ,
"some-hpa\tReplicationController/some-rc\t<none>\t<unset>\t10\t4\t<unknown>\n" ,
} ,
// pods source type (no current)
{
autoscaling . HorizontalPodAutoscaler {
ObjectMeta : metav1 . ObjectMeta { Name : "some-hpa" } ,
Spec : autoscaling . HorizontalPodAutoscalerSpec {
ScaleTargetRef : autoscaling . CrossVersionObjectReference {
Name : "some-rc" ,
Kind : "ReplicationController" ,
} ,
MinReplicas : & minReplicasVal ,
MaxReplicas : 10 ,
Metrics : [ ] autoscaling . MetricSpec {
{
Type : autoscaling . PodsMetricSourceType ,
Pods : & autoscaling . PodsMetricSource {
MetricName : "some-pods-metric" ,
TargetAverageValue : * resource . NewMilliQuantity ( 100 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
Status : autoscaling . HorizontalPodAutoscalerStatus {
CurrentReplicas : 4 ,
DesiredReplicas : 5 ,
} ,
} ,
2017-11-24 10:06:20 +00:00
"some-hpa\tReplicationController/some-rc\t<unknown>/100m\t2\t10\t4\t<unknown>\n" ,
2016-11-30 20:58:58 +00:00
} ,
// pods source type
{
autoscaling . HorizontalPodAutoscaler {
ObjectMeta : metav1 . ObjectMeta { Name : "some-hpa" } ,
Spec : autoscaling . HorizontalPodAutoscalerSpec {
ScaleTargetRef : autoscaling . CrossVersionObjectReference {
Name : "some-rc" ,
Kind : "ReplicationController" ,
} ,
MinReplicas : & minReplicasVal ,
MaxReplicas : 10 ,
Metrics : [ ] autoscaling . MetricSpec {
{
Type : autoscaling . PodsMetricSourceType ,
Pods : & autoscaling . PodsMetricSource {
MetricName : "some-pods-metric" ,
TargetAverageValue : * resource . NewMilliQuantity ( 100 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
Status : autoscaling . HorizontalPodAutoscalerStatus {
CurrentReplicas : 4 ,
DesiredReplicas : 5 ,
CurrentMetrics : [ ] autoscaling . MetricStatus {
{
Type : autoscaling . PodsMetricSourceType ,
Pods : & autoscaling . PodsMetricStatus {
MetricName : "some-pods-metric" ,
CurrentAverageValue : * resource . NewMilliQuantity ( 50 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
} ,
2017-11-24 10:06:20 +00:00
"some-hpa\tReplicationController/some-rc\t50m/100m\t2\t10\t4\t<unknown>\n" ,
2016-11-30 20:58:58 +00:00
} ,
// object source type (no current)
{
autoscaling . HorizontalPodAutoscaler {
ObjectMeta : metav1 . ObjectMeta { Name : "some-hpa" } ,
Spec : autoscaling . HorizontalPodAutoscalerSpec {
ScaleTargetRef : autoscaling . CrossVersionObjectReference {
Name : "some-rc" ,
Kind : "ReplicationController" ,
} ,
MinReplicas : & minReplicasVal ,
MaxReplicas : 10 ,
Metrics : [ ] autoscaling . MetricSpec {
{
Type : autoscaling . ObjectMetricSourceType ,
Object : & autoscaling . ObjectMetricSource {
Target : autoscaling . CrossVersionObjectReference {
Name : "some-service" ,
Kind : "Service" ,
} ,
MetricName : "some-service-metric" ,
TargetValue : * resource . NewMilliQuantity ( 100 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
Status : autoscaling . HorizontalPodAutoscalerStatus {
CurrentReplicas : 4 ,
DesiredReplicas : 5 ,
} ,
} ,
2017-11-24 10:06:20 +00:00
"some-hpa\tReplicationController/some-rc\t<unknown>/100m\t2\t10\t4\t<unknown>\n" ,
2016-11-30 20:58:58 +00:00
} ,
// object source type
{
autoscaling . HorizontalPodAutoscaler {
ObjectMeta : metav1 . ObjectMeta { Name : "some-hpa" } ,
Spec : autoscaling . HorizontalPodAutoscalerSpec {
ScaleTargetRef : autoscaling . CrossVersionObjectReference {
Name : "some-rc" ,
Kind : "ReplicationController" ,
} ,
MinReplicas : & minReplicasVal ,
MaxReplicas : 10 ,
Metrics : [ ] autoscaling . MetricSpec {
{
Type : autoscaling . ObjectMetricSourceType ,
Object : & autoscaling . ObjectMetricSource {
Target : autoscaling . CrossVersionObjectReference {
Name : "some-service" ,
Kind : "Service" ,
} ,
MetricName : "some-service-metric" ,
TargetValue : * resource . NewMilliQuantity ( 100 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
Status : autoscaling . HorizontalPodAutoscalerStatus {
CurrentReplicas : 4 ,
DesiredReplicas : 5 ,
CurrentMetrics : [ ] autoscaling . MetricStatus {
{
Type : autoscaling . ObjectMetricSourceType ,
Object : & autoscaling . ObjectMetricStatus {
Target : autoscaling . CrossVersionObjectReference {
Name : "some-service" ,
Kind : "Service" ,
} ,
MetricName : "some-service-metric" ,
CurrentValue : * resource . NewMilliQuantity ( 50 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
} ,
2017-11-24 10:06:20 +00:00
"some-hpa\tReplicationController/some-rc\t50m/100m\t2\t10\t4\t<unknown>\n" ,
2016-11-30 20:58:58 +00:00
} ,
// resource source type, targetVal (no current)
{
autoscaling . HorizontalPodAutoscaler {
ObjectMeta : metav1 . ObjectMeta { Name : "some-hpa" } ,
Spec : autoscaling . HorizontalPodAutoscalerSpec {
ScaleTargetRef : autoscaling . CrossVersionObjectReference {
Name : "some-rc" ,
Kind : "ReplicationController" ,
} ,
MinReplicas : & minReplicasVal ,
MaxReplicas : 10 ,
Metrics : [ ] autoscaling . MetricSpec {
{
Type : autoscaling . ResourceMetricSourceType ,
Resource : & autoscaling . ResourceMetricSource {
Name : api . ResourceCPU ,
TargetAverageValue : resource . NewMilliQuantity ( 100 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
Status : autoscaling . HorizontalPodAutoscalerStatus {
CurrentReplicas : 4 ,
DesiredReplicas : 5 ,
} ,
} ,
2017-11-24 10:06:20 +00:00
"some-hpa\tReplicationController/some-rc\t<unknown>/100m\t2\t10\t4\t<unknown>\n" ,
2016-11-30 20:58:58 +00:00
} ,
// resource source type, targetVal
{
autoscaling . HorizontalPodAutoscaler {
ObjectMeta : metav1 . ObjectMeta { Name : "some-hpa" } ,
Spec : autoscaling . HorizontalPodAutoscalerSpec {
ScaleTargetRef : autoscaling . CrossVersionObjectReference {
Name : "some-rc" ,
Kind : "ReplicationController" ,
} ,
MinReplicas : & minReplicasVal ,
MaxReplicas : 10 ,
Metrics : [ ] autoscaling . MetricSpec {
{
Type : autoscaling . ResourceMetricSourceType ,
Resource : & autoscaling . ResourceMetricSource {
Name : api . ResourceCPU ,
TargetAverageValue : resource . NewMilliQuantity ( 100 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
Status : autoscaling . HorizontalPodAutoscalerStatus {
CurrentReplicas : 4 ,
DesiredReplicas : 5 ,
CurrentMetrics : [ ] autoscaling . MetricStatus {
{
Type : autoscaling . ResourceMetricSourceType ,
Resource : & autoscaling . ResourceMetricStatus {
Name : api . ResourceCPU ,
CurrentAverageValue : * resource . NewMilliQuantity ( 50 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
} ,
2017-11-24 10:06:20 +00:00
"some-hpa\tReplicationController/some-rc\t50m/100m\t2\t10\t4\t<unknown>\n" ,
2016-11-30 20:58:58 +00:00
} ,
// resource source type, targetUtil (no current)
{
autoscaling . HorizontalPodAutoscaler {
ObjectMeta : metav1 . ObjectMeta { Name : "some-hpa" } ,
Spec : autoscaling . HorizontalPodAutoscalerSpec {
ScaleTargetRef : autoscaling . CrossVersionObjectReference {
Name : "some-rc" ,
Kind : "ReplicationController" ,
} ,
MinReplicas : & minReplicasVal ,
MaxReplicas : 10 ,
Metrics : [ ] autoscaling . MetricSpec {
{
Type : autoscaling . ResourceMetricSourceType ,
Resource : & autoscaling . ResourceMetricSource {
Name : api . ResourceCPU ,
TargetAverageUtilization : & targetUtilizationVal ,
} ,
} ,
} ,
} ,
Status : autoscaling . HorizontalPodAutoscalerStatus {
CurrentReplicas : 4 ,
DesiredReplicas : 5 ,
} ,
} ,
2017-11-24 10:06:20 +00:00
"some-hpa\tReplicationController/some-rc\t<unknown>/80%\t2\t10\t4\t<unknown>\n" ,
2016-11-30 20:58:58 +00:00
} ,
// resource source type, targetUtil
{
autoscaling . HorizontalPodAutoscaler {
ObjectMeta : metav1 . ObjectMeta { Name : "some-hpa" } ,
Spec : autoscaling . HorizontalPodAutoscalerSpec {
ScaleTargetRef : autoscaling . CrossVersionObjectReference {
Name : "some-rc" ,
Kind : "ReplicationController" ,
} ,
MinReplicas : & minReplicasVal ,
MaxReplicas : 10 ,
Metrics : [ ] autoscaling . MetricSpec {
{
Type : autoscaling . ResourceMetricSourceType ,
Resource : & autoscaling . ResourceMetricSource {
Name : api . ResourceCPU ,
TargetAverageUtilization : & targetUtilizationVal ,
} ,
} ,
} ,
} ,
Status : autoscaling . HorizontalPodAutoscalerStatus {
CurrentReplicas : 4 ,
DesiredReplicas : 5 ,
CurrentMetrics : [ ] autoscaling . MetricStatus {
{
Type : autoscaling . ResourceMetricSourceType ,
Resource : & autoscaling . ResourceMetricStatus {
Name : api . ResourceCPU ,
CurrentAverageUtilization : & currentUtilizationVal ,
CurrentAverageValue : * resource . NewMilliQuantity ( 40 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
} ,
2017-11-24 10:06:20 +00:00
"some-hpa\tReplicationController/some-rc\t50%/80%\t2\t10\t4\t<unknown>\n" ,
2016-11-30 20:58:58 +00:00
} ,
// multiple specs
{
autoscaling . HorizontalPodAutoscaler {
ObjectMeta : metav1 . ObjectMeta { Name : "some-hpa" } ,
Spec : autoscaling . HorizontalPodAutoscalerSpec {
ScaleTargetRef : autoscaling . CrossVersionObjectReference {
Name : "some-rc" ,
Kind : "ReplicationController" ,
} ,
MinReplicas : & minReplicasVal ,
MaxReplicas : 10 ,
Metrics : [ ] autoscaling . MetricSpec {
{
Type : autoscaling . PodsMetricSourceType ,
Pods : & autoscaling . PodsMetricSource {
MetricName : "some-pods-metric" ,
TargetAverageValue : * resource . NewMilliQuantity ( 100 , resource . DecimalSI ) ,
} ,
} ,
{
Type : autoscaling . ResourceMetricSourceType ,
Resource : & autoscaling . ResourceMetricSource {
Name : api . ResourceCPU ,
TargetAverageUtilization : & targetUtilizationVal ,
} ,
} ,
{
Type : autoscaling . PodsMetricSourceType ,
Pods : & autoscaling . PodsMetricSource {
MetricName : "other-pods-metric" ,
TargetAverageValue : * resource . NewMilliQuantity ( 400 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
Status : autoscaling . HorizontalPodAutoscalerStatus {
CurrentReplicas : 4 ,
DesiredReplicas : 5 ,
CurrentMetrics : [ ] autoscaling . MetricStatus {
{
Type : autoscaling . PodsMetricSourceType ,
Pods : & autoscaling . PodsMetricStatus {
MetricName : "some-pods-metric" ,
CurrentAverageValue : * resource . NewMilliQuantity ( 50 , resource . DecimalSI ) ,
} ,
} ,
{
Type : autoscaling . ResourceMetricSourceType ,
Resource : & autoscaling . ResourceMetricStatus {
Name : api . ResourceCPU ,
CurrentAverageUtilization : & currentUtilizationVal ,
CurrentAverageValue : * resource . NewMilliQuantity ( 40 , resource . DecimalSI ) ,
} ,
} ,
} ,
} ,
} ,
2017-11-24 10:06:20 +00:00
"some-hpa\tReplicationController/some-rc\t50m/100m, 50%/80% + 1 more...\t2\t10\t4\t<unknown>\n" ,
2016-11-30 20:58:58 +00:00
} ,
}
buff := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
2017-07-27 10:02:54 +00:00
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . hpa , printers . PrintOptions { } )
2016-11-30 20:58:58 +00:00
if err != nil {
2017-07-27 10:02:54 +00:00
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buff , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
2016-11-30 20:58:58 +00:00
}
if buff . String ( ) != test . expected {
t . Errorf ( "expected %q, got %q" , test . expected , buff . String ( ) )
}
buff . Reset ( )
}
}
2016-02-04 07:08:44 +00:00
func TestPrintPodShowLabels ( t * testing . T ) {
tests := [ ] struct {
pod api . Pod
showLabels bool
2017-05-26 23:00:01 +00:00
expect [ ] metav1alpha1 . TableRow
2016-02-04 07:08:44 +00:00
} {
{
// Test name, num of containers, restarts, container ready status
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2016-02-04 07:08:44 +00:00
Name : "test1" ,
Labels : map [ string ] string { "col1" : "asd" , "COL2" : "zxc" } ,
} ,
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
} ,
true ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test1" , "1/2" , "podPhase" , 6 , "<unknown>" , "COL2=zxc,col1=asd" } } } ,
2016-02-04 07:08:44 +00:00
} ,
{
// Test name, num of containers, restarts, container ready status
api . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2016-02-04 07:08:44 +00:00
Name : "test1" ,
Labels : map [ string ] string { "col3" : "asd" , "COL4" : "zxc" } ,
} ,
Spec : api . PodSpec { Containers : make ( [ ] api . Container , 2 ) } ,
Status : api . PodStatus {
Phase : "podPhase" ,
ContainerStatuses : [ ] api . ContainerStatus {
{ Ready : true , RestartCount : 3 , State : api . ContainerState { Running : & api . ContainerStateRunning { } } } ,
{ RestartCount : 3 } ,
} ,
} ,
} ,
false ,
2017-05-26 23:00:01 +00:00
[ ] metav1alpha1 . TableRow { { Cells : [ ] interface { } { "test1" , "1/2" , "podPhase" , 6 , "<unknown>" } } } ,
2016-02-04 07:08:44 +00:00
} ,
}
2017-05-26 23:00:01 +00:00
for i , test := range tests {
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . pod , printers . PrintOptions { ShowLabels : test . showLabels } )
if err != nil {
t . Fatal ( err )
}
rows := table . Rows
for i := range rows {
rows [ i ] . Object . Object = nil
}
if ! reflect . DeepEqual ( test . expect , rows ) {
t . Errorf ( "%d mismatch: %s" , i , diff . ObjectReflectDiff ( test . expect , rows ) )
2016-02-04 07:08:44 +00:00
}
}
}
2016-10-17 05:48:56 +00:00
func TestPrintService ( t * testing . T ) {
2017-06-23 16:10:33 +00:00
single_ExternalIP := [ ] string { "80.11.12.10" }
mul_ExternalIP := [ ] string { "80.11.12.10" , "80.11.12.11" }
2016-10-17 05:48:56 +00:00
tests := [ ] struct {
service api . Service
expect string
} {
{
// Test name, cluster ip, port with protocol
api . Service {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test1" } ,
2016-10-17 05:48:56 +00:00
Spec : api . ServiceSpec {
Type : api . ServiceTypeClusterIP ,
Ports : [ ] api . ServicePort {
2017-06-23 16:10:33 +00:00
{
Protocol : "tcp" ,
Port : 2233 ,
} ,
2016-10-17 05:48:56 +00:00
} ,
2017-06-18 04:19:57 +00:00
ClusterIP : "10.9.8.7" ,
2016-10-17 05:48:56 +00:00
} ,
} ,
2017-06-18 04:19:57 +00:00
"test1\tClusterIP\t10.9.8.7\t<none>\t2233/tcp\t<unknown>\n" ,
2016-10-17 05:48:56 +00:00
} ,
{
2017-06-23 16:10:33 +00:00
// Test NodePort service
2016-10-17 05:48:56 +00:00
api . Service {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "test2" } ,
2016-10-17 05:48:56 +00:00
Spec : api . ServiceSpec {
2017-06-18 04:19:57 +00:00
Type : api . ServiceTypeNodePort ,
2016-10-17 05:48:56 +00:00
Ports : [ ] api . ServicePort {
2017-06-23 16:10:33 +00:00
{
Protocol : "tcp" ,
2016-10-17 05:48:56 +00:00
Port : 8888 ,
NodePort : 9999 ,
} ,
} ,
ClusterIP : "10.9.8.7" ,
} ,
} ,
2017-06-18 04:19:57 +00:00
"test2\tNodePort\t10.9.8.7\t<none>\t8888:9999/tcp\t<unknown>\n" ,
2016-10-17 05:48:56 +00:00
} ,
2017-06-23 16:10:33 +00:00
{
// Test LoadBalancer service
api . Service {
ObjectMeta : metav1 . ObjectMeta { Name : "test3" } ,
Spec : api . ServiceSpec {
Type : api . ServiceTypeLoadBalancer ,
Ports : [ ] api . ServicePort {
{
Protocol : "tcp" ,
Port : 8888 ,
} ,
} ,
ClusterIP : "10.9.8.7" ,
} ,
} ,
"test3\tLoadBalancer\t10.9.8.7\t<pending>\t8888/tcp\t<unknown>\n" ,
} ,
{
// Test LoadBalancer service with single ExternalIP and no LoadBalancerStatus
api . Service {
ObjectMeta : metav1 . ObjectMeta { Name : "test4" } ,
Spec : api . ServiceSpec {
Type : api . ServiceTypeLoadBalancer ,
Ports : [ ] api . ServicePort {
{
Protocol : "tcp" ,
Port : 8888 ,
} ,
} ,
ClusterIP : "10.9.8.7" ,
ExternalIPs : single_ExternalIP ,
} ,
} ,
"test4\tLoadBalancer\t10.9.8.7\t80.11.12.10\t8888/tcp\t<unknown>\n" ,
} ,
{
// Test LoadBalancer service with single ExternalIP
api . Service {
ObjectMeta : metav1 . ObjectMeta { Name : "test5" } ,
Spec : api . ServiceSpec {
Type : api . ServiceTypeLoadBalancer ,
Ports : [ ] api . ServicePort {
{
Protocol : "tcp" ,
Port : 8888 ,
} ,
} ,
ClusterIP : "10.9.8.7" ,
ExternalIPs : single_ExternalIP ,
} ,
Status : api . ServiceStatus {
LoadBalancer : api . LoadBalancerStatus {
Ingress : [ ] api . LoadBalancerIngress {
{
IP : "3.4.5.6" ,
Hostname : "test.cluster.com" ,
} ,
} ,
} ,
} ,
} ,
"test5\tLoadBalancer\t10.9.8.7\t3.4.5.6,80.11.12.10\t8888/tcp\t<unknown>\n" ,
} ,
{
// Test LoadBalancer service with mul ExternalIPs
api . Service {
ObjectMeta : metav1 . ObjectMeta { Name : "test6" } ,
Spec : api . ServiceSpec {
Type : api . ServiceTypeLoadBalancer ,
Ports : [ ] api . ServicePort {
{
Protocol : "tcp" ,
Port : 8888 ,
} ,
} ,
ClusterIP : "10.9.8.7" ,
ExternalIPs : mul_ExternalIP ,
} ,
Status : api . ServiceStatus {
LoadBalancer : api . LoadBalancerStatus {
Ingress : [ ] api . LoadBalancerIngress {
{
IP : "2.3.4.5" ,
Hostname : "test.cluster.local" ,
} ,
{
IP : "3.4.5.6" ,
Hostname : "test.cluster.com" ,
} ,
} ,
} ,
} ,
} ,
"test6\tLoadBalancer\t10.9.8.7\t2.3.4.5,3.4.5.6,80.11.12.10,80.11.12.11\t8888/tcp\t<unknown>\n" ,
} ,
{
// Test ExternalName service
api . Service {
ObjectMeta : metav1 . ObjectMeta { Name : "test7" } ,
Spec : api . ServiceSpec {
Type : api . ServiceTypeExternalName ,
ExternalName : "my.database.example.com" ,
} ,
} ,
"test7\tExternalName\t<none>\tmy.database.example.com\t<none>\t<unknown>\n" ,
} ,
2016-10-17 05:48:56 +00:00
}
buf := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
2017-07-21 07:42:30 +00:00
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . service , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
2016-10-17 05:48:56 +00:00
// We ignore time
if buf . String ( ) != test . expect {
2017-04-19 01:30:26 +00:00
t . Fatalf ( "Expected: %s, but got: %s" , test . expect , buf . String ( ) )
2016-10-17 05:48:56 +00:00
}
buf . Reset ( )
}
}
2016-11-09 12:39:16 +00:00
func TestPrintPodDisruptionBudget ( t * testing . T ) {
2017-05-15 23:50:23 +00:00
minAvailable := intstr . FromInt ( 22 )
2017-07-19 14:22:01 +00:00
maxUnavailable := intstr . FromInt ( 11 )
2016-11-09 12:39:16 +00:00
tests := [ ] struct {
pdb policy . PodDisruptionBudget
expect string
} {
{
policy . PodDisruptionBudget {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2016-11-09 12:39:16 +00:00
Namespace : "ns1" ,
Name : "pdb1" ,
2016-12-03 18:57:26 +00:00
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
2016-11-09 12:39:16 +00:00
} ,
Spec : policy . PodDisruptionBudgetSpec {
2017-05-15 23:50:23 +00:00
MinAvailable : & minAvailable ,
2016-11-09 12:39:16 +00:00
} ,
Status : policy . PodDisruptionBudgetStatus {
PodDisruptionsAllowed : 5 ,
} ,
} ,
2017-05-15 23:50:23 +00:00
"pdb1\t22\tN/A\t5\t0s\n" ,
2017-07-19 14:22:01 +00:00
} ,
{
policy . PodDisruptionBudget {
ObjectMeta : metav1 . ObjectMeta {
Namespace : "ns2" ,
Name : "pdb2" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
} ,
Spec : policy . PodDisruptionBudgetSpec {
MaxUnavailable : & maxUnavailable ,
} ,
Status : policy . PodDisruptionBudgetStatus {
PodDisruptionsAllowed : 5 ,
} ,
} ,
"pdb2\tN/A\t11\t5\t0s\n" ,
2016-11-09 12:39:16 +00:00
} }
buf := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
2017-06-24 22:31:36 +00:00
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . pdb , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
2016-11-09 12:39:16 +00:00
if buf . String ( ) != test . expect {
t . Fatalf ( "Expected: %s, got: %s" , test . expect , buf . String ( ) )
}
buf . Reset ( )
}
}
2017-01-05 20:29:44 +00:00
func TestAllowMissingKeys ( t * testing . T ) {
tests := [ ] struct {
2017-10-30 19:54:44 +00:00
Name string
PrintOpts * printers . PrintOptions
Input runtime . Object
Expect string
Error string
2017-01-05 20:29:44 +00:00
} {
2017-10-30 19:54:44 +00:00
{ "test template, allow missing keys" , & printers . PrintOptions { OutputFormatType : "template" , OutputFormatArgument : "{{.blarg}}" , AllowMissingKeys : true } , & api . Pod { } , "<no value>" , "" } ,
{ "test template, strict" , & printers . PrintOptions { OutputFormatType : "template" , OutputFormatArgument : "{{.blarg}}" , AllowMissingKeys : false } , & api . Pod { } , "" , ` error executing template " {{ .blarg }} ": template: output:1:2: executing "output" at <.blarg>: map has no entry for key "blarg" ` } ,
{ "test jsonpath, allow missing keys" , & printers . PrintOptions { OutputFormatType : "jsonpath" , OutputFormatArgument : "{.blarg}" , AllowMissingKeys : true } , & api . Pod { } , "" , "" } ,
{ "test jsonpath, strict" , & printers . PrintOptions { OutputFormatType : "jsonpath" , OutputFormatArgument : "{.blarg}" , AllowMissingKeys : false } , & api . Pod { } , "" , "error executing jsonpath \"{.blarg}\": blarg is not found\n" } ,
2017-01-05 20:29:44 +00:00
}
for _ , test := range tests {
buf := bytes . NewBuffer ( [ ] byte { } )
2017-10-30 19:54:44 +00:00
printer , err := printers . GetStandardPrinter ( legacyscheme . Registry . RESTMapper ( legacyscheme . Registry . EnabledVersions ( ) ... ) , legacyscheme . Scheme , legacyscheme . Codecs . LegacyCodec ( legacyscheme . Registry . EnabledVersions ( ) ... ) , [ ] runtime . Decoder { legacyscheme . Codecs . UniversalDecoder ( ) , unstructured . UnstructuredJSONScheme } , * test . PrintOpts )
2017-01-05 20:29:44 +00:00
if err != nil {
t . Errorf ( "in %s, unexpected error: %#v" , test . Name , err )
}
err = printer . PrintObj ( test . Input , buf )
if len ( test . Error ) == 0 && err != nil {
t . Errorf ( "in %s, unexpected error: %v" , test . Name , err )
continue
}
if len ( test . Error ) > 0 {
if err == nil {
t . Errorf ( "in %s, expected to get error: %v" , test . Name , test . Error )
} else if e , a := test . Error , err . Error ( ) ; e != a {
t . Errorf ( "in %s, expected error %q, got %q" , test . Name , e , a )
}
continue
}
if buf . String ( ) != test . Expect {
t . Errorf ( "in %s, expect %q, got %q" , test . Name , test . Expect , buf . String ( ) )
}
}
}
2017-05-30 23:10:56 +00:00
func TestPrintControllerRevision ( t * testing . T ) {
tests := [ ] struct {
history apps . ControllerRevision
expect string
} {
{
apps . ControllerRevision {
ObjectMeta : metav1 . ObjectMeta {
Name : "test1" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
OwnerReferences : [ ] metav1 . OwnerReference {
{
Controller : boolP ( true ) ,
Kind : "DaemonSet" ,
Name : "foo" ,
} ,
} ,
} ,
Revision : 1 ,
} ,
"test1\tDaemonSet/foo\t1\t0s\n" ,
} ,
{
apps . ControllerRevision {
ObjectMeta : metav1 . ObjectMeta {
Name : "test2" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
OwnerReferences : [ ] metav1 . OwnerReference {
{
Controller : boolP ( false ) ,
Kind : "ABC" ,
Name : "foo" ,
} ,
} ,
} ,
Revision : 2 ,
} ,
"test2\t<none>\t2\t0s\n" ,
} ,
{
apps . ControllerRevision {
ObjectMeta : metav1 . ObjectMeta {
Name : "test3" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
OwnerReferences : [ ] metav1 . OwnerReference { } ,
} ,
Revision : 3 ,
} ,
"test3\t<none>\t3\t0s\n" ,
} ,
{
apps . ControllerRevision {
ObjectMeta : metav1 . ObjectMeta {
Name : "test4" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
OwnerReferences : nil ,
} ,
Revision : 4 ,
} ,
"test4\t<none>\t4\t0s\n" ,
} ,
}
buf := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
2017-07-28 08:29:45 +00:00
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . history , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
2017-05-30 23:10:56 +00:00
if buf . String ( ) != test . expect {
t . Fatalf ( "Expected: %s, but got: %s" , test . expect , buf . String ( ) )
}
buf . Reset ( )
}
}
func boolP ( b bool ) * bool {
return & b
}
2017-06-02 02:07:30 +00:00
func TestPrintReplicaSet ( t * testing . T ) {
tests := [ ] struct {
replicaSet extensions . ReplicaSet
expect string
wideExpect string
} {
{
extensions . ReplicaSet {
ObjectMeta : metav1 . ObjectMeta {
Name : "test1" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
} ,
Spec : extensions . ReplicaSetSpec {
Replicas : 5 ,
Template : api . PodTemplateSpec {
Spec : api . PodSpec {
Containers : [ ] api . Container {
{
Name : "fake-container1" ,
Image : "fake-image1" ,
} ,
{
Name : "fake-container2" ,
Image : "fake-image2" ,
} ,
} ,
} ,
} ,
Selector : & metav1 . LabelSelector { MatchLabels : map [ string ] string { "foo" : "bar" } } ,
} ,
Status : extensions . ReplicaSetStatus {
Replicas : 5 ,
ReadyReplicas : 2 ,
} ,
} ,
"test1\t5\t5\t2\t0s\n" ,
"test1\t5\t5\t2\t0s\tfake-container1,fake-container2\tfake-image1,fake-image2\tfoo=bar\n" ,
} ,
}
buf := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
2017-06-24 22:31:36 +00:00
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . replicaSet , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
2017-06-02 02:07:30 +00:00
if buf . String ( ) != test . expect {
t . Fatalf ( "Expected: %s, got: %s" , test . expect , buf . String ( ) )
}
buf . Reset ( )
2017-06-24 22:31:36 +00:00
table , err = printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . replicaSet , printers . PrintOptions { Wide : true } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true , Wide : true } ) ; err != nil {
t . Fatal ( err )
}
2017-06-02 02:07:30 +00:00
if buf . String ( ) != test . wideExpect {
t . Fatalf ( "Expected: %s, got: %s" , test . wideExpect , buf . String ( ) )
}
buf . Reset ( )
}
}
2017-08-19 09:02:58 +00:00
func TestPrintPersistentVolumeClaim ( t * testing . T ) {
myScn := "my-scn"
tests := [ ] struct {
pvc api . PersistentVolumeClaim
expect string
} {
{
// Test name, num of containers, restarts, container ready status
api . PersistentVolumeClaim {
ObjectMeta : metav1 . ObjectMeta {
Name : "test1" ,
} ,
Spec : api . PersistentVolumeClaimSpec {
VolumeName : "my-volume" ,
} ,
Status : api . PersistentVolumeClaimStatus {
Phase : api . ClaimBound ,
AccessModes : [ ] api . PersistentVolumeAccessMode { api . ReadOnlyMany } ,
Capacity : map [ api . ResourceName ] resource . Quantity {
api . ResourceStorage : resource . MustParse ( "4Gi" ) ,
} ,
} ,
} ,
"test1\tBound\tmy-volume\t4Gi\tROX\t\t<unknown>\n" ,
} ,
{
// Test name, num of containers, restarts, container ready status
api . PersistentVolumeClaim {
ObjectMeta : metav1 . ObjectMeta {
Name : "test2" ,
} ,
Spec : api . PersistentVolumeClaimSpec { } ,
Status : api . PersistentVolumeClaimStatus {
Phase : api . ClaimLost ,
AccessModes : [ ] api . PersistentVolumeAccessMode { api . ReadOnlyMany } ,
Capacity : map [ api . ResourceName ] resource . Quantity {
api . ResourceStorage : resource . MustParse ( "4Gi" ) ,
} ,
} ,
} ,
"test2\tLost\t\t\t\t\t<unknown>\n" ,
} ,
{
// Test name, num of containers, restarts, container ready status
api . PersistentVolumeClaim {
ObjectMeta : metav1 . ObjectMeta {
Name : "test3" ,
} ,
Spec : api . PersistentVolumeClaimSpec {
VolumeName : "my-volume" ,
} ,
Status : api . PersistentVolumeClaimStatus {
Phase : api . ClaimPending ,
AccessModes : [ ] api . PersistentVolumeAccessMode { api . ReadWriteMany } ,
Capacity : map [ api . ResourceName ] resource . Quantity {
api . ResourceStorage : resource . MustParse ( "10Gi" ) ,
} ,
} ,
} ,
"test3\tPending\tmy-volume\t10Gi\tRWX\t\t<unknown>\n" ,
} ,
{
// Test name, num of containers, restarts, container ready status
api . PersistentVolumeClaim {
ObjectMeta : metav1 . ObjectMeta {
Name : "test4" ,
} ,
Spec : api . PersistentVolumeClaimSpec {
VolumeName : "my-volume" ,
StorageClassName : & myScn ,
} ,
Status : api . PersistentVolumeClaimStatus {
Phase : api . ClaimPending ,
AccessModes : [ ] api . PersistentVolumeAccessMode { api . ReadWriteOnce } ,
Capacity : map [ api . ResourceName ] resource . Quantity {
api . ResourceStorage : resource . MustParse ( "10Gi" ) ,
} ,
} ,
} ,
"test4\tPending\tmy-volume\t10Gi\tRWO\tmy-scn\t<unknown>\n" ,
} ,
}
buf := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . pvc , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
if buf . String ( ) != test . expect {
fmt . Println ( buf . String ( ) )
fmt . Println ( test . expect )
t . Fatalf ( "Expected: %s, but got: %s" , test . expect , buf . String ( ) )
}
buf . Reset ( )
}
}
2017-09-15 09:55:40 +00:00
func TestPrintCronJob ( t * testing . T ) {
suspend := false
tests := [ ] struct {
cronjob batch . CronJob
expect string
} {
{
batch . CronJob {
ObjectMeta : metav1 . ObjectMeta {
Name : "cronjob1" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
} ,
Spec : batch . CronJobSpec {
Schedule : "0/5 * * * ?" ,
Suspend : & suspend ,
} ,
Status : batch . CronJobStatus {
LastScheduleTime : & metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
} ,
} ,
"cronjob1\t0/5 * * * ?\tFalse\t0\t0s\t0s\n" ,
} ,
{
batch . CronJob {
ObjectMeta : metav1 . ObjectMeta {
Name : "cronjob2" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( - 3e11 ) } ,
} ,
Spec : batch . CronJobSpec {
Schedule : "0/5 * * * ?" ,
Suspend : & suspend ,
} ,
Status : batch . CronJobStatus {
LastScheduleTime : & metav1 . Time { Time : time . Now ( ) . Add ( - 3e10 ) } ,
} ,
} ,
"cronjob2\t0/5 * * * ?\tFalse\t0\t30s\t5m\n" ,
} ,
{
batch . CronJob {
ObjectMeta : metav1 . ObjectMeta {
Name : "cronjob3" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( - 3e11 ) } ,
} ,
Spec : batch . CronJobSpec {
Schedule : "0/5 * * * ?" ,
Suspend : & suspend ,
} ,
Status : batch . CronJobStatus { } ,
} ,
"cronjob3\t0/5 * * * ?\tFalse\t0\t<none>\t5m\n" ,
} ,
}
buf := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . cronjob , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
if buf . String ( ) != test . expect {
t . Fatalf ( "Expected: %s, got: %s" , test . expect , buf . String ( ) )
}
buf . Reset ( )
}
}
func TestPrintStorageClass ( t * testing . T ) {
tests := [ ] struct {
sc storage . StorageClass
expect string
} {
{
storage . StorageClass {
ObjectMeta : metav1 . ObjectMeta {
Name : "sc1" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( 1.9e9 ) } ,
} ,
Provisioner : "kubernetes.io/glusterfs" ,
} ,
"sc1\tkubernetes.io/glusterfs\t0s\n" ,
} ,
{
storage . StorageClass {
ObjectMeta : metav1 . ObjectMeta {
Name : "sc2" ,
CreationTimestamp : metav1 . Time { Time : time . Now ( ) . Add ( - 3e11 ) } ,
} ,
Provisioner : "kubernetes.io/nfs" ,
} ,
"sc2\tkubernetes.io/nfs\t5m\n" ,
} ,
}
buf := bytes . NewBuffer ( [ ] byte { } )
for _ , test := range tests {
table , err := printers . NewTablePrinter ( ) . With ( AddHandlers ) . PrintTable ( & test . sc , printers . PrintOptions { } )
if err != nil {
t . Fatal ( err )
}
if err := printers . PrintTable ( table , buf , printers . PrintOptions { NoHeaders : true } ) ; err != nil {
t . Fatal ( err )
}
if buf . String ( ) != test . expect {
t . Fatalf ( "Expected: %s, got: %s" , test . expect , buf . String ( ) )
}
buf . Reset ( )
}
}