/**
   * Check how prefetch override works.
   *
   * @throws Exception IF failed.
   */
  public void testOpenPrefetchOverride() throws Exception {
    create(igfsSecondary, paths(DIR, SUBDIR), paths(FILE));

    // Write enough data to the secondary file system.
    final int blockSize = IGFS_BLOCK_SIZE;

    IgfsOutputStream out = igfsSecondary.append(FILE, false);

    int totalWritten = 0;

    while (totalWritten < blockSize * 2 + chunk.length) {
      out.write(chunk);

      totalWritten += chunk.length;
    }

    out.close();

    awaitFileClose(igfsSecondary.asSecondary(), FILE);

    // Instantiate file system with overridden "seq reads before prefetch" property.
    Configuration cfg = new Configuration();

    cfg.addResource(U.resolveIgniteUrl(PRIMARY_CFG));

    int seqReads = SEQ_READS_BEFORE_PREFETCH + 1;

    cfg.setInt(String.format(PARAM_IGFS_SEQ_READS_BEFORE_PREFETCH, "igfs:grid@"), seqReads);

    FileSystem fs = FileSystem.get(new URI(PRIMARY_URI), cfg);

    // Read the first two blocks.
    Path fsHome = new Path(PRIMARY_URI);
    Path dir = new Path(fsHome, DIR.name());
    Path subdir = new Path(dir, SUBDIR.name());
    Path file = new Path(subdir, FILE.name());

    FSDataInputStream fsIn = fs.open(file);

    final byte[] readBuf = new byte[blockSize * 2];

    fsIn.readFully(0, readBuf, 0, readBuf.length);

    // Wait for a while for prefetch to finish (if any).
    IgfsMetaManager meta = igfs.context().meta();

    IgfsFileInfo info = meta.info(meta.fileId(FILE));

    IgfsBlockKey key = new IgfsBlockKey(info.id(), info.affinityKey(), info.evictExclude(), 2);

    IgniteCache<IgfsBlockKey, byte[]> dataCache =
        igfs.context().kernalContext().cache().jcache(igfs.configuration().getDataCacheName());

    for (int i = 0; i < 10; i++) {
      if (dataCache.containsKey(key)) break;
      else U.sleep(100);
    }

    fsIn.close();

    // Remove the file from the secondary file system.
    igfsSecondary.delete(FILE, false);

    // Try reading the third block. Should fail.
    GridTestUtils.assertThrows(
        log,
        new Callable<Object>() {
          @Override
          public Object call() throws Exception {
            IgfsInputStream in0 = igfs.open(FILE);

            in0.seek(blockSize * 2);

            try {
              in0.read(readBuf);
            } finally {
              U.closeQuiet(in0);
            }

            return null;
          }
        },
        IOException.class,
        "Failed to read data due to secondary file system exception: /dir/subdir/file");
  }
 /**
  * @param cache Cache.
  * @param key Key.
  * @return {@code True} if cache contains given key.
  * @throws Exception If failed.
  */
 @SuppressWarnings("unchecked")
 protected boolean containsKey(IgniteCache cache, Object key) throws Exception {
   return offheapTiered(cache)
       ? cache.localPeek(key, CachePeekMode.OFFHEAP) != null
       : cache.containsKey(key);
 }
  /** @throws Exception If error occur. */
  public void testBasicOps() throws Exception {
    CountDownLatch latch = new CountDownLatch(3);

    CacheEventListener lsnr = new CacheEventListener(latch);

    try {
      IgniteCache<String, String> cache1 = ignite1.cache(null);
      IgniteCache<String, String> cache2 = ignite2.cache(null);
      IgniteCache<String, String> cache3 = ignite3.cache(null);

      ignite1.events().localListen(lsnr, EVT_CACHE_OBJECT_PUT, EVT_CACHE_OBJECT_REMOVED);
      ignite2.events().localListen(lsnr, EVT_CACHE_OBJECT_PUT, EVT_CACHE_OBJECT_REMOVED);
      ignite3.events().localListen(lsnr, EVT_CACHE_OBJECT_PUT, EVT_CACHE_OBJECT_REMOVED);

      assert !cache1.containsKey("1");
      assert !cache2.containsKey("1");
      assert !cache3.containsKey("1");

      info("First put");

      cache1.put("1", "a");

      info("Start latch wait 1");

      assert latch.await(5, SECONDS);

      info("Stop latch wait 1");

      assert cache1.containsKey("1");
      assert cache2.containsKey("1");
      assert cache3.containsKey("1");

      latch = new CountDownLatch(6);

      lsnr.setLatch(latch);

      cache2.put("1", "b");
      cache3.put("1", "c");

      info("Start latch wait 2");

      assert latch.await(5, SECONDS);

      info("Stop latch wait 2");

      assert cache1.containsKey("1");
      assert cache2.containsKey("1");
      assert cache3.containsKey("1");

      latch = new CountDownLatch(3);

      lsnr.setLatch(latch);

      cache1.remove("1");

      info("Start latch wait 3");

      assert latch.await(5, SECONDS);

      info("Stop latch wait 3");

      assert !cache1.containsKey("1");
      assert !cache2.containsKey("1");
      assert !cache3.containsKey("1");
    } finally {
      ignite1.events().stopLocalListen(lsnr);
      ignite2.events().stopLocalListen(lsnr);
      ignite3.events().stopLocalListen(lsnr);
    }
  }