Skip to content

Commit 685c1ee

Browse files
author
Pan
committed
WIP - Added event implementation and tests.
1 parent 3762d19 commit 685c1ee

File tree

4 files changed

+214
-1
lines changed

4 files changed

+214
-1
lines changed

ssh/event.pxd

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# This file is part of ssh-python.
2+
# Copyright (C) 2018 Panos Kittenis
3+
#
4+
# This library is free software; you can redistribute it and/or
5+
# modify it under the terms of the GNU Lesser General Public
6+
# License as published by the Free Software Foundation, version 2.1.
7+
#
8+
# This library is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+
# Lesser General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU Lesser General Public
14+
# License along with this library; if not, write to the Free Software
15+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130
16+
17+
from session cimport Session
18+
from channel cimport Channel
19+
20+
cimport c_ssh
21+
22+
23+
cdef class Event:
24+
cdef c_ssh.ssh_event _event
25+
cdef object _sock
26+
cdef Session session
27+
cdef Channel channel
28+
29+
@staticmethod
30+
cdef Event from_ptr(c_ssh.ssh_event _event)
31+
32+
@staticmethod
33+
cdef int event_callback(c_ssh.socket_t fd, int revent, void *userdata)

ssh/event.pyx

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# This file is part of ssh-python.
2+
# Copyright (C) 2018 Panos Kittenis
3+
#
4+
# This library is free software; you can redistribute it and/or
5+
# modify it under the terms of the GNU Lesser General Public
6+
# License as published by the Free Software Foundation, version 2.1.
7+
#
8+
# This library is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+
# Lesser General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU Lesser General Public
14+
# License along with this library; if not, write to the Free Software
15+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130
16+
17+
from cpython cimport PyObject_AsFileDescriptor
18+
19+
from utils cimport handle_ssh_error_codes
20+
21+
from connector cimport Connector
22+
from session cimport Session
23+
24+
cimport c_ssh
25+
26+
27+
cdef class Event:
28+
29+
def __cinit__(self):
30+
self._event = c_ssh.ssh_event_new()
31+
if self._event is NULL:
32+
raise MemoryError
33+
34+
def __dealloc__(self):
35+
if self._event is not NULL:
36+
c_ssh.ssh_event_free(self._event)
37+
self._event = NULL
38+
39+
@property
40+
def session(self):
41+
return self.session
42+
43+
@property
44+
def channel(self):
45+
return self.channel
46+
47+
@staticmethod
48+
cdef Event from_ptr(c_ssh.ssh_event _event):
49+
cdef Event event = Event.__new__(Event)
50+
event._event = _event
51+
return event
52+
53+
@staticmethod
54+
cdef int event_callback(c_ssh.socket_t fd, int revent, void *userdata):
55+
try:
56+
func = <object>userdata
57+
return func()
58+
except Exception:
59+
return -1
60+
61+
def add_fd(self, socket, short events=0, callback=None):
62+
cdef c_ssh.socket_t _sock = PyObject_AsFileDescriptor(socket)
63+
cdef c_ssh.ssh_event_callback cb = <c_ssh.ssh_event_callback>&Event.event_callback
64+
cdef int rc
65+
cdef void *_cb = NULL if callback is None else <void *>callback
66+
cb = NULL if callback is None else cb
67+
rc = c_ssh.ssh_event_add_fd(
68+
self._event, _sock, events, cb, _cb)
69+
if rc == 0:
70+
self._sock = socket
71+
return rc
72+
73+
def remove_fd(self, socket):
74+
cdef c_ssh.socket_t _sock = PyObject_AsFileDescriptor(socket)
75+
cdef int rc
76+
with nogil:
77+
rc = c_ssh.ssh_event_remove_fd(self._event, _sock)
78+
if rc == 0:
79+
self._sock = None
80+
return rc
81+
82+
def add_session(self, Session session):
83+
cdef int rc
84+
with nogil:
85+
rc = c_ssh.ssh_event_add_session(self._event, session._session)
86+
handle_ssh_error_codes(rc, session._session)
87+
self.session = session
88+
return rc
89+
90+
def add_connector(self, Connector connector):
91+
cdef int rc
92+
with nogil:
93+
rc = c_ssh.ssh_event_add_connector(
94+
self._event, connector._connector)
95+
if rc == 0:
96+
self.connector = connector
97+
return rc
98+
99+
def dopoll(self, int timeout):
100+
cdef int rc
101+
with nogil:
102+
rc = c_ssh.ssh_event_dopoll(self._event, timeout)
103+
return rc
104+
105+
def remove_session(self, Session session):
106+
cdef int rc
107+
with nogil:
108+
rc = c_ssh.ssh_event_remove_session(self._event, session._session)
109+
handle_ssh_error_codes(rc, session._session)
110+
self.session = None
111+
return rc
112+
113+
def remove_connector(self, Connector connector):
114+
cdef int rc
115+
with nogil:
116+
rc = c_ssh.ssh_event_remove_connector(
117+
self._event, connector._connector)
118+
if rc == 0:
119+
self.connector = None
120+
return rc

tests/base_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def setUp(self):
6060
self.session.options_set_port(self.port)
6161
self.session.options_set(options.USER, self.user)
6262
self.pkey = import_privkey_file(self.user_key)
63-
# self.session.options_set(options.LOG_VERBOSITY, '1')
63+
self.session.options_set(options.LOG_VERBOSITY, '1')
6464

6565
def tearDown(self):
6666
del self.session

tests/test_event.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# This file is part of ssh-python.
2+
# Copyright (C) 2018 Panos Kittenis
3+
#
4+
# This library is free software; you can redistribute it and/or
5+
# modify it under the terms of the GNU Lesser General Public
6+
# License as published by the Free Software Foundation, version 2.1.
7+
#
8+
# This library is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+
# Lesser General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU Lesser General Public
14+
# License along with this library; if not, write to the Free Software
15+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130
16+
17+
import unittest
18+
import socket
19+
20+
from .base_test import SSHTestCase
21+
22+
from ssh.session import Session
23+
from ssh import options
24+
from ssh.event import Event
25+
from ssh.connector import CONNECTOR_STDOUT, CONNECTOR_STDERR, \
26+
CONNECTOR_BOTH
27+
28+
29+
class EventTest(SSHTestCase):
30+
31+
def test_event_session(self):
32+
self._auth()
33+
event = Event()
34+
self.assertIsInstance(event, Event)
35+
self.assertEqual(event.add_session(self.session), 0)
36+
self.assertEqual(self.session, event.session)
37+
self.assertEqual(event.remove_session(self.session), 0)
38+
self.assertIsNone(event.session)
39+
40+
def test_event_connector(self):
41+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
42+
sock.connect((self.host, self.port))
43+
session = Session()
44+
session.options_set(options.USER, self.user)
45+
session.options_set(options.HOST, self.host)
46+
session.options_set_port(self.port)
47+
self.assertEqual(session.set_socket(sock), 0)
48+
self.assertEqual(session.connect(), 0)
49+
self.assertEqual(
50+
session.userauth_publickey(self.pkey), 0)
51+
52+
event = Event()
53+
connector = session.connector_new()
54+
chan = session.channel_new()
55+
connector.set_in_channel(chan, CONNECTOR_STDOUT)
56+
connector.set_out_fd(sock)
57+
self.assertEqual(event.add_connector(connector), 0)
58+
# self.assertEqual(connector, event.connector)
59+
# self.assertEqual(event.remove_connector(connector), 0)
60+
# self.assertIsNone(event.connector)

0 commit comments

Comments
 (0)