Home | History | Annotate | Download | only in include
      1 /*
      2  * Copyright 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef __VTS_PROTO_FUZZER_MUTATOR_H_
     18 #define __VTS_PROTO_FUZZER_MUTATOR_H_
     19 
     20 #include <functional>
     21 #include <memory>
     22 #include <string>
     23 #include <unordered_map>
     24 
     25 #include "ProtoFuzzerUtils.h"
     26 #include "test/vts-testcase/fuzz/iface_fuzzer/proto/ExecutionSpecificationMessage.pb.h"
     27 #include "test/vts/proto/ComponentSpecificationMessage.pb.h"
     28 
     29 namespace android {
     30 namespace vts {
     31 namespace fuzzer {
     32 
     33 using BiasedRandomScalarGen = std::function<uint64_t(Random &rand)>;
     34 using Odds = std::pair<uint64_t, uint64_t>;
     35 using VarMutateFn = std::function<VarInstance(const VarInstance &)>;
     36 using VarRandomGenFn = std::function<VarInstance(const VarSpec &)>;
     37 using VarTransformFn = std::function<VariableSpecificationMessage(
     38     const VariableSpecificationMessage &)>;
     39 
     40 // Encapsulates heuristic strategy for biased mutation/random generation.
     41 struct ProtoFuzzerMutatorConfig {
     42   // Generates biased random scalars.
     43   BiasedRandomScalarGen scalar_bias_ = [](Random &rand) { return rand.Rand(); };
     44   // Used to decide if enum will be mutated/generated like a scalar.
     45   Odds enum_bias_ = {0, 1};
     46   // Odds that a function in an execution is mutated rather than regenerated.
     47   Odds func_mutated_ = {100, 1};
     48   // Default size used to randomly generate a vector.
     49   size_t default_vector_size_ = 64;
     50 };
     51 
     52 // Provides methods for mutation or random generation.
     53 class ProtoFuzzerMutator {
     54  public:
     55   ProtoFuzzerMutator(Random &, std::unordered_map<std::string, TypeSpec>,
     56                      ProtoFuzzerMutatorConfig);
     57   // Generates a random ExecSpec.
     58   ExecSpec RandomGen(const IfaceSpec &, size_t);
     59   // Mutates in-place an ExecSpec.
     60   void Mutate(const IfaceSpec &, ExecSpec *);
     61   // Generates a random FuncSpec.
     62   FuncSpec RandomGen(const FuncSpec &);
     63   // Mutates a FuncSpec.
     64   FuncSpec Mutate(const FuncSpec &);
     65   // Generates a random VarInstance.
     66   VarInstance RandomGen(const VarSpec &);
     67   // Mutates a VarInstance.
     68   VarInstance Mutate(const VarInstance &);
     69 
     70  private:
     71   // Used for mutation/random generation of VarInstance.
     72   VarInstance ArrayRandomGen(const VarSpec &);
     73   VarInstance ArrayMutate(const VarInstance &);
     74   VarInstance EnumRandomGen(const VarSpec &);
     75   VarInstance EnumMutate(const VarInstance &);
     76   VarInstance ScalarRandomGen(const VarSpec &);
     77   VarInstance ScalarMutate(const VarInstance &);
     78   VarInstance StructRandomGen(const VarSpec &);
     79   VarInstance StructMutate(const VarInstance &);
     80   VarInstance UnionRandomGen(const VarSpec &);
     81   VarInstance UnionMutate(const VarInstance &);
     82   VarInstance VectorRandomGen(const VarSpec &);
     83   VarInstance VectorMutate(const VarInstance &);
     84 
     85   // Used for mutation/random generation of ScalarData.
     86   ScalarData RandomGen(const ScalarData &, const std::string &);
     87   ScalarData Mutate(const ScalarData &, const string &);
     88   // Used for mutation/random generation of variables of fundamental data types
     89   // e.g. char, int, double.
     90   template <typename T>
     91   T RandomGen(T);
     92   template <typename T>
     93   T Mutate(T);
     94   bool RandomGen(bool);
     95   bool Mutate(bool);
     96   float Mutate(float);
     97   double Mutate(double);
     98 
     99   // Looks up predefined type by name.
    100   const TypeSpec &FindPredefinedType(std::string);
    101 
    102   // 64-bit random number generator.
    103   Random &rand_;
    104   // Used to look up definition of a predefined type by its name.
    105   std::unordered_map<std::string, TypeSpec> predefined_types_;
    106   // Used to delegate mutation/random generation of VariableSpecifationMessage
    107   // of different VariableType to mutation/random delegation function for that
    108   // VariableType.
    109   std::unordered_map<VariableType, VarMutateFn> mutate_fns_;
    110   std::unordered_map<VariableType, VarRandomGenFn> random_gen_fns_;
    111   // Used for biased mutation/random generation of variables.
    112   ProtoFuzzerMutatorConfig mutator_config_;
    113 };
    114 
    115 }  // namespace fuzzer
    116 }  // namespace vts
    117 }  // namespace android
    118 
    119 #endif  // __VTS_PROTO_FUZZER_MUTATOR__
    120