public static IApplicationBuilder UseFoundationDb(this IApplicationBuilder builder, Action <IFdbDatabaseProvider> setup)
        {
            var provider = builder.ApplicationServices.GetRequiredService <IFdbDatabaseProvider>();
            var lifetime = builder.ApplicationServices.GetRequiredService <IApplicationLifetime>();

            var cts = new CancellationTokenSource();

            lifetime.ApplicationStarted.Register(() =>
            {
                var options = builder.ApplicationServices.GetRequiredService <IOptions <FdbDatabaseProviderOptions> >().Value;

                //Console.WriteLine("Initializing FDB client...");
                Fdb.Start(options.ApiVersion);
                //Console.WriteLine("Start FDB connection...");
                provider.Start(cts.Token);
            });

            lifetime.ApplicationStopping.Register(() =>
            {
                cts.Cancel();
                provider.Stop();
            });

            lifetime.ApplicationStopped.Register(() =>
            {
                cts.Dispose();
                //Console.WriteLine("Stopping FDB database...");
                provider.Dispose();
                //Console.WriteLine("Stopping FDB client...");
                Fdb.Stop();
            });

            return(builder);
        }
示例#2
0
        public async Task Test_Can_Open_Database()
        {
            //README: if your default cluster is remote, you need to be connected to the netword, or it will fail.

            // the hard way
            using (var cluster = await Fdb.CreateClusterAsync(null, this.Cancellation))
            {
                Assert.That(cluster, Is.Not.Null);
                Assert.That(cluster.Path, Is.Null);

                using (var db = await cluster.OpenDatabaseAsync("DB", KeySubspace.Empty, false, this.Cancellation))
                {
                    Assert.That(db, Is.Not.Null, "Should return a valid object");
                    Assert.That(db.Name, Is.EqualTo("DB"), "FdbDatabase.Name should match");
                    Assert.That(db.Cluster, Is.SameAs(cluster), "FdbDatabase.Cluster should point to the parent cluster");
                }
            }

            // the easy way
            using (var db = await Fdb.OpenAsync())
            {
                Assert.That(db, Is.Not.Null);
                Assert.That(db.Name, Is.EqualTo("DB"));
                Assert.That(db.Cluster, Is.Not.Null);
                Assert.That(db.Cluster.Path, Is.Null);
            }
        }
示例#3
0
        public static void Main(string[] args)
        {
            //TODO: move this to the main, and add a command line argument to on/off ?
            try
            {
                if (Console.LargestWindowWidth > 0 && Console.LargestWindowHeight > 0)
                {
                    Console.WindowWidth  = 160;
                    Console.WindowHeight = 60;
                }
            }
            catch
            {
                // this sometimes fail on small screen sizes
            }

            // Initialize FDB

            try
            {
                Fdb.Start(Fdb.GetMaxSafeApiVersion(200, Fdb.GetDefaultApiVersion()));
                using (var go = new CancellationTokenSource())
                {
                    MainAsync(args, go.Token).GetAwaiter().GetResult();
                }
            }
            finally
            {
                Fdb.Stop();
                StdOut("Bye");
            }
        }
示例#4
0
        public void RunAfterAnyTests()
        {
            using (_source)
                using (_database) { }

            Fdb.Stop();
        }
