def test_ssh_copy(self): simple_data = 'rkjlhfwf9whoaa' def touch(p): with open(os.path.join(local_home, p), 'w') as f: f.write(simple_data) for sh in self.all_possible_sh: with self.subTest(sh=sh), tempfile.TemporaryDirectory( ) as remote_home, tempfile.TemporaryDirectory( ) as local_home, set_paths(home=local_home): tuple(map(touch, 'simple-file g.1 g.2'.split())) os.makedirs(f'{local_home}/d1/d2/d3') touch('d1/d2/x') touch('d1/d2/w.exclude') os.symlink('d2/x', f'{local_home}/d1/y') conf = '''\ copy simple-file copy --dest=a/sfa simple-file copy --glob g.* copy --exclude */w.* d1 ''' copy = load_config( overrides=filter(None, conf.splitlines())).copy self.check_bootstrap(sh, remote_home, test_script='env; exit 0', SHELL_INTEGRATION_VALUE='', ssh_opts={'copy': copy}) tname = '.terminfo' if os.path.exists('/usr/share/misc/terminfo.cdb'): tname += '.cdb' self.assertTrue(os.path.lexists(f'{remote_home}/{tname}/78')) self.assertTrue( os.path.exists(f'{remote_home}/{tname}/78/xterm-kitty')) self.assertTrue( os.path.exists(f'{remote_home}/{tname}/x/xterm-kitty')) for w in ('simple-file', 'a/sfa'): with open(os.path.join(remote_home, w), 'r') as f: self.ae(f.read(), simple_data) self.assertTrue(os.path.lexists(f'{remote_home}/d1/y')) self.assertTrue(os.path.exists(f'{remote_home}/d1/y')) self.ae(os.readlink(f'{remote_home}/d1/y'), 'd2/x') contents = set(files_in(remote_home)) contents.discard('.zshrc') # added by check_bootstrap() # depending on platform one of these is a symlink and hence # isnt in contents contents.discard(f'{tname}/x/xterm-kitty') contents.discard(f'{tname}/78/xterm-kitty') self.ae( contents, { 'g.1', 'g.2', f'{tname}/kitty.terminfo', 'simple-file', 'd1/d2/x', 'd1/y', 'a/sfa', '.local/share/kitty-ssh-kitten/kitty/version', '.local/share/kitty-ssh-kitten/kitty/bin/kitty' }) self.ae(len(glob.glob(f'{remote_home}/{tname}/*/xterm-kitty')), 2)
def tf(args, expected, different_home=''): if opts.mode == 'mirror': all_specs = args dest = '' else: all_specs = args[:-1] dest = args[-1] files, specs = gm(all_specs) orig_home = home_path() with set_paths(cwd_path(), different_home or orig_home): files = list( files_for_receive(opts, dest, files, orig_home, specs)) self.ae(len(files), len(expected)) am(files, expected)
def test_path_mapping_send(self): opts = parse_transfer_args([])[0] b = Path(os.path.join(self.tdir, 'b')) os.makedirs(b) open(b / 'r', 'w').close() os.mkdir(b / 'd') open(b / 'd' / 'r', 'w').close() def gm(*args): return files_for_send(opts, list(map(str, args))) def am(files, kw): m = {f.expanded_local_path: f.remote_path for f in files} kw = {str(k): str(v) for k, v in kw.items()} self.ae(m, kw) def tf(args, expected): files = gm(*args) self.ae(len(files), len(expected)) am(files, expected) opts.mode = 'mirror' with set_paths(cwd=b, home='/foo/bar'): tf(['r', 'd'], { b / 'r': b / 'r', b / 'd': b / 'd', b / 'd' / 'r': b / 'd' / 'r' }) tf(['r', 'd/r'], {b / 'r': b / 'r', b / 'd' / 'r': b / 'd' / 'r'}) with set_paths(cwd=b, home=self.tdir): tf(['r', 'd'], { b / 'r': '~/b/r', b / 'd': '~/b/d', b / 'd' / 'r': '~/b/d/r' }) opts.mode = 'normal' with set_paths(cwd='/some/else', home='/foo/bar'): tf([b / 'r', b / 'd', '/dest'], { b / 'r': '/dest/r', b / 'd': '/dest/d', b / 'd' / 'r': '/dest/d/r' }) tf( [b / 'r', b / 'd', '~/dest'], { b / 'r': '~/dest/r', b / 'd': '~/dest/d', b / 'd' / 'r': '~/dest/d/r' }) with set_paths(cwd=b, home='/foo/bar'): tf(['r', 'd', '/dest'], { b / 'r': '/dest/r', b / 'd': '/dest/d', b / 'd' / 'r': '/dest/d/r' }) os.symlink('/foo/b', b / 'e') os.symlink('r', b / 's') os.link(b / 'r', b / 'h') with set_paths(cwd='/some/else', home='/foo/bar'): files = gm(b / 'e', 'dest') self.ae(files[0].symbolic_link_target, 'path:/foo/b') files = gm(b / 's', b / 'r', 'dest') self.ae(files[0].symbolic_link_target, 'fid:2') files = gm(b / 'h', 'dest') self.ae(files[0].file_type, FileType.regular) files = gm(b / 'h', b / 'r', 'dest') self.ae(files[1].file_type, FileType.link) self.ae(files[1].hard_link_target, '1')
def test_path_mapping_receive(self): opts = parse_transfer_args([])[0] b = Path(os.path.join(self.tdir, 'b')) os.makedirs(b) open(b / 'r', 'w').close() os.mkdir(b / 'd') open(b / 'd' / 'r', 'w').close() def am(files, kw): m = {f.remote_path: f.expanded_local_path for f in files} kw = {str(k): expand_home(str(v)) for k, v in kw.items()} self.ae(kw, m) def gm(all_specs): specs = list((str(i), str(s)) for i, s in enumerate(all_specs)) files = [] for x in iter_file_metadata(specs): if isinstance(x, Exception): raise x files.append(File(x)) return files, specs def tf(args, expected, different_home=''): if opts.mode == 'mirror': all_specs = args dest = '' else: all_specs = args[:-1] dest = args[-1] files, specs = gm(all_specs) orig_home = home_path() with set_paths(cwd_path(), different_home or orig_home): files = list( files_for_receive(opts, dest, files, orig_home, specs)) self.ae(len(files), len(expected)) am(files, expected) opts.mode = 'mirror' with set_paths(cwd=b, home='/foo/bar'): tf([b / 'r', b / 'd'], { b / 'r': b / 'r', b / 'd': b / 'd', b / 'd' / 'r': b / 'd' / 'r' }) tf([b / 'r', b / 'd/r'], { b / 'r': b / 'r', b / 'd' / 'r': b / 'd' / 'r' }) with set_paths(cwd=b, home=self.tdir): tf([b / 'r', b / 'd'], { b / 'r': '~/b/r', b / 'd': '~/b/d', b / 'd' / 'r': '~/b/d/r' }, different_home='/foo/bar') opts.mode = 'normal' with set_paths(cwd='/some/else', home='/foo/bar'): tf([b / 'r', b / 'd', '/dest'], { b / 'r': '/dest/r', b / 'd': '/dest/d', b / 'd' / 'r': '/dest/d/r' }) tf( [b / 'r', b / 'd', '~/dest'], { b / 'r': '~/dest/r', b / 'd': '~/dest/d', b / 'd' / 'r': '~/dest/d/r' }) with set_paths(cwd=b, home='/foo/bar'): tf([b / 'r', b / 'd', '/dest'], { b / 'r': '/dest/r', b / 'd': '/dest/d', b / 'd' / 'r': '/dest/d/r' }) os.symlink('/foo/b', b / 'e') os.symlink('r', b / 's') os.link(b / 'r', b / 'h') with set_paths(cwd='/some/else', home='/foo/bar'): files = gm((b / 'e', b / 's', b / 'r', b / 'h'))[0] self.assertEqual(files[0].ftype, FileType.symlink) self.assertEqual(files[1].ftype, FileType.symlink) self.assertEqual(files[1].remote_target, files[2].remote_id) self.assertEqual(files[3].ftype, FileType.link) self.assertEqual(files[3].remote_target, files[2].remote_id)
def test_file_get(self): # send refusal for quiet in (0, 1, 2): ft = FileTransmission(allow=False) ft.handle_serialized_command( serialized_cmd(action='receive', id='x', quiet=quiet)) self.cr( ft.test_responses, [] if quiet == 2 else [response(id='x', status='EPERM:User refused the transfer')]) self.assertFalse(ft.active_sends) # reading metadata for specs cwd = os.path.join(self.tdir, 'cwd') home = os.path.join(self.tdir, 'home') os.mkdir(cwd), os.mkdir(home) with set_paths(cwd=cwd, home=home): ft = FileTransmission() self.responses = [] ft.handle_serialized_command( serialized_cmd(action='receive', size=1)) self.assertResponses(ft, status='OK') ft.handle_serialized_command( serialized_cmd(action='file', file_id='missing', name='XXX')) self.responses.append( response(status='ENOENT:Failed to read spec', file_id='missing')) self.assertResponses(ft, status='OK', name=home) ft = FileTransmission() self.responses = [] ft.handle_serialized_command( serialized_cmd(action='receive', size=2)) self.assertResponses(ft, status='OK') with open(os.path.join(home, 'a'), 'w') as f: f.write('a') os.mkdir(f.name + 'd') with open(os.path.join(f.name + 'd', 'b'), 'w') as f2: f2.write('bbb') os.symlink(f.name, f.name + 'd/s') os.link(f.name, f.name + 'd/h') os.symlink('XXX', f.name + 'd/q') ft.handle_serialized_command( serialized_cmd(action='file', file_id='a', name='a')) ft.handle_serialized_command( serialized_cmd(action='file', file_id='b', name='ad')) files = { r['name']: r for r in ft.test_responses if r['action'] == 'file' } self.ae(len(files), 6) q = files[f.name] tgt = q['status'].encode('ascii') self.ae(q['size'], 1), self.assertNotIn('ftype', q) q = files[f.name + 'd'] self.ae(q['ftype'], 'directory') q = files[f.name + 'd/b'] self.ae(q['size'], 3) q = files[f.name + 'd/s'] self.ae(q['ftype'], 'symlink') self.ae(q['data'], tgt) q = files[f.name + 'd/h'] self.ae(q['ftype'], 'link') self.ae(q['data'], tgt) q = files[f.name + 'd/q'] self.ae(q['ftype'], 'symlink') self.assertNotIn('data', q) base = os.path.join(self.tdir, 'base') os.mkdir(base) src = os.path.join(base, 'src.bin') data = os.urandom(16 * 1024) with open(src, 'wb') as f: f.write(data) sl = os.path.join(base, 'src.link') os.symlink(src, sl) for compress in ('none', 'zlib'): ft = FileTransmission() self.responses = [] ft.handle_serialized_command( serialized_cmd(action='receive', size=1)) self.assertResponses(ft, status='OK') ft.handle_serialized_command( serialized_cmd(action='file', file_id='src', name=src)) ft.active_sends['test'].metadata_sent = True ft.test_responses = [] ft.handle_serialized_command( serialized_cmd(action='file', file_id='src', name=src, compression=compress)) received = b''.join(x['data'] for x in ft.test_responses) if compress == 'zlib': received = ZlibDecompressor()(received, True) self.ae(data, received) ft.test_responses = [] ft.handle_serialized_command( serialized_cmd(action='file', file_id='sl', name=sl, compression=compress)) received = b''.join(x['data'] for x in ft.test_responses) self.ae(received.decode('utf-8'), src)