Set up tests on postgres

This commit is contained in:
ta264 2022-03-28 21:46:21 +01:00 committed by Robin Dadswell
parent bd53092f0c
commit 9b21408a03
14 changed files with 538 additions and 18 deletions

View File

@ -515,6 +515,61 @@ stages:
testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(testName) Unit Tests'
failTaskOnFailedTests: true
- job: Unit_LinuxCore_Postgres
displayName: Unit Native LinuxCore with Postgres Database
dependsOn: Prepare
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
variables:
pattern: 'Radarr.*.linux-core-x64.tar.gz'
artifactName: LinuxCoreTests
Radarr__Postgres__Host: 'localhost'
Radarr__Postgres__Port: '5432'
Radarr__Postgres__User: 'radarr'
Radarr__Postgres__Password: 'radarr'
pool:
vmImage: 'ubuntu-18.04'
timeoutInMinutes: 10
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
inputs:
version: $(dotnetVersion)
- checkout: none
- task: DownloadPipelineArtifact@2
displayName: Download Test Artifact
inputs:
buildType: 'current'
artifactName: $(artifactName)
targetPath: $(testsFolder)
- bash: |
chmod a+x _tests/ffprobe
displayName: Make ffprobe Executable
- bash: find ${TESTSFOLDER} -name "Radarr.Test.Dummy" -exec chmod a+x {} \;
displayName: Make Test Dummy Executable
condition: and(succeeded(), ne(variables['osName'], 'Windows'))
- bash: |
docker run -d --name=postgres14 \
-e POSTGRES_PASSWORD=radarr \
-e POSTGRES_USER=radarr \
-p 5432:5432/tcp \
postgres:14
displayName: Start postgres
- bash: |
chmod a+x ${TESTSFOLDER}/test.sh
ls -lR ${TESTSFOLDER}
${TESTSFOLDER}/test.sh Linux Unit Test
displayName: Run Tests
- task: PublishTestResults@2
displayName: Publish Test Results
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '**/TestResult.xml'
testRunTitle: 'LinuxCore Postgres Unit Tests'
failTaskOnFailedTests: true
- stage: Integration
displayName: Integration
@ -599,6 +654,67 @@ stages:
failTaskOnFailedTests: true
displayName: Publish Test Results
- job: Integration_LinuxCore_Postgres
displayName: Integration Native LinuxCore with Postgres Database
dependsOn: Prepare
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
variables:
pattern: 'Radarr.*.linux-core-x64.tar.gz'
Radarr__Postgres__Host: 'localhost'
Radarr__Postgres__Port: '5432'
Radarr__Postgres__User: 'radarr'
Radarr__Postgres__Password: 'radarr'
pool:
vmImage: 'ubuntu-18.04'
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
inputs:
version: $(dotnetVersion)
- checkout: none
- task: DownloadPipelineArtifact@2
displayName: Download Test Artifact
inputs:
buildType: 'current'
artifactName: 'LinuxCoreTests'
targetPath: $(testsFolder)
- task: DownloadPipelineArtifact@2
displayName: Download Build Artifact
inputs:
buildType: 'current'
artifactName: Packages
itemPattern: '**/$(pattern)'
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
mkdir -p ./bin/
cp -r -v ${BUILD_ARTIFACTSTAGINGDIRECTORY}/bin/Radarr/. ./bin/
displayName: Move Package Contents
- bash: |
docker run -d --name=postgres14 \
-e POSTGRES_PASSWORD=radarr \
-e POSTGRES_USER=radarr \
-p 5432:5432/tcp \
postgres:14
displayName: Start postgres
- bash: |
chmod a+x ${TESTSFOLDER}/test.sh
${TESTSFOLDER}/test.sh Linux Integration Test
displayName: Run Integration Tests
- task: PublishTestResults@2
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '**/TestResult.xml'
testRunTitle: 'Integration LinuxCore Postgres Database Integration Tests'
failTaskOnFailedTests: true
displayName: Publish Test Results
- job: Integration_FreeBSD
displayName: Integration Native FreeBSD
dependsOn: Prepare

View File

@ -44,7 +44,7 @@ namespace NzbDrone.Automation.Test
driver.Manage().Window.Size = new System.Drawing.Size(1920, 1080);
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger());
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger(), null);
_runner.KillAll();
_runner.Start();

