test suite reviews and discussions
 help / color / mirror / Atom feed
* [dts] [PATCH 1/2] framework: add new module to create email report
@ 2015-02-16  4:45 Yong Liu
  2015-02-16  4:45 ` [dts] [PATCH 2/2] framework: support load execution result from excel report Yong Liu
  2015-02-16  5:02 ` [dts] [PATCH 1/2] framework: add new module to create email report Qiu, Michael
  0 siblings, 2 replies; 3+ messages in thread
From: Yong Liu @ 2015-02-16  4:45 UTC (permalink / raw)
  To: dts

This module will parse excel result file and create email like below.

Summary: Run XXX cases (PASS-Count FAIL-Count BLOCK-Count)
Latest commit log:
Kernel Version:
CPU info:
GCC Version:
Target: x86_64-native-linuxapp-gcc                   FAIL:XXX/YYY
Detail information of failed cases:
Target: x86_64-native-linuxapp-gcc
Test Case                                            Result
Case name                                            FAILED

Signed-off-by: Marvinliu <yong.liu@intel.com>

diff --git a/framework/email_report.py b/framework/email_report.py
new file mode 100644
index 0000000..38e390c
--- /dev/null
+++ b/framework/email_report.py
@@ -0,0 +1,132 @@
+import argparse      # prase arguments module
+import smtplib       # send email module
+from email.mime.text import MIMEText
+from email.mime.multipart import MIMEMultipart
+
+from excel_reporter import ExcelReporter  # excel parse module
+from texttable import Texttable          # formatted output module
+
+rece_maillist = ["dts@dpdk.org"]
+from_maillist = "sys_stv@intel.com"
+
+# Global variable
+total_target = 0
+global os_type
+global test_type
+global git_commit
+global dut_config
+dut_config = []
+os_type = ""
+test_type = ""
+git_commit = ""
+
+
+# Format of Email
+class Email():
+
+    def __init__(self, excel):
+        self.subject_format = "%s %s Test Report"
+        self.summary_format = "Summary: Run %d cases (PASS-%d FAIL-%d BLOCK-%d)"
+        self.result_summary_format = "Target: %-30s               FAIL:%d/%d\r\n"
+        excel = ExcelReporter(excel)
+        self.result = excel.load()
+        self.smtp = smtplib.SMTP()
+        self.smtp.connect("mail.intel.com", 25)
+
+    def subject(self):
+        return self.subject_format % (os_type, test_type)
+
+    def summary(self):
+        total = 0
+        passed = 0
+        fail = 0
+        block = 0
+        for dut in self.result.all_duts():
+            targets = self.result.all_targets(dut)
+            for target in targets:
+                suites = self.result.get_target_suites(dut, target)
+                results = self.result.get_suites_status(suites)
+                total += len(results)
+                passed += results.count("PASSED")
+                fail += results.count("FAILED")
+                block += results.count("BLOCKED")
+
+        return self.summary_format % (total, passed, fail, block)
+
+    def target_summary(self):
+        summary = ""
+        for dut in self.result.all_duts():
+            targets = self.result.all_targets(dut)
+            for target in targets:
+                suites = self.result.get_target_suites(dut, target)
+                results = self.result.get_suites_status(suites)
+                summary += self.result_summary_format % (target, results.count("FAILED"), len(results))
+        return summary
+
+    def failed_case_summary(self):
+        summary = ""
+        for dut in self.result.all_duts():
+            targets = self.result.all_targets(dut)
+            for target in targets:
+                summary += "Target: %s\r\n" % (target)
+                table = Texttable()
+                table.set_deco(Texttable.HEADER)
+                table.set_cols_align(["l", "l"])
+                table.set_cols_width([50, 10])
+                table.add_row(["Test Case", "Result"])
+                suites = self.result.get_target_suites(dut, target)
+                failed = self.result.get_cases_by_status(suites, 'FAILED')
+                blocked = self.result.get_cases_by_status(suites, 'BLOCKED')
+                for case in failed:
+                    table.add_row([case, 'FAILED'])
+                for case in blocked:
+                    table.add_row([case, 'BLOCKED'])
+                summary += table.draw()
+                summary += "\r\n\r\n"
+
+        return summary
+
+    def send(self, _from, _to, attachment):
+        content = ""
+        msg = MIMEMultipart('alternative')
+        msg['Subject'] = self.subject()
+        msg['From'] = _from
+        msg['To'] = ", ".join(_to)
+        content += self.summary()
+        content += "\r\n\r\n"
+        content += git_commit
+        content += "\r\n\r\n"
+        content += "".join(dut_config)
+        content += "\r\n\r\n"
+        content += self.target_summary()
+        content += "\r\n\r\n"
+        content += "Detail information of failed cases:\r\n"
+        content += self.failed_case_summary()
+        part2 = MIMEText(content, "plain", "utf-8")
+        msg.attach(part2)
+        fp = open(attachment, 'r')
+        part1 = MIMEText(fp.read(), 'base64', 'utf-8')
+        part1['Content-type'] = 'application/octet-stream'
+        part1['Content-Disposition'] = 'attachment;filename="output.zip"'
+        fp.close()
+        msg.attach(part1)
+        self.smtp.sendmail(
+            _from, _to, msg.as_string())
+        self.smtp.quit()
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description="DTS Email Report Module")
+    parser.add_argument("-o", "--os_type", default="Fedora20")
+    parser.add_argument("-t", "--test_type", default="Functional")
+    parser.add_argument(
+        "-e", "--excel_file", default="output/test_results.xls")
+    parser.add_argument("-g", "--git_commit", default="test commit")
+    args = parser.parse_args()
+    os_type = args.os_type
+    test_type = args.test_type
+    git_commit = args.git_commit
+    email = Email(args.excel_file)
+    print email.subject()
+    print email.summary()
+    print email.target_summary()
+    print email.failed_case_summary()
-- 
1.9.3

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [dts] [PATCH 2/2] framework: support load execution result from excel report
  2015-02-16  4:45 [dts] [PATCH 1/2] framework: add new module to create email report Yong Liu
