1#!/usr/bin/env python3 2# Copyright 2016 gRPC authors. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15"""Definition of targets run distribution package tests.""" 16 17import os.path 18import sys 19 20sys.path.insert(0, os.path.abspath('..')) 21import python_utils.jobset as jobset 22 23 24def create_docker_jobspec(name, 25 dockerfile_dir, 26 shell_command, 27 environ={}, 28 flake_retries=0, 29 timeout_retries=0, 30 copy_rel_path=None, 31 timeout_seconds=30 * 60): 32 """Creates jobspec for a task running under docker.""" 33 environ = environ.copy() 34 # the entire repo will be cloned if copy_rel_path is not set. 35 if copy_rel_path: 36 environ['RELATIVE_COPY_PATH'] = copy_rel_path 37 38 docker_args = [] 39 for k, v in list(environ.items()): 40 docker_args += ['-e', '%s=%s' % (k, v)] 41 docker_env = { 42 'DOCKERFILE_DIR': dockerfile_dir, 43 'DOCKER_RUN_SCRIPT': 'tools/run_tests/dockerize/docker_run.sh', 44 'DOCKER_RUN_SCRIPT_COMMAND': shell_command, 45 } 46 jobspec = jobset.JobSpec( 47 cmdline=['tools/run_tests/dockerize/build_and_run_docker.sh'] + 48 docker_args, 49 environ=docker_env, 50 shortname='distribtest.%s' % (name), 51 timeout_seconds=timeout_seconds, 52 flake_retries=flake_retries, 53 timeout_retries=timeout_retries) 54 return jobspec 55 56 57def create_jobspec(name, 58 cmdline, 59 environ=None, 60 shell=False, 61 flake_retries=0, 62 timeout_retries=0, 63 use_workspace=False, 64 timeout_seconds=10 * 60): 65 """Creates jobspec.""" 66 environ = environ.copy() 67 if use_workspace: 68 environ['WORKSPACE_NAME'] = 'workspace_%s' % name 69 cmdline = ['bash', 'tools/run_tests/artifacts/run_in_workspace.sh' 70 ] + cmdline 71 jobspec = jobset.JobSpec(cmdline=cmdline, 72 environ=environ, 73 shortname='distribtest.%s' % (name), 74 timeout_seconds=timeout_seconds, 75 flake_retries=flake_retries, 76 timeout_retries=timeout_retries, 77 shell=shell) 78 return jobspec 79 80 81class CSharpDistribTest(object): 82 """Tests C# NuGet package""" 83 84 def __init__(self, 85 platform, 86 arch, 87 docker_suffix=None, 88 use_dotnet_cli=False, 89 presubmit=False): 90 self.name = 'csharp_%s_%s' % (platform, arch) 91 self.platform = platform 92 self.arch = arch 93 self.docker_suffix = docker_suffix 94 self.labels = ['distribtest', 'csharp', platform, arch] 95 if presubmit: 96 self.labels.append('presubmit') 97 self.script_suffix = '' 98 if docker_suffix: 99 self.name += '_%s' % docker_suffix 100 self.labels.append(docker_suffix) 101 if use_dotnet_cli: 102 self.name += '_dotnetcli' 103 self.script_suffix = '_dotnetcli' 104 self.labels.append('dotnetcli') 105 else: 106 self.labels.append('olddotnet') 107 108 def pre_build_jobspecs(self): 109 return [] 110 111 def build_jobspec(self, inner_jobs=None): 112 del inner_jobs # arg unused as there is little opportunity for parallelizing whats inside the distribtests 113 if self.platform == 'linux': 114 return create_docker_jobspec( 115 self.name, 116 'tools/dockerfile/distribtest/csharp_%s_%s' % 117 (self.docker_suffix, self.arch), 118 'test/distrib/csharp/run_distrib_test%s.sh' % 119 self.script_suffix, 120 copy_rel_path='test/distrib') 121 elif self.platform == 'macos': 122 return create_jobspec(self.name, [ 123 'test/distrib/csharp/run_distrib_test%s.sh' % self.script_suffix 124 ], 125 environ={ 126 'EXTERNAL_GIT_ROOT': '../../../..', 127 'SKIP_NETCOREAPP21_DISTRIBTEST': '1', 128 'SKIP_NET50_DISTRIBTEST': '1', 129 }, 130 use_workspace=True) 131 elif self.platform == 'windows': 132 # TODO(jtattermusch): re-enable windows distribtest 133 return create_jobspec( 134 self.name, 135 ['bash', 'tools/run_tests/artifacts/run_distribtest_csharp.sh'], 136 environ={}, 137 use_workspace=True) 138 else: 139 raise Exception("Not supported yet.") 140 141 def __str__(self): 142 return self.name 143 144 145class PythonDistribTest(object): 146 """Tests Python package""" 147 148 def __init__(self, 149 platform, 150 arch, 151 docker_suffix, 152 source=False, 153 presubmit=False): 154 self.source = source 155 if source: 156 self.name = 'python_dev_%s_%s_%s' % (platform, arch, docker_suffix) 157 else: 158 self.name = 'python_%s_%s_%s' % (platform, arch, docker_suffix) 159 self.platform = platform 160 self.arch = arch 161 self.docker_suffix = docker_suffix 162 self.labels = ['distribtest', 'python', platform, arch, docker_suffix] 163 if presubmit: 164 self.labels.append('presubmit') 165 166 def pre_build_jobspecs(self): 167 return [] 168 169 def build_jobspec(self, inner_jobs=None): 170 # TODO(jtattermusch): honor inner_jobs arg for this task. 171 del inner_jobs 172 if not self.platform == 'linux': 173 raise Exception("Not supported yet.") 174 175 if self.source: 176 return create_docker_jobspec( 177 self.name, 178 'tools/dockerfile/distribtest/python_dev_%s_%s' % 179 (self.docker_suffix, self.arch), 180 'test/distrib/python/run_source_distrib_test.sh', 181 copy_rel_path='test/distrib') 182 else: 183 return create_docker_jobspec( 184 self.name, 185 'tools/dockerfile/distribtest/python_%s_%s' % 186 (self.docker_suffix, self.arch), 187 'test/distrib/python/run_binary_distrib_test.sh', 188 copy_rel_path='test/distrib') 189 190 def __str__(self): 191 return self.name 192 193 194class RubyDistribTest(object): 195 """Tests Ruby package""" 196 197 def __init__(self, 198 platform, 199 arch, 200 docker_suffix, 201 ruby_version=None, 202 source=False, 203 presubmit=False): 204 self.package_type = 'binary' 205 if source: 206 self.package_type = 'source' 207 self.name = 'ruby_%s_%s_%s_version_%s_package_type_%s' % ( 208 platform, arch, docker_suffix, ruby_version or 209 'unspecified', self.package_type) 210 self.platform = platform 211 self.arch = arch 212 self.docker_suffix = docker_suffix 213 self.ruby_version = ruby_version 214 self.labels = ['distribtest', 'ruby', platform, arch, docker_suffix] 215 if presubmit: 216 self.labels.append('presubmit') 217 218 def pre_build_jobspecs(self): 219 return [] 220 221 def build_jobspec(self, inner_jobs=None): 222 # TODO(jtattermusch): honor inner_jobs arg for this task. 223 del inner_jobs 224 arch_to_gem_arch = { 225 'x64': 'x86_64', 226 'x86': 'x86', 227 } 228 if not self.platform == 'linux': 229 raise Exception("Not supported yet.") 230 231 dockerfile_name = 'tools/dockerfile/distribtest/ruby_%s_%s' % ( 232 self.docker_suffix, self.arch) 233 if self.ruby_version is not None: 234 dockerfile_name += '_%s' % self.ruby_version 235 return create_docker_jobspec( 236 self.name, 237 dockerfile_name, 238 'test/distrib/ruby/run_distrib_test.sh %s %s %s' % 239 (arch_to_gem_arch[self.arch], self.platform, self.package_type), 240 copy_rel_path='test/distrib') 241 242 def __str__(self): 243 return self.name 244 245 246class PHP7DistribTest(object): 247 """Tests PHP7 package""" 248 249 def __init__(self, platform, arch, docker_suffix=None, presubmit=False): 250 self.name = 'php7_%s_%s_%s' % (platform, arch, docker_suffix) 251 self.platform = platform 252 self.arch = arch 253 self.docker_suffix = docker_suffix 254 self.labels = ['distribtest', 'php', 'php7', platform, arch] 255 if presubmit: 256 self.labels.append('presubmit') 257 if docker_suffix: 258 self.labels.append(docker_suffix) 259 260 def pre_build_jobspecs(self): 261 return [] 262 263 def build_jobspec(self, inner_jobs=None): 264 # TODO(jtattermusch): honor inner_jobs arg for this task. 265 del inner_jobs 266 if self.platform == 'linux': 267 return create_docker_jobspec( 268 self.name, 269 'tools/dockerfile/distribtest/php7_%s_%s' % 270 (self.docker_suffix, self.arch), 271 'test/distrib/php/run_distrib_test.sh', 272 copy_rel_path='test/distrib') 273 elif self.platform == 'macos': 274 return create_jobspec( 275 self.name, ['test/distrib/php/run_distrib_test_macos.sh'], 276 environ={'EXTERNAL_GIT_ROOT': '../../../..'}, 277 timeout_seconds=20 * 60, 278 use_workspace=True) 279 else: 280 raise Exception("Not supported yet.") 281 282 def __str__(self): 283 return self.name 284 285 286class CppDistribTest(object): 287 """Tests Cpp make install by building examples.""" 288 289 def __init__(self, 290 platform, 291 arch, 292 docker_suffix=None, 293 testcase=None, 294 presubmit=False): 295 if platform == 'linux': 296 self.name = 'cpp_%s_%s_%s_%s' % (platform, arch, docker_suffix, 297 testcase) 298 else: 299 self.name = 'cpp_%s_%s_%s' % (platform, arch, testcase) 300 self.platform = platform 301 self.arch = arch 302 self.docker_suffix = docker_suffix 303 self.testcase = testcase 304 self.labels = [ 305 'distribtest', 306 'cpp', 307 platform, 308 arch, 309 testcase, 310 ] 311 if presubmit: 312 self.labels.append('presubmit') 313 if docker_suffix: 314 self.labels.append(docker_suffix) 315 316 def pre_build_jobspecs(self): 317 return [] 318 319 def build_jobspec(self, inner_jobs=None): 320 environ = {} 321 if inner_jobs is not None: 322 # set number of parallel jobs for the C++ build 323 environ['GRPC_CPP_DISTRIBTEST_BUILD_COMPILER_JOBS'] = str( 324 inner_jobs) 325 326 if self.platform == 'linux': 327 return create_docker_jobspec( 328 self.name, 329 'tools/dockerfile/distribtest/cpp_%s_%s' % 330 (self.docker_suffix, self.arch), 331 'test/distrib/cpp/run_distrib_test_%s.sh' % self.testcase, 332 timeout_seconds=45 * 60) 333 elif self.platform == 'windows': 334 return create_jobspec( 335 self.name, 336 ['test\\distrib\\cpp\\run_distrib_test_%s.bat' % self.testcase], 337 environ={}, 338 timeout_seconds=45 * 60, 339 use_workspace=True) 340 else: 341 raise Exception("Not supported yet.") 342 343 def __str__(self): 344 return self.name 345 346 347def targets(): 348 """Gets list of supported targets""" 349 return [ 350 # C++ 351 CppDistribTest('linux', 'x64', 'debian10', 'cmake', presubmit=True), 352 CppDistribTest('linux', 353 'x64', 354 'debian10', 355 'cmake_as_submodule', 356 presubmit=True), 357 CppDistribTest('linux', 358 'x64', 359 'debian10', 360 'cmake_as_externalproject', 361 presubmit=True), 362 CppDistribTest('linux', 363 'x64', 364 'debian10', 365 'cmake_fetchcontent', 366 presubmit=True), 367 CppDistribTest('linux', 368 'x64', 369 'debian10', 370 'cmake_module_install', 371 presubmit=True), 372 CppDistribTest('linux', 373 'x64', 374 'debian10', 375 'cmake_pkgconfig', 376 presubmit=True), 377 CppDistribTest('linux', 378 'x64', 379 'debian10_aarch64_cross', 380 'cmake_aarch64_cross', 381 presubmit=True), 382 CppDistribTest('windows', 'x86', testcase='cmake', presubmit=True), 383 CppDistribTest('windows', 384 'x86', 385 testcase='cmake_as_externalproject', 386 presubmit=True), 387 # C# 388 CSharpDistribTest('linux', 389 'x64', 390 'debian10', 391 use_dotnet_cli=True, 392 presubmit=True), 393 CSharpDistribTest('linux', 'x64', 'ubuntu1604', use_dotnet_cli=True), 394 CSharpDistribTest('linux', 395 'x64', 396 'alpine', 397 use_dotnet_cli=True, 398 presubmit=True), 399 CSharpDistribTest('linux', 400 'x64', 401 'dotnet31', 402 use_dotnet_cli=True, 403 presubmit=True), 404 CSharpDistribTest('linux', 405 'x64', 406 'dotnet5', 407 use_dotnet_cli=True, 408 presubmit=True), 409 CSharpDistribTest('macos', 'x64', use_dotnet_cli=True, presubmit=True), 410 CSharpDistribTest('windows', 'x86', presubmit=True), 411 CSharpDistribTest('windows', 'x64', presubmit=True), 412 # Python 413 PythonDistribTest('linux', 'x64', 'buster', presubmit=True), 414 PythonDistribTest('linux', 'x86', 'buster', presubmit=True), 415 PythonDistribTest('linux', 'x64', 'fedora34'), 416 PythonDistribTest('linux', 'x64', 'arch'), 417 PythonDistribTest('linux', 'x64', 'alpine'), 418 PythonDistribTest('linux', 'x64', 'ubuntu2004'), 419 PythonDistribTest('linux', 'aarch64', 'python38_buster', 420 presubmit=True), 421 PythonDistribTest('linux', 422 'x64', 423 'alpine3.7', 424 source=True, 425 presubmit=True), 426 PythonDistribTest('linux', 'x64', 'buster', source=True, 427 presubmit=True), 428 PythonDistribTest('linux', 'x86', 'buster', source=True, 429 presubmit=True), 430 PythonDistribTest('linux', 'x64', 'fedora34', source=True), 431 PythonDistribTest('linux', 'x64', 'arch', source=True), 432 PythonDistribTest('linux', 'x64', 'ubuntu2004', source=True), 433 # Ruby 434 RubyDistribTest('linux', 435 'x64', 436 'debian10', 437 ruby_version='ruby_2_6', 438 source=True, 439 presubmit=True), 440 RubyDistribTest('linux', 441 'x64', 442 'debian10', 443 ruby_version='ruby_2_7', 444 presubmit=True), 445 RubyDistribTest('linux', 'x64', 'centos7'), 446 RubyDistribTest('linux', 'x64', 'ubuntu1604'), 447 RubyDistribTest('linux', 'x64', 'ubuntu1804', presubmit=True), 448 # PHP7 449 PHP7DistribTest('linux', 'x64', 'debian10', presubmit=True), 450 PHP7DistribTest('macos', 'x64', presubmit=True), 451 ] 452