View File

@ -0,0 +1,206 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.Datastore
{
[TestFixture]
public class WhereBuilderPostgresFixture : CoreTest
{
private WhereBuilderPostgres _subject;
[OneTimeSetUp]
public void MapTables()
{
// Generate table mapping
Mocker.Resolve<DbFactory>();
}
private WhereBuilderPostgres Where(Expression<Func<Movie, bool>> filter)
{
return new WhereBuilderPostgres(filter, true, 0);
}
[Test]
public void postgres_where_equal_const()
{
_subject = Where(x => x.Id == 10);
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = @Clause1_P1)");
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(10);
}
[Test]
public void postgres_where_equal_variable()
{
var id = 10;
_subject = Where(x => x.Id == id);
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = @Clause1_P1)");
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(id);
}
[Test]
public void postgres_where_equal_property()
{
var movie = new Movie { Id = 10 };
_subject = Where(x => x.Id == movie.Id);
_subject.Parameters.ParameterNames.Should().HaveCount(1);
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = @Clause1_P1)");
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(movie.Id);
}
[Test]
public void postgres_where_equal_joined_property()
{
_subject = Where(x => x.Profile.Id == 1);
_subject.Parameters.ParameterNames.Should().HaveCount(1);
_subject.ToString().Should().Be($"(\"Profiles\".\"Id\" = @Clause1_P1)");
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(1);
}
[Test]
public void postgres_where_throws_without_concrete_condition_if_requiresConcreteCondition()
{
Expression<Func<Movie, Movie, bool>> filter = (x, y) => x.Id == y.Id;
_subject = new WhereBuilderPostgres(filter, true, 0);
Assert.Throws<InvalidOperationException>(() => _subject.ToString());
}
[Test]
public void postgres_where_allows_abstract_condition_if_not_requiresConcreteCondition()
{
Expression<Func<Movie, Movie, bool>> filter = (x, y) => x.Id == y.Id;
_subject = new WhereBuilderPostgres(filter, false, 0);
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = \"Movies\".\"Id\")");
}
[Test]
public void postgres_where_string_is_null()
{
_subject = Where(x => x.CleanTitle == null);
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
}
[Test]
public void postgres_where_string_is_null_value()
{
string cleanTitle = null;
_subject = Where(x => x.CleanTitle == cleanTitle);
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
}
[Test]
public void postgres_where_equal_null_property()
{
var movie = new Movie { CleanTitle = null };
_subject = Where(x => x.CleanTitle == movie.CleanTitle);
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
}
[Test]
public void postgres_where_column_contains_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.Contains(test));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" ILIKE '%' || @Clause1_P1 || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
[Test]
public void postgres_where_string_contains_column()
{
var test = "small";
_subject = Where(x => test.Contains(x.CleanTitle));
_subject.ToString().Should().Be($"(@Clause1_P1 ILIKE '%' || \"Movies\".\"CleanTitle\" || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
[Test]
public void postgres_where_column_starts_with_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.StartsWith(test));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" ILIKE @Clause1_P1 || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
[Test]
public void postgres_where_column_ends_with_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.EndsWith(test));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" ILIKE '%' || @Clause1_P1)");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
[Test]
public void postgres_where_in_list()
{
var list = new List<int> { 1, 2, 3 };
_subject = Where(x => list.Contains(x.Id));
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = ANY (('{{1, 2, 3}}')))");
}
[Test]
public void postgres_where_in_list_2()
{
var list = new List<int> { 1, 2, 3 };
_subject = Where(x => x.CleanTitle == "test" && list.Contains(x.Id));
_subject.ToString().Should().Be($"((\"Movies\".\"CleanTitle\" = @Clause1_P1) AND (\"Movies\".\"Id\" = ANY (('{{1, 2, 3}}'))))");
}
[Test]
public void postgres_where_in_string_list()
{
var list = new List<string> { "first", "second", "third" };
_subject = Where(x => list.Contains(x.CleanTitle));
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" = ANY (@Clause1_P1))");
}
[Test]
public void enum_as_int()
{
_subject = Where(x => x.Status == MovieStatusType.Announced);
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = @Clause1_P1)");
}
[Test]
public void enum_in_list()
{
var allowed = new List<MovieStatusType> { MovieStatusType.Announced, MovieStatusType.InCinemas };
_subject = Where(x => allowed.Contains(x.Status));
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = ANY (@Clause1_P1))");
}
[Test]
public void enum_in_array()
{
var allowed = new MovieStatusType[] { MovieStatusType.Announced, MovieStatusType.InCinemas };
_subject = Where(x => allowed.Contains(x.Status));
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = ANY (@Clause1_P1))");
}
}
}

