@BeforeMethod
  public void setUp() {
    super.setUp();

    EntityMemcache mc = new EntityMemcache(null);
    cads = new CachingAsyncDatastoreService(DatastoreServiceFactory.getAsyncDatastoreService(), mc);
    nods = new CachingAsyncDatastoreService(new MockAsyncDatastoreService(), mc);

    key = KeyFactory.createKey("thing", 1);
    keyInSet = Collections.singleton(key);
    entity = new Entity(key);
    entity.setProperty("foo", "bar");
    entityInList = Collections.singletonList(entity);
  }
/** @author higa */
public class DatastoreUtilTest extends AppEngineTestCase {

  private AsyncDatastoreService ds = DatastoreServiceFactory.getAsyncDatastoreService();

  private HogeMeta meta = new HogeMeta();

  @Override
  public void setUp() throws Exception {
    super.setUp();
    CipherFactory.getFactory().setGlobalKey("xxxxxxxxxxxxxxxx");
  }

  @Override
  public void tearDown() throws Exception {
    CipherFactory.getFactory().clearGlobalKey();
    super.tearDown();
  }

  /** @throws Exception */
  @Test
  public void beginTransaction() throws Exception {
    assertThat(DatastoreUtil.beginTransaction(ds), is(notNullValue()));
  }

  /** @throws Exception */
  @Test
  public void allocateIdsAsync() throws Exception {
    Future<KeyRange> future = DatastoreUtil.allocateIdsAsync(ds, "Hoge", 2);
    assertThat(future, is(notNullValue()));
    assertThat(future.get().getSize(), is(2L));
  }

  /** @throws Exception */
  @Test
  public void allocateIdsAsyncWithParentKey() throws Exception {
    Key parentKey = KeyFactory.createKey("Parent", 1);
    Future<KeyRange> future = DatastoreUtil.allocateIdsAsync(ds, parentKey, "Child", 2);
    assertThat(future, is(notNullValue()));
    assertThat(future.get().getSize(), is(2L));
  }

  /** @throws Exception */
  @Test
  public void allocateId() throws Exception {
    DatastoreUtil.keysCache.remove("Hoge");
    Key key = DatastoreUtil.allocateId(ds, "Hoge");
    assertThat(key, is(notNullValue()));
    Iterator<Key> keys = DatastoreUtil.keysCache.get("Hoge");
    assertThat(keys, is(notNullValue()));
    for (int i = 0; i < 49; i++) {
      DatastoreUtil.allocateId(ds, "Hoge");
      assertThat(DatastoreUtil.keysCache.get("Hoge"), is(sameInstance(keys)));
    }
    DatastoreUtil.allocateId(ds, "Hoge");
    assertThat(DatastoreUtil.keysCache.get("Hoge"), is(not(sameInstance(keys))));
  }

  /** @throws Exception */
  @Test
  public void allocateIdWithParentKey() throws Exception {
    Key parentKey = KeyFactory.createKey("Parent", 1);
    Key key = DatastoreUtil.allocateId(ds, parentKey, "Child");
    assertThat(key, is(notNullValue()));
    assertThat(key.isComplete(), is(true));
  }

  /** @throws Exception */
  @Test
  public void assignKeyIfNecessary() throws Exception {
    Entity entity = new Entity("Hoge");
    DatastoreUtil.assignKeyIfNecessary(ds, entity);
    assertThat(entity.getKey().getId(), is(not(0L)));
  }

  /** @throws Exception */
  @Test
  public void assignKeyIfNecessaryWhenParentExists() throws Exception {
    DatastoreUtil.allocateId(ds, "Child");
    Key dummyKey2 = DatastoreUtil.allocateId(ds, "Child");
    Key parentKey = DatastoreUtil.allocateId(ds, "Parent");
    Entity entity = new Entity("Child", parentKey);
    DatastoreUtil.assignKeyIfNecessary(ds, entity);
    assertThat(entity.getKey().getId(), is(not(dummyKey2.getId() + 1)));
  }

  /** @throws Exception */
  @Test
  public void assignKeyIfNecessaryForEntities() throws Exception {
    Entity entity = new Entity("Hoge");
    DatastoreUtil.assignKeyIfNecessary(ds, Arrays.asList(entity));
    assertThat(entity.getKey().getId(), is(not(0L)));
  }

