Fix: sink.text.pretty: check that port is connected before creating message iterator
authorSimon Marchi <simon.marchi@efficios.com>
Tue, 14 Apr 2020 15:22:17 +0000 (11:22 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 15 Apr 2020 00:26:26 +0000 (20:26 -0400)
sink.text.pretty does not check if its input port is connected before
trying to create a message iterator on it.  This can lead to a
precondition assertion failure.  It can be reproduced with this Python
snippet.

    import bt2
    g = bt2.Graph()
    g.add_component(bt2.find_plugin('text').sink_component_classes['pretty'], 'snk')
    g.run()

The assertion failure we get is:

    04-14 11:35:27.339 1231815 1231815 F LIB/MSG-ITER create_self_component_input_port_message_iterator@iterator.c:295 Babeltrace 2 library precondition not satisfied; error is:
    04-14 11:35:27.339 1231815 1231815 F LIB/MSG-ITER create_self_component_input_port_message_iterator@iterator.c:295 Input port is not connected: port-addr=0x607000001d70, port-type=INPUT, port-name="in"
    04-14 11:35:27.339 1231815 1231815 F LIB/MSG-ITER create_self_component_input_port_message_iterator@iterator.c:295 Aborting...
    ./tests/utils/../utils/utils.sh: line 283: 1231815 Aborted (core dumped) env "${env_args[@]}" "$@"

Add a check and return an error if that happens instead.  A
corresponding test is also added.

Change-Id: Ibeed94cd6ece543817fe8a765a69cb52bbaaba76
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/3403
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
src/plugins/text/pretty/pretty.c
tests/Makefile.am
tests/plugins/sink.text.pretty/test_pretty [new file with mode: 0755]
tests/plugins/sink.text.pretty/test_pretty.py [new file with mode: 0644]

index f177ad23316c1b38166909a88db9abfc5817f31c..1a5a759d17603887d6c5fb092f95609155efebb8 100644 (file)
@@ -121,20 +121,34 @@ bt_message_iterator_class_next_method_status handle_message(
 
 BT_HIDDEN
 bt_component_class_sink_graph_is_configured_method_status
-pretty_graph_is_configured(bt_self_component_sink *comp)
+pretty_graph_is_configured(bt_self_component_sink *self_comp_sink)
 {
        bt_component_class_sink_graph_is_configured_method_status status;
        bt_message_iterator_create_from_sink_component_status
                msg_iter_status;
        struct pretty_component *pretty;
+       bt_self_component *self_comp =
+               bt_self_component_sink_as_self_component(self_comp_sink);
+       const bt_component *comp = bt_self_component_as_component(self_comp);
+       bt_self_component_port_input *in_port;
+       bt_logging_level log_level = bt_component_get_logging_level(comp);
 
-       pretty = bt_self_component_get_data(
-                       bt_self_component_sink_as_self_component(comp));
+       pretty = bt_self_component_get_data(self_comp);
        BT_ASSERT(pretty);
        BT_ASSERT(!pretty->iterator);
+
+       in_port = bt_self_component_sink_borrow_input_port_by_name(self_comp_sink,
+               in_port_name);
+       if (!bt_port_is_connected(bt_port_input_as_port_const(
+                       bt_self_component_port_input_as_port_input(in_port)))) {
+               BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Single input port is not connected: "
+                       "port-name=\"%s\"", in_port_name);
+               status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR;
+               goto end;
+       }
+
        msg_iter_status = bt_message_iterator_create_from_sink_component(
-               comp, bt_self_component_sink_borrow_input_port_by_name(comp,
-                       in_port_name), &pretty->iterator);
+               self_comp_sink, in_port, &pretty->iterator);
        if (msg_iter_status != BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
                status = (int) msg_iter_status;
                goto end;
index 7f3bc8eac4846001059f52e7ffd1e85f1bd4cdd4..c545f9a71695a930ae334abee1551aea9ef82034 100644 (file)
@@ -55,6 +55,8 @@ dist_check_SCRIPTS = \
        cli/test_trace_read \
        cli/test_trimmer \
        plugins/sink.text.details/succeed/test_succeed \
+       plugins/sink.text.pretty/test_pretty \
+       plugins/sink.text.pretty/test_pretty.py \
        plugins/src.ctf.lttng-live/test_live \
        python-plugin-provider/bt_plugin_test_python_plugin_provider.py \
        python-plugin-provider/test_python_plugin_provider \
@@ -145,6 +147,7 @@ TESTS_PYTHON_PLUGIN_PROVIDER =
 
 if ENABLE_PYTHON_PLUGINS
 TESTS_PYTHON_PLUGIN_PROVIDER += python-plugin-provider/test_python_plugin_provider
+TESTS_PLUGINS += plugins/sink.text.pretty/test_pretty
 if ENABLE_DEBUG_INFO
 TESTS_PLUGINS += \
        plugins/flt.lttng-utils.debug-info/test_succeed
diff --git a/tests/plugins/sink.text.pretty/test_pretty b/tests/plugins/sink.text.pretty/test_pretty
new file mode 100755 (executable)
index 0000000..3fdac62
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+
+if [ "x${BT_TESTS_SRCDIR:-}" != "x" ]; then
+       UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+       UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+run_python_bt2_test "${BT_TESTS_SRCDIR}/plugins/sink.text.pretty" "test_*"
diff --git a/tests/plugins/sink.text.pretty/test_pretty.py b/tests/plugins/sink.text.pretty/test_pretty.py
new file mode 100644 (file)
index 0000000..368afb6
--- /dev/null
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2020 EfficiOS, Inc.
+
+import unittest
+import bt2
+
+
+class Test(unittest.TestCase):
+    # Test that the component returns an error if the graph is configured while
+    # the component's input port is left disconnected.
+    def test_unconnected_port_raises(self):
+        graph = bt2.Graph()
+        graph.add_component(
+            bt2.find_plugin('text').sink_component_classes['pretty'], 'snk'
+        )
+
+        with self.assertRaisesRegex(
+            bt2._Error, 'Single input port is not connected: port-name="in"'
+        ):
+            graph.run()
+
+
+if __name__ == '__main__':
+    unittest.main()
This page took 0.027223 seconds and 4 git commands to generate.