public async Task InitializeAsync()
        {
            var timeoutTokenSource = CancellationTokenSource.CreateLinkedTokenSource(CancellationToken.None);

            timeoutTokenSource.CancelAfter(TimeSpan.FromMinutes(10));
            var cancellationToken = timeoutTokenSource.Token;


            while (true)
            {
                using (var connection = new SparkConnection(ConnectionString))
                {
                    try
                    {
                        // cluster will start, but fail until it finishing initilizaing
                        // so we are going to keep trying until it works
                        connection.Open();
                        return;
                    }
                    catch (TTransportException ex) when(ex.Message.Contains("503 (Service Unavailable)"))
                    {
                        await Task.Delay(5000, cancellationToken);
                    }
                }
            }
        }
예제 #2
0
        public async Task ShouldAcceptAccessToken()
        {
            var httpClient = new HttpClient();
            var response   = await httpClient.PostAsync($"https://login.microsoftonline.com/{Config.AccessTokenCredentials.Tenant}/oauth2/v2.0/token", new FormUrlEncodedContent(new Dictionary <string, string>()
            {
                { "grant_type", "client_credentials" },
                { "scope", "2ff814a6-3304-4ab8-85cb-cd0e6f879c1d/.default" },
                { "client_id", Config.AccessTokenCredentials.ClientId },
                { "client_secret", Config.AccessTokenCredentials.ClientSecret },
            }));

            response.EnsureSuccessStatusCode();
            var accessToken = JsonConvert.DeserializeObject <JObject>(await response.Content.ReadAsStringAsync())["access_token"].ToString();


            // Arrange
            var connectionStringBuilder = new SparkConnectionStringBuilder(Config.ConnectionString);

            await using var conn = new SparkConnection($"Data Source={connectionStringBuilder.DataSource}");
            conn.AccessToken     = accessToken;

            // Assert and Act
            conn.Open();
            Assert.Equal(ConnectionState.Open, conn.State);
        }
