Browse Source

Uvicorn remaining test types (#2868)

* Added uvicorn, an asyncio server for Python 3.

* Include uvicorn in .travis.yml

* Fix content-type on json test case

* Write pid file to /tmp

* Fix content-type of JSON test type

* Add 'fortunes' test type for uvicorn

* Use default port for database connection

* Set database to Postgres in benchmark_config.json

* Resolve postgresql dependancy

* Fix fortunes URL and table name

* Minor correction to 'Additional fortune' text string.

* Fix fortune.html

* Added missing tests for uvicorn

* Remove prints :see_no_evil:
Tom Christie 8 years ago
parent
commit
fb3240943c
2 changed files with 79 additions and 1 deletions
  1. 76 1
      frameworks/Python/uvicorn/app.py
  2. 3 0
      frameworks/Python/uvicorn/benchmark_config.json

+ 76 - 1
frameworks/Python/uvicorn/app.py

@@ -3,7 +3,10 @@ import asyncpg
 import jinja2
 import os
 import ujson as json
+from functools import partial
+from random import randint
 from operator import itemgetter
+from urllib import parse
 
 
 async def setup():
@@ -30,6 +33,25 @@ loop = asyncio.get_event_loop()
 loop.run_until_complete(setup())
 
 
+def get_query_count(query_string):
+    # helper to deal with the querystring passed in
+    queries = parse.parse_qs(query_string).get(b'queries', [None])[0]
+    if queries:
+        try:
+            query_count = int(queries)
+            if query_count < 1:
+                return 1
+            if query_count > 500:
+                return 500
+            return query_count
+        except ValueError:
+            pass
+    return 1
+
+
+random_int = partial(randint, 1, 10000)
+
+
 async def json_endpoint(message, channels):
     content = json.dumps({'message': 'Hello, world!'}).encode('utf-8')
     await channels['reply'].send({
@@ -79,10 +101,63 @@ async def handle_404(message, channels):
     })
 
 
+async def db_endpoint(message, channels):
+    """Test Type 2: Single database object"""
+    async with pool.acquire() as connection:
+        row = await connection.fetchrow('SELECT id, "randomnumber" FROM "world" WHERE id = ' + str(random_int()))
+        world = {'id': row[0], 'randomNumber': row[1]}
+        await channels['reply'].send({
+            'status': 200,
+            'headers': [
+                [b'content-type', b'application/json'],
+            ],
+            'content': json.dumps(world).encode('utf-8')
+        })
+
+
+async def queries_endpoint(message, channels):
+    """Test Type 3: Multiple database queries"""
+    queries = get_query_count(message.get('query_string', {}))
+    async with pool.acquire() as connection:
+        worlds = []
+        for i in range(queries):
+            sql = 'SELECT id, "randomnumber" FROM "world" WHERE id = ' + str(random_int())
+            row = await connection.fetchrow(sql)
+            worlds.append({'id': row[0], 'randomNumber': row[1]})
+        await channels['reply'].send({
+            'status': 200,
+            'headers': [
+                [b'content-type', b'application/json'],
+            ],
+            'content': json.dumps(worlds).encode('utf-8')
+        })
+
+
+async def updates_endpoint(message, channels):
+    """Test 5: Database Updates"""
+    queries = get_query_count(message.get('query_string', {}))
+    async with pool.acquire() as connection:
+        worlds = []
+        for i in range(queries):
+            row = await connection.fetchrow('SELECT id FROM "world" WHERE id=' + str(random_int()))
+            worlds.append({'id': row[0], 'randomNumber': random_int()})
+            await connection.execute('UPDATE "world" SET "randomnumber"=%s WHERE id=%s' % (random_int(), row[0]))
+        await channels['reply'].send({
+            'status': 200,
+            'headers': [
+                [b'content-type', b'application/json'],
+            ],
+            'content': json.dumps(worlds).encode('utf-8')
+        })
+
+
 routes = {
     '/json': json_endpoint,
     '/fortunes': fortunes_endpoint,
-    '/plaintext': plaintext_endpoint
+    '/plaintext': plaintext_endpoint,
+    '/db': db_endpoint,
+    '/queries': queries_endpoint,
+    '/updates': updates_endpoint,
 }
 
 

+ 3 - 0
frameworks/Python/uvicorn/benchmark_config.json

@@ -6,6 +6,9 @@
       "json_url": "/json",
       "fortune_url": "/fortunes",
       "plaintext_url": "/plaintext",
+      "db_url": "/db",
+      "query_url": "/queries?queries=",
+      "update_url": "/updates?queries=",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",