This repository was archived by the owner on Jul 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 68
Add App Services Heartbeat with environment variable monitor #873
Merged
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
514aa15
Add heartbeat provider for Azure App Services (in particular, Web App…
d3r3kk e9c2d47
Move new TelemetryModule AppServicesHeartbeat out of Web package and …
d3r3kk f2bd436
Fix stylecop issues
d3r3kk 53fba65
Update for PR suggestions
d3r3kk 710d4bb
Fix for build - stylecop
d3r3kk d4a21c3
Add monitor to keep track of current value of App Services env vars
d3r3kk 0c261da
Add tests, clean up AppServiceHearbeatModule class (unused variables)…
d3r3kk fc44730
Fix for installed modules count test
d3r3kk aab6721
Correct perf issues and suggestions from PR, add tests
d3r3kk 86911c0
Make container of env vars cached into a readonly member
d3r3kk 9c407f9
Update AzureWebAppRoleEnvironmentTelemetryInitializer to use the AppS…
d3r3kk 3f31500
Re-add the WindowsServer.Shared.Tests shared project into the Windows…
d3r3kk cb857fb
Merge PR #869 and #870 into a single PR for submission to 2.6.0-beta3
d3r3kk 1635111
Merge PR #870 and #869, regarding heartbeat providers for App Services
d3r3kk 1bbe3a2
Fix tests to allow for parallel testing of methods that alter environ…
d3r3kk da7e4d0
Finish merging PR #869 and #870
d3r3kk 275271a
Cleanup of some comments and usings
d3r3kk 09a28fb
Update file name for tests to match module being tested
d3r3kk f4487c9
For App Services heartbeats, handle detected environment variable cha…
d3r3kk e173905
Separate the environment variable monitor from the App Services envir…
d3r3kk 571f92e
Construct tests for the subscriber-model environment variable monitor
d3r3kk 8a1c079
Update tests for AzureWebRoleEnvironmentTelemetryInitializer module
d3r3kk 43d6bc8
PR suggestion: Correct access level of abstract class EnvironmentVari…
d3r3kk 3f9cc36
PR Suggestions
d3r3kk 87c1fd7
Fix PR CI Build break due to StyleCop rules
d3r3kk 74cb7d5
PR Suggestions: Disable monitor if we don't detect that we are in Azu…
d3r3kk 13715bc
PR Suggestion: Correct AppServicesEnvVarMonitor to properly follow C#…
d3r3kk d31e0e9
PR Suggestion: Handle exceptions during timer callback for environmen…
d3r3kk 50e876f
PR suggestions/fixes for tests and log warnings
d3r3kk be1ffe6
Ensure test for updated environment values operates correctly
d3r3kk c61fb45
PR Suggestion: Change informational message to warning.
d3r3kk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
Src/WindowsServer/WindowsServer.Shared.Tests/AppServicesHeartbeatTelemetryModuleTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| namespace Microsoft.ApplicationInsights.WindowsServer | ||
| { | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.IO; | ||
| using System.Net.Http; | ||
| using System.Runtime.Serialization.Json; | ||
| using System.Text; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.ApplicationInsights.Extensibility; | ||
| using Microsoft.ApplicationInsights.WindowsServer.Implementation; | ||
| using Microsoft.ApplicationInsights.WindowsServer.Implementation.DataContracts; | ||
| using Microsoft.ApplicationInsights.WindowsServer.Mock; | ||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
| using Assert = Xunit.Assert; | ||
|
|
||
| [TestClass] | ||
| public class AppServicesHeartbeatTelemetryModuleTests | ||
| { | ||
| private HeartbeatProviderMock testHeartbeatPropertyManager; | ||
| private AppServicesHeartbeatTelemetryModule testAppServiceHbeatModule; | ||
| private Dictionary<string, string> testEnvironmentVariables; | ||
|
|
||
| [TestInitialize] | ||
| public void BeforeEachTestMethod() | ||
| { | ||
| this.testHeartbeatPropertyManager = new HeartbeatProviderMock(); | ||
| this.testAppServiceHbeatModule = this.GetAppServiceHeartbeatModuleWithUniqueTestEnvVars(this.testHeartbeatPropertyManager); | ||
| this.testEnvironmentVariables = this.GetEnvVarsAssociatedToModule(this.testAppServiceHbeatModule); | ||
| } | ||
|
|
||
| [TestCleanup] | ||
| public void AfterEachTestMethod() | ||
| { | ||
| this.RemoveTestEnvVarsAssociatedToModule(this.testAppServiceHbeatModule); | ||
| } | ||
|
|
||
| [TestMethod] | ||
| public void InitializeIsWorking() | ||
| { | ||
| this.testAppServiceHbeatModule.Initialize(null); | ||
|
|
||
| foreach (var kvp in this.testAppServiceHbeatModule.WebHeartbeatPropertyNameEnvVarMap) | ||
| { | ||
| Assert.True(this.testHeartbeatPropertyManager.HbeatProps.ContainsKey(kvp.Key)); | ||
| Assert.Equal(this.testHeartbeatPropertyManager.HbeatProps[kvp.Key], this.testEnvironmentVariables[kvp.Value]); | ||
| } | ||
| } | ||
|
|
||
| [TestMethod] | ||
| [Description("This test causes a delay and must be updated to be more deterministic.")] | ||
| [Owner("dekeeler")] | ||
| public void UpdateEnvVarsWorksWhenEnvironmentValuesChange() | ||
| { | ||
| this.testAppServiceHbeatModule.Initialize(null); | ||
|
|
||
| // update each environment variable to have a different value | ||
| foreach (var envVarKvp in this.testEnvironmentVariables) | ||
| { | ||
| string newVal = string.Concat(envVarKvp.Value, "_1"); | ||
| Environment.SetEnvironmentVariable(envVarKvp.Key, newVal); | ||
| } | ||
|
|
||
| // wait for the delay set into the monitor, plus one second to ensure we got updated | ||
| Task.Delay( | ||
| AppServiceEnvironmentVariableMonitor.Instance.MonitorInterval + TimeSpan.FromSeconds(1)) | ||
| .ConfigureAwait(false).GetAwaiter().GetResult(); | ||
|
|
||
| var updatedEnvVars = this.GetEnvVarsAssociatedToModule(this.testAppServiceHbeatModule); | ||
|
|
||
| foreach (var kvp in this.testAppServiceHbeatModule.WebHeartbeatPropertyNameEnvVarMap) | ||
| { | ||
| Assert.True(this.testHeartbeatPropertyManager.HbeatProps.ContainsKey(kvp.Key)); | ||
| Assert.Equal(this.testHeartbeatPropertyManager.HbeatProps[kvp.Key], updatedEnvVars[kvp.Value]); | ||
| } | ||
| } | ||
|
|
||
| [TestMethod] | ||
| public void NoHeartbeatManagerAvailableDoesntThrow() | ||
| { | ||
| var appSrvHbeatModule = new AppServicesHeartbeatTelemetryModule(); | ||
| var envVars = this.GetEnvVarsAssociatedToModule(appSrvHbeatModule); | ||
|
|
||
| try | ||
| { | ||
| appSrvHbeatModule.Initialize(null); | ||
| } | ||
| catch (Exception any) | ||
| { | ||
| Assert.False(any == null); | ||
| } | ||
| } | ||
|
|
||
| [TestMethod] | ||
| public void NoAppServicesEnvVarsWorksWithoutFailure() | ||
| { | ||
| // ensure all environment variables are set to nothing (remove them from the environment) | ||
| this.RemoveTestEnvVarsAssociatedToModule(this.testAppServiceHbeatModule); | ||
|
|
||
| this.testAppServiceHbeatModule.UpdateHeartbeatWithAppServiceEnvVarValues(); | ||
| foreach (var kvp in this.testAppServiceHbeatModule.WebHeartbeatPropertyNameEnvVarMap) | ||
| { | ||
| Assert.Null(this.testHeartbeatPropertyManager.HbeatProps[kvp.Key]); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Return a dictionary containing the expected environment variables for the AppServicesHeartbeat module. If | ||
| /// the environment does not contain a value for them, set the environment to have them. | ||
| /// </summary> | ||
| /// <returns>Dictionary with expected environment variable names as the key, current environment variable content as the value.</returns> | ||
| private Dictionary<string, string> GetEnvVarsAssociatedToModule(AppServicesHeartbeatTelemetryModule testAppServicesHeartbeatModule) | ||
| { | ||
| Dictionary<string, string> uniqueTestEnvironmentVariables = new Dictionary<string, string>(); | ||
| foreach (var kvp in testAppServicesHeartbeatModule.WebHeartbeatPropertyNameEnvVarMap) | ||
| { | ||
| uniqueTestEnvironmentVariables.Add(kvp.Value, Environment.GetEnvironmentVariable(kvp.Value)); | ||
| if (string.IsNullOrEmpty(uniqueTestEnvironmentVariables[kvp.Value])) | ||
| { | ||
| Environment.SetEnvironmentVariable(kvp.Value, kvp.Key); | ||
| uniqueTestEnvironmentVariables[kvp.Value] = kvp.Key; | ||
| } | ||
| } | ||
|
|
||
| return uniqueTestEnvironmentVariables; | ||
| } | ||
|
|
||
| private AppServicesHeartbeatTelemetryModule GetAppServiceHeartbeatModuleWithUniqueTestEnvVars(HeartbeatProviderMock heartbeatProvider) | ||
| { | ||
| var appServicesHbeatModule = new AppServicesHeartbeatTelemetryModule(heartbeatProvider); | ||
| string testSuffix = Guid.NewGuid().ToString(); | ||
| for (int i = 0; i < appServicesHbeatModule.WebHeartbeatPropertyNameEnvVarMap.Length; ++i) | ||
| { | ||
| var kvp = appServicesHbeatModule.WebHeartbeatPropertyNameEnvVarMap[i]; | ||
| appServicesHbeatModule.WebHeartbeatPropertyNameEnvVarMap[i] = new KeyValuePair<string, string>(kvp.Key, string.Concat(kvp.Value, "_", testSuffix)); | ||
| } | ||
|
|
||
| return appServicesHbeatModule; | ||
| } | ||
|
|
||
| private void RemoveTestEnvVarsAssociatedToModule(AppServicesHeartbeatTelemetryModule appServicesHbeatModule) | ||
| { | ||
| foreach (var kvp in appServicesHbeatModule.WebHeartbeatPropertyNameEnvVarMap) | ||
| { | ||
| Environment.SetEnvironmentVariable(kvp.Value, string.Empty); | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we change the ENV vars?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now have 3 classes that all use the same environment variables and testing each of them means we update/clear/change that small set of environment variables as we go. If we run the tests in parallel, tests will have that value changed unexpectedly during their execution by other tests.