  /** @throws Exception */
  @Test
  public void getOrNull() throws Exception {
    Key key = ds.put(new Entity("Hoge")).get();
    Transaction tx = ds.beginTransaction().get();
    assertThat(DatastoreUtil.getOrNull(ds, tx, key), is(notNullValue()));
  }

  /** @throws Exception */
  @Test
  public void getOrNullNoEntityIsFound() throws Exception {
    Transaction tx = ds.beginTransaction().get();
    assertThat(
        DatastoreUtil.getOrNull(ds, tx, KeyFactory.createKey("Hoge", "xxx")), is(nullValue()));
  }

  /** @throws Exception */
  @Test
  public void get() throws Exception {
    Key key = ds.put(new Entity("Hoge")).get();
    Transaction tx = ds.beginTransaction().get();
    assertThat(DatastoreUtil.get(ds, tx, key), is(notNullValue()));
  }

  /** @throws Exception */
  @Test(expected = EntityNotFoundRuntimeException.class)
  public void getNoEntityIsFound() throws Exception {
    Transaction tx = ds.beginTransaction().get();
    DatastoreUtil.get(ds, tx, KeyFactory.createKey("Hoge", "xxx"));
  }

  /** @throws Exception */
  @Test
  public void getAsMapAsync() throws Exception {
    Key key = ds.put(new Entity("Hoge")).get();
    Key key2 = ds.put(new Entity("Hoge", key)).get();
    Transaction tx = ds.beginTransaction().get();
    Map<Key, Entity> map = DatastoreUtil.getAsMapAsync(ds, tx, Arrays.asList(key, key2)).get();
    assertThat(map, is(notNullValue()));
    assertThat(map.size(), is(2));
  }

  /** @throws Exception */
  @Test(expected = IllegalStateException.class)
  public void getAsMapAsyncTxIsIllegal() throws Exception {
    Key key = ds.put(new Entity("Hoge")).get();
    Key key2 = ds.put(new Entity("Hoge", key)).get();
    Transaction tx = ds.beginTransaction().get();
    tx.rollback();
    DatastoreUtil.getAsMapAsync(ds, tx, Arrays.asList(key, key2));
  }

  /** @throws Exception */
  @Test
  public void getAsMapAsyncNoTx() throws Exception {
    Key key = ds.put(new Entity("Hoge")).get();
    Key key2 = ds.put(new Entity("Hoge", key)).get();
    Map<Key, Entity> map = DatastoreUtil.getAsMapAsync(ds, null, Arrays.asList(key, key2)).get();
    assertThat(map, is(notNullValue()));
    assertThat(map.size(), is(2));
  }

  /** @throws Exception */
  @Test
  public void putAsync() throws Exception {
    Entity entity = new Entity(KeyFactory.createKey("Hoge", 1));
    Entity entity2 = new Entity(KeyFactory.createKey(entity.getKey(), "Hoge", 1));
    Transaction tx = ds.beginTransaction().get();
    List<Key> keys = DatastoreUtil.putAsync(ds, tx, Arrays.asList(entity, entity2)).get();
    tx.rollback();
    assertThat(keys, is(notNullValue()));
    assertThat(keys.size(), is(2));
    assertThat(tester.count("Hoge"), is(0));
  }

  /** @throws Exception */
  @Test(expected = IllegalStateException.class)
  public void putAsyncIllegalTx() throws Exception {
    Entity entity = new Entity(KeyFactory.createKey("Hoge", 1));
    Entity entity2 = new Entity(KeyFactory.createKey(entity.getKey(), "Hoge", 1));
    Transaction tx = ds.beginTransaction().get();
    tx.rollback();
    DatastoreUtil.putAsync(ds, tx, Arrays.asList(entity, entity2)).get();
  }

  /** @throws Exception */
  @Test
  public void putAsyncNoTx() throws Exception {
    Entity entity = new Entity(KeyFactory.createKey("Hoge", 1));
    Entity entity2 = new Entity(KeyFactory.createKey(entity.getKey(), "Hoge", 1));
    List<Key> keys = DatastoreUtil.putAsync(ds, null, Arrays.asList(entity, entity2)).get();
    assertThat(keys, is(notNullValue()));
    assertThat(keys.size(), is(2));
    assertThat(tester.count("Hoge"), is(2));
  }

