//
// 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.Diagnostics;
using System.IO;
using System.Text;
using NUnit.Framework;
namespace Microsoft.SqlTools.ServiceLayer.Test.Common.Baselined
{
///
/// This class serves as the base class for all baselined tests
/// It will provide easy services for you to interact with your test files and their baselines
///
public abstract class BaselinedTest
{
///
/// Holds the extension for the TestScripts
///
private string _testScriptExtension;
///
/// Holds the extensionf or the Baseline files
///
private string _baselineExtension;
///
/// Holds the path to the base location of both TestScripts and Baselines
///
private string _testCategoryName;
///
/// Holds the ROOT Dir for trace output
///
private string _traceOutputDir;
///
/// Holds the prefix for the baseline
///
private string _baselinePrefix;
///
/// Holds the prefix for the Testscript
///
private string _testscriptPrefix;
///
/// Holds the name of the current test
///
private string _currentTestname;
private string _baselineSubDir = string.Empty;
public const string TestScriptDirectory = @"Testscripts";
public const string BaselineDirectory = @"Baselines";
///
/// Gets/Sets the extension for the Testscript files
///
public string TestscriptFileExtension
{
get
{
return _testScriptExtension;
}
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentException("TestscriptFileExtension needs a value");
_testScriptExtension = value;
}
}
///
/// Gets/Sets the extension for the Baseline files
///
public string BaselineFileExtension
{
get
{
return _baselineExtension;
}
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentException("BaselineFileExtension needs a value");
_baselineExtension = value;
}
}
///
/// Gets/Sets the path to the base location of both test scripts and baseline files
///
///
/// Just use the SubDir name
/// TestScripts should be in FileBaseLocation\Testscripts; and Baselines should be in FileBaseLocation\Baselines
/// The value of this will be appended to ROOT_DIR (QA\SrcUTest\Common)
///
public string CategoryName
{
get
{
return _testCategoryName;
}
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentException("FileBaseLocation needs a value");
_testCategoryName = value;
}
}
///
/// Gets/Sets the output base directory for trace output (null = no trace output)
///
public string TraceOutputDirectory
{
get
{
return _traceOutputDir;
}
set
{
_traceOutputDir = value;
}
}
///
/// Gets the full path of where the files will be pulled from
///
public string FilesLocation
{
get
{
return Path.Combine(RunEnvironmentInfo.GetTestDataLocation(), CategoryName, TestScriptDirectory);
}
}
///
/// Gets or Sets the sub directory in Baselines where the exected baseline results are located
///
public string BaselinesSubdir
{
get
{
this._baselineSubDir ??= string.Empty;
return this._baselineSubDir;
}
set { this._baselineSubDir = value; }
}
///
/// Gets the full path of where the baseline files will be pulled from
///
public string BaselineFilePath
{
get
{
return Path.Combine(RunEnvironmentInfo.GetTestDataLocation(), CategoryName, Path.Combine( BaselineDirectory, BaselinesSubdir ));
}
}
///
/// Gets the full path of where the Trace will output
///
public string TraceFilePath
{
get
{
return Path.Combine(Path.GetFullPath(TraceOutputDirectory), this.CategoryName, this.BaselinesSubdir);
}
}
///
/// Gets/Sets the prefix used for baseline files
///
public string BaselinePrefix
{
get
{
return _baselinePrefix;
}
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentException("BaselinePrefix needs a value");
_baselinePrefix = value;
}
}
///
/// Gets/Sets the prefix used for testscript files
///
public string TestscriptPrefix
{
get
{
return _testscriptPrefix;
}
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentException("TestscriptPrefix needs a value");
_testscriptPrefix = value;
}
}
///
/// Gets/Sets the name of the current test
///
public string CurrentTestName
{
get
{
return _currentTestname;
}
}
///
/// Constructor
///
public BaselinedTest()
{
Initialize();
}
///
/// Initializes the class
///
private void Initialize()
{
_testScriptExtension = _baselineExtension = "txt"; //default to txt
_testCategoryName = null;
string projectPath = Environment.GetEnvironmentVariable(Constants.ProjectPath);
if (projectPath != null)
{
_traceOutputDir = Path.Combine(projectPath, "trace");
}
else
{
_traceOutputDir = Environment.ExpandEnvironmentVariables(@"%SystemDrive%\trace\");
}
_baselinePrefix = "BL";
_testscriptPrefix = "TS";
}
///
/// This method should be called whenever you do a [TestInitialize]
///
public virtual void TestInitialize()
{
if (string.IsNullOrEmpty(_testCategoryName))
throw new ArgumentException("Set CategoryName to the name of the directory containing your Testscripts and Baseline files");
if (!Directory.Exists(FilesLocation))
throw new FileNotFoundException(string.Format("Path to Testscripts ([{0}]) does not exist.", FilesLocation));
if (!Directory.Exists(BaselineFilePath))
throw new FileNotFoundException(string.Format("Path to Baseline Files [{0}] does not exist.", BaselineFilePath));
if (!string.IsNullOrEmpty(TraceFilePath) && !Directory.Exists(TraceFilePath)) //if this does not exist, then we want it (pronto)
Directory.CreateDirectory(TraceFilePath);
}
///
/// Gets the name of the testscript with the provided name
///
/// Name of the test
/// the path to the baseline file
/// Asserts that file exists
public string GetTestscriptFilePath(string name)
{
string retVal = Path.Combine(FilesLocation, string.Format("{0}-{1}.{2}", TestscriptPrefix, name, TestscriptFileExtension));
Assert.True(File.Exists(retVal), string.Format("TestScript [{0}] does not exist", retVal));
return retVal;
}
///
/// Gets the name of the test script with the provided name and the provided index
///
/// Name of the test
/// File index
/// the path to the baseline file
/// Asserts that file exists
public string GetTestscriptFilePath(string name, int index)
{
string retVal = Path.Combine(FilesLocation, string.Format("{0}-{1}{2}.{3}", TestscriptPrefix, name, index.ToString(), TestscriptFileExtension));
Assert.True(File.Exists(retVal), string.Format("TestScript [{0}] does not exist", retVal));
return retVal;
}
///
/// Gets the formatted baseline file name
///
/// Name of the test
public string GetBaselineFileName(string name)
{
return string.Format("{0}-{1}.{2}", BaselinePrefix, name, BaselineFileExtension);
}
///
/// Gets the file path to the baseline file for the named case
///
/// Name of the test
/// the path to the baseline file
/// Asserts that file exists
public string GetBaselineFilePath(string name, bool assertIfNotFound)
{
string retVal = Path.Combine(BaselineFilePath, GetBaselineFileName(name));
if (assertIfNotFound)
{
Assert.True(File.Exists(retVal), string.Format("Baseline [{0}] does not exist", retVal));
}
return retVal;
}
public string GetBaselineFilePath(string name)
{
return GetBaselineFilePath(name, true);
}
///
/// Gets the contents of a file
///
/// Path of the file to read
/// The contents of the file
public string GetFileContent(string path)
{
Trace.WriteLine(string.Format("GetFileContent for [{0}]", Path.GetFullPath(path)));
using (StreamReader sr = new StreamReader(File.Open(path, FileMode.Open), Encoding.UTF8))
{
return sr.ReadToEnd();
}
}
///
/// Dumps the text to a Trace file
///
/// Test name used to create file name
/// Text to dump to the trace file
/// Overwrites whatever is already in the file (if anything)
public string DumpToTrace(string testName, string text)
{
if (string.IsNullOrEmpty(TraceFilePath))
{
return string.Empty; //nothing to do
}
string traceFile = Path.Combine(TraceFilePath, GetBaselineFileName(testName));
if (File.Exists(traceFile))
{
Trace.Write(string.Format("Overwriting existing trace file [{0}]", traceFile));
File.Delete(traceFile);
}
else
{
Trace.Write(string.Format("Dumping to trace file [{0}]", traceFile));
}
if (Directory.Exists(TraceFilePath) == false)
{
Directory.CreateDirectory(TraceFilePath);
}
WriteTraceFile(traceFile, text);
return traceFile;
}
///
/// Writes the context to the trace file
///
/// The file name for the trace output
/// The content for the trace file
public void WriteTraceFile(string traceFile, string text)
{
File.WriteAllText(traceFile, text);
}
///
/// Converts a string to a stream
///
///
///
private Stream GetStreamFromString(string s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
///
/// Starts the actual running of the test after nicely initializing
///
/// Name of the test
public void Start(string testname)
{
Trace.WriteLine(string.Format("Starting test named [{0}]", testname));
_currentTestname = testname;
Run();
Trace.WriteLine("Test Completed");
}
///
/// Runs the actual test
///
/// Override this method to put in your test logic
public abstract void Run();
}
}