示例#5
0
        public async Task Test_FdbDatabase_Key_Validation()
        {
            using (var db = await Fdb.OpenAsync())
            {
                // IsKeyValid
                Assert.That(db.IsKeyValid(Slice.Nil), Is.False, "Null key is invalid");
                Assert.That(db.IsKeyValid(Slice.Empty), Is.True, "Empty key is allowed");
                Assert.That(db.IsKeyValid(Slice.FromString("hello")), Is.True);
                Assert.That(db.IsKeyValid(Slice.Create(Fdb.MaxKeySize + 1)), Is.False, "Key is too large");
                Assert.That(db.IsKeyValid(Fdb.System.Coordinators), Is.True, "System keys are valid");

                // EnsureKeyIsValid
                Assert.That(() => db.EnsureKeyIsValid(Slice.Nil), Throws.InstanceOf <ArgumentException>());
                Assert.That(() => db.EnsureKeyIsValid(Slice.Empty), Throws.Nothing);
                Assert.That(() => db.EnsureKeyIsValid(Slice.FromString("hello")), Throws.Nothing);
                Assert.That(() => db.EnsureKeyIsValid(Slice.Create(Fdb.MaxKeySize + 1)), Throws.InstanceOf <ArgumentException>());
                Assert.That(() => db.EnsureKeyIsValid(Fdb.System.Coordinators), Throws.Nothing);

                // EnsureKeyIsValid ref
                Assert.That(() => { Slice key = Slice.Nil; db.EnsureKeyIsValid(ref key); }, Throws.InstanceOf <ArgumentException>());
                Assert.That(() => { Slice key = Slice.Empty; db.EnsureKeyIsValid(ref key); }, Throws.Nothing);
                Assert.That(() => { Slice key = Slice.FromString("hello"); db.EnsureKeyIsValid(ref key); }, Throws.Nothing);
                Assert.That(() => { Slice key = Slice.Create(Fdb.MaxKeySize + 1); db.EnsureKeyIsValid(ref key); }, Throws.InstanceOf <ArgumentException>());
                Assert.That(() => { Slice key = Fdb.System.Coordinators; db.EnsureKeyIsValid(ref key); }, Throws.Nothing);
            }
        }
示例#6
0
文件: Pool.cs 项目: DotLab/Futilef
        static void TestRandomAllocFree()
        {
            var       pool = stackalloc Pool[1]; Init(pool);
            const int len  = 200;
            var       ptrs = new System.Collections.Generic.List <long>();

            for (int i = 0; i < len; i += 1)
            {
                int size = Fdb.Random(1, 1000);
                ptrs.Add((long)Pool.Alloc(pool, size));
                if (pool->shift != 0)
                {
                    long shift = pool->shift;
                    for (int j = 0; j < ptrs.Count - 1; j += 1)
                    {
                        ptrs[j] += shift;
                    }
                    pool->shift = 0;
                }
                if (Fdb.Random(0, 2) == 0)                    // 1/3 chance to free
                {
                    int idx = Fdb.Random(0, ptrs.Count - 1);
                    Pool.Free(pool, (void *)ptrs[idx]);
                    ptrs.RemoveAt(idx);
                }
            }
            for (int i = 0; i < ptrs.Count; i += 1)
            {
                Pool.Free(pool, (void *)ptrs[i]);
            }
            // the first *real* free node should be 0x54 long (containing all space)
            Should.Equal("*(int *)(pool->arr + 0x28)", *(int *)(pool->arr + 0x18), pool->len - 11 * 4);
        }
        public async Task Test_Open_Or_CreateCluster_With_Corrupted_ClusterFile_Should_Fail()
        {
            // Using a corrupted cluster file should fail with "ConnectionStringInvalid"

            // write some random bytes into a cluster file
            string path = System.IO.Path.GetTempFileName();

            try
            {
                var rnd   = new Random();
                var bytes = new byte[128];
                rnd.NextBytes(bytes);
                System.IO.File.WriteAllBytes(path, bytes);

                await TestHelpers.AssertThrowsFdbErrorAsync(() => Fdb.CreateClusterAsync(path, this.Cancellation), FdbError.ConnectionStringInvalid, "Should fail if file is corrupted");

                await TestHelpers.AssertThrowsFdbErrorAsync(() => Fdb.OpenAsync(new FdbConnectionOptions {
                    ClusterFile = path
                }, this.Cancellation), FdbError.ConnectionStringInvalid, "Should fail if file is corrupted");
            }
            finally
            {
                System.IO.File.Delete(path);
            }
        }
        public FdbFixture()
        {
            const int fallbackFdbApiVersion = 520;

            var apiVersion    = Environment.GetEnvironmentVariable("FdbApiVersion");
            var serverVersion = Environment.GetEnvironmentVariable("FdbServerVersion");

            if (apiVersion == null ||
                !int.TryParse(apiVersion, out int fdbApiVersion))
            {
                fdbApiVersion = fallbackFdbApiVersion;
            }

            var availableVersions = Enum.GetNames(typeof(FdbServerVersion));

            if (serverVersion != null &&
                availableVersions.Contains(serverVersion))
            {
                _serverVersion = (FdbServerVersion)Enum.Parse(typeof(FdbServerVersion), serverVersion);
            }
            else
            {
                _serverVersion = FdbServerVersion.v6_0_15;
            }

            EnsureApiVersionAndServerVersionCompatible(fdbApiVersion, _serverVersion);

            Fdb = Fdb.Instance;
            Fdb.SelectApiVersion(fdbApiVersion);
        }
        public async Task Test_Open_Or_CreateCluster_With_Invalid_ClusterFile_Path_Should_Fail()
        {
            // Missing/Invalid cluster files should fail with "NoClusterFileFound"

            // file not found
            await TestHelpers.AssertThrowsFdbErrorAsync(() => Fdb.CreateClusterAsync(@".\file_not_found.cluster", this.Cancellation), FdbError.NoClusterFileFound, "Should fail if cluster file is missing");

            await TestHelpers.AssertThrowsFdbErrorAsync(() => Fdb.OpenAsync(new FdbConnectionOptions {
                ClusterFile = @".\file_not_found.cluster"
            }, this.Cancellation), FdbError.NoClusterFileFound, "Should fail if cluster file is missing");

            // unreachable path
            await TestHelpers.AssertThrowsFdbErrorAsync(() => Fdb.CreateClusterAsync(@"C:\..\..\fdb.cluster", this.Cancellation), FdbError.NoClusterFileFound, "Should fail if path is malformed");

            await TestHelpers.AssertThrowsFdbErrorAsync(() => Fdb.OpenAsync(new FdbConnectionOptions {
                ClusterFile = @"C:\..\..\fdb.cluster"
            }, this.Cancellation), FdbError.NoClusterFileFound, "Should fail if path is malformed");

            // malformed path
            await TestHelpers.AssertThrowsFdbErrorAsync(() => Fdb.CreateClusterAsync(@"FOO:\invalid$path!/fdb.cluster", this.Cancellation), FdbError.NoClusterFileFound, "Should fail if path is malformed");

            await TestHelpers.AssertThrowsFdbErrorAsync(() => Fdb.OpenAsync(new FdbConnectionOptions {
                ClusterFile = @"FOO:\invalid$path!/fdb.cluster"
            }, this.Cancellation), FdbError.NoClusterFileFound, "Should fail if path is malformed");
        }
