# 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/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.
#
# 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") {
  if (!disable_libfuzzer &&
      (use_libfuzzer || use_afl || 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"

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

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

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

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

        outputs = [
          out,
        ]

        deps = [
          "//testing/libfuzzer:seed_corpus",
        ]
      }

      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_name = target_name + ".options"
      action(config_name) {
        script = "//testing/libfuzzer/gen_fuzzer_config.py"
        args = [
          "--config",
          rebase_path("$root_build_dir/" + config_name),
        ]

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

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

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

    test(target_name) {
      forward_variables_from(invoker,
                             [
                               "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
      }
    }
  } else {
    # noop on unsupported platforms.
    # mark attributes as used.
    assert(invoker.sources == [] || invoker.sources != [])
    if (defined(invoker.additional_configs)) {
      assert(
          invoker.additional_configs == [] || invoker.additional_configs != [])
    }
    if (defined(invoker.deps)) {
      assert(invoker.deps == [] || invoker.deps != [])
    }
    if (defined(invoker.dict)) {
      assert(invoker.dict == [] || invoker.dict != [])
    }
    if (defined(invoker.libfuzzer_options)) {
      assert(invoker.libfuzzer_options == [] || invoker.libfuzzer_options != [])
    }
    if (defined(invoker.seed_corpus)) {
      assert(invoker.seed_corpus == [] || invoker.seed_corpus != [])
    }
    if (defined(invoker.seed_corpuses)) {
      assert(invoker.seed_corpuses == [] || invoker.seed_corpuses != [])
    }
    assert(!defined(invoker.check_includes) || invoker.check_includes != [])
    assert(!defined(invoker.include_dirs) || invoker.include_dirs != [])
    assert(!defined(invoker.defines) || invoker.defines != [])

    group(target_name) {
    }
  }
}