View File

@ -1,14 +1,18 @@
using System;
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Npgsql;
using NUnit.Framework;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Test.Common.Datastore;
namespace NzbDrone.Core.Test.Framework
{
@ -49,6 +53,7 @@ namespace NzbDrone.Core.Test.Framework
public abstract class DbTest : CoreTest
{
private ITestDatabase _db;
private DatabaseType _databaseType;
protected virtual MigrationType MigrationType => MigrationType.Main;
@ -101,17 +106,39 @@ namespace NzbDrone.Core.Test.Framework
private IDatabase CreateDatabase(MigrationContext migrationContext)
{
if (_databaseType == DatabaseType.PostgreSQL)
{
CreatePostgresDb();
}
var factory = Mocker.Resolve<DbFactory>();
// If a special migration test or log migration then create new
if (migrationContext.BeforeMigration != null)
if (migrationContext.BeforeMigration != null || _databaseType == DatabaseType.PostgreSQL)
{
return factory.Create(migrationContext);
}
return CreateSqliteDatabase(factory, migrationContext);
}
private void CreatePostgresDb()
{
var options = Mocker.Resolve<IOptions<PostgresOptions>>().Value;
PostgresDatabase.Create(options, MigrationType);
}
private void DropPostgresDb()
{
var options = Mocker.Resolve<IOptions<PostgresOptions>>().Value;
PostgresDatabase.Drop(options, MigrationType);
}
private IDatabase CreateSqliteDatabase(IDbFactory factory, MigrationContext migrationContext)
{
// Otherwise try to use a cached migrated db
var cachedDb = GetCachedDatabase(migrationContext.MigrationType);
var testDb = GetTestDb(migrationContext.MigrationType);
var cachedDb = SqliteDatabase.GetCachedDb(migrationContext.MigrationType);
var testDb = GetTestSqliteDb(migrationContext.MigrationType);
if (File.Exists(cachedDb))
{
TestLogger.Info($"Using cached initial database {cachedDb}");
@ -131,12 +158,7 @@ namespace NzbDrone.Core.Test.Framework
}
}
private string GetCachedDatabase(MigrationType type)
{
return Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_{type}.db");
}
private string GetTestDb(MigrationType type)
private string GetTestSqliteDb(MigrationType type)
{
return type == MigrationType.Main ? TestFolderInfo.GetDatabase() : TestFolderInfo.GetLogDatabase();
}
@ -151,6 +173,13 @@ namespace NzbDrone.Core.Test.Framework
WithTempAsAppPath();
SetupLogging();
// populate the possible postgres options
var postgresOptions = PostgresDatabase.GetTestOptions();
_databaseType = postgresOptions.Host.IsNotNullOrWhiteSpace() ? DatabaseType.PostgreSQL : DatabaseType.SQLite;
// Set up remaining container services
Mocker.SetConstant(Options.Create(postgresOptions));
Mocker.SetConstant<IConfigFileProvider>(Mocker.Resolve<ConfigFileProvider>());
Mocker.SetConstant<IConnectionStringFactory>(Mocker.Resolve<ConnectionStringFactory>());
Mocker.SetConstant<IMigrationController>(Mocker.Resolve<MigrationController>());
@ -170,12 +199,19 @@ namespace NzbDrone.Core.Test.Framework
// Make sure there are no lingering connections. (When this happens it means we haven't disposed something properly)
GC.Collect();
GC.WaitForPendingFinalizers();
SQLiteConnection.ClearAllPools();
NpgsqlConnection.ClearAllPools();
if (TestFolderInfo != null)
{
DeleteTempFolder(TestFolderInfo.AppDataFolder);
}
if (_databaseType == DatabaseType.PostgreSQL)
{
DropPostgresDb();
}
}
}
}

View File

