예제 #1
0
  public void testTransformDiamondProperty(int numIterations) {
    log.info("TESTING testTransformDiamondProperty");
    Random r = new Random(0);

    for (int iteration = 0; iteration < numIterations; iteration++) {
      log.info("Iteration: " + iteration);

      D d1 = domain.initialState();

      try {
        for (int i = 0; i < INITIAL_MUTATION_COUNT; i++) {
          O op = generator.randomOperation(d1, r);
          domain.apply(op, d1);
        }

        D d2 = copy(d1);

        for (int i = 0; i < FEATURE_ITERATION_COUNT; i++) {
          D original = copy(d1);

          O op1 = generator.randomOperation(original, r);
          O op2 = generator.randomOperation(original, r);

          domain.apply(op1, d1);
          domain.apply(op2, d2);

          D client = copy(d1);
          D server = copy(d2);

          OperationPair<O> pair = domain.transform(op1, op2);

          domain.apply(pair.serverOp(), d1);
          domain.apply(pair.clientOp(), d2);

          if (!domain.equivalent(d1, d2)) {
            log.inconsistent(
                "TRANSFORM BUG",
                "Subiteration: " + i,
                "Client: " + op1,
                "Server: " + op2,
                "Client': " + pair.clientOp(),
                "Server': " + pair.serverOp(),
                "Initial state: " + original,
                "Client state 1:" + client,
                "Client state 2:" + d1,
                "Server state 1:" + server,
                "Server state 2:" + d2);
          }
        }

      } catch (OperationException e) {
        logException("TRANSFORM BUG? Operation exception", e);
      } catch (TransformException e) {
        logException("TRANSFORM BUG? Transform exception", e);
      } catch (RuntimeException e) {
        logException("TRANSFORM BUG? Runtime exception", e);
      }
    }
  }
예제 #2
0
  /**
   * Transforms the specified client operations against the specified server operations, returning
   * the transformed client operations in a new list.
   *
   * @param clientOps may be unmodifiable
   * @param clientAuthor
   * @param serverOps may be unmodifiable
   * @param serverAuthor
   * @return The transformed client ops
   */
  private List<WaveletOperation> transformOps(
      List<WaveletOperation> clientOps,
      ParticipantId clientAuthor,
      List<WaveletOperation> serverOps,
      ParticipantId serverAuthor)
      throws OperationException {
    List<WaveletOperation> transformedClientOps = new ArrayList<WaveletOperation>();

    for (WaveletOperation c : clientOps) {
      for (WaveletOperation s : serverOps) {
        OperationPair<WaveletOperation> pair;
        try {
          pair = Transform.transform(c, clientAuthor, s, serverAuthor);
        } catch (TransformException e) {
          throw new OperationException(e);
        }
        c = pair.clientOp();
      }
      transformedClientOps.add(c);
    }
    return transformedClientOps;
  }
예제 #3
0
  /**
   * Tests that transformation and composition are compatible
   *
   * <p>Assumes the diamond property of transformation
   *
   * <p>NOTE: This should be rewritten to do proper comparison of operations.
   *
   * @param numIterations
   */
  public void testTransformationCompositionCompatible(int numIterations) {
    log.info("TESTING testTransformationCompositionCompatible");
    Random r = new Random(0);

    for (int iteration = 0; iteration < numIterations; iteration++) {
      log.info("Iteration: " + iteration);

      D server = domain.initialState();

      try {
        for (int i = 0; i < INITIAL_MUTATION_COUNT; i++) {
          O op = generator.randomOperation(server, r);
          domain.apply(op, server);
        }

        D client = copy(server);

        for (int i = 0; i < FEATURE_ITERATION_COUNT; i++) {
          D original = copy(server);
          if (!domain.equivalent(client, server)) {
            log.inconsistent(
                "Sanity check failed: client and server not the same at start of test");
          }

          // Client is on the left for the first pass, but this
          // is reversed in the second pass (the meaning of the
          // variables "client" and "server" also reverses).
          //
          //        original (o)
          //          / \
          // client  a   b  server
          //        / \ /
          //       c   d
          //        \ /
          //        end (e)
          //

          O oa = generator.randomOperation(client, r);
          O ob = generator.randomOperation(server, r);

          domain.apply(oa, client);
          domain.apply(ob, server);

          D a = copy(client);
          D b = copy(server);

          OperationPair<O> pair1 = domain.transform(oa, ob);
          O bd = pair1.clientOp();
          O ad = pair1.serverOp();

          O ac = generator.randomOperation(a, r);
          domain.apply(ac, client);
          D c = copy(client);

          domain.apply(bd, server);
          D d = copy(server);

          D test = copy(a);
          domain.apply(ad, test);

          OperationPair<O> pair2 = domain.transform(ac, ad);
          O ce = pair2.serverOp();
          O de = pair2.clientOp();

          domain.apply(de, server);
          domain.apply(ce, client);
          D end = copy(client);

          O oc = domain.compose(ac, oa);
          O be = domain.compose(de, bd);

          // The property we want to test is that ce = ce2 and be = be2
          //
          OperationPair<O> pair3 = domain.transform(oc, ob);
          O ce2 = pair3.serverOp();
          O be2 = pair3.clientOp();

          D d1 = copy(c);
          domain.apply(ce2, d1);

          D d2 = copy(b);
          domain.apply(be2, d2);

          boolean ceOK = domain.equivalent(end, d1);
          boolean beOK = domain.equivalent(end, d2);
          if (!ceOK || !beOK) {
            log.inconsistent(
                "TRANSFORM AND COMPOSITION NOT COMPATIBLE",
                "Subiteration: " + i,
                ceOK ? "GOOD:" : "BAD:",
                "ce: " + ce,
                "ce2: " + ce2,
                beOK ? "GOOD:" : "BAD:",
                "be: " + be,
                "be2: " + be2,
                "-- States without compose: ",
                "        original (o)",
                "          / \\",
                " client  a   b  server",
                "        / \\ /",
                "       c   d",
                "        \\ /",
                "        end (e)",
                "o: " + original,
                "a: " + a,
                "b: " + b,
                "c: " + c,
                "d: " + d,
                "e: " + end);
          }
        }

      } catch (OperationException e) {
        logException("TRANSFORM BUG? Operation exception", e);
      } catch (TransformException e) {
        logException("TRANSFORM BUG? Transform exception", e);
      } catch (RuntimeException e) {
        logException("TRANSFORM BUG? Runtime exception", e);
      }
    }
  }