Package org.waveprotocol.wave.model.document.indexed

Source Code of org.waveprotocol.wave.model.document.indexed.IndexedDocumentImplRandomLargeTest

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.waveprotocol.wave.model.document.indexed;


import junit.framework.AssertionFailedError;
import junit.framework.TestCase;

import org.waveprotocol.wave.model.document.bootstrap.BootstrapDocument;
import org.waveprotocol.wave.model.document.operation.Automatons;
import org.waveprotocol.wave.model.document.operation.DocOp;
import org.waveprotocol.wave.model.document.operation.DocInitialization;
import org.waveprotocol.wave.model.document.operation.ModifiableDocument;
import org.waveprotocol.wave.model.document.operation.Nindo;
import org.waveprotocol.wave.model.document.operation.DocOp.IsDocOp;
import org.waveprotocol.wave.model.document.operation.algorithm.DocOpInverter;
import org.waveprotocol.wave.model.document.operation.automaton.AutomatonDocument;
import org.waveprotocol.wave.model.document.operation.automaton.DocOpAutomaton;
import org.waveprotocol.wave.model.document.operation.automaton.DocumentSchema;
import org.waveprotocol.wave.model.document.operation.automaton.DocOpAutomaton.ViolationCollector;
import org.waveprotocol.wave.model.document.operation.impl.DocOpBuffer;
import org.waveprotocol.wave.model.document.operation.impl.DocOpUtil;
import org.waveprotocol.wave.model.document.operation.impl.DocOpValidator;
import org.waveprotocol.wave.model.document.raw.impl.Element;
import org.waveprotocol.wave.model.document.raw.impl.Node;
import org.waveprotocol.wave.model.document.raw.impl.RawDocumentImpl;
import org.waveprotocol.wave.model.document.raw.impl.Text;
import org.waveprotocol.wave.model.document.util.DocProviders;
import org.waveprotocol.wave.model.operation.OperationException;
import org.waveprotocol.wave.model.testing.RandomDocOpGenerator;
import org.waveprotocol.wave.model.testing.RandomNindoGenerator;
import org.waveprotocol.wave.model.testing.RandomProviderImpl;
import org.waveprotocol.wave.model.testing.RandomDocOpGenerator.RandomProvider;
import org.waveprotocol.wave.model.util.CollectionUtils;

/**
* Randomized test cases for IndexedDocumentImpl.
*
* @author ohler@google.com (Christian Ohler)
*/

public class IndexedDocumentImplRandomLargeTest extends TestCase {

  static final int NUM_INITIAL_MUTATIONS = 10;
  static final int NUM_REVERSED_MUTATIONS_PER_RUN = 20;
  static final int NUM_RUNS = 300; // NOTE: increase if you test changes to IndexedDocument
  static final RandomDocOpGenerator.Parameters[] PARAM_SETS = {
    // Default parameters.
    new RandomDocOpGenerator.Parameters(),
  };