@ 2015-02-16  4:45 ` Yong Liu
  2015-02-16  5:02 ` [dts] [PATCH 1/2] framework: add new module to create email report Qiu, Michael
  1 sibling, 0 replies; 3+ messages in thread
From: Yong Liu @ 2015-02-16  4:45 UTC (permalink / raw)
  To: dts

DTS used to save Result object to excel file. This patch support prase excel
back into Result object. Implement some functions in test_result module that
can get cases result by target and suites.

Signed-off-by: Marvinliu <yong.liu@intel.com>

diff --git a/framework/excel_reporter.py b/framework/excel_reporter.py
index 809dead..2b86754 100644
--- a/framework/excel_reporter.py
+++ b/framework/excel_reporter.py
@@ -52,6 +52,8 @@ Result:
 
 """
 import xlwt
+import xlrd
+from test_result import Result
 from xlwt.ExcelFormula import Formula
 
 
@@ -68,43 +70,50 @@ class ExcelReporter(object):
         self.xsl_file = None
         self.result = None
         self.__styles()
-
-    def __init(self):
+        self.titles = [	{'row': 0, 'col': 0, 'width': 4000, 'title': 'DUT', 'style': self.header_style},
+                        {'row': 0, 'col': 1, 'width': 7500, 'title': 'Target', 'style': self.header_style},
+                        {'row': 0, 'col': 2, 'width': 3000, 'title': 'NIC', 'style': self.header_style},
+                        {'row': 0, 'col': 3, 'width': 5000, 'title': 'Test suite', 'style': self.header_style},
+                        {'row': 0, 'col': 4, 'width': 8000, 'title': 'Test case', 'style': self.header_style},
+                        {'row': 0, 'col': 5, 'width': 3000, 'title': 'Results', 'style': self.header_style},
+                        {'row': 0, 'col': 7, 'width': 1000, 'title': 'Pass', 'style': self.header_style},
+                        {'row': 0, 'col': 8, 'width': 3000, 'title': 'Fail', 'style': self.header_style},
+                        {'row': 0, 'col': 9, 'width': 3000, 'title': 'Blocked', 'style': self.header_style},
+                        {'row': 0, 'col': 10, 'width': 3000, 'title': 'Not Run', 'style': self.header_style},
+                        {'row': 0, 'col': 11, 'width': 3000, 'title': 'Total', 'style': self.header_style},
+                        ]
+
+    def __get_col_by_title(self, title):
+        cols = []
+        for ti in self.titles:
+            if ti['title'] == title:
+                cols.append(ti['col'])
+        return cols
+
+    def __write_init(self):
         self.workbook = xlwt.Workbook()
         self.sheet = self.workbook.add_sheet(
             "Test Results", cell_overwrite_ok=True)
 
+    def __read_init(self):
+        self.row = 0
+        self.col = 0
+        try:
+            self.workboot = xlrd.open_workbook(self.filename)
+            self.rsheet = self.workboot.sheet_by_name("Test Results")
+        except Exception as e:
+            print "FAILED TO LOAD EXCEL FILE %s: %s" % (self.filename, e)
+
     def __add_header(self):
-        self.sheet.write(0, 0, 'DUT', self.header_style)
-        self.sheet.write(0, 1, 'Target', self.header_style)
-        self.sheet.write(0, 2, 'NIC', self.header_style)
-        self.sheet.write(0, 3, 'Test suite', self.header_style)
-        self.sheet.write(0, 4, 'Test case', self.header_style)
-        self.sheet.write(0, 5, 'Results', self.header_style)
-
-        self.sheet.write(0, 7, 'Pass', self.header_style)
-        self.sheet.write(0, 8, 'Fail', self.header_style)
-        self.sheet.write(0, 9, 'Blocked', self.header_style)
-        self.sheet.write(0, 10, 'Not Run', self.header_style)
-        self.sheet.write(0, 11, 'Total', self.header_style)
-
-        self.sheet.write(1, 7, Formula('COUNTIF(F2:F2000,"PASSED")'))
-        self.sheet.write(1, 8, Formula('COUNTIF(F2:F2000,"FAILED*") + COUNTIF(F2:F2000,"IXA*")'))
-        self.sheet.write(1, 9, Formula('COUNTIF(F2:F2000,"BLOCKED*")'))
-        self.sheet.write(1, 11, Formula('H2+I2+J2+K2'))
-
-        self.sheet.col(0).width = 4000
-        self.sheet.col(1).width = 7500
-        self.sheet.col(2).width = 3000
-        self.sheet.col(3).width = 5000
-        self.sheet.col(4).width = 8000
-        self.sheet.col(5).width = 3000
-        self.sheet.col(6).width = 1000
-        self.sheet.col(7).width = 3000
-        self.sheet.col(8).width = 3000
-        self.sheet.col(9).width = 3000
-        self.sheet.col(10).width = 3000
-        self.sheet.col(11).width = 3000
+        for title in self.titles:
+            self.sheet.write(title['row'], title['col'], title['title'], title['style'])
+
+        self.sheet.write(1, self.__get_col_by_title('Pass')[0], Formula('COUNTIF(F2:F2000,"PASSED")'))
+        self.sheet.write(1, self.__get_col_by_title('Fail')[0], Formula('COUNTIF(F2:F2000,"FAILED*") + COUNTIF(F2:F2000,"IXA*")'))
+        self.sheet.write(1, self.__get_col_by_title('Blocked')[0], Formula('H2+I2+J2+K2'))
+
+        for title in self.titles:
+            self.sheet.col(title['col']).width = title['width']
 
     def __styles(self):
         header_pattern = xlwt.Pattern()
@@ -208,8 +217,44 @@ class ExcelReporter(object):
                 self.__write_targets(dut)
             self.row += 1
 
+    def __save_result(self):
+        dut_col = self.__get_col_by_title('DUT')[0]
+        target_col = self.__get_col_by_title('Target')[0]
+        nic_col = self.__get_col_by_title('NIC')[0]
+        suite_col = self.__get_col_by_title('Test suite')[0]
+        case_col = self.__get_col_by_title('Test case')[0]
+        result_col = self.__get_col_by_title('Results')[0]
+
+        # skip first title row
+        for row in range(1, self.rsheet.nrows):
+            dutIP = self.rsheet.cell(row, dut_col).value
+            target = self.rsheet.cell(row, target_col).value
+            nic = self.rsheet.cell(row, nic_col).value
+            suite = self.rsheet.cell(row, suite_col).value
+            case = self.rsheet.cell(row, case_col).value
+            result = self.rsheet.cell(row, result_col).value
+            if dutIP is not '':
+                self.result.dut = dutIP
+            if target is not '':
+                self.result.target = target
+            if nic is not '':
+                self.result.nic = nic
+            if suite is not '':
+                self.result.test_suite = suite
+            if case is not '':
+                self.result.test_case = case
+
+            results = result.replace('\'', '').split(' ', 1)
+
+            if 'PASSED' in result:
+                self.result.test_case_passed()
+            elif 'BLOCKED' in result:
+                self.result.test_case_blocked(results[1])
+            elif result != '':
+                self.result.test_case_failed(results[1])
+
     def save(self, result):
-        self.__init()
+        self.__write_init()
         self.__add_header()
         self.row = 1
         self.col = 0
@@ -218,3 +263,9 @@ class ExcelReporter(object):
         self.__parse_result()
 
         self.workbook.save(self.filename)
+
+    def load(self):
+        self.__read_init()
+        self.result = Result()
+        self.__save_result()
+        return self.result
diff --git a/framework/test_result.py b/framework/test_result.py
index 79faee1..a77c451 100644
--- a/framework/test_result.py
+++ b/framework/test_result.py
@@ -207,6 +207,49 @@ class Result(object):
             return None
         return self.__internals[dut_idx + 1][target_idx + 2][::2]
 
+    def get_target_suites(self, dut, target):
+        """
+        Return suite status for a given DUT, target.
+        """
+        try:
+            target_status = []
+            dut_idx = self.__internals.index(dut)
+            target_idx = self.__internals[dut_idx + 1].index(target)
+            suites = self.__internals[dut_idx + 1][target_idx + 2]
+        except:
+            return None
+        return suites
+
+    def get_cases_by_status(self, suites, status):
+        cases = []
+        try:
+            suite_results = suites[1::2]
+            for suite in suite_results:
+                case_names = suite[0::2]
+                case_results = suite[1::2]
+                index = 0
+                for case in case_results:
+                    if case[0] == status:
+                        cases.append(case_names[index])
+                    index += 1
+
+        except:
+            return None
+        return cases
+
+    def get_suites_status(self, suites):
+        status = []
+        try:
+            suite_results = suites[1::2]
+            for suite in suite_results:
+                case_results = suite[1::2]
+                for case in case_results:
+                    status.append(case[0])
+        except:
+            return None
+
+        return status
+
     def all_test_cases(self, dut, target, suite):
         """
         Returns all the test cases for a given DUT, target and test case.
