This allows avoiding false positives for rare failures and failures with ever changing messages.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48912 Signed-off-by: Francois Gouget fgouget@codeweavers.com --- This patch requires updating the database schema and restarting the TestBot Engine and web server.
Notes: - This first patch only introduces the core infrastructure. The other parts are: - Providing a web interface to enter known failures (next patch). - Matching the known failures in the logs and recording the matches in the database. - Taking the known failures into account in the report emails and patches status. - Identifying the known failures on the JobDetails page. - Update the associated bug information.
- Because more patches are needed to to actually do anything useful, these two patches are mostly meant to show what the framework looks like. So if desired they can be dropped so they are committed as part of a more complete set.
- Most bug tracking systems use integers to identify bugs. If we ever want to move Wine's bug tracking away from Bugzilla we may have to change the type of the BugId field. We may also need a way to know which bug tracker a given BugId refers to which may involve adding a BugTracker field or replacing the BugId field with the whole bug URL.
- The Jobs::Restart() chunk depends on the patch that turns Itemrefs into virtual properties. Without it it would be unable to filter the TaskFailures table on the JobId property. --- testbot/ddl/update47.sql | 33 + testbot/ddl/winetestbot.sql | 32 + testbot/doc/winetestbot-schema.dia | 852 +++++++++++++++++++++--- testbot/lib/WineTestBot/Failures.pm | 150 +++++ testbot/lib/WineTestBot/Jobs.pm | 6 + testbot/lib/WineTestBot/TaskFailures.pm | 120 ++++ testbot/lib/WineTestBot/Tasks.pm | 4 + 7 files changed, 1108 insertions(+), 89 deletions(-) create mode 100644 testbot/ddl/update47.sql create mode 100644 testbot/lib/WineTestBot/Failures.pm create mode 100644 testbot/lib/WineTestBot/TaskFailures.pm
diff --git a/testbot/ddl/update47.sql b/testbot/ddl/update47.sql new file mode 100644 index 000000000..ff59339f1 --- /dev/null +++ b/testbot/ddl/update47.sql @@ -0,0 +1,33 @@ +USE winetestbot; + +CREATE TABLE Failures +( + Id INT NOT NULL AUTO_INCREMENT, + TestModule VARCHAR(64) NOT NULL, + TestUnit VARCHAR(32) NOT NULL, + ConfigRegExp VARCHAR(64) NULL, + FailureRegExp VARCHAR(256) NOT NULL, + Notes VARCHAR(128) NULL, + LastNew DATETIME NULL, + LastOld DATETIME NULL, + BugId INT NOT NULL, + BugStatus VARCHAR(32) NULL, + BugDescription VARCHAR(128) NULL, + PRIMARY KEY (Id) +) +ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE TaskFailures +( + FailureId INT NOT NULL, + JobId INT NOT NULL, + StepNo INT(2) NOT NULL, + TaskNo INT(2) NOT NULL, + TaskLog VARCHAR(32) NOT NULL, + NewCount INT NULL, + OldCount INT NULL, + FOREIGN KEY(FailureId) REFERENCES Failures(Id), + FOREIGN KEY(JobId, StepNo, TaskNo) REFERENCES Tasks(JobId, StepNo, No), + PRIMARY KEY (FailureId, JobId, StepNo, TaskNo, TaskLog) +) +ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/testbot/ddl/winetestbot.sql b/testbot/ddl/winetestbot.sql index 2d085247c..9781fb8dd 100644 --- a/testbot/ddl/winetestbot.sql +++ b/testbot/ddl/winetestbot.sql @@ -164,6 +164,38 @@ CREATE TABLE Tasks ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE Failures +( + Id INT NOT NULL AUTO_INCREMENT, + TestModule VARCHAR(64) NOT NULL, + TestUnit VARCHAR(32) NOT NULL, + ConfigRegExp VARCHAR(64) NULL, + FailureRegExp VARCHAR(256) NOT NULL, + Notes VARCHAR(128) NULL, + LastNew DATETIME NULL, + LastOld DATETIME NULL, + BugId INT NOT NULL, + BugStatus VARCHAR(32) NULL, + BugDescription VARCHAR(128) NULL, + PRIMARY KEY (Id) +) +ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE TaskFailures +( + FailureId INT NOT NULL, + JobId INT NOT NULL, + StepNo INT(2) NOT NULL, + TaskNo INT(2) NOT NULL, + TaskLog VARCHAR(32) NOT NULL, + NewCount INT NULL, + OldCount INT NULL, + FOREIGN KEY(FailureId) REFERENCES Failures(Id), + FOREIGN KEY(JobId, StepNo, TaskNo) REFERENCES Tasks(JobId, StepNo, No), + PRIMARY KEY (FailureId, JobId, StepNo, TaskNo, TaskLog) +) +ENGINE=InnoDB DEFAULT CHARSET=utf8; + CREATE TABLE RecordGroups ( Id INT NOT NULL AUTO_INCREMENT, diff --git a/testbot/doc/winetestbot-schema.dia b/testbot/doc/winetestbot-schema.dia index b2a686285..13374ad73 100644 --- a/testbot/doc/winetestbot-schema.dia +++ b/testbot/doc/winetestbot-schema.dia @@ -669,7 +669,7 @@ <dia:point val="-7.87083,-21.5"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="-7.92083,-23;-4.3375,-21.45"/> + <dia:rectangle val="-7.92083,-22.9955;-4.3375,-21.45"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> @@ -729,7 +729,7 @@ <dia:point val="4.6125,-22.35"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="4.5625,-23;11.0958,-22.2834"/> + <dia:rectangle val="4.5625,-22.9955;11.0958,-22.2834"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> @@ -789,7 +789,7 @@ <dia:point val="19.6608,-21.5334"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="19.6108,-22.2;25.4458,-21.4834"/> + <dia:rectangle val="19.6108,-22.1955;25.4458,-21.4834"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> @@ -846,16 +846,16 @@ </dia:object> <dia:object type="Database - Table" version="0" id="O7"> <dia:attribute name="obj_pos"> - <dia:point val="-16.8208,-13.3167"/> + <dia:point val="-16.8208,-6.6667"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="-16.8208,-13.3167;-7.8208,-10.3167"/> + <dia:rectangle val="-16.8208,-6.6667;-7.8208,-3.6667"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="elem_corner"> - <dia:point val="-16.8208,-13.3167"/> + <dia:point val="-16.8208,-6.6667"/> </dia:attribute> <dia:attribute name="elem_width"> <dia:real val="9"/> @@ -962,16 +962,16 @@ </dia:object> <dia:object type="Database - Table" version="0" id="O8"> <dia:attribute name="obj_pos"> - <dia:point val="-16.3208,-2.55002"/> + <dia:point val="-16.3208,3.89998"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="-16.3208,-2.55002;-6.1658,5.24998"/> + <dia:rectangle val="-16.3208,3.89998;-6.1658,11.7"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="elem_corner"> - <dia:point val="-16.3208,-2.55002"/> + <dia:point val="-16.3208,3.89998"/> </dia:attribute> <dia:attribute name="elem_width"> <dia:real val="10.155000000000001"/> @@ -1216,16 +1216,16 @@ </dia:object> <dia:object type="Database - Table" version="0" id="O9"> <dia:attribute name="obj_pos"> - <dia:point val="-4.57083,-14.9167"/> + <dia:point val="-4.57083,-8.2667"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="-4.57083,-14.9167;4.81417,-6.3167"/> + <dia:rectangle val="-4.57083,-8.2667;4.81417,0.3333"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="elem_corner"> - <dia:point val="-4.57083,-14.9167"/> + <dia:point val="-4.57083,-8.2667"/> </dia:attribute> <dia:attribute name="elem_width"> <dia:real val="9.3850000000000016"/> @@ -1493,16 +1493,16 @@ </dia:object> <dia:object type="Database - Table" version="0" id="O10"> <dia:attribute name="obj_pos"> - <dia:point val="-2.55417,-2.51669"/> + <dia:point val="-2.55417,3.88331"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="-2.55417,-2.51669;12.6058,2.88331"/> + <dia:rectangle val="-2.55417,3.88331;12.6058,9.28331"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="elem_corner"> - <dia:point val="-2.55417,-2.51669"/> + <dia:point val="-2.55417,3.88331"/> </dia:attribute> <dia:attribute name="elem_width"> <dia:real val="15.16"/> @@ -1678,16 +1678,16 @@ </dia:object> <dia:object type="Database - Table" version="0" id="O11"> <dia:attribute name="obj_pos"> - <dia:point val="8.24583,-14.8834"/> + <dia:point val="8.19583,-8.2334"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="8.24583,-14.8834;22.2508,-6.2834"/> + <dia:rectangle val="8.19583,-8.2334;22.2008,0.3666"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="elem_corner"> - <dia:point val="8.24583,-14.8834"/> + <dia:point val="8.19583,-8.2334"/> </dia:attribute> <dia:attribute name="elem_width"> <dia:real val="14.004999999999999"/> @@ -1955,16 +1955,16 @@ </dia:object> <dia:object type="Database - Table" version="0" id="O12"> <dia:attribute name="obj_pos"> - <dia:point val="25.4792,-14.8834"/> + <dia:point val="25.4792,-8.2334"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="25.4792,-14.8834;36.0192,-4.6834"/> + <dia:rectangle val="25.4792,-8.2334;36.0192,1.9666"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="elem_corner"> - <dia:point val="25.4792,-14.8834"/> + <dia:point val="25.4792,-8.2334"/> </dia:attribute> <dia:attribute name="elem_width"> <dia:real val="10.539999999999999"/> @@ -2278,16 +2278,16 @@ </dia:object> <dia:object type="Database - Table" version="0" id="O13"> <dia:attribute name="obj_pos"> - <dia:point val="25.6708,-2.02919"/> + <dia:point val="25.6708,3.87081"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="25.6708,-2.02919;36.5958,12.1708"/> + <dia:rectangle val="25.6708,3.87081;36.5958,18.0708"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="elem_corner"> - <dia:point val="25.6708,-2.02919"/> + <dia:point val="25.6708,3.87081"/> </dia:attribute> <dia:attribute name="elem_width"> <dia:real val="10.925000000000001"/> @@ -2716,19 +2716,19 @@ </dia:object> <dia:object type="Database - Reference" version="0" id="O14"> <dia:attribute name="obj_pos"> - <dia:point val="-7.8208,-11.6167"/> + <dia:point val="-7.8208,-4.9667"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="-7.8708,-12.2667;-4.52083,-11.5667"/> + <dia:rectangle val="-7.8708,-5.61225;-4.52083,-4.9167"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="orth_points"> - <dia:point val="-7.8208,-11.6167"/> - <dia:point val="-5.92083,-11.6167"/> - <dia:point val="-5.92083,-11.6167"/> - <dia:point val="-4.57083,-11.6167"/> + <dia:point val="-7.8208,-4.9667"/> + <dia:point val="-5.92083,-4.9667"/> + <dia:point val="-5.92083,-4.9667"/> + <dia:point val="-4.57083,-4.9667"/> </dia:attribute> <dia:attribute name="orth_orient"> <dia:enum val="0"/> @@ -2776,19 +2776,19 @@ </dia:object> <dia:object type="Database - Reference" version="0" id="O15"> <dia:attribute name="obj_pos"> - <dia:point val="4.81417,-13.2167"/> + <dia:point val="4.81417,-6.5667"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="4.76417,-13.8667;8.29583,-13.1334"/> + <dia:rectangle val="4.76417,-7.21225;8.24583,-6.4834"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="orth_points"> - <dia:point val="4.81417,-13.2167"/> - <dia:point val="6.4625,-13.2167"/> - <dia:point val="6.4625,-13.1834"/> - <dia:point val="8.24583,-13.1834"/> + <dia:point val="4.81417,-6.5667"/> + <dia:point val="6.4625,-6.5667"/> + <dia:point val="6.4625,-6.5334"/> + <dia:point val="8.19583,-6.5334"/> </dia:attribute> <dia:attribute name="orth_orient"> <dia:enum val="0"/> @@ -2836,19 +2836,19 @@ </dia:object> <dia:object type="Database - Reference" version="0" id="O16"> <dia:attribute name="obj_pos"> - <dia:point val="22.2508,-12.3834"/> + <dia:point val="22.2008,-5.7334"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="22.2008,-13.0334;25.5292,-12.3334"/> + <dia:rectangle val="22.1508,-6.37895;25.5292,-5.6834"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="orth_points"> - <dia:point val="22.2508,-12.3834"/> - <dia:point val="23.7334,-12.3834"/> - <dia:point val="23.7334,-12.3834"/> - <dia:point val="25.4792,-12.3834"/> + <dia:point val="22.2008,-5.7334"/> + <dia:point val="23.7334,-5.7334"/> + <dia:point val="23.7334,-5.7334"/> + <dia:point val="25.4792,-5.7334"/> </dia:attribute> <dia:attribute name="orth_orient"> <dia:enum val="0"/> @@ -2896,19 +2896,19 @@ </dia:object> <dia:object type="Database - Reference" version="0" id="O17"> <dia:attribute name="obj_pos"> - <dia:point val="36.0192,-9.98336"/> + <dia:point val="36.0192,-3.3334"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="35.9692,-10.6334;37.6693,-0.27919"/> + <dia:rectangle val="35.9692,-3.97895;37.6693,5.62081"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="orth_points"> - <dia:point val="36.0192,-9.98336"/> - <dia:point val="37.6193,-9.98336"/> - <dia:point val="37.6193,-0.32919"/> - <dia:point val="36.5958,-0.32919"/> + <dia:point val="36.0192,-3.3334"/> + <dia:point val="37.6193,-3.3334"/> + <dia:point val="37.6193,5.57081"/> + <dia:point val="36.5958,5.57081"/> </dia:attribute> <dia:attribute name="orth_orient"> <dia:enum val="0"/> @@ -2959,7 +2959,7 @@ <dia:point val="0.1125,-17.85"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="0.0625,-17.9;1.48167,-14.8667"/> + <dia:rectangle val="0.0625,-17.9;1.48167,-8.2167"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> @@ -2968,7 +2968,7 @@ <dia:point val="0.1125,-17.85"/> <dia:point val="0.1125,-15.3584"/> <dia:point val="0.12167,-15.3584"/> - <dia:point val="0.12167,-14.9167"/> + <dia:point val="0.12167,-8.2667"/> </dia:attribute> <dia:attribute name="orth_orient"> <dia:enum val="1"/> @@ -3016,19 +3016,19 @@ </dia:object> <dia:object type="Database - Reference" version="0" id="O19"> <dia:attribute name="obj_pos"> - <dia:point val="-4.57083,-6.8167"/> + <dia:point val="-4.57083,-0.1667"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="-18.2807,-7.4667;-4.52083,-0.80002"/> + <dia:rectangle val="-18.2807,-0.812247;-4.52083,5.64998"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="orth_points"> - <dia:point val="-4.57083,-6.8167"/> - <dia:point val="-18.2307,-6.8167"/> - <dia:point val="-18.2307,-0.85002"/> - <dia:point val="-16.3208,-0.85002"/> + <dia:point val="-4.57083,-0.1667"/> + <dia:point val="-18.2307,-0.1667"/> + <dia:point val="-18.2307,5.59998"/> + <dia:point val="-16.3208,5.59998"/> </dia:attribute> <dia:attribute name="orth_orient"> <dia:enum val="0"/> @@ -3076,19 +3076,19 @@ </dia:object> <dia:object type="Database - Reference" version="0" id="O20"> <dia:attribute name="obj_pos"> - <dia:point val="-6.1658,-0.85002"/> + <dia:point val="-6.1658,5.59998"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="-6.2158,-1.50002;-2.50417,1.63331"/> + <dia:rectangle val="-6.2158,4.95443;-2.50417,8.03331"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="orth_points"> - <dia:point val="-6.1658,-0.85002"/> - <dia:point val="-4.29249,-0.85002"/> - <dia:point val="-4.29249,1.58331"/> - <dia:point val="-2.55417,1.58331"/> + <dia:point val="-6.1658,5.59998"/> + <dia:point val="-4.29249,5.59998"/> + <dia:point val="-4.29249,7.98331"/> + <dia:point val="-2.55417,7.98331"/> </dia:attribute> <dia:attribute name="orth_orient"> <dia:enum val="0"/> @@ -3136,19 +3136,19 @@ </dia:object> <dia:object type="Database - Reference" version="0" id="O21"> <dia:attribute name="obj_pos"> - <dia:point val="12.6058,-0.81669"/> + <dia:point val="12.6058,5.58331"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="12.5558,-1.50002;15.1193,-0.76669"/> + <dia:rectangle val="12.5558,4.93776;15.1193,5.64998"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="orth_points"> - <dia:point val="12.6058,-0.81669"/> - <dia:point val="13.7696,-0.81669"/> - <dia:point val="13.7696,-0.85002"/> - <dia:point val="15.0693,-0.85002"/> + <dia:point val="12.6058,5.58331"/> + <dia:point val="13.7696,5.58331"/> + <dia:point val="13.7696,5.59998"/> + <dia:point val="15.0693,5.59998"/> </dia:attribute> <dia:attribute name="orth_orient"> <dia:enum val="0"/> @@ -3196,16 +3196,16 @@ </dia:object> <dia:object type="Database - Table" version="0" id="O22"> <dia:attribute name="obj_pos"> - <dia:point val="15.0693,-2.55002"/> + <dia:point val="15.0693,3.89998"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="15.0693,-2.55002;24.4543,1.24998"/> + <dia:rectangle val="15.0693,3.89998;24.4543,7.69998"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="elem_corner"> - <dia:point val="15.0693,-2.55002"/> + <dia:point val="15.0693,3.89998"/> </dia:attribute> <dia:attribute name="elem_width"> <dia:real val="9.3850000000000016"/> @@ -3335,16 +3335,16 @@ </dia:object> <dia:object type="Database - Table" version="0" id="O23"> <dia:attribute name="obj_pos"> - <dia:point val="14.12,3.7"/> + <dia:point val="11.32,12.4"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="14.12,3.7;24.66,8.3"/> + <dia:rectangle val="11.32,12.4;21.86,17"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="elem_corner"> - <dia:point val="14.12,3.7"/> + <dia:point val="11.32,12.4"/> </dia:attribute> <dia:attribute name="elem_width"> <dia:real val="10.539999999999999"/> @@ -3497,16 +3497,16 @@ </dia:object> <dia:object type="Database - Table" version="0" id="O24"> <dia:attribute name="obj_pos"> - <dia:point val="2.61,3.7125"/> + <dia:point val="-0.19,12.3625"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="2.61,3.7125;10.455,6.7125"/> + <dia:rectangle val="-0.19,12.3625;7.655,15.3625"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="elem_corner"> - <dia:point val="2.61,3.7125"/> + <dia:point val="-0.19,12.3625"/> </dia:attribute> <dia:attribute name="elem_width"> <dia:real val="7.8449999999999998"/> @@ -3613,19 +3613,19 @@ </dia:object> <dia:object type="Database - Reference" version="0" id="O25"> <dia:attribute name="obj_pos"> - <dia:point val="10.455,5.4125"/> + <dia:point val="7.655,14.0625"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="10.405,4.75;14.17,5.4625"/> + <dia:rectangle val="7.605,13.417;11.37,14.15"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="orth_points"> - <dia:point val="10.455,5.4125"/> - <dia:point val="11.95,5.4125"/> - <dia:point val="11.95,5.4"/> - <dia:point val="14.12,5.4"/> + <dia:point val="7.655,14.0625"/> + <dia:point val="9.8693,14.0625"/> + <dia:point val="9.8693,14.1"/> + <dia:point val="11.32,14.1"/> </dia:attribute> <dia:attribute name="orth_orient"> <dia:enum val="0"/> @@ -3673,19 +3673,19 @@ </dia:object> <dia:object type="Database - Reference" version="0" id="O26"> <dia:attribute name="obj_pos"> - <dia:point val="8.24583,-12.3834"/> + <dia:point val="8.19583,-5.7334"/> </dia:attribute> <dia:attribute name="obj_bb"> - <dia:rectangle val="5.87763,-13.0334;8.29583,-11.5334"/> + <dia:rectangle val="5.87763,-6.37895;8.24583,-4.8834"/> </dia:attribute> <dia:attribute name="meta"> <dia:composite type="dict"/> </dia:attribute> <dia:attribute name="orth_points"> - <dia:point val="8.24583,-12.3834"/> - <dia:point val="5.92763,-12.3834"/> - <dia:point val="5.92763,-11.5834"/> - <dia:point val="8.24583,-11.5834"/> + <dia:point val="8.19583,-5.7334"/> + <dia:point val="5.92763,-5.7334"/> + <dia:point val="5.92763,-4.9334"/> + <dia:point val="8.19583,-4.9334"/> </dia:attribute> <dia:attribute name="orth_orient"> <dia:enum val="0"/> @@ -3731,5 +3731,679 @@ <dia:connection handle="1" to="O11" connection="16"/> </dia:connections> </dia:object> + <dia:object type="Database - Table" version="0" id="O27"> + <dia:attribute name="obj_pos"> + <dia:point val="25.4168,-19.2167"/> + </dia:attribute> + <dia:attribute name="obj_bb"> + <dia:rectangle val="25.4168,-19.2167;34.4168,-12.2167"/> + </dia:attribute> + <dia:attribute name="meta"> + <dia:composite type="dict"/> + </dia:attribute> + <dia:attribute name="elem_corner"> + <dia:point val="25.4168,-19.2167"/> + </dia:attribute> + <dia:attribute name="elem_width"> + <dia:real val="9"/> + </dia:attribute> + <dia:attribute name="elem_height"> + <dia:real val="7"/> + </dia:attribute> + <dia:attribute name="name"> + dia:string#TaskFailures#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="visible_comment"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="underline_primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="tagging_comment"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="bold_primary_keys"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="attributes"> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#FailureId#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#INT#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#JobId#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#INT#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#StepNo#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#INT(2)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#TaskNo#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#INT(2)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#TaskLog#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#VARCHAR(32)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#NewCount#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#INT#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#OldCount#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#INT#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + </dia:attribute> + <dia:attribute name="normal_font"> + <dia:font family="monospace" style="0" name="Courier"/> + </dia:attribute> + <dia:attribute name="name_font"> + <dia:font family="sans" style="80" name="Helvetica-Bold"/> + </dia:attribute> + <dia:attribute name="comment_font"> + <dia:font family="sans" style="8" name="Helvetica-Oblique"/> + </dia:attribute> + <dia:attribute name="normal_font_height"> + <dia:real val="0.80000000000000004"/> + </dia:attribute> + <dia:attribute name="name_font_height"> + <dia:real val="0.99999999999999989"/> + </dia:attribute> + <dia:attribute name="comment_font_height"> + <dia:real val="0.69999999999999996"/> + </dia:attribute> + <dia:attribute name="text_colour"> + <dia:color val="#000000ff"/> + </dia:attribute> + <dia:attribute name="line_colour"> + <dia:color val="#000000ff"/> + </dia:attribute> + <dia:attribute name="fill_colour"> + <dia:color val="#ffffffff"/> + </dia:attribute> + <dia:attribute name="line_width"> + <dia:real val="0.10000000000000001"/> + </dia:attribute> + </dia:object> + <dia:object type="Database - Table" version="0" id="O28"> + <dia:attribute name="obj_pos"> + <dia:point val="9.8001,-19.2167"/> + </dia:attribute> + <dia:attribute name="obj_bb"> + <dia:rectangle val="9.8001,-19.2167;21.1101,-9.0167"/> + </dia:attribute> + <dia:attribute name="meta"> + <dia:composite type="dict"/> + </dia:attribute> + <dia:attribute name="elem_corner"> + <dia:point val="9.8001,-19.2167"/> + </dia:attribute> + <dia:attribute name="elem_width"> + <dia:real val="11.309999999999999"/> + </dia:attribute> + <dia:attribute name="elem_height"> + <dia:real val="10.199999999999999"/> + </dia:attribute> + <dia:attribute name="name"> + dia:string#Failures#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="visible_comment"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="underline_primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="tagging_comment"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="bold_primary_keys"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="attributes"> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#Id#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#INT#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#TestModule#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#VARCHAR(64)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#TestUnit#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#VARCHAR(32)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#ConfigRegExp#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#VARCHAR(64)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#FailureRegExp#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#VARCHAR(256)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#Notes#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#VARCHAR(128)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#LastNew#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#DATETIME#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#LastOld#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#DATETIME#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#BugId#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#INT#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#BugStatus#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#VARCHAR(32)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + <dia:composite type="table_attribute"> + <dia:attribute name="name"> + dia:string#BugDescription#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + dia:string#VARCHAR(128)#</dia:string> + </dia:attribute> + <dia:attribute name="comment"> + dia:string##</dia:string> + </dia:attribute> + <dia:attribute name="primary_key"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="nullable"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="unique"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="default_value"> + dia:string##</dia:string> + </dia:attribute> + </dia:composite> + </dia:attribute> + <dia:attribute name="normal_font"> + <dia:font family="monospace" style="0" name="Courier"/> + </dia:attribute> + <dia:attribute name="name_font"> + <dia:font family="sans" style="80" name="Helvetica-Bold"/> + </dia:attribute> + <dia:attribute name="comment_font"> + <dia:font family="sans" style="8" name="Helvetica-Oblique"/> + </dia:attribute> + <dia:attribute name="normal_font_height"> + <dia:real val="0.80000000000000004"/> + </dia:attribute> + <dia:attribute name="name_font_height"> + <dia:real val="0.99999999999999989"/> + </dia:attribute> + <dia:attribute name="comment_font_height"> + <dia:real val="0.69999999999999996"/> + </dia:attribute> + <dia:attribute name="text_colour"> + <dia:color val="#000000ff"/> + </dia:attribute> + <dia:attribute name="line_colour"> + <dia:color val="#000000ff"/> + </dia:attribute> + <dia:attribute name="fill_colour"> + <dia:color val="#ffffffff"/> + </dia:attribute> + <dia:attribute name="line_width"> + <dia:real val="0.10000000000000001"/> + </dia:attribute> + </dia:object> + <dia:object type="Database - Reference" version="0" id="O29"> + <dia:attribute name="obj_pos"> + <dia:point val="34.4168,-15.9167"/> + </dia:attribute> + <dia:attribute name="obj_bb"> + <dia:rectangle val="34.3668,-16.5622;37.6001,-5.6834"/> + </dia:attribute> + <dia:attribute name="meta"> + <dia:composite type="dict"/> + </dia:attribute> + <dia:attribute name="orth_points"> + <dia:point val="34.4168,-15.9167"/> + <dia:point val="37.5501,-15.9167"/> + <dia:point val="37.5501,-5.7334"/> + <dia:point val="36.0192,-5.7334"/> + </dia:attribute> + <dia:attribute name="orth_orient"> + <dia:enum val="0"/> + <dia:enum val="1"/> + <dia:enum val="0"/> + </dia:attribute> + <dia:attribute name="orth_autoroute"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="text_colour"> + <dia:color val="#000000ff"/> + </dia:attribute> + <dia:attribute name="line_colour"> + <dia:color val="#000000ff"/> + </dia:attribute> + <dia:attribute name="line_width"> + <dia:real val="0.10000000000000001"/> + </dia:attribute> + <dia:attribute name="line_style"> + <dia:enum val="0"/> + <dia:real val="1"/> + </dia:attribute> + <dia:attribute name="corner_radius"> + <dia:real val="0"/> + </dia:attribute> + <dia:attribute name="end_arrow"> + <dia:enum val="0"/> + </dia:attribute> + <dia:attribute name="start_point_desc"> + dia:string#0..n#</dia:string> + </dia:attribute> + <dia:attribute name="end_point_desc"> + dia:string#1#</dia:string> + </dia:attribute> + <dia:attribute name="normal_font"> + <dia:font family="monospace" style="0" name="Courier"/> + </dia:attribute> + <dia:attribute name="normal_font_height"> + <dia:real val="0.59999999999999998"/> + </dia:attribute> + dia:connections + <dia:connection handle="0" to="O27" connection="17"/> + <dia:connection handle="1" to="O12" connection="15"/> + </dia:connections> + </dia:object> + <dia:object type="Database - Reference" version="0" id="O30"> + <dia:attribute name="obj_pos"> + <dia:point val="21.1101,-17.5167"/> + </dia:attribute> + <dia:attribute name="obj_bb"> + <dia:rectangle val="21.0601,-18.1622;25.4668,-17.4667"/> + </dia:attribute> + <dia:attribute name="meta"> + <dia:composite type="dict"/> + </dia:attribute> + <dia:attribute name="orth_points"> + <dia:point val="21.1101,-17.5167"/> + <dia:point val="22.6693,-17.5167"/> + <dia:point val="22.6693,-17.5167"/> + <dia:point val="25.4168,-17.5167"/> + </dia:attribute> + <dia:attribute name="orth_orient"> + <dia:enum val="0"/> + <dia:enum val="1"/> + <dia:enum val="0"/> + </dia:attribute> + <dia:attribute name="orth_autoroute"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="text_colour"> + <dia:color val="#000000ff"/> + </dia:attribute> + <dia:attribute name="line_colour"> + <dia:color val="#000000ff"/> + </dia:attribute> + <dia:attribute name="line_width"> + <dia:real val="0.10000000000000001"/> + </dia:attribute> + <dia:attribute name="line_style"> + <dia:enum val="0"/> + <dia:real val="1"/> + </dia:attribute> + <dia:attribute name="corner_radius"> + <dia:real val="0"/> + </dia:attribute> + <dia:attribute name="end_arrow"> + <dia:enum val="0"/> + </dia:attribute> + <dia:attribute name="start_point_desc"> + dia:string#1#</dia:string> + </dia:attribute> + <dia:attribute name="end_point_desc"> + dia:string#0..n#</dia:string> + </dia:attribute> + <dia:attribute name="normal_font"> + <dia:font family="monospace" style="0" name="Courier"/> + </dia:attribute> + <dia:attribute name="normal_font_height"> + <dia:real val="0.59999999999999998"/> + </dia:attribute> + dia:connections + <dia:connection handle="0" to="O28" connection="13"/> + <dia:connection handle="1" to="O27" connection="12"/> + </dia:connections> + </dia:object> </dia:layer> </dia:diagram> diff --git a/testbot/lib/WineTestBot/Failures.pm b/testbot/lib/WineTestBot/Failures.pm new file mode 100644 index 000000000..2443d0c5b --- /dev/null +++ b/testbot/lib/WineTestBot/Failures.pm @@ -0,0 +1,150 @@ +# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*- +# Copyright 2022 Francois Gouget +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +use strict; + + +package WineTestBot::Failure; + +=head1 NAME + +WineTestBot::Failure - Describes a known Wine test failure + +=head1 DESCRIPTION + +Failure objects document known test failures and link them to the corresponding +bug describing the issue. They are mainly used to avoid reporting a test +failure as new when it has in fact happened before despite not being present +in the reference WineTest logs, either because it is just too rare, or because +its text is ever changing. + +Finally Failure objects are linked to the Task+Log they match by means of the +TaskFailure objects. + +=cut + +use WineTestBot::WineTestBotObjects; +our @ISA = qw(WineTestBot::WineTestBotItem); + + +sub Compare($$) +{ + my ($self, $B) = @_; + + # Sort deleted entries last + my %StatusOrders = ("deleted" => 1); + + return ($StatusOrders{$self->GetColValue("BugStatus")} || 0) <=> ($StatusOrders{$B->GetColValue("BugStatus")} || 0) || + $self->GetColValue("TestModule") cmp $B->GetColValue("TestModule") || + $self->GetColValue("TestUnit") cmp $B->GetColValue("TestUnit") || + $self->GetColValue("Id") <=> $B->GetColValue("Id"); +} + + +package WineTestBot::Failures; + +=head1 NAME + +WineTestBot::Failures - A Failure collection + +=head1 DESCRIPTION + +This collection contains all known failures. + +=cut + +use Exporter 'import'; +use WineTestBot::WineTestBotObjects; +BEGIN +{ + our @ISA = qw(WineTestBot::WineTestBotCollection); + our @EXPORT = qw(CreateFailures); +} + +use ObjectModel::BasicPropertyDescriptor; +use ObjectModel::EnumPropertyDescriptor; +use ObjectModel::DetailrefPropertyDescriptor; +use WineTestBot::TaskFailures; + + +sub CreateItem($) +{ + my ($self) = @_; + + return WineTestBot::Failure->new($self); +} + +my @PropertyDescriptors = ( + # Rather than using a combination of the other fields, give each entry a + # unique id. This allows having multiple entries for a single Wine bug in + # case there are too many failures to match for the regular expression to + # fit in a single regular expression field. This also avoids using the + # regular expression as part of the primary key which would be troublesome + # as it may need to be adjusted in case it is buggy or if the test changes. + CreateBasicPropertyDescriptor("Id", "Id", 1, 1, "S", 10), + + # Identify the test unit the failure can occur in. + CreateBasicPropertyDescriptor("TestModule", "Test module", !1, 1, "A", 64), + CreateBasicPropertyDescriptor("TestUnit", "Test unit", !1, 1, "A", 32), + + # A regular expression to match the configurations the failure can happen in. + # A configuration name is of the form 'VMNAME:REPORTNAME'. + CreateBasicPropertyDescriptor("ConfigRegExp", "Configurations RegExp", !1, !1, "A", 64), + + # A regular expression to match the troublesome failures. + CreateBasicPropertyDescriptor("FailureRegExp", "Failures RegExp", !1, 1, "A", 256), + + # Can be used for documentation when multiple entries are needed to match + # all the failures associated with a given bug. + # Can also be used to document when a regular expression has been modified, + # for instance to match changes in a test. + CreateBasicPropertyDescriptor("Notes", "Notes", !1, !1, "A", 128), + + # Record when an entry was last identified as a new or old failure, even + # after the corresponding tasks have expired (see the TaskFailures table). + CreateBasicPropertyDescriptor("LastNew", "Last new", !1, !1, "DT", 19), + CreateBasicPropertyDescriptor("LastOld", "Last old", !1, !1, "DT", 19), + + # Every entry must be associated with a Wine bug. + # Note: The 'deleted' bug status means this failure entry should be + # deleted as soon as it is not referenced anymore. + CreateBasicPropertyDescriptor("BugId", "WineHQ bug id", !1, 1, "N", 10), + CreateBasicPropertyDescriptor("BugStatus", "WineHQ bug status", !1, !1, "A", 32), + CreateBasicPropertyDescriptor("BugDescription", "WineHQ bug description", !1, !1, "A", 128), + + CreateDetailrefPropertyDescriptor("TaskFailures", "Tasks", &CreateTaskFailures), +); +SetDetailrefKeyPrefix("Failure", @PropertyDescriptors); + +=pod +=over 12 + +=item C<CreateFailures()> + +Creates a collection of Failure objects. + +=back +=cut + +sub CreateFailures(;$) +{ + my ($ScopeObject) = @_; + return WineTestBot::Failures->new("Failures", "Failures", "Failure", + @PropertyDescriptors, $ScopeObject); +} + +1; diff --git a/testbot/lib/WineTestBot/Jobs.pm b/testbot/lib/WineTestBot/Jobs.pm index 7f15a9c57..3da6ae7b0 100644 --- a/testbot/lib/WineTestBot/Jobs.pm +++ b/testbot/lib/WineTestBot/Jobs.pm @@ -89,6 +89,7 @@ use File::Path; use WineTestBot::Config; use WineTestBot::Branches; use WineTestBot::Engine::Notify; +use WineTestBot::TaskFailures;
sub _initialize($$) @@ -435,6 +436,11 @@ sub Restart($) my ($ErrProperty, $ErrMessage) = $self->Save(); # Save it all return "$ErrMessage ($ErrProperty)" if ($ErrMessage);
+ # Remove the corresponding TaskFailures if any + my $TaskFailures = CreateTaskFailures(); + $TaskFailures->AddFilter("JobId", [$self->Id]); + $TaskFailures->DeleteAll(); + return undef; }
diff --git a/testbot/lib/WineTestBot/TaskFailures.pm b/testbot/lib/WineTestBot/TaskFailures.pm new file mode 100644 index 000000000..bdbfd6e2e --- /dev/null +++ b/testbot/lib/WineTestBot/TaskFailures.pm @@ -0,0 +1,120 @@ +# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*- +# Copyright 2022 Francois Gouget +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +use strict; + + +package WineTestBot::TaskFailure; + +=head1 NAME + +WineTestBot::TaskFailure - Ties a failure to its task+log matches + +=head1 DESCRIPTION + +A TaskFailure is created when a WineTestBot::Failure matches a line in a +task's log. It also records whether the matching failures occurred in previous +logs or not. This makes it possible to detect fixed failures. + +=cut + +use WineTestBot::WineTestBotObjects; +our @ISA = qw(WineTestBot::WineTestBotItem); + + +sub Compare($$) +{ + my ($self, $B) = @_; + + return $B->Task->Started <=> $self->Task->Started || # newest first by default + $self->TaskLog cmp $B->TaskLog; +} + + +package WineTestBot::TaskFailures; + +=head1 NAME + +WineTestBot::TaskFailures - A TaskFailure collection + +=head1 DESCRIPTION + +This collection cross references the known failures with the tasks and logs they +matched. + +=cut + +use Exporter 'import'; +use WineTestBot::WineTestBotObjects; +BEGIN +{ + our @ISA = qw(WineTestBot::WineTestBotCollection); + our @EXPORT = qw(CreateTaskFailures); +} + +use ObjectModel::BasicPropertyDescriptor; +use ObjectModel::ItemrefPropertyDescriptor; +use WineTestBot::Tasks; + + +sub CreateItem($) +{ + my ($self) = @_; + + return WineTestBot::TaskFailure->new($self); +} + +my @PropertyDescriptors = ( + # Identifies the task which has matching failures + CreateBasicPropertyDescriptor("JobId", "Job id", 1, 1, "N", 10), + CreateBasicPropertyDescriptor("StepNo", "Step no", 1, 1, "N", 2), + CreateBasicPropertyDescriptor("TaskNo", "Task", 1, 1, "N", 2), + CreateItemrefPropertyDescriptor("Task", "Task", 1, &WineTestBot::Tasks::CreateTasks, ["JobId", "StepNo", "TaskNo"]), + + # and more specifically in which of its logs + CreateBasicPropertyDescriptor("TaskLog", "Task log", 1, 1, "A", 32), + + # Also store a count of matching new and old failures + CreateBasicPropertyDescriptor("NewCount", "Count of matching new failures", !1, !1, "N", 10), + CreateBasicPropertyDescriptor("OldCount", "Count of matching old failures", !1, !1, "N", 10), +); +SetupItemrefColumns(@PropertyDescriptors); +my @FlatPropertyDescriptors = ( + CreateBasicPropertyDescriptor("FailureId", "Failure id", 1, 1, "N", 10), + @PropertyDescriptors +); + +=pod +=over 12 + +=item C<CreateTaskFailures()> + +Creates a collection of TaskFailure objects. + +=back +=cut + +sub CreateTaskFailures(;$$) +{ + my ($ScopeObject, $Failure) = @_; + return WineTestBot::TaskFailures->new("TaskFailures", + "TaskFailures", "TaskFailure", + $Failure ? @PropertyDescriptors : @FlatPropertyDescriptors, + $ScopeObject, $Failure); +} + +1; diff --git a/testbot/lib/WineTestBot/Tasks.pm b/testbot/lib/WineTestBot/Tasks.pm index 0360e4ebc..5b87c782b 100644 --- a/testbot/lib/WineTestBot/Tasks.pm +++ b/testbot/lib/WineTestBot/Tasks.pm @@ -341,7 +341,9 @@ BEGIN use ObjectModel::BasicPropertyDescriptor; use ObjectModel::EnumPropertyDescriptor; use ObjectModel::ItemrefPropertyDescriptor; +use ObjectModel::DetailrefPropertyDescriptor; use WineTestBot::VMs; +use WineTestBot::TaskFailures;
sub CreateItem($) @@ -362,8 +364,10 @@ my @PropertyDescriptors = ( CreateBasicPropertyDescriptor("Started", "Started", !1, !1, "DT", 19), CreateBasicPropertyDescriptor("Ended", "Ended", !1, !1, "DT", 19), CreateBasicPropertyDescriptor("TestFailures", "Failures", !1, !1, "N", 6), + CreateDetailrefPropertyDescriptor("Failures", "Known failures", &CreateTaskFailures), ); SetupItemrefColumns(@PropertyDescriptors); +SetDetailrefKeyPrefix("Task", @PropertyDescriptors); my @FlatPropertyDescriptors = ( CreateBasicPropertyDescriptor("JobId", "Job id", 1, 1, "N", 10), CreateBasicPropertyDescriptor("StepNo", "Step no", 1, 1, "N", 2),