From 71b5c87f752f039f4d67c86fe9e345125bf3b02f Mon Sep 17 00:00:00 2001
From: cis-kuldeep <kuldeep.k@cisinlabs.com>
Date: Fri, 28 May 2021 18:41:23 +0530
Subject: [PATCH 1/8] Enabled python3, fixed type errors due to string
 encode/decode

Ported api to python3

Ported 10 test cases for test_api to Python3

Fixed decode error & some import errors

fixed all bugs for python3

fixed code quality

Python 2/3 compatible base64 encoding

code quality fixes

pylint: disable=e1101

fixed type error in test_logger

code quality fixes

fixed pybitmessage binary

changes in binary

added new binary
---
 setup.py                  |   2 +-
 src/helper_random.py      |   1 -
 src/multiqueue.py         |   6 +-
 src/pybitmessage          |   6 +-
 src/pybitmessage3         |  15 ++
 src/tests/test_api.py     | 360 ++++++++++++++++++++++++++------------
 src/tests/test_logger.py  |  16 +-
 src/tests/test_process.py |   5 +-
 8 files changed, 281 insertions(+), 130 deletions(-)
 create mode 100644 src/pybitmessage3

diff --git a/setup.py b/setup.py
index 0de2eb8c..e33b1ae0 100644
--- a/setup.py
+++ b/setup.py
@@ -168,7 +168,7 @@ if __name__ == "__main__":
                 'pybitmessage = pybitmessage.bitmessagemain:main'
             ] if sys.platform[:3] == 'win' else []
         },
