-
Notifications
You must be signed in to change notification settings - Fork 18.9k
Add test coverage to pkg/term #33520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| package term | ||
|
|
||
| import ( | ||
| "bytes" | ||
| "fmt" | ||
| "reflect" | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| func TestEscapeProxyRead(t *testing.T) { | ||
| escapeKeys, _ := ToBytes("DEL") | ||
| keys, _ := ToBytes("a,b,c,+") | ||
| reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) | ||
| buf := make([]byte, len(keys)) | ||
| nr, err := reader.Read(buf) | ||
| require.NoError(t, err) | ||
| require.EqualValues(t, nr, len(keys), fmt.Sprintf("nr %d should be equal to the number of %d", nr, len(keys))) | ||
| require.Equal(t, keys, buf, "keys & the read buffer should be equal") | ||
|
|
||
| keys, _ = ToBytes("") | ||
| reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) | ||
| buf = make([]byte, len(keys)) | ||
| nr, err = reader.Read(buf) | ||
| require.Error(t, err, "Should throw error when no keys are to read") | ||
| require.EqualValues(t, nr, 0, "nr should be zero") | ||
| require.Condition(t, func() (success bool) { return len(keys) == 0 && len(buf) == 0 }, "keys & the read buffer size should be zero") | ||
|
|
||
| escapeKeys, _ = ToBytes("ctrl-x,ctrl-@") | ||
| keys, _ = ToBytes("DEL") | ||
| reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) | ||
| buf = make([]byte, len(keys)) | ||
| nr, err = reader.Read(buf) | ||
| require.NoError(t, err) | ||
| require.EqualValues(t, nr, 1, fmt.Sprintf("nr %d should be equal to the number of 1", nr)) | ||
| require.Equal(t, keys, buf, "keys & the read buffer should be equal") | ||
|
|
||
| escapeKeys, _ = ToBytes("ctrl-c") | ||
| keys, _ = ToBytes("ctrl-c") | ||
| reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) | ||
| buf = make([]byte, len(keys)) | ||
| nr, err = reader.Read(buf) | ||
| require.Condition(t, func() (success bool) { | ||
| return reflect.TypeOf(err).Name() == "EscapeError" | ||
| }, err) | ||
| require.EqualValues(t, nr, 0, "nr should be equal to 0") | ||
| require.Equal(t, keys, buf, "keys & the read buffer should be equal") | ||
|
|
||
| escapeKeys, _ = ToBytes("ctrl-c,ctrl-z") | ||
| keys, _ = ToBytes("ctrl-c,ctrl-z") | ||
| reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) | ||
| buf = make([]byte, 1) | ||
| nr, err = reader.Read(buf) | ||
| require.NoError(t, err) | ||
| require.EqualValues(t, nr, 0, "nr should be equal to 0") | ||
| require.Equal(t, keys[0:1], buf, "keys & the read buffer should be equal") | ||
| nr, err = reader.Read(buf) | ||
| require.Condition(t, func() (success bool) { | ||
| return reflect.TypeOf(err).Name() == "EscapeError" | ||
| }, err) | ||
| require.EqualValues(t, nr, 0, "nr should be equal to 0") | ||
| require.Equal(t, keys[1:], buf, "keys & the read buffer should be equal") | ||
|
|
||
| escapeKeys, _ = ToBytes("ctrl-c,ctrl-z") | ||
| keys, _ = ToBytes("ctrl-c,DEL,+") | ||
| reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) | ||
| buf = make([]byte, 1) | ||
| nr, err = reader.Read(buf) | ||
| require.NoError(t, err) | ||
| require.EqualValues(t, nr, 0, "nr should be equal to 0") | ||
| require.Equal(t, keys[0:1], buf, "keys & the read buffer should be equal") | ||
| buf = make([]byte, len(keys)) | ||
| nr, err = reader.Read(buf) | ||
| require.NoError(t, err) | ||
| require.EqualValues(t, nr, len(keys), fmt.Sprintf("nr should be equal to %d", len(keys))) | ||
| require.Equal(t, keys, buf, "keys & the read buffer should be equal") | ||
|
|
||
| escapeKeys, _ = ToBytes("ctrl-c,ctrl-z") | ||
| keys, _ = ToBytes("ctrl-c,DEL") | ||
| reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) | ||
| buf = make([]byte, 1) | ||
| nr, err = reader.Read(buf) | ||
| require.NoError(t, err) | ||
| require.EqualValues(t, nr, 0, "nr should be equal to 0") | ||
| require.Equal(t, keys[0:1], buf, "keys & the read buffer should be equal") | ||
| buf = make([]byte, len(keys)) | ||
| nr, err = reader.Read(buf) | ||
| require.NoError(t, err) | ||
| require.EqualValues(t, nr, len(keys), fmt.Sprintf("nr should be equal to %d", len(keys))) | ||
| require.Equal(t, keys, buf, "keys & the read buffer should be equal") | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| //+build linux | ||
|
|
||
| package term | ||
|
|
||
| import ( | ||
| "flag" | ||
| "io/ioutil" | ||
| "os" | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| var rootEnabled bool | ||
|
|
||
| func init() { | ||
| flag.BoolVar(&rootEnabled, "test.root", false, "enable tests that require root") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this flag necessary? Why not just skip the tests if the uid isn't 0? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose that would work, but I think I prefer the flag, because it means the set of tests that runs won't be sensitive to the environment. It's nice to avoid scenarios where the tests pass for one person but fail for another person running the same comment. containerd uses this flag to enable/disable tests that require root privileges.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm more concerned that tests don't run unless you happen to provide this flag. and there's really no way to discover this flag. I really don't think this is a good solution. Skipping if If we know a test is going to fail, why bother running it? This is what we do for all the integration tests, we skip them if the environment does not support the test. This is pretty standard for many tests suites I think. If for some reason we really want to force these to run, unless someone sets something explicit then I think we should be using an environment variable. We can always run the tests, unless the environment variable |
||
| } | ||
|
|
||
| // RequiresRoot skips tests that require root, unless the test.root flag has | ||
| // been set | ||
| func RequiresRoot(t *testing.T) { | ||
| if !rootEnabled { | ||
| t.Skip("skipping test that requires root") | ||
| return | ||
| } | ||
| assert.Equal(t, 0, os.Getuid(), "This test must be run as root.") | ||
| } | ||
|
|
||
| func newTtyForTest(t *testing.T) (*os.File, error) { | ||
| RequiresRoot(t) | ||
| return os.OpenFile("/dev/tty", os.O_RDWR, os.ModeDevice) | ||
| } | ||
|
|
||
| func newTempFile() (*os.File, error) { | ||
| return ioutil.TempFile(os.TempDir(), "temp") | ||
| } | ||
|
|
||
| func TestGetWinsize(t *testing.T) { | ||
| tty, err := newTtyForTest(t) | ||
| defer tty.Close() | ||
| require.NoError(t, err) | ||
| winSize, err := GetWinsize(tty.Fd()) | ||
| require.NoError(t, err) | ||
| require.NotNil(t, winSize) | ||
| require.NotNil(t, winSize.Height) | ||
| require.NotNil(t, winSize.Width) | ||
| newSize := Winsize{Width: 200, Height: 200, x: winSize.x, y: winSize.y} | ||
| err = SetWinsize(tty.Fd(), &newSize) | ||
| require.NoError(t, err) | ||
| winSize, err = GetWinsize(tty.Fd()) | ||
| require.NoError(t, err) | ||
| require.Equal(t, *winSize, newSize) | ||
| } | ||
|
|
||
| func TestSetWinsize(t *testing.T) { | ||
| tty, err := newTtyForTest(t) | ||
| defer tty.Close() | ||
| require.NoError(t, err) | ||
| winSize, err := GetWinsize(tty.Fd()) | ||
| require.NoError(t, err) | ||
| require.NotNil(t, winSize) | ||
| newSize := Winsize{Width: 200, Height: 200, x: winSize.x, y: winSize.y} | ||
| err = SetWinsize(tty.Fd(), &newSize) | ||
| require.NoError(t, err) | ||
| winSize, err = GetWinsize(tty.Fd()) | ||
| require.NoError(t, err) | ||
| require.Equal(t, *winSize, newSize) | ||
| } | ||
|
|
||
| func TestGetFdInfo(t *testing.T) { | ||
| tty, err := newTtyForTest(t) | ||
| defer tty.Close() | ||
| require.NoError(t, err) | ||
| inFd, isTerminal := GetFdInfo(tty) | ||
| require.Equal(t, inFd, tty.Fd()) | ||
| require.Equal(t, isTerminal, true) | ||
| tmpFile, err := newTempFile() | ||
| defer tmpFile.Close() | ||
| inFd, isTerminal = GetFdInfo(tmpFile) | ||
| require.Equal(t, inFd, tmpFile.Fd()) | ||
| require.Equal(t, isTerminal, false) | ||
| } | ||
|
|
||
| func TestIsTerminal(t *testing.T) { | ||
| tty, err := newTtyForTest(t) | ||
| defer tty.Close() | ||
| require.NoError(t, err) | ||
| isTerminal := IsTerminal(tty.Fd()) | ||
| require.Equal(t, isTerminal, true) | ||
| tmpFile, err := newTempFile() | ||
| defer tmpFile.Close() | ||
| isTerminal = IsTerminal(tmpFile.Fd()) | ||
| require.Equal(t, isTerminal, false) | ||
| } | ||
|
|
||
| func TestSaveState(t *testing.T) { | ||
| tty, err := newTtyForTest(t) | ||
| defer tty.Close() | ||
| require.NoError(t, err) | ||
| state, err := SaveState(tty.Fd()) | ||
| require.NoError(t, err) | ||
| require.NotNil(t, state) | ||
| tty, err = newTtyForTest(t) | ||
| defer tty.Close() | ||
| err = RestoreTerminal(tty.Fd(), state) | ||
| require.NoError(t, err) | ||
| } | ||
|
|
||
| func TestDisableEcho(t *testing.T) { | ||
| tty, err := newTtyForTest(t) | ||
| defer tty.Close() | ||
| require.NoError(t, err) | ||
| state, err := SetRawTerminal(tty.Fd()) | ||
| require.NoError(t, err) | ||
| require.NotNil(t, state) | ||
| err = DisableEcho(tty.Fd(), state) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm running the unit tests on master and I'm seeing my shell is missing echo after running these tests. I think this tests needs to re-enable echo to clean up after itself. I'm preparing a PR to fix this now. |
||
| require.NoError(t, err) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