Compare commits

...

4 Commits

Author SHA1 Message Date
Lee Miller 652aaccfd6
Move s and state into the base 2023-08-02 04:43:25 +03:00
Dmitri Bogomolov 0d221317b7
Inherit I2P classes from base util.I2PThread() 2023-08-02 04:43:25 +03:00
Lee Miller ebfe9ebf9f
Install and start i2pd in buildbot 2023-08-02 04:43:25 +03:00
Dmitri Bogomolov e417bc2752
Try to test with i2pd:
- TestProcessI2P runs minode with i2p args with _connection_limit = 4
 - TestProcess waits for connections _wait_time sec (120 for TestProcessI2P)
2023-08-02 04:42:51 +03:00
7 changed files with 61 additions and 48 deletions

View File

@ -2,8 +2,15 @@ FROM ubuntu:focal
RUN apt-get update RUN apt-get update
RUN apt-get install -yq software-properties-common
RUN apt-add-repository ppa:purplei2p/i2pd
RUN apt-get update
RUN apt-get install -yq --no-install-suggests --no-install-recommends \ RUN apt-get install -yq --no-install-suggests --no-install-recommends \
python3-dev python3-pip python3.9 python3.9-dev python3.9-venv python3-dev python3-pip python3.9 python3.9-dev python3.9-venv sudo i2pd
RUN echo 'builder ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
RUN python3.9 -m pip install setuptools wheel RUN python3.9 -m pip install setuptools wheel
RUN python3.9 -m pip install --upgrade pip tox virtualenv RUN python3.9 -m pip install --upgrade pip tox virtualenv

3
.buildbot/ubuntu/build.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
sudo service i2pd start

View File

@ -3,17 +3,15 @@ import base64
import logging import logging
import os import os
import socket import socket
import threading
import time import time
from .util import receive_line, pub_from_priv from .util import I2PThread, pub_from_priv
class I2PController(threading.Thread): class I2PController(I2PThread):
def __init__(self, state, host='127.0.0.1', port=7656, dest_priv=b''): def __init__(self, state, host='127.0.0.1', port=7656, dest_priv=b''):
super().__init__(name='I2P Controller') super().__init__(state, name='I2P Controller')
self.state = state
self.host = host self.host = host
self.port = port self.port = port
self.nick = b'MiNode_' + base64.b16encode(os.urandom(4)).lower() self.nick = b'MiNode_' + base64.b16encode(os.urandom(4)).lower()
@ -41,15 +39,6 @@ class I2PController(threading.Thread):
self.create_session() self.create_session()
def _receive_line(self):
line = receive_line(self.s)
# logging.debug('I2PController <- %s', line)
return line
def _send(self, command):
# logging.debug('I2PController -> %s', command)
self.s.sendall(command)
def init_connection(self): def init_connection(self):
self._send(b'HELLO VERSION MIN=3.0 MAX=3.3\n') self._send(b'HELLO VERSION MIN=3.0 MAX=3.3\n')
self.version_reply = self._receive_line().split() self.version_reply = self._receive_line().split()

View File

@ -1,23 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging import logging
import socket import socket
import threading
from .util import receive_line from .util import I2PThread
class I2PDialer(threading.Thread): class I2PDialer(I2PThread):
def __init__( def __init__(
self, state, destination, nick, sam_host='127.0.0.1', sam_port=7656 self, state, destination, nick, sam_host='127.0.0.1', sam_port=7656
): ):
self.state = state
self.sam_host = sam_host self.sam_host = sam_host
self.sam_port = sam_port self.sam_port = sam_port
self.nick = nick self.nick = nick
self.destination = destination self.destination = destination
super().__init__(name='I2P Dial to {}'.format(self.destination)) super().__init__(state, name='I2P Dial to {}'.format(self.destination))
self.s = socket.create_connection((self.sam_host, self.sam_port)) self.s = socket.create_connection((self.sam_host, self.sam_port))
@ -34,15 +33,6 @@ class I2PDialer(threading.Thread):
c.start() c.start()
self.state.connections.add(c) self.state.connections.add(c)
def _receive_line(self):
line = receive_line(self.s)
# logging.debug('I2PDialer <- %s', line)
return line
def _send(self, command):
# logging.debug('I2PDialer -> %s', command)
self.s.sendall(command)
def _connect(self): def _connect(self):
self._send(b'HELLO VERSION MIN=3.0 MAX=3.3\n') self._send(b'HELLO VERSION MIN=3.0 MAX=3.3\n')
self.version_reply = self._receive_line().split() self.version_reply = self._receive_line().split()