  public void consumeMethodsTestOneRun(RandomProvider random,
      RandomDocOpGenerator.Parameters params) throws OperationException {
    IndexedDocument<Node, Element, Text> doc =
      new IndexedDocumentImpl<Node, Element, Text, Void>(RawDocumentImpl.PROVIDER.parse("<a></a>"),
          new AnnotationTree<Object>("a", "b", null), DocumentSchema.NO_SCHEMA_CONSTRAINTS);
    AutomatonDocument autoDoc = Automatons.fromReadable(doc);

    ModifiableDocument checkDoc;
    IsDocOp checkDocOpProvider;
    AutomatonDocument checkAuto;

    // Set to false for faster test runs
    boolean checkAgainstBootstrapDocument = true;
    if (checkAgainstBootstrapDocument) {
      BootstrapDocument bootstrapDoc = new BootstrapDocument();
      checkDocOpProvider = bootstrapDoc;
      checkDoc = bootstrapDoc;
      checkAuto = bootstrapDoc;
    } else {
      IndexedDocument<Node, Element, Text> indexedDoc = DocProviders.POJO.parse("");
      checkDocOpProvider = indexedDoc;
      checkDoc = indexedDoc;
      checkAuto = Automatons.fromReadable(indexedDoc);
    }

    for (int i = 0; i < NUM_INITIAL_MUTATIONS; i++) {
      DocOp op = RandomDocOpGenerator.generate(random, params,
          // FIXME(ohler): Add back schema constraints
          // DocumentOperationValidator.DEFAULT_BLIP_SCHEMA_CONSTRAINTS,
          autoDoc);
      doc.consume(op);
      checkDoc.consume(op);
    }

    String originalXml = DocOpUtil.toXmlString(doc.asOperation());

    for (int i = 0; i < NUM_REVERSED_MUTATIONS_PER_RUN; i++) {

      // Apply random mutation and revert it.
      DocOp op = RandomDocOpGenerator.generate(random, params,
          // FIXME(ohler): Add back schema constraints
          // DocumentOperationValidator.DEFAULT_BLIP_SCHEMA_CONSTRAINTS,
          autoDoc);

      Nindo nindo = null;
      String finalXml = null;
      DocOp docOpCopy = null;
      DocInitialization docAsOp = null;

      try {

        //System.out.println("  " + i);
        //System.out.println("\n===" + iteration + "." + i + "===============================");

        docAsOp = doc.asOperation();
        validate(DocOpAutomaton.EMPTY_DOCUMENT, docAsOp);
        IndexedDocument<Node, Element, Text> copy = DocProviders.POJO.build(docAsOp,
            DocumentSchema.NO_SCHEMA_CONSTRAINTS);
        BootstrapDocument copy2 = new BootstrapDocument();
        copy2.consume(docAsOp);

        // CONSUME
        doc.consume(op);
        checkDoc.consume(op);

        finalXml = DocOpUtil.toXmlString(checkDocOpProvider.asOperation());

        assertEquals(finalXml, DocOpUtil.toXmlString(doc.asOperation()));

        // UNDO
        DocOp inverted1 = DocOpInverter.invert(op);
        validate(autoDoc, inverted1);
        doc.consume(inverted1);
        assertEquals(originalXml, DocOpUtil.toXmlString(doc.asOperation()));

        // CONSUME NINDO
        // TODO(danilatos): Both remove and don't remove the trailing skip, randomly
        nindo = Nindo.fromDocOp(op, true);
        docOpCopy = doc.consumeAndReturnInvertible(nindo);
        assertEquals(finalXml, DocOpUtil.toXmlString(doc.asOperation()));

        validate(Automatons.fromReadable(copy), docOpCopy);
        validate(copy2, docOpCopy);
        copy2.consume(docOpCopy);
        assertEquals(finalXml, DocOpUtil.toXmlString(copy2.asOperation()));

        // UNDO NINDO
        DocOp inverted2 = DocOpInverter.invert(docOpCopy);
        validate(checkAuto, inverted2);
        validate(autoDoc, inverted2);
        doc.consume(inverted2);
        assertEquals(originalXml, DocOpUtil.toXmlString(doc.asOperation()));
        checkDoc.consume(inverted2);

        // GENERATE NINDO
        nindo = RandomNindoGenerator.generate(random, params,
            DocumentSchema.NO_SCHEMA_CONSTRAINTS, doc);
        docAsOp = doc.asOperation();
        docOpCopy = doc.consumeAndReturnInvertible(nindo);
        validate(checkAuto, docOpCopy);
        doc.consume(DocOpInverter.invert(docOpCopy));
//        System.err.println(CollectionUtils.join('\n', "INLINE: ",
//            DocOpUtil.visualiseOpWithDocument(docAsOp, docOpCopy)));

      } catch (Throwable e) {
        if (e instanceof RuntimeException ||
            e instanceof AssertionError ||
            e instanceof AssertionFailedError) {
          System.err.println(originalXml);
          System.err.println(finalXml);
          System.err.println("ORIGINAL THEN COPY: ");
          System.err.println(op);
          System.err.println(docOpCopy);
          System.err.println(nindo);
          System.err.println("NORMALISED: ");
          System.err.println(DocOpUtil.normalize(op));
          if (docOpCopy != null) {
            System.err.println(DocOpUtil.normalize(docOpCopy));
          }

          System.err.println("NORMALISED INVERTED: ");
          System.err.println(DocOpUtil.normalize(DocOpInverter.invert(op)));
          if (docOpCopy != null) {
            System.err.println(DocOpUtil.normalize(DocOpInverter.invert(docOpCopy)));
          }
          if (docOpCopy != null) {
            System.err.println(CollectionUtils.join('\n', "INLINE: ",
                DocOpUtil.visualiseOpWithDocument(docAsOp, docOpCopy)));
          }

        }
        if (e instanceof Error) {
          throw (Error) e;
        } else if (e instanceof OperationException) {
          throw (OperationException) e;
        } else {
          throw (RuntimeException) e;
        }
      }

//      ViolationAccu v = DocumentOperationValidator.validate(doc, reverse,
//          DocumentOperationValidator.DEFAULT_BLIP_SCHEMA_CONSTRAINTS);
//      try {
//        assertTrue(v.isValid());
//      } catch (AssertionFailedError e) {
//        System.err.println("reverse op invalid:");
//        v.printDescriptions(System.err);
//        System.err.print(DocumentOperationCodePrinter.getCode(m, "m"));
//        System.err.print(DocumentOperationCodePrinter.getCode(reverse, "reverse"));
//        throw e;
//      }

//      reverse.apply(doc);

//      String finalXml = OperationXmlifier.xmlify(doc);
//
//      try {
//        assertEquals(originalXml, finalXml);
//      } catch (AssertionFailedError e) {
//        System.err.println("reverse op did not revert properly:");
//        System.err.print(DocumentOperationCodePrinter.getCode(m, "m"));
//        System.err.print(DocumentOperationCodePrinter.getCode(reverse, "reverse"));
//        throw e;
//      }
    }
  }

