У меня есть проект, который считывает XML-файл ожидаемых результатов сборки для каждой области сборки и сравнивает ее с журналами сборки, чтобы определить, прошла ли сборка. Прямо сейчас linq показывает каждое условие в отдельной строке результатов, но (поскольку я просматриваю каждую строку результатов linq, чтобы проверить успешность) мне нужно иметь возможность проверять оба условия (если их два) в момент в одно и то же время, а не в разное время. В противном случае я мог бы проверять не ту строку файла журнала. Обратите внимание, что иногда существует два критерия успеха, но не всегда. Мне нужно проверить только два условия одновременно.
Мой вопрос: как проверить оба условия одновременно? Например, таблица, которую я помещаю в xml, для некоторых частей журнала выглядит так: ParseISLogStats (поэтому мне нужно проверить правильность BuildProject и BaseBuildArea в журнале, поскольку это разные столбцы, но критерий успеха только один для этих двух условия):
ParseISLogStats BuildProject=DInstallerBuild BaseBuildArea=D:\R\K\v2.1\nightly Status=Success
ParseISLogStats BuildProject=KInstallerBuild BaseBuildArea=D:\R\K\v2.1\nightly Status=Success
ParseISLogStats BuildProject=IInstallerBuild BaseBuildArea=D:\R\K\v2.1\nightly Status=Success
и файл журнала, который я проверяю, выглядит так:
StartTime EndTime Day Elapsed sec Status BuildProj Desc Projects FailedProj Errors Warnings FailedProjList BaseBuildArea LogFile AdditionalInfo
04/16/24 21:57:31 04/16/24 22:02:46 Tue 00:05:15 315 Success DInstallerBuild K v2.1 nightly 16 0 0 20 D:\R_Builds\K\v2.1\nightly X:\D\Build\Installers\DInstallerBuild.log
04/16/24 22:06:53 04/16/24 22:18:20 Tue 00:11:27 687 Success KInstallerBuild K v2.1 nightly 9 0 0 19 D:\R_Builds\K\v2.1\nightly X:\K\Build\Installers\KInstallerBuild.log
04/16/24 22:26:43 04/16/24 22:29:32 Tue 00:02:49 169 Success KInstallerBuild K v2.1 nightly 2 0 0 5 D:\R_Builds\K\v2.1\nightly X:\K\Build\Installers\KInstallerBuild.log
04/17/24 00:19:00 04/17/24 00:24:00 Wed 00:05:00 300 Success Incremental_v2.1 v2.1 Incremental Installer Builds 5 0 0 8 D:\R_Builds\K\v2.1\nightly I:\Logs\IncrementalInstallBuildLog_v2.1.txt
Я рассматривал следующие примеры:
linq
linq
В моем коде linq извлекает то, что выглядит вот так:
19:00
build_machine='mach31', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\R\filename1.cs', field='Status', comparison='equal', value='Success'
build_machine='mach31', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\R\filename2.cs', field='Status', comparison='equal', value='Success'
build_machine='mach31', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\R\filename3.h', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\fiename5.h', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename6.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\D\filename7.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\K\filename8.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\K\filename9.h', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\K\filename11.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename22.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename33.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinISProjectVersionStats', condition name='ProductName', condition value = 'P1', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinISProjectVersionStats', condition name='ProductName', condition value = 'P2', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinISProjectVersionStats', condition name='ProductName', condition value = 'P3', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='GetSWStats', condition name='DestinationPath', condition value = 'D:\Builds\Retail\nightly', field='UpdateRequired', comparison='equal', value='YES'
build_machine='mach46', process_name='GetSWStats', condition name='DestinationPath', condition value = 'D:\Builds\Retail\nightly', field='Status', comparison='equal', value='Successful'
build_machine='mach46', process_name='ParseISLogStats', condition name='BuildProject', condition value = 'RetailInstallerBuild', field='Projects', comparison='equal', value='33'
build_machine='mach46', process_name='ParseISLogStats', condition name='BuildProject', condition value = 'RetailInstallerBuild', field='Projects', comparison='equal', value='8'
build_machine='mach46', process_name='ParseISLogStats', condition name='BuildProject', condition value = 'RetailInstallerBuild', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='ParseISLogStats', condition name='BuildProject', condition value = 'DInstallerBuild', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='ParseISLogStats', condition name='BaseBuildArea', condition value = 'D:\R_Builds\K\v2.1\nightly', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='ParseISLogStats', condition name='BuildProject', condition value = 'KInstallerBuild', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='ParseISLogStats', condition name='BaseBuildArea', condition value = 'D:\R_Builds\K\v2.1\nightly', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='ParseISLogStats', condition name='BuildProject', condition value = 'KInstallerBuild', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='ParseISLogStats', condition name='BaseBuildArea', condition value = 'D:\R_Builds\K\v2.1\nightly', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='ParseISLogStats', condition name='BuildProject', condition value = 'Incremental_v2.1', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='ParseISLogStats', condition name='BaseBuildArea', condition value = 'D:\RP_Builds\KPEX\v24.1\nightly', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='UpdateBuildArea-Stats', condition name='DestPath', condition value = '\\mach62\Builds\nightly', field='Dir', comparison='equal', value='Retail'
build_machine='mach46', process_name='UpdateBuildArea-Stats', condition name='DestPath', condition value = '\\mach62\Builds\nightly', field='eSecs', comparison='greaterThan', value='0'
Пока у меня есть этот код:
void ReadXml()
{
int i_results = 0; //0 is successful for all; if it increases we have failed in one
XmlDocument xml = new XmlDocument();
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string newPath = Path.GetFullPath(Path.Combine(path, @"..\.."));
string finalPathXml = Path.GetFullPath(Path.Combine(newPath, @"BuildVerificationBuildAttributes_t.xml"));
//linq
XDocument xmlDoc1 = XDocument.Load(finalPathXml);
XElement buildVerificationElement = xmlDoc1.Element("BuildVerification");
IEnumerable buildElements = buildVerificationElement.Elements("build");
IEnumerable buildMachines = buildElements.Elements("BuildMachine");
//get just the times from the xml
var codeFreezeTime = xmlDoc1.Descendants("codeFreezeTime").First()?.Value;
Console.WriteLine(codeFreezeTime);
IEnumerable processes = buildMachines.Elements("Process");
IEnumerable processNames = processes.Elements("ProcessName");
IEnumerable conditions = processNames.Elements("Conditions");
var found = xmlDoc1.XPathEvaluate("/BuildVerification/build/BuildMachine/Process/ProcessName/Conditions") as IEnumerable;
var results =
xmlDoc1.Descendants("build")
.SelectMany(b => b.Descendants("Process")
.SelectMany(p => p.Descendants("Condition")
.SelectMany(c =>c.Descendants("SuccessCriteria")
.Select(sc => new
{
buildMach = (string)b.Element("BuildMachine"),
p1 = (string)p.Element("ProcessName"),
startTimeHeader = (string)p.Element("startTimeHeader"),
cName = (string)c.Attribute("name"),
cValue = (string)c.Attribute("value"),
f1 = (string)sc.Element("field"),
c1 = (string)sc.Element("comparison"),
v1 = (string)sc.Element("value")
})))).ToList();
foreach (var cur in results)
{
Console.WriteLine("build_machine='{0}', process_name='{1}', condition name='{2}', condition value = '{3}', field='{4}', comparison='{5}', value='{6}'",
cur.buildMach, cur.p1, cur.cName, cur.cValue, cur.f1, cur.c1, cur.v1);
i_results += ParseLogFile(codeFreezeTime, cur.startTimeHeader, cur.buildMach, cur.p1, cur.cName, cur.cValue, cur.f1, cur.c1, cur.v1);
}
if(i_results > 0)
Console.WriteLine("Build has failed this many times:{0} ", i_results);
}
Код, который получает информацию из linq, выглядит следующим образом, но он длинный, но я показываю только первую часть:
int ParseLogFile(string codeFreezeTime, string startTimeHeader, string serverName, string logName, string cName, string cValue, string field1, string comparison1, string val)
{
//bool b_results = false; //failed
bool b_foundResultWhenExpected = false;
int i_results = 0; //add 1 for each fail
//path to file to read and parse
string serverPath = @"\\\\" + serverName;
string logNameFull = logName + ".txt";
string partialPath = "";
string combinedPath2 = partialPath + logNameFull;
Uri serverUri = new Uri(serverPath + combinedPath2);
string finalPath = serverUri.LocalPath;
DateTime today = DateTime.Today;
string s_today = today.ToString("MM/dd/yyyy");
DateTime yesterday = DateTime.Today.AddDays(-1); //code freeze day is day before run check
DateTime dayBeforeYesterday = DateTime.Today.AddDays(-2); //for SpinFile logs we use any time after previous code freeze
string yesterdayDate = (yesterday).ToString("MM/dd/yyyy");
string dayBeforeYesterdayDate = (dayBeforeYesterday).ToString("MM/dd/yyyy");
string yesterdayDateWithTime = yesterdayDate + " " + codeFreezeTime;
string dayBeforeYesterdayDateWithTime = dayBeforeYesterdayDate + " " + codeFreezeTime;
CultureInfo provider = CultureInfo.CurrentCulture;
DateTime yesterdayDateTime = DateTime.ParseExact(yesterdayDateWithTime, "MM/dd/yyyy HH:mm", provider);
DateTime DayBeforeYesterdayDateTime = DateTime.ParseExact(dayBeforeYesterdayDateWithTime, "MM/dd/yyyy HH:mm", provider);
// Read file content into a DataTable using delimiters
DataTable dataTable = ReadDataTable(finalPath);
foreach (DataRow row in dataTable.Rows)
{
if (Regex.IsMatch((row[startTimeHeader]).ToString(), @"^\d+")) //date starts with number..filter out rows that have general logging instead of dated table entries
{
string tmpStartDT = ((row[startTimeHeader]).ToString()).Trim(); //in case extra spaces for date string
tmpStartDT = tmpStartDT.Replace(" ", " "); //take care of datetime that have two spaces between date and time, which is an error
//using H and not HH because military time (capital H), and this handles 0:01 and 05:01 and 14:01 (one H)
if (((logName.Contains("Spin")) && (startDate > DayBeforeYesterdayDateTime)) || (startDate > yesterdayDateTime))
{
if (((string)row[cName]).Replace("\\", "") == (cValue).Replace("\\", "")) //put this after date check
{
float left = 0, right = 0;
string mostRecentComparison = row[field1].ToString();
switch (comparison1)
{
case "equal":
if (mostRecentComparison == val) //pass/success
{
Console.WriteLine(serverName + " " + logName + " " + cName + " " + cValue + " " + field1 + " " + comparison1 + " " + mostRecentComparison + " Perfect!");
}
else if (logName == "GetSWStats")
{
if (val == "UpToDate")
{
Console.WriteLine(serverName + " " + logName + " " + cName + " " + cValue + " " + field1 + " " + comparison1 + " " + mostRecentComparison + "Which is ok");
}
}
else //fail
{ //check for retries
if (!peekAheadToSeeIfSuccessWhenInFailure(dataTable, (debug_i - 1), cValue, cName, field1, comparison1, val)) //it never retries successfully
{
Console.WriteLine(serverName + " " + logName + " " + cName + " " + cValue + " " + field1 + " " + mostRecentComparison + " " + " does not " + comparison1 + " " + val + " Found: " + mostRecentComparison + " Error! *****"); //show value of row, not xml val
i_results++;
}
}
break;
...
}//valid time
}//foreach
} //ParseLogFile
Вот как выглядит мой XML:
19:00
mach31
SpinFileVersionStats
StartTime
Status
equal
Success
SpinFileVersionStats
StartTime
Status
equal
Success
SpinFileVersionStats
StartTime
Status
equal
Success
mach46
SpinFileVersionStats
StartTime
Status
equal
Success
SpinFileVersionStats
StartTime
Status
equal
Success
SpinFileVersionStats
StartTime
Status
equal
Success
SpinFileVersionStats
StartTime
Status
equal
Success
SpinFileVersionStats
StartTime
Status
equal
Success
SpinFileVersionStats
StartTime
Status
equal
Success
SpinFileVersionStats
StartTime
Status
equal & l t ; ! - - c a n ' t u s e & g t ; = h e r e - - & g t ; < b r / > & l t ; v a l u e & g t ; S u c c e s s & l t ; / v a l u e & g t ; < b r / > & l t ; / S u c c e s s C r i t e r i a & g t ; < b r / > & l t ; / C o n d i t i o n & g t ; < b r / > & l t ; / C o n d i t i o n s & g t ; < b r / > & l t ; / P r o c e s s & g t ; < b r / > & l t ; P r o c e s s & g t ; < b r / > & l t ; P r o c e s s N a m e & g t ; S p i n F i l e V e r s i o n S t a t s & l t ; / P r o c e s s N a m e & g t ; < b r / > & l t ; s t a r t T i m e H e a d e r & g t ; S t a r t T i m e & l t ; / s t a r t T i m e H e a d e r & g t ; < b r / > & l t ; C o n d i t i o n s & g t ; < b r / > & l t ; C o n d i t i o n < b r / > n a m e = ' V e r s i o n F i l e ' v a l u e = & q u o t ; \ \ v i e w \ B u i l d _ N i g h t l y D e v e l o p e r \ K \ f i l e n a m e 2 2 . c s & q u o t ; & g t ; < b r / > < b r / > & l t ; S u c c e s s C r i t e r i a & g t ; < b r / > & l t ; f i e l d & g t ; S t a t u s & l t ; / f i e l d & g t ; < b r / > & l t ; c o m p a r i s o n & g t ; e q u a l & l t ; / c o m p a r i s o n & g t ; < b r / > & l t ; v a l u e & g t ; S u c c e s s & l t ; / v a l u e & g t ; < b r / > < b r / > & l t ; / S u c c e s s C r i t e r i a & g t ; < b r / > & l t ; / C o n d i t i o n & g t ; < b r / > & l t ; / C o n d i t i o n s & g t ; < b r / > & l t ; / P r o c e s s & g t ; < b r / > & l t ; P r o c e s s & g t ; < b r / > & l t ; P r o c e s s N a m e & g t ; S p i n F i l e V e r s i o n S t a t s & l t ; / P r o c e s s N a m e & g t ; < b r / > & l t ; s t a r t T i m e H e a d e r & g t ; S t a r t T i m e & l t ; / s t a r t T i m e H e a d e r & g t ; < b r / > & l t ; C o n d i t i o n s & g t ; < b r / > & l t ; C o n d i t i o n < b r / > n a m e = ' V e r s i o n F i l e ' v a l u e = & q u o t ; \ \ v i e w \ B u i l d _ N i g h t l y D e v e l o p e r \ K \ f i l e n a m e 3 3 . c s & q u o t ; & g t ; < b r / > < b r / >
Status
equal
Success
SpinISProjectVersionStats
StartTime
Status
equal
Success
SpinISProjectVersionStats
StartTime
Status
equal
Success
SpinISProjectVersionStats
StartTime
Status
equal
Success
GetSWStats
StartTime
UpdateRequired
equal
YES
Status
equal
Successful
ParseISLogStats
StartTime
Projects
equal
33
Projects
equal
8
Status
equal
Success
ParseISLogStats
StartTime
Status
equal
Success
Status
equal
Success
ParseISLogStats
StartTime
Status
equal
Success
Status
equal
Success
ParseISLogStats
StartTime
Status
equal
Success
Status
equal
Success
ParseISLogStats
StartTime
Status
equal
Success
Status
equal
Success
UpdateBuildArea-Stats
StartTime
Dir
equal
Retail
eSecs
greaterThan
0
Подробнее здесь: https://stackoverflow.com/questions/783 ... conditions