示例#10
0
文件: PtrLst.cs 项目: DotLab/Futilef
        static void TestPushRemovePush()
        {
            const int len = 1000;
            var       arr = new System.Collections.Generic.List <int>();
            var       lst = stackalloc PtrLst[1]; Init(lst);

            for (int i = 0; i < len; i += 1)
            {
                int v = Fdb.Random(0, len);
                arr.Add(v);
                Push(lst, (void *)v);
            }
            for (int i = 0; i < len >> 1; i += 1)
            {
                int idx = Fdb.Random(0, arr.Count);
                arr.RemoveAt(idx);
                RemoveAt(lst, idx);
            }
            for (int i = 0; i < len; i += 1)
            {
                int v = Fdb.Random(0, len);
                arr.Add(v);
                Push(lst, (void *)v);
            }
            void **ptr = lst->arr;

            for (int i = 0; i < arr.Count; i += 1)
            {
                Should.Equal("(int)ptr[i]", (int)ptr[i], arr[i]);
            }
        }
示例#11
0
文件: PtrLst.cs 项目: DotLab/Futilef
 public static void Remove(PtrLst *self, void *ptr)
 {
                 #if FDB
     Should.NotNull("self", self);
     Should.TypeEqual("self", self->type, Type);
     int oldCount = self->count;
                 #endif
     void **arr = self->arr;
     int    i = 0, len = self->count;
     while (i < len && arr[i] != ptr)
     {
         i += 1;
     }
     if (i < len)                // arr[i] == p
     // for (len = self->count -= 1; i < len; i += 1) arr[i] = arr[i + 1];
     {
         byte *src   = (byte *)(arr + i);
         int   size  = self->size;
         int   count = self->count -= 1;
         Mem.Memmove(src, src + size, (count - i) * size);
     }
                 #if FDB
     else
     {
         Fdb.Error("{0:X} does not exist in PtrLst {1:X}", (ulong)ptr, (ulong)self);
     }
     Should.Equal("self->count", self->count, oldCount - 1);
                 #endif
 }
