Skip to content

Commit

Permalink
test: Add integration tests for Audit logging. (#2030) (#2108)
Browse files Browse the repository at this point in the history
  • Loading branch information
tippmar-nr authored Nov 30, 2023
1 parent 6bb2ad1 commit 924765b
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2020 New Relic, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Threading;
using Xunit.Abstractions;

namespace NewRelic.Agent.IntegrationTestHelpers
{
public class AuditLogFile : AgentLogBase
{
private readonly string _filePath;
private readonly string _fileName;

public bool Found => File.Exists(_filePath);

public AuditLogFile(string logDirectoryPath, ITestOutputHelper testLogger, string fileName = "", TimeSpan? timeoutOrZero = null, bool throwIfNotFound = true)
: base(testLogger)
{
Contract.Assert(logDirectoryPath != null);

_fileName = fileName;

var timeout = timeoutOrZero ?? TimeSpan.Zero;

var timeTaken = Stopwatch.StartNew();

var searchPattern = _fileName != string.Empty ? _fileName : "*_audit.log";

do
{
var mostRecentlyUpdatedFile = Directory.Exists(logDirectoryPath) ?
Directory.GetFiles(logDirectoryPath, searchPattern)
.OrderByDescending(File.GetLastWriteTimeUtc)
.FirstOrDefault() : null;

if (mostRecentlyUpdatedFile != null)
{
_filePath = mostRecentlyUpdatedFile;
return;
}

Thread.Sleep(TimeSpan.FromSeconds(1));
} while (timeTaken.Elapsed < timeout);

if (throwIfNotFound)
throw new Exception($"Waited {timeout.TotalSeconds:N0}s but didn't find an audit log matching {Path.Combine(logDirectoryPath, searchPattern)}.");
}

public override IEnumerable<string> GetFileLines()
{
if (!Found)
yield break;

string line;
using (var fileStream = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var streamReader = new StreamReader(fileStream))
while ((line = streamReader.ReadLine()) != null)
{
yield return line;
}
}

public string GetFullLogAsString()
{
using (var fileStream = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var streamReader = new StreamReader(fileStream))
{
return streamReader.ReadToEnd();
}
}

public const string AuditLogLinePrefixRegex = @"^.*?NewRelic Audit: ";
public const string AuditDataSentLogLineRegex = AuditLogLinePrefixRegex + "Data Sent from the InstrumentedApp : .*";
public const string AuditDataReceivedLogLineRegex = AuditLogLinePrefixRegex + "Data Received from the Collector : .*";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -414,5 +414,11 @@ public NewRelicConfigModifier EnableAspNetCore6PlusBrowserInjection(bool enableB
CommonUtils.ModifyOrCreateXmlAttributeInNewRelicConfig(_configFilePath, new[] { "configuration", "appSettings", "add"}, "value", $"{enableBrowserInjection}");
return this;
}

public void EnableAuditLog(bool enableAuditLog)
{
CommonUtils.ModifyOrCreateXmlAttributeInNewRelicConfig(_configFilePath, new[] { "configuration", "log" }, "auditLog",
enableAuditLog.ToString().ToLower());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public void SetTestClassType(Type testClassType)

public AgentLogFile AgentLog => _agentLogFile ?? (_agentLogFile = new AgentLogFile(DestinationNewRelicLogFileDirectoryPath, TestLogger, AgentLogFileName, Timing.TimeToWaitForLog, AgentLogExpected));

private AuditLogFile _auditLogFile;
public bool AuditLogExpected { get; set; } = false;
public AuditLogFile AuditLog => _auditLogFile ?? (_auditLogFile = new AuditLogFile(DestinationNewRelicLogFileDirectoryPath, TestLogger, timeoutOrZero: Timing.TimeToWaitForLog, throwIfNotFound: AuditLogExpected));


public ProfilerLogFile ProfilerLog { get { return RemoteApplication.ProfilerLog; } }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2020 New Relic, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
using System.Linq;
using NewRelic.Agent.IntegrationTestHelpers;
using Xunit;
using Xunit.Abstractions;

namespace NewRelic.Agent.IntegrationTests.Logging.AuditLog
{
[NetCoreTest]
public class AuditLogTests : NewRelicIntegrationTest<RemoteServiceFixtures.AspNetCoreMvcBasicRequestsFixture>
{
private readonly RemoteServiceFixtures.AspNetCoreMvcBasicRequestsFixture _fixture;

public AuditLogTests(RemoteServiceFixtures.AspNetCoreMvcBasicRequestsFixture fixture, ITestOutputHelper output) :
base(fixture)
{
_fixture = fixture;
_fixture.TestLogger = output;

_fixture.AuditLogExpected = true;

_fixture.AddActions
(
setupConfiguration: () =>
{
var configModifier = new NewRelicConfigModifier(fixture.DestinationNewRelicConfigFilePath);
configModifier.EnableAuditLog(true);
},
exerciseApplication: () =>
{
_fixture.Get();
_fixture.AgentLog.WaitForLogLine(AgentLogBase.ShutdownLogLineRegex, TimeSpan.FromMinutes(2));
}
);

_fixture.Initialize();

}

[Fact]
public void AuditLogExistsAndHasSentAndReceivedData()
{
Assert.True(_fixture.AuditLog.Found);

var dataSentLogLines = _fixture.AuditLog.TryGetLogLines(AuditLogFile.AuditDataSentLogLineRegex).ToList();
var dataReceivedLogLines = _fixture.AuditLog.TryGetLogLines(AuditLogFile.AuditDataReceivedLogLineRegex).ToList();

Assert.Multiple(() =>
{
Assert.True(dataSentLogLines.Count == 2 * dataReceivedLogLines.Count); // audit log always contains 2 "sent" lines for every "received" line
});
}
}
}

0 comments on commit 924765b

Please sign in to comment.