浏览代码

Various toolset fixes and updates (#8951)

* Fix the MongoDB Docker image
* Update the toolset Docker images to Ubuntu 24.04
* Update Dool to version 1.3.1
* Fix any warnings that are printed by the toolset scripts
Anton Kirilov 1 年之前
父节点
当前提交
bda05af939

+ 12 - 13
Dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:22.04
+FROM ubuntu:24.04
 
 
 ARG DEBIAN_FRONTEND=noninteractive
 ARG DEBIAN_FRONTEND=noninteractive
 # WARNING: DON'T PUT A SPACE AFTER ANY BACKSLASH OR APT WILL BREAK
 # WARNING: DON'T PUT A SPACE AFTER ANY BACKSLASH OR APT WILL BREAK
@@ -20,22 +20,21 @@ RUN apt-get -yqq update && \
       python3 \
       python3 \
       python3-dev \
       python3-dev \
       python3-pip \
       python3-pip \
+      python3-psutil \
+      python3-psycopg2 \
+      python3-requests \
       siege \
       siege \
-      software-properties-common
-
-RUN pip3 install \
+      software-properties-common && \
+    # Ubuntu's equivalent packages are too old and/or broken.
+    pip3 install \
+      --break-system-packages \
       colorama==0.3.1 \
       colorama==0.3.1 \
-      docker==4.0.2 \
-      mysqlclient \
-      psutil \
-      psycopg2-binary \
-      pymongo==3.13.0 \
-      # urllib3 incompatibility:
-      # https://github.com/docker/docker-py/issues/3113#issuecomment-1525500104
-      requests==2.28.1
+      docker==7.0.0 \
+      mysqlclient==2.2.4 \
+      pymongo==3.13.0
 
 
 # Collect resource usage statistics
 # Collect resource usage statistics
-ARG DOOL_VERSION=v1.2.0
+ARG DOOL_VERSION=v1.3.1
 
 
 WORKDIR /tmp
 WORKDIR /tmp
 RUN curl -LSs "https://github.com/scottchiefbaker/dool/archive/${DOOL_VERSION}.tar.gz" | \
 RUN curl -LSs "https://github.com/scottchiefbaker/dool/archive/${DOOL_VERSION}.tar.gz" | \

+ 2 - 6
frameworks/Rust/trillium/benchmark_config.json

@@ -27,9 +27,7 @@
         "notes": "",
         "notes": "",
         "versus": "None",
         "versus": "None",
         "tags": ["verified"]
         "tags": ["verified"]
-      }
-    },
-    {
+      },
       "async-std": {
       "async-std": {
         "db_url": "/db",
         "db_url": "/db",
         "json_url": "/json",
         "json_url": "/json",
@@ -54,9 +52,7 @@
         "notes": "",
         "notes": "",
         "versus": "None",
         "versus": "None",
         "tags": ["verified"]
         "tags": ["verified"]
-      }
-    },
-    {
+      },
       "tokio": {
       "tokio": {
         "db_url": "/db",
         "db_url": "/db",
         "json_url": "/json",
         "json_url": "/json",

+ 6 - 4
toolset/databases/__init__.py

@@ -1,4 +1,4 @@
-import imp
+import importlib
 import re
 import re
 
 
 from colorama import Fore
 from colorama import Fore
@@ -14,14 +14,16 @@ for folder in db_folders:
     # regex that grabs the characters between "toolset/database/"
     # regex that grabs the characters between "toolset/database/"
     # and the final "/" in the db folder string to get the db name
     # and the final "/" in the db folder string to get the db name
     db_name = re.findall(r'.+\/(.+)\/$', folder, re.M)[0]
     db_name = re.findall(r'.+\/(.+)\/$', folder, re.M)[0]
-    # ignore generate __pycache__ folder
+    # ignore generated __pycache__ folder
     if db_name == '__pycache__':
     if db_name == '__pycache__':
         continue
         continue
-    db = imp.load_source("Database", "%s%s.py" % (folder, db_name))
+    spec = importlib.util.spec_from_file_location("Database", "%s%s.py" % (folder, db_name))
+    db = importlib.util.module_from_spec(spec)
+    spec.loader.exec_module(db)
 
 
     if not hasattr(db.Database, "get_current_world_table")\
     if not hasattr(db.Database, "get_current_world_table")\
             or not hasattr(db.Database, "test_connection"):
             or not hasattr(db.Database, "test_connection"):
-        log("Database %s does not implement the required methods" + db_name,
+        log("Database %s does not implement the required methods" % (db_name),
             color=Fore.RED)
             color=Fore.RED)
 
 
     databases[db_name] = db.Database
     databases[db_name] = db.Database

+ 3 - 3
toolset/databases/abstract_database.py

@@ -11,7 +11,7 @@ class AbstractDatabase:
     '''
     '''
     #margin of tolerance on the results (rows read or updated only)
     #margin of tolerance on the results (rows read or updated only)
     margin = 1.011
     margin = 1.011
-    
+
     @classmethod
     @classmethod
     @abc.abstractmethod
     @abc.abstractmethod
     def get_connection(cls, config):
     def get_connection(cls, config):
@@ -94,13 +94,13 @@ class AbstractDatabase:
             process = subprocess.run(shlex.split(
             process = subprocess.run(shlex.split(
                 "siege -c %s -r %s %s -R %s/.siegerc" % (concurrency, count, url, path)),
                 "siege -c %s -r %s %s -R %s/.siegerc" % (concurrency, count, url, path)),
                 stdout = subprocess.PIPE, stderr = subprocess.STDOUT, timeout=20, text=True
                 stdout = subprocess.PIPE, stderr = subprocess.STDOUT, timeout=20, text=True
-            )  
+            )
         except subprocess.TimeoutExpired as e:
         except subprocess.TimeoutExpired as e:
             print("Verification failed: %s" % (e))
             print("Verification failed: %s" % (e))
         else:
         else:
             output = process.stdout
             output = process.stdout
             #Search for failed transactions
             #Search for failed transactions
-            match = re.search('Failed transactions:.*?(\d+)\n', output, re.MULTILINE)
+            match = re.search(r'Failed transactions:.*?(\d+)\n', output, re.MULTILINE)
             if match:
             if match:
                 trans_failures = int(match.group(1))
                 trans_failures = int(match.group(1))
                 print(output)
                 print(output)

+ 0 - 1
toolset/databases/mongodb/create.js

@@ -1,4 +1,3 @@
-disableTelemetry()
 db = db.getSiblingDB('hello_world')
 db = db.getSiblingDB('hello_world')
 db.world.drop()
 db.world.drop()
 for (var i = 1; i <= 10000; i++) {
 for (var i = 1; i <= 10000; i++) {

+ 1 - 1
toolset/databases/mongodb/mongodb.py

@@ -44,7 +44,7 @@ class Database(AbstractDatabase):
             connection = cls.get_connection(config)
             connection = cls.get_connection(config)
             db = connection.hello_world
             db = connection.hello_world
             db.world.find()
             db.world.find()
-            db.close()
+            connection.close()
             return True
             return True
         except:
         except:
             return False
             return False

+ 4 - 2
toolset/test_types/__init__.py

@@ -1,4 +1,4 @@
-import imp
+import importlib
 import re
 import re
 
 
 from glob import glob
 from glob import glob
@@ -14,5 +14,7 @@ for folder in test_type_folders:
     # ignore generated __pycache__ folder
     # ignore generated __pycache__ folder
     if test_type_name == '__pycache__':
     if test_type_name == '__pycache__':
         continue
         continue
-    test_type = imp.load_source("TestType", "%s%s.py" % (folder, test_type_name))
+    spec = importlib.util.spec_from_file_location("TestType", "%s%s.py" % (folder, test_type_name))
+    test_type = importlib.util.module_from_spec(spec)
+    spec.loader.exec_module(test_type)
     test_types[test_type_name] = test_type.TestType
     test_types[test_type_name] = test_type.TestType

+ 28 - 28
toolset/utils/scaffolding.py

@@ -8,7 +8,7 @@ class Scaffolding:
     def __init__(self, benchmarker):
     def __init__(self, benchmarker):
         print("""
         print("""
 -------------------------------------------------------------------------------
 -------------------------------------------------------------------------------
-    This wizard is intended to help build the scaffolding required for a new 
+    This wizard is intended to help build the scaffolding required for a new
     test to be benchmarked.
     test to be benchmarked.
 
 
     From here, you will be prompted for values related to the test you
     From here, you will be prompted for values related to the test you
@@ -87,12 +87,12 @@ class Scaffolding:
 
 
             print("""
             print("""
   That language is not currently in our list of known languages.
   That language is not currently in our list of known languages.
-  
+
   Here is a list of similar languages present in our benchmark suite that you
   Here is a list of similar languages present in our benchmark suite that you
   may have meant:
   may have meant:
 
 
   %s
   %s
-      
+
   Did you mean to add the new language, '%s', to the benchmark suite?
   Did you mean to add the new language, '%s', to the benchmark suite?
       """ % (similar, self.language))
       """ % (similar, self.language))
             valid = self.__prompt_confirm_new_language()
             valid = self.__prompt_confirm_new_language()
@@ -115,8 +115,8 @@ class Scaffolding:
         print("""
         print("""
   The approach of your test implementation.
   The approach of your test implementation.
 
 
-  1) Realistic: Uses the framework with most out-of-the-box functionality 
-                enabled. We consider this realistic because most applications 
+  1) Realistic: Uses the framework with most out-of-the-box functionality
+                enabled. We consider this realistic because most applications
                 built with the framework will leave these features enabled.
                 built with the framework will leave these features enabled.
   2) Stripped:  Removes or outright avoids implementing features that are
   2) Stripped:  Removes or outright avoids implementing features that are
                 unnecessary for the particulars of the benchmark exercise. This
                 unnecessary for the particulars of the benchmark exercise. This
@@ -143,14 +143,14 @@ class Scaffolding:
         print("""
         print("""
   The classification of your test implementation.
   The classification of your test implementation.
 
 
-  1) Fullstack: Robust framework expected to provide high-level functionality 
-                for serving as a web application; for example, ability to 
-                compose views, provide functions for responding with several 
-                data types (json, html, etc), connecting to a database, form 
+  1) Fullstack: Robust framework expected to provide high-level functionality
+                for serving as a web application; for example, ability to
+                compose views, provide functions for responding with several
+                data types (json, html, etc), connecting to a database, form
                 processing, etc.
                 processing, etc.
   2) Micro:     Simple framework expected to provide enough middleware to build
   2) Micro:     Simple framework expected to provide enough middleware to build
