public async Task Test_FdbMap_List() { using (var db = await OpenTestPartitionAsync()) { var location = db.Root["Collections"]["Maps"]; await CleanLocation(db, location); var mapFoos = new FdbMap <string, string>(location.ByKey("Foos"), BinaryEncoding.StringEncoder); // write a bunch of keys await mapFoos.WriteAsync(db, (tr, foos) => { foos.Set(tr, "foo", "foo_value"); foos.Set(tr, "bar", "bar_value"); }, this.Cancellation); #if FULL_DEBUG await DumpSubspace(db, location); #endif // read them back await mapFoos.ReadAsync(db, async (tr, foos) => { var value = await foos.GetAsync(tr, "foo"); Assert.That(value, Is.EqualTo("foo_value")); value = await foos.GetAsync(tr, "bar"); Assert.That(value, Is.EqualTo("bar_value")); Assert.That(async() => await foos.GetAsync(tr, "baz"), Throws.InstanceOf <KeyNotFoundException>()); var opt = await foos.TryGetAsync(tr, "baz"); Assert.That(opt.HasValue, Is.False); }, this.Cancellation); } }
public async Task Test_FdbMap_Read_Write_Delete() { using (var db = await OpenTestPartitionAsync()) { var location = db.Root["Collections"]["Maps"]; await CleanLocation(db, location); var mapFoos = new FdbMap <string, string>(location.ByKey("Foos"), BinaryEncoding.StringEncoder); string secret = "world:" + Guid.NewGuid().ToString(); // read non existing value await mapFoos.WriteAsync(db, async (tr, foos) => { Assert.That(async() => await foos.GetAsync(tr, "hello"), Throws.InstanceOf <KeyNotFoundException>()); var value = await foos.TryGetAsync(tr, "hello"); Assert.That(value.HasValue, Is.False); Assert.That(value.Value, Is.Null); }, this.Cancellation); // write value await mapFoos.WriteAsync(db, (tr, foos) => foos.Set(tr, "hello", secret), this.Cancellation); #if FULL_DEBUG await DumpSubspace(db, location); #endif // read value back await mapFoos.ReadAsync(db, async (tr, foos) => { var value = await foos.GetAsync(tr, "hello"); Assert.That(value, Is.EqualTo(secret)); var opt = await foos.TryGetAsync(tr, "hello"); Assert.That(opt.HasValue, Is.True); Assert.That(opt.Value, Is.EqualTo(secret)); }, this.Cancellation); // directly read the value, behind the table's back await mapFoos.ReadAsync(db, async (tr, foos) => { var value = await tr.GetAsync(foos.Subspace.AsDynamic().Encode("Foos", "hello")); Assert.That(value, Is.Not.EqualTo(Slice.Nil)); Assert.That(value.ToString(), Is.EqualTo(secret)); }, this.Cancellation); // delete the value await mapFoos.WriteAsync(db, (tr, foos) => foos.Remove(tr, "hello"), this.Cancellation); #if FULL_DEBUG await DumpSubspace(db, location); #endif // verifiy that it is gone await mapFoos.ReadAsync(db, async (tr, foos) => { Assert.That(async() => await foos.GetAsync(tr, "hello"), Throws.InstanceOf <KeyNotFoundException>()); var value = await foos.TryGetAsync(tr, "hello"); Assert.That(value.HasValue, Is.False); // also check directly var folder = await location.Resolve(tr); var data = await tr.GetAsync(folder.Encode("Foos", "hello")); Assert.That(data, Is.EqualTo(Slice.Nil)); }, this.Cancellation); } }
public async Task Test_FdbMap_With_Custom_Key_Encoder() { // Use a table as a backing store for the rules of a Poor Man's firewall, where each keys are the IPEndPoint (tcp only!), and the values are "pass" or "block" // Encode IPEndPoint as the (IP, Port,) encoded with the Tuple codec // note: there is a much simpler way or creating composite keys, this is just a quick and dirty test! var keyEncoder = new KeyEncoder <IPEndPoint>( (ipe) => ipe == null ? Slice.Empty : TuPack.EncodeKey(ipe.Address, ipe.Port), (packed) => { if (packed.IsNullOrEmpty) { return(default(IPEndPoint)); } var t = TuPack.Unpack(packed); return(new IPEndPoint(t.Get <IPAddress>(0), t.Get <int>(1))); } ); var rules = new Dictionary <IPEndPoint, string>() { { new IPEndPoint(IPAddress.Parse("172.16.12.34"), 6667), "block" }, { new IPEndPoint(IPAddress.Parse("192.168.34.56"), 80), "pass" }, { new IPEndPoint(IPAddress.Parse("192.168.34.56"), 443), "pass" } }; using (var db = await OpenTestPartitionAsync()) { var location = db.Root["Collections"]["Maps"]; await CleanLocation(db, location); var mapHosts = new FdbMap <IPEndPoint, string>(location.ByKey("Hosts").AsTyped <IPEndPoint>(keyEncoder), BinaryEncoding.StringEncoder); // import all the rules await mapHosts.WriteAsync(db, (tr, hosts) => { foreach (var rule in rules) { hosts.Set(tr, rule.Key, rule.Value); } }, this.Cancellation); #if FULL_DEBUG await DumpSubspace(db, location); #endif // test the rules await mapHosts.ReadAsync(db, async (tr, hosts) => { var value = await hosts.GetAsync(tr, new IPEndPoint(IPAddress.Parse("172.16.12.34"), 6667)); Assert.That(value, Is.EqualTo("block")); value = await hosts.GetAsync(tr, new IPEndPoint(IPAddress.Parse("192.168.34.56"), 443)); Assert.That(value, Is.EqualTo("pass")); var baz = new IPEndPoint(IPAddress.Parse("172.16.12.34"), 80); Assert.That(async() => await hosts.GetAsync(tr, baz), Throws.InstanceOf <KeyNotFoundException>()); var opt = await hosts.TryGetAsync(tr, baz); Assert.That(opt.HasValue, Is.False); }, this.Cancellation); } }