crons.service.test.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import mockMilvusClient from '../__mocks__/milvus/milvusClient';
  2. import { schedule } from 'node-cron';
  3. import { CollectionsService } from '../../collections/collections.service';
  4. import { CronsService, SchedulerRegistry } from '../../crons/crons.service';
  5. import { MilvusService } from '../../milvus/milvus.service';
  6. import { WS_EVENTS, WS_EVENTS_TYPE } from '../../utils/Const';
  7. import { insightCacheForTest, mockAddress } from '../__mocks__/consts';
  8. import { MilvusClient } from '@zilliz/milvus2-sdk-node/dist/milvus';
  9. // mock Milvus client
  10. jest.mock('@zilliz/milvus2-sdk-node', () => {
  11. return {
  12. MilvusClient: mockMilvusClient,
  13. };
  14. });
  15. // mock node-cron
  16. jest.mock('node-cron', () => {
  17. return {
  18. schedule: jest.fn(),
  19. };
  20. });
  21. // mock variable
  22. const mockCronFrequency = '30 00 * * *';
  23. const mockCronEverySec = '* * * * * *';
  24. const mockCb = jest.fn();
  25. const mockErrCb = jest.fn(() => {
  26. throw new Error('error');
  27. });
  28. const mockName = 'j1';
  29. const mockSecName = 'everySec';
  30. describe('test crons service', () => {
  31. let milvusService: any;
  32. let collectionService: any;
  33. let cronsService: any;
  34. let schedulerRegistry: any;
  35. const handleStartTask = jest.fn();
  36. const handleEndTask = jest.fn();
  37. const setup = async () => {
  38. milvusService = new MilvusService();
  39. MilvusService.activeAddress = mockAddress;
  40. MilvusService.activeMilvusClient = new MilvusClient(mockAddress);
  41. await milvusService.connectMilvus(
  42. { address: mockAddress },
  43. insightCacheForTest
  44. );
  45. collectionService = new CollectionsService(milvusService);
  46. schedulerRegistry = new SchedulerRegistry([]);
  47. cronsService = new CronsService(collectionService, schedulerRegistry);
  48. };
  49. beforeAll(async () => {
  50. // setup Milvus service and connect to mock Milvus client
  51. await setup();
  52. });
  53. beforeEach(() => {
  54. // mock schedule
  55. (schedule as jest.Mock).mockImplementationOnce((frequency, callback) => {
  56. callback();
  57. return {
  58. start: handleStartTask,
  59. stop: handleEndTask,
  60. };
  61. });
  62. });
  63. afterAll(() => {
  64. milvusService = null;
  65. collectionService = null;
  66. schedulerRegistry = null;
  67. cronsService = null;
  68. });
  69. test('test SchedulerRegistry related methods', async () => {
  70. schedulerRegistry.setCronJob(mockName, mockCronFrequency, () => mockCb());
  71. expect(mockCb).toBeCalledTimes(1);
  72. expect(schedule).toBeCalledWith(mockCronFrequency, expect.any(Function));
  73. const job = schedulerRegistry.getCronJob(mockName);
  74. expect(job).toEqual({
  75. start: handleStartTask,
  76. stop: handleEndTask,
  77. });
  78. schedulerRegistry.setCronJob(mockName, mockCronFrequency, () => mockCb());
  79. expect(handleEndTask).toBeCalled();
  80. schedulerRegistry.setCronJobEverySecond(mockSecName, () => mockCb());
  81. expect(schedule).toBeCalledWith(mockCronEverySec, expect.any(Function));
  82. schedulerRegistry.setCronJob(mockName, mockCronFrequency, () => mockCb());
  83. expect(handleEndTask).toBeCalled();
  84. schedulerRegistry.setCronJob(mockName, mockCronFrequency, () =>
  85. mockErrCb()
  86. );
  87. expect(() => {
  88. mockErrCb();
  89. }).toThrow();
  90. });
  91. test('test CronService related methods', async () => {
  92. try {
  93. await cronsService.toggleCronJobByName({
  94. name: WS_EVENTS.COLLECTION,
  95. type: WS_EVENTS_TYPE.STOP,
  96. });
  97. } catch (err) {
  98. expect(err.message).toBe('No existed job entity');
  99. }
  100. await cronsService.toggleCronJobByName({
  101. name: WS_EVENTS.COLLECTION,
  102. type: WS_EVENTS_TYPE.START,
  103. });
  104. expect(schedule).toBeCalledWith(mockCronEverySec, expect.any(Function));
  105. schedulerRegistry.setCronJob(WS_EVENTS.COLLECTION, mockCronFrequency, () =>
  106. mockCb()
  107. );
  108. await cronsService.toggleCronJobByName({
  109. name: WS_EVENTS.COLLECTION,
  110. type: WS_EVENTS_TYPE.START,
  111. });
  112. expect(handleStartTask).toBeCalled();
  113. await cronsService.toggleCronJobByName({
  114. name: WS_EVENTS.COLLECTION,
  115. type: WS_EVENTS_TYPE.STOP,
  116. });
  117. expect(handleStartTask).toBeCalled();
  118. try {
  119. await cronsService.toggleCronJobByName({
  120. name: mockName,
  121. type: WS_EVENTS_TYPE.STOP,
  122. });
  123. } catch (err) {
  124. expect(err.message).toBe('Unsupported event type');
  125. }
  126. });
  127. test('test getCollections error', async () => {
  128. // reset setup to trigger error
  129. const newCollectionService = new CollectionsService(milvusService);
  130. const newSchedulerRegistry = new SchedulerRegistry([]);
  131. newCollectionService.getAllCollections = () => {
  132. throw new Error('error');
  133. };
  134. const newCronsService = new CronsService(
  135. newCollectionService,
  136. newSchedulerRegistry
  137. );
  138. await newCronsService.getCollections(
  139. WS_EVENTS.COLLECTION,
  140. '127.0.0.1:19530'
  141. );
  142. expect(schedule).toBeCalledWith(mockCronEverySec, expect.any(Function));
  143. expect(handleEndTask).toBeCalled();
  144. });
  145. });