summaryrefslogtreecommitdiff
path: root/test-paramiko
blob: 6256466aa423e138c37765321f517168710d7e54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# Copyright 2010  Lars Wirzenius
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


'''Test paramiko by doing an sftp copy from localhost.'''


import os
import paramiko
import pwd
import socket
import subprocess
import sys
import tempfile
import time


class SSHChannelAdapter(object):

    '''Take an ssh subprocess and pretend it is a paramiko Channel.'''

    def __init__(self, proc):
        self.proc = proc

    def send(self, data):
        return os.write(self.proc.stdin.fileno(), data)

    def recv(self, count):
        try:
            return os.read(self.proc.stdout.fileno(), count)
        except socket.error, e:
            if e.args[0] in (errno.EPIPE, errno.ECONNRESET, errno.ECONNABORTED,
                             errno.EBADF):
                # Connection has closed.  Paramiko expects an empty string in
                # this case, not an exception.
                return ''
            raise

    def get_name(self):
        return 'obnam SSHChannelAdapter'

    def close(self):
        for func in [proc.stdin.close, proc.stdout.close, proc.wait]:
            try:
                func()
            except OSError:
                pass


username = pwd.getpwuid(os.getuid()).pw_name
host = 'localhost'
port = 22
path = '/tmp/zeroes'

subsystem = 'sftp'
args = ['ssh',
        '-oForwardX11=no', '-oForwardAgent=no',
        '-oClearAllForwardings=yes', '-oProtocol=2']
if port is not None:
    args.extend(['-p', str(port)])
if username is not None:
    args.extend(['-l', username])
args.extend(['-s', host, subsystem])

try:
    proc = subprocess.Popen(args,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            close_fds=True)
except OSError:
    transport = paramiko.Transport((host, port))
    transport.connect()
    agent = paramiko.Agent()
    agent_keys = agent.get_keys()
    for key in agent_keys:
        try:
            transport.auth_publickey(username, key)
            break
        except paramiko.SSHException:
            pass
    else:
        raise Exception('no auth')
    sftp = paramiko.SFTPClient.from_transport(transport)
else:
    sftp = paramiko.SFTPClient(SSHChannelAdapter(proc))

n = 0
f = sftp.open(path)
start = time.time()
while True:
    data = f.read(32*1024)
    if not data:
        break
    n += len(data)
end = time.time()

duration = end - start
n = float(n)
print duration, n/1024/1024, 8 * n / duration / 1024 / 1024