Skip to content

Commit 39f8e70

Browse files
committed
Ensure uniqueness of pipeline_id and datasource_id
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent 8c07713 commit 39f8e70

5 files changed

Lines changed: 139 additions & 1 deletion

File tree

vulnerabilities/pipelines/v2_importers/collect_fix_commits.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,184 +3,221 @@
33

44
class CollectLinuxFixCommitsPipeline(CollectVCSFixCommitPipeline):
55
pipeline_id = "collect_linux_fix_commits"
6+
datasource_id = "linux_fix_commits"
67
repo_url = "https://github.com/torvalds/linux"
78

89

910
class CollectBusyBoxFixCommitsPipeline(CollectVCSFixCommitPipeline):
1011
pipeline_id = "collect_busybox_fix_commits"
12+
datasource_id = "busybox_fix_commits"
1113
repo_url = "https://github.com/mirror/busybox"
1214

1315

1416
class CollectNginxFixCommitsPipeline(CollectVCSFixCommitPipeline):
1517
pipeline_id = "collect_nginx_fix_commits"
18+
datasource_id = "nginx_fix_commits"
1619
repo_url = "https://github.com/nginx/nginx"
1720

1821

1922
class CollectApacheTomcatFixCommitsPipeline(CollectVCSFixCommitPipeline):
2023
pipeline_id = "collect_apache_tomcat_fix_commits"
24+
datasource_id = "apache_tomcat_fix_commits"
2125
repo_url = "https://github.com/apache/tomcat"
2226

2327

2428
class CollectMysqlServerFixCommitsPipeline(CollectVCSFixCommitPipeline):
2529
pipeline_id = "collect_mysql_server_fix_commits"
30+
datasource_id = "mysql_server_fix_commits"
2631
repo_url = "https://github.com/mysql/mysql-server"
2732

2833

2934
class CollectPostgresqlFixCommitsPipeline(CollectVCSFixCommitPipeline):
3035
pipeline_id = "collect_postgresql_fix_commits"
36+
datasource_id = "postgresql_fix_commits"
3137
repo_url = "https://github.com/postgres/postgres"
3238

3339

3440
class CollectMongodbFixCommitsPipeline(CollectVCSFixCommitPipeline):
3541
pipeline_id = "collect_mongodb_fix_commits"
42+
datasource_id = "mongodb_fix_commits"
3643
repo_url = "https://github.com/mongodb/mongo"
3744

3845

3946
class CollectRedisFixCommitsPipeline(CollectVCSFixCommitPipeline):
4047
pipeline_id = "collect_redis_fix_commits"
48+
datasource_id = "redis_fix_commits"
4149
repo_url = "https://github.com/redis/redis"
4250

4351

4452
class CollectSqliteFixCommitsPipeline(CollectVCSFixCommitPipeline):
4553
pipeline_id = "collect_sqlite_fix_commits"
54+
datasource_id = "sqlite_fix_commits"
4655
repo_url = "https://github.com/sqlite/sqlite"
4756

4857

4958
class CollectPhpFixCommitsPipeline(CollectVCSFixCommitPipeline):
5059
pipeline_id = "collect_php_fix_commits"
60+
datasource_id = "php_fix_commits"
5161
repo_url = "https://github.com/php/php-src"
5262

5363

5464
class CollectPythonCpythonFixCommitsPipeline(CollectVCSFixCommitPipeline):
5565
pipeline_id = "collect_python_cpython_fix_commits"
66+
datasource_id = "python_cpython_fix_commits"
5667
repo_url = "https://github.com/python/cpython"
5768

5869

5970
class CollectRubyFixCommitsPipeline(CollectVCSFixCommitPipeline):
6071
pipeline_id = "collect_ruby_fix_commits"
72+
datasource_id = "ruby_fix_commits"
6173
repo_url = "https://github.com/ruby/ruby"
6274

6375

6476
class CollectGoFixCommitsPipeline(CollectVCSFixCommitPipeline):
6577
pipeline_id = "collect_go_fix_commits"
78+
datasource_id = "go_fix_commits"
6679
repo_url = "https://github.com/golang/go"
6780

6881

6982
class CollectNodeJsFixCommitsPipeline(CollectVCSFixCommitPipeline):
7083
pipeline_id = "collect_node_js_fix_commits"
84+
datasource_id = "node_js_fix_commits"
7185
repo_url = "https://github.com/nodejs/node"
7286

7387