示例#12
0
        public static void Main(string[] args)
        {
            //TODO: move this to the main, and add a command line argument to on/off ?
            if (Console.LargestWindowWidth > 0 && Console.LargestWindowHeight > 0)
            {
                Console.WindowWidth  = 160;
                Console.WindowHeight = 60;
            }

            // Initialize FDB

            //note: always use the latest version available
            Fdb.UseApiVersion(Fdb.GetMaxSafeApiVersion());
            try
            {
                Fdb.Start();
                using (var go = new CancellationTokenSource())
                {
                    MainAsync(args, go.Token).GetAwaiter().GetResult();
                }
            }
            finally
            {
                Fdb.Stop();
                Console.WriteLine("Bye");
            }
        }
示例#13
0
 private static Task <IFdbDatabase> ChangeDatabase(FdbConnectionOptions options, CancellationToken ct)
 {
     options.DefaultTimeout    = TimeSpan.FromSeconds(30);
     options.DefaultRetryLimit = 50;
     Program.StdOut("Connecting to cluster...", ConsoleColor.Gray);
     return(Fdb.OpenAsync(options, ct));
 }
示例#14
0
        public Task <IFdbDatabaseHandler> OpenDatabaseAsync(string databaseName, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <IFdbDatabaseHandler>(cancellationToken));
            }

            var future = FdbNative.ClusterCreateDatabase(m_handle, databaseName);

            return(FdbFuture.CreateTaskFromHandle(
                       future,
                       (h) =>
            {
                DatabaseHandle database;
                var err = FdbNative.FutureGetDatabase(h, out database);
                if (err != FdbError.Success)
                {
                    database.Dispose();
                    throw Fdb.MapToException(err);
                }
                var handler = new FdbNativeDatabase(database);
                return (IFdbDatabaseHandler)handler;
            },
                       cancellationToken
                       ));
        }
        public async Task Test_Check_Timeout_On_Non_Existing_Database()
        {
            string clusterPath = Path.Combine(TestContext.CurrentContext.WorkDirectory, "notfound.cluster");

            File.WriteAllText(clusterPath, "local:[email protected]:4566");
            var options = new FdbConnectionOptions {
                ClusterFile = clusterPath
            };

            using (var db = await Fdb.OpenAsync(options, this.Cancellation))
            {
                bool exists = false;
                var  err    = FdbError.Success;
                try
                {
                    using (var tr = await db.BeginReadOnlyTransactionAsync(this.Cancellation))
                    {
                        tr.Timeout = 250;                         // ms
                        Log("check ...");
                        await tr.GetAsync(Slice.FromString("key_not_found"));

                        Log("Uhoh ...?");
                        exists = true;
                    }
                }
                catch (FdbException e)
                {
                    err = e.Code;
                }

                Assert.That(exists, Is.False);
                Assert.That(err, Is.EqualTo(FdbError.TransactionTimedOut));
            }
        }
