Пример #1
0
        public override void Help(Player p, string message)
        {
            if (message.CaselessEq("variable") || message.CaselessEq("variables"))
            {
                p.Message("%HVariables: &f{0}", EnvOptions.Options.Join(o => o.Name));
                p.Message("%HUse %T/Help env [variable] %Hto see details for that variable");
                return;
            }
            else if (message.CaselessEq("presets"))
            {
                MessagePresets(p); return;
            }

            EnvOption opt = EnvOptions.Find(message);

            if (opt != null)
            {
                p.Message("%T/Env {0} [value]", opt.Name);
                p.Message(opt.Help);
                p.Message("%HUse 'normal' for [value] to reset to default");
            }
            else
            {
                p.Message("%WUnrecognised property \"{0}\"", message);
            }
        }
        public async void HandleEnvRequestAsync_ReturnsExpected()
        {
            var opts = new EnvOptions();

            ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

            configurationBuilder.AddInMemoryCollection(appSettings);
            var config = configurationBuilder.Build();
            var host   = new HostingEnvironment()
            {
                EnvironmentName = "EnvironmentName"
            };
            var ep     = new EnvEndpoint(opts, config, host);
            var middle = new EnvEndpointMiddleware(null, ep);

            var context = CreateRequest("GET", "/env");
            await middle.HandleEnvRequestAsync(context);

            context.Response.Body.Seek(0, SeekOrigin.Begin);
            var reader = new StreamReader(context.Response.Body, Encoding.UTF8);
            var json   = await reader.ReadLineAsync();

            var expected = "{\"activeProfiles\":[\"EnvironmentName\"],\"propertySources\":[{\"properties\":{\"management:endpoints:sensitive\":{\"value\":\"false\"},\"management:endpoints:path\":{\"value\":\"/cloudfoundryapplication\"},\"management:endpoints:enabled\":{\"value\":\"true\"},\"Logging:LogLevel:Steeltoe\":{\"value\":\"Information\"},\"Logging:LogLevel:Pivotal\":{\"value\":\"Information\"},\"Logging:LogLevel:Default\":{\"value\":\"Warning\"},\"Logging:IncludeScopes\":{\"value\":\"false\"}},\"name\":\"MemoryConfigurationProvider\"}]}";

            Assert.Equal(expected, json);
        }
Пример #3
0
 public static bool UpdateEnv(EnvOptions env)
 {
     using (var conn = new MySqlConnection(Global.MySQLConnection))
     {
         var sql    = "update env set `key`=@key,val=@val where id=@id";
         var result = conn.Execute(sql, env);
         return(result > 0);
     }
 }
Пример #4
0
        public void Constructor_InitializesWithDefaults()
        {
            var opts = new EnvOptions();

            Assert.True(opts.Enabled);
            Assert.True(opts.Sensitive);
            Assert.Equal("env", opts.Id);
            Assert.Equal(Permissions.RESTRICTED, opts.RequiredPermissions);
        }
Пример #5
0
        public static void UseEnvActuator(IConfiguration configuration, IHostingEnvironment hostingEnvironment = null, ILoggerFactory loggerFactory = null)
        {
            var options = new EnvOptions(configuration);

            hostingEnvironment = hostingEnvironment ?? new DefaultHostingEnvironment("development");
            var ep      = new EnvEndpoint(options, configuration, hostingEnvironment, CreateLogger <EnvEndpoint>(loggerFactory));
            var handler = new EnvHandler(ep, SecurityService, CreateLogger <EnvHandler>(loggerFactory));

            ConfiguredHandlers.Add(handler);
        }
Пример #6
0
 public static bool AddEnv(EnvOptions env)
 {
     using (var conn = new MySqlConnection(Global.MySQLConnection))
     {
         env.id          = Guid.NewGuid().ToString("N");
         env.create_time = DateTime.Now;
         var sql    = "insert into env(id,`key`,val,create_time) values(@id,@key,@val,@create_time)";
         var result = conn.Execute(sql, env);
         return(result > 0);
     }
 }
Пример #7
0
 public IActionResult OperaEnv([FromQuery] EnvOptions env, [FromQuery] bool isSet)
 {
     if (isSet)
     {
         TaskRepository.AddEnv(env);
     }
     else
     {
         TaskRepository.UpdateEnv(env);
     }
     return(Ok(new { status = true, msg = "操作成功" }));
 }
