Files
sqltoolsservice/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ResourceProvider/FirewallRuleServiceTest.cs
David Shiflet 839acf67cd Convert most tools service tests to nunit (#1037)
* Remove xunit dependency from testdriver

* swap expected/actual as needed

* Convert Test.Common to nunit

* port hosting unit tests to nunit

* port batchparser integration tests to nunit

* port testdriver.tests to nunit

* fix target to copy dependency

* port servicelayer unittests to nunit

* more unit test fixes

* port integration tests to nunit

* fix test method type

* try using latest windows build for PRs

* reduce test memory use
2020-08-05 13:43:14 -04:00

528 lines
24 KiB
C#

//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.SqlTools.ResourceProvider.Core;
using Microsoft.SqlTools.ResourceProvider.Core.Authentication;
using Microsoft.SqlTools.ResourceProvider.Core.Firewall;
using Moq;
using NUnit.Framework;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ResourceProvider
{
/// <summary>
/// Tests to verify FirewallRuleService by mocking the azure authentication and resource managers
/// </summary>
public class FirewallRuleServiceTest
{
[Test]
public async Task CreateShouldThrowExceptionGivenNullServerName()
{
string serverName = null;
ServiceTestContext testContext = new ServiceTestContext();
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, serverName));
}
[Test]
public async Task CreateShouldThrowExceptionGivenNullStartIp()
{
string serverName = "serverName";
ServiceTestContext testContext = new ServiceTestContext();
testContext.StartIpAddress = null;
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, serverName));
}
[Test]
public async Task CreateShouldThrowExceptionGivenInvalidEndIp()
{
string serverName = "serverName";
ServiceTestContext testContext = new ServiceTestContext();
testContext.EndIpAddress = "invalid ip";
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, serverName));
}
[Test]
public async Task CreateShouldThrowExceptionGivenInvalidStartIp()
{
string serverName = "serverName";
ServiceTestContext testContext = new ServiceTestContext();
testContext.StartIpAddress = "invalid ip";
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, serverName));
}
[Test]
public async Task CreateShouldThrowExceptionGivenNullEndIp()
{
ServiceTestContext testContext = new ServiceTestContext();
testContext.EndIpAddress = null;
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, testContext.ServerName));
}
[Test]
public async Task CreateShouldThrowExceptionIfUserIsNotLoggedIn()
{
var applicationAuthenticationManagerMock = new Mock<IAzureAuthenticationManager>();
applicationAuthenticationManagerMock.Setup(x => x.GetUserNeedsReauthenticationAsync()).Throws(new ApplicationException());
var azureResourceManagerMock = new Mock<IAzureResourceManager>();
ServiceTestContext testContext = new ServiceTestContext();
testContext.ApplicationAuthenticationManagerMock = applicationAuthenticationManagerMock;
testContext.AzureResourceManagerMock = azureResourceManagerMock;
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, testContext.ServerName));
azureResourceManagerMock.Verify(x => x.CreateFirewallRuleAsync(
It.IsAny<IAzureResourceManagementSession>(), It.IsAny<IAzureSqlServerResource>(), It.IsAny<FirewallRuleRequest>()),
Times.Never);
}
[Test]
public async Task CreateShouldThrowExceptionIfUserDoesNotHaveSubscriptions()
{
var applicationAuthenticationManagerMock =
new Mock<IAzureAuthenticationManager>();
applicationAuthenticationManagerMock.Setup(x => x.GetUserNeedsReauthenticationAsync()).Returns(Task.FromResult(false));
applicationAuthenticationManagerMock.Setup(x => x.GetSubscriptionsAsync())
.Returns(Task.FromResult(Enumerable.Empty<IAzureUserAccountSubscriptionContext>()));
var azureResourceManagerMock = new Mock<IAzureResourceManager>();
ServiceTestContext testContext = new ServiceTestContext();
testContext.ApplicationAuthenticationManagerMock = applicationAuthenticationManagerMock;
testContext.AzureResourceManagerMock = azureResourceManagerMock;
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, testContext.ServerName));
azureResourceManagerMock.Verify(x => x.CreateFirewallRuleAsync(
It.IsAny<IAzureResourceManagementSession>(), It.IsAny<IAzureSqlServerResource>(), It.IsAny<FirewallRuleRequest>()),
Times.Never);
}
[Test]
public async Task CreateShouldThrowExceptionIfAuthenticationManagerFailsToReturnSubscription()
{
var applicationAuthenticationManagerMock = new Mock<IAzureAuthenticationManager>();
applicationAuthenticationManagerMock.Setup(x => x.GetUserNeedsReauthenticationAsync()).Returns(Task.FromResult(false));
applicationAuthenticationManagerMock.Setup(x => x.GetSubscriptionsAsync()).Throws(new Exception());
var azureResourceManagerMock = new Mock<IAzureResourceManager>();
ServiceTestContext testContext = new ServiceTestContext();
testContext.ApplicationAuthenticationManagerMock = applicationAuthenticationManagerMock;
testContext.AzureResourceManagerMock = azureResourceManagerMock;
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, "invalid server"));
azureResourceManagerMock.Verify(x => x.CreateFirewallRuleAsync(
It.IsAny<IAzureResourceManagementSession>(), It.IsAny<IAzureSqlServerResource>(), It.IsAny<FirewallRuleRequest>()),
Times.Never);
}
[Test]
public async Task CreateShouldThrowExceptionGivenNoSubscriptionFound()
{
ServiceTestContext testContext = new ServiceTestContext();
testContext = CreateMocks(testContext);
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, "invalid server"));
}
[Test]
public async Task CreateShouldCreateFirewallSuccessfullyGivenValidUserAccount()
{
ServiceTestContext testContext = new ServiceTestContext();
testContext = CreateMocks(testContext);
await VerifyCreateAsync(testContext, testContext.ServerName);
}
[Test]
public async Task CreateShouldFindTheRightSubscriptionGivenValidSubscriptionInFirstPlace()
{
ServiceTestContext testContext = new ServiceTestContext();
testContext.Subscriptions = new List<IAzureUserAccountSubscriptionContext>
{
testContext.ValidSubscription,
ServiceTestContext.CreateSubscriptionContext(),
ServiceTestContext.CreateSubscriptionContext(),
};
testContext = CreateMocks(testContext);
await VerifyCreateAsync(testContext, testContext.ServerName);
}
[Test]
public async Task CreateShouldFindTheRightSubscriptionGivenValidSubscriptionInSecondPlace()
{
ServiceTestContext testContext = new ServiceTestContext();
testContext.Subscriptions = new List<IAzureUserAccountSubscriptionContext>
{
ServiceTestContext.CreateSubscriptionContext(),
testContext.ValidSubscription,
ServiceTestContext.CreateSubscriptionContext(),
};
testContext.Initialize();
testContext = CreateMocks(testContext);
await VerifyCreateAsync(testContext, testContext.ServerName);
}
[Test]
public async Task CreateShouldFindTheRightSubscriptionGivenValidSubscriptionInLastPlace()
{
ServiceTestContext testContext = new ServiceTestContext();
testContext.Subscriptions = new List<IAzureUserAccountSubscriptionContext>
{
ServiceTestContext.CreateSubscriptionContext(),
ServiceTestContext.CreateSubscriptionContext(),
testContext.ValidSubscription
};
testContext.Initialize();
testContext = CreateMocks(testContext);
await VerifyCreateAsync(testContext, testContext.ServerName);
}
[Test]
public async Task CreateShouldFindTheRightResourceGivenValidResourceInLastPlace()
{
ServiceTestContext testContext = new ServiceTestContext();
var resources = new List<IAzureSqlServerResource>
{
ServiceTestContext.CreateAzureSqlServer(Guid.NewGuid().ToString()),
ServiceTestContext.CreateAzureSqlServer(testContext.ServerName),
};
testContext.SubscriptionToResourcesMap[testContext.ValidSubscription.Subscription.SubscriptionId] = resources;
testContext = CreateMocks(testContext);
await VerifyCreateAsync(testContext, testContext.ServerName);
}
[Test]
public async Task CreateShouldFindTheRightResourceGivenValidResourceInFirstPlace()
{
ServiceTestContext testContext = new ServiceTestContext();
var resources = new List<IAzureSqlServerResource>
{
ServiceTestContext.CreateAzureSqlServer(testContext.ServerName),
ServiceTestContext.CreateAzureSqlServer(Guid.NewGuid().ToString()),
};
testContext.SubscriptionToResourcesMap[testContext.ValidSubscription.Subscription.SubscriptionId] = resources;
testContext = CreateMocks(testContext);
await VerifyCreateAsync(testContext, testContext.ServerName);
}
[Test]
public async Task CreateShouldFindTheRightResourceGivenValidResourceInMiddle()
{
ServiceTestContext testContext = new ServiceTestContext();
var resources = new List<IAzureSqlServerResource>
{
ServiceTestContext.CreateAzureSqlServer(Guid.NewGuid().ToString()),
ServiceTestContext.CreateAzureSqlServer(testContext.ServerName),
ServiceTestContext.CreateAzureSqlServer(Guid.NewGuid().ToString())
};
testContext.SubscriptionToResourcesMap[testContext.ValidSubscription.Subscription.SubscriptionId] = resources;
testContext = CreateMocks(testContext);
await VerifyCreateAsync(testContext, testContext.ServerName);
}
[Test]
public async Task CreateThrowExceptionIfResourceNotFound()
{
ServiceTestContext testContext = new ServiceTestContext();
var resources = new List<IAzureSqlServerResource>
{
ServiceTestContext.CreateAzureSqlServer(Guid.NewGuid().ToString()),
ServiceTestContext.CreateAzureSqlServer(Guid.NewGuid().ToString()),
};
testContext.SubscriptionToResourcesMap[testContext.ValidSubscription.Subscription.SubscriptionId] = resources;
testContext = CreateMocks(testContext);
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, testContext.ServerName));
}
[Test]
public async Task CreateThrowExceptionIfResourcesIsEmpty()
{
ServiceTestContext testContext = new ServiceTestContext();
testContext.SubscriptionToResourcesMap[testContext.ValidSubscription.Subscription.SubscriptionId] = new List<IAzureSqlServerResource>();
testContext = CreateMocks(testContext);
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, testContext.ServerName, false));
}
[Test]
public async Task CreateShouldThrowExceptionIfThereIsNoSubscriptionForUser()
{
ServiceTestContext testContext = new ServiceTestContext();
testContext.Subscriptions = new List<IAzureUserAccountSubscriptionContext>();
testContext = CreateMocks(testContext);
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, testContext.ServerName, false));
}
[Test]
public async Task CreateShouldThrowExceptionIfSubscriptionIsInAnotherAccount()
{
ServiceTestContext testContext = new ServiceTestContext();
testContext.Subscriptions = new List<IAzureUserAccountSubscriptionContext>
{
ServiceTestContext.CreateSubscriptionContext(),
ServiceTestContext.CreateSubscriptionContext(),
};
testContext = CreateMocks(testContext);
Assert.ThrowsAsync<FirewallRuleException>(() => VerifyCreateAsync(testContext, testContext.ServerName, false));
}
[Test]
public async Task CreateShouldCreateFirewallForTheRightServerFullyQualifiedName()
{
ServiceTestContext testContext = new ServiceTestContext();
string serverNameWithDifferentDomain = testContext.ServerNameWithoutDomain + ".myaliased.domain.name";
testContext.ServerName = serverNameWithDifferentDomain;
testContext.Initialize();
testContext = CreateMocks(testContext);
await VerifyCreateAsync(testContext, testContext.ServerName);
}
private async Task<FirewallRuleResponse> VerifyCreateAsync(ServiceTestContext testContext, string serverName, bool verifyFirewallRuleCreated = true)
{
try
{
FirewallRuleService service = new FirewallRuleService();
service.AuthenticationManager = testContext.ApplicationAuthenticationManager;
service.ResourceManager = testContext.AzureResourceManager;
FirewallRuleResponse response = await service.CreateFirewallRuleAsync(serverName, testContext.StartIpAddress, testContext.EndIpAddress);
if (verifyFirewallRuleCreated)
{
testContext.AzureResourceManagerMock.Verify(x => x.CreateFirewallRuleAsync(
It.Is<IAzureResourceManagementSession>(s => s.SubscriptionContext.Subscription.SubscriptionId == testContext.ValidSubscription.Subscription.SubscriptionId),
It.Is<IAzureSqlServerResource>(r => r.FullyQualifiedDomainName == serverName),
It.Is<FirewallRuleRequest>(y => y.EndIpAddress.ToString().Equals(testContext.EndIpAddress) && y.StartIpAddress.ToString().Equals(testContext.StartIpAddress))),
Times.AtLeastOnce);
}
else
{
testContext.AzureResourceManagerMock.Verify(x => x.CreateFirewallRuleAsync(
It.Is<IAzureResourceManagementSession>(s => s.SubscriptionContext.Subscription.SubscriptionId == testContext.ValidSubscription.Subscription.SubscriptionId),
It.Is<IAzureSqlServerResource>(r => r.FullyQualifiedDomainName == serverName),
It.Is<FirewallRuleRequest>(y => y.EndIpAddress.ToString().Equals(testContext.EndIpAddress) && y.StartIpAddress.ToString().Equals(testContext.StartIpAddress))),
Times.Never);
}
return response;
}
catch (Exception ex)
{
if (ex is FirewallRuleException)
{
Assert.True(ex.InnerException == null || !(ex.InnerException is FirewallRuleException));
}
throw;
}
}
private ServiceTestContext CreateMocks(ServiceTestContext testContext)
{
var accountMock = new Mock<IUserAccount>();
accountMock.Setup(x => x.UniqueId).Returns(Guid.NewGuid().ToString());
var applicationAuthenticationManagerMock = new Mock<IAzureAuthenticationManager>();
applicationAuthenticationManagerMock.Setup(x => x.GetUserNeedsReauthenticationAsync())
.Returns(Task.FromResult(false));
applicationAuthenticationManagerMock.Setup(x => x.GetCurrentAccountAsync()).Returns(Task.FromResult(accountMock.Object));
applicationAuthenticationManagerMock.Setup(x => x.GetSubscriptionsAsync()).Returns(Task.FromResult(testContext.Subscriptions as IEnumerable<IAzureUserAccountSubscriptionContext>));
var azureResourceManagerMock = new Mock<IAzureResourceManager>();
CreateMocksForResources(testContext, azureResourceManagerMock);
testContext.ApplicationAuthenticationManagerMock = applicationAuthenticationManagerMock;
testContext.AzureResourceManagerMock = azureResourceManagerMock;
return testContext;
}
private void CreateMocksForResources(
ServiceTestContext testContext,
Mock<IAzureResourceManager> azureResourceManagerMock)
{
foreach (IAzureUserAccountSubscriptionContext subscription in testContext.Subscriptions)
{
var sessionMock = new Mock<IAzureResourceManagementSession>();
sessionMock.Setup(x => x.SubscriptionContext).Returns(subscription);
azureResourceManagerMock.Setup(x => x.CreateSessionAsync(subscription)).Returns(Task.FromResult(sessionMock.Object));
List<IAzureSqlServerResource> resources;
if (testContext.SubscriptionToResourcesMap.TryGetValue(subscription.Subscription.SubscriptionId,
out resources))
{
azureResourceManagerMock.Setup(x => x.GetSqlServerAzureResourcesAsync(It.Is<IAzureResourceManagementSession>(
m => m.SubscriptionContext.Subscription.SubscriptionId == subscription.Subscription.SubscriptionId)))
.Returns(Task.FromResult(resources as IEnumerable<IAzureSqlServerResource>));
}
else
{
azureResourceManagerMock.Setup(x => x.GetSqlServerAzureResourcesAsync(
It.Is<IAzureResourceManagementSession>(m => m.SubscriptionContext.Subscription.SubscriptionId == subscription.Subscription.SubscriptionId)))
.Returns(Task.FromResult<IEnumerable<IAzureSqlServerResource>>(null));
}
}
azureResourceManagerMock
.Setup(x => x.CreateFirewallRuleAsync(
It.IsAny<IAzureResourceManagementSession>(),
It.IsAny<IAzureSqlServerResource>(),
It.Is<FirewallRuleRequest>(
y => y.EndIpAddress.ToString().Equals(testContext.EndIpAddress)
&& y.StartIpAddress.ToString().Equals(testContext.StartIpAddress))))
.Returns(Task.FromResult(new FirewallRuleResponse() {Created = true}));
}
}
internal class ServiceTestContext
{
private string _validServerName = "validServerName.database.windows.net";
private string _startIpAddressValue = "1.2.3.6";
private string _endIpAddressValue = "1.2.3.6";
private Dictionary<string, List<IAzureSqlServerResource>> _subscriptionToResourcesMap;
public ServiceTestContext()
{
StartIpAddress = _startIpAddressValue;
EndIpAddress = _endIpAddressValue;
ServerName = _validServerName;
Initialize();
}
internal void Initialize()
{
CreateSubscriptions();
CreateAzureResources();
}
internal static IAzureUserAccountSubscriptionContext CreateSubscriptionContext()
{
var subscriptionContext = new Mock<IAzureUserAccountSubscriptionContext>();
var subscriptionMock = new Mock<IAzureSubscriptionIdentifier>();
subscriptionMock.Setup(x => x.SubscriptionId).Returns(Guid.NewGuid().ToString());
subscriptionContext.Setup(x => x.Subscription).Returns(subscriptionMock.Object);
return subscriptionContext.Object;
}
private void CreateSubscriptions()
{
if (Subscriptions == null || Subscriptions.Count == 0)
{
ValidSubscriptionMock = new Mock<IAzureUserAccountSubscriptionContext>();
var subscriptionMock = new Mock<IAzureSubscriptionIdentifier>();
subscriptionMock.Setup(x => x.SubscriptionId).Returns(Guid.NewGuid().ToString());
ValidSubscriptionMock.Setup(x => x.Subscription).Returns(subscriptionMock.Object);
Subscriptions = new List<IAzureUserAccountSubscriptionContext>
{
ValidSubscription,
CreateSubscriptionContext(),
CreateSubscriptionContext()
};
}
}
internal void CreateAzureResources(Dictionary<string, List<IAzureSqlServerResource>> subscriptionToResourcesMap = null)
{
_subscriptionToResourcesMap = new Dictionary<string, List<IAzureSqlServerResource>>();
if (subscriptionToResourcesMap == null)
{
foreach (var subscriptionDetails in Subscriptions)
{
if (subscriptionDetails.Subscription.SubscriptionId == ValidSubscription.Subscription.SubscriptionId)
{
var resources = new List<IAzureSqlServerResource>();
resources.Add(CreateAzureSqlServer(Guid.NewGuid().ToString()));
resources.Add(CreateAzureSqlServer(Guid.NewGuid().ToString()));
resources.Add(CreateAzureSqlServer(ServerName));
_subscriptionToResourcesMap.Add(ValidSubscription.Subscription.SubscriptionId, resources);
}
else
{
var resources = new List<IAzureSqlServerResource>();
resources.Add(CreateAzureSqlServer(Guid.NewGuid().ToString()));
resources.Add(CreateAzureSqlServer(Guid.NewGuid().ToString()));
_subscriptionToResourcesMap.Add(subscriptionDetails.Subscription.SubscriptionId, resources);
}
}
}
else
{
_subscriptionToResourcesMap = subscriptionToResourcesMap;
}
}
internal static IAzureSqlServerResource CreateAzureSqlServer(string serverName)
{
var azureSqlServer =
new Mock<IAzureSqlServerResource>();
azureSqlServer.Setup(x => x.Name).Returns(GetServerNameWithoutDomain(serverName));
azureSqlServer.Setup(x => x.FullyQualifiedDomainName).Returns(serverName);
return azureSqlServer.Object;
}
internal Dictionary<string, List<IAzureSqlServerResource>> SubscriptionToResourcesMap
{
get { return _subscriptionToResourcesMap; }
}
internal static string GetServerNameWithoutDomain(string serverName)
{
int index = serverName.IndexOf('.');
if (index > 0)
{
return serverName.Substring(0, index);
}
return serverName;
}
internal string StartIpAddress { get; set; }
internal string EndIpAddress { get; set; }
internal IList<IAzureUserAccountSubscriptionContext> Subscriptions { get; set; }
internal Mock<IAzureUserAccountSubscriptionContext> ValidSubscriptionMock { get; set; }
internal IAzureUserAccountSubscriptionContext ValidSubscription { get { return ValidSubscriptionMock.Object; } }
internal string ServerName { get; set; }
internal string ServerNameWithoutDomain
{
get { return GetServerNameWithoutDomain(ServerName); }
}
internal Mock<IAzureAuthenticationManager> ApplicationAuthenticationManagerMock { get; set; }
internal IAzureAuthenticationManager ApplicationAuthenticationManager { get { return ApplicationAuthenticationManagerMock?.Object; } }
internal Mock<IAzureResourceManager> AzureResourceManagerMock { get; set; }
internal IAzureResourceManager AzureResourceManager { get { return AzureResourceManagerMock?.Object; } }
}
}