]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
test/mon: add auth change benchmark
authorJosh Durgin <jdurgin@redhat.com>
Tue, 18 Aug 2020 04:16:51 +0000 (04:16 +0000)
committerJosh Durgin <jdurgin@redhat.com>
Thu, 3 Sep 2020 19:13:27 +0000 (19:13 +0000)
Signed-off-by: Josh Durgin <jdurgin@redhat.com>
src/test/mon/bench_auth.py [new file with mode: 0755]

diff --git a/src/test/mon/bench_auth.py b/src/test/mon/bench_auth.py
new file mode 100755 (executable)
index 0000000..143e76c
--- /dev/null
@@ -0,0 +1,104 @@
+#!/usr/bin/python3
+
+import argparse
+import copy
+import json
+import rados
+import time
+import threading
+
+caps_base = ["mon", "profile rbd", "osd", "profile rbd pool=rbd namespace=test"]
+
+def create_users(conn, num_namespaces, num_users):
+    cmd = {'prefix': 'auth get-or-create'}
+
+    for i in range(num_namespaces):
+        caps_base[-1] += ", profile rbd pool=rbd namespace=namespace{}".format(i)
+
+    cmd['caps'] = caps_base
+    for i in range(num_users):
+        cmd['entity'] = "client.{}".format(i)
+        conn.mon_command(json.dumps(cmd), b'')
+
+class Worker(threading.Thread):
+    def __init__(self, conn, num, queue, duration):
+        super().__init__()
+        self.conn = conn
+        self.num = num
+        self.queue = queue
+        self.duration = duration
+
+    def run(self):
+        client = "client.{}".format(self.num)
+        cmd = {'prefix': 'auth caps', 'entity': client}
+        start_time = time.time()
+        num_complete = 0
+        while True:
+            now = time.time()
+            diff = now - start_time
+            if diff > self.duration:
+                self.queue.put((num_complete, diff))
+                return
+            caps = copy.deepcopy(caps_base)
+            caps[-1] += ", profile rbd pool=rbd namespace=namespace{}".format(self.num * 10000 + num_complete)
+            cmd['caps'] = caps
+            cmd_start = time.time()
+            ret, buf, out = self.conn.mon_command(json.dumps(cmd), b'')
+            cmd_end = time.time()
+            if ret != 0:
+                self.queue.put((Exception("{0}: {1}".format(ret, out)), 0))
+                return
+            num_complete += 1
+            print("Process {} finished op {} - latency: {}".format(self.num, num_complete, cmd_end - cmd_start))
+
+def main():
+    parser = argparse.ArgumentParser(description="""
+Benchmark updates to ceph users' capabilities. Run one update at a time in each thread.
+""")
+    parser.add_argument(
+        '-n', '--num-namespaces',
+        type=int,
+        default=300,
+        help='number of namespaces per user',
+    )
+    parser.add_argument(
+        '-t', '--threads',
+        type=int,
+        default=10,
+        help='number of threads (and thus parallel operations) to use',
+    )
+    parser.add_argument(
+        '-d', '--duration',
+        type=int,
+        default=30,
+        help='how long to run, in seconds',
+    )
+    args = parser.parse_args()
+    num_namespaces = args.num_namespaces
+    num_threads = args.threads
+    duration = args.duration
+    workers = []
+    results = []
+    q = queue.Queue()
+    with rados.Rados(conffile=rados.Rados.DEFAULT_CONF_FILES) as conn:
+        create_users(conn, num_namespaces, num_threads)
+        for i in range(num_threads):
+            workers.append(Worker(conn, i, q, duration))
+            workers[-1].start()
+        for i in range(num_threads):
+            num_complete, seconds = q.get()
+            if isinstance(num_complete, Exception):
+                raise num_complete
+            results.append((num_complete, seconds))
+    total = 0
+    total_rate = 0
+    for num, sec in results:
+        print("Completed {} in {} ({} / s)".format(num, sec, num / sec))
+        total += num
+        total_rate += num / sec
+
+    print("Total: ", total)
+    print("Avg rate: ", total_rate / len(results))
+
+if __name__ == '__main__':
+    main()