2014-12-27 21:48:27 +00:00
/ *
2016-06-03 00:25:58 +00:00
Copyright 2014 The Kubernetes Authors .
2014-12-27 21:48:27 +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 .
* /
package resource
import (
"bytes"
2015-05-14 04:35:11 +00:00
"fmt"
2014-12-27 21:48:27 +00:00
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
2016-03-28 19:44:21 +00:00
"os"
2016-12-15 22:58:49 +00:00
"path/filepath"
2014-12-27 21:48:27 +00:00
"reflect"
2016-03-28 19:44:21 +00:00
"strings"
2014-12-27 21:48:27 +00:00
"testing"
2018-05-09 19:02:06 +00:00
"github.com/davecgh/go-spew/spew"
2015-01-14 05:03:56 +00:00
"github.com/ghodss/yaml"
2017-01-25 13:39:54 +00:00
apiequality "k8s.io/apimachinery/pkg/api/equality"
2017-01-11 14:09:48 +00:00
"k8s.io/apimachinery/pkg/api/meta"
2018-04-26 15:55:50 +00:00
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
2017-01-25 13:13:07 +00:00
"k8s.io/apimachinery/pkg/api/resource"
2017-01-11 14:09:48 +00:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
2017-11-02 20:06:07 +00:00
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
2017-01-11 14:09:48 +00:00
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/watch"
2017-11-16 02:00:32 +00:00
"k8s.io/client-go/rest"
2017-01-24 15:00:24 +00:00
"k8s.io/client-go/rest/fake"
2017-01-18 21:01:15 +00:00
restclientwatch "k8s.io/client-go/rest/watch"
2017-01-23 18:37:22 +00:00
utiltesting "k8s.io/client-go/util/testing"
2018-04-27 12:40:57 +00:00
2018-05-09 19:02:06 +00:00
// TODO we need to remove this linkage and create our own scheme
2018-05-10 12:20:27 +00:00
"k8s.io/api/core/v1"
2018-05-09 19:02:06 +00:00
"k8s.io/client-go/kubernetes/scheme"
2017-11-02 20:06:07 +00:00
)
var (
corev1GV = schema . GroupVersion { Version : "v1" }
corev1Codec = scheme . Codecs . CodecForVersions ( scheme . Codecs . LegacyCodec ( corev1GV ) , scheme . Codecs . UniversalDecoder ( corev1GV ) , corev1GV , corev1GV )
metaAccessor = meta . NewAccessor ( )
2014-12-27 21:48:27 +00:00
)
func stringBody ( body string ) io . ReadCloser {
return ioutil . NopCloser ( bytes . NewReader ( [ ] byte ( body ) ) )
}
func watchBody ( events ... watch . Event ) string {
buf := & bytes . Buffer { }
2017-11-02 20:06:07 +00:00
codec := corev1Codec
2016-12-11 20:59:34 +00:00
enc := restclientwatch . NewEncoder ( streaming . NewEncoder ( buf , codec ) , codec )
2014-12-27 21:48:27 +00:00
for _ , e := range events {
enc . Encode ( & e )
}
return buf . String ( )
}
2018-04-27 15:38:34 +00:00
func fakeClient ( ) FakeClientFunc {
return func ( version schema . GroupVersion ) ( RESTClient , error ) {
2015-09-11 20:47:53 +00:00
return & fake . RESTClient { } , nil
2018-04-27 15:38:34 +00:00
}
2014-12-27 21:48:27 +00:00
}
2018-04-27 15:38:34 +00:00
func fakeClientWith ( testName string , t * testing . T , data map [ string ] string ) FakeClientFunc {
return func ( version schema . GroupVersion ) ( RESTClient , error ) {
2015-09-11 20:47:53 +00:00
return & fake . RESTClient {
2017-11-02 20:06:07 +00:00
GroupVersion : corev1GV ,
NegotiatedSerializer : serializer . DirectCodecFactory { CodecFactory : scheme . Codecs } ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2014-12-27 21:48:27 +00:00
p := req . URL . Path
q := req . URL . RawQuery
if len ( q ) != 0 {
p = p + "?" + q
}
body , ok := data [ p ]
if ! ok {
2015-04-20 19:00:52 +00:00
t . Fatalf ( "%s: unexpected request: %s (%s)\n%#v" , testName , p , req . URL , req )
2014-12-27 21:48:27 +00:00
}
2016-05-11 07:50:47 +00:00
header := http . Header { }
header . Set ( "Content-Type" , runtime . ContentTypeJSON )
2014-12-27 21:48:27 +00:00
return & http . Response {
StatusCode : http . StatusOK ,
2016-05-11 07:50:47 +00:00
Header : header ,
2014-12-27 21:48:27 +00:00
Body : stringBody ( body ) ,
} , nil
} ) ,
} , nil
2018-04-27 15:38:34 +00:00
}
2014-12-27 21:48:27 +00:00
}
2017-11-02 20:06:07 +00:00
func testData ( ) ( * v1 . PodList , * v1 . ServiceList ) {
pods := & v1 . PodList {
2016-12-03 18:57:26 +00:00
ListMeta : metav1 . ListMeta {
2014-12-27 21:48:27 +00:00
ResourceVersion : "15" ,
} ,
2017-11-02 20:06:07 +00:00
Items : [ ] v1 . Pod {
2014-12-27 21:48:27 +00:00
{
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo" , Namespace : "test" , ResourceVersion : "10" } ,
2017-11-02 20:06:07 +00:00
Spec : V1DeepEqualSafePodSpec ( ) ,
2014-12-27 21:48:27 +00:00
} ,
{
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "bar" , Namespace : "test" , ResourceVersion : "11" } ,
2017-11-02 20:06:07 +00:00
Spec : V1DeepEqualSafePodSpec ( ) ,
2014-12-27 21:48:27 +00:00
} ,
} ,
}
2017-11-02 20:06:07 +00:00
svc := & v1 . ServiceList {
2016-12-03 18:57:26 +00:00
ListMeta : metav1 . ListMeta {
2014-12-27 21:48:27 +00:00
ResourceVersion : "16" ,
} ,
2017-11-02 20:06:07 +00:00
Items : [ ] v1 . Service {
2014-12-27 21:48:27 +00:00
{
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "baz" , Namespace : "test" , ResourceVersion : "12" } ,
2017-11-02 20:06:07 +00:00
Spec : v1 . ServiceSpec {
2015-07-09 09:05:13 +00:00
Type : "ClusterIP" ,
SessionAffinity : "None" ,
} ,
2014-12-27 21:48:27 +00:00
} ,
} ,
}
return pods , svc
}
2017-11-02 20:06:07 +00:00
func streamTestData ( ) ( io . Reader , * v1 . PodList , * v1 . ServiceList ) {
2014-12-27 21:48:27 +00:00
pods , svc := testData ( )
r , w := io . Pipe ( )
go func ( ) {
defer w . Close ( )
2017-11-02 20:06:07 +00:00
w . Write ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , pods ) ) )
w . Write ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , svc ) ) )
2014-12-27 21:48:27 +00:00
} ( )
return r , pods , svc
}
2015-01-14 05:03:56 +00:00
func JSONToYAMLOrDie ( in [ ] byte ) [ ] byte {
data , err := yaml . JSONToYAML ( in )
if err != nil {
panic ( err )
}
return data
}
2017-11-02 20:06:07 +00:00
func streamYAMLTestData ( ) ( io . Reader , * v1 . PodList , * v1 . ServiceList ) {
2015-01-14 05:03:56 +00:00
pods , svc := testData ( )
r , w := io . Pipe ( )
go func ( ) {
defer w . Close ( )
2017-11-02 20:06:07 +00:00
w . Write ( JSONToYAMLOrDie ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , pods ) ) ) )
2015-01-14 05:03:56 +00:00
w . Write ( [ ] byte ( "\n---\n" ) )
2017-11-02 20:06:07 +00:00
w . Write ( JSONToYAMLOrDie ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , svc ) ) ) )
2015-01-14 05:03:56 +00:00
} ( )
return r , pods , svc
}
2015-05-08 03:51:36 +00:00
func streamTestObject ( obj runtime . O bject ) io . Reader {
r , w := io . Pipe ( )
go func ( ) {
defer w . Close ( )
2017-11-02 20:06:07 +00:00
w . Write ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , obj ) ) )
2015-05-08 03:51:36 +00:00
} ( )
return r
}
2014-12-27 21:48:27 +00:00
type testVisitor struct {
InjectErr error
Infos [ ] * Info
}
2015-06-15 02:48:56 +00:00
func ( v * testVisitor ) Handle ( info * Info , err error ) error {
if err != nil {
return err
}
2014-12-27 21:48:27 +00:00
v . Infos = append ( v . Infos , info )
return v . InjectErr
}
func ( v * testVisitor ) Objects ( ) [ ] runtime . Object {
objects := [ ] runtime . Object { }
for i := range v . Infos {
objects = append ( objects , v . Infos [ i ] . Object )
}
return objects
}
2016-03-28 19:44:21 +00:00
var aPod string = `
{
"kind" : "Pod" ,
2017-11-02 20:06:07 +00:00
"apiVersion" : "` + corev1GV.String() + `" ,
2016-03-28 19:44:21 +00:00
"metadata" : {
"name" : "busybox{id}" ,
"labels" : {
"name" : "busybox{id}"
}
} ,
"spec" : {
"containers" : [
{
"name" : "busybox" ,
"image" : "busybox" ,
"command" : [
"sleep" ,
"3600"
] ,
"imagePullPolicy" : "IfNotPresent"
}
] ,
"restartPolicy" : "Always"
}
}
`
var aRC string = `
{
"kind" : "ReplicationController" ,
2017-11-02 20:06:07 +00:00
"apiVersion" : "` + corev1GV.String() + `" ,
2016-03-28 19:44:21 +00:00
"metadata" : {
"name" : "busybox{id}" ,
"labels" : {
"app" : "busybox"
}
} ,
"spec" : {
"replicas" : 1 ,
"template" : {
"metadata" : {
"name" : "busybox{id}" ,
"labels" : {
"app" : "busybox{id}"
}
} ,
"spec" : {
"containers" : [
{
"name" : "busybox" ,
"image" : "busybox" ,
"command" : [
"sleep" ,
"3600"
] ,
"imagePullPolicy" : "IfNotPresent"
}
] ,
"restartPolicy" : "Always"
}
}
}
}
`
2017-11-14 03:56:59 +00:00
func newDefaultBuilder ( ) * Builder {
return newDefaultBuilderWith ( fakeClient ( ) )
}
2018-04-27 15:38:34 +00:00
func newDefaultBuilderWith ( fakeClientFn FakeClientFunc ) * Builder {
2018-05-09 15:12:32 +00:00
return NewFakeBuilder ( fakeClientFn , testrestmapper . TestOnlyStaticRESTMapper ( scheme . Scheme ) , FakeCategoryExpander ) .
2018-05-07 12:32:20 +00:00
WithScheme ( scheme . Scheme , scheme . Scheme . PrioritizedVersionsAllGroups ( ) ... )
2017-11-14 03:56:59 +00:00
}
2015-12-21 05:37:49 +00:00
func TestPathBuilderAndVersionedObjectNotDefaulted ( t * testing . T ) {
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2018-05-10 12:20:27 +00:00
FilenameParam ( false , & FilenameOptions { Recursive : false , Filenames : [ ] string { "../../../../test/fixtures/pkg/kubectl/builder/kitten-rc.yaml" } } )
2014-12-27 21:48:27 +00:00
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2014-12-27 21:48:27 +00:00
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err != nil || ! singleItemImplied || len ( test . Infos ) != 1 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2014-12-27 21:48:27 +00:00
}
info := test . Infos [ 0 ]
2015-12-21 05:37:49 +00:00
if info . Name != "update-demo-kitten" || info . Namespace != "" || info . Object == nil {
2014-12-27 21:48:27 +00:00
t . Errorf ( "unexpected info: %#v" , info )
}
2018-04-30 13:25:45 +00:00
obj := info . Object
2017-11-14 03:56:59 +00:00
version , ok := obj . ( * v1 . ReplicationController )
2015-12-21 05:37:49 +00:00
// versioned object does not have defaulting applied
2017-11-14 03:56:59 +00:00
if obj == nil || ! ok || version . Spec . Replicas != nil {
t . Errorf ( "unexpected versioned object: %#v" , obj )
2015-12-21 05:37:49 +00:00
}
2014-12-27 21:48:27 +00:00
}
2015-01-29 20:10:08 +00:00
func TestNodeBuilder ( t * testing . T ) {
2017-11-02 20:06:07 +00:00
node := & v1 . Node {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "node1" , Namespace : "should-not-have" , ResourceVersion : "10" } ,
2017-11-02 20:06:07 +00:00
Spec : v1 . NodeSpec { } ,
Status : v1 . NodeStatus {
Capacity : v1 . ResourceList {
v1 . ResourceCPU : resource . MustParse ( "1000m" ) ,
v1 . ResourceMemory : resource . MustParse ( "1Mi" ) ,
2015-01-29 20:10:08 +00:00
} ,
} ,
}
r , w := io . Pipe ( )
go func ( ) {
defer w . Close ( )
2017-11-02 20:06:07 +00:00
w . Write ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , node ) ) )
2015-01-29 20:10:08 +00:00
} ( )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) . NamespaceParam ( "test" ) . Stream ( r , "STDIN" )
2015-01-29 20:10:08 +00:00
test := & testVisitor { }
err := b . Do ( ) . Visit ( test . Handle )
if err != nil || len ( test . Infos ) != 1 {
t . Fatalf ( "unexpected response: %v %#v" , err , test . Infos )
}
info := test . Infos [ 0 ]
if info . Name != "node1" || info . Namespace != "" || info . Object == nil {
t . Errorf ( "unexpected info: %#v" , info )
}
}
2016-03-28 19:44:21 +00:00
func createTestDir ( t * testing . T , path string ) {
if err := os . MkdirAll ( path , 0750 ) ; err != nil {
t . Fatalf ( "error creating test dir: %v" , err )
}
}
func writeTestFile ( t * testing . T , path string , contents string ) {
if err := ioutil . WriteFile ( path , [ ] byte ( contents ) , 0644 ) ; err != nil {
t . Fatalf ( "error creating test file %#v" , err )
}
}
2014-12-27 21:48:27 +00:00
func TestPathBuilderWithMultiple ( t * testing . T ) {
2016-03-28 19:44:21 +00:00
// create test dirs
tmpDir , err := utiltesting . MkTmpdir ( "recursive_test_multiple" )
if err != nil {
t . Fatalf ( "error creating temp dir: %v" , err )
}
createTestDir ( t , fmt . Sprintf ( "%s/%s" , tmpDir , "recursive/pod/pod_1" ) )
createTestDir ( t , fmt . Sprintf ( "%s/%s" , tmpDir , "recursive/rc/rc_1" ) )
createTestDir ( t , fmt . Sprintf ( "%s/%s" , tmpDir , "inode/hardlink" ) )
defer os . RemoveAll ( tmpDir )
// create test files
writeTestFile ( t , fmt . Sprintf ( "%s/recursive/pod/busybox.json" , tmpDir ) , strings . Replace ( aPod , "{id}" , "0" , - 1 ) )
writeTestFile ( t , fmt . Sprintf ( "%s/recursive/pod/pod_1/busybox.json" , tmpDir ) , strings . Replace ( aPod , "{id}" , "1" , - 1 ) )
writeTestFile ( t , fmt . Sprintf ( "%s/recursive/rc/busybox.json" , tmpDir ) , strings . Replace ( aRC , "{id}" , "0" , - 1 ) )
writeTestFile ( t , fmt . Sprintf ( "%s/recursive/rc/rc_1/busybox.json" , tmpDir ) , strings . Replace ( aRC , "{id}" , "1" , - 1 ) )
writeTestFile ( t , fmt . Sprintf ( "%s/inode/hardlink/busybox.json" , tmpDir ) , strings . Replace ( aPod , "{id}" , "0" , - 1 ) )
if err := os . Link ( fmt . Sprintf ( "%s/inode/hardlink/busybox.json" , tmpDir ) , fmt . Sprintf ( "%s/inode/hardlink/busybox-link.json" , tmpDir ) ) ; err != nil {
t . Fatalf ( "error creating test file: %v" , err )
}
tests := [ ] struct {
name string
object runtime . Object
recursive bool
directory string
expectedNames [ ] string
} {
2018-05-10 12:20:27 +00:00
{ "pod" , & v1 . Pod { } , false , "../../../../test/e2e/testing-manifests/pod" , [ ] string { "nginx" } } ,
2017-11-02 20:06:07 +00:00
{ "recursive-pod" , & v1 . Pod { } , true , fmt . Sprintf ( "%s/recursive/pod" , tmpDir ) , [ ] string { "busybox0" , "busybox1" } } ,
2018-05-10 12:20:27 +00:00
{ "rc" , & v1 . ReplicationController { } , false , "../../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml" , [ ] string { "redis-master" } } ,
2017-11-02 20:06:07 +00:00
{ "recursive-rc" , & v1 . ReplicationController { } , true , fmt . Sprintf ( "%s/recursive/rc" , tmpDir ) , [ ] string { "busybox0" , "busybox1" } } ,
{ "hardlink" , & v1 . Pod { } , false , fmt . Sprintf ( "%s/inode/hardlink/busybox-link.json" , tmpDir ) , [ ] string { "busybox0" } } ,
{ "hardlink" , & v1 . Pod { } , true , fmt . Sprintf ( "%s/inode/hardlink/busybox-link.json" , tmpDir ) , [ ] string { "busybox0" } } ,
2016-03-28 19:44:21 +00:00
}
2014-12-27 21:48:27 +00:00
2018-05-12 09:24:28 +00:00
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
b := newDefaultBuilder ( ) .
FilenameParam ( false , & FilenameOptions { Recursive : tt . recursive , Filenames : [ ] string { tt . directory } } ) .
NamespaceParam ( "test" ) . DefaultNamespace ( )
2016-03-28 19:44:21 +00:00
2018-05-12 09:24:28 +00:00
testVisitor := & testVisitor { }
singleItemImplied := false
2016-03-28 19:44:21 +00:00
2018-05-12 09:24:28 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( testVisitor . Handle )
if err != nil {
t . Fatalf ( "unexpected response: %v %t %#v %s" , err , singleItemImplied , testVisitor . Infos , tt . name )
}
2016-03-28 19:44:21 +00:00
2018-05-12 09:24:28 +00:00
info := testVisitor . Infos
for i , v := range info {
switch tt . object . ( type ) {
case * v1 . Pod :
if _ , ok := v . Object . ( * v1 . Pod ) ; ! ok || v . Name != tt . expectedNames [ i ] || v . Namespace != "test" {
t . Errorf ( "unexpected info: %v" , spew . Sdump ( v . Object ) )
}
case * v1 . ReplicationController :
if _ , ok := v . Object . ( * v1 . ReplicationController ) ; ! ok || v . Name != tt . expectedNames [ i ] || v . Namespace != "test" {
t . Errorf ( "unexpected info: %v" , spew . Sdump ( v . Object ) )
}
2016-03-28 19:44:21 +00:00
}
}
2018-05-12 09:24:28 +00:00
} )
2014-12-27 21:48:27 +00:00
}
2016-03-28 19:44:21 +00:00
}
2014-12-27 21:48:27 +00:00
2016-03-28 19:44:21 +00:00
func TestPathBuilderWithMultipleInvalid ( t * testing . T ) {
// create test dirs
tmpDir , err := utiltesting . MkTmpdir ( "recursive_test_multiple_invalid" )
if err != nil {
t . Fatalf ( "error creating temp dir: %v" , err )
2015-07-07 20:43:55 +00:00
}
2016-03-28 19:44:21 +00:00
createTestDir ( t , fmt . Sprintf ( "%s/%s" , tmpDir , "inode/symlink/pod" ) )
defer os . RemoveAll ( tmpDir )
// create test files
writeTestFile ( t , fmt . Sprintf ( "%s/inode/symlink/pod/busybox.json" , tmpDir ) , strings . Replace ( aPod , "{id}" , "0" , - 1 ) )
if err := os . Symlink ( fmt . Sprintf ( "%s/inode/symlink/pod" , tmpDir ) , fmt . Sprintf ( "%s/inode/symlink/pod-link" , tmpDir ) ) ; err != nil {
t . Fatalf ( "error creating test file: %v" , err )
}
if err := os . Symlink ( fmt . Sprintf ( "%s/inode/symlink/loop" , tmpDir ) , fmt . Sprintf ( "%s/inode/symlink/loop" , tmpDir ) ) ; err != nil {
t . Fatalf ( "error creating test file: %v" , err )
}
tests := [ ] struct {
name string
recursive bool
directory string
} {
{ "symlink" , false , fmt . Sprintf ( "%s/inode/symlink/pod-link" , tmpDir ) } ,
{ "symlink" , true , fmt . Sprintf ( "%s/inode/symlink/pod-link" , tmpDir ) } ,
{ "loop" , false , fmt . Sprintf ( "%s/inode/symlink/loop" , tmpDir ) } ,
{ "loop" , true , fmt . Sprintf ( "%s/inode/symlink/loop" , tmpDir ) } ,
}
2018-05-12 09:24:28 +00:00
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
b := newDefaultBuilder ( ) .
FilenameParam ( false , & FilenameOptions { Recursive : tt . recursive , Filenames : [ ] string { tt . directory } } ) .
NamespaceParam ( "test" ) . DefaultNamespace ( )
2016-03-28 19:44:21 +00:00
2018-05-12 09:24:28 +00:00
testVisitor := & testVisitor { }
singleItemImplied := false
2016-03-28 19:44:21 +00:00
2018-05-12 09:24:28 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( testVisitor . Handle )
if err == nil {
t . Fatalf ( "unexpected response: %v %t %#v %s" , err , singleItemImplied , testVisitor . Infos , tt . name )
}
} )
2014-12-27 21:48:27 +00:00
}
}
func TestDirectoryBuilder ( t * testing . T ) {
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2018-05-10 12:20:27 +00:00
FilenameParam ( false , & FilenameOptions { Recursive : false , Filenames : [ ] string { "../../../../test/e2e/testing-manifests/guestbook/legacy" } } ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) . DefaultNamespace ( )
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2014-12-27 21:48:27 +00:00
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err != nil || singleItemImplied || len ( test . Infos ) < 3 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2014-12-27 21:48:27 +00:00
}
found := false
for _ , info := range test . Infos {
2015-04-22 21:37:46 +00:00
if info . Name == "redis-master" && info . Namespace == "test" && info . Object != nil {
2014-12-27 21:48:27 +00:00
found = true
2016-07-23 05:49:04 +00:00
break
2014-12-27 21:48:27 +00:00
}
}
if ! found {
t . Errorf ( "unexpected responses: %#v" , test . Infos )
}
}
2015-06-26 20:49:34 +00:00
func TestNamespaceOverride ( t * testing . T ) {
s := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , req * http . Request ) {
w . WriteHeader ( http . StatusOK )
2017-11-02 20:06:07 +00:00
w . Write ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , & v1 . Pod { ObjectMeta : metav1 . ObjectMeta { Namespace : "foo" , Name : "test" } } ) ) )
2015-06-26 20:49:34 +00:00
} ) )
2016-04-21 11:50:55 +00:00
defer s . Close ( )
2015-06-26 20:49:34 +00:00
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2016-08-17 18:28:07 +00:00
FilenameParam ( false , & FilenameOptions { Recursive : false , Filenames : [ ] string { s . URL } } ) .
2015-06-26 20:49:34 +00:00
NamespaceParam ( "test" )
test := & testVisitor { }
err := b . Do ( ) . Visit ( test . Handle )
if err != nil || len ( test . Infos ) != 1 && test . Infos [ 0 ] . Namespace != "foo" {
t . Fatalf ( "unexpected response: %v %#v" , err , test . Infos )
}
2017-11-14 03:56:59 +00:00
b = newDefaultBuilder ( ) .
2016-08-17 18:28:07 +00:00
FilenameParam ( true , & FilenameOptions { Recursive : false , Filenames : [ ] string { s . URL } } ) .
2015-06-26 20:49:34 +00:00
NamespaceParam ( "test" )
test = & testVisitor { }
err = b . Do ( ) . Visit ( test . Handle )
if err == nil {
t . Fatalf ( "expected namespace error. got: %#v" , test . Infos )
}
}
2014-12-27 21:48:27 +00:00
func TestURLBuilder ( t * testing . T ) {
s := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , req * http . Request ) {
w . WriteHeader ( http . StatusOK )
2017-11-02 20:06:07 +00:00
w . Write ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , & v1 . Pod { ObjectMeta : metav1 . ObjectMeta { Namespace : "foo" , Name : "test" } } ) ) )
w . Write ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , & v1 . Pod { ObjectMeta : metav1 . ObjectMeta { Namespace : "foo" , Name : "test1" } } ) ) )
2014-12-27 21:48:27 +00:00
} ) )
2016-04-21 11:50:55 +00:00
defer s . Close ( )
2014-12-27 21:48:27 +00:00
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2016-08-17 18:28:07 +00:00
FilenameParam ( false , & FilenameOptions { Recursive : false , Filenames : [ ] string { s . URL } } ) .
2016-02-25 20:43:48 +00:00
NamespaceParam ( "foo" )
2014-12-27 21:48:27 +00:00
test := & testVisitor { }
2016-02-25 20:43:48 +00:00
err := b . Do ( ) . Visit ( test . Handle )
if err != nil || len ( test . Infos ) != 2 {
t . Fatalf ( "unexpected response: %v %#v" , err , test . Infos )
2014-12-27 21:48:27 +00:00
}
info := test . Infos [ 0 ]
if info . Name != "test" || info . Namespace != "foo" || info . Object == nil {
t . Errorf ( "unexpected info: %#v" , info )
}
2016-02-25 20:43:48 +00:00
info = test . Infos [ 1 ]
if info . Name != "test1" || info . Namespace != "foo" || info . Object == nil {
t . Errorf ( "unexpected info: %#v" , info )
}
2014-12-27 21:48:27 +00:00
}
func TestURLBuilderRequireNamespace ( t * testing . T ) {
s := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , req * http . Request ) {
w . WriteHeader ( http . StatusOK )
2017-11-02 20:06:07 +00:00
w . Write ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , & v1 . Pod { ObjectMeta : metav1 . ObjectMeta { Namespace : "foo" , Name : "test" } } ) ) )
2014-12-27 21:48:27 +00:00
} ) )
2016-04-21 11:50:55 +00:00
defer s . Close ( )
2014-12-27 21:48:27 +00:00
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2016-08-17 18:28:07 +00:00
FilenameParam ( false , & FilenameOptions { Recursive : false , Filenames : [ ] string { s . URL } } ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) . RequireNamespace ( )
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2014-12-27 21:48:27 +00:00
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err == nil || ! singleItemImplied || len ( test . Infos ) != 0 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2014-12-27 21:48:27 +00:00
}
}
2018-05-08 17:50:36 +00:00
func TestReplaceAliases ( t * testing . T ) {
tests := [ ] struct {
name string
arg string
expected string
} {
{
name : "no-replacement" ,
arg : "service" ,
expected : "service" ,
} ,
{
name : "all-replacement" ,
arg : "all" ,
expected : "pods,replicationcontrollers,services,statefulsets.apps,horizontalpodautoscalers.autoscaling,jobs.batch,cronjobs.batch,daemonsets.extensions,deployments.extensions,replicasets.extensions" ,
} ,
{
name : "alias-in-comma-separated-arg" ,
arg : "all,secrets" ,
expected : "pods,replicationcontrollers,services,statefulsets.apps,horizontalpodautoscalers.autoscaling,jobs.batch,cronjobs.batch,daemonsets.extensions,deployments.extensions,replicasets.extensions,secrets" ,
} ,
}
b := newDefaultBuilder ( )
for _ , test := range tests {
replaced := b . ReplaceAliases ( test . arg )
if replaced != test . expected {
t . Errorf ( "%s: unexpected argument: expected %s, got %s" , test . name , test . expected , replaced )
}
}
}
2014-12-27 21:48:27 +00:00
func TestResourceByName ( t * testing . T ) {
pods , _ := testData ( )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-11-02 20:06:07 +00:00
"/namespaces/test/pods/foo" : runtime . EncodeOrDie ( corev1Codec , & pods . Items [ 0 ] ) ,
2017-11-14 03:56:59 +00:00
} ) ) . NamespaceParam ( "test" )
2014-12-27 21:48:27 +00:00
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2014-12-27 21:48:27 +00:00
if b . Do ( ) . Err ( ) == nil {
t . Errorf ( "unexpected non-error" )
}
2015-02-12 14:59:58 +00:00
b . ResourceTypeOrNameArgs ( true , "pods" , "foo" )
2014-12-27 21:48:27 +00:00
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err != nil || ! singleItemImplied || len ( test . Infos ) != 1 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2014-12-27 21:48:27 +00:00
}
2017-03-21 03:07:57 +00:00
if ! apiequality . Semantic . DeepEqual ( & pods . Items [ 0 ] , test . Objects ( ) [ 0 ] ) {
2015-07-09 09:05:13 +00:00
t . Errorf ( "unexpected object: %#v" , test . Objects ( ) [ 0 ] )
2014-12-27 21:48:27 +00:00
}
mapping , err := b . Do ( ) . ResourceMapping ( )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2018-05-01 17:02:44 +00:00
if mapping . Resource != ( schema . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ) {
2014-12-27 21:48:27 +00:00
t . Errorf ( "unexpected resource mapping: %#v" , mapping )
}
}
2015-08-19 08:33:02 +00:00
func TestMultipleResourceByTheSameName ( t * testing . T ) {
pods , svcs := testData ( )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-11-02 20:06:07 +00:00
"/namespaces/test/pods/foo" : runtime . EncodeOrDie ( corev1Codec , & pods . Items [ 0 ] ) ,
"/namespaces/test/pods/baz" : runtime . EncodeOrDie ( corev1Codec , & pods . Items [ 1 ] ) ,
"/namespaces/test/services/foo" : runtime . EncodeOrDie ( corev1Codec , & svcs . Items [ 0 ] ) ,
"/namespaces/test/services/baz" : runtime . EncodeOrDie ( corev1Codec , & svcs . Items [ 0 ] ) ,
2017-11-14 03:56:59 +00:00
} ) ) .
2015-08-19 08:33:02 +00:00
NamespaceParam ( "test" )
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2015-08-19 08:33:02 +00:00
if b . Do ( ) . Err ( ) == nil {
t . Errorf ( "unexpected non-error" )
}
b . ResourceTypeOrNameArgs ( true , "pods,services" , "foo" , "baz" )
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err != nil || singleItemImplied || len ( test . Infos ) != 4 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2015-08-19 08:33:02 +00:00
}
2017-01-25 13:39:54 +00:00
if ! apiequality . Semantic . DeepDerivative ( [ ] runtime . Object { & pods . Items [ 0 ] , & pods . Items [ 1 ] , & svcs . Items [ 0 ] , & svcs . Items [ 0 ] } , test . Objects ( ) ) {
2015-08-19 08:33:02 +00:00
t . Errorf ( "unexpected visited objects: %#v" , test . Objects ( ) )
}
if _ , err := b . Do ( ) . ResourceMapping ( ) ; err == nil {
t . Errorf ( "unexpected non-error" )
}
}
2017-11-16 02:00:32 +00:00
func TestRequestModifier ( t * testing . T ) {
2018-05-07 18:14:23 +00:00
for _ , tc := range [ ] struct {
name string
f func ( t * testing . T , got * * rest . Request ) * Builder
} {
{
name : "simple" ,
f : func ( t * testing . T , got * * rest . Request ) * Builder {
return newDefaultBuilderWith ( fakeClientWith ( t . Name ( ) , t , nil ) ) .
NamespaceParam ( "foo" ) .
TransformRequests ( func ( req * rest . Request ) {
* got = req
} ) .
ResourceNames ( "" , "services/baz" ) .
RequireObject ( false )
} ,
} ,
{
name : "flatten" ,
f : func ( t * testing . T , got * * rest . Request ) * Builder {
pods , _ := testData ( )
return newDefaultBuilderWith ( fakeClientWith ( t . Name ( ) , t , map [ string ] string {
"/namespaces/foo/pods" : runtime . EncodeOrDie ( corev1Codec , pods ) ,
} ) ) .
NamespaceParam ( "foo" ) .
TransformRequests ( func ( req * rest . Request ) {
* got = req
} ) .
ResourceTypeOrNameArgs ( true , "pods" ) .
Flatten ( )
} ,
} ,
} {
t . Run ( tc . name , func ( t * testing . T ) {
var got * rest . Request
b := tc . f ( t , & got )
i , err := b . Do ( ) . Infos ( )
if err != nil {
t . Fatal ( err )
}
req := i [ 0 ] . Client . Get ( )
if got != req {
t . Fatalf ( "request was not received by modifier: %#v" , req )
}
} )
2017-11-16 02:00:32 +00:00
}
}
2015-07-09 09:05:13 +00:00
func TestResourceNames ( t * testing . T ) {
pods , svc := testData ( )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-11-02 20:06:07 +00:00
"/namespaces/test/pods/foo" : runtime . EncodeOrDie ( corev1Codec , & pods . Items [ 0 ] ) ,
"/namespaces/test/services/baz" : runtime . EncodeOrDie ( corev1Codec , & svc . Items [ 0 ] ) ,
2017-11-14 03:56:59 +00:00
} ) ) . NamespaceParam ( "test" )
2015-07-09 09:05:13 +00:00
test := & testVisitor { }
if b . Do ( ) . Err ( ) == nil {
t . Errorf ( "unexpected non-error" )
}
b . ResourceNames ( "pods" , "foo" , "services/baz" )
err := b . Do ( ) . Visit ( test . Handle )
if err != nil || len ( test . Infos ) != 2 {
t . Fatalf ( "unexpected response: %v %#v" , err , test . Infos )
}
2017-03-21 03:07:57 +00:00
if ! apiequality . Semantic . DeepEqual ( & pods . Items [ 0 ] , test . Objects ( ) [ 0 ] ) {
2015-07-09 09:05:13 +00:00
t . Errorf ( "unexpected object: \n%#v, expected: \n%#v" , test . Objects ( ) [ 0 ] , & pods . Items [ 0 ] )
}
2017-03-21 03:07:57 +00:00
if ! apiequality . Semantic . DeepEqual ( & svc . Items [ 0 ] , test . Objects ( ) [ 1 ] ) {
2015-07-09 09:05:13 +00:00
t . Errorf ( "unexpected object: \n%#v, expected: \n%#v" , test . Objects ( ) [ 1 ] , & svc . Items [ 0 ] )
}
}
2016-08-16 21:51:08 +00:00
func TestResourceNamesWithoutResource ( t * testing . T ) {
pods , svc := testData ( )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-11-02 20:06:07 +00:00
"/namespaces/test/pods/foo" : runtime . EncodeOrDie ( corev1Codec , & pods . Items [ 0 ] ) ,
"/namespaces/test/services/baz" : runtime . EncodeOrDie ( corev1Codec , & svc . Items [ 0 ] ) ,
2017-11-14 03:56:59 +00:00
} ) ) . NamespaceParam ( "test" )
2016-08-16 21:51:08 +00:00
test := & testVisitor { }
if b . Do ( ) . Err ( ) == nil {
t . Errorf ( "unexpected non-error" )
}
b . ResourceNames ( "" , "foo" , "services/baz" )
err := b . Do ( ) . Visit ( test . Handle )
if err == nil || ! strings . Contains ( err . Error ( ) , "must be RESOURCE/NAME" ) {
t . Fatalf ( "unexpected response: %v" , err )
}
}
2015-04-20 19:00:52 +00:00
func TestResourceByNameWithoutRequireObject ( t * testing . T ) {
2017-11-14 03:56:59 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string { } ) ) . NamespaceParam ( "test" )
2015-04-20 19:00:52 +00:00
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2015-04-20 19:00:52 +00:00
if b . Do ( ) . Err ( ) == nil {
t . Errorf ( "unexpected non-error" )
}
b . ResourceTypeOrNameArgs ( true , "pods" , "foo" ) . RequireObject ( false )
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err != nil || ! singleItemImplied || len ( test . Infos ) != 1 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2015-04-20 19:00:52 +00:00
}
if test . Infos [ 0 ] . Name != "foo" {
t . Errorf ( "unexpected name: %#v" , test . Infos [ 0 ] . Name )
}
if test . Infos [ 0 ] . Object != nil {
t . Errorf ( "unexpected object: %#v" , test . Infos [ 0 ] . Object )
}
mapping , err := b . Do ( ) . ResourceMapping ( )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2018-05-01 17:02:44 +00:00
if mapping . GroupVersionKind . Kind != "Pod" || mapping . Resource != ( schema . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ) {
2015-04-20 19:00:52 +00:00
t . Errorf ( "unexpected resource mapping: %#v" , mapping )
}
}
2014-12-27 21:48:27 +00:00
func TestResourceByNameAndEmptySelector ( t * testing . T ) {
pods , _ := testData ( )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-11-02 20:06:07 +00:00
"/namespaces/test/pods/foo" : runtime . EncodeOrDie ( corev1Codec , & pods . Items [ 0 ] ) ,
2017-11-14 03:56:59 +00:00
} ) ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) .
2017-08-04 06:54:17 +00:00
LabelSelectorParam ( "" ) .
2015-02-12 14:59:58 +00:00
ResourceTypeOrNameArgs ( true , "pods" , "foo" )
2014-12-27 21:48:27 +00:00
2017-01-09 19:21:24 +00:00
singleItemImplied := false
infos , err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Infos ( )
if err != nil || ! singleItemImplied || len ( infos ) != 1 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , infos )
2014-12-27 21:48:27 +00:00
}
2017-03-21 03:07:57 +00:00
if ! apiequality . Semantic . DeepEqual ( & pods . Items [ 0 ] , infos [ 0 ] . Object ) {
2014-12-27 21:48:27 +00:00
t . Errorf ( "unexpected object: %#v" , infos [ 0 ] )
}
mapping , err := b . Do ( ) . ResourceMapping ( )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2018-05-01 17:02:44 +00:00
if mapping . Resource != ( schema . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ) {
2014-12-27 21:48:27 +00:00
t . Errorf ( "unexpected resource mapping: %#v" , mapping )
}
}
2017-08-04 06:54:17 +00:00
func TestLabelSelector ( t * testing . T ) {
2014-12-27 21:48:27 +00:00
pods , svc := testData ( )
2017-11-02 20:06:07 +00:00
labelKey := metav1 . LabelSelectorQueryParam ( corev1GV . String ( ) )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-11-02 20:06:07 +00:00
"/namespaces/test/pods?" + labelKey + "=a%3Db" : runtime . EncodeOrDie ( corev1Codec , pods ) ,
"/namespaces/test/services?" + labelKey + "=a%3Db" : runtime . EncodeOrDie ( corev1Codec , svc ) ,
2017-11-14 03:56:59 +00:00
} ) ) .
2017-08-04 06:54:17 +00:00
LabelSelectorParam ( "a=b" ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) .
Flatten ( )
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2014-12-27 21:48:27 +00:00
if b . Do ( ) . Err ( ) == nil {
t . Errorf ( "unexpected non-error" )
}
2015-02-12 14:59:58 +00:00
b . ResourceTypeOrNameArgs ( true , "pods,service" )
2014-12-27 21:48:27 +00:00
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err != nil || singleItemImplied || len ( test . Infos ) != 3 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2014-12-27 21:48:27 +00:00
}
2017-01-25 13:39:54 +00:00
if ! apiequality . Semantic . DeepDerivative ( [ ] runtime . Object { & pods . Items [ 0 ] , & pods . Items [ 1 ] , & svc . Items [ 0 ] } , test . Objects ( ) ) {
2014-12-27 21:48:27 +00:00
t . Errorf ( "unexpected visited objects: %#v" , test . Objects ( ) )
}
if _ , err := b . Do ( ) . ResourceMapping ( ) ; err == nil {
t . Errorf ( "unexpected non-error" )
}
}
2017-08-04 06:54:17 +00:00
func TestLabelSelectorRequiresKnownTypes ( t * testing . T ) {
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2017-08-04 06:54:17 +00:00
LabelSelectorParam ( "a=b" ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) .
ResourceTypes ( "unknown" )
if b . Do ( ) . Err ( ) == nil {
t . Errorf ( "unexpected non-error" )
}
}
2017-08-05 05:25:53 +00:00
func TestFieldSelector ( t * testing . T ) {
pods , svc := testData ( )
fieldKey := metav1 . FieldSelectorQueryParam ( corev1GV . String ( ) )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-08-05 05:25:53 +00:00
"/namespaces/test/pods?" + fieldKey + "=a%3Db" : runtime . EncodeOrDie ( corev1Codec , pods ) ,
"/namespaces/test/services?" + fieldKey + "=a%3Db" : runtime . EncodeOrDie ( corev1Codec , svc ) ,
2017-11-14 03:56:59 +00:00
} ) ) .
2017-08-05 05:25:53 +00:00
FieldSelectorParam ( "a=b" ) .
NamespaceParam ( "test" ) .
Flatten ( )
test := & testVisitor { }
singleItemImplied := false
if b . Do ( ) . Err ( ) == nil {
t . Errorf ( "unexpected non-error" )
}
b . ResourceTypeOrNameArgs ( true , "pods,service" )
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err != nil || singleItemImplied || len ( test . Infos ) != 3 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
}
if ! apiequality . Semantic . DeepDerivative ( [ ] runtime . Object { & pods . Items [ 0 ] , & pods . Items [ 1 ] , & svc . Items [ 0 ] } , test . Objects ( ) ) {
t . Errorf ( "unexpected visited objects: %#v" , test . Objects ( ) )
}
if _ , err := b . Do ( ) . ResourceMapping ( ) ; err == nil {
t . Errorf ( "unexpected non-error" )
}
}
func TestFieldSelectorRequiresKnownTypes ( t * testing . T ) {
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2017-08-05 05:25:53 +00:00
FieldSelectorParam ( "a=b" ) .
NamespaceParam ( "test" ) .
ResourceTypes ( "unknown" )
if b . Do ( ) . Err ( ) == nil {
t . Errorf ( "unexpected non-error" )
}
}
2014-12-27 21:48:27 +00:00
func TestSingleResourceType ( t * testing . T ) {
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2017-08-04 06:54:17 +00:00
LabelSelectorParam ( "a=b" ) .
2014-12-27 21:48:27 +00:00
SingleResourceType ( ) .
2015-02-12 14:59:58 +00:00
ResourceTypeOrNameArgs ( true , "pods,services" )
2014-12-27 21:48:27 +00:00
if b . Do ( ) . Err ( ) == nil {
t . Errorf ( "unexpected non-error" )
}
}
2015-03-25 05:01:07 +00:00
func TestResourceTuple ( t * testing . T ) {
expectNoErr := func ( err error ) bool { return err == nil }
expectErr := func ( err error ) bool { return err != nil }
testCases := map [ string ] struct {
args [ ] string
errFn func ( error ) bool
} {
"valid" : {
args : [ ] string { "pods/foo" } ,
errFn : expectNoErr ,
} ,
"valid multiple with name indirection" : {
args : [ ] string { "pods/foo" , "pod/bar" } ,
errFn : expectNoErr ,
} ,
"valid multiple with namespaced and non-namespaced types" : {
2015-09-15 07:26:50 +00:00
args : [ ] string { "nodes/foo" , "pod/bar" } ,
2015-03-25 05:01:07 +00:00
errFn : expectNoErr ,
} ,
"mixed arg types" : {
args : [ ] string { "pods/foo" , "bar" } ,
errFn : expectErr ,
} ,
/ * "missing resource" : {
args : [ ] string { "pods/foo2" } ,
errFn : expectNoErr , // not an error because resources are lazily visited
} , * /
"comma in resource" : {
args : [ ] string { ",pods/foo" } ,
errFn : expectErr ,
} ,
"multiple types in resource" : {
args : [ ] string { "pods,services/foo" } ,
errFn : expectErr ,
} ,
"unknown resource type" : {
args : [ ] string { "unknown/foo" } ,
errFn : expectErr ,
} ,
"leading slash" : {
args : [ ] string { "/bar" } ,
errFn : expectErr ,
} ,
"trailing slash" : {
args : [ ] string { "bar/" } ,
errFn : expectErr ,
} ,
}
2018-05-12 09:24:28 +00:00
for k , tt := range testCases {
t . Run ( "using default namespace" , func ( t * testing . T ) {
for _ , requireObject := range [ ] bool { true , false } {
expectedRequests := map [ string ] string { }
if requireObject {
pods , _ := testData ( )
expectedRequests = map [ string ] string {
"/namespaces/test/pods/foo" : runtime . EncodeOrDie ( corev1Codec , & pods . Items [ 0 ] ) ,
"/namespaces/test/pods/bar" : runtime . EncodeOrDie ( corev1Codec , & pods . Items [ 0 ] ) ,
"/nodes/foo" : runtime . EncodeOrDie ( corev1Codec , & v1 . Node { ObjectMeta : metav1 . ObjectMeta { Name : "foo" } } ) ,
}
2015-04-20 19:00:52 +00:00
}
2018-05-12 09:24:28 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( k , t , expectedRequests ) ) .
NamespaceParam ( "test" ) . DefaultNamespace ( ) .
ResourceTypeOrNameArgs ( true , tt . args ... ) . RequireObject ( requireObject )
2015-04-20 19:00:52 +00:00
2018-05-12 09:24:28 +00:00
r := b . Do ( )
2015-04-20 19:00:52 +00:00
2018-05-12 09:24:28 +00:00
if ! tt . errFn ( r . Err ( ) ) {
t . Errorf ( "%s: unexpected error: %v" , k , r . Err ( ) )
}
if r . Err ( ) != nil {
continue
}
switch {
case ( r . singleItemImplied && len ( tt . args ) != 1 ) ,
( ! r . singleItemImplied && len ( tt . args ) == 1 ) :
t . Errorf ( "%s: result had unexpected singleItemImplied value" , k )
}
info , err := r . Infos ( )
if err != nil {
// test error
continue
}
if len ( info ) != len ( tt . args ) {
t . Errorf ( "%s: unexpected number of infos returned: %#v" , k , info )
}
2015-04-20 19:00:52 +00:00
}
2018-05-12 09:24:28 +00:00
} )
2015-03-25 05:01:07 +00:00
}
}
2014-12-27 21:48:27 +00:00
func TestStream ( t * testing . T ) {
r , pods , rc := streamTestData ( )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) . Stream ( r , "STDIN" ) . Flatten ( )
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2014-12-27 21:48:27 +00:00
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err != nil || singleItemImplied || len ( test . Infos ) != 3 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2015-01-14 05:03:56 +00:00
}
2017-01-25 13:39:54 +00:00
if ! apiequality . Semantic . DeepDerivative ( [ ] runtime . Object { & pods . Items [ 0 ] , & pods . Items [ 1 ] , & rc . Items [ 0 ] } , test . Objects ( ) ) {
2015-01-14 05:03:56 +00:00
t . Errorf ( "unexpected visited objects: %#v" , test . Objects ( ) )
}
}
func TestYAMLStream ( t * testing . T ) {
r , pods , rc := streamYAMLTestData ( )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2015-01-14 05:03:56 +00:00
NamespaceParam ( "test" ) . Stream ( r , "STDIN" ) . Flatten ( )
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2015-01-14 05:03:56 +00:00
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err != nil || singleItemImplied || len ( test . Infos ) != 3 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2014-12-27 21:48:27 +00:00
}
2017-01-25 13:39:54 +00:00
if ! apiequality . Semantic . DeepDerivative ( [ ] runtime . Object { & pods . Items [ 0 ] , & pods . Items [ 1 ] , & rc . Items [ 0 ] } , test . Objects ( ) ) {
2014-12-27 21:48:27 +00:00
t . Errorf ( "unexpected visited objects: %#v" , test . Objects ( ) )
}
}
func TestMultipleObject ( t * testing . T ) {
r , pods , svc := streamTestData ( )
2017-11-14 03:56:59 +00:00
obj , err := newDefaultBuilder ( ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) . Stream ( r , "STDIN" ) . Flatten ( ) .
Do ( ) . Object ( )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2017-10-18 16:27:52 +00:00
expected := & v1 . List {
Items : [ ] runtime . RawExtension {
{ Object : & pods . Items [ 0 ] } ,
{ Object : & pods . Items [ 1 ] } ,
{ Object : & svc . Items [ 0 ] } ,
2014-12-27 21:48:27 +00:00
} ,
}
2017-01-25 13:39:54 +00:00
if ! apiequality . Semantic . DeepDerivative ( expected , obj ) {
2014-12-27 21:48:27 +00:00
t . Errorf ( "unexpected visited objects: %#v" , obj )
}
}
2015-05-14 04:35:11 +00:00
func TestContinueOnErrorVisitor ( t * testing . T ) {
r , _ , _ := streamTestData ( )
2017-11-14 03:56:59 +00:00
req := newDefaultBuilder ( ) .
2015-05-14 04:35:11 +00:00
ContinueOnError ( ) .
NamespaceParam ( "test" ) . Stream ( r , "STDIN" ) . Flatten ( ) .
Do ( )
count := 0
testErr := fmt . Errorf ( "test error" )
2015-06-15 02:48:56 +00:00
err := req . Visit ( func ( _ * Info , _ error ) error {
2015-05-14 04:35:11 +00:00
count ++
if count > 1 {
return testErr
}
return nil
} )
if err == nil {
t . Fatalf ( "unexpected error: %v" , err )
}
if count != 3 {
t . Fatalf ( "did not visit all infos: %d" , count )
}
2015-10-14 05:18:37 +00:00
agg , ok := err . ( utilerrors . Aggregate )
2015-05-14 04:35:11 +00:00
if ! ok {
t . Fatalf ( "unexpected error: %v" , err )
}
if len ( agg . Errors ( ) ) != 2 || agg . Errors ( ) [ 0 ] != testErr || agg . Errors ( ) [ 1 ] != testErr {
t . Fatalf ( "unexpected error: %v" , err )
}
}
2017-01-09 19:21:24 +00:00
func TestSingleItemImpliedObject ( t * testing . T ) {
2017-11-14 03:56:59 +00:00
obj , err := newDefaultBuilder ( ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) . DefaultNamespace ( ) .
2018-05-10 12:20:27 +00:00
FilenameParam ( false , & FilenameOptions { Recursive : false , Filenames : [ ] string { "../../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml" } } ) .
2014-12-27 21:48:27 +00:00
Flatten ( ) .
Do ( ) . Object ( )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2017-11-02 20:06:07 +00:00
rc , ok := obj . ( * v1 . ReplicationController )
2014-12-27 21:48:27 +00:00
if ! ok {
t . Fatalf ( "unexpected object: %#v" , obj )
}
2015-04-22 21:37:46 +00:00
if rc . Name != "redis-master" || rc . Namespace != "test" {
2015-02-05 23:20:27 +00:00
t . Errorf ( "unexpected controller: %#v" , rc )
2014-12-27 21:48:27 +00:00
}
}
2017-01-09 19:21:24 +00:00
func TestSingleItemImpliedObjectNoExtension ( t * testing . T ) {
2017-11-14 03:56:59 +00:00
obj , err := newDefaultBuilder ( ) .
2015-07-07 20:43:55 +00:00
NamespaceParam ( "test" ) . DefaultNamespace ( ) .
2018-05-10 12:20:27 +00:00
FilenameParam ( false , & FilenameOptions { Recursive : false , Filenames : [ ] string { "../../../../test/e2e/testing-manifests/pod" } } ) .
2015-07-07 20:43:55 +00:00
Flatten ( ) .
Do ( ) . Object ( )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2017-11-02 20:06:07 +00:00
pod , ok := obj . ( * v1 . Pod )
2015-07-07 20:43:55 +00:00
if ! ok {
t . Fatalf ( "unexpected object: %#v" , obj )
}
if pod . Name != "nginx" || pod . Namespace != "test" {
t . Errorf ( "unexpected pod: %#v" , pod )
}
}
2017-01-09 19:21:24 +00:00
func TestSingleItemImpliedRootScopedObject ( t * testing . T ) {
2018-04-04 20:43:50 +00:00
node := & v1 . Node { ObjectMeta : metav1 . ObjectMeta { Name : "test" } }
2015-05-08 03:51:36 +00:00
r := streamTestObject ( node )
2017-11-14 03:56:59 +00:00
infos , err := newDefaultBuilder ( ) .
2015-05-08 03:51:36 +00:00
NamespaceParam ( "test" ) . DefaultNamespace ( ) .
Stream ( r , "STDIN" ) .
Flatten ( ) .
Do ( ) . Infos ( )
if err != nil || len ( infos ) != 1 {
t . Fatalf ( "unexpected error: %v" , err )
}
if infos [ 0 ] . Namespace != "" {
t . Errorf ( "namespace should be empty: %#v" , infos [ 0 ] )
}
2017-11-02 20:06:07 +00:00
n , ok := infos [ 0 ] . Object . ( * v1 . Node )
2015-05-08 03:51:36 +00:00
if ! ok {
t . Fatalf ( "unexpected object: %#v" , infos [ 0 ] . Object )
}
if n . Name != "test" || n . Namespace != "" {
t . Errorf ( "unexpected object: %#v" , n )
}
}
2014-12-27 21:48:27 +00:00
func TestListObject ( t * testing . T ) {
pods , _ := testData ( )
2017-11-02 20:06:07 +00:00
labelKey := metav1 . LabelSelectorQueryParam ( corev1GV . String ( ) )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-11-02 20:06:07 +00:00
"/namespaces/test/pods?" + labelKey + "=a%3Db" : runtime . EncodeOrDie ( corev1Codec , pods ) ,
2017-11-14 03:56:59 +00:00
} ) ) .
2017-08-04 06:54:17 +00:00
LabelSelectorParam ( "a=b" ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) .
2015-02-12 14:59:58 +00:00
ResourceTypeOrNameArgs ( true , "pods" ) .
2014-12-27 21:48:27 +00:00
Flatten ( )
obj , err := b . Do ( ) . Object ( )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2017-10-18 16:27:52 +00:00
list , ok := obj . ( * v1 . List )
2014-12-27 21:48:27 +00:00
if ! ok {
t . Fatalf ( "unexpected object: %#v" , obj )
}
if list . ResourceVersion != pods . ResourceVersion || len ( list . Items ) != 2 {
t . Errorf ( "unexpected list: %#v" , list )
}
mapping , err := b . Do ( ) . ResourceMapping ( )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2018-05-01 17:02:44 +00:00
if mapping . Resource != ( schema . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ) {
2014-12-27 21:48:27 +00:00
t . Errorf ( "unexpected resource mapping: %#v" , mapping )
}
}
func TestListObjectWithDifferentVersions ( t * testing . T ) {
pods , svc := testData ( )
2017-11-02 20:06:07 +00:00
labelKey := metav1 . LabelSelectorQueryParam ( corev1GV . String ( ) )
2017-11-14 03:56:59 +00:00
obj , err := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-11-02 20:06:07 +00:00
"/namespaces/test/pods?" + labelKey + "=a%3Db" : runtime . EncodeOrDie ( corev1Codec , pods ) ,
"/namespaces/test/services?" + labelKey + "=a%3Db" : runtime . EncodeOrDie ( corev1Codec , svc ) ,
2017-11-14 03:56:59 +00:00
} ) ) .
2017-08-04 06:54:17 +00:00
LabelSelectorParam ( "a=b" ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) .
2015-02-12 14:59:58 +00:00
ResourceTypeOrNameArgs ( true , "pods,services" ) .
2014-12-27 21:48:27 +00:00
Flatten ( ) .
Do ( ) . Object ( )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2017-10-18 16:27:52 +00:00
list , ok := obj . ( * v1 . List )
2014-12-27 21:48:27 +00:00
if ! ok {
t . Fatalf ( "unexpected object: %#v" , obj )
}
// resource version differs between type lists, so it's not possible to get a single version.
if list . ResourceVersion != "" || len ( list . Items ) != 3 {
t . Errorf ( "unexpected list: %#v" , list )
}
}
func TestWatch ( t * testing . T ) {
2015-02-05 23:20:27 +00:00
_ , svc := testData ( )
2017-11-14 03:56:59 +00:00
w , err := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-01-09 21:21:23 +00:00
"/namespaces/test/services?fieldSelector=metadata.name%3Dredis-master&resourceVersion=12&watch=true" : watchBody ( watch . Event {
2014-12-27 21:48:27 +00:00
Type : watch . Added ,
2015-02-05 23:20:27 +00:00
Object : & svc . Items [ 0 ] ,
2014-12-27 21:48:27 +00:00
} ) ,
2017-11-14 03:56:59 +00:00
} ) ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) . DefaultNamespace ( ) .
2018-05-10 12:20:27 +00:00
FilenameParam ( false , & FilenameOptions { Recursive : false , Filenames : [ ] string { "../../../../test/e2e/testing-manifests/guestbook/redis-master-service.yaml" } } ) . Flatten ( ) .
2015-02-05 23:20:27 +00:00
Do ( ) . Watch ( "12" )
2014-12-27 21:48:27 +00:00
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
defer w . Stop ( )
ch := w . ResultChan ( )
select {
case obj := <- ch :
if obj . Type != watch . Added {
2015-03-31 22:32:02 +00:00
t . Fatalf ( "unexpected watch event %#v" , obj )
2014-12-27 21:48:27 +00:00
}
2017-11-02 20:06:07 +00:00
service , ok := obj . Object . ( * v1 . Service )
2014-12-27 21:48:27 +00:00
if ! ok {
t . Fatalf ( "unexpected object: %#v" , obj )
}
2015-02-05 23:20:27 +00:00
if service . Name != "baz" || service . ResourceVersion != "12" {
t . Errorf ( "unexpected service: %#v" , service )
2014-12-27 21:48:27 +00:00
}
}
}
func TestWatchMultipleError ( t * testing . T ) {
2017-11-14 03:56:59 +00:00
_ , err := newDefaultBuilder ( ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "test" ) . DefaultNamespace ( ) .
2018-05-10 12:20:27 +00:00
FilenameParam ( false , & FilenameOptions { Recursive : false , Filenames : [ ] string { "../../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml" } } ) . Flatten ( ) .
FilenameParam ( false , & FilenameOptions { Recursive : false , Filenames : [ ] string { "../../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml" } } ) . Flatten ( ) .
2014-12-27 21:48:27 +00:00
Do ( ) . Watch ( "" )
if err == nil {
t . Fatalf ( "unexpected non-error" )
}
}
func TestLatest ( t * testing . T ) {
r , _ , _ := streamTestData ( )
2017-11-02 20:06:07 +00:00
newPod := & v1 . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "foo" , Namespace : "test" , ResourceVersion : "13" } ,
2014-12-27 21:48:27 +00:00
}
2017-11-02 20:06:07 +00:00
newPod2 := & v1 . Pod {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "bar" , Namespace : "test" , ResourceVersion : "14" } ,
2014-12-27 21:48:27 +00:00
}
2017-11-02 20:06:07 +00:00
newSvc := & v1 . Service {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "baz" , Namespace : "test" , ResourceVersion : "15" } ,
2014-12-27 21:48:27 +00:00
}
2017-11-14 03:56:59 +00:00
b := newDefaultBuilderWith ( fakeClientWith ( "" , t , map [ string ] string {
2017-11-02 20:06:07 +00:00
"/namespaces/test/pods/foo" : runtime . EncodeOrDie ( corev1Codec , newPod ) ,
"/namespaces/test/pods/bar" : runtime . EncodeOrDie ( corev1Codec , newPod2 ) ,
"/namespaces/test/services/baz" : runtime . EncodeOrDie ( corev1Codec , newSvc ) ,
2017-11-14 03:56:59 +00:00
} ) ) .
2014-12-27 21:48:27 +00:00
NamespaceParam ( "other" ) . Stream ( r , "STDIN" ) . Flatten ( ) . Latest ( )
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2014-12-27 21:48:27 +00:00
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err != nil || singleItemImplied || len ( test . Infos ) != 3 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2014-12-27 21:48:27 +00:00
}
2017-01-25 13:39:54 +00:00
if ! apiequality . Semantic . DeepDerivative ( [ ] runtime . Object { newPod , newPod2 , newSvc } , test . Objects ( ) ) {
2014-12-27 21:48:27 +00:00
t . Errorf ( "unexpected visited objects: %#v" , test . Objects ( ) )
}
}
func TestReceiveMultipleErrors ( t * testing . T ) {
pods , svc := testData ( )
r , w := io . Pipe ( )
go func ( ) {
defer w . Close ( )
w . Write ( [ ] byte ( ` { } ` ) )
2017-11-02 20:06:07 +00:00
w . Write ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , & pods . Items [ 0 ] ) ) )
2014-12-27 21:48:27 +00:00
} ( )
r2 , w2 := io . Pipe ( )
go func ( ) {
defer w2 . Close ( )
w2 . Write ( [ ] byte ( ` { } ` ) )
2017-11-02 20:06:07 +00:00
w2 . Write ( [ ] byte ( runtime . EncodeOrDie ( corev1Codec , & svc . Items [ 0 ] ) ) )
2014-12-27 21:48:27 +00:00
} ( )
2017-11-14 03:56:59 +00:00
b := newDefaultBuilder ( ) .
2014-12-27 21:48:27 +00:00
Stream ( r , "1" ) . Stream ( r2 , "2" ) .
ContinueOnError ( )
test := & testVisitor { }
2017-01-09 19:21:24 +00:00
singleItemImplied := false
2014-12-27 21:48:27 +00:00
2017-01-09 19:21:24 +00:00
err := b . Do ( ) . IntoSingleItemImplied ( & singleItemImplied ) . Visit ( test . Handle )
if err == nil || singleItemImplied || len ( test . Infos ) != 2 {
t . Fatalf ( "unexpected response: %v %t %#v" , err , singleItemImplied , test . Infos )
2014-12-27 21:48:27 +00:00
}
2015-10-14 05:18:37 +00:00
errs , ok := err . ( utilerrors . Aggregate )
2014-12-27 21:48:27 +00:00
if ! ok {
t . Fatalf ( "unexpected error: %v" , reflect . TypeOf ( err ) )
}
if len ( errs . Errors ( ) ) != 2 {
2015-03-31 22:32:02 +00:00
t . Errorf ( "unexpected errors %v" , errs )
2014-12-27 21:48:27 +00:00
}
}
2015-04-08 15:05:41 +00:00
2015-12-03 19:32:22 +00:00
func TestHasNames ( t * testing . T ) {
2016-12-15 22:58:49 +00:00
basename := filepath . Base ( os . Args [ 0 ] )
2015-12-03 19:32:22 +00:00
tests := [ ] struct {
2018-05-12 09:24:28 +00:00
name string
2015-12-03 19:32:22 +00:00
args [ ] string
expectedHasName bool
expectedError error
} {
{
2018-05-12 09:24:28 +00:00
name : "test1" ,
2015-12-03 19:32:22 +00:00
args : [ ] string { "" } ,
expectedHasName : false ,
expectedError : nil ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test2" ,
2015-12-03 19:32:22 +00:00
args : [ ] string { "rc" } ,
expectedHasName : false ,
expectedError : nil ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test3" ,
2015-12-03 19:32:22 +00:00
args : [ ] string { "rc,pod,svc" } ,
expectedHasName : false ,
expectedError : nil ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test4" ,
2015-12-03 19:32:22 +00:00
args : [ ] string { "rc/foo" } ,
expectedHasName : true ,
expectedError : nil ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test5" ,
2015-12-03 19:32:22 +00:00
args : [ ] string { "rc" , "foo" } ,
expectedHasName : true ,
expectedError : nil ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test6" ,
2015-12-03 19:32:22 +00:00
args : [ ] string { "rc,pod,svc" , "foo" } ,
expectedHasName : true ,
expectedError : nil ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test7" ,
2015-12-03 19:32:22 +00:00
args : [ ] string { "rc/foo" , "rc/bar" , "rc/zee" } ,
expectedHasName : true ,
expectedError : nil ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test8" ,
2015-12-03 19:32:22 +00:00
args : [ ] string { "rc/foo" , "bar" } ,
expectedHasName : false ,
2016-12-15 22:58:49 +00:00
expectedError : fmt . Errorf ( "there is no need to specify a resource type as a separate argument when passing arguments in resource/name form (e.g. '" + basename + " get resource/<resource_name>' instead of '" + basename + " get resource resource/<resource_name>'" ) ,
2015-12-03 19:32:22 +00:00
} ,
}
2018-05-12 09:24:28 +00:00
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
hasNames , err := HasNames ( tt . args )
if ! reflect . DeepEqual ( tt . expectedError , err ) {
t . Errorf ( "expected HasName to error:\n%s\tgot:\n%s" , tt . expectedError , err )
}
if hasNames != tt . expectedHasName {
t . Errorf ( "expected HasName to return %v for %s" , tt . expectedHasName , tt . args )
}
} )
2015-12-03 19:32:22 +00:00
}
}
2016-11-29 17:25:10 +00:00
func TestMultipleTypesRequested ( t * testing . T ) {
tests := [ ] struct {
2018-05-12 09:24:28 +00:00
name string
2016-11-29 17:25:10 +00:00
args [ ] string
expectedMultipleTypes bool
} {
{
2018-05-12 09:24:28 +00:00
name : "test1" ,
2016-11-29 17:25:10 +00:00
args : [ ] string { "" } ,
expectedMultipleTypes : false ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test2" ,
2016-11-29 17:25:10 +00:00
args : [ ] string { "all" } ,
expectedMultipleTypes : true ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test3" ,
2016-11-29 17:25:10 +00:00
args : [ ] string { "rc" } ,
expectedMultipleTypes : false ,
} ,
2017-01-17 23:13:23 +00:00
{
2018-05-12 09:24:28 +00:00
name : "test4" ,
2017-01-17 23:13:23 +00:00
args : [ ] string { "pod,all" } ,
expectedMultipleTypes : true ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test5" ,
2017-01-17 23:13:23 +00:00
args : [ ] string { "all,rc,pod" } ,
expectedMultipleTypes : true ,
} ,
2016-11-29 17:25:10 +00:00
{
2018-05-12 09:24:28 +00:00
name : "test6" ,
2016-11-29 17:25:10 +00:00
args : [ ] string { "rc,pod,svc" } ,
expectedMultipleTypes : true ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test7" ,
2016-11-29 17:25:10 +00:00
args : [ ] string { "rc/foo" } ,
expectedMultipleTypes : false ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test8" ,
2016-11-29 17:25:10 +00:00
args : [ ] string { "rc/foo" , "rc/bar" } ,
expectedMultipleTypes : false ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test9" ,
2016-11-29 17:25:10 +00:00
args : [ ] string { "rc" , "foo" } ,
expectedMultipleTypes : false ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test10" ,
2016-11-29 17:25:10 +00:00
args : [ ] string { "rc,pod,svc" , "foo" } ,
expectedMultipleTypes : true ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test11" ,
2016-11-29 17:25:10 +00:00
args : [ ] string { "rc,secrets" } ,
expectedMultipleTypes : true ,
} ,
{
2018-05-12 09:24:28 +00:00
name : "test12" ,
2016-11-29 17:25:10 +00:00
args : [ ] string { "rc/foo" , "rc/bar" , "svc/svc" } ,
expectedMultipleTypes : true ,
} ,
}
2018-05-12 09:24:28 +00:00
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
hasMultipleTypes := MultipleTypesRequested ( tt . args )
if hasMultipleTypes != tt . expectedMultipleTypes {
t . Errorf ( "expected MultipleTypesRequested to return %v for %s" , tt . expectedMultipleTypes , tt . args )
}
} )
2016-11-29 17:25:10 +00:00
}
}