@Test
public void testRegeneration() throws IOException, InterruptedException {

  // In this test we run the generator twice, changing the generated
  // google/example/library/v1/BUILD.bazel
  // after the first run, and verifying that some changed values are preserved
  // (and some are not).
  Path tempDirPath = getTemporaryDirectory();

  // I'm lazy, so let's just "cp -r" stuff.
  Path fixturesPath = Paths.get(PATH_PREFIX, SRC_DIR);
  new ProcessBuilder(new String[] {"cp", "-r", fixturesPath.toString(), tempDirPath.toString()})
      .start()
      .waitFor();

  String buildozerPath = getBuildozerPath();
  Path copiedGoogleapis = Paths.get(tempDirPath.toString(), "googleapis");
  ArgsParser args =
      new ArgsParser(new String[] {"--buildozer=" + buildozerPath, "--src=" + copiedGoogleapis});
  new BuildFileGenerator()
      .generateBuildFiles(args.createApisVisitor(null, tempDirPath.toString()));

  Path fileBodyPathPrefix =
      Paths.get(copiedGoogleapis.toString(), "google", "example", "library");
  Path gapicBuildFilePath = Paths.get(fileBodyPathPrefix.toString(), "v1", "BUILD.bazel");
  String rawBuildFilePath = Paths.get(fileBodyPathPrefix.toString(), "BUILD.bazel").toString();

  Assert.assertEquals(
      ApisVisitor.readFile(gapicBuildFilePath.toString() + ".baseline"),
      ApisVisitor.readFile(gapicBuildFilePath.toString()));
  Assert.assertEquals(
      ApisVisitor.readFile(rawBuildFilePath + ".baseline"),
      ApisVisitor.readFile(rawBuildFilePath));

  // Now change some values in google/example/library/v1/BUILD.bazel
  Buildozer.setBinaryPath(buildozerPath);
  Buildozer buildozer = Buildozer.getInstance();
  // The following values should be preserved:
  buildozer.batchSetAttribute(
      gapicBuildFilePath, "library_nodejs_gapic", "package_name", "@google-cloud/library");
  buildozer.batchRemoveAttribute(
      gapicBuildFilePath, "library_nodejs_gapic", "extra_protoc_parameters");
  buildozer.batchAddAttribute(
      gapicBuildFilePath, "library_nodejs_gapic", "extra_protoc_parameters", "param1");
  buildozer.batchAddAttribute(
      gapicBuildFilePath, "library_nodejs_gapic", "extra_protoc_parameters", "param2");
  buildozer.batchSetAttribute(
      gapicBuildFilePath,
      "google-cloud-example-library-v1-csharp",
      "name",
      "renamed_csharp_rule");
  buildozer.batchSetAttribute(
      gapicBuildFilePath, "google-cloud-example-library-v1-java", "name", "renamed_java_rule");

  // The following values should NOT be preserved:
  buildozer.batchSetAttribute(
      gapicBuildFilePath,
      "library_nodejs_gapic",
      "grpc_service_config",
      "fake_grpc_service_config");

  buildozer.commit();

  // Run the generator again
  new BuildFileGenerator()
      .generateBuildFiles(args.createApisVisitor(null, tempDirPath.toString()));

  // Check that values are preserved
  Assert.assertEquals(
      "@google-cloud/library",
      buildozer.getAttribute(gapicBuildFilePath, "library_nodejs_gapic", "package_name"));
  Assert.assertEquals(
      "[param1 param2]",
      buildozer.getAttribute(
          gapicBuildFilePath, "library_nodejs_gapic", "extra_protoc_parameters"));
  Assert.assertEquals(
      "renamed_csharp_rule",
      buildozer.getAttribute(gapicBuildFilePath, "%csharp_gapic_assembly_pkg", "name"));
  Assert.assertEquals(
      "renamed_java_rule",
      buildozer.getAttribute(gapicBuildFilePath, "%java_gapic_assembly_gradle_pkg", "name"));
  // Check that grpc_service_config value is not preserved:
  Assert.assertEquals(
      "library_example_grpc_service_config.json",
      buildozer.getAttribute(gapicBuildFilePath, "library_nodejs_gapic", "grpc_service_config"));

  // Now run with overwrite and verify it actually ignores all the changes
  ArgsParser argsOverwrite =
      new ArgsParser(
          new String[] {
            "--overwrite", "--buildozer=" + buildozerPath, "--src=" + copiedGoogleapis
          });
  new BuildFileGenerator()
      .generateBuildFiles(argsOverwrite.createApisVisitor(null, tempDirPath.toString()));
  Assert.assertEquals(
      ApisVisitor.readFile(gapicBuildFilePath.toString() + ".baseline"),
      ApisVisitor.readFile(gapicBuildFilePath.toString()));
  Assert.assertEquals(
      ApisVisitor.readFile(rawBuildFilePath + ".baseline"),
      ApisVisitor.readFile(rawBuildFilePath));
}