7488
class CollectRustFixCommitsPipeline(CollectVCSFixCommitPipeline):
7589
pipeline_id = "collect_rust_fix_commits"
90+
datasource_id = "rust_fix_commits"
7691
repo_url = "https://github.com/rust-lang/rust"
7792

7893

7994
class CollectOpenjdkFixCommitsPipeline(CollectVCSFixCommitPipeline):
8095
pipeline_id = "collect_openjdk_fix_commits"
96+
datasource_id = "openjdk_fix_commits"
8197
repo_url = "https://github.com/openjdk/jdk"
8298

8399

84100
class CollectSwiftFixCommitsPipeline(CollectVCSFixCommitPipeline):
85101
pipeline_id = "collect_swift_fix_commits"
102+
datasource_id = "swift_fix_commits"
86103
repo_url = "https://github.com/swiftlang/swift"
87104

88105

89106
class CollectDjangoFixCommitsPipeline(CollectVCSFixCommitPipeline):
90107
pipeline_id = "collect_django_fix_commits"
108+
datasource_id = "django_fix_commits"
91109
repo_url = "https://github.com/django/django"
92110

93111

94112
class CollectRailsFixCommitsPipeline(CollectVCSFixCommitPipeline):
95113
pipeline_id = "collect_rails_fix_commits"
114+
datasource_id = "rails_fix_commits"
96115
repo_url = "https://github.com/rails/rails"
97116

98117

99118
class CollectLaravelFixCommitsPipeline(CollectVCSFixCommitPipeline):
100119
pipeline_id = "collect_laravel_fix_commits"
120+
datasource_id = "laravel_fix_commits"
101121
repo_url = "https://github.com/laravel/framework"
102122

103123

104124
class CollectSpringFrameworkFixCommitsPipeline(CollectVCSFixCommitPipeline):
105125
pipeline_id = "collect_spring_framework_fix_commits"
126+
datasource_id = "spring_framework_fix_commits"
106127
repo_url = "https://github.com/spring-projects/spring-framework"
107128

108129

109130
class CollectReactFixCommitsPipeline(CollectVCSFixCommitPipeline):
110131
pipeline_id = "collect_react_fix_commits"
132+
datasource_id = "react_fix_commits"
111133
repo_url = "https://github.com/facebook/react"
112134

113135

114136
class CollectAngularFixCommitsPipeline(CollectVCSFixCommitPipeline):
115137
pipeline_id = "collect_angular_fix_commits"
138+
datasource_id = "angular_fix_commits"
116139
repo_url = "https://github.com/angular/angular"
117140

118141

119142
class CollectWordpressFixCommitsPipeline(CollectVCSFixCommitPipeline):
120143
pipeline_id = "collect_wordpress_fix_commits"
144+
datasource_id = "wordpress_fix_commits"
121145
repo_url = "https://github.com/WordPress/WordPress"
122146

123147

124148
class CollectDockerMobyFixCommitsPipeline(CollectVCSFixCommitPipeline):
125149
pipeline_id = "collect_docker_moby_fix_commits"
150+
datasource_id = "docker_moby_fix_commits"
126151
repo_url = "https://github.com/moby/moby"
127152

128153

129154
class CollectKubernetesFixCommitsPipeline(CollectVCSFixCommitPipeline):
130155
pipeline_id = "collect_kubernetes_fix_commits"
156+
datasource_id = "kubernetes_fix_commits"
131157
repo_url = "https://github.com/kubernetes/kubernetes"
132158

133159

134160
class CollectQemuFixCommitsPipeline(CollectVCSFixCommitPipeline):
135161
pipeline_id = "collect_qemu_fix_commits"
162+
datasource_id = "qemu_fix_commits"
136163
repo_url = "https://gitlab.com/qemu-project/qemu"
137164

138165

139166
class CollectXenProjectFixCommitsPipeline(CollectVCSFixCommitPipeline):
140167
pipeline_id = "collect_xen_project_fix_commits"
168+
datasource_id = "xen_project_fix_commits"
141169
repo_url = "https://github.com/xen-project/xen"
142170

143171

144172
class CollectVirtualboxFixCommitsPipeline(CollectVCSFixCommitPipeline):
145173
pipeline_id = "collect_virtualbox_fix_commits"
174+
datasource_id = "virtualbox_fix_commits"
146175
repo_url = "https://github.com/mirror/vbox"
147176

148177

149178
class CollectContainerdFixCommitsPipeline(CollectVCSFixCommitPipeline):
150179
pipeline_id = "collect_containerd_fix_commits"
180+
datasource_id = "containerd_fix_commits"
151181
repo_url = "https://github.com/containerd/containerd"
152182

