Azure DevOps 托管构建控制器 - Azure Storage Emulator 支持吗?

12

我想运行使用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构建中的模拟器?


请注意,除了下面的答案之外,即使VSTS托管的构建代理支持交互模式,由于权限不足,Azure存储仿真器仍将无法工作。请参阅https://github.com/Microsoft/vso-agent/issues/72。 - Livven
5个回答

20

尽管这里所有的回答都说不行,但我已经在VS2017托管的构建代理上运行Azure存储模拟器一年多了。

诀窍是首先初始化SQL LocalDB(模拟器使用它),然后启动模拟器。您可以使用一个命令行任务来运行此操作:

sqllocaldb create MSSQLLocalDB
sqllocaldb start MSSQLLocalDB
sqllocaldb info MSSQLLocalDB

"C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\AzureStorageEmulator.exe" start

3

正如已经说明的那样,你不能运行Azure存储模拟器。但是你可以运行Azurite,这是一个开源的替代品。

请注意:Azurite可以模拟块、表格和队列。但是我只在此方式中使用了块存储仿真。

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

它在与Azure存储模拟器相同的端口上运行,因此你可以使用标准连接字符串。


1
不,托管的构建控制器不在交互模式下运行,因此仿真器在该环境下无法工作。有关详细信息,请参见XAML 构建的托管构建控制器中的问答部分。

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

答:不需要。然后您可以使用托管的构建控制器。

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

1
似乎答案可能来自 Visual Studio Online 方面。如果有类似问题,可以查看用户反馈
不太确定为什么模拟器没有非交互模式,个人99%的时间都不使用其用户界面。有一个通用的用户反馈条目,用于使 Azure 存储更易于单元测试。

1
如果您想在C#的集成测试代码中启动Azure Storage模拟器,可以将以下内容放入测试初始化(启动)代码中(示例适用于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.
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接