  /** @throws Exception */
  @Test
  public void deleteAsync() throws Exception {
    Key key = ds.put(new Entity("Hoge")).get();
    Transaction tx = ds.beginTransaction().get();
    DatastoreUtil.deleteAsync(ds, tx, Arrays.asList(key)).get();
    tx.rollback();
    assertThat(tester.count("Hoge"), is(1));
  }

  /** @throws Exception */
  @Test(expected = IllegalStateException.class)
  public void deleteAsyncIllegalTx() throws Exception {
    Key key = ds.put(new Entity("Hoge")).get();
    Transaction tx = ds.beginTransaction().get();
    tx.rollback();
    DatastoreUtil.deleteAsync(ds, tx, Arrays.asList(key)).get();
  }

  /** @throws Exception */
  @Test
  public void deleteAsyncNoTx() throws Exception {
    Key key = ds.put(new Entity("Hoge")).get();
    DatastoreUtil.deleteAsync(ds, null, Arrays.asList(key)).get();
    assertThat(tester.count("Hoge"), is(0));
  }

  /** @throws Exception */
  @Test
  public void filterInMemory() throws Exception {
    List<Hoge> list = new ArrayList<Hoge>();
    Hoge hoge = new Hoge();
    hoge.setMyInteger(1);
    list.add(hoge);
    hoge = new Hoge();
    hoge.setMyInteger(3);
    list.add(hoge);
    hoge = new Hoge();
    hoge.setMyInteger(2);
    list.add(hoge);

    List<Hoge> filtered =
        DatastoreUtil.filterInMemory(
            list,
            Arrays.asList(
                (InMemoryFilterCriterion) meta.myInteger.greaterThanOrEqual(2),
                (InMemoryFilterCriterion) meta.myInteger.lessThan(3)));
    assertThat(filtered.size(), is(1));
    assertThat(filtered.get(0).getMyInteger(), is(2));
  }

  /** @throws Exception */
  @Test
  public void filterInMemoryForEnum() throws Exception {
    List<Hoge> list = new ArrayList<Hoge>();
    Hoge hoge = new Hoge();
    hoge.setMyEnum(SortDirection.ASCENDING);
    list.add(hoge);
    hoge = new Hoge();
    hoge.setMyEnum(SortDirection.DESCENDING);
    list.add(hoge);

    List<Hoge> filtered =
        DatastoreUtil.filterInMemory(
            list, Arrays.asList(meta.myEnum.equal(SortDirection.ASCENDING)));
    assertThat(filtered.size(), is(1));
    assertThat(filtered.get(0).getMyEnum(), is(SortDirection.ASCENDING));
  }

  /** @throws Exception */
  @Test
  public void sortInMemory() throws Exception {
    List<Hoge> list = new ArrayList<Hoge>();
    Hoge hoge = new Hoge();
    hoge.setMyInteger(1);
    list.add(hoge);
    hoge = new Hoge();
    hoge.setMyInteger(3);
    list.add(hoge);
    hoge = new Hoge();
    hoge.setMyInteger(2);
    list.add(hoge);

    List<Hoge> sorted =
        DatastoreUtil.sortInMemory(
            list, Arrays.asList((InMemorySortCriterion) meta.myInteger.desc));
    assertThat(sorted.size(), is(3));
    assertThat(sorted.get(0).getMyInteger(), is(3));
    assertThat(sorted.get(1).getMyInteger(), is(2));
    assertThat(sorted.get(2).getMyInteger(), is(1));
  }

  /** @throws Exception */
  @Test
  public void sortInMemoryForEnumWhenAscending() throws Exception {
    List<Hoge> list = new ArrayList<Hoge>();
    Hoge hoge = new Hoge();
    hoge.setMyEnum(SortDirection.ASCENDING);
    list.add(hoge);
    hoge = new Hoge();
    hoge.setMyEnum(SortDirection.DESCENDING);
    list.add(hoge);

    List<Hoge> sorted =
        DatastoreUtil.sortInMemory(list, Arrays.asList((InMemorySortCriterion) meta.myEnum.asc));
    assertThat(sorted.size(), is(2));
    assertThat(sorted.get(0).getMyEnum(), is(SortDirection.ASCENDING));
    assertThat(sorted.get(1).getMyEnum(), is(SortDirection.DESCENDING));
  }

