# 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, 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",
        ]
      }

      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, 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_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) {
    }
  }
}
