Commits

Kirill Simonov committed 184c34a

Fixed `tweak.timeout`, added tests.

Comments (0)

Files changed (4)

src/htsql_tweak/timeout/__init__.py

 
 
 from htsql.validator import PIntVal
-from htsql.addon import Addon, Parameter
+from htsql.addon import Addon, Parameter, addon_registry
 
 
 class TweakTimeoutAddon(Addon):
     name = 'tweak.timeout'
     hint = """limit query execution time"""
     help = """
-      To help deployments ensure against accidental denial of
-      service, this plugin automatically limits all queries to
-      a given number of seconds (the default is 60s).  This 
-      plugin is currently only supported by PostgreSQL.
+    This addon limits all queries to a given amount of time.
+    Use it to ensure against accidental denial of service caused
+    by complex queries.
+
+    Parameter `timeout` sets the timeout value (the default is 60
+    seconds).
+
+    Currently, only PostgreSQL backend is supported.
     """
 
     parameters = [
-            Parameter('timeout', PIntVal(is_nullable=True),
-                      default=60),
+            Parameter('timeout', PIntVal(is_nullable=True), default=60,
+                      value_name="SEC",
+                      hint="""query timeout, in sec (default: 60)"""),
     ]
 
     @classmethod
     def get_extension(cls, app, attributes):
-        return 'tweak.timeout.%s' % app.htsql.db.engine
+        if app.htsql.db is not None:
+            name = '%s.%s' % (cls.name, app.htsql.db.engine)
+            if name not in addon_registry:
+                raise ImportError("%s is not implemented for %s"
+                                  % (cls.name, app.htsql.db.engine))
+            return name
 
 

src/htsql_tweak/timeout/pgsql/connect.py

 
 class TimeoutConnectPGSQL(ConnectPGSQL):
 
-    def open_connection(self, with_autocommit=False):
-        connection = super(TimeoutConnectPGSQL, self).open_connection(
-                                    with_autocommit=with_autocommit)
+    def open(self):
+        connection = super(TimeoutConnectPGSQL, self).open()
         timeout = context.app.tweak.timeout.timeout
         if timeout is not None:
             cursor = connection.cursor()

test/input/addon.yaml

       tweak.system: {}
   - uri: /pg_class{relname, relkind}?pg_namespace.nspname='ad'
 
+# TWEAK.TIMEOUT - limit query execution time
+- title: tweak.system
+  ifdef: pgsql
+  tests:
+  # Addon description
+  - ctl: [ext, tweak.timeout]
 
+  # Test canceling of a query
+  - load: demo
+    extensions:
+      tweak.timeout:
+        timeout: 3
+  - uri: /count(enrollment.fork().fork())
+    expect: 409
+    ignore: true
+
+

test/output/pgsql.yaml

                              ON ("pg_class"."relnamespace" = "pg_namespace"."oid")
              WHERE ("pg_namespace"."nspname" = 'ad')
              ORDER BY "pg_class"."oid" ASC
+      - id: tweak.system
+        tests:
+        - ctl: [ext, tweak.timeout]
+          stdout: |+
+            TWEAK.TIMEOUT - limit query execution time
+
+            This addon limits all queries to a given amount of time.
+            Use it to ensure against accidental denial of service caused
+            by complex queries.
+
+            Parameter `timeout` sets the timeout value (the default is 60
+            seconds).
+
+            Currently, only PostgreSQL backend is supported.
+
+            Parameters:
+              timeout=SEC              : query timeout, in sec (default: 60)
+
+          exit: 0
+        - uri: /count(enrollment.fork().fork())
+          status: 409 Conflict
+          headers:
+          - [Content-Type, text/plain; charset=UTF-8]
+          body: |+
+            engine failure: failed to execute a database query: canceling statement due to statement timeout
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.