diff options
Diffstat (limited to 'meta/lib/patchtest')
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.1.fail (renamed from meta/lib/patchtest/selftest/files/Author.test_author_valid.1.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.1.pass (renamed from meta/lib/patchtest/selftest/files/Author.test_author_valid.1.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.2.fail (renamed from meta/lib/patchtest/selftest/files/Author.test_author_valid.2.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.2.pass (renamed from meta/lib/patchtest/selftest/files/Author.test_author_valid.2.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_bugzilla_entry_format.fail (renamed from meta/lib/patchtest/selftest/files/Bugzilla.test_bugzilla_entry_format.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_bugzilla_entry_format.pass (renamed from meta/lib/patchtest/selftest/files/Bugzilla.test_bugzilla_entry_format.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_commit_message_presence.fail (renamed from meta/lib/patchtest/selftest/files/CommitMessage.test_commit_message_presence.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_commit_message_presence.pass (renamed from meta/lib/patchtest/selftest/files/CommitMessage.test_commit_message_presence.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_cve_presence_in_commit_message.fail (renamed from meta/lib/patchtest/selftest/files/CVE.test_cve_presence_in_commit_message.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_cve_presence_in_commit_message.pass (renamed from meta/lib/patchtest/selftest/files/CVE.test_cve_presence_in_commit_message.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_mbox_format.1.fail (renamed from meta/lib/patchtest/selftest/files/MboxFormat.test_mbox_format.1.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_mbox_format.2.fail (renamed from meta/lib/patchtest/selftest/files/MboxFormat.test_mbox_format.2.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_mbox_format.pass (renamed from meta/lib/patchtest/selftest/files/MboxFormat.test_mbox_format.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_series_merge_on_head.1.skip (renamed from meta/lib/patchtest/selftest/files/Merge.test_series_merge_on_head.1.skip) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_series_merge_on_head.2.skip (renamed from meta/lib/patchtest/selftest/files/Merge.test_series_merge_on_head.2.skip) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_format.fail (renamed from meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_format.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_format.pass (renamed from meta/lib/patchtest/selftest/files/CVE.test_cve_tag_format.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_length.fail (renamed from meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_length.fail) | 2 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_length.pass (renamed from meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_format.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_signed_off_by_presence.1.fail (renamed from meta/lib/patchtest/selftest/files/SignedOffBy.test_signed_off_by_presence.1.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_signed_off_by_presence.2.fail (renamed from meta/lib/patchtest/selftest/files/SignedOffBy.test_signed_off_by_presence.2.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMbox.test_signed_off_by_presence.pass (renamed from meta/lib/patchtest/selftest/files/PatchSignedOffBy.test_signed_off_by_presence.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_modified_not_mentioned.fail (renamed from meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_modified_not_mentioned.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_modified_not_mentioned.pass (renamed from meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_modified_not_mentioned.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_presence.fail (renamed from meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_presence.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_presence.pass (renamed from meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_presence.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMetadata.test_src_uri_left_files.fail (renamed from meta/lib/patchtest/selftest/files/SrcUri.test_src_uri_left_files.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMetadata.test_src_uri_left_files.pass (renamed from meta/lib/patchtest/selftest/files/SrcUri.test_src_uri_left_files.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMetadata.test_summary_presence.fail (renamed from meta/lib/patchtest/selftest/files/Summary.test_summary_presence.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestMetadata.test_summary_presence.pass (renamed from meta/lib/patchtest/selftest/files/Summary.test_summary_presence.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestPatch.test_cve_tag_format.fail (renamed from meta/lib/patchtest/selftest/files/CVE.test_cve_tag_format.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestPatch.test_cve_tag_format.pass (renamed from meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_length.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestPatch.test_signed_off_by_presence.fail (renamed from meta/lib/patchtest/selftest/files/PatchSignedOffBy.test_signed_off_by_presence.fail) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/selftest/files/TestPatch.test_signed_off_by_presence.pass (renamed from meta/lib/patchtest/selftest/files/SignedOffBy.test_signed_off_by_presence.pass) | 0 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox.py | 183 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox_author.py | 29 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox_bugzilla.py | 20 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox_cve.py | 38 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox_description.py | 15 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox_format.py | 14 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox_mailinglist.py | 62 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox_merge.py | 27 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox_shortlog.py | 39 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox_signed_off_by.py | 27 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_metadata.py | 204 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_metadata_lic_files_chksum.py | 74 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_metadata_license.py | 50 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_metadata_max_length.py | 25 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_metadata_src_uri.py | 73 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_metadata_summary.py | 26 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_patch.py (renamed from meta/lib/patchtest/tests/test_patch_upstream_status.py) | 53 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_patch_cve.py | 37 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_patch_signed_off_by.py | 41 |
53 files changed, 436 insertions, 603 deletions
diff --git a/meta/lib/patchtest/selftest/files/Author.test_author_valid.1.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.1.fail index 0c40cdc1b6..0c40cdc1b6 100644 --- a/meta/lib/patchtest/selftest/files/Author.test_author_valid.1.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.1.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/Author.test_author_valid.1.pass b/meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.1.pass index cbb8ef2cef..cbb8ef2cef 100644 --- a/meta/lib/patchtest/selftest/files/Author.test_author_valid.1.pass +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.1.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/Author.test_author_valid.2.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.2.fail index 3e2b81bca1..3e2b81bca1 100644 --- a/meta/lib/patchtest/selftest/files/Author.test_author_valid.2.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.2.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/Author.test_author_valid.2.pass b/meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.2.pass index f84e1265a7..f84e1265a7 100644 --- a/meta/lib/patchtest/selftest/files/Author.test_author_valid.2.pass +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_author_valid.2.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/Bugzilla.test_bugzilla_entry_format.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_bugzilla_entry_format.fail index 80f409e952..80f409e952 100644 --- a/meta/lib/patchtest/selftest/files/Bugzilla.test_bugzilla_entry_format.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_bugzilla_entry_format.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/Bugzilla.test_bugzilla_entry_format.pass b/meta/lib/patchtest/selftest/files/TestMbox.test_bugzilla_entry_format.pass index 2648b03364..2648b03364 100644 --- a/meta/lib/patchtest/selftest/files/Bugzilla.test_bugzilla_entry_format.pass +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_bugzilla_entry_format.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/CommitMessage.test_commit_message_presence.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_commit_message_presence.fail index 93ca0f9119..93ca0f9119 100644 --- a/meta/lib/patchtest/selftest/files/CommitMessage.test_commit_message_presence.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_commit_message_presence.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/CommitMessage.test_commit_message_presence.pass b/meta/lib/patchtest/selftest/files/TestMbox.test_commit_message_presence.pass index 5e3dcbd58b..5e3dcbd58b 100644 --- a/meta/lib/patchtest/selftest/files/CommitMessage.test_commit_message_presence.pass +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_commit_message_presence.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/CVE.test_cve_presence_in_commit_message.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_cve_presence_in_commit_message.fail index d40b8a936b..d40b8a936b 100644 --- a/meta/lib/patchtest/selftest/files/CVE.test_cve_presence_in_commit_message.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_cve_presence_in_commit_message.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/CVE.test_cve_presence_in_commit_message.pass b/meta/lib/patchtest/selftest/files/TestMbox.test_cve_presence_in_commit_message.pass index 433c7a450a..433c7a450a 100644 --- a/meta/lib/patchtest/selftest/files/CVE.test_cve_presence_in_commit_message.pass +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_cve_presence_in_commit_message.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/MboxFormat.test_mbox_format.1.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_mbox_format.1.fail index 9cc4aab38a..9cc4aab38a 100644 --- a/meta/lib/patchtest/selftest/files/MboxFormat.test_mbox_format.1.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_mbox_format.1.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/MboxFormat.test_mbox_format.2.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_mbox_format.2.fail index eca1c60085..eca1c60085 100644 --- a/meta/lib/patchtest/selftest/files/MboxFormat.test_mbox_format.2.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_mbox_format.2.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/MboxFormat.test_mbox_format.pass b/meta/lib/patchtest/selftest/files/TestMbox.test_mbox_format.pass index 33940adffc..33940adffc 100644 --- a/meta/lib/patchtest/selftest/files/MboxFormat.test_mbox_format.pass +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_mbox_format.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/Merge.test_series_merge_on_head.1.skip b/meta/lib/patchtest/selftest/files/TestMbox.test_series_merge_on_head.1.skip index 2a72457878..2a72457878 100644 --- a/meta/lib/patchtest/selftest/files/Merge.test_series_merge_on_head.1.skip +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_series_merge_on_head.1.skip | |||
diff --git a/meta/lib/patchtest/selftest/files/Merge.test_series_merge_on_head.2.skip b/meta/lib/patchtest/selftest/files/TestMbox.test_series_merge_on_head.2.skip index 49bd1f8ede..49bd1f8ede 100644 --- a/meta/lib/patchtest/selftest/files/Merge.test_series_merge_on_head.2.skip +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_series_merge_on_head.2.skip | |||
diff --git a/meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_format.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_format.fail index cdbbc61b61..cdbbc61b61 100644 --- a/meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_format.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_format.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/CVE.test_cve_tag_format.pass b/meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_format.pass index ef6017037c..ef6017037c 100644 --- a/meta/lib/patchtest/selftest/files/CVE.test_cve_tag_format.pass +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_format.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_length.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_length.fail index 247b2a8a80..629e78540b 100644 --- a/meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_length.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_length.fail | |||
@@ -56,7 +56,7 @@ index 547587bef4..76975a6729 100644 | |||
56 | 56 | ||
57 | -SRC_URI = "file://helloworld.c" | 57 | -SRC_URI = "file://helloworld.c" |
58 | +SRC_URI = "file://helloworld.c \ | 58 | +SRC_URI = "file://helloworld.c \ |
59 | + file://CVE-1234-56789.patch \ | 59 | + file://0001-Fix-CVE-1234-56789.patch \ |
60 | + " | 60 | + " |
61 | 61 | ||
62 | S = "${WORKDIR}" | 62 | S = "${WORKDIR}" |
diff --git a/meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_format.pass b/meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_length.pass index ef6017037c..ef6017037c 100644 --- a/meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_format.pass +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_shortlog_length.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/SignedOffBy.test_signed_off_by_presence.1.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_signed_off_by_presence.1.fail index 35d92aeed7..35d92aeed7 100644 --- a/meta/lib/patchtest/selftest/files/SignedOffBy.test_signed_off_by_presence.1.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_signed_off_by_presence.1.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/SignedOffBy.test_signed_off_by_presence.2.fail b/meta/lib/patchtest/selftest/files/TestMbox.test_signed_off_by_presence.2.fail index 68f38dee06..68f38dee06 100644 --- a/meta/lib/patchtest/selftest/files/SignedOffBy.test_signed_off_by_presence.2.fail +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_signed_off_by_presence.2.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/PatchSignedOffBy.test_signed_off_by_presence.pass b/meta/lib/patchtest/selftest/files/TestMbox.test_signed_off_by_presence.pass index ea34c76f0d..ea34c76f0d 100644 --- a/meta/lib/patchtest/selftest/files/PatchSignedOffBy.test_signed_off_by_presence.pass +++ b/meta/lib/patchtest/selftest/files/TestMbox.test_signed_off_by_presence.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_modified_not_mentioned.fail b/meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_modified_not_mentioned.fail index ab6c52c374..ab6c52c374 100644 --- a/meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_modified_not_mentioned.fail +++ b/meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_modified_not_mentioned.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_modified_not_mentioned.pass b/meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_modified_not_mentioned.pass index 99d9f144da..99d9f144da 100644 --- a/meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_modified_not_mentioned.pass +++ b/meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_modified_not_mentioned.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_presence.fail b/meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_presence.fail index e14d644bb2..e14d644bb2 100644 --- a/meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_presence.fail +++ b/meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_presence.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_presence.pass b/meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_presence.pass index b8da16dfe5..b8da16dfe5 100644 --- a/meta/lib/patchtest/selftest/files/LicFilesChkSum.test_lic_files_chksum_presence.pass +++ b/meta/lib/patchtest/selftest/files/TestMetadata.test_lic_files_chksum_presence.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/SrcUri.test_src_uri_left_files.fail b/meta/lib/patchtest/selftest/files/TestMetadata.test_src_uri_left_files.fail index 983b6e0c2b..983b6e0c2b 100644 --- a/meta/lib/patchtest/selftest/files/SrcUri.test_src_uri_left_files.fail +++ b/meta/lib/patchtest/selftest/files/TestMetadata.test_src_uri_left_files.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/SrcUri.test_src_uri_left_files.pass b/meta/lib/patchtest/selftest/files/TestMetadata.test_src_uri_left_files.pass index 1f1a77e581..1f1a77e581 100644 --- a/meta/lib/patchtest/selftest/files/SrcUri.test_src_uri_left_files.pass +++ b/meta/lib/patchtest/selftest/files/TestMetadata.test_src_uri_left_files.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/Summary.test_summary_presence.fail b/meta/lib/patchtest/selftest/files/TestMetadata.test_summary_presence.fail index 2d2b4e683d..2d2b4e683d 100644 --- a/meta/lib/patchtest/selftest/files/Summary.test_summary_presence.fail +++ b/meta/lib/patchtest/selftest/files/TestMetadata.test_summary_presence.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/Summary.test_summary_presence.pass b/meta/lib/patchtest/selftest/files/TestMetadata.test_summary_presence.pass index 55f0309b3f..55f0309b3f 100644 --- a/meta/lib/patchtest/selftest/files/Summary.test_summary_presence.pass +++ b/meta/lib/patchtest/selftest/files/TestMetadata.test_summary_presence.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/CVE.test_cve_tag_format.fail b/meta/lib/patchtest/selftest/files/TestPatch.test_cve_tag_format.fail index c763a7506e..c763a7506e 100644 --- a/meta/lib/patchtest/selftest/files/CVE.test_cve_tag_format.fail +++ b/meta/lib/patchtest/selftest/files/TestPatch.test_cve_tag_format.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_length.pass b/meta/lib/patchtest/selftest/files/TestPatch.test_cve_tag_format.pass index ef6017037c..ef6017037c 100644 --- a/meta/lib/patchtest/selftest/files/Shortlog.test_shortlog_length.pass +++ b/meta/lib/patchtest/selftest/files/TestPatch.test_cve_tag_format.pass | |||
diff --git a/meta/lib/patchtest/selftest/files/PatchSignedOffBy.test_signed_off_by_presence.fail b/meta/lib/patchtest/selftest/files/TestPatch.test_signed_off_by_presence.fail index ce8bf7b7d1..ce8bf7b7d1 100644 --- a/meta/lib/patchtest/selftest/files/PatchSignedOffBy.test_signed_off_by_presence.fail +++ b/meta/lib/patchtest/selftest/files/TestPatch.test_signed_off_by_presence.fail | |||
diff --git a/meta/lib/patchtest/selftest/files/SignedOffBy.test_signed_off_by_presence.pass b/meta/lib/patchtest/selftest/files/TestPatch.test_signed_off_by_presence.pass index ea34c76f0d..ea34c76f0d 100644 --- a/meta/lib/patchtest/selftest/files/SignedOffBy.test_signed_off_by_presence.pass +++ b/meta/lib/patchtest/selftest/files/TestPatch.test_signed_off_by_presence.pass | |||
diff --git a/meta/lib/patchtest/tests/test_mbox.py b/meta/lib/patchtest/tests/test_mbox.py new file mode 100644 index 0000000000..95002c9e2a --- /dev/null +++ b/meta/lib/patchtest/tests/test_mbox.py | |||
@@ -0,0 +1,183 @@ | |||
1 | # Checks related to the patch's author | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | import collections | ||
9 | import parse_cve_tags | ||
10 | import parse_shortlog | ||
11 | import parse_signed_off_by | ||
12 | import pyparsing | ||
13 | import subprocess | ||
14 | from data import PatchTestInput | ||
15 | |||
16 | def headlog(): | ||
17 | output = subprocess.check_output( | ||
18 | "cd %s; git log --pretty='%%h#%%aN#%%cD:#%%s' -1" % PatchTestInput.repodir, | ||
19 | universal_newlines=True, | ||
20 | shell=True | ||
21 | ) | ||
22 | return output.split('#') | ||
23 | |||
24 | class TestMbox(base.Base): | ||
25 | |||
26 | auh_email = 'auh@auh.yoctoproject.org' | ||
27 | |||
28 | invalids = [pyparsing.Regex("^Upgrade Helper.+"), | ||
29 | pyparsing.Regex(auh_email), | ||
30 | pyparsing.Regex("uh@not\.set"), | ||
31 | pyparsing.Regex("\S+@example\.com")] | ||
32 | |||
33 | rexp_detect = pyparsing.Regex('\[\s?YOCTO.*\]') | ||
34 | rexp_validation = pyparsing.Regex('\[(\s?YOCTO\s?#\s?(\d+)\s?,?)+\]') | ||
35 | revert_shortlog_regex = pyparsing.Regex('Revert\s+".*"') | ||
36 | prog = parse_cve_tags.cve_tag | ||
37 | patch_prog = parse_cve_tags.patch_cve_tag | ||
38 | signoff_prog = parse_signed_off_by.signed_off_by | ||
39 | revert_shortlog_regex = pyparsing.Regex('Revert\s+".*"') | ||
40 | maxlength = 90 | ||
41 | |||
42 | # base paths of main yocto project sub-projects | ||
43 | paths = { | ||
44 | 'oe-core': ['meta-selftest', 'meta-skeleton', 'meta', 'scripts'], | ||
45 | 'bitbake': ['bitbake'], | ||
46 | 'documentation': ['documentation'], | ||
47 | 'poky': ['meta-poky','meta-yocto-bsp'], | ||
48 | 'oe': ['meta-gpe', 'meta-gnome', 'meta-efl', 'meta-networking', 'meta-multimedia','meta-initramfs', 'meta-ruby', 'contrib', 'meta-xfce', 'meta-filesystems', 'meta-perl', 'meta-webserver', 'meta-systemd', 'meta-oe', 'meta-python'] | ||
49 | } | ||
50 | |||
51 | # scripts folder is a mix of oe-core and poky, most is oe-core code except: | ||
52 | poky_scripts = ['scripts/yocto-bsp', 'scripts/yocto-kernel', 'scripts/yocto-layer', 'scripts/lib/bsp'] | ||
53 | |||
54 | Project = collections.namedtuple('Project', ['name', 'listemail', 'gitrepo', 'paths']) | ||
55 | |||
56 | bitbake = Project(name='Bitbake', listemail='bitbake-devel@lists.openembedded.org', gitrepo='http://git.openembedded.org/bitbake/', paths=paths['bitbake']) | ||
57 | doc = Project(name='Documentantion', listemail='yocto@yoctoproject.org', gitrepo='http://git.yoctoproject.org/cgit/cgit.cgi/yocto-docs/', paths=paths['documentation']) | ||
58 | poky = Project(name='Poky', listemail='poky@yoctoproject.org', gitrepo='http://git.yoctoproject.org/cgit/cgit.cgi/poky/', paths=paths['poky']) | ||
59 | oe = Project(name='oe', listemail='openembedded-devel@lists.openembedded.org', gitrepo='http://git.openembedded.org/meta-openembedded/', paths=paths['oe']) | ||
60 | |||
61 | |||
62 | def test_signed_off_by_presence(self): | ||
63 | for commit in TestMbox.commits: | ||
64 | # skip those patches that revert older commits, these do not required the tag presence | ||
65 | if self.revert_shortlog_regex.search_string(commit.shortlog): | ||
66 | continue | ||
67 | if not self.signoff_prog.search_string(commit.payload): | ||
68 | self.fail('Mbox is missing Signed-off-by. Add it manually or with "git commit --amend -s"', | ||
69 | commit=commit) | ||
70 | |||
71 | def test_shortlog_format(self): | ||
72 | for commit in TestMbox.commits: | ||
73 | shortlog = commit.shortlog | ||
74 | if not shortlog.strip(): | ||
75 | self.skip('Empty shortlog, no reason to execute shortlog format test') | ||
76 | else: | ||
77 | # no reason to re-check on revert shortlogs | ||
78 | if shortlog.startswith('Revert "'): | ||
79 | continue | ||
80 | try: | ||
81 | parse_shortlog.shortlog.parseString(shortlog) | ||
82 | except pyparsing.ParseException as pe: | ||
83 | self.fail('Commit shortlog (first line of commit message) should follow the format "<target>: <summary>"', | ||
84 | commit=commit) | ||
85 | |||
86 | def test_shortlog_length(self): | ||
87 | for commit in TestMbox.commits: | ||
88 | # no reason to re-check on revert shortlogs | ||
89 | shortlog = commit.shortlog | ||
90 | if shortlog.startswith('Revert "'): | ||
91 | continue | ||
92 | l = len(shortlog) | ||
93 | if l > self.maxlength: | ||
94 | self.fail('Edit shortlog so that it is %d characters or less (currently %d characters)' % (self.maxlength, l), | ||
95 | commit=commit) | ||
96 | |||
97 | def test_series_merge_on_head(self): | ||
98 | self.skip("Merge test is disabled for now") | ||
99 | if PatchTestInput.repo.branch != "master": | ||
100 | self.skip("Skipping merge test since patch is not intended for master branch. Target detected is %s" % PatchTestInput.repo.branch) | ||
101 | if not PatchTestInput.repo.ismerged: | ||
102 | commithash, author, date, shortlog = headlog() | ||
103 | self.fail('Series does not apply on top of target branch. Rebase your series and ensure the target is correct', | ||
104 | data=[('Targeted branch', '%s (currently at %s)' % (PatchTestInput.repo.branch, commithash))]) | ||
105 | |||
106 | def test_target_mailing_list(self): | ||
107 | """In case of merge failure, check for other targeted projects""" | ||
108 | if PatchTestInput.repo.ismerged: | ||
109 | self.skip('Series merged, no reason to check other mailing lists') | ||
110 | |||
111 | # a meta project may be indicted in the message subject, if this is the case, just fail | ||
112 | # TODO: there may be other project with no-meta prefix, we also need to detect these | ||
113 | project_regex = pyparsing.Regex("\[(?P<project>meta-.+)\]") | ||
114 | for commit in TestMbox.commits: | ||
115 | match = project_regex.search_string(commit.subject) | ||
116 | if match: | ||
117 | self.fail('Series sent to the wrong mailing list. Check the project\'s README (%s) and send the patch to the indicated list' % match.group('project'), | ||
118 | commit=commit) | ||
119 | |||
120 | for patch in self.patchset: | ||
121 | folders = patch.path.split('/') | ||
122 | base_path = folders[0] | ||
123 | for project in [self.bitbake, self.doc, self.oe, self.poky]: | ||
124 | if base_path in project.paths: | ||
125 | self.fail('Series sent to the wrong mailing list or some patches from the series correspond to different mailing lists. Send the series again to the correct mailing list (ML)', | ||
126 | data=[('Suggested ML', '%s [%s]' % (project.listemail, project.gitrepo)), | ||
127 | ('Patch\'s path:', patch.path)]) | ||
128 | |||
129 | # check for poky's scripts code | ||
130 | if base_path.startswith('scripts'): | ||
131 | for poky_file in self.poky_scripts: | ||
132 | if patch.path.startswith(poky_file): | ||
133 | self.fail('Series sent to the wrong mailing list or some patches from the series correspond to different mailing lists. Send the series again to the correct mailing list (ML)', | ||
134 | data=[('Suggested ML', '%s [%s]' % (self.poky.listemail, self.poky.gitrepo)),('Patch\'s path:', patch.path)]) | ||
135 | |||
136 | def test_mbox_format(self): | ||
137 | if self.unidiff_parse_error: | ||
138 | self.fail('Series cannot be parsed correctly due to malformed diff lines. Create the series again using git-format-patch and ensure it can be applied using git am', | ||
139 | data=[('Diff line',self.unidiff_parse_error)]) | ||
140 | |||
141 | def test_commit_message_presence(self): | ||
142 | for commit in TestMbox.commits: | ||
143 | if not commit.commit_message.strip(): | ||
144 | self.fail('Mbox is missing a descriptive commit message. Please include a commit message on your patch explaining the change', commit=commit) | ||
145 | |||
146 | def test_cve_presence_in_commit_message(self): | ||
147 | if self.unidiff_parse_error: | ||
148 | self.skip('Parse error %s' % self.unidiff_parse_error) | ||
149 | |||
150 | # we are just interested in series that introduce CVE patches, thus discard other | ||
151 | # possibilities: modification to current CVEs, patch directly introduced into the | ||
152 | # recipe, upgrades already including the CVE, etc. | ||
153 | new_patches = [p for p in self.patchset if p.path.endswith('.patch') and p.is_added_file] | ||
154 | if not new_patches: | ||
155 | self.skip('No new patches introduced') | ||
156 | |||
157 | for commit in TestMbox.commits: | ||
158 | # skip those patches that revert older commits, these do not required the tag presence | ||
159 | if self.revert_shortlog_regex.search_string(commit.shortlog): | ||
160 | continue | ||
161 | if not self.patch_prog.search_string(commit.payload): | ||
162 | self.skip("No CVE tag in added patch, so not needed in mbox") | ||
163 | elif not self.prog.search_string(commit.payload): | ||
164 | self.fail('Missing or incorrectly formatted CVE tag in mbox. Correct or include the CVE tag in the mbox with format: "CVE: CVE-YYYY-XXXX"', | ||
165 | commit=commit) | ||
166 | |||
167 | def test_bugzilla_entry_format(self): | ||
168 | for commit in TestMbox.commits: | ||
169 | if not self.rexp_detect.search_string(commit.commit_message): | ||
170 | self.skip("No bug ID found") | ||
171 | elif not self.rexp_validation.search_string(commit.commit_message): | ||
172 | self.fail('Bugzilla issue ID is not correctly formatted - specify it with format: "[YOCTO #<bugzilla ID>]"', commit=commit) | ||
173 | |||
174 | def test_author_valid(self): | ||
175 | for commit in self.commits: | ||
176 | for invalid in self.invalids: | ||
177 | if invalid.search_string(commit.author): | ||
178 | self.fail('Invalid author %s. Resend the series with a valid patch author' % commit.author, commit=commit) | ||
179 | |||
180 | def test_non_auh_upgrade(self): | ||
181 | for commit in self.commits: | ||
182 | if self.auh_email in commit.payload: | ||
183 | self.fail('Invalid author %s. Resend the series with a valid patch author' % self.auh_email, commit=commit) | ||
diff --git a/meta/lib/patchtest/tests/test_mbox_author.py b/meta/lib/patchtest/tests/test_mbox_author.py deleted file mode 100644 index 74bc441250..0000000000 --- a/meta/lib/patchtest/tests/test_mbox_author.py +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
1 | # Checks related to the patch's author | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | import pyparsing | ||
9 | |||
10 | class Author(base.Base): | ||
11 | |||
12 | auh_email = 'auh@auh.yoctoproject.org' | ||
13 | |||
14 | invalids = [pyparsing.Regex("^Upgrade Helper.+"), | ||
15 | pyparsing.Regex(auh_email), | ||
16 | pyparsing.Regex("uh@not\.set"), | ||
17 | pyparsing.Regex("\S+@example\.com")] | ||
18 | |||
19 | |||
20 | def test_author_valid(self): | ||
21 | for commit in self.commits: | ||
22 | for invalid in self.invalids: | ||
23 | if invalid.search_string(commit.author): | ||
24 | self.fail('Invalid author %s. Resend the series with a valid patch author' % commit.author, commit=commit) | ||
25 | |||
26 | def test_non_auh_upgrade(self): | ||
27 | for commit in self.commits: | ||
28 | if self.auh_email in commit.payload: | ||
29 | self.fail('Invalid author %s. Resend the series with a valid patch author' % self.auh_email, commit=commit) | ||
diff --git a/meta/lib/patchtest/tests/test_mbox_bugzilla.py b/meta/lib/patchtest/tests/test_mbox_bugzilla.py deleted file mode 100644 index 99b529b755..0000000000 --- a/meta/lib/patchtest/tests/test_mbox_bugzilla.py +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | # Checks related to the patch's bugzilla tag | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import pyparsing | ||
8 | import base | ||
9 | |||
10 | class Bugzilla(base.Base): | ||
11 | rexp_detect = pyparsing.Regex('\[\s?YOCTO.*\]') | ||
12 | rexp_validation = pyparsing.Regex('\[(\s?YOCTO\s?#\s?(\d+)\s?,?)+\]') | ||
13 | |||
14 | def test_bugzilla_entry_format(self): | ||
15 | for commit in Bugzilla.commits: | ||
16 | if not self.rexp_detect.search_string(commit.commit_message): | ||
17 | self.skip("No bug ID found") | ||
18 | elif not self.rexp_validation.search_string(commit.commit_message): | ||
19 | self.fail('Bugzilla issue ID is not correctly formatted - specify it with format: "[YOCTO #<bugzilla ID>]"', commit=commit) | ||
20 | |||
diff --git a/meta/lib/patchtest/tests/test_mbox_cve.py b/meta/lib/patchtest/tests/test_mbox_cve.py deleted file mode 100644 index 29ab12cbb5..0000000000 --- a/meta/lib/patchtest/tests/test_mbox_cve.py +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | # Checks related to the patch's CVE lines | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | # | ||
7 | |||
8 | import base | ||
9 | import parse_cve_tags | ||
10 | import pyparsing | ||
11 | |||
12 | class CVE(base.Base): | ||
13 | |||
14 | revert_shortlog_regex = pyparsing.Regex('Revert\s+".*"') | ||
15 | prog = parse_cve_tags.cve_tag | ||
16 | patch_prog = parse_cve_tags.patch_cve_tag | ||
17 | |||
18 | def setUp(self): | ||
19 | if self.unidiff_parse_error: | ||
20 | self.skip('Parse error %s' % self.unidiff_parse_error) | ||
21 | |||
22 | # we are just interested in series that introduce CVE patches, thus discard other | ||
23 | # possibilities: modification to current CVEs, patch directly introduced into the | ||
24 | # recipe, upgrades already including the CVE, etc. | ||
25 | new_patches = [p for p in self.patchset if p.path.endswith('.patch') and p.is_added_file] | ||
26 | if not new_patches: | ||
27 | self.skip('No new patches introduced') | ||
28 | |||
29 | def test_cve_presence_in_commit_message(self): | ||
30 | for commit in CVE.commits: | ||
31 | # skip those patches that revert older commits, these do not required the tag presence | ||
32 | if self.revert_shortlog_regex.search_string(commit.shortlog): | ||
33 | continue | ||
34 | if not self.patch_prog.search_string(commit.payload): | ||
35 | self.skip("No CVE tag in added patch, so not needed in mbox") | ||
36 | elif not self.prog.search_string(commit.payload): | ||
37 | self.fail('Missing or incorrectly formatted CVE tag in mbox. Correct or include the CVE tag in the mbox with format: "CVE: CVE-YYYY-XXXX"', | ||
38 | commit=commit) | ||
diff --git a/meta/lib/patchtest/tests/test_mbox_description.py b/meta/lib/patchtest/tests/test_mbox_description.py deleted file mode 100644 index 7874f9d038..0000000000 --- a/meta/lib/patchtest/tests/test_mbox_description.py +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | # Checks related to the patch's commit_message | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | |||
9 | class CommitMessage(base.Base): | ||
10 | |||
11 | def test_commit_message_presence(self): | ||
12 | for commit in CommitMessage.commits: | ||
13 | if not commit.commit_message.strip(): | ||
14 | self.fail('Mbox is missing a descriptive commit message. Please include a commit message on your patch explaining the change', commit=commit) | ||
15 | |||
diff --git a/meta/lib/patchtest/tests/test_mbox_format.py b/meta/lib/patchtest/tests/test_mbox_format.py deleted file mode 100644 index fea3793e2e..0000000000 --- a/meta/lib/patchtest/tests/test_mbox_format.py +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | # Checks correct parsing of mboxes | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | |||
9 | class MboxFormat(base.Base): | ||
10 | |||
11 | def test_mbox_format(self): | ||
12 | if self.unidiff_parse_error: | ||
13 | self.fail('Series cannot be parsed correctly due to malformed diff lines. Create the series again using git-format-patch and ensure it can be applied using git am', | ||
14 | data=[('Diff line',self.unidiff_parse_error)]) | ||
diff --git a/meta/lib/patchtest/tests/test_mbox_mailinglist.py b/meta/lib/patchtest/tests/test_mbox_mailinglist.py deleted file mode 100644 index feff436089..0000000000 --- a/meta/lib/patchtest/tests/test_mbox_mailinglist.py +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | # Check if the series was intended for other project (not OE-Core) | ||
2 | # | ||
3 | # Copyright (C) 2017 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import collections | ||
8 | import base | ||
9 | import pyparsing | ||
10 | from data import PatchTestInput | ||
11 | |||
12 | class MailingList(base.Base): | ||
13 | |||
14 | # base paths of main yocto project sub-projects | ||
15 | paths = { | ||
16 | 'oe-core': ['meta-selftest', 'meta-skeleton', 'meta', 'scripts'], | ||
17 | 'bitbake': ['bitbake'], | ||
18 | 'documentation': ['documentation'], | ||
19 | 'poky': ['meta-poky','meta-yocto-bsp'], | ||
20 | 'oe': ['meta-gpe', 'meta-gnome', 'meta-efl', 'meta-networking', 'meta-multimedia','meta-initramfs', 'meta-ruby', 'contrib', 'meta-xfce', 'meta-filesystems', 'meta-perl', 'meta-webserver', 'meta-systemd', 'meta-oe', 'meta-python'] | ||
21 | } | ||
22 | |||
23 | # scripts folder is a mix of oe-core and poky, most is oe-core code except: | ||
24 | poky_scripts = ['scripts/yocto-bsp', 'scripts/yocto-kernel', 'scripts/yocto-layer', 'scripts/lib/bsp'] | ||
25 | |||
26 | Project = collections.namedtuple('Project', ['name', 'listemail', 'gitrepo', 'paths']) | ||
27 | |||
28 | bitbake = Project(name='Bitbake', listemail='bitbake-devel@lists.openembedded.org', gitrepo='http://git.openembedded.org/bitbake/', paths=paths['bitbake']) | ||
29 | doc = Project(name='Documentantion', listemail='yocto@yoctoproject.org', gitrepo='http://git.yoctoproject.org/cgit/cgit.cgi/yocto-docs/', paths=paths['documentation']) | ||
30 | poky = Project(name='Poky', listemail='poky@yoctoproject.org', gitrepo='http://git.yoctoproject.org/cgit/cgit.cgi/poky/', paths=paths['poky']) | ||
31 | oe = Project(name='oe', listemail='openembedded-devel@lists.openembedded.org', gitrepo='http://git.openembedded.org/meta-openembedded/', paths=paths['oe']) | ||
32 | |||
33 | |||
34 | def test_target_mailing_list(self): | ||
35 | """In case of merge failure, check for other targeted projects""" | ||
36 | if PatchTestInput.repo.ismerged: | ||
37 | self.skip('Series merged, no reason to check other mailing lists') | ||
38 | |||
39 | # a meta project may be indicted in the message subject, if this is the case, just fail | ||
40 | # TODO: there may be other project with no-meta prefix, we also need to detect these | ||
41 | project_regex = pyparsing.Regex("\[(?P<project>meta-.+)\]") | ||
42 | for commit in MailingList.commits: | ||
43 | match = project_regex.search_string(commit.subject) | ||
44 | if match: | ||
45 | self.fail('Series sent to the wrong mailing list. Check the project\'s README (%s) and send the patch to the indicated list' % match.group('project'), | ||
46 | commit=commit) | ||
47 | |||
48 | for patch in self.patchset: | ||
49 | folders = patch.path.split('/') | ||
50 | base_path = folders[0] | ||
51 | for project in [self.bitbake, self.doc, self.oe, self.poky]: | ||
52 | if base_path in project.paths: | ||
53 | self.fail('Series sent to the wrong mailing list or some patches from the series correspond to different mailing lists. Send the series again to the correct mailing list (ML)', | ||
54 | data=[('Suggested ML', '%s [%s]' % (project.listemail, project.gitrepo)), | ||
55 | ('Patch\'s path:', patch.path)]) | ||
56 | |||
57 | # check for poky's scripts code | ||
58 | if base_path.startswith('scripts'): | ||
59 | for poky_file in self.poky_scripts: | ||
60 | if patch.path.startswith(poky_file): | ||
61 | self.fail('Series sent to the wrong mailing list or some patches from the series correspond to different mailing lists. Send the series again to the correct mailing list (ML)', | ||
62 | data=[('Suggested ML', '%s [%s]' % (self.poky.listemail, self.poky.gitrepo)),('Patch\'s path:', patch.path)]) | ||
diff --git a/meta/lib/patchtest/tests/test_mbox_merge.py b/meta/lib/patchtest/tests/test_mbox_merge.py deleted file mode 100644 index 535026209f..0000000000 --- a/meta/lib/patchtest/tests/test_mbox_merge.py +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | # Check if mbox was merged by patchtest | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import subprocess | ||
8 | import base | ||
9 | from data import PatchTestInput | ||
10 | |||
11 | def headlog(): | ||
12 | output = subprocess.check_output( | ||
13 | "cd %s; git log --pretty='%%h#%%aN#%%cD:#%%s' -1" % PatchTestInput.repodir, | ||
14 | universal_newlines=True, | ||
15 | shell=True | ||
16 | ) | ||
17 | return output.split('#') | ||
18 | |||
19 | class Merge(base.Base): | ||
20 | def test_series_merge_on_head(self): | ||
21 | self.skip("Merge test is disabled for now") | ||
22 | if PatchTestInput.repo.branch != "master": | ||
23 | self.skip("Skipping merge test since patch is not intended for master branch. Target detected is %s" % PatchTestInput.repo.branch) | ||
24 | if not PatchTestInput.repo.ismerged: | ||
25 | commithash, author, date, shortlog = headlog() | ||
26 | self.fail('Series does not apply on top of target branch. Rebase your series and ensure the target is correct', | ||
27 | data=[('Targeted branch', '%s (currently at %s)' % (PatchTestInput.repo.branch, commithash))]) | ||
diff --git a/meta/lib/patchtest/tests/test_mbox_shortlog.py b/meta/lib/patchtest/tests/test_mbox_shortlog.py deleted file mode 100644 index f5dbbc7807..0000000000 --- a/meta/lib/patchtest/tests/test_mbox_shortlog.py +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | # Checks related to the patch's summary | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | import parse_shortlog | ||
9 | import pyparsing | ||
10 | |||
11 | maxlength = 90 | ||
12 | |||
13 | class Shortlog(base.Base): | ||
14 | |||
15 | def test_shortlog_format(self): | ||
16 | for commit in Shortlog.commits: | ||
17 | shortlog = commit.shortlog | ||
18 | if not shortlog.strip(): | ||
19 | self.skip('Empty shortlog, no reason to execute shortlog format test') | ||
20 | else: | ||
21 | # no reason to re-check on revert shortlogs | ||
22 | if shortlog.startswith('Revert "'): | ||
23 | continue | ||
24 | try: | ||
25 | parse_shortlog.shortlog.parseString(shortlog) | ||
26 | except pyparsing.ParseException as pe: | ||
27 | self.fail('Commit shortlog (first line of commit message) should follow the format "<target>: <summary>"', | ||
28 | commit=commit) | ||
29 | |||
30 | def test_shortlog_length(self): | ||
31 | for commit in Shortlog.commits: | ||
32 | # no reason to re-check on revert shortlogs | ||
33 | shortlog = commit.shortlog | ||
34 | if shortlog.startswith('Revert "'): | ||
35 | continue | ||
36 | l = len(shortlog) | ||
37 | if l > maxlength: | ||
38 | self.fail('Edit shortlog so that it is %d characters or less (currently %d characters)' % (maxlength, l), | ||
39 | commit=commit) | ||
diff --git a/meta/lib/patchtest/tests/test_mbox_signed_off_by.py b/meta/lib/patchtest/tests/test_mbox_signed_off_by.py deleted file mode 100644 index f3c5770961..0000000000 --- a/meta/lib/patchtest/tests/test_mbox_signed_off_by.py +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | # Checks related to the patch's signed-off-by lines | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | import parse_signed_off_by | ||
9 | import pyparsing | ||
10 | |||
11 | class SignedOffBy(base.Base): | ||
12 | |||
13 | revert_shortlog_regex = pyparsing.Regex('Revert\s+".*"') | ||
14 | |||
15 | @classmethod | ||
16 | def setUpClassLocal(cls): | ||
17 | # match self.mark with no '+' preceding it | ||
18 | cls.prog = parse_signed_off_by.signed_off_by | ||
19 | |||
20 | def test_signed_off_by_presence(self): | ||
21 | for commit in SignedOffBy.commits: | ||
22 | # skip those patches that revert older commits, these do not required the tag presence | ||
23 | if self.revert_shortlog_regex.search_string(commit.shortlog): | ||
24 | continue | ||
25 | if not SignedOffBy.prog.search_string(commit.payload): | ||
26 | self.fail('Mbox is missing Signed-off-by. Add it manually or with "git commit --amend -s"', | ||
27 | commit=commit) | ||
diff --git a/meta/lib/patchtest/tests/test_metadata.py b/meta/lib/patchtest/tests/test_metadata.py new file mode 100644 index 0000000000..34e119174f --- /dev/null +++ b/meta/lib/patchtest/tests/test_metadata.py | |||
@@ -0,0 +1,204 @@ | |||
1 | # Checks related to the patch's LIC_FILES_CHKSUM metadata variable | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | import os | ||
9 | import pyparsing | ||
10 | from data import PatchTestInput, PatchTestDataStore | ||
11 | |||
12 | class TestMetadata(base.Metadata): | ||
13 | metadata_lic = 'LICENSE' | ||
14 | invalid_license = 'PATCHTESTINVALID' | ||
15 | metadata_chksum = 'LIC_FILES_CHKSUM' | ||
16 | license_var = 'LICENSE' | ||
17 | closed = 'CLOSED' | ||
18 | lictag_re = pyparsing.AtLineStart("License-Update:") | ||
19 | add_mark = pyparsing.Regex('\+ ') | ||
20 | max_length = 200 | ||
21 | metadata_src_uri = 'SRC_URI' | ||
22 | md5sum = 'md5sum' | ||
23 | sha256sum = 'sha256sum' | ||
24 | git_regex = pyparsing.Regex('^git\:\/\/.*') | ||
25 | metadata_summary = 'SUMMARY' | ||
26 | |||
27 | def test_license_presence(self): | ||
28 | if not self.added: | ||
29 | self.skip('No added recipes, skipping test') | ||
30 | |||
31 | # TODO: this is a workaround so we can parse the recipe not | ||
32 | # containing the LICENSE var: add some default license instead | ||
33 | # of INVALID into auto.conf, then remove this line at the end | ||
34 | auto_conf = os.path.join(os.environ.get('BUILDDIR'), 'conf', 'auto.conf') | ||
35 | open_flag = 'w' | ||
36 | if os.path.exists(auto_conf): | ||
37 | open_flag = 'a' | ||
38 | with open(auto_conf, open_flag) as fd: | ||
39 | for pn in self.added: | ||
40 | fd.write('LICENSE ??= "%s"\n' % self.invalid_license) | ||
41 | |||
42 | no_license = False | ||
43 | for pn in self.added: | ||
44 | rd = self.tinfoil.parse_recipe(pn) | ||
45 | license = rd.getVar(self.metadata_lic) | ||
46 | if license == self.invalid_license: | ||
47 | no_license = True | ||
48 | break | ||
49 | |||
50 | # remove auto.conf line or the file itself | ||
51 | if open_flag == 'w': | ||
52 | os.remove(auto_conf) | ||
53 | else: | ||
54 | fd = open(auto_conf, 'r') | ||
55 | lines = fd.readlines() | ||
56 | fd.close() | ||
57 | with open(auto_conf, 'w') as fd: | ||
58 | fd.write(''.join(lines[:-1])) | ||
59 | |||
60 | if no_license: | ||
61 | self.fail('Recipe does not have the LICENSE field set.') | ||
62 | |||
63 | def test_lic_files_chksum_presence(self): | ||
64 | if not self.added: | ||
65 | self.skip('No added recipes, skipping test') | ||
66 | |||
67 | for pn in self.added: | ||
68 | rd = self.tinfoil.parse_recipe(pn) | ||
69 | pathname = rd.getVar('FILE') | ||
70 | # we are not interested in images | ||
71 | if '/images/' in pathname: | ||
72 | continue | ||
73 | lic_files_chksum = rd.getVar(self.metadata_chksum) | ||
74 | if rd.getVar(self.license_var) == self.closed: | ||
75 | continue | ||
76 | if not lic_files_chksum: | ||
77 | self.fail('%s is missing in newly added recipe' % self.metadata_chksum) | ||
78 | |||
79 | def pretest_lic_files_chksum_modified_not_mentioned(self): | ||
80 | if not self.modified: | ||
81 | self.skip('No modified recipes, skipping pretest') | ||
82 | # get the proper metadata values | ||
83 | for pn in self.modified: | ||
84 | rd = self.tinfoil.parse_recipe(pn) | ||
85 | pathname = rd.getVar('FILE') | ||
86 | # we are not interested in images | ||
87 | if '/images/' in pathname: | ||
88 | continue | ||
89 | PatchTestDataStore['%s-%s-%s' % (self.shortid(),self.metadata_chksum,pn)] = rd.getVar(self.metadata_chksum) | ||
90 | |||
91 | def test_lic_files_chksum_modified_not_mentioned(self): | ||
92 | if not self.modified: | ||
93 | self.skip('No modified recipes, skipping test') | ||
94 | |||
95 | # get the proper metadata values | ||
96 | for pn in self.modified: | ||
97 | rd = self.tinfoil.parse_recipe(pn) | ||
98 | pathname = rd.getVar('FILE') | ||
99 | # we are not interested in images | ||
100 | if '/images/' in pathname: | ||
101 | continue | ||
102 | PatchTestDataStore['%s-%s-%s' % (self.shortid(),self.metadata_chksum,pn)] = rd.getVar(self.metadata_chksum) | ||
103 | # compare if there were changes between pre-merge and merge | ||
104 | for pn in self.modified: | ||
105 | pretest = PatchTestDataStore['pre%s-%s-%s' % (self.shortid(),self.metadata_chksum, pn)] | ||
106 | test = PatchTestDataStore['%s-%s-%s' % (self.shortid(),self.metadata_chksum, pn)] | ||
107 | |||
108 | # TODO: this is workaround to avoid false-positives when pretest metadata is empty (not reason found yet) | ||
109 | # For more info, check bug 12284 | ||
110 | if not pretest: | ||
111 | return | ||
112 | |||
113 | if pretest != test: | ||
114 | # if any patch on the series contain reference on the metadata, fail | ||
115 | for commit in self.commits: | ||
116 | if self.lictag_re.search_string(commit.commit_message): | ||
117 | break | ||
118 | else: | ||
119 | self.fail('LIC_FILES_CHKSUM changed on target %s but there is no "License-Update:" tag in commit message. Include it with a brief description' % pn, | ||
120 | data=[('Current checksum', pretest), ('New checksum', test)]) | ||
121 | |||
122 | def test_max_line_length(self): | ||
123 | for patch in self.patchset: | ||
124 | # for the moment, we are just interested in metadata | ||
125 | if patch.path.endswith('.patch'): | ||
126 | continue | ||
127 | payload = str(patch) | ||
128 | for line in payload.splitlines(): | ||
129 | if self.add_mark.search_string(line): | ||
130 | current_line_length = len(line[1:]) | ||
131 | if current_line_length > self.max_length: | ||
132 | self.fail('Patch line too long (current length %s, maximum is %s)' % (current_line_length, self.max_length), | ||
133 | data=[('Patch', patch.path), ('Line', '%s ...' % line[0:80])]) | ||
134 | |||
135 | def pretest_src_uri_left_files(self): | ||
136 | # these tests just make sense on patches that can be merged | ||
137 | if not PatchTestInput.repo.canbemerged: | ||
138 | self.skip('Patch cannot be merged') | ||
139 | if not self.modified: | ||
140 | self.skip('No modified recipes, skipping pretest') | ||
141 | |||
142 | # get the proper metadata values | ||
143 | for pn in self.modified: | ||
144 | # we are not interested in images | ||
145 | if 'core-image' in pn: | ||
146 | continue | ||
147 | rd = self.tinfoil.parse_recipe(pn) | ||
148 | PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)] = rd.getVar(self.metadata_src_uri) | ||
149 | |||
150 | def test_src_uri_left_files(self): | ||
151 | # these tests just make sense on patches that can be merged | ||
152 | if not PatchTestInput.repo.canbemerged: | ||
153 | self.skip('Patch cannot be merged') | ||
154 | if not self.modified: | ||
155 | self.skip('No modified recipes, skipping pretest') | ||
156 | |||
157 | # get the proper metadata values | ||
158 | for pn in self.modified: | ||
159 | # we are not interested in images | ||
160 | if 'core-image' in pn: | ||
161 | continue | ||
162 | rd = self.tinfoil.parse_recipe(pn) | ||
163 | PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)] = rd.getVar(self.metadata_src_uri) | ||
164 | |||
165 | for pn in self.modified: | ||
166 | pretest_src_uri = PatchTestDataStore['pre%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)].split() | ||
167 | test_src_uri = PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)].split() | ||
168 | |||
169 | pretest_files = set([os.path.basename(patch) for patch in pretest_src_uri if patch.startswith('file://')]) | ||
170 | test_files = set([os.path.basename(patch) for patch in test_src_uri if patch.startswith('file://')]) | ||
171 | |||
172 | # check if files were removed | ||
173 | if len(test_files) < len(pretest_files): | ||
174 | |||
175 | # get removals from patchset | ||
176 | filesremoved_from_patchset = set() | ||
177 | for patch in self.patchset: | ||
178 | if patch.is_removed_file: | ||
179 | filesremoved_from_patchset.add(os.path.basename(patch.path)) | ||
180 | |||
181 | # get the deleted files from the SRC_URI | ||
182 | filesremoved_from_usr_uri = pretest_files - test_files | ||
183 | |||
184 | # finally, get those patches removed at SRC_URI and not removed from the patchset | ||
185 | # TODO: we are not taking into account renames, so test may raise false positives | ||
186 | not_removed = filesremoved_from_usr_uri - filesremoved_from_patchset | ||
187 | if not_removed: | ||
188 | self.fail('Patches not removed from tree. Remove them and amend the submitted mbox', | ||
189 | data=[('Patch', f) for f in not_removed]) | ||
190 | |||
191 | def test_summary_presence(self): | ||
192 | if not self.added: | ||
193 | self.skip('No added recipes, skipping test') | ||
194 | |||
195 | for pn in self.added: | ||
196 | # we are not interested in images | ||
197 | if 'core-image' in pn: | ||
198 | continue | ||
199 | rd = self.tinfoil.parse_recipe(pn) | ||
200 | summary = rd.getVar(self.metadata_summary) | ||
201 | |||
202 | # "${PN} version ${PN}-${PR}" is the default, so fail if default | ||
203 | if summary.startswith('%s version' % pn): | ||
204 | self.fail('%s is missing in newly added recipe' % self.metadata_summary) | ||
diff --git a/meta/lib/patchtest/tests/test_metadata_lic_files_chksum.py b/meta/lib/patchtest/tests/test_metadata_lic_files_chksum.py deleted file mode 100644 index fa4a28c7b2..0000000000 --- a/meta/lib/patchtest/tests/test_metadata_lic_files_chksum.py +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | # Checks related to the patch's LIC_FILES_CHKSUM metadata variable | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | import pyparsing | ||
9 | from data import PatchTestInput, PatchTestDataStore | ||
10 | |||
11 | class LicFilesChkSum(base.Metadata): | ||
12 | metadata = 'LIC_FILES_CHKSUM' | ||
13 | license = 'LICENSE' | ||
14 | closed = 'CLOSED' | ||
15 | lictag_re = pyparsing.AtLineStart("License-Update:") | ||
16 | |||
17 | def test_lic_files_chksum_presence(self): | ||
18 | if not self.added: | ||
19 | self.skip('No added recipes, skipping test') | ||
20 | |||
21 | for pn in self.added: | ||
22 | rd = self.tinfoil.parse_recipe(pn) | ||
23 | pathname = rd.getVar('FILE') | ||
24 | # we are not interested in images | ||
25 | if '/images/' in pathname: | ||
26 | continue | ||
27 | lic_files_chksum = rd.getVar(self.metadata) | ||
28 | if rd.getVar(self.license) == self.closed: | ||
29 | continue | ||
30 | if not lic_files_chksum: | ||
31 | self.fail('%s is missing in newly added recipe' % self.metadata) | ||
32 | |||
33 | def pretest_lic_files_chksum_modified_not_mentioned(self): | ||
34 | if not self.modified: | ||
35 | self.skip('No modified recipes, skipping pretest') | ||
36 | # get the proper metadata values | ||
37 | for pn in self.modified: | ||
38 | rd = self.tinfoil.parse_recipe(pn) | ||
39 | pathname = rd.getVar('FILE') | ||
40 | # we are not interested in images | ||
41 | if '/images/' in pathname: | ||
42 | continue | ||
43 | PatchTestDataStore['%s-%s-%s' % (self.shortid(),self.metadata,pn)] = rd.getVar(self.metadata) | ||
44 | |||
45 | def test_lic_files_chksum_modified_not_mentioned(self): | ||
46 | if not self.modified: | ||
47 | self.skip('No modified recipes, skipping test') | ||
48 | |||
49 | # get the proper metadata values | ||
50 | for pn in self.modified: | ||
51 | rd = self.tinfoil.parse_recipe(pn) | ||
52 | pathname = rd.getVar('FILE') | ||
53 | # we are not interested in images | ||
54 | if '/images/' in pathname: | ||
55 | continue | ||
56 | PatchTestDataStore['%s-%s-%s' % (self.shortid(),self.metadata,pn)] = rd.getVar(self.metadata) | ||
57 | # compare if there were changes between pre-merge and merge | ||
58 | for pn in self.modified: | ||
59 | pretest = PatchTestDataStore['pre%s-%s-%s' % (self.shortid(),self.metadata, pn)] | ||
60 | test = PatchTestDataStore['%s-%s-%s' % (self.shortid(),self.metadata, pn)] | ||
61 | |||
62 | # TODO: this is workaround to avoid false-positives when pretest metadata is empty (not reason found yet) | ||
63 | # For more info, check bug 12284 | ||
64 | if not pretest: | ||
65 | return | ||
66 | |||
67 | if pretest != test: | ||
68 | # if any patch on the series contain reference on the metadata, fail | ||
69 | for commit in self.commits: | ||
70 | if self.lictag_re.search_string(commit.commit_message): | ||
71 | break | ||
72 | else: | ||
73 | self.fail('LIC_FILES_CHKSUM changed on target %s but there is no "License-Update:" tag in commit message. Include it with a brief description' % pn, | ||
74 | data=[('Current checksum', pretest), ('New checksum', test)]) | ||
diff --git a/meta/lib/patchtest/tests/test_metadata_license.py b/meta/lib/patchtest/tests/test_metadata_license.py deleted file mode 100644 index 1a7f09b747..0000000000 --- a/meta/lib/patchtest/tests/test_metadata_license.py +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | # Checks related to the patch's LIC_FILES_CHKSUM metadata variable | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | import os | ||
9 | from data import PatchTestInput | ||
10 | |||
11 | class License(base.Metadata): | ||
12 | metadata = 'LICENSE' | ||
13 | invalid_license = 'PATCHTESTINVALID' | ||
14 | |||
15 | def test_license_presence(self): | ||
16 | if not self.added: | ||
17 | self.skip('No added recipes, skipping test') | ||
18 | |||
19 | # TODO: this is a workaround so we can parse the recipe not | ||
20 | # containing the LICENSE var: add some default license instead | ||
21 | # of INVALID into auto.conf, then remove this line at the end | ||
22 | auto_conf = os.path.join(os.environ.get('BUILDDIR'), 'conf', 'auto.conf') | ||
23 | open_flag = 'w' | ||
24 | if os.path.exists(auto_conf): | ||
25 | open_flag = 'a' | ||
26 | with open(auto_conf, open_flag) as fd: | ||
27 | for pn in self.added: | ||
28 | fd.write('LICENSE ??= "%s"\n' % self.invalid_license) | ||
29 | |||
30 | no_license = False | ||
31 | for pn in self.added: | ||
32 | rd = self.tinfoil.parse_recipe(pn) | ||
33 | license = rd.getVar(self.metadata) | ||
34 | if license == self.invalid_license: | ||
35 | no_license = True | ||
36 | break | ||
37 | |||
38 | # remove auto.conf line or the file itself | ||
39 | if open_flag == 'w': | ||
40 | os.remove(auto_conf) | ||
41 | else: | ||
42 | fd = open(auto_conf, 'r') | ||
43 | lines = fd.readlines() | ||
44 | fd.close() | ||
45 | with open(auto_conf, 'w') as fd: | ||
46 | fd.write(''.join(lines[:-1])) | ||
47 | |||
48 | if no_license: | ||
49 | self.fail('Recipe does not have the LICENSE field set.') | ||
50 | |||
diff --git a/meta/lib/patchtest/tests/test_metadata_max_length.py b/meta/lib/patchtest/tests/test_metadata_max_length.py deleted file mode 100644 index 98c48ef787..0000000000 --- a/meta/lib/patchtest/tests/test_metadata_max_length.py +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | # Checks related to patch line lengths | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | import pyparsing | ||
9 | |||
10 | class MaxLength(base.Base): | ||
11 | add_mark = pyparsing.Regex('\+ ') | ||
12 | max_length = 200 | ||
13 | |||
14 | def test_max_line_length(self): | ||
15 | for patch in self.patchset: | ||
16 | # for the moment, we are just interested in metadata | ||
17 | if patch.path.endswith('.patch'): | ||
18 | continue | ||
19 | payload = str(patch) | ||
20 | for line in payload.splitlines(): | ||
21 | if self.add_mark.search_string(line): | ||
22 | current_line_length = len(line[1:]) | ||
23 | if current_line_length > self.max_length: | ||
24 | self.fail('Patch line too long (current length %s, maximum is %s)' % (current_line_length, self.max_length), | ||
25 | data=[('Patch', patch.path), ('Line', '%s ...' % line[0:80])]) | ||
diff --git a/meta/lib/patchtest/tests/test_metadata_src_uri.py b/meta/lib/patchtest/tests/test_metadata_src_uri.py deleted file mode 100644 index 87a24ea937..0000000000 --- a/meta/lib/patchtest/tests/test_metadata_src_uri.py +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | # Checks related to the patch's SRC_URI metadata variable | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | import os | ||
9 | import pyparsing | ||
10 | from data import PatchTestInput, PatchTestDataStore | ||
11 | |||
12 | class SrcUri(base.Metadata): | ||
13 | |||
14 | metadata = 'SRC_URI' | ||
15 | md5sum = 'md5sum' | ||
16 | sha256sum = 'sha256sum' | ||
17 | git_regex = pyparsing.Regex('^git\:\/\/.*') | ||
18 | |||
19 | def setUp(self): | ||
20 | # these tests just make sense on patches that can be merged | ||
21 | if not PatchTestInput.repo.canbemerged: | ||
22 | self.skip('Patch cannot be merged') | ||
23 | |||
24 | def pretest_src_uri_left_files(self): | ||
25 | if not self.modified: | ||
26 | self.skip('No modified recipes, skipping pretest') | ||
27 | |||
28 | # get the proper metadata values | ||
29 | for pn in self.modified: | ||
30 | # we are not interested in images | ||
31 | if 'core-image' in pn: | ||
32 | continue | ||
33 | rd = self.tinfoil.parse_recipe(pn) | ||
34 | PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata, pn)] = rd.getVar(self.metadata) | ||
35 | |||
36 | def test_src_uri_left_files(self): | ||
37 | if not self.modified: | ||
38 | self.skip('No modified recipes, skipping pretest') | ||
39 | |||
40 | # get the proper metadata values | ||
41 | for pn in self.modified: | ||
42 | # we are not interested in images | ||
43 | if 'core-image' in pn: | ||
44 | continue | ||
45 | rd = self.tinfoil.parse_recipe(pn) | ||
46 | PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata, pn)] = rd.getVar(self.metadata) | ||
47 | |||
48 | for pn in self.modified: | ||
49 | pretest_src_uri = PatchTestDataStore['pre%s-%s-%s' % (self.shortid(), self.metadata, pn)].split() | ||
50 | test_src_uri = PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata, pn)].split() | ||
51 | |||
52 | pretest_files = set([os.path.basename(patch) for patch in pretest_src_uri if patch.startswith('file://')]) | ||
53 | test_files = set([os.path.basename(patch) for patch in test_src_uri if patch.startswith('file://')]) | ||
54 | |||
55 | # check if files were removed | ||
56 | if len(test_files) < len(pretest_files): | ||
57 | |||
58 | # get removals from patchset | ||
59 | filesremoved_from_patchset = set() | ||
60 | for patch in self.patchset: | ||
61 | if patch.is_removed_file: | ||
62 | filesremoved_from_patchset.add(os.path.basename(patch.path)) | ||
63 | |||
64 | # get the deleted files from the SRC_URI | ||
65 | filesremoved_from_usr_uri = pretest_files - test_files | ||
66 | |||
67 | # finally, get those patches removed at SRC_URI and not removed from the patchset | ||
68 | # TODO: we are not taking into account renames, so test may raise false positives | ||
69 | not_removed = filesremoved_from_usr_uri - filesremoved_from_patchset | ||
70 | if not_removed: | ||
71 | self.fail('Patches not removed from tree. Remove them and amend the submitted mbox', | ||
72 | data=[('Patch', f) for f in not_removed]) | ||
73 | |||
diff --git a/meta/lib/patchtest/tests/test_metadata_summary.py b/meta/lib/patchtest/tests/test_metadata_summary.py deleted file mode 100644 index 170e79eb4b..0000000000 --- a/meta/lib/patchtest/tests/test_metadata_summary.py +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | # Checks related to the patch's summary metadata variable | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | from data import PatchTestInput | ||
9 | |||
10 | class Summary(base.Metadata): | ||
11 | metadata = 'SUMMARY' | ||
12 | |||
13 | def test_summary_presence(self): | ||
14 | if not self.added: | ||
15 | self.skip('No added recipes, skipping test') | ||
16 | |||
17 | for pn in self.added: | ||
18 | # we are not interested in images | ||
19 | if 'core-image' in pn: | ||
20 | continue | ||
21 | rd = self.tinfoil.parse_recipe(pn) | ||
22 | summary = rd.getVar(self.metadata) | ||
23 | |||
24 | # "${PN} version ${PN}-${PR}" is the default, so fail if default | ||
25 | if summary.startswith('%s version' % pn): | ||
26 | self.fail('%s is missing in newly added recipe' % self.metadata) | ||
diff --git a/meta/lib/patchtest/tests/test_patch_upstream_status.py b/meta/lib/patchtest/tests/test_patch.py index a5b278304e..b6904b185f 100644 --- a/meta/lib/patchtest/tests/test_patch_upstream_status.py +++ b/meta/lib/patchtest/tests/test_patch.py | |||
@@ -1,15 +1,19 @@ | |||
1 | # Checks related to the patch's upstream-status lines | 1 | # Checks related to the patch's CVE lines |
2 | # | 2 | # |
3 | # Copyright (C) 2016 Intel Corporation | 3 | # Copyright (C) 2016 Intel Corporation |
4 | # | 4 | # |
5 | # SPDX-License-Identifier: GPL-2.0-only | 5 | # SPDX-License-Identifier: GPL-2.0-only |
6 | # | ||
6 | 7 | ||
7 | import base | 8 | import base |
9 | import parse_signed_off_by | ||
8 | import parse_upstream_status | 10 | import parse_upstream_status |
9 | import pyparsing | 11 | import pyparsing |
10 | 12 | ||
11 | class PatchUpstreamStatus(base.Base): | 13 | class TestPatch(base.Base): |
12 | 14 | ||
15 | re_cve_pattern = pyparsing.Regex("CVE\-\d{4}\-\d+") | ||
16 | re_cve_payload_tag = pyparsing.Regex("\+CVE:(\s+CVE\-\d{4}\-\d+)+") | ||
13 | upstream_status_regex = pyparsing.AtLineStart("+" + "Upstream-Status") | 17 | upstream_status_regex = pyparsing.AtLineStart("+" + "Upstream-Status") |
14 | 18 | ||
15 | @classmethod | 19 | @classmethod |
@@ -20,17 +24,30 @@ class PatchUpstreamStatus(base.Base): | |||
20 | if patch.path.endswith('.patch') and patch.is_added_file: | 24 | if patch.path.endswith('.patch') and patch.is_added_file: |
21 | cls.newpatches.append(patch) | 25 | cls.newpatches.append(patch) |
22 | 26 | ||
27 | cls.mark = str(parse_signed_off_by.signed_off_by_mark).strip('"') | ||
28 | |||
29 | # match PatchSignedOffBy.mark with '+' preceding it | ||
30 | cls.prog = parse_signed_off_by.patch_signed_off_by | ||
31 | |||
23 | def setUp(self): | 32 | def setUp(self): |
24 | if self.unidiff_parse_error: | 33 | if self.unidiff_parse_error: |
25 | self.skip('Python-unidiff parse error') | 34 | self.skip('Parse error %s' % self.unidiff_parse_error) |
35 | |||
26 | self.valid_status = ', '.join(parse_upstream_status.upstream_status_nonliteral_valid_status) | 36 | self.valid_status = ', '.join(parse_upstream_status.upstream_status_nonliteral_valid_status) |
27 | self.standard_format = 'Upstream-Status: <Valid status>' | 37 | self.standard_format = 'Upstream-Status: <Valid status>' |
28 | 38 | ||
39 | # we are just interested in series that introduce CVE patches, thus discard other | ||
40 | # possibilities: modification to current CVEs, patch directly introduced into the | ||
41 | # recipe, upgrades already including the CVE, etc. | ||
42 | new_cves = [p for p in self.patchset if p.path.endswith('.patch') and p.is_added_file] | ||
43 | if not new_cves: | ||
44 | self.skip('No new CVE patches introduced') | ||
45 | |||
29 | def test_upstream_status_presence_format(self): | 46 | def test_upstream_status_presence_format(self): |
30 | if not PatchUpstreamStatus.newpatches: | 47 | if not TestPatch.newpatches: |
31 | self.skip("There are no new software patches, no reason to test Upstream-Status presence/format") | 48 | self.skip("There are no new software patches, no reason to test Upstream-Status presence/format") |
32 | 49 | ||
33 | for newpatch in PatchUpstreamStatus.newpatches: | 50 | for newpatch in TestPatch.newpatches: |
34 | payload = newpatch.__str__() | 51 | payload = newpatch.__str__() |
35 | if not self.upstream_status_regex.search_string(payload): | 52 | if not self.upstream_status_regex.search_string(payload): |
36 | self.fail('Added patch file is missing Upstream-Status in the header. Add Upstream-Status: <Valid status> to the header', | 53 | self.fail('Added patch file is missing Upstream-Status in the header. Add Upstream-Status: <Valid status> to the header', |
@@ -57,3 +74,29 @@ class PatchUpstreamStatus(base.Base): | |||
57 | except pyparsing.ParseException as pe: | 74 | except pyparsing.ParseException as pe: |
58 | self.fail('Upstream-Status is in incorrect format', | 75 | self.fail('Upstream-Status is in incorrect format', |
59 | data=[('Current', pe.pstr), ('Standard format', self.standard_format), ('Valid status', self.valid_status)]) | 76 | data=[('Current', pe.pstr), ('Standard format', self.standard_format), ('Valid status', self.valid_status)]) |
77 | |||
78 | def test_signed_off_by_presence(self): | ||
79 | if not TestPatch.newpatches: | ||
80 | self.skip("There are no new software patches, no reason to test %s presence" % PatchSignedOffBy.mark) | ||
81 | |||
82 | for newpatch in TestPatch.newpatches: | ||
83 | payload = newpatch.__str__() | ||
84 | for line in payload.splitlines(): | ||
85 | if self.patchmetadata_regex.match(line): | ||
86 | continue | ||
87 | if TestPatch.prog.search_string(payload): | ||
88 | break | ||
89 | else: | ||
90 | self.fail('A patch file has been added, but does not have a Signed-off-by tag. Sign off the added patch file (%s)' % newpatch.path) | ||
91 | |||
92 | def test_cve_tag_format(self): | ||
93 | for commit in TestPatch.commits: | ||
94 | if self.re_cve_pattern.search_string(commit.shortlog) or self.re_cve_pattern.search_string(commit.commit_message): | ||
95 | tag_found = False | ||
96 | for line in commit.payload.splitlines(): | ||
97 | if self.re_cve_payload_tag.search_string(line): | ||
98 | tag_found = True | ||
99 | break | ||
100 | if not tag_found: | ||
101 | self.fail('Missing or incorrectly formatted CVE tag in patch file. Correct or include the CVE tag in the patch with format: "CVE: CVE-YYYY-XXXX"', | ||
102 | commit=commit) | ||
diff --git a/meta/lib/patchtest/tests/test_patch_cve.py b/meta/lib/patchtest/tests/test_patch_cve.py deleted file mode 100644 index c77848de45..0000000000 --- a/meta/lib/patchtest/tests/test_patch_cve.py +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | # Checks related to the patch's CVE lines | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | # | ||
7 | |||
8 | import base | ||
9 | import pyparsing | ||
10 | |||
11 | class CVE(base.Base): | ||
12 | |||
13 | re_cve_pattern = pyparsing.Regex("CVE\-\d{4}\-\d+") | ||
14 | re_cve_payload_tag = pyparsing.Regex("\+CVE:(\s+CVE\-\d{4}\-\d+)+") | ||
15 | |||
16 | def setUp(self): | ||
17 | if self.unidiff_parse_error: | ||
18 | self.skip('Parse error %s' % self.unidiff_parse_error) | ||
19 | |||
20 | # we are just interested in series that introduce CVE patches, thus discard other | ||
21 | # possibilities: modification to current CVEs, patch directly introduced into the | ||
22 | # recipe, upgrades already including the CVE, etc. | ||
23 | new_cves = [p for p in self.patchset if p.path.endswith('.patch') and p.is_added_file] | ||
24 | if not new_cves: | ||
25 | self.skip('No new CVE patches introduced') | ||
26 | |||
27 | def test_cve_tag_format(self): | ||
28 | for commit in CVE.commits: | ||
29 | if self.re_cve_pattern.search_string(commit.shortlog) or self.re_cve_pattern.search_string(commit.commit_message): | ||
30 | tag_found = False | ||
31 | for line in commit.payload.splitlines(): | ||
32 | if self.re_cve_payload_tag.search_string(line): | ||
33 | tag_found = True | ||
34 | break | ||
35 | if not tag_found: | ||
36 | self.fail('Missing or incorrectly formatted CVE tag in patch file. Correct or include the CVE tag in the patch with format: "CVE: CVE-YYYY-XXXX"', | ||
37 | commit=commit) | ||
diff --git a/meta/lib/patchtest/tests/test_patch_signed_off_by.py b/meta/lib/patchtest/tests/test_patch_signed_off_by.py deleted file mode 100644 index b091ff6f10..0000000000 --- a/meta/lib/patchtest/tests/test_patch_signed_off_by.py +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | # Checks related to the patch's signed-off-by lines | ||
2 | # | ||
3 | # Copyright (C) 2016 Intel Corporation | ||
4 | # | ||
5 | # SPDX-License-Identifier: GPL-2.0-only | ||
6 | |||
7 | import base | ||
8 | import parse_signed_off_by | ||
9 | |||
10 | class PatchSignedOffBy(base.Base): | ||
11 | |||
12 | @classmethod | ||
13 | def setUpClassLocal(cls): | ||
14 | cls.newpatches = [] | ||
15 | # get just those relevant patches: new software patches | ||
16 | for patch in cls.patchset: | ||
17 | if patch.path.endswith('.patch') and patch.is_added_file: | ||
18 | cls.newpatches.append(patch) | ||
19 | |||
20 | cls.mark = str(parse_signed_off_by.signed_off_by_mark).strip('"') | ||
21 | |||
22 | # match PatchSignedOffBy.mark with '+' preceding it | ||
23 | cls.prog = parse_signed_off_by.patch_signed_off_by | ||
24 | |||
25 | def setUp(self): | ||
26 | if self.unidiff_parse_error: | ||
27 | self.skip('Parse error %s' % self.unidiff_parse_error) | ||
28 | |||
29 | def test_signed_off_by_presence(self): | ||
30 | if not PatchSignedOffBy.newpatches: | ||
31 | self.skip("There are no new software patches, no reason to test %s presence" % PatchSignedOffBy.mark) | ||
32 | |||
33 | for newpatch in PatchSignedOffBy.newpatches: | ||
34 | payload = newpatch.__str__() | ||
35 | for line in payload.splitlines(): | ||
36 | if self.patchmetadata_regex.match(line): | ||
37 | continue | ||
38 | if PatchSignedOffBy.prog.search_string(payload): | ||
39 | break | ||
40 | else: | ||
41 | self.fail('A patch file has been added, but does not have a Signed-off-by tag. Sign off the added patch file (%s)' % newpatch.path) | ||