예제 #3
0
        public async Task WhenScalerShouldReturnFirstRow()
        {
            // Arrange
            var table = DataFactory.TableName();

            await using var conn = new SparkConnection(Config.ConnectionString);
            await conn.OpenAsync();

            await DataFactory.DropAndCreateTable(conn, table, new[]
            {
                "myInt INT"
            });

            await DataFactory.CreateCommand(conn, $@"INSERT INTO {table} VALUES 
                    (1), (2), (3)").ExecuteNonQueryAsync();

            // Act
            var command = DataFactory.CreateCommand(conn, $@"SELECT * FROM {table} ORDER BY myInt DESC");

            command.CommandTimeout = 1;
            var result      = command.ExecuteScalar();
            var resultAsync = await command.ExecuteScalarAsync();

            // Assert
            Assert.Equal(3, result);
            Assert.Equal(3, resultAsync);
        }
예제 #4
0
        public async Task WhenParallelisationShouldSucceed()
        {
            await using var conn = new SparkConnection(Config.ConnectionString);
            await conn.OpenAsync();

            var tableName = DataFactory.TableName();

            int order = 0;
            await DataFactory.DropAndCreateTable(conn, tableName, new[] { "order INT", "value INT" });

            await Task.WhenAll(Enumerable.Range(1, 5).Select(async _ =>
            {
                await using var insertConn = new SparkConnection(Config.ConnectionString);
                await insertConn.OpenAsync().ConfigureAwait(false);
                await Task.WhenAll(Enumerable.Range(1, 5).Select(async i =>
                {
                    var values = string.Join(",", Enumerable.Range(1, 40000).Select(i => $"({ Interlocked.Increment(ref order)}, {i})"));
                    await insertConn.ExecuteAsync($"INSERT INTO {tableName} VALUES {values}").ConfigureAwait(false);
                }));
            }).ToArray());


            var result = await conn.QueryAsync <int?>($"SELECT value FROM {tableName} ORDER BY random()");

            var resultList = result.ToList();

            Assert.Equal(1000000, resultList.Count);
        }
예제 #5
0
        public async Task WhenAtParameterWithinQuotesShouldNotReplace()
        {
            // Arrange
            await using var conn = new SparkConnection(Config.ConnectionString);
            conn.Open();

            var cmd = DataFactory.CreateCommand(conn, $@"SELECT 
""This is \"" @MyValue \"" string"" as `@MyValue string`,
'This is also \' @MyValue \' string' as `also @MyValue string`,
@MyValue+3 as MyValue");

            var param = cmd.CreateParameter();

            param.ParameterName = "MyValue";
            param.Value         = 12;
            cmd.Parameters.Add(param);

            // Act
            using var resultReader      = cmd.ExecuteReader();
            using var resultReaderAsync = await cmd.ExecuteReaderAsync();

            // Assert
            Assert.True(await resultReader.ReadAsync());
            Assert.Equal("This is \" @MyValue \" string", resultReader["@MyValue string"]);
            Assert.Equal("This is also \' @MyValue \' string", resultReader["also @MyValue string"]);
            Assert.Equal(15, resultReader["MyValue"]);
            Assert.False(await resultReader.ReadAsync());

            Assert.True(await resultReaderAsync.ReadAsync());
            Assert.Equal("This is \" @MyValue \" string", resultReaderAsync["@MyValue string"]);
            Assert.Equal("This is also \' @MyValue \' string", resultReaderAsync["also @MyValue string"]);
            Assert.Equal(15, resultReaderAsync["MyValue"]);
            Assert.False(await resultReaderAsync.ReadAsync());
        }
예제 #6
0
        public async Task ServerVersionShouldNotBeSupported()
        {
            // Arrange
            await using var conn = new SparkConnection(Config.ConnectionString);

            // Act and Assert
            Assert.Throws <NotSupportedException>(() => conn.ServerVersion);
        }
예제 #7
0
        public async Task BeginTransactionShouldNotBeSupported()
        {
            // Arrange
            await using var conn = new SparkConnection(Config.ConnectionString);

            // Act and Assert
            Assert.Throws <NotSupportedException>(() => conn.BeginTransaction());
            await Assert.ThrowsAsync <NotSupportedException>(async() => await conn.BeginTransactionAsync());
        }
예제 #8
0
        public async Task ChangeDatabaseShouldNotBeSupported()
        {
            // Arrange
            await using var conn = new SparkConnection(Config.ConnectionString);

            // Act and Assert
            Assert.Throws <NotSupportedException>(() => conn.ChangeDatabase("db2"));
            await Assert.ThrowsAsync <NotSupportedException>(() => conn.ChangeDatabaseAsync("db2"));
        }
예제 #9
0
        public async Task PrepareShouldNotBeSupported()
        {
            // Arrange
            await using var conn = new SparkConnection(Config.ConnectionString);
            var command = DataFactory.CreateCommand(conn, $"SELECT 1");

            // Act and Assert
            Assert.Throws <NotSupportedException>(() => command.Prepare());
        }
예제 #10
0
        public async Task ConnectionStringShouldBeReadonly()
        {
            // Arrange
            await using var conn = new SparkConnection(Config.ConnectionString);

            // Act and Assert

            Assert.Equal(new SparkConnectionStringBuilder(Config.ConnectionString).ConnectionString, conn.ConnectionString, ignoreCase: true);
            Assert.Throws <NotSupportedException>(() => conn.ConnectionString = Config.ConnectionString);
        }
예제 #11
0
        public async Task UpdatedRowSourceShouldNotBeSupported()
        {
            // Arrange
            await using var conn = new SparkConnection(Config.ConnectionString);
            var command = DataFactory.CreateCommand(conn, $"SELECT 1");

            // Act and Assert
            command.UpdatedRowSource = System.Data.UpdateRowSource.None;
            Assert.Throws <NotSupportedException>(() => command.UpdatedRowSource = System.Data.UpdateRowSource.FirstReturnedRecord);
        }
예제 #12
0
        public async Task DesignTimeVisibleShouldNotBeSupported()
        {
            // Arrange
            await using var conn = new SparkConnection(Config.ConnectionString);
            var command = DataFactory.CreateCommand(conn, $"SELECT 1");

            // Act and Assert
            command.DesignTimeVisible = false;
            Assert.Throws <NotSupportedException>(() => command.DesignTimeVisible = true);
        }
예제 #13
0
        public async Task CommandTypeShouldNotBeSupported()
        {
            // Arrange
            await using var conn = new SparkConnection(Config.ConnectionString);
            var command = DataFactory.CreateCommand(conn, $"SELECT 1");

            // Act and Assert
            command.CommandType = System.Data.CommandType.Text;
            Assert.Throws <NotSupportedException>(() => command.CommandType = System.Data.CommandType.StoredProcedure);
        }
예제 #14
0
        public async Task OpenCloseShouldChangeState()
        {
            // Arrange
            await using var conn = new SparkConnection(Config.ConnectionString);
            conn.Open();
            Assert.Equal(ConnectionState.Open, conn.State);

            // Assert and Act
            conn.Close();
            Assert.Equal(ConnectionState.Closed, conn.State);

            // Assert and Act
            conn.Open();
            Assert.Equal(ConnectionState.Open, conn.State);
        }
예제 #15
0
        public async Task WhenParameterMissingShouldThrow()
        {
            var table = DataFactory.TableName();

            await using var conn = new SparkConnection(Config.ConnectionString);
            await conn.OpenAsync();

            await DataFactory.DropAndCreateTable(conn, table, new[] { "myString STRING NOT NULL" });

            var ex = await Assert.ThrowsAsync <MissingParameterException>(() => conn.ExecuteAsync($@"INSERT INTO {table} VALUES (@DoesNotExist)", new
            {
                DoesExist = "test"
            }));

            Assert.Equal("DoesNotExist", ex.ParameterName);
        }
예제 #16
0
        public async Task WhenExecuteWithoutOpenShouldThrow()
        {
            // Arrange
            var table = DataFactory.TableName();

            await using var conn = new SparkConnection(Config.ConnectionString);
            var command = DataFactory.CreateCommand(conn, $"CREATE TABLE {table} (myInt INT) USING DELTA");

            // Act and Assert
            Assert.Throws <InvalidOperationException>(() => command.ExecuteReader());
            await Assert.ThrowsAsync <InvalidOperationException>(async() => await command.ExecuteReaderAsync());

            Assert.Throws <InvalidOperationException>(() => command.ExecuteScalar());
            await Assert.ThrowsAsync <InvalidOperationException>(async() => await command.ExecuteScalarAsync());

            Assert.Throws <InvalidOperationException>(() => command.ExecuteNonQuery());
            await Assert.ThrowsAsync <InvalidOperationException>(async() => await command.ExecuteNonQueryAsync());
        }
예제 #17
0
        public async Task WhenNullFirstOfManyItemsShouldReturn()
        {
            await using var conn = new SparkConnection(Config.ConnectionString);
            await conn.OpenAsync();

            var tableName = DataFactory.TableName();
            int order     = 0;
            await DataFactory.DropAndCreateTable(conn, tableName, new[] { "order INT", "value INT" });

            await conn.ExecuteAsync($"INSERT INTO {tableName} VALUES ({order++}, null)");

            Task.WaitAll(Enumerable.Range(1, 16).Select(i =>
                                                        conn.ExecuteAsync($"INSERT INTO {tableName} VALUES ({Interlocked.Increment(ref order)}, {i})")
                                                        ).ToArray());

            var result = await conn.QueryAsync <int?>($"SELECT value FROM {tableName} ORDER BY order");

            var resultList = result.ToList();

            Assert.Equal(17, resultList.Count);
            Assert.Equal(new int?[] { null }.Concat(Enumerable.Range(1, 16).Cast <int?>()).ToList(), resultList);
        }
예제 #18
0
        public async Task WhenNonQueryShouldReturnUnknownRowsUpdated()
        {
            // Arrange
            var table = DataFactory.TableName();

            await using var conn = new SparkConnection(Config.ConnectionString);
            await conn.OpenAsync();

            await DataFactory.DropAndCreateTable(conn, table, new[]
            {
                "myInt INT"
            });

            // Act
            var result      = DataFactory.CreateCommand(conn, $@"INSERT INTO {table} VALUES 
                    (1), (2), (3)").ExecuteNonQuery();
            var resultAsync = await DataFactory.CreateCommand(conn, $@"INSERT INTO {table} VALUES 
                    (1), (2), (3)").ExecuteNonQueryAsync();

            // Assert
            Assert.Equal(-1, result);
            Assert.Equal(-1, resultAsync);
        }
예제 #19
0
        public async Task WhenDapperShouldExecute()
        {
            var timestamp = new DateTime(2055, 3, 1, 21, 33, 43, 432);
            var date      = new DateTime(2055, 3, 1, 21, 33, 43, 432).Date;

            var table = DataFactory.TableName();

            await using var conn = new SparkConnection(Config.ConnectionString);
            await conn.OpenAsync();

            await DataFactory.DropAndCreateTable(conn, table, TypeRainbow.TableColumns);

            await conn.ExecuteAsync($@"INSERT INTO {table} VALUES 
                    (
                        @MyBigInt, 
                        @MyInt, 
                        @MySmallInt, 
                        @MyTinyInt, 
                        @MyBoolean,
                        @MyDouble, 
                        @MyFloat, 
                        @MyDecimal,
                        @MyString,
                        @MyDate,
                        @MyTimestamp,
                        @MyBinary,
                        array('AAA', 'BBB', 'CCC'),
                        map('AAA', 1, 'BBB', 2, 'CCC', 3)
                    )", new TypeRainbow()
            {
                MyBigInt    = Int64.MaxValue,
                MyInt       = Int32.MaxValue,
                MySmallInt  = Int16.MaxValue,
                MyTinyInt   = Byte.MaxValue,
                MyBoolean   = true,
                MyDouble    = 99999999.99d,
                MyFloat     = 99999999.99f,
                MyDecimal   = 99999999.99m,
                MyString    = "AAA",
                MyDate      = date,
                MyTimestamp = timestamp,
                MyBinary    = new byte[] { 0x48, 0x65, 0x6c, 0x6c, 0x6f }
            });

            var results = await conn.QueryAsync <TypeRainbow>($"SELECT * FROM {table}");

            var result = Assert.Single(results);

            Assert.Equal(Int64.MaxValue, result.MyBigInt);
            Assert.Equal(Int32.MaxValue, result.MyInt);
            Assert.Equal(Int16.MaxValue, result.MySmallInt);
            Assert.Equal(Byte.MaxValue, result.MyTinyInt);
            Assert.True(result.MyBoolean);
            Assert.Equal(99999999.99d, result.MyDouble);
            Assert.Equal(99999999.99f, result.MyFloat);
            Assert.Equal(99999999.99m, result.MyDecimal);
            Assert.Equal("AAA", result.MyString);
            Assert.Equal(date, result.MyDate);
            Assert.Equal(timestamp, result.MyTimestamp);
            Assert.Equal(new byte[] { 0x48, 0x65, 0x6c, 0x6c, 0x6f }, result.MyBinary);
            Assert.Equal(@"[""AAA"",""BBB"",""CCC""]", result.MyArray);
            Assert.Equal(@"{""AAA"":1,""BBB"":2,""CCC"":3}", result.MyMap);
        }