Пример #8
0
        public void Constructor_ThrowsIfNulls()
        {
            IEnvOptions         options       = null;
            IConfiguration      configuration = null;
            IHostingEnvironment env           = null;

            Assert.Throws <ArgumentNullException>(() => new EnvEndpoint(options, configuration, env));

            options = new EnvOptions();
            Assert.Throws <ArgumentNullException>(() => new EnvEndpoint(options, configuration, env));

            configuration = new ConfigurationBuilder().Build();
            Assert.Throws <ArgumentNullException>(() => new EnvEndpoint(options, configuration, env));
        }
Пример #9
0
        public void EnvEndpointMiddleware_PathAndVerbMatching_ReturnsExpected()
        {
            var opts = new EnvOptions();
            ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
            var config = configurationBuilder.Build();
            var host   = new GenericHostingEnvironment()
            {
                EnvironmentName = "EnvironmentName"
            };
            var ep     = new EnvEndpoint(opts, config, host);
            var middle = new EndpointOwinMiddleware <EnvironmentDescriptor>(null, ep);

            Assert.True(middle.RequestVerbAndPathMatch("GET", "/env"));
            Assert.False(middle.RequestVerbAndPathMatch("PUT", "/env"));
            Assert.False(middle.RequestVerbAndPathMatch("GET", "/badpath"));
        }
Пример #10
0
        internal static bool Handle(Player p, Level lvl, string type, string value, EnvConfig cfg, string area)
        {
            if (type.CaselessEq("preset"))
            {
                EnvPreset preset = FindPreset(value);
                if (preset == null)
                {
                    MessagePresets(p); return(false);
                }

                cfg.SkyColor    = preset.Sky;
                cfg.CloudColor  = preset.Clouds;
                cfg.FogColor    = preset.Fog;
                cfg.ShadowColor = preset.Shadow;
                cfg.LightColor  = preset.Sun;
            }
            else if (type.CaselessEq("normal"))
            {
                cfg.ResetEnv();
                p.Message("Reset environment for {0} %Sto normal", area);
            }
            else
            {
                EnvOption opt = EnvOptions.Find(type);
                if (opt == null)
                {
                    return(false);
                }
                opt.SetFunc(p, area, cfg, value);
            }

            if (lvl == null)
            {
                Player[] players = PlayerInfo.Online.Items;
                foreach (Player pl in players)
                {
                    pl.SendCurrentEnv();
                }
                SrvProperties.Save();
            }
            else
            {
                SendEnv(lvl);
                lvl.SaveSettings();
            }
            return(true);
        }
        public void EnvEndpointMiddleware_PathAndVerbMatching_ReturnsExpected()
        {
            var opts = new EnvOptions();
            ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

            configurationBuilder.AddInMemoryCollection(appSettings);
            var config = configurationBuilder.Build();
            var host   = new HostingEnvironment()
            {
                EnvironmentName = "EnvironmentName"
            };
            var ep     = new EnvEndpoint(opts, config, host);
            var middle = new EnvEndpointMiddleware(null, ep);

            Assert.True(middle.RequestVerbAndPathMatch("GET", "/env"));
            Assert.False(middle.RequestVerbAndPathMatch("PUT", "/env"));
            Assert.False(middle.RequestVerbAndPathMatch("GET", "/badpath"));
        }
Пример #12
0
        public void DoInvoke_ReturnsExpected()
        {
            var opts        = new EnvOptions();
            var appsettings = new Dictionary <string, string>()
            {
                ["management:endpoints:enabled"]            = "false",
                ["management:endpoints:sensitive"]          = "false",
                ["management:endpoints:path"]               = "/cloudfoundryapplication",
                ["management:endpoints:loggers:enabled"]    = "false",
                ["management:endpoints:loggers:sensitive"]  = "true",
                ["management:endpoints:heapdump:enabled"]   = "true",
                ["management:endpoints:heapdump:sensitive"] = "true",
                ["management:endpoints:cloudfoundry:validatecertificates"] = "true",
                ["management:endpoints:cloudfoundry:enabled"] = "true"
            };
            ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

            configurationBuilder.AddInMemoryCollection(appsettings);
            var config = configurationBuilder.Build();

            var ep     = new EnvEndpoint(opts, config, new TestHosting());
            var result = ep.DoInvoke(config);

            Assert.NotNull(result);
            Assert.Single(result.ActiveProfiles);
            Assert.Equal("EnvironmentName", result.ActiveProfiles[0]);
            Assert.Single(result.PropertySources);

            var desc = result.PropertySources[0];

            Assert.Equal("MemoryConfigurationProvider", desc.Name);
            var props = desc.Properties;

            Assert.NotNull(props);
            Assert.Equal(9, props.Count);
            Assert.Contains("management:endpoints:loggers:enabled", props.Keys);
            var prop = props["management:endpoints:loggers:enabled"];

            Assert.NotNull(prop);
            Assert.Equal("false", prop.Value);
            Assert.Null(prop.Origin);
        }
