ytest.py 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221
  1. from __future__ import print_function
  2. import os
  3. import re
  4. import sys
  5. import six
  6. import json
  7. import copy
  8. import base64
  9. import shlex
  10. import _common
  11. import lib.test_const as consts
  12. import _requirements as reqs
  13. from collections.abc import Buffer
  14. try:
  15. from StringIO import StringIO
  16. except ImportError:
  17. from io import StringIO
  18. import subprocess
  19. import collections
  20. import ymake
  21. CANON_DATA_DIR_NAME = 'canondata'
  22. CANON_OUTPUT_STORAGE = 'canondata_storage'
  23. CANON_RESULT_FILE_NAME = 'result.json'
  24. BLOCK_SEPARATOR = '============================================================='
  25. SPLIT_FACTOR_MAX_VALUE = 1000
  26. SPLIT_FACTOR_TEST_FILES_MAX_VALUE = 4250
  27. PARTITION_MODS = ('SEQUENTIAL', 'MODULO')
  28. DEFAULT_TIDY_CONFIG = "build/config/tests/clang_tidy/config.yaml"
  29. DEFAULT_TIDY_CONFIG_MAP_PATH = "build/yandex_specific/config/clang_tidy/tidy_default_map.json"
  30. PROJECT_TIDY_CONFIG_MAP_PATH = "build/yandex_specific/config/clang_tidy/tidy_project_map.json"
  31. KTLINT_CURRENT_EDITOR_CONFIG = "arcadia/build/platform/java/ktlint/.editorconfig"
  32. KTLINT_OLD_EDITOR_CONFIG = "arcadia/build/platform/java/ktlint_old/.editorconfig"
  33. tidy_config_map = None
  34. def ontest_data(unit, *args):
  35. ymake.report_configure_error("TEST_DATA is removed in favour of DATA")
  36. def format_recipes(data: str | None) -> str:
  37. if not data:
  38. return ""
  39. data = data.replace('"USE_RECIPE_DELIM"', "\n")
  40. data = data.replace("$TEST_RECIPES_VALUE", "")
  41. return data
  42. def prepare_recipes(data: str | None) -> Buffer:
  43. formatted = format_recipes(data)
  44. return base64.b64encode(six.ensure_binary(formatted))
  45. def prepare_env(data):
  46. data = data.replace("$TEST_ENV_VALUE", "")
  47. return serialize_list(shlex.split(data))
  48. def is_yt_spec_contain_pool_info(filename): # XXX switch to yson in ymake + perf test for configure
  49. pool_re = re.compile(r"""['"]*pool['"]*\s*?=""")
  50. cypress_root_re = re.compile(r"""['"]*cypress_root['"]*\s*=""")
  51. with open(filename, 'r') as afile:
  52. yt_spec = afile.read()
  53. return pool_re.search(yt_spec) and cypress_root_re.search(yt_spec)
  54. def validate_test(unit, kw):
  55. def get_list(key):
  56. return deserialize_list(kw.get(key, ""))
  57. valid_kw = copy.deepcopy(kw)
  58. errors = []
  59. warnings = []
  60. if valid_kw.get('SCRIPT-REL-PATH') == 'boost.test':
  61. project_path = valid_kw.get('BUILD-FOLDER-PATH', "")
  62. if not project_path.startswith(
  63. ("contrib", "mail", "maps", "tools/idl", "metrika", "devtools", "mds", "yandex_io", "smart_devices")
  64. ):
  65. errors.append("BOOSTTEST is not allowed here")
  66. size_timeout = collections.OrderedDict(sorted(consts.TestSize.DefaultTimeouts.items(), key=lambda t: t[1]))
  67. size = valid_kw.get('SIZE', consts.TestSize.Small).lower()
  68. tags = set(get_list("TAG"))
  69. requirements_orig = get_list("REQUIREMENTS")
  70. in_autocheck = consts.YaTestTags.NotAutocheck not in tags and consts.YaTestTags.Manual not in tags
  71. is_fat = consts.YaTestTags.Fat in tags
  72. is_force_sandbox = consts.YaTestTags.ForceDistbuild not in tags and is_fat
  73. is_ytexec_run = consts.YaTestTags.YtRunner in tags
  74. is_fuzzing = valid_kw.get("FUZZING", False)
  75. is_kvm = 'kvm' in requirements_orig
  76. requirements = {}
  77. secret_requirements = ('sb_vault', 'yav')
  78. list_requirements = secret_requirements
  79. for req in requirements_orig:
  80. if req in ('kvm',):
  81. requirements[req] = str(True)
  82. continue
  83. if ":" in req:
  84. req_name, req_value = req.split(":", 1)
  85. if req_name in list_requirements:
  86. requirements[req_name] = ",".join(filter(None, [requirements.get(req_name), req_value]))
  87. else:
  88. if req_name in requirements:
  89. if req_value in ["0"]:
  90. warnings.append(
  91. "Requirement [[imp]]{}[[rst]] is dropped [[imp]]{}[[rst]] -> [[imp]]{}[[rst]]".format(
  92. req_name, requirements[req_name], req_value
  93. )
  94. )
  95. del requirements[req_name]
  96. elif requirements[req_name] != req_value:
  97. warnings.append(
  98. "Requirement [[imp]]{}[[rst]] is redefined [[imp]]{}[[rst]] -> [[imp]]{}[[rst]]".format(
  99. req_name, requirements[req_name], req_value
  100. )
  101. )
  102. requirements[req_name] = req_value
  103. else:
  104. requirements[req_name] = req_value
  105. else:
  106. errors.append("Invalid requirement syntax [[imp]]{}[[rst]]: expect <requirement>:<value>".format(req))
  107. if not errors:
  108. for req_name, req_value in requirements.items():
  109. try:
  110. error_msg = reqs.validate_requirement(
  111. req_name,
  112. req_value,
  113. size,
  114. is_force_sandbox,
  115. in_autocheck,
  116. is_fuzzing,
  117. is_kvm,
  118. is_ytexec_run,
  119. requirements,
  120. )
  121. except Exception as e:
  122. error_msg = str(e)
  123. if error_msg:
  124. errors += [error_msg]
  125. invalid_requirements_for_distbuild = [
  126. requirement for requirement in requirements.keys() if requirement not in ('ram', 'ram_disk', 'cpu', 'network')
  127. ]
  128. sb_tags = []
  129. # XXX Unfortunately, some users have already started using colons
  130. # in their tag names. Use skip set to avoid treating their tag as system ones.
  131. # Remove this check when all such user tags are removed.
  132. skip_set = ('ynmt_benchmark', 'bert_models', 'zeliboba_map')
  133. # Verify the prefixes of the system tags to avoid pointless use of the REQUIREMENTS macro parameters in the TAG macro.
  134. for tag in tags:
  135. if tag.startswith('sb:'):
  136. sb_tags.append(tag)
  137. elif ':' in tag and not tag.startswith('ya:') and tag.split(':')[0] not in skip_set:
  138. errors.append(
  139. "Only [[imp]]sb:[[rst]] and [[imp]]ya:[[rst]] prefixes are allowed in system tags: {}".format(tag)
  140. )
  141. if is_fat:
  142. if size != consts.TestSize.Large:
  143. errors.append("Only LARGE test may have ya:fat tag")
  144. if in_autocheck and not is_force_sandbox:
  145. if invalid_requirements_for_distbuild:
  146. errors.append(
  147. "'{}' REQUIREMENTS options can be used only for FAT tests without ya:force_distbuild tag. Remove TAG(ya:force_distbuild) or an option.".format(
  148. invalid_requirements_for_distbuild
  149. )
  150. )
  151. if sb_tags:
  152. errors.append(
  153. "You can set sandbox tags '{}' only for FAT tests without ya:force_distbuild. Remove TAG(ya:force_sandbox) or sandbox tags.".format(
  154. sb_tags
  155. )
  156. )
  157. if consts.YaTestTags.SandboxCoverage in tags:
  158. errors.append("You can set 'ya:sandbox_coverage' tag only for FAT tests without ya:force_distbuild.")
  159. if is_ytexec_run:
  160. errors.append(
  161. "Running LARGE tests over YT (ya:yt) on Distbuild (ya:force_distbuild) is forbidden. Consider removing TAG(ya:force_distbuild)."
  162. )
  163. else:
  164. if is_force_sandbox:
  165. errors.append('ya:force_sandbox can be used with LARGE tests only')
  166. if consts.YaTestTags.Privileged in tags:
  167. errors.append("ya:privileged can be used with LARGE tests only")
  168. if in_autocheck and size == consts.TestSize.Large:
  169. errors.append("LARGE test must have ya:fat tag")
  170. if consts.YaTestTags.Privileged in tags and 'container' not in requirements:
  171. errors.append("Only tests with 'container' requirement can have 'ya:privileged' tag")
  172. if size not in size_timeout:
  173. errors.append(
  174. "Unknown test size: [[imp]]{}[[rst]], choose from [[imp]]{}[[rst]]".format(
  175. size.upper(), ", ".join([sz.upper() for sz in size_timeout.keys()])
  176. )
  177. )
  178. else:
  179. try:
  180. timeout = int(valid_kw.get('TEST-TIMEOUT', size_timeout[size]) or size_timeout[size])
  181. script_rel_path = valid_kw.get('SCRIPT-REL-PATH')
  182. if timeout < 0:
  183. raise Exception("Timeout must be > 0")
  184. skip_timeout_verification = script_rel_path in ('java.style', 'ktlint')
  185. if size_timeout[size] < timeout and in_autocheck and not skip_timeout_verification:
  186. suggested_size = None
  187. for s, t in size_timeout.items():
  188. if timeout <= t:
  189. suggested_size = s
  190. break
  191. if suggested_size:
  192. suggested_size = ", suggested size: [[imp]]{}[[rst]]".format(suggested_size.upper())
  193. else:
  194. suggested_size = ""
  195. errors.append(
  196. "Max allowed timeout for test size [[imp]]{}[[rst]] is [[imp]]{} sec[[rst]]{}".format(
  197. size.upper(), size_timeout[size], suggested_size
  198. )
  199. )
  200. except Exception as e:
  201. errors.append("Error when parsing test timeout: [[bad]]{}[[rst]]".format(e))
  202. requirements_list = []
  203. for req_name, req_value in six.iteritems(requirements):
  204. requirements_list.append(req_name + ":" + req_value)
  205. valid_kw['REQUIREMENTS'] = serialize_list(sorted(requirements_list))
  206. # Mark test with ya:external tag if it requests any secret from external storages
  207. # It's not stable and nonreproducible by definition
  208. for x in secret_requirements:
  209. if x in requirements:
  210. tags.add(consts.YaTestTags.External)
  211. if valid_kw.get("FUZZ-OPTS"):
  212. for option in get_list("FUZZ-OPTS"):
  213. if not option.startswith("-"):
  214. errors.append(
  215. "Unrecognized fuzzer option '[[imp]]{}[[rst]]'. All fuzzer options should start with '-'".format(
  216. option
  217. )
  218. )
  219. break
  220. eqpos = option.find("=")
  221. if eqpos == -1 or len(option) == eqpos + 1:
  222. errors.append(
  223. "Unrecognized fuzzer option '[[imp]]{}[[rst]]'. All fuzzer options should obtain value specified after '='".format(
  224. option
  225. )
  226. )
  227. break
  228. if option[eqpos - 1] == " " or option[eqpos + 1] == " ":
  229. errors.append("Spaces are not allowed: '[[imp]]{}[[rst]]'".format(option))
  230. break
  231. if option[:eqpos] in ("-runs", "-dict", "-jobs", "-workers", "-artifact_prefix", "-print_final_stats"):
  232. errors.append(
  233. "You can't use '[[imp]]{}[[rst]]' - it will be automatically calculated or configured during run".format(
  234. option
  235. )
  236. )
  237. break
  238. if valid_kw.get("YT-SPEC"):
  239. if not is_ytexec_run:
  240. errors.append("You can use YT_SPEC macro only tests marked with ya:yt tag")
  241. else:
  242. for filename in get_list("YT-SPEC"):
  243. filename = unit.resolve('$S/' + filename)
  244. if not os.path.exists(filename):
  245. errors.append("File '{}' specified in the YT_SPEC macro doesn't exist".format(filename))
  246. continue
  247. if not is_yt_spec_contain_pool_info(filename):
  248. tags.add(consts.YaTestTags.External)
  249. tags.add("ya:yt_research_pool")
  250. partition = valid_kw.get('TEST_PARTITION', 'SEQUENTIAL')
  251. if partition not in PARTITION_MODS:
  252. raise ValueError('partition mode should be one of {}, detected: {}'.format(PARTITION_MODS, partition))
  253. if valid_kw.get('SPLIT-FACTOR'):
  254. if valid_kw.get('FORK-MODE') == 'none':
  255. errors.append('SPLIT_FACTOR must be use with FORK_TESTS() or FORK_SUBTESTS() macro')
  256. value = 1
  257. try:
  258. value = int(valid_kw.get('SPLIT-FACTOR'))
  259. if value <= 0:
  260. raise ValueError("must be > 0")
  261. if value > SPLIT_FACTOR_MAX_VALUE:
  262. raise ValueError("the maximum allowed value is {}".format(SPLIT_FACTOR_MAX_VALUE))
  263. except ValueError as e:
  264. errors.append('Incorrect SPLIT_FACTOR value: {}'.format(e))
  265. if valid_kw.get('FORK-TEST-FILES') and size != consts.TestSize.Large:
  266. nfiles = count_entries(valid_kw.get('TEST-FILES'))
  267. if nfiles * value > SPLIT_FACTOR_TEST_FILES_MAX_VALUE:
  268. errors.append(
  269. 'Too much chunks generated:{} (limit: {}). Remove FORK_TEST_FILES() macro or reduce SPLIT_FACTOR({}).'.format(
  270. nfiles * value, SPLIT_FACTOR_TEST_FILES_MAX_VALUE, value
  271. )
  272. )
  273. if tags:
  274. valid_kw['TAG'] = serialize_list(sorted(tags))
  275. unit_path = _common.get_norm_unit_path(unit)
  276. if (
  277. not is_fat
  278. and consts.YaTestTags.Noretries in tags
  279. and not is_ytexec_run
  280. and not unit_path.startswith("devtools/dummy_arcadia/test/noretries")
  281. ):
  282. errors.append("Only LARGE tests can have 'ya:noretries' tag")
  283. if errors:
  284. return None, warnings, errors
  285. return valid_kw, warnings, errors
  286. def dump_test(unit, kw, trim_falsy_fields=True):
  287. if trim_falsy_fields:
  288. # "SCRIPT-REL-PATH", "SOURCE-FOLDER-PATH", "TEST-NAME" are required to distinguish dart files
  289. # TODO remove "TEST-FILES", "FILES" once defaults are moved to tests suites
  290. dont_trim = ("SCRIPT-REL-PATH", "SOURCE-FOLDER-PATH", "TEST-NAME", "TEST-FILES", "FILES")
  291. kw = {k: v for k, v in kw.items() if k in dont_trim or v and (not isinstance(v, (str, bytes)) or v.strip())}
  292. valid_kw, warnings, errors = validate_test(unit, kw)
  293. for w in warnings:
  294. unit.message(['warn', w])
  295. for e in errors:
  296. ymake.report_configure_error(e)
  297. if valid_kw is None:
  298. return None
  299. string_handler = StringIO()
  300. for k, v in six.iteritems(valid_kw):
  301. print(k + ': ' + six.ensure_str(v), file=string_handler)
  302. print(BLOCK_SEPARATOR, file=string_handler)
  303. data = string_handler.getvalue()
  304. string_handler.close()
  305. return data
  306. def serialize_list(lst):
  307. lst = list(filter(None, lst))
  308. return '\"' + ';'.join(lst) + '\"' if lst else ''
  309. def deserialize_list(val):
  310. return list(filter(None, val.replace('"', "").split(";")))
  311. def reference_group_var(varname: str, extensions: list[str] | None = None) -> str:
  312. if extensions is None:
  313. return f'"${{join=\\;:{varname}}}"'
  314. return serialize_list(f'${{ext={ext};join=\\;:{varname}}}' for ext in extensions)
  315. def count_entries(x):
  316. # see (de)serialize_list
  317. assert x is None or isinstance(x, str), type(x)
  318. if not x:
  319. return 0
  320. return x.count(";") + 1
  321. def get_values_list(unit, key):
  322. res = map(str.strip, (unit.get(key) or '').replace('$' + key, '').strip().split())
  323. return [r for r in res if r and r not in ['""', "''"]]
  324. def get_norm_paths(unit, key):
  325. # return paths without trailing (back)slash
  326. return [x.rstrip('\\/').replace('${ARCADIA_ROOT}/', '') for x in get_values_list(unit, key)]
  327. def get_unit_list_variable(unit, name):
  328. items = unit.get(name)
  329. if items:
  330. items = items.split(' ')
  331. assert items[0] == "${}".format(name), (items, name)
  332. return items[1:]
  333. return []
  334. def implies(a, b):
  335. return bool((not a) or b)
  336. def match_coverage_extractor_requirements(unit):
  337. # we shouldn't add test if
  338. return all(
  339. (
  340. # tests are not requested
  341. unit.get("TESTS_REQUESTED") == "yes",
  342. # build doesn't imply clang coverage, which supports segment extraction from the binaries
  343. unit.get("CLANG_COVERAGE") == "yes",
  344. # contrib wasn't requested
  345. implies(
  346. _common.get_norm_unit_path(unit).startswith("contrib/"), unit.get("ENABLE_CONTRIB_COVERAGE") == "yes"
  347. ),
  348. )
  349. )
  350. def get_tidy_config_map(unit, map_path):
  351. config_map_path = unit.resolve(os.path.join("$S", map_path))
  352. config_map = {}
  353. try:
  354. with open(config_map_path, 'r') as afile:
  355. config_map = json.load(afile)
  356. except ValueError:
  357. ymake.report_configure_error("{} is invalid json".format(map_path))
  358. except Exception as e:
  359. ymake.report_configure_error(str(e))
  360. return config_map
  361. def get_default_tidy_config(unit):
  362. unit_path = _common.get_norm_unit_path(unit)
  363. tidy_default_config_map = get_tidy_config_map(unit, DEFAULT_TIDY_CONFIG_MAP_PATH)
  364. for project_prefix, config_path in tidy_default_config_map.items():
  365. if unit_path.startswith(project_prefix):
  366. return config_path
  367. return DEFAULT_TIDY_CONFIG
  368. ordered_tidy_map = None
  369. def get_project_tidy_config(unit):
  370. global ordered_tidy_map
  371. if ordered_tidy_map is None:
  372. ordered_tidy_map = list(reversed(sorted(get_tidy_config_map(unit, PROJECT_TIDY_CONFIG_MAP_PATH).items())))
  373. unit_path = _common.get_norm_unit_path(unit)
  374. for project_prefix, config_path in ordered_tidy_map:
  375. if unit_path.startswith(project_prefix):
  376. return config_path
  377. else:
  378. return get_default_tidy_config(unit)
  379. def java_srcdirs_to_data(unit, var):
  380. extra_data = []
  381. for srcdir in (unit.get(var) or '').replace('$' + var, '').split():
  382. if srcdir == '.':
  383. srcdir = unit.get('MODDIR')
  384. if srcdir.startswith('${ARCADIA_ROOT}/') or srcdir.startswith('$ARCADIA_ROOT/'):
  385. srcdir = srcdir.replace('${ARCADIA_ROOT}/', '$S/')
  386. srcdir = srcdir.replace('$ARCADIA_ROOT/', '$S/')
  387. if srcdir.startswith('${CURDIR}') or srcdir.startswith('$CURDIR'):
  388. srcdir = srcdir.replace('${CURDIR}', os.path.join('$S', unit.get('MODDIR')))
  389. srcdir = srcdir.replace('$CURDIR', os.path.join('$S', unit.get('MODDIR')))
  390. srcdir = unit.resolve_arc_path(srcdir)
  391. if not srcdir.startswith('$'):
  392. srcdir = os.path.join('$S', unit.get('MODDIR'), srcdir)
  393. if srcdir.startswith('$S'):
  394. extra_data.append(srcdir.replace('$S', 'arcadia'))
  395. return serialize_list(extra_data)
  396. def check_data(unit, *args):
  397. flat_args, spec_args = _common.sort_by_keywords(
  398. {
  399. "DEPENDS": -1,
  400. "TIMEOUT": 1,
  401. "DATA": -1,
  402. "TAG": -1,
  403. "REQUIREMENTS": -1,
  404. "FORK_MODE": 1,
  405. "SPLIT_FACTOR": 1,
  406. "FORK_SUBTESTS": 0,
  407. "FORK_TESTS": 0,
  408. "SIZE": 1,
  409. },
  410. args,
  411. )
  412. check_type = flat_args[0]
  413. test_dir = _common.get_norm_unit_path(unit)
  414. test_files = flat_args[1:]
  415. uid_ext = unit.get("SBR_UID_EXT").split(" ", 1)[-1] # strip variable name
  416. data_re = re.compile(r"sbr:/?/?(\d+)=?.*")
  417. data = flat_args[1:]
  418. resources = []
  419. for f in data:
  420. matched = re.match(data_re, f)
  421. if matched:
  422. resources.append(matched.group(1))
  423. if resources:
  424. test_files = resources
  425. else:
  426. return
  427. serialized_test_files = serialize_list(test_files)
  428. test_record = {
  429. 'TEST-NAME': check_type.lower(),
  430. 'SCRIPT-REL-PATH': 'check.data',
  431. 'TESTED-PROJECT-NAME': os.path.basename(test_dir),
  432. 'SOURCE-FOLDER-PATH': test_dir,
  433. 'CUSTOM-DEPENDENCIES': " ".join(spec_args.get('DEPENDS', [])),
  434. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  435. 'SBR-UID-EXT': uid_ext,
  436. 'REQUIREMENTS': " ".join(spec_args.get('REQUIREMENTS', [])),
  437. 'USE_ARCADIA_PYTHON': unit.get('USE_ARCADIA_PYTHON'),
  438. # TODO remove FILES, see DEVTOOLS-7052
  439. 'FILES': serialized_test_files,
  440. 'TEST-FILES': serialized_test_files,
  441. }
  442. data = dump_test(unit, test_record)
  443. if data:
  444. unit.set_property(["DART_DATA", data])
  445. def check_resource(unit, *args):
  446. flat_args, spec_args = _common.sort_by_keywords(
  447. {
  448. "DEPENDS": -1,
  449. "TIMEOUT": 1,
  450. "DATA": -1,
  451. "TAG": -1,
  452. "REQUIREMENTS": -1,
  453. "FORK_MODE": 1,
  454. "SPLIT_FACTOR": 1,
  455. "FORK_SUBTESTS": 0,
  456. "FORK_TESTS": 0,
  457. "SIZE": 1,
  458. },
  459. args,
  460. )
  461. check_type = flat_args[0]
  462. test_dir = _common.get_norm_unit_path(unit)
  463. test_files = flat_args[1:]
  464. uid_ext = unit.get("SBR_UID_EXT").split(" ", 1)[-1] # strip variable name
  465. serialized_test_files = serialize_list(test_files)
  466. test_record = {
  467. 'TEST-NAME': check_type.lower(),
  468. 'SCRIPT-REL-PATH': 'check.resource',
  469. 'TESTED-PROJECT-NAME': os.path.basename(test_dir),
  470. 'SOURCE-FOLDER-PATH': test_dir,
  471. 'CUSTOM-DEPENDENCIES': " ".join(spec_args.get('DEPENDS', [])),
  472. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  473. 'SBR-UID-EXT': uid_ext,
  474. 'REQUIREMENTS': " ".join(spec_args.get('REQUIREMENTS', [])),
  475. 'USE_ARCADIA_PYTHON': unit.get('USE_ARCADIA_PYTHON'),
  476. # TODO remove FILES, see DEVTOOLS-7052
  477. 'FILES': serialized_test_files,
  478. 'TEST-FILES': serialized_test_files,
  479. }
  480. data = dump_test(unit, test_record)
  481. if data:
  482. unit.set_property(["DART_DATA", data])
  483. def ktlint(unit, *args):
  484. flat_args, spec_args = _common.sort_by_keywords(
  485. {
  486. "DEPENDS": -1,
  487. "TIMEOUT": 1,
  488. "DATA": -1,
  489. "TAG": -1,
  490. "REQUIREMENTS": -1,
  491. "FORK_MODE": 1,
  492. "SPLIT_FACTOR": 1,
  493. "FORK_SUBTESTS": 0,
  494. "FORK_TESTS": 0,
  495. "SIZE": 1,
  496. },
  497. args,
  498. )
  499. check_type = flat_args[0]
  500. test_dir = _common.get_norm_unit_path(unit)
  501. extra_test_dart_data = {}
  502. test_files = flat_args[1:]
  503. if unit.get('_USE_KTLINT_OLD') == 'yes':
  504. extra_test_data = serialize_list([KTLINT_OLD_EDITOR_CONFIG])
  505. extra_test_dart_data['KTLINT_BINARY'] = '$(KTLINT_OLD)/run.bat'
  506. extra_test_dart_data['USE_KTLINT_OLD'] = 'yes'
  507. else:
  508. data_list = [KTLINT_CURRENT_EDITOR_CONFIG]
  509. baseline_path_relative = unit.get('_KTLINT_BASELINE_FILE')
  510. if baseline_path_relative:
  511. baseline_path = unit.resolve_arc_path(baseline_path_relative).replace('$S', 'arcadia')
  512. data_list += [baseline_path]
  513. extra_test_dart_data['KTLINT_BASELINE_FILE'] = baseline_path_relative
  514. extra_test_data = serialize_list(data_list)
  515. extra_test_dart_data['KTLINT_BINARY'] = '$(KTLINT)/run.bat'
  516. serialized_test_files = serialize_list(test_files)
  517. test_record = {
  518. 'TEST-NAME': check_type.lower(),
  519. 'TEST-TIMEOUT': '120',
  520. 'SCRIPT-REL-PATH': 'ktlint',
  521. 'TESTED-PROJECT-NAME': os.path.basename(test_dir),
  522. 'SOURCE-FOLDER-PATH': test_dir,
  523. 'CUSTOM-DEPENDENCIES': " ".join(spec_args.get('DEPENDS', [])),
  524. 'TEST-DATA': extra_test_data,
  525. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  526. 'REQUIREMENTS': " ".join(spec_args.get('REQUIREMENTS', [])),
  527. 'USE_ARCADIA_PYTHON': unit.get('USE_ARCADIA_PYTHON'),
  528. # TODO remove FILES, see DEVTOOLS-7052
  529. 'FILES': serialized_test_files,
  530. 'TEST-FILES': serialized_test_files,
  531. 'MODULE_LANG': consts.ModuleLang.KOTLIN,
  532. }
  533. test_record.update(extra_test_dart_data)
  534. data = dump_test(unit, test_record)
  535. if data:
  536. unit.set_property(["DART_DATA", data])
  537. def java_style(unit, *args):
  538. flat_args, spec_args = _common.sort_by_keywords(
  539. {
  540. "DEPENDS": -1,
  541. "TIMEOUT": 1,
  542. "DATA": -1,
  543. "TAG": -1,
  544. "REQUIREMENTS": -1,
  545. "FORK_MODE": 1,
  546. "SPLIT_FACTOR": 1,
  547. "FORK_SUBTESTS": 0,
  548. "FORK_TESTS": 0,
  549. "SIZE": 1,
  550. },
  551. args,
  552. )
  553. check_type = flat_args[0]
  554. test_dir = _common.get_norm_unit_path(unit)
  555. ymake_java_test = unit.get('YMAKE_JAVA_TEST') == 'yes'
  556. test_files = flat_args[1:]
  557. if len(flat_args) < 2:
  558. raise Exception("Not enough arguments for JAVA_STYLE check")
  559. check_level = flat_args[1]
  560. allowed_levels = {
  561. 'base': '/yandex_checks.xml',
  562. 'strict': '/yandex_checks_strict.xml',
  563. 'extended': '/yandex_checks_extended.xml',
  564. 'library': '/yandex_checks_library.xml',
  565. }
  566. if check_level not in allowed_levels:
  567. raise Exception("'{}' is not allowed in LINT(), use one of {}".format(check_level, allowed_levels.keys()))
  568. test_files[0] = allowed_levels[check_level] # replace check_level with path to config file
  569. # jstyle should use the latest jdk
  570. unit.onpeerdir([unit.get('JDK_LATEST_PEERDIR')])
  571. serialized_test_files = serialize_list(test_files)
  572. test_record = {
  573. 'TEST-NAME': check_type.lower(),
  574. 'TEST-TIMEOUT': '240',
  575. 'SCRIPT-REL-PATH': "java.style",
  576. 'TESTED-PROJECT-NAME': os.path.basename(test_dir),
  577. 'SOURCE-FOLDER-PATH': test_dir,
  578. 'CUSTOM-DEPENDENCIES': " ".join(spec_args.get('DEPENDS', [])),
  579. 'TEST-DATA': java_srcdirs_to_data(unit, 'ALL_SRCDIRS') if ymake_java_test else '',
  580. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  581. 'FORK-MODE': unit.get('TEST_FORK_MODE'),
  582. 'REQUIREMENTS': " ".join(spec_args.get('REQUIREMENTS', [])),
  583. 'USE_ARCADIA_PYTHON': unit.get('USE_ARCADIA_PYTHON'),
  584. # TODO remove FILES, see DEVTOOLS-7052
  585. 'FILES': serialized_test_files,
  586. 'TEST-FILES': serialized_test_files,
  587. 'JDK_LATEST_VERSION': unit.get('JDK_LATEST_VERSION'),
  588. 'JDK_RESOURCE': 'JDK' + (unit.get('JDK_VERSION') or unit.get('JDK_REAL_VERSION') or '_DEFAULT'),
  589. 'MODULE_LANG': consts.ModuleLang.JAVA,
  590. }
  591. data = dump_test(unit, test_record)
  592. if data:
  593. unit.set_property(["DART_DATA", data])
  594. def gofmt(unit, *args):
  595. flat_args, spec_args = _common.sort_by_keywords(
  596. {
  597. "DEPENDS": -1,
  598. "TIMEOUT": 1,
  599. "DATA": -1,
  600. "TAG": -1,
  601. "REQUIREMENTS": -1,
  602. "FORK_MODE": 1,
  603. "SPLIT_FACTOR": 1,
  604. "FORK_SUBTESTS": 0,
  605. "FORK_TESTS": 0,
  606. "SIZE": 1,
  607. },
  608. args,
  609. )
  610. check_type = flat_args[0]
  611. test_dir = _common.get_norm_unit_path(unit)
  612. test_files = flat_args[1:]
  613. if test_files:
  614. test_dir = os.path.dirname(test_files[0]).lstrip("$S/")
  615. serialized_test_files = serialize_list(test_files)
  616. test_record = {
  617. 'TEST-NAME': check_type.lower(),
  618. 'SCRIPT-REL-PATH': 'gofmt',
  619. 'TESTED-PROJECT-NAME': os.path.basename(test_dir),
  620. 'SOURCE-FOLDER-PATH': test_dir,
  621. 'CUSTOM-DEPENDENCIES': " ".join(spec_args.get('DEPENDS', [])),
  622. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  623. 'REQUIREMENTS': " ".join(spec_args.get('REQUIREMENTS', [])),
  624. 'USE_ARCADIA_PYTHON': unit.get('USE_ARCADIA_PYTHON'),
  625. # TODO remove FILES, see DEVTOOLS-7052
  626. 'FILES': serialized_test_files,
  627. 'TEST-FILES': serialized_test_files,
  628. 'MODULE_LANG': consts.ModuleLang.GO,
  629. }
  630. data = dump_test(unit, test_record)
  631. if data:
  632. unit.set_property(["DART_DATA", data])
  633. def govet(unit, *args):
  634. flat_args, spec_args = _common.sort_by_keywords(
  635. {
  636. "DEPENDS": -1,
  637. "TIMEOUT": 1,
  638. "DATA": -1,
  639. "TAG": -1,
  640. "REQUIREMENTS": -1,
  641. "FORK_MODE": 1,
  642. "SPLIT_FACTOR": 1,
  643. "FORK_SUBTESTS": 0,
  644. "FORK_TESTS": 0,
  645. "SIZE": 1,
  646. },
  647. args,
  648. )
  649. check_type = flat_args[0]
  650. test_dir = _common.get_norm_unit_path(unit)
  651. test_files = flat_args[1:]
  652. serialized_test_files = serialize_list(test_files)
  653. test_record = {
  654. 'TEST-NAME': check_type.lower(),
  655. 'SCRIPT-REL-PATH': 'govet',
  656. 'TESTED-PROJECT-NAME': os.path.basename(test_dir),
  657. 'SOURCE-FOLDER-PATH': test_dir,
  658. 'CUSTOM-DEPENDENCIES': " ".join(spec_args.get('DEPENDS', [])),
  659. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  660. 'REQUIREMENTS': " ".join(spec_args.get('REQUIREMENTS', [])),
  661. 'USE_ARCADIA_PYTHON': unit.get('USE_ARCADIA_PYTHON'),
  662. # TODO remove FILES, see DEVTOOLS-7052
  663. 'FILES': serialized_test_files,
  664. 'TEST-FILES': serialized_test_files,
  665. 'MODULE_LANG': consts.ModuleLang.GO,
  666. }
  667. data = dump_test(unit, test_record)
  668. if data:
  669. unit.set_property(["DART_DATA", data])
  670. def onadd_check(unit, *args):
  671. if unit.get("TIDY") == "yes":
  672. # graph changed for clang_tidy tests
  673. return
  674. flat_args, *_ = _common.sort_by_keywords(
  675. {
  676. "DEPENDS": -1,
  677. "TIMEOUT": 1,
  678. "DATA": -1,
  679. "TAG": -1,
  680. "REQUIREMENTS": -1,
  681. "FORK_MODE": 1,
  682. "SPLIT_FACTOR": 1,
  683. "FORK_SUBTESTS": 0,
  684. "FORK_TESTS": 0,
  685. "SIZE": 1,
  686. },
  687. args,
  688. )
  689. check_type = flat_args[0]
  690. if check_type == "check.data" and unit.get('VALIDATE_DATA') != "no":
  691. check_data(unit, *args)
  692. elif check_type == "check.resource" and unit.get('VALIDATE_DATA') != "no":
  693. check_resource(unit, *args)
  694. elif check_type == "ktlint":
  695. ktlint(unit, *args)
  696. elif check_type == "JAVA_STYLE" and (unit.get('YMAKE_JAVA_TEST') != 'yes' or unit.get('ALL_SRCDIRS')):
  697. java_style(unit, *args)
  698. elif check_type == "gofmt":
  699. gofmt(unit, *args)
  700. elif check_type == "govet":
  701. govet(unit, *args)
  702. def on_register_no_check_imports(unit):
  703. s = unit.get('NO_CHECK_IMPORTS_FOR_VALUE')
  704. if s not in ('', 'None'):
  705. unit.onresource(['-', 'py/no_check_imports/{}="{}"'.format(_common.pathid(s), s)])
  706. def onadd_check_py_imports(unit, *args):
  707. if unit.get("TIDY") == "yes":
  708. # graph changed for clang_tidy tests
  709. return
  710. if unit.get('NO_CHECK_IMPORTS_FOR_VALUE').strip() == "":
  711. return
  712. unit.onpeerdir(['library/python/testing/import_test'])
  713. check_type = "py.imports"
  714. test_dir = _common.get_norm_unit_path(unit)
  715. test_files = serialize_list([_common.get_norm_unit_path(unit, unit.filename())])
  716. test_record = {
  717. 'TEST-NAME': "pyimports",
  718. 'SCRIPT-REL-PATH': check_type,
  719. 'TESTED-PROJECT-NAME': os.path.basename(test_dir),
  720. 'SOURCE-FOLDER-PATH': test_dir,
  721. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  722. 'USE_ARCADIA_PYTHON': unit.get('USE_ARCADIA_PYTHON'),
  723. # TODO remove FILES, see DEVTOOLS-7052
  724. 'FILES': test_files,
  725. 'TEST-FILES': test_files,
  726. 'MODULE_LANG': consts.ModuleLang.PY,
  727. }
  728. if unit.get('NO_CHECK_IMPORTS_FOR_VALUE') != "None":
  729. test_record["NO-CHECK"] = serialize_list(get_values_list(unit, 'NO_CHECK_IMPORTS_FOR_VALUE') or ["*"])
  730. data = dump_test(unit, test_record)
  731. if data:
  732. unit.set_property(["DART_DATA", data])
  733. def onadd_pytest_bin(unit, *args):
  734. if unit.get("TIDY") == "yes":
  735. # graph changed for clang_tidy tests
  736. return
  737. flat, kws = _common.sort_by_keywords({'RUNNER_BIN': 1}, args)
  738. if flat:
  739. ymake.report_configure_error('Unknown arguments found while processing add_pytest_bin macro: {!r}'.format(flat))
  740. runner_bin = kws.get('RUNNER_BIN', [None])[0]
  741. test_type = 'py3test.bin' if (unit.get("PYTHON3") == 'yes') else "pytest.bin"
  742. if unit.get('ADD_SRCDIR_TO_TEST_DATA') == "yes":
  743. unit.ondata_files(_common.get_norm_unit_path(unit))
  744. custom_deps = get_values_list(unit, 'TEST_DEPENDS_VALUE')
  745. timeout = list(filter(None, [unit.get(["TEST_TIMEOUT"])]))
  746. if timeout:
  747. timeout = timeout[0]
  748. else:
  749. timeout = '0'
  750. yt_spec = get_values_list(unit, 'TEST_YT_SPEC_VALUE')
  751. unit.ondata_files(yt_spec)
  752. unit_path = unit.path()
  753. test_files = get_values_list(unit, 'TEST_SRCS_VALUE')
  754. tags = _get_test_tags(unit)
  755. requirements = get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  756. test_data = get_norm_paths(unit, 'TEST_DATA_VALUE')
  757. data, _ = get_canonical_test_resources(unit)
  758. test_data += data
  759. python_paths = get_values_list(unit, 'TEST_PYTHON_PATH_VALUE')
  760. binary_path = os.path.join(unit_path, unit.filename())
  761. script_rel_path = test_type
  762. unit_path = unit.path()
  763. fork_test_files = unit.get('FORK_TEST_FILES_MODE')
  764. fork_mode = unit.get('TEST_FORK_MODE').split() or ''
  765. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  766. use_arcadia_python = unit.get('USE_ARCADIA_PYTHON')
  767. test_cwd = unit.get('TEST_CWD_VALUE') or ''
  768. if test_cwd:
  769. test_cwd = test_cwd.replace("$TEST_CWD_VALUE", "").replace('"MACRO_CALLS_DELIM"', "").strip()
  770. test_name = os.path.basename(binary_path)
  771. test_record = {
  772. 'TEST-NAME': os.path.splitext(test_name)[0],
  773. 'TEST-TIMEOUT': timeout,
  774. 'SCRIPT-REL-PATH': script_rel_path,
  775. 'TESTED-PROJECT-NAME': test_name,
  776. 'SOURCE-FOLDER-PATH': _common.get_norm_unit_path(unit),
  777. 'CUSTOM-DEPENDENCIES': " ".join(custom_deps),
  778. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  779. # 'TEST-PRESERVE-ENV': 'da',
  780. 'TEST-DATA': serialize_list(sorted(_common.filter_out_by_keyword(test_data, 'AUTOUPDATED'))),
  781. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  782. 'SPLIT-FACTOR': unit.get('TEST_SPLIT_FACTOR'),
  783. 'TEST_PARTITION': unit.get('TEST_PARTITION'),
  784. 'FORK-MODE': fork_mode,
  785. 'FORK-TEST-FILES': fork_test_files,
  786. 'TEST-FILES': serialize_list(test_files),
  787. 'SIZE': unit.get('TEST_SIZE_NAME'),
  788. 'TAG': serialize_list(sorted(tags)),
  789. 'REQUIREMENTS': serialize_list(requirements),
  790. 'USE_ARCADIA_PYTHON': use_arcadia_python,
  791. 'OLD_PYTEST': 'no',
  792. 'PYTHON-PATHS': serialize_list(python_paths),
  793. 'TEST-CWD': test_cwd,
  794. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  795. 'BUILD-FOLDER-PATH': _common.strip_roots(unit_path),
  796. 'BLOB': unit.get('TEST_BLOB_DATA'),
  797. 'CANONIZE_SUB_PATH': unit.get('CANONIZE_SUB_PATH'),
  798. 'MODULE_LANG': consts.ModuleLang.PY,
  799. }
  800. if binary_path:
  801. test_record['BINARY-PATH'] = _common.strip_roots(binary_path)
  802. if runner_bin:
  803. test_record['TEST-RUNNER-BIN'] = runner_bin
  804. if yt_spec:
  805. test_record['YT-SPEC'] = serialize_list(yt_spec)
  806. data = dump_test(unit, test_record)
  807. if data:
  808. unit.set_property(["DART_DATA", data])
  809. def extract_java_system_properties(unit, args):
  810. if len(args) % 2:
  811. return [], 'Wrong use of SYSTEM_PROPERTIES in {}: odd number of arguments'.format(unit.path())
  812. props = []
  813. for x, y in zip(args[::2], args[1::2]):
  814. if x == 'FILE':
  815. if y.startswith('${BINDIR}') or y.startswith('${ARCADIA_BUILD_ROOT}') or y.startswith('/'):
  816. return [], 'Wrong use of SYSTEM_PROPERTIES in {}: absolute/build file path {}'.format(unit.path(), y)
  817. y = _common.rootrel_arc_src(y, unit)
  818. if not os.path.exists(unit.resolve('$S/' + y)):
  819. return [], 'Wrong use of SYSTEM_PROPERTIES in {}: can\'t resolve {}'.format(unit.path(), y)
  820. y = '${ARCADIA_ROOT}/' + y
  821. props.append({'type': 'file', 'path': y})
  822. else:
  823. props.append({'type': 'inline', 'key': x, 'value': y})
  824. return props, None
  825. def onjava_test(unit, *args):
  826. if unit.get("TIDY") == "yes":
  827. # graph changed for clang_tidy tests
  828. return
  829. assert unit.get('MODULE_TYPE') is not None
  830. if unit.get('MODULE_TYPE') == 'JTEST_FOR':
  831. if not unit.get('UNITTEST_DIR'):
  832. ymake.report_configure_error('skip JTEST_FOR in {}: no args provided'.format(unit.path()))
  833. return
  834. java_cp_arg_type = unit.get('JAVA_CLASSPATH_CMD_TYPE_VALUE') or 'MANIFEST'
  835. if java_cp_arg_type not in ('MANIFEST', 'COMMAND_FILE', 'LIST'):
  836. ymake.report_configure_error(
  837. '{}: TEST_JAVA_CLASSPATH_CMD_TYPE({}) are invalid. Choose argument from MANIFEST, COMMAND_FILE or LIST)'.format(
  838. unit.path(), java_cp_arg_type
  839. )
  840. )
  841. return
  842. unit_path = unit.path()
  843. path = _common.strip_roots(unit_path)
  844. if unit.get('ADD_SRCDIR_TO_TEST_DATA') == "yes":
  845. unit.ondata_files(_common.get_norm_unit_path(unit))
  846. yt_spec_values = get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')
  847. unit.ondata_files(yt_spec_values)
  848. test_data = get_norm_paths(unit, 'TEST_DATA_VALUE')
  849. test_data.append('arcadia/build/scripts/run_junit.py')
  850. test_data.append('arcadia/build/scripts/unpacking_jtest_runner.py')
  851. data, data_files = get_canonical_test_resources(unit)
  852. test_data += data
  853. props, error_mgs = extract_java_system_properties(unit, get_values_list(unit, 'SYSTEM_PROPERTIES_VALUE'))
  854. if error_mgs:
  855. ymake.report_configure_error(error_mgs)
  856. return
  857. for prop in props:
  858. if prop['type'] == 'file':
  859. test_data.append(prop['path'].replace('${ARCADIA_ROOT}', 'arcadia'))
  860. props = base64.b64encode(six.ensure_binary(json.dumps(props)))
  861. if unit.get('MODULE_TYPE') == 'JUNIT5':
  862. script_rel_path = 'junit5.test'
  863. else:
  864. script_rel_path = 'junit.test'
  865. ymake_java_test = unit.get('YMAKE_JAVA_TEST') == 'yes'
  866. test_record = {
  867. 'SOURCE-FOLDER-PATH': path,
  868. 'TEST-NAME': '-'.join([os.path.basename(os.path.dirname(path)), os.path.basename(path)]),
  869. 'SCRIPT-REL-PATH': script_rel_path,
  870. 'TEST-TIMEOUT': unit.get('TEST_TIMEOUT'),
  871. 'TESTED-PROJECT-NAME': path,
  872. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  873. # 'TEST-PRESERVE-ENV': 'da',
  874. 'TEST-DATA': serialize_list(sorted(_common.filter_out_by_keyword(test_data, 'AUTOUPDATED'))),
  875. 'FORK-MODE': unit.get('TEST_FORK_MODE'),
  876. 'SPLIT-FACTOR': unit.get('TEST_SPLIT_FACTOR'),
  877. 'CUSTOM-DEPENDENCIES': ' '.join(get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  878. 'TAG': serialize_list(sorted(_get_test_tags(unit))),
  879. 'SIZE': unit.get('TEST_SIZE_NAME'),
  880. 'REQUIREMENTS': serialize_list(get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')),
  881. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  882. # JTEST/JTEST_FOR only
  883. 'MODULE_TYPE': unit.get('MODULE_TYPE'),
  884. 'UNITTEST_DIR': unit.get('UNITTEST_DIR'),
  885. 'JVM_ARGS': serialize_list(get_values_list(unit, 'JVM_ARGS_VALUE')),
  886. 'SYSTEM_PROPERTIES': props,
  887. 'TEST-CWD': unit.get('TEST_CWD_VALUE'), # TODO: validate test_cwd value
  888. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  889. 'JAVA_CLASSPATH_CMD_TYPE': java_cp_arg_type,
  890. 'JDK_RESOURCE': 'JDK' + (unit.get('JDK_VERSION') or unit.get('JDK_REAL_VERSION') or '_DEFAULT'),
  891. 'JDK_FOR_TESTS': 'JDK' + (unit.get('JDK_VERSION') or unit.get('JDK_REAL_VERSION') or '_DEFAULT') + '_FOR_TESTS',
  892. 'YT-SPEC': serialize_list(yt_spec_values),
  893. 'MODULE_LANG': consts.ModuleLang.JAVA,
  894. }
  895. test_classpath_origins = unit.get('TEST_CLASSPATH_VALUE')
  896. if test_classpath_origins:
  897. test_record['TEST_CLASSPATH_ORIGINS'] = test_classpath_origins
  898. test_record['TEST_CLASSPATH'] = '${TEST_CLASSPATH_MANAGED}'
  899. elif ymake_java_test:
  900. test_record['TEST_CLASSPATH'] = '${DART_CLASSPATH}'
  901. test_record['TEST_CLASSPATH_DEPS'] = '${DART_CLASSPATH_DEPS}'
  902. if unit.get('UNITTEST_DIR'):
  903. test_record['TEST_JAR'] = '${UNITTEST_MOD}'
  904. else:
  905. test_record['TEST_JAR'] = '{}/{}.jar'.format(unit.get('MODDIR'), unit.get('REALPRJNAME'))
  906. data = dump_test(unit, test_record)
  907. if data:
  908. unit.set_property(['DART_DATA', data])
  909. def onjava_test_deps(unit, *args):
  910. if unit.get("TIDY") == "yes":
  911. # graph changed for clang_tidy tests
  912. return
  913. assert unit.get('MODULE_TYPE') is not None
  914. assert len(args) == 1
  915. mode = args[0]
  916. path = _common.get_norm_unit_path(unit)
  917. ymake_java_test = unit.get('YMAKE_JAVA_TEST') == 'yes'
  918. test_record = {
  919. 'SOURCE-FOLDER-PATH': path,
  920. 'TEST-NAME': '-'.join([os.path.basename(os.path.dirname(path)), os.path.basename(path), 'dependencies']).strip(
  921. '-'
  922. ),
  923. 'SCRIPT-REL-PATH': 'java.dependency.test',
  924. 'TESTED-PROJECT-NAME': path,
  925. 'CUSTOM-DEPENDENCIES': ' '.join(get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  926. 'IGNORE_CLASSPATH_CLASH': ' '.join(get_values_list(unit, 'JAVA_IGNORE_CLASSPATH_CLASH_VALUE')),
  927. # JTEST/JTEST_FOR only
  928. 'MODULE_TYPE': unit.get('MODULE_TYPE'),
  929. 'MODULE_LANG': consts.ModuleLang.JAVA,
  930. }
  931. if mode == 'strict':
  932. test_record['STRICT_CLASSPATH_CLASH'] = 'yes'
  933. if ymake_java_test:
  934. test_record['CLASSPATH'] = '$B/{}/{}.jar ${{DART_CLASSPATH}}'.format(
  935. unit.get('MODDIR'), unit.get('REALPRJNAME')
  936. )
  937. data = dump_test(unit, test_record)
  938. unit.set_property(['DART_DATA', data])
  939. def _get_test_tags(unit, spec_args=None):
  940. if spec_args is None:
  941. spec_args = {}
  942. tags = spec_args.get('TAG', []) + get_values_list(unit, 'TEST_TAGS_VALUE')
  943. tags = set(tags)
  944. if unit.get('EXPORT_SEM') == 'yes':
  945. filter_only_tags = sorted(t for t in tags if ':' not in t)
  946. unit.set(['FILTER_ONLY_TEST_TAGS', ' '.join(filter_only_tags)])
  947. # DEVTOOLS-7571
  948. if unit.get('SKIP_TEST_VALUE') and consts.YaTestTags.Fat in tags:
  949. tags.add(consts.YaTestTags.NotAutocheck)
  950. return tags
  951. def onsetup_pytest_bin(unit, *args):
  952. use_arcadia_python = unit.get('USE_ARCADIA_PYTHON') == "yes"
  953. if use_arcadia_python:
  954. unit.onresource(['-', 'PY_MAIN={}'.format("library.python.pytest.main:main")]) # XXX
  955. unit.onadd_pytest_bin(list(args))
  956. def onrun(unit, *args):
  957. exectest_cmd = unit.get(["EXECTEST_COMMAND_VALUE"]) or ''
  958. exectest_cmd += "\n" + subprocess.list2cmdline(args)
  959. unit.set(["EXECTEST_COMMAND_VALUE", exectest_cmd])
  960. def onsetup_exectest(unit, *args):
  961. if unit.get("TIDY") == "yes":
  962. # graph changed for clang_tidy tests
  963. return
  964. command = unit.get(["EXECTEST_COMMAND_VALUE"])
  965. if command is None:
  966. ymake.report_configure_error("EXECTEST must have at least one RUN macro")
  967. return
  968. command = command.replace("$EXECTEST_COMMAND_VALUE", "")
  969. if "PYTHON_BIN" in command:
  970. unit.ondepends('contrib/tools/python')
  971. unit.set(["TEST_BLOB_DATA", base64.b64encode(six.ensure_binary(command))])
  972. if unit.get('ADD_SRCDIR_TO_TEST_DATA') == "yes":
  973. unit.ondata_files(_common.get_norm_unit_path(unit))
  974. custom_deps = get_values_list(unit, 'TEST_DEPENDS_VALUE')
  975. timeout = list(filter(None, [unit.get(["TEST_TIMEOUT"])]))
  976. if timeout:
  977. timeout = timeout[0]
  978. else:
  979. timeout = '0'
  980. split_factor = unit.get('TEST_SPLIT_FACTOR')
  981. test_cwd = unit.get('TEST_CWD_VALUE')
  982. yt_spec = get_values_list(unit, 'TEST_YT_SPEC_VALUE')
  983. unit.ondata_files(yt_spec)
  984. test_files = get_values_list(unit, 'TEST_SRCS_VALUE')
  985. tags = _get_test_tags(unit)
  986. requirements = get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  987. test_data = get_norm_paths(unit, 'TEST_DATA_VALUE')
  988. data, _ = get_canonical_test_resources(unit)
  989. test_data += data
  990. python_paths = get_values_list(unit, 'TEST_PYTHON_PATH_VALUE')
  991. unit_path = unit.path()
  992. fork_test_files = unit.get('FORK_TEST_FILES_MODE')
  993. fork_mode = unit.get('TEST_FORK_MODE').split() or ''
  994. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  995. use_arcadia_python = unit.get('USE_ARCADIA_PYTHON')
  996. if test_cwd:
  997. test_cwd = test_cwd.replace("$TEST_CWD_VALUE", "").replace('"MACRO_CALLS_DELIM"', "").strip()
  998. test_name = os.path.basename(os.path.join(unit.path(), unit.filename()).replace(".pkg", ""))
  999. test_record = {
  1000. 'TEST-NAME': os.path.splitext(test_name)[0],
  1001. 'TEST-TIMEOUT': timeout,
  1002. 'SCRIPT-REL-PATH': "exectest",
  1003. 'TESTED-PROJECT-NAME': test_name,
  1004. 'SOURCE-FOLDER-PATH': _common.get_norm_unit_path(unit),
  1005. 'CUSTOM-DEPENDENCIES': " ".join(custom_deps),
  1006. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1007. # 'TEST-PRESERVE-ENV': 'da',
  1008. 'TEST-DATA': serialize_list(sorted(_common.filter_out_by_keyword(test_data, 'AUTOUPDATED'))),
  1009. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1010. 'SPLIT-FACTOR': split_factor,
  1011. 'TEST_PARTITION': unit.get('TEST_PARTITION'),
  1012. 'FORK-MODE': fork_mode,
  1013. 'FORK-TEST-FILES': fork_test_files,
  1014. 'TEST-FILES': serialize_list(test_files),
  1015. 'SIZE': unit.get('TEST_SIZE_NAME'),
  1016. 'TAG': serialize_list(sorted(tags)),
  1017. 'REQUIREMENTS': serialize_list(requirements),
  1018. 'USE_ARCADIA_PYTHON': use_arcadia_python,
  1019. 'OLD_PYTEST': 'no',
  1020. 'PYTHON-PATHS': serialize_list(python_paths),
  1021. 'TEST-CWD': test_cwd,
  1022. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1023. 'BUILD-FOLDER-PATH': _common.strip_roots(unit_path),
  1024. 'BLOB': unit.get('TEST_BLOB_DATA'),
  1025. 'CANONIZE_SUB_PATH': unit.get('CANONIZE_SUB_PATH'),
  1026. }
  1027. test_record['BINARY-PATH'] = _common.strip_roots(os.path.join(unit.path(), unit.filename()).replace(".pkg", ""))
  1028. if yt_spec:
  1029. test_record['YT-SPEC'] = serialize_list(yt_spec)
  1030. data = dump_test(unit, test_record)
  1031. if data:
  1032. unit.set_property(["DART_DATA", data])
  1033. def onsetup_run_python(unit):
  1034. if unit.get("USE_ARCADIA_PYTHON") == "yes":
  1035. unit.ondepends('contrib/tools/python')
  1036. def get_canonical_test_resources(unit):
  1037. unit_path = unit.path()
  1038. if unit.get("CUSTOM_CANONDATA_PATH"):
  1039. path_to_canondata = unit_path.replace("$S", unit.get("CUSTOM_CANONDATA_PATH"))
  1040. else:
  1041. path_to_canondata = unit.resolve(unit_path)
  1042. canon_data_dir = os.path.join(path_to_canondata, CANON_DATA_DIR_NAME, unit.get('CANONIZE_SUB_PATH') or '')
  1043. try:
  1044. _, dirs, files = next(os.walk(canon_data_dir))
  1045. except StopIteration:
  1046. # path doesn't exist
  1047. return [], []
  1048. if CANON_RESULT_FILE_NAME in files:
  1049. return _get_canonical_data_resources_v2(os.path.join(canon_data_dir, CANON_RESULT_FILE_NAME), unit_path)
  1050. return [], []
  1051. def _load_canonical_file(filename, unit_path):
  1052. try:
  1053. with open(filename, 'rb') as results_file:
  1054. return json.load(results_file)
  1055. except Exception as e:
  1056. print("malformed canonical data in {}: {} ({})".format(unit_path, e, filename), file=sys.stderr)
  1057. return {}
  1058. def _get_resource_from_uri(uri):
  1059. m = consts.CANON_MDS_RESOURCE_REGEX.match(uri)
  1060. if m:
  1061. key = m.group(1)
  1062. return "{}:{}".format(consts.MDS_SCHEME, key)
  1063. m = consts.CANON_BACKEND_RESOURCE_REGEX.match(uri)
  1064. if m:
  1065. key = m.group(1)
  1066. return "{}:{}".format(consts.MDS_SCHEME, key)
  1067. m = consts.CANON_SBR_RESOURCE_REGEX.match(uri)
  1068. if m:
  1069. # There might be conflict between resources, because all resources in sandbox have 'resource.tar.gz' name
  1070. # That's why we use notation with '=' to specify specific path for resource
  1071. uri = m.group(1)
  1072. res_id = m.group(2)
  1073. return "{}={}".format(uri, '/'.join([CANON_OUTPUT_STORAGE, res_id]))
  1074. def _get_external_resources_from_canon_data(data):
  1075. # Method should work with both canonization versions:
  1076. # result.json: {'uri':X 'checksum':Y}
  1077. # result.json: {'testname': {'uri':X 'checksum':Y}}
  1078. # result.json: {'testname': [{'uri':X 'checksum':Y}]}
  1079. # Also there is a bug - if user returns {'uri': 1} from test - machinery will fail
  1080. # That's why we check 'uri' and 'checksum' fields presence
  1081. # (it's still a bug - user can return {'uri':X, 'checksum': Y}, we need to unify canonization format)
  1082. res = set()
  1083. if isinstance(data, dict):
  1084. if 'uri' in data and 'checksum' in data:
  1085. resource = _get_resource_from_uri(data['uri'])
  1086. if resource:
  1087. res.add(resource)
  1088. else:
  1089. for k, v in six.iteritems(data):
  1090. res.update(_get_external_resources_from_canon_data(v))
  1091. elif isinstance(data, list):
  1092. for e in data:
  1093. res.update(_get_external_resources_from_canon_data(e))
  1094. return res
  1095. def _get_canonical_data_resources_v2(filename, unit_path):
  1096. return (_get_external_resources_from_canon_data(_load_canonical_file(filename, unit_path)), [filename])
  1097. def on_add_linter_check(unit, *args):
  1098. if unit.get("TIDY") == "yes":
  1099. return
  1100. source_root_from_prefix = '${ARCADIA_ROOT}/'
  1101. source_root_to_prefix = '$S/'
  1102. unlimited = -1
  1103. no_lint_value = _common.get_no_lint_value(unit)
  1104. if no_lint_value in ("none", "none_internal"):
  1105. return
  1106. keywords = {
  1107. "DEPENDS": unlimited,
  1108. "FILES": unlimited,
  1109. "CONFIGS": unlimited,
  1110. "GLOBAL_RESOURCES": unlimited,
  1111. "FILE_PROCESSING_TIME": 1,
  1112. "EXTRA_PARAMS": unlimited,
  1113. }
  1114. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1115. if len(flat_args) != 2:
  1116. unit.message(['ERROR', '_ADD_LINTER_CHECK params: expected 2 free parameters'])
  1117. return
  1118. configs = []
  1119. for cfg in spec_args.get('CONFIGS', []):
  1120. filename = unit.resolve(source_root_to_prefix + cfg)
  1121. if not os.path.exists(filename):
  1122. unit.message(['ERROR', 'Configuration file {} is not found'.format(filename)])
  1123. return
  1124. configs.append(cfg)
  1125. deps = []
  1126. lint_name, linter = flat_args
  1127. deps.append(os.path.dirname(linter))
  1128. test_files = []
  1129. for path in spec_args.get('FILES', []):
  1130. if path.startswith(source_root_from_prefix):
  1131. test_files.append(path.replace(source_root_from_prefix, source_root_to_prefix, 1))
  1132. elif path.startswith(source_root_to_prefix):
  1133. test_files.append(path)
  1134. if lint_name == 'cpp_style':
  1135. files_dart = reference_group_var("ALL_SRCS", consts.STYLE_CPP_ALL_EXTS)
  1136. else:
  1137. if not test_files:
  1138. unit.message(['WARN', 'No files to lint for {}'.format(lint_name)])
  1139. return
  1140. files_dart = serialize_list(test_files)
  1141. for arg in spec_args.get('EXTRA_PARAMS', []):
  1142. if '=' not in arg:
  1143. unit.message(['WARN', 'Wrong EXTRA_PARAMS value: "{}". Values must have format "name=value".'.format(arg)])
  1144. return
  1145. deps += spec_args.get('DEPENDS', [])
  1146. for dep in deps:
  1147. unit.ondepends(dep)
  1148. for resource in spec_args.get('GLOBAL_RESOURCES', []):
  1149. unit.onpeerdir(resource)
  1150. test_record = {
  1151. 'TEST-NAME': lint_name,
  1152. 'SCRIPT-REL-PATH': 'custom_lint',
  1153. 'TESTED-PROJECT-NAME': unit.name(),
  1154. 'SOURCE-FOLDER-PATH': _common.get_norm_unit_path(unit),
  1155. 'CUSTOM-DEPENDENCIES': " ".join(deps),
  1156. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1157. 'USE_ARCADIA_PYTHON': unit.get('USE_ARCADIA_PYTHON') or '',
  1158. # TODO remove FILES, see DEVTOOLS-7052
  1159. 'FILES': files_dart,
  1160. 'TEST-FILES': files_dart,
  1161. # Linter specific parameters
  1162. # TODO Add configs to DATA. See YMAKE-427
  1163. 'LINT-CONFIGS': serialize_list(configs),
  1164. 'LINT-NAME': lint_name,
  1165. 'LINT-FILE-PROCESSING-TIME': spec_args.get('FILE_PROCESSING_TIME', [''])[0],
  1166. 'LINT-EXTRA-PARAMS': serialize_list(spec_args.get('EXTRA_PARAMS', [])),
  1167. 'LINTER': linter,
  1168. }
  1169. data = dump_test(unit, test_record)
  1170. if data:
  1171. unit.set_property(["DART_DATA", data])
  1172. def clang_tidy(unit, *args, from_other_type=False):
  1173. keywords = {
  1174. "DEPENDS": -1,
  1175. "DATA": -1,
  1176. "TIMEOUT": 1,
  1177. "FORK_MODE": 1,
  1178. "SPLIT_FACTOR": 1,
  1179. "FORK_SUBTESTS": 0,
  1180. "FORK_TESTS": 0,
  1181. }
  1182. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1183. # TODO see if we can get rid of 'from_other_type' parameter
  1184. if from_other_type:
  1185. if unit.get('ADD_SRCDIR_TO_TEST_DATA') == "yes":
  1186. unit.ondata_files(_common.get_norm_unit_path(unit))
  1187. if flat_args[1] == "boost.test":
  1188. unit.ondata_files(get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE'))
  1189. flat_args[1] = "clang_tidy"
  1190. test_size = 'SMALL'
  1191. test_tags = ''
  1192. test_timeout = "60"
  1193. test_requirements = []
  1194. unit.set(["TEST_YT_SPEC_VALUE", ""])
  1195. else:
  1196. unit.ondata_files(get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE'))
  1197. test_size = ''.join(spec_args.get('SIZE', [])) or unit.get('TEST_SIZE_NAME')
  1198. test_tags = serialize_list(sorted(_get_test_tags(unit, spec_args)))
  1199. test_timeout = ''.join(spec_args.get('TIMEOUT', [])) or unit.get('TEST_TIMEOUT')
  1200. test_requirements = spec_args.get('REQUIREMENTS', []) + get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  1201. test_data = sorted(
  1202. _common.filter_out_by_keyword(
  1203. spec_args.get('DATA', []) + get_norm_paths(unit, 'TEST_DATA_VALUE'), 'AUTOUPDATED'
  1204. )
  1205. )
  1206. if unit.get("TIDY_CONFIG"):
  1207. default_config_path = unit.get("TIDY_CONFIG")
  1208. project_config_path = unit.get("TIDY_CONFIG")
  1209. else:
  1210. default_config_path = get_default_tidy_config(unit)
  1211. project_config_path = get_project_tidy_config(unit)
  1212. unit.set(["DEFAULT_TIDY_CONFIG", default_config_path])
  1213. unit.set(["PROJECT_TIDY_CONFIG", project_config_path])
  1214. fork_mode = []
  1215. if 'FORK_SUBTESTS' in spec_args:
  1216. fork_mode.append('subtests')
  1217. if 'FORK_TESTS' in spec_args:
  1218. fork_mode.append('tests')
  1219. fork_mode = fork_mode or spec_args.get('FORK_MODE', []) or unit.get('TEST_FORK_MODE').split()
  1220. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  1221. unit_path = _common.get_norm_unit_path(unit)
  1222. test_record = {
  1223. 'TEST-NAME': flat_args[0],
  1224. 'SCRIPT-REL-PATH': flat_args[1],
  1225. 'TESTED-PROJECT-NAME': unit.name(),
  1226. 'TESTED-PROJECT-FILENAME': unit.filename(),
  1227. 'SOURCE-FOLDER-PATH': unit_path,
  1228. # TODO get rid of BUILD-FOLDER-PATH
  1229. 'BUILD-FOLDER-PATH': unit_path,
  1230. 'BINARY-PATH': "{}/{}".format(unit_path, unit.filename()),
  1231. 'GLOBAL-LIBRARY-PATH': unit.global_filename(),
  1232. 'CUSTOM-DEPENDENCIES': ' '.join(spec_args.get('DEPENDS', []) + get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  1233. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1234. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1235. # 'TEST-PRESERVE-ENV': 'da',
  1236. 'TEST-DATA': serialize_list(sorted(test_data)),
  1237. 'TEST-TIMEOUT': test_timeout,
  1238. 'FORK-MODE': fork_mode,
  1239. 'SPLIT-FACTOR': ''.join(spec_args.get('SPLIT_FACTOR', [])) or unit.get('TEST_SPLIT_FACTOR'),
  1240. 'SIZE': test_size,
  1241. 'TAG': test_tags,
  1242. 'REQUIREMENTS': serialize_list(test_requirements),
  1243. 'TEST-CWD': unit.get('TEST_CWD_VALUE'),
  1244. 'YT-SPEC': serialize_list(spec_args.get('YT_SPEC', []) + get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')),
  1245. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1246. 'TEST_IOS_DEVICE_TYPE': unit.get('TEST_IOS_DEVICE_TYPE_VALUE'),
  1247. 'TEST_IOS_RUNTIME_TYPE': unit.get('TEST_IOS_RUNTIME_TYPE_VALUE'),
  1248. 'ANDROID_APK_TEST_ACTIVITY': unit.get('ANDROID_APK_TEST_ACTIVITY_VALUE'),
  1249. 'TEST_PARTITION': unit.get("TEST_PARTITION"),
  1250. 'MODULE_LANG': consts.ModuleLang.CPP,
  1251. }
  1252. data = dump_test(unit, test_record)
  1253. if data:
  1254. unit.set_property(["DART_DATA", data])
  1255. def unittest_py(unit, *args):
  1256. keywords = {
  1257. "DEPENDS": -1,
  1258. "DATA": -1,
  1259. "TIMEOUT": 1,
  1260. "FORK_MODE": 1,
  1261. "SPLIT_FACTOR": 1,
  1262. "FORK_SUBTESTS": 0,
  1263. "FORK_TESTS": 0,
  1264. }
  1265. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1266. if unit.get('ADD_SRCDIR_TO_TEST_DATA') == "yes":
  1267. unit.ondata_files(_common.get_norm_unit_path(unit))
  1268. test_data = sorted(
  1269. _common.filter_out_by_keyword(
  1270. spec_args.get('DATA', []) + get_norm_paths(unit, 'TEST_DATA_VALUE'), 'AUTOUPDATED'
  1271. )
  1272. )
  1273. test_size = ''.join(spec_args.get('SIZE', [])) or unit.get('TEST_SIZE_NAME') or ''
  1274. test_tags = serialize_list(sorted(_get_test_tags(unit, spec_args)))
  1275. test_timeout = ''.join(spec_args.get('TIMEOUT', [])) or unit.get('TEST_TIMEOUT') or ''
  1276. test_requirements = spec_args.get('REQUIREMENTS', []) + get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  1277. fork_mode = []
  1278. if 'FORK_SUBTESTS' in spec_args:
  1279. fork_mode.append('subtests')
  1280. if 'FORK_TESTS' in spec_args:
  1281. fork_mode.append('tests')
  1282. fork_mode = fork_mode or spec_args.get('FORK_MODE', []) or unit.get('TEST_FORK_MODE').split()
  1283. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  1284. unit_path = _common.get_norm_unit_path(unit)
  1285. test_record = {
  1286. 'TEST-NAME': flat_args[0],
  1287. 'SCRIPT-REL-PATH': flat_args[1],
  1288. 'TESTED-PROJECT-NAME': unit.name(),
  1289. 'TESTED-PROJECT-FILENAME': unit.filename(),
  1290. 'SOURCE-FOLDER-PATH': unit_path,
  1291. # TODO get rid of BUILD-FOLDER-PATH
  1292. 'BUILD-FOLDER-PATH': unit_path,
  1293. 'BINARY-PATH': "{}/{}".format(unit_path, unit.filename()),
  1294. 'GLOBAL-LIBRARY-PATH': unit.global_filename(),
  1295. 'CUSTOM-DEPENDENCIES': ' '.join(spec_args.get('DEPENDS', []) + get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  1296. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1297. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1298. # 'TEST-PRESERVE-ENV': 'da',
  1299. 'TEST-DATA': serialize_list(sorted(test_data)),
  1300. 'TEST-TIMEOUT': test_timeout,
  1301. 'FORK-MODE': fork_mode,
  1302. 'SPLIT-FACTOR': ''.join(spec_args.get('SPLIT_FACTOR', [])) or unit.get('TEST_SPLIT_FACTOR'),
  1303. 'SIZE': test_size,
  1304. 'TAG': test_tags,
  1305. 'REQUIREMENTS': serialize_list(test_requirements),
  1306. 'TEST-CWD': unit.get('TEST_CWD_VALUE'),
  1307. 'YT-SPEC': serialize_list(spec_args.get('YT_SPEC', []) + get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')),
  1308. 'BLOB': unit.get('TEST_BLOB_DATA'),
  1309. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1310. 'TEST_IOS_DEVICE_TYPE': unit.get('TEST_IOS_DEVICE_TYPE_VALUE'),
  1311. 'TEST_IOS_RUNTIME_TYPE': unit.get('TEST_IOS_RUNTIME_TYPE_VALUE'),
  1312. 'ANDROID_APK_TEST_ACTIVITY': unit.get('ANDROID_APK_TEST_ACTIVITY_VALUE'),
  1313. 'TEST_PARTITION': unit.get("TEST_PARTITION"),
  1314. 'MODULE_LANG': consts.ModuleLang.CPP,
  1315. }
  1316. data = dump_test(unit, test_record)
  1317. if data:
  1318. unit.set_property(["DART_DATA", data])
  1319. def gunittest(unit, *args):
  1320. keywords = {
  1321. "DEPENDS": -1,
  1322. "DATA": -1,
  1323. "TIMEOUT": 1,
  1324. "FORK_MODE": 1,
  1325. "SPLIT_FACTOR": 1,
  1326. "FORK_SUBTESTS": 0,
  1327. "FORK_TESTS": 0,
  1328. }
  1329. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1330. if unit.get('ADD_SRCDIR_TO_TEST_DATA') == "yes":
  1331. unit.ondata_files(_common.get_norm_unit_path(unit))
  1332. test_data = sorted(
  1333. _common.filter_out_by_keyword(
  1334. spec_args.get('DATA', []) + get_norm_paths(unit, 'TEST_DATA_VALUE'), 'AUTOUPDATED'
  1335. )
  1336. )
  1337. test_size = ''.join(spec_args.get('SIZE', [])) or unit.get('TEST_SIZE_NAME') or ''
  1338. test_tags = serialize_list(sorted(_get_test_tags(unit, spec_args)))
  1339. test_timeout = ''.join(spec_args.get('TIMEOUT', [])) or unit.get('TEST_TIMEOUT') or ''
  1340. test_requirements = spec_args.get('REQUIREMENTS', []) + get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  1341. fork_mode = []
  1342. if 'FORK_SUBTESTS' in spec_args:
  1343. fork_mode.append('subtests')
  1344. if 'FORK_TESTS' in spec_args:
  1345. fork_mode.append('tests')
  1346. fork_mode = fork_mode or spec_args.get('FORK_MODE', []) or unit.get('TEST_FORK_MODE').split()
  1347. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  1348. unit_path = _common.get_norm_unit_path(unit)
  1349. test_record = {
  1350. 'TEST-NAME': flat_args[0],
  1351. 'SCRIPT-REL-PATH': flat_args[1],
  1352. 'TESTED-PROJECT-NAME': unit.name(),
  1353. 'TESTED-PROJECT-FILENAME': unit.filename(),
  1354. 'SOURCE-FOLDER-PATH': unit_path,
  1355. # TODO get rid of BUILD-FOLDER-PATH
  1356. 'BUILD-FOLDER-PATH': unit_path,
  1357. 'BINARY-PATH': "{}/{}".format(unit_path, unit.filename()),
  1358. 'GLOBAL-LIBRARY-PATH': unit.global_filename(),
  1359. 'CUSTOM-DEPENDENCIES': ' '.join(spec_args.get('DEPENDS', []) + get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  1360. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1361. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1362. # 'TEST-PRESERVE-ENV': 'da',
  1363. 'TEST-DATA': serialize_list(sorted(test_data)),
  1364. 'TEST-TIMEOUT': test_timeout,
  1365. 'FORK-MODE': fork_mode,
  1366. 'SPLIT-FACTOR': ''.join(spec_args.get('SPLIT_FACTOR', [])) or unit.get('TEST_SPLIT_FACTOR'),
  1367. 'SIZE': test_size,
  1368. 'TAG': test_tags,
  1369. 'REQUIREMENTS': serialize_list(test_requirements),
  1370. 'TEST-CWD': unit.get('TEST_CWD_VALUE'),
  1371. 'YT-SPEC': serialize_list(spec_args.get('YT_SPEC', []) + get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')),
  1372. 'BLOB': unit.get('TEST_BLOB_DATA'),
  1373. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1374. 'TEST_IOS_DEVICE_TYPE': unit.get('TEST_IOS_DEVICE_TYPE_VALUE'),
  1375. 'TEST_IOS_RUNTIME_TYPE': unit.get('TEST_IOS_RUNTIME_TYPE_VALUE'),
  1376. 'ANDROID_APK_TEST_ACTIVITY': unit.get('ANDROID_APK_TEST_ACTIVITY_VALUE'),
  1377. 'TEST_PARTITION': unit.get("TEST_PARTITION"),
  1378. 'MODULE_LANG': consts.ModuleLang.CPP,
  1379. }
  1380. data = dump_test(unit, test_record)
  1381. if data:
  1382. unit.set_property(["DART_DATA", data])
  1383. def g_benchmark(unit, *args):
  1384. keywords = {
  1385. "DEPENDS": -1,
  1386. "DATA": -1,
  1387. "TIMEOUT": 1,
  1388. "FORK_MODE": 1,
  1389. "SPLIT_FACTOR": 1,
  1390. "FORK_SUBTESTS": 0,
  1391. "FORK_TESTS": 0,
  1392. }
  1393. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1394. if unit.get('ADD_SRCDIR_TO_TEST_DATA') == "yes":
  1395. unit.ondata_files(_common.get_norm_unit_path(unit))
  1396. test_data = sorted(
  1397. _common.filter_out_by_keyword(
  1398. spec_args.get('DATA', []) + get_norm_paths(unit, 'TEST_DATA_VALUE'), 'AUTOUPDATED'
  1399. )
  1400. )
  1401. test_size = ''.join(spec_args.get('SIZE', [])) or unit.get('TEST_SIZE_NAME') or ''
  1402. test_tags = serialize_list(sorted(_get_test_tags(unit, spec_args)))
  1403. test_timeout = ''.join(spec_args.get('TIMEOUT', [])) or unit.get('TEST_TIMEOUT') or ''
  1404. test_requirements = spec_args.get('REQUIREMENTS', []) + get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  1405. fork_mode = []
  1406. if 'FORK_SUBTESTS' in spec_args:
  1407. fork_mode.append('subtests')
  1408. if 'FORK_TESTS' in spec_args:
  1409. fork_mode.append('tests')
  1410. fork_mode = fork_mode or spec_args.get('FORK_MODE', []) or unit.get('TEST_FORK_MODE').split()
  1411. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  1412. unit_path = _common.get_norm_unit_path(unit)
  1413. test_record = {
  1414. 'TEST-NAME': flat_args[0],
  1415. 'SCRIPT-REL-PATH': flat_args[1],
  1416. 'TESTED-PROJECT-NAME': unit.name(),
  1417. 'TESTED-PROJECT-FILENAME': unit.filename(),
  1418. 'SOURCE-FOLDER-PATH': unit_path,
  1419. # TODO get rid of BUILD-FOLDER-PATH
  1420. 'BUILD-FOLDER-PATH': unit_path,
  1421. 'BINARY-PATH': "{}/{}".format(unit_path, unit.filename()),
  1422. 'GLOBAL-LIBRARY-PATH': unit.global_filename(),
  1423. 'CUSTOM-DEPENDENCIES': ' '.join(spec_args.get('DEPENDS', []) + get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  1424. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1425. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1426. # 'TEST-PRESERVE-ENV': 'da',
  1427. 'TEST-DATA': serialize_list(sorted(test_data)),
  1428. 'TEST-TIMEOUT': test_timeout,
  1429. 'FORK-MODE': fork_mode,
  1430. 'SPLIT-FACTOR': ''.join(spec_args.get('SPLIT_FACTOR', [])) or unit.get('TEST_SPLIT_FACTOR'),
  1431. 'SIZE': test_size,
  1432. 'TAG': test_tags,
  1433. 'REQUIREMENTS': serialize_list(test_requirements),
  1434. 'TEST-CWD': unit.get('TEST_CWD_VALUE'),
  1435. 'YT-SPEC': serialize_list(spec_args.get('YT_SPEC', []) + get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')),
  1436. 'BLOB': unit.get('TEST_BLOB_DATA'),
  1437. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1438. 'TEST_IOS_DEVICE_TYPE': unit.get('TEST_IOS_DEVICE_TYPE_VALUE'),
  1439. 'TEST_IOS_RUNTIME_TYPE': unit.get('TEST_IOS_RUNTIME_TYPE_VALUE'),
  1440. 'ANDROID_APK_TEST_ACTIVITY': unit.get('ANDROID_APK_TEST_ACTIVITY_VALUE'),
  1441. 'TEST_PARTITION': unit.get("TEST_PARTITION"),
  1442. 'MODULE_LANG': consts.ModuleLang.CPP,
  1443. }
  1444. benchmark_opts = get_unit_list_variable(unit, 'BENCHMARK_OPTS_VALUE')
  1445. test_record['BENCHMARK-OPTS'] = serialize_list(benchmark_opts)
  1446. data = dump_test(unit, test_record)
  1447. if data:
  1448. unit.set_property(["DART_DATA", data])
  1449. def go_test(unit, *args):
  1450. keywords = {
  1451. "DEPENDS": -1,
  1452. "DATA": -1,
  1453. "TIMEOUT": 1,
  1454. "FORK_MODE": 1,
  1455. "SPLIT_FACTOR": 1,
  1456. "FORK_SUBTESTS": 0,
  1457. "FORK_TESTS": 0,
  1458. }
  1459. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1460. if unit.get('ADD_SRCDIR_TO_TEST_DATA') == "yes":
  1461. unit.ondata_files(_common.get_norm_unit_path(unit))
  1462. unit.ondata_files(get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE'))
  1463. test_data = sorted(
  1464. _common.filter_out_by_keyword(
  1465. spec_args.get('DATA', []) + get_norm_paths(unit, 'TEST_DATA_VALUE'), 'AUTOUPDATED'
  1466. )
  1467. )
  1468. data, _ = get_canonical_test_resources(unit)
  1469. test_data += data
  1470. test_size = ''.join(spec_args.get('SIZE', [])) or unit.get('TEST_SIZE_NAME')
  1471. test_tags = serialize_list(sorted(_get_test_tags(unit, spec_args)))
  1472. test_timeout = ''.join(spec_args.get('TIMEOUT', [])) or unit.get('TEST_TIMEOUT')
  1473. test_requirements = spec_args.get('REQUIREMENTS', []) + get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  1474. fork_mode = []
  1475. if 'FORK_SUBTESTS' in spec_args:
  1476. fork_mode.append('subtests')
  1477. if 'FORK_TESTS' in spec_args:
  1478. fork_mode.append('tests')
  1479. fork_mode = fork_mode or spec_args.get('FORK_MODE', []) or unit.get('TEST_FORK_MODE').split()
  1480. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  1481. unit_path = _common.get_norm_unit_path(unit)
  1482. test_record = {
  1483. 'TEST-NAME': flat_args[0],
  1484. 'SCRIPT-REL-PATH': flat_args[1],
  1485. 'TESTED-PROJECT-NAME': unit.name(),
  1486. 'TESTED-PROJECT-FILENAME': unit.filename(),
  1487. 'SOURCE-FOLDER-PATH': unit_path,
  1488. # TODO get rid of BUILD-FOLDER-PATH
  1489. 'BUILD-FOLDER-PATH': unit_path,
  1490. 'BINARY-PATH': "{}/{}".format(unit_path, unit.filename()),
  1491. 'GLOBAL-LIBRARY-PATH': unit.global_filename(),
  1492. 'CUSTOM-DEPENDENCIES': ' '.join(spec_args.get('DEPENDS', []) + get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  1493. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1494. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1495. # 'TEST-PRESERVE-ENV': 'da',
  1496. 'TEST-DATA': serialize_list(sorted(test_data)),
  1497. 'TEST-TIMEOUT': test_timeout,
  1498. 'FORK-MODE': fork_mode,
  1499. 'SPLIT-FACTOR': ''.join(spec_args.get('SPLIT_FACTOR', [])) or unit.get('TEST_SPLIT_FACTOR'),
  1500. 'SIZE': test_size,
  1501. 'TAG': test_tags,
  1502. 'REQUIREMENTS': serialize_list(test_requirements),
  1503. 'TEST-CWD': unit.get('TEST_CWD_VALUE'),
  1504. 'YT-SPEC': serialize_list(spec_args.get('YT_SPEC', []) + get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')),
  1505. 'BLOB': unit.get('TEST_BLOB_DATA'),
  1506. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1507. 'TEST_IOS_DEVICE_TYPE': unit.get('TEST_IOS_DEVICE_TYPE_VALUE'),
  1508. 'TEST_IOS_RUNTIME_TYPE': unit.get('TEST_IOS_RUNTIME_TYPE_VALUE'),
  1509. 'ANDROID_APK_TEST_ACTIVITY': unit.get('ANDROID_APK_TEST_ACTIVITY_VALUE'),
  1510. 'TEST_PARTITION': unit.get("TEST_PARTITION"),
  1511. 'MODULE_LANG': consts.ModuleLang.GO,
  1512. }
  1513. data = dump_test(unit, test_record)
  1514. if data:
  1515. unit.set_property(["DART_DATA", data])
  1516. def boost_test(unit, *args):
  1517. keywords = {
  1518. "DEPENDS": -1,
  1519. "DATA": -1,
  1520. "TIMEOUT": 1,
  1521. "FORK_MODE": 1,
  1522. "SPLIT_FACTOR": 1,
  1523. "FORK_SUBTESTS": 0,
  1524. "FORK_TESTS": 0,
  1525. }
  1526. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1527. if unit.get('ADD_SRCDIR_TO_TEST_DATA') == "yes":
  1528. unit.ondata_files(_common.get_norm_unit_path(unit))
  1529. unit.ondata_files(get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE'))
  1530. test_data = sorted(
  1531. _common.filter_out_by_keyword(
  1532. spec_args.get('DATA', []) + get_norm_paths(unit, 'TEST_DATA_VALUE'), 'AUTOUPDATED'
  1533. )
  1534. )
  1535. test_size = ''.join(spec_args.get('SIZE', [])) or unit.get('TEST_SIZE_NAME')
  1536. test_tags = serialize_list(sorted(_get_test_tags(unit, spec_args)))
  1537. test_timeout = ''.join(spec_args.get('TIMEOUT', [])) or unit.get('TEST_TIMEOUT')
  1538. test_requirements = spec_args.get('REQUIREMENTS', []) + get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  1539. fork_mode = []
  1540. if 'FORK_SUBTESTS' in spec_args:
  1541. fork_mode.append('subtests')
  1542. if 'FORK_TESTS' in spec_args:
  1543. fork_mode.append('tests')
  1544. fork_mode = fork_mode or spec_args.get('FORK_MODE', []) or unit.get('TEST_FORK_MODE').split()
  1545. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  1546. unit_path = _common.get_norm_unit_path(unit)
  1547. test_record = {
  1548. 'TEST-NAME': flat_args[0],
  1549. 'SCRIPT-REL-PATH': flat_args[1],
  1550. 'TESTED-PROJECT-NAME': unit.name(),
  1551. 'TESTED-PROJECT-FILENAME': unit.filename(),
  1552. 'SOURCE-FOLDER-PATH': unit_path,
  1553. # TODO get rid of BUILD-FOLDER-PATH
  1554. 'BUILD-FOLDER-PATH': unit_path,
  1555. 'BINARY-PATH': "{}/{}".format(unit_path, unit.filename()),
  1556. 'GLOBAL-LIBRARY-PATH': unit.global_filename(),
  1557. 'CUSTOM-DEPENDENCIES': ' '.join(spec_args.get('DEPENDS', []) + get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  1558. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1559. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1560. # 'TEST-PRESERVE-ENV': 'da',
  1561. 'TEST-DATA': serialize_list(sorted(test_data)),
  1562. 'TEST-TIMEOUT': test_timeout,
  1563. 'FORK-MODE': fork_mode,
  1564. 'SPLIT-FACTOR': ''.join(spec_args.get('SPLIT_FACTOR', [])) or unit.get('TEST_SPLIT_FACTOR'),
  1565. 'SIZE': test_size,
  1566. 'TAG': test_tags,
  1567. 'REQUIREMENTS': serialize_list(test_requirements),
  1568. 'TEST-CWD': unit.get('TEST_CWD_VALUE'),
  1569. 'YT-SPEC': serialize_list(spec_args.get('YT_SPEC', []) + get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')),
  1570. 'BLOB': unit.get('TEST_BLOB_DATA'),
  1571. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1572. 'TEST_IOS_DEVICE_TYPE': unit.get('TEST_IOS_DEVICE_TYPE_VALUE'),
  1573. 'TEST_IOS_RUNTIME_TYPE': unit.get('TEST_IOS_RUNTIME_TYPE_VALUE'),
  1574. 'ANDROID_APK_TEST_ACTIVITY': unit.get('ANDROID_APK_TEST_ACTIVITY_VALUE'),
  1575. 'TEST_PARTITION': unit.get("TEST_PARTITION"),
  1576. }
  1577. data = dump_test(unit, test_record)
  1578. if data:
  1579. unit.set_property(["DART_DATA", data])
  1580. def fuzz_test(unit, *args):
  1581. keywords = {
  1582. "DEPENDS": -1,
  1583. "DATA": -1,
  1584. "TIMEOUT": 1,
  1585. "FORK_MODE": 1,
  1586. "SPLIT_FACTOR": 1,
  1587. "FORK_SUBTESTS": 0,
  1588. "FORK_TESTS": 0,
  1589. }
  1590. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1591. if unit.get('ADD_SRCDIR_TO_TEST_DATA') == "yes":
  1592. unit.ondata_files(_common.get_norm_unit_path(unit))
  1593. unit.ondata_files("fuzzing/{}/corpus.json".format(_common.get_norm_unit_path(unit)))
  1594. unit.ondata_files(get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE'))
  1595. test_data = sorted(
  1596. _common.filter_out_by_keyword(
  1597. spec_args.get('DATA', []) + get_norm_paths(unit, 'TEST_DATA_VALUE'), 'AUTOUPDATED'
  1598. )
  1599. )
  1600. test_size = ''.join(spec_args.get('SIZE', [])) or unit.get('TEST_SIZE_NAME')
  1601. test_tags = serialize_list(sorted(_get_test_tags(unit, spec_args)))
  1602. test_timeout = ''.join(spec_args.get('TIMEOUT', [])) or unit.get('TEST_TIMEOUT')
  1603. test_requirements = spec_args.get('REQUIREMENTS', []) + get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  1604. fork_mode = []
  1605. if 'FORK_SUBTESTS' in spec_args:
  1606. fork_mode.append('subtests')
  1607. if 'FORK_TESTS' in spec_args:
  1608. fork_mode.append('tests')
  1609. fork_mode = fork_mode or spec_args.get('FORK_MODE', []) or unit.get('TEST_FORK_MODE').split()
  1610. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  1611. unit_path = _common.get_norm_unit_path(unit)
  1612. test_record = {
  1613. 'TEST-NAME': flat_args[0],
  1614. 'SCRIPT-REL-PATH': flat_args[1],
  1615. 'TESTED-PROJECT-NAME': unit.name(),
  1616. 'TESTED-PROJECT-FILENAME': unit.filename(),
  1617. 'SOURCE-FOLDER-PATH': unit_path,
  1618. # TODO get rid of BUILD-FOLDER-PATH
  1619. 'BUILD-FOLDER-PATH': unit_path,
  1620. 'BINARY-PATH': "{}/{}".format(unit_path, unit.filename()),
  1621. 'GLOBAL-LIBRARY-PATH': unit.global_filename(),
  1622. 'CUSTOM-DEPENDENCIES': ' '.join(spec_args.get('DEPENDS', []) + get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  1623. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1624. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1625. # 'TEST-PRESERVE-ENV': 'da',
  1626. 'TEST-DATA': serialize_list(sorted(test_data)),
  1627. 'TEST-TIMEOUT': test_timeout,
  1628. 'FORK-MODE': fork_mode,
  1629. 'SPLIT-FACTOR': ''.join(spec_args.get('SPLIT_FACTOR', [])) or unit.get('TEST_SPLIT_FACTOR'),
  1630. 'SIZE': test_size,
  1631. 'TAG': test_tags,
  1632. 'REQUIREMENTS': serialize_list(test_requirements),
  1633. 'TEST-CWD': unit.get('TEST_CWD_VALUE'),
  1634. 'FUZZ-DICTS': serialize_list(
  1635. spec_args.get('FUZZ_DICTS', []) + get_unit_list_variable(unit, 'FUZZ_DICTS_VALUE')
  1636. ),
  1637. 'FUZZ-OPTS': serialize_list(spec_args.get('FUZZ_OPTS', []) + get_unit_list_variable(unit, 'FUZZ_OPTS_VALUE')),
  1638. 'YT-SPEC': serialize_list(spec_args.get('YT_SPEC', []) + get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')),
  1639. 'BLOB': unit.get('TEST_BLOB_DATA'),
  1640. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1641. 'TEST_IOS_DEVICE_TYPE': unit.get('TEST_IOS_DEVICE_TYPE_VALUE'),
  1642. 'TEST_IOS_RUNTIME_TYPE': unit.get('TEST_IOS_RUNTIME_TYPE_VALUE'),
  1643. 'ANDROID_APK_TEST_ACTIVITY': unit.get('ANDROID_APK_TEST_ACTIVITY_VALUE'),
  1644. 'TEST_PARTITION': unit.get("TEST_PARTITION"),
  1645. }
  1646. if unit.get('FUZZING') == 'yes':
  1647. test_record['FUZZING'] = '1'
  1648. # use all cores if fuzzing requested
  1649. test_record['REQUIREMENTS'] = serialize_list(
  1650. filter(None, deserialize_list(test_record['REQUIREMENTS']) + ["cpu:all", "ram:all"])
  1651. )
  1652. data = dump_test(unit, test_record)
  1653. if data:
  1654. unit.set_property(["DART_DATA", data])
  1655. def y_benchmark(unit, *args):
  1656. keywords = {
  1657. "DEPENDS": -1,
  1658. "DATA": -1,
  1659. "TIMEOUT": 1,
  1660. "FORK_MODE": 1,
  1661. "SPLIT_FACTOR": 1,
  1662. "FORK_SUBTESTS": 0,
  1663. "FORK_TESTS": 0,
  1664. }
  1665. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1666. unit.ondata_files(get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE'))
  1667. test_data = sorted(
  1668. _common.filter_out_by_keyword(
  1669. spec_args.get('DATA', []) + get_norm_paths(unit, 'TEST_DATA_VALUE'), 'AUTOUPDATED'
  1670. )
  1671. )
  1672. test_size = ''.join(spec_args.get('SIZE', [])) or unit.get('TEST_SIZE_NAME')
  1673. test_tags = serialize_list(sorted(_get_test_tags(unit, spec_args)))
  1674. test_timeout = ''.join(spec_args.get('TIMEOUT', [])) or unit.get('TEST_TIMEOUT')
  1675. test_requirements = spec_args.get('REQUIREMENTS', []) + get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  1676. fork_mode = []
  1677. if 'FORK_SUBTESTS' in spec_args:
  1678. fork_mode.append('subtests')
  1679. if 'FORK_TESTS' in spec_args:
  1680. fork_mode.append('tests')
  1681. fork_mode = fork_mode or spec_args.get('FORK_MODE', []) or unit.get('TEST_FORK_MODE').split()
  1682. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  1683. unit_path = _common.get_norm_unit_path(unit)
  1684. test_record = {
  1685. 'TEST-NAME': flat_args[0],
  1686. 'SCRIPT-REL-PATH': flat_args[1],
  1687. 'TESTED-PROJECT-NAME': unit.name(),
  1688. 'TESTED-PROJECT-FILENAME': unit.filename(),
  1689. 'SOURCE-FOLDER-PATH': unit_path,
  1690. # TODO get rid of BUILD-FOLDER-PATH
  1691. 'BUILD-FOLDER-PATH': unit_path,
  1692. 'BINARY-PATH': "{}/{}".format(unit_path, unit.filename()),
  1693. 'GLOBAL-LIBRARY-PATH': unit.global_filename(),
  1694. 'CUSTOM-DEPENDENCIES': ' '.join(spec_args.get('DEPENDS', []) + get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  1695. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1696. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1697. # 'TEST-PRESERVE-ENV': 'da',
  1698. 'TEST-DATA': serialize_list(sorted(test_data)),
  1699. 'TEST-TIMEOUT': test_timeout,
  1700. 'FORK-MODE': fork_mode,
  1701. 'SPLIT-FACTOR': ''.join(spec_args.get('SPLIT_FACTOR', [])) or unit.get('TEST_SPLIT_FACTOR'),
  1702. 'SIZE': test_size,
  1703. 'TAG': test_tags,
  1704. 'REQUIREMENTS': serialize_list(test_requirements),
  1705. 'TEST-CWD': unit.get('TEST_CWD_VALUE'),
  1706. 'YT-SPEC': serialize_list(spec_args.get('YT_SPEC', []) + get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')),
  1707. 'BLOB': unit.get('TEST_BLOB_DATA'),
  1708. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1709. 'TEST_IOS_DEVICE_TYPE': unit.get('TEST_IOS_DEVICE_TYPE_VALUE'),
  1710. 'TEST_IOS_RUNTIME_TYPE': unit.get('TEST_IOS_RUNTIME_TYPE_VALUE'),
  1711. 'ANDROID_APK_TEST_ACTIVITY': unit.get('ANDROID_APK_TEST_ACTIVITY_VALUE'),
  1712. 'TEST_PARTITION': unit.get("TEST_PARTITION"),
  1713. 'MODULE_LANG': consts.ModuleLang.CPP,
  1714. }
  1715. benchmark_opts = get_unit_list_variable(unit, 'BENCHMARK_OPTS_VALUE')
  1716. test_record['BENCHMARK-OPTS'] = serialize_list(benchmark_opts)
  1717. data = dump_test(unit, test_record)
  1718. if data:
  1719. unit.set_property(["DART_DATA", data])
  1720. def coverage_extractor(unit, *args):
  1721. keywords = {
  1722. "DEPENDS": -1,
  1723. "DATA": -1,
  1724. "TIMEOUT": 1,
  1725. "FORK_MODE": 1,
  1726. "SPLIT_FACTOR": 1,
  1727. "FORK_SUBTESTS": 0,
  1728. "FORK_TESTS": 0,
  1729. }
  1730. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1731. unit.ondata_files(get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE'))
  1732. test_data = sorted(
  1733. _common.filter_out_by_keyword(
  1734. spec_args.get('DATA', []) + get_norm_paths(unit, 'TEST_DATA_VALUE'), 'AUTOUPDATED'
  1735. )
  1736. )
  1737. test_size = ''.join(spec_args.get('SIZE', [])) or unit.get('TEST_SIZE_NAME')
  1738. test_tags = serialize_list(sorted(_get_test_tags(unit, spec_args)))
  1739. test_timeout = ''.join(spec_args.get('TIMEOUT', [])) or unit.get('TEST_TIMEOUT')
  1740. test_requirements = spec_args.get('REQUIREMENTS', []) + get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  1741. fork_mode = []
  1742. if 'FORK_SUBTESTS' in spec_args:
  1743. fork_mode.append('subtests')
  1744. if 'FORK_TESTS' in spec_args:
  1745. fork_mode.append('tests')
  1746. fork_mode = fork_mode or spec_args.get('FORK_MODE', []) or unit.get('TEST_FORK_MODE').split()
  1747. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  1748. unit_path = _common.get_norm_unit_path(unit)
  1749. test_record = {
  1750. 'TEST-NAME': flat_args[0],
  1751. 'SCRIPT-REL-PATH': flat_args[1],
  1752. 'TESTED-PROJECT-NAME': unit.name(),
  1753. 'TESTED-PROJECT-FILENAME': unit.filename(),
  1754. 'SOURCE-FOLDER-PATH': unit_path,
  1755. # TODO get rid of BUILD-FOLDER-PATH
  1756. 'BUILD-FOLDER-PATH': unit_path,
  1757. 'BINARY-PATH': "{}/{}".format(unit_path, unit.filename()),
  1758. 'GLOBAL-LIBRARY-PATH': unit.global_filename(),
  1759. 'CUSTOM-DEPENDENCIES': ' '.join(spec_args.get('DEPENDS', []) + get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  1760. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1761. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1762. # 'TEST-PRESERVE-ENV': 'da',
  1763. 'TEST-DATA': serialize_list(sorted(test_data)),
  1764. 'TEST-TIMEOUT': test_timeout,
  1765. 'FORK-MODE': fork_mode,
  1766. 'SPLIT-FACTOR': ''.join(spec_args.get('SPLIT_FACTOR', [])) or unit.get('TEST_SPLIT_FACTOR'),
  1767. 'SIZE': test_size,
  1768. 'TAG': test_tags,
  1769. 'REQUIREMENTS': serialize_list(test_requirements),
  1770. 'TEST-CWD': unit.get('TEST_CWD_VALUE'),
  1771. 'YT-SPEC': serialize_list(spec_args.get('YT_SPEC', []) + get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')),
  1772. 'BLOB': unit.get('TEST_BLOB_DATA'),
  1773. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1774. 'TEST_IOS_DEVICE_TYPE': unit.get('TEST_IOS_DEVICE_TYPE_VALUE'),
  1775. 'TEST_IOS_RUNTIME_TYPE': unit.get('TEST_IOS_RUNTIME_TYPE_VALUE'),
  1776. 'ANDROID_APK_TEST_ACTIVITY': unit.get('ANDROID_APK_TEST_ACTIVITY_VALUE'),
  1777. 'TEST_PARTITION': unit.get("TEST_PARTITION"),
  1778. }
  1779. data = dump_test(unit, test_record)
  1780. if data:
  1781. unit.set_property(["DART_DATA", data])
  1782. def go_bench(unit, *args):
  1783. keywords = {
  1784. "DEPENDS": -1,
  1785. "DATA": -1,
  1786. "TIMEOUT": 1,
  1787. "FORK_MODE": 1,
  1788. "SPLIT_FACTOR": 1,
  1789. "FORK_SUBTESTS": 0,
  1790. "FORK_TESTS": 0,
  1791. }
  1792. flat_args, spec_args = _common.sort_by_keywords(keywords, args)
  1793. unit.ondata_files(get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE'))
  1794. test_data = sorted(
  1795. _common.filter_out_by_keyword(
  1796. spec_args.get('DATA', []) + get_norm_paths(unit, 'TEST_DATA_VALUE'), 'AUTOUPDATED'
  1797. )
  1798. )
  1799. test_size = ''.join(spec_args.get('SIZE', [])) or unit.get('TEST_SIZE_NAME')
  1800. test_tags = serialize_list(sorted(_get_test_tags(unit, spec_args)))
  1801. test_timeout = ''.join(spec_args.get('TIMEOUT', [])) or unit.get('TEST_TIMEOUT')
  1802. test_requirements = spec_args.get('REQUIREMENTS', []) + get_values_list(unit, 'TEST_REQUIREMENTS_VALUE')
  1803. fork_mode = []
  1804. if 'FORK_SUBTESTS' in spec_args:
  1805. fork_mode.append('subtests')
  1806. if 'FORK_TESTS' in spec_args:
  1807. fork_mode.append('tests')
  1808. fork_mode = fork_mode or spec_args.get('FORK_MODE', []) or unit.get('TEST_FORK_MODE').split()
  1809. fork_mode = ' '.join(fork_mode) if fork_mode else ''
  1810. unit_path = _common.get_norm_unit_path(unit)
  1811. test_record = {
  1812. 'TEST-NAME': flat_args[0],
  1813. 'SCRIPT-REL-PATH': flat_args[1],
  1814. 'TESTED-PROJECT-NAME': unit.name(),
  1815. 'TESTED-PROJECT-FILENAME': unit.filename(),
  1816. 'SOURCE-FOLDER-PATH': unit_path,
  1817. # TODO get rid of BUILD-FOLDER-PATH
  1818. 'BUILD-FOLDER-PATH': unit_path,
  1819. 'BINARY-PATH': "{}/{}".format(unit_path, unit.filename()),
  1820. 'GLOBAL-LIBRARY-PATH': unit.global_filename(),
  1821. 'CUSTOM-DEPENDENCIES': ' '.join(spec_args.get('DEPENDS', []) + get_values_list(unit, 'TEST_DEPENDS_VALUE')),
  1822. 'TEST-RECIPES': prepare_recipes(unit.get("TEST_RECIPES_VALUE")),
  1823. 'TEST-ENV': prepare_env(unit.get("TEST_ENV_VALUE")),
  1824. # 'TEST-PRESERVE-ENV': 'da',
  1825. 'TEST-DATA': serialize_list(sorted(test_data)),
  1826. 'TEST-TIMEOUT': test_timeout,
  1827. 'FORK-MODE': fork_mode,
  1828. 'SPLIT-FACTOR': ''.join(spec_args.get('SPLIT_FACTOR', [])) or unit.get('TEST_SPLIT_FACTOR'),
  1829. 'SIZE': test_size,
  1830. 'TAG': test_tags,
  1831. 'REQUIREMENTS': serialize_list(test_requirements),
  1832. 'TEST-CWD': unit.get('TEST_CWD_VALUE'),
  1833. 'YT-SPEC': serialize_list(spec_args.get('YT_SPEC', []) + get_unit_list_variable(unit, 'TEST_YT_SPEC_VALUE')),
  1834. 'BLOB': unit.get('TEST_BLOB_DATA'),
  1835. 'SKIP_TEST': unit.get('SKIP_TEST_VALUE'),
  1836. 'TEST_IOS_DEVICE_TYPE': unit.get('TEST_IOS_DEVICE_TYPE_VALUE'),
  1837. 'TEST_IOS_RUNTIME_TYPE': unit.get('TEST_IOS_RUNTIME_TYPE_VALUE'),
  1838. 'ANDROID_APK_TEST_ACTIVITY': unit.get('ANDROID_APK_TEST_ACTIVITY_VALUE'),
  1839. 'TEST_PARTITION': unit.get("TEST_PARTITION"),
  1840. 'GO_BENCH_TIMEOUT': unit.get('GO_BENCH_TIMEOUT'),
  1841. 'MODULE_LANG': consts.ModuleLang.GO,
  1842. }
  1843. if "ya:run_go_benchmark" not in test_record["TAG"]:
  1844. return
  1845. else:
  1846. test_record["TEST-NAME"] += "_bench"
  1847. data = dump_test(unit, test_record)
  1848. if data:
  1849. unit.set_property(["DART_DATA", data])
  1850. def onadd_ytest(unit, *args):
  1851. keywords = {
  1852. "DEPENDS": -1,
  1853. "DATA": -1,
  1854. "TIMEOUT": 1,
  1855. "FORK_MODE": 1,
  1856. "SPLIT_FACTOR": 1,
  1857. "FORK_SUBTESTS": 0,
  1858. "FORK_TESTS": 0,
  1859. }
  1860. flat_args, *_ = _common.sort_by_keywords(keywords, args)
  1861. test_type = flat_args[1]
  1862. if unit.get("TIDY_ENABLED") == "yes" and test_type in (
  1863. "unittest.py",
  1864. "gunittest",
  1865. "g_benchmark",
  1866. "boost.test",
  1867. ):
  1868. clang_tidy(unit, *args, from_other_type=True)
  1869. elif unit.get("TIDY_ENABLED") == "yes" and test_type not in (
  1870. "clang_tidy",
  1871. "unittest.py",
  1872. "gunittest",
  1873. "g_benchmark",
  1874. "boost.test",
  1875. ):
  1876. return
  1877. elif test_type == "clang_tidy" and unit.get("TIDY_ENABLED") != "yes":
  1878. return
  1879. elif unit.get("TIDY") == "yes" and unit.get("TIDY_ENABLED") != "yes":
  1880. return
  1881. elif test_type == "no.test":
  1882. return
  1883. elif test_type == "clang_tidy" and unit.get("TIDY_ENABLED") == "yes":
  1884. clang_tidy(unit, *args)
  1885. elif test_type == "unittest.py":
  1886. unittest_py(unit, *args)
  1887. elif test_type == "gunittest":
  1888. gunittest(unit, *args)
  1889. elif test_type == "g_benchmark":
  1890. g_benchmark(unit, *args)
  1891. elif test_type == "go.test":
  1892. go_test(unit, *args)
  1893. elif test_type == "boost.test":
  1894. boost_test(unit, *args)
  1895. elif test_type == "fuzz.test":
  1896. fuzz_test(unit, *args)
  1897. elif test_type == "y_benchmark":
  1898. y_benchmark(unit, *args)
  1899. elif test_type == "coverage.extractor" and match_coverage_extractor_requirements(unit):
  1900. coverage_extractor(unit, *args)
  1901. elif test_type == "go.bench":
  1902. go_bench(unit, *args)