Move package into src

Prevents accidental imports when running tests.
diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 0000000..5bc0e03
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,12 @@
+[run]
+branch = True
+source = OpenSSL
+
+[paths]
+source =
+   src/OpenSSL
+   .tox/*/lib/python*/site-packages/OpenSSL
+   .tox/pypy/site-packages/OpenSSL
+
+[report]
+show_missing = True
diff --git a/.gitignore b/.gitignore
index 11e37b7..2040b80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,7 +6,7 @@
 __pycache__
 .tox
 doc/_build/
-.coverage
+.coverage*
 .eggs
 examples/simple/*.cert
 examples/simple/*.pkey
diff --git a/runtests.py b/runtests.py
index 13f5c4c..85a96c8 100644
--- a/runtests.py
+++ b/runtests.py
@@ -3,9 +3,9 @@
 sys.modules['_hashlib'] = None
 
 try:
-   import memdbg
+    from OpenSSL.test import memdbg  # noqa
 except Exception as e:
-   pass
+    pass
 
 from twisted.scripts.trial import run
 run()
diff --git a/setup.py b/setup.py
index f742c1e..c7c59ee 100755
--- a/setup.py
+++ b/setup.py
@@ -11,14 +11,12 @@
 import codecs
 import os
 import re
-import sys
 
-from setuptools import setup
-from setuptools.command.test import test as TestCommand
+from setuptools import setup, find_packages
 
 
 HERE = os.path.abspath(os.path.dirname(__file__))
-META_PATH = os.path.join("OpenSSL", "version.py")
+META_PATH = os.path.join("src", "OpenSSL", "version.py")
 
 
 def read_file(*parts):
@@ -46,82 +44,45 @@
     raise RuntimeError("Unable to find __{meta}__ string.".format(meta=meta))
 
 
-class PyTest(TestCommand):
-    user_options = [("pytest-args=", "a", "Arguments to pass to py.test")]
+if __name__ == "__main__":
+    setup(
+        name=find_meta("title"),
+        version=find_meta("version"),
+        description=find_meta("summary"),
+        long_description=read_file("README.rst"),
+        author=find_meta("author"),
+        author_email=find_meta("email"),
+        maintainer="Hynek Schlawack",
+        maintainer_email="hs@ox.cx",
+        url=find_meta("uri"),
+        license=find_meta("license"),
+        classifiers=[
+            'Development Status :: 6 - Mature',
+            'Intended Audience :: Developers',
+            'License :: OSI Approved :: Apache Software License',
+            'Operating System :: MacOS :: MacOS X',
+            'Operating System :: Microsoft :: Windows',
+            'Operating System :: POSIX',
 
-    def initialize_options(self):
-        TestCommand.initialize_options(self)
-        self.pytest_args = None
+            'Programming Language :: Python :: 2',
+            'Programming Language :: Python :: 2.6',
+            'Programming Language :: Python :: 2.7',
+            'Programming Language :: Python :: 3',
+            'Programming Language :: Python :: 3.3',
+            'Programming Language :: Python :: 3.4',
+            'Programming Language :: Python :: 3.5',
 
-    def finalize_options(self):
-        TestCommand.finalize_options(self)
-        self.test_args = []
-        self.test_suite = True
+            'Programming Language :: Python :: Implementation :: CPython',
+            'Programming Language :: Python :: Implementation :: PyPy',
+            'Topic :: Security :: Cryptography',
+            'Topic :: Software Development :: Libraries :: Python Modules',
+            'Topic :: System :: Networking',
+        ],
 
-    def run_tests(self):
-        # import here, cause outside the eggs aren't loaded
-        import pytest
-        errno = pytest.main(self.pytest_args or [] +
-                            ["OpenSSL"])
-        sys.exit(errno)
-
-
-setup(
-    name=find_meta("title"),
-    version=find_meta("version"),
-    description=find_meta("summary"),
-    long_description=read_file("README.rst"),
-    author=find_meta("author"),
-    author_email=find_meta("email"),
-    maintainer="Hynek Schlawack",
-    maintainer_email="hs@ox.cx",
-    url=find_meta("uri"),
-    license=find_meta("license"),
-    classifiers=[
-        'Development Status :: 6 - Mature',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: Apache Software License',
-        'Operating System :: MacOS :: MacOS X',
-        'Operating System :: Microsoft :: Windows',
-        'Operating System :: POSIX',
-
-        'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.6',
-        'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.3',
-
-        'Programming Language :: Python :: Implementation :: CPython',
-        'Programming Language :: Python :: Implementation :: PyPy',
-        'Topic :: Security :: Cryptography',
-        'Topic :: Software Development :: Libraries :: Python Modules',
-        'Topic :: System :: Networking',
-    ],
-
-    packages=['OpenSSL'],
-    package_dir={'OpenSSL': 'OpenSSL'},
-    py_modules=['OpenSSL.__init__',
-                'OpenSSL.tsafe',
-                'OpenSSL.rand',
-                'OpenSSL.crypto',
-                'OpenSSL.SSL',
-                'OpenSSL.version',
-                'OpenSSL.test.__init__',
-                'OpenSSL.test.util',
-                'OpenSSL.test.test_crypto',
-                'OpenSSL.test.test_rand',
-                'OpenSSL.test.test_ssl',
-                'OpenSSL.test.test_tsafe',
-                'OpenSSL.test.test_util',],
-    install_requires=[
-        "cryptography>=0.7",
-        "six>=1.5.2"
-    ],
-    test_suite="OpenSSL",
-    tests_require=[
-        "pytest",
-    ],
-    cmdclass={
-        "test": PyTest,
-    }
-)
+        packages=find_packages(where="src"),
+        package_dir={"": "src"},
+        install_requires=[
+            "cryptography>=0.7",
+            "six>=1.5.2"
+        ],
+    )
diff --git a/OpenSSL/SSL.py b/src/OpenSSL/SSL.py
similarity index 100%
rename from OpenSSL/SSL.py
rename to src/OpenSSL/SSL.py
diff --git a/OpenSSL/__init__.py b/src/OpenSSL/__init__.py
similarity index 100%
rename from OpenSSL/__init__.py
rename to src/OpenSSL/__init__.py
diff --git a/OpenSSL/_util.py b/src/OpenSSL/_util.py
similarity index 100%
rename from OpenSSL/_util.py
rename to src/OpenSSL/_util.py
diff --git a/OpenSSL/crypto.py b/src/OpenSSL/crypto.py
similarity index 100%
rename from OpenSSL/crypto.py
rename to src/OpenSSL/crypto.py
diff --git a/OpenSSL/rand.py b/src/OpenSSL/rand.py
similarity index 100%
rename from OpenSSL/rand.py
rename to src/OpenSSL/rand.py
diff --git a/OpenSSL/tsafe.py b/src/OpenSSL/tsafe.py
similarity index 100%
rename from OpenSSL/tsafe.py
rename to src/OpenSSL/tsafe.py
diff --git a/OpenSSL/version.py b/src/OpenSSL/version.py
similarity index 100%
rename from OpenSSL/version.py
rename to src/OpenSSL/version.py
diff --git a/OpenSSL/test/README b/tests/README
similarity index 100%
rename from OpenSSL/test/README
rename to tests/README
diff --git a/OpenSSL/test/__init__.py b/tests/__init__.py
similarity index 100%
rename from OpenSSL/test/__init__.py
rename to tests/__init__.py
diff --git a/memdbg.py b/tests/memdbg.py
similarity index 100%
rename from memdbg.py
rename to tests/memdbg.py
diff --git a/OpenSSL/test/test_crypto.py b/tests/test_crypto.py
similarity index 99%
rename from OpenSSL/test/test_crypto.py
rename to tests/test_crypto.py
index 0c906b6..196e490 100644
--- a/OpenSSL/test/test_crypto.py
+++ b/tests/test_crypto.py
@@ -35,10 +35,11 @@
 from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
 from OpenSSL.crypto import (
     sign, verify, get_elliptic_curve, get_elliptic_curves)
-from OpenSSL.test.util import (
+from OpenSSL._util import native, lib
+
+from .util import (
     EqualityTestsMixin, TestCase, WARNING_TYPE_EXPECTED
 )
-from OpenSSL._util import native, lib
 
 
 def normalize_certificate_pem(pem):
diff --git a/OpenSSL/test/test_rand.py b/tests/test_rand.py
similarity index 98%
rename from OpenSSL/test/test_rand.py
rename to tests/test_rand.py
index d5d75cb..8064011 100644
--- a/OpenSSL/test/test_rand.py
+++ b/tests/test_rand.py
@@ -10,9 +10,10 @@
 import stat
 import sys
 
-from OpenSSL.test.util import NON_ASCII, TestCase, b
 from OpenSSL import rand
 
+from .util import NON_ASCII, TestCase, b
+
 
 class RandTests(TestCase):
     def test_bytes_wrong_args(self):
diff --git a/OpenSSL/test/test_ssl.py b/tests/test_ssl.py
similarity index 99%
rename from OpenSSL/test/test_ssl.py
rename to tests/test_ssl.py
index 3db1f8f..4aac429 100644
--- a/OpenSSL/test/test_ssl.py
+++ b/tests/test_ssl.py
@@ -47,12 +47,6 @@
 
 from OpenSSL._util import lib as _lib
 
-from OpenSSL.test.util import WARNING_TYPE_EXPECTED, NON_ASCII, TestCase, b
-from OpenSSL.test.test_crypto import (
-    cleartextCertificatePEM, cleartextPrivateKeyPEM,
-    client_cert_pem, client_key_pem, server_cert_pem, server_key_pem,
-    root_cert_pem)
-
 try:
     from OpenSSL.SSL import OP_NO_QUERY_MTU
 except ImportError:
@@ -89,6 +83,12 @@
     SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP, SSL_CB_CONNECT_EXIT,
     SSL_CB_HANDSHAKE_START, SSL_CB_HANDSHAKE_DONE)
 
+from .util import WARNING_TYPE_EXPECTED, NON_ASCII, TestCase, b
+from .test_crypto import (
+    cleartextCertificatePEM, cleartextPrivateKeyPEM,
+    client_cert_pem, client_key_pem, server_cert_pem, server_key_pem,
+    root_cert_pem)
+
 
 # openssl dhparam 128 -out dh-128.pem (note that 128 is a small number of bits
 # to use)
diff --git a/OpenSSL/test/test_tsafe.py b/tests/test_tsafe.py
similarity index 94%
rename from OpenSSL/test/test_tsafe.py
rename to tests/test_tsafe.py
index 0456957..97045ce 100644
--- a/OpenSSL/test/test_tsafe.py
+++ b/tests/test_tsafe.py
@@ -7,7 +7,8 @@
 
 from OpenSSL.SSL import TLSv1_METHOD, Context
 from OpenSSL.tsafe import Connection
-from OpenSSL.test.util import TestCase
+
+from .util import TestCase
 
 
 class ConnectionTest(TestCase):
diff --git a/OpenSSL/test/test_util.py b/tests/test_util.py
similarity index 93%
rename from OpenSSL/test/test_util.py
rename to tests/test_util.py
index 24ccc1d..2aaded2 100644
--- a/OpenSSL/test/test_util.py
+++ b/tests/test_util.py
@@ -1,5 +1,6 @@
 from OpenSSL._util import exception_from_error_queue, lib
-from OpenSSL.test.util import TestCase
+
+from .util import TestCase
 
 
 class ErrorTests(TestCase):
diff --git a/OpenSSL/test/util.py b/tests/util.py
similarity index 99%
rename from OpenSSL/test/util.py
rename to tests/util.py
index b0a5d62..5b53dc2 100644
--- a/OpenSSL/test/util.py
+++ b/tests/util.py
@@ -22,7 +22,7 @@
 from OpenSSL.crypto import Error
 
 
-import memdbg
+from . import memdbg
 
 from OpenSSL._util import ffi, lib, byte_string as b
 
diff --git a/tox.ini b/tox.ini
index 7a40309..f32b667 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,30 +1,29 @@
 [tox]
-envlist = {pypy,py26,py27,py33,py34,py35}{,-cryptographyMaster},pypi-readme,check-manifest,flake8,pyroma,docs
+envlist = coverage-clean,{pypy,py26,py27,py33,py34,py35}{,-cryptographyMaster},pypi-readme,check-manifest,flake8,pyroma,docs,coverage-report
 
 [testenv]
 whitelist_externals =
     openssl
 passenv = ARCHFLAGS CFLAGS LC_ALL LDFLAGS PATH LD_LIBRARY_PATH
 deps =
-    setuptools>=7.0  # older setuptools pollute CWD with egg files of dependencies
     coverage
+    pytest
     cryptographyMaster: git+https://github.com/pyca/cryptography.git
 setenv =
-    # Do not allowed the executing environment to pollute the test environment
+    # Do not allow the executing environment to pollute the test environment
     # with extra packages.
     PYTHONPATH=
 commands =
     openssl version
     python -c "import OpenSSL.SSL; print(OpenSSL.SSL.SSLeay_version(OpenSSL.SSL.SSLEAY_VERSION))"
     python -c "import cryptography; print(cryptography.__version__)"
-    coverage run --branch --source=OpenSSL setup.py test
-    coverage report -m
+    coverage run --parallel -m pytest tests
 
 [testenv:flake8]
 deps =
      flake8
 commands =
-     flake8 OpenSSL
+     flake8 src tests setup.py
 
 [testenv:pyroma]
 deps =
@@ -49,3 +48,15 @@
 basepython = python2.7
 commands =
      sphinx-build -W -b html doc doc/_build/html
+
+[testenv:coverage-clean]
+deps = coverage
+skip_install = true
+commands = coverage erase
+
+[testenv:coverage-report]
+deps = coverage
+skip_install = true
+commands =
+    coverage combine
+    coverage report