You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2021/09/02 01:24:46 UTC

[apisix] branch master updated: test: track perf test script (#4903)

This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new 05ee435  test: track perf test script (#4903)
05ee435 is described below

commit 05ee435d4d20f65766e588668f8b75b9718a81a2
Author: 罗泽轩 <sp...@gmail.com>
AuthorDate: Thu Sep 2 09:24:38 2021 +0800

    test: track perf test script (#4903)
---
 t/perf/conf/nginx.conf  |  38 ++++++++++
 t/perf/requirements.txt |   1 +
 t/perf/test_http.py     | 185 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 224 insertions(+)

diff --git a/t/perf/conf/nginx.conf b/t/perf/conf/nginx.conf
new file mode 100644
index 0000000..307e725
--- /dev/null
+++ b/t/perf/conf/nginx.conf
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+master_process on;
+daemon off;
+worker_processes 1;
+error_log logs/error.log error;
+pid logs/nginx.pid;
+worker_rlimit_nofile 204800;
+events {
+    worker_connections 204800;
+}
+http {
+    access_log off;
+    server_tokens off;
+    more_clear_headers Server;
+
+    server {
+        listen 6666 reuseport;
+        location / {
+            return 200;
+        }
+    }
+}
diff --git a/t/perf/requirements.txt b/t/perf/requirements.txt
new file mode 100644
index 0000000..2170c1e
--- /dev/null
+++ b/t/perf/requirements.txt
@@ -0,0 +1 @@
+PyYAML=5.3.1
diff --git a/t/perf/test_http.py b/t/perf/test_http.py
new file mode 100755
index 0000000..91fa89d
--- /dev/null
+++ b/t/perf/test_http.py
@@ -0,0 +1,185 @@
+#! /usr/bin/env python
+
+#
+# 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.
+#
+
+# Usage:
+# 1. pip3 install -r t/perf/requirements.txt
+# 2. python3 ./t/perf/test_http.py
+import http.client
+import os
+import shutil
+import subprocess
+import tempfile
+import time
+import unittest
+import yaml
+
+
+RULE_SIZE = 100
+
+
+def create_conf():
+    with open("./conf/config-perf.yaml", "w") as f:
+        conf = {
+            "apisix": {
+                "config_center": "yaml",
+                "enable_admin": False,
+            },
+            "nginx_config": {
+                "worker_processes": 2
+            }
+        }
+        yaml.dump(conf, f)
+
+    routes = []
+    consumers = []
+    for i in range(RULE_SIZE):
+        i = str(i)
+        consumers.append({
+            "username": "jack" + i,
+            "plugins": {
+                "jwt-auth": {
+                    "key": "user-key-" + i,
+                    "secret": "my-secret-key"
+                }
+            }
+        })
+        routes.append({
+            "upstream_id": 1,
+            "uri": "/*",
+            "host": "test" + i + ".com",
+            "plugins": {
+                "limit-count": {
+                    "count": 1e8,
+                    "time_window": 3600,
+                },
+                "jwt-auth": {
+                },
+                "proxy-rewrite": {
+                    "uri": "/" + i,
+                    "headers": {
+                        "X-APISIX-Route": "apisix-" + i
+                    }
+                },
+                "response-rewrite": {
+                    "headers": {
+                        "X-APISIX-Route": "$http_x_apisix_route"
+                    }
+                },
+            },
+        })
+    upstreams = [{
+        "id": 1,
+        "nodes": {
+            "127.0.0.1:6666": 1
+        },
+        "type": "roundrobin"
+    }]
+
+    conf = {}
+    conf["routes"] = routes
+    conf["consumers"] = consumers
+    conf["upstreams"] = upstreams
+    with open("./conf/apisix-perf.yaml", "w") as f:
+        yaml.dump(conf, f)
+        f.write("#END\n")
+
+def apisix_executable():
+    exe = "apisix"
+    if os.path.exists("./bin/apisix"):
+        exe = "./bin/apisix"
+    return exe
+
+def start_apisix():
+    os.environ["APISIX_PROFILE"] = "perf"
+    create_conf()
+    subprocess.run([apisix_executable(), "start"])
+    time.sleep(2)
+
+def stop_apisix():
+    subprocess.run([apisix_executable(), "stop"])
+
+def start_upstream(wd):
+    return subprocess.Popen(["nginx", "-p", wd])
+
+def create_env():
+    temp = tempfile.mkdtemp()
+    print("Create test directory %s" % temp)
+    shutil.copytree("t/perf/conf", os.path.join(temp, "conf"))
+    os.mkdir(os.path.join(temp, "logs"))
+    return temp
+
+
+class TestHTTP(unittest.TestCase):
+
+    def setUp(self):
+        self.duration = os.environ.get("APISIX_PERF_DURATION", "30")
+        self.n_client = os.environ.get("APISIX_PERF_CLIENT", "100")
+        self.n_thread = os.environ.get("APISIX_PERF_THREAD", "2")
+        self.qps = os.environ.get("APISIX_PERF_QPS", "8000")
+
+        start_apisix()
+        tempdir = create_env()
+        self.upstream = start_upstream(tempdir)
+        self.tempdir = tempdir
+
+    def test_perf(self):
+        signs = []
+        conn = http.client.HTTPConnection("127.0.0.1", port=9080)
+        for i in range(RULE_SIZE):
+            i = str(i)
+            conn.request("GET", "/apisix/plugin/jwt/sign?key=user-key-" + i)
+            response = conn.getresponse()
+            if response.status >= 300:
+                print("failed to sign, got: %s" % response.read())
+                conn.close()
+                return
+            signs.append('"' + response.read().decode() + '"')
+        conn.close()
+
+        script = os.path.join(self.tempdir, "wrk.lua")
+        with open(script, "w") as f:
+            sign_list = ",\n".join(signs)
+            s = """
+                signs = {%s}
+                function request()
+                    local i = math.random(%s) - 1
+                    wrk.headers["Host"] = "test" .. i .. ".com"
+                    wrk.headers["Authorization"] = signs[i+1]
+                    return wrk.format()
+                end
+            """ % (sign_list, RULE_SIZE)
+            f.write(s)
+        # We use https://github.com/giltene/wrk2
+        subprocess.run(["wrk",
+            "-d", self.duration,
+            "-c", self.n_client,
+            "-t", self.n_thread,
+            "-s", script,
+            "-R", self.qps,
+            "--u_latency", "http://127.0.0.1:9080/12345",
+        ])
+
+    def tearDown(self):
+        stop_apisix()
+        self.upstream.terminate()
+        self.upstream.wait()
+
+
+if __name__ == '__main__':
+    unittest.main()