示例#16
0
文件: Pool.cs 项目: DotLab/Futilef
        static void TestRandomExpand()
        {
            var       pool = stackalloc Pool[1]; Init(pool);
            const int len  = 200;
            var       ptrs = stackalloc byte *[len];

            for (int i = 0; i < len; i += 1)
            {
                int size = Fdb.Random(1, 1000);
                ptrs[i] = (byte *)Pool.Alloc(pool, size);
                if (pool->shift != 0)
                {
                    long shift = pool->shift;
                    for (int j = 0; j < i; j += 1)
                    {
                        ptrs[j] += shift;
                    }
                    pool->shift = 0;
                }
            }
            for (int i = 0; i < len; i += 1)
            {
                Pool.Free(pool, ptrs[i]);
            }
            // the first *real* free node should be 0x54 long (containing all space)
            Should.Equal("*(int *)(pool->arr + 0x28)", *(int *)(pool->arr + 0x18), pool->len - 11 * 4);
        }
        public async Task Test_Compare_Implementations()
        {
            for (int mode = 1; mode <= 6; mode++)
            {
                Console.WriteLine("#### SCENARIO " + mode + " ####");

                using (var db = await Fdb.OpenAsync(this.Cancellation))
                {
                    using (var tr = db.BeginTransaction(this.Cancellation))
                    {
                        await tr.GetReadVersionAsync();

                        switch (mode)
                        {
                        case 1: await Scenario1(tr); break;

                        case 2: await Scenario2(tr); break;

                        case 3: await Scenario3(tr); break;

                        case 4: await Scenario4(tr); break;

                        case 5: await Scenario5(tr); break;

                        case 6: await Scenario6(tr); break;
                        }

                        await tr.CommitAsync();
                    }
                }

                using (var db = MemoryDatabase.CreateNew("DB"))
                {
                    using (var tr = db.BeginTransaction(FdbTransactionMode.Default, this.Cancellation))
                    {
                        await tr.GetReadVersionAsync();

                        switch (mode)
                        {
                        case 1: await Scenario1(tr); break;

                        case 2: await Scenario2(tr); break;

                        case 3: await Scenario3(tr); break;

                        case 4: await Scenario4(tr); break;

                        case 5: await Scenario5(tr); break;

                        case 6: await Scenario6(tr); break;
                        }

                        await tr.CommitAsync();
                    }

                    db.Debug_Dump();
                }
            }
        }
示例#18
0
 public async Task Test_Can_Connect_To_Local_Cluster()
 {
     using (var cluster = await Fdb.CreateClusterAsync(this.Cancellation))
     {
         Assert.That(cluster, Is.Not.Null, "Should return a valid object");
         Assert.That(cluster.Path, Is.Null, "FdbCluster.Path should be null");
     }
 }
 public void Test_Open_Database_With_Cancelled_Token_Should_Fail()
 {
     using (var cts = new CancellationTokenSource())
     {
         cts.Cancel();
         Assert.That(async() => await Fdb.OpenAsync(cts.Token), Throws.InstanceOf <OperationCanceledException>());
     }
 }
示例#20
0
        public static async Task <IFdbDatabase> OpenDefaultAsync(this Fdb fdb)
        {
            using (var cluster = await fdb.OpenDefaultClusterAsync().ConfigureAwait(false))
            {
                var database = await cluster.OpenDefaultDatabaseAsync().ConfigureAwait(false);

                return(database);
            }
        }
示例#21
0
        /// <summary>Extract a chunk of result from a completed Future</summary>
        /// <param name="h">Handle to the completed Future</param>
        /// <param name="more">Receives true if there are more result, or false if all results have been transmitted</param>
        /// <param name="first">Receives the first key in the page, or default if page is empty</param>
        /// <param name="last">Receives the last key in the page, or default if page is empty</param>
        /// <returns>Array of key/value pairs, or an exception</returns>
        private static KeyValuePair <Slice, Slice>[] GetKeyValueArrayResultValuesOnly(FutureHandle h, out bool more, out Slice first, out Slice last)
        {
            var err = FdbNative.FutureGetKeyValueArrayValuesOnly(h, out var result, out more, out first, out last);

            Fdb.DieOnError(err);
            //note: result can only be null if an error occured!
            Contract.Ensures(result != null);
            return(result);
        }
示例#22
0
        public void Test_Connecting_To_Cluster_With_Cancelled_Token_Should_Fail()
        {
            using (var cts = new CancellationTokenSource())
            {
                cts.Cancel();

                Assert.Throws <OperationCanceledException>(() => Fdb.CreateClusterAsync(cts.Token).GetAwaiter().GetResult());
            }
        }