-- 
1.9.3

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [dts] [PATCH 1/2] framework: add new module to create email report
  2015-02-16  4:45 [dts] [PATCH 1/2] framework: add new module to create email report Yong Liu
  2015-02-16  4:45 ` [dts] [PATCH 2/2] framework: support load execution result from excel report Yong Liu
@ 2015-02-16  5:02 ` Qiu, Michael
  1 sibling, 0 replies; 3+ messages in thread
From: Qiu, Michael @ 2015-02-16  5:02 UTC (permalink / raw)
  To: Liu, Yong, dts

On 2/16/2015 12:45 PM, Yong Liu wrote:
> This module will parse excel result file and create email like below.
>
> Summary: Run XXX cases (PASS-Count FAIL-Count BLOCK-Count)
> Latest commit log:
> Kernel Version:
> CPU info:
> GCC Version:

Here I don't see any place try to show this field

Thanks,
Michael
> Target: x86_64-native-linuxapp-gcc                   FAIL:XXX/YYY
> Detail information of failed cases:
> Target: x86_64-native-linuxapp-gcc
> Test Case                                            Result
> Case name                                            FAILED
>
> Signed-off-by: Marvinliu <yong.liu@intel.com>
>
> diff --git a/framework/email_report.py b/framework/email_report.py
> new file mode 100644
> index 0000000..38e390c
> --- /dev/null
> +++ b/framework/email_report.py
> @@ -0,0 +1,132 @@
> +import argparse      # prase arguments module
> +import smtplib       # send email module
> +from email.mime.text import MIMEText
> +from email.mime.multipart import MIMEMultipart
> +
> +from excel_reporter import ExcelReporter  # excel parse module
> +from texttable import Texttable          # formatted output module
> +
> +rece_maillist = ["dts@dpdk.org"]
> +from_maillist = "sys_stv@intel.com"
> +
> +# Global variable
> +total_target = 0
> +global os_type
> +global test_type
> +global git_commit
> +global dut_config
> +dut_config = []
> +os_type = ""
> +test_type = ""
> +git_commit = ""
> +
> +
> +# Format of Email
> +class Email():
> +
> +    def __init__(self, excel):
> +        self.subject_format = "%s %s Test Report"
> +        self.summary_format = "Summary: Run %d cases (PASS-%d FAIL-%d BLOCK-%d)"
> +        self.result_summary_format = "Target: %-30s               FAIL:%d/%d\r\n"
> +        excel = ExcelReporter(excel)
> +        self.result = excel.load()
> +        self.smtp = smtplib.SMTP()
> +        self.smtp.connect("mail.intel.com", 25)
> +
> +    def subject(self):
> +        return self.subject_format % (os_type, test_type)
> +
> +    def summary(self):
> +        total = 0
> +        passed = 0
> +        fail = 0
> +        block = 0
> +        for dut in self.result.all_duts():
> +            targets = self.result.all_targets(dut)
> +            for target in targets:
> +                suites = self.result.get_target_suites(dut, target)
> +                results = self.result.get_suites_status(suites)
> +                total += len(results)
> +                passed += results.count("PASSED")
> +                fail += results.count("FAILED")
> +                block += results.count("BLOCKED")
> +
> +        return self.summary_format % (total, passed, fail, block)
> +
> +    def target_summary(self):
> +        summary = ""
> +        for dut in self.result.all_duts():
> +            targets = self.result.all_targets(dut)
> +            for target in targets:
> +                suites = self.result.get_target_suites(dut, target)
> +                results = self.result.get_suites_status(suites)
> +                summary += self.result_summary_format % (target, results.count("FAILED"), len(results))
> +        return summary
> +
> +    def failed_case_summary(self):
> +        summary = ""
> +        for dut in self.result.all_duts():
> +            targets = self.result.all_targets(dut)
> +            for target in targets:
> +                summary += "Target: %s\r\n" % (target)
> +                table = Texttable()
> +                table.set_deco(Texttable.HEADER)
> +                table.set_cols_align(["l", "l"])
> +                table.set_cols_width([50, 10])
> +                table.add_row(["Test Case", "Result"])
> +                suites = self.result.get_target_suites(dut, target)
> +                failed = self.result.get_cases_by_status(suites, 'FAILED')
> +                blocked = self.result.get_cases_by_status(suites, 'BLOCKED')
> +                for case in failed:
> +                    table.add_row([case, 'FAILED'])
> +                for case in blocked:
> +                    table.add_row([case, 'BLOCKED'])
> +                summary += table.draw()
> +                summary += "\r\n\r\n"
> +
> +        return summary
> +
> +    def send(self, _from, _to, attachment):
> +        content = ""
> +        msg = MIMEMultipart('alternative')
> +        msg['Subject'] = self.subject()
> +        msg['From'] = _from
> +        msg['To'] = ", ".join(_to)
> +        content += self.summary()
> +        content += "\r\n\r\n"
> +        content += git_commit
> +        content += "\r\n\r\n"
> +        content += "".join(dut_config)
> +        content += "\r\n\r\n"
> +        content += self.target_summary()
> +        content += "\r\n\r\n"
> +        content += "Detail information of failed cases:\r\n"
> +        content += self.failed_case_summary()
> +        part2 = MIMEText(content, "plain", "utf-8")
> +        msg.attach(part2)
> +        fp = open(attachment, 'r')
> +        part1 = MIMEText(fp.read(), 'base64', 'utf-8')
> +        part1['Content-type'] = 'application/octet-stream'
> +        part1['Content-Disposition'] = 'attachment;filename="output.zip"'
> +        fp.close()
> +        msg.attach(part1)
> +        self.smtp.sendmail(
> +            _from, _to, msg.as_string())
> +        self.smtp.quit()
> +
> +if __name__ == '__main__':
> +    parser = argparse.ArgumentParser(description="DTS Email Report Module")
> +    parser.add_argument("-o", "--os_type", default="Fedora20")
> +    parser.add_argument("-t", "--test_type", default="Functional")
> +    parser.add_argument(
> +        "-e", "--excel_file", default="output/test_results.xls")
> +    parser.add_argument("-g", "--git_commit", default="test commit")
> +    args = parser.parse_args()
> +    os_type = args.os_type
> +    test_type = args.test_type
> +    git_commit = args.git_commit
> +    email = Email(args.excel_file)
> +    print email.subject()
> +    print email.summary()
> +    print email.target_summary()
> +    print email.failed_case_summary()


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-02-16  5:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-16  4:45 [dts] [PATCH 1/2] framework: add new module to create email report Yong Liu
2015-02-16  4:45 ` [dts] [PATCH 2/2] framework: support load execution result from excel report Yong Liu
2015-02-16  5:02 ` [dts] [PATCH 1/2] framework: add new module to create email report Qiu, Michael

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).