static String toDotString(RunnerApi.Pipeline pipeline) {
    return new PortablePipelineDotRenderer().toDot(pipeline);
  }
@Test
  public void testCompositePipeline() {
    p.apply(Create.timestamped(TimestampedValue.of(KV.of(1, 1), new Instant(1))))
        .apply(Window.into(FixedWindows.of(Duration.millis(10))))
        .apply(Sum.integersPerKey());

    assertEquals(
        "digraph {"
            + "    rankdir=LR"
            + "    0 [label=\"Create.TimestampedValues\\n\"]"
            + "    1 [label=\"Window.Into()\\n\"]"
            + "    0 -> 1 [style=solid label=\"Create.TimestampedValues/ParDo(ConvertTimestamps)/ParMultiDo(ConvertTimestamps).output\"]"
            + "    2 [label=\"Combine.perKey(SumInteger)\\nbeam:transform:combine_per_key:v1\"]"
            + "    1 -> 2 [style=solid label=\"Window.Into()/Window.Assign.out\"]"
            + "}",
        PortablePipelineDotRenderer.toDotString(PipelineTranslation.toProto(p))
            .replaceAll(System.lineSeparator(), ""));
  }