diff --git a/tcp_tests/fixtures/__init__.py b/tcp_tests/fixtures/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tcp_tests/fixtures/__init__.py
diff --git a/tcp_tests/fixtures/common_fixtures.py b/tcp_tests/fixtures/common_fixtures.py
new file mode 100644
index 0000000..9d121e5
--- /dev/null
+++ b/tcp_tests/fixtures/common_fixtures.py
@@ -0,0 +1,75 @@
+#    Copyright 2016 Mirantis, Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from __future__ import division
+import time
+
+import pytest
+
+from tcp_tests import logger
+from tcp_tests.helpers import log_step
+from tcp_tests.helpers import utils
+
+
+LOG = logger.logger
+
+
+@pytest.yield_fixture(scope='session')
+def ssh_keys_dir(request):
+    ssh_keys_dir = utils.generate_keys()
+    LOG.info("SSH keys were generated in {}".format(ssh_keys_dir))
+    yield ssh_keys_dir
+    utils.clean_dir(ssh_keys_dir)
+    LOG.info("Tmp dir {} with generated ssh keys was cleaned".format(
+        ssh_keys_dir))
+
+
+@pytest.hookimpl(tryfirst=True, hookwrapper=True)
+def pytest_runtest_makereport(item, call):
+    outcome = yield
+    rep = outcome.get_result()
+    setattr(item, "rep_" + rep.when, rep)
+
+
+def pytest_runtest_setup(item):
+    if item.cls is not None:
+        item.cls._current_test = item.function
+    item._start_time = time.time()
+    head = "<" * 5 + "#" * 30 + "[ {} ]" + "#" * 30 + ">" * 5
+    head = head.format(item.function.__name__)
+    start_step = "\n{head}".format(head=head)
+    LOG.info(start_step)
+
+
+def pytest_runtest_teardown(item):
+    step_name = item.function.__name__
+    if hasattr(item, '_start_time'):
+        spent_time = time.time() - item._start_time
+    else:
+        spent_time = 0
+    minutes = spent_time // 60
+    seconds = int(round(spent_time)) % 60
+    finish_step = "FINISH {} TEST. TOOK {} min {} sec".format(
+        step_name, minutes, seconds
+    )
+    foot = "\n" + "<" * 5 + "#" * 30 + "[ {} ]" + "#" * 30 + ">" * 5
+    foot = foot.format(finish_step)
+    LOG.info(foot)
+
+
+@pytest.fixture(scope='function')
+def show_step(request):
+    def _show_step(step_number):
+        return log_step.log_step(request.function, step_number)
+    return _show_step
diff --git a/tcp_tests/fixtures/config_fixtures.py b/tcp_tests/fixtures/config_fixtures.py
new file mode 100644
index 0000000..ffcaea9
--- /dev/null
+++ b/tcp_tests/fixtures/config_fixtures.py
@@ -0,0 +1,33 @@
+#    Copyright 2016 Mirantis, Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+import os
+
+import pytest
+
+from tcp_tests import settings_oslo
+
+
+@pytest.fixture(scope='session')
+def config():
+
+    config_files = []
+
+    tests_configs = os.environ.get('TESTS_CONFIGS', None)
+    if tests_configs:
+        for test_config in tests_configs.split(','):
+            config_files.append(test_config)
+
+    config_opts = settings_oslo.load_config(config_files)
+
+    return config_opts
diff --git a/tcp_tests/fixtures/rally_fixtures.py b/tcp_tests/fixtures/rally_fixtures.py
new file mode 100644
index 0000000..45e828a
--- /dev/null
+++ b/tcp_tests/fixtures/rally_fixtures.py
@@ -0,0 +1,30 @@
+#    Copyright 2016 Mirantis, Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import pytest
+
+from tcp_tests.managers import rallymanager
+
+
+@pytest.fixture(scope='function')
+def rally(underlay):
+    """Fixture that provides various actions for TCP
+
+    :param config: fixture provides oslo.config
+    :param underlay: fixture provides underlay manager
+    :rtype: RallyManager
+
+    For use in tests or fixtures to deploy a custom TCP
+    """
+    return rallymanager.RallyManager(underlay, 'cfg01')
diff --git a/tcp_tests/fixtures/underlay_fixtures.py b/tcp_tests/fixtures/underlay_fixtures.py
new file mode 100644
index 0000000..e7aaaf8
--- /dev/null
+++ b/tcp_tests/fixtures/underlay_fixtures.py
@@ -0,0 +1,211 @@
+#    Copyright 2016 Mirantis, Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import pytest
+from datetime import datetime
+
+from tcp_tests.helpers import ext
+from tcp_tests import logger
+from tcp_tests import settings
+from tcp_tests.managers import envmanager_devops
+from tcp_tests.managers import envmanager_empty
+from tcp_tests.managers import underlay_ssh_manager
+
+LOG = logger.logger
+
+
+def extract_name_from_mark(mark):
+    """Simple function to extract name from mark
+
+    :param mark: pytest.mark.MarkInfo
+    :rtype: string or None
+    """
+    if mark:
+        if len(mark.args) > 0:
+            return mark.args[0]
+        elif 'name' in mark.kwargs:
+            return mark.kwargs['name']
+    return None
+
+
+@pytest.fixture(scope="session")
+def hardware(request, config):
+    """Fixture for manage the hardware layer.
+
+       - start/stop/reboot libvirt/IPMI(/MaaS?) nodes
+       - snapshot/revert libvirt nodes (fuel-devops only)
+       - block/unblock libvirt  networks/interfaces (fuel-devops only)
+
+       This fixture should get a hardware configuration from
+       'config' object or create a virtual/baremetal underlay
+       using EnvironmentManager.
+
+       Creates a snapshot 'hardware' with ready-to-use virtual environment
+       (Only for config.hardware.manager='devops'):
+        - just created virtual nodes in power-on state
+        - node volumes filled with necessary content
+        - node network interfaces connected to necessary devices
+
+       config.hardware.manager: one of ('devops', 'maas', None)
+       config.hardware.config: path to the config file for the manager
+       config.hardware.current_snapshot = Latest created or reverted snapshot
+
+       :rtype EnvironmentModel: if config.hardware.manager == 'devops'
+       :rtype EnvironmentManagerEmpty: if config.hardware.manager == 'empty'
+    """
+    env = None
+
+    manager = config.hardware.manager
+
+    if manager == 'empty':
+        # No environment manager is used.
+        # 'config' should contain config.underlay.ssh settings
+        # 'config' should contain config.underlay.current_snapshot setting
+        env = envmanager_empty.EnvironmentManagerEmpty(config=config)
+
+    elif manager == 'devops':
+        # fuel-devops environment manager is used.
+        # config.underlay.ssh settings can be empty or witn SSH to existing env
+        # config.underlay.current_snapshot
+        env = envmanager_devops.EnvironmentManager(config=config)
+    else:
+        raise Exception("Unknown hardware manager: '{}'".format(manager))
+
+    # for devops manager: power on nodes and wait for SSH
+    # for empty manager: do nothing
+    # for maas manager: provision nodes and wait for SSH
+    env.start()
+    if not env.has_snapshot(ext.SNAPSHOT.hardware):
+        env.create_snapshot(ext.SNAPSHOT.hardware)
+
+    def fin():
+        if settings.SHUTDOWN_ENV_ON_TEARDOWN:
+            LOG.info("Shutdown environment...")
+            env.stop()
+
+    request.addfinalizer(fin)
+    return env
+
+
+@pytest.fixture(scope='function')
+def revert_snapshot(request, hardware):
+    """Revert snapshot for the test case
+
+    Usage:
+    @pytest.mark.revert_snapshot(name='<required_snapshot_name>')
+
+    If the mark 'revert_snapshot' is absend, or <required_snapshot_name>
+    not found, then an initial 'hardware' snapshot will be reverted.
+
+    :rtype string: name of the reverted snapshot or None
+    """
+    revert_snapshot = request.keywords.get('revert_snapshot', None)
+    snapshot_name = extract_name_from_mark(revert_snapshot)
+
+    if snapshot_name and \
+            hardware.has_snapshot(snapshot_name) and \
+            hardware.has_snapshot_config(snapshot_name):
+        hardware.revert_snapshot(snapshot_name)
+        return snapshot_name
+    else:
+        hardware.revert_snapshot(ext.SNAPSHOT.hardware)
+        return None
+
+
+@pytest.fixture(scope='function', autouse=True)
+def snapshot(request, hardware):
+    """Fixture for creating snapshot at the end of test if it's needed
+
+    Marks:
+        snapshot_needed(name=None) - make snapshot if test is passed. If
+        name argument provided, it will be used for creating snapshot,
+        otherwise, test function name will be used
+
+        fail_snapshot - make snapshot if test failed
+
+    :param request: pytest.python.FixtureRequest
+    :param env: envmanager.EnvironmentManager
+    """
+    snapshot_needed = request.keywords.get('snapshot_needed', None)
+    fail_snapshot = request.keywords.get('fail_snapshot', None)
+
+    def test_fin():
+        default_snapshot_name = getattr(request.node.function,
+                                        '_snapshot_name',
+                                        request.node.function.__name__)
+        if hasattr(request.node, 'rep_call') and request.node.rep_call.passed \
+                and snapshot_needed:
+            snapshot_name = extract_name_from_mark(snapshot_needed) or \
+                "{}_passed".format(default_snapshot_name)
+            hardware.create_snapshot(snapshot_name)
+
+        elif hasattr(request.node, 'rep_setup') and \
+                request.node.rep_setup.failed and fail_snapshot:
+            snapshot_name = "{0}_prep_failed".format(default_snapshot_name)
+            hardware.create_snapshot(snapshot_name)
+
+        elif hasattr(request.node, 'rep_call') and \
+                request.node.rep_call.failed and fail_snapshot:
+            snapshot_name = "{0}_failed".format(default_snapshot_name)
+            hardware.create_snapshot(snapshot_name)
+
+    request.addfinalizer(test_fin)
+
+
+@pytest.fixture(scope="function")
+def underlay(revert_snapshot, config, hardware):
+    """Fixture that should provide SSH access to underlay objects.
+
+    - Starts the 'hardware' environment and creates 'underlay' with required
+      configuration.
+    - Fills the following object using the 'hardware' fixture:
+      config.underlay.ssh = JSONList of SSH access credentials for nodes.
+                            This list will be used for initialization the
+                            model UnderlaySSHManager, see it for details.
+
+    :rtype UnderlaySSHManager: Object that encapsulate SSH credentials;
+                               - provide list of underlay nodes;
+                               - provide SSH access to underlay nodes using
+                                 node names or node IPs.
+    """
+    # If no snapshot was reverted, then try to revert the snapshot
+    # that belongs to the fixture.
+    # Note: keep fixtures in strict dependences from each other!
+    if not revert_snapshot:
+        if hardware.has_snapshot(ext.SNAPSHOT.underlay) and \
+                hardware.has_snapshot_config(ext.SNAPSHOT.underlay):
+            hardware.revert_snapshot(ext.SNAPSHOT.underlay)
+
+    # Create Underlay
+    if not config.underlay.ssh:
+        # If config.underlay.ssh wasn't provided from external config, then
+        # try to get necessary data from hardware manager (fuel-devops)
+        config.underlay.ssh = hardware.get_ssh_data(
+            roles=config.underlay.roles)
+
+        underlay = underlay_ssh_manager.UnderlaySSHManager(config.underlay.ssh)
+
+        if not config.underlay.lvm:
+            underlay.enable_lvm(hardware.lvm_storages())
+            config.underlay.lvm = underlay.config_lvm
+
+        hardware.create_snapshot(ext.SNAPSHOT.underlay)
+
+    else:
+        # 1. hardware environment created and powered on
+        # 2. config.underlay.ssh contains SSH access to provisioned nodes
+        #    (can be passed from external config with TESTS_CONFIGS variable)
+        underlay = underlay_ssh_manager.UnderlaySSHManager(config.underlay.ssh)
+
+    return underlay