153183

154184
class CollectAnsibleFixCommitsPipeline(CollectVCSFixCommitPipeline):
155185
pipeline_id = "collect_ansible_fix_commits"
186+
datasource_id = "ansible_fix_commits"
156187
repo_url = "https://github.com/ansible/ansible"
157188

158189

159190
class CollectTerraformFixCommitsPipeline(CollectVCSFixCommitPipeline):
160191
pipeline_id = "collect_terraform_fix_commits"
192+
datasource_id = "terraform_fix_commits"
161193
repo_url = "https://github.com/hashicorp/terraform"
162194

163195

164196
class CollectWiresharkFixCommitsPipeline(CollectVCSFixCommitPipeline):
165197
pipeline_id = "collect_wireshark_fix_commits"
198+
datasource_id = "wireshark_fix_commits"
166199
repo_url = "https://gitlab.com/wireshark/wireshark"
167200

168201

169202
class CollectTcpdumpFixCommitsPipeline(CollectVCSFixCommitPipeline):
170203
pipeline_id = "collect_tcpdump_fix_commits"
204+
datasource_id = "tcpdump_fix_commits"
171205
repo_url = "https://github.com/the-tcpdump-group/tcpdump"
172206

173207

174208
class CollectGitFixCommitsPipeline(CollectVCSFixCommitPipeline):
175209
pipeline_id = "collect_git_fix_commits"
210+
datasource_id = "git_fix_commits"
176211
repo_url = "https://github.com/git/git"
177212

178213

179214
class CollectJenkinsFixCommitsPipeline(CollectVCSFixCommitPipeline):
180215
pipeline_id = "collect_jenkins_fix_commits"
216+
datasource_id = "jenkins_fix_commits"
181217
repo_url = "https://github.com/jenkinsci/jenkins"
182218

183219

184220
class CollectGitlabFixCommitsPipeline(CollectVCSFixCommitPipeline):
185221
pipeline_id = "collect_gitlab_fix_commits"
222+
datasource_id = "gitlab_fix_commits"
186223
repo_url = "https://gitlab.com/gitlab-org/gitlab-foss"

vulnerabilities/pipelines/v2_importers/glibc_importer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class GlibcImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
3030
"""
3131

3232
pipeline_id = "glibc_importer_v2"
33+
datasource_id = "glibc"
3334
spdx_license_expression = "LGPL-2.1-only"
3435
license_url = "https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=LICENSES"
3536
repo_url = "git+https://sourceware.org/git/glibc.git"

vulnerabilities/pipelines/v2_importers/linux_kernel_importer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class LinuxKernelPipeline(VulnerableCodeBaseImporterPipelineV2):
3030
"""
3131

3232
pipeline_id = "linux_kernel_cves_fix_commits"
33+
datasource_id = "linux_kernel"
3334
spdx_license_expression = "Apache-2.0"
3435
license_url = "https://github.com/nluedtke/linux_kernel_cves/blob/master/LICENSE"
3536
run_once = True

vulnerabilities/pipes/vcs_collector_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class CollectVCSFixCommitPipeline(VulnerableCodeBaseImporterPipelineV2):
3434

3535
pipeline_id = "collect_vcs_fix_commits"
3636

37-
datasource_id = pipeline_id.replace("collect_", "")
37+
datasource_id = "vcs_fix_commits"
3838

