public void Timeout() { var connectionStringBuilder = new SpannerConnectionStringBuilder("timeout=100"); Assert.Equal(100, connectionStringBuilder.Timeout); connectionStringBuilder.Timeout = 10; Assert.Equal(10, connectionStringBuilder.Timeout); // DbConnectionStringBuilder lower-cases keywords, annoyingly. Assert.Equal("timeout=10", connectionStringBuilder.ToString()); Assert.Throws <ArgumentOutOfRangeException>(() => connectionStringBuilder.Timeout = -1); }
public void MaxConcurrentStreamsLowWatermark() { var connectionStringBuilder = new SpannerConnectionStringBuilder("MaxConcurrentStreamsLowWatermark=100"); Assert.Equal(100, connectionStringBuilder.MaxConcurrentStreamsLowWatermark); connectionStringBuilder.MaxConcurrentStreamsLowWatermark = 10; Assert.Equal(10, connectionStringBuilder.MaxConcurrentStreamsLowWatermark); // DbConnectionStringBuilder lower-cases keywords, annoyingly. Assert.Equal("maxconcurrentstreamslowwatermark=10", connectionStringBuilder.ToString()); Assert.Throws <ArgumentOutOfRangeException>(() => connectionStringBuilder.MaxConcurrentStreamsLowWatermark = 0); }
public void EndPointSettableViaProperty() { var connectionStringBuilder = new SpannerConnectionStringBuilder { Host = "foo", Port = 1234 }; Assert.Equal("foo", connectionStringBuilder.Host); Assert.Equal(1234, connectionStringBuilder.Port); }
public void MaximumGrpcChannels() { var connectionStringBuilder = new SpannerConnectionStringBuilder("MaximumGrpcChannels=5"); Assert.Equal(5, connectionStringBuilder.MaximumGrpcChannels); connectionStringBuilder.MaximumGrpcChannels = 10; Assert.Equal(10, connectionStringBuilder.MaximumGrpcChannels); // DbConnectionStringBuilder lower-cases keywords, annoyingly. Assert.Equal("maximumgrpcchannels=10", connectionStringBuilder.ToString()); Assert.Throws <ArgumentOutOfRangeException>(() => connectionStringBuilder.MaximumGrpcChannels = 0); }
public async Task CredentialFile() { string appFolder = AppDomain.CurrentDomain.BaseDirectory; string jsonFile = Path.Combine(appFolder, "SpannerEF-8dfc036f6000.json"); Assert.True(File.Exists(jsonFile)); var builder = new SpannerConnectionStringBuilder($"CredentialFile={jsonFile}"); var options = new SpannerClientCreationOptions(builder); Assert.NotNull(await options.GetCredentialsAsync()); }
public void EndPointSettableViaProperty() { var connectionStringBuilder = new SpannerConnectionStringBuilder { Host = "foo", Port = 1234 }; Assert.Equal("foo", connectionStringBuilder.Host); Assert.Equal(1234, connectionStringBuilder.Port); Assert.Throws <ArgumentOutOfRangeException>(() => connectionStringBuilder.Port = 0); }
/// <summary> /// Creates a connection to the Cloud Spanner instance that is referenced by <see cref="RelationalConnection.ConnectionString"/>. /// The connection is not associated with any specific database. /// </summary> public ISpannerRelationalConnection CreateMasterConnection() { var builder = new SpannerConnectionStringBuilder(ConnectionString); //Spanner actually has no master or admin db, so we just use a normal connection. var masterConn = new SpannerRetriableConnection(new SpannerConnection($"Data Source=projects/{builder.Project}/instances/{builder.SpannerInstance}")); var optionsBuilder = new DbContextOptionsBuilder(); optionsBuilder.UseSpanner(masterConn); return(new SpannerRelationalConnection(Dependencies.With(optionsBuilder.Options))); }
public void LogCommitStats() { var connectionStringBuilder = new SpannerConnectionStringBuilder("LogCommitStats=true"); Assert.True(connectionStringBuilder.LogCommitStats); connectionStringBuilder.LogCommitStats = false; Assert.False(connectionStringBuilder.LogCommitStats); // DbConnectionStringBuilder lower-cases keywords, annoyingly. Assert.Equal("logcommitstats=False", connectionStringBuilder.ToString()); connectionStringBuilder = new SpannerConnectionStringBuilder(""); Assert.False(connectionStringBuilder.LogCommitStats); }
public void DataSourceSettableViaProperty() { var connectionStringBuilder = new SpannerConnectionStringBuilder { DataSource = "projects/project1/instances/instance1/databases/database1" }; Assert.Equal("project1", connectionStringBuilder.Project); Assert.Equal("instance1", connectionStringBuilder.SpannerInstance); Assert.Equal("database1", connectionStringBuilder.SpannerDatabase); }
public MigrationsSpannerFixture() { var serviceProvider = new ServiceCollection() .AddEntityFrameworkSpanner() .BuildServiceProvider(); var connectionStringBuilder = new SpannerConnectionStringBuilder(TestEnvironment.DefaultConnection) .WithDatabase(nameof(MigrationsSpannerTest)); _options = new DbContextOptionsBuilder() .UseInternalServiceProvider(serviceProvider) .UseSpanner(connectionStringBuilder.ConnectionString).Options; }
public void OpenWithNoDatabase_InvalidCredentials() { var builder = new SpannerConnectionStringBuilder { DataSource = "projects/project_id/instances/instance_id", CredentialFile = "this_will_not_exist.json" }; using (var connection = new SpannerConnection(builder)) { Assert.Throws <FileNotFoundException>(() => connection.Open()); } }
public NavigationTestFixture() { var serviceProvider = new ServiceCollection() .AddEntityFrameworkSpanner() .BuildServiceProvider(); var connStrBuilder = new SpannerConnectionStringBuilder(TestEnvironment.DefaultConnection); _options = new DbContextOptionsBuilder() .UseSpanner(connStrBuilder.ConnectionString) .UseInternalServiceProvider(serviceProvider) .Options; }
public void WithDatabase() { var connectionStringBuilder = new SpannerConnectionStringBuilder("Data Source=projects/project1/instances/instance1"); Assert.Null(connectionStringBuilder.SpannerDatabase); connectionStringBuilder = connectionStringBuilder.WithDatabase("db1"); Assert.Equal("db1", connectionStringBuilder.SpannerDatabase); connectionStringBuilder = connectionStringBuilder.WithDatabase("db2"); Assert.Equal("db2", connectionStringBuilder.SpannerDatabase); connectionStringBuilder = connectionStringBuilder.WithDatabase(null); Assert.Null(connectionStringBuilder.SpannerDatabase); }
public void WithDatabase() { var builder = new SpannerConnectionStringBuilder("Data Source=projects/project1/instances/instance1"); Assert.Null(builder.SpannerDatabase); builder = builder.WithDatabase("db1"); Assert.Equal("project1", builder.Project); Assert.Equal("instance1", builder.SpannerInstance); Assert.Equal("db1", builder.SpannerDatabase); builder = builder.WithDatabase("db2"); Assert.Equal("db2", builder.SpannerDatabase); builder = builder.WithDatabase(null); Assert.Null(builder.SpannerDatabase); }
public static string CreateConnectionString(string name) { var builder = new SpannerConnectionStringBuilder(TestEnvironment.DefaultConnection); if (string.IsNullOrEmpty(name)) { builder.DataSource = $"projects/{builder.Project}/instances/{builder.SpannerInstance}"; } else { builder.DataSource = $"projects/{builder.Project}/instances/{builder.SpannerInstance}/databases/{name}"; } return(builder.ConnectionString); }
public void DatabaseName() { var builder = new SpannerConnectionStringBuilder(); Assert.Null(builder.DatabaseName); builder.DataSource = "projects/x/instances/y/databases/z"; Assert.Equal(new DatabaseName("x", "y", "z"), builder.DatabaseName); builder.DatabaseName = new DatabaseName("a", "b", "c"); Assert.Equal("projects/a/instances/b/databases/c", builder.DataSource); builder.DatabaseName = null; Assert.Null(builder.DatabaseName); Assert.Equal("", builder.DataSource); }
public async Task CreateWithExtrasDrop2() { string dbName = GenerateDatabaseName(); var builder = new SpannerConnectionStringBuilder(_fixture.Database.NoDbConnectionString); using (var connection = new SpannerConnection(builder)) { var createCmd = connection.CreateDdlCommand( $"CREATE DATABASE {dbName}"); await createCmd.ExecuteNonQueryAsync().ConfigureAwait(false); } using (var connection = new SpannerConnection(builder.WithDatabase(dbName))) { const string tableCreate1 = @"CREATE TABLE TX1 ( K STRING(MAX) NOT NULL, StringValue STRING(MAX), ) PRIMARY KEY (K)"; const string tableCreate2 = @"CREATE TABLE TX2 ( K STRING(MAX) NOT NULL, StringValue STRING(MAX), ) PRIMARY KEY (K)"; var updateCmd = connection.CreateDdlCommand(tableCreate1, tableCreate2); await updateCmd.ExecuteNonQueryAsync().ConfigureAwait(false); var cmd = connection.CreateInsertCommand("TX2", new SpannerParameterCollection { { "K", SpannerDbType.String, "key" }, { "StringValue", SpannerDbType.String, "value" } }); await cmd.ExecuteNonQueryAsync(); cmd = connection.CreateSelectCommand("SELECT * FROM TX2"); using (var reader = await cmd.ExecuteReaderAsync()) { await reader.ReadAsync(); Assert.Equal("key", reader.GetFieldValue <string>("K")); Assert.Equal("value", reader.GetFieldValue <string>("StringValue")); } } using (var connection = new SpannerConnection(builder)) { var dropCommand = connection.CreateDdlCommand($"DROP DATABASE {dbName}"); await dropCommand.ExecuteNonQueryAsync().ConfigureAwait(false); } }
public void EmulatorDetectionProperty() { var connectionStringBuilder = new SpannerConnectionStringBuilder("EmulatorDetection=EmulatorOnly"); Assert.Equal(EmulatorDetection.EmulatorOnly, connectionStringBuilder.EmulatorDetection); connectionStringBuilder.EmulatorDetection = EmulatorDetection.ProductionOnly; Assert.Equal(EmulatorDetection.ProductionOnly, connectionStringBuilder.EmulatorDetection); // DbConnectionStringBuilder lower-cases keywords, annoyingly. Assert.Equal("emulatordetection=ProductionOnly", connectionStringBuilder.ToString()); // Ignores invalid values set in the connection string. var invalidConnectionStringBuilder = new SpannerConnectionStringBuilder("EmulatorDetection=Prod"); Assert.Equal(EmulatorDetection.None, invalidConnectionStringBuilder.EmulatorDetection); Assert.Throws <ArgumentException>(() => connectionStringBuilder.EmulatorDetection = (EmulatorDetection)(-1)); }
public async Task EmulatorDetection_AlwaysUsesRegularOptions(string emulatorHost) { var regularOptions = new SessionPoolOptions(); var manager = new SessionPoolManager(regularOptions, SessionPoolManager.CreateDefaultSpannerSettings(), Logger.DefaultLogger, FailingSpannerClient.Factory); var builder = new SpannerConnectionStringBuilder(ConnectionString) { EmulatorDetection = EmulatorDetection.EmulatorOrProduction, // Effectively "there are no environment variables" EnvironmentVariableProvider = key => key == "SPANNER_EMULATOR_HOST" ? emulatorHost: null }; var clientCreationOptions = new SpannerClientCreationOptions(new SpannerConnectionStringBuilder(ConnectionString)); var pool = await manager.AcquireSessionPoolAsync(clientCreationOptions); Assert.Same(regularOptions, pool.Options); }
public SnippetFixture() { var builder = new SpannerConnectionStringBuilder { Host = SpannerHost, DataSource = $"projects/{ProjectId}/instances/{SpannerInstance}" }; if (SpannerPort != null) { builder.Port = int.Parse(SpannerPort); } NoDbConnectionString = builder.ConnectionString; ConnectionString = builder.WithDatabase(SpannerDatabase).ConnectionString; _creationTask = new Lazy<Task>(EnsureTestDatabaseImplAsync); }
public async Task DdlCommandReturnsErrors() { string dbName = GenerateDatabaseName(); var builder = new SpannerConnectionStringBuilder(_fixture.Database.NoDbConnectionString); using (var connection = new SpannerConnection(builder)) { const string tableSingers = @" CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), ComposerInfo BYTES(MAX), ) PRIMARY KEY(SingerId)"; const string tableAlbums = @"CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX), ) PRIMARY KEY(SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE"; var createCmd = connection.CreateDdlCommand( $"CREATE DATABASE {dbName}", tableSingers, tableAlbums); await createCmd.ExecuteNonQueryAsync().ConfigureAwait(false); } using (var connection = new SpannerConnection(builder.WithDatabase(dbName))) { var dropSingersCmd = connection.CreateDdlCommand("DROP TABLE Singers"); var dropAlbumsCmd = connection.CreateDdlCommand("DROP TABLE Albums"); await Assert.ThrowsAsync <SpannerException>(() => dropSingersCmd.ExecuteNonQueryAsync()); await dropAlbumsCmd.ExecuteNonQueryAsync(); await dropSingersCmd.ExecuteNonQueryAsync(); } using (var connection = new SpannerConnection(builder)) { var dropCommand = connection.CreateDdlCommand($"DROP DATABASE {dbName}"); await dropCommand.ExecuteNonQueryAsync().ConfigureAwait(false); } }
public void ClientCreatedWithEmulatorDetection() { Mock <SpannerClient> spannerClientMock = SpannerClientHelpers .CreateMockClient(Logger.DefaultLogger, MockBehavior.Strict); spannerClientMock .SetupBatchCreateSessionsAsync() .SetupExecuteStreamingSql(); var spannerClient = spannerClientMock.Object; var sessionPoolOptions = new SessionPoolOptions { MaintenanceLoopDelay = TimeSpan.Zero }; var sessionPoolManager = new SessionPoolManager( sessionPoolOptions, spannerClient.Settings.Logger, (_o, _s, _l) => { Assert.True(_o.UsesEmulator); return(Task.FromResult(spannerClient)); }); SpannerConnectionStringBuilder builder = new SpannerConnectionStringBuilder { DataSource = DatabaseName.Format(SpannerClientHelpers.ProjectId, SpannerClientHelpers.Instance, SpannerClientHelpers.Database), SessionPoolManager = sessionPoolManager, EmulatorDetection = EmulatorDetection.EmulatorOrProduction, EnvironmentVariableProvider = key => key == "SPANNER_EMULATOR_HOST" ? "localhost" : null }; var connection = new SpannerConnection(builder); var command = connection.CreateSelectCommand("SELECT * FROM FOO"); using (var reader = command.ExecuteReader()) { Assert.True(reader.HasRows); } spannerClientMock.Verify(client => client.ExecuteStreamingSql( It.IsAny <ExecuteSqlRequest>(), It.IsAny <CallSettings>()), Times.Once()); }
private SpannerConnection BuildSpannerConnection(Mock<SpannerClient> spannerClientMock) { var spannerClient = spannerClientMock.Object; var sessionPoolOptions = new SessionPoolOptions { MaintenanceLoopDelay = TimeSpan.Zero }; var sessionPoolManager = new SessionPoolManager(sessionPoolOptions, spannerClient.Settings.Logger, (_o, _s, _l) => Task.FromResult(spannerClient)); sessionPoolManager.SpannerSettings.Scheduler = spannerClient.Settings.Scheduler; sessionPoolManager.SpannerSettings.Clock = spannerClient.Settings.Clock; SpannerConnectionStringBuilder builder = new SpannerConnectionStringBuilder { DataSource = DatabaseName.Format(SpannerClientHelpers.ProjectId, SpannerClientHelpers.Instance, SpannerClientHelpers.Database), SessionPoolManager = sessionPoolManager }; return new SpannerConnection(builder); }
internal void SetConnectionString(string value, ChannelCredentials channelCredentials = null) { lock (lck) { if (_connectionString == null && _connectionStringBuilder != null) { // This means that the provider has already seen at least two different // connection strings. return; } var builder = new SpannerConnectionStringBuilder(value); // Ignore connection strings without a valid database. if (builder.DatabaseName == null) { return; } // Check if this is the first valid connection string that has been set. // If so, register this as THE connection string and use that for validation. if (_connectionString == null && _connectionStringBuilder == null) { // This is the first valid connection string. _connectionStringBuilder = builder; _connectionString = value; _channelCredentials = channelCredentials; return; } // This is not the first valid connection string. Check whether the new // connection string is connecting to the same database. If it is, it is // still safe to do validation against the database. if (!builder.DatabaseName.Equals(_connectionStringBuilder.DatabaseName)) { // The application is connecting to a new database. It is no longer safe // to validate against the database, as there is no guarantee that the // order of validation will be equal to the order of calling UseSpanner(connectionString). _connectionString = null; _channelCredentials = null; } } }
private SpannerTestDatabase(string projectId) { TestLogger.Install(); ProjectId = projectId; var builder = new SpannerConnectionStringBuilder { Host = SpannerHost, DataSource = $"projects/{ProjectId}/instances/{SpannerInstance}", EmulatorDetection = EmulatorDetection.EmulatorOrProduction }; if (SpannerPort != null) { builder.Port = int.Parse(SpannerPort); } NoDbConnectionString = builder.ConnectionString; SpannerClientCreationOptions = new SpannerClientCreationOptions(builder); var databaseBuilder = builder.WithDatabase(SpannerDatabase); ConnectionString = databaseBuilder.ConnectionString; DatabaseName = databaseBuilder.DatabaseName; MaybeCreateInstanceOnEmulator(projectId); if (Fresh) { using (var connection = new SpannerConnection(NoDbConnectionString)) { var createCmd = connection.CreateDdlCommand($"CREATE DATABASE {SpannerDatabase}"); createCmd.ExecuteNonQuery(); Logger.DefaultLogger.Debug($"Created database {SpannerDatabase}"); } } else { Logger.DefaultLogger.Debug($"Using existing database {SpannerDatabase}"); } }
internal static async Task RunSampleAsync(Func <string, Task> sampleMethod) { Environment.SetEnvironmentVariable("SPANNER_EMULATOR_HOST", "localhost:9010"); var emulatorRunner = new EmulatorRunner(); try { Console.WriteLine(""); Console.WriteLine("Starting emulator..."); emulatorRunner.StartEmulator().WaitWithUnwrappedExceptions(); Console.WriteLine(""); var projectId = "sample-project"; var instanceId = "sample-instance"; var databaseId = "sample-database"; DatabaseName databaseName = DatabaseName.FromProjectInstanceDatabase(projectId, instanceId, databaseId); var dataSource = $"Data Source={databaseName}"; var connectionStringBuilder = new SpannerConnectionStringBuilder(dataSource) { EmulatorDetection = EmulatorDetection.EmulatorOnly, }; await MaybeCreateInstanceOnEmulatorAsync(databaseName.ProjectId, databaseName.InstanceId); await MaybeCreateDatabaseOnEmulatorAsync(databaseName); await sampleMethod.Invoke(connectionStringBuilder.ConnectionString); } catch (Exception e) { Console.WriteLine($"Running sample failed: {e.Message}"); } finally { Console.WriteLine(""); Console.WriteLine("Stopping emulator..."); emulatorRunner.StopEmulator().WaitWithUnwrappedExceptions(); Console.WriteLine(""); } }
public void Equality_DefaultHostAndPort() { string dataSource = "projects/p1/instances/i1/databases/d1"; var builder = new SpannerConnectionStringBuilder { DataSource = dataSource }; // Timeout doesn't matter var equalBuilder = new SpannerConnectionStringBuilder($"Data Source={dataSource}; Timeout=100"); var unequalBuilders = new[] { new SpannerConnectionStringBuilder { DataSource = dataSource, CredentialFile = "creds.json" }, new SpannerConnectionStringBuilder($"Data Source={dataSource}", new ComputeCredential().ToChannelCredentials()) }; var options = new SpannerClientCreationOptions(builder); var equalOptions = new SpannerClientCreationOptions(equalBuilder); var unequalOptions = unequalBuilders.Select(b => new SpannerClientCreationOptions(b)).ToArray(); EqualityTester.AssertEqual(options, new[] { equalOptions }, unequalOptions); }
public async Task CredentialFileNotFound() { var builder = new SpannerConnectionStringBuilder("CredentialFile=..\\BadFilePath.json"); var options = new SpannerClientCreationOptions(builder); await Assert.ThrowsAsync <FileNotFoundException>(() => options.GetCredentialsAsync()); }
public async Task CredentialFileP12Error() { var builder = new SpannerConnectionStringBuilder("CredentialFile=SpannerEF-8dfc036f6000.p12"); var options = new SpannerClientCreationOptions(builder); await Assert.ThrowsAsync <InvalidOperationException>(() => options.GetCredentialsAsync()); }
public void EmptyInstance_EmptyConnectionString() { var builder = new SpannerConnectionStringBuilder(); Assert.Equal("", builder.ConnectionString); }