  /** @throws Exception */
  @Test
  public void sortInMemoryForEnumWhenDescending() throws Exception {
    List<Hoge> list = new ArrayList<Hoge>();
    Hoge hoge = new Hoge();
    hoge.setMyEnum(SortDirection.ASCENDING);
    list.add(hoge);
    hoge = new Hoge();
    hoge.setMyEnum(SortDirection.DESCENDING);
    list.add(hoge);

    List<Hoge> sorted =
        DatastoreUtil.sortInMemory(list, Arrays.asList((InMemorySortCriterion) meta.myEnum.desc));
    assertThat(sorted.size(), is(2));
    assertThat(sorted.get(0).getMyEnum(), is(SortDirection.DESCENDING));
    assertThat(sorted.get(1).getMyEnum(), is(SortDirection.ASCENDING));
  }

  /** @throws Exception */
  @SuppressWarnings("unchecked")
  @Test
  public void getModelMeta() throws Exception {
    ModelMeta<Hoge> modelMeta = DatastoreUtil.getModelMeta(Hoge.class);
    assertThat(modelMeta, is(notNullValue()));
    assertThat(modelMeta, is(sameInstance((ModelMeta) Datastore.getModelMeta(Hoge.class))));
  }

  /** @throws Exception */
  @Test
  public void getModelMetaWithEntity() throws Exception {
    AaaMeta aaaMeta = new AaaMeta();
    Entity entity = new Entity("Aaa");
    entity.setProperty(aaaMeta.getClassHierarchyListName(), Arrays.asList(Bbb.class.getName()));
    ModelMeta<Aaa> modelMeta = DatastoreUtil.getModelMeta(aaaMeta, entity);
    assertThat(modelMeta, is(notNullValue()));
    assertThat(modelMeta.getModelClass().getName(), is(Bbb.class.getName()));
  }

  /** @throws Exception */
  @Test(expected = IllegalArgumentException.class)
  public void getModelMetaWithEntityForIllegalClass() throws Exception {
    AaaMeta aaaMeta = new AaaMeta();
    Entity entity = new Entity("Aaa");
    entity.setProperty(aaaMeta.getClassHierarchyListName(), Arrays.asList(Bbb.class.getName()));
    DatastoreUtil.getModelMeta(meta, entity);
  }

  /** @throws Exception */
  @Test(expected = IllegalArgumentException.class)
  public void getModelMetaWhenModelMetaIsNotFound() throws Exception {
    DatastoreUtil.getModelMeta(getClass());
  }

  /** @throws Exception */
  @Test
  public void createModelMetaWhenGWT() throws Exception {
    ModelMeta<?> modelMeta = DatastoreUtil.getModelMeta(Ccc.class);
    assertThat(modelMeta, is(notNullValue()));
  }

  /** @throws Exception */
  @Test
  public void replacePackageName() throws Exception {
    assertThat(
        DatastoreUtil.replacePackageName("abc.model.Hoge", "model", "meta"), is("abc.meta.Hoge"));
    assertThat(
        DatastoreUtil.replacePackageName("abc.model.xxx.model.Hoge", "model", "meta"),
        is("abc.model.xxx.meta.Hoge"));
    assertThat(DatastoreUtil.replacePackageName("abc.Hoge", "model", "meta"), is("abc.Hoge"));
  }

  /** @throws Exception */
  @Test
  public void entityToBytes() throws Exception {
    assertThat(DatastoreUtil.entityToBytes(new Entity("Hoge")), is(notNullValue()));
  }

  /** @throws Exception */
  @Test
  public void bytesToEntity() throws Exception {
    Entity entity = new Entity(Datastore.createKey("Hoge", 1));
    byte[] bytes = DatastoreUtil.entityToBytes(entity);
    Entity entity2 = DatastoreUtil.bytesToEntity(bytes);
    assertThat(entity2, is(notNullValue()));
    assertThat(entity2, is(entity));
  }

