ytest.py 83 KB

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