|
9 | 9 | using System.Linq;
|
10 | 10 | using System.Net;
|
11 | 11 | using System.Net.Http;
|
12 |
| -using System.Reflection; |
13 | 12 | using System.Runtime.InteropServices;
|
14 |
| -using System.Text; |
15 | 13 | using System.Threading;
|
16 | 14 | using System.Threading.Tasks;
|
17 | 15 | using Microsoft.Azure.WebJobs.Script.Config;
|
18 | 16 | using Microsoft.Azure.WebJobs.Script.Configuration;
|
19 | 17 | using Microsoft.Azure.WebJobs.Script.ExtensionBundle;
|
20 |
| -using Microsoft.Extensions.Configuration; |
21 | 18 | using Microsoft.Extensions.Logging;
|
22 |
| -using Microsoft.Extensions.Logging.Abstractions; |
23 |
| -using Microsoft.Extensions.Options; |
24 | 19 | using Moq;
|
25 |
| -using Newtonsoft.Json; |
26 | 20 | using NuGet.Versioning;
|
27 | 21 | using Xunit;
|
28 | 22 | using static Microsoft.Azure.WebJobs.Script.EnvironmentSettingNames;
|
@@ -407,22 +401,125 @@ public void LimitMaxVersion(string versionRange, string hostConfigVersion, strin
|
407 | 401 | }
|
408 | 402 | }
|
409 | 403 |
|
410 |
| - var resolvedVersion = ExtensionBundleManager.FindBestVersionMatch(range, new List<string>() |
411 |
| - { "3.7.0", "3.10.0", "3.11.0", "3.15.0", "3.14.0", "2.16.0", "3.13.0", "3.12.0", "3.9.1", "2.12.1", "2.18.0", "3.16.0", "2.19.0", "3.17.0", "4.0.2", "2.20.0", "3.18.0", "4.1.0", "4.2.0", "2.21.0", "3.19.0", "3.19.2", "4.3.0", "3.20.0" }, |
412 |
| - ScriptConstants.DefaultExtensionBundleId, hostingConfiguration); |
| 404 | + var options = GetTestExtensionBundleOptions(BundleId, versionRange); |
| 405 | + var manager = GetExtensionBundleManager(options, GetTestAppServiceEnvironment()); |
| 406 | + |
| 407 | + var resolvedVersion = manager.FindBestVersionMatch(range, GetLargeVersionsList(), ScriptConstants.DefaultExtensionBundleId, hostingConfiguration); |
| 408 | + |
| 409 | + Assert.Equal(expectedVersion, resolvedVersion); |
| 410 | + } |
| 411 | + |
| 412 | + [Theory] |
| 413 | + [InlineData(ScriptConstants.LatestPlatformChannelNameUpper, "[4.*, 5.0.0)", "4.2.0", "4.2.0")] |
| 414 | + [InlineData(ScriptConstants.StandardPlatformChannelNameUpper, "[4.*, 5.0.0)", "4.2.0", "4.2.0")] |
| 415 | + [InlineData(ScriptConstants.ExtendedPlatformChannelNameUpper, "[4.*, 5.0.0)", "4.2.0", "4.2.0")] |
| 416 | + [InlineData(ScriptConstants.StandardPlatformChannelNameUpper, "[4.*, 5.0.0)", "4.3.0", "4.2.0")] |
| 417 | + [InlineData(ScriptConstants.ExtendedPlatformChannelNameUpper, "[4.*, 5.0.0)", "4.3.0", "4.2.0")] |
| 418 | + [InlineData(ScriptConstants.StandardPlatformChannelNameUpper, "[4.*, 5.0.0)", "4.1.0", "4.1.0")] |
| 419 | + [InlineData(ScriptConstants.ExtendedPlatformChannelNameUpper, "[4.*, 5.0.0)", "4.1.0", "4.1.0")] |
| 420 | + [InlineData(ScriptConstants.LatestPlatformChannelNameUpper, "[4.*, 5.0.0)", null, "4.3.0")] |
| 421 | + [InlineData("latest", "[4.*, 5.0.0)", null, "4.3.0")] |
| 422 | + [InlineData(ScriptConstants.StandardPlatformChannelNameUpper, "[4.*, 5.0.0)", null, "4.2.0")] |
| 423 | + [InlineData("standard", "[4.*, 5.0.0)", null, "4.2.0")] |
| 424 | + [InlineData(ScriptConstants.ExtendedPlatformChannelNameUpper, "[4.*, 5.0.0)", null, "4.2.0")] |
| 425 | + [InlineData("extended", "[4.*, 5.0.0)", null, "4.2.0")] |
| 426 | + public void WhenPlatformReleaseChannelSet_ExpectedVersionChosen(string platformReleaseChannelName, string versionRange, string hostConfigMaxVersion, string expectedVersion) |
| 427 | + { |
| 428 | + var range = VersionRange.Parse(versionRange); |
| 429 | + var hostingConfiguration = new FunctionsHostingConfigOptions(); |
| 430 | + |
| 431 | + if (!string.IsNullOrEmpty(hostConfigMaxVersion)) |
| 432 | + { |
| 433 | + if (range.MinVersion.Major == 3) |
| 434 | + { |
| 435 | + hostingConfiguration.Features.Add(ScriptConstants.MaximumBundleV3Version, hostConfigMaxVersion); |
| 436 | + } |
| 437 | + |
| 438 | + if (range.MinVersion.Major == 4) |
| 439 | + { |
| 440 | + hostingConfiguration.Features.Add(ScriptConstants.MaximumBundleV4Version, hostConfigMaxVersion); |
| 441 | + } |
| 442 | + } |
| 443 | + |
| 444 | + var options = GetTestExtensionBundleOptions(BundleId, versionRange); |
| 445 | + var testEnvironment = GetTestAppServiceEnvironment(platformReleaseChannelName); |
| 446 | + var manager = GetExtensionBundleManager(options, testEnvironment); |
| 447 | + |
| 448 | + var versions = GetLargeVersionsList(); |
| 449 | + |
| 450 | + var resolvedVersion = manager.FindBestVersionMatch(range, versions, ScriptConstants.DefaultExtensionBundleId, hostingConfiguration); |
413 | 451 |
|
414 | 452 | Assert.Equal(expectedVersion, resolvedVersion);
|
415 | 453 | }
|
416 | 454 |
|
417 |
| - private ExtensionBundleManager GetExtensionBundleManager(ExtensionBundleOptions bundleOptions, TestEnvironment environment = null) |
| 455 | + [Theory] |
| 456 | + [InlineData(ScriptConstants.ExtendedPlatformChannelNameUpper)] |
| 457 | + [InlineData(ScriptConstants.StandardPlatformChannelNameUpper)] |
| 458 | + public void StandardExtendedReleaseChannel_OneBundleVersionOnDisk_Handled(string platformReleaseChannelName) |
| 459 | + { |
| 460 | + // these release channels take the version prior to the latest version |
| 461 | + // however, if there is only one bundle version available on disk, that bundle should be chosen and information logged |
| 462 | + |
| 463 | + var versions = new List<string>() { "4.20.0" }; // only one bundle version available on disk |
| 464 | + var versionRange = "[4.*, 5.0.0)"; |
| 465 | + var expected = "4.20.0"; |
| 466 | + |
| 467 | + var loggedString = $"Unable to apply platform release channel configuration {platformReleaseChannelName}. Only one matching bundle version is available. {expected} will be used"; |
| 468 | + var mockLogger = GetVerifiableMockLogger(loggedString, LogLevel.Warning); |
| 469 | + var mockLoggerFactory = new Mock<ILoggerFactory>(); |
| 470 | + mockLoggerFactory.Setup(f => f.CreateLogger(It.IsAny<string>())).Returns(() => mockLogger.Object); |
| 471 | + |
| 472 | + var options = GetTestExtensionBundleOptions(BundleId, versionRange); |
| 473 | + var testEnvironment = GetTestAppServiceEnvironment(platformReleaseChannelName); |
| 474 | + var manager = GetExtensionBundleManager(options, testEnvironment, mockLoggerFactory); |
| 475 | + |
| 476 | + var resolvedVersion = manager.FindBestVersionMatch(VersionRange.Parse(versionRange), versions, ScriptConstants.DefaultExtensionBundleId, new FunctionsHostingConfigOptions()); |
| 477 | + |
| 478 | + Assert.Equal(expected, resolvedVersion); |
| 479 | + mockLogger.Verify(); |
| 480 | + } |
| 481 | + |
| 482 | + [Fact] |
| 483 | + public void UnknownReleaseChannel_ExpectedVersionChosen() |
| 484 | + { |
| 485 | + var versions = new List<string>() { "4.20.0" }; |
| 486 | + var versionRange = "[4.*, 5.0.0)"; |
| 487 | + var expected = "4.20.0"; |
| 488 | + |
| 489 | + var incorrectChannelName = "someIncorrectReleaseChannelName"; |
| 490 | + var loggedString = $"Unknown platform release channel name {incorrectChannelName}. The latest bundle version, {expected}, will be used."; |
| 491 | + var mockLogger = GetVerifiableMockLogger(loggedString, LogLevel.Warning); |
| 492 | + var mockLoggerFactory = new Mock<ILoggerFactory>(); |
| 493 | + mockLoggerFactory.Setup(f => f.CreateLogger(It.IsAny<string>())).Returns(() => mockLogger.Object); |
| 494 | + |
| 495 | + var options = GetTestExtensionBundleOptions(BundleId, versionRange); |
| 496 | + var testEnvironment = GetTestAppServiceEnvironment(incorrectChannelName); |
| 497 | + var manager = GetExtensionBundleManager(options, testEnvironment, mockLoggerFactory); |
| 498 | + |
| 499 | + var resolvedVersion = manager.FindBestVersionMatch(VersionRange.Parse(versionRange), versions, ScriptConstants.DefaultExtensionBundleId, new FunctionsHostingConfigOptions()); |
| 500 | + |
| 501 | + Assert.Equal(expected, resolvedVersion); // unknown release channel should default to latest and log information |
| 502 | + mockLogger.Verify(); |
| 503 | + } |
| 504 | + |
| 505 | + private ExtensionBundleManager GetExtensionBundleManager(ExtensionBundleOptions bundleOptions, TestEnvironment environment = null, Mock<ILoggerFactory> mockLoggerFactory = null) |
418 | 506 | {
|
419 | 507 | environment = environment ?? new TestEnvironment();
|
420 |
| - return new ExtensionBundleManager(bundleOptions, environment, MockNullLoggerFactory.CreateLoggerFactory(), new FunctionsHostingConfigOptions()); |
| 508 | + |
| 509 | + if (mockLoggerFactory is null) |
| 510 | + { |
| 511 | + return new ExtensionBundleManager(bundleOptions, environment, MockNullLoggerFactory.CreateLoggerFactory(), new FunctionsHostingConfigOptions()); |
| 512 | + } |
| 513 | + else |
| 514 | + { |
| 515 | + return new ExtensionBundleManager(bundleOptions, environment, mockLoggerFactory.Object, new FunctionsHostingConfigOptions()); |
| 516 | + } |
421 | 517 | }
|
422 | 518 |
|
423 |
| - private TestEnvironment GetTestAppServiceEnvironment() |
| 519 | + private TestEnvironment GetTestAppServiceEnvironment(string platformReleaseChannel = null) |
424 | 520 | {
|
425 | 521 | var environment = new TestEnvironment();
|
| 522 | + environment.SetEnvironmentVariable(AntaresPlatformReleaseChannel, platformReleaseChannel); |
426 | 523 | environment.SetEnvironmentVariable(AzureWebsiteInstanceId, Guid.NewGuid().ToString("N"));
|
427 | 524 | string downloadPath = string.Empty;
|
428 | 525 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
@@ -473,6 +570,26 @@ public void Dispose()
|
473 | 570 | FileUtility.Instance = null;
|
474 | 571 | }
|
475 | 572 |
|
| 573 | + private IList<string> GetLargeVersionsList() |
| 574 | + { |
| 575 | + return new List<string>() |
| 576 | + { "3.7.0", "3.10.0", "3.11.0", "3.15.0", "3.14.0", "2.16.0", "3.13.0", "3.12.0", "3.9.1", "2.12.1", "2.18.0", "3.16.0", "2.19.0", "3.17.0", "4.0.2", "2.20.0", "3.18.0", "4.1.0", "4.2.0", "2.21.0", "3.19.0", "3.19.2", "4.3.0", "3.20.0" }; |
| 577 | + } |
| 578 | + |
| 579 | + private Mock<ILogger> GetVerifiableMockLogger(string stringToVerify, LogLevel logLevel) |
| 580 | + { |
| 581 | + var mockLogger = new Mock<ILogger>(); |
| 582 | + mockLogger |
| 583 | + .Setup(x => x.Log( |
| 584 | + logLevel, |
| 585 | + It.IsAny<EventId>(), |
| 586 | + It.Is<It.IsAnyType>((v, t) => v.ToString().Contains(stringToVerify)), |
| 587 | + It.IsAny<Exception>(), |
| 588 | + It.IsAny<Func<It.IsAnyType, Exception, string>>())) |
| 589 | + .Verifiable(); |
| 590 | + return mockLogger; |
| 591 | + } |
| 592 | + |
476 | 593 | private class MockHttpHandler : HttpClientHandler
|
477 | 594 | {
|
478 | 595 | private readonly string _version;
|
|
0 commit comments