Пример #13
0
        public void GetPropertySourceName_ReturnsExpected()
        {
            var opts    = new EnvOptions();
            var builder = new ConfigurationBuilder();

            builder.AddEnvironmentVariables();
            var config = builder.Build();
            var ep     = new EnvEndpoint(opts, config, new TestHosting());

            var    provider = config.Providers.Single();
            string name     = ep.GetPropertySourceName(provider);

            Assert.Equal(provider.GetType().Name, name);

            builder = new ConfigurationBuilder();
            builder.AddJsonFile("c:\\foobar", true);
            config = builder.Build();

            ep = new EnvEndpoint(opts, config, new TestHosting());

            provider = config.Providers.Single();
            name     = ep.GetPropertySourceName(provider);
            Assert.Equal("JsonConfigurationProvider: [foobar]", name);
        }
Пример #14
0
        public void FunctionalTest()
        {
            string temp   = Path.GetTempPath();
            var    testdb = Path.Combine(temp, "functional_test");
            string path   = Environment.ExpandEnvironmentVariables(testdb);

            if (Directory.Exists(testdb))
            {
                Directory.Delete(testdb, true);
            }

            var options = new DbOptions()
                          .SetCreateIfMissing(true)
                          .EnableStatistics();

            // Using standard open
            using (var db = RocksDb.Open(options, path))
            {
                // With strings
                string value = db.Get("key");
                db.Put("key", "value");
                Assert.Equal("value", db.Get("key"));
                Assert.Null(db.Get("non-existent-key"));
                db.Remove("key");
                Assert.Null(db.Get("value"));

                // With bytes
                db.Put(Encoding.UTF8.GetBytes("key"), Encoding.UTF8.GetBytes("value"));
                Assert.True(BinaryComparer.Default.Equals(Encoding.UTF8.GetBytes("value"), db.Get(Encoding.UTF8.GetBytes("key"))));
                // non-existent kiey
                Assert.Null(db.Get(new byte[] { 0, 1, 2 }));
                db.Remove(Encoding.UTF8.GetBytes("key"));
                Assert.Null(db.Get(Encoding.UTF8.GetBytes("key")));

                db.Put(Encoding.UTF8.GetBytes("key"), new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 });

                // With buffers
                var  buffer = new byte[100];
                long length = db.Get(Encoding.UTF8.GetBytes("key"), buffer, 0, buffer.Length);
                Assert.Equal(8, length);
                Assert.Equal(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }, buffer.Take((int)length).ToList());

                // Write batches
                // With strings
                using (WriteBatch batch = new WriteBatch()
                                          .Put("one", "uno")
                                          .Put("two", "deuce")
                                          .Put("two", "dos")
                                          .Put("three", "tres"))
                {
                    db.Write(batch);
                }
                Assert.Equal("uno", db.Get("one"));

                // With save point
                using (WriteBatch batch = new WriteBatch())
                {
                    batch
                    .Put("hearts", "red")
                    .Put("diamonds", "red");
                    batch.SetSavePoint();
                    batch
                    .Put("clubs", "black");
                    batch.SetSavePoint();
                    batch
                    .Put("spades", "black");
                    batch.RollbackToSavePoint();
                    db.Write(batch);
                }
                Assert.Equal("red", db.Get("diamonds"));
                Assert.Equal("black", db.Get("clubs"));
                Assert.Null(db.Get("spades"));

                // With bytes
                var utf8 = Encoding.UTF8;
                using (WriteBatch batch = new WriteBatch()
                                          .Put(utf8.GetBytes("four"), new byte[] { 4, 4, 4 })
                                          .Put(utf8.GetBytes("five"), new byte[] { 5, 5, 5 }))
                {
                    db.Write(batch);
                }
                Assert.True(BinaryComparer.Default.Equals(new byte[] { 4, 4, 4 }, db.Get(utf8.GetBytes("four"))));

                // Snapshots
                using (var snapshot = db.CreateSnapshot())
                {
                    var before = db.Get("one");
                    db.Put("one", "1");

                    var useSnapshot = new ReadOptions()
                                      .SetSnapshot(snapshot);

                    // the database value was written
                    Assert.Equal("1", db.Get("one"));
                    // but the snapshot still sees the old version
                    var after = db.Get("one", readOptions: useSnapshot);
                    Assert.Equal(before, after);
                }

                var two = db.Get("two");
                Assert.Equal("dos", two);

                // Iterators
                using (var iterator = db.NewIterator(
                           readOptions: new ReadOptions()
                           .SetIterateUpperBound("t")
                           ))
                {
                    iterator.Seek("k");
                    Assert.True(iterator.Valid());
                    Assert.Equal("key", iterator.StringKey());
                    iterator.Next();
                    Assert.True(iterator.Valid());
                    Assert.Equal("one", iterator.StringKey());
                    Assert.Equal("1", iterator.StringValue());
                    iterator.Next();
                    Assert.False(iterator.Valid());
                }

                // MultiGet
                var multiGetResult = db.MultiGet(new[] { "two", "three", "nine" });
                Assert.Equal(
                    expected: new[]
                {
                    new KeyValuePair <string, string>("two", "dos"),
                    new KeyValuePair <string, string>("three", "tres"),
                    new KeyValuePair <string, string>("nine", null)
                },
                    actual: multiGetResult
                    );
            }

            // Test with column families
            var optionsCf = new DbOptions()
                            .SetCreateIfMissing(true)
                            .SetCreateMissingColumnFamilies(true);

            var columnFamilies = new ColumnFamilies
            {
                { "reverse", new ColumnFamilyOptions() },
            };

            using (var db = RocksDb.Open(optionsCf, path, columnFamilies))
            {
                var reverse = db.GetColumnFamily("reverse");

                db.Put("one", "uno");
                db.Put("two", "dos");
                db.Put("three", "tres");

                db.Put("uno", "one", cf: reverse);
                db.Put("dos", "two", cf: reverse);
                db.Put("tres", "three", cf: reverse);
            }

            // Test Cf Delete
            using (var db = RocksDb.Open(optionsCf, path, columnFamilies))
            {
                var reverse = db.GetColumnFamily("reverse");

                db.Put("cuatro", "four", cf: reverse);
                db.Put("cinco", "five", cf: reverse);

                Assert.Equal("four", db.Get("cuatro", cf: reverse));
                Assert.Equal("five", db.Get("cinco", cf: reverse));

                byte[] keyBytes = Encoding.UTF8.GetBytes("cuatro");
                db.Remove(keyBytes, reverse);
                db.Remove("cinco", reverse);

                Assert.Null(db.Get("cuatro", cf: reverse));
                Assert.Null(db.Get("cinco", cf: reverse));
            }

            // Test list
            {
                var list = RocksDb.ListColumnFamilies(optionsCf, path);
                Assert.Equal(new[] { "default", "reverse" }, list.ToArray());
            }

            // Test reopen with column families
            using (var db = RocksDb.Open(optionsCf, path, columnFamilies))
            {
                var reverse = db.GetColumnFamily("reverse");

                Assert.Equal("uno", db.Get("one"));
                Assert.Equal("one", db.Get("uno", cf: reverse));
                Assert.Null(db.Get("uno"));
                Assert.Null(db.Get("one", cf: reverse));
            }

            // Test dropping and creating column family
            using (var db = RocksDb.Open(options, path, columnFamilies))
            {
                db.DropColumnFamily("reverse");
                var reverse = db.CreateColumnFamily(new ColumnFamilyOptions(), "reverse");
                Assert.Null(db.Get("uno", cf: reverse));
                db.Put("red", "rouge", cf: reverse);
                Assert.Equal("rouge", db.Get("red", cf: reverse));
            }

            // Test reopen after drop and create
            using (var db = RocksDb.Open(options, path, columnFamilies))
            {
                var reverse = db.GetColumnFamily("reverse");
                Assert.Null(db.Get("uno", cf: reverse));
                Assert.Equal("rouge", db.Get("red", cf: reverse));
            }

            // Test read only
            using (var db = RocksDb.OpenReadOnly(options, path, columnFamilies, false))
            {
                Assert.Equal("uno", db.Get("one"));
            }

            // Test SstFileWriter
            {
                var envOpts  = new EnvOptions();
                var ioOpts   = new ColumnFamilyOptions();
                var sst      = new SstFileWriter(envOpts, ioOpts);
                var filename = Path.Combine(temp, "test.sst");
                if (File.Exists(filename))
                {
                    File.Delete(filename);
                }
                sst.Open(filename);
                sst.Add("four", "quatro");
                sst.Add("one", "uno");
                sst.Add("two", "dos");
                sst.Finish();

                using (var db = RocksDb.Open(options, path, columnFamilies))
                {
                    Assert.NotEqual("four", db.Get("four"));
                    var ingestOptions = new IngestExternalFileOptions()
                                        .SetMoveFiles(true);
                    db.IngestExternalFiles(new string[] { filename }, ingestOptions);
                    Assert.Equal("quatro", db.Get("four"));
                }
            }

            // test comparator
            unsafe {
                var comparator = new IntegerStringComparator();

                var opts = new ColumnFamilyOptions()
                           .SetComparator(comparator);

                var filename = Path.Combine(temp, "test.sst");
                if (File.Exists(filename))
                {
                    File.Delete(filename);
                }
                var sst = new SstFileWriter(ioOptions: opts);
                sst.Open(filename);
                sst.Add("111", "111");
                sst.Add("1001", "1001"); // this order is only allowed using an integer comparator
                sst.Finish();
            }

            // test write batch with index
            {
                var wbwi = new WriteBatchWithIndex(reservedBytes: 1024);
                wbwi.Put("one", "un");
                wbwi.Put("two", "deux");
                var oneValueIn  = Encoding.UTF8.GetBytes("one");
                var oneValueOut = wbwi.Get("one");
                Assert.Equal("un", oneValueOut);
                using (var db = RocksDb.Open(options, path, columnFamilies))
                {
                    var oneCombinedOut   = wbwi.Get(db, "one");
                    var threeCombinedOut = wbwi.Get(db, "three");
                    Assert.Equal("un", oneCombinedOut);
                    Assert.Equal("tres", threeCombinedOut);

                    using (var wbIterator = wbwi.NewIterator(db.NewIterator()))
                    {
                        wbIterator.Seek("o");
                        Assert.True(wbIterator.Valid());
                        var itkey = wbIterator.StringKey();
                        Assert.Equal("one", itkey);
                        var itval = wbIterator.StringValue();
                        Assert.Equal("un", itval);

                        wbIterator.Next();
                        Assert.True(wbIterator.Valid());
                        itkey = wbIterator.StringKey();
                        Assert.Equal("three", itkey);
                        itval = wbIterator.StringValue();
                        Assert.Equal("tres", itval);

                        wbIterator.Next();
                        Assert.True(wbIterator.Valid());
                        itkey = wbIterator.StringKey();
                        Assert.Equal("two", itkey);
                        itval = wbIterator.StringValue();
                        Assert.Equal("deux", itval);

                        wbIterator.Next();
                        Assert.False(wbIterator.Valid());
                    }

                    db.Write(wbwi);

                    var oneDbOut = wbwi.Get("one");
                    Assert.Equal("un", oneDbOut);
                }
            }

            // compact range
            {
                using (var db = RocksDb.Open(options, path, columnFamilies))
                {
                    db.CompactRange("o", "tw");
                }
            }
        }