@ -1,5 +1,7 @@
using System.IO;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Test.Common.Datastore;
namespace NzbDrone.Core.Test
{
@ -10,13 +12,13 @@ namespace NzbDrone.Core.Test
[OneTimeTearDown]
public void ClearCachedDatabase()
{
var mainCache = Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_Main.db");
var mainCache = SqliteDatabase.GetCachedDb(MigrationType.Main);
if (File.Exists(mainCache))
{
File.Delete(mainCache);
}
var logCache = Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_Log.db");
var logCache = SqliteDatabase.GetCachedDb(MigrationType.Log);
if (File.Exists(logCache))
{
File.Delete(logCache);

View File

@ -23,6 +23,7 @@ namespace NzbDrone.Core.Test.Framework
where T : ModelBase, new();
IDirectDataMapper GetDirectDataMapper();
IDbConnection OpenConnection();
DatabaseType DatabaseType { get; }
}
public class TestDatabase : ITestDatabase
@ -30,6 +31,8 @@ namespace NzbDrone.Core.Test.Framework
private readonly IDatabase _dbConnection;
private readonly IEventAggregator _eventAggregator;
public DatabaseType DatabaseType => _dbConnection.DatabaseType;
public TestDatabase(IDatabase dbConnection)
{
_eventAggregator = new Mock<IEventAggregator>().Object;

View File

@ -7,7 +7,6 @@ using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Exceptions;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore

View File

@ -1,3 +1,5 @@
using Microsoft.Extensions.Configuration;
namespace NzbDrone.Core.Datastore
{
public class PostgresOptions
@ -8,5 +10,17 @@ namespace NzbDrone.Core.Datastore
public string Password { get; set; }
public string MainDb { get; set; }
public string LogDb { get; set; }
public static PostgresOptions GetOptions()
{
var config = new ConfigurationBuilder()
.AddEnvironmentVariables("Radarr__")
.Build();
var postgresOptions = new PostgresOptions();
config.GetSection("Postgres").Bind(postgresOptions);
return postgresOptions;
}
}
}

View File

@ -91,7 +91,7 @@ namespace NzbDrone.Core.Datastore
// Only use the SQL condition if the expression didn't resolve to an actual value
if (tableName != null && !gotValue)
{
_sb.Append($"\"{tableName}\".\"{expression.Member.Name.ToLower()}\"");
_sb.Append($"\"{tableName}\".\"{expression.Member.Name}\"");
}
else
{

View File

@ -1,9 +1,15 @@
using System.Collections.Generic;
using System.Threading;
using Microsoft.Extensions.Configuration;
using NLog;
using Npgsql;
using NUnit.Framework;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Core.Indexers.Newznab;
using NzbDrone.Test.Common;
using NzbDrone.Test.Common.Datastore;
using Radarr.Http.ClientSchema;
namespace NzbDrone.Integration.Test
@ -19,6 +25,8 @@ namespace NzbDrone.Integration.Test
protected int Port { get; private set; }
protected PostgresOptions PostgresOptions { get; set; } = new ();
protected override string RootUrl => $"http://localhost:{Port}/";
protected override string ApiKey => _runner.ApiKey;
@ -27,7 +35,14 @@ namespace NzbDrone.Integration.Test
{
Port = Interlocked.Increment(ref StaticPort);
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger(), Port);
PostgresOptions = PostgresDatabase.GetTestOptions();
if (PostgresOptions?.Host != null)
{
CreatePostgresDb(PostgresOptions);
}
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger(), PostgresOptions, Port);
_runner.Kill();
_runner.Start();
@ -59,6 +74,22 @@ namespace NzbDrone.Integration.Test
protected override void StopTestTarget()
{
_runner.Kill();
if (PostgresOptions?.Host != null)
{
DropPostgresDb(PostgresOptions);
}
}
private static void CreatePostgresDb(PostgresOptions options)
{
PostgresDatabase.Create(options, MigrationType.Main);
PostgresDatabase.Create(options, MigrationType.Log);
}
private static void DropPostgresDb(PostgresOptions options)
{
PostgresDatabase.Drop(options, MigrationType.Main);
PostgresDatabase.Drop(options, MigrationType.Log);
}
}
}

View File

