You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_model.py 28 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. # Copyright 2019 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ============================================================================
  15. """
  16. Function:
  17. Test the query module about lineage information.
  18. Usage:
  19. The query module test should be run after lineagemgr/collection/model/test_model_lineage.py
  20. pytest lineagemgr
  21. """
  22. import os
  23. from unittest import TestCase
  24. import pytest
  25. from mindinsight.lineagemgr.model import filter_summary_lineage, get_summary_lineage
  26. from mindinsight.lineagemgr.common.exceptions.exceptions import (LineageFileNotFoundError, LineageParamSummaryPathError,
  27. LineageParamTypeError, LineageParamValueError,
  28. LineageSearchConditionParamError)
  29. from .conftest import BASE_SUMMARY_DIR, DATASET_GRAPH, SUMMARY_DIR, SUMMARY_DIR_2
  30. from ....ut.lineagemgr.querier import event_data
  31. from ....utils.tools import assert_equal_lineages
  32. LINEAGE_INFO_RUN1 = {
  33. 'summary_dir': os.path.join(BASE_SUMMARY_DIR, 'run1'),
  34. 'metric': {
  35. 'accuracy': 0.78
  36. },
  37. 'hyper_parameters': {
  38. 'optimizer': 'Momentum',
  39. 'learning_rate': 0.12,
  40. 'loss_function': 'SoftmaxCrossEntropyWithLogits',
  41. 'epoch': 14,
  42. 'parallel_mode': 'stand_alone',
  43. 'device_num': 2,
  44. 'batch_size': 32
  45. },
  46. 'algorithm': {
  47. 'network': 'ResNet'
  48. },
  49. 'train_dataset': {
  50. 'train_dataset_size': 1024
  51. },
  52. 'valid_dataset': {
  53. 'valid_dataset_size': 1024
  54. },
  55. 'model': {
  56. 'path': '{"ckpt": "'
  57. + BASE_SUMMARY_DIR + '/run1/CKPtest_model.ckpt"}',
  58. 'size': 64
  59. },
  60. 'dataset_graph': DATASET_GRAPH
  61. }
  62. LINEAGE_FILTRATION_EXCEPT_RUN = {
  63. 'summary_dir': os.path.join(BASE_SUMMARY_DIR, 'except_run'),
  64. 'model_lineage': {
  65. 'loss_function': 'SoftmaxCrossEntropyWithLogits',
  66. 'train_dataset_path': None,
  67. 'train_dataset_count': 1024,
  68. 'test_dataset_path': None,
  69. 'test_dataset_count': None,
  70. 'user_defined': {},
  71. 'network': 'ResNet',
  72. 'optimizer': 'Momentum',
  73. 'learning_rate': 0.12,
  74. 'epoch': 10,
  75. 'batch_size': 32,
  76. 'device_num': 2,
  77. 'loss': 0.03,
  78. 'model_size': 64,
  79. 'metric': {},
  80. 'dataset_mark': 2
  81. },
  82. 'dataset_graph': DATASET_GRAPH
  83. }
  84. LINEAGE_FILTRATION_RUN1 = {
  85. 'summary_dir': os.path.join(BASE_SUMMARY_DIR, 'run1'),
  86. 'model_lineage': {
  87. 'loss_function': 'SoftmaxCrossEntropyWithLogits',
  88. 'train_dataset_path': None,
  89. 'train_dataset_count': 1024,
  90. 'test_dataset_path': None,
  91. 'test_dataset_count': 1024,
  92. 'user_defined': {
  93. 'info': 'info1',
  94. 'version': 'v1',
  95. 'eval_version': 'version2'
  96. },
  97. 'network': 'ResNet',
  98. 'optimizer': 'Momentum',
  99. 'learning_rate': 0.12,
  100. 'epoch': 14,
  101. 'batch_size': 32,
  102. 'device_num': 2,
  103. 'loss': None,
  104. 'model_size': 64,
  105. 'metric': {
  106. 'accuracy': 0.78
  107. },
  108. 'dataset_mark': 2
  109. },
  110. 'dataset_graph': DATASET_GRAPH
  111. }
  112. LINEAGE_FILTRATION_RUN2 = {
  113. 'summary_dir': os.path.join(BASE_SUMMARY_DIR, 'run2'),
  114. 'model_lineage': {
  115. 'loss_function': "SoftmaxCrossEntropyWithLogits",
  116. 'train_dataset_path': None,
  117. 'train_dataset_count': 1024,
  118. 'test_dataset_path': None,
  119. 'test_dataset_count': 1024,
  120. 'user_defined': {},
  121. 'network': "ResNet",
  122. 'optimizer': "Momentum",
  123. 'learning_rate': 0.12,
  124. 'epoch': 10,
  125. 'batch_size': 32,
  126. 'device_num': 2,
  127. 'loss': 0.03,
  128. 'model_size': 10,
  129. 'metric': {
  130. 'accuracy': 2.78
  131. },
  132. 'dataset_mark': 3
  133. },
  134. 'dataset_graph': DATASET_GRAPH
  135. }
  136. @pytest.mark.usefixtures("create_summary_dir")
  137. class TestModelApi(TestCase):
  138. """Test lineage information query interface."""
  139. @classmethod
  140. def setup_class(cls):
  141. """The initial process."""
  142. cls.dir_with_empty_lineage = os.path.join(
  143. BASE_SUMMARY_DIR, 'dir_with_empty_lineage'
  144. )
  145. os.makedirs(cls.dir_with_empty_lineage)
  146. ms_file = os.path.join(
  147. cls.dir_with_empty_lineage, 'empty.summary.1581499502.bms_MS'
  148. )
  149. lineage_file = ms_file + '_lineage'
  150. with open(ms_file, mode='w'):
  151. pass
  152. with open(lineage_file, mode='w'):
  153. pass
  154. cls.empty_dir = os.path.join(BASE_SUMMARY_DIR, 'empty_dir')
  155. os.makedirs(cls.empty_dir)
  156. @pytest.mark.level0
  157. @pytest.mark.platform_arm_ascend_training
  158. @pytest.mark.platform_x86_gpu_training
  159. @pytest.mark.platform_x86_ascend_training
  160. @pytest.mark.platform_x86_cpu
  161. @pytest.mark.env_single
  162. def test_get_summary_lineage(self):
  163. """Test the interface of get_summary_lineage."""
  164. total_res = get_summary_lineage(None, SUMMARY_DIR)
  165. partial_res1 = get_summary_lineage(None, SUMMARY_DIR, ['hyper_parameters'])
  166. partial_res2 = get_summary_lineage(None, SUMMARY_DIR, ['metric', 'algorithm'])
  167. expect_total_res = LINEAGE_INFO_RUN1
  168. expect_partial_res1 = {
  169. 'summary_dir': os.path.join(BASE_SUMMARY_DIR, 'run1'),
  170. 'hyper_parameters': {
  171. 'optimizer': 'Momentum',
  172. 'learning_rate': 0.12,
  173. 'loss_function': 'SoftmaxCrossEntropyWithLogits',
  174. 'epoch': 14,
  175. 'parallel_mode': 'stand_alone',
  176. 'device_num': 2,
  177. 'batch_size': 32
  178. }
  179. }
  180. expect_partial_res2 = {
  181. 'summary_dir': os.path.join(BASE_SUMMARY_DIR, 'run1'),
  182. 'metric': {
  183. 'accuracy': 0.78
  184. },
  185. 'algorithm': {
  186. 'network': 'ResNet'
  187. }
  188. }
  189. assert_equal_lineages(expect_total_res, total_res, self.assertDictEqual)
  190. assert_equal_lineages(expect_partial_res1, partial_res1, self.assertDictEqual)
  191. assert_equal_lineages(expect_partial_res2, partial_res2, self.assertDictEqual)
  192. # the lineage summary file is empty
  193. result = get_summary_lineage(None, self.dir_with_empty_lineage)
  194. assert {} == result
  195. # keys is empty list
  196. expect_result = {
  197. 'summary_dir': SUMMARY_DIR
  198. }
  199. result = get_summary_lineage(None, SUMMARY_DIR, [])
  200. assert expect_result == result
  201. @pytest.mark.level0
  202. @pytest.mark.platform_arm_ascend_training
  203. @pytest.mark.platform_x86_gpu_training
  204. @pytest.mark.platform_x86_ascend_training
  205. @pytest.mark.platform_x86_cpu
  206. @pytest.mark.env_single
  207. def test_get_summary_lineage_exception_1(self):
  208. """Test the interface of get_summary_lineage with exception."""
  209. # summary path does not exist
  210. self.assertRaisesRegex(
  211. LineageParamSummaryPathError,
  212. 'The summary path does not exist or is not a dir.',
  213. get_summary_lineage,
  214. None,
  215. '/tmp/fake/dir'
  216. )
  217. # summary path is relative path
  218. self.assertRaisesRegex(
  219. LineageParamSummaryPathError,
  220. 'The summary path is invalid.',
  221. get_summary_lineage,
  222. None,
  223. 'tmp'
  224. )
  225. # the type of input param is invalid
  226. self.assertRaisesRegex(
  227. LineageParamSummaryPathError,
  228. 'The summary path is invalid.',
  229. get_summary_lineage,
  230. None,
  231. ['/root/linage1', '/root/lineage2']
  232. )
  233. # summary path is empty str
  234. self.assertRaisesRegex(
  235. LineageParamSummaryPathError,
  236. 'The summary path is invalid.',
  237. get_summary_lineage,
  238. None,
  239. '',
  240. keys=None
  241. )
  242. # summary path invalid
  243. self.assertRaisesRegex(
  244. LineageParamSummaryPathError,
  245. 'The summary path is invalid.',
  246. get_summary_lineage,
  247. None,
  248. '\\',
  249. keys=None
  250. )
  251. @pytest.mark.level0
  252. @pytest.mark.platform_arm_ascend_training
  253. @pytest.mark.platform_x86_gpu_training
  254. @pytest.mark.platform_x86_ascend_training
  255. @pytest.mark.platform_x86_cpu
  256. @pytest.mark.env_single
  257. def test_get_summary_lineage_exception_2(self):
  258. """Test the interface of get_summary_lineage with exception."""
  259. # keys is invalid
  260. self.assertRaisesRegex(
  261. LineageParamValueError,
  262. 'Keys must be in',
  263. get_summary_lineage,
  264. None,
  265. SUMMARY_DIR,
  266. ['metric', 'fake_name']
  267. )
  268. self.assertRaisesRegex(
  269. LineageParamTypeError,
  270. 'Element of keys must be str.',
  271. get_summary_lineage,
  272. None,
  273. SUMMARY_DIR,
  274. [1, 2, 3]
  275. )
  276. @pytest.mark.level0
  277. @pytest.mark.platform_arm_ascend_training
  278. @pytest.mark.platform_x86_gpu_training
  279. @pytest.mark.platform_x86_ascend_training
  280. @pytest.mark.platform_x86_cpu
  281. @pytest.mark.env_single
  282. def test_get_summary_lineage_exception_3(self):
  283. """Test the interface of get_summary_lineage with exception."""
  284. for keys in [0, 0.1, True, (3, 4), {'a': 'b'}]:
  285. self.assertRaisesRegex(
  286. LineageParamTypeError,
  287. 'Keys must be list.',
  288. get_summary_lineage,
  289. None,
  290. SUMMARY_DIR,
  291. keys
  292. )
  293. @pytest.mark.level0
  294. @pytest.mark.platform_arm_ascend_training
  295. @pytest.mark.platform_x86_gpu_training
  296. @pytest.mark.platform_x86_ascend_training
  297. @pytest.mark.platform_x86_cpu
  298. @pytest.mark.env_single
  299. def test_filter_summary_lineage(self):
  300. """Test the interface of filter_summary_lineage."""
  301. expect_result = {
  302. 'customized': event_data.CUSTOMIZED__1,
  303. 'object': [
  304. LINEAGE_FILTRATION_EXCEPT_RUN,
  305. LINEAGE_FILTRATION_RUN1,
  306. LINEAGE_FILTRATION_RUN2
  307. ],
  308. 'count': 3
  309. }
  310. search_condition = {
  311. 'sorted_name': 'summary_dir'
  312. }
  313. res = filter_summary_lineage(None, BASE_SUMMARY_DIR, search_condition)
  314. expect_objects = expect_result.get('object')
  315. for idx, res_object in enumerate(res.get('object')):
  316. expect_objects[idx]['model_lineage']['dataset_mark'] = res_object['model_lineage'].get('dataset_mark')
  317. assert_equal_lineages(expect_result, res, self.assertDictEqual)
  318. expect_result = {
  319. 'customized': {},
  320. 'object': [],
  321. 'count': 0
  322. }
  323. res = filter_summary_lineage(None, self.dir_with_empty_lineage)
  324. expect_objects = expect_result.get('object')
  325. for idx, res_object in enumerate(res.get('object')):
  326. expect_objects[idx]['model_lineage']['dataset_mark'] = res_object['model_lineage'].get('dataset_mark')
  327. assert_equal_lineages(expect_result, res, self.assertDictEqual)
  328. @pytest.mark.level0
  329. @pytest.mark.platform_arm_ascend_training
  330. @pytest.mark.platform_x86_gpu_training
  331. @pytest.mark.platform_x86_ascend_training
  332. @pytest.mark.platform_x86_cpu
  333. @pytest.mark.env_single
  334. def test_filter_summary_lineage_with_condition_1(self):
  335. """Test the interface of filter_summary_lineage with condition."""
  336. search_condition = {
  337. 'summary_dir': {
  338. 'in': [
  339. SUMMARY_DIR,
  340. SUMMARY_DIR_2
  341. ]
  342. },
  343. 'metric/accuracy': {
  344. 'lt': 3.0,
  345. 'gt': 0.5
  346. },
  347. 'sorted_name': 'metric/accuracy',
  348. 'sorted_type': 'descending',
  349. 'limit': 3,
  350. 'offset': 0
  351. }
  352. expect_result = {
  353. 'customized': event_data.CUSTOMIZED__1,
  354. 'object': [
  355. LINEAGE_FILTRATION_RUN2,
  356. LINEAGE_FILTRATION_RUN1
  357. ],
  358. 'count': 2
  359. }
  360. partial_res = filter_summary_lineage(None, BASE_SUMMARY_DIR, search_condition)
  361. expect_objects = expect_result.get('object')
  362. for idx, res_object in enumerate(partial_res.get('object')):
  363. expect_objects[idx]['model_lineage']['dataset_mark'] = res_object['model_lineage'].get('dataset_mark')
  364. assert_equal_lineages(expect_result, partial_res, self.assertDictEqual)
  365. @pytest.mark.level0
  366. @pytest.mark.platform_arm_ascend_training
  367. @pytest.mark.platform_x86_gpu_training
  368. @pytest.mark.platform_x86_ascend_training
  369. @pytest.mark.platform_x86_cpu
  370. @pytest.mark.env_single
  371. def test_filter_summary_lineage_with_condition_2(self):
  372. """Test the interface of filter_summary_lineage with condition."""
  373. search_condition = {
  374. 'summary_dir': {
  375. 'in': [
  376. './run1',
  377. './run2'
  378. ]
  379. },
  380. 'metric/accuracy': {
  381. 'lt': 3.0,
  382. 'gt': 0.5
  383. },
  384. 'sorted_name': 'metric/accuracy',
  385. 'sorted_type': 'descending',
  386. 'limit': 3,
  387. 'offset': 0
  388. }
  389. expect_result = {
  390. 'customized': event_data.CUSTOMIZED__1,
  391. 'object': [
  392. LINEAGE_FILTRATION_RUN2,
  393. LINEAGE_FILTRATION_RUN1
  394. ],
  395. 'count': 2
  396. }
  397. partial_res = filter_summary_lineage(None, BASE_SUMMARY_DIR, search_condition)
  398. expect_objects = expect_result.get('object')
  399. for idx, res_object in enumerate(partial_res.get('object')):
  400. expect_objects[idx]['model_lineage']['dataset_mark'] = res_object['model_lineage'].get('dataset_mark')
  401. assert_equal_lineages(expect_result, partial_res, self.assertDictEqual)
  402. @pytest.mark.level0
  403. @pytest.mark.platform_arm_ascend_training
  404. @pytest.mark.platform_x86_gpu_training
  405. @pytest.mark.platform_x86_ascend_training
  406. @pytest.mark.platform_x86_cpu
  407. @pytest.mark.env_single
  408. def test_filter_summary_lineage_with_condition_3(self):
  409. """Test the interface of filter_summary_lineage with condition."""
  410. search_condition1 = {
  411. 'batch_size': {
  412. 'ge': 30
  413. },
  414. 'sorted_name': 'metric/accuracy',
  415. }
  416. expect_result = {
  417. 'customized': event_data.CUSTOMIZED__1,
  418. 'object': [
  419. LINEAGE_FILTRATION_EXCEPT_RUN,
  420. LINEAGE_FILTRATION_RUN1,
  421. LINEAGE_FILTRATION_RUN2
  422. ],
  423. 'count': 3
  424. }
  425. partial_res1 = filter_summary_lineage(None, BASE_SUMMARY_DIR, search_condition1)
  426. expect_objects = expect_result.get('object')
  427. for idx, res_object in enumerate(partial_res1.get('object')):
  428. expect_objects[idx]['model_lineage']['dataset_mark'] = res_object['model_lineage'].get('dataset_mark')
  429. assert_equal_lineages(expect_result, partial_res1, self.assertDictEqual)
  430. search_condition2 = {
  431. 'batch_size': {
  432. 'lt': 30
  433. },
  434. 'lineage_type': {
  435. 'eq': 'model'
  436. },
  437. }
  438. expect_result = {
  439. 'customized': {},
  440. 'object': [],
  441. 'count': 0
  442. }
  443. partial_res2 = filter_summary_lineage(None, BASE_SUMMARY_DIR, search_condition2)
  444. assert expect_result == partial_res2
  445. @pytest.mark.level0
  446. @pytest.mark.platform_arm_ascend_training
  447. @pytest.mark.platform_x86_gpu_training
  448. @pytest.mark.platform_x86_ascend_training
  449. @pytest.mark.platform_x86_cpu
  450. @pytest.mark.env_single
  451. def test_filter_summary_lineage_with_lineage_type(self):
  452. """Test the interface of filter_summary_lineage with lineage_type."""
  453. summary_dir = os.path.join(BASE_SUMMARY_DIR, 'except_run')
  454. search_condition = {
  455. 'summary_dir': {
  456. 'in': [summary_dir]
  457. },
  458. 'lineage_type': {
  459. 'eq': 'dataset'
  460. },
  461. }
  462. expect_result = {
  463. 'customized': {},
  464. 'object': [
  465. {
  466. 'summary_dir': summary_dir,
  467. 'dataset_graph': DATASET_GRAPH
  468. }
  469. ],
  470. 'count': 1
  471. }
  472. res = filter_summary_lineage(None, BASE_SUMMARY_DIR, search_condition)
  473. assert expect_result == res
  474. @pytest.mark.level0
  475. @pytest.mark.platform_arm_ascend_training
  476. @pytest.mark.platform_x86_gpu_training
  477. @pytest.mark.platform_x86_ascend_training
  478. @pytest.mark.platform_x86_cpu
  479. @pytest.mark.env_single
  480. def test_filter_summary_lineage_exception_1(self):
  481. """Test the abnormal execution of the filter_summary_lineage interface."""
  482. # summary base dir is relative path
  483. self.assertRaisesRegex(
  484. LineageParamSummaryPathError,
  485. 'The summary path is invalid.',
  486. filter_summary_lineage,
  487. None,
  488. 'relative_path'
  489. )
  490. # summary base dir does not exist
  491. self.assertRaisesRegex(
  492. LineageParamSummaryPathError,
  493. 'The summary path does not exist or is not a dir.',
  494. filter_summary_lineage,
  495. None,
  496. '/path/does/not/exist'
  497. )
  498. # no summary log file under summary_base_dir
  499. self.assertRaisesRegex(
  500. LineageFileNotFoundError,
  501. 'There is no summary log file under summary_base_dir.',
  502. filter_summary_lineage,
  503. None,
  504. self.empty_dir
  505. )
  506. @pytest.mark.level0
  507. @pytest.mark.platform_arm_ascend_training
  508. @pytest.mark.platform_x86_gpu_training
  509. @pytest.mark.platform_x86_ascend_training
  510. @pytest.mark.platform_x86_cpu
  511. @pytest.mark.env_single
  512. def test_filter_summary_lineage_exception_2(self):
  513. """Test the abnormal execution of the filter_summary_lineage interface."""
  514. # search_condition type error
  515. search_condition = {
  516. 'summary_dir': 1.0
  517. }
  518. self.assertRaisesRegex(
  519. LineageSearchConditionParamError,
  520. 'The search_condition element summary_dir should be dict.',
  521. filter_summary_lineage,
  522. None,
  523. BASE_SUMMARY_DIR,
  524. search_condition
  525. )
  526. # only sorted_type (no sorted_name)
  527. search_condition = {
  528. 'sorted_type': 'descending'
  529. }
  530. self.assertRaisesRegex(
  531. LineageSearchConditionParamError,
  532. 'The sorted_name have to exist when sorted_type exists.',
  533. filter_summary_lineage,
  534. None,
  535. BASE_SUMMARY_DIR,
  536. search_condition
  537. )
  538. # search condition is not dict or None
  539. search_condition = []
  540. self.assertRaisesRegex(
  541. LineageSearchConditionParamError,
  542. 'Invalid search_condition type, it should be dict.',
  543. filter_summary_lineage,
  544. None,
  545. BASE_SUMMARY_DIR,
  546. search_condition
  547. )
  548. # the condition of limit is invalid
  549. search_condition = {
  550. 'limit': True
  551. }
  552. self.assertRaisesRegex(
  553. LineageSearchConditionParamError,
  554. 'The limit must be int.',
  555. filter_summary_lineage,
  556. None,
  557. BASE_SUMMARY_DIR,
  558. search_condition
  559. )
  560. @pytest.mark.level0
  561. @pytest.mark.platform_arm_ascend_training
  562. @pytest.mark.platform_x86_gpu_training
  563. @pytest.mark.platform_x86_ascend_training
  564. @pytest.mark.platform_x86_cpu
  565. @pytest.mark.env_single
  566. def test_filter_summary_lineage_exception_3(self):
  567. """Test the abnormal execution of the filter_summary_lineage interface."""
  568. # the condition of offset is invalid
  569. search_condition = {
  570. 'offset': 1.0
  571. }
  572. self.assertRaisesRegex(
  573. LineageSearchConditionParamError,
  574. 'The offset must be int.',
  575. filter_summary_lineage,
  576. None,
  577. BASE_SUMMARY_DIR,
  578. search_condition
  579. )
  580. # the search attribute not supported
  581. search_condition = {
  582. 'dataset_graph': {
  583. 'le': 1
  584. }
  585. }
  586. self.assertRaisesRegex(
  587. LineageSearchConditionParamError,
  588. 'The search attribute not supported.',
  589. filter_summary_lineage,
  590. None,
  591. BASE_SUMMARY_DIR,
  592. search_condition
  593. )
  594. @pytest.mark.level0
  595. @pytest.mark.platform_arm_ascend_training
  596. @pytest.mark.platform_x86_gpu_training
  597. @pytest.mark.platform_x86_ascend_training
  598. @pytest.mark.platform_x86_cpu
  599. @pytest.mark.env_single
  600. def test_filter_summary_lineage_exception_4(self):
  601. """Test the abnormal execution of the filter_summary_lineage interface."""
  602. # the sorted_type not supported
  603. search_condition = {
  604. 'sorted_name': 'summary_dir',
  605. 'sorted_type': 'xxx'
  606. }
  607. self.assertRaisesRegex(
  608. LineageSearchConditionParamError,
  609. 'The sorted_type must be ascending or descending',
  610. filter_summary_lineage,
  611. None,
  612. BASE_SUMMARY_DIR,
  613. search_condition
  614. )
  615. # the search condition not supported
  616. search_condition = {
  617. 'batch_size': {
  618. 'dd': 30
  619. }
  620. }
  621. self.assertRaisesRegex(
  622. LineageSearchConditionParamError,
  623. 'The compare condition should be in',
  624. filter_summary_lineage,
  625. None,
  626. BASE_SUMMARY_DIR,
  627. search_condition
  628. )
  629. # the search condition type error
  630. search_condition = {
  631. 'metric/accuracy': {
  632. 'lt': 'xxx'
  633. }
  634. }
  635. self.assertRaisesRegex(
  636. LineageSearchConditionParamError,
  637. 'The parameter metric/accuracy is invalid.',
  638. filter_summary_lineage,
  639. None,
  640. BASE_SUMMARY_DIR,
  641. search_condition
  642. )
  643. @pytest.mark.level0
  644. @pytest.mark.platform_arm_ascend_training
  645. @pytest.mark.platform_x86_gpu_training
  646. @pytest.mark.platform_x86_ascend_training
  647. @pytest.mark.platform_x86_cpu
  648. @pytest.mark.env_single
  649. def test_filter_summary_lineage_exception_5(self):
  650. """Test the abnormal execution of the filter_summary_lineage interface."""
  651. # the summary dir is invalid in search condition
  652. search_condition = {
  653. 'summary_dir': {
  654. 'in': [
  655. 'xxx'
  656. ]
  657. }
  658. }
  659. self.assertRaisesRegex(
  660. LineageParamSummaryPathError,
  661. 'The summary path is invalid.',
  662. filter_summary_lineage,
  663. None,
  664. BASE_SUMMARY_DIR,
  665. search_condition
  666. )
  667. @pytest.mark.level0
  668. @pytest.mark.platform_arm_ascend_training
  669. @pytest.mark.platform_x86_gpu_training
  670. @pytest.mark.platform_x86_ascend_training
  671. @pytest.mark.platform_x86_cpu
  672. @pytest.mark.env_single
  673. def test_filter_summary_lineage_exception_6(self):
  674. """Test the abnormal execution of the filter_summary_lineage interface."""
  675. # gt > lt
  676. search_condition1 = {
  677. 'metric/accuracy': {
  678. 'gt': 1,
  679. 'lt': 0.5
  680. }
  681. }
  682. expect_result = {
  683. 'customized': {},
  684. 'object': [],
  685. 'count': 0
  686. }
  687. partial_res1 = filter_summary_lineage(None, BASE_SUMMARY_DIR, search_condition1)
  688. assert expect_result == partial_res1
  689. # the (offset + 1) * limit > count
  690. search_condition2 = {
  691. 'loss': {
  692. 'lt': 1
  693. },
  694. 'limit': 1,
  695. 'offset': 4
  696. }
  697. expect_result = {
  698. 'customized': {},
  699. 'object': [],
  700. 'count': 2
  701. }
  702. partial_res2 = filter_summary_lineage(None, BASE_SUMMARY_DIR, search_condition2)
  703. assert expect_result == partial_res2
  704. @pytest.mark.level0
  705. @pytest.mark.platform_arm_ascend_training
  706. @pytest.mark.platform_x86_gpu_training
  707. @pytest.mark.platform_x86_ascend_training
  708. @pytest.mark.platform_x86_cpu
  709. @pytest.mark.env_single
  710. def test_filter_summary_lineage_exception_7(self):
  711. """Test the abnormal execution of the filter_summary_lineage interface."""
  712. condition_keys = ["summary_dir", "lineage_type", "loss_function", "optimizer", "network", "dataset_mark"]
  713. for condition_key in condition_keys:
  714. # the condition type not supported in summary_dir and lineage_type
  715. search_condition = {
  716. condition_key: {
  717. 'lt': '/xxx'
  718. }
  719. }
  720. self.assertRaisesRegex(
  721. LineageSearchConditionParamError,
  722. f'The parameter {condition_key} is invalid. Its operation should be `eq`, `in` or `not_in`.',
  723. filter_summary_lineage,
  724. None,
  725. BASE_SUMMARY_DIR,
  726. search_condition
  727. )
  728. @pytest.mark.level0
  729. @pytest.mark.platform_arm_ascend_training
  730. @pytest.mark.platform_x86_gpu_training
  731. @pytest.mark.platform_x86_ascend_training
  732. @pytest.mark.platform_x86_cpu
  733. @pytest.mark.env_single
  734. def test_filter_summary_lineage_exception_8(self):
  735. """Test the abnormal execution of the filter_summary_lineage interface."""
  736. invalid_lineage_types = ['xxx', None]
  737. for lineage_type in invalid_lineage_types:
  738. search_condition = {
  739. 'lineage_type': {
  740. 'eq': lineage_type
  741. }
  742. }
  743. self.assertRaisesRegex(
  744. LineageSearchConditionParamError,
  745. "The parameter lineage_type is invalid. It should be 'dataset' or 'model'.",
  746. filter_summary_lineage,
  747. None,
  748. BASE_SUMMARY_DIR,
  749. search_condition
  750. )
  751. @pytest.mark.level0
  752. @pytest.mark.platform_arm_ascend_training
  753. @pytest.mark.platform_x86_gpu_training
  754. @pytest.mark.platform_x86_ascend_training
  755. @pytest.mark.platform_x86_cpu
  756. @pytest.mark.env_single
  757. def test_filter_summary_lineage_exception_9(self):
  758. """Test the abnormal execution of the filter_summary_lineage interface."""
  759. invalid_sorted_names = ['xxx', 'metric_', 1]
  760. for sorted_name in invalid_sorted_names:
  761. search_condition = {
  762. 'sorted_name': sorted_name
  763. }
  764. self.assertRaisesRegex(
  765. LineageSearchConditionParamError,
  766. 'The sorted_name must be in',
  767. filter_summary_lineage,
  768. None,
  769. BASE_SUMMARY_DIR,
  770. search_condition
  771. )