test_workflow.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. # -*- coding:utf-8 -*-
  2. from unittest.mock import MagicMock
  3. import pytest
  4. from dw_base.ds.workflow import (
  5. find_schedule_by_workflow,
  6. find_workflow_by_name,
  7. gen_task_codes,
  8. get_workflow_full,
  9. list_workflow_names,
  10. release_schedule,
  11. release_workflow,
  12. )
  13. PC = 999 # 项目码占位
  14. def _make_client():
  15. return MagicMock()
  16. # --- find_workflow_by_name ---
  17. def test_find_workflow_by_name_hit():
  18. client = _make_client()
  19. client.get.return_value = {
  20. 'code': 0,
  21. 'data': {'totalList': [
  22. {'name': 'wf_a', 'code': 100},
  23. {'name': 'wf_b', 'code': 200},
  24. ]}
  25. }
  26. result = find_workflow_by_name(client, PC, 'wf_b')
  27. assert result == {'name': 'wf_b', 'code': 200}
  28. client.get.assert_called_once_with(
  29. '/projects/999/workflow-definition',
  30. params={'pageNo': 1, 'pageSize': 200, 'searchVal': ''},
  31. expect_business_ok=True,
  32. )
  33. def test_find_workflow_by_name_miss_returns_none():
  34. client = _make_client()
  35. client.get.return_value = {'code': 0, 'data': {'totalList': []}}
  36. assert find_workflow_by_name(client, PC, 'wf_x') is None
  37. def test_find_workflow_by_name_custom_page_size():
  38. client = _make_client()
  39. client.get.return_value = {'code': 0, 'data': {'totalList': []}}
  40. find_workflow_by_name(client, PC, 'x', page_size=50)
  41. assert client.get.call_args[1]['params']['pageSize'] == 50
  42. # --- list_workflow_names ---
  43. def test_list_workflow_names():
  44. client = _make_client()
  45. client.get.return_value = {
  46. 'code': 0,
  47. 'data': {'totalList': [
  48. {'name': 'a'}, {'name': 'b'}, {'name': 'c'},
  49. ]}
  50. }
  51. assert list_workflow_names(client, PC) == ['a', 'b', 'c']
  52. def test_list_workflow_names_empty():
  53. client = _make_client()
  54. client.get.return_value = {'code': 0, 'data': {'totalList': []}}
  55. assert list_workflow_names(client, PC) == []
  56. # --- get_workflow_full ---
  57. def test_get_workflow_full():
  58. client = _make_client()
  59. payload = {
  60. 'workflowDefinition': {'code': 100, 'name': 'x'},
  61. 'taskDefinitionList': [{'code': 1, 'version': 1}],
  62. 'workflowTaskRelationList': [],
  63. }
  64. client.get.return_value = {'code': 0, 'data': payload}
  65. assert get_workflow_full(client, PC, 100) == payload
  66. client.get.assert_called_once_with(
  67. '/projects/999/workflow-definition/100',
  68. expect_business_ok=True,
  69. )
  70. # --- gen_task_codes ---
  71. def test_gen_task_codes_default_one():
  72. client = _make_client()
  73. client.get.return_value = {'code': 0, 'data': [171234567890]}
  74. codes = gen_task_codes(client, PC)
  75. assert codes == [171234567890]
  76. client.get.assert_called_once_with(
  77. '/projects/999/task-definition/gen-task-codes',
  78. params={'genNum': 1},
  79. expect_business_ok=True,
  80. )
  81. def test_gen_task_codes_multi():
  82. client = _make_client()
  83. client.get.return_value = {'code': 0, 'data': [1, 2, 3]}
  84. assert gen_task_codes(client, PC, n=3) == [1, 2, 3]
  85. assert client.get.call_args[1]['params']['genNum'] == 3
  86. # --- find_schedule_by_workflow ---
  87. def test_find_schedule_hit():
  88. client = _make_client()
  89. client.get.return_value = {
  90. 'code': 0,
  91. 'data': {'totalList': [
  92. {'id': 5, 'workflowDefinitionCode': 100, 'releaseState': 'ONLINE'},
  93. ]}
  94. }
  95. s = find_schedule_by_workflow(client, PC, 100)
  96. assert s['id'] == 5
  97. assert s['releaseState'] == 'ONLINE'
  98. client.get.assert_called_once_with(
  99. '/projects/999/schedules',
  100. params={'pageNo': 1, 'pageSize': 100, 'searchVal': '',
  101. 'workflowDefinitionCode': 100},
  102. expect_business_ok=True,
  103. )
  104. def test_find_schedule_miss_returns_none():
  105. client = _make_client()
  106. client.get.return_value = {'code': 0, 'data': {'totalList': []}}
  107. assert find_schedule_by_workflow(client, PC, 100) is None
  108. def test_find_schedule_filters_mismatched_wf_code():
  109. """totalList 可能含其他 workflow 的 schedule(保险二次过滤)。"""
  110. client = _make_client()
  111. client.get.return_value = {
  112. 'code': 0,
  113. 'data': {'totalList': [
  114. {'id': 1, 'workflowDefinitionCode': 999},
  115. {'id': 2, 'workflowDefinitionCode': 100},
  116. ]}
  117. }
  118. s = find_schedule_by_workflow(client, PC, 100)
  119. assert s['id'] == 2
  120. # --- release_workflow ---
  121. def test_release_workflow_online():
  122. client = _make_client()
  123. client.post.return_value = {'code': 0}
  124. release_workflow(client, PC, 100, 'ONLINE')
  125. client.post.assert_called_once_with(
  126. '/projects/999/workflow-definition/100/release',
  127. form_data={'releaseState': 'ONLINE'},
  128. expect_business_ok=True,
  129. )
  130. def test_release_workflow_offline():
  131. client = _make_client()
  132. client.post.return_value = {'code': 0}
  133. release_workflow(client, PC, 100, 'OFFLINE')
  134. assert client.post.call_args[1]['form_data'] == {'releaseState': 'OFFLINE'}
  135. def test_release_workflow_invalid_state_raises():
  136. client = _make_client()
  137. with pytest.raises(ValueError, match="ONLINE.*OFFLINE"):
  138. release_workflow(client, PC, 100, 'PAUSE')
  139. client.post.assert_not_called()
  140. # --- release_schedule ---
  141. def test_release_schedule_online_uses_online_endpoint():
  142. client = _make_client()
  143. client.post.return_value = {'code': 0}
  144. release_schedule(client, PC, 5, 'ONLINE')
  145. client.post.assert_called_once_with(
  146. '/projects/999/schedules/5/online',
  147. form_data={},
  148. expect_business_ok=True,
  149. )
  150. def test_release_schedule_offline_uses_offline_endpoint():
  151. client = _make_client()
  152. client.post.return_value = {'code': 0}
  153. release_schedule(client, PC, 5, 'OFFLINE')
  154. assert client.post.call_args[0][0] == '/projects/999/schedules/5/offline'
  155. def test_release_schedule_invalid_state_raises():
  156. client = _make_client()
  157. with pytest.raises(ValueError, match="ONLINE.*OFFLINE"):
  158. release_schedule(client, PC, 5, 'PAUSE')
  159. client.post.assert_not_called()