mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-21 11:39:57 +03:00
Add more integration testing for the transfer kitten
This commit is contained in:
parent
e24dd7be2c
commit
c11d1d3430
@ -48,7 +48,9 @@
|
|||||||
:code:`/path/to/dir/` on the local computer.
|
:code:`/path/to/dir/` on the local computer.
|
||||||
|
|
||||||
Note that when copying multiple files or directories, the destination
|
Note that when copying multiple files or directories, the destination
|
||||||
must be an existing directory on the receiving computer.
|
must be an existing directory on the receiving computer. Relative file
|
||||||
|
paths are resolved with respect to the current directory on the computer
|
||||||
|
running the kitten and the home directory on the other computer.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"kitty/tools/utils/humanize"
|
"kitty/tools/utils/humanize"
|
||||||
"kitty/tools/wcswidth"
|
"kitty/tools/wcswidth"
|
||||||
|
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -683,6 +684,8 @@ func files_for_receive(opts *Options, dest string, files []*remote_file, remote_
|
|||||||
}
|
}
|
||||||
spec_paths := make([]string, len(specs))
|
spec_paths := make([]string, len(specs))
|
||||||
for i := range specs {
|
for i := range specs {
|
||||||
|
// use the shortest path as the path for the spec
|
||||||
|
slices.SortStableFunc(spec_map[i], func(a, b *remote_file) bool { return len(a.remote_path) < len(b.remote_path) })
|
||||||
spec_paths[i] = spec_map[i][0].remote_path
|
spec_paths[i] = spec_map[i][0].remote_path
|
||||||
}
|
}
|
||||||
if opts.Mode == "mirror" {
|
if opts.Mode == "mirror" {
|
||||||
|
@ -177,14 +177,14 @@ func process(opts *Options, paths []string, remote_base string, counter *int) (a
|
|||||||
|
|
||||||
func process_mirrored_files(opts *Options, args []string) (ans []*File, err error) {
|
func process_mirrored_files(opts *Options, args []string) (ans []*File, err error) {
|
||||||
paths := utils.Map(func(x string) string { return abspath(expand_home(x)) }, args)
|
paths := utils.Map(func(x string) string { return abspath(expand_home(x)) }, args)
|
||||||
common_path := utils.Commonpath(paths...)
|
home := strings.TrimRight(home_path(), string(filepath.Separator)) + string(filepath.Separator)
|
||||||
home := strings.TrimRight(home_path(), string(filepath.Separator))
|
paths = utils.Map(func(path string) string {
|
||||||
if common_path != "" && strings.HasPrefix(common_path, home+string(filepath.Separator)) {
|
if strings.HasPrefix(path, home) {
|
||||||
paths = utils.Map(func(x string) string {
|
r, _ := filepath.Rel(home, path)
|
||||||
r, _ := filepath.Rel(home, x)
|
|
||||||
return filepath.Join("~", r)
|
return filepath.Join("~", r)
|
||||||
}, paths)
|
}
|
||||||
}
|
return path
|
||||||
|
}, paths)
|
||||||
counter := 0
|
counter := 0
|
||||||
return process(opts, paths, "", &counter)
|
return process(opts, paths, "", &counter)
|
||||||
}
|
}
|
||||||
@ -232,7 +232,7 @@ func files_for_send(opts *Options, args []string) (files []*File, err error) {
|
|||||||
// detect symlinks to other transferred files
|
// detect symlinks to other transferred files
|
||||||
for i, f := range files {
|
for i, f := range files {
|
||||||
if f.file_type == FileType_symlink {
|
if f.file_type == FileType_symlink {
|
||||||
link_dest, err := os.Readlink(f.local_path)
|
link_dest, err := os.Readlink(f.expanded_local_path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remove = append(remove, i)
|
remove = append(remove, i)
|
||||||
continue
|
continue
|
||||||
@ -241,7 +241,7 @@ func files_for_send(opts *Options, args []string) (files []*File, err error) {
|
|||||||
is_abs := filepath.IsAbs(link_dest)
|
is_abs := filepath.IsAbs(link_dest)
|
||||||
q := link_dest
|
q := link_dest
|
||||||
if !is_abs {
|
if !is_abs {
|
||||||
q = filepath.Join(filepath.Dir(f.local_path), link_dest)
|
q = filepath.Join(filepath.Dir(f.expanded_local_path), link_dest)
|
||||||
}
|
}
|
||||||
st, err := os.Stat(q)
|
st, err := os.Stat(q)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -447,9 +447,9 @@ class DestFile:
|
|||||||
def __init__(self, ftc: FileTransmissionCommand) -> None:
|
def __init__(self, ftc: FileTransmissionCommand) -> None:
|
||||||
self.name = ftc.name
|
self.name = ftc.name
|
||||||
if not os.path.isabs(self.name):
|
if not os.path.isabs(self.name):
|
||||||
self.name = os.path.expanduser(self.name)
|
self.name = expand_home(self.name)
|
||||||
if not os.path.isabs(self.name):
|
if not os.path.isabs(self.name):
|
||||||
self.name = os.path.join(tempfile.gettempdir(), self.name)
|
self.name = abspath(self.name, use_home=True)
|
||||||
try:
|
try:
|
||||||
self.existing_stat: Optional[os.stat_result] = os.stat(self.name, follow_symlinks=False)
|
self.existing_stat: Optional[os.stat_result] = os.stat(self.name, follow_symlinks=False)
|
||||||
except OSError:
|
except OSError:
|
||||||
|
@ -181,6 +181,7 @@ class TestFileTransmission(BaseTest):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.direction_receive = False
|
self.direction_receive = False
|
||||||
|
self.kitty_home = self.kitty_cwd = self.kitten_home = self.kitten_cwd = ''
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.tdir = os.path.realpath(tempfile.mkdtemp())
|
self.tdir = os.path.realpath(tempfile.mkdtemp())
|
||||||
self.responses = []
|
self.responses = []
|
||||||
@ -196,8 +197,12 @@ def tearDown(self):
|
|||||||
super().tearDown()
|
super().tearDown()
|
||||||
|
|
||||||
def clean_tdir(self):
|
def clean_tdir(self):
|
||||||
shutil.rmtree(self.tdir)
|
for x in os.listdir(self.tdir):
|
||||||
self.tdir = os.path.realpath(tempfile.mkdtemp())
|
x = os.path.join(self.tdir, x)
|
||||||
|
if os.path.isdir(x):
|
||||||
|
shutil.rmtree(x)
|
||||||
|
else:
|
||||||
|
os.remove(x)
|
||||||
self.responses = []
|
self.responses = []
|
||||||
|
|
||||||
def cr(self, a, b):
|
def cr(self, a, b):
|
||||||
@ -324,22 +329,18 @@ def test_rsync_hashers(self):
|
|||||||
self.assertEqual(h128.hexdigest(), '8d6b60383dfa90c21be79eecd1b1353d')
|
self.assertEqual(h128.hexdigest(), '8d6b60383dfa90c21be79eecd1b1353d')
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def run_kitten(self, cmd, home_dir='', allow=True):
|
def run_kitten(self, cmd, home_dir='', allow=True, cwd=''):
|
||||||
cwd = os.path.realpath(tempfile.mkdtemp(suffix='-cwd', dir=self.tdir))
|
cwd = cwd or self.kitten_cwd or self.tdir
|
||||||
cmd = [kitten_exe(), 'transfer'] + (['--direction=receive'] if self.direction_receive else []) + cmd
|
cmd = [kitten_exe(), 'transfer'] + (['--direction=receive'] if self.direction_receive else []) + cmd
|
||||||
env = {'PWD': cwd}
|
env = {'PWD': cwd}
|
||||||
if home_dir:
|
env['HOME'] = home_dir or self.kitten_home or self.tdir
|
||||||
env['HOME'] = home_dir
|
with set_paths(home=self.kitty_home, cwd=self.kitty_cwd):
|
||||||
try:
|
|
||||||
pty = TransferPTY(cmd, cwd=cwd, allow=allow, env=env)
|
pty = TransferPTY(cmd, cwd=cwd, allow=allow, env=env)
|
||||||
i = 10
|
i = 10
|
||||||
while i > 0 and not pty.screen_contents().strip():
|
while i > 0 and not pty.screen_contents().strip():
|
||||||
pty.process_input_from_child()
|
pty.process_input_from_child()
|
||||||
i -= 1
|
i -= 1
|
||||||
yield pty
|
yield pty
|
||||||
finally:
|
|
||||||
if os.path.exists(cwd):
|
|
||||||
shutil.rmtree(cwd)
|
|
||||||
|
|
||||||
def basic_transfer_tests(self):
|
def basic_transfer_tests(self):
|
||||||
src = os.path.join(self.tdir, 'src')
|
src = os.path.join(self.tdir, 'src')
|
||||||
@ -445,19 +446,62 @@ def de(path):
|
|||||||
multiple_files('--transmit-deltas')
|
multiple_files('--transmit-deltas')
|
||||||
multiple_files('--transmit-deltas')
|
multiple_files('--transmit-deltas')
|
||||||
|
|
||||||
|
def setup_dirs(self):
|
||||||
|
self.clean_tdir()
|
||||||
|
self.kitty_home = os.path.join(self.tdir, 'kitty-home')
|
||||||
|
self.kitty_cwd = os.path.join(self.tdir, 'kitty-cwd')
|
||||||
|
self.kitten_home = os.path.join(self.tdir, 'kitten-home')
|
||||||
|
self.kitten_cwd = os.path.join(self.tdir, 'kitten-cwd')
|
||||||
|
tuple(map(os.mkdir, (self.kitty_home, self.kitty_cwd, self.kitten_home, self.kitten_cwd)))
|
||||||
|
|
||||||
|
def create_src(self, base):
|
||||||
|
src = os.path.join(base, 'src')
|
||||||
|
with open(src, 'wb') as s:
|
||||||
|
s.write(self.src_data)
|
||||||
|
return src
|
||||||
|
|
||||||
|
def mirror_test(self, src, dest, prefix=''):
|
||||||
|
self.create_src(src)
|
||||||
|
os.symlink('/', os.path.join(src, 'sym'))
|
||||||
|
os.mkdir(os.path.join(src, 'sub'))
|
||||||
|
os.link(os.path.join(src, 'src'), os.path.join(src, 'sub', 'hardlink'))
|
||||||
|
with self.run_kitten(['--mode=mirror', f'{prefix}src', f'{prefix}sym', f'{prefix}sub']) as pty:
|
||||||
|
pty.wait_till_child_exits(require_exit_code=0)
|
||||||
|
os.remove(os.path.join(dest, 'src'))
|
||||||
|
os.remove(os.path.join(dest, 'sym'))
|
||||||
|
shutil.rmtree(os.path.join(dest, 'sub'))
|
||||||
|
|
||||||
def test_transfer_receive(self):
|
def test_transfer_receive(self):
|
||||||
self.direction_receive = True
|
self.direction_receive = True
|
||||||
self.basic_transfer_tests()
|
self.basic_transfer_tests()
|
||||||
src = os.path.join(self.tdir, 'src')
|
|
||||||
with open(src, 'wb') as s:
|
|
||||||
s.write(self.src_data)
|
|
||||||
# home dir expansion
|
|
||||||
fname = 'tstest-file'
|
|
||||||
home = os.path.dirname(src)
|
|
||||||
with set_paths(home=home), self.run_kitten(['~/'+os.path.basename(src), f'~/{fname}'], home_dir=home) as pty:
|
|
||||||
pty.wait_till_child_exits(require_exit_code=0)
|
|
||||||
os.remove(os.path.join(home, fname))
|
|
||||||
|
|
||||||
|
self.setup_dirs()
|
||||||
|
self.create_src(self.kitty_home)
|
||||||
|
|
||||||
|
# dir expansion with single transfer
|
||||||
|
with self.run_kitten(['~/src', '~/src']) as pty:
|
||||||
|
pty.wait_till_child_exits(require_exit_code=0)
|
||||||
|
os.remove(os.path.join(self.kitten_home, 'src'))
|
||||||
|
|
||||||
|
with self.run_kitten(['src', 'src']) as pty:
|
||||||
|
pty.wait_till_child_exits(require_exit_code=0)
|
||||||
|
os.remove(os.path.join(self.kitten_cwd, 'src'))
|
||||||
|
|
||||||
|
# dir expansion with multiple transfers
|
||||||
|
os.symlink('/', os.path.join(self.kitty_home, 'sym'))
|
||||||
|
with self.run_kitten(['~/src', '~/sym', '~']) as pty:
|
||||||
|
pty.wait_till_child_exits(require_exit_code=0)
|
||||||
|
os.remove(os.path.join(self.kitten_home, 'src'))
|
||||||
|
os.remove(os.path.join(self.kitten_home, 'sym'))
|
||||||
|
|
||||||
|
with self.run_kitten(['src', 'sym', '.']) as pty:
|
||||||
|
pty.wait_till_child_exits(require_exit_code=0)
|
||||||
|
os.remove(os.path.join(self.kitten_cwd, 'src'))
|
||||||
|
os.remove(os.path.join(self.kitten_cwd, 'sym'))
|
||||||
|
|
||||||
|
# mirroring
|
||||||
|
self.setup_dirs()
|
||||||
|
self.mirror_test(self.kitty_home, self.kitten_home)
|
||||||
|
|
||||||
def test_transfer_send(self):
|
def test_transfer_send(self):
|
||||||
self.basic_transfer_tests()
|
self.basic_transfer_tests()
|
||||||
@ -465,19 +509,32 @@ def test_transfer_send(self):
|
|||||||
with open(src, 'wb') as s:
|
with open(src, 'wb') as s:
|
||||||
s.write(self.src_data)
|
s.write(self.src_data)
|
||||||
|
|
||||||
# home dir expansion
|
self.setup_dirs()
|
||||||
fname = 'tstest-file'
|
self.create_src(self.kitten_home)
|
||||||
home = os.path.dirname(src)
|
|
||||||
with set_paths(home=home), self.run_kitten(['~/'+os.path.basename(src), '~/'+fname], home_dir=home) as pty:
|
|
||||||
pty.wait_till_child_exits(require_exit_code=0)
|
|
||||||
os.remove(os.path.expanduser('~/'+fname))
|
|
||||||
|
|
||||||
# mirror mode
|
# dir expansion with single transfer
|
||||||
src_home = os.path.join(self.tdir, 'misrc')
|
with self.run_kitten(['~/src', '~/src']) as pty:
|
||||||
os.mkdir(src_home)
|
|
||||||
open(os.path.join(src_home, fname), 'w').close()
|
|
||||||
with self.run_kitten(['--mode=mirror', '~/'+fname], home_dir=src_home) as pty:
|
|
||||||
pty.wait_till_child_exits(require_exit_code=0)
|
pty.wait_till_child_exits(require_exit_code=0)
|
||||||
with open(os.path.expanduser('~/'+fname)) as f:
|
os.remove(os.path.join(self.kitty_home, 'src'))
|
||||||
self.assertEqual('', f.read())
|
|
||||||
os.remove(f.name)
|
self.create_src(self.kitten_cwd)
|
||||||
|
with self.run_kitten(['src', 'src']) as pty:
|
||||||
|
pty.wait_till_child_exits(require_exit_code=0)
|
||||||
|
os.remove(os.path.join(self.kitty_home, 'src'))
|
||||||
|
|
||||||
|
# dir expansion with multiple transfers
|
||||||
|
os.symlink('/', os.path.join(self.kitten_home, 'sym'))
|
||||||
|
with self.run_kitten(['~/src', '~/sym', '~']) as pty:
|
||||||
|
pty.wait_till_child_exits(require_exit_code=0)
|
||||||
|
os.remove(os.path.join(self.kitty_home, 'src'))
|
||||||
|
os.remove(os.path.join(self.kitty_home, 'sym'))
|
||||||
|
|
||||||
|
os.symlink('/', os.path.join(self.kitten_cwd, 'sym'))
|
||||||
|
with self.run_kitten(['src', 'sym', '.']) as pty:
|
||||||
|
pty.wait_till_child_exits(require_exit_code=0)
|
||||||
|
os.remove(os.path.join(self.kitty_home, 'src'))
|
||||||
|
os.remove(os.path.join(self.kitty_home, 'sym'))
|
||||||
|
|
||||||
|
# mirroring
|
||||||
|
self.setup_dirs()
|
||||||
|
self.mirror_test(self.kitten_home, self.kitty_home, prefix='~/')
|
||||||
|
Loading…
Reference in New Issue
Block a user