diff --git a/ironic_python_agent/extensions/base.py b/ironic_python_agent/extensions/base.py
index 2d8cbc068..344adf95d 100644
--- a/ironic_python_agent/extensions/base.py
+++ b/ironic_python_agent/extensions/base.py
@@ -80,7 +80,7 @@ class SyncCommandResult(BaseCommandResult):
         super(SyncCommandResult, self).__init__(command_name,
                                                 command_params)
 
-        if type(result_or_error) in (str, unicode):
+        if isinstance(result_or_error, (bytes, six.text_type)):
             result_key = 'result' if success else 'error'
             result_or_error = {result_key: result_or_error}
 
@@ -148,7 +148,7 @@ class AsyncCommandResult(BaseCommandResult):
         try:
             result = self.execute_method(**self.command_params)
 
-            if type(result) in (str, unicode):
+            if isinstance(result, (bytes, six.text_type)):
                 result = {'result': '{}: {}'.format(self.command_name, result)}
 
             with self.command_state_lock:
diff --git a/ironic_python_agent/extensions/standby.py b/ironic_python_agent/extensions/standby.py
index 5b9ac4960..98d8054c7 100644
--- a/ironic_python_agent/extensions/standby.py
+++ b/ironic_python_agent/extensions/standby.py
@@ -18,7 +18,6 @@ import hashlib
 import os
 import requests
 import six
-import StringIO
 import time
 
 from oslo_concurrency import processutils
@@ -76,7 +75,7 @@ def _download_configdrive_to_file(configdrive, filename):
 def _write_configdrive_to_file(configdrive, filename):
     LOG.debug('Writing configdrive to {0}'.format(filename))
     # configdrive data is base64'd, decode it first
-    data = StringIO.StringIO(base64.b64decode(configdrive))
+    data = six.StringIO(base64.b64decode(configdrive))
     gunzipped = gzip.GzipFile('configdrive', 'rb', 9, data)
     with open(filename, 'wb') as f:
         f.write(gunzipped.read())
diff --git a/ironic_python_agent/netutils.py b/ironic_python_agent/netutils.py
index 8b005eba4..5a89cd8bb 100644
--- a/ironic_python_agent/netutils.py
+++ b/ironic_python_agent/netutils.py
@@ -30,7 +30,6 @@ from ironic_python_agent.cmd import agent  # noqa
 LOG = logging.getLogger(__name__)
 CONF = cfg.CONF
 
-
 LLDP_ETHERTYPE = 0x88cc
 IFF_PROMISC = 0x100
 SIOCGIFFLAGS = 0x8913
@@ -66,7 +65,7 @@ class RawPromiscuousSockets(object):
             LOG.info('Interface %s entering promiscuous mode to capture ',
                      interface_name)
             try:
-                ifr.ifr_ifrn = interface_name
+                ifr.ifr_ifrn = interface_name.encode()
                 # Get current flags
                 fcntl.ioctl(sock.fileno(), SIOCGIFFLAGS, ifr)  # G for Get
                 # bitwise or the flags with promiscuous mode, set the new flags
@@ -91,7 +90,7 @@ class RawPromiscuousSockets(object):
 
     def __exit__(self, exception_type, exception_val, trace):
         if exception_type:
-            LOG.exception('Error while using raw socket: %(type)s: %(val)',
+            LOG.exception('Error while using raw socket: %(type)s: %(val)s',
                           {'type': exception_type, 'val': exception_val})
 
         for _name, sock, ifr in self.interfaces:
diff --git a/ironic_python_agent/tests/extensions/standby.py b/ironic_python_agent/tests/extensions/standby.py
index de16f887f..bc3b9ea1d 100644
--- a/ironic_python_agent/tests/extensions/standby.py
+++ b/ironic_python_agent/tests/extensions/standby.py
@@ -204,7 +204,7 @@ class TestStandbyExtension(test_base.BaseTestCase):
         response = requests_mock.return_value
         response.status_code = 200
         response.iter_content.return_value = ['some', 'content']
-        file_mock = mock.Mock(spec=file)
+        file_mock = mock.Mock()
         open_mock.return_value.__enter__.return_value = file_mock
         file_mock.read.return_value = None
         hexdigest_mock = md5_mock.return_value.hexdigest
@@ -247,7 +247,7 @@ class TestStandbyExtension(test_base.BaseTestCase):
         image_info = self._build_fake_image_info()
         hexdigest_mock = md5_mock.return_value.hexdigest
         hexdigest_mock.return_value = image_info['checksum']
-        file_mock = mock.Mock(spec=file)
+        file_mock = mock.Mock()
         file_mock.read.return_value = None
         open_mock.return_value.__enter__.return_value = file_mock
         image_location = '/foo/bar'
@@ -261,7 +261,7 @@ class TestStandbyExtension(test_base.BaseTestCase):
     def test_verify_image_failure(self, md5_mock, open_mock):
         image_info = self._build_fake_image_info()
         md5_mock.return_value.hexdigest.return_value = 'wrong hash'
-        file_mock = mock.Mock(spec=file)
+        file_mock = mock.Mock()
         file_mock.read.return_value = None
         open_mock.return_value.__enter__.return_value = file_mock
         image_location = '/foo/bar'
diff --git a/ironic_python_agent/tests/netutils.py b/ironic_python_agent/tests/netutils.py
index 9a45b48b8..9efdfba09 100644
--- a/ironic_python_agent/tests/netutils.py
+++ b/ironic_python_agent/tests/netutils.py
@@ -39,15 +39,15 @@ class TestNetutils(test_base.BaseTestCase):
     def test_get_lldp_info(self, sock_mock, select_mock, fcntl_mock):
         expected_lldp = {
             'eth1': [
-                (0, ''),
-                (1, '\x04\x88Z\x92\xecTY'),
-                (2, '\x05Ethernet1/18'),
-                (3, '\x00x')],
+                (0, b''),
+                (1, b'\x04\x88Z\x92\xecTY'),
+                (2, b'\x05Ethernet1/18'),
+                (3, b'\x00x')],
             'eth0': [
-                (0, ''),
-                (1, '\x04\x88Z\x92\xecTY'),
-                (2, '\x05Ethernet1/18'),
-                (3, '\x00x')]
+                (0, b''),
+                (1, b'\x04\x88Z\x92\xecTY'),
+                (2, b'\x05Ethernet1/18'),
+                (3, b'\x00x')]
         }
 
         interface_names = ['eth0', 'eth1']