-        scripts=['src/pybitmessage'],
+        scripts=['src/pybitmessage3'],
         cmdclass={'install': InstallCmd},
         command_options={
             'build_sphinx': {
diff --git a/src/helper_random.py b/src/helper_random.py
index 9a29d5e2..54db5acf 100644
--- a/src/helper_random.py
+++ b/src/helper_random.py
@@ -2,7 +2,6 @@
 
 import os
 import random
-
 from pyelliptic.openssl import OpenSSL
 
 NoneType = type(None)
diff --git a/src/multiqueue.py b/src/multiqueue.py
index 886d693d..1b251cbc 100644
--- a/src/multiqueue.py
+++ b/src/multiqueue.py
@@ -3,6 +3,7 @@ A queue with multiple internal subqueues.
 Elements are added into a random subqueue, and retrieval rotates
 """
 
+import helper_random
 import sys
 if sys.version_info[0] == 3:
     import queue as Queue
@@ -11,11 +12,6 @@ else:
 
 from collections import deque
 
-if sys.version_info[0] == 3:
-    from . import helper_random
-else:
-    import helper_random
-
 
 class MultiQueue(Queue.Queue):
     """A base queue class"""
diff --git a/src/pybitmessage b/src/pybitmessage
index decebfff..5c674cc4 100644
--- a/src/pybitmessage
+++ b/src/pybitmessage
@@ -3,9 +3,13 @@
 import os
 import pkg_resources
 
+
 dist = pkg_resources.get_distribution('pybitmessage')
 script_file = os.path.join(dist.location, dist.key, 'bitmessagemain.py')
 new_globals = globals()
 new_globals.update(__file__=script_file)
 
-execfile(script_file, new_globals)
+try:
+    execfile(script_file, new_globals)
+except NameError:
+    exec(compile(open(script_file, "rb").read(), script_file, 'exec'), new_globals)
\ No newline at end of file
diff --git a/src/pybitmessage3 b/src/pybitmessage3
new file mode 100644
index 00000000..5c674cc4
--- /dev/null
+++ b/src/pybitmessage3
@@ -0,0 +1,15 @@
+#!/usr/bin/python2.7
+
+import os
+import pkg_resources
+
+
+dist = pkg_resources.get_distribution('pybitmessage')
+script_file = os.path.join(dist.location, dist.key, 'bitmessagemain.py')
+new_globals = globals()
+new_globals.update(__file__=script_file)
+
+try:
+    execfile(script_file, new_globals)
+except NameError:
+    exec(compile(open(script_file, "rb").read(), script_file, 'exec'), new_globals)
\ No newline at end of file
diff --git a/src/tests/test_api.py b/src/tests/test_api.py
index 1d8891a8..c96e46dc 100644
--- a/src/tests/test_api.py
+++ b/src/tests/test_api.py
@@ -1,3 +1,4 @@
+# pylint: disable=E1101
 """
 Tests using API.
 """
@@ -5,9 +6,7 @@ Tests using API.
 import base64
 import json
 import time
-from .common import skip_python3
-
-skip_python3()
+import sys
 
 try:  # nosec
     from xmlrpclib import ServerProxy, ProtocolError
@@ -16,6 +15,8 @@ except ImportError:
 
 from .test_process import TestProcessProto, TestProcessShutdown
 
+PY3 = sys.version_info[0] >= 3
+
 
 class TestAPIProto(TestProcessProto):
     """Test case logic for testing API"""
@@ -63,12 +64,18 @@ class TestAPIShutdown(TestAPIProto, TestProcessShutdown):
 
 class TestAPI(TestAPIProto):
     """Main API test case"""
-    _seed = base64.encodestring(
-        'TIGER, tiger, burning bright. In the forests of the night'
-    )
+    if PY3:
+        _seed = base64.encodebytes(
+            b'TIGER, tiger, burning bright. In the forests of the night')
+    else:
+        _seed = base64.encodestring(
+            'TIGER, tiger, burning bright. In the forests of the night')
 
     def _add_random_address(self, label):
-        return self.api.createRandomAddress(base64.encodestring(label))
+        if PY3:
+            return self.api.createRandomAddress(base64.encodebytes(bytes(label, 'UTF-8')).decode('utf-8'))
+        else:
+            return self.api.createRandomAddress(base64.encodestring(label))
 
     def test_user_password(self):
         """Trying to connect with wrong username/password"""
@@ -119,108 +126,202 @@ class TestAPI(TestAPIProto):
 
     def test_create_deterministic_addresses(self):
         """Test creation of deterministic addresses"""
-        self.assertEqual(
-            self.api.getDeterministicAddress(self._seed, 4, 1),
-            'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
-        self.assertEqual(
-            self.api.getDeterministicAddress(self._seed, 3, 1),
-            'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN')
-        self.assertRegexpMatches(
-            self.api.getDeterministicAddress(self._seed, 2, 1),
-            r'^API Error 0002:')
+        if PY3:
+            self.assertEqual(
+                self.api.getDeterministicAddress(self._seed.decode('utf-8'), 4, 1),
+                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
+            self.assertEqual(
+                self.api.getDeterministicAddress(self._seed.decode('utf-8'), 3, 1),
+                'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN')
+            self.assertRegex(
+                self.api.getDeterministicAddress(self._seed.decode('utf-8'), 2, 1),
+                r'^API Error 0002:')
 
-        # This is here until the streams will be implemented
-        self.assertRegexpMatches(
-            self.api.getDeterministicAddress(self._seed, 3, 2),
-            r'API Error 0003:')
-        self.assertRegexpMatches(
-            self.api.createDeterministicAddresses(self._seed, 1, 4, 2),
-            r'API Error 0003:')
+            # This is here until the streams will be implemented
+            self.assertRegex(
+                self.api.getDeterministicAddress(self._seed.decode('utf-8'), 3, 2),
+                r'API Error 0003:')
+            self.assertRegex(
+                self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 1, 4, 2),
+                r'API Error 0003:')
 
-        self.assertRegexpMatches(
-            self.api.createDeterministicAddresses('', 1),
-            r'API Error 0001:')
-        self.assertRegexpMatches(
-            self.api.createDeterministicAddresses(self._seed, 1, 2),
-            r'API Error 0002:')
-        self.assertRegexpMatches(
-            self.api.createDeterministicAddresses(self._seed, 0),
-            r'API Error 0004:')
-        self.assertRegexpMatches(
-            self.api.createDeterministicAddresses(self._seed, 1000),
-            r'API Error 0005:')
+            self.assertRegex(
+                self.api.createDeterministicAddresses('', 1),
+                r'API Error 0001:')
+            self.assertRegex(
+                self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 1, 2),
+                r'API Error 0002:')
+            self.assertRegex(
+                self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 0),
+                r'API Error 0004:')
+            self.assertRegex(
+                self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 1000),
+                r'API Error 0005:')
 
-        addresses = json.loads(
-            self.api.createDeterministicAddresses(self._seed, 2, 4)
-        )['addresses']
-        self.assertEqual(len(addresses), 2)
-        self.assertEqual(addresses[0], 'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
-        for addr in addresses:
-            self.assertEqual(self.api.deleteAddress(addr), 'success')
+            addresses = json.loads(
+                self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 2, 4)
+            )['addresses']
+            self.assertEqual(len(addresses), 2)
+            self.assertEqual(addresses[0], 'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
+            for addr in addresses:
+                self.assertEqual(self.api.deleteAddress(addr), 'success')
+        else:
+            self.assertEqual(
+                self.api.getDeterministicAddress(self._seed, 4, 1),
+                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
+            self.assertEqual(
+                self.api.getDeterministicAddress(self._seed, 3, 1),
+                'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN')
+            self.assertRegexpMatches(
+                self.api.getDeterministicAddress(self._seed, 2, 1),
+                r'^API Error 0002:')
+
+            # This is here until the streams will be implemented
+            self.assertRegexpMatches(
+                self.api.getDeterministicAddress(self._seed, 3, 2),
+                r'API Error 0003:')
+            self.assertRegexpMatches(
+                self.api.createDeterministicAddresses(self._seed, 1, 4, 2),
+                r'API Error 0003:')
+
+            self.assertRegexpMatches(
+                self.api.createDeterministicAddresses('', 1),
+                r'API Error 0001:')
+            self.assertRegexpMatches(
+                self.api.createDeterministicAddresses(self._seed, 1, 2),
+                r'API Error 0002:')
+            self.assertRegexpMatches(
+                self.api.createDeterministicAddresses(self._seed, 0),
+                r'API Error 0004:')
+            self.assertRegexpMatches(
+                self.api.createDeterministicAddresses(self._seed, 1000),
+                r'API Error 0005:')
+
+            addresses = json.loads(
+                self.api.createDeterministicAddresses(self._seed, 2, 4)
+            )['addresses']
+            self.assertEqual(len(addresses), 2)
+            self.assertEqual(addresses[0], 'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
+            for addr in addresses:
+                self.assertEqual(self.api.deleteAddress(addr), 'success')
 
     def test_create_random_address(self):
         """API command 'createRandomAddress': basic BM-address validation"""
         addr = self._add_random_address('random_1')
-        self.assertRegexpMatches(addr, r'^BM-')
-        self.assertRegexpMatches(addr[3:], r'[a-zA-Z1-9]+$')
+        if PY3:
+            self.assertRegex(addr, r'^BM-')
+            self.assertRegex(addr[3:], r'[a-zA-Z1-9]+$')
+        else:
+            self.assertRegexpMatches(addr, r'^BM-')
+            self.assertRegexpMatches(addr[3:], r'[a-zA-Z1-9]+$')
         # Whitepaper says "around 36 character"
         self.assertLessEqual(len(addr[3:]), 40)
         self.assertEqual(self.api.deleteAddress(addr), 'success')
 
     def test_addressbook(self):
         """Testing API commands for addressbook manipulations"""
-        # Initially it's empty
-        self.assertEqual(
-            json.loads(self.api.listAddressBookEntries()).get('addresses'),
-            []
-        )
-        # Add known address
-        self.api.addAddressBookEntry(
-            'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK',
-            base64.encodestring('tiger_4')
-        )
-        # Check addressbook entry
-        entries = json.loads(
-            self.api.listAddressBookEntries()).get('addresses')[0]
-        self.assertEqual(
-            entries['address'], 'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
-        self.assertEqual(
-            base64.decodestring(entries['label']), 'tiger_4')
-        # Remove known address
-        self.api.deleteAddressBookEntry(
-            'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
-        # Addressbook should be empty again
-        self.assertEqual(
-            json.loads(self.api.listAddressBookEntries()).get('addresses'),
-            []
-        )
+        if PY3:
+            # Initially it's empty
+            self.assertEqual(
+                json.loads(self.api.listAddressBookEntries()).get('addresses'),
+                []
+            )
+            # Add known address
+            self.api.addAddressBookEntry(
+                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK',
+                base64.encodebytes('tiger_4'.encode('UTF-8')).decode('utf-8')
+            )
+            # Check addressbook entry
+            entries = json.loads(
+                self.api.listAddressBookEntries()).get('addresses')[0]
+            self.assertEqual(
+                entries['address'], 'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
+            self.assertEqual(
+                base64.decodebytes(bytes(entries['label'], 'utf-8')).decode('utf-8'), 'tiger_4')
+            # Remove known address
+            self.api.deleteAddressBookEntry(
+                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
+            # Addressbook should be empty again
+            self.assertEqual(
+                json.loads(self.api.listAddressBookEntries()).get('addresses'),
+                []
+            )
+        else:
+            # Initially it's empty
+            self.assertEqual(
+                json.loads(self.api.listAddressBookEntries()).get('addresses'),
+                []
+            )
+            # Add known address
+            self.api.addAddressBookEntry(
+                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK',
+                base64.encodestring('tiger_4')
+            )
+            # Check addressbook entry
+            entries = json.loads(
+                self.api.listAddressBookEntries()).get('addresses')[0]
+            self.assertEqual(
+                entries['address'], 'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
+            self.assertEqual(
+                base64.decodestring(entries['label']), 'tiger_4')
+            # Remove known address
+            self.api.deleteAddressBookEntry(
+                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
+            # Addressbook should be empty again
+            self.assertEqual(
+                json.loads(self.api.listAddressBookEntries()).get('addresses'),
+                []
+            )
 
     def test_subscriptions(self):
         """Testing the API commands related to subscriptions"""
-        for s in json.loads(self.api.listSubscriptions())['subscriptions']:
-            # special address, added when sqlThread starts
-            if s['address'] == 'BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw':
-                self.assertEqual(
-                    base64.decodestring(s['label']),
-                    'Bitmessage new releases/announcements')
-                self.assertTrue(s['enabled'])
-                break
+        if PY3:
+            for s in json.loads(self.api.listSubscriptions())['subscriptions']:
+                # special address, added when sqlThread starts
+                if s['address'] == 'BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw':
+                    self.assertEqual(
+                        base64.decodebytes(bytes(s['label'], 'utf-8')).decode('utf-8'),
+                        'Bitmessage new releases/announcements')
+                    self.assertTrue(s['enabled'])
+                    break
+            else:
+                self.fail(
+                    'Could not find Bitmessage new releases/announcements'
+                    ' in subscriptions')
+            self.assertEqual(
+                self.api.deleteSubscription('BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw'),
+                'Deleted subscription if it existed.')
+            self.assertEqual(
+                json.loads(self.api.listSubscriptions())['subscriptions'], [])
         else:
-            self.fail(
-                'Could not find Bitmessage new releases/announcements'
-                ' in subscriptions')
-        self.assertEqual(
-            self.api.deleteSubscription('BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw'),
-            'Deleted subscription if it existed.')
-        self.assertEqual(
-            json.loads(self.api.listSubscriptions())['subscriptions'], [])
+            for s in json.loads(self.api.listSubscriptions())['subscriptions']:
+                # special address, added when sqlThread starts
+                if s['address'] == 'BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw':
+                    self.assertEqual(
+                        base64.decodestring(s['label']),
+                        'Bitmessage new releases/announcements')
+                    self.assertTrue(s['enabled'])
+                    break
+            else:
+                self.fail(
+                    'Could not find Bitmessage new releases/announcements'
+                    ' in subscriptions')
+            self.assertEqual(
+                self.api.deleteSubscription('BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw'),
+                'Deleted subscription if it existed.')
+            self.assertEqual(
+                json.loads(self.api.listSubscriptions())['subscriptions'], [])
 
     def test_send(self):
         """Test message sending"""
-        # self.api.createDeterministicAddresses(self._seed, 1, 4)
-        addr = self._add_random_address('random_2')
-        msg = base64.encodestring('test message')
-        msg_subject = base64.encodestring('test_subject')
+        if PY3:
+            addr = str(self._add_random_address('random_2'))
+            msg = str(base64.encodebytes('test message'.encode('UTF-8')).decode('utf-8'))
+            msg_subject = str(base64.encodebytes('test_subject'.encode('UTF-8')).decode('utf-8'))
+        else:
+            addr = self._add_random_address('random_2')
+            msg = base64.encodestring('test message')
+            msg_subject = base64.encodestring('test_subject')
         ackdata = self.api.sendMessage(
             'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK', addr, msg_subject, msg)
         try:
@@ -277,10 +378,16 @@ class TestAPI(TestAPIProto):
 
     def test_send_broadcast(self):
         """Test broadcast sending"""
-        addr = self._add_random_address('random_2')
-        msg = base64.encodestring('test broadcast')
-        ackdata = self.api.sendBroadcast(
-            addr, base64.encodestring('test_subject'), msg)
+        if PY3:
+            addr = self._add_random_address('random_2')
+            msg = base64.encodebytes('test broadcast'.encode('UTF-8')).decode('utf-8')
+            ackdata = self.api.sendBroadcast(
+                addr, base64.encodebytes('test_subject'.encode('UTF-8')).decode('utf-8'), msg)
+        else:
+            addr = self._add_random_address('random_2')
+            msg = base64.encodestring('test broadcast')
+            ackdata = self.api.sendBroadcast(
+                addr, base64.encodestring('test_subject'), msg)
         try:
             int(ackdata, 16)
             status = self.api.getStatus(ackdata)
@@ -324,25 +431,48 @@ class TestAPI(TestAPIProto):
 
     def test_chan(self):
         """Testing chan creation/joining"""
-        # Create chan with known address
-        self.assertEqual(
-            self.api.createChan(self._seed),
-            'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'
-        )
-        # cleanup
-        self.assertEqual(
-            self.api.leaveChan('BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'),
-            'success'
-        )
-        # Join chan with addresses of version 3 or 4
-        for addr in (
-            'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK',
-            'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN'
-        ):
-            self.assertEqual(self.api.joinChan(self._seed, addr), 'success')
-            self.assertEqual(self.api.leaveChan(addr), 'success')
-        # Joining with wrong address should fail
-        self.assertRegexpMatches(
-            self.api.joinChan(self._seed, 'BM-2cWzSnwjJ7yRP3nLEW'),
-            r'^API Error 0008:'
-        )
+        if PY3:
+            # Create chan with known address
+            self.assertEqual(
+                self.api.createChan(self._seed.decode("utf-8")),
+                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'
+            )
+            # cleanup
+            self.assertEqual(
+                self.api.leaveChan('BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'),
+                'success'
+            )
+            # Join chan with addresses of version 3 or 4
+            for addr in (
+                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK',
+                'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN'
+            ):
+                self.assertEqual(self.api.joinChan(self._seed.decode("utf-8"), addr), 'success')
+                self.assertEqual(self.api.leaveChan(addr), 'success')
+            # Joining with wrong address should fail
+            self.assertRegex(
+                self.api.joinChan(self._seed.decode("utf-8"), 'BM-2cWzSnwjJ7yRP3nLEW'),
+                r'^API Error 0008:'
+            )
+        else:
+            self.assertEqual(
+                self.api.createChan(self._seed),
+                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'
+            )
+            # cleanup
+            self.assertEqual(
+                self.api.leaveChan('BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'),
+                'success'
+            )
+            # Join chan with addresses of version 3 or 4
+            for addr in (
+                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK',
+                'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN'
+            ):
+                self.assertEqual(self.api.joinChan(self._seed, addr), 'success')
+                self.assertEqual(self.api.leaveChan(addr), 'success')
+            # Joining with wrong address should fail
+            self.assertRegexpMatches(
+                self.api.joinChan(self._seed, 'BM-2cWzSnwjJ7yRP3nLEW'),
+                r'^API Error 0008:'
+            )
diff --git a/src/tests/test_logger.py b/src/tests/test_logger.py
index da0f9341..c9095f2a 100644
--- a/src/tests/test_logger.py
+++ b/src/tests/test_logger.py
@@ -1,11 +1,14 @@
+# pylint: disable=E1101
 """
 Testing the logger configuration
 """
 
 import os
 import tempfile
+import sys
 
 from .test_process import TestProcessProto
+PY3 = sys.version_info[0] >= 3
 
 
 class TestLogger(TestProcessProto):
@@ -43,7 +46,10 @@ handlers=default
         cls.log_file = os.path.join(cls.home, 'debug.log')
 
         with open(os.path.join(cls.home, 'logging.dat'), 'wb') as dst:
-            dst.write(cls.conf_template.format(cls.log_file, cls.pattern))
+            if PY3:
+                dst.write(bytes(cls.conf_template.format(cls.log_file, cls.pattern), 'utf-8'))
+            else:
+                dst.write(cls.conf_template.format(cls.log_file, cls.pattern))
 
         super(TestLogger, cls).setUpClass()
 
@@ -52,5 +58,9 @@ handlers=default
 
         self._stop_process()
         data = open(self.log_file).read()
-        self.assertRegexpMatches(data, self.pattern)
-        self.assertRegexpMatches(data, 'Loaded logger configuration')
+        if PY3:
+            self.assertRegex(data, self.pattern)
+            self.assertRegex(data, 'Loaded logger configuration')
+        else:
+            self.assertRegexpMatches(data, self.pattern)
+            self.assertRegexpMatches(data, 'Loaded logger configuration')
diff --git a/src/tests/test_process.py b/src/tests/test_process.py
index d976aa18..76be96a0 100644
--- a/src/tests/test_process.py
+++ b/src/tests/test_process.py
@@ -12,10 +12,7 @@ import unittest
 
 import psutil
 
-from .common import cleanup, put_signal_file, skip_python3
-
-
-skip_python3()
+from .common import cleanup, put_signal_file
 
 
 class TestProcessProto(unittest.TestCase):
-- 
2.45.1


From 9bf5c84c418f211982b43e44563b6915b6c3b830 Mon Sep 17 00:00:00 2001
From: cis-kuldeep <kuldeep.k@cisinlabs.com>
Date: Fri, 9 Jul 2021 15:49:11 +0530
Subject: [PATCH 2/8] fixed unclosed file error

---
 src/tests/test_process.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/tests/test_process.py b/src/tests/test_process.py
index 76be96a0..7a7549ef 100644
--- a/src/tests/test_process.py
+++ b/src/tests/test_process.py
@@ -84,7 +84,8 @@ class TestProcessProto(unittest.TestCase):
     def _get_readline(cls, pfile):
         pfile = os.path.join(cls.home, pfile)
         try:
-            return open(pfile, 'rb').readline().strip()
+            with open(pfile, 'rb') as p:
+                return p.readline().strip()
         except (OSError, IOError):
             pass
 
-- 
2.45.1


From 956408ff50f492b550832abda1a8687efa358498 Mon Sep 17 00:00:00 2001
From: cis-kuldeep <kuldeep.k@cisinlabs.com>
Date: Fri, 9 Jul 2021 16:01:20 +0530
Subject: [PATCH 3/8] reverted pybitmessage binary

---
 setup.py          |  2 +-
 src/pybitmessage3 | 15 ---------------
 2 files changed, 1 insertion(+), 16 deletions(-)
 delete mode 100644 src/pybitmessage3

diff --git a/setup.py b/setup.py
index e33b1ae0..0de2eb8c 100644
--- a/setup.py
+++ b/setup.py
@@ -168,7 +168,7 @@ if __name__ == "__main__":
                 'pybitmessage = pybitmessage.bitmessagemain:main'
             ] if sys.platform[:3] == 'win' else []
         },
-        scripts=['src/pybitmessage3'],
+        scripts=['src/pybitmessage'],
         cmdclass={'install': InstallCmd},
         command_options={
             'build_sphinx': {
diff --git a/src/pybitmessage3 b/src/pybitmessage3
deleted file mode 100644
index 5c674cc4..00000000
--- a/src/pybitmessage3
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/python2.7
-
-import os
-import pkg_resources
-
-
-dist = pkg_resources.get_distribution('pybitmessage')
-script_file = os.path.join(dist.location, dist.key, 'bitmessagemain.py')
-new_globals = globals()
-new_globals.update(__file__=script_file)
-
-try:
-    execfile(script_file, new_globals)
-except NameError:
-    exec(compile(open(script_file, "rb").read(), script_file, 'exec'), new_globals)
\ No newline at end of file
-- 
2.45.1


From 669f5c6c8508ec8678d4a2883a10f8eb213bcf7e Mon Sep 17 00:00:00 2001
From: cis-kuldeep <kuldeep.k@cisinlabs.com>
Date: Mon, 12 Jul 2021 17:31:13 +0530
Subject: [PATCH 4/8] fixes in test_process

---
 src/tests/test_process.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/tests/test_process.py b/src/tests/test_process.py
index 7a7549ef..efe4adcb 100644
--- a/src/tests/test_process.py
+++ b/src/tests/test_process.py
@@ -153,7 +153,7 @@ class TestProcessProto(unittest.TestCase):
             missing_threads = []
             for thread_name in thread_names:
                 if thread_name not in self._threads_names:
-                    extra_threads.append(thread_name)
+                    extra_threads.append(thread_name.decode('utf-8'))
             for thread_name in self._threads_names:
                 if thread_name not in thread_names:
                     missing_threads.append(thread_name)
@@ -191,7 +191,7 @@ class TestProcess(TestProcessProto):
     """A test case for pybitmessage process"""
     def test_process_name(self):
         """Check PyBitmessage process name"""
-        self.assertEqual(self.process.name(), 'PyBitmessage')
+        self.assertEqual(self.process.name(), 'pybitmessage')
 
     @unittest.skipIf(psutil.version_info < (4, 0), 'psutil is too old')
     def test_home(self):
-- 
2.45.1


From d24281901d0571bca09cde2b72ac8f9305ca2a50 Mon Sep 17 00:00:00 2001
From: cis-kuldeep <kuldeep.k@cisinlabs.com>
Date: Mon, 12 Jul 2021 17:58:32 +0530
Subject: [PATCH 5/8] fixes for py2

---
 src/tests/test_process.py | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/tests/test_process.py b/src/tests/test_process.py
index efe4adcb..8e064d00 100644
--- a/src/tests/test_process.py
+++ b/src/tests/test_process.py
@@ -9,11 +9,11 @@ import sys
 import tempfile
 import time
 import unittest
-
 import psutil
 
 from .common import cleanup, put_signal_file
 
+PY3 = sys.version_info[0] >= 3
 
 class TestProcessProto(unittest.TestCase):
     """Test case implementing common logic for external testing:
@@ -191,7 +191,10 @@ class TestProcess(TestProcessProto):
     """A test case for pybitmessage process"""
     def test_process_name(self):
         """Check PyBitmessage process name"""
-        self.assertEqual(self.process.name(), 'pybitmessage')
+        if PY3:
+            self.assertEqual(self.process.name(), 'pybitmessage')
+        else:
+            self.assertEqual(self.process.name(), 'PyBitmessage')
 
     @unittest.skipIf(psutil.version_info < (4, 0), 'psutil is too old')
     def test_home(self):
-- 
2.45.1


From 2e8da0e765ee17a045dd8729ad5c276c985bca5e Mon Sep 17 00:00:00 2001
From: cis-kuldeep <kuldeep.k@cisinlabs.com>
Date: Mon, 12 Jul 2021 18:01:22 +0530
Subject: [PATCH 6/8] code quality fixes

---
 src/tests/test_process.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/tests/test_process.py b/src/tests/test_process.py
index 8e064d00..72e532fd 100644
--- a/src/tests/test_process.py
+++ b/src/tests/test_process.py
@@ -15,6 +15,7 @@ from .common import cleanup, put_signal_file
 
 PY3 = sys.version_info[0] >= 3
 
+
 class TestProcessProto(unittest.TestCase):
     """Test case implementing common logic for external testing:
     it starts pybitmessage in setUpClass() and stops it in tearDownClass()
-- 
2.45.1


From b47827fb5493b96b116224d92d4f6939635737ad Mon Sep 17 00:00:00 2001
From: cis-kuldeep <kuldeep.k@cisinlabs.com>
Date: Mon, 12 Jul 2021 19:29:08 +0530
Subject: [PATCH 7/8] reverted some changes

---
 src/tests/test_process.py | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/src/tests/test_process.py b/src/tests/test_process.py
index 72e532fd..fe234247 100644
--- a/src/tests/test_process.py
+++ b/src/tests/test_process.py
@@ -13,8 +13,6 @@ import psutil
 
 from .common import cleanup, put_signal_file
 
-PY3 = sys.version_info[0] >= 3
-
 
 class TestProcessProto(unittest.TestCase):
     """Test case implementing common logic for external testing:
@@ -192,10 +190,7 @@ class TestProcess(TestProcessProto):
     """A test case for pybitmessage process"""
     def test_process_name(self):
         """Check PyBitmessage process name"""
-        if PY3:
-            self.assertEqual(self.process.name(), 'pybitmessage')
-        else:
-            self.assertEqual(self.process.name(), 'PyBitmessage')
+        self.assertEqual(self.process.name(), 'PyBitmessage')
 
     @unittest.skipIf(psutil.version_info < (4, 0), 'psutil is too old')
     def test_home(self):
-- 
2.45.1


From 7da2369b939e41954b9bc47bc776dd6af4ab9023 Mon Sep 17 00:00:00 2001
From: cis-kuldeep <kuldeep.k@cisinlabs.com>
Date: Tue, 13 Jul 2021 17:14:07 +0530
Subject: [PATCH 8/8] added six.assertRegex() & few more changes

---
 src/tests/test_api.py     | 186 ++++++++++++--------------------------
 src/tests/test_process.py |   2 +-
 2 files changed, 61 insertions(+), 127 deletions(-)

diff --git a/src/tests/test_api.py b/src/tests/test_api.py
index c96e46dc..585e952e 100644
--- a/src/tests/test_api.py
+++ b/src/tests/test_api.py
@@ -7,6 +7,7 @@ import base64
 import json
 import time
 import sys
+import six
 
 try:  # nosec
     from xmlrpclib import ServerProxy, ProtocolError
@@ -126,94 +127,50 @@ class TestAPI(TestAPIProto):
 
     def test_create_deterministic_addresses(self):
         """Test creation of deterministic addresses"""
-        if PY3:
-            self.assertEqual(
-                self.api.getDeterministicAddress(self._seed.decode('utf-8'), 4, 1),
-                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
-            self.assertEqual(
-                self.api.getDeterministicAddress(self._seed.decode('utf-8'), 3, 1),
-                'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN')
-            self.assertRegex(
-                self.api.getDeterministicAddress(self._seed.decode('utf-8'), 2, 1),
-                r'^API Error 0002:')
+        self.assertEqual(
+            self.api.getDeterministicAddress(self._seed.decode('utf-8'), 4, 1),
+            'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
+        self.assertEqual(
+            self.api.getDeterministicAddress(self._seed.decode('utf-8'), 3, 1),
+            'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN')
+        six.assertRegex(
+            self, self.api.getDeterministicAddress(self._seed.decode('utf-8'), 2, 1),
+            r'^API Error 0002:')
 
-            # This is here until the streams will be implemented
-            self.assertRegex(
-                self.api.getDeterministicAddress(self._seed.decode('utf-8'), 3, 2),
-                r'API Error 0003:')
-            self.assertRegex(
-                self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 1, 4, 2),
-                r'API Error 0003:')
+        # This is here until the streams will be implemented
+        six.assertRegex(
+            self, self.api.getDeterministicAddress(self._seed.decode('utf-8'), 3, 2),
+            r'API Error 0003:')
+        six.assertRegex(
+            self, self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 1, 4, 2),
+            r'API Error 0003:')
 
-            self.assertRegex(
-                self.api.createDeterministicAddresses('', 1),
-                r'API Error 0001:')
-            self.assertRegex(
-                self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 1, 2),
-                r'API Error 0002:')
-            self.assertRegex(
-                self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 0),
-                r'API Error 0004:')
-            self.assertRegex(
-                self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 1000),
-                r'API Error 0005:')
+        six.assertRegex(
+            self, self.api.createDeterministicAddresses('', 1),
+            r'API Error 0001:')
+        six.assertRegex(
+            self, self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 1, 2),
+            r'API Error 0002:')
+        six.assertRegex(
+            self, self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 0),
+            r'API Error 0004:')
+        six.assertRegex(
+            self, self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 1000),
+            r'API Error 0005:')
 
