Files
OpenShell/sdk/go/openshell/v1/exec_control_test.go
Varsha 7139df8ca5 fix(exec): preserve output after stdin EOF and verify stream completion (#3359)
* fix(exec): preserve output after stdin EOF and verify stream completion

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

* test(exec): cover fair duplex progress and live SDK completion

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

* test(sdk): compare large exec buffers with native equality

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

* test(exec): use workspace-scoped sandbox name in EOF regression

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

---------

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
2026-09-22 14:11:06 +00:00

57 lines
2.1 KiB
Go

// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package v1
import (
"errors"
"io"
"testing"
"github.com/stretchr/testify/require"
)
// Deliberately implements only the original interface: downstream mocks must
// continue compiling without adding the optional lifecycle methods.
type legacyInteractiveSession struct {
closed bool
err error
}
var _ InteractiveSession = (*legacyInteractiveSession)(nil)
func (*legacyInteractiveSession) Read([]byte) (int, error) { return 0, io.EOF }
func (*legacyInteractiveSession) Write(p []byte) (int, error) { return len(p), nil }
func (*legacyInteractiveSession) Resize(uint32, uint32) error { return nil }
func (*legacyInteractiveSession) ExitCode() (int, error) { return 0, nil }
func (s *legacyInteractiveSession) Close() error { s.closed = true; return s.err }
type controlledInteractiveSession struct {
legacyInteractiveSession
inputClosed bool
cancelled bool
}
func (s *controlledInteractiveSession) CloseWrite() error { s.inputClosed = true; return s.err }
func (s *controlledInteractiveSession) Cancel() error { s.cancelled = true; return s.err }
func TestInteractiveControlLegacyCompatibility(t *testing.T) {
s := &legacyInteractiveSession{err: errors.New("close error")}
var statusErr *StatusError
require.ErrorAs(t, CloseInteractiveInput(s), &statusErr)
require.Equal(t, ErrorUnimplemented, statusErr.Code)
require.False(t, s.closed, "unsupported input closure must not cancel the session")
require.ErrorIs(t, CancelInteractive(s), s.err)
require.True(t, s.closed)
}
func TestInteractiveControlDispatch(t *testing.T) {
s := &controlledInteractiveSession{legacyInteractiveSession: legacyInteractiveSession{err: errors.New("control error")}}
require.Implements(t, (*InteractiveSessionControl)(nil), s)
require.ErrorIs(t, CloseInteractiveInput(s), s.err)
require.True(t, s.inputClosed)
require.ErrorIs(t, CancelInteractive(s), s.err)
require.True(t, s.cancelled)
require.False(t, s.closed, "explicit cancellation takes precedence over fallback")
}