1 // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 package org.rocksdb;
7 
8 import org.junit.ClassRule;
9 import org.junit.Rule;
10 import org.junit.Test;
11 import org.junit.rules.TemporaryFolder;
12 
13 import java.util.*;
14 
15 import static org.assertj.core.api.Assertions.assertThat;
16 
17 public class OptionsUtilTest {
18   @ClassRule
19   public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE = new RocksNativeLibraryResource();
20 
21   @Rule public TemporaryFolder dbFolder = new TemporaryFolder();
22 
23   enum TestAPI { LOAD_LATEST_OPTIONS, LOAD_OPTIONS_FROM_FILE }
24 
25   @Test
loadLatestOptions()26   public void loadLatestOptions() throws RocksDBException {
27     verifyOptions(TestAPI.LOAD_LATEST_OPTIONS);
28   }
29 
30   @Test
loadOptionsFromFile()31   public void loadOptionsFromFile() throws RocksDBException {
32     verifyOptions(TestAPI.LOAD_OPTIONS_FROM_FILE);
33   }
34 
35   @Test
getLatestOptionsFileName()36   public void getLatestOptionsFileName() throws RocksDBException {
37     final String dbPath = dbFolder.getRoot().getAbsolutePath();
38     try (final Options options = new Options().setCreateIfMissing(true);
39          final RocksDB db = RocksDB.open(options, dbPath)) {
40       assertThat(db).isNotNull();
41     }
42 
43     String fName = OptionsUtil.getLatestOptionsFileName(dbPath, Env.getDefault());
44     assertThat(fName).isNotNull();
45     assert(fName.startsWith("OPTIONS-") == true);
46     // System.out.println("latest options fileName: " + fName);
47   }
48 
verifyOptions(TestAPI apiType)49   private void verifyOptions(TestAPI apiType) throws RocksDBException {
50     final String dbPath = dbFolder.getRoot().getAbsolutePath();
51     final Options options = new Options()
52                                 .setCreateIfMissing(true)
53                                 .setParanoidChecks(false)
54                                 .setMaxOpenFiles(478)
55                                 .setDelayedWriteRate(1234567L);
56     final ColumnFamilyOptions baseDefaultCFOpts = new ColumnFamilyOptions();
57     final byte[] secondCFName = "new_cf".getBytes();
58     final ColumnFamilyOptions baseSecondCFOpts =
59         new ColumnFamilyOptions()
60             .setWriteBufferSize(70 * 1024)
61             .setMaxWriteBufferNumber(7)
62             .setMaxBytesForLevelBase(53 * 1024 * 1024)
63             .setLevel0FileNumCompactionTrigger(3)
64             .setLevel0SlowdownWritesTrigger(51)
65             .setBottommostCompressionType(CompressionType.ZSTD_COMPRESSION);
66 
67     // Create a database with a new column family
68     try (final RocksDB db = RocksDB.open(options, dbPath)) {
69       assertThat(db).isNotNull();
70 
71       // create column family
72       try (final ColumnFamilyHandle columnFamilyHandle =
73                db.createColumnFamily(new ColumnFamilyDescriptor(secondCFName, baseSecondCFOpts))) {
74         assert(columnFamilyHandle != null);
75       }
76     }
77 
78     // Read the options back and verify
79     DBOptions dbOptions = new DBOptions();
80     final List<ColumnFamilyDescriptor> cfDescs = new ArrayList<>();
81     String path = dbPath;
82     if (apiType == TestAPI.LOAD_LATEST_OPTIONS) {
83       OptionsUtil.loadLatestOptions(path, Env.getDefault(), dbOptions, cfDescs, false);
84     } else if (apiType == TestAPI.LOAD_OPTIONS_FROM_FILE) {
85       path = dbPath + "/" + OptionsUtil.getLatestOptionsFileName(dbPath, Env.getDefault());
86       OptionsUtil.loadOptionsFromFile(path, Env.getDefault(), dbOptions, cfDescs, false);
87     }
88 
89     assertThat(dbOptions.createIfMissing()).isEqualTo(options.createIfMissing());
90     assertThat(dbOptions.paranoidChecks()).isEqualTo(options.paranoidChecks());
91     assertThat(dbOptions.maxOpenFiles()).isEqualTo(options.maxOpenFiles());
92     assertThat(dbOptions.delayedWriteRate()).isEqualTo(options.delayedWriteRate());
93 
94     assertThat(cfDescs.size()).isEqualTo(2);
95     assertThat(cfDescs.get(0)).isNotNull();
96     assertThat(cfDescs.get(1)).isNotNull();
97     assertThat(cfDescs.get(0).getName()).isEqualTo(RocksDB.DEFAULT_COLUMN_FAMILY);
98     assertThat(cfDescs.get(1).getName()).isEqualTo(secondCFName);
99 
100     ColumnFamilyOptions defaultCFOpts = cfDescs.get(0).getOptions();
101     assertThat(defaultCFOpts.writeBufferSize()).isEqualTo(baseDefaultCFOpts.writeBufferSize());
102     assertThat(defaultCFOpts.maxWriteBufferNumber())
103         .isEqualTo(baseDefaultCFOpts.maxWriteBufferNumber());
104     assertThat(defaultCFOpts.maxBytesForLevelBase())
105         .isEqualTo(baseDefaultCFOpts.maxBytesForLevelBase());
106     assertThat(defaultCFOpts.level0FileNumCompactionTrigger())
107         .isEqualTo(baseDefaultCFOpts.level0FileNumCompactionTrigger());
108     assertThat(defaultCFOpts.level0SlowdownWritesTrigger())
109         .isEqualTo(baseDefaultCFOpts.level0SlowdownWritesTrigger());
110     assertThat(defaultCFOpts.bottommostCompressionType())
111         .isEqualTo(baseDefaultCFOpts.bottommostCompressionType());
112 
113     ColumnFamilyOptions secondCFOpts = cfDescs.get(1).getOptions();
114     assertThat(secondCFOpts.writeBufferSize()).isEqualTo(baseSecondCFOpts.writeBufferSize());
115     assertThat(secondCFOpts.maxWriteBufferNumber())
116         .isEqualTo(baseSecondCFOpts.maxWriteBufferNumber());
117     assertThat(secondCFOpts.maxBytesForLevelBase())
118         .isEqualTo(baseSecondCFOpts.maxBytesForLevelBase());
119     assertThat(secondCFOpts.level0FileNumCompactionTrigger())
120         .isEqualTo(baseSecondCFOpts.level0FileNumCompactionTrigger());
121     assertThat(secondCFOpts.level0SlowdownWritesTrigger())
122         .isEqualTo(baseSecondCFOpts.level0SlowdownWritesTrigger());
123     assertThat(secondCFOpts.bottommostCompressionType())
124         .isEqualTo(baseSecondCFOpts.bottommostCompressionType());
125   }
126 }
127