什么的仪式| 晚上吃什么容易减肥| 1月25日是什么星座| 爱的本质是什么| 猫叫是什么原因| 吃茄子有什么好处和坏处| 蒙古族的那达慕大会是在什么时候| 为什么身体没力气也没有精神| 子宫肌瘤吃什么药| 刮腻子是什么意思| 名创优品是卖什么的| 服役是什么意思| 指甲凹陷是什么原因引起的| 三角巾是什么| 南宁有什么好吃的| 陪产假什么时候开始休| 腿胖是什么原因引起的| 1941属什么生肖| 11.16是什么星座| 空调外机为什么会滴水| ga是什么激素| 病理是什么意思| 爷爷的妹妹叫什么| 猪砂是什么东西| 是什么标点符号| 钼靶是什么检查| 看病人带什么水果| 初伏是什么意思| 出痧是什么原因| 早上五点半是什么时辰| 黄酒是什么酒| 托腮是什么意思| 坐东朝西是什么意思| 眼睛跳是什么原因| 玉米炒什么好吃| 什么泡茶好喝| 5月20日是什么日子| 宫颈光滑说明什么| 口臭看什么科| 凉拌菜用什么醋最好| 安宫牛黄丸什么时候吃最好| 祸从口出什么意思| 人体最大器官是什么| 大放厥词是什么意思| 神话故事有什么| 急性荨麻疹不能吃什么食物| 菊花是什么意思| 牙龈肿痛发炎吃什么药| 什么是叶酸| 男扮女装是什么意思| 肝囊肿是什么原因引起的| 属虎男和什么属相最配| 国家的实质是什么| 经常感冒的人吃什么能增强抵抗力| 6克血是什么概念| 恶心头晕是什么症状| 孩子为什么厌学| 陶渊明字什么| 8月出生的是什么星座| 为什么上小厕会有刺痛感| 什么是生僻字| 乞丐是什么生肖| 五月二十四是什么星座| 梦见自己又结婚了是什么意思| 眼镜框什么材质的好| 鱼香肉丝用什么肉做| 吃南瓜有什么好处| 羔羊是什么意思| 间质性肺炎是什么意思| l1椎体在什么位置| 小孩掉头发是什么原因| 66岁生日有什么讲究| 单侧耳鸣是什么原因引起的| 不打紧是什么意思| 奇美拉是什么| 房颤是什么病| 平肝什么意思| 羊绒和羊毛有什么区别| 什么是c字裤| 感冒发烧吃什么水果好| 月柱华盖是什么意思| 牙疼可以吃什么| 气血不足吃什么好食补| ozark是什么牌子| 美妞是什么意思| samsonite什么牌子| amh是什么| vpc是什么| afar是什么意思| 6月25号是什么星座| 老放屁吃什么药好| 膀胱炎什么症状| 枸杞泡水喝有什么作用和功效| 经常肚子痛什么原因| 百思不得其解是什么意思| 送人梳子的寓意是什么| 儿女情长是什么意思| 人得猫癣用什么药| 为什么耳屎是湿的| 美国为什么打伊拉克| 什么是思维| 反复口腔溃疡是什么原因| 什么运动能长高| 拔罐紫色说明什么| 奶嚼口是什么| 王字加一笔是什么字| 什么是翘舌音| 鼻炎用什么药效果好| 心电图窦性心动过速是什么意思| 七一年属什么生肖| 无性恋是什么| 2007年是什么生肖| 手脚脱皮是什么原因导致的| 心影增大是什么意思| 眼睛蒙蒙的是什么原因| 抹布什么意思| 干咳是什么原因引起的| 腐男是什么意思| 武五行属什么| 心什么神往| 邪不压正什么意思| 狗狗不能吃什么水果| 眼角发痒用什么眼药水| 下面瘙痒用什么药| 贵人多忘事什么意思| 89年是什么年| 为什么白带是黄色的| 四月什么星座| 软件开发需要学什么| 灌肠为什么能通输卵管| 南昌有什么好玩的景点| 咖啡对心脏有什么影响| 畏寒肢冷是什么意思| 四川酸菜是什么菜| 斗鱼吃什么| 肺间质纤维化是什么病| 单元剧是什么意思| 脸发红发痒是什么原因| 天蝎是什么动物| 张家界莓茶有什么功效| 夜明珠代表什么生肖| 什么叫缘分| 经期适合喝什么茶| 老是打嗝是什么病的征兆| 旦是什么意思| 小妮子是什么意思| 小舅子是什么意思| 低压高吃什么中成药| 小腿麻木是什么原因引起的| 眩光是什么意思| 7月29是什么星座| 什么时候放开二胎| 传教士是什么姿势| 增加性功能吃什么药| 头晕是什么原因引起| 吃什么对肝好怎么养肝| 结膜炎滴什么眼药水| 玩游戏有什么好处| 丹毒病是什么原因引起的| 柜子是什么意思| 得莫利是什么意思| 供血不足吃什么药好| 夏至是什么时候| 火彩是什么| 腿不自觉的抖是什么原因| 大三阳吃什么药好| 黑木耳是什么意思| 尿量少是什么原因| 北海有什么好玩的| 甲沟炎用什么药膏好| 千里共婵娟什么意思| 痔疮吃什么消炎药好得快| 女人下面长什么样| 女人喝茶有什么好处| 冠冕堂皇什么意思| 绝经后吃什么能来月经| 蜂蜜吃了有什么好处| 扁桃是什么水果| 09年属什么生肖| 小孩呕吐是什么原因| 百合有什么功效| 什么病会引起恶心| 犹太人为什么不受欢迎| 肚子疼发烧是什么病症| 乳房发痒什么原因| 醉代表什么生肖| 古灵精怪什么意思| 甲乙丙丁戊己庚辛壬癸代表什么| 乳腺应该挂什么科| 眼睛做激光手术有什么后遗症| 玉髓什么颜色最贵| 经期吃什么好排除瘀血| 肚脐周围痛挂什么科| 寿眉茶属于什么茶| 一个米一个参念什么| 梅子是什么| 秋天开什么花| 激凸是什么意思| 哪吒长什么样子| 痔疮什么感觉| 挖空细胞是什么意思啊| 中性粒细胞绝对值高是什么原因| 丽江机场叫什么名字| 生理盐水敷脸有什么作用| 什么药可以缩阴紧致| 蜜蜂蛰了用什么药| 心脾两虚吃什么药| 眉目的比喻义是什么| 补铁吃什么食物好| 1993年五行属什么| lp0是什么意思| 什么中药可以降糖| 火红火红的什么| gbs是什么意思| 田螺不能和什么一起吃| 长情是什么意思| 朱砂痣是什么意思| 为什么单位不愿意申请工伤| 长沙为什么叫星城| 荨麻疹吃什么药最管用| 4个月念什么字| 原发性和继发性是什么意思| 白帆是什么| 筱是什么意思| 被蜱虫咬了挂什么科| 梦见手机屏幕摔碎了是什么意思| 什么时候普及高中义务教育| twin是什么意思| 什么开窍于耳| 10月24号是什么星座| 没有胎心胎芽是什么原因造成的| 这个季节吃什么水果| 澳大利亚有什么动物| 阴囊潮湿是什么原因| 减肥早上吃什么比较好| 世事无常什么意思| 众里寻他千百度是什么意思| 陕西什么面| 脑干出血是什么原因造成的| 肴肉是什么肉| 什么是菩提| 尿酸高都有什么症状| brunch是什么意思| 什么是abo文| 低血糖有什么症状表现| 澳大利亚属于什么国家| 血肌酐高是什么原因| 腰两边疼是什么原因| 家里停电打什么电话| 梅雨季节是什么意思| 小气是什么意思| 彼岸花是什么花| 为什么会有月经| 女人吃什么排湿气最快| 女人大把掉头发是什么原因| KT是什么| 宋五行属什么| 小便带血是什么原因| 真实的印度是什么样的| 什么原因引起甲亢| 鼻基底填充用什么材料比较好| 老师为什么叫老师| 南字五行属什么| 核磁共振挂什么科| 百度
blob: b2ee70ec80b51b8f6970e4dbbfc0c36da475e86d [file] [log] [blame]
#!/usr/bin/env vpython3
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Tests for find_bad_builds."""
from __future__ import division
from __future__ import print_function
import contextlib
import datetime
import json
import argparse
import unittest
import git_utils
import find_bad_builds
import mock
class Pool:
"""Simple object used to mock out multiprocessing.Pool."""
def map(self, fn, lst):
return map(fn, lst)
@mock.patch('find_bad_builds._get_pool')
class FindBadBuildsIntegrationTest(unittest.TestCase):
"""Integration tests for find_bad_builds.
This only tests that the script works from an end to end perspective. It mocks
all the interactions with git and buildbucket in the script. That
functionality is fairly simple, and doesn't need to be tested.
"""
def _gen_build(self,
bid,
rev,
running_time,
builder='linux-rel',
bucket='try',
project='chromium'):
"""Generates a buildbucket dict representing a single build."""
return {
'id': str(bid),
'revision': rev,
'running_time': running_time,
'builder': {
'builder': builder,
'bucket': bucket,
'project': project
},
}
@contextlib.contextmanager
def _setup_git(self, commits, first_commit_date=None, time_gap=1):
"""Sets up git mocks.
Args:
commits: An ordered list of commit hashes. The first commit is assumed to
be the most recent.
first_commit_date: When the first commit starts. Datetime object.
time_gap: How long between git commits (minutes).
Returns:
Nothing. Yields to the caller, to allow the patches to be used during the
test.
"""
if not first_commit_date:
first_commit_date = datetime.datetime(2020, 1, 1, 0, 0, 0)
with mock.patch('git_utils.get_revisions_between') as rev_btwn:
def find_btwn(commit1, commit2):
# technically inefficient, but probably fine.
first = commits.index(commit1)
last = commits.index(commit2)
# Only want commits in between these two
return commits[first + 1:last]
rev_btwn.side_effect = find_btwn
with mock.patch('git_utils.get_commit_date') as rev_date:
def calc_date(rev):
ind = commits.index(rev)
return first_commit_date + datetime.timedelta(minutes=ind * time_gap)
rev_date.side_effect = calc_date
yield
@contextlib.contextmanager
def _setup_buildbucket(self, builds):
"""Sets up buildbucket mocks.
Args:
builds: A list of buildbucket builds (dict).
Yields:
The mock object for '_find_builds'. Callers can modify its side_effect to
verify attributes of the predicate passed to buildbucket.
"""
with mock.patch('find_bad_builds._find_builds') as find_builds:
find_builds.return_value = [json.dumps(b) for b in builds]
with mock.patch('find_bad_builds._fetch_build_revision') as fetch_rev:
def find_rev(bid):
for b in builds:
if b['id'] == bid:
return b['revision']
self.fail('build %s is missing a revision' % bid)
return None
fetch_rev.side_effect = find_rev
with mock.patch('find_bad_builds._get_build_running_time') as b_runtime:
b_runtime.side_effect = lambda build: datetime.timedelta(minutes=int(
build['running_time']))
# Yield find_builds so callers can assert on the predicate being
# passed to find_builds.
yield find_builds
def _run(self, args):
"""Runs the script. Returns the exit code and printed lines."""
lines = []
return find_bad_builds.main(args, lines.append), set(lines)
def test_simple(self, get_pool):
get_pool.return_value = Pool()
with self._setup_git(['1,', '2', '3', '4', '5']):
with self._setup_buildbucket([
self._gen_build(11, '1', 5),
self._gen_build(22, '2', 4),
self._gen_build(33, '3', 3),
self._gen_build(44, '4', 2),
self._gen_build(55, '5', 1),
]) as find_builds:
rval = find_builds.return_value
def se(predicate):
self.assertEqual(
predicate['createTime']['startTime'],
# commit '2' commit time.
'2025-08-05T00:01:00+00:00')
self.assertEqual(
predicate['createTime']['endTime'],
# commit '4' commit time, plus git replication lag.
'2025-08-05T00:23:00+00:00')
return rval
find_builds.side_effect = se
self.assertEqual(
self._run(['4', '2', '100']),
(
# Only builds with revision '2' and '3' should be cancelled. '4'
# has the good commit, so it's fine to run.
0,
set(['22', '33'])))
def test_print_builds(self, get_pool):
get_pool.return_value = Pool()
with self._setup_git(['1,', '2', '3', '4', '5']):
with self._setup_buildbucket([
self._gen_build(11, '1', 29),
self._gen_build(22, '2', 28),
self._gen_build(33, '3', 27),
self._gen_build(44, '4', 26),
self._gen_build(55, '5', 25),
]):
retcode, lines = self._run(['4', '2', '100', '-s'])
self.assertEqual(retcode, 0)
# Sort to get rid of header, then remove.
lines = sorted(lines)
self.assertTrue(lines[-1].startswith('Build '))
self.assertTrue(lines[0].startswith('------'))
self.assertEqual(
set(lines[1:-1]),
set([
'11 | False | 29 ',
'22 | True | 28 ',
'33 | True | 27 ',
'44 | False | 26 ',
'55 | False | 25 ',
]))
def test_build_time_filter(self, get_pool):
get_pool.return_value = Pool()
with self._setup_git(['1,', '2', '3', '4', '5']):
with self._setup_buildbucket([
self._gen_build(11, '1', 31),
self._gen_build(22, '2', 29),
self._gen_build(33, '3', 27),
self._gen_build(34, '3', 26),
self._gen_build(44, '4', 25),
self._gen_build(55, '5', 23),
]):
self.assertEqual(self._run(['4', '2', '28']), (0, set(['34', '33'])))
def test_builder_filter(self, get_pool):
get_pool.return_value = Pool()
with self._setup_git(['1,', '2', '3', '4', '5']):
with self._setup_buildbucket([
self._gen_build(11, '1', 4),
self._gen_build(21, '2', 5, builder='linux-rel'),
self._gen_build(22, '2', 5, builder='mac-rel'),
self._gen_build(23, '2', 5, builder='win-rel'),
self._gen_build(33, '3', 3),
self._gen_build(44, '4', 2),
self._gen_build(55, '5', 1),
]):
self.assertEqual(
self._run(['4', '2', '100', '-b', 'linux-rel', '-b', 'mac-rel']),
(0, set(['21', '22', '33'])))
def test_git_replication(self, get_pool):
get_pool.return_value = Pool()
with self._setup_git(['1,', '2', '3', '4', '5']):
with self._setup_buildbucket([
self._gen_build(11, '1', 6),
self._gen_build(22, '2', 5),
self._gen_build(33, '3', 4),
self._gen_build(44, '4', 3),
self._gen_build(55, '5', 2),
# Sometimes git has replication lag, which means that builds can get
# old git data. In this case, a build which ran after '5', which was
# committed after '4', gets '4' as the HEAD revision. This can happen
# in prod.
self._gen_build(66, '3', 1),
]):
self.assertEqual(self._run(['4', '2', '100']),
(0, set(['22', '33', '66'])))
if __name__ == '__main__':
unittest.main()
彩超是检查什么的 盗墓笔记讲的是什么故事 码放是什么意思 布偶猫长什么样 脑供血不足做什么检查能查出来
体征是什么意思 人参和什么泡酒壮阳 10月10是什么星座 内热是什么原因引起的怎么调理 什么动物三只爪
去医院看肛门挂什么科 什么还珠 心率过快有什么危害 7月29号是什么星座 abr是什么检查
joy是什么意思 流口水是什么病的前兆 7月30号是什么星座 阴茎进入阴道是什么感觉 什么药不能一起吃
脖子发麻是什么原因hcv8jop0ns4r.cn 做不好的梦预示着什么hcv8jop6ns0r.cn 斯里兰卡用什么货币hcv9jop1ns0r.cn 龙葵是什么hcv7jop6ns5r.cn 疱疹性咽峡炎用什么药hcv8jop9ns9r.cn
五味指的是什么hcv8jop7ns9r.cn 撒拉族和回族有什么区别helloaicloud.com 什么叫败血症hcv8jop8ns3r.cn 窦骁父母是干什么的hcv8jop9ns2r.cn 转氨酶高吃什么食物降得快dajiketang.com
异常的异是什么意思hcv9jop1ns3r.cn 为什么放屁多hcv8jop0ns0r.cn 补体c1q偏低说明什么xinjiangjialails.com 牙齿黄是什么原因造成的hcv7jop6ns6r.cn 县教育局局长是什么级别hcv8jop0ns7r.cn
pm是什么hcv7jop7ns4r.cn 脑死亡是什么原因引起的hcv7jop6ns9r.cn 什么食物含钾最高huizhijixie.com 孕酮什么意思zhiyanzhang.com 幼儿园转园需要什么手续hcv9jop5ns5r.cn
百度