Azure DevOps托管生成控制器-是否支持Azure存储模拟器



我想运行单元/集成测试,这些测试使用Azure存储模拟器,而不是Azure DevOps构建中的实际存储。

模拟器作为Azure SDK的一部分安装在托管生成控制器上的正常位置(C:\Program Files(x86)\Microsoft SDKs\Azure\Storage emulator \AzureStorageEmulator.exe)。

但是,模拟器在生成控制器上处于未初始化状态。当尝试从命令行运行命令Init时,我得到以下错误:

This operation requires an interactive window station

是否有已知的解决方法或计划在Azure DevOps构建中支持模拟器?

尽管这里的答案都相反,但我已经在VS2017托管的构建代理上运行Azure Storage Emulator一年多了。

诀窍是先初始化SQLLocalDB(模拟器使用它),然后启动模拟器。您可以通过运行以下命令行任务来完成此操作:

sqllocaldb create MSSQLLocalDB
sqllocaldb start MSSQLLocalDB
sqllocaldb info MSSQLLocalDB
"C:Program Files (x86)Microsoft SDKsAzureStorage EmulatorAzureStorageEmulator.exe" start

如前所述,您无法运行Azure存储模拟器。不过,您可以运行的是Azurite,这是一个开源的替代方案。

请注意:Azurite可以模拟Blob、表和队列。然而,我只以这种方式使用了blob存储模拟。

在构建配置开始时,添加一个运行自定义nuget命令install Azurite -version 2.2.2的nuget步骤。然后添加一个运行start /b $(Build.SourcesDirectory)Azurite.2.2.2toolsblob.exe的命令行步骤。

它与Azure Storage Emulator在同一端口上运行,因此您可以使用标准连接字符串。

否,Hosted Build Controller不在交互模式下运行,因此模拟器无法在该环境下工作。参见Q&XAML生成的托管内生成控制器以获取详细信息。

Q: 您需要在交互模式下运行构建服务吗?

A: 不可以。然后您可以使用托管的生成控制器。

我建议您设置本地生成控制器,并在交互模式下运行生成服务器。有关详细信息,请参阅安装生成服务器和安装生成控制器。

似乎答案可能来自Visual Studio Online方面。如果有人有类似的问题,会有一个用户语音条目。

不太清楚为什么模拟器没有非交互式模式,就我个人而言,99%的时间我都不使用它的UI。有一个通用的用户语音条目,用于使Azure存储更易于单元测试。

如果您想在C#中的集成测试代码中启动Azure Storage Emulator,您可以将其放入测试初始化(启动)代码中(例如xUnit):

[Collection("Database collection")]
public sealed class IntegrationTests
{
    public IntegrationTests(DatabaseFixture fixture)
    {
        this.fixture = fixture;
    }
    [Fact]
    public async Task TestMethod1()
    {
        // use fixture.Table to run tests on the Azure Storage
    }
    private readonly DatabaseFixture fixture;
}
public class DatabaseFixture : IDisposable
{
    public DatabaseFixture()
    {
        StartProcess("SqlLocalDB.exe", "create MSSQLLocalDB");
        StartProcess("SqlLocalDB.exe", "start MSSQLLocalDB");
        StartProcess("SqlLocalDB.exe", "info MSSQLLocalDB");
        StartProcess(EXE_PATH, "start");
        var client = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudTableClient();
        Table = client.GetTableReference("tablename");
        InitAsync().Wait();
    }
    public void Dispose()
    {
        Table.DeleteIfExistsAsync().Wait();
        StartProcess(EXE_PATH, "stop");
    }
    private async Task InitAsync()
    {
        await Table.DeleteIfExistsAsync();
        await Table.CreateAsync();
    }
    static void StartProcess(string path, string arguments, int waitTime = WAIT_FOR_EXIT) => 
        Process.Start(path, arguments).WaitForExit(waitTime);
    public CloudTable Table { get; }
    private const string EXE_PATH = 
    "C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\AzureStorageEmulator.exe";
    private const int WAIT_FOR_EXIT = 60_000;
}
[CollectionDefinition("Database collection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{
    // This class has no code, and is never created. Its purpose is simply
    // to be the place to apply [CollectionDefinition] and all the
    // ICollectionFixture<> interfaces.
}

最新更新