test: add core case and coverage ignore file (#23)

diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 0000000..8086340
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+[run]
+omit =
+    */__init__.py
diff --git a/.gitignore b/.gitignore
index 92150d1..507b2fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,5 +20,6 @@
 .idea
 .vscode
 .DS_Store
+.coverage
 .pytest_cache/
 **/__pycache__/
diff --git a/.licenserc.yaml b/.licenserc.yaml
index 66451b4..02c0d56 100644
--- a/.licenserc.yaml
+++ b/.licenserc.yaml
@@ -22,10 +22,12 @@
 
   paths-ignore:
     - '.gitignore'
-    - '.pytest_cache/**'
+    - '.coverage'
+    - '.coveragerc'
     - 'LICENSE'
     - 'NOTICE'
     - 'pytest.ini'
+    - '.pytest_cache/**'
     - '**/__pycache__/**'
     - '**/images/**'
 
diff --git a/apisix/runner/http/response.py b/apisix/runner/http/response.py
index f998f4c..a1b17ee 100644
--- a/apisix/runner/http/response.py
+++ b/apisix/runner/http/response.py
@@ -31,7 +31,7 @@
 
 class Response:
 
-    def __init__(self, ty: int):
+    def __init__(self, ty: int = 0):
         """
         Init and parse request
         :param ty:
diff --git a/apisix/runner/plugin/core.py b/apisix/runner/plugin/core.py
index b2b6bab..93c20a9 100644
--- a/apisix/runner/plugin/core.py
+++ b/apisix/runner/plugin/core.py
@@ -21,17 +21,21 @@
 from apisix.runner.server.response import RESP_STATUS_CODE_OK
 from apisix.runner.server.response import RESP_STATUS_MESSAGE_OK
 from apisix.runner.server.response import RESP_STATUS_CODE_SERVICE_UNAVAILABLE
+from apisix.runner.server.response import RESP_STATUS_CODE_BAD_REQUEST
 
 
 def execute(configs: dict, request, response) -> Tuple[int, str]:
     for name in configs:
         plugin = configs.get(name)
-        if not plugin:
-            return RESP_STATUS_CODE_SERVICE_UNAVAILABLE, "plugin `%s` undefined" % name
+        if type(plugin).__name__.lower() != name.lower():
+            return RESP_STATUS_CODE_BAD_REQUEST, "execute plugin `%s`, plugin handler is not object" % name
+
         try:
             plugin.filter(request, response)
-        except AttributeError:
-            return RESP_STATUS_CODE_SERVICE_UNAVAILABLE, "plugin `%s` object has no attribute `filter`" % name
+        except AttributeError as e:
+            return RESP_STATUS_CODE_SERVICE_UNAVAILABLE, "execute plugin `%s`, %s" % (name, e.args.__str__())
+        except TypeError as e:
+            return RESP_STATUS_CODE_BAD_REQUEST, "execute plugin `%s`, %s" % (name, e.args.__str__())
     return RESP_STATUS_CODE_OK, RESP_STATUS_MESSAGE_OK
 
 
diff --git a/apisix/runner/server/response.py b/apisix/runner/server/response.py
index 2835910..8dc7a42 100644
--- a/apisix/runner/server/response.py
+++ b/apisix/runner/server/response.py
@@ -21,8 +21,8 @@
 RESP_STATUS_MESSAGE_OK = "OK"
 RESP_STATUS_CODE_BAD_REQUEST = A6ErrCode.Code.BAD_REQUEST
 RESP_STATUS_MESSAGE_BAD_REQUEST = "Bad Request"
-RESP_STATUS_CODE_SERVICE_UNAVAILABLE = A6ErrCode.Code.BAD_REQUEST
-RESP_STATUS_CODE_CONF_TOKEN_NOT_FOUND = A6ErrCode.Code.SERVICE_UNAVAILABLE
+RESP_STATUS_CODE_SERVICE_UNAVAILABLE = A6ErrCode.Code.SERVICE_UNAVAILABLE
+RESP_STATUS_CODE_CONF_TOKEN_NOT_FOUND = A6ErrCode.Code.CONF_TOKEN_NOT_FOUND
 
 
 class Response:
diff --git a/tests/runner/plugin/test_core.py b/tests/runner/plugin/test_core.py
index b1312a0..376090a 100644
--- a/tests/runner/plugin/test_core.py
+++ b/tests/runner/plugin/test_core.py
@@ -14,3 +14,50 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+
+import os
+from pkgutil import iter_modules
+from apisix.runner.plugin.core import loading as plugin_loading
+from apisix.runner.plugin.core import execute as plugin_execute
+from apisix.runner.http.request import Request as NewHttpRequest
+from apisix.runner.http.response import Response as NewHttpResponse
+from apisix.runner.server.response import RESP_STATUS_CODE_OK
+from apisix.runner.server.response import RESP_STATUS_CODE_SERVICE_UNAVAILABLE
+from apisix.runner.server.response import RESP_STATUS_CODE_BAD_REQUEST
+
+
+class Test:
+    """
+    test plugin
+    """
+    def filter(self):
+        """
+        test plugin handler
+        :return:
+        """
+        pass
+
+
+def test_loading():
+    configs = plugin_loading()
+    assert isinstance(configs, dict)
+    config_keys = configs.keys()
+    path = "%s/plugins" % os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
+    modules = iter_modules(path=[path])
+    for _, name, _ in modules:
+        assert name in config_keys
+
+
+def test_execute():
+    request = NewHttpRequest()
+    response = NewHttpResponse()
+    configs = plugin_loading()
+    for p_name in configs:
+        configs[p_name] = configs.get(p_name)()
+    (code, _) = plugin_execute(configs, request, response)
+    assert code == RESP_STATUS_CODE_OK
+    (code, _) = plugin_execute(configs, request, None)
+    assert code == RESP_STATUS_CODE_SERVICE_UNAVAILABLE
+    configs["test"] = Test()
+    (code, _) = plugin_execute(configs, request, response)
+    assert code == RESP_STATUS_CODE_BAD_REQUEST