mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-05 15:37:24 +00:00
Fix Windows terminal handling
Fix some issues with Windows terminal handling with respect to TTYs that came up as part of the code that adds support for terminal resizing.
This commit is contained in:
@@ -20,9 +20,11 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@@ -65,19 +67,19 @@ func TestPodAndContainer(t *testing.T) {
|
||||
name: "empty",
|
||||
},
|
||||
{
|
||||
p: &ExecOptions{PodName: "foo"},
|
||||
p: &ExecOptions{StreamOptions: StreamOptions{PodName: "foo"}},
|
||||
argsLenAtDash: -1,
|
||||
expectError: true,
|
||||
name: "no cmd",
|
||||
},
|
||||
{
|
||||
p: &ExecOptions{PodName: "foo", ContainerName: "bar"},
|
||||
p: &ExecOptions{StreamOptions: StreamOptions{PodName: "foo", ContainerName: "bar"}},
|
||||
argsLenAtDash: -1,
|
||||
expectError: true,
|
||||
name: "no cmd, w/ container",
|
||||
},
|
||||
{
|
||||
p: &ExecOptions{PodName: "foo"},
|
||||
p: &ExecOptions{StreamOptions: StreamOptions{PodName: "foo"}},
|
||||
args: []string{"cmd"},
|
||||
argsLenAtDash: -1,
|
||||
expectedPod: "foo",
|
||||
@@ -115,7 +117,7 @@ func TestPodAndContainer(t *testing.T) {
|
||||
name: "cmd, cmd is behind dash",
|
||||
},
|
||||
{
|
||||
p: &ExecOptions{ContainerName: "bar"},
|
||||
p: &ExecOptions{StreamOptions: StreamOptions{ContainerName: "bar"}},
|
||||
args: []string{"foo", "cmd"},
|
||||
argsLenAtDash: -1,
|
||||
expectedPod: "foo",
|
||||
@@ -206,12 +208,14 @@ func TestExec(t *testing.T) {
|
||||
ex.execErr = fmt.Errorf("exec error")
|
||||
}
|
||||
params := &ExecOptions{
|
||||
PodName: "foo",
|
||||
ContainerName: "bar",
|
||||
In: bufIn,
|
||||
Out: bufOut,
|
||||
Err: bufErr,
|
||||
Executor: ex,
|
||||
StreamOptions: StreamOptions{
|
||||
PodName: "foo",
|
||||
ContainerName: "bar",
|
||||
In: bufIn,
|
||||
Out: bufOut,
|
||||
Err: bufErr,
|
||||
},
|
||||
Executor: ex,
|
||||
}
|
||||
cmd := &cobra.Command{}
|
||||
args := []string{"test", "command"}
|
||||
@@ -257,3 +261,124 @@ func execPod() *api.Pod {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetupTTY(t *testing.T) {
|
||||
stderr := &bytes.Buffer{}
|
||||
|
||||
// test 1 - don't attach stdin
|
||||
o := &StreamOptions{
|
||||
// InterruptParent: ,
|
||||
Stdin: false,
|
||||
In: &bytes.Buffer{},
|
||||
Out: &bytes.Buffer{},
|
||||
Err: stderr,
|
||||
TTY: true,
|
||||
}
|
||||
|
||||
tty := o.setupTTY()
|
||||
|
||||
if o.In != nil {
|
||||
t.Errorf("don't attach stdin: o.In should be nil")
|
||||
}
|
||||
if tty.In != nil {
|
||||
t.Errorf("don't attach stdin: tty.In should be nil")
|
||||
}
|
||||
if o.TTY {
|
||||
t.Errorf("don't attach stdin: o.TTY should be false")
|
||||
}
|
||||
if tty.Raw {
|
||||
t.Errorf("don't attach stdin: tty.Raw should be false")
|
||||
}
|
||||
if len(stderr.String()) > 0 {
|
||||
t.Errorf("don't attach stdin: stderr wasn't empty: %s", stderr.String())
|
||||
}
|
||||
|
||||
// tests from here on attach stdin
|
||||
// test 2 - don't request a TTY
|
||||
o.Stdin = true
|
||||
o.In = &bytes.Buffer{}
|
||||
o.TTY = false
|
||||
|
||||
tty = o.setupTTY()
|
||||
|
||||
if o.In == nil {
|
||||
t.Errorf("attach stdin, no TTY: o.In should not be nil")
|
||||
}
|
||||
if tty.In != o.In {
|
||||
t.Errorf("attach stdin, no TTY: tty.In should equal o.In")
|
||||
}
|
||||
if o.TTY {
|
||||
t.Errorf("attach stdin, no TTY: o.TTY should be false")
|
||||
}
|
||||
if tty.Raw {
|
||||
t.Errorf("attach stdin, no TTY: tty.Raw should be false")
|
||||
}
|
||||
if len(stderr.String()) > 0 {
|
||||
t.Errorf("attach stdin, no TTY: stderr wasn't empty: %s", stderr.String())
|
||||
}
|
||||
|
||||
// test 3 - request a TTY, but stdin is not a terminal
|
||||
o.Stdin = true
|
||||
o.In = &bytes.Buffer{}
|
||||
o.Err = stderr
|
||||
o.TTY = true
|
||||
|
||||
tty = o.setupTTY()
|
||||
|
||||
if o.In == nil {
|
||||
t.Errorf("attach stdin, TTY, not a terminal: o.In should not be nil")
|
||||
}
|
||||
if tty.In != o.In {
|
||||
t.Errorf("attach stdin, TTY, not a terminal: tty.In should equal o.In")
|
||||
}
|
||||
if o.TTY {
|
||||
t.Errorf("attach stdin, TTY, not a terminal: o.TTY should be false")
|
||||
}
|
||||
if tty.Raw {
|
||||
t.Errorf("attach stdin, TTY, not a terminal: tty.Raw should be false")
|
||||
}
|
||||
if !strings.Contains(stderr.String(), "input is not a terminal") {
|
||||
t.Errorf("attach stdin, TTY, not a terminal: expected 'input is not a terminal' to stderr")
|
||||
}
|
||||
|
||||
// test 4 - request a TTY, stdin is a terminal
|
||||
o.Stdin = true
|
||||
o.In = &bytes.Buffer{}
|
||||
stderr.Reset()
|
||||
o.TTY = true
|
||||
|
||||
overrideStdin := ioutil.NopCloser(&bytes.Buffer{})
|
||||
overrideStdout := &bytes.Buffer{}
|
||||
overrideStderr := &bytes.Buffer{}
|
||||
o.overrideStreams = func() (io.ReadCloser, io.Writer, io.Writer) {
|
||||
return overrideStdin, overrideStdout, overrideStderr
|
||||
}
|
||||
|
||||
o.isTerminalIn = func(tty term.TTY) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
tty = o.setupTTY()
|
||||
|
||||
if o.In != overrideStdin {
|
||||
t.Errorf("attach stdin, TTY, is a terminal: o.In should equal overrideStdin")
|
||||
}
|
||||
if tty.In != o.In {
|
||||
t.Errorf("attach stdin, TTY, is a terminal: tty.In should equal o.In")
|
||||
}
|
||||
if !o.TTY {
|
||||
t.Errorf("attach stdin, TTY, is a terminal: o.TTY should be true")
|
||||
}
|
||||
if !tty.Raw {
|
||||
t.Errorf("attach stdin, TTY, is a terminal: tty.Raw should be true")
|
||||
}
|
||||
if len(stderr.String()) > 0 {
|
||||
t.Errorf("attach stdin, TTY, is a terminal: stderr wasn't empty: %s", stderr.String())
|
||||
}
|
||||
if o.Out != overrideStdout {
|
||||
t.Errorf("attach stdin, TTY, is a terminal: o.Out should equal overrideStdout")
|
||||
}
|
||||
if tty.Out != o.Out {
|
||||
t.Errorf("attach stdin, TTY, is a terminal: tty.Out should equal o.Out")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user