def test_valid_timeout(self): """All e2e jobs has 20min or more container timeout than kubetest timeout.""" bad_jobs = set() with open(config_sort.test_infra('jobs/config.json')) as fp: config = json.loads(fp.read()) for job in config: if config.get(job, {}).get('scenario') != 'kubernetes_e2e': continue realjob = self.get_real_bootstrap_job(job) self.assertTrue(realjob) self.assertIn('timeout', realjob, job) container_timeout = int(realjob['timeout']) kubetest_timeout = None for arg in config[job]['args']: mat = re.match(r'--timeout=(\d+)m', arg) if not mat: continue kubetest_timeout = int(mat.group(1)) if kubetest_timeout is None: self.fail('Missing timeout: %s' % job) if kubetest_timeout > container_timeout: bad_jobs.add((job, kubetest_timeout, container_timeout)) elif kubetest_timeout + 20 > container_timeout: bad_jobs.add(('insufficient kubetest leeway', job, kubetest_timeout, container_timeout)) if bad_jobs: self.fail( 'jobs: %s, ' 'prow timeout need to be at least 20min longer than timeout in config.json' % ('\n'.join(str(s) for s in bad_jobs)))
def test_valid_timeout(self): """All e2e jobs has 20min or more container timeout than kubetest timeout.""" bad_jobs = set() with open(config_sort.test_infra('jobs/config.json')) as fp: config = json.loads(fp.read()) for job in config: if config.get(job, {}).get('scenario') != 'kubernetes_e2e': continue realjob = self.get_real_bootstrap_job(job) self.assertTrue(realjob) self.assertIn('timeout', realjob, job) container_timeout = int(realjob['timeout']) kubetest_timeout = None for arg in config[job]['args']: mat = re.match(r'--timeout=(\d+)m', arg) if not mat: continue kubetest_timeout = int(mat.group(1)) if kubetest_timeout is None: self.fail('Missing timeout: %s' % job) if kubetest_timeout > container_timeout: bad_jobs.add((job, kubetest_timeout, container_timeout)) elif kubetest_timeout + 20 > container_timeout: bad_jobs.add(( 'insufficient kubetest leeway', job, kubetest_timeout, container_timeout )) if bad_jobs: self.fail( 'jobs: %s, ' 'prow timeout need to be at least 20min longer than timeout in config.json' % ('\n'.join(str(s) for s in bad_jobs)) )
def test_config_is_sorted(self): """Test jobs/config.json and prow/config.yaml are sorted.""" with open(config_sort.test_infra('jobs/config.json')) as fp: original = fp.read() expect = json.dumps(json.loads(original), sort_keys=True, indent=2, separators=(',', ': ')) + '\n' if original != expect: self.fail('jobs/config.json is not sorted, please run ' '`bazel run //jobs:config_sort`') with open(config_sort.test_infra('prow/config.yaml')) as fp: original = fp.read() expect = config_sort.sorted_prow_config().getvalue() if original != expect: self.fail('prow/config.yaml is not sorted, please run ' '`bazel run //jobs:config_sort`')
def jobs(self): """[(job, job_path)] sequence""" for path, _, filenames in os.walk(config_sort.test_infra('jobs')): print >>sys.stderr, path if 'e2e_node' in path: # Node e2e image configs, ignore them continue for job in [f for f in filenames if f not in self.excludes]: job_path = os.path.join(path, job) yield job, job_path
def jobs(self): """[(job, job_path)] sequence""" for path, _, filenames in os.walk(config_sort.test_infra('jobs')): print >> sys.stderr, path if 'e2e_node' in path: # Node e2e image configs, ignore them continue for job in [f for f in filenames if f not in self.excludes]: job_path = os.path.join(path, job) yield job, job_path
def test_config_is_sorted(self): """Test jobs/config.json and prow/config.yaml are sorted.""" with open(config_sort.test_infra('jobs/config.json')) as fp: original = fp.read() expect = json.dumps( json.loads(original), sort_keys=True, indent=2, separators=(',', ': ') ) + '\n' if original != expect: self.fail('jobs/config.json is not sorted, please run ' '`bazel run //jobs:config_sort`') with open(config_sort.test_infra('prow/config.yaml')) as fp: original = fp.read() expect = config_sort.sorted_prow_config().getvalue() if original != expect: self.fail('prow/config.yaml is not sorted, please run ' '`bazel run //jobs:config_sort`')
def test_config_is_sorted(self): """Test jobs/config.json, prow/config.yaml and boskos/resources.json are sorted.""" with open(config_sort.test_infra('jobs/config.json')) as fp: original = fp.read() expect = config_sort.sorted_job_config().getvalue() if original != expect: self.fail('jobs/config.json is not sorted, please run ' '`bazel run //jobs:config_sort`') with open(config_sort.test_infra('prow/config.yaml')) as fp: original = fp.read() expect = config_sort.sorted_prow_config().getvalue() if original != expect: self.fail('prow/config.yaml is not sorted, please run ' '`bazel run //jobs:config_sort`') with open(config_sort.test_infra('boskos/resources.json')) as fp: original = fp.read() expect = config_sort.sorted_boskos_config().getvalue() if original != expect: self.fail('boskos/resources.json is not sorted, please run ' '`bazel run //jobs:config_sort`')
def get_required_jobs(): required_jobs = set() configs_dir = config_sort.test_infra('mungegithub', 'submit-queue', 'deployment') for root, _, files in os.walk(configs_dir): for file_name in files: if file_name == 'configmap.yaml': path = os.path.join(root, file_name) with open(path) as fp: conf = yaml.safe_load(fp) for job in conf.get('required-retest-contexts', '').split(','): if job: required_jobs.add(job) return required_jobs
def load_bootstrap_yaml(self, path): with open(config_sort.test_infra(path)) as fp: doc = yaml.safe_load(fp) project = None defined_templates = set() for item in doc: if not isinstance(item, dict): continue if isinstance(item.get('job-template'), dict): defined_templates.add(item['job-template']['name']) self.check_job_template(item['job-template']) if not isinstance(item.get('project'), dict): continue project = item['project'] self.assertIn('bootstrap-', project.get('name')) break else: self.fail('Could not find bootstrap-pull-jobs project') self.assertIn('jobs', project) used_templates = {j for j in project['jobs']} msg = '\nMissing templates: %s\nUnused templates: %s' % ( ','.join(used_templates - defined_templates), ','.join(defined_templates - used_templates)) self.assertEquals(defined_templates, used_templates, msg) self.assertIn(path, self.yaml_suffix) jobs = project.get(self.yaml_suffix[path]) if not jobs or not isinstance(jobs, list): self.fail('Could not find suffix list in %s' % (project)) real_jobs = {} for job in jobs: # Things to check on all bootstrap jobs if not isinstance(job, dict): self.fail('suffix items should be dicts: %s' % jobs) self.assertEquals(1, len(job), job) name = job.keys()[0] real_job = job[name] self.assertNotIn(name, real_jobs, 'duplicate job: %s' % name) real_jobs[name] = real_job real_name = real_job.get('job-name', 'unset-%s' % name) if real_name not in self.realjobs: self.realjobs[real_name] = real_job return real_jobs
def test_all_project_are_unique(self): # pylint: disable=line-too-long allowed_list = { # The cos image validation jobs intentionally share projects. 'ci-kubernetes-e2e-gce-cosdev-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', # The ubuntu image validation jobs intentionally share projects. 'ci-kubernetes-e2enode-ubuntu1-k8sbeta-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sbeta-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable1-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable1-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable2-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable2-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable3-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable3-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sbeta-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sbeta-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sbeta-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable1-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable1-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable1-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable2-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable2-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable2-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable3-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable3-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable3-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2enode-ubuntu2-k8sbeta-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sbeta-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable1-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable1-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable2-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable2-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable3-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable3-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sbeta-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sbeta-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sbeta-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable1-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable1-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable1-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable2-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable2-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable2-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable3-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable3-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable3-slow': 'ci-kubernetes-e2e-gce-ubuntu*', # The release branch scalability jobs intentionally share projects. 'ci-kubernetes-e2e-gci-gce-scalability-stable2': 'ci-kubernetes-e2e-gci-gce-scalability-release-*', 'ci-kubernetes-e2e-gci-gce-scalability-stable1': 'ci-kubernetes-e2e-gci-gce-scalability-release-*', 'ci-kubernetes-e2e-gce-scalability': 'ci-kubernetes-e2e-gce-scalability-*', 'ci-kubernetes-e2e-gce-scalability-canary': 'ci-kubernetes-e2e-gce-scalability-*', # TODO(fejta): remove these (found while migrating jobs) 'ci-kubernetes-kubemark-100-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-prow-canary': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-100-canary': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-gce-last-release': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-high-density-100-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-gce-scale': 'ci-kubernetes-scale-*', 'pull-kubernetes-kubemark-e2e-gce-big': 'ci-kubernetes-scale-*', 'pull-kubernetes-kubemark-e2e-gce-scale': 'ci-kubernetes-scale-*', 'pull-kubernetes-e2e-gce-100-performance': 'ci-kubernetes-scale-*', 'pull-kubernetes-e2e-gce-big-performance': 'ci-kubernetes-scale-*', 'pull-kubernetes-e2e-gce-large-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-manual-up': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-manual-down': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-scale-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-scale-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-performance-regional': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-deploy': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-teardown': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-scale-correctness': 'ci-kubernetes-scale-*', 'pull-kubernetes-e2e-gce': 'pull-kubernetes-e2e-gce-*', 'pull-kubernetes-e2e-gce-canary': 'pull-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gce': 'ci-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gce-canary': 'ci-kubernetes-e2e-gce-*', 'ci-kubernetes-node-kubelet-serial': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-orphans': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-serial-cpu-manager': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-features': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-flaky': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-conformance': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-benchmark': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-stable1': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-stable2': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-stable3': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-alpha': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-beta': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-beta-features': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-non-cri-1-6': 'ci-kubernetes-node-kubelet-*', # The cri-containerd validation node e2e jobs intentionally share projects. 'ci-cri-containerd-node-e2e': 'cri-containerd-node-e2e-*', 'ci-cri-containerd-node-e2e-serial': 'cri-containerd-node-e2e-*', 'ci-cri-containerd-node-e2e-features': 'cri-containerd-node-e2e-*', 'ci-cri-containerd-node-e2e-flaky': 'cri-containerd-node-e2e-*', 'ci-cri-containerd-node-e2e-benchmark': 'cri-containerd-node-e2e-*', 'ci-containerd-node-e2e': 'cri-containerd-node-e2e-*', 'ci-containerd-node-e2e-1-1': 'cri-containerd-node-e2e-*', 'ci-containerd-node-e2e-features': 'cri-containerd-node-e2e-*', # ci-cri-containerd-e2e-gce-stackdriver intentionally share projects with # ci-kubernetes-e2e-gce-stackdriver. 'ci-kubernetes-e2e-gce-stackdriver': 'k8s-jkns-e2e-gce-stackdriver', 'ci-cri-containerd-e2e-gce-stackdriver': 'k8s-jkns-e2e-gce-stackdriver', # ingress-GCE e2e jobs 'pull-ingress-gce-e2e': 'e2e-ingress-gce', 'ci-ingress-gce-e2e': 'e2e-ingress-gce', # sig-autoscaling jobs intentionally share projetcs 'ci-kubernetes-e2e-gci-gce-autoscaling-hpa': 'ci-kubernetes-e2e-gci-gce-autoscaling', 'ci-kubernetes-e2e-gci-gce-autoscaling-migs-hpa': 'ci-kubernetes-e2e-gci-gce-autoscaling-migs', 'ci-kubernetes-e2e-gci-gke-autoscaling-hpa': 'ci-kubernetes-e2e-gci-gke-autoscaling', # gpu+autoscaling jobs intentionally share projects with gpu tests 'ci-kubernetes-e2e-gci-gke-autoscaling-gpu-v100': 'ci-kubernetes-e2e-gke-staging-latest-device-plugin-gpu-v100', } # pylint: enable=line-too-long projects = collections.defaultdict(set) boskos = [] with open(config_sort.test_infra('boskos/resources.yaml')) as fp: boskos_config = yaml.safe_load(fp) for rtype in boskos_config['resources']: if 'project' in rtype['type']: for name in rtype['names']: boskos.append(name) with open(config_sort.test_infra('jobs/config.json')) as fp: job_config = json.load(fp) for job in job_config: project = '' cfg = job_config.get(job.rsplit('.', 1)[0], {}) if cfg.get('scenario') == 'kubernetes_e2e': for arg in cfg.get('args', []): if not arg.startswith('--gcp-project='): continue project = arg.split('=', 1)[1] if project: if project in boskos: self.fail( 'Project %s cannot be in boskos/resources.yaml!' % project) projects[project].add(allowed_list.get(job, job)) duplicates = [(p, j) for p, j in projects.items() if len(j) > 1] if duplicates: self.fail('Jobs duplicate projects:\n %s' % ('\n '.join('%s: %s' % t for t in duplicates)))
def test_all_project_are_unique(self): # pylint: disable=line-too-long allowed_list = { # The cos image validation jobs intentionally share projects. 'ci-kubernetes-e2e-gce-cosdev-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-slow': 'ci-kubernetes-e2e-gce-cos*', # The ubuntu image validation jobs intentionally share projects. 'ci-kubernetes-e2e-gce-ubuntudev-k8sdev-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sdev-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sdev-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sbeta-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sbeta-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sbeta-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable1-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable1-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable1-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sdev-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sdev-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sdev-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable1-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable1-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable1-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable2-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable2-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable2-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-alphafeatures': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-autoscaling': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-default': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-flaky': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-ingress': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-reboot': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-serial': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-slow': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-updown': 'ci-kubernetes-e2e-gke-ubuntu*', # The 1.5 and 1.6 scalability jobs intentionally share projects. 'ci-kubernetes-e2e-gci-gce-scalability-release-1-7': 'ci-kubernetes-e2e-gci-gce-scalability-release-*', 'ci-kubernetes-e2e-gci-gce-scalability-stable1': 'ci-kubernetes-e2e-gci-gce-scalability-release-*', 'ci-kubernetes-e2e-gce-scalability': 'ci-kubernetes-e2e-gce-scalability-*', 'ci-kubernetes-e2e-gce-scalability-canary': 'ci-kubernetes-e2e-gce-scalability-*', # TODO(fejta): remove these (found while migrating jobs) 'ci-kubernetes-kubemark-100-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-gce-last-release': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-high-density-100-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-gce-scale': 'ci-kubernetes-scale-*', 'pull-kubernetes-kubemark-e2e-gce-big': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-manual-up': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-manual-down': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-scale-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-scale-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-deploy': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-teardown': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-scale-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-federation': 'ci-kubernetes-federation-*', 'pull-kubernetes-federation-e2e-gce': 'pull-kubernetes-federation-e2e-gce-*', 'ci-kubernetes-pull-gce-federation-deploy': 'pull-kubernetes-federation-e2e-gce-*', 'pull-kubernetes-federation-e2e-gce-canary': 'pull-kubernetes-federation-e2e-gce-*', 'pull-kubernetes-e2e-gce': 'pull-kubernetes-e2e-gce-*', 'pull-kubernetes-e2e-gce-canary': 'pull-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gce': 'ci-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gce-canary': 'ci-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gke-gpu': 'ci-kubernetes-e2e-gke-gpu-*', 'pull-kubernetes-e2e-gke-gpu': 'ci-kubernetes-e2e-gke-gpu-*', 'ci-kubernetes-node-kubelet-serial': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-flaky': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-conformance': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-benchmark': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet': 'ci-kubernetes-node-kubelet-*', } for soak_prefix in [ 'ci-kubernetes-soak-gce-1.5', 'ci-kubernetes-soak-gce-1-7', 'ci-kubernetes-soak-gce-1.6', 'ci-kubernetes-soak-gce-2', 'ci-kubernetes-soak-gce', 'ci-kubernetes-soak-gci-gce-1.5', 'ci-kubernetes-soak-gce-gci', 'ci-kubernetes-soak-gke-gci', 'ci-kubernetes-soak-gce-federation', 'ci-kubernetes-soak-gci-gce-stable1', 'ci-kubernetes-soak-gci-gce-1.6', 'ci-kubernetes-soak-gci-gce-1-7', 'ci-kubernetes-soak-cos-docker-validation', 'ci-kubernetes-soak-gke', ]: allowed_list['%s-deploy' % soak_prefix] = '%s-*' % soak_prefix allowed_list['%s-test' % soak_prefix] = '%s-*' % soak_prefix # pylint: enable=line-too-long projects = collections.defaultdict(set) boskos = [] with open(config_sort.test_infra('boskos/resources.json')) as fp: for rtype in json.loads(fp.read()): if 'project' in rtype['type']: for name in rtype['names']: boskos.append(name) with open(config_sort.test_infra('jobs/config.json')) as fp: job_config = json.load(fp) for job in job_config: project = '' cfg = job_config.get(job.rsplit('.', 1)[0], {}) if cfg.get('scenario') == 'kubernetes_e2e': for arg in cfg.get('args', []): if not arg.startswith('--gcp-project='): continue project = arg.split('=', 1)[1] if project: if project in boskos: self.fail('Project %s cannot be in boskos/resources.json!' % project) projects[project].add(allowed_list.get(job, job)) duplicates = [(p, j) for p, j in projects.items() if len(j) > 1] if duplicates: self.fail('Jobs duplicate projects:\n %s' % ( '\n '.join('%s: %s' % t for t in duplicates)))
def test_all_project_are_unique(self): # pylint: disable=line-too-long allowed_list = { # The cos image validation jobs intentionally share projects. 'ci-kubernetes-e2e-gce-cosdev-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', # The ubuntu image validation jobs intentionally share projects. 'ci-kubernetes-e2enode-ubuntu1-k8sbeta-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sbeta-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable1-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable1-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable2-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable2-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable3-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu1-k8sstable3-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sbeta-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sbeta-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sbeta-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable1-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable1-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable1-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable2-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable2-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable2-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable3-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable3-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu1-k8sstable3-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2enode-ubuntu2-k8sbeta-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sbeta-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable1-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable1-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable2-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable2-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable3-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntu2-k8sstable3-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sbeta-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sbeta-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sbeta-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable1-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable1-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable1-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable2-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable2-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable2-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable3-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable3-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntu2-k8sstable3-slow': 'ci-kubernetes-e2e-gce-ubuntu*', # The release branch scalability jobs intentionally share projects. 'ci-kubernetes-e2e-gci-gce-scalability-stable2': 'ci-kubernetes-e2e-gci-gce-scalability-release-*', 'ci-kubernetes-e2e-gci-gce-scalability-stable1': 'ci-kubernetes-e2e-gci-gce-scalability-release-*', 'ci-kubernetes-e2e-gce-scalability': 'ci-kubernetes-e2e-gce-scalability-*', 'ci-kubernetes-e2e-gce-scalability-canary': 'ci-kubernetes-e2e-gce-scalability-*', # TODO(fejta): remove these (found while migrating jobs) 'ci-kubernetes-kubemark-100-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-prow-canary': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-100-canary': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-gce-last-release': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-high-density-100-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-gce-scale': 'ci-kubernetes-scale-*', 'pull-kubernetes-kubemark-e2e-gce-big': 'ci-kubernetes-scale-*', 'pull-kubernetes-kubemark-e2e-gce-scale': 'ci-kubernetes-scale-*', 'pull-kubernetes-e2e-gce-100-performance': 'ci-kubernetes-scale-*', 'pull-kubernetes-e2e-gce-big-performance': 'ci-kubernetes-scale-*', 'pull-kubernetes-e2e-gce-large-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-manual-up': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-manual-down': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-scale-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-scale-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-performance-regional': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-deploy': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-teardown': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-scale-correctness': 'ci-kubernetes-scale-*', 'pull-kubernetes-e2e-gce': 'pull-kubernetes-e2e-gce-*', 'pull-kubernetes-e2e-gce-canary': 'pull-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gce': 'ci-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gce-canary': 'ci-kubernetes-e2e-gce-*', 'ci-kubernetes-node-kubelet-serial': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-serial-cpu-manager': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-flaky': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-conformance': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-benchmark': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-stable1': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-stable2': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-stable3': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-alpha': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-beta': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-non-cri-1-6': 'ci-kubernetes-node-kubelet-*', # The cri-containerd validation node e2e jobs intentionally share projects. 'ci-cri-containerd-node-e2e': 'cri-containerd-node-e2e-*', 'ci-cri-containerd-node-e2e-serial': 'cri-containerd-node-e2e-*', 'ci-cri-containerd-node-e2e-flaky': 'cri-containerd-node-e2e-*', 'ci-cri-containerd-node-e2e-benchmark': 'cri-containerd-node-e2e-*', 'ci-containerd-node-e2e': 'cri-containerd-node-e2e-*', # ci-cri-containerd-e2e-gce-stackdriver intentionally share projects with # ci-kubernetes-e2e-gce-stackdriver. 'ci-kubernetes-e2e-gce-stackdriver': 'k8s-jkns-e2e-gce-stackdriver', 'ci-cri-containerd-e2e-gce-stackdriver': 'k8s-jkns-e2e-gce-stackdriver', # ingress-GCE e2e jobs 'pull-ingress-gce-e2e': 'e2e-ingress-gce', 'ci-ingress-gce-e2e': 'e2e-ingress-gce', # sig-autoscaling jobs intentionally share projetcs 'ci-kubernetes-e2e-gci-gce-autoscaling-hpa':'ci-kubernetes-e2e-gci-gce-autoscaling', 'ci-kubernetes-e2e-gci-gce-autoscaling-migs-hpa':'ci-kubernetes-e2e-gci-gce-autoscaling-migs', 'ci-kubernetes-e2e-gci-gke-autoscaling-hpa':'ci-kubernetes-e2e-gci-gke-autoscaling', # kubemark presubmits 'pull-kubernetes-kubemark-e2e-gce-canary':'k8s-jkns-pr-kubemark', 'pull-kubernetes-kubemark-e2e-gce':'k8s-jkns-pr-kubemark', } # pylint: enable=line-too-long projects = collections.defaultdict(set) boskos = [] with open(config_sort.test_infra('boskos/resources.yaml')) as fp: boskos_config = yaml.safe_load(fp) for rtype in boskos_config['resources']: if 'project' in rtype['type']: for name in rtype['names']: boskos.append(name) with open(config_sort.test_infra('jobs/config.json')) as fp: job_config = json.load(fp) for job in job_config: project = '' cfg = job_config.get(job.rsplit('.', 1)[0], {}) if cfg.get('scenario') == 'kubernetes_e2e': for arg in cfg.get('args', []): if not arg.startswith('--gcp-project='): continue project = arg.split('=', 1)[1] if project: if project in boskos: self.fail('Project %s cannot be in boskos/resources.yaml!' % project) projects[project].add(allowed_list.get(job, job)) duplicates = [(p, j) for p, j in projects.items() if len(j) > 1] if duplicates: self.fail('Jobs duplicate projects:\n %s' % ( '\n '.join('%s: %s' % t for t in duplicates)))
def test_valid_job_config_json(self): """Validate jobs/config.json.""" # bootstrap integration test scripts ignore = [ 'fake-failure', 'fake-branch', 'fake-pr', 'random_job', ] self.load_prow_yaml(self.prow_config) config = config_sort.test_infra('jobs/config.json') owners = config_sort.test_infra('jobs/validOwners.json') with open(config) as fp, open(owners) as ownfp: config = json.loads(fp.read()) valid_owners = json.loads(ownfp.read()) for job in config: if job not in ignore: self.assertTrue( job in self.prowjobs or job in self.realjobs, '%s must have a matching jenkins/prow entry' % job) # ownership assertions self.assertIn('sigOwners', config[job], job) self.assertIsInstance(config[job]['sigOwners'], list, job) self.assertTrue(config[job]['sigOwners'], job) # non-empty owners = config[job]['sigOwners'] for owner in owners: self.assertIsInstance(owner, basestring, job) self.assertIn(owner, valid_owners, job) # env assertions self.assertTrue('scenario' in config[job], job) scenario = config_sort.test_infra('scenarios/%s.py' % config[job]['scenario']) self.assertTrue(os.path.isfile(scenario), job) self.assertTrue(os.access(scenario, os.X_OK | os.R_OK), job) args = config[job].get('args', []) use_shared_build_in_args = False extract_in_args = False build_in_args = False for arg in args: if arg.startswith('--use-shared-build'): use_shared_build_in_args = True elif arg.startswith('--build'): build_in_args = True elif arg.startswith('--extract'): extract_in_args = True match = re.match(r'--env-file=([^\"]+)\.env', arg) if match: env_path = match.group(1) self.assertTrue(env_path.startswith('jobs/'), env_path) path = config_sort.test_infra('%s.env' % env_path) self.assertTrue( os.path.isfile(path), '%s does not exist for %s' % (path, job)) elif 'kops' not in job: match = re.match(r'--cluster=([^\"]+)', arg) if match: cluster = match.group(1) self.assertLessEqual( len(cluster), 23, 'Job %r, --cluster should be 23 chars or fewer' % job) # these args should not be combined: # --use-shared-build and (--build or --extract) self.assertFalse(use_shared_build_in_args and build_in_args) self.assertFalse(use_shared_build_in_args and extract_in_args) if config[job]['scenario'] == 'kubernetes_e2e': if job in self.prowjobs: for arg in args: # --mode=local is default now self.assertNotIn('--mode', arg, job) else: self.assertIn('--mode=docker', args, job) for arg in args: if "--env=" in arg: self._check_env(job, arg.split("=", 1)[1]) if '--provider=gke' in args: self.assertTrue('--deployment=gke' in args, '%s must use --deployment=gke' % job) self.assertFalse( any('--gcp-master-image' in a for a in args), '%s cannot use --gcp-master-image on GKE' % job) self.assertFalse( any('--gcp-nodes' in a for a in args), '%s cannot use --gcp-nodes on GKE' % job) if '--deployment=gke' in args: self.assertTrue( any('--gcp-node-image' in a for a in args), job) self.assertNotIn('--charts-tests', args) # Use --charts if any('--check_version_skew' in a for a in args): self.fail( 'Use --check-version-skew, not --check_version_skew in %s' % job) if '--check-leaked-resources=true' in args: self.fail( 'Use --check-leaked-resources (no value) in %s' % job) if '--check-leaked-resources==false' in args: self.fail( 'Remove --check-leaked-resources=false (default value) from %s' % job) if ('--env-file=jobs/pull-kubernetes-e2e.env' in args and '--check-leaked-resources' in args): self.fail( 'PR job %s should not check for resource leaks' % job) # Consider deleting any job with --check-leaked-resources=false if ('--provider=gce' not in args and '--provider=gke' not in args and '--check-leaked-resources' in args and 'generated' not in config[job].get('tags', [])): self.fail( 'Only GCP jobs can --check-leaked-resources, not %s' % job) if '--mode=local' in args: self.fail( '--mode=local is default now, drop that for %s' % job) extracts = [a for a in args if '--extract=' in a] shared_builds = [ a for a in args if '--use-shared-build' in a ] node_e2e = [a for a in args if '--deployment=node' in a] local_e2e = [a for a in args if '--deployment=local' in a] builds = [a for a in args if '--build' in a] if shared_builds and extracts: self.fail(('e2e jobs cannot have --use-shared-build' ' and --extract: %s %s') % (job, args)) elif not extracts and not shared_builds and not node_e2e: # we should at least have --build and --stage if not builds: self.fail(('e2e job needs --extract or' ' --use-shared-build or' ' --build: %s %s') % (job, args)) if shared_builds or node_e2e: expected = 0 elif builds and not extracts: expected = 0 elif 'ingress' in job: expected = 1 elif any(s in job for s in [ 'upgrade', 'skew', 'downgrade', 'rollback', 'ci-kubernetes-e2e-gce-canary', ]): expected = 2 else: expected = 1 if len(extracts) != expected: self.fail( 'Wrong number of --extract args (%d != %d) in %s' % (len(extracts), expected, job)) has_image_family = any( [x for x in args if x.startswith('--image-family')]) has_image_project = any( [x for x in args if x.startswith('--image-project')]) docker_mode = any( [x for x in args if x.startswith('--mode=docker')]) if ((has_image_family or has_image_project) and docker_mode): self.fail('--image-family / --image-project is not ' 'supported in docker mode: %s' % job) if has_image_family != has_image_project: self.fail('--image-family and --image-project must be' 'both set or unset: %s' % job) if job.startswith('pull-kubernetes-' ) and not node_e2e and not local_e2e: if 'gke' in job: stage = 'gs://kubernetes-release-dev/ci' suffix = True elif 'kubeadm' in job: # kubeadm-based jobs use out-of-band .deb artifacts, # not the --stage flag. continue else: stage = 'gs://kubernetes-release-pull/ci/%s' % job suffix = False if not shared_builds: self.assertIn('--stage=%s' % stage, args) self.assertEquals( suffix, any('--stage-suffix=' in a for a in args), ('--stage-suffix=', suffix, job, args))
def test_all_project_are_unique(self): # pylint: disable=line-too-long allowed_list = { # The cos image validation jobs intentionally share projects. 'ci-kubernetes-e2e-gce-cosdev-k8sdev-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sdev-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sdev-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-slow.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-default.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-serial.env': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-slow.env': 'ci-kubernetes-e2e-gce-cos*', # The ubuntu image validation jobs intentionally share projects. 'ci-kubernetes-e2e-gce-ubuntudev-k8sdev-default.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sdev-serial.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sdev-slow.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sbeta-default.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sbeta-serial.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sbeta-slow.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable1-default.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable1-serial.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable1-slow.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sdev-default.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sdev-serial.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sdev-slow.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable1-default.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable1-serial.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable1-slow.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable2-default.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable2-serial.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable2-slow.env': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-alphafeatures.env': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-autoscaling.env': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-default.env': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-flaky.env': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-ingress.env': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-reboot.env': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-serial.env': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-slow.env': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-updown.env': 'ci-kubernetes-e2e-gke-ubuntu*', # The 1.5 and 1.6 scalability jobs intentionally share projects. 'ci-kubernetes-e2e-gci-gce-scalability-release-1-7.env': 'ci-kubernetes-e2e-gci-gce-scalability-release-*', 'ci-kubernetes-e2e-gci-gce-scalability-stable1.env': 'ci-kubernetes-e2e-gci-gce-scalability-release-*', 'ci-kubernetes-e2e-gce-scalability.env': 'ci-kubernetes-e2e-gce-scalability-*', 'ci-kubernetes-e2e-gce-scalability-canary.env': 'ci-kubernetes-e2e-gce-scalability-*', # TODO(fejta): remove these (found while migrating jobs) 'ci-kubernetes-kubemark-100-gce.env': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-gce.env': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-high-density-100-gce.env': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-gce-scale.env': 'ci-kubernetes-scale-*', 'pull-kubernetes-kubemark-e2e-gce-big.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-manual-up.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-manual-down.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-correctness.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-performance.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-scale-correctness.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-scale-performance.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-correctness.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-performance.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-deploy.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-teardown.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-scale-correctness.env': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-federation.env': 'ci-kubernetes-federation-*', 'pull-kubernetes-federation-e2e-gce.env': 'pull-kubernetes-federation-e2e-gce-*', 'ci-kubernetes-pull-gce-federation-deploy.env': 'pull-kubernetes-federation-e2e-gce-*', 'pull-kubernetes-federation-e2e-gce-canary.env': 'pull-kubernetes-federation-e2e-gce-*', 'ci-kubernetes-pull-gce-federation-deploy-canary.env': 'pull-kubernetes-federation-e2e-gce-*', 'pull-kubernetes-e2e-gce.env': 'pull-kubernetes-e2e-gce-*', 'pull-kubernetes-e2e-gce-canary.env': 'pull-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gce.env': 'ci-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gce-canary.env': 'ci-kubernetes-e2e-gce-*', } for soak_prefix in [ 'ci-kubernetes-soak-gce-1.5', 'ci-kubernetes-soak-gce-1-7', 'ci-kubernetes-soak-gce-1.6', 'ci-kubernetes-soak-gce-2', 'ci-kubernetes-soak-gce', 'ci-kubernetes-soak-gci-gce-1.5', 'ci-kubernetes-soak-gce-gci', 'ci-kubernetes-soak-gke-gci', 'ci-kubernetes-soak-gce-federation', 'ci-kubernetes-soak-gci-gce-stable1', 'ci-kubernetes-soak-gci-gce-1.6', 'ci-kubernetes-soak-gci-gce-1-7', 'ci-kubernetes-soak-cos-docker-validation', 'ci-kubernetes-soak-gke', ]: allowed_list['%s-deploy.env' % soak_prefix] = '%s-*' % soak_prefix allowed_list['%s-test.env' % soak_prefix] = '%s-*' % soak_prefix # pylint: enable=line-too-long projects = collections.defaultdict(set) boskos = [] with open(config_sort.test_infra('boskos/resources.json')) as fp: for rtype in json.loads(fp.read()): if rtype['type'] == 'gce-project' or rtype['type'] == 'gke-project': for name in rtype['names']: boskos.append(name) with open(config_sort.test_infra('jobs/config.json')) as fp: job_config = json.load(fp) for job, job_path in self.jobs: with open(job_path) as fp: lines = list(fp) project = '' for line in lines: line = line.strip() if not line.startswith('PROJECT='): continue if '-soak-' in job: # Soak jobs have deploy/test pairs job = job.replace('-test', '-*').replace('-deploy', '-*') if job.startswith('ci-kubernetes-node-'): job = 'ci-kubernetes-node-*' if not line.startswith('#') and job.endswith('.sh'): self.assertIn('export', line, line) if job.endswith('.sh'): project = re.search(r'PROJECT="([^"]+)"', line).group(1) else: project = re.search(r'PROJECT=([^"]+)', line).group(1) if project in boskos: self.fail('Project %s cannot be in boskos/resources.json!' % project) cfg = job_config.get(job.rsplit('.', 1)[0], {}) if not project and cfg.get('scenario') == 'kubernetes_e2e': for arg in cfg.get('args', []): if not arg.startswith('--gcp-project='): continue project = arg.split('=', 1)[1] if project: projects[project].add(allowed_list.get(job, job)) duplicates = [(p, j) for p, j in projects.items() if len(j) > 1] if duplicates: self.fail('Jobs duplicate projects:\n %s' % ( '\n '.join('%s: %s' % t for t in duplicates)))
def test_valid_timeout(self): """All jobs set a timeout less than 120m or set DOCKER_TIMEOUT.""" default_timeout = 60 bad_jobs = set() with open(config_sort.test_infra('jobs/config.json')) as fp: config = json.loads(fp.read()) for job, job_path in self.jobs: job_name = job.rsplit('.', 1)[0] modern = config.get(job_name, {}).get('scenario') in [ 'kubernetes_e2e', 'kubernetes_kops_aws', ] valids = [ 'kubernetes-e2e-', 'kubernetes-kubemark-', 'kubernetes-soak-', 'kubernetes-federation-e2e-', 'kops-e2e-', ] if not re.search('|'.join(valids), job): continue with open(job_path) as fp: lines = list(l for l in fp if not l.startswith('#')) container_timeout = default_timeout kubetest_timeout = None for line in lines: # Validate old pattern no longer used if line.startswith('### Reporting'): bad_jobs.add(job) if '{rc}' in line: bad_jobs.add(job) self.assertFalse(job.endswith('.sh'), job) self.assertTrue(modern, job) realjob = self.get_real_bootstrap_job(job) self.assertTrue(realjob) self.assertIn('timeout', realjob, job) container_timeout = int(realjob['timeout']) for line in lines: if 'DOCKER_TIMEOUT=' in line: self.fail('Set container timeout in prow and/or bootstrap yaml: %s' % job) if 'KUBEKINS_TIMEOUT=' in line: self.fail( 'Set kubetest --timeout in config.json, not KUBEKINS_TIMEOUT: %s' % job ) for arg in config[job_name]['args']: if arg == '--timeout=None': bad_jobs.add(('Must specify a timeout', job, arg)) mat = re.match(r'--timeout=(\d+)m', arg) if not mat: continue kubetest_timeout = int(mat.group(1)) if kubetest_timeout is None: self.fail('Missing timeout: %s' % job) if kubetest_timeout > container_timeout: bad_jobs.add((job, kubetest_timeout, container_timeout)) elif kubetest_timeout + 20 > container_timeout: bad_jobs.add(( 'insufficient kubetest leeway', job, kubetest_timeout, container_timeout )) if bad_jobs: self.fail( 'jobs: %s, ' 'prow timeout need to be at least 20min longer than timeout in config.json' % ('\n'.join(str(s) for s in bad_jobs)) )
def jobs(self): """[(job, job_path)] sequence""" for path, _, filenames in os.walk(config_sort.test_infra('jobs')): for job in [f for f in filenames if f not in self.excludes]: job_path = os.path.join(path, job) yield job, job_path
def test_valid_timeout(self): """All jobs set a timeout less than 120m or set DOCKER_TIMEOUT.""" default_timeout = 60 bad_jobs = set() with open(config_sort.test_infra('jobs/config.json')) as fp: config = json.loads(fp.read()) for job, job_path in self.jobs: job_name = job.rsplit('.', 1)[0] modern = config.get(job_name, {}).get('scenario') in [ 'kubernetes_e2e', 'kubernetes_kops_aws', ] valids = [ 'kubernetes-e2e-', 'kubernetes-kubemark-', 'kubernetes-soak-', 'kubernetes-federation-e2e-', 'kops-e2e-', ] if not re.search('|'.join(valids), job): continue with open(job_path) as fp: lines = list(l for l in fp if not l.startswith('#')) container_timeout = default_timeout kubetest_timeout = None for line in lines: # Validate old pattern no longer used if line.startswith('### Reporting'): bad_jobs.add(job) if '{rc}' in line: bad_jobs.add(job) self.assertFalse(job.endswith('.sh'), job) self.assertTrue(modern, job) realjob = self.get_real_bootstrap_job(job) self.assertTrue(realjob) self.assertIn('timeout', realjob, job) container_timeout = int(realjob['timeout']) for line in lines: if 'DOCKER_TIMEOUT=' in line: self.fail('Set container timeout in prow and/or bootstrap yaml: %s' % job) if 'KUBEKINS_TIMEOUT=' in line: self.fail( 'Set kubetest --timeout in config.json, not KUBEKINS_TIMEOUT: %s' % job ) for arg in config[job_name]['args']: if arg == '--timeout=None': bad_jobs.add(('Must specify a timeout', job, arg)) mat = re.match(r'--timeout=(\d+)m', arg) if not mat: continue kubetest_timeout = int(mat.group(1)) if kubetest_timeout is None: self.fail('Missing timeout: %s' % job) if kubetest_timeout > container_timeout: bad_jobs.add((job, kubetest_timeout, container_timeout)) elif kubetest_timeout + 20 > container_timeout: bad_jobs.add(( 'insufficient kubetest leeway', job, kubetest_timeout, container_timeout )) if bad_jobs: self.fail('\n'.join(str(s) for s in bad_jobs))
def test_valid_job_config_json(self): """Validate jobs/config.json.""" # bootstrap integration test scripts ignore = [ 'fake-failure', 'fake-branch', 'fake-pr', 'random_job', ] self.load_prow_yaml(self.prow_config) config = config_sort.test_infra('jobs/config.json') owners = config_sort.test_infra('jobs/validOwners.json') with open(config) as fp, open(owners) as ownfp: config = json.loads(fp.read()) valid_owners = json.loads(ownfp.read()) for job in config: if job not in ignore: self.assertTrue(job in self.prowjobs or job in self.realjobs, '%s must have a matching jenkins/prow entry' % job) # onwership assertions self.assertIn('sigOwners', config[job], job) self.assertIsInstance(config[job]['sigOwners'], list, job) self.assertTrue(config[job]['sigOwners'], job) # non-empty owners = config[job]['sigOwners'] for owner in owners: self.assertIsInstance(owner, basestring, job) self.assertIn(owner, valid_owners, job) # env assertions self.assertTrue('scenario' in config[job], job) scenario = config_sort.test_infra('scenarios/%s.py' % config[job]['scenario']) self.assertTrue(os.path.isfile(scenario), job) self.assertTrue(os.access(scenario, os.X_OK|os.R_OK), job) args = config[job].get('args', []) use_shared_build_in_args = False extract_in_args = False build_in_args = False for arg in args: if arg.startswith('--use-shared-build'): use_shared_build_in_args = True elif arg.startswith('--build'): build_in_args = True elif arg.startswith('--extract'): extract_in_args = True match = re.match(r'--env-file=([^\"]+)\.env', arg) if match: env_path = match.group(1) self.assertTrue(env_path.startswith('jobs/'), env_path) path = config_sort.test_infra('%s.env' % env_path) self.assertTrue( os.path.isfile(path), '%s does not exist for %s' % (path, job)) elif 'kops' not in job: match = re.match(r'--cluster=([^\"]+)', arg) if match: cluster = match.group(1) self.assertLessEqual( len(cluster), 20, 'Job %r, --cluster should be 20 chars or fewer' % job ) # these args should not be combined: # --use-shared-build and (--build or --extract) self.assertFalse(use_shared_build_in_args and build_in_args) self.assertFalse(use_shared_build_in_args and extract_in_args) if config[job]['scenario'] == 'kubernetes_e2e': if job in self.prowjobs: for arg in args: # --mode=local is default now self.assertNotIn('--mode', arg, job) else: self.assertIn('--mode=docker', args, job) for arg in args: if "--env=" in arg: self._check_env(job, arg.split("=", 1)[1]) if '--provider=gke' in args: self.assertTrue('--deployment=gke' in args, '%s must use --deployment=gke' % job) self.assertFalse(any('--gcp-master-image' in a for a in args), '%s cannot use --gcp-master-image on GKE' % job) self.assertFalse(any('--gcp-nodes' in a for a in args), '%s cannot use --gcp-nodes on GKE' % job) if '--deployment=gke' in args: self.assertTrue(any('--gcp-node-image' in a for a in args), job) self.assertNotIn('--charts-tests', args) # Use --charts if any('--check_version_skew' in a for a in args): self.fail('Use --check-version-skew, not --check_version_skew in %s' % job) if '--check-leaked-resources=true' in args: self.fail('Use --check-leaked-resources (no value) in %s' % job) if '--check-leaked-resources==false' in args: self.fail( 'Remove --check-leaked-resources=false (default value) from %s' % job) if ( '--env-file=jobs/pull-kubernetes-e2e.env' in args and '--check-leaked-resources' in args): self.fail('PR job %s should not check for resource leaks' % job) # Consider deleting any job with --check-leaked-resources=false if ( '--provider=gce' not in args and '--provider=gke' not in args and '--check-leaked-resources' in args and 'generated' not in config[job].get('tags', [])): self.fail('Only GCP jobs can --check-leaked-resources, not %s' % job) if '--mode=local' in args: self.fail('--mode=local is default now, drop that for %s' % job) extracts = [a for a in args if '--extract=' in a] shared_builds = [a for a in args if '--use-shared-build' in a] node_e2e = [a for a in args if '--deployment=node' in a] pull = job.startswith('pull-') if shared_builds and extracts: self.fail(('e2e jobs cannot have --use-shared-build' ' and --extract: %s %s') % (job, args)) elif not extracts and not shared_builds and not node_e2e: self.fail(('e2e job needs --extract or' ' --use-shared-build: %s %s') % (job, args)) if shared_builds or node_e2e and not pull: expected = 0 elif any(s in job for s in [ 'upgrade', 'skew', 'downgrade', 'rollback', 'ci-kubernetes-e2e-gce-canary', ]): expected = 2 else: expected = 1 if len(extracts) != expected: self.fail('Wrong number of --extract args (%d != %d) in %s' % ( len(extracts), expected, job)) has_image_family = any( [x for x in args if x.startswith('--image-family')]) has_image_project = any( [x for x in args if x.startswith('--image-project')]) docker_mode = any( [x for x in args if x.startswith('--mode=docker')]) if ( (has_image_family or has_image_project) and docker_mode): self.fail('--image-family / --image-project is not ' 'supported in docker mode: %s' % job) if has_image_family != has_image_project: self.fail('--image-family and --image-project must be' 'both set or unset: %s' % job) if job.startswith('pull-kubernetes-'): self.assertIn('--cluster=', args) if 'gke' in job: stage = 'gs://kubernetes-release-dev/ci' suffix = True elif 'kubeadm' in job: # kubeadm-based jobs use out-of-band .deb artifacts, # not the --stage flag. continue else: stage = 'gs://kubernetes-release-pull/ci/%s' % job suffix = False if not shared_builds: self.assertIn('--stage=%s' % stage, args) self.assertEquals( suffix, any('--stage-suffix=' in a for a in args), ('--stage-suffix=', suffix, job, args))
def test_all_project_are_unique(self): # pylint: disable=line-too-long allowed_list = { # The cos image validation jobs intentionally share projects. 'ci-kubernetes-e2e-gce-cosdev-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosdev-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable2-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosbeta-k8sstable3-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sdev-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sbeta-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable1-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable2-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2e-gce-cosstable1-k8sstable3-slow': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sdev-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sdev-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sbeta-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sbeta-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable1-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable1-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable2-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable2-serial': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable3-default': 'ci-kubernetes-e2e-gce-cos*', 'ci-kubernetes-e2enode-cosbeta-k8sstable3-serial': 'ci-kubernetes-e2e-gce-cos*', # The ubuntu image validation jobs intentionally share projects. 'ci-kubernetes-e2e-gce-ubuntudev-k8sdev-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sdev-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sdev-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sbeta-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sbeta-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sbeta-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable1-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable1-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable1-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable2-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable2-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev-k8sstable2-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev2-k8sdev-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev2-k8sdev-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev2-k8sdev-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev2-k8sbeta-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev2-k8sbeta-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntudev2-k8sbeta-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sdev-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sdev-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sdev-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable1-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable1-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable1-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable2-default': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable2-serial': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gce-ubuntustable1-k8sstable2-slow': 'ci-kubernetes-e2e-gce-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-alphafeatures': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-autoscaling': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-default': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-flaky': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-ingress': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-reboot': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-serial': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-slow': 'ci-kubernetes-e2e-gke-ubuntu*', 'ci-kubernetes-e2e-gke-ubuntustable1-k8sstable1-updown': 'ci-kubernetes-e2e-gke-ubuntu*', # ubuntu node image tests share the same ubuntu project 'ci-kubernetes-e2e-gce-ubuntu-1-6-node': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2e-gce-ubuntu-1-7-node': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2e-gce-ubuntu-node': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2e-gce-ubuntu-1-6-node-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2e-gce-ubuntu-1-7-node-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2e-gce-ubuntu-node-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntustable1-k8sdev-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntudev-k8sstable1-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntudev-k8sstable2-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntudev2-k8sdev-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntudev2-k8sdev-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntudev2-k8sbeta-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntudev2-k8sbeta-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntustable1-k8sstable1-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntudev-k8sstable2-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntudev-k8sdev-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntustable1-k8sstable2-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntudev-k8sdev-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntustable1-k8sstable2-gkespec': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntustable1-k8sdev-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntustable1-k8sstable1-serial': 'ci-kubernetes-e2e-ubuntu-node*', 'ci-kubernetes-e2enode-ubuntudev-k8sstable1-serial': 'ci-kubernetes-e2e-ubuntu-node*', # The 1.5 and 1.6 scalability jobs intentionally share projects. 'ci-kubernetes-e2e-gci-gce-scalability-release-1-7': 'ci-kubernetes-e2e-gci-gce-scalability-release-*', 'ci-kubernetes-e2e-gci-gce-scalability-stable1': 'ci-kubernetes-e2e-gci-gce-scalability-release-*', 'ci-kubernetes-e2e-gce-scalability': 'ci-kubernetes-e2e-gce-scalability-*', 'ci-kubernetes-e2e-gce-scalability-canary': 'ci-kubernetes-e2e-gce-scalability-*', # TODO(fejta): remove these (found while migrating jobs) 'ci-kubernetes-kubemark-100-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-prow-canary': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-100-canary': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-5-gce-last-release': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-high-density-100-gce': 'ci-kubernetes-kubemark-*', 'ci-kubernetes-kubemark-gce-scale': 'ci-kubernetes-scale-*', 'pull-kubernetes-kubemark-e2e-gce-big': 'ci-kubernetes-scale-*', 'pull-kubernetes-kubemark-e2e-gce-scale': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-manual-up': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-manual-down': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-large-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-scale-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gce-scale-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-correctness': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-performance': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-deploy': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-large-teardown': 'ci-kubernetes-scale-*', 'ci-kubernetes-e2e-gke-scale-correctness': 'ci-kubernetes-scale-*', 'pull-kubernetes-e2e-gce': 'pull-kubernetes-e2e-gce-*', 'pull-kubernetes-e2e-gce-canary': 'pull-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gce': 'ci-kubernetes-e2e-gce-*', 'ci-kubernetes-e2e-gce-canary': 'ci-kubernetes-e2e-gce-*', 'ci-kubernetes-node-kubelet-serial': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-serial-cpu-manager': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-flaky': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-conformance': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-benchmark': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-stable1': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-stable2': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-stable3': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-beta': 'ci-kubernetes-node-kubelet-*', 'ci-kubernetes-node-kubelet-non-cri-1-6': 'ci-kubernetes-node-kubelet-*', # The cri-containerd validation node e2e jobs intentionally share projects. 'ci-cri-containerd-node-e2e': 'cri-containerd-node-e2e-*', 'ci-cri-containerd-node-e2e-serial': 'cri-containerd-node-e2e-*', 'ci-cri-containerd-node-e2e-flaky': 'cri-containerd-node-e2e-*', 'ci-cri-containerd-node-e2e-benchmark': 'cri-containerd-node-e2e-*', # ci-cri-containerd-e2e-gce-stackdriver intentionally share projects with # ci-kubernetes-e2e-gce-stackdriver. 'ci-kubernetes-e2e-gce-stackdriver': 'k8s-jkns-e2e-gce-stackdriver', 'ci-cri-containerd-e2e-gce-stackdriver': 'k8s-jkns-e2e-gce-stackdriver', # ingress-GCE e2e jobs 'pull-ingress-gce-e2e': 'e2e-ingress-gce', 'ci-ingress-gce-e2e': 'e2e-ingress-gce', } for soak_prefix in [ 'ci-kubernetes-soak-gce-1.5', 'ci-kubernetes-soak-gce-1-7', 'ci-kubernetes-soak-gce-1.6', 'ci-kubernetes-soak-gce-2', 'ci-kubernetes-soak-gce', 'ci-kubernetes-soak-gci-gce-1.5', 'ci-kubernetes-soak-gce-gci', 'ci-kubernetes-soak-gke-gci', 'ci-kubernetes-soak-gci-gce-stable1', 'ci-kubernetes-soak-gci-gce-1.6', 'ci-kubernetes-soak-gci-gce-1-7', 'ci-kubernetes-soak-cos-docker-validation', 'ci-kubernetes-soak-gke', ]: allowed_list['%s-deploy' % soak_prefix] = '%s-*' % soak_prefix allowed_list['%s-test' % soak_prefix] = '%s-*' % soak_prefix # pylint: enable=line-too-long projects = collections.defaultdict(set) boskos = [] with open(config_sort.test_infra('boskos/resources.json')) as fp: for rtype in json.loads(fp.read()): if 'project' in rtype['type']: for name in rtype['names']: boskos.append(name) with open(config_sort.test_infra('jobs/config.json')) as fp: job_config = json.load(fp) for job in job_config: project = '' cfg = job_config.get(job.rsplit('.', 1)[0], {}) if cfg.get('scenario') == 'kubernetes_e2e': for arg in cfg.get('args', []): if not arg.startswith('--gcp-project='): continue project = arg.split('=', 1)[1] if project: if project in boskos: self.fail('Project %s cannot be in boskos/resources.json!' % project) projects[project].add(allowed_list.get(job, job)) duplicates = [(p, j) for p, j in projects.items() if len(j) > 1] if duplicates: self.fail('Jobs duplicate projects:\n %s' % ( '\n '.join('%s: %s' % t for t in duplicates)))