  /** @throws Exception */
  @Test
  public void modelToEntity() throws Exception {
    Hoge hoge = new Hoge();
    Entity entity = DatastoreUtil.modelToEntity(ds, hoge);
    assertThat((Long) entity.getProperty("version"), is(1L));
    assertThat(hoge.getKey(), is(notNullValue()));
    assertThat(hoge.getKey(), is(entity.getKey()));
  }

  /** @throws Exception */
  @Test
  public void modelsToEntities() throws Exception {
    Hoge hoge = new Hoge();
    Entity entity = new Entity("Hoge");
    List<Entity> entities = DatastoreUtil.modelsToEntities(ds, Arrays.asList(hoge, entity));
    assertThat(entities.size(), is(2));
    assertThat((Long) entities.get(0).getProperty("version"), is(1L));
    assertThat(hoge.getKey(), is(notNullValue()));
    assertThat(hoge.getKey(), is(entities.get(0).getKey()));
  }

  /** @throws Exception */
  @Test
  public void entityMapToEntityList() throws Exception {
    Key key = Datastore.createKey("Hoge", 1);
    Key key2 = Datastore.createKey("Hoge", 2);
    Key key3 = Datastore.createKey("Hoge", 3);
    Entity entity = new Entity(key);
    Entity entity2 = new Entity(key2);
    Entity entity3 = new Entity(key3);
    Map<Key, Entity> map = new HashMap<Key, Entity>();
    map.put(key3, entity3);
    map.put(key2, entity2);
    map.put(key, entity);
    List<Entity> list = DatastoreUtil.entityMapToEntityList(Arrays.asList(key, key2, key3), map);
    assertThat(list.size(), is(3));
    assertThat(list.get(0), is(entity));
    assertThat(list.get(1), is(entity2));
    assertThat(list.get(2), is(entity3));
  }

  /** @throws Exception */
  @Test(expected = EntityNotFoundRuntimeException.class)
  public void entityMapToEntityListWhenNoEntityIsFound() throws Exception {
    Key key = Datastore.createKey("Hoge", 1);
    Key key2 = Datastore.createKey("Hoge", 2);
    Key key3 = Datastore.createKey("Hoge", 3);
    Entity entity = new Entity(key);
    Entity entity2 = new Entity(key2);
    Map<Key, Entity> map = new HashMap<Key, Entity>();
    map.put(key2, entity2);
    map.put(key, entity);
    DatastoreUtil.entityMapToEntityList(Arrays.asList(key, key2, key3), map);
  }

  /** @throws Exception */
  @Test
  public void entityMapToModelList() throws Exception {
    Key key = Datastore.createKey("Hoge", 1);
    Key key2 = Datastore.createKey("Hoge", 2);
    Key key3 = Datastore.createKey("Hoge", 3);
    Entity entity = new Entity(key);
    Entity entity2 = new Entity(key2);
    Entity entity3 = new Entity(key3);
    Map<Key, Entity> map = new HashMap<Key, Entity>();
    map.put(key3, entity3);
    map.put(key2, entity2);
    map.put(key, entity);
    List<Hoge> list = DatastoreUtil.entityMapToModelList(meta, Arrays.asList(key, key2, key3), map);
    assertThat(list.size(), is(3));
    assertThat(list.get(0).getKey(), is(key));
    assertThat(list.get(1).getKey(), is(key2));
    assertThat(list.get(2).getKey(), is(key3));
  }

  /** @throws Exception */
  @Test(expected = EntityNotFoundRuntimeException.class)
  public void entityMapToModelListWhenNoEntityIsFound() throws Exception {
    Key key = Datastore.createKey("Hoge", 1);
    Key key2 = Datastore.createKey("Hoge", 2);
    Key key3 = Datastore.createKey("Hoge", 3);
    Entity entity = new Entity(key);
    Entity entity2 = new Entity(key2);
    Map<Key, Entity> map = new HashMap<Key, Entity>();
    map.put(key2, entity2);
    map.put(key, entity);
    DatastoreUtil.entityMapToModelList(meta, Arrays.asList(key, key2, key3), map);
  }