@ -0,0 +1,69 @@
using System;
using Npgsql;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Test.Common.Datastore
{
public static class PostgresDatabase
{
public static PostgresOptions GetTestOptions()
{
var options = PostgresOptions.GetOptions();
var uid = TestBase.GetUID();
options.MainDb = uid + "_main";
options.LogDb = uid + "_log";
return options;
}
public static void Create(PostgresOptions options, MigrationType migrationType)
{
var db = GetDatabaseName(options, migrationType);
var connectionString = GetConnectionString(options);
using var conn = new NpgsqlConnection(connectionString);
conn.Open();
using var cmd = conn.CreateCommand();
cmd.CommandText = $"CREATE DATABASE \"{db}\" WITH OWNER = {options.User} ENCODING = 'UTF8' CONNECTION LIMIT = -1;";
cmd.ExecuteNonQuery();
}
public static void Drop(PostgresOptions options, MigrationType migrationType)
{
var db = GetDatabaseName(options, migrationType);
var connectionString = GetConnectionString(options);
using var conn = new NpgsqlConnection(connectionString);
conn.Open();
using var cmd = conn.CreateCommand();
cmd.CommandText = $"DROP DATABASE \"{db}\" WITH (FORCE);";
cmd.ExecuteNonQuery();
}
private static string GetConnectionString(PostgresOptions options)
{
var builder = new NpgsqlConnectionStringBuilder()
{
Host = options.Host,
Port = options.Port,
Username = options.User,
Password = options.Password,
Enlist = false
};
return builder.ConnectionString;
}
private static string GetDatabaseName(PostgresOptions options, MigrationType migrationType)
{
return migrationType switch
{
MigrationType.Main => options.MainDb,
MigrationType.Log => options.LogDb,
_ => throw new NotImplementedException("Unknown migration type")
};
}
}
}

View File

@ -0,0 +1,14 @@
using System.IO;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Test.Common.Datastore
{
public static class SqliteDatabase
{
public static string GetCachedDb(MigrationType type)
{
return Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_{type}.db");
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
@ -9,7 +10,9 @@ using NUnit.Framework;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Processes;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Datastore;
using RestSharp;
namespace NzbDrone.Test.Common
@ -22,13 +25,15 @@ namespace NzbDrone.Test.Common
public string AppData { get; private set; }
public string ApiKey { get; private set; }
public PostgresOptions PostgresOptions { get; private set; }
public int Port { get; private set; }
public NzbDroneRunner(Logger logger, int port = 7878)
public NzbDroneRunner(Logger logger, PostgresOptions postgresOptions, int port = 7878)
{
_processProvider = new ProcessProvider(logger);
_restClient = new RestClient($"http://localhost:{port}/api/v3");
PostgresOptions = postgresOptions;
Port = port;
}
@ -132,9 +137,23 @@ namespace NzbDrone.Test.Common
private void Start(string outputRadarrConsoleExe)
{
StringDictionary envVars = new ();
if (PostgresOptions?.Host != null)
{
envVars.Add("Radarr__Postgres__Host", PostgresOptions.Host);
envVars.Add("Radarr__Postgres__Port", PostgresOptions.Port.ToString());
envVars.Add("Radarr__Postgres__User", PostgresOptions.User);
envVars.Add("Radarr__Postgres__Password", PostgresOptions.Password);
envVars.Add("Radarr__Postgres__MainDb", PostgresOptions.MainDb);
envVars.Add("Radarr__Postgres__LogDb", PostgresOptions.LogDb);
TestContext.Progress.WriteLine("Using env vars:\n{0}", envVars.ToJson());
}
TestContext.Progress.WriteLine("Starting instance from {0} on port {1}", outputRadarrConsoleExe, Port);
var args = "-nobrowser -nosingleinstancecheck -data=\"" + AppData + "\"";
_nzbDroneProcess = _processProvider.Start(outputRadarrConsoleExe, args, null, OnOutputDataReceived, OnOutputDataReceived);
_nzbDroneProcess = _processProvider.Start(outputRadarrConsoleExe, args, envVars, OnOutputDataReceived, OnOutputDataReceived);
}
private void OnOutputDataReceived(string data)

11
src/postgres.runsettings Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<RunConfiguration>
<EnvironmentVariables>
<Radarr__Postgres__Host>192.168.100.5</Radarr__Postgres__Host>
<Radarr__Postgres__Port>5432</Radarr__Postgres__Port>
<Radarr__Postgres__User>abc</Radarr__Postgres__User>
<Radarr__Postgres__Password>abc</Radarr__Postgres__Password>
</EnvironmentVariables>
</RunConfiguration>
</RunSettings>