2014-11-18 18:04:10 +00:00
/ *
2015-05-01 16:19:44 +00:00
Copyright 2014 The Kubernetes Authors All rights reserved .
2014-11-18 18:04:10 +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 .
* /
2015-03-26 01:52:12 +00:00
package cmd
2014-11-18 18:04:10 +00:00
import (
"bytes"
2015-04-16 23:21:13 +00:00
encjson "encoding/json"
2014-11-18 18:04:10 +00:00
"fmt"
2014-12-31 00:42:55 +00:00
"io"
"io/ioutil"
2014-11-18 18:04:10 +00:00
"net/http"
"reflect"
2014-12-12 21:33:18 +00:00
"strings"
2014-11-18 18:04:10 +00:00
"testing"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/api"
2015-11-12 10:45:42 +00:00
"k8s.io/kubernetes/pkg/api/meta"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/api/testapi"
2015-09-14 21:56:51 +00:00
apitesting "k8s.io/kubernetes/pkg/api/testing"
2015-09-09 21:59:11 +00:00
"k8s.io/kubernetes/pkg/api/unversioned"
2015-08-13 19:01:50 +00:00
client "k8s.io/kubernetes/pkg/client/unversioned"
2015-09-11 20:47:53 +00:00
"k8s.io/kubernetes/pkg/client/unversioned/fake"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/watch"
"k8s.io/kubernetes/pkg/watch/json"
2014-11-18 18:04:10 +00:00
)
2015-02-05 23:20:27 +00:00
func testData ( ) ( * api . PodList , * api . ServiceList , * api . ReplicationControllerList ) {
2014-12-31 00:42:55 +00:00
pods := & api . PodList {
2015-09-09 21:59:11 +00:00
ListMeta : unversioned . ListMeta {
2014-12-31 00:42:55 +00:00
ResourceVersion : "15" ,
} ,
Items : [ ] api . Pod {
{
ObjectMeta : api . ObjectMeta { Name : "foo" , Namespace : "test" , ResourceVersion : "10" } ,
2015-09-14 21:56:51 +00:00
Spec : apitesting . DeepEqualSafePodSpec ( ) ,
2014-12-31 00:42:55 +00:00
} ,
{
ObjectMeta : api . ObjectMeta { Name : "bar" , Namespace : "test" , ResourceVersion : "11" } ,
2015-09-14 21:56:51 +00:00
Spec : apitesting . DeepEqualSafePodSpec ( ) ,
2014-12-31 00:42:55 +00:00
} ,
} ,
}
svc := & api . ServiceList {
2015-09-09 21:59:11 +00:00
ListMeta : unversioned . ListMeta {
2014-12-31 00:42:55 +00:00
ResourceVersion : "16" ,
} ,
Items : [ ] api . Service {
{
ObjectMeta : api . ObjectMeta { Name : "baz" , Namespace : "test" , ResourceVersion : "12" } ,
2015-01-26 17:52:50 +00:00
Spec : api . ServiceSpec {
SessionAffinity : "None" ,
2015-05-22 21:49:26 +00:00
Type : api . ServiceTypeClusterIP ,
2015-01-26 17:52:50 +00:00
} ,
2014-12-31 00:42:55 +00:00
} ,
} ,
}
2015-02-05 23:20:27 +00:00
rc := & api . ReplicationControllerList {
2015-09-09 21:59:11 +00:00
ListMeta : unversioned . ListMeta {
2015-02-05 23:20:27 +00:00
ResourceVersion : "17" ,
} ,
Items : [ ] api . ReplicationController {
{
ObjectMeta : api . ObjectMeta { Name : "rc1" , Namespace : "test" , ResourceVersion : "18" } ,
Spec : api . ReplicationControllerSpec {
Replicas : 1 ,
} ,
} ,
} ,
}
return pods , svc , rc
2014-12-31 00:42:55 +00:00
}
2015-04-15 19:23:02 +00:00
func testComponentStatusData ( ) * api . ComponentStatusList {
2015-10-01 01:07:03 +00:00
good := api . ComponentStatus {
2015-04-15 19:23:02 +00:00
Conditions : [ ] api . ComponentCondition {
2015-11-05 21:26:03 +00:00
{ Type : api . ComponentHealthy , Status : api . ConditionTrue , Message : "ok" } ,
2015-04-15 19:23:02 +00:00
} ,
2015-10-15 04:47:51 +00:00
ObjectMeta : api . ObjectMeta { Name : "servergood" } ,
2015-04-15 19:23:02 +00:00
}
2015-04-20 23:49:16 +00:00
2015-10-01 01:07:03 +00:00
bad := api . ComponentStatus {
2015-04-15 19:23:02 +00:00
Conditions : [ ] api . ComponentCondition {
{ Type : api . ComponentHealthy , Status : api . ConditionFalse , Message : "" , Error : "bad status: 500" } ,
} ,
2015-10-15 04:47:51 +00:00
ObjectMeta : api . ObjectMeta { Name : "serverbad" } ,
2015-04-15 19:23:02 +00:00
}
2015-04-20 23:49:16 +00:00
2015-10-01 01:07:03 +00:00
unknown := api . ComponentStatus {
2015-04-15 19:23:02 +00:00
Conditions : [ ] api . ComponentCondition {
{ Type : api . ComponentHealthy , Status : api . ConditionUnknown , Message : "" , Error : "fizzbuzz error" } ,
} ,
2015-10-15 04:47:51 +00:00
ObjectMeta : api . ObjectMeta { Name : "serverunknown" } ,
2015-04-15 19:23:02 +00:00
}
return & api . ComponentStatusList {
2015-10-01 01:07:03 +00:00
Items : [ ] api . ComponentStatus { good , bad , unknown } ,
2015-04-15 19:23:02 +00:00
}
}
2014-11-18 18:04:10 +00:00
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func TestGetUnknownSchemaObject ( t * testing . T ) {
f , tf , codec := NewTestFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2014-11-18 18:04:10 +00:00
Codec : codec ,
Resp : & http . Response { StatusCode : 200 , Body : objBody ( codec , & internalType { Name : "foo" } ) } ,
}
2015-01-02 18:08:37 +00:00
tf . Namespace = "test"
2015-11-13 21:20:54 +00:00
tf . ClientConfig = & client . Config { GroupVersion : testapi . Default . GroupVersion ( ) }
2014-11-18 18:04:10 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2014-12-31 00:42:55 +00:00
cmd . SetOutput ( buf )
2014-11-18 18:04:10 +00:00
cmd . Run ( cmd , [ ] string { "type" , "foo" } )
expected := & internalType { Name : "foo" }
2014-12-31 00:42:55 +00:00
actual := tf . Printer . ( * testPrinter ) . Objects [ 0 ]
2014-11-18 18:04:10 +00:00
if ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "unexpected object: %#v" , actual )
}
if buf . String ( ) != fmt . Sprintf ( "%#v" , expected ) {
t . Errorf ( "unexpected output: %s" , buf . String ( ) )
}
}
2014-12-12 21:33:18 +00:00
2015-04-16 23:21:13 +00:00
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
// Because api.List is part of the Kube API, resource.Builder has to perform a conversion on
// api.Scheme, which may not have access to all objects, and not all objects are at the same
// internal versioning scheme. This test verifies that two isolated schemes (Test, and api.Scheme)
// can be conjoined into a single output object.
2015-06-05 20:55:33 +00:00
//
// The expected behavior of the `kubectl get` command is:
// 1. objects using unrecognized schemes will always be returned using that scheme/version, "unlikelyversion" in this test;
2015-09-11 00:20:53 +00:00
// 2. if the specified output-version is a recognized, valid Scheme, then the list should use that scheme, and otherwise it will default to the client version, testapi.Default.Version() in this test;
2015-06-05 20:55:33 +00:00
// 3a. if the specified output-version is a recognized, valid Scheme, in which the requested object (replicationcontroller) can be represented, then the object should be returned using that version;
2015-09-11 00:20:53 +00:00
// 3b. otherwise if the specified output-version is unrecognized, but the requested object (replicationcontroller) is recognized by the client's codec, then it will be converted to the client version, testapi.Default.Version() in this test.
2015-04-16 23:21:13 +00:00
func TestGetUnknownSchemaObjectListGeneric ( t * testing . T ) {
testCases := map [ string ] struct {
2015-06-05 20:55:33 +00:00
outputVersion string
listVersion string
testtypeVersion string
rcVersion string
2015-04-16 23:21:13 +00:00
} {
"handles specific version" : {
2015-09-11 00:20:53 +00:00
outputVersion : testapi . Default . Version ( ) ,
listVersion : testapi . Default . Version ( ) ,
2015-11-13 13:13:55 +00:00
testtypeVersion : unlikelyGV . String ( ) ,
2015-09-11 00:20:53 +00:00
rcVersion : testapi . Default . Version ( ) ,
2015-04-16 23:21:13 +00:00
} ,
"handles second specific version" : {
2015-06-05 20:55:33 +00:00
outputVersion : "unlikelyversion" ,
2015-09-11 00:20:53 +00:00
listVersion : testapi . Default . Version ( ) ,
2015-11-13 13:13:55 +00:00
testtypeVersion : unlikelyGV . String ( ) ,
2015-09-11 00:20:53 +00:00
rcVersion : testapi . Default . Version ( ) , // see expected behavior 3b
2015-04-16 23:21:13 +00:00
} ,
"handles common version" : {
2015-09-04 07:06:01 +00:00
outputVersion : testapi . Default . Version ( ) ,
listVersion : testapi . Default . Version ( ) ,
2015-11-13 13:13:55 +00:00
testtypeVersion : unlikelyGV . String ( ) ,
2015-09-04 07:06:01 +00:00
rcVersion : testapi . Default . Version ( ) ,
2015-04-16 23:21:13 +00:00
} ,
}
for k , test := range testCases {
2015-09-04 07:06:01 +00:00
apiCodec := runtime . CodecFor ( api . Scheme , testapi . Default . Version ( ) )
2015-09-11 20:47:53 +00:00
regularClient := & fake . RESTClient {
2015-04-16 23:21:13 +00:00
Codec : apiCodec ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2015-04-16 23:21:13 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( apiCodec , & api . ReplicationController { ObjectMeta : api . ObjectMeta { Name : "foo" } } ) } , nil
} ) ,
}
f , tf , codec := NewMixedFactory ( regularClient )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2015-04-16 23:21:13 +00:00
Codec : codec ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2015-04-16 23:21:13 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( codec , & internalType { Name : "foo" } ) } , nil
} ) ,
}
tf . Namespace = "test"
2015-11-13 21:20:54 +00:00
tf . ClientConfig = & client . Config { GroupVersion : testapi . Default . GroupVersion ( ) }
2015-04-16 23:21:13 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
cmd := NewCmdGet ( f , buf )
cmd . SetOutput ( buf )
cmd . Flags ( ) . Set ( "output" , "json" )
2015-11-13 13:13:55 +00:00
2015-06-05 20:55:33 +00:00
cmd . Flags ( ) . Set ( "output-version" , test . outputVersion )
2015-08-14 18:46:43 +00:00
err := RunGet ( f , buf , cmd , [ ] string { "type/foo" , "replicationcontrollers/foo" } , & GetOptions { } )
2015-04-16 23:21:13 +00:00
if err != nil {
t . Errorf ( "%s: unexpected error: %v" , k , err )
continue
}
out := make ( map [ string ] interface { } )
if err := encjson . Unmarshal ( buf . Bytes ( ) , & out ) ; err != nil {
t . Errorf ( "%s: unexpected error: %v\n%s" , k , err , buf . String ( ) )
continue
}
2015-06-05 20:55:33 +00:00
if out [ "apiVersion" ] != test . listVersion {
2015-04-16 23:21:13 +00:00
t . Errorf ( "%s: unexpected list: %#v" , k , out )
}
arr := out [ "items" ] . ( [ ] interface { } )
2015-06-05 20:55:33 +00:00
if arr [ 0 ] . ( map [ string ] interface { } ) [ "apiVersion" ] != test . testtypeVersion {
2015-04-16 23:21:13 +00:00
t . Errorf ( "%s: unexpected list: %#v" , k , out )
}
2015-06-05 20:55:33 +00:00
if arr [ 1 ] . ( map [ string ] interface { } ) [ "apiVersion" ] != test . rcVersion {
2015-04-16 23:21:13 +00:00
t . Errorf ( "%s: unexpected list: %#v" , k , out )
}
}
}
2014-12-12 21:33:18 +00:00
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func TestGetSchemaObject ( t * testing . T ) {
f , tf , _ := NewTestFactory ( )
2015-09-11 00:20:53 +00:00
tf . Mapper = testapi . Default . RESTMapper ( )
2015-01-03 20:38:33 +00:00
tf . Typer = api . Scheme
2015-09-11 00:20:53 +00:00
codec := testapi . Default . Codec ( )
2014-12-12 21:33:18 +00:00
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2014-12-12 21:33:18 +00:00
Codec : codec ,
Resp : & http . Response { StatusCode : 200 , Body : objBody ( codec , & api . ReplicationController { ObjectMeta : api . ObjectMeta { Name : "foo" } } ) } ,
}
2015-01-02 18:08:37 +00:00
tf . Namespace = "test"
2015-11-13 21:20:54 +00:00
tf . ClientConfig = & client . Config { GroupVersion : & unversioned . GroupVersion { Version : "v1" } }
2014-12-12 21:33:18 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2014-12-12 21:33:18 +00:00
cmd . Run ( cmd , [ ] string { "replicationcontrollers" , "foo" } )
if ! strings . Contains ( buf . String ( ) , "\"foo\"" ) {
t . Errorf ( "unexpected output: %s" , buf . String ( ) )
}
}
2014-12-31 00:42:55 +00:00
func TestGetObjects ( t * testing . T ) {
2015-02-05 23:20:27 +00:00
pods , _ , _ := testData ( )
2014-12-31 00:42:55 +00:00
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2014-12-31 00:42:55 +00:00
Codec : codec ,
Resp : & http . Response { StatusCode : 200 , Body : objBody ( codec , & pods . Items [ 0 ] ) } ,
}
2015-01-02 18:08:37 +00:00
tf . Namespace = "test"
2014-12-31 00:42:55 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2014-12-31 00:42:55 +00:00
cmd . SetOutput ( buf )
cmd . Run ( cmd , [ ] string { "pods" , "foo" } )
expected := [ ] runtime . Object { & pods . Items [ 0 ] }
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "unexpected object: %#v" , actual )
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
2015-08-10 11:02:14 +00:00
func TestGetObjectsIdentifiedByFile ( t * testing . T ) {
pods , _ , _ := testData ( )
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2015-08-10 11:02:14 +00:00
Codec : codec ,
Resp : & http . Response { StatusCode : 200 , Body : objBody ( codec , & pods . Items [ 0 ] ) } ,
}
tf . Namespace = "test"
buf := bytes . NewBuffer ( [ ] byte { } )
cmd := NewCmdGet ( f , buf )
cmd . SetOutput ( buf )
cmd . Flags ( ) . Set ( "filename" , "../../../examples/cassandra/cassandra.yaml" )
cmd . Run ( cmd , [ ] string { } )
expected := [ ] runtime . Object { & pods . Items [ 0 ] }
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "unexpected object: %#v" , actual )
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
2014-12-31 00:42:55 +00:00
func TestGetListObjects ( t * testing . T ) {
2015-02-05 23:20:27 +00:00
pods , _ , _ := testData ( )
2014-12-31 00:42:55 +00:00
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2014-12-31 00:42:55 +00:00
Codec : codec ,
Resp : & http . Response { StatusCode : 200 , Body : objBody ( codec , pods ) } ,
}
2015-01-02 18:08:37 +00:00
tf . Namespace = "test"
2014-12-31 00:42:55 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2014-12-31 00:42:55 +00:00
cmd . SetOutput ( buf )
cmd . Run ( cmd , [ ] string { "pods" } )
2015-10-01 01:07:03 +00:00
expected , err := extractResourceList ( [ ] runtime . Object { pods } )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2014-12-31 00:42:55 +00:00
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
2015-10-01 01:07:03 +00:00
t . Errorf ( "unexpected object: expected %#v, got %#v" , expected , actual )
2014-12-31 00:42:55 +00:00
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
2015-10-01 01:07:03 +00:00
func extractResourceList ( objs [ ] runtime . Object ) ( [ ] runtime . Object , error ) {
finalObjs := [ ] runtime . Object { }
for _ , obj := range objs {
2015-11-12 10:45:42 +00:00
items , err := meta . ExtractList ( obj )
2015-10-01 01:07:03 +00:00
if err != nil {
return nil , err
}
for _ , item := range items {
finalObjs = append ( finalObjs , item )
}
}
return finalObjs , nil
}
2015-07-31 23:42:34 +00:00
func TestGetAllListObjects ( t * testing . T ) {
pods , _ , _ := testData ( )
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2015-07-31 23:42:34 +00:00
Codec : codec ,
Resp : & http . Response { StatusCode : 200 , Body : objBody ( codec , pods ) } ,
}
tf . Namespace = "test"
buf := bytes . NewBuffer ( [ ] byte { } )
cmd := NewCmdGet ( f , buf )
cmd . SetOutput ( buf )
cmd . Flags ( ) . Set ( "show-all" , "true" )
cmd . Run ( cmd , [ ] string { "pods" } )
2015-10-01 01:07:03 +00:00
expected , err := extractResourceList ( [ ] runtime . Object { pods } )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2015-07-31 23:42:34 +00:00
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "unexpected object: %#v %#v" , expected , actual )
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
2015-04-15 19:23:02 +00:00
func TestGetListComponentStatus ( t * testing . T ) {
statuses := testComponentStatusData ( )
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2015-04-15 19:23:02 +00:00
Codec : codec ,
Resp : & http . Response { StatusCode : 200 , Body : objBody ( codec , statuses ) } ,
}
tf . Namespace = "test"
buf := bytes . NewBuffer ( [ ] byte { } )
cmd := NewCmdGet ( f , buf )
cmd . SetOutput ( buf )
cmd . Run ( cmd , [ ] string { "componentstatuses" } )
2015-10-01 01:07:03 +00:00
expected , err := extractResourceList ( [ ] runtime . Object { statuses } )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2015-04-15 19:23:02 +00:00
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
2015-10-01 01:07:03 +00:00
t . Errorf ( "unexpected object: expected %#v, got %#v" , expected , actual )
2015-04-15 19:23:02 +00:00
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
2014-12-31 00:42:55 +00:00
func TestGetMultipleTypeObjects ( t * testing . T ) {
2015-02-05 23:20:27 +00:00
pods , svc , _ := testData ( )
2014-12-31 00:42:55 +00:00
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2014-12-31 00:42:55 +00:00
Codec : codec ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2014-12-31 00:42:55 +00:00
switch req . URL . Path {
2015-01-19 21:50:00 +00:00
case "/namespaces/test/pods" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( codec , pods ) } , nil
2015-01-19 21:50:00 +00:00
case "/namespaces/test/services" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( codec , svc ) } , nil
default :
t . Fatalf ( "unexpected request: %#v\n%#v" , req . URL , req )
return nil , nil
}
} ) ,
}
2015-01-02 18:08:37 +00:00
tf . Namespace = "test"
2014-12-31 00:42:55 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2014-12-31 00:42:55 +00:00
cmd . SetOutput ( buf )
cmd . Run ( cmd , [ ] string { "pods,services" } )
2015-10-01 01:07:03 +00:00
expected , err := extractResourceList ( [ ] runtime . Object { pods , svc } )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2014-12-31 00:42:55 +00:00
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "unexpected object: %#v" , actual )
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
func TestGetMultipleTypeObjectsAsList ( t * testing . T ) {
2015-02-05 23:20:27 +00:00
pods , svc , _ := testData ( )
2014-12-31 00:42:55 +00:00
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2014-12-31 00:42:55 +00:00
Codec : codec ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2014-12-31 00:42:55 +00:00
switch req . URL . Path {
2015-01-19 21:50:00 +00:00
case "/namespaces/test/pods" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( codec , pods ) } , nil
2015-01-19 21:50:00 +00:00
case "/namespaces/test/services" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( codec , svc ) } , nil
default :
t . Fatalf ( "unexpected request: %#v\n%#v" , req . URL , req )
return nil , nil
}
} ) ,
}
2015-01-02 18:08:37 +00:00
tf . Namespace = "test"
2015-11-13 21:20:54 +00:00
tf . ClientConfig = & client . Config { GroupVersion : testapi . Default . GroupVersion ( ) }
2014-12-31 00:42:55 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2014-12-31 00:42:55 +00:00
cmd . SetOutput ( buf )
cmd . Flags ( ) . Set ( "output" , "json" )
cmd . Run ( cmd , [ ] string { "pods,services" } )
if tf . Printer . ( * testPrinter ) . Objects != nil {
t . Errorf ( "unexpected print to default printer" )
}
out , err := codec . Decode ( buf . Bytes ( ) )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2015-11-12 10:45:42 +00:00
list , err := meta . ExtractList ( out )
2015-04-29 03:15:16 +00:00
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
if errs := runtime . DecodeList ( list , api . Scheme ) ; len ( errs ) > 0 {
t . Fatalf ( "unexpected error: %v" , errs )
}
2015-11-12 10:45:42 +00:00
if err := meta . SetList ( out , list ) ; err != nil {
2015-04-29 03:15:16 +00:00
t . Fatalf ( "unexpected error: %v" , err )
}
2014-12-31 00:42:55 +00:00
expected := & api . List {
Items : [ ] runtime . Object {
& pods . Items [ 0 ] ,
& pods . Items [ 1 ] ,
& svc . Items [ 0 ] ,
} ,
}
if ! reflect . DeepEqual ( expected , out ) {
t . Errorf ( "unexpected output: %#v" , out )
}
}
func TestGetMultipleTypeObjectsWithSelector ( t * testing . T ) {
2015-02-05 23:20:27 +00:00
pods , svc , _ := testData ( )
2014-12-31 00:42:55 +00:00
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2014-12-31 00:42:55 +00:00
Codec : codec ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2015-10-09 01:30:38 +00:00
if req . URL . Query ( ) . Get ( unversioned . LabelSelectorQueryParam ( testapi . Default . Version ( ) ) ) != "a=b" {
2014-12-31 00:42:55 +00:00
t . Fatalf ( "unexpected request: %#v\n%#v" , req . URL , req )
}
switch req . URL . Path {
2015-01-19 21:50:00 +00:00
case "/namespaces/test/pods" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( codec , pods ) } , nil
2015-01-19 21:50:00 +00:00
case "/namespaces/test/services" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( codec , svc ) } , nil
default :
t . Fatalf ( "unexpected request: %#v\n%#v" , req . URL , req )
return nil , nil
}
} ) ,
}
2015-01-02 18:08:37 +00:00
tf . Namespace = "test"
2014-12-31 00:42:55 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2014-12-31 00:42:55 +00:00
cmd . SetOutput ( buf )
cmd . Flags ( ) . Set ( "selector" , "a=b" )
cmd . Run ( cmd , [ ] string { "pods,services" } )
2015-10-01 01:07:03 +00:00
expected , err := extractResourceList ( [ ] runtime . Object { pods , svc } )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2014-12-31 00:42:55 +00:00
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "unexpected object: %#v" , actual )
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
2015-03-25 05:01:07 +00:00
func TestGetMultipleTypeObjectsWithDirectReference ( t * testing . T ) {
_ , svc , _ := testData ( )
node := & api . Node {
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
} ,
2015-04-01 23:11:33 +00:00
Spec : api . NodeSpec {
ExternalID : "ext" ,
} ,
2015-03-25 05:01:07 +00:00
}
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2015-03-25 05:01:07 +00:00
Codec : codec ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2015-03-25 05:01:07 +00:00
switch req . URL . Path {
case "/nodes/foo" :
return & http . Response { StatusCode : 200 , Body : objBody ( codec , node ) } , nil
case "/namespaces/test/services/bar" :
return & http . Response { StatusCode : 200 , Body : objBody ( codec , & svc . Items [ 0 ] ) } , nil
default :
t . Fatalf ( "unexpected request: %#v\n%#v" , req . URL , req )
return nil , nil
}
} ) ,
}
tf . Namespace = "test"
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2015-03-25 05:01:07 +00:00
cmd . SetOutput ( buf )
cmd . Run ( cmd , [ ] string { "services/bar" , "node/foo" } )
expected := [ ] runtime . Object { & svc . Items [ 0 ] , node }
actual := tf . Printer . ( * testPrinter ) . Objects
if ! api . Semantic . DeepEqual ( expected , actual ) {
t . Errorf ( "unexpected object: %s" , util . ObjectDiff ( expected , actual ) )
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
2014-12-31 00:42:55 +00:00
func watchTestData ( ) ( [ ] api . Pod , [ ] watch . Event ) {
pods := [ ] api . Pod {
{
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
Namespace : "test" ,
ResourceVersion : "10" ,
} ,
2015-09-14 21:56:51 +00:00
Spec : apitesting . DeepEqualSafePodSpec ( ) ,
2014-12-31 00:42:55 +00:00
} ,
}
events := [ ] watch . Event {
{
Type : watch . Modified ,
Object : & api . Pod {
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
Namespace : "test" ,
ResourceVersion : "11" ,
} ,
2015-09-14 21:56:51 +00:00
Spec : apitesting . DeepEqualSafePodSpec ( ) ,
2014-12-31 00:42:55 +00:00
} ,
} ,
{
Type : watch . Deleted ,
Object : & api . Pod {
ObjectMeta : api . ObjectMeta {
Name : "foo" ,
Namespace : "test" ,
ResourceVersion : "12" ,
} ,
2015-09-14 21:56:51 +00:00
Spec : apitesting . DeepEqualSafePodSpec ( ) ,
2014-12-31 00:42:55 +00:00
} ,
} ,
}
return pods , events
}
func TestWatchSelector ( t * testing . T ) {
pods , events := watchTestData ( )
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2014-12-31 00:42:55 +00:00
Codec : codec ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2015-10-09 01:30:38 +00:00
if req . URL . Query ( ) . Get ( unversioned . LabelSelectorQueryParam ( testapi . Default . Version ( ) ) ) != "a=b" {
2014-12-31 00:42:55 +00:00
t . Fatalf ( "unexpected request: %#v\n%#v" , req . URL , req )
}
switch req . URL . Path {
2015-01-19 21:50:00 +00:00
case "/namespaces/test/pods" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( codec , & api . PodList { Items : pods } ) } , nil
2015-01-19 21:50:00 +00:00
case "/watch/namespaces/test/pods" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : watchBody ( codec , events ) } , nil
default :
t . Fatalf ( "unexpected request: %#v\n%#v" , req . URL , req )
return nil , nil
}
} ) ,
}
2015-01-02 18:08:37 +00:00
tf . Namespace = "test"
2014-12-31 00:42:55 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2014-12-31 00:42:55 +00:00
cmd . SetOutput ( buf )
cmd . Flags ( ) . Set ( "watch" , "true" )
cmd . Flags ( ) . Set ( "selector" , "a=b" )
cmd . Run ( cmd , [ ] string { "pods" } )
expected := [ ] runtime . Object { & api . PodList { Items : pods } , events [ 0 ] . Object , events [ 1 ] . Object }
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
2015-09-14 21:56:51 +00:00
t . Errorf ( "unexpected object:\nExpected: %#v\n\nGot: %#v\n\n" , expected [ 0 ] , actual [ 0 ] )
2014-12-31 00:42:55 +00:00
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
func TestWatchResource ( t * testing . T ) {
pods , events := watchTestData ( )
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2014-12-31 00:42:55 +00:00
Codec : codec ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2014-12-31 00:42:55 +00:00
switch req . URL . Path {
2015-01-19 21:50:00 +00:00
case "/namespaces/test/pods/foo" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( codec , & pods [ 0 ] ) } , nil
2015-01-19 21:50:00 +00:00
case "/watch/namespaces/test/pods/foo" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : watchBody ( codec , events ) } , nil
default :
t . Fatalf ( "unexpected request: %#v\n%#v" , req . URL , req )
return nil , nil
}
} ) ,
}
2015-01-02 18:08:37 +00:00
tf . Namespace = "test"
2014-12-31 00:42:55 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2014-12-31 00:42:55 +00:00
cmd . SetOutput ( buf )
cmd . Flags ( ) . Set ( "watch" , "true" )
cmd . Run ( cmd , [ ] string { "pods" , "foo" } )
expected := [ ] runtime . Object { & pods [ 0 ] , events [ 0 ] . Object , events [ 1 ] . Object }
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
2015-09-14 21:56:51 +00:00
t . Errorf ( "unexpected object:\nExpected: %#v\n\nGot: %#v\n\n" , expected , actual )
2014-12-31 00:42:55 +00:00
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
2015-08-10 11:02:14 +00:00
func TestWatchResourceIdentifiedByFile ( t * testing . T ) {
pods , events := watchTestData ( )
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2015-08-10 11:02:14 +00:00
Codec : codec ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2015-08-10 11:02:14 +00:00
switch req . URL . Path {
case "/namespaces/test/pods/cassandra" :
return & http . Response { StatusCode : 200 , Body : objBody ( codec , & pods [ 0 ] ) } , nil
case "/watch/namespaces/test/pods/cassandra" :
return & http . Response { StatusCode : 200 , Body : watchBody ( codec , events ) } , nil
default :
t . Fatalf ( "unexpected request: %#v\n%#v" , req . URL , req )
return nil , nil
}
} ) ,
}
tf . Namespace = "test"
buf := bytes . NewBuffer ( [ ] byte { } )
cmd := NewCmdGet ( f , buf )
cmd . SetOutput ( buf )
cmd . Flags ( ) . Set ( "watch" , "true" )
cmd . Flags ( ) . Set ( "filename" , "../../../examples/cassandra/cassandra.yaml" )
cmd . Run ( cmd , [ ] string { } )
expected := [ ] runtime . Object { & pods [ 0 ] , events [ 0 ] . Object , events [ 1 ] . Object }
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "expected object: %#v unexpected object: %#v" , expected , actual )
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
2014-12-31 00:42:55 +00:00
func TestWatchOnlyResource ( t * testing . T ) {
pods , events := watchTestData ( )
f , tf , codec := NewAPIFactory ( )
tf . Printer = & testPrinter { }
2015-09-11 20:47:53 +00:00
tf . Client = & fake . RESTClient {
2014-12-31 00:42:55 +00:00
Codec : codec ,
2015-11-11 19:54:58 +00:00
Client : fake . CreateHTTPClient ( func ( req * http . Request ) ( * http . Response , error ) {
2014-12-31 00:42:55 +00:00
switch req . URL . Path {
2015-01-19 21:50:00 +00:00
case "/namespaces/test/pods/foo" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : objBody ( codec , & pods [ 0 ] ) } , nil
2015-01-19 21:50:00 +00:00
case "/watch/namespaces/test/pods/foo" :
2014-12-31 00:42:55 +00:00
return & http . Response { StatusCode : 200 , Body : watchBody ( codec , events ) } , nil
default :
t . Fatalf ( "unexpected request: %#v\n%#v" , req . URL , req )
return nil , nil
}
} ) ,
}
2015-01-02 18:08:37 +00:00
tf . Namespace = "test"
2014-12-31 00:42:55 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
2015-04-07 18:21:25 +00:00
cmd := NewCmdGet ( f , buf )
2014-12-31 00:42:55 +00:00
cmd . SetOutput ( buf )
cmd . Flags ( ) . Set ( "watch-only" , "true" )
cmd . Run ( cmd , [ ] string { "pods" , "foo" } )
expected := [ ] runtime . Object { events [ 0 ] . Object , events [ 1 ] . Object }
actual := tf . Printer . ( * testPrinter ) . Objects
if ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "unexpected object: %#v" , actual )
}
if len ( buf . String ( ) ) == 0 {
t . Errorf ( "unexpected empty output" )
}
}
func watchBody ( codec runtime . Codec , events [ ] watch . Event ) io . ReadCloser {
buf := bytes . NewBuffer ( [ ] byte { } )
enc := json . NewEncoder ( buf , codec )
for i := range events {
enc . Encode ( & events [ i ] )
}
return ioutil . NopCloser ( buf )
}