lib: prepare the ground for stateful query operations
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 25 Jul 2019 22:07:59 +0000 (18:07 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 26 Jul 2019 23:19:09 +0000 (19:19 -0400)
This patch changes the library (and everything which depends on it) so
that it is possible to make query operations stateful in the future if
needed.

Without this patch, a query operation can return the
`BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN` status. The query
executor's user can then retry the operation until it works, or abandon.
However, there's no way for this query function to keep state between
calls, so the process starts over every time whereas it could have
progressed otherwise (for example, a temporary unresponsive network).

Library changes
===============
This patch does two things to address the limitation above:

* It makes bt_query_executor_create() accept the component class, query
  object, and query parameters. It also removes those parameters, as
  well as the logging level, from bt_query_executor_query().

  This ensures that a given query executor is dedicated to a specific
  query operation. Once you create a query executor, you cannot change
  the target component class, query object, and query parameters
  afterwards.

  The initial query executor's logging level is `BT_LOGGING_LEVEL_NONE`.
  You can set it before you call bt_query_executor_query() with
  bt_query_executor_set_logging_level().

  Internally, the query executor keeps a reference on the component
  class, a copy of the query object, and a reference on the query
  parameters.

* It makes a query method receive a private query executor
  (`bt_private_query_executor *`) object, and not receive the logging
  level.

  A private query executor is a private view of the query executor. This
  is where we can eventually add bt_private_query_executor_set_data()
  and bt_private_query_executor_get_data() to make the query operation
  stateful. From the query method's point of view, the private query
  executor is borrowed: there are no bt_private_query_executor_get_ref()
  and bt_private_query_executor_put_ref() functions.

  You can go from a private query executor to a constant query executor
  with bt_private_query_executor_as_query_executor_const(). This is how
  you can get the query executor's current logging level with
  bt_query_executor_get_logging_level().

  To keep the changes minimal, query methods still receive the object
  and parameters every time. They are guaranteed, however, that for the
  same query executor, they remain unchanged. This guarantee is not
  relevant now anyway as there's no way to set and get private data.

Python bindings changes
=======================
* The new `_QueryExecutorCommon` class contains the common properties of
  a query executor and a private query executor (`is_interrupted` and
  `logging_level`). It requires its subclasses to implement the
  _as_query_executor_ptr() method to get the query executor pointer.

* `QueryExecutor` inherits `_QueryExecutorCommon`.

  You now build a query executor with the component class, object, and
  (optional) query parameters:

      query_exec = bt2.QueryExecutor(MySrc, 'avail-servers',
                                     {'blacklist': ['node67']})

  You now call the query() method without parameters:

      query_exec.query()

  You can set the logging level with:

      query_exec.logging_level = bt2.LoggingLevel.TRACE

* The new `_PrivateQueryExecutor` class inherits `_QueryExecutorCommon`.

  An instance of `_PrivateQueryExecutor` is passed to the query method
  during a query operation.

  Once the user's query method returns, _bt_query_from_native()
  invalidates the private query executor in case the user kept a
  reference somewhere. Calling any method of an invalid private query
  executor raises `RuntimeError`.

CLI changes
===========
To centralize how query operations are performed in the CLI, all the
sites which need to query use the new cli_query(), implemented in
`src/cli/babeltrace2-query.c`.

cli_query() is similar to the static query() function in
`babeltrace2.c`, which already existed, but it accepts the logging level
directly and returns `bt_query_executor_query_status`.

The static query() function still exists, but calls cli_query() now.

The automatic source discovery feature now uses cli_query() instead of
creating its own query executor.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I3c254325817c2c0091b6c4f0030bc7020443b8e0
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1787
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
34 files changed:
include/Makefile.am
include/babeltrace2/babeltrace.h
include/babeltrace2/graph/component-class-filter.h
include/babeltrace2/graph/component-class-sink.h
include/babeltrace2/graph/component-class-source.h
include/babeltrace2/graph/private-query-executor.h [new file with mode: 0644]
include/babeltrace2/graph/query-executor-const.h
include/babeltrace2/graph/query-executor.h
include/babeltrace2/types.h
src/bindings/python/bt2/bt2/component.py
src/bindings/python/bt2/bt2/native_bt_component_class.i
src/bindings/python/bt2/bt2/native_bt_query_exec.i
src/bindings/python/bt2/bt2/query_executor.py
src/bindings/python/bt2/bt2/trace_collection_message_iterator.py
src/cli/Makefile.am
src/cli/babeltrace2-cfg-cli-args.c
src/cli/babeltrace2-cfg-src-auto-disc.c
src/cli/babeltrace2-plugins.c
src/cli/babeltrace2-query.c [new file with mode: 0644]
src/cli/babeltrace2-query.h [new file with mode: 0644]
src/cli/babeltrace2.c
src/lib/graph/query-executor.c
src/lib/graph/query-executor.h
src/plugins/ctf/fs-src/fs.c
src/plugins/ctf/fs-src/fs.h
src/plugins/ctf/lttng-live/lttng-live.c
src/plugins/ctf/lttng-live/lttng-live.h
tests/bindings/python/bt2/test_component_class.py
tests/bindings/python/bt2/test_error.py
tests/bindings/python/bt2/test_query_executor.py
tests/data/cli/auto-source-discovery/bt_plugin_test.py
tests/lib/plugin.c
tests/lib/test-plugin-plugins/sfs.c
tests/plugins/src.ctf.fs/query/test_query_trace_info.py

index 4baed59b982e60b8c17cad0248472b93fa96886c..bddc8a5dba8f0d4b2dcc56d47f946b9c6c9dad34 100644 (file)
@@ -112,6 +112,7 @@ babeltrace2graphinclude_HEADERS = \
        babeltrace2/graph/port-input-const.h \
        babeltrace2/graph/port-output-const.h \
        babeltrace2/graph/port-output-message-iterator.h \
+       babeltrace2/graph/private-query-executor.h \
        babeltrace2/graph/query-executor-const.h \
        babeltrace2/graph/query-executor.h \
        babeltrace2/graph/self-component-class-filter.h \
index d4613ca45861bb42a5261568f20e88051d889470..edd45d76d3380c3c259156fe93d91475e1f28cd4 100644 (file)
 #include <babeltrace2/graph/port-output-const.h>
 
 /* Query executor API */
+#include <babeltrace2/graph/private-query-executor.h>
 #include <babeltrace2/graph/query-executor-const.h>
 #include <babeltrace2/graph/query-executor.h>
 
index 1b1bc66aa3524bcef8783f3c9271bfc020860ad9..08c0ff48c2dddf7be00b598f742d359e7203ab82 100644 (file)
@@ -82,9 +82,9 @@ typedef bt_bool
 typedef bt_component_class_query_method_status
 (*bt_component_class_filter_query_method)(
                bt_self_component_class_filter *comp_class,
-               const bt_query_executor *query_executor,
+               bt_private_query_executor *query_executor,
                const char *object, const bt_value *params,
-               bt_logging_level logging_level, const bt_value **result);
+               const bt_value **result);
 
 typedef bt_component_class_port_connected_method_status
 (*bt_component_class_filter_input_port_connected_method)(
index 05bbd3705ca079899778bc0e336f3944b787286b..044895cfae03609c9d855322b4f5d7ea59ee23bd 100644 (file)
@@ -48,9 +48,8 @@ typedef void (*bt_component_class_sink_finalize_method)(
 typedef bt_component_class_query_method_status
 (*bt_component_class_sink_query_method)(
                bt_self_component_class_sink *comp_class,
-               const bt_query_executor *query_executor,
+               bt_private_query_executor *query_executor,
                const char *object, const bt_value *params,
-               bt_logging_level logging_level,
                const bt_value **result);
 
 typedef bt_component_class_port_connected_method_status
index 03648e2a72f0cfd7df056146f0959429c1a6d02a..54cc2330580dbe4f9b3011be892f1f658a1a336f 100644 (file)
@@ -82,9 +82,8 @@ typedef bt_bool
 typedef bt_component_class_query_method_status
 (*bt_component_class_source_query_method)(
                bt_self_component_class_source *comp_class,
-               const bt_query_executor *query_executor,
+               bt_private_query_executor *query_executor,
                const char *object, const bt_value *params,
-               bt_logging_level logging_level,
                const bt_value **result);
 
 typedef bt_component_class_port_connected_method_status
diff --git a/include/babeltrace2/graph/private-query-executor.h b/include/babeltrace2/graph/private-query-executor.h
new file mode 100644 (file)
index 0000000..348d30d
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef BABELTRACE2_GRAPH_PRIVATE_QUERY_EXECUTOR_H
+#define BABELTRACE2_GRAPH_PRIVATE_QUERY_EXECUTOR_H
+
+/*
+ * Copyright (c) 2010-2019 EfficiOS Inc. and Linux Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __BT_IN_BABELTRACE_H
+# error "Please include <babeltrace2/babeltrace.h> instead."
+#endif
+
+#include <babeltrace2/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline
+const bt_query_executor *
+bt_private_query_executor_as_query_executor_const(
+               bt_private_query_executor *query_executor)
+{
+       return __BT_UPCAST_CONST(bt_query_executor, query_executor);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE2_GRAPH_PRIVATE_QUERY_EXECUTOR_H */
index 9b6be7e5bc1133b04f5822a464b9d2cfcf5b824b..a857ed7071817715d485485a2a0dc04ff3121abe 100644 (file)
@@ -36,6 +36,9 @@ extern "C" {
 extern bt_bool bt_query_executor_is_interrupted(
                const bt_query_executor *query_executor);
 
+extern bt_logging_level bt_query_executor_get_logging_level(
+               const bt_query_executor *query_executor);
+
 extern void bt_query_executor_get_ref(const bt_query_executor *query_executor);
 
 extern void bt_query_executor_put_ref(const bt_query_executor *query_executor);
index 460899bdeecd55f5a755f6b79ad85397f13d7e4f..4ffc4ec42977246b51cff2c6991eae0dd4c67be0 100644 (file)
@@ -35,7 +35,9 @@ extern "C" {
 #endif
 
 extern
-bt_query_executor *bt_query_executor_create(void);
+bt_query_executor *bt_query_executor_create(
+               const bt_component_class *component_class, const char *object,
+               const bt_value *params);
 
 typedef enum bt_query_executor_query_status {
        BT_QUERY_EXECUTOR_QUERY_STATUS_OK               = __BT_FUNC_STATUS_OK,
@@ -47,10 +49,7 @@ typedef enum bt_query_executor_query_status {
 
 extern
 bt_query_executor_query_status bt_query_executor_query(
-               bt_query_executor *query_executor,
-               const bt_component_class *component_class,
-               const char *object, const bt_value *params,
-               bt_logging_level logging_level, const bt_value **result);
+               bt_query_executor *query_executor, const bt_value **result);
 
 typedef enum bt_query_executor_add_interrupter_status {
        BT_QUERY_EXECUTOR_ADD_INTERRUPTER_STATUS_OK     = __BT_FUNC_STATUS_OK,
@@ -63,6 +62,14 @@ bt_query_executor_add_interrupter(bt_query_executor *query_executor,
 
 extern void bt_query_executor_interrupt(bt_query_executor *query_executor);
 
+typedef enum bt_query_executor_set_logging_level_status {
+       BT_QUERY_EXECUTOR_SET_LOGGING_LEVEL_STATUS_OK   = __BT_FUNC_STATUS_OK,
+} bt_query_executor_set_logging_level_status;
+
+extern bt_query_executor_set_logging_level_status
+bt_query_executor_set_logging_level(bt_query_executor *query_executor,
+               bt_logging_level logging_level);
+
 #ifdef __cplusplus
 }
 #endif
index 7f40fd8c3d2654f78bf2ce598d1cc87ab8f67c7a..54bfc4853ffc7814143dc0534d827ae75137746b 100644 (file)
@@ -129,6 +129,7 @@ typedef struct bt_port bt_port;
 typedef struct bt_port_input bt_port_input;
 typedef struct bt_port_output bt_port_output;
 typedef struct bt_port_output_message_iterator bt_port_output_message_iterator;
+typedef struct bt_private_query_executor bt_private_query_executor;
 typedef struct bt_query_executor bt_query_executor;
 typedef struct bt_self_component bt_self_component;
 typedef struct bt_self_component_class bt_self_component_class;
index 865ff13598523cc197ec8607d6351339ea14f339..a057019aa379c37cb7af3f471b2fe46cb070a146 100644 (file)
@@ -573,7 +573,7 @@ class _UserComponentType(type):
     def addr(cls):
         return int(cls._bt_cc_ptr)
 
-    def _bt_query_from_native(cls, query_exec_ptr, obj, params_ptr, log_level):
+    def _bt_query_from_native(cls, priv_query_exec_ptr, obj, params_ptr):
         # this can raise, in which case the native call to
         # bt_component_class_query() returns NULL
         if params_ptr is not None:
@@ -581,12 +581,19 @@ class _UserComponentType(type):
         else:
             params = None
 
-        query_exec = bt2_query_executor.QueryExecutor._create_from_ptr_and_get_ref(
-            query_exec_ptr
-        )
+        priv_query_exec = bt2_query_executor._PrivateQueryExecutor(priv_query_exec_ptr)
 
-        # this can raise, but the native side checks the exception
-        results = cls._user_query(query_exec, obj, params, log_level)
+        try:
+            # this can raise, but the native side checks the exception
+            results = cls._user_query(priv_query_exec, obj, params)
+        finally:
+            # the private query executor is a private view on the query
+            # executor; it's not a shared object (the library does not
+            # offer an API to get/put a reference, just like "self"
+            # objects) from this query's point of view, so invalidate
+            # the object in case the user kept a reference and uses it
+            # later
+            priv_query_exec._invalidate()
 
         # this can raise, but the native side checks the exception
         results = bt2.create_value(results)
@@ -594,15 +601,13 @@ class _UserComponentType(type):
         if results is None:
             results_ptr = native_bt.value_null
         else:
-            # return new reference
             results_ptr = results._ptr
 
-        # We return a new reference.
+        # return new reference
         bt2_value._Value._get_ref(results_ptr)
-
         return int(results_ptr)
 
-    def _user_query(cls, query_executor, obj, params, log_level):
+    def _user_query(cls, priv_query_executor, obj, params):
         raise bt2.UnknownObject
 
     def _bt_component_class_ptr(self):
index fffb4d7ff4a825d0e33ed43e6bd5996a0c013ec4..784b0f402daa371b62d6758ee329a12d1ae8032b 100644 (file)
@@ -862,18 +862,22 @@ static
 bt_component_class_query_method_status component_class_query(
                const bt_component_class *component_class,
                bt_self_component_class *self_component_class,
-               const bt_query_executor *query_executor,
+               bt_private_query_executor *priv_query_executor,
                const char *object, const bt_value *params,
-               bt_logging_level log_level,
                const bt_value **result)
 {
        PyObject *py_cls = NULL;
        PyObject *py_params_ptr = NULL;
-       PyObject *py_query_exec_ptr = NULL;
+       PyObject *py_priv_query_exec_ptr = NULL;
        PyObject *py_query_func = NULL;
        PyObject *py_object = NULL;
        PyObject *py_results_addr = NULL;
        bt_component_class_query_method_status status = __BT_FUNC_STATUS_OK;
+       const bt_query_executor *query_exec =
+               bt_private_query_executor_as_query_executor_const(
+                       priv_query_executor);
+       bt_logging_level log_level =
+               bt_query_executor_get_logging_level(query_exec);
 
        py_cls = lookup_cc_ptr_to_py_cls(component_class);
        if (!py_cls) {
@@ -891,9 +895,10 @@ bt_component_class_query_method_status component_class_query(
                goto error;
        }
 
-       py_query_exec_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(query_executor),
-               SWIGTYPE_p_bt_query_executor, 0);
-       if (!py_query_exec_ptr) {
+       py_priv_query_exec_ptr = SWIG_NewPointerObj(
+               SWIG_as_voidptr(priv_query_executor),
+               SWIGTYPE_p_bt_private_query_executor, 0);
+       if (!py_priv_query_exec_ptr) {
                BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR, log_level, BT_LOG_TAG,
                        "Failed to create a SWIG pointer object.");
                goto error;
@@ -907,8 +912,8 @@ bt_component_class_query_method_status component_class_query(
        }
 
        py_results_addr = PyObject_CallMethod(py_cls,
-               "_bt_query_from_native", "(OOOi)", py_query_exec_ptr,
-               py_object, py_params_ptr, (int) log_level);
+               "_bt_query_from_native", "(OOO)", py_priv_query_exec_ptr,
+               py_object, py_params_ptr);
        if (!py_results_addr) {
                BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING, log_level, BT_LOG_TAG,
                        "Failed to call Python class's _bt_query_from_native() method: "
@@ -934,7 +939,7 @@ error:
 
 end:
        Py_XDECREF(py_params_ptr);
-       Py_XDECREF(py_query_exec_ptr);
+       Py_XDECREF(py_priv_query_exec_ptr);
        Py_XDECREF(py_query_func);
        Py_XDECREF(py_object);
        Py_XDECREF(py_results_addr);
@@ -944,46 +949,46 @@ end:
 static
 bt_component_class_query_method_status component_class_source_query(
                bt_self_component_class_source *self_component_class_source,
-               const bt_query_executor *query_executor,
+               bt_private_query_executor *priv_query_executor,
                const char *object, const bt_value *params,
-               bt_logging_level log_level,
                const bt_value **result)
 {
        const bt_component_class_source *component_class_source = bt_self_component_class_source_as_component_class_source(self_component_class_source);
        const bt_component_class *component_class = bt_component_class_source_as_component_class_const(component_class_source);
        bt_self_component_class *self_component_class = bt_self_component_class_source_as_self_component_class(self_component_class_source);
 
-       return component_class_query(component_class, self_component_class, query_executor, object, params, log_level, result);
+       return component_class_query(component_class, self_component_class,
+               priv_query_executor, object, params, result);
 }
 
 static
 bt_component_class_query_method_status component_class_filter_query(
                bt_self_component_class_filter *self_component_class_filter,
-               const bt_query_executor *query_executor,
+               bt_private_query_executor *priv_query_executor,
                const char *object, const bt_value *params,
-               bt_logging_level log_level,
                const bt_value **result)
 {
        const bt_component_class_filter *component_class_filter = bt_self_component_class_filter_as_component_class_filter(self_component_class_filter);
        const bt_component_class *component_class = bt_component_class_filter_as_component_class_const(component_class_filter);
        bt_self_component_class *self_component_class = bt_self_component_class_filter_as_self_component_class(self_component_class_filter);
 
-       return component_class_query(component_class, self_component_class, query_executor, object, params, log_level, result);
+       return component_class_query(component_class, self_component_class,
+               priv_query_executor, object, params, result);
 }
 
 static
 bt_component_class_query_method_status component_class_sink_query(
                bt_self_component_class_sink *self_component_class_sink,
-               const bt_query_executor *query_executor,
+               bt_private_query_executor *priv_query_executor,
                const char *object, const bt_value *params,
-               bt_logging_level log_level,
                const bt_value **result)
 {
        const bt_component_class_sink *component_class_sink = bt_self_component_class_sink_as_component_class_sink(self_component_class_sink);
        const bt_component_class *component_class = bt_component_class_sink_as_component_class_const(component_class_sink);
        bt_self_component_class *self_component_class = bt_self_component_class_sink_as_self_component_class(self_component_class_sink);
 
-       return component_class_query(component_class, self_component_class, query_executor, object, params, log_level, result);
+       return component_class_query(component_class, self_component_class,
+               priv_query_executor, object, params, result);
 }
 
 static
index c8ccb29bb7ae8811964604bb92803bb0ef126557..a69d7a586197f26d248522e6079274f2758662d0 100644 (file)
@@ -22,5 +22,6 @@
  * THE SOFTWARE.
  */
 
+%include <babeltrace2/graph/private-query-executor.h>
 %include <babeltrace2/graph/query-executor-const.h>
 %include <babeltrace2/graph/query-executor.h>
index 146a2cf461b81b2cb59633d3e3049b8f7952e9ef..77b5857496fbae9b2143892734f5bb94c01df541 100644 (file)
@@ -28,37 +28,29 @@ from bt2 import value as bt2_value
 import bt2
 
 
-class QueryExecutor(object._SharedObject):
-    _get_ref = staticmethod(native_bt.query_executor_get_ref)
-    _put_ref = staticmethod(native_bt.query_executor_put_ref)
+class _QueryExecutorCommon:
+    @property
+    def _common_ptr(self):
+        return self._as_query_executor_ptr()
 
-    def __init__(self):
-        ptr = native_bt.query_executor_create()
+    @property
+    def is_interrupted(self):
+        is_interrupted = native_bt.query_executor_is_interrupted(self._common_ptr)
+        return bool(is_interrupted)
 
-        if ptr is None:
-            raise bt2._MemoryError('cannot create query executor object')
+    @property
+    def logging_level(self):
+        return native_bt.query_executor_get_logging_level(self._common_ptr)
 
-        super().__init__(ptr)
 
-    def add_interrupter(self, interrupter):
-        utils._check_type(interrupter, bt2_interrupter.Interrupter)
-        native_bt.query_executor_add_interrupter(self._ptr, interrupter._ptr)
+class QueryExecutor(object._SharedObject, _QueryExecutorCommon):
+    _get_ref = staticmethod(native_bt.query_executor_get_ref)
+    _put_ref = staticmethod(native_bt.query_executor_put_ref)
 
-    def interrupt(self):
-        native_bt.query_executor_interrupt(self._ptr)
+    def _as_query_executor_ptr(self):
+        return self._ptr
 
-    @property
-    def is_interrupted(self):
-        is_interrupted = native_bt.query_executor_is_interrupted(self._ptr)
-        return bool(is_interrupted)
-
-    def query(
-        self,
-        component_class,
-        object,
-        params=None,
-        logging_level=bt2_logging.LoggingLevel.NONE,
-    ):
+    def __init__(self, component_class, object, params=None):
         if not isinstance(component_class, bt2_component._ComponentClass):
             err = False
 
@@ -80,12 +72,54 @@ class QueryExecutor(object._SharedObject):
             params = bt2.create_value(params)
             params_ptr = params._ptr
 
-        utils._check_log_level(logging_level)
         cc_ptr = component_class._bt_component_class_ptr()
+        assert cc_ptr is not None
+        ptr = native_bt.query_executor_create(cc_ptr, object, params_ptr)
+
+        if ptr is None:
+            raise bt2._MemoryError('cannot create query executor object')
+
+        super().__init__(ptr)
+
+    def add_interrupter(self, interrupter):
+        utils._check_type(interrupter, bt2_interrupter.Interrupter)
+        native_bt.query_executor_add_interrupter(self._ptr, interrupter._ptr)
+
+    def interrupt(self):
+        native_bt.query_executor_interrupt(self._ptr)
+
+    def _set_logging_level(self, log_level):
+        utils._check_log_level(log_level)
+        status = native_bt.query_executor_set_logging_level(self._ptr, log_level)
+        utils._handle_func_status(status, "cannot set query executor's logging level")
 
-        status, result_ptr = native_bt.query_executor_query(
-            self._ptr, cc_ptr, object, params_ptr, logging_level
-        )
+    logging_level = property(
+        fget=_QueryExecutorCommon.logging_level, fset=_set_logging_level
+    )
+
+    @property
+    def is_interrupted(self):
+        is_interrupted = native_bt.query_executor_is_interrupted(self._ptr)
+        return bool(is_interrupted)
+
+    def query(self):
+        status, result_ptr = native_bt.query_executor_query(self._ptr)
         utils._handle_func_status(status, 'cannot query component class')
-        assert result_ptr
+        assert result_ptr is not None
         return bt2_value._create_from_ptr(result_ptr)
+
+
+class _PrivateQueryExecutor(_QueryExecutorCommon):
+    def __init__(self, ptr):
+        self._ptr = ptr
+
+    def _check_validity(self):
+        if self._ptr is None:
+            raise RuntimeError('this object is not valid anymore')
+
+    def _as_query_executor_ptr(self):
+        self._check_validity()
+        return native_bt.private_query_executor_as_query_executor_const(self._ptr)
+
+    def _invalidate(self):
+        self._ptr = None
index f7b819d9af1c59c6579abd855fe5ca66f944a94f..fd579068e10abab6538c559fc80d546951158f4c 100644 (file)
@@ -160,10 +160,10 @@ class TraceCollectionMessageIterator(bt2_message_iterator._MessageIterator):
         # query the port's component for the `babeltrace.trace-info`
         # object which contains the stream intersection range for each
         # exposed trace
-        query_exec = bt2.QueryExecutor()
-        trace_info_res = query_exec.query(
+        query_exec = bt2.QueryExecutor(
             src_comp_and_spec.comp.cls, 'babeltrace.trace-info', params
         )
+        trace_info_res = query_exec.query()
         begin = None
         end = None
 
index 8c8717571aa9ef445cd94dac675bf4243fe71397..fdee56c106c5b0e7b9f1a618ece3dbab366aa821 100644 (file)
@@ -36,6 +36,8 @@ babeltrace2_bin_SOURCES = \
        babeltrace2-cfg-src-auto-disc.h \
        babeltrace2-plugins.c \
        babeltrace2-plugins.h \
+       babeltrace2-query.c \
+       babeltrace2-query.h \
        logging.c \
        logging.h
 
index 8bf2c25439ddeaf33e41cf2e40f484e36a209080..49ceca46b2e6a558e43e7ff61c9a64880f25f258 100644 (file)
@@ -22,7 +22,7 @@
  * SOFTWARE.
  */
 
-#define BT_LOG_TAG "CLI-CFG-CLI-ARGS"
+#define BT_LOG_TAG "CLI/CFG-CLI-ARGS"
 #include "logging.h"
 
 #include <errno.h>
index 22aae2dafedcfe7f49417cdf0a7ce95a1b4831eb..1ffb1005e5fdc94cb05062265c3922f105ef3207 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "babeltrace2-cfg-src-auto-disc.h"
 #include "babeltrace2-plugins.h"
+#include "babeltrace2-query.h"
 #include "common/common.h"
 
 /* Finalize and free a `struct auto_source_discovery_result`. */
@@ -241,8 +242,7 @@ end:
  */
 static
 int support_info_query_all_sources(const char *input,
-               const char *input_type,
-               bt_query_executor *query_executor, size_t plugin_count,
+               const char *input_type, size_t plugin_count,
                const char *plugin_restrict,
                const char *component_class_restrict,
                enum bt_logging_level log_level,
@@ -319,8 +319,9 @@ int support_info_query_all_sources(const char *input,
                                "type=%s", plugin_name, source_cc_name, input, input_type);
 
                        BT_VALUE_PUT_REF_AND_RESET(query_result);
-                       query_status = bt_query_executor_query(query_executor, cc, "babeltrace.support-info",
-                               query_params, log_level, &query_result);
+                       query_status = cli_query(cc, "babeltrace.support-info",
+                               query_params, log_level, NULL, &query_result,
+                               NULL);
 
                        if (query_status == BT_QUERY_EXECUTOR_QUERY_STATUS_OK) {
                                double weight;
@@ -470,21 +471,19 @@ end:
 
 static
 int auto_discover_source_for_input_as_string(const char *input,
-               bt_query_executor *query_executor, size_t plugin_count,
-               const char *plugin_restrict,
+               size_t plugin_count, const char *plugin_restrict,
                const char *component_class_restrict,
                enum bt_logging_level log_level,
                struct auto_source_discovery *auto_disc)
 {
        return support_info_query_all_sources(input, "string",
-               query_executor, plugin_count, plugin_restrict,
-               component_class_restrict, log_level, auto_disc);
+               plugin_count, plugin_restrict, component_class_restrict,
+               log_level, auto_disc);
 }
 
 static
 int auto_discover_source_for_input_as_dir_or_file_rec(GString *input,
-               bt_query_executor *query_executor, size_t plugin_count,
-               const char *plugin_restrict,
+               size_t plugin_count, const char *plugin_restrict,
                const char *component_class_restrict,
                enum bt_logging_level log_level,
                struct auto_source_discovery *auto_disc)
@@ -495,7 +494,7 @@ int auto_discover_source_for_input_as_dir_or_file_rec(GString *input,
        if (g_file_test(input->str, G_FILE_TEST_IS_REGULAR)) {
                /* It's a file. */
                status = support_info_query_all_sources(input->str,
-                       "file", query_executor, plugin_count,
+                       "file", plugin_count,
                        plugin_restrict, component_class_restrict, log_level, auto_disc);
        } else if (g_file_test(input->str, G_FILE_TEST_IS_DIR)) {
                GDir *dir;
@@ -505,7 +504,7 @@ int auto_discover_source_for_input_as_dir_or_file_rec(GString *input,
 
                /* It's a directory. */
                status = support_info_query_all_sources(input->str,
-                       "directory", query_executor, plugin_count,
+                       "directory", plugin_count,
                        plugin_restrict, component_class_restrict, log_level,
                        auto_disc);
 
@@ -546,7 +545,7 @@ int auto_discover_source_for_input_as_dir_or_file_rec(GString *input,
                                g_string_append(input, dirent);
 
                                status = auto_discover_source_for_input_as_dir_or_file_rec(
-                                       input, query_executor, plugin_count,
+                                       input, plugin_count,
                                        plugin_restrict, component_class_restrict,
                                        log_level, auto_disc);
 
@@ -596,8 +595,7 @@ end:
 
 static
 int auto_discover_source_for_input_as_dir_or_file(const char *input,
-               bt_query_executor *query_executor, size_t plugin_count,
-               const char *plugin_restrict,
+               size_t plugin_count, const char *plugin_restrict,
                const char *component_class_restrict,
                enum bt_logging_level log_level,
                struct auto_source_discovery *auto_disc)
@@ -612,7 +610,7 @@ int auto_discover_source_for_input_as_dir_or_file(const char *input,
        }
 
        status = auto_discover_source_for_input_as_dir_or_file_rec(
-               mutable_input, query_executor, plugin_count, plugin_restrict,
+               mutable_input, plugin_count, plugin_restrict,
                component_class_restrict, log_level, auto_disc);
 
        g_string_free(mutable_input, TRUE);
@@ -631,7 +629,6 @@ int auto_discover_source_components(
        uint64_t i_inputs, input_count;
        int status;
        size_t plugin_count;
-       bt_query_executor *query_executor = NULL;
 
        input_count = bt_value_array_get_size(inputs);
 
@@ -642,19 +639,13 @@ int auto_discover_source_components(
 
        plugin_count = get_loaded_plugins_count();
 
-       query_executor = bt_query_executor_create();
-       if (!query_executor) {
-               BT_CLI_LOGE_APPEND_CAUSE("Failed to allocate a query executor.");
-               goto end;
-       }
-
        for (i_inputs = 0; i_inputs < input_count; i_inputs++) {
                const bt_value *input_value;
                const char *input;
 
                input_value = bt_value_array_borrow_element_by_index_const(inputs, i_inputs);
                input = bt_value_string_get(input_value);
-               status = auto_discover_source_for_input_as_string(input, query_executor,
+               status = auto_discover_source_for_input_as_string(input,
                        plugin_count, plugin_restrict, component_class_restrict,
                        log_level, auto_disc);
                if (status < 0) {
@@ -666,8 +657,8 @@ int auto_discover_source_components(
                }
 
                status = auto_discover_source_for_input_as_dir_or_file(input,
-                       query_executor, plugin_count, plugin_restrict,
-                       component_class_restrict, log_level, auto_disc);
+                       plugin_count, plugin_restrict, component_class_restrict,
+                       log_level, auto_disc);
                if (status < 0) {
                        /* Fatal error. */
                        goto end;
@@ -683,6 +674,5 @@ int auto_discover_source_components(
 
        status = 0;
 end:
-       bt_query_executor_put_ref(query_executor);
        return status;
 }
index cc950ff21ff1ee3b87bc007a4b05b578e9dca8b3..73123408a542a88045f22c340e489166e9f6a722 100644 (file)
@@ -22,7 +22,7 @@
  * SOFTWARE.
  */
 
-#define BT_LOG_TAG "CLI"
+#define BT_LOG_TAG "CLI/PLUGINS"
 #include "logging.h"
 
 #include "babeltrace2-plugins.h"
diff --git a/src/cli/babeltrace2-query.c b/src/cli/babeltrace2-query.c
new file mode 100644 (file)
index 0000000..4455bcc
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2016-2019 EfficiOS Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "CLI/QUERY"
+#include "logging.h"
+
+#include <babeltrace2/babeltrace.h>
+
+#include "common/common.h"
+
+#include "babeltrace2-query.h"
+
+static
+void set_fail_reason(const char **fail_reason, const char *reason)
+{
+       if (fail_reason) {
+               *fail_reason = reason;
+       }
+}
+
+BT_HIDDEN
+bt_query_executor_query_status cli_query(const bt_component_class *comp_cls,
+               const char *obj, const bt_value *params,
+               bt_logging_level log_level, const bt_interrupter *interrupter,
+               const bt_value **user_result, const char **fail_reason)
+{
+       const bt_value *result = NULL;
+       bt_query_executor_query_status status;
+       bt_query_executor *query_exec;
+
+       set_fail_reason(fail_reason, "unknown error");
+       BT_ASSERT(user_result);
+       query_exec = bt_query_executor_create(comp_cls, obj, params);
+       if (!query_exec) {
+               BT_CLI_LOGE_APPEND_CAUSE("Cannot create a query executor.");
+               goto error;
+       }
+
+       if (bt_query_executor_set_logging_level(query_exec, log_level) !=
+                       BT_QUERY_EXECUTOR_SET_LOGGING_LEVEL_STATUS_OK) {
+               BT_CLI_LOGE_APPEND_CAUSE(
+                       "Cannot set query executor's logging level: "
+                       "log-level=%s",
+                       bt_common_logging_level_string(log_level));
+               goto error;
+       }
+
+       if (interrupter) {
+               if (bt_query_executor_add_interrupter(query_exec,
+                               interrupter) !=
+                               BT_QUERY_EXECUTOR_ADD_INTERRUPTER_STATUS_OK) {
+                       BT_CLI_LOGE_APPEND_CAUSE(
+                               "Cannot add interrupter to query executor.");
+                       goto error;
+               }
+       }
+
+       while (true) {
+               status = bt_query_executor_query(query_exec, &result);
+               switch (status) {
+               case BT_QUERY_EXECUTOR_QUERY_STATUS_OK:
+                       goto ok;
+               case BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN:
+               {
+                       const uint64_t sleep_time_us = 100000;
+
+                       if (interrupter && bt_interrupter_is_set(interrupter)) {
+                               set_fail_reason(fail_reason, "interrupted by user");
+                               goto error;
+                       }
+
+                       /* Wait 100 ms and retry */
+                       BT_LOGD("Got BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN: sleeping: "
+                               "time-us=%" PRIu64, sleep_time_us);
+
+                       if (usleep(sleep_time_us)) {
+                               if (interrupter && bt_interrupter_is_set(interrupter)) {
+                                       BT_CLI_LOGW_APPEND_CAUSE(
+                                               "Query was interrupted by user: "
+                                               "comp-cls-addr=%p, comp-cls-name=\"%s\", "
+                                               "query-obj=\"%s\"", comp_cls,
+                                               bt_component_class_get_name(comp_cls),
+                                               obj);
+                                       set_fail_reason(fail_reason,
+                                               "interrupted by user");
+                                       goto error;
+                               }
+                       }
+
+                       continue;
+               }
+               case BT_QUERY_EXECUTOR_QUERY_STATUS_ERROR:
+                       if (interrupter && bt_interrupter_is_set(interrupter)) {
+                               set_fail_reason(fail_reason, "interrupted by user");
+                               goto error;
+                       }
+
+                       goto error;
+               case BT_QUERY_EXECUTOR_QUERY_STATUS_UNKNOWN_OBJECT:
+                       set_fail_reason(fail_reason, "unknown query object");
+                       goto end;
+               case BT_QUERY_EXECUTOR_QUERY_STATUS_MEMORY_ERROR:
+                       set_fail_reason(fail_reason, "not enough memory");
+                       goto error;
+               default:
+                       BT_LOGF("Unknown query status: status=%s",
+                               bt_common_func_status_string(status));
+                       abort();
+               }
+       }
+
+ok:
+       *user_result = result;
+       result = NULL;
+       goto end;
+
+error:
+       status = BT_QUERY_EXECUTOR_QUERY_STATUS_ERROR;
+
+end:
+       bt_query_executor_put_ref(query_exec);
+       bt_value_put_ref(result);
+       return status;
+}
diff --git a/src/cli/babeltrace2-query.h b/src/cli/babeltrace2-query.h
new file mode 100644 (file)
index 0000000..c8d8a15
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef CLI_BABELTRACE_QUERY_H
+#define CLI_BABELTRACE_QUERY_H
+
+/*
+ * Copyright 2016-2019 EfficiOS Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace2/babeltrace.h>
+#include "common/macros.h"
+
+BT_HIDDEN
+bt_query_executor_query_status cli_query(const bt_component_class *comp_cls,
+               const char *obj, const bt_value *params,
+               bt_logging_level log_level, const bt_interrupter *interrupter,
+               const bt_value **user_result, const char **fail_reason);
+
+#endif /* CLI_BABELTRACE_QUERY_H */
index 12d9cc0cadfd2154e9626be899c182b346d015a2..6a3440242049e9102d395a18aed2ffb1f0a81c2a 100644 (file)
@@ -40,6 +40,7 @@
 #include "babeltrace2-cfg-cli-args.h"
 #include "babeltrace2-cfg-cli-args-default.h"
 #include "babeltrace2-plugins.h"
+#include "babeltrace2-query.h"
 
 #define ENV_BABELTRACE_WARN_COMMAND_NAME_DIRECTORY_CLASH "BABELTRACE_CLI_WARN_COMMAND_NAME_DIRECTORY_CLASH"
 #define ENV_BABELTRACE_CLI_LOG_LEVEL "BABELTRACE_CLI_LOG_LEVEL"
@@ -115,93 +116,10 @@ int query(struct bt_config *cfg, const bt_component_class *comp_cls,
                const char *obj, const bt_value *params,
                const bt_value **user_result, const char **fail_reason)
 {
-       const bt_value *result = NULL;
-       bt_query_executor_query_status query_status;
-       bt_query_executor *query_exec;
-       *fail_reason = "unknown error";
-       int ret = 0;
-
-       BT_ASSERT(fail_reason);
-       BT_ASSERT(user_result);
-       query_exec = bt_query_executor_create();
-       if (!query_exec) {
-               BT_CLI_LOGE_APPEND_CAUSE("Cannot create a query executor.");
-               goto error;
-       }
-
-       bt_query_executor_add_interrupter(query_exec, the_interrupter);
-
-       while (true) {
-               query_status = bt_query_executor_query(
-                       query_exec, comp_cls, obj, params,
-                       cfg->log_level, &result);
-               switch (query_status) {
-               case BT_QUERY_EXECUTOR_QUERY_STATUS_OK:
-                       goto ok;
-               case BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN:
-               {
-                       const uint64_t sleep_time_us = 100000;
-
-                       if (bt_interrupter_is_set(the_interrupter)) {
-                               *fail_reason = "interrupted by user";
-                               goto error;
-                       }
-
-                       /* Wait 100 ms and retry */
-                       BT_LOGD("Got BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN: sleeping: "
-                               "time-us=%" PRIu64, sleep_time_us);
-
-                       if (usleep(sleep_time_us)) {
-                               if (bt_interrupter_is_set(the_interrupter)) {
-                                       BT_CLI_LOGW_APPEND_CAUSE(
-                                               "Query was interrupted by user: "
-                                               "comp-cls-addr=%p, comp-cls-name=\"%s\", "
-                                               "query-obj=\"%s\"", comp_cls,
-                                               bt_component_class_get_name(comp_cls),
-                                               obj);
-                                       *fail_reason = "interrupted by user";
-                                       goto error;
-                               }
-                       }
-
-                       continue;
-               }
-               case BT_QUERY_EXECUTOR_QUERY_STATUS_ERROR:
-                       if (bt_interrupter_is_set(the_interrupter)) {
-                               *fail_reason = "interrupted by user";
-                               goto error;
-                       }
-
-                       goto error;
-               case BT_QUERY_EXECUTOR_QUERY_STATUS_UNKNOWN_OBJECT:
-                       *fail_reason = "unknown query object";
-                       goto error;
-               case BT_QUERY_EXECUTOR_QUERY_STATUS_MEMORY_ERROR:
-                       *fail_reason = "not enough memory";
-                       goto error;
-               default:
-                       BT_LOGF("Unknown query status: status=%s",
-                               bt_common_func_status_string(query_status));
-                       abort();
-               }
-       }
-
-ok:
-       *user_result = result;
-       result = NULL;
-       goto end;
-
-error:
-       ret = -1;
-
-end:
-       bt_query_executor_put_ref(query_exec);
-       bt_value_put_ref(result);
-       return ret;
+       return cli_query(comp_cls, obj, params, cfg->log_level,
+               the_interrupter, user_result, fail_reason);
 }
 
-
-
 typedef const void *(*plugin_borrow_comp_cls_func_t)(
                const bt_plugin *, const char *);
 
index a602911c374928fa39d54e693ec65415ff14a8e5..ebc1991ebfe659301449994e85c4620808cbacc5 100644 (file)
@@ -54,16 +54,31 @@ void bt_query_executor_destroy(struct bt_object *obj)
                query_exec->interrupters = NULL;
        }
 
-       BT_OBJECT_PUT_REF_AND_RESET(query_exec->default_interrupter);
+       BT_LOGD_STR("Putting component class.");
+       BT_OBJECT_PUT_REF_AND_RESET(query_exec->comp_cls);
+
+       if (query_exec->object) {
+               g_string_free(query_exec->object, TRUE);
+               query_exec->object = NULL;
+       }
 
+       BT_LOGD_STR("Putting parameters.");
+       BT_OBJECT_PUT_REF_AND_RESET(query_exec->params);
+       BT_OBJECT_PUT_REF_AND_RESET(query_exec->default_interrupter);
        g_free(query_exec);
 }
 
-struct bt_query_executor *bt_query_executor_create(void)
+struct bt_query_executor *bt_query_executor_create(
+               const bt_component_class *comp_cls, const char *object,
+               const bt_value *params)
 {
        struct bt_query_executor *query_exec;
 
-       BT_LOGD_STR("Creating query executor.");
+       BT_ASSERT_PRE_NON_NULL(comp_cls, "Component class");
+       BT_ASSERT_PRE_NON_NULL(object, "Object");
+       BT_LIB_LOGD("Creating query executor: "
+               "%![comp-cls-]+C, object=\"%s\", %![params-]%+v",
+               comp_cls, object, params);
        query_exec = g_new0(struct bt_query_executor, 1);
        if (!query_exec) {
                BT_LIB_LOGE_APPEND_CAUSE(
@@ -87,11 +102,31 @@ struct bt_query_executor *bt_query_executor_create(void)
                goto end;
        }
 
+       query_exec->object = g_string_new(object);
+       if (!query_exec->object) {
+               BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one GString.");
+               BT_OBJECT_PUT_REF_AND_RESET(query_exec);
+               goto end;
+       }
+
+       query_exec->comp_cls = comp_cls;
+       bt_object_get_no_null_check(query_exec->comp_cls);
+
+       if (!params) {
+               query_exec->params = bt_value_null;
+       } else {
+               query_exec->params = params;
+       }
+
+       bt_object_get_no_null_check(query_exec->params);
+       query_exec->log_level = BT_LOGGING_LEVEL_NONE;
        bt_query_executor_add_interrupter(query_exec,
                query_exec->default_interrupter);
        bt_object_init_shared(&query_exec->base,
                bt_query_executor_destroy);
-       BT_LOGD("Created query executor: addr=%p", query_exec);
+       BT_LIB_LOGD("Created query executor: "
+               "addr=%p, %![comp-cls-]+C, object=\"%s\", %![params-]%+v",
+               query_exec, comp_cls, object, params);
 
 end:
        return (void *) query_exec;
@@ -99,22 +134,20 @@ end:
 
 enum bt_query_executor_query_status bt_query_executor_query(
                struct bt_query_executor *query_exec,
-               const struct bt_component_class *comp_cls,
-               const char *object, const struct bt_value *params,
-               enum bt_logging_level log_level,
                const struct bt_value **user_result)
 {
-       typedef enum bt_component_class_query_method_status (*method_t)(void *,
-               const void *, const void *, const void *, enum bt_logging_level,
-               const void *);
+       typedef enum bt_component_class_query_method_status (*method_t)(
+               void * /* self component class */,
+               void * /* private query executor */,
+               const char * /* object */,
+               const struct bt_value * /* parameters */,
+               const struct bt_value ** /* result */);
 
        enum bt_query_executor_query_status status;
        enum bt_component_class_query_method_status query_status;
        method_t method = NULL;
 
        BT_ASSERT_PRE_NON_NULL(query_exec, "Query executor");
-       BT_ASSERT_PRE_NON_NULL(comp_cls, "Component class");
-       BT_ASSERT_PRE_NON_NULL(object, "Object");
        BT_ASSERT_PRE_NON_NULL(user_result, "Result (output)");
 
        /*
@@ -133,34 +166,34 @@ enum bt_query_executor_query_status bt_query_executor_query(
                        "not performing the query operation: "
                        "query-exec-addr=%p, %![cc-]+C, object=\"%s\", "
                        "%![params-]+v, log-level=%s",
-                       query_exec, comp_cls, object, params,
-                       bt_common_logging_level_string(log_level));
+                       query_exec, query_exec->comp_cls,
+                       query_exec->object->str, query_exec->params,
+                       bt_common_logging_level_string(query_exec->log_level));
                status = BT_FUNC_STATUS_AGAIN;
                goto end;
        }
 
-       if (!params) {
-               params = bt_value_null;
-       }
-
-       switch (comp_cls->type) {
+       switch (query_exec->comp_cls->type) {
        case BT_COMPONENT_CLASS_TYPE_SOURCE:
        {
-               struct bt_component_class_source *src_cc = (void *) comp_cls;
+               struct bt_component_class_source *src_cc = (void *)
+                       query_exec->comp_cls;
 
                method = (method_t) src_cc->methods.query;
                break;
        }
        case BT_COMPONENT_CLASS_TYPE_FILTER:
        {
-               struct bt_component_class_filter *flt_cc = (void *) comp_cls;
+               struct bt_component_class_filter *flt_cc = (void *)
+                       query_exec->comp_cls;
 
                method = (method_t) flt_cc->methods.query;
                break;
        }
        case BT_COMPONENT_CLASS_TYPE_SINK:
        {
-               struct bt_component_class_sink *sink_cc = (void *) comp_cls;
+               struct bt_component_class_sink *sink_cc = (void *)
+                       query_exec->comp_cls;
 
                method = (method_t) sink_cc->methods.query;
                break;
@@ -172,7 +205,7 @@ enum bt_query_executor_query_status bt_query_executor_query(
        if (!method) {
                /* Not an error: nothing to query */
                BT_LIB_LOGD("Component class has no registered query method: "
-                       "%!+C", comp_cls);
+                       "%!+C", query_exec->comp_cls);
                status = BT_FUNC_STATUS_UNKNOWN_OBJECT;
                goto end;
        }
@@ -180,11 +213,13 @@ enum bt_query_executor_query_status bt_query_executor_query(
        BT_LIB_LOGD("Calling user's query method: "
                "query-exec-addr=%p, %![cc-]+C, object=\"%s\", %![params-]+v, "
                "log-level=%s",
-               query_exec, comp_cls, object, params,
-               bt_common_logging_level_string(log_level));
+               query_exec, query_exec->comp_cls, query_exec->object->str,
+               query_exec->params,
+               bt_common_logging_level_string(query_exec->log_level));
        *user_result = NULL;
-       query_status = method((void *) comp_cls, query_exec, object, params,
-               log_level, user_result);
+       query_status = method((void *) query_exec->comp_cls,
+               (void *) query_exec, query_exec->object->str,
+               query_exec->params, user_result);
        BT_LIB_LOGD("User method returned: status=%s, %![res-]+v",
                bt_common_func_status_string(query_status), *user_result);
        BT_ASSERT_POST(query_status != BT_FUNC_STATUS_OK || *user_result,
@@ -195,8 +230,10 @@ enum bt_query_executor_query_status bt_query_executor_query(
                BT_LIB_LOGW_APPEND_CAUSE(
                        "Component class's \"query\" method failed: "
                        "query-exec-addr=%p, %![cc-]+C, object=\"%s\", "
-                       "%![params-]+v, log-level=%s", query_exec, comp_cls,
-                       object, params, bt_common_logging_level_string(log_level));
+                       "%![params-]+v, log-level=%s", query_exec,
+                       query_exec->comp_cls, query_exec->object->str,
+                       query_exec->params,
+                       bt_common_logging_level_string(query_exec->log_level));
                goto end;
        }
 
@@ -233,6 +270,22 @@ void bt_query_executor_interrupt(struct bt_query_executor *query_exec)
                query_exec);
 }
 
+enum bt_query_executor_set_logging_level_status
+bt_query_executor_set_logging_level(struct bt_query_executor *query_exec,
+               enum bt_logging_level log_level)
+{
+       BT_ASSERT_PRE_NON_NULL(query_exec, "Query executor");
+       query_exec->log_level = log_level;
+       return BT_FUNC_STATUS_OK;
+}
+
+enum bt_logging_level bt_query_executor_get_logging_level(
+               const struct bt_query_executor *query_exec)
+{
+       BT_ASSERT_PRE_NON_NULL(query_exec, "Query executor");
+       return query_exec->log_level;
+}
+
 void bt_query_executor_get_ref(const struct bt_query_executor *query_executor)
 {
        bt_object_get_ref(query_executor);
index c1dcc9c4a943dfe5015d3261339e1a215ed53416..250bc1b835a18d96b848c991b3f137b55549b7d0 100644 (file)
@@ -30,6 +30,7 @@
 #include <babeltrace2/graph/component-class.h>
 
 #include "lib/object.h"
+#include "lib/value.h"
 
 struct bt_query_executor {
        struct bt_object base;
@@ -46,6 +47,16 @@ struct bt_query_executor {
         * owned by this.
         */
        struct bt_interrupter *default_interrupter;
+
+       /* Owned by this */
+       const struct bt_component_class *comp_cls;
+
+       GString *object;
+
+       /* Owned by this */
+       const struct bt_value *params;
+
+       enum bt_logging_level log_level;
 };
 
 #endif /* BABELTRACE_GRAPH_QUERY_EXECUTOR_INTERNAL_H */
index 398708db8e0eef24cc5427efc929fef12d3c2337..8b6d547a6f24bae5b70c4bffa392712b5fa0087e 100644 (file)
@@ -1989,13 +1989,15 @@ bt_component_class_init_method_status ctf_fs_init(
 BT_HIDDEN
 bt_component_class_query_method_status ctf_fs_query(
                bt_self_component_class_source *comp_class,
-               const bt_query_executor *query_exec,
+               bt_private_query_executor *priv_query_exec,
                const char *object, const bt_value *params,
-               bt_logging_level log_level,
                const bt_value **result)
 {
        bt_component_class_query_method_status status =
                BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK;
+       bt_logging_level log_level = bt_query_executor_get_logging_level(
+               bt_private_query_executor_as_query_executor_const(
+                       priv_query_exec));
 
        if (strcmp(object, "metadata-info") == 0) {
                status = metadata_info_query(comp_class, params, log_level,
index 8e7ca952797454849756735c0c1805ebb951b527..74432046d0d3fbefab048aaf95902da3612e6215 100644 (file)
@@ -213,9 +213,8 @@ void ctf_fs_finalize(bt_self_component_source *component);
 BT_HIDDEN
 bt_component_class_query_method_status ctf_fs_query(
                bt_self_component_class_source *comp_class,
-               const bt_query_executor *query_exec,
+               bt_private_query_executor *priv_query_exec,
                const char *object, const bt_value *params,
-               bt_logging_level log_level,
                const bt_value **result);
 
 BT_HIDDEN
index 7b5eddbde167b71bac624e9b4671630bd1de33a3..62dc28f0d8b4ebfe28e06a585362c1271d6ad2c8 100644 (file)
@@ -1443,13 +1443,16 @@ end:
 BT_HIDDEN
 bt_component_class_query_method_status lttng_live_query(
                bt_self_component_class_source *comp_class,
-               const bt_query_executor *query_exec,
+               bt_private_query_executor *priv_query_exec,
                const char *object, const bt_value *params,
-               bt_logging_level log_level, const bt_value **result)
+               const bt_value **result)
 {
        bt_component_class_query_method_status status =
                BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK;
        bt_self_component *self_comp = NULL;
+       bt_logging_level log_level = bt_query_executor_get_logging_level(
+               bt_private_query_executor_as_query_executor_const(
+                       priv_query_exec));
 
        if (strcmp(object, "sessions") == 0) {
                status = lttng_live_query_list_sessions(params, result,
index 77632daf59a2ee8214072b18987e5e4c3af2ca26..3ae12082830a55cf0ff1dd2b64611f85239f3d50 100644 (file)
@@ -263,9 +263,8 @@ bt_component_class_init_method_status lttng_live_component_init(
 
 bt_component_class_query_method_status lttng_live_query(
                bt_self_component_class_source *comp_class,
-               const bt_query_executor *query_exec,
+               bt_private_query_executor *priv_query_exec,
                const char *object, const bt_value *params,
-               bt_logging_level log_level,
                const bt_value **result);
 
 void lttng_live_component_finalize(bt_self_component_source *component);
index aa13cd6aff5f16f64b2a42c5f2758717baba176f..00a952c2b35d2a02c83809d4e9e90bfeec69990f 100644 (file)
@@ -185,7 +185,7 @@ class UserComponentClassTestCase(unittest.TestCase):
                 pass
 
         with self.assertRaises(bt2.UnknownObject):
-            bt2.QueryExecutor().query(MySink, 'obj', 23)
+            bt2.QueryExecutor(MySink, 'obj', 23).query()
 
     def test_query_raises(self):
         class MySink(bt2._UserSinkComponent):
@@ -193,11 +193,11 @@ class UserComponentClassTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 raise ValueError
 
         with self.assertRaises(bt2._Error):
-            bt2.QueryExecutor().query(MySink, 'obj', 23)
+            bt2.QueryExecutor(MySink, 'obj', 23).query()
 
     def test_query_wrong_return_type(self):
         class MySink(bt2._UserSinkComponent):
@@ -205,11 +205,11 @@ class UserComponentClassTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 return ...
 
         with self.assertRaises(bt2._Error):
-            bt2.QueryExecutor().query(MySink, 'obj', 23)
+            bt2.QueryExecutor(MySink, 'obj', 23).query()
 
     def test_query_params_none(self):
         class MySink(bt2._UserSinkComponent):
@@ -217,14 +217,14 @@ class UserComponentClassTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 nonlocal query_params
                 query_params = params
                 return None
 
         query_params = None
         params = None
-        res = bt2.QueryExecutor().query(MySink, 'obj', params)
+        res = bt2.QueryExecutor(MySink, 'obj', params).query()
         self.assertEqual(query_params, params)
         self.assertIsNone(res)
         del query_params
@@ -235,12 +235,14 @@ class UserComponentClassTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 nonlocal query_log_level
-                query_log_level = log_level
+                query_log_level = priv_query_exec.logging_level
 
         query_log_level = None
-        res = bt2.QueryExecutor().query(MySink, 'obj', None, bt2.LoggingLevel.WARNING)
+        query_exec = bt2.QueryExecutor(MySink, 'obj', None)
+        query_exec.logging_level = bt2.LoggingLevel.WARNING
+        query_exec.query()
         self.assertEqual(query_log_level, bt2.LoggingLevel.WARNING)
         del query_log_level
 
@@ -250,10 +252,10 @@ class UserComponentClassTestCase(unittest.TestCase):
                 pass
 
             @staticmethod
-            def _user_query(query_exec, obj, params, log_level):
+            def _user_query(priv_query_exec, obj, params):
                 return
 
-        res = bt2.QueryExecutor().query(MySink, 'obj', None)
+        res = bt2.QueryExecutor(MySink, 'obj', None).query()
         self.assertIsNone(res)
 
     def test_query_simple(self):
@@ -262,14 +264,14 @@ class UserComponentClassTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 nonlocal query_params
                 query_params = params
                 return 17.5
 
         query_params = None
         params = ['coucou', 23, None]
-        res = bt2.QueryExecutor().query(MySink, 'obj', params)
+        res = bt2.QueryExecutor(MySink, 'obj', params).query()
         self.assertEqual(query_params, params)
         self.assertEqual(res, 17.5)
         del query_params
@@ -280,7 +282,7 @@ class UserComponentClassTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 nonlocal query_params
                 query_params = params
                 return {'null': None, 'bt2': 'BT2'}
@@ -292,7 +294,7 @@ class UserComponentClassTestCase(unittest.TestCase):
             'null': None,
         }
 
-        res = bt2.QueryExecutor().query(MySink, 'obj', params)
+        res = bt2.QueryExecutor(MySink, 'obj', params).query()
         self.assertEqual(query_params, params)
         self.assertEqual(res, {'null': None, 'bt2': 'BT2'})
         del query_params
@@ -318,7 +320,7 @@ class ComponentClassTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 return [obj, params, 23]
 
         self._py_comp_cls = MySink
@@ -352,8 +354,8 @@ class ComponentClassTestCase(unittest.TestCase):
         self.assertEqual(self._py_comp_cls, self._comp_cls)
 
     def test_query(self):
-        res = bt2.QueryExecutor().query(
+        res = bt2.QueryExecutor(
             self._comp_cls, 'an object', {'yes': 'no', 'book': -17}
-        )
+        ).query()
         expected = ['an object', {'yes': 'no', 'book': -17}, 23]
         self.assertEqual(res, expected)
index ca750aea6cd4acfe80987d836eab1e4c07d1af23..b09dded2b36e267c2fb8ff7bf9d93804c5e50930 100644 (file)
@@ -70,7 +70,7 @@ class SinkWithFailingQuery(bt2._UserSinkComponent):
         pass
 
     @staticmethod
-    def _user_query(executor, obj, params, log_level):
+    def _user_query(priv_executor, obj, params):
         raise ValueError('Query is failing')
 
 
@@ -177,10 +177,10 @@ class ErrorTestCase(unittest.TestCase):
         self.assertIsNone(cause.plugin_name)
 
     def test_component_class_error_cause(self):
-        q = bt2.QueryExecutor()
+        q = bt2.QueryExecutor(SinkWithFailingQuery, 'hello')
 
         with self.assertRaises(bt2._Error) as ctx:
-            q.query(SinkWithFailingQuery, 'hello')
+            q.query()
 
         cause = ctx.exception[0]
         self.assertIs(type(cause), bt2._ComponentClassErrorCause)
index 6d0cc3bdeab6dc920ae87d84c67aeaeecff58091..453cf5fe14feff33305dec1ec8c6d2f1aab928a0 100644 (file)
@@ -29,7 +29,7 @@ class QueryExecutorTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 nonlocal query_params
                 query_params = params
                 return {'null': None, 'bt2': 'BT2'}
@@ -41,7 +41,7 @@ class QueryExecutorTestCase(unittest.TestCase):
             'null': None,
         }
 
-        res = bt2.QueryExecutor().query(MySink, 'obj', params)
+        res = bt2.QueryExecutor(MySink, 'obj', params).query()
         self.assertEqual(query_params, params)
         self.assertEqual(res, {'null': None, 'bt2': 'BT2'})
         del query_params
@@ -52,13 +52,28 @@ class QueryExecutorTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 nonlocal query_params
                 query_params = params
 
         query_params = 23
-        res = bt2.QueryExecutor().query(MySink, 'obj', None)
-        self.assertEqual(query_params, None)
+        res = bt2.QueryExecutor(MySink, 'obj', None).query()
+        self.assertIs(query_params, None)
+        del query_params
+
+    def test_query_no_params(self):
+        class MySink(bt2._UserSinkComponent):
+            def _user_consume(self):
+                pass
+
+            @classmethod
+            def _user_query(cls, priv_query_exec, obj, params):
+                nonlocal query_params
+                query_params = params
+
+        query_params = 23
+        res = bt2.QueryExecutor(MySink, 'obj').query()
+        self.assertIs(query_params, None)
         del query_params
 
     def test_query_logging_level(self):
@@ -67,12 +82,14 @@ class QueryExecutorTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 nonlocal query_log_level
-                query_log_level = log_level
+                query_log_level = priv_query_exec.logging_level
 
         query_log_level = None
-        res = bt2.QueryExecutor().query(MySink, 'obj', None, bt2.LoggingLevel.INFO)
+        query_exec = bt2.QueryExecutor(MySink, 'obj', None)
+        query_exec.logging_level = bt2.LoggingLevel.INFO
+        query_exec.query()
         self.assertEqual(query_log_level, bt2.LoggingLevel.INFO)
         del query_log_level
 
@@ -82,11 +99,11 @@ class QueryExecutorTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 raise ValueError
 
         with self.assertRaises(bt2._Error) as ctx:
-            res = bt2.QueryExecutor().query(MySink, 'obj', [17, 23])
+            res = bt2.QueryExecutor(MySink, 'obj', [17, 23]).query()
 
         exc = ctx.exception
         self.assertEqual(len(exc), 2)
@@ -102,11 +119,11 @@ class QueryExecutorTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 raise bt2.UnknownObject
 
         with self.assertRaises(bt2.UnknownObject):
-            res = bt2.QueryExecutor().query(MySink, 'obj', [17, 23])
+            res = bt2.QueryExecutor(MySink, 'obj', [17, 23]).query()
 
     def test_query_logging_level_invalid_type(self):
         class MySink(bt2._UserSinkComponent):
@@ -114,11 +131,13 @@ class QueryExecutorTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 pass
 
+        query_exec = bt2.QueryExecutor(MySink, 'obj', [17, 23])
+
         with self.assertRaises(TypeError):
-            res = bt2.QueryExecutor().query(MySink, 'obj', [17, 23], 'yeah')
+            query_exec.logging_level = 'yeah'
 
     def test_query_logging_level_invalid_value(self):
         class MySink(bt2._UserSinkComponent):
@@ -126,11 +145,13 @@ class QueryExecutorTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 pass
 
+        query_exec = bt2.QueryExecutor(MySink, 'obj', [17, 23])
+
         with self.assertRaises(ValueError):
-            res = bt2.QueryExecutor().query(MySink, 'obj', [17, 23], 12345)
+            query_exec.logging_level = 12345
 
     def test_query_try_again(self):
         class MySink(bt2._UserSinkComponent):
@@ -138,11 +159,11 @@ class QueryExecutorTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 raise bt2.TryAgain
 
         with self.assertRaises(bt2.TryAgain):
-            res = bt2.QueryExecutor().query(MySink, 'obj', [17, 23])
+            res = bt2.QueryExecutor(MySink, 'obj', [17, 23]).query()
 
     def test_query_add_interrupter(self):
         class MySink(bt2._UserSinkComponent):
@@ -150,7 +171,7 @@ class QueryExecutorTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 nonlocal interrupter2
                 test_self.assertFalse(query_exec.is_interrupted)
                 interrupter2.set()
@@ -161,10 +182,10 @@ class QueryExecutorTestCase(unittest.TestCase):
         interrupter1 = bt2.Interrupter()
         interrupter2 = bt2.Interrupter()
         test_self = self
-        query_exec = bt2.QueryExecutor()
+        query_exec = bt2.QueryExecutor(MySink, 'obj', [17, 23])
         query_exec.add_interrupter(interrupter1)
         query_exec.add_interrupter(interrupter2)
-        query_exec.query(MySink, 'obj', [17, 23])
+        query_exec.query()
 
     def test_query_interrupt(self):
         class MySink(bt2._UserSinkComponent):
@@ -172,11 +193,31 @@ class QueryExecutorTestCase(unittest.TestCase):
                 pass
 
             @classmethod
-            def _user_query(cls, query_exec, obj, params, log_level):
+            def _user_query(cls, priv_query_exec, obj, params):
                 test_self.assertFalse(query_exec.is_interrupted)
                 query_exec.interrupt()
                 test_self.assertTrue(query_exec.is_interrupted)
 
         test_self = self
-        query_exec = bt2.QueryExecutor()
-        query_exec.query(MySink, 'obj', [17, 23])
+        query_exec = bt2.QueryExecutor(MySink, 'obj', [17, 23])
+        query_exec.query()
+
+    def test_query_priv_executor_invalid_after(self):
+        class MySink(bt2._UserSinkComponent):
+            def _user_consume(self):
+                pass
+
+            @classmethod
+            def _user_query(cls, priv_query_exec, obj, params):
+                nonlocal test_priv_query_exec
+                test_priv_query_exec = priv_query_exec
+
+        test_priv_query_exec = None
+        query_exec = bt2.QueryExecutor(MySink, 'obj', [17, 23])
+        query_exec.query()
+        assert test_priv_query_exec is not None
+
+        with self.assertRaises(RuntimeError):
+            test_priv_query_exec.logging_level
+
+        del test_priv_query_exec
index a4177240ed03b674fe32afd39dc893cd3b3a000a..4d6e86e2da8e20c97c2fbab845324ad4b6d54b54 100644 (file)
@@ -26,7 +26,7 @@ class TestSourceExt(Base, bt2._UserSourceComponent, message_iterator_class=TestI
         self._print_params(params)
 
     @staticmethod
-    def _user_query(query_exec, obj, params, log_level):
+    def _user_query(priv_query_exec, obj, params):
         if obj == 'babeltrace.support-info':
             if params['type'] == 'file':
                 name = os.path.basename(str(params['input']))
@@ -64,7 +64,7 @@ class TestSourceSomeDir(
         self._print_params(params)
 
     @staticmethod
-    def _user_query(query_exec, obj, params, log_level):
+    def _user_query(priv_query_exec, obj, params):
         if obj == 'babeltrace.support-info':
             if params['type'] == 'directory':
                 name = os.path.basename(str(params['input']))
@@ -83,7 +83,7 @@ class TestSourceABCDE(Base, bt2._UserSourceComponent, message_iterator_class=Tes
         self._print_params(params)
 
     @staticmethod
-    def _user_query(query_exec, obj, params, log_level):
+    def _user_query(priv_query_exec, obj, params):
         if obj == 'babeltrace.support-info':
             return (
                 1.0
index 11ec41d12025f39d2c270afaac4182c8b1e65657..3b5c05fcc2f4a2fb91a9899300c72e155e2bdb3c 100644 (file)
@@ -129,11 +129,10 @@ static void test_sfs(const char *plugin_dir)
        bt_graph *graph;
        const char *object_str;
        bt_graph_add_component_status graph_ret;
-       bt_query_executor *query_exec = bt_query_executor_create();
+       bt_query_executor *query_exec;
        int ret;
        bt_plugin_find_all_from_file_status status;
 
-       BT_ASSERT(query_exec);
        BT_ASSERT(sfs_path);
        diag("sfs plugin test below");
 
@@ -181,9 +180,11 @@ static void test_sfs(const char *plugin_dir)
                "bt_plugin_borrow_filter_component_class_by_name_const() finds a filter component class");
        params = bt_value_integer_signed_create_init(23);
        BT_ASSERT(params);
-       ret = bt_query_executor_query(query_exec,
-               bt_component_class_filter_as_component_class_const(filter_comp_class),
-               "get-something", params, BT_LOGGING_LEVEL_NONE, &results);
+       query_exec = bt_query_executor_create(
+               bt_component_class_filter_as_component_class_const(
+                       filter_comp_class), "get-something", params);
+       BT_ASSERT(query_exec);
+       ret = bt_query_executor_query(query_exec, &results);
        ok(ret == 0 && results, "bt_query_executor_query() succeeds");
        BT_ASSERT(bt_value_is_array(results) && bt_value_array_get_size(results) == 2);
        object = bt_value_array_borrow_element_by_index_const(results, 0);
index 6e0e0a4b0ba1b65433db6bab93977ffe708e0b85..3d9e74a5c4e28be6067f306e273fd8b56420957f 100644 (file)
@@ -58,9 +58,8 @@ dummy_iterator_next_method(
 
 static bt_component_class_query_method_status flt_query_method(
                bt_self_component_class_filter *component_class,
-               const bt_query_executor *query_exec,
+               bt_private_query_executor *priv_query_exec,
                const char *object, const bt_value *params,
-               __attribute__((unused)) bt_logging_level log_level,
                const bt_value **result)
 {
        bt_value *res = bt_value_array_create();
index 8d8cda783a58e7762fb61e478b44550d6436b25c..2d99d681086020f909d5ab0ab3800090518b42b8 100644 (file)
@@ -40,7 +40,6 @@ class QueryTraceInfoClockOffsetTestCase(unittest.TestCase):
         self._inputs = [
             os.path.join(test_ctf_traces_path, 'intersection', '3eventsintersect')
         ]
-        self._executor = bt2.QueryExecutor()
 
     def _check(self, trace, offset):
         self.assertEqual(trace['range-ns']['begin'], 13515309000000000 + offset)
@@ -64,38 +63,38 @@ class QueryTraceInfoClockOffsetTestCase(unittest.TestCase):
     # Without clock class offset
 
     def test_no_clock_class_offset(self):
-        res = self._executor.query(
+        res = bt2.QueryExecutor(
             self._fs, 'babeltrace.trace-info', {'inputs': self._inputs}
-        )
+        ).query()
         trace = res[0]
         self._check(trace, 0)
 
     # With clock-class-offset-s
 
     def test_clock_class_offset_s(self):
-        res = self._executor.query(
+        res = bt2.QueryExecutor(
             self._fs,
             'babeltrace.trace-info',
             {'inputs': self._inputs, 'clock-class-offset-s': 2},
-        )
+        ).query()
         trace = res[0]
         self._check(trace, 2000000000)
 
     # With clock-class-offset-ns
 
     def test_clock_class_offset_ns(self):
-        res = self._executor.query(
+        res = bt2.QueryExecutor(
             self._fs,
             'babeltrace.trace-info',
             {'inputs': self._inputs, 'clock-class-offset-ns': 2},
-        )
+        ).query()
         trace = res[0]
         self._check(trace, 2)
 
     # With both, negative
 
     def test_clock_class_offset_both(self):
-        res = self._executor.query(
+        res = bt2.QueryExecutor(
             self._fs,
             'babeltrace.trace-info',
             {
@@ -103,41 +102,41 @@ class QueryTraceInfoClockOffsetTestCase(unittest.TestCase):
                 'clock-class-offset-s': -2,
                 'clock-class-offset-ns': -2,
             },
-        )
+        ).query()
         trace = res[0]
         self._check(trace, -2000000002)
 
     def test_clock_class_offset_s_wrong_type(self):
         with self.assertRaises(bt2._Error):
-            self._executor.query(
+            bt2.QueryExecutor(
                 self._fs,
                 'babeltrace.trace-info',
                 {'inputs': self._inputs, 'clock-class-offset-s': "2"},
-            )
+            ).query()
 
     def test_clock_class_offset_s_wrong_type_none(self):
         with self.assertRaises(bt2._Error):
-            self._executor.query(
+            bt2.QueryExecutor(
                 self._fs,
                 'babeltrace.trace-info',
                 {'inputs': self._inputs, 'clock-class-offset-s': None},
-            )
+            ).query()
 
     def test_clock_class_offset_ns_wrong_type(self):
         with self.assertRaises(bt2._Error):
-            self._executor.query(
+            bt2.QueryExecutor(
                 self._fs,
                 'babeltrace.trace-info',
                 {'inputs': self._inputs, 'clock-class-offset-ns': "2"},
-            )
+            ).query()
 
     def test_clock_class_offset_ns_wrong_type_none(self):
         with self.assertRaises(bt2._Error):
-            self._executor.query(
+            bt2.QueryExecutor(
                 self._fs,
                 'babeltrace.trace-info',
                 {'inputs': self._inputs, 'clock-class-offset-ns': None},
-            )
+            ).query()
 
 
 class QueryTraceInfoPortNameTestCase(unittest.TestCase):
@@ -145,10 +144,8 @@ class QueryTraceInfoPortNameTestCase(unittest.TestCase):
         ctf = bt2.find_plugin("ctf")
         self._fs = ctf.source_component_classes["fs"]
 
-        self._executor = bt2.QueryExecutor()
-
     def test_trace_uuid_stream_class_id_no_stream_id(self):
-        res = self._executor.query(
+        res = bt2.QueryExecutor(
             self._fs,
             "babeltrace.trace-info",
             {
@@ -158,7 +155,7 @@ class QueryTraceInfoPortNameTestCase(unittest.TestCase):
                     )
                 ]
             },
-        )
+        ).query()
 
         os_stream_path = PurePosixPath(
             '/tests/data/ctf-traces/intersection/3eventsintersect/'
@@ -184,11 +181,11 @@ class QueryTraceInfoPortNameTestCase(unittest.TestCase):
         )
 
     def test_trace_uuid_no_stream_class_id_no_stream_id(self):
-        res = self._executor.query(
+        res = bt2.QueryExecutor(
             self._fs,
             "babeltrace.trace-info",
             {"inputs": [os.path.join(test_ctf_traces_path, "succeed", "succeed1")]},
-        )
+        ).query()
 
         os_stream_path = PurePosixPath(
             '/tests/data/ctf-traces/succeed/succeed1/dummystream'
@@ -213,19 +210,17 @@ class QueryTraceInfoRangeTestCase(unittest.TestCase):
         ctf = bt2.find_plugin("ctf")
         self._fs = ctf.source_component_classes["fs"]
 
-        self._executor = bt2.QueryExecutor()
-
     def test_trace_no_range(self):
         # This trace has no `timestamp_begin` and `timestamp_end` in its
         # packet context. The `babeltrace.trace-info` query should omit
         # the `range-ns` fields in the `trace` and `stream` data
         # structures.
 
-        res = self._executor.query(
+        res = bt2.QueryExecutor(
             self._fs,
             "babeltrace.trace-info",
             {"inputs": [os.path.join(test_ctf_traces_path, "succeed", "succeed1")]},
-        )
+        ).query()
 
         self.assertEqual(len(res), 1)
         trace = res[0]
This page took 0.055438 seconds and 4 git commands to generate.