Skip to content
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

cat/play: tip that multiple files can be processed #1029

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cli/cmd/cat.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ var catFlags = checkpoint.Opts{
func NewCatCmd() *cobra.Command {
var catCmd = &cobra.Command{
Use: "cat <FILE>...",
Short: "Print into stdout the contents of .snap/.xlog files",
Short: "Print into stdout the contents of .snap/.xlog FILE(s)",
Run: func(cmd *cobra.Command, args []string) {
cmdCtx.CommandName = cmd.Name()
err := modules.RunCmd(&cmdCtx, cmd.CommandPath(), &modulesInfo,
internalCatModule, args)
util.HandleCmdErr(cmd, err)
},
Example: "tt cat /path/to/xlog --timestamp 2024-11-13T14:02:36.818700000+00:00\n" +
" tt cat /path/to/snap --timestamp=1731592956.818",
" tt cat /path/to/file.xlog /path/to/file.snap --timestamp=1731592956.818",
}

catCmd.Flags().Uint64Var(&catFlags.To, "to", catFlags.To,
Expand Down
4 changes: 2 additions & 2 deletions cli/cmd/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ var (
func NewPlayCmd() *cobra.Command {
var playCmd = &cobra.Command{
Use: "play <URI> <FILE>...",
Short: "Play the contents of .snap/.xlog files to another Tarantool instance",
Short: "Play the contents of .snap/.xlog FILE(s) to another Tarantool instance",
Run: func(cmd *cobra.Command, args []string) {
cmdCtx.CommandName = cmd.Name()
err := modules.RunCmd(&cmdCtx, cmd.CommandPath(), &modulesInfo,
internalPlayModule, args)
util.HandleCmdErr(cmd, err)
},
Example: "tt play uri /path/to/xlog --timestamp 2024-11-13T14:02:36.818700000+00:00\n" +
" tt play uri /path/to/xlog --timestamp=1731592956.818",
" tt play uri /path/to/file.xlog /path/to/file.snap --timestamp=1731592956.818",
}

playCmd.Flags().StringVarP(&playUsername, "username", "u", "", "username")
Expand Down
172 changes: 98 additions & 74 deletions test/integration/cat/test_cat.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,116 +7,140 @@
from utils import run_command_and_get_output


def test_cat_unset_arg(tt_cmd, tmp_path):
# Testing with unset .xlog or .snap file.
# Failed `args` tests
def make_test_cat_args_param_failed(
args={},
found={},
):
return pytest.param(args, found)


@pytest.mark.parametrize("args, found", [
make_test_cat_args_param_failed(
# Testing with unset .xlog or .snap file.
found={"it is required to specify at least one .xlog or .snap file"},
),
make_test_cat_args_param_failed(
args={"path-to-non-existent-file"},
found={"No such file or directory"},
),
])
def test_cat_args_tests_failed(tt_cmd, tmp_path, args, found):
# Copy the .xlog file to the "run" directory.
test_xlog_file = os.path.join(os.path.dirname(__file__), "test_file", "test.xlog")
test_snap_file = os.path.join(os.path.dirname(__file__), "test_file", "test.snap")
shutil.copy(test_xlog_file, tmp_path)
shutil.copy(test_snap_file, tmp_path)

cmd = [tt_cmd, "cat"]
cmd.extend(args)
rc, output = run_command_and_get_output(cmd, cwd=tmp_path)
assert rc == 1
assert re.search(r"it is required to specify at least one .xlog or .snap file", output)
for item in found:
assert re.search(r"{0}".format(item), output)


def test_cat_non_existent_file(tt_cmd, tmp_path):
# Testing with non-existent .xlog or .snap file.
cmd = [tt_cmd, "cat", "path-to-non-existent-file"]
rc, output = run_command_and_get_output(cmd, cwd=tmp_path)
assert rc == 1
assert re.search(r"No such file or directory", output)
# Successful args tests
def make_test_cat_args_param_valid(
args={},
found={},
):
return pytest.param(args, found)


def test_cat_snap_file(tt_cmd, tmp_path):
# Copy the .snap file to the "run" directory.
test_app_path = os.path.join(os.path.dirname(__file__), "test_file", "test.snap")
shutil.copy(test_app_path, tmp_path)
@pytest.mark.parametrize("args, found", [
make_test_cat_args_param_valid(
args={"test.snap", "--show-system", "--space=320",
"--space=296", "--from=423", "--to=513"},
found={"lsn: 423", "lsn: 512",
"space_id: 320", "space_id: 296"},
),
make_test_cat_args_param_valid(
args={"test.xlog", "--show-system", "--replica=1"},
found={"replica_id: 1"},
),
make_test_cat_args_param_valid(
args={"test.xlog", "test.snap"},
found={'Result of cat: the file "test.xlog" is processed below',
'Result of cat: the file "test.snap" is processed below'},
),
])
def test_cat_args_tests_successed(tt_cmd, tmp_path, args, found):
# Copy the .xlog file to the "run" directory.
test_xlog_file = os.path.join(os.path.dirname(__file__), "test_file", "test.xlog")
test_snap_file = os.path.join(os.path.dirname(__file__), "test_file", "test.snap")
shutil.copy(test_xlog_file, tmp_path)
shutil.copy(test_snap_file, tmp_path)

# Testing .snap file.
cmd = [
tt_cmd, "cat", "test.snap", "--show-system",
"--space=320", "--space=296", "--from=423", "--to=513"
]
cmd = [tt_cmd, "cat"]
cmd.extend(args)
rc, output = run_command_and_get_output(cmd, cwd=tmp_path)
assert rc == 0
assert re.search(r"lsn: 423", output)
assert re.search(r"lsn: 512", output)
assert re.search(r"space_id: 320", output)
assert re.search(r"space_id: 296", output)
for item in found:
assert re.search(r"{0}".format(item), output)


def test_cat_xlog_file(tt_cmd, tmp_path):
# Failed `timestamp` tests
@pytest.mark.parametrize("input, found", [
pytest.param(
"abcdef",
{'failed to parse a timestamp: parsing time "abcdef"'},
),
pytest.param(
"2024-11-14T14:02:36.abc",
{'failed to parse a timestamp: parsing time "2024-11-14T14:02:36.abc"'},
),
])
def test_cat_test_timestamp_failed(tt_cmd, tmp_path, input, found):
# Copy the .xlog file to the "run" directory.
test_app_path = os.path.join(os.path.dirname(__file__), "test_file", "test.xlog")
test_app_path = os.path.join(os.path.dirname(__file__), "test_file", "timestamp.xlog")
shutil.copy(test_app_path, tmp_path)

# Testing .xlog file.
cmd = [tt_cmd, "cat", "test.xlog", "--show-system", "--replica=1"]
cmd = [tt_cmd, "cat", "timestamp.xlog", "--timestamp={0}".format(input)]
rc, output = run_command_and_get_output(cmd, cwd=tmp_path)
assert rc == 0
assert re.search(r"replica_id: 1", output)


TEST_CAT_TIMESTAMP_PARAMS_CCONFIG = ("input, cat_result, found, not_found")
assert rc == 1
for item in found:
assert re.search(r"{0}".format(item), output)


def make_test_cat_timestamp_param(
# Successful `timestamp` tests
def make_test_cat_timestamp_param_valid(
input="",
cat_result=0,
found={},
not_found={},
):
return pytest.param(input, cat_result, found, not_found)
return pytest.param(input, found, not_found)


@pytest.mark.parametrize(TEST_CAT_TIMESTAMP_PARAMS_CCONFIG, [
make_test_cat_timestamp_param(
input="abcdef",
cat_result=1,
found={"failed to parse a timestamp: parsing time \"abcdef\""},
),
make_test_cat_timestamp_param(
input="2024-11-14T14:02:36.abc",
cat_result=1,
found={"failed to parse a timestamp: parsing time \"2024-11-14T14:02:36.abc\""},
),
make_test_cat_timestamp_param(
input="",
cat_result=0,
@pytest.mark.parametrize("input, found, not_found", [
make_test_cat_timestamp_param_valid(
found={"lsn: 12"},
),
make_test_cat_timestamp_param(
make_test_cat_timestamp_param_valid(
input="1731592956.8182",
cat_result=0,
found={"lsn: 6",
"timestamp: 1731592956.8181"},
not_found={"lsn: 8",
"timestamp: 1731592956.8184"},
found={"lsn: 6", "timestamp: 1731592956.8181"},
not_found={"lsn: 8", "timestamp: 1731592956.8184"},
),
make_test_cat_timestamp_param(
make_test_cat_timestamp_param_valid(
input="2024-11-14T14:02:36.818299999Z",
cat_result=0,
found={"lsn: 6",
"timestamp: 1731592956.8181"},
not_found={"lsn: 8",
"timestamp: 1731592956.8184"},
found={"lsn: 6", "timestamp: 1731592956.8181"},
not_found={"lsn: 8", "timestamp: 1731592956.8184"},
),
make_test_cat_timestamp_param(
make_test_cat_timestamp_param_valid(
input="2024-11-14T14:02:35+00:00",
cat_result=0,
not_found={"lsn: 6",
"timestamp: 1731592956.8181",
"lsn: 8",
"timestamp: 1731592956.8184"},
not_found={"lsn: 6", "timestamp: 1731592956.8181",
"lsn: 8", "timestamp: 1731592956.8184"},
),
])
def test_cat_test_remote_instance_timestamp(tt_cmd, tmp_path, input,
cat_result, found, not_found):
def test_cat_test_timestamp_successed(tt_cmd, tmp_path, input, found, not_found):
# Copy the .xlog file to the "run" directory.
test_app_path = os.path.join(os.path.dirname(__file__), "test_file", "timestamp.xlog")
shutil.copy(test_app_path, tmp_path)

cmd = [tt_cmd, "cat", "timestamp.xlog", "--timestamp={0}".format(input)]
rc, output = run_command_and_get_output(cmd, cwd=tmp_path)
assert rc == cat_result
if cat_result == 0:
for item in found:
assert re.search(r"{0}".format(item), output)
for item in not_found:
assert not re.search(r"{0}".format(item), output)
assert rc == 0
for item in found:
assert re.search(r"{0}".format(item), output)
for item in not_found:
assert not re.search(r"{0}".format(item), output)
Loading
Loading