code: def check_results(self, flow, checker):
      from collections import defaultdict
  
      join_sets = defaultdict(set)
      lineages = {}
      graph = flow._graph
  
      # traverse all paths from the start step to the end,
      # collect lineages on the way and finally compare them
      # to the lineages produced by the actual run
      def traverse(step, lineage):
          if graph[step].type == "join":
              join_sets[step].add(tuple(lineage))
              if len(join_sets[step]) < len(graph[step].in_funcs):
                  return
              else:
                  lineage = (tuple(sorted(join_sets[step])),)
          lineages[step] = lineage + (step,)
          for n in graph[step].out_funcs:
              traverse(n, lineage + (step,))
  
      traverse("start", ())
  
      for step in flow:
          checker.assert_artifact(
              step.name, "lineage", lineages[step.name]
          )
  
imports: from metaflow_test import MetaflowTest, ExpectationFailed, steps
label_desc: Use image node_id 4 for calling the LineageTest obj's underlying member method code with example usage: obj.check_results(flow, checker) without return types