# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Defines fuzzer_test.
#
import("//build/config/coverage/coverage.gni")
import("//build/config/features.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//testing/test.gni")

# fuzzer_test is used to define individual libfuzzer tests.
#
# Supported attributes:
# - (required) sources - fuzzer test source files
# - deps - test dependencies
# - additional_configs - additional configs to be used for compilation
# - dict - a dictionary file for the fuzzer.
# - libfuzzer_options - options for the fuzzer (e.g. -max_len or -timeout).
# - seed_corpus - a directory with seed corpus.
# - seed_corpus_deps - dependencies for generating the seed corpus.
# - skip_owners - if true, skips writing the owners file.
#
# If use_libfuzzer gn flag is defined, then proper fuzzer would be build.
# Without use_libfuzzer or use_afl a unit-test style binary would be built on
# linux and the whole target is a no-op otherwise.
#
# The template wraps test() target with appropriate dependencies.
# If any test run-time options are present (dict or libfuzzer_options), then a
# config (.options file) file would be generated or modified in root output
# dir (next to test).
template("fuzzer_test") {
  assert(!(is_mac && use_clang_coverage && use_fuzzing_engine),
         "Code Coverage for fuzz targets does not work on Mac until " +
             "crbug.com/790747 is resolved.")

  if (!disable_libfuzzer && (use_fuzzing_engine || use_drfuzz || is_linux)) {
    assert(defined(invoker.sources), "Need sources in $target_name.")

    test_deps = [ "//testing/libfuzzer:libfuzzer_main" ]

    if (defined(invoker.deps)) {
      test_deps += invoker.deps
    }

    if (defined(invoker.seed_corpus) || defined(invoker.seed_corpuses)) {
      assert(!(defined(invoker.seed_corpus) && defined(invoker.seed_corpuses)),
             "Do not use both seed_corpus and seed_corpuses for $target_name.")

      out = "$root_build_dir/$target_name" + "_seed_corpus.zip"

      seed_corpus_deps = []

      if (defined(invoker.seed_corpus_deps)) {
        seed_corpus_deps += invoker.seed_corpus_deps
      }

      action(target_name + "_seed_corpus") {
        script = "//testing/libfuzzer/archive_corpus.py"

        args = [
          "--output",
          rebase_path(out, root_build_dir),
        ]

        if (defined(invoker.seed_corpus)) {
          args += [ rebase_path(invoker.seed_corpus, root_build_dir) ]
        }

        if (defined(invoker.seed_corpuses)) {
          foreach(seed_corpus_path, invoker.seed_corpuses) {
            args += [ rebase_path(seed_corpus_path, root_build_dir) ]
          }
        }

        outputs = [
          out,
        ]

        deps = [ "//testing/libfuzzer:seed_corpus" ] + seed_corpus_deps
      }

      test_deps += [ ":" + target_name + "_seed_corpus" ]
    }

    if (defined(invoker.dict) || defined(invoker.libfuzzer_options)) {
      if (defined(invoker.dict)) {
        # Copy dictionary to output.
        copy(target_name + "_dict_copy") {
          sources = [
            invoker.dict,
          ]
          outputs = [
            "$root_build_dir/" + target_name + ".dict",
          ]
        }
        test_deps += [ ":" + target_name + "_dict_copy" ]
      }

      # Generate .options file.
      config_file_name = target_name + ".options"
      action(config_file_name) {
        script = "//testing/libfuzzer/gen_fuzzer_config.py"
        args = [
          "--config",
          rebase_path("$root_build_dir/" + config_file_name, root_build_dir),
        ]

        if (defined(invoker.dict)) {
          args += [
            "--dict",
            rebase_path("$root_build_dir/" + invoker.target_name + ".dict",
                        root_build_dir),
          ]
        }

        if (defined(invoker.libfuzzer_options)) {
          args += [ "--libfuzzer_options" ]
          args += invoker.libfuzzer_options
        }

        outputs = [
          "$root_build_dir/$config_file_name",
        ]
      }
      test_deps += [ ":" + config_file_name ]
    }

    # Generate .owners file (if skip_owners is not true).
    owners_file_name = target_name + ".owners"
    action(owners_file_name) {
      script = "//testing/libfuzzer/gen_fuzzer_owners.py"
      args = [
        "--owners",
        rebase_path("$root_build_dir/" + owners_file_name, root_build_dir),
      ]

      if (defined(invoker.sources) && invoker.sources != []) {
        args += [ "--sources" ] + rebase_path(invoker.sources, "//")
      } else if (defined(invoker.deps) && invoker.deps != []) {
        _full_deps = []
        foreach(_dep, invoker.deps) {
          _full_deps += [ get_label_info(_dep, "dir") + ":" +
                          get_label_info(_dep, "name") ]
        }
        args += [
                  "--build-dir",
                  rebase_path("$root_build_dir/", root_build_dir),
                  "--deps",
                ] + _full_deps
      }

      outputs = [
        "$root_build_dir/$owners_file_name",
      ]
    }
    test_deps += [ ":" + owners_file_name ]

    test(target_name) {
      forward_variables_from(invoker,
                             [
                               "cflags",
                               "cflags_cc",
                               "check_includes",
                               "defines",
                               "include_dirs",
                               "sources",
                             ])
      deps = test_deps

      if (defined(invoker.additional_configs)) {
        configs += invoker.additional_configs
      }
      configs += [ "//testing/libfuzzer:fuzzer_test_config" ]

      # Used by WebRTC to suppress some Clang warnings in their codebase.
      if (defined(invoker.suppressed_configs)) {
        configs -= invoker.suppressed_configs
      }

      if (is_mac) {
        sources += [ "//testing/libfuzzer/libfuzzer_exports.h" ]
      }
    }
  } else {
    # noop on unsupported platforms.
    # mark attributes as used.
    not_needed(invoker, "*")

    group(target_name) {
    }
  }
}
