Package com.google.javascript.jscomp.fuzzing

Source Code of com.google.javascript.jscomp.fuzzing.FuzzerTest

/*
* Copyright 2013 The Closure Compiler Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.javascript.jscomp.fuzzing;

import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.Token;

import junit.framework.TestCase;

import java.util.Map.Entry;
import java.util.Random;

/**
* @author zplin@google.com (Zhongpeng Lin)
*/
public class FuzzerTest extends TestCase{
  private FuzzingContext context;

  @Override
  public void setUp() {
    Random random = new Random(123);
    JsonObject config = TestConfig.getConfig();
    context = new FuzzingContext(random, config, true);
  }

  public void testGenerateArray() {
    ArrayFuzzer fuzzer =
        new ArrayFuzzer(context);
    int budget = 10;
    Node node = fuzzer.generate(budget);
    String code = ArrayFuzzer.getPrettyCode(node);
    assertTrue(code.startsWith("["));
    assertTrue(code.endsWith("]"));
    JsonObject config = fuzzer.getOwnConfig();
    assertTrue(
        "\nGenerated code: \n" + code,
        code.split(",").length
            < (int) (config.get("maxLength").getAsDouble()
                * (budget - 1)));
  }

  public void testGenerateNull() {
    SimpleFuzzer fuzzer = new SimpleFuzzer(Token.NULL, "null", Type.OBJECT);
    Node node = fuzzer.generate(30);
    assertEquals("null", SimpleFuzzer.getPrettyCode(node));
  }

  public void testGenerateBoolean() {
    BooleanFuzzer fuzzer = new BooleanFuzzer(context);
    Node node = fuzzer.generate(10);
    String code = BooleanFuzzer.getPrettyCode(node).trim();
    assertTrue(
        "\nGenerated code: \n" + code,
        code.equals("true") || code.equals("false"));
  }
  public void testGenerateNumeric() {
    NumericFuzzer fuzzer = new NumericFuzzer(context);
    Node node = fuzzer.generate(10);
    String code = NumericFuzzer.getPrettyCode(node);
    for (int i = 0; i < code.length(); i++) {
      assertTrue("\nGenerated code: \n" + code, code.charAt(i) >= '0');
      assertTrue("\nGenerated code: \n" + code, code.charAt(i) <= '9');
    }
  }

  public void testGenerateString() {
    StringFuzzer fuzzer = new StringFuzzer(context);
    Node node = fuzzer.generate(10);
    String code = StringFuzzer.getPrettyCode(node);
    assertTrue("\nGenerated code: \n" + code, code.startsWith("\""));
    assertTrue("\nGenerated code: \n" + code, code.endsWith("\""));
  }

  public void testGenerateRegex() {
    RegularExprFuzzer fuzzer = new RegularExprFuzzer(context);
    Node node = fuzzer.generate(10);
    String code = RegularExprFuzzer.getPrettyCode(node);
    assertTrue("\nGenerated code: \n" + code, code.startsWith("/"));
    assertNotSame('/', code.charAt(1));
  }

  public void testGenerateObjectLiteral() {
    ObjectFuzzer fuzzer = new ObjectFuzzer(context);
    Node node = fuzzer.generate(10);
    String code = ObjectFuzzer.getPrettyCode(node);
    assertTrue("\nGenerated code: \n" + code, code.startsWith("{"));
    assertTrue("\nGenerated code: \n" + code, code.endsWith("}"));
  }

  public void testGenerateLiteral() throws JsonParseException {
    int budget = 0;
    LiteralFuzzer literalFuzzer = new LiteralFuzzer(context);
    LiteralFuzzer spyFuzzer = spy(literalFuzzer);
    doThrow(new RuntimeException("Not enough budget for literal")).
    when(spyFuzzer).generate(budget);
    budget = 1;
    leaveOneSubtype(literalFuzzer.getOwnConfig(), "null");
    Node node = literalFuzzer.generate(budget);
    String code = AbstractFuzzer.getPrettyCode(node);
    assertEquals("null", code.trim());
}

  public void testPostfixExpressions() throws JsonParseException {
    String[] postfixes = {"++", "--"};
    String[] types = {"postInc", "postDec"};
    for (int i = 0; i < postfixes.length; i++) {
      setUp();
      UnaryExprFuzzer fuzzer = new UnaryExprFuzzer(context);
      leaveOneSubtype(fuzzer.getOwnConfig(), types[i]);
      Node node = fuzzer.generate(10);
      String code = UnaryExprFuzzer.getPrettyCode(node);
      assertTrue(code.endsWith(postfixes[i]));
    }
  }

  public void testPrefixExpressions() throws JsonParseException {
    String[] prefixes =
      {"void", "typeof", "+", "-", "~", "!", "++", "--", "delete"};
    String[] types = {"void", "typeof", "pos", "neg", "bitNot", "not", "inc",
        "dec", "delProp"};
    for (int i = 0; i < prefixes.length; i++) {
      setUp();
      UnaryExprFuzzer fuzzer = new UnaryExprFuzzer(context);
      leaveOneSubtype(fuzzer.getOwnConfig(), types[i]);
      Node node = fuzzer.generate(10);
      String code = UnaryExprFuzzer.getPrettyCode(node);
      assertTrue(code.startsWith(prefixes[i]));
    }
  }

  public void testNewExpression() throws JsonParseException {
    FunctionCallFuzzer fuzzer =
        new FunctionCallFuzzer(context);
    leaveOneSubtype(fuzzer.getOwnConfig(), "constructorCall");
    Node node = fuzzer.generate(10);
    String code = FunctionCallFuzzer.getPrettyCode(node);
    assertTrue(code.startsWith("new "));
  }

  public void testCallExpression() throws JsonParseException {
    FunctionCallFuzzer fuzzer =
        new FunctionCallFuzzer(context);
    leaveOneSubtype(fuzzer.getOwnConfig(), "normalCall");
    Node node = fuzzer.generate(10);
    String code = FunctionCallFuzzer.getPrettyCode(node);
    assertFalse(code.startsWith("new "));
  }

  public void testGenerateBinaryExpression() throws JsonParseException {
    int budget = 50;
    String[] operators = {"*", "/", "%", "+", "-", "<<", ">>", ">>>", "<", ">",
        "<=", ">=", "instanceof", "in", "==", "!=", "===", "!==", "&", "^",
        "|", "&&", "||", "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=",
        ">>>=", "&=", "^=", "|="};
    String[] types = {"mul", "div", "mod", "add", "sub", "lsh", "rsh", "ursh",
        "lt", "gt", "le", "ge", "instanceof", "in", "eq", "ne", "sheq", "shne",
        "bitAnd", "bitXor", "bitOr", "and", "or", "assign", "assignMul",
        "assignDiv", "assignMod", "assignAdd", "assignSub", "assignLsh",
        "assignRsh", "assignUrsh", "assignBitAnd", "assignBitXor",
        "assignBitOr"};
    for (int i = 0; i < operators.length; i++) {
      context =
          new FuzzingContext(new Random(123), TestConfig.getConfig(), true);
      BinaryExprFuzzer fuzzer =
          new BinaryExprFuzzer(context);
      leaveOneSubtype(fuzzer.getOwnConfig(), types[i]);
      Node node = fuzzer.generate(budget);
      String code = BinaryExprFuzzer.getPrettyCode(node).trim();
      assertNotSame(-1, code.indexOf(" " + operators[i] + " "));
    }
  }

  public void testTrinaryExpression() {
    TernaryExprFuzzer fuzzer =
        new TernaryExprFuzzer(context);
    Node node = fuzzer.generate(4);
    String code = TernaryExprFuzzer.getPrettyCode(node);
    assertNotSame(-1, code.indexOf(" ? "));
    assertTrue(code.indexOf(" : ") > code.indexOf(" ? "));
  }

  public void testVariableStatement() {
    VarFuzzer fuzzer = new VarFuzzer(context);
    Node node = fuzzer.generate(10);
    String code = VarFuzzer.getPrettyCode(node);
    assertTrue(code.startsWith("var "));
  }

  public void testEmptyStatement() {
    SimpleFuzzer fuzzer = new SimpleFuzzer(Token.EMPTY, "empty", Type.UNDEFINED);
    Node emptyStmt = fuzzer.generate(10);
    assertEquals(Token.EMPTY, emptyStmt.getType());
  }

  public void testIfStatement() {
    IfFuzzer fuzzer = new IfFuzzer(context);
    Node ifStatement = fuzzer.generate(10);
    String code = IfFuzzer.getPrettyCode(ifStatement);
    assertTrue(code.startsWith("if ("));
  }

  public void testWhileStatement() {
    WhileFuzzer fuzzer =
        new WhileFuzzer(context);
    Node whileStatement = fuzzer.generate(10);
    String code = WhileFuzzer.getPrettyCode(whileStatement);
    assertTrue(code.startsWith("while ("));
  }

  public void testDoWhileStatement() {
    DoWhileFuzzer fuzzer =
        new DoWhileFuzzer(context);
    Node doStatement = fuzzer.generate(10);
    String code = DoWhileFuzzer.getPrettyCode(doStatement);
    assertTrue(code.startsWith("do {"));
    assertTrue(code.trim().endsWith(");"));

  }

  public void testForStatement() {
    ForFuzzer fuzzer = new ForFuzzer(context);
    Node forStatement = fuzzer.generate(10);
    String code = ForFuzzer.getPrettyCode(forStatement);
    assertTrue(code.startsWith("for ("));
  }

  public void testForInStatement() {
    ForInFuzzer fuzzer =
        new ForInFuzzer(context);
    Node forInStatement = fuzzer.generate(10);
    String code = ForInFuzzer.getPrettyCode(forInStatement);
    assertTrue("\nGenerated code: \n" + code, code.startsWith("for ("));
    assertTrue("\nGenerated code: \n" + code, code.contains(" in "));
  }

  public void testSwitchStatement() {
    SwitchFuzzer fuzzer =
        new SwitchFuzzer(context);
    Node switchStmt = fuzzer.generate(20);
    String code = SwitchFuzzer.getPrettyCode(switchStmt);
    assertTrue("\nGenerated code: \n" + code, code.startsWith("switch("));
  }

  public void testThrowStatement() {
    ThrowFuzzer fuzzer =
        new ThrowFuzzer(context);
    Node throwStatement = fuzzer.generate(10);
    String code = ThrowFuzzer.getPrettyCode(throwStatement);
    assertTrue("\nGenerated code: \n" + code, code.startsWith("throw"));
  }

  public void testTryStatement() {
    TryFuzzer fuzzer = new TryFuzzer(context);
    Node tryStatement = fuzzer.generate(20);
    String code = TryFuzzer.getPrettyCode(tryStatement);
    assertTrue("\nGenerated code: \n" + code, code.startsWith("try {"));
  }

  public void testFunctionDeclaration() {
    FunctionFuzzer fuzzer =
        new FunctionFuzzer(context, false);
    Node functionDecl = fuzzer.generate(20);
    String code = FunctionFuzzer.getPrettyCode(functionDecl);
    assertTrue("\nGenerated code: \n" + code, code.startsWith("function "));
  }

  public void testBreakStatement() throws JsonParseException {
    BreakFuzzer fuzzer = new BreakFuzzer(context);
    fuzzer.getOwnConfig().addProperty("toLabel", 1);
    Scope scope = context.scopeManager.localScope();
    scope.otherLabels.add("testLabel");
    Node breakStmt = fuzzer.generate(10);
    String code = BreakFuzzer.getPrettyCode(breakStmt);
    assertEquals("break testLabel;", code.trim());
  }

  public void testContinueStatement() throws JsonParseException {
    ContinueFuzzer fuzzer = new ContinueFuzzer(context);
    fuzzer.getOwnConfig().addProperty("toLabel", 1);
    Scope scope = context.scopeManager.localScope();
    scope.loopLabels.add("testLabel");
    Node continueStmt = fuzzer.generate(10);
    String code = ContinueFuzzer.getPrettyCode(continueStmt);
    assertEquals("continue testLabel;", code.trim());
  }

  public void testDeterministicProgramGenerating() {
    ScriptFuzzer fuzzer = new ScriptFuzzer(context);
    Node nodes = fuzzer.generate(100);
    String code1 = ScriptFuzzer.getPrettyCode(nodes);

    setUp();
    context =
        new FuzzingContext(new Random(123), TestConfig.getConfig(), true);
    fuzzer = new ScriptFuzzer(context);
    nodes = fuzzer.generate(100);
    String code2 = ScriptFuzzer.getPrettyCode(nodes);

    assertEquals(code1, code2);
  }
  private static void leaveOneSubtype(JsonObject typeConfig, String subtypeName)
      throws JsonParseException {
    JsonObject weightConfig = typeConfig.get("weights").getAsJsonObject();

    for (Entry<String, JsonElement> entry : weightConfig.entrySet()) {
      String name = entry.getKey();
      if (name.equals(subtypeName)) {
        weightConfig.addProperty(name, 1);
      } else {
        weightConfig.addProperty(name, 0);
      }
    }
  }
}
TOP

Related Classes of com.google.javascript.jscomp.fuzzing.FuzzerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.