@Test
  public void testRemoteFullRegionQueries() throws CacheException {

    final String name = getName();
    final Host host = Host.getHost(0);
    VM vm0 = host.getVM(0);
    VM vm1 = host.getVM(1);
    final int numberOfEntries = 100;

    // Start server
    vm0.invoke(new CacheSerializableRunnable("Create cache server") {
      @Override
      public void run2() throws CacheException {
        Properties config = new Properties();
        config.setProperty(LOCATORS,
            "localhost[" + DistributedTestUtils.getDUnitLocatorPort() + "]");
        getSystem(config);
        AttributesFactory factory = new AttributesFactory();
        factory.setScope(Scope.LOCAL);
        createRegion(name, factory.create());
        Wait.pause(1000);
        try {
          startBridgeServer(0, false);
        } catch (Exception ex) {
          Assert.fail("While starting CacheServer", ex);
        }
      }
    });

    // Initialize server region
    vm0.invoke(new CacheSerializableRunnable("Create cache server") {
      @Override
      public void run2() throws CacheException {
        Region region = getRootRegion().getSubregion(name);
        for (int i = 0; i < numberOfEntries; i++) {
          region.put("key-" + i, new TestObject(i, "ibm"));
        }
      }
    });

    // Create client region
    final int port = vm0.invoke(RemoteQueryDUnitTest::getCacheServerPort);
    final String host0 = NetworkUtils.getServerHostName(vm0.getHost());
    vm1.invoke(new CacheSerializableRunnable("Create region") {
      @Override
      public void run2() throws CacheException {
        Properties config = new Properties();
        config.setProperty(MCAST_PORT, "0");
        getSystem(config);
        getCache();
        AttributesFactory factory = new AttributesFactory();
        factory.setScope(Scope.LOCAL);
        ClientServerTestCase.configureConnectionPool(factory, host0, port, -1, true, -1, -1, null);
        createRegion(name, factory.create());
      }
    });

    // Execute client queries
    vm1.invoke(new CacheSerializableRunnable("Execute queries") {
      @Override
      public void run2() throws CacheException {
        Region region = getRootRegion().getSubregion(name);
        String queryString = null;
        SelectResults results = null;
        Comparator comparator = null;
        Object[] resultsArray = null;

        // value query
        queryString = "SELECT DISTINCT itr.value FROM " + region.getFullPath()
            + ".entries itr where itr.key = 'key-1'";
        try {
          results = region.query(queryString);
        } catch (Exception e) {
          Assert.fail("Failed executing " + queryString, e);
        }
        assertEquals(1, results.size());
        assertTrue(!results.getCollectionType().allowsDuplicates());
        assertTrue(results.asList().get(0) instanceof TestObject);

        // key query
        queryString = "SELECT DISTINCT itr.key FROM " + region.getFullPath()
            + ".entries itr where itr.key = 'key-1'";
        try {
          results = region.query(queryString);
        } catch (Exception e) {
          Assert.fail("Failed executing " + queryString, e);
        }
        assertEquals(1, results.size());
        assertTrue(!results.getCollectionType().allowsDuplicates());
        assertEquals("key-1", results.asList().get(0));

        // order by value query
        queryString =
            "SELECT DISTINCT * FROM " + region.getFullPath() + " WHERE id < 101 ORDER BY id";
        try {
          results = region.query(queryString);
        } catch (Exception e) {
          Assert.fail("Failed executing " + queryString, e);
        }
        assertEquals(numberOfEntries, results.size());
        // All order-by query results are stored in a ResultsCollectionWrapper
        // wrapping a list, so the assertion below is not correct even though
        // it should be.
        // assertTrue(!results.getCollectionType().allowsDuplicates());
        assertTrue(results.getCollectionType().isOrdered());
        comparator = new IdComparator();
        resultsArray = results.toArray();
        for (int i = 0; i < resultsArray.length; i++) {
          if (i + 1 != resultsArray.length) {
            // The id of the current element in the result set must be less
            // than the id of the next one to pass.
            assertTrue(
                "The id for " + resultsArray[i] + " should be less than the id for "
                    + resultsArray[i + 1],
                comparator.compare(resultsArray[i], resultsArray[i + 1]) == -1);
          }
        }

        // order by struct query
        queryString = "SELECT DISTINCT id, ticker, price FROM " + region.getFullPath()
            + " WHERE id < 101 ORDER BY id";
        try {
          results = region.query(queryString);
        } catch (Exception e) {
          Assert.fail("Failed executing " + queryString, e);
        }
        assertEquals(numberOfEntries, results.size());
        // All order-by query results are stored in a ResultsCollectionWrapper
        // wrapping a list, so the assertion below is not correct even though
        // it should be.
        // assertTrue(!results.getCollectionType().allowsDuplicates());
        assertTrue(results.getCollectionType().isOrdered());
        comparator = new StructIdComparator();
        resultsArray = results.toArray();
        for (int i = 0; i < resultsArray.length; i++) {
          if (i + 1 != resultsArray.length) {
            // The id of the current element in the result set must be less
            // than the id of the next one to pass.
            assertTrue(
                "The id for " + resultsArray[i] + " should be less than the id for "
                    + resultsArray[i + 1],
                comparator.compare(resultsArray[i], resultsArray[i + 1]) == -1);
          }
        }

        // size query
        queryString = "(SELECT DISTINCT * FROM " + region.getFullPath() + " WHERE id < 101).size";
        try {
          results = region.query(queryString);
        } catch (Exception e) {
          Assert.fail("Failed executing " + queryString, e);
        }
        assertEquals(1, results.size());
        Object result = results.iterator().next();
        assertTrue(result instanceof Integer);
        int resultInt = (Integer) result;
        assertEquals(resultInt, 100);

        // query with leading/trailing spaces
        queryString = " SELECT DISTINCT itr.key FROM " + region.getFullPath()
            + ".entries itr where itr.key = 'key-1' ";
        try {
          results = region.query(queryString);
        } catch (Exception e) {
          Assert.fail("Failed executing " + queryString, e);
        }
        assertEquals(1, results.size());
        assertEquals("key-1", results.asList().get(0));
      }
    });

    // Stop server
    vm0.invoke(new SerializableRunnable("Stop CacheServer") {
      @Override
      public void run() {
        stopBridgeServer(getCache());
      }
    });
  }
Tests remote full region query execution.
geode-core/src/distributedTest/java/org/apache/geode/cache/query/dunit/RemoteQueryDUnitTest.java