Package com.google.appengine.tck.datastore

Source Code of com.google.appengine.tck.datastore.TransactionTest$GroupParentKeys

/*
* Copyright 2013 Google Inc. All Rights Reserved.
* 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.appengine.tck.datastore;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.google.appengine.api.NamespaceManager;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.datastore.TransactionOptions;
import org.jboss.arquillian.junit.Arquillian;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertEquals;

/**
* XG. Cross group test.  This feature is only for HRD app.
* To use it in dev_appserver, need following flag to start dev_appserver
* --jvm_flag=-Ddatastore.default_high_rep_job_policy_unapplied_job_pct=20
*
* @author hchen@google.com (Hannah Chen)
* @author ales.justin@jboss.org
*/
@RunWith(Arquillian.class)
public class TransactionTest extends DatastoreTestBase {
    private String kindName = "TrData";
    private String otherKind = "OtData";
    private int sleepTime = 3000;

    private class GroupParentKeys {
        public Key firstParent;
        public Key secondParent;
    }

    // single entity
    @Test
    public void testSingleDefault() throws EntityNotFoundException, InterruptedException {
        clearData(kindName);
        Transaction tx = service.beginTransaction();
        Entity newRec = new Entity(kindName);
        newRec.setProperty("check", "4100331");
        newRec.setProperty("step", "added");
        Key key = service.put(tx, newRec);
        tx.commit();
        Entity qRec = service.get(key);
        assertEquals("4100331", qRec.getProperty("check"));

        tx = service.beginTransaction();
        qRec = service.get(key);
        qRec.setUnindexedProperty("step", "update");
        service.put(tx, newRec);
        tx.rollback();
        qRec = service.get(key);
        assertEquals("added", qRec.getProperty("step"));
    }

    // multiple entities in same group with default transaction setting
    @Test
    public void testMultipleSameGroupDefault() throws InterruptedException {
        clearData(kindName);
        List<Key> keys = new ArrayList<>();
        Transaction tx = service.beginTransaction();
        Entity parent = new Entity(kindName);
        parent.setProperty("check", "parent");
        parent.setProperty("stamp", new Date());
        Key pKey = service.put(tx, parent);
        keys.add(pKey);

        Entity child = new Entity(kindName, pKey);
        child.setProperty("check", "other");
        child.setProperty("stamp", new Date());
        Key cKey = service.put(tx, child);
        keys.add(cKey);
        tx.commit();
        sync(sleepTime);

        Query q = new Query(kindName).setAncestor(pKey);
        int count = service.prepare(q).countEntities(FetchOptions.Builder.withDefaults());
        assertEquals(2, count);

        Map<Key, Entity> es;
        tx = service.beginTransaction();
        es = service.get(tx, keys);
        for (Entity readRec : es.values()) {
            if (readRec.getProperty("check").equals("parent")) {
                pKey = readRec.getKey();
            } else {
                child = readRec;
            }
        }
        assertEquals(pKey, child.getParent());

        service.delete(tx, keys);
        tx.commit();
        sync(sleepTime);
        es = service.get(keys);
        assertEquals(0, es.size());
    }

    // multiple entities in different group with default transaction setting
    @Test(expected = IllegalArgumentException.class)
    public void testMultipleNotSameGroupDefault() throws Exception {
        clearData(kindName);
        writeMultipleGroup(false);
    }

    // use closed transaction
    @Test(expected = IllegalStateException.class)
    public void testClosedTx() throws InterruptedException {
        clearData(kindName);
        Transaction tx = service.beginTransaction();
        Entity newRec = new Entity(kindName);
        newRec.setProperty("check", "4100331");
        newRec.setProperty("stamp", new Date());
        service.put(newRec);
        tx.commit();
        service.put(tx, new Entity(kindName));
    }

    // transactionOptions setting
    @Test
    public void testTransactionOptions() {
        TransactionOptions tos = TransactionOptions.Builder.withXG(true);
        assertEquals(true, tos.isXG());
        tos.clearXG();
        assertEquals(false, tos.isXG());
    }

    // multiple entities in different group with true setting on allowsMultipleEntityGroups
    @Test
    public void testAllowMultipleGroupTrue() throws Exception {
        clearData(kindName);
        clearData(otherKind);
        writeMultipleGroup(true);

        Query q = new Query(kindName);
        Entity e = service.prepare(q).asSingleEntity();
        assertEquals("parent", e.getProperty("check"));
        q = new Query(otherKind);
        e = service.prepare(q).asSingleEntity();
        assertEquals("other", e.getProperty("check"));
    }

    // multiple entities in different group with true setting on allowsMultipleEntityGroups
    @Test
    public void testAllowMultipleGroupTrueWithList() throws Exception {
        clearData(kindName);
        clearData(otherKind);
        GroupParentKeys keys = writeMultipleInList(true);

        List<Entity> es = readMultipleGroup(keys);
        assertEquals("parent", es.get(0).getProperty("check"));
        assertEquals("other", es.get(1).getProperty("check"));
    }

    // rollback transaction with true setting for allowsMultipleEntityGroups
    @Test
    public void testTransactionRollback() throws Exception {
        clearData(kindName);
        clearData(otherKind);
        GroupParentKeys keys = writeMultipleGroup(true);
        List<Entity> es = readMultipleGroup(keys);

        TransactionOptions tos = TransactionOptions.Builder.withXG(true);
        Transaction tx = service.beginTransaction(tos);
        es.get(0).setProperty("check", "parent-update");
        es.get(1).setProperty("check", "other-update");
        service.put(tx, es);
        tx.rollback();
        es = readMultipleGroup(keys);
        assertEquals("parent", es.get(0).getProperty("check"));
        assertEquals("other", es.get(1).getProperty("check"));
    }

