@Test
  public void testContinueOnSomeDbDirectoriesMissing() throws Exception {
    File targetDir1 = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());
    File targetDir2 = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());

    try {
      assertTrue(targetDir1.mkdirs());
      assertTrue(targetDir2.mkdirs());

      if (!targetDir1.setWritable(false, false)) {
        System.err.println(
            "Cannot execute 'testContinueOnSomeDbDirectoriesMissing' because cannot mark directory non-writable");
        return;
      }

      RocksDBStateBackend rocksDbBackend = new RocksDBStateBackend(TEMP_URI);
      rocksDbBackend.setDbStoragePaths(targetDir1.getAbsolutePath(), targetDir2.getAbsolutePath());

      try {
        rocksDbBackend.initializeForJob(getMockEnvironment(), "foobar", IntSerializer.INSTANCE);
      } catch (Exception e) {
        e.printStackTrace();
        fail("Backend initialization failed even though some paths were available");
      }
    } finally {
      //noinspection ResultOfMethodCallIgnored
      targetDir1.setWritable(true, false);
      FileUtils.deleteDirectory(targetDir1);
      FileUtils.deleteDirectory(targetDir2);
    }
  }
  @Test
  public void testFailWhenNoLocalStorageDir() throws Exception {
    File targetDir = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());
    try {
      assertTrue(targetDir.mkdirs());

      if (!targetDir.setWritable(false, false)) {
        System.err.println(
            "Cannot execute 'testFailWhenNoLocalStorageDir' because cannot mark directory non-writable");
        return;
      }

      RocksDBStateBackend rocksDbBackend = new RocksDBStateBackend(TEMP_URI);
      rocksDbBackend.setDbStoragePath(targetDir.getAbsolutePath());

      try {
        rocksDbBackend.initializeForJob(getMockEnvironment(), "foobar", IntSerializer.INSTANCE);
      } catch (Exception e) {
        assertTrue(e.getMessage().contains("No local storage directories available"));
        assertTrue(e.getMessage().contains(targetDir.getAbsolutePath()));
      }
    } finally {
      //noinspection ResultOfMethodCallIgnored
      targetDir.setWritable(true, false);
      FileUtils.deleteDirectory(targetDir);
    }
  }
  @Test
  public void testCallsForwardedToNonPartitionedBackend() throws Exception {
    AbstractStateBackend nonPartBackend = mock(AbstractStateBackend.class);
    RocksDBStateBackend rocksDbBackend = new RocksDBStateBackend(TEMP_URI, nonPartBackend);

    rocksDbBackend.initializeForJob(getMockEnvironment(), "foo", IntSerializer.INSTANCE);
    verify(nonPartBackend, times(1))
        .initializeForJob(any(Environment.class), anyString(), any(TypeSerializer.class));

    rocksDbBackend.disposeAllStateForCurrentJob();
    verify(nonPartBackend, times(1)).disposeAllStateForCurrentJob();

    rocksDbBackend.close();
    verify(nonPartBackend, times(1)).close();
  }
  @Test
  public void testOptionsFactory() throws Exception {
    RocksDBStateBackend rocksDbBackend = new RocksDBStateBackend(TEMP_URI);

    rocksDbBackend.setOptions(
        new OptionsFactory() {
          @Override
          public Options createOptions(Options currentOptions) {
            return currentOptions.setCompactionStyle(CompactionStyle.FIFO);
          }
        });

    assertNotNull(rocksDbBackend.getOptions());
    assertEquals(CompactionStyle.FIFO, rocksDbBackend.getRocksDBOptions().compactionStyle());
  }
  @Test
  public void testPredefinedOptions() throws Exception {
    RocksDBStateBackend rocksDbBackend = new RocksDBStateBackend(TEMP_URI);

    assertEquals(PredefinedOptions.DEFAULT, rocksDbBackend.getPredefinedOptions());

    rocksDbBackend.setPredefinedOptions(PredefinedOptions.SPINNING_DISK_OPTIMIZED);
    assertEquals(PredefinedOptions.SPINNING_DISK_OPTIMIZED, rocksDbBackend.getPredefinedOptions());

    Options opt1 = rocksDbBackend.getRocksDBOptions();
    Options opt2 = rocksDbBackend.getRocksDBOptions();

    assertEquals(opt1, opt2);

    assertEquals(CompactionStyle.LEVEL, opt1.compactionStyle());
  }
  @Test
  public void testSetDbPath() throws Exception {
    RocksDBStateBackend rocksDbBackend = new RocksDBStateBackend(TEMP_URI);

    assertNull(rocksDbBackend.getDbStoragePaths());

    rocksDbBackend.setDbStoragePath("/abc/def");
    assertArrayEquals(new String[] {"/abc/def"}, rocksDbBackend.getDbStoragePaths());

    rocksDbBackend.setDbStoragePath(null);
    assertNull(rocksDbBackend.getDbStoragePaths());

    rocksDbBackend.setDbStoragePaths("/abc/def", "/uvw/xyz");
    assertArrayEquals(new String[] {"/abc/def", "/uvw/xyz"}, rocksDbBackend.getDbStoragePaths());

    //noinspection NullArgumentToVariableArgMethod
    rocksDbBackend.setDbStoragePaths(null);
    assertNull(rocksDbBackend.getDbStoragePaths());
  }
  @Test
  public void testUseTempDirectories() throws Exception {
    File dir1 = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());
    File dir2 = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());

    File[] tempDirs = new File[] {dir1, dir2};

    try {
      assertTrue(dir1.mkdirs());
      assertTrue(dir2.mkdirs());

      RocksDBStateBackend rocksDbBackend = new RocksDBStateBackend(TEMP_URI);
      assertNull(rocksDbBackend.getDbStoragePaths());

      rocksDbBackend.initializeForJob(
          getMockEnvironment(tempDirs), "foobar", IntSerializer.INSTANCE);
      assertArrayEquals(tempDirs, rocksDbBackend.getStoragePaths());
    } finally {
      FileUtils.deleteDirectory(dir1);
      FileUtils.deleteDirectory(dir2);
    }
  }
  @Test
  public void testPredefinedAndOptionsFactory() throws Exception {
    RocksDBStateBackend rocksDbBackend = new RocksDBStateBackend(TEMP_URI);

    assertEquals(PredefinedOptions.DEFAULT, rocksDbBackend.getPredefinedOptions());

    rocksDbBackend.setPredefinedOptions(PredefinedOptions.SPINNING_DISK_OPTIMIZED);
    rocksDbBackend.setOptions(
        new OptionsFactory() {
          @Override
          public Options createOptions(Options currentOptions) {
            return currentOptions.setCompactionStyle(CompactionStyle.UNIVERSAL);
          }
        });

    assertEquals(PredefinedOptions.SPINNING_DISK_OPTIMIZED, rocksDbBackend.getPredefinedOptions());
    assertNotNull(rocksDbBackend.getOptions());
    assertEquals(CompactionStyle.UNIVERSAL, rocksDbBackend.getRocksDBOptions().compactionStyle());
  }
 @Test(expected = IllegalArgumentException.class)
 public void testNonFileSchemePath() throws Exception {
   RocksDBStateBackend rocksDbBackend = new RocksDBStateBackend(TEMP_URI);
   rocksDbBackend.setDbStoragePath("hdfs:///some/path/to/perdition");
 }
 @Test(expected = IllegalArgumentException.class)
 public void testSetNullPaths() throws Exception {
   RocksDBStateBackend rocksDbBackend = new RocksDBStateBackend(TEMP_URI);
   rocksDbBackend.setDbStoragePaths();
 }