Skip to content

Commit efac397

Browse files
committed
Drop log streaming in favour of reading the application log file
Integration tests should become more reliable
1 parent b20fc52 commit efac397

File tree

7 files changed

+73
-9
lines changed

7 files changed

+73
-9
lines changed

Next-Release-ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Build, Test, Documentation
3030
========================
3131
- Terraform and PowerShell scripts to setup a dev VM.
3232
- Use latest GitVersion.
33+
- Drop log streaming in favour of reading the application log file: integration tests should become more reliable.
3334

3435

3536
File Hashes

src/aggregator-cli/Instances/AggregatorInstances.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,19 @@ internal async Task<bool> StreamLogsAsync(InstanceName instance, CancellationTok
306306
return true;
307307
}
308308

309+
internal async Task<string> ReadLogAsync(InstanceName instance, string functionName, int logIndex, CancellationToken cancellationToken)
310+
{
311+
var kudu = GetKudu(instance);
312+
logger.WriteVerbose($"Connecting to {instance.PlainName}...");
313+
314+
// Main takes care of resetting color
315+
Console.ForegroundColor = ConsoleColor.Green;
316+
317+
string logData = await kudu.ReadApplicationLogAsync(functionName, logIndex, cancellationToken);
318+
Console.Write(logData);
319+
return logData;
320+
}
321+
309322
internal async Task<bool> UpdateAsync(InstanceName instance, string requiredVersion, string sourceUrl, CancellationToken cancellationToken)
310323
{
311324
// update runtime package

src/aggregator-cli/Kudu/KuduApi.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Net.Http;
55
using System.Net.Http.Headers;
66
using System.Text;
7+
using System.Text.Json;
78
using System.Text.RegularExpressions;
89
using System.Threading;
910
using System.Threading.Tasks;
@@ -88,6 +89,48 @@ internal async Task<HttpRequestMessage> GetRequestAsync(HttpMethod method, strin
8889
return request;
8990
}
9091

92+
public class ListingEntry
93+
{
94+
public string name { get; set; }
95+
public string href { get; set; }
96+
}
97+
98+
internal async Task<string> ReadApplicationLogAsync(string functionName, int logIndex, CancellationToken cancellationToken)
99+
{
100+
const string FunctionLogPath = "api/vfs/LogFiles/Application/Functions/Function";
101+
102+
logger.WriteVerbose($"Listing application logs for {functionName}");
103+
using (var client = new HttpClient())
104+
{
105+
ListingEntry[] listingResult = null;
106+
107+
using (var listingRequest = await GetRequestAsync(HttpMethod.Get, $"{FunctionLogPath}/{functionName}/", cancellationToken))
108+
{
109+
var listingResponse = await client.SendAsync(listingRequest, cancellationToken);
110+
var listingStream = await listingResponse.Content.ReadAsStreamAsync();
111+
if (listingResponse.IsSuccessStatusCode)
112+
{
113+
listingResult = await JsonSerializer.DeserializeAsync<ListingEntry[]>(listingStream);
114+
}
115+
}
116+
117+
if (logIndex < 0) logIndex = listingResult.Length - 1;
118+
string logName = listingResult[logIndex].name;
119+
120+
using (var logRequest = await GetRequestAsync(HttpMethod.Get, $"{FunctionLogPath}/{functionName}/{logName}", cancellationToken))
121+
{
122+
var logResponse = await client.SendAsync(logRequest, cancellationToken);
123+
string logData = await logResponse.Content.ReadAsStringAsync();
124+
if (!logResponse.IsSuccessStatusCode)
125+
{
126+
logger.WriteError($"Cannot list {functionName}'s {logName} log: {logResponse.ReasonPhrase}");
127+
return null;
128+
}
129+
return logData;
130+
}
131+
}
132+
}
133+
91134
internal async Task StreamLogsAsync(TextWriter output, string lastLinePattern, CancellationToken cancellationToken)
92135
{
93136
var regex = new Regex(lastLinePattern);

src/aggregator-cli/TestCommands/CreateTestCommand.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Threading;
1+
using System;
2+
using System.Threading;
23
using System.Threading.Tasks;
34
using CommandLine;
45

@@ -19,8 +20,10 @@ class CreateTestCommand : CommandBase
1920
[Option('t', "title", Required = false, Default = "Aggregator CLI Test Task", HelpText = "Title for new Work Item.")]
2021
public string Title { get; set; }
2122

22-
[Option('l', "lastLinePattern", Required = false, Default = @"Executed \'Functions\.", HelpText = "RegEx Pattern identifying last line of logs.")]
23-
public string LastLinePattern { get; set; }
23+
//[Option('l', "lastLinePattern", Required = false, Default = @"Executed \'Functions\.", HelpText = "RegEx Pattern identifying last line of logs.")]
24+
//public string LastLinePattern { get; set; }
25+
[Option('r', "rule", Required = true, HelpText = "Aggregator rule name.")]
26+
public string RuleName { get; set; }
2427

2528
internal override async Task<int> RunAsync(CancellationToken cancellationToken)
2629
{
@@ -32,9 +35,13 @@ internal override async Task<int> RunAsync(CancellationToken cancellationToken)
3235
var instances = new AggregatorInstances(context.Azure, context.Logger, context.Naming);
3336
var boards = new Boards(context.Devops, context.Logger);
3437

35-
var streamTask = instances.StreamLogsAsync(instance, lastLinePattern: this.LastLinePattern, cancellationToken: cancellationToken);
3638
int id = await boards.CreateWorkItemAsync(this.Project, this.Title, cancellationToken);
37-
streamTask.Wait(cancellationToken);
39+
40+
// wait for the Event to be processed in AzDO, sent via WebHooks, and the Function to run
41+
Thread.Sleep(new TimeSpan(0, 2, 0));
42+
43+
await instances.ReadLogAsync(instance, this.RuleName, -1, cancellationToken: cancellationToken);
44+
3845
return id > 0 ? 0 : 1;
3946
}
4047
}

src/integrationtests-cli/Scenario1_Minimal.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void MapRules()
7373
[Fact, Order(40)]
7474
void CreateWorkItemAndCheckTrigger()
7575
{
76-
(int rc, string output) = RunAggregatorCommand($"test.create --verbose --resourceGroup {TestLogonData.ResourceGroup} --instance {instanceName} --project \"{TestLogonData.ProjectName}\" ");
76+
(int rc, string output) = RunAggregatorCommand($"test.create --verbose --resourceGroup {TestLogonData.ResourceGroup} --instance {instanceName} --project \"{TestLogonData.ProjectName}\" --rule {ruleName} ");
7777
Assert.Equal(0, rc);
7878
// Sample output from rule:
7979
// Returning 'Hello Task #118 from Rule 5!' from 'TestRule5'

src/integrationtests-cli/Scenario3_MultiInstance.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ void ListMappings(string instancePrefix, string rule)
107107
void CreateWorkItemAndCheckTrigger(string instancePrefix, string rule)
108108
{
109109
string instance = instancePrefix + TestLogonData.UniqueSuffix;
110-
(int rc, string output) = RunAggregatorCommand($"test.create --verbose --resourceGroup {TestLogonData.ResourceGroup} --instance {instance} --project \"{TestLogonData.ProjectName}\" ");
110+
(int rc, string output) = RunAggregatorCommand($"test.create --verbose --resourceGroup {TestLogonData.ResourceGroup} --instance {instance} --project \"{TestLogonData.ProjectName}\" --rule {rule} ");
111111
Assert.Equal(0, rc);
112112
// Sample output from rule:
113113
// Returning 'Hello Task #118 from Rule 5!' from 'TestRule5'
@@ -132,7 +132,7 @@ void RemapRules()
132132
void CreateAnotherWorkItemAndCheckTrigger(string instancePrefix, string rule)
133133
{
134134
string instance = instancePrefix + TestLogonData.UniqueSuffix;
135-
(int rc, string output) = RunAggregatorCommand($"test.create --verbose --resourceGroup {TestLogonData.ResourceGroup} --instance {instance} --project \"{TestLogonData.ProjectName}\" ");
135+
(int rc, string output) = RunAggregatorCommand($"test.create --verbose --resourceGroup {TestLogonData.ResourceGroup} --instance {instance} --project \"{TestLogonData.ProjectName}\" --rule {rule} ");
136136
Assert.Equal(0, rc);
137137
// Sample output from rule:
138138
// Returning 'Hello Task #118 from Rule 5!' from 'TestRule5'

src/integrationtests-cli/Scenario4_NamingTemplate.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ void ListMappings(string instancePrefix, string rule)
108108
void CreateWorkItemAndCheckTrigger(string instancePrefix, string rule)
109109
{
110110
string instance = instancePrefix + TestLogonData.UniqueSuffix;
111-
(int rc, string output) = RunAggregatorCommand($"test.create --verbose --namingTemplate {TemplateFile} --resourceGroup {ResourceGroupName} --instance {instance} --project \"{TestLogonData.ProjectName}\" ");
111+
(int rc, string output) = RunAggregatorCommand($"test.create --verbose --namingTemplate {TemplateFile} --resourceGroup {ResourceGroupName} --instance {instance} --project \"{TestLogonData.ProjectName}\" --rule {rule} ");
112112
Assert.Equal(0, rc);
113113
// Sample output from rule:
114114
// Returning 'Hello Task #118 from Rule 5!' from 'test5'

0 commit comments

Comments
 (0)