Пример #15
0
        public void FunctionalTest()
        {
            string temp    = Path.GetTempPath();
            var    testdir = Path.Combine(temp, "functional_test");
            var    testdb  = Path.Combine(testdir, "main");
            var    testcp  = Path.Combine(testdir, "cp");
            var    path    = Environment.ExpandEnvironmentVariables(testdb);
            var    cppath  = Environment.ExpandEnvironmentVariables(testcp);

            if (Directory.Exists(testdir))
            {
                Directory.Delete(testdir, true);
            }
            Directory.CreateDirectory(testdir);

            var options = new DbOptions()
                          .SetCreateIfMissing(true)
                          .EnableStatistics();

            // Using standard open
            using (var db = RocksDb.Open(options, path))
            {
                // With strings
                string value = db.Get("key");
                db.Put("key", "value");
                Assert.Equal("value", db.Get("key"));
                Assert.Null(db.Get("non-existent-key"));
                db.Remove("key");
                Assert.Null(db.Get("value"));

                // With bytes
                db.Put(Encoding.UTF8.GetBytes("key"), Encoding.UTF8.GetBytes("value"));
                Assert.True(BinaryComparer.Default.Equals(Encoding.UTF8.GetBytes("value"), db.Get(Encoding.UTF8.GetBytes("key"))));
                // non-existent kiey
                Assert.Null(db.Get(new byte[] { 0, 1, 2 }));
                db.Remove(Encoding.UTF8.GetBytes("key"));
                Assert.Null(db.Get(Encoding.UTF8.GetBytes("key")));

                db.Put(Encoding.UTF8.GetBytes("key"), new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 });

                // With buffers
                var  buffer = new byte[100];
                long length = db.Get(Encoding.UTF8.GetBytes("key"), buffer, 0, buffer.Length);
                Assert.Equal(8, length);
                Assert.Equal(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }, buffer.Take((int)length).ToList());

                buffer = new byte[5];
                length = db.Get(Encoding.UTF8.GetBytes("key"), buffer, 0, buffer.Length);
                Assert.Equal(8, length);
                Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, buffer.Take((int)Math.Min(buffer.Length, length)));

                length = db.Get(Encoding.UTF8.GetBytes("bogus"), buffer, 0, buffer.Length);
                Assert.Equal(-1, length);

                // Write batches
                // With strings
                using (WriteBatch batch = new WriteBatch()
                                          .Put("one", "uno")
                                          .Put("two", "deuce")
                                          .Put("two", "dos")
                                          .Put("three", "tres"))
                {
                    db.Write(batch);
                }
                Assert.Equal("uno", db.Get("one"));

                // With save point
                using (WriteBatch batch = new WriteBatch())
                {
                    batch
                    .Put("hearts", "red")
                    .Put("diamonds", "red");
                    batch.SetSavePoint();
                    batch
                    .Put("clubs", "black");
                    batch.SetSavePoint();
                    batch
                    .Put("spades", "black");
                    batch.RollbackToSavePoint();
                    db.Write(batch);
                }
                Assert.Equal("red", db.Get("diamonds"));
                Assert.Equal("black", db.Get("clubs"));
                Assert.Null(db.Get("spades"));

                // Save a checkpoint
                using (var cp = db.Checkpoint())
                {
                    cp.Save(cppath);
                }

                // With bytes
                var utf8 = Encoding.UTF8;
                using (WriteBatch batch = new WriteBatch()
                                          .Put(utf8.GetBytes("four"), new byte[] { 4, 4, 4 })
                                          .Put(utf8.GetBytes("five"), new byte[] { 5, 5, 5 }))
                {
                    db.Write(batch);
                }
                Assert.True(BinaryComparer.Default.Equals(new byte[] { 4, 4, 4 }, db.Get(utf8.GetBytes("four"))));

                // Snapshots
                using (var snapshot = db.CreateSnapshot())
                {
                    var before = db.Get("one");
                    db.Put("one", "1");

                    var useSnapshot = new ReadOptions()
                                      .SetSnapshot(snapshot);

                    // the database value was written
                    Assert.Equal("1", db.Get("one"));
                    // but the snapshot still sees the old version
                    var after = db.Get("one", readOptions: useSnapshot);
                    Assert.Equal(before, after);
                }

                var two = db.Get("two");
                Assert.Equal("dos", two);

                // Iterators
                using (var iterator = db.NewIterator(
                           readOptions: new ReadOptions()
                           .SetIterateUpperBound("t")
                           ))
                {
                    iterator.Seek("k");
                    Assert.True(iterator.Valid());
                    Assert.Equal("key", iterator.StringKey());
                    iterator.Next();
                    Assert.True(iterator.Valid());
                    Assert.Equal("one", iterator.StringKey());
                    Assert.Equal("1", iterator.StringValue());
                    iterator.Next();
                    Assert.False(iterator.Valid());
                }

                // MultiGet
                var multiGetResult = db.MultiGet(new[] { "two", "three", "nine" });
                Assert.Equal(
                    expected: new[]
                {
                    new KeyValuePair <string, string>("two", "dos"),
                    new KeyValuePair <string, string>("three", "tres"),
                    new KeyValuePair <string, string>("nine", null)
                },
                    actual: multiGetResult
                    );
            }

            // Test reading checkpointed db
            using (var cpdb = RocksDb.Open(options, cppath))
            {
                Assert.Equal("red", cpdb.Get("diamonds"));
                Assert.Equal("black", cpdb.Get("clubs"));
                Assert.Null(cpdb.Get("spades"));
                // Checkpoint occurred before these changes:
                Assert.Null(cpdb.Get("four"));
            }

            // Test with column families
            var optionsCf = new DbOptions()
                            .SetCreateIfMissing(true)
                            .SetCreateMissingColumnFamilies(true);

            var columnFamilies = new ColumnFamilies
            {
                { "reverse", new ColumnFamilyOptions() },
            };

            using (var db = RocksDb.Open(optionsCf, path, columnFamilies))
            {
                var reverse = db.GetColumnFamily("reverse");

                db.Put("one", "uno");
                db.Put("two", "dos");
                db.Put("three", "tres");

                db.Put("uno", "one", cf: reverse);
                db.Put("dos", "two", cf: reverse);
                db.Put("tres", "three", cf: reverse);
            }

            // Test Cf Delete
            using (var db = RocksDb.Open(optionsCf, path, columnFamilies))
            {
                var reverse = db.GetColumnFamily("reverse");

                db.Put("cuatro", "four", cf: reverse);
                db.Put("cinco", "five", cf: reverse);

                Assert.Equal("four", db.Get("cuatro", cf: reverse));
                Assert.Equal("five", db.Get("cinco", cf: reverse));

                byte[] keyBytes = Encoding.UTF8.GetBytes("cuatro");
                db.Remove(keyBytes, reverse);
                db.Remove("cinco", reverse);

                Assert.Null(db.Get("cuatro", cf: reverse));
                Assert.Null(db.Get("cinco", cf: reverse));
            }

            // Test list
            {
                var list = RocksDb.ListColumnFamilies(optionsCf, path);
                Assert.Equal(new[] { "default", "reverse" }, list.ToArray());
            }

            // Test reopen with column families
            using (var db = RocksDb.Open(optionsCf, path, columnFamilies))
            {
                var reverse = db.GetColumnFamily("reverse");

                Assert.Equal("uno", db.Get("one"));
                Assert.Equal("one", db.Get("uno", cf: reverse));
                Assert.Null(db.Get("uno"));
                Assert.Null(db.Get("one", cf: reverse));
            }

            // Test dropping and creating column family
            using (var db = RocksDb.Open(options, path, columnFamilies))
            {
                db.DropColumnFamily("reverse");
                var reverse = db.CreateColumnFamily(new ColumnFamilyOptions(), "reverse");
                Assert.Null(db.Get("uno", cf: reverse));
                db.Put("red", "rouge", cf: reverse);
                Assert.Equal("rouge", db.Get("red", cf: reverse));
            }

            // Test reopen after drop and create
            using (var db = RocksDb.Open(options, path, columnFamilies))
            {
                var reverse = db.GetColumnFamily("reverse");
                Assert.Null(db.Get("uno", cf: reverse));
                Assert.Equal("rouge", db.Get("red", cf: reverse));
            }

            // Test read only
            using (var db = RocksDb.OpenReadOnly(options, path, columnFamilies, false))
            {
                Assert.Equal("uno", db.Get("one"));
            }

            // Test SstFileWriter
            {
                using (var writer = new SstFileWriter())
                {
                }

                var envOpts = new EnvOptions();
                var ioOpts  = new ColumnFamilyOptions();
                using (var sst = new SstFileWriter(envOpts, ioOpts))
                {
                    var filename = Path.Combine(temp, "test.sst");
                    if (File.Exists(filename))
                    {
                        File.Delete(filename);
                    }
                    sst.Open(filename);
                    sst.Add("four", "quatro");
                    sst.Add("one", "uno");
                    sst.Add("two", "dos");
                    sst.Finish();

                    using (var db = RocksDb.Open(options, path, columnFamilies))
                    {
                        Assert.NotEqual("four", db.Get("four"));
                        var ingestOptions = new IngestExternalFileOptions()
                                            .SetMoveFiles(true);
                        db.IngestExternalFiles(new string[] { filename }, ingestOptions);
                        Assert.Equal("quatro", db.Get("four"));
                    }
                }
            }

            // test comparator
            unsafe {
                var opts = new ColumnFamilyOptions()
                           .SetComparator(new IntegerStringComparator());

                var filename = Path.Combine(temp, "test.sst");
                if (File.Exists(filename))
                {
                    File.Delete(filename);
                }
                using (var sst = new SstFileWriter(ioOptions: opts))
                {
                    sst.Open(filename);
                    sst.Add("111", "111");
                    sst.Add("1001", "1001"); // this order is only allowed using an integer comparator
                    sst.Finish();
                }
            }

            // test write batch with index
            {
                var wbwi = new WriteBatchWithIndex(reservedBytes: 1024);
                wbwi.Put("one", "un");
                wbwi.Put("two", "deux");
                var oneValueIn  = Encoding.UTF8.GetBytes("one");
                var oneValueOut = wbwi.Get("one");
                Assert.Equal("un", oneValueOut);
                using (var db = RocksDb.Open(options, path, columnFamilies))
                {
                    var oneCombinedOut   = wbwi.Get(db, "one");
                    var threeCombinedOut = wbwi.Get(db, "three");
                    Assert.Equal("un", oneCombinedOut);
                    Assert.Equal("tres", threeCombinedOut);

                    using (var wbIterator = wbwi.NewIterator(db.NewIterator()))
                    {
                        wbIterator.Seek("o");
                        Assert.True(wbIterator.Valid());
                        var itkey = wbIterator.StringKey();
                        Assert.Equal("one", itkey);
                        var itval = wbIterator.StringValue();
                        Assert.Equal("un", itval);

                        wbIterator.Next();
                        Assert.True(wbIterator.Valid());
                        itkey = wbIterator.StringKey();
                        Assert.Equal("three", itkey);
                        itval = wbIterator.StringValue();
                        Assert.Equal("tres", itval);

                        wbIterator.Next();
                        Assert.True(wbIterator.Valid());
                        itkey = wbIterator.StringKey();
                        Assert.Equal("two", itkey);
                        itval = wbIterator.StringValue();
                        Assert.Equal("deux", itval);

                        wbIterator.Next();
                        Assert.False(wbIterator.Valid());
                    }

                    db.Write(wbwi);

                    var oneDbOut = wbwi.Get("one");
                    Assert.Equal("un", oneDbOut);
                }
            }

            // compact range
            {
                using (var db = RocksDb.Open(options, path, columnFamilies))
                {
                    db.CompactRange("o", "tw");
                }
            }

            // Smoke test various options
            {
                var dbname = "test-options";
                if (Directory.Exists(dbname))
                {
                    Directory.Delete(dbname, true);
                }
                var optsTest = (DbOptions) new RocksDbSharp.DbOptions()
                               .SetCreateIfMissing(true)
                               .SetCreateMissingColumnFamilies(true)
                               .SetBlockBasedTableFactory(new BlockBasedTableOptions().SetBlockCache(Cache.CreateLru(1024 * 1024)));
                GC.Collect();
                using (var db = RocksDbSharp.RocksDb.Open(optsTest, dbname))
                {
                }
                if (Directory.Exists(dbname))
                {
                    Directory.Delete(dbname, true);
                }
            }

            // Smoke test OpenWithTtl
            {
                var dbname = "test-with-ttl";
                if (Directory.Exists(dbname))
                {
                    Directory.Delete(dbname, true);
                }
                var optsTest = (DbOptions) new RocksDbSharp.DbOptions()
                               .SetCreateIfMissing(true)
                               .SetCreateMissingColumnFamilies(true);
                using (var db = RocksDbSharp.RocksDb.OpenWithTtl(optsTest, dbname, 1))
                {
                }
                if (Directory.Exists(dbname))
                {
                    Directory.Delete(dbname, true);
                }
            }

            // Smoke test MergeOperator
            {
                var dbname = "test-merge-operator";
                if (Directory.Exists(dbname))
                {
                    Directory.Delete(dbname, true);
                }
                var optsTest = (DbOptions) new RocksDbSharp.DbOptions()
                               .SetCreateIfMissing(true)
                               .SetMergeOperator(MergeOperators.Create(
                                                     name: "test-merge-operator",
                                                     partialMerge: (key, keyLength, operandsList, operandsListLength, numOperands, success, newValueLength) => IntPtr.Zero,
                                                     fullMerge: (key, keyLength, existingValue, existingValueLength, operandsList, operandsListLength, numOperands, success, newValueLength) => IntPtr.Zero,
                                                     deleteValue: (value, valueLength) => { }
                                                     ));
                GC.Collect();
                using (var db = RocksDbSharp.RocksDb.Open(optsTest, dbname))
                {
                }
                if (Directory.Exists(dbname))
                {
                    Directory.Delete(dbname, true);
                }
            }

            // Test that GC does not cause access violation on Comparers
            {
                var dbname = "test-av-error";
                if (Directory.Exists(dbname))
                {
                    Directory.Delete(dbname, true);
                }
                options = new RocksDbSharp.DbOptions()
                          .SetCreateIfMissing(true)
                          .SetCreateMissingColumnFamilies(true);
                var sc = new RocksDbSharp.StringComparator(StringComparer.InvariantCultureIgnoreCase);
                columnFamilies = new RocksDbSharp.ColumnFamilies
                {
                    { "cf1", new RocksDbSharp.ColumnFamilyOptions()
                      .SetComparator(sc) },
                };
                GC.Collect();
                using (var db = RocksDbSharp.RocksDb.Open(options, dbname, columnFamilies))
                {
                }
                if (Directory.Exists(dbname))
                {
                    Directory.Delete(dbname, true);
                }
            }
        }