add hacking.py rule to prevent docstrings

add new rule for hacking.py to catch and prevent docstrings on
test_ functions in the tempest/test directory. Found 2 oddballs
that I missed on the last conversion.

update ./run_tests.sh to not ingore all N4* errors (basically all
our custom rules), 401 and 402 still ignored because we actually
have a lot of errors on both of those.

Change-Id: I894d181433b7dcd1a9f4429f1a463be75018f05e
diff --git a/run_tests.sh b/run_tests.sh
index 0df8a99..fd7da88 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -77,9 +77,9 @@
   srcfiles+=" `find tools -type f -name "*.py"`"
   srcfiles+=" setup.py"
 
-  ignore='--ignore=N4,E121,E122,E125,E126'
+  ignore='--ignore=N401,N402,E121,E122,E125,E126'
 
-  ${wrapper} python tools/hacking.py ${ignore} ${srcfiles}
+    ${wrapper} python tools/hacking.py ${ignore} ${srcfiles}
 }
 
 NOSETESTS="nosetests $noseargs"
diff --git a/tempest/tests/compute/floating_ips/test_floating_ips_actions.py b/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
index e5b4e0d..9a9914a 100644
--- a/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
@@ -111,11 +111,9 @@
 
     @attr(type='negative')
     def test_delete_nonexistant_floating_ip(self):
-        """
+        # Negative test:Deletion of a nonexistent floating IP
+        # from project should fail
 
-        Negative test:Deletion of a nonexistent floating IP
-        from project should fail
-        """
         #Deleting the non existent floating IP
         try:
             resp, body = self.client.delete_floating_ip(self.non_exist_id)
diff --git a/tempest/tests/compute/security_groups/test_security_group_rules.py b/tempest/tests/compute/security_groups/test_security_group_rules.py
index fdf2892..805adf4 100644
--- a/tempest/tests/compute/security_groups/test_security_group_rules.py
+++ b/tempest/tests/compute/security_groups/test_security_group_rules.py
@@ -58,11 +58,10 @@
 
     @attr(type='positive')
     def test_security_group_rules_create_with_optional_arguments(self):
-        """
-        Positive test: Creation of Security Group rule
-        with optional arguments
-        should be successfull
-        """
+        # Positive test: Creation of Security Group rule
+        # with optional arguments
+        # should be successfull
+
         rule_id = None
         secgroup1 = None
         secgroup2 = None
diff --git a/tools/hacking.py b/tools/hacking.py
index 6e66005..58e56c4 100755
--- a/tools/hacking.py
+++ b/tools/hacking.py
@@ -290,7 +290,7 @@
     end = max([physical_line[-4:-1] == i for i in DOCSTRING_TRIPLE])  # end
     if (pos != -1 and end and len(physical_line) > pos + 4):
         if (physical_line[-5] != '.'):
-            return pos, "TEMPEST N402: one line docstring needs a period"
+            return pos, "N402: one line docstring needs a period"
 
 
 def tempest_docstring_multiline_end(physical_line):
@@ -306,6 +306,23 @@
             return (pos, "TEMPEST N403: multi line docstring end on new line")
 
 
+def tempest_no_test_docstring(physical_line, previous_logical, filename):
+    """Check that test_ functions don't have docstrings
+
+    This ensure we get better results out of tempest, instead
+    of them being hidden behind generic descriptions of the
+    functions.
+
+    N404
+    """
+    if "tempest/test" in filename:
+        pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])
+        if pos != -1:
+            if previous_logical.startswith("def test_"):
+                return (pos, "TEMPEST N404: test functions must "
+                        "not have doc strings")
+
+
 FORMAT_RE = re.compile("%(?:"
                        "%|"           # Ignore plain percents
                        "(\(\w+\))?"   # mapping key
diff --git a/tox.ini b/tox.ini
index 2d8e627..aabac63 100644
--- a/tox.ini
+++ b/tox.ini
@@ -15,4 +15,4 @@
 
 [testenv:pep8]
 deps = pep8==1.3.3
-commands = python tools/hacking.py --ignore=N4,E122,E125,E126 --repeat --show-source --exclude=.venv,.tox,dist,doc,openstack,*egg .
+commands = python tools/hacking.py --ignore=N401,N402,E122,E125,E126 --repeat --show-source --exclude=.venv,.tox,dist,doc,openstack,*egg .