]> granicus.if.org Git - graphviz/commitdiff
add new simple test_engines test
authorMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Tue, 5 Jul 2022 17:22:31 +0000 (19:22 +0200)
committerMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Mon, 25 Jul 2022 18:24:05 +0000 (20:24 +0200)
Upcoming commits in this series will make changes to gvFreeLayout and
we want to ensure that those changes don't introduce any memory leaks
when run with ASan, since gvFreeLayout calls layout-specific cleanup
functions.

This test is run in CI with ASan leak detection enabled. It currently
fails because of a memory leak in the osage layout.

Towards https://gitlab.com/graphviz/graphviz/-/issues/1800.

tests/CMakeLists.txt
tests/test_engines.cpp [new file with mode: 0644]

index 7ba4b6e04a2fdfebab332cf5ebd15a9b6c07cec9..242d1c322b67b7f604a6d37493891eea05e8eefd 100644 (file)
@@ -67,6 +67,8 @@ macro(CREATE_TEST testname)
 endmacro()
 
 CREATE_TEST(AGraph_construction)
+CREATE_TEST(engines)
+set_tests_properties(test_engines PROPERTIES WILL_FAIL true)
 CREATE_TEST(GVContext_construction)
 CREATE_TEST(GVContext_render_svg)
 CREATE_TEST(GVLayout_construction)
diff --git a/tests/test_engines.cpp b/tests/test_engines.cpp
new file mode 100644 (file)
index 0000000..24b0898
--- /dev/null
@@ -0,0 +1,81 @@
+#include <string>
+
+#include <catch2/catch.hpp>
+#include <fmt/format.h>
+
+#include <cgraph/cgraph.h>
+#include <gvc/gvc.h>
+
+#include "svg_analyzer.h"
+
+TEST_CASE(
+    "simple directed and undirected graph with different layout engines") {
+  const auto directed_graph = GENERATE(false, true);
+
+  const std::string graph_type = directed_graph ? "digraph" : "graph";
+  const std::string edge_op = directed_graph ? "->" : "--";
+
+  std::string dot = fmt::format("{} {{a {} b}}", graph_type, edge_op);
+  INFO(fmt::format("DOT source: {}", dot));
+
+  auto g = agmemread(dot.c_str());
+  REQUIRE(g != nullptr);
+
+  const std::string engine = GENERATE("dot",      //
+                                      "neato",    //
+                                      "fdp",      //
+                                      "sfdp",     //
+                                      "circo",    //
+                                      "twopi",    //
+                                      "osage",    //
+                                      "patchwork" //
+  );
+  INFO("Layout engine: " + engine);
+
+  auto gvc = gvContextPlugins(lt_preloaded_symbols, false);
+
+  {
+    const auto rc = gvLayout(gvc, g, engine.c_str());
+    REQUIRE(rc == 0);
+  }
+
+  char *result = nullptr;
+  unsigned length = 0;
+  {
+    const auto rc = gvRenderData(gvc, g, "svg", &result, &length);
+    REQUIRE(rc == 0);
+  }
+  REQUIRE(result != nullptr);
+  REQUIRE(length > 0);
+
+  SVGAnalyzer svg_analyzer{result};
+
+  const std::size_t num_nodes = 2;
+  const std::size_t num_edges = engine == "patchwork" ? 0 : 1;
+  const std::size_t num_arrowheads = directed_graph ? num_edges : 0;
+
+  const std::size_t num_svgs = 1;
+  const std::size_t num_groups = 1 + num_nodes + num_edges;
+  const std::size_t num_ellipses = engine == "patchwork" ? 0 : num_nodes;
+  const std::size_t num_polygons =
+      1 + (engine == "patchwork" ? num_nodes : 0) + num_arrowheads;
+  const std::size_t num_paths = num_edges;
+  const std::size_t num_titles = num_nodes + num_edges;
+
+  CHECK(svg_analyzer.num_svgs() == num_svgs);
+  CHECK(svg_analyzer.num_groups() == num_groups);
+  CHECK(svg_analyzer.num_circles() == 0);
+  CHECK(svg_analyzer.num_ellipses() == num_ellipses);
+  CHECK(svg_analyzer.num_lines() == 0);
+  CHECK(svg_analyzer.num_paths() == num_paths);
+  CHECK(svg_analyzer.num_polygons() == num_polygons);
+  CHECK(svg_analyzer.num_polylines() == 0);
+  CHECK(svg_analyzer.num_rects() == 0);
+  CHECK(svg_analyzer.num_titles() == num_titles);
+  CHECK(svg_analyzer.num_unknowns() == 0);
+
+  gvFreeRenderData(result);
+  gvFreeLayout(gvc, g);
+  agclose(g);
+  gvFreeContext(gvc);
+}