content: // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
  //  This source code is licensed under both the GPLv2 (found in the
  //  COPYING file in the root directory) and Apache 2.0 License
  //  (found in the LICENSE.Apache file in the root directory).
  
  package org.rocksdb;
  
  import org.junit.ClassRule;
  import org.junit.Test;
  
  import java.nio.file.Paths;
  import java.util.*;
  
  import static org.assertj.core.api.Assertions.assertThat;
  
  public class DBOptionsTest {
  
    @ClassRule
    public static final RocksMemoryResource rocksMemoryResource =
        new RocksMemoryResource();
  
    public static final Random rand = PlatformRandomHelper.
        getPlatformSpecificRandomFactory();
  
    @Test
    public void getDBOptionsFromProps() {
      // setup sample properties
      final Properties properties = new Properties();
      properties.put("allow_mmap_reads", "true");
      properties.put("bytes_per_sync", "13");
      try(final DBOptions opt = DBOptions.getDBOptionsFromProps(properties)) {
        assertThat(opt).isNotNull();
        assertThat(String.valueOf(opt.allowMmapReads())).
            isEqualTo(properties.get("allow_mmap_reads"));
        assertThat(String.valueOf(opt.bytesPerSync())).
            isEqualTo(properties.get("bytes_per_sync"));
      }
    }
  
    @Test
    public void failDBOptionsFromPropsWithIllegalValue() {
      // setup sample properties
      final Properties properties = new Properties();
      properties.put("tomato", "1024");
      properties.put("burger", "2");
      try(final DBOptions opt = DBOptions.getDBOptionsFromProps(properties)) {
        assertThat(opt).isNull();
      }
    }
  
    @Test(expected = IllegalArgumentException.class)
    public void failDBOptionsFromPropsWithNullValue() {
      try(final DBOptions opt = DBOptions.getDBOptionsFromProps(null)) {
        //no-op
      }
    }
  
    @Test(expected = IllegalArgumentException.class)
    public void failDBOptionsFromPropsWithEmptyProps() {
      try(final DBOptions opt = DBOptions.getDBOptionsFromProps(
          new Properties())) {
        //no-op
      }
    }
  
    @Test
    public void linkageOfPrepMethods() {
      try (final DBOptions opt = new DBOptions()) {
        opt.optimizeForSmallDb();
      }
    }
  
    @Test
    public void env() {
      try (final DBOptions opt = new DBOptions();
           final Env env = Env.getDefault()) {
        opt.setEnv(env);
        assertThat(opt.getEnv()).isSameAs(env);
      }
    }
  
    @Test
    public void setIncreaseParallelism() {
      try(final DBOptions opt = new DBOptions()) {
        final int threads = Runtime.getRuntime().availableProcessors() * 2;
        opt.setIncreaseParallelism(threads);
      }
    }
  
    @Test
    public void createIfMissing() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setCreateIfMissing(boolValue);
        assertThat(opt.createIfMissing()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void createMissingColumnFamilies() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setCreateMissingColumnFamilies(boolValue);
        assertThat(opt.createMissingColumnFamilies()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void errorIfExists() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setErrorIfExists(boolValue);
        assertThat(opt.errorIfExists()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void paranoidChecks() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setParanoidChecks(boolValue);
        assertThat(opt.paranoidChecks()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void maxTotalWalSize() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setMaxTotalWalSize(longValue);
        assertThat(opt.maxTotalWalSize()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void maxOpenFiles() {
      try(final DBOptions opt = new DBOptions()) {
        final int intValue = rand.nextInt();
        opt.setMaxOpenFiles(intValue);
        assertThat(opt.maxOpenFiles()).isEqualTo(intValue);
      }
    }
  
    @Test
    public void maxFileOpeningThreads() {
      try(final DBOptions opt = new DBOptions()) {
        final int intValue = rand.nextInt();
        opt.setMaxFileOpeningThreads(intValue);
        assertThat(opt.maxFileOpeningThreads()).isEqualTo(intValue);
      }
    }
  
    @Test
    public void useFsync() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setUseFsync(boolValue);
        assertThat(opt.useFsync()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void dbPaths() {
      final List<DbPath> dbPaths = new ArrayList<>();
      dbPaths.add(new DbPath(Paths.get("/a"), 10));
      dbPaths.add(new DbPath(Paths.get("/b"), 100));
      dbPaths.add(new DbPath(Paths.get("/c"), 1000));
  
      try(final DBOptions opt = new DBOptions()) {
        assertThat(opt.dbPaths()).isEqualTo(Collections.emptyList());
  
        opt.setDbPaths(dbPaths);
  
        assertThat(opt.dbPaths()).isEqualTo(dbPaths);
      }
    }
  
    @Test
    public void dbLogDir() {
      try(final DBOptions opt = new DBOptions()) {
        final String str = "path/to/DbLogDir";
        opt.setDbLogDir(str);
        assertThat(opt.dbLogDir()).isEqualTo(str);
      }
    }
  
    @Test
    public void walDir() {
      try(final DBOptions opt = new DBOptions()) {
        final String str = "path/to/WalDir";
        opt.setWalDir(str);
        assertThat(opt.walDir()).isEqualTo(str);
      }
    }
  
    @Test
    public void deleteObsoleteFilesPeriodMicros() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setDeleteObsoleteFilesPeriodMicros(longValue);
        assertThat(opt.deleteObsoleteFilesPeriodMicros()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void baseBackgroundCompactions() {
      try (final DBOptions opt = new DBOptions()) {
        final int intValue = rand.nextInt();
        opt.setBaseBackgroundCompactions(intValue);
        assertThat(opt.baseBackgroundCompactions()).
            isEqualTo(intValue);
      }
    }
  
    @Test
    public void maxBackgroundCompactions() {
      try(final DBOptions opt = new DBOptions()) {
        final int intValue = rand.nextInt();
        opt.setMaxBackgroundCompactions(intValue);
        assertThat(opt.maxBackgroundCompactions()).isEqualTo(intValue);
      }
    }
  
    @Test
    public void maxSubcompactions() {
      try (final DBOptions opt = new DBOptions()) {
        final int intValue = rand.nextInt();
        opt.setMaxSubcompactions(intValue);
        assertThat(opt.maxSubcompactions()).
            isEqualTo(intValue);
      }
    }
  
    @Test
    public void maxBackgroundFlushes() {
      try(final DBOptions opt = new DBOptions()) {
        final int intValue = rand.nextInt();
        opt.setMaxBackgroundFlushes(intValue);
        assertThat(opt.maxBackgroundFlushes()).isEqualTo(intValue);
      }
    }
  
    @Test
    public void maxLogFileSize() throws RocksDBException {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setMaxLogFileSize(longValue);
        assertThat(opt.maxLogFileSize()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void logFileTimeToRoll() throws RocksDBException {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setLogFileTimeToRoll(longValue);
        assertThat(opt.logFileTimeToRoll()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void keepLogFileNum() throws RocksDBException {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setKeepLogFileNum(longValue);
        assertThat(opt.keepLogFileNum()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void recycleLogFileNum() throws RocksDBException {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setRecycleLogFileNum(longValue);
        assertThat(opt.recycleLogFileNum()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void maxManifestFileSize() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setMaxManifestFileSize(longValue);
        assertThat(opt.maxManifestFileSize()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void tableCacheNumshardbits() {
      try(final DBOptions opt = new DBOptions()) {
        final int intValue = rand.nextInt();
        opt.setTableCacheNumshardbits(intValue);
        assertThat(opt.tableCacheNumshardbits()).isEqualTo(intValue);
      }
    }
  
    @Test
    public void walSizeLimitMB() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setWalSizeLimitMB(longValue);
        assertThat(opt.walSizeLimitMB()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void walTtlSeconds() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setWalTtlSeconds(longValue);
        assertThat(opt.walTtlSeconds()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void manifestPreallocationSize() throws RocksDBException {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setManifestPreallocationSize(longValue);
        assertThat(opt.manifestPreallocationSize()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void useDirectReads() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setUseDirectReads(boolValue);
        assertThat(opt.useDirectReads()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void useDirectIoForFlushAndCompaction() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setUseDirectIoForFlushAndCompaction(boolValue);
        assertThat(opt.useDirectIoForFlushAndCompaction()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void allowFAllocate() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setAllowFAllocate(boolValue);
        assertThat(opt.allowFAllocate()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void allowMmapReads() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setAllowMmapReads(boolValue);
        assertThat(opt.allowMmapReads()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void allowMmapWrites() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setAllowMmapWrites(boolValue);
        assertThat(opt.allowMmapWrites()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void isFdCloseOnExec() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setIsFdCloseOnExec(boolValue);
        assertThat(opt.isFdCloseOnExec()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void statsDumpPeriodSec() {
      try(final DBOptions opt = new DBOptions()) {
        final int intValue = rand.nextInt();
        opt.setStatsDumpPeriodSec(intValue);
        assertThat(opt.statsDumpPeriodSec()).isEqualTo(intValue);
      }
    }
  
    @Test
    public void adviseRandomOnOpen() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setAdviseRandomOnOpen(boolValue);
        assertThat(opt.adviseRandomOnOpen()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void dbWriteBufferSize() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setDbWriteBufferSize(longValue);
        assertThat(opt.dbWriteBufferSize()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void accessHintOnCompactionStart() {
      try(final DBOptions opt = new DBOptions()) {
        final AccessHint accessHint = AccessHint.SEQUENTIAL;
        opt.setAccessHintOnCompactionStart(accessHint);
        assertThat(opt.accessHintOnCompactionStart()).isEqualTo(accessHint);
      }
    }
  
    @Test
    public void newTableReaderForCompactionInputs() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setNewTableReaderForCompactionInputs(boolValue);
        assertThat(opt.newTableReaderForCompactionInputs()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void compactionReadaheadSize() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setCompactionReadaheadSize(longValue);
        assertThat(opt.compactionReadaheadSize()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void randomAccessMaxBufferSize() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setRandomAccessMaxBufferSize(longValue);
        assertThat(opt.randomAccessMaxBufferSize()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void writableFileMaxBufferSize() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setWritableFileMaxBufferSize(longValue);
        assertThat(opt.writableFileMaxBufferSize()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void useAdaptiveMutex() {
      try(final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setUseAdaptiveMutex(boolValue);
        assertThat(opt.useAdaptiveMutex()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void bytesPerSync() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setBytesPerSync(longValue);
        assertThat(opt.bytesPerSync()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void walBytesPerSync() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setWalBytesPerSync(longValue);
        assertThat(opt.walBytesPerSync()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void enableThreadTracking() {
      try (final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setEnableThreadTracking(boolValue);
        assertThat(opt.enableThreadTracking()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void delayedWriteRate() {
      try(final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setDelayedWriteRate(longValue);
        assertThat(opt.delayedWriteRate()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void allowConcurrentMemtableWrite() {
      try (final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setAllowConcurrentMemtableWrite(boolValue);
        assertThat(opt.allowConcurrentMemtableWrite()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void enableWriteThreadAdaptiveYield() {
      try (final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setEnableWriteThreadAdaptiveYield(boolValue);
        assertThat(opt.enableWriteThreadAdaptiveYield()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void writeThreadMaxYieldUsec() {
      try (final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setWriteThreadMaxYieldUsec(longValue);
        assertThat(opt.writeThreadMaxYieldUsec()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void writeThreadSlowYieldUsec() {
      try (final DBOptions opt = new DBOptions()) {
        final long longValue = rand.nextLong();
        opt.setWriteThreadSlowYieldUsec(longValue);
        assertThat(opt.writeThreadSlowYieldUsec()).isEqualTo(longValue);
      }
    }
  
    @Test
    public void skipStatsUpdateOnDbOpen() {
      try (final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setSkipStatsUpdateOnDbOpen(boolValue);
        assertThat(opt.skipStatsUpdateOnDbOpen()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void walRecoveryMode() {
      try (final DBOptions opt = new DBOptions()) {
        for (final WALRecoveryMode walRecoveryMode : WALRecoveryMode.values()) {
          opt.setWalRecoveryMode(walRecoveryMode);
          assertThat(opt.walRecoveryMode()).isEqualTo(walRecoveryMode);
        }
      }
    }
  
    @Test
    public void allow2pc() {
      try (final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setAllow2pc(boolValue);
        assertThat(opt.allow2pc()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void rowCache() {
      try (final DBOptions opt = new DBOptions()) {
        assertThat(opt.rowCache()).isNull();
  
        try(final Cache lruCache = new LRUCache(1000)) {
          opt.setRowCache(lruCache);
          assertThat(opt.rowCache()).isEqualTo(lruCache);
        }
  
        try(final Cache clockCache = new ClockCache(1000)) {
          opt.setRowCache(clockCache);
          assertThat(opt.rowCache()).isEqualTo(clockCache);
        }
      }
    }
  
    @Test
    public void failIfOptionsFileError() {
      try (final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setFailIfOptionsFileError(boolValue);
        assertThat(opt.failIfOptionsFileError()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void dumpMallocStats() {
      try (final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setDumpMallocStats(boolValue);
        assertThat(opt.dumpMallocStats()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void avoidFlushDuringRecovery() {
      try (final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setAvoidFlushDuringRecovery(boolValue);
        assertThat(opt.avoidFlushDuringRecovery()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void avoidFlushDuringShutdown() {
      try (final DBOptions opt = new DBOptions()) {
        final boolean boolValue = rand.nextBoolean();
        opt.setAvoidFlushDuringShutdown(boolValue);
        assertThat(opt.avoidFlushDuringShutdown()).isEqualTo(boolValue);
      }
    }
  
    @Test
    public void rateLimiter() {
      try(final DBOptions options = new DBOptions();
          final DBOptions anotherOptions = new DBOptions();
          final RateLimiter rateLimiter = new RateLimiter(1000, 100 * 1000, 1)) {
        options.setRateLimiter(rateLimiter);
        // Test with parameter initialization
        anotherOptions.setRateLimiter(
            new RateLimiter(1000));
      }
    }
  
    @Test
    public void statistics() {
      try(final DBOptions options = new DBOptions()) {
        final Statistics statistics = options.statistics();
        assertThat(statistics).isNull();
      }
  
      try(final Statistics statistics = new Statistics();
          final DBOptions options = new DBOptions().setStatistics(statistics);
          final Statistics stats = options.statistics()) {
        assertThat(stats).isNotNull();
      }
    }
  }
  