示例#23
0
        public void Test_Fdb_GetErrorMessage()
        {
            Assert.That(Fdb.GetErrorMessage(FdbError.Success), Is.EqualTo("success"));

            Assert.That(Fdb.GetErrorMessage(FdbError.OperationFailed), Is.EqualTo("operation_failed"));

            Assert.That(Fdb.GetErrorMessage(FdbError.TimedOut), Is.EqualTo("timed_out"));

            Assert.That(Fdb.GetErrorMessage(FdbError.PastVersion), Is.EqualTo("past_version"));
        }
示例#24
0
        public long GetCommittedVersion()
        {
            var err = FdbNative.TransactionGetCommittedVersion(m_handle, out long version);

#if DEBUG_TRANSACTIONS
            Debug.WriteLine("FdbTransaction[" + m_id + "].GetCommittedVersion() => err=" + err + ", version=" + version);
#endif
            Fdb.DieOnError(err);
            return(version);
        }
示例#25
0
        public void Test_Fdb_MapToException()
        {
            Assert.That(Fdb.MapToException(FdbError.Success), Is.Null);

            Assert.That(Fdb.MapToException(FdbError.OperationFailed), Is.InstanceOf <FdbException>().And.Property("Code").EqualTo(FdbError.OperationFailed));

            Assert.That(Fdb.MapToException(FdbError.TimedOut), Is.InstanceOf <TimeoutException>());

            Assert.That(Fdb.MapToException(FdbError.LargeAllocFailed), Is.InstanceOf <OutOfMemoryException>());
        }
        private static KeyValuePair <Slice, Slice>[] GetKeyValueArrayResult(FutureHandle h, out bool more)
        {
            KeyValuePair <Slice, Slice>[] result;
            var err = FdbNative.FutureGetKeyValueArray(h, out result, out more);

            Fdb.DieOnError(err);
            //note: result can only be null if an error occured!
            Contract.Ensures(result != null);
            return(result);
        }
        public async Task Test_Can_Open_Local_Database()
        {
            //README: if your test database is remote, and you don't have FDB running locally, this test will fail and you should ignore this one.

            using (var db = await Fdb.OpenAsync(this.Cancellation))
            {
                Assert.That(db, Is.Not.Null, "Should return a valid database");
                Assert.That(db.ClusterFile, Is.Null, "Cluster path should be null (default)");
            }
        }
示例#28
0
        /// <summary>Extract a chunk of result from a completed Future</summary>
        /// <param name="h">Handle to the completed Future</param>
        /// <param name="more">Receives true if there are more result, or false if all results have been transmitted</param>
        /// <param name="first">Receives the first key in the page, or default if page is empty</param>
        /// <param name="last">Receives the last key in the page, or default if page is empty</param>
        /// <returns>Array of key/value pairs, or an exception</returns>
        private static KeyValuePair <Slice, Slice>[] GetKeyValueArrayResultKeysOnly(FutureHandle h, out bool more, out Slice first, out Slice last)
        {
            var err = FdbNative.FutureGetKeyValueArrayKeysOnly(h, out var result, out more);

            Fdb.DieOnError(err);
            //note: result can only be null if an error occured!
            Contract.Ensures(result != null);
            first = result.Length > 0 ? result[0].Key : default;
            last  = result.Length > 0 ? result[result.Length - 1].Key : default;
            return(result);
        }
示例#29
0
 private static Task <IFdbDatabase> ChangeDatabase(string clusterFile, string dbName, string[] partition, CancellationToken ct)
 {
     if (partition == null || partition.Length == 0)
     {
         return(Fdb.OpenAsync(clusterFile, dbName, ct));
     }
     else
     {
         return(Fdb.Directory.OpenNamedPartitionAsync(clusterFile, dbName, partition, false, ct));
     }
 }
        /// <summary>Connect to the local test partition</summary>
        public static Task <IFdbDatabase> OpenTestPartitionAsync(CancellationToken ct)
        {
            var options = new FdbConnectionOptions
            {
                ClusterFile    = TestClusterFile,
                Root           = FdbPath.Absolute(FdbPathSegment.Partition("Tests"), FdbPathSegment.Create("Fdb"), FdbPathSegment.Partition(Environment.MachineName)),
                DefaultTimeout = TimeSpan.FromMilliseconds(DefaultTimeout),
            };

            return(Fdb.OpenAsync(options, ct));
        }