-                a robust web application such as request routing and some 
-                simple plumbing, but may not include built-in functionality 
+                a robust web application such as request routing and some
+                simple plumbing, but may not include built-in functionality
                 such as, for example, server-composed views.
                 such as, for example, server-composed views.
   3) Platform:  Barebones infrastructure for servicing HTTP requests, but does
   3) Platform:  Barebones infrastructure for servicing HTTP requests, but does
                 not include a framework at all.
                 not include a framework at all.
@@ -181,7 +181,7 @@ class Scaffolding:
         print("""
         print("""
   The platform of your test implementation.
   The platform of your test implementation.
 
 
-  The platform is the low-level software or API used to host web applications 
+  The platform is the low-level software or API used to host web applications
   for the framework; the platform provides an implementation of the HTTP
   for the framework; the platform provides an implementation of the HTTP
   fundamentals.
   fundamentals.
 
 
@@ -233,11 +233,11 @@ class Scaffolding:
         print("""
         print("""
   How you would classify the ORM (object relational mapper) of your test?
   How you would classify the ORM (object relational mapper) of your test?
 
 
-  1) Full:  A feature-rich ORM which provides functionality for interacting 
-            with a database without writing a query in all but the most edge 
+  1) Full:  A feature-rich ORM which provides functionality for interacting
+            with a database without writing a query in all but the most edge
             cases.
             cases.
   2) Micro: An ORM which provides functionality for interacting with a database
   2) Micro: An ORM which provides functionality for interacting with a database
