This commit is contained in:
+1
-1
@@ -388,7 +388,7 @@ class ShopDataCrawlTaskServiceRetentionTest {
|
||||
when(taskDistributedLockService.acquire(MODULE_TYPE, TASK_ID))
|
||||
.thenReturn(mock(TaskDistributedLockService.LockHandle.class));
|
||||
when(fileResultMapper.selectById(RESULT_ID)).thenReturn(currentRow);
|
||||
when(fileResultMapper.selectById(200L)).thenReturn(previous);
|
||||
when(fileResultMapper.selectBatchIds(List.of(200L))).thenReturn(List.of(previous));
|
||||
when(fileResultMapper.selectList(any())).thenReturn(List.of());
|
||||
when(dailyFileService.findByLatestResultId(RESULT_ID)).thenReturn(List.of(daily));
|
||||
when(dailyFileService.findMembersByResultId(RESULT_ID)).thenReturn(List.of(removedMember));
|
||||
|
||||
+107
@@ -3,6 +3,7 @@ package com.nanri.aiimage.modules.ziniao.service;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.nanri.aiimage.common.exception.BusinessException;
|
||||
import com.nanri.aiimage.config.ZiniaoProperties;
|
||||
import com.nanri.aiimage.modules.ziniao.memory.model.entity.ZiniaoMemoryStoreEntity;
|
||||
import com.nanri.aiimage.modules.ziniao.memory.service.ZiniaoMemoryStoreService;
|
||||
import com.nanri.aiimage.modules.ziniao.memory.service.ZiniaoTransientCacheService;
|
||||
import com.nanri.aiimage.modules.ziniao.model.cache.ZiniaoShopIndexEntryDto;
|
||||
@@ -17,6 +18,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -24,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
@@ -209,6 +212,110 @@ class ZiniaoShopIndexServiceTest {
|
||||
assertEquals(Integer.valueOf(0), cursor.getNextApiKeyOffset());
|
||||
}
|
||||
|
||||
@Test
|
||||
void staleRowsWithoutPayloadChangeSkipRewriteAndOnlyTouchExpiry() throws Exception {
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount key = new ZiniaoApiKeyProvider.ApiKeyAccount("key", "acct");
|
||||
when(ziniaoApiKeyProvider.listApiKeyAccounts()).thenReturn(List.of(key));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("key")).thenReturn(1L);
|
||||
when(ziniaoAuthService.getOrLoadStaffForIndex("key", 1L)).thenReturn(List.of(staff(11L)));
|
||||
when(ziniaoAuthService.getOrLoadUserStoresForIndex("key", 1L, 11L)).thenReturn(List.of());
|
||||
|
||||
ZiniaoShopIndexEntryDto dto = new ZiniaoShopIndexEntryDto();
|
||||
dto.setNormalizedShopName("shop-a");
|
||||
dto.setCompanyName("acct");
|
||||
dto.setStatus("STALE");
|
||||
dto.setMessage("店铺索引已过期,请等待后台刷新");
|
||||
dto.setLastRefreshedAt(1000L);
|
||||
String payload = new ObjectMapper().writeValueAsString(dto);
|
||||
ZiniaoMemoryStoreEntity row = new ZiniaoMemoryStoreEntity();
|
||||
row.setId(1L);
|
||||
row.setCacheType("SHOP_INDEX_ENTRY");
|
||||
row.setCacheKey("n:shop-a");
|
||||
row.setCompanyName("acct");
|
||||
row.setPayloadJson(payload);
|
||||
row.setExpiresAt(LocalDateTime.now().plusHours(12));
|
||||
when(ziniaoMemoryStoreService.listAliveEntitiesByType("SHOP_INDEX_ENTRY", 10000)).thenReturn(List.of(row));
|
||||
|
||||
service.refreshAllShopIndex();
|
||||
|
||||
verify(ziniaoMemoryStoreService, never()).updateStaleMarks(anyList());
|
||||
verify(ziniaoMemoryStoreService).touchExpiryBatch(anyList(), any(Duration.class));
|
||||
verify(ziniaoMemoryStoreService, never()).put(any(), any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeEntryMissingFromThisRoundGetsRewrittenAsStale() throws Exception {
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount key = new ZiniaoApiKeyProvider.ApiKeyAccount("key", "acct");
|
||||
when(ziniaoApiKeyProvider.listApiKeyAccounts()).thenReturn(List.of(key));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("key")).thenReturn(1L);
|
||||
when(ziniaoAuthService.getOrLoadStaffForIndex("key", 1L)).thenReturn(List.of(staff(11L)));
|
||||
when(ziniaoAuthService.getOrLoadUserStoresForIndex("key", 1L, 11L)).thenReturn(List.of());
|
||||
|
||||
ZiniaoShopIndexEntryDto dto = new ZiniaoShopIndexEntryDto();
|
||||
dto.setNormalizedShopName("shop-a");
|
||||
dto.setStatus("ACTIVE");
|
||||
dto.setLastRefreshedAt(1000L);
|
||||
String payload = new ObjectMapper().writeValueAsString(dto);
|
||||
ZiniaoMemoryStoreEntity row = new ZiniaoMemoryStoreEntity();
|
||||
row.setId(1L);
|
||||
row.setCacheType("SHOP_INDEX_ENTRY");
|
||||
row.setCacheKey("n:shop-a");
|
||||
row.setCompanyName("acct");
|
||||
row.setPayloadJson(payload);
|
||||
row.setExpiresAt(LocalDateTime.now().plusHours(12));
|
||||
when(ziniaoMemoryStoreService.listAliveEntitiesByType("SHOP_INDEX_ENTRY", 10000)).thenReturn(List.of(row));
|
||||
|
||||
service.refreshAllShopIndex();
|
||||
|
||||
ArgumentCaptor<List<ZiniaoMemoryStoreEntity>> captor = ArgumentCaptor.forClass(List.class);
|
||||
verify(ziniaoMemoryStoreService).updateStaleMarks(captor.capture());
|
||||
assertEquals(1, captor.getValue().size());
|
||||
ZiniaoMemoryStoreEntity updated = captor.getValue().get(0);
|
||||
assertEquals(1L, updated.getId());
|
||||
assertTrue(updated.getPayloadJson().contains("\"STALE\""));
|
||||
assertEquals("店铺索引已过期,请等待后台刷新",
|
||||
new ObjectMapper().readTree(updated.getPayloadJson()).get("message").asText());
|
||||
verify(ziniaoMemoryStoreService, never()).touchExpiryBatch(anyList(), any(Duration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeKeysFromThisRoundAreSkippedInStaleMarking() throws Exception {
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount key = new ZiniaoApiKeyProvider.ApiKeyAccount("key", "acct");
|
||||
when(ziniaoApiKeyProvider.listApiKeyAccounts()).thenReturn(List.of(key));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("key")).thenReturn(1L);
|
||||
when(ziniaoAuthService.getOrLoadStaffForIndex("key", 1L)).thenReturn(List.of(staff(11L)));
|
||||
when(ziniaoAuthService.getOrLoadUserStoresForIndex("key", 1L, 11L)).thenReturn(List.of(shop("s-1", "shop-1")));
|
||||
|
||||
ZiniaoShopIndexEntryDto activeDto = new ZiniaoShopIndexEntryDto();
|
||||
activeDto.setNormalizedShopName("shop-1");
|
||||
activeDto.setStatus("ACTIVE");
|
||||
ZiniaoMemoryStoreEntity activeRow = new ZiniaoMemoryStoreEntity();
|
||||
activeRow.setId(1L);
|
||||
activeRow.setCacheType("SHOP_INDEX_ENTRY");
|
||||
activeRow.setCacheKey("s:s-1");
|
||||
activeRow.setPayloadJson(new ObjectMapper().writeValueAsString(activeDto));
|
||||
activeRow.setExpiresAt(LocalDateTime.now().plusHours(12));
|
||||
|
||||
ZiniaoShopIndexEntryDto staleDto = new ZiniaoShopIndexEntryDto();
|
||||
staleDto.setNormalizedShopName("shop-2");
|
||||
staleDto.setStatus("ACTIVE");
|
||||
ZiniaoMemoryStoreEntity staleRow = new ZiniaoMemoryStoreEntity();
|
||||
staleRow.setId(2L);
|
||||
staleRow.setCacheType("SHOP_INDEX_ENTRY");
|
||||
staleRow.setCacheKey("n:shop-2");
|
||||
staleRow.setPayloadJson(new ObjectMapper().writeValueAsString(staleDto));
|
||||
staleRow.setExpiresAt(LocalDateTime.now().plusHours(12));
|
||||
when(ziniaoMemoryStoreService.listAliveEntitiesByType("SHOP_INDEX_ENTRY", 10000))
|
||||
.thenReturn(List.of(activeRow, staleRow));
|
||||
|
||||
service.refreshAllShopIndex();
|
||||
|
||||
ArgumentCaptor<List<ZiniaoMemoryStoreEntity>> captor = ArgumentCaptor.forClass(List.class);
|
||||
verify(ziniaoMemoryStoreService).updateStaleMarks(captor.capture());
|
||||
assertEquals(1, captor.getValue().size());
|
||||
assertEquals("n:shop-2", captor.getValue().get(0).getCacheKey());
|
||||
}
|
||||
|
||||
private ZiniaoShopIndexRefreshCursorDto capturedCursor() {
|
||||
ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(ziniaoTransientCacheService, times(2)).put(
|
||||
|
||||
Reference in New Issue
Block a user