Merge "Add unit tests for security group default rules"
diff --git a/.gitignore b/.gitignore
index f584532..efba45e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,4 +19,4 @@
 .coverage*
 !.coveragerc
 cover/
-doc/source/_static/tempest.conf
+doc/source/_static/tempest.conf.sample
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 3ec25ea..f85899b 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -15,18 +15,6 @@
 import os
 import subprocess
 
-# Build a tempest sample config file:
-def build_sample_config(app):
-    root_dir = os.path.dirname(
-        os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-    subprocess.call(["oslo-config-generator", "--config-file",
-                     "tools/config/config-generator.tempest.conf",
-                     "--output-file", "doc/source/_static/tempest.conf"],
-                    cwd=root_dir)
-
-def setup(app):
-    app.connect('builder-inited', build_sample_config)
-
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
@@ -42,9 +30,13 @@
 extensions = ['sphinx.ext.autodoc',
               'sphinx.ext.todo',
               'sphinx.ext.viewcode',
-              'oslosphinx'
+              'oslosphinx',
+              'oslo_config.sphinxconfiggen',
              ]
 
+config_generator_config_file = '../../tools/config/config-generator.tempest.conf'
+sample_config_basename = '_static/tempest'
+
 todo_include_todos = True
 
 # Add any paths that contain templates here, relative to this directory.
diff --git a/doc/source/sampleconf.rst b/doc/source/sampleconf.rst
index 2a72971..c290140 100644
--- a/doc/source/sampleconf.rst
+++ b/doc/source/sampleconf.rst
@@ -8,7 +8,6 @@
 if you are having issues with an option, please compare your version of
 Tempest with the version of this documentation.
 
-The sample configuration can also be viewed in `file form <_static/tempest.conf>`_.
+The sample configuration can also be viewed in `file form <_static/tempest.conf.sample>`_.
 
-.. include:: _static/tempest.conf
-   :code:
+.. literalinclude:: _static/tempest.conf.sample
diff --git a/tempest/tests/fake_tempest_plugin.py b/tempest/tests/fake_tempest_plugin.py
new file mode 100644
index 0000000..f718d0b
--- /dev/null
+++ b/tempest/tests/fake_tempest_plugin.py
@@ -0,0 +1,40 @@
+# Copyright (c) 2015 Deutsche Telekom AG
+# All Rights Reserved.
+#
+#    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 tempest.test_discover import plugins
+
+
+class FakePlugin(plugins.TempestPlugin):
+    expected_load_test = ["my/test/path", "/home/dir"]
+
+    def load_tests(self):
+        return self.expected_load_test
+
+    def register_opts(self, conf):
+        return
+
+    def get_opt_lists(self):
+        return []
+
+
+class FakeStevedoreObj(object):
+    obj = FakePlugin()
+
+    @property
+    def name(self):
+        return self._name
+
+    def __init__(self, name='Test1'):
+        self._name = name
diff --git a/tempest/tests/test_tempest_plugin.py b/tempest/tests/test_tempest_plugin.py
new file mode 100644
index 0000000..c07e98c
--- /dev/null
+++ b/tempest/tests/test_tempest_plugin.py
@@ -0,0 +1,44 @@
+# Copyright (c) 2015 Deutsche Telekom AG
+# All Rights Reserved.
+#
+#    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 tempest.test_discover import plugins
+from tempest.tests import base
+from tempest.tests import fake_tempest_plugin as fake_plugin
+
+
+class TestPluginDiscovery(base.TestCase):
+    def test_load_tests_with_one_plugin(self):
+        # we can't mock stevedore since it's a singleton and already executed
+        # during test discovery. So basically this test covers the plugin loop
+        # and the abstract plugin interface.
+        manager = plugins.TempestTestPluginManager()
+        fake_obj = fake_plugin.FakeStevedoreObj()
+        manager.ext_plugins = [fake_obj]
+        result = manager.get_plugin_load_tests_tuple()
+
+        self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+                         result[fake_obj.name])
+
+    def test_load_tests_with_two_plugins(self):
+        manager = plugins.TempestTestPluginManager()
+        obj1 = fake_plugin.FakeStevedoreObj('fake01')
+        obj2 = fake_plugin.FakeStevedoreObj('fake02')
+        manager.ext_plugins = [obj1, obj2]
+        result = manager.get_plugin_load_tests_tuple()
+
+        self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+                         result['fake01'])
+        self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+                         result['fake02'])