View File

@ -1,35 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging import logging
import socket import socket
import threading
from .util import receive_line from .util import I2PThread
class I2PListener(threading.Thread): class I2PListener(I2PThread):
def __init__(self, state, nick, host='127.0.0.1', port=7656): def __init__(self, state, nick, host='127.0.0.1', port=7656):
super().__init__(name='I2P Listener') super().__init__(state, name='I2P Listener')
self.state = state
self.host = host self.host = host
self.port = port self.port = port
self.nick = nick self.nick = nick
self.s = None
self.version_reply = [] self.version_reply = []
self.new_socket() self.new_socket()
def _receive_line(self):
line = receive_line(self.s)
# logging.debug('I2PListener <- %s', line)
return line
def _send(self, command):
# logging.debug('I2PListener -> %s', command)
self.s.sendall(command)
def new_socket(self): def new_socket(self):
self.s = socket.create_connection((self.host, self.port)) self.s = socket.create_connection((self.host, self.port))
self._send(b'HELLO VERSION MIN=3.0 MAX=3.3\n') self._send(b'HELLO VERSION MIN=3.0 MAX=3.3\n')

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import base64 import base64
import hashlib import hashlib
import threading
def receive_line(s): def receive_line(s):
@ -14,16 +15,35 @@ def receive_line(s):
return data[0] return data[0]
class I2PThread(threading.Thread):
"""
Abstract I2P thread with _receive_line() and _send() methods,
reused in I2PDialer, I2PListener and I2PController
"""
def __init__(self, state, name=''):
super().__init__(name=name)
self.state = state
self.s = None
def _receive_line(self):
line = receive_line(self.s)
# logging.debug('I2PListener <- %s', line)
return line
def _send(self, command):
# logging.debug('I2PListener -> %s', command)
self.s.sendall(command)
def pub_from_priv(priv): def pub_from_priv(priv):
priv = base64.b64decode(priv, altchars=b'-~') priv = base64.b64decode(priv, altchars=b'-~')
# 256 for public key + 128 for signing key + 3 for certificate header # 256 for public key + 128 for signing key + 3 for certificate header
# + value of bytes priv[385:387] # + value of bytes priv[385:387]
pub = priv[:387 + int.from_bytes(priv[385:387], byteorder='big')] pub = priv[:387 + int.from_bytes(priv[385:387], byteorder='big')]
pub = base64.b64encode(pub, altchars=b'-~') return base64.b64encode(pub, altchars=b'-~')
return pub
def b32_from_pub(pub): def b32_from_pub(pub):
return base64.b32encode( return base64.b32encode(
hashlib.sha256(base64.b64decode(pub, b'-~')).digest() hashlib.sha256(base64.b64decode(pub, b'-~')).digest()
).replace(b"=", b"").lower() + b'.b32.i2p' ).replace(b'=', b'').lower() + b'.b32.i2p'

View File

@ -1,6 +1,7 @@
"""Blind tests, starting the minode process""" """Blind tests, starting the minode process"""
import unittest import unittest
import signal import signal
import socket
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
@ -8,6 +9,12 @@ import time
import psutil import psutil
try:
socket.socket().bind(('127.0.0.1', 7656))
i2p_port_free = True
except (OSError, socket.error):
i2p_port_free = False
class TestProcessProto(unittest.TestCase): class TestProcessProto(unittest.TestCase):
"""Test process attributes, common flow""" """Test process attributes, common flow"""
@ -113,3 +120,13 @@ class TestProcess(TestProcessProto):
else: else:
if self._listen: if self._listen:
self.fail('No listening connection found') self.fail('No listening connection found')
@unittest.skipIf(i2p_port_free, 'No running i2pd detected')
class TestProcessI2P(TestProcess):
"""Test minode process with --i2p and no IP"""
_process_cmd = ['minode', '--i2p', '--no-ip']
_connection_limit = 4
_wait_time = 120
_listen = True
_listening_port = 8448