Beispiel #1
0
        /// <summary>
        /// Returns a correct implementation of the persistence provider according to environment variables.
        /// </summary>
        /// <remarks>If the environment invariants have failed to hold upon creation of the storage provider,
        /// a <em>null</em> value will be provided.</remarks>
        public async Task<IStorageProvider> GetStorageProvider(string storageInvariant)
        {
            //Make sure the environment invariants hold before trying to give a functioning SUT instantiation.
            //This is done instead of the constructor to have more granularity on how the environment should be initialized.
            try
            {
                using(await StorageLock.LockAsync())
                {
                    if(AdoNetInvariants.Invariants.Contains(storageInvariant))
                    {
                        if(!StorageProviders.ContainsKey(storageInvariant))
                        {
                            Storage = Invariants.EnsureStorageForTesting(Invariants.ActiveSettings.ConnectionStrings.First(i => i.StorageInvariant == storageInvariant));

                            var properties = new Dictionary<string, string>();
                            properties["DataConnectionString"] = Storage.Storage.ConnectionString;
                            properties["AdoInvariant"] = storageInvariant;

                            var config = new ProviderConfiguration(properties, null);
                            var storageProvider = new AdoNetStorageProvider();
                            await storageProvider.Init(storageInvariant + "_StorageProvider", DefaultProviderRuntime, config);

                            StorageProviders[storageInvariant] = storageProvider;
                        }
                    }
                }
            }
            catch
            {
                StorageProviders.Add(storageInvariant, null);
            }

            return StorageProviders[storageInvariant];
        }
Beispiel #2
0
        public static void ClassInitialize(TestContext testContext)
        {
            TraceLogger.AddTraceLevelOverride("RelationalStreamingTests", Severity.Verbose3);
            try
            {
                SqlServerStorage = RelationalStorageForTesting.SetupInstance(AdoNetInvariants.InvariantNameSqlServer, testDatabaseName).GetAwaiter().GetResult();
            }
            catch(Exception ex)
            {
                Console.WriteLine("Failed to initialize SQL Server for RelationalGeneralTests: {0}", ex);
            }

            try
            {
                MySqlStorage = RelationalStorageForTesting.SetupInstance(AdoNetInvariants.InvariantNameMySql, testDatabaseName).GetAwaiter().GetResult();
            }
            catch(Exception ex)
            {
                Console.WriteLine("Failed to initialize MySQL for RelationalGeneralTests: {0}", ex);
            }
        }
Beispiel #3
0
        private static Task CancellationTokenTest(RelationalStorageForTesting sut, TimeSpan timeoutLimit)
        {
            using(var tokenSource = new CancellationTokenSource(timeoutLimit))
            {
                try
                {
                    //Here one second is added to the task timeout limit in order to account for the delays.
                    //The delays are mainly in the underlying ADO.NET libraries and database.
                    var task = sut.Storage.ReadAsync<int>(sut.CancellationTestQuery, tokenSource.Token);
                    if(!task.Wait(timeoutLimit.Add(TimeSpan.FromSeconds(1))))
                    {
                        Assert.Fail(string.Format("Timeout limit {0} ms exceeded.", timeoutLimit.TotalMilliseconds));
                    }
                }
                catch(Exception ex)
                {
                    //There can be a DbException due to the operation being forcefully cancelled...
                    //... Unless this is a test for a provider which does not support for cancellation.
                    if(sut.Storage.SupportsCommandCancellation())
                    {
                        //If the operation is cancelled already before database calls, a OperationCancelledException
                        //will be thrown in any case.
                        Assert.IsTrue(ex is DbException || ex is OperationCanceledException, "Unexcepted exception: {0}", ex);
                    }
                    else
                    {
                        Assert.IsTrue(ex is OperationCanceledException, "Unexcepted exception: {0}", ex);
                    }
                }
            }

            return TaskDone.Done;
        }
Beispiel #4
0
        private static async Task<StreamingTest> ReadFromDatabaseUsingAsyncStream(RelationalStorageForTesting sut, int streamId, CancellationToken cancellationToken)
        {
            return (await sut.Storage.ReadAsync(sut.StreamTestSelect, command =>
            {
                var p = command.CreateParameter();
                p.ParameterName = "streamId";
                p.Value = streamId;
                command.Parameters.Add(p);
            }, async (selector, resultSetCount, canellationToken) =>
            {
                var streamSelector = (DbDataReader)selector;
                var id = await streamSelector.GetValueAsync<int>("Id");
                using(var ms = new MemoryStream())
                {                    
                    using(var downloadStream = streamSelector.GetStream(1, sut.Storage))
                    {
                        await downloadStream.CopyToAsync(ms);

                        return new StreamingTest { Id = id, StreamData = ms.ToArray() };
                    }
                }                
            }, cancellationToken, CommandBehavior.SequentialAccess).ConfigureAwait(false)).Single();
        }
Beispiel #5
0
        private static async Task InsertIntoDatabaseUsingStream(RelationalStorageForTesting sut, int streamId, byte[] dataToInsert, CancellationToken cancellationToken)
        {
            //The dataToInsert could be inserted here directly, but it wouldn't be streamed.
            using(var ms = new MemoryStream(dataToInsert))
            {
                await sut.Storage.ExecuteAsync(sut.StreamTestInsert, command =>
                {
                    var p1 = command.CreateParameter();
                    p1.ParameterName = "Id";
                    p1.Value = streamId;
                    command.Parameters.Add(p1);

                    //MySQL does not support streams in and for the time being there
                    //is not a custom stream defined. For ideas, see http://dev.mysql.com/doc/refman/5.7/en/blob.html
                    //for string operations for blobs and http://rusanu.com/2010/12/28/download-and-upload-images-from-sql-server-with-asp-net-mvc/
                    //on how one could go defining one.
                    var p2 = command.CreateParameter();
                    p2.ParameterName = "StreamData";
                    p2.Value = dataToInsert;
                    p2.DbType = DbType.Binary;
                    p2.Size = dataToInsert.Length;
                    command.Parameters.Add(p2);

                }, cancellationToken, CommandBehavior.SequentialAccess).ConfigureAwait(false);
            }
        }
Beispiel #6
0
        private static Task<bool>[] InsertAndReadStreamsAndCheckMatch(RelationalStorageForTesting sut, int streamSize, int countOfStreams, CancellationToken cancellationToken)
        {
            //Stream in and steam out three binary streams in parallel.
            var streamChecks = new Task<bool>[countOfStreams];
            var sr = new SafeRandom();
            for(int i = 0; i < countOfStreams; ++i)
            {
                int streamId = i;
                streamChecks[i] = Task.Run(async () =>
                {
                    var rb = new byte[streamSize];
                    sr.NextBytes(rb);
                    await InsertIntoDatabaseUsingStream(sut, streamId, rb, cancellationToken);
                    var dataStreamFromTheDb = await ReadFromDatabaseUsingAsyncStream(sut, streamId, cancellationToken);
                    return dataStreamFromTheDb.StreamData.SequenceEqual(rb);
                });
            }

            return streamChecks;
        }