diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cb3b2a8f..7648ddc96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Command `\set delimiter [marker]` works correctly and don't hangs `tt` console. - `tt log -f` crash on removing log directory. +- `tt connect` crash due to an empty response. ### Changed diff --git a/cli/connect/connect.go b/cli/connect/connect.go index d23222775..dbd534fd3 100644 --- a/cli/connect/connect.go +++ b/cli/connect/connect.go @@ -122,13 +122,20 @@ func Eval(connectCtx ConnectCtx, connOpts connector.ConnectOpts, args []string) // Check that the result is encoded in YAML and convert it to bytes, // since the ""gopkg.in/yaml.v2" library handles YAML as an array // of bytes. - resYAML := []byte((response[0]).(string)) + var resYAML string + if len(response) > 0 { + if str, ok := response[0].(string); ok { + resYAML = str + } else { + return nil, fmt.Errorf("unexpected response type: %T", response[0]) + } + } var checkMock interface{} - if err = yaml.Unmarshal(resYAML, &checkMock); err != nil { + if err = yaml.Unmarshal([]byte(resYAML), &checkMock); err != nil { return nil, err } - return resYAML, nil + return []byte(resYAML), nil } // runConsole run a new console. diff --git a/test/integration/connect/test_connect.py b/test/integration/connect/test_connect.py index 821fea15e..2b2b1f178 100644 --- a/test/integration/connect/test_connect.py +++ b/test/integration/connect/test_connect.py @@ -66,14 +66,19 @@ def stop_app(tt_cmd, tmpdir, app_name): def try_execute_on_instance(tt_cmd, tmpdir, instance, file_path=None, stdin=None, + stdin_as_file=False, env=None, opts=None, args=None): connect_cmd = [tt_cmd, "connect", instance] + if file_path is not None: connect_cmd.append("-f") connect_cmd.append(file_path) + if stdin_as_file: + connect_cmd.append("-f-") + if opts is not None: for k, v in opts.items(): connect_cmd.append(k) @@ -138,6 +143,12 @@ def get_version(tt_cmd, tmpdir): return False, 0, 0, 0 +def is_quit_supported(tt_cmd, tmpdir): + ok, major, minor, patch = get_version(tt_cmd, tmpdir) + assert ok + return major >= 2 + + def is_language_supported(tt_cmd, tmpdir): ok, major, minor, patch = get_version(tt_cmd, tmpdir) assert ok @@ -169,6 +180,11 @@ def is_tarantool_major_one(): return False +def skip_if_quit_unsupported(tt_cmd, tmpdir): + if not is_quit_supported(tt_cmd, tmpdir): + pytest.skip("\\q is unsupported") + + def skip_if_language_unsupported(tt_cmd, tmpdir, test_app): if not is_language_supported(tt_cmd, tmpdir): stop_app(tt_cmd, tmpdir, test_app) @@ -359,6 +375,38 @@ def test_connect_and_get_commands_errors(tt_cmd, tmpdir_with_cfg): stop_app(tt_cmd, tmpdir, "test_app") +def test_connect_and_execute_quit(tt_cmd, tmpdir_with_cfg): + tmpdir = tmpdir_with_cfg + empty_file = "empty.lua" + + skip_if_quit_unsupported(tt_cmd, tmpdir) + + # The test application file. + test_app_path = os.path.join(os.path.dirname(__file__), "test_single_app", "test_app.lua") + # The test file. + empty_file_path = os.path.join(os.path.dirname(__file__), "test_file", empty_file) + # Copy test data into temporary directory. + copy_data(tmpdir, [test_app_path, empty_file_path]) + + # Start an instance. + start_app(tt_cmd, tmpdir, "test_app") + + # Check for start. + file = wait_file(os.path.join(tmpdir, "test_app", run_path, "test_app"), + control_socket, []) + assert file != "" + + try: + ret, output = try_execute_on_instance(tt_cmd, tmpdir, "test_app", + stdin="\\q", + stdin_as_file=True) + assert ret + + assert output == "\n" + finally: + stop_app(tt_cmd, tmpdir, "test_app") + + def test_connect_to_localhost_app(tt_cmd, tmpdir_with_cfg): tmpdir = tmpdir_with_cfg empty_file = "empty.lua"