    // multiple entities in different group with false setting on allowsMultipleEntityGroups
    @Test(expected = IllegalArgumentException.class)
    public void testAllowMultipleGroupFalse() throws Exception {
        clearData(kindName);
        clearData(otherKind);
        writeMultipleInList(false);
    }

    // false on allowsMultipleEntityGroups + namespaces
    @Test(expected = IllegalArgumentException.class)
    public void testAllowMultipleGroupFalseWithNs() throws Exception {
        NamespaceManager.set("");
        clearData(kindName);
        NamespaceManager.set("trns");
        try {
            clearData(kindName);
            TransactionOptions tos = TransactionOptions.Builder.withXG(false);
            Transaction tx = service.beginTransaction(tos);
            try {
                List<Entity> es = new ArrayList<>();
                NamespaceManager.set("");
                Entity ens1 = new Entity(kindName);
                ens1.setProperty("check", "entity-nons");
                ens1.setProperty("stamp", new Date());
                es.add(ens1);

                NamespaceManager.set("trns");
                Entity ens2 = new Entity(kindName);
                ens2.setProperty("check", "entity-trns");
                ens2.setProperty("stamp", new Date());
                es.add(ens2);
                service.put(tx, es);
                tx.commit();
            } catch (Exception e) {
                tx.rollback();
                throw e;
            }
        } finally {
            NamespaceManager.set("");
        }
    }

    // true on allowsMultipleEntityGroups + namespaces
    @Test
    public void testAllowMultipleGroupTrueWithNs() throws InterruptedException {
        NamespaceManager.set("");
        clearData(kindName);
        NamespaceManager.set("trns");
        clearData(kindName);
        List<Entity> es = new ArrayList<>();
        TransactionOptions tos = TransactionOptions.Builder.withXG(true);
        Transaction tx = service.beginTransaction(tos);

        NamespaceManager.set("");
        Entity ens1 = new Entity(kindName);
        ens1.setProperty("check", "entity-nons");
        ens1.setProperty("stamp", new Date());
        es.add(ens1);

        NamespaceManager.set("trns");
        Entity ens2 = new Entity(kindName);
        ens2.setProperty("check", "entity-trns");
        ens2.setProperty("stamp", new Date());
        es.add(ens2);
        service.put(tx, es);
        tx.commit();

        sync(sleepTime);

        NamespaceManager.set("");
        Query q = new Query(kindName);
        Entity e = service.prepare(q).asSingleEntity();
        assertEquals("entity-nons", e.getProperty("check"));
        NamespaceManager.set("trns");
        q = new Query(kindName);
        e = service.prepare(q).asSingleEntity();
        assertEquals("entity-trns", e.getProperty("check"));
        NamespaceManager.set("");
    }

    private GroupParentKeys writeMultipleGroup(boolean allow) throws Exception {

        GroupParentKeys keys = new GroupParentKeys();

        TransactionOptions tos = TransactionOptions.Builder.withXG(allow);
        Transaction tx = service.beginTransaction(tos);
        try {
            Entity parent = new Entity(kindName);
            parent.setProperty("check", "parent");
            parent.setProperty("stamp", new Date());
            keys.firstParent = service.put(tx, parent);

            Entity other = new Entity(otherKind);
            other.setProperty("check", "other");
            other.setProperty("stamp", new Date());
            keys.secondParent = service.put(tx, other);
            tx.commit();

            sync(sleepTime);
        } catch (Exception e) {
            tx.rollback();
            throw e;
        }
        sync(sleepTime);

        return keys;
    }

    private GroupParentKeys writeMultipleInList(boolean allow) throws Exception {

        GroupParentKeys keys = new GroupParentKeys();

        List<Entity> es = new ArrayList<>();
        TransactionOptions tos = TransactionOptions.Builder.withXG(allow);
        Transaction tx = service.beginTransaction(tos);
        try {
            Entity parent = new Entity(kindName);
            parent.setProperty("check", "parent");
            parent.setProperty("stamp", new Date());
            es.add(parent);
            keys.firstParent = parent.getKey();

            Entity other = new Entity(otherKind);
            other.setProperty("check", "other");
            other.setProperty("stamp", new Date());
            es.add(other);
            keys.secondParent = other.getKey();
            service.put(tx, es);
            tx.commit();

            sync(sleepTime);
        } catch (Exception e) {
            tx.rollback();
            throw e;
        }
        sync(sleepTime);
        return keys;
    }

    private List<Entity> readMultipleGroup(GroupParentKeys keys) {
        List<Entity> es = new ArrayList<>();
        es.clear();
        Query q = new Query(kindName).setAncestor(keys.firstParent);
        es.add(service.prepare(q).asSingleEntity());
        q = new Query(otherKind).setAncestor(keys.secondParent);
        es.add(service.prepare(q).asSingleEntity());
        return es;
    }

    @Override
    public void clearData(String kind) {
        List<Key> elist = new ArrayList<>();
        Query query = new Query(kind);
        for (Entity readRec : service.prepare(query).asIterable()) {
            elist.add(readRec.getKey());
        }
        service.delete(elist);

        sync(sleepTime);
    }
}
TOP

Related Classes of com.google.appengine.tck.datastore.TransactionTest$GroupParentKeys

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.