Files
Sakshi Sharma 4334d79d76 Add "Open XEL file" support to profiler in sqltoolsservice (#2091)
* Open XEL file changes

* placeholders for openxel

* add observable xe reader

* md format tweaks

* implement localfile as a new session type

* add ErrorMessage to session stopped notice

* fix flaky test

* handle already running session

* fix stopped session event send on file completion

* fix flaky unit test

* Update XElite and dependent versions

* Fix errors after merge and remove failing tests for now

* Fix main merge mess-up.
Address comments.
Add one more relevant test.

* Remove extra namespace.

* Remove unnecessary import

* Fix build error

* Address comments.

* Remove disabiling JSON002 compiler warning

* Address comments and update json handling

* Fix build error

* Fix integration test (emerged due to Main merge mess up)

* Clean up code (no functional changes)

---------

Co-authored-by: Karl Burtram <karlb@microsoft.com>
Co-authored-by: shueybubbles <david.shiflet@microsoft.com>
2023-06-27 14:25:18 -07:00

114 lines
4.2 KiB
C#

//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System;
using System.Collections.Generic;
using System.IO;
using NUnit.Framework;
using System.Reflection;
using Microsoft.SqlTools.ServiceLayer.Profiler.Contracts;
using Microsoft.SqlTools.ServiceLayer.Profiler;
using System.Threading;
using System.Linq;
using Moq;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Profiler
{
public class XeStreamObservableTests
{
/// <summary>
/// this might technically be an integration test but putting it here because it doesn't require any connectivity.
/// </summary>
[Test]
public void XeStreamObservable_reads_entire_xel_file()
{
var observer = InitializeFileObserver();
observer.Observable.Start();
var retries = 100;
while (!observer.Completed && retries-- > 0)
{
Thread.Sleep(100);
}
Assert.That(observer.Completed, Is.True, $"Reading the file didn't complete in 10 seconds. Events read: {observer.ProfilerEvents.Count}");
Assert.Multiple(() =>
{
Assert.That(observer.ProfilerEvents.Count, Is.EqualTo(149), "Number of events read");
Assert.That(observer.ProfilerEvents[0].Name, Is.EqualTo("rpc_completed"), "First event in the file");
Assert.That(observer.ProfilerEvents.Last().Name, Is.EqualTo("sql_batch_completed"), "Last event in the file");
});
}
[Test]
public void XeStreamObservable_calls_OnError_when_the_fetcher_fails()
{
var observer = InitializeFileObserver("thispathdoesnotexist.xel");
observer.Observable.Start();
var retries = 10;
while (!observer.Completed && retries-- > 0)
{
Thread.Sleep(100);
}
Assert.Multiple(() =>
{
Assert.That(observer.Completed, Is.True, $"Reading the missing file didn't complete in 1 second.");
Assert.That(observer.Error?.GetBaseException(), Is.InstanceOf<FileNotFoundException>(), $"Expected Error from missing file. Error:{observer.Error}");
});
}
private XeStreamObserver InitializeFileObserver(string filePath = null)
{
filePath ??= Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Profiler", "TestXel_0.xel");
var profilerService = SetupProfilerService(filePath);
var xeStreamObservable = new XeStreamObservable(() =>
{
return profilerService.initIXEventFetcher(filePath);
});
var observer = new XeStreamObserver() { Observable = xeStreamObservable };
xeStreamObservable.Subscribe(observer);
return observer;
}
private ProfilerService SetupProfilerService (string filePath = null)
{
filePath ??= Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Profiler", "TestXel_0.xel");
var sessionFactory = new Mock<IXEventSessionFactory>();
var profilerService = new ProfilerService() { XEventSessionFactory = sessionFactory.Object };
return profilerService;
}
}
sealed class XeStreamObserver : IObserver<ProfilerEvent>
{
public XeStreamObservable Observable { get; set; }
public readonly List<ProfilerEvent> ProfilerEvents = new List<ProfilerEvent>();
public bool Completed { get; private set; }
public Exception Error { get; private set; }
public void OnCompleted()
{
Completed = true;
}
public void OnError(Exception error)
{
Error = error;
}
public void OnNext(ProfilerEvent value)
{
ProfilerEvents.Add(value);
OnEventAdded?.Invoke(this, EventArgs.Empty);
}
public event EventHandler OnEventAdded;
}
}