3939
repo_url: str
4040
patterns: list[str] = [

vulnerabilities/tests/pipelines/test_pipeline_id.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
99

10+
import collections
1011
import importlib
1112
import inspect
1213
import unittest
1314
from pathlib import Path
1415

16+
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipelineV2
1517
from vulnerabilities.pipelines import VulnerableCodePipeline
1618

1719
PIPELINE_DIR = Path(__file__).parent.parent.parent / "pipelines"
@@ -20,6 +22,7 @@
2022
class PipelineTests(unittest.TestCase):
2123
def setUp(self):
2224
self.pipeline_dict = self.collect_pipeline_ids()
25+
self.v2_pipeline_dict = self.collect_v2_pipeline_ids()
2326

2427
def collect_pipeline_ids(self):
2528
"""Return pipeline_ids from all the VulnerableCodePipeline."""
@@ -40,6 +43,32 @@ def collect_pipeline_ids(self):
4043

4144
return pipeline_dict
4245

46+
def import_all_pipeline_modules(self):
47+
"""Import all modules under vulnerabilities.pipelines recursively."""
48+
for pipeline in PIPELINE_DIR.rglob("*.py"):
49+
if pipeline.name == "__init__.py":
50+
continue
51+
52+
module_name = ".".join(pipeline.relative_to(PIPELINE_DIR).with_suffix("").parts)
53+
importlib.import_module(f"vulnerabilities.pipelines.{module_name}")
54+
55+
def collect_v2_pipeline_ids(self):
56+
"""Return pipeline_id and datasource_id from all VulnerableCodeBaseImporterPipelineV2 subclasses."""
57+
self.import_all_pipeline_modules()
58+
importlib.import_module("vulnerabilities.pipes.vcs_collector_utils")
59+
60+
pipeline_dict = {}
61+
for obj in self._all_subclasses(VulnerableCodeBaseImporterPipelineV2):
62+
pipeline_dict[obj] = (obj.pipeline_id, obj.datasource_id)
63+
64+
return pipeline_dict
65+
66+
def _all_subclasses(self, cls):
67+
subclasses = set(cls.__subclasses__())
68+
for subclass in list(subclasses):
69+
subclasses.update(self._all_subclasses(subclass))
70+
return subclasses
71+
4372
def test_no_empty_pipeline_ids(self):
4473
empty_pipeline_ids = [cls for cls, pid in self.pipeline_dict.items() if pid == ""]
4574

@@ -64,3 +93,73 @@ def test_unique_pipeline_ids(self):
6493
pipeline_ids = self.pipeline_dict.values()
6594
unique_ids = set(pipeline_ids)
6695
assert len(pipeline_ids) == len(unique_ids), "`pipeline_id` should be unique."
96+
97+
def test_v2_pipeline_ids_are_defined(self):
98+
missing_pipeline_ids = [
99+
cls.__name__
100+
for cls, (pipeline_id, _) in self.v2_pipeline_dict.items()
101+
if pipeline_id is None or pipeline_id == ""
102+
]
103+
104+
if missing_pipeline_ids:
105+
error_messages = [
106+
f"{pipeline} has missing pipeline_id." for pipeline in missing_pipeline_ids
107+
]
108+
error_message = (
109+
"`pipeline_id` for V2 pipelines must be defined and non-empty:\n"
110+
+ "\n".join(error_messages)
111+
)
112+
assert False, error_message
113+
114+
def test_v2_datasource_ids_are_defined(self):
115+
missing_datasource_ids = [
116+
cls.__name__
117+
for cls, (_, datasource_id) in self.v2_pipeline_dict.items()
118+
if datasource_id is None or datasource_id == ""
119+
]
120+
121+
if missing_datasource_ids:
122+
error_messages = [
123+
f"{pipeline} has missing datasource_id." for pipeline in missing_datasource_ids
124+
]
125+
error_message = (
126+
"`datasource_id` for V2 pipelines must be defined and non-empty:\n"
127+
+ "\n".join(error_messages)
128+
)
129+
assert False, error_message
130+
131+
def test_unique_v2_pipeline_ids(self):
132+
pipeline_to_classes = collections.defaultdict(list)
133+
for cls, (pipeline_id, _) in self.v2_pipeline_dict.items():
134+
pipeline_to_classes[pipeline_id].append(cls.__name__)
135+
136+
duplicates = {
137+
pipeline_id: classes
138+
for pipeline_id, classes in pipeline_to_classes.items()
139+
if pipeline_id and len(classes) > 1
140+
}
141+
142+
assert not duplicates, (
143+
"Duplicate V2 pipeline_id values found: "
144+
+ ", ".join(
145+
f"{pipeline_id}: {classes}" for pipeline_id, classes in duplicates.items()
146+
)
147+
)
148+
149+
def test_unique_v2_datasource_ids(self):
150+
datasource_to_classes = collections.defaultdict(list)
151+
for cls, (_, datasource_id) in self.v2_pipeline_dict.items():
152+
datasource_to_classes[datasource_id].append(cls.__name__)
153+
154+
duplicates = {
155+
datasource_id: classes
156+
for datasource_id, classes in datasource_to_classes.items()
157+
if datasource_id and len(classes) > 1
158+
}
159+
160+
assert not duplicates, (
161+
"Duplicate V2 datasource_id values found: "
162+
+ ", ".join(
163+
f"{datasource_id}: {classes}" for datasource_id, classes in duplicates.items()
164+
)
165+
)

0 commit comments

Comments
 (0)