On Thu, Nov 27, 2025 at 06:20:34PM +0100, Dumitru Ceara via dev wrote:
> This commit introduces the ability to dump a (partial) representation
> of the incremental processing graph.  It's currently supported for
> ovn-northd and ovn-controller through a command-line argument,
> --dump-inc-proc-graph[=<i-p-node>].
> 
> If the command line argument is present the binary (ovn-northd or
> ovn-controller) just dumps a representation of the incremental
> processing graph in DOT format to stdout.  The binary then exits.
> 
> If the '<i-p-node>' optional argument value is present the
> representation only includes nodes up to (and including) '<i-p-node>'.
> 
> The goal of the feature is to make lives of the developers/maintainers
> easier when writing or debugging features that require incremental
> processing.
> 
> Reported-at: https://issues.redhat.com/browse/FDP-2646
> Assisted-by: gemini-cli, with model: gemini-3-pro-preview
> Signed-off-by: Dumitru Ceara <[email protected]>
> ---
>  build-aux/initial-tab-whitelist  |   1 +
>  controller/ovn-controller.c      |  28 ++
>  lib/inc-proc-eng.c               |  64 +++-
>  lib/inc-proc-eng.h               |  23 +-
>  northd/ovn-northd.c              |  25 ++
>  tests/automake.mk                |   3 +-
>  tests/ovn-inc-proc-graph-dump.at | 513 +++++++++++++++++++++++++++++++
>  tests/testsuite.at               |   1 +
>  8 files changed, 646 insertions(+), 12 deletions(-)
>  create mode 100644 tests/ovn-inc-proc-graph-dump.at
> 
> diff --git a/build-aux/initial-tab-whitelist b/build-aux/initial-tab-whitelist
> index eb5c1a23a3..2dd02b6579 100644
> --- a/build-aux/initial-tab-whitelist
> +++ b/build-aux/initial-tab-whitelist
> @@ -9,3 +9,4 @@
>  ^debian/rules$
>  ^\.gitmodules$
>  ^utilities/containers/Makefile
> +^tests/ovn-inc-proc-graph-dump.at
> diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> index 52fc69f31f..5b7652fbf9 100644
> --- a/controller/ovn-controller.c
> +++ b/controller/ovn-controller.c
> @@ -8081,6 +8081,23 @@ loop_done:
>      exit(retval);
>  }
>  
> +static void
> +inc_proc_graph_dump(const char *end_node)
> +{
> +    struct ovsdb_idl_loop ovs_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
> +        ovsdb_idl_create_unconnected(&ovsrec_idl_class, true));
> +    struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
> +        ovsdb_idl_create_unconnected(&sbrec_idl_class, true));
> +
> +    inc_proc_ovn_controller_init(&ovnsb_idl_loop, &ovs_idl_loop,
> +                                 NULL, NULL, NULL, NULL, NULL,
> +                                 NULL, NULL, NULL, NULL);
> +    engine_dump_graph(end_node);
> +
> +    ovsdb_idl_loop_destroy(&ovs_idl_loop);
> +    ovsdb_idl_loop_destroy(&ovnsb_idl_loop);
> +}
> +
>  static char *
>  parse_options(int argc, char *argv[])
>  {
> @@ -8091,6 +8108,7 @@ parse_options(int argc, char *argv[])
>          OVN_DAEMON_OPTION_ENUMS,
>          SSL_OPTION_ENUMS,
>          OPT_ENABLE_DUMMY_VIF_PLUG,
> +        OPT_DUMP_INC_PROC_GRAPH,
>      };
>  
>      static struct option long_options[] = {
> @@ -8105,6 +8123,8 @@ parse_options(int argc, char *argv[])
>          {"chassis", required_argument, NULL, 'n'},
>          {"enable-dummy-vif-plug", no_argument, NULL,
>           OPT_ENABLE_DUMMY_VIF_PLUG},
> +        {"dump-inc-proc-graph", optional_argument, NULL,
> +         OPT_DUMP_INC_PROC_GRAPH},
>          {NULL, 0, NULL, 0}
>      };
>      char *short_options = 
> ovs_cmdl_long_options_to_short_options(long_options);
> @@ -8173,6 +8193,14 @@ parse_options(int argc, char *argv[])
>              vif_plug_dummy_enable();
>              break;
>  
> +        /* --dump-inc-proc-graph[=<i-p-node>]: Whether to dump the I-P engine
> +         * graph representation in DOT format to stdout.  Optionally only up
> +         * to <i-p-node>.
> +         */
> +        case OPT_DUMP_INC_PROC_GRAPH:
> +            inc_proc_graph_dump(optarg);
> +            exit(EXIT_SUCCESS);
> +
>          case 'n':
>              free(cli_system_id);
>              cli_system_id = xstrdup(optarg);
> diff --git a/lib/inc-proc-eng.c b/lib/inc-proc-eng.c
> index bd366cb906..839f6cfcaf 100644
> --- a/lib/inc-proc-eng.c
> +++ b/lib/inc-proc-eng.c
> @@ -32,6 +32,7 @@
>  #include "timeval.h"
>  #include "unixctl.h"
>  #include "vec.h"
> +#include "sset.h"
>  
>  VLOG_DEFINE_THIS_MODULE(inc_proc_eng);
>  
> @@ -266,24 +267,27 @@ engine_get_input_data(const char *input_name, struct 
> engine_node *node)
>  }
>  
>  void
> -engine_add_input(struct engine_node *node, struct engine_node *input,
> -                 enum engine_input_handler_result (*change_handler)
> -                     (struct engine_node *, void *))
> +engine_add_input_impl(struct engine_node *node, struct engine_node *input,
> +                      enum engine_input_handler_result (*change_handler)
> +                          (struct engine_node *, void *),
> +                      const char *change_handler_name)
>  {
>      ovs_assert(node->n_inputs < ENGINE_MAX_INPUT);
>      node->inputs[node->n_inputs].node = input;
>      node->inputs[node->n_inputs].change_handler = change_handler;
> +    node->inputs[node->n_inputs].change_handler_name = change_handler_name;
>      node->n_inputs ++;
>  }
>  
>  void
> -engine_add_input_with_compute_debug(
> +engine_add_input_with_compute_debug_impl(
>          struct engine_node *node, struct engine_node *input,
>          enum engine_input_handler_result (*change_handler)
>              (struct engine_node *, void *),
> -        void (*get_compute_failure_info)(struct engine_node *))
> +        void (*get_compute_failure_info)(struct engine_node *),
> +        const char *change_handler_name)
>  {
> -    engine_add_input(node, input, change_handler);
> +    engine_add_input_impl(node, input, change_handler, change_handler_name);
>      node->get_compute_failure_info = get_compute_failure_info;
>  }
>  
> @@ -611,3 +615,51 @@ engine_trigger_recompute(void)
>      VLOG_INFO("User triggered force recompute.");
>      engine_set_force_recompute_immediate();
>  }
> +
> +static void
> +engine_dump_node(struct engine_node *node, struct sset *visited_nodes)
> +{
> +    if (sset_contains(visited_nodes, node->name)) {
> +        return;
> +    }
> +    sset_add(visited_nodes, node->name);
> +
> +    printf("\t%s [style=filled, shape=box, fillcolor=white, "
> +           "label=\"%s\"];\n",
> +           node->name, node->name);
> +    for (size_t i = 0; i < node->n_inputs; i++) {
> +        const char *label = node->inputs[i].change_handler
> +                            ? node->inputs[i].change_handler_name
> +                            : NULL;
> +
> +        printf("\t%s -> %s [label=\"%s\"];\n",
> +               node->inputs[i].node->name, node->name,
> +               label ? label : "");
> +
> +        engine_dump_node(node->inputs[i].node, visited_nodes);
> +    }
> +}
> +
> +void
> +engine_dump_graph(const char *node_name)
> +{
> +    printf("digraph \"Incremental-Processing-Engine\" {\n");
> +    printf("\trankdir=LR;\n");
> +
> +    struct sset visited_nodes = SSET_INITIALIZER(&visited_nodes);
> +    struct engine_node *node;
> +    VECTOR_FOR_EACH (&engine_nodes, node) {
> +        if (node_name && strcmp(node->name, node_name)) {
> +            continue;
> +        }
> +
> +        engine_dump_node(node, &visited_nodes);
> +
> +        if (node_name) {
> +            break;
> +        }
> +    }
> +
> +    sset_destroy(&visited_nodes);
> +    printf("}\n");
> +}
> diff --git a/lib/inc-proc-eng.h b/lib/inc-proc-eng.h
> index 6a9e39efe6..02eeb46fe8 100644
> --- a/lib/inc-proc-eng.h
> +++ b/lib/inc-proc-eng.h
> @@ -209,6 +209,7 @@ struct engine_node_input {
>       * handler needs to use the txn pointers returned by 
> engine_get_context(),
>       * and the pointers are NULL, the change handler MUST return 
> EN_UNHANDLED.
>       */
> +    const char *change_handler_name;
>      enum engine_input_handler_result (*change_handler)
>          (struct engine_node *node, void *data);
>  };
> @@ -315,14 +316,24 @@ void *engine_get_input_data(const char *input_name, 
> struct engine_node *);
>   * which can be NULL. If the change_handler is NULL, the engine will not
>   * be able to process the change incrementally, and will fall back to call
>   * the run method to recompute. */
> -void engine_add_input(struct engine_node *node, struct engine_node *input,
> -                      enum engine_input_handler_result (*change_handler)
> -                          (struct engine_node *, void *));
> -void engine_add_input_with_compute_debug(
> +void engine_add_input_impl(struct engine_node *node, struct engine_node 
> *input,
> +                           enum engine_input_handler_result (*change_handler)
> +                               (struct engine_node *, void *),
> +                           const char *change_handler_name);
> +#define engine_add_input(node, input, change_handler) \
> +    engine_add_input_impl(node, input, change_handler, #change_handler)
> +
> +void engine_add_input_with_compute_debug_impl(
>          struct engine_node *node, struct engine_node *input,
>          enum engine_input_handler_result (*change_handler)
>              (struct engine_node *, void *),
> -        void (*get_compute_failure_info)(struct engine_node *));
> +        void (*get_compute_failure_info)(struct engine_node *),
> +        const char *change_handler_name);
> +#define engine_add_input_with_compute_debug(node, input, change_handler, \
> +                                            get_failure_info) \
> +    engine_add_input_with_compute_debug_impl(node, input, change_handler, \
> +                                             get_failure_info,            \
> +                                             #change_handler)
>  
>  /* Force the engine to recompute everything. It is used
>   * in circumstances when we are not sure there is change or not, or
> @@ -330,6 +341,8 @@ void engine_add_input_with_compute_debug(
>   * iteration, and the change can't be tracked across iterations. */
>  void engine_set_force_recompute(void);
>  
> +void engine_dump_graph(const char *node_name);
> +
>  /* Same as "engine_set_force_recompute()", but the poll_loop is woken up
>   * immediately and the next engine run is not delayed. */
>  void engine_set_force_recompute_immediate(void);
> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index 52a3c78832..f718c81afb 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -590,6 +590,20 @@ update_sequence_numbers(int64_t loop_start_time,
>          nbrec_nb_global_set_hv_cfg_timestamp(nb, hv_cfg_ts);
>      }
>  }
> +
> +static void inc_proc_graph_dump(const char *end_node)
> +{
> +    struct ovsdb_idl_loop ovnnb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
> +        ovsdb_idl_create_unconnected(&nbrec_idl_class, true));
> +    struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
> +        ovsdb_idl_create_unconnected(&sbrec_idl_class, true));
> +
> +    inc_proc_northd_init(&ovnnb_idl_loop, &ovnsb_idl_loop);
> +    engine_dump_graph(end_node);
> +
> +    ovsdb_idl_loop_destroy(&ovnnb_idl_loop);
> +    ovsdb_idl_loop_destroy(&ovnsb_idl_loop);
> +}
>  
>  static void
>  usage(void)
> @@ -625,6 +639,7 @@ parse_options(int argc OVS_UNUSED, char *argv[] 
> OVS_UNUSED,
>          SSL_OPTION_ENUMS,
>          OPT_DRY_RUN,
>          OPT_N_THREADS,
> +        OPT_DUMP_INC_PROC_GRAPH,
>      };
>      static const struct option long_options[] = {
>          {"ovnsb-db", required_argument, NULL, 'd'},
> @@ -635,6 +650,8 @@ parse_options(int argc OVS_UNUSED, char *argv[] 
> OVS_UNUSED,
>          {"version", no_argument, NULL, 'V'},
>          {"dry-run", no_argument, NULL, OPT_DRY_RUN},
>          {"n-threads", required_argument, NULL, OPT_N_THREADS},
> +        {"dump-inc-proc-graph", optional_argument, NULL,
> +         OPT_DUMP_INC_PROC_GRAPH},
>          OVN_DAEMON_LONG_OPTIONS,
>          VLOG_LONG_OPTIONS,
>          STREAM_SSL_LONG_OPTIONS,
> @@ -727,6 +744,14 @@ parse_options(int argc OVS_UNUSED, char *argv[] 
> OVS_UNUSED,
>              *paused = true;
>              break;
>  
> +        /* --dump-inc-proc-graph[=<i-p-node>]: Whether to dump the I-P engine
> +         * graph representation in DOT format to stdout.  Optionally only up
> +         * to <i-p-node>.
> +         */
> +        case OPT_DUMP_INC_PROC_GRAPH:
> +            inc_proc_graph_dump(optarg);
> +            exit(EXIT_SUCCESS);
> +
>          default:
>              break;
>          }
> diff --git a/tests/automake.mk b/tests/automake.mk
> index 8ae3105478..18472d9cc0 100644
> --- a/tests/automake.mk
> +++ b/tests/automake.mk
> @@ -47,7 +47,8 @@ TESTSUITE_AT = \
>       tests/ovn-ipsec.at \
>       tests/ovn-vif-plug.at \
>       tests/ovn-util.at \
> -     tests/ovn-br-controller.at
> +     tests/ovn-br-controller.at \
> +     tests/ovn-inc-proc-graph-dump.at
>  
>  SYSTEM_DPDK_TESTSUITE_AT = \
>       tests/system-dpdk-testsuite.at \
> diff --git a/tests/ovn-inc-proc-graph-dump.at 
> b/tests/ovn-inc-proc-graph-dump.at
> new file mode 100644
> index 0000000000..1775cf5d5e
> --- /dev/null
> +++ b/tests/ovn-inc-proc-graph-dump.at
> @@ -0,0 +1,513 @@
> +AT_BANNER([OVN Incremental Processing Engine Graph Dump])
> +
> +AT_SETUP([northd: dump full incremental processing graph])
> +AT_KEYWORDS([inc-proc-graph])
> +AT_CHECK([ovn-northd --dump-inc-proc-graph], [0], [dnl
> +digraph "Incremental-Processing-Engine" {
> +     rankdir=LR;
> +     NB_acl [[style=filled, shape=box, fillcolor=white, label="NB_acl"]];
> +     SB_acl_id [[style=filled, shape=box, fillcolor=white, 
> label="SB_acl_id"]];
> +     acl_id [[style=filled, shape=box, fillcolor=white, label="acl_id"]];
> +     NB_acl -> acl_id [[label=""]];
> +     SB_acl_id -> acl_id [[label=""]];
> +     NB_mirror [[style=filled, shape=box, fillcolor=white, 
> label="NB_mirror"]];
> +     NB_mirror_rule [[style=filled, shape=box, fillcolor=white, 
> label="NB_mirror_rule"]];
> +     NB_static_mac_binding [[style=filled, shape=box, fillcolor=white, 
> label="NB_static_mac_binding"]];
> +     NB_chassis_template_var [[style=filled, shape=box, fillcolor=white, 
> label="NB_chassis_template_var"]];
> +     NB_network_function [[style=filled, shape=box, fillcolor=white, 
> label="NB_network_function"]];
> +     NB_network_function_group [[style=filled, shape=box, fillcolor=white, 
> label="NB_network_function_group"]];
> +     SB_chassis [[style=filled, shape=box, fillcolor=white, 
> label="SB_chassis"]];
> +     SB_mirror [[style=filled, shape=box, fillcolor=white, 
> label="SB_mirror"]];
> +     SB_meter [[style=filled, shape=box, fillcolor=white, label="SB_meter"]];
> +     SB_dns [[style=filled, shape=box, fillcolor=white, label="SB_dns"]];
> +     SB_ha_chassis_group [[style=filled, shape=box, fillcolor=white, 
> label="SB_ha_chassis_group"]];
> +     SB_service_monitor [[style=filled, shape=box, fillcolor=white, 
> label="SB_service_monitor"]];
> +     SB_static_mac_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_static_mac_binding"]];
> +     SB_chassis_template_var [[style=filled, shape=box, fillcolor=white, 
> label="SB_chassis_template_var"]];
> +     ic_learned_svc_monitors [[style=filled, shape=box, fillcolor=white, 
> label="ic_learned_svc_monitors"]];
> +     SB_service_monitor -> ic_learned_svc_monitors [[label=""]];
> +     SB_fdb [[style=filled, shape=box, fillcolor=white, label="SB_fdb"]];
> +     NB_nb_global [[style=filled, shape=box, fillcolor=white, 
> label="NB_nb_global"]];
> +     NB_logical_switch [[style=filled, shape=box, fillcolor=white, 
> label="NB_logical_switch"]];
> +     SB_sb_global [[style=filled, shape=box, fillcolor=white, 
> label="SB_sb_global"]];
> +     NB_sampling_app [[style=filled, shape=box, fillcolor=white, 
> label="NB_sampling_app"]];
> +     sampling_app [[style=filled, shape=box, fillcolor=white, 
> label="sampling_app"]];
> +     NB_sampling_app -> sampling_app [[label=""]];
> +     global_config [[style=filled, shape=box, fillcolor=white, 
> label="global_config"]];
> +     NB_nb_global -> global_config 
> [[label="global_config_nb_global_handler"]];
> +     NB_logical_switch -> global_config 
> [[label="global_config_nb_logical_switch_handler"]];
> +     SB_sb_global -> global_config 
> [[label="global_config_sb_global_handler"]];
> +     SB_chassis -> global_config 
> [[label="global_config_sb_chassis_handler"]];
> +     sampling_app -> global_config [[label=""]];
> +     SB_mac_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_mac_binding"]];
> +     SB_port_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_port_binding"]];
> +     SB_datapath_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_datapath_binding"]];
> +     datapath_logical_switch [[style=filled, shape=box, fillcolor=white, 
> label="datapath_logical_switch"]];
> +     NB_logical_switch -> datapath_logical_switch 
> [[label="datapath_logical_switch_handler"]];
> +     global_config -> datapath_logical_switch 
> [[label="datapath_logical_switch_handler"]];
> +     NB_logical_router [[style=filled, shape=box, fillcolor=white, 
> label="NB_logical_router"]];
> +     datapath_logical_router [[style=filled, shape=box, fillcolor=white, 
> label="datapath_logical_router"]];
> +     NB_logical_router -> datapath_logical_router 
> [[label="en_datapath_logical_router_logical_router_handler"]];
> +     datapath_sync [[style=filled, shape=box, fillcolor=white, 
> label="datapath_sync"]];
> +     global_config -> datapath_sync 
> [[label="datapath_sync_global_config_handler"]];
> +     SB_datapath_binding -> datapath_sync 
> [[label="datapath_sync_sb_datapath_binding"]];
> +     datapath_logical_switch -> datapath_sync 
> [[label="datapath_sync_logical_switch_handler"]];
> +     datapath_logical_router -> datapath_sync 
> [[label="datapath_sync_logical_router_handler"]];
> +     datapath_synced_logical_switch [[style=filled, shape=box, 
> fillcolor=white, label="datapath_synced_logical_switch"]];
> +     datapath_sync -> datapath_synced_logical_switch 
> [[label="en_datapath_synced_logical_switch_datapath_sync_handler"]];
> +     datapath_synced_logical_router [[style=filled, shape=box, 
> fillcolor=white, label="datapath_synced_logical_router"]];
> +     datapath_sync -> datapath_synced_logical_router 
> [[label="en_datapath_synced_logical_router_datapath_sync_handler"]];
> +     NB_load_balancer [[style=filled, shape=box, fillcolor=white, 
> label="NB_load_balancer"]];
> +     NB_load_balancer_group [[style=filled, shape=box, fillcolor=white, 
> label="NB_load_balancer_group"]];
> +     lb_data [[style=filled, shape=box, fillcolor=white, label="lb_data"]];
> +     NB_load_balancer -> lb_data [[label="lb_data_load_balancer_handler"]];
> +     NB_load_balancer_group -> lb_data 
> [[label="lb_data_load_balancer_group_handler"]];
> +     datapath_synced_logical_switch -> lb_data 
> [[label="lb_data_synced_logical_switch_handler"]];
> +     datapath_synced_logical_router -> lb_data 
> [[label="lb_data_synced_logical_router_handler"]];
> +     NB_port_group [[style=filled, shape=box, fillcolor=white, 
> label="NB_port_group"]];
> +     SB_ip_multicast [[style=filled, shape=box, fillcolor=white, 
> label="SB_ip_multicast"]];
> +     northd [[style=filled, shape=box, fillcolor=white, label="northd"]];
> +     NB_mirror -> northd [[label=""]];
> +     NB_mirror_rule -> northd [[label=""]];
> +     NB_static_mac_binding -> northd [[label=""]];
> +     NB_chassis_template_var -> northd [[label=""]];
> +     NB_network_function -> northd [[label=""]];
> +     NB_network_function_group -> northd [[label=""]];
> +     SB_chassis -> northd [[label=""]];
> +     SB_mirror -> northd [[label=""]];
> +     SB_meter -> northd [[label=""]];
> +     SB_dns -> northd [[label=""]];
> +     SB_ha_chassis_group -> northd [[label=""]];
> +     SB_service_monitor -> northd [[label=""]];
> +     SB_static_mac_binding -> northd [[label=""]];
> +     SB_chassis_template_var -> northd [[label=""]];
> +     ic_learned_svc_monitors -> northd [[label=""]];
> +     SB_fdb -> northd [[label="northd_sb_fdb_change_handler"]];
> +     global_config -> northd [[label="northd_global_config_handler"]];
> +     SB_mac_binding -> northd [[label="engine_noop_handler"]];
> +     SB_port_binding -> northd [[label="northd_sb_port_binding_handler"]];
> +     datapath_synced_logical_switch -> northd 
> [[label="northd_nb_logical_switch_handler"]];
> +     datapath_synced_logical_router -> northd 
> [[label="northd_nb_logical_router_handler"]];
> +     lb_data -> northd [[label="northd_lb_data_handler"]];
> +     NB_port_group -> northd [[label="northd_nb_port_group_handler"]];
> +     SB_ip_multicast -> northd [[label="engine_noop_handler"]];
> +     sync_from_sb [[style=filled, shape=box, fillcolor=white, 
> label="sync_from_sb"]];
> +     northd -> sync_from_sb [[label="sync_from_sb_northd_handler"]];
> +     SB_port_binding -> sync_from_sb [[label=""]];
> +     SB_ha_chassis_group -> sync_from_sb [[label=""]];
> +     lr_nat [[style=filled, shape=box, fillcolor=white, label="lr_nat"]];
> +     northd -> lr_nat [[label="lr_nat_northd_handler"]];
> +     lr_stateful [[style=filled, shape=box, fillcolor=white, 
> label="lr_stateful"]];
> +     northd -> lr_stateful [[label="lr_stateful_northd_handler"]];
> +     lr_nat -> lr_stateful [[label="lr_stateful_lr_nat_handler"]];
> +     lb_data -> lr_stateful [[label="lr_stateful_lb_data_handler"]];
> +     SB_address_set [[style=filled, shape=box, fillcolor=white, 
> label="SB_address_set"]];
> +     NB_address_set [[style=filled, shape=box, fillcolor=white, 
> label="NB_address_set"]];
> +     sync_to_sb_addr_set [[style=filled, shape=box, fillcolor=white, 
> label="sync_to_sb_addr_set"]];
> +     northd -> sync_to_sb_addr_set [[label=""]];
> +     lr_stateful -> sync_to_sb_addr_set [[label=""]];
> +     SB_address_set -> sync_to_sb_addr_set [[label=""]];
> +     NB_address_set -> sync_to_sb_addr_set 
> [[label="sync_to_sb_addr_set_nb_address_set_handler"]];
> +     NB_port_group -> sync_to_sb_addr_set 
> [[label="sync_to_sb_addr_set_nb_port_group_handler"]];
> +     global_config -> sync_to_sb_addr_set 
> [[label="node_global_config_handler"]];
> +     SB_port_group [[style=filled, shape=box, fillcolor=white, 
> label="SB_port_group"]];
> +     port_group [[style=filled, shape=box, fillcolor=white, 
> label="port_group"]];
> +     NB_port_group -> port_group 
> [[label="port_group_nb_port_group_handler"]];
> +     SB_port_group -> port_group [[label=""]];
> +     northd -> port_group [[label="engine_noop_handler"]];
> +     NB_meter [[style=filled, shape=box, fillcolor=white, label="NB_meter"]];
> +     sync_meters [[style=filled, shape=box, fillcolor=white, 
> label="sync_meters"]];
> +     NB_acl -> sync_meters [[label="sync_meters_nb_acl_handler"]];
> +     NB_meter -> sync_meters [[label=""]];
> +     SB_meter -> sync_meters [[label=""]];
> +     SB_load_balancer [[style=filled, shape=box, fillcolor=white, 
> label="SB_load_balancer"]];
> +     SB_logical_dp_group [[style=filled, shape=box, fillcolor=white, 
> label="SB_logical_dp_group"]];
> +     sync_to_sb_lb [[style=filled, shape=box, fillcolor=white, 
> label="sync_to_sb_lb"]];
> +     global_config -> sync_to_sb_lb [[label="node_global_config_handler"]];
> +     northd -> sync_to_sb_lb [[label="sync_to_sb_lb_northd_handler"]];
> +     SB_load_balancer -> sync_to_sb_lb 
> [[label="sync_to_sb_lb_sb_load_balancer"]];
> +     SB_logical_dp_group -> sync_to_sb_lb [[label=""]];
> +     sync_to_sb_pb [[style=filled, shape=box, fillcolor=white, 
> label="sync_to_sb_pb"]];
> +     northd -> sync_to_sb_pb [[label="sync_to_sb_pb_northd_handler"]];
> +     lr_stateful -> sync_to_sb_pb 
> [[label="sync_to_sb_pb_lr_stateful_handler"]];
> +     sync_to_sb [[style=filled, shape=box, fillcolor=white, 
> label="sync_to_sb"]];
> +     sync_to_sb_addr_set -> sync_to_sb [[label=""]];
> +     port_group -> sync_to_sb [[label=""]];
> +     sync_meters -> sync_to_sb [[label=""]];
> +     sync_to_sb_lb -> sync_to_sb [[label=""]];
> +     sync_to_sb_pb -> sync_to_sb [[label=""]];
> +     SB_logical_flow [[style=filled, shape=box, fillcolor=white, 
> label="SB_logical_flow"]];
> +     SB_multicast_group [[style=filled, shape=box, fillcolor=white, 
> label="SB_multicast_group"]];
> +     NB_bfd [[style=filled, shape=box, fillcolor=white, label="NB_bfd"]];
> +     SB_bfd [[style=filled, shape=box, fillcolor=white, label="SB_bfd"]];
> +     bfd [[style=filled, shape=box, fillcolor=white, label="bfd"]];
> +     NB_bfd -> bfd [[label=""]];
> +     SB_bfd -> bfd [[label=""]];
> +     routes [[style=filled, shape=box, fillcolor=white, label="routes"]];
> +     bfd -> routes [[label=""]];
> +     northd -> routes [[label="routes_northd_change_handler"]];
> +     route_policies [[style=filled, shape=box, fillcolor=white, 
> label="route_policies"]];
> +     bfd -> route_policies [[label=""]];
> +     northd -> route_policies 
> [[label="route_policies_northd_change_handler"]];
> +     bfd_sync [[style=filled, shape=box, fillcolor=white, label="bfd_sync"]];
> +     bfd -> bfd_sync [[label=""]];
> +     NB_bfd -> bfd_sync [[label=""]];
> +     routes -> bfd_sync [[label=""]];
> +     route_policies -> bfd_sync [[label=""]];
> +     northd -> bfd_sync [[label="bfd_sync_northd_change_handler"]];
> +     SB_learned_route [[style=filled, shape=box, fillcolor=white, 
> label="SB_learned_route"]];
> +     learned_route_sync [[style=filled, shape=box, fillcolor=white, 
> label="learned_route_sync"]];
> +     SB_learned_route -> learned_route_sync 
> [[label="learned_route_sync_sb_learned_route_change_handler"]];
> +     northd -> learned_route_sync 
> [[label="learned_route_sync_northd_change_handler"]];
> +     group_ecmp_route [[style=filled, shape=box, fillcolor=white, 
> label="group_ecmp_route"]];
> +     routes -> group_ecmp_route [[label=""]];
> +     learned_route_sync -> group_ecmp_route 
> [[label="group_ecmp_route_learned_route_change_handler"]];
> +     ls_stateful [[style=filled, shape=box, fillcolor=white, 
> label="ls_stateful"]];
> +     northd -> ls_stateful [[label="ls_stateful_northd_handler"]];
> +     port_group -> ls_stateful [[label="ls_stateful_port_group_handler"]];
> +     NB_acl -> ls_stateful [[label="ls_stateful_acl_handler"]];
> +     SB_igmp_group [[style=filled, shape=box, fillcolor=white, 
> label="SB_igmp_group"]];
> +     multicast_igmp [[style=filled, shape=box, fillcolor=white, 
> label="multicast_igmp"]];
> +     northd -> multicast_igmp [[label="multicast_igmp_northd_handler"]];
> +     SB_multicast_group -> multicast_igmp [[label=""]];
> +     SB_igmp_group -> multicast_igmp [[label=""]];
> +     lflow [[style=filled, shape=box, fillcolor=white, label="lflow"]];
> +     sync_meters -> lflow [[label=""]];
> +     SB_logical_flow -> lflow [[label=""]];
> +     SB_multicast_group -> lflow [[label=""]];
> +     SB_logical_dp_group -> lflow [[label=""]];
> +     bfd_sync -> lflow [[label=""]];
> +     route_policies -> lflow [[label=""]];
> +     routes -> lflow [[label=""]];
> +     group_ecmp_route -> lflow 
> [[label="lflow_group_ecmp_route_change_handler"]];
> +     global_config -> lflow [[label="node_global_config_handler"]];
> +     sampling_app -> lflow [[label=""]];
> +     northd -> lflow [[label="lflow_northd_handler"]];
> +     port_group -> lflow [[label="engine_noop_handler"]];
> +     lr_stateful -> lflow [[label="lflow_lr_stateful_handler"]];
> +     ls_stateful -> lflow [[label="lflow_ls_stateful_handler"]];
> +     multicast_igmp -> lflow [[label="lflow_multicast_igmp_handler"]];
> +     SB_acl_id -> lflow [[label=""]];
> +     ic_learned_svc_monitors -> lflow 
> [[label="lflow_ic_learned_svc_mons_handler"]];
> +     mac_binding_aging_waker [[style=filled, shape=box, fillcolor=white, 
> label="mac_binding_aging_waker"]];
> +     mac_binding_aging [[style=filled, shape=box, fillcolor=white, 
> label="mac_binding_aging"]];
> +     SB_mac_binding -> mac_binding_aging [[label=""]];
> +     northd -> mac_binding_aging [[label=""]];
> +     mac_binding_aging_waker -> mac_binding_aging [[label=""]];
> +     global_config -> mac_binding_aging 
> [[label="node_global_config_handler"]];
> +     fdb_aging_waker [[style=filled, shape=box, fillcolor=white, 
> label="fdb_aging_waker"]];
> +     fdb_aging [[style=filled, shape=box, fillcolor=white, 
> label="fdb_aging"]];
> +     SB_fdb -> fdb_aging [[label=""]];
> +     northd -> fdb_aging [[label=""]];
> +     fdb_aging_waker -> fdb_aging [[label=""]];
> +     global_config -> fdb_aging [[label="node_global_config_handler"]];
> +     SB_ecmp_nexthop [[style=filled, shape=box, fillcolor=white, 
> label="SB_ecmp_nexthop"]];
> +     ecmp_nexthop [[style=filled, shape=box, fillcolor=white, 
> label="ecmp_nexthop"]];
> +     global_config -> ecmp_nexthop [[label=""]];
> +     routes -> ecmp_nexthop [[label=""]];
> +     SB_ecmp_nexthop -> ecmp_nexthop [[label=""]];
> +     SB_port_binding -> ecmp_nexthop [[label=""]];
> +     SB_mac_binding -> ecmp_nexthop 
> [[label="ecmp_nexthop_mac_binding_handler"]];
> +     dynamic_routes [[style=filled, shape=box, fillcolor=white, 
> label="dynamic_routes"]];
> +     lr_stateful -> dynamic_routes [[label=""]];
> +     northd -> dynamic_routes [[label="engine_noop_handler"]];
> +     SB_advertised_route [[style=filled, shape=box, fillcolor=white, 
> label="SB_advertised_route"]];
> +     advertised_route_sync [[style=filled, shape=box, fillcolor=white, 
> label="advertised_route_sync"]];
> +     routes -> advertised_route_sync [[label=""]];
> +     dynamic_routes -> advertised_route_sync [[label=""]];
> +     SB_advertised_route -> advertised_route_sync [[label=""]];
> +     lr_stateful -> advertised_route_sync 
> [[label="advertised_route_sync_lr_stateful_change_handler"]];
> +     northd -> advertised_route_sync 
> [[label="advertised_route_sync_northd_change_handler"]];
> +     SB_advertised_mac_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_advertised_mac_binding"]];
> +     advertised_mac_binding_sync [[style=filled, shape=box, fillcolor=white, 
> label="advertised_mac_binding_sync"]];
> +     SB_port_binding -> advertised_mac_binding_sync [[label=""]];
> +     SB_advertised_mac_binding -> advertised_mac_binding_sync [[label=""]];
> +     northd -> advertised_mac_binding_sync [[label="engine_noop_handler"]];
> +     northd_output [[style=filled, shape=box, fillcolor=white, 
> label="northd_output"]];
> +     acl_id -> northd_output [[label=""]];
> +     sync_from_sb -> northd_output [[label=""]];
> +     sync_to_sb -> northd_output 
> [[label="northd_output_sync_to_sb_handler"]];
> +     lflow -> northd_output [[label="northd_output_lflow_handler"]];
> +     mac_binding_aging -> northd_output 
> [[label="northd_output_mac_binding_aging_handler"]];
> +     fdb_aging -> northd_output [[label="northd_output_fdb_aging_handler"]];
> +     ecmp_nexthop -> northd_output 
> [[label="northd_output_ecmp_nexthop_handler"]];
> +     acl_id -> northd_output [[label="northd_output_acl_id_handler"]];
> +     advertised_route_sync -> northd_output 
> [[label="northd_output_advertised_route_sync_handler"]];
> +     advertised_mac_binding_sync -> northd_output 
> [[label="northd_output_advertised_mac_binding_sync_handler"]];
> +}
> +])
> +AT_CLEANUP
> +
> +AT_SETUP([northd: dump partial incremental processing graph (up to 
> datapath_sync)])
> +AT_KEYWORDS([inc-proc-graph])
> +AT_CHECK([ovn-northd --dump-inc-proc-graph=datapath_sync], [0], [dnl
> +digraph "Incremental-Processing-Engine" {
> +     rankdir=LR;
> +     datapath_sync [[style=filled, shape=box, fillcolor=white, 
> label="datapath_sync"]];
> +     global_config -> datapath_sync 
> [[label="datapath_sync_global_config_handler"]];
> +     global_config [[style=filled, shape=box, fillcolor=white, 
> label="global_config"]];
> +     NB_nb_global -> global_config 
> [[label="global_config_nb_global_handler"]];
> +     NB_nb_global [[style=filled, shape=box, fillcolor=white, 
> label="NB_nb_global"]];
> +     NB_logical_switch -> global_config 
> [[label="global_config_nb_logical_switch_handler"]];
> +     NB_logical_switch [[style=filled, shape=box, fillcolor=white, 
> label="NB_logical_switch"]];
> +     SB_sb_global -> global_config 
> [[label="global_config_sb_global_handler"]];
> +     SB_sb_global [[style=filled, shape=box, fillcolor=white, 
> label="SB_sb_global"]];
> +     SB_chassis -> global_config 
> [[label="global_config_sb_chassis_handler"]];
> +     SB_chassis [[style=filled, shape=box, fillcolor=white, 
> label="SB_chassis"]];
> +     sampling_app -> global_config [[label=""]];
> +     sampling_app [[style=filled, shape=box, fillcolor=white, 
> label="sampling_app"]];
> +     NB_sampling_app -> sampling_app [[label=""]];
> +     NB_sampling_app [[style=filled, shape=box, fillcolor=white, 
> label="NB_sampling_app"]];
> +     SB_datapath_binding -> datapath_sync 
> [[label="datapath_sync_sb_datapath_binding"]];
> +     SB_datapath_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_datapath_binding"]];
> +     datapath_logical_switch -> datapath_sync 
> [[label="datapath_sync_logical_switch_handler"]];
> +     datapath_logical_switch [[style=filled, shape=box, fillcolor=white, 
> label="datapath_logical_switch"]];
> +     NB_logical_switch -> datapath_logical_switch 
> [[label="datapath_logical_switch_handler"]];
> +     global_config -> datapath_logical_switch 
> [[label="datapath_logical_switch_handler"]];
> +     datapath_logical_router -> datapath_sync 
> [[label="datapath_sync_logical_router_handler"]];
> +     datapath_logical_router [[style=filled, shape=box, fillcolor=white, 
> label="datapath_logical_router"]];
> +     NB_logical_router -> datapath_logical_router 
> [[label="en_datapath_logical_router_logical_router_handler"]];
> +     NB_logical_router [[style=filled, shape=box, fillcolor=white, 
> label="NB_logical_router"]];
> +}
> +])
> +AT_CLEANUP
> +
> +AT_SETUP([controller: dump full incremental processing graph])
> +AT_KEYWORDS([inc-proc-graph])
> +AT_CHECK([ovn-controller --dump-inc-proc-graph], [0], [dnl
> +digraph "Incremental-Processing-Engine" {
> +     rankdir=LR;
> +     SB_dns [[style=filled, shape=box, fillcolor=white, label="SB_dns"]];
> +     dns_cache [[style=filled, shape=box, fillcolor=white, 
> label="dns_cache"]];
> +     SB_dns -> dns_cache [[label="dns_cache_sb_dns_handler"]];
> +     SB_sb_global [[style=filled, shape=box, fillcolor=white, 
> label="SB_sb_global"]];
> +     northd_options [[style=filled, shape=box, fillcolor=white, 
> label="northd_options"]];
> +     SB_sb_global -> northd_options 
> [[label="en_northd_options_sb_sb_global_handler"]];
> +     SB_dhcp_options [[style=filled, shape=box, fillcolor=white, 
> label="SB_dhcp_options"]];
> +     SB_dhcpv6_options [[style=filled, shape=box, fillcolor=white, 
> label="SB_dhcpv6_options"]];
> +     dhcp_options [[style=filled, shape=box, fillcolor=white, 
> label="dhcp_options"]];
> +     SB_dhcp_options -> dhcp_options [[label=""]];
> +     SB_dhcpv6_options -> dhcp_options [[label=""]];
> +     SB_address_set [[style=filled, shape=box, fillcolor=white, 
> label="SB_address_set"]];
> +     addr_sets [[style=filled, shape=box, fillcolor=white, 
> label="addr_sets"]];
> +     SB_address_set -> addr_sets 
> [[label="addr_sets_sb_address_set_handler"]];
> +     SB_port_group [[style=filled, shape=box, fillcolor=white, 
> label="SB_port_group"]];
> +     ofctrl_is_connected [[style=filled, shape=box, fillcolor=white, 
> label="ofctrl_is_connected"]];
> +     OVS_open_vswitch [[style=filled, shape=box, fillcolor=white, 
> label="OVS_open_vswitch"]];
> +     OVS_bridge [[style=filled, shape=box, fillcolor=white, 
> label="OVS_bridge"]];
> +     OVS_qos [[style=filled, shape=box, fillcolor=white, label="OVS_qos"]];
> +     OVS_queue [[style=filled, shape=box, fillcolor=white, 
> label="OVS_queue"]];
> +     SB_chassis [[style=filled, shape=box, fillcolor=white, 
> label="SB_chassis"]];
> +     SB_datapath_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_datapath_binding"]];
> +     SB_port_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_port_binding"]];
> +     postponed_ports [[style=filled, shape=box, fillcolor=white, 
> label="postponed_ports"]];
> +     sb_ro [[style=filled, shape=box, fillcolor=white, label="sb_ro"]];
> +     OVS_port [[style=filled, shape=box, fillcolor=white, label="OVS_port"]];
> +     OVS_interface [[style=filled, shape=box, fillcolor=white, 
> label="OVS_interface"]];
> +     ovs_interface_shadow [[style=filled, shape=box, fillcolor=white, 
> label="ovs_interface_shadow"]];
> +     OVS_interface -> ovs_interface_shadow 
> [[label="ovs_interface_shadow_ovs_interface_handler"]];
> +     runtime_data [[style=filled, shape=box, fillcolor=white, 
> label="runtime_data"]];
> +     ofctrl_is_connected -> runtime_data [[label=""]];
> +     OVS_open_vswitch -> runtime_data [[label=""]];
> +     OVS_bridge -> runtime_data [[label=""]];
> +     OVS_qos -> runtime_data [[label=""]];
> +     OVS_queue -> runtime_data [[label=""]];
> +     SB_chassis -> runtime_data [[label=""]];
> +     SB_datapath_binding -> runtime_data 
> [[label="runtime_data_sb_datapath_binding_handler"]];
> +     SB_port_binding -> runtime_data 
> [[label="runtime_data_sb_port_binding_handler"]];
> +     postponed_ports -> runtime_data 
> [[label="runtime_data_sb_port_binding_handler"]];
> +     sb_ro -> runtime_data [[label="runtime_data_sb_ro_handler"]];
> +     OVS_port -> runtime_data [[label="engine_noop_handler"]];
> +     ovs_interface_shadow -> runtime_data 
> [[label="runtime_data_ovs_interface_shadow_handler"]];
> +     port_groups [[style=filled, shape=box, fillcolor=white, 
> label="port_groups"]];
> +     SB_port_group -> port_groups 
> [[label="port_groups_sb_port_group_handler"]];
> +     runtime_data -> port_groups 
> [[label="port_groups_runtime_data_handler"]];
> +     SB_chassis_template_var [[style=filled, shape=box, fillcolor=white, 
> label="SB_chassis_template_var"]];
> +     template_vars [[style=filled, shape=box, fillcolor=white, 
> label="template_vars"]];
> +     OVS_open_vswitch -> template_vars [[label=""]];
> +     SB_chassis -> template_vars [[label=""]];
> +     SB_chassis_template_var -> template_vars 
> [[label="template_vars_sb_chassis_template_var_handler"]];
> +     non_vif_data [[style=filled, shape=box, fillcolor=white, 
> label="non_vif_data"]];
> +     OVS_open_vswitch -> non_vif_data [[label=""]];
> +     OVS_bridge -> non_vif_data [[label=""]];
> +     SB_chassis -> non_vif_data [[label=""]];
> +     OVS_interface -> non_vif_data 
> [[label="non_vif_data_ovs_iface_handler"]];
> +     SB_multicast_group [[style=filled, shape=box, fillcolor=white, 
> label="SB_multicast_group"]];
> +     OVS_flow_sample_collector_set [[style=filled, shape=box, 
> fillcolor=white, label="OVS_flow_sample_collector_set"]];
> +     SB_mac_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_mac_binding"]];
> +     SB_static_mac_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_static_mac_binding"]];
> +     SB_logical_flow [[style=filled, shape=box, fillcolor=white, 
> label="SB_logical_flow"]];
> +     SB_logical_dp_group [[style=filled, shape=box, fillcolor=white, 
> label="SB_logical_dp_group"]];
> +     SB_load_balancer [[style=filled, shape=box, fillcolor=white, 
> label="SB_load_balancer"]];
> +     lb_data [[style=filled, shape=box, fillcolor=white, label="lb_data"]];
> +     SB_load_balancer -> lb_data 
> [[label="lb_data_sb_load_balancer_handler"]];
> +     template_vars -> lb_data [[label="lb_data_template_var_handler"]];
> +     runtime_data -> lb_data [[label="lb_data_runtime_data_handler"]];
> +     SB_fdb [[style=filled, shape=box, fillcolor=white, label="SB_fdb"]];
> +     SB_meter [[style=filled, shape=box, fillcolor=white, label="SB_meter"]];
> +     lflow_output [[style=filled, shape=box, fillcolor=white, 
> label="lflow_output"]];
> +     northd_options -> lflow_output [[label=""]];
> +     dhcp_options -> lflow_output [[label=""]];
> +     addr_sets -> lflow_output [[label="lflow_output_addr_sets_handler"]];
> +     port_groups -> lflow_output 
> [[label="lflow_output_port_groups_handler"]];
> +     template_vars -> lflow_output 
> [[label="lflow_output_template_vars_handler"]];
> +     runtime_data -> lflow_output 
> [[label="lflow_output_runtime_data_handler"]];
> +     non_vif_data -> lflow_output [[label=""]];
> +     SB_multicast_group -> lflow_output 
> [[label="lflow_output_sb_multicast_group_handler"]];
> +     SB_chassis -> lflow_output 
> [[label="pflow_lflow_output_sb_chassis_handler"]];
> +     SB_port_binding -> lflow_output 
> [[label="lflow_output_sb_port_binding_handler"]];
> +     OVS_open_vswitch -> lflow_output [[label=""]];
> +     OVS_bridge -> lflow_output [[label=""]];
> +     OVS_flow_sample_collector_set -> lflow_output 
> [[label="lflow_output_flow_sample_collector_set_handler"]];
> +     SB_mac_binding -> lflow_output 
> [[label="lflow_output_sb_mac_binding_handler"]];
> +     SB_static_mac_binding -> lflow_output 
> [[label="lflow_output_sb_static_mac_binding_handler"]];
> +     SB_logical_flow -> lflow_output 
> [[label="lflow_output_sb_logical_flow_handler"]];
> +     SB_logical_dp_group -> lflow_output [[label="engine_noop_handler"]];
> +     lb_data -> lflow_output [[label="lflow_output_lb_data_handler"]];
> +     SB_fdb -> lflow_output [[label="lflow_output_sb_fdb_handler"]];
> +     SB_meter -> lflow_output [[label="lflow_output_sb_meter_handler"]];
> +     ct_zones [[style=filled, shape=box, fillcolor=white, label="ct_zones"]];
> +     OVS_open_vswitch -> ct_zones [[label=""]];
> +     OVS_bridge -> ct_zones [[label=""]];
> +     SB_datapath_binding -> ct_zones 
> [[label="ct_zones_datapath_binding_handler"]];
> +     runtime_data -> ct_zones [[label="ct_zones_runtime_data_handler"]];
> +     if_status_mgr [[style=filled, shape=box, fillcolor=white, 
> label="if_status_mgr"]];
> +     OVS_interface -> if_status_mgr 
> [[label="if_status_mgr_ovs_interface_handler"]];
> +     activated_ports [[style=filled, shape=box, fillcolor=white, 
> label="activated_ports"]];
> +     SB_encap [[style=filled, shape=box, fillcolor=white, label="SB_encap"]];
> +     mff_ovn_geneve [[style=filled, shape=box, fillcolor=white, 
> label="mff_ovn_geneve"]];
> +     SB_advertised_mac_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_advertised_mac_binding"]];
> +     neighbor [[style=filled, shape=box, fillcolor=white, label="neighbor"]];
> +     OVS_open_vswitch -> neighbor [[label=""]];
> +     SB_chassis -> neighbor [[label=""]];
> +     SB_advertised_mac_binding -> neighbor [[label=""]];
> +     runtime_data -> neighbor [[label="neighbor_runtime_data_handler"]];
> +     SB_datapath_binding -> neighbor 
> [[label="neighbor_sb_datapath_binding_handler"]];
> +     SB_port_binding -> neighbor 
> [[label="neighbor_sb_port_binding_handler"]];
> +     host_if_monitor [[style=filled, shape=box, fillcolor=white, 
> label="host_if_monitor"]];
> +     neighbor_table_notify [[style=filled, shape=box, fillcolor=white, 
> label="neighbor_table_notify"]];
> +     neighbor_exchange_status [[style=filled, shape=box, fillcolor=white, 
> label="neighbor_exchange_status"]];
> +     neighbor_exchange [[style=filled, shape=box, fillcolor=white, 
> label="neighbor_exchange"]];
> +     neighbor -> neighbor_exchange [[label=""]];
> +     host_if_monitor -> neighbor_exchange [[label=""]];
> +     neighbor_table_notify -> neighbor_exchange [[label=""]];
> +     neighbor_exchange_status -> neighbor_exchange [[label=""]];
> +     evpn_vtep_binding [[style=filled, shape=box, fillcolor=white, 
> label="evpn_vtep_binding"]];
> +     OVS_open_vswitch -> evpn_vtep_binding [[label=""]];
> +     OVS_bridge -> evpn_vtep_binding [[label=""]];
> +     neighbor_exchange -> evpn_vtep_binding [[label=""]];
> +     runtime_data -> evpn_vtep_binding [[label="engine_noop_handler"]];
> +     OVS_interface -> evpn_vtep_binding 
> [[label="evpn_vtep_binding_ovs_interface_handler"]];
> +     SB_datapath_binding -> evpn_vtep_binding 
> [[label="evpn_vtep_binding_datapath_binding_handler"]];
> +     evpn_fdb [[style=filled, shape=box, fillcolor=white, label="evpn_fdb"]];
> +     neighbor_exchange -> evpn_fdb [[label=""]];
> +     evpn_vtep_binding -> evpn_fdb [[label="evpn_fdb_vtep_binding_handler"]];
> +     evpn_arp [[style=filled, shape=box, fillcolor=white, label="evpn_arp"]];
> +     neighbor_exchange -> evpn_arp [[label=""]];
> +     evpn_vtep_binding -> evpn_arp [[label="evpn_arp_vtep_binding_handler"]];
> +     pflow_output [[style=filled, shape=box, fillcolor=white, 
> label="pflow_output"]];
> +     non_vif_data -> pflow_output [[label=""]];
> +     northd_options -> pflow_output [[label=""]];
> +     ct_zones -> pflow_output [[label="pflow_output_ct_zones_handler"]];
> +     SB_chassis -> pflow_output 
> [[label="pflow_lflow_output_sb_chassis_handler"]];
> +     if_status_mgr -> pflow_output 
> [[label="pflow_output_if_status_mgr_handler"]];
> +     SB_port_binding -> pflow_output 
> [[label="pflow_output_sb_port_binding_handler"]];
> +     SB_multicast_group -> pflow_output 
> [[label="pflow_output_sb_multicast_group_handler"]];
> +     SB_datapath_binding -> pflow_output [[label="engine_noop_handler"]];
> +     activated_ports -> pflow_output 
> [[label="pflow_output_activated_ports_handler"]];
> +     runtime_data -> pflow_output 
> [[label="pflow_output_runtime_data_handler"]];
> +     SB_encap -> pflow_output [[label=""]];
> +     mff_ovn_geneve -> pflow_output [[label=""]];
> +     OVS_open_vswitch -> pflow_output [[label=""]];
> +     OVS_bridge -> pflow_output [[label=""]];
> +     OVS_flow_sample_collector_set -> pflow_output 
> [[label="pflow_output_debug_handler"]];
> +     SB_sb_global -> pflow_output [[label="pflow_output_debug_handler"]];
> +     evpn_vtep_binding -> pflow_output 
> [[label="pflow_output_evpn_binding_handler"]];
> +     evpn_fdb -> pflow_output [[label="pflow_output_fdb_handler"]];
> +     evpn_arp -> pflow_output [[label="pflow_output_arp_handler"]];
> +     mac_cache [[style=filled, shape=box, fillcolor=white, 
> label="mac_cache"]];
> +     runtime_data -> mac_cache [[label="mac_cache_runtime_data_handler"]];
> +     SB_mac_binding -> mac_cache 
> [[label="mac_cache_sb_mac_binding_handler"]];
> +     SB_fdb -> mac_cache [[label="mac_cache_sb_fdb_handler"]];
> +     SB_datapath_binding -> mac_cache 
> [[label="mac_cache_sb_datapath_binding_handler"]];
> +     SB_port_binding -> mac_cache [[label="engine_noop_handler"]];
> +     SB_ha_chassis_group [[style=filled, shape=box, fillcolor=white, 
> label="SB_ha_chassis_group"]];
> +     bfd_chassis [[style=filled, shape=box, fillcolor=white, 
> label="bfd_chassis"]];
> +     OVS_open_vswitch -> bfd_chassis [[label=""]];
> +     SB_chassis -> bfd_chassis [[label=""]];
> +     SB_ha_chassis_group -> bfd_chassis [[label=""]];
> +     SB_advertised_route [[style=filled, shape=box, fillcolor=white, 
> label="SB_advertised_route"]];
> +     route [[style=filled, shape=box, fillcolor=white, label="route"]];
> +     OVS_open_vswitch -> route [[label=""]];
> +     SB_chassis -> route [[label=""]];
> +     SB_port_binding -> route [[label="route_sb_port_binding_data_handler"]];
> +     runtime_data -> route [[label="route_runtime_data_handler"]];
> +     SB_advertised_route -> route 
> [[label="route_sb_advertised_route_data_handler"]];
> +     SB_learned_route [[style=filled, shape=box, fillcolor=white, 
> label="SB_learned_route"]];
> +     route_table_notify [[style=filled, shape=box, fillcolor=white, 
> label="route_table_notify"]];
> +     route_exchange_status [[style=filled, shape=box, fillcolor=white, 
> label="route_exchange_status"]];
> +     route_exchange [[style=filled, shape=box, fillcolor=white, 
> label="route_exchange"]];
> +     route -> route_exchange [[label=""]];
> +     SB_learned_route -> route_exchange [[label="engine_noop_handler"]];
> +     SB_port_binding -> route_exchange [[label="engine_noop_handler"]];
> +     route_table_notify -> route_exchange [[label=""]];
> +     route_exchange_status -> route_exchange [[label=""]];
> +     sb_ro -> route_exchange [[label="route_exchange_sb_ro_handler"]];
> +     garp_rarp [[style=filled, shape=box, fillcolor=white, 
> label="garp_rarp"]];
> +     OVS_open_vswitch -> garp_rarp [[label=""]];
> +     SB_chassis -> garp_rarp [[label=""]];
> +     SB_port_binding -> garp_rarp 
> [[label="garp_rarp_sb_port_binding_handler"]];
> +     SB_datapath_binding -> garp_rarp 
> [[label="garp_rarp_sb_datapath_binding_handler"]];
> +     SB_mac_binding -> garp_rarp [[label="engine_noop_handler"]];
> +     runtime_data -> garp_rarp [[label="garp_rarp_runtime_data_handler"]];
> +     SB_acl_id [[style=filled, shape=box, fillcolor=white, 
> label="SB_acl_id"]];
> +     acl_id [[style=filled, shape=box, fillcolor=white, label="acl_id"]];
> +     SB_acl_id -> acl_id [[label=""]];
> +     controller_output [[style=filled, shape=box, fillcolor=white, 
> label="controller_output"]];
> +     dns_cache -> controller_output [[label=""]];
> +     lflow_output -> controller_output 
> [[label="controller_output_lflow_output_handler"]];
> +     pflow_output -> controller_output 
> [[label="controller_output_pflow_output_handler"]];
> +     mac_cache -> controller_output 
> [[label="controller_output_mac_cache_handler"]];
> +     bfd_chassis -> controller_output 
> [[label="controller_output_bfd_chassis_handler"]];
> +     route_exchange -> controller_output 
> [[label="controller_output_route_exchange_handler"]];
> +     garp_rarp -> controller_output 
> [[label="controller_output_garp_rarp_handler"]];
> +     acl_id -> controller_output 
> [[label="controller_output_acl_id_handler"]];
> +}
> +])
> +AT_CLEANUP
> +
> +AT_SETUP([controller: dump partial incremental processing graph (up to 
> runtime_data)])
> +AT_KEYWORDS([inc-proc-graph])
> +AT_CHECK([ovn-controller --dump-inc-proc-graph=runtime_data], [0], [dnl
> +digraph "Incremental-Processing-Engine" {
> +     rankdir=LR;
> +     runtime_data [[style=filled, shape=box, fillcolor=white, 
> label="runtime_data"]];
> +     ofctrl_is_connected -> runtime_data [[label=""]];
> +     ofctrl_is_connected [[style=filled, shape=box, fillcolor=white, 
> label="ofctrl_is_connected"]];
> +     OVS_open_vswitch -> runtime_data [[label=""]];
> +     OVS_open_vswitch [[style=filled, shape=box, fillcolor=white, 
> label="OVS_open_vswitch"]];
> +     OVS_bridge -> runtime_data [[label=""]];
> +     OVS_bridge [[style=filled, shape=box, fillcolor=white, 
> label="OVS_bridge"]];
> +     OVS_qos -> runtime_data [[label=""]];
> +     OVS_qos [[style=filled, shape=box, fillcolor=white, label="OVS_qos"]];
> +     OVS_queue -> runtime_data [[label=""]];
> +     OVS_queue [[style=filled, shape=box, fillcolor=white, 
> label="OVS_queue"]];
> +     SB_chassis -> runtime_data [[label=""]];
> +     SB_chassis [[style=filled, shape=box, fillcolor=white, 
> label="SB_chassis"]];
> +     SB_datapath_binding -> runtime_data 
> [[label="runtime_data_sb_datapath_binding_handler"]];
> +     SB_datapath_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_datapath_binding"]];
> +     SB_port_binding -> runtime_data 
> [[label="runtime_data_sb_port_binding_handler"]];
> +     SB_port_binding [[style=filled, shape=box, fillcolor=white, 
> label="SB_port_binding"]];
> +     postponed_ports -> runtime_data 
> [[label="runtime_data_sb_port_binding_handler"]];
> +     postponed_ports [[style=filled, shape=box, fillcolor=white, 
> label="postponed_ports"]];
> +     sb_ro -> runtime_data [[label="runtime_data_sb_ro_handler"]];
> +     sb_ro [[style=filled, shape=box, fillcolor=white, label="sb_ro"]];
> +     OVS_port -> runtime_data [[label="engine_noop_handler"]];
> +     OVS_port [[style=filled, shape=box, fillcolor=white, label="OVS_port"]];
> +     ovs_interface_shadow -> runtime_data 
> [[label="runtime_data_ovs_interface_shadow_handler"]];
> +     ovs_interface_shadow [[style=filled, shape=box, fillcolor=white, 
> label="ovs_interface_shadow"]];
> +     OVS_interface -> ovs_interface_shadow 
> [[label="ovs_interface_shadow_ovs_interface_handler"]];
> +     OVS_interface [[style=filled, shape=box, fillcolor=white, 
> label="OVS_interface"]];
> +}
> +])
> +AT_CLEANUP
> diff --git a/tests/testsuite.at b/tests/testsuite.at
> index 5f5eabb42a..6216ac761d 100644
> --- a/tests/testsuite.at
> +++ b/tests/testsuite.at
> @@ -42,3 +42,4 @@ m4_include([tests/ovn-ipsec.at])
>  m4_include([tests/ovn-vif-plug.at])
>  m4_include([tests/ovn-util.at])
>  m4_include([tests/ovn-br-controller.at])
> +m4_include([tests/ovn-inc-proc-graph-dump.at])
> -- 
> 2.51.1
> 
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> 

Looks good to me.

Acked-by: Mairtin O'Loingsigh <[email protected]>

Regards,
Mairtin

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to