From 2e486f02ffb83192fd46fd231fb3604e1b982416 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Fri, 6 Jun 2025 12:17:04 -0400 Subject: implement no-op caches for testing --- packages/backend/test/misc/noOpCaches.ts | 196 +++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 packages/backend/test/misc/noOpCaches.ts (limited to 'packages/backend/test') diff --git a/packages/backend/test/misc/noOpCaches.ts b/packages/backend/test/misc/noOpCaches.ts new file mode 100644 index 0000000000..373c7bddcc --- /dev/null +++ b/packages/backend/test/misc/noOpCaches.ts @@ -0,0 +1,196 @@ +/* + * SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import * as Redis from 'ioredis'; +import { Inject } from '@nestjs/common'; +import { FakeInternalEventService } from './FakeInternalEventService.js'; +import type { BlockingsRepository, FollowingsRepository, MiFollowing, MiUser, MiUserProfile, MutingsRepository, RenoteMutingsRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js'; +import type { MiLocalUser } from '@/models/User.js'; +import { MemoryKVCache, MemorySingleCache, QuantumKVCache, QuantumKVOpts, RedisKVCache, RedisSingleCache } from '@/misc/cache.js'; +import { CacheService, CachedTranslationEntity, FollowStats } from '@/core/CacheService.js'; +import { DI } from '@/di-symbols.js'; +import { UserEntityService } from '@/core/entities/UserEntityService.js'; + +export function noOpRedis() { + return { + set: () => Promise.resolve(), + get: () => Promise.resolve(null), + del: () => Promise.resolve(), + on: () => {}, + off: () => {}, + } as unknown as Redis.Redis; +} + +export class NoOpCacheService extends CacheService { + public readonly fakeRedis: { + [K in keyof Redis.Redis]: Redis.Redis[K]; + }; + public readonly fakeInternalEventService: FakeInternalEventService; + + constructor( + @Inject(DI.usersRepository) + usersRepository: UsersRepository, + + @Inject(DI.userProfilesRepository) + userProfilesRepository: UserProfilesRepository, + + @Inject(DI.mutingsRepository) + mutingsRepository: MutingsRepository, + + @Inject(DI.blockingsRepository) + blockingsRepository: BlockingsRepository, + + @Inject(DI.renoteMutingsRepository) + renoteMutingsRepository: RenoteMutingsRepository, + + @Inject(DI.followingsRepository) + followingsRepository: FollowingsRepository, + + @Inject(UserEntityService) + userEntityService: UserEntityService, + ) { + const fakeRedis = noOpRedis(); + const fakeInternalEventService = new FakeInternalEventService(); + + super( + fakeRedis, + fakeRedis, + usersRepository, + userProfilesRepository, + mutingsRepository, + blockingsRepository, + renoteMutingsRepository, + followingsRepository, + userEntityService, + fakeInternalEventService, + ); + + this.fakeRedis = fakeRedis; + this.fakeInternalEventService = fakeInternalEventService; + + // Override caches + this.userByIdCache = new NoOpMemoryKVCache(); + this.localUserByNativeTokenCache = new NoOpMemoryKVCache(); + this.localUserByIdCache = new NoOpMemoryKVCache(); + this.uriPersonCache = new NoOpMemoryKVCache(); + this.userProfileCache = new NoOpQuantumKVCache({ + internalEventService: fakeInternalEventService, + fetcher: this.userProfileCache.fetcher, + onSet: this.userProfileCache.onSet, + onDelete: this.userProfileCache.onDelete, + }); + this.userMutingsCache = new NoOpQuantumKVCache>({ + internalEventService: fakeInternalEventService, + fetcher: this.userMutingsCache.fetcher, + onSet: this.userMutingsCache.onSet, + onDelete: this.userMutingsCache.onDelete, + }); + this.userBlockingCache = new NoOpQuantumKVCache>({ + internalEventService: fakeInternalEventService, + fetcher: this.userBlockingCache.fetcher, + onSet: this.userBlockingCache.onSet, + onDelete: this.userBlockingCache.onDelete, + }); + this.userBlockedCache = new NoOpQuantumKVCache>({ + internalEventService: fakeInternalEventService, + fetcher: this.userBlockedCache.fetcher, + onSet: this.userBlockedCache.onSet, + onDelete: this.userBlockedCache.onDelete, + }); + this.renoteMutingsCache = new NoOpQuantumKVCache>({ + internalEventService: fakeInternalEventService, + fetcher: this.renoteMutingsCache.fetcher, + onSet: this.renoteMutingsCache.onSet, + onDelete: this.renoteMutingsCache.onDelete, + }); + this.userFollowingsCache = new NoOpQuantumKVCache | undefined>>({ + internalEventService: fakeInternalEventService, + fetcher: this.userFollowingsCache.fetcher, + onSet: this.userFollowingsCache.onSet, + onDelete: this.userFollowingsCache.onDelete, + }); + this.userFollowStatsCache = new NoOpMemoryKVCache(); + this.translationsCache = new NoOpRedisKVCache({ + redis: fakeRedis, + fetcher: this.translationsCache.fetcher, + toRedisConverter: this.translationsCache.toRedisConverter, + fromRedisConverter: this.translationsCache.fromRedisConverter, + }); + } +} + +export class NoOpMemoryKVCache extends MemoryKVCache { + constructor() { + super(-1); + } +} + +export class NoOpMemorySingleCache extends MemorySingleCache { + constructor() { + super(-1); + } +} + +export class NoOpRedisKVCache extends RedisKVCache { + constructor(opts?: { + redis?: Redis.Redis; + fetcher?: RedisKVCache['fetcher']; + toRedisConverter?: RedisKVCache['toRedisConverter']; + fromRedisConverter?: RedisKVCache['fromRedisConverter']; + }) { + super( + opts?.redis ?? noOpRedis(), + 'no-op', + { + lifetime: -1, + memoryCacheLifetime: -1, + fetcher: opts?.fetcher, + toRedisConverter: opts?.toRedisConverter, + fromRedisConverter: opts?.fromRedisConverter, + }, + ); + } +} + +export class NoOpRedisSingleCache extends RedisSingleCache { + constructor(opts?: { + fakeRedis?: Redis.Redis; + fetcher?: RedisSingleCache['fetcher']; + toRedisConverter?: RedisSingleCache['toRedisConverter']; + fromRedisConverter?: RedisSingleCache['fromRedisConverter']; + }) { + super( + opts?.fakeRedis ?? noOpRedis(), + 'no-op', + { + lifetime: -1, + memoryCacheLifetime: -1, + fetcher: opts?.fetcher, + toRedisConverter: opts?.toRedisConverter, + fromRedisConverter: opts?.fromRedisConverter, + }, + ); + } +} + +export class NoOpQuantumKVCache extends QuantumKVCache { + constructor(opts: { + internalEventService?: FakeInternalEventService, + fetcher: QuantumKVOpts['fetcher'], + onSet?: QuantumKVOpts['onSet'], + onDelete?: QuantumKVOpts['onDelete'], + }) { + super( + opts.internalEventService ?? new FakeInternalEventService(), + 'no-op', + { + lifetime: -1, + fetcher: opts.fetcher, + onSet: opts.onSet, + onDelete: opts.onDelete, + }, + ); + } +} -- cgit v1.2.3-freya