-            addresses = json.loads(
-                self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 2, 4)
-            )['addresses']
-            self.assertEqual(len(addresses), 2)
-            self.assertEqual(addresses[0], 'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
-            for addr in addresses:
-                self.assertEqual(self.api.deleteAddress(addr), 'success')
-        else:
-            self.assertEqual(
-                self.api.getDeterministicAddress(self._seed, 4, 1),
-                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
-            self.assertEqual(
-                self.api.getDeterministicAddress(self._seed, 3, 1),
-                'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN')
-            self.assertRegexpMatches(
-                self.api.getDeterministicAddress(self._seed, 2, 1),
-                r'^API Error 0002:')
-
-            # This is here until the streams will be implemented
-            self.assertRegexpMatches(
-                self.api.getDeterministicAddress(self._seed, 3, 2),
-                r'API Error 0003:')
-            self.assertRegexpMatches(
-                self.api.createDeterministicAddresses(self._seed, 1, 4, 2),
-                r'API Error 0003:')
-
-            self.assertRegexpMatches(
-                self.api.createDeterministicAddresses('', 1),
-                r'API Error 0001:')
-            self.assertRegexpMatches(
-                self.api.createDeterministicAddresses(self._seed, 1, 2),
-                r'API Error 0002:')
-            self.assertRegexpMatches(
-                self.api.createDeterministicAddresses(self._seed, 0),
-                r'API Error 0004:')
-            self.assertRegexpMatches(
-                self.api.createDeterministicAddresses(self._seed, 1000),
-                r'API Error 0005:')
-
-            addresses = json.loads(
-                self.api.createDeterministicAddresses(self._seed, 2, 4)
-            )['addresses']
-            self.assertEqual(len(addresses), 2)
-            self.assertEqual(addresses[0], 'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
-            for addr in addresses:
-                self.assertEqual(self.api.deleteAddress(addr), 'success')
+        addresses = json.loads(
+            self.api.createDeterministicAddresses(self._seed.decode('utf-8'), 2, 4)
+        )['addresses']
+        self.assertEqual(len(addresses), 2)
+        self.assertEqual(addresses[0], 'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
+        for addr in addresses:
+            self.assertEqual(self.api.deleteAddress(addr), 'success')
 
     def test_create_random_address(self):
         """API command 'createRandomAddress': basic BM-address validation"""
         addr = self._add_random_address('random_1')
-        if PY3:
-            self.assertRegex(addr, r'^BM-')
-            self.assertRegex(addr[3:], r'[a-zA-Z1-9]+$')
-        else:
-            self.assertRegexpMatches(addr, r'^BM-')
-            self.assertRegexpMatches(addr[3:], r'[a-zA-Z1-9]+$')
+        six.assertRegex(self, addr, r'^BM-')
+        six.assertRegex(self, addr[3:], r'[a-zA-Z1-9]+$')
         # Whitepaper says "around 36 character"
         self.assertLessEqual(len(addr[3:]), 40)
         self.assertEqual(self.api.deleteAddress(addr), 'success')
@@ -431,48 +388,25 @@ class TestAPI(TestAPIProto):
 
     def test_chan(self):
         """Testing chan creation/joining"""
-        if PY3:
-            # Create chan with known address
-            self.assertEqual(
-                self.api.createChan(self._seed.decode("utf-8")),
-                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'
-            )
-            # cleanup
-            self.assertEqual(
-                self.api.leaveChan('BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'),
-                'success'
-            )
-            # Join chan with addresses of version 3 or 4
-            for addr in (
-                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK',
-                'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN'
-            ):
-                self.assertEqual(self.api.joinChan(self._seed.decode("utf-8"), addr), 'success')
-                self.assertEqual(self.api.leaveChan(addr), 'success')
-            # Joining with wrong address should fail
-            self.assertRegex(
-                self.api.joinChan(self._seed.decode("utf-8"), 'BM-2cWzSnwjJ7yRP3nLEW'),
-                r'^API Error 0008:'
-            )
-        else:
-            self.assertEqual(
-                self.api.createChan(self._seed),
-                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'
-            )
-            # cleanup
-            self.assertEqual(
-                self.api.leaveChan('BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'),
-                'success'
-            )
-            # Join chan with addresses of version 3 or 4
-            for addr in (
-                'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK',
-                'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN'
-            ):
-                self.assertEqual(self.api.joinChan(self._seed, addr), 'success')
-                self.assertEqual(self.api.leaveChan(addr), 'success')
-            # Joining with wrong address should fail
-            self.assertRegexpMatches(
-                self.api.joinChan(self._seed, 'BM-2cWzSnwjJ7yRP3nLEW'),
-                r'^API Error 0008:'
-            )
+        # Create chan with known address
+        self.assertEqual(
+            self.api.createChan(self._seed.decode("utf-8")),
+            'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'
+        )
+        # cleanup
+        self.assertEqual(
+            self.api.leaveChan('BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'),
+            'success'
+        )
+        # Join chan with addresses of version 3 or 4
+        for addr in (
+            'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK',
+            'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN'
+        ):
+            self.assertEqual(self.api.joinChan(self._seed.decode("utf-8"), addr), 'success')
+            self.assertEqual(self.api.leaveChan(addr), 'success')
+        # Joining with wrong address should fail
+        six.assertRegex(
+            self, self.api.joinChan(self._seed.decode("utf-8"), 'BM-2cWzSnwjJ7yRP3nLEW'),
+            r'^API Error 0008:'
+        )
diff --git a/src/tests/test_process.py b/src/tests/test_process.py
index fe234247..a17b3a31 100644
--- a/src/tests/test_process.py
+++ b/src/tests/test_process.py
@@ -142,7 +142,7 @@ class TestProcessProto(unittest.TestCase):
             thread_names = subprocess.check_output([
                 "ps", "-L", "-o", "comm=", "--pid",
                 str(self.process.pid)
-            ]).split()
+            ]).decode('utf-8').split()
         except:  # pylint: disable=bare-except
             thread_names = []
 
-- 
2.45.1