@@ -87,15 +87,15 @@ class TestNetutils(test_base.BaseTestCase):
     def test_get_lldp_info_multiple(self, sock_mock, select_mock, fcntl_mock):
         expected_lldp = {
             'eth1': [
-                (0, ''),
-                (1, '\x04\x88Z\x92\xecTY'),
-                (2, '\x05Ethernet1/18'),
-                (3, '\x00x')],
+                (0, b''),
+                (1, b'\x04\x88Z\x92\xecTY'),
+                (2, b'\x05Ethernet1/18'),
+                (3, b'\x00x')],
             'eth0': [
-                (0, ''),
-                (1, '\x04\x88Z\x92\xecTY'),
-                (2, '\x05Ethernet1/18'),
-                (3, '\x00x')]
+                (0, b''),
+                (1, b'\x04\x88Z\x92\xecTY'),
+                (2, b'\x05Ethernet1/18'),
+                (3, b'\x00x')]
         }
 
         interface_names = ['eth0', 'eth1']
@@ -136,10 +136,10 @@ class TestNetutils(test_base.BaseTestCase):
         expected_lldp = {
             'eth1': [],
             'eth0': [
-                (0, ''),
-                (1, '\x04\x88Z\x92\xecTY'),
-                (2, '\x05Ethernet1/18'),
-                (3, '\x00x')]
+                (0, b''),
+                (1, b'\x04\x88Z\x92\xecTY'),
+                (2, b'\x05Ethernet1/18'),
+                (3, b'\x00x')]
         }
 
         interface_names = ['eth0', 'eth1']
diff --git a/ironic_python_agent/tests/utils.py b/ironic_python_agent/tests/utils.py
index d7e51cadf..35955d358 100644
--- a/ironic_python_agent/tests/utils.py
+++ b/ironic_python_agent/tests/utils.py
@@ -69,7 +69,7 @@ exit 1
                 self.assertRaises(processutils.ProcessExecutionError,
                                   utils.execute,
                                   tmpfilename, tmpfilename2, attempts=10,
-                                  process_input='foo',
+                                  process_input=b'foo',
                                   delay_on_retry=False)
             except OSError as e:
                 if e.errno == errno.EACCES:
@@ -120,7 +120,7 @@ grep foo
             try:
                 utils.execute(tmpfilename,
                               tmpfilename2,
-                              process_input='foo',
+                              process_input=b'foo',
                               attempts=2)
             except OSError as e:
                 if e.errno == errno.EACCES:
@@ -181,8 +181,8 @@ class GetAgentParamsTestCase(test_base.BaseTestCase):
         get_cache_mock.return_value = {}
         kernel_params = {'boot_method': 'vmedia'}
         vmedia_params = {'a': 'b'}
-        expected_params = dict(kernel_params.items() +
-                               vmedia_params.items())
+        expected_params = dict(list(kernel_params.items()) +
+                               list(vmedia_params.items()))
         read_params_mock.return_value = kernel_params
         get_vmedia_params_mock.return_value = vmedia_params
 
@@ -210,7 +210,7 @@ class GetAgentParamsTestCase(test_base.BaseTestCase):
                                   '/sys/class/block/sdb/device/model',
                                   '/sys/class/block/sdc/device/model']
         fobj_mock = mock.MagicMock()
-        mock_file_handle = mock.MagicMock(spec=file)
+        mock_file_handle = mock.MagicMock()
         mock_file_handle.__enter__.return_value = fobj_mock
         open_mock.return_value = mock_file_handle
 
diff --git a/ironic_python_agent/utils.py b/ironic_python_agent/utils.py
index 4e7367b18..04854e15f 100644
--- a/ironic_python_agent/utils.py
+++ b/ironic_python_agent/utils.py
@@ -228,7 +228,7 @@ def parse_root_device_hints():
         raise errors.DeviceNotFound(error_msg)
 
     # Normalise the values
-    hints = {k: normalize(v) for k, v in hints.iteritems()}
+    hints = {k: normalize(v) for k, v in hints.items()}
 
     if 'size' in hints:
         # NOTE(lucasagomes): Ironic should validate before passing to
diff --git a/tox.ini b/tox.ini
index 21828fc6f..003a9d852 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,7 @@
 [tox]
 minversion = 1.6
 skipsdist = True
-envlist = py27,pep8
+envlist = py27,py34,pep8
 
 [testenv]
 usedevelop = True