/**
   * Tests that an iterator can correctly iterate over a store.
   *
   * <p>There is no assumption about the order of iteration, it just makes sure all key-value pairs
   * are iterated.
   */
  @Test
  public void noOrderIteratorTest() throws Exception {
    List<TachyonURI> storeUris = Lists.newArrayList();
    List<List<KeyValuePair>> keyValuePairs = Lists.newArrayList();

    List<KeyValuePair> pairs = Lists.newArrayList();
    storeUris.add(createStoreOfSize(0, pairs));
    keyValuePairs.add(pairs);

    pairs = Lists.newArrayList();
    storeUris.add(createStoreOfSize(2, pairs));
    keyValuePairs.add(pairs);

    pairs = Lists.newArrayList();
    storeUris.add(createStoreOfMultiplePartitions(3, pairs));
    keyValuePairs.add(pairs);

    int numStoreUri = storeUris.size();
    for (int i = 0; i < numStoreUri; i++) {
      List<KeyValuePair> expectedPairs = keyValuePairs.get(i);
      List<KeyValuePair> iteratedPairs = Lists.newArrayList();
      mReader = sKeyValueSystem.openStore(storeUris.get(i));
      KeyValueIterator iterator = mReader.iterator();
      while (iterator.hasNext()) {
        iteratedPairs.add(iterator.next());
      }

      // If size is not the same, no need for the time-consuming list comparison below.
      Assert.assertEquals(expectedPairs.size(), iteratedPairs.size());
      // Sorts and then compares pairs and iteratedPairs.
      Collections.sort(expectedPairs);
      Collections.sort(iteratedPairs);
      Assert.assertEquals(expectedPairs, iteratedPairs);
    }
  }
  private void testMergeStore(
      TachyonURI store1,
      List<KeyValuePair> keyValuePairs1,
      TachyonURI store2,
      List<KeyValuePair> keyValuePairs2)
      throws Exception {
    sKeyValueSystem.mergeStore(store1, store2);

    // store2 contains all key-value pairs in both store1 and store2.
    List<KeyValuePair> mergedPairs = Lists.newArrayList();
    mergedPairs.addAll(keyValuePairs1);
    mergedPairs.addAll(keyValuePairs2);

    List<KeyValuePair> store2Pairs = Lists.newArrayList();
    KeyValueIterator iterator = sKeyValueSystem.openStore(store2).iterator();
    while (iterator.hasNext()) {
      store2Pairs.add(iterator.next());
    }

    // If size is not the same, no need for the time-consuming list comparison below.
    Assert.assertEquals(mergedPairs.size(), store2Pairs.size());
    Collections.sort(mergedPairs);
    Collections.sort(store2Pairs);
    Assert.assertEquals(mergedPairs, store2Pairs);

    // store1 no longer exists, because it has been merged into store2.
    // TachyonException is expected to be thrown.
    try {
      sKeyValueSystem.openStore(store1);
    } catch (TachyonException e) {
      Assert.assertEquals(e.getMessage(), ExceptionMessage.PATH_DOES_NOT_EXIST.getMessage(store1));
      return;
    }
    Assert.assertTrue("The URI to the deleted key-value store still exists", false);
  }
  /** Tests that an iterator for an empty store has no next elements. */
  @Test
  public void emptyStoreIteratorTest() throws Exception {
    mWriter = sKeyValueSystem.createStore(mStoreUri);
    mWriter.close();

    mReader = sKeyValueSystem.openStore(mStoreUri);
    KeyValueIterator iterator = mReader.iterator();
    Assert.assertFalse(iterator.hasNext());
  }