-            for many trivial operations (querying, updating), but not more 
+            for many trivial operations (querying, updating), but not more
             robust cases (for example, gathering relations).
             robust cases (for example, gathering relations).
   3) Raw:   No ORM; raw database access.
   3) Raw:   No ORM; raw database access.
     """)
     """)
@@ -277,9 +277,9 @@ class Scaffolding:
         print("""
         print("""
   The name of another test (elsewhere in this project) that is a subset of this
   The name of another test (elsewhere in this project) that is a subset of this
   framework.
   framework.
-  This allows for the generation of the framework efficiency chart in the 
+  This allows for the generation of the framework efficiency chart in the
   results web site.
   results web site.
-  For example, Compojure is compared to "servlet" since Compojure is built on 
+  For example, Compojure is compared to "servlet" since Compojure is built on
   the Servlet platform.
   the Servlet platform.
 
 
   Example: Servlet, Wai, Undertow
   Example: Servlet, Wai, Undertow
@@ -344,31 +344,31 @@ class Scaffolding:
     def __edit_scaffold_files(self):
     def __edit_scaffold_files(self):
         for file in os.listdir(os.path.join(self.test_dir)):
         for file in os.listdir(os.path.join(self.test_dir)):
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$NAME", self.name)
+                os.path.join(self.test_dir, file), r'\$NAME', self.name)
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$DISPLAY_NAME",
+                os.path.join(self.test_dir, file), r'\$DISPLAY_NAME',
                 self.display_name)
                 self.display_name)
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$APPROACH", self.approach)
+                os.path.join(self.test_dir, file), r'\$APPROACH', self.approach)
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$CLASSIFICATION",
+                os.path.join(self.test_dir, file), r'\$CLASSIFICATION',
                 self.classification)
                 self.classification)
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$FRAMEWORK",
+                os.path.join(self.test_dir, file), r'\$FRAMEWORK',
                 self.framework)
                 self.framework)
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$LANGUAGE", self.language)
+                os.path.join(self.test_dir, file), r'\$LANGUAGE', self.language)
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$DATABASE", self.database)
+                os.path.join(self.test_dir, file), r'\$DATABASE', self.database)
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$ORM", self.orm)
+                os.path.join(self.test_dir, file), r'\$ORM', self.orm)
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$PLATFORM", self.platform)
+                os.path.join(self.test_dir, file), r'\$PLATFORM', self.platform)
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$WEBSERVER",
+                os.path.join(self.test_dir, file), r'\$WEBSERVER',
                 self.webserver)
                 self.webserver)
             self.__replace_text(
             self.__replace_text(
-                os.path.join(self.test_dir, file), "\$VERSUS", self.versus)
+                os.path.join(self.test_dir, file), r'\$VERSUS', self.versus)
 
 
     def __print_success(self):
     def __print_success(self):
         print("""
         print("""

+ 1 - 1
toolset/wrk/wrk.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:22.04
+FROM ubuntu:24.04
 
 
 # Required scripts for benchmarking
 # Required scripts for benchmarking
 COPY concurrency.sh pipeline.lua pipeline.sh query.sh ./
 COPY concurrency.sh pipeline.lua pipeline.sh query.sh ./