  /** @throws Exception */
  @Test
  public void entityMapToModelMap() throws Exception {
    Key key = Datastore.createKey("Hoge", 1);
    Key key2 = Datastore.createKey("Hoge", 2);
    Key key3 = Datastore.createKey("Hoge", 3);
    Entity entity = new Entity(key);
    Entity entity2 = new Entity(key2);
    Entity entity3 = new Entity(key3);
    Map<Key, Entity> map = new HashMap<Key, Entity>();
    map.put(key3, entity3);
    map.put(key2, entity2);
    map.put(key, entity);
    Map<Key, Hoge> map2 = DatastoreUtil.entityMapToModelMap(meta, map);
    assertThat(map2.size(), is(3));
    assertThat(map2.get(key).getKey(), is(key));
    assertThat(map2.get(key2).getKey(), is(key2));
    assertThat(map2.get(key3).getKey(), is(key3));
  }

  /** @throws Exception */
  @Test
  public void refereceToKeyForId() throws Exception {
    Key key = KeyFactory.createKey("Hoge", 1);
    Reference reference = new Reference();
    Path path = new Path();
    reference.setPath(path);
    Element element = path.addElement();
    element.setType("Hoge");
    element.setId(1);
    assertThat(DatastoreUtil.referenceToKey(reference), is(key));
  }

  /** @throws Exception */
  @Test
  public void refereceToKeyForMinusId() throws Exception {
    Key key = KeyFactory.createKey("Hoge", -1);
    Reference reference = new Reference();
    Path path = new Path();
    reference.setPath(path);
    Element element = path.addElement();
    element.setType("Hoge");
    element.setId(-1);
    assertThat(DatastoreUtil.referenceToKey(reference), is(key));
  }

  /** @throws Exception */
  @Test
  public void refereceToKeyForName() throws Exception {
    Key key = KeyFactory.createKey("Hoge", "aaa");
    Reference reference = new Reference();
    Path path = new Path();
    reference.setPath(path);
    Element element = path.addElement();
    element.setType("Hoge");
    element.setName("aaa");
    assertThat(DatastoreUtil.referenceToKey(reference), is(key));
  }

  /** @throws Exception */
  @Test
  public void refereceToKeyForParent() throws Exception {
    Key parentKey = KeyFactory.createKey("Parent", 1);
    Key childKey = KeyFactory.createKey(parentKey, "Child", 1);
    Reference reference = new Reference();
    Path path = new Path();
    reference.setPath(path);
    Element element = path.addElement();
    element.setType("Parent");
    element.setId(1);
    element = path.addElement();
    element.setType("Child");
    element.setId(1);
    assertThat(DatastoreUtil.referenceToKey(reference), is(childKey));
  }

  /** @throws Exception */
  @Test
  public void getRoot() throws Exception {
    Key parentKey = KeyFactory.createKey("Parent", 1);
    Key childKey = KeyFactory.createKey(parentKey, "Child", 1);
    Key grandChildKey = KeyFactory.createKey(childKey, "GrandChild", 1);
    assertThat(DatastoreUtil.getRoot(parentKey), is(parentKey));
    assertThat(DatastoreUtil.getRoot(childKey), is(parentKey));
    assertThat(DatastoreUtil.getRoot(grandChildKey), is(parentKey));
  }

  /** @throws Exception */
  @Test
  public void toFilters() throws Exception {
    List<Filter> filters = DatastoreUtil.toFilters(meta, meta.myString.equal("aaa"));
    assertThat(filters.size(), is(1));
    assertThat(filters.get(0), is(Query.FilterPredicate.class));
  }
}
 @Deprecated
 public static AsyncDatastoreService getInstance() {
   return DatastoreServiceFactory.getAsyncDatastoreService();
 }
 /**
  * BaseDatastoreService binds will be done according to last invocation of this method or
  * withDatastoreService
  *
  * @return
  */
 public AppEngineGuiceModule withAsyncDatastoreService() {
   this.datastoreService = null;
   this.asyncDatastoreService = DatastoreServiceFactory.getAsyncDatastoreService();
   return this;
 }