mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-12-01 17:44:30 +00:00
Request and handle server-side printing when watching with kubectl
This commit is contained in:
@@ -1403,6 +1403,113 @@ foo 0/0 0 <unknown>
|
||||
}
|
||||
}
|
||||
|
||||
func TestWatchResourceTable(t *testing.T) {
|
||||
columns := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: "the name", Priority: 0},
|
||||
{Name: "Active", Type: "boolean", Description: "active", Priority: 0},
|
||||
}
|
||||
|
||||
listTable := &metav1beta1.Table{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: "meta.k8s.io/v1beta1", Kind: "Table"},
|
||||
ColumnDefinitions: columns,
|
||||
Rows: []metav1beta1.TableRow{
|
||||
{
|
||||
Cells: []interface{}{"a", true},
|
||||
Object: runtime.RawExtension{
|
||||
Object: &corev1.Pod{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Pod"},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "a", Namespace: "test", ResourceVersion: "10"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Cells: []interface{}{"b", true},
|
||||
Object: runtime.RawExtension{
|
||||
Object: &corev1.Pod{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Pod"},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "b", Namespace: "test", ResourceVersion: "20"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
events := []watch.Event{
|
||||
{
|
||||
Type: watch.Added,
|
||||
Object: &metav1beta1.Table{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: "meta.k8s.io/v1beta1", Kind: "Table"},
|
||||
ColumnDefinitions: columns, // first event includes the columns
|
||||
Rows: []metav1beta1.TableRow{{
|
||||
Cells: []interface{}{"a", false},
|
||||
Object: runtime.RawExtension{
|
||||
Object: &corev1.Pod{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Pod"},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "a", Namespace: "test", ResourceVersion: "30"},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: watch.Deleted,
|
||||
Object: &metav1beta1.Table{
|
||||
ColumnDefinitions: []metav1beta1.TableColumnDefinition{},
|
||||
Rows: []metav1beta1.TableRow{{
|
||||
Cells: []interface{}{"b", false},
|
||||
Object: runtime.RawExtension{
|
||||
Object: &corev1.Pod{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Pod"},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "b", Namespace: "test", ResourceVersion: "40"},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
defer tf.Cleanup()
|
||||
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
|
||||
|
||||
tf.UnstructuredClient = &fake.RESTClient{
|
||||
NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
|
||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||
switch req.URL.Path {
|
||||
case "/namespaces/test/pods":
|
||||
if req.URL.Query().Get("watch") != "true" && req.URL.Query().Get("fieldSelector") == "" {
|
||||
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, listTable)}, nil
|
||||
}
|
||||
if req.URL.Query().Get("watch") == "true" && req.URL.Query().Get("fieldSelector") == "" {
|
||||
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: watchBody(codec, events)}, nil
|
||||
}
|
||||
t.Fatalf("request url: %#v,and request: %#v", req.URL, req)
|
||||
return nil, nil
|
||||
default:
|
||||
t.Fatalf("request url: %#v,and request: %#v", req.URL, req)
|
||||
return nil, nil
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
cmd := NewCmdGet("kubectl", tf, streams)
|
||||
cmd.SetOutput(buf)
|
||||
|
||||
cmd.Flags().Set("watch", "true")
|
||||
cmd.Run(cmd, []string{"pods"})
|
||||
|
||||
expected := `NAME ACTIVE
|
||||
a true
|
||||
b true
|
||||
a false
|
||||
b false
|
||||
`
|
||||
if e, a := expected, buf.String(); e != a {
|
||||
t.Errorf("expected\n%v\ngot\n%v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWatchResourceIdentifiedByFile(t *testing.T) {
|
||||
pods, events := watchTestData()
|
||||
|
||||
@@ -1538,7 +1645,9 @@ func watchBody(codec runtime.Codec, events []watch.Event) io.ReadCloser {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
enc := restclientwatch.NewEncoder(streaming.NewEncoder(buf, codec), codec)
|
||||
for i := range events {
|
||||
enc.Encode(&events[i])
|
||||
if err := enc.Encode(&events[i]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return json.Framer.NewFrameReader(ioutil.NopCloser(buf))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user