Skip to content

Commit 9e38fe1

Browse files
Fixing faulty logic in InstallFunctionAppDependencies and adding unit test (#250)
* Fixing faulty logic in InstallFunctionAppDependencies and refactoring DependencyManager.cs to accommodate for unit test. * Adding unit test to validate the retry logic in InstallFunctionAppDependencies as well as a successful module download. * Adding Save-Module number of attempts to error log. Updating unit test to reflect this change. * Adding logic to dependency manager to fail in the first dependencies installation run if the PSGallery could not be reached, but continue if previous dependencies exist. * Adding unit test to validate that a function app execution should continue if the PSGallery could not be reached but a previous installation of managed dependencies exists.
1 parent 28cb6b9 commit 9e38fe1

File tree

4 files changed

+558
-173
lines changed

4 files changed

+558
-173
lines changed

src/DependencyManagement/DependencyManagementUtils.cs

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,11 @@
66
using System;
77
using System.Collections.Generic;
88
using System.IO;
9-
using System.Net;
10-
using System.Xml;
119

1210
namespace Microsoft.Azure.Functions.PowerShellWorker.DependencyManagement
1311
{
1412
internal class DependencyManagementUtils
1513
{
16-
// The PowerShellGallery uri to query for the latest module version.
17-
private const string PowerShellGalleryFindPackagesByIdUri = "https://www.powershellgallery.com/api/v2/FindPackagesById()?id=";
18-
1914
/// <summary>
2015
/// Deletes the contents at the given directory.
2116
/// </summary>
@@ -51,104 +46,5 @@ internal static void EmptyDirectory(string path)
5146
throw new InvalidOperationException(errorMsg);
5247
}
5348
}
54-
55-
/// <summary>
56-
/// Returns the latest module version from the PSGallery for the given module name and major version.
57-
/// </summary>
58-
internal static string GetModuleLatestSupportedVersion(string moduleName, string majorVersion)
59-
{
60-
Uri address = new Uri($"{PowerShellGalleryFindPackagesByIdUri}'{moduleName}'");
61-
int configuredRetries = 3;
62-
int noOfRetries = 1;
63-
64-
string latestVersionForMajorVersion = null;
65-
66-
while (noOfRetries <= configuredRetries)
67-
{
68-
try
69-
{
70-
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
71-
using (HttpWebResponse response = request?.GetResponse() as HttpWebResponse)
72-
{
73-
if (response != null)
74-
{
75-
// Load up the XML response
76-
XmlDocument doc = new XmlDocument();
77-
using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
78-
{
79-
doc.Load(reader);
80-
}
81-
82-
// Add the namespaces for the gallery xml content
83-
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
84-
nsmgr.AddNamespace("ps", "http://www.w3.org/2005/Atom");
85-
nsmgr.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");
86-
nsmgr.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
87-
88-
// Find the version information
89-
XmlNode root = doc.DocumentElement;
90-
var props = root.SelectNodes("//m:properties/d:Version", nsmgr);
91-
if (props != null && props.Count > 0)
92-
{
93-
for (int i = 0; i < props.Count; i++)
94-
{
95-
if (props[i].FirstChild.Value.StartsWith(majorVersion))
96-
{
97-
latestVersionForMajorVersion = props[i].FirstChild.Value;
98-
}
99-
}
100-
}
101-
break;
102-
}
103-
}
104-
}
105-
catch (Exception ex)
106-
{
107-
WebException webEx = ex as WebException;
108-
if (webEx == null || noOfRetries >= configuredRetries)
109-
{
110-
throw;
111-
}
112-
113-
// Only retry the web exception
114-
if (ShouldRetry(webEx))
115-
{
116-
noOfRetries++;
117-
}
118-
}
119-
}
120-
121-
// If we could not find the latest module version error out.
122-
if (string.IsNullOrEmpty(latestVersionForMajorVersion))
123-
{
124-
var errorMsg = string.Format(PowerShellWorkerStrings.CannotFindModuleVersion, moduleName, majorVersion);
125-
var argException = new ArgumentException(errorMsg);
126-
throw argException;
127-
}
128-
129-
return latestVersionForMajorVersion;
130-
}
131-
132-
/// <summary>
133-
/// Returns true if the given WebException status matches one of the following:
134-
/// SendFailure, ConnectFailure, UnknownError or Timeout.
135-
/// </summary>
136-
private static bool ShouldRetry(WebException webEx)
137-
{
138-
if (webEx == null)
139-
{
140-
return false;
141-
}
142-
143-
if (webEx.Status == WebExceptionStatus.SendFailure ||
144-
webEx.Status == WebExceptionStatus.ConnectFailure ||
145-
webEx.Status == WebExceptionStatus.UnknownError ||
146-
webEx.Status == WebExceptionStatus.Timeout)
147-
{
148-
return true;
149-
}
150-
151-
return false;
152-
}
15349
}
15450
}

0 commit comments

Comments
 (0)