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()