Package com.google.appengine.tck.datastore

Source Code of com.google.appengine.tck.datastore.RequiredIndexesTest

/*
* 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.List;

import com.google.appengine.api.datastore.DatastoreNeedIndexException;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.PropertyProjection;
import com.google.appengine.api.datastore.Query;
import org.jboss.arquillian.junit.Arquillian;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

import static com.google.appengine.api.datastore.Query.CompositeFilterOperator.and;
import static com.google.appengine.api.datastore.Query.FilterOperator.EQUAL;
import static com.google.appengine.api.datastore.Query.FilterOperator.GREATER_THAN;
import static com.google.appengine.api.datastore.Query.FilterOperator.LESS_THAN;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
* Tests that check if certain queries throw DatastoreNeedIndexException when an explicit index is required for the query,
* and don't throw the exception, when an explicit index is not required, because an automatic index is used for the query.
*
* @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
*/
@RunWith(Arquillian.class)
public class RequiredIndexesTest extends QueryTestBase {

    private static final String EXPECTED_DS_INDEX_MSG = "Expected DatastoreNeedIndexException.";

    @Test
    public void testKindlessQueryUsingOnlyAncestorAndKeyFiltersDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(new Query()
            .setAncestor(KeyFactory.createKey("Ancestor", 1))
            .setFilter(new Query.FilterPredicate(Entity.KEY_RESERVED_PROPERTY, GREATER_THAN, KeyFactory.createKey("Kind", 1))));
    }

    @Test
    public void testQueryUsingOnlyEqualityFiltersDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(new Query("Unindexed")
            .setFilter(new Query.FilterPredicate("someProperty", EQUAL, "foo")));

        executeQuery(new Query("Unindexed")
            .setFilter(
                and(new Query.FilterPredicate("someProperty", EQUAL, "foo"),
                    new Query.FilterPredicate("otherProperty", EQUAL, "bar"))));
    }

    @Test
    public void testQueryUsingOnlyInequalityFiltersOnSinglePropertyDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(new Query("Unindexed")
            .setFilter(new Query.FilterPredicate("someProperty", GREATER_THAN, "foo")));

        executeQuery(new Query("Unindexed")
            .setFilter(
                and(new Query.FilterPredicate("someProperty", GREATER_THAN, "foo"),
                    new Query.FilterPredicate("someProperty", LESS_THAN, "bar"))));
    }

    @Test
    public void testQueryUsingOnlyAncestorAndEqualityFiltersDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(new Query("Unindexed")
            .setAncestor(KeyFactory.createKey("Ancestor", 1))
            .setFilter(new Query.FilterPredicate("someProperty", EQUAL, "foo")));

        executeQuery(new Query("Unindexed")
            .setAncestor(KeyFactory.createKey("Ancestor", 1))
            .setFilter(
                and(new Query.FilterPredicate("someProperty", EQUAL, "foo"),
                    new Query.FilterPredicate("otherProperty", EQUAL, "bar"))));
    }

    @Test(expected = DatastoreNeedIndexException.class)
    public void testQueryWithAncestorAndInequalityFiltersRequiresConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setAncestor(KeyFactory.createKey("Ancestor", 1))
                .setFilter(new Query.FilterPredicate("someProperty", GREATER_THAN, "a")));
    }

    @Test
    public void testQueryWithEqalityAndInequalityFilterOnKeyPropertyDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setFilter(
                    and(new Query.FilterPredicate(Entity.KEY_RESERVED_PROPERTY, GREATER_THAN, KeyFactory.createKey("Unindexed", 1)),
                        new Query.FilterPredicate(Entity.KEY_RESERVED_PROPERTY, EQUAL, KeyFactory.createKey("Unindexed", 2)))));
    }

    @Test
    public void testQueryWithAncestorAndInequalityFilterOnKeyPropertyDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setAncestor(KeyFactory.createKey("Ancestor", 1))
                .setFilter(new Query.FilterPredicate(Entity.KEY_RESERVED_PROPERTY, GREATER_THAN, KeyFactory.createKey("Unindexed", 1))));
    }

    @Test
    public void testQueryWithInequalityFilterOnKeyPropertyAndEqualityFilterOnOtherPropertyDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setFilter(
                    and(new Query.FilterPredicate(Entity.KEY_RESERVED_PROPERTY, GREATER_THAN, KeyFactory.createKey("Unindexed", 1)),
                        new Query.FilterPredicate("otherProperty", EQUAL, "b"))));
    }

    @Test(expected = DatastoreNeedIndexException.class)
    public void testQueryWithEqualityFilterOnKeyPropertyAndInequalityFilterOnOtherPropertyRequiresConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setFilter(
                    and(new Query.FilterPredicate(Entity.KEY_RESERVED_PROPERTY, EQUAL, KeyFactory.createKey("Unindexed", 1)),
                        new Query.FilterPredicate("someProperty", GREATER_THAN, "a"))));
    }

    @Test(expected = DatastoreNeedIndexException.class)
    public void testQueryWithInequalityFilterOnSomePropertyAndEqualityFilterOnOtherPropertyRequiresConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setFilter(
                    and(new Query.FilterPredicate("someProperty", GREATER_THAN, "a"),
                        new Query.FilterPredicate("otherProperty", EQUAL, "b"))));
    }

    @Ignore("Fails intermittently on appspot. Is an index needed in this case or not?")
    @Test(expected = DatastoreNeedIndexException.class)
    public void testQueryWithInequalityFilterOnSomePropertyAndEqualityFilterOnSamePropertyRequiresConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setFilter(
                    and(new Query.FilterPredicate("someProperty", EQUAL, "b"),
                        new Query.FilterPredicate("someProperty", GREATER_THAN, "a"))));
    }

    @Test(expected = DatastoreNeedIndexException.class)
    public void testAncestorQueryWithInequalityFilterOnSomePropertyAndEqualityFilterOnSamePropertyRequiresConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setAncestor(KeyFactory.createKey("Ancestor", 1))
                .setFilter(
                    and(new Query.FilterPredicate("someProperty", EQUAL, "b"),
                        new Query.FilterPredicate("someProperty", GREATER_THAN, "a"))));
    }

    @Test
    public void testQueryWithEqualityAndInequalityFiltersAndSortOnASinglePropertyDoesRequireConfiguredIndex() throws Exception {
        try {
            executeQuery(
                new Query("Unindexed")
                    .setFilter(
                        and(new Query.FilterPredicate("someProperty", GREATER_THAN, "a"),
                            new Query.FilterPredicate("someProperty", EQUAL, "b")))
                    .addSort("someProperty"));
        } catch (Exception e) {
            assertTrue(EXPECTED_DS_INDEX_MSG + " instead got " + e.toString(), e instanceof DatastoreNeedIndexException);
            return;
        }
        fail(EXPECTED_DS_INDEX_MSG);
    }

    @Test
    public void testAncestorQueryWithEqualityAndInequalityFiltersAndSortOnASinglePropertyDoesRequireConfiguredIndex() throws Exception {
        try {
            executeQuery(
                new Query("Unindexed")
                    .setAncestor(KeyFactory.createKey("Ancestor", 1))
                    .setFilter(
                        and(new Query.FilterPredicate("someProperty", GREATER_THAN, "a"),
                            new Query.FilterPredicate("someProperty", EQUAL, "b")))
                    .addSort("someProperty"));
        } catch (Exception e) {
            assertTrue(EXPECTED_DS_INDEX_MSG + " instead got " + e.toString(), e instanceof DatastoreNeedIndexException);
            return;
        }
        fail(EXPECTED_DS_INDEX_MSG);
    }

    @Test
    public void testQueryUsingOnlyAncestorFiltersAndEqualityFiltersOnPropertiesAndInequalityFiltersOnKeysDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(new Query("Unindexed")
            .setAncestor(KeyFactory.createKey("Ancestor", 1))
            .setFilter(
                and(new Query.FilterPredicate("someProperty", EQUAL, "foo"),
                    new Query.FilterPredicate(Entity.KEY_RESERVED_PROPERTY, GREATER_THAN, KeyFactory.createKey("Unindexed", 1)))));
    }

    @Test
    public void testQueryWithoutFiltersAndOnlyOneSortOrderDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(new Query("Unindexed")
            .addSort("someProperty"));

        executeQuery(new Query("Unindexed")
            .addSort("someProperty", Query.SortDirection.DESCENDING));
    }

    @Test
    public void testQueryWithAncestorAndSortOrderOnKeyPropertyDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(new Query("Unindexed")
            .setAncestor(KeyFactory.createKey("Ancestor", 1))
            .addSort(Entity.KEY_RESERVED_PROPERTY));
    }

    @Test(expected = DatastoreNeedIndexException.class)
    public void testQueryWithAncestorAndSortOrderRequiresConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setAncestor(KeyFactory.createKey("Ancestor", 1))
                .addSort("someProperty"));
    }

    @Test
    public void testProjectionQueryOperatingOnlyOnASinglePropertyDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(new Query("Unindexed")
            .addProjection(new PropertyProjection("someProperty", null)));

        executeQuery(new Query("Unindexed")
            .addProjection(new PropertyProjection("someProperty", null))
            .setFilter(new Query.FilterPredicate("someProperty", GREATER_THAN, "a")));

        executeQuery(new Query("Unindexed")
            .addProjection(new PropertyProjection("someProperty", null))
            .setFilter(new Query.FilterPredicate("someProperty", GREATER_THAN, "a"))
            .addSort("someProperty"));

        executeQuery(new Query("Unindexed")
            .addProjection(new PropertyProjection("someProperty", null))
            .setFilter(new Query.FilterPredicate("someProperty", GREATER_THAN, "a"))
            .addSort("someProperty", Query.SortDirection.DESCENDING));
    }

    @Test(expected = DatastoreNeedIndexException.class)
    public void testQueryWithDescendingSortOrderOnKeysRequiresConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .addSort(Entity.KEY_RESERVED_PROPERTY, Query.SortDirection.DESCENDING));
    }

    @Test(expected = DatastoreNeedIndexException.class)
    public void testQueryWithMultipleSortOrdersRequiresConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .addSort("someProperty")
                .addSort("otherProperty"));
    }

    @Test(expected = DatastoreNeedIndexException.class)
    public void testQueryWithEqualityFilterAndSortOnAnotherPropertyRequiresConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setFilter(new Query.FilterPredicate("someProperty", EQUAL, "foo"))
                .addSort("otherProperty"));
    }

    @Test
    public void testQueryWithEqualityFilterAndSortOnKeyPropertyDoesNotRequireConfiguredIndex() throws Exception {
        executeQuery(new Query("Unindexed")
            .setFilter(new Query.FilterPredicate("someProperty", EQUAL, "foo"))
            .addSort(Entity.KEY_RESERVED_PROPERTY));
    }

    @Test(expected = DatastoreNeedIndexException.class)
    public void testQueryWithInequalityFilterAndSortOnAnotherPropertyRequiresConfiguredIndex() throws Exception {
        executeQuery(
            new Query("Unindexed")
                .setFilter(new Query.FilterPredicate("someProperty", GREATER_THAN, "foo"))
                .addSort("someProperty")
                .addSort("otherProperty"));
    }

    @Test
    public void testExceptionIsThrownOnlyWhenResultsAreAccessedAndNotEarlier() throws Exception {
        List<Entity> list = null;
        try {
            Query query = new Query("Unindexed")
                .addSort("someProperty")
                .addSort("otherProperty");

            PreparedQuery preparedQuery = service.prepare(query);
            list = preparedQuery.asList(withDefaults());
        } catch (DatastoreNeedIndexException ex) {
            Assert.fail("DatastoreNeedIndexException thrown too early");
        }

        try {
            list.size();
            Assert.fail("Expected DatastoreNeedIndexException");
        } catch (DatastoreNeedIndexException ex) {
            // pass
        }
    }

    private void executeQuery(Query query) {
        PreparedQuery preparedQuery = service.prepare(query);
        List<Entity> list = preparedQuery.asList(withDefaults());
        list.size();    // only here is the query actually executed
    }
}
TOP

Related Classes of com.google.appengine.tck.datastore.RequiredIndexesTest

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.