  private void validate(AutomatonDocument doc, DocOp op) {
    ViolationCollector v = new ViolationCollector();
    if (!DocOpValidator.validate(v, null, doc, op).isValid()) {
      v.printDescriptions(System.err);
      throw new AssertionFailedError("Validation failed: " + v);
    }
  }

  private int iteration;

  public void testConsumeMethods() throws OperationException {
    IndexedDocumentImpl.performValidation = false;
    try {
      RandomProvider r = new RandomProviderImpl(1);
      for (RandomDocOpGenerator.Parameters params : PARAM_SETS) {
        for (iteration = 0; iteration < NUM_RUNS; iteration++) {
          System.out.println(iteration);
          consumeMethodsTestOneRun(r, params);
        }
      }
    } finally {
      IndexedDocumentImpl.performValidation = true;
    }
  }

  /** For performance testing
   * @throws OperationException */
  public static void main(String[] argv) throws OperationException {
    RandomProvider random = new RandomProviderImpl(1);
    RandomDocOpGenerator.Parameters params = PARAM_SETS[0];
    DocumentSchema constraints = DocumentSchema.NO_SCHEMA_CONSTRAINTS;
    IndexedDocument<Node, Element, Text> doc =
      new IndexedDocumentImpl<Node, Element, Text, Void>(RawDocumentImpl.PROVIDER.parse("<a></a>"),
          new AnnotationTree<Object>("a", "b", null), constraints);
    AutomatonDocument autoDoc = Automatons.fromReadable(doc);

    final boolean testAsOperation = true;
    final boolean testNindos = true;
    final int NUM_OPS = 200;

    System.out.print("Pre-generating ops....");

    DocOp[] docOps = new DocOp[NUM_OPS * 2];
    Nindo[] nindos = new Nindo[NUM_OPS * 2];
    IsDocOp[] docs = new IsDocOp[NUM_OPS];

    for (int i = 0; i < NUM_OPS; i++) {
      System.out.print(".");
      if (testAsOperation) {
        Nindo nindo = RandomNindoGenerator.generate(random, params, constraints, doc);
        DocOp docOp = doc.consumeAndReturnInvertible(nindo);
        docs[i] = DocProviders.POJO.build(doc.asOperation(), constraints);
      } else if (testNindos) {
        Nindo nindo = RandomNindoGenerator.generate(random, params, constraints, doc);
        DocOp docOp = doc.consumeAndReturnInvertible(nindo);
        nindos[i] = nindo;
        nindos[NUM_OPS * 2 - i - 1] = Nindo.fromDocOp(DocOpInverter.invert(docOp), true);
      } else {
        DocOp docOp = RandomDocOpGenerator.generate(random, params, //constraints,
            Automatons.fromReadable(doc));
        doc.consume(docOp);
        docOps[i] = docOp;
        docOps[NUM_OPS * 2 - i - 1] =DocOpInverter.invert(docOp);
      }
    }

    System.out.println("\nDone pre-generating ops");

    int iteration = 0;

    IndexedDocument<Node, Element, Text> original = doc;

    doc = new IndexedDocumentImpl<Node, Element, Text, Void>(
        RawDocumentImpl.PROVIDER.parse("<a></a>"),
        new AnnotationTree<Object>("a", "b", null), constraints);

    final int numToAverage = 50;
    int[] times = new int[numToAverage];
    while (true) {
      System.out.print((testAsOperation ? "asOperation"
          : (testNindos ? "Nindo " : "DocOp ")) + ++iteration);
      long start = System.currentTimeMillis();
      if (testAsOperation) {
        for (IsDocOp d : docs) {
          d.asOperation().apply(new DocOpBuffer());
        }
      } else if (testNindos) {
        for (Nindo nindo : nindos) {
          doc.consumeAndReturnInvertible(nindo);
        }
      } else {
        for (DocOp docOp : docOps) {
          doc.consume(docOp);
        }
      }
      int duration = (int) (System.currentTimeMillis() - start);
      times[iteration % numToAverage] = duration;
      int sum = 0;
      for (int time : times) {
        sum += time;
      }
      System.out.println(" - took: " + duration + "ms, "
          + "average last " + numToAverage + ": " + (sum / numToAverage) + "ms");
    }
  }
}
TOP

Related Classes of org.waveprotocol.wave.model.document.indexed.IndexedDocumentImplRandomLargeTest

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.