1959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle/*
2959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Copyright (C) 2014 The Android Open Source Project
3959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle *
4959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Licensed under the Apache License, Version 2.0 (the "License");
5959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * you may not use this file except in compliance with the License.
6959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * You may obtain a copy of the License at
7959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle *
8959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle *      http://www.apache.org/licenses/LICENSE-2.0
9959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle *
10959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Unless required by applicable law or agreed to in writing, software
11959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * distributed under the License is distributed on an "AS IS" BASIS,
12959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * See the License for the specific language governing permissions and
14959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * limitations under the License.
15959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */
16959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
17959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepackage dexfuzz.program.mutators;
18959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
19959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.Log;
20959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.MutationStats;
21959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.Options;
22959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.program.MutatableCode;
23959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.program.Mutation;
24959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
25959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport java.util.List;
26959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport java.util.Random;
27959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
28959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle/**
29959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * The base class for all classes that can mutate methods.
30959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */
31959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepublic abstract class CodeMutator {
32959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  /**
33959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * The RNG, passed in by the Program that initialised us.
34959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   */
35959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  protected Random rng;
36959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
37959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  /**
38959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * Used to track which mutations happen.
39959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   */
40959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  protected MutationStats stats;
41959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
42959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  /**
43959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * Used to track mutations that have been applied so far.
44959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   */
45959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  protected List<Mutation> mutations;
46959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
47959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  /**
48959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * The chance, out of 100, that this mutator actually mutates the the program
49959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * when asked to by the Program. The default is 50% chance, but each mutator that
50959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * extends CodeMutator should its own default.
51959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   */
52959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  protected int likelihood = 50;
53959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
54959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  /**
55959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * This constructor is only intended for use in MutationRecorder...
56959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   */
57959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public CodeMutator() {
58959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
59959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
60959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
61959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  /**
62959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * Constructor that all subclasses must call...
63959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   *
64959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * @param rng The RNG that the Program created.
65959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   */
66959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public CodeMutator(Random rng, MutationStats stats, List<Mutation> mutations) {
67959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    this.rng = rng;
68959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    this.stats = stats;
69959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    this.mutations = mutations;
70959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
71959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    String name = this.getClass().getSimpleName().toLowerCase();
72959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
73959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    if (Options.mutationLikelihoods.containsKey(name)) {
74959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle      likelihood = Options.mutationLikelihoods.get(name);
75959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle      Log.info("Set mutation likelihood to " + likelihood
76959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle          + "% for " + this.getClass().getSimpleName());
77959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    }
78959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
79959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
80959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  /**
81959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * When the Program picks a particular mutator to mutate the code, it calls
82959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * this function, that determines if the mutator will actually mutate the code.
83959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * If so, it then calls the mutationFunction() method, that every subclass CodeMutator
84959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * is expected to implement to perform its mutation.
85959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   *
86959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * @return If mutation took place.
87959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   */
88959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public boolean attemptToMutate(MutatableCode mutatableCode) {
89959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    if (shouldMutate(mutatableCode)) {
90959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle      generateAndApplyMutation(mutatableCode);
91959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle      return true;
92959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    }
93959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    Log.info("Skipping mutation.");
94959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    return false;
95959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
96959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
97959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public void forceMutate(Mutation mutation) {
98959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    Log.info("Forcing mutation.");
99959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    applyMutation(mutation);
100959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
101959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
102959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public boolean canBeTriggered() {
103959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    return (likelihood > 0);
104959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
105959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
106959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  /**
107959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * Randomly determine if the mutator will actually mutate a method, based on its
108959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * provided likelihood of mutation.
109959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   *
110959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * @return If the method should be mutated.
111959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   */
112959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  private boolean shouldMutate(MutatableCode mutatableCode) {
113959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    return ((rng.nextInt(100) < likelihood) && canMutate(mutatableCode));
114959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
115959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
116959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  private void generateAndApplyMutation(MutatableCode mutatableCode) {
117959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    Mutation mutation = generateMutation(mutatableCode);
118959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    // Always save the mutation.
119959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    mutations.add(mutation);
120959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    applyMutation(mutation);
121959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
122959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
123959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  /**
124959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * A CodeMutator must override this method if there is any reason why could not mutate
125959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * a particular method, and return false in that case.
126959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   */
127959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  protected boolean canMutate(MutatableCode mutatableCode) {
128959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    return true;
129959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
130959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
131959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  protected abstract Mutation generateMutation(MutatableCode mutatableCode);
132959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
133959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  protected abstract void applyMutation(Mutation uncastMutation);
134959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
135959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public abstract Mutation getNewMutation();
136959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle}
137