diff --git a/packages/relay/src/lib/clients/cache/localLRUCache.ts b/packages/relay/src/lib/clients/cache/localLRUCache.ts index ab2250b53..5a7262838 100644 --- a/packages/relay/src/lib/clients/cache/localLRUCache.ts +++ b/packages/relay/src/lib/clients/cache/localLRUCache.ts @@ -251,6 +251,7 @@ export class LocalLRUCache implements ICacheClient { */ public async clear(): Promise { this.cache.clear(); + this.reservedCache?.clear(); } /** diff --git a/packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts b/packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts index b4c1d880b..5e5cd93dd 100644 --- a/packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts +++ b/packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts @@ -131,7 +131,8 @@ export class HbarSpendingPlanConfigService { const spendingPlanConfig = ConfigService.get('HBAR_SPENDING_PLANS_CONFIG') as string; if (!spendingPlanConfig) { - throw new Error('HBAR_SPENDING_PLANS_CONFIG is undefined'); + logger.trace('HBAR_SPENDING_PLANS_CONFIG is undefined'); + return []; } // Try to parse the value directly as JSON @@ -148,9 +149,8 @@ export class HbarSpendingPlanConfigService { const fileContent = fs.readFileSync(configFilePath, 'utf-8'); return JSON.parse(fileContent) as SpendingPlanConfig[]; } else { - throw new Error( - `HBAR Spending Configuration file not found at path "${configFilePath ?? spendingPlanConfig}"`, - ); + logger.trace(`HBAR Spending Configuration file not found at path "${configFilePath ?? spendingPlanConfig}"`); + return []; } } catch (fileError: any) { throw new Error(`File error: ${fileError.message}`); diff --git a/packages/relay/tests/lib/config/hbarSpendingPlanConfigService.spec.ts b/packages/relay/tests/lib/config/hbarSpendingPlanConfigService.spec.ts index 0b0cecfb4..0afda8841 100644 --- a/packages/relay/tests/lib/config/hbarSpendingPlanConfigService.spec.ts +++ b/packages/relay/tests/lib/config/hbarSpendingPlanConfigService.spec.ts @@ -31,9 +31,8 @@ import { SpendingPlanConfig } from '../../../src/lib/types/spendingPlanConfig'; import { RequestDetails } from '../../../src/lib/types'; import { overrideEnvsInMochaDescribe, - startRedisInMemoryServer, - stopRedisInMemoryServer, toHex, + useInMemoryRedisServer, verifyResult, withOverriddenEnvsInMochaTest, } from '../../helpers'; @@ -47,8 +46,6 @@ import { HbarSpendingPlanNotFoundError, IPAddressHbarSpendingPlanNotFoundError, } from '../../../src/lib/db/types/hbarLimiter/errors'; -import { ConfigServiceTestHelper } from '@hashgraph/json-rpc-config-service/tests/configServiceTestHelper'; -import { RedisInMemoryServer } from '../../redisInMemoryServer'; chai.use(chaiAsPromised); @@ -71,7 +68,7 @@ describe('HbarSpendingPlanConfigService', function () { const path = findConfig(spendingPlansConfigFile); const spendingPlansConfig = JSON.parse(fs.readFileSync(path!, 'utf-8')) as SpendingPlanConfig[]; - const tests = (isSharedCacheEnabled: boolean, isSpendingPlansConfigFile: boolean) => { + const tests = (hbarSpendingPlansConfigEnv: string) => { let cacheService: CacheService; let hbarSpendingPlanRepository: HbarSpendingPlanRepository; let ethAddressHbarSpendingPlanRepository: EthAddressHbarSpendingPlanRepository; @@ -83,26 +80,14 @@ describe('HbarSpendingPlanConfigService', function () { let hbarSpendingPlanRepositorySpy: sinon.SinonSpiedInstance; let ethAddressHbarSpendingPlanRepositorySpy: sinon.SinonSpiedInstance; let ipAddressHbarSpendingPlanRepositorySpy: sinon.SinonSpiedInstance; - let redisInMemoryServer: RedisInMemoryServer; overrideEnvsInMochaDescribe({ + HBAR_SPENDING_PLANS_CONFIG: hbarSpendingPlansConfigEnv, CACHE_TTL: '100', CACHE_MAX: spendingPlansConfig.length.toString(), }); - if (isSpendingPlansConfigFile) { - ConfigServiceTestHelper.dynamicOverride('HBAR_SPENDING_PLANS_CONFIG', spendingPlansConfigFile); - } else { - ConfigServiceTestHelper.dynamicOverride('HBAR_SPENDING_PLANS_CONFIG', JSON.stringify(spendingPlansConfig)); - } - before(async function () { - if (isSharedCacheEnabled) { - redisInMemoryServer = await startRedisInMemoryServer(logger, 6384); - } else { - overrideEnvsInMochaDescribe({ REDIS_ENABLED: 'false' }); - } - const reservedKeys = HbarSpendingPlanConfigService.getPreconfiguredSpendingPlanKeys(logger); cacheService = new CacheService(logger.child({ name: 'cache-service' }), registry, reservedKeys); hbarSpendingPlanRepository = new HbarSpendingPlanRepository( @@ -125,13 +110,7 @@ describe('HbarSpendingPlanConfigService', function () { ); }); - after(async function () { - if (isSharedCacheEnabled) { - await stopRedisInMemoryServer(redisInMemoryServer); - } - }); - - beforeEach(function () { + beforeEach(async function () { loggerSpy = sinon.spy(logger); cacheServiceSpy = sinon.spy(cacheService); hbarSpendingPlanRepositorySpy = sinon.spy(hbarSpendingPlanRepository); @@ -158,9 +137,9 @@ describe('HbarSpendingPlanConfigService', function () { () => { it('should throw an error if configuration file is not a parsable JSON', async function () { sinon.stub(fs, 'readFileSync').returns('invalid JSON'); - await expect(hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans()).to.be.rejectedWith( - `Unexpected token 'i', "invalid JSON" is not valid JSON`, - ); + await expect( + hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans(), + ).to.be.eventually.rejectedWith(`Unexpected token 'i', "invalid JSON" is not valid JSON`); }); }, ); @@ -175,9 +154,9 @@ describe('HbarSpendingPlanConfigService', function () { .stub(HbarSpendingPlanConfigService, 'loadSpendingPlansConfig' as any) .returns([...spendingPlansConfig, invalidPlan]); - await expect(hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans()).to.be.rejectedWith( - `Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`, - ); + await expect( + hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans(), + ).to.be.eventually.rejectedWith(`Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`); }); it('should throw an error if the configuration file has entry without name', async function () { @@ -190,9 +169,9 @@ describe('HbarSpendingPlanConfigService', function () { .stub(HbarSpendingPlanConfigService, 'loadSpendingPlansConfig' as any) .returns([...spendingPlansConfig, invalidPlan]); - await expect(hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans()).to.be.rejectedWith( - `Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`, - ); + await expect( + hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans(), + ).to.be.eventually.rejectedWith(`Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`); }); it('should throw an error if the configuration file has entry without subscriptionTier', async function () { @@ -205,9 +184,9 @@ describe('HbarSpendingPlanConfigService', function () { .stub(HbarSpendingPlanConfigService, 'loadSpendingPlansConfig' as any) .returns([...spendingPlansConfig, invalidPlan]); - await expect(hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans()).to.be.rejectedWith( - `Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`, - ); + await expect( + hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans(), + ).to.be.eventually.rejectedWith(`Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`); }); it('should throw an error if the configuration file has entry with invalid subscriptionTier', async function () { @@ -221,9 +200,9 @@ describe('HbarSpendingPlanConfigService', function () { .stub(HbarSpendingPlanConfigService, 'loadSpendingPlansConfig' as any) .returns([...spendingPlansConfig, invalidPlan]); - await expect(hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans()).to.be.rejectedWith( - `Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`, - ); + await expect( + hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans(), + ).to.be.eventually.rejectedWith(`Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`); }); it('should throw an error if the configuration file has entry without ethAddresses and ipAddresses', async function () { @@ -236,9 +215,9 @@ describe('HbarSpendingPlanConfigService', function () { .stub(HbarSpendingPlanConfigService, 'loadSpendingPlansConfig' as any) .returns([...spendingPlansConfig, invalidPlan]); - await expect(hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans()).to.be.rejectedWith( - `Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`, - ); + await expect( + hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans(), + ).to.be.eventually.rejectedWith(`Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`); }); it('should throw an error if the configuration file has entry with empty ethAddresses and ipAddresses', async function () { @@ -253,9 +232,9 @@ describe('HbarSpendingPlanConfigService', function () { .stub(HbarSpendingPlanConfigService, 'loadSpendingPlansConfig' as any) .returns([...spendingPlansConfig, invalidPlan]); - await expect(hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans()).to.be.rejectedWith( - `Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`, - ); + await expect( + hbarSpendingPlanConfigService.populatePreconfiguredSpendingPlans(), + ).to.be.eventually.rejectedWith(`Invalid spending plan configuration: ${JSON.stringify(invalidPlan)}`); }); }); @@ -680,22 +659,26 @@ describe('HbarSpendingPlanConfigService', function () { }; describe('using Redis cache', function () { + useInMemoryRedisServer(logger, 6384); + describe('and with a spending plan config file', function () { - tests(true, true); + tests(spendingPlansConfigFile); }); describe('and with a spending plan config variable', function () { - tests(true, false); + tests(JSON.stringify(spendingPlansConfig)); }); }); - describe('using LRU cache', function () { + describe.only('using LRU cache', function () { + overrideEnvsInMochaDescribe({ REDIS_ENABLED: false }); + describe('and with a spending plan config file', function () { - tests(false, true); + tests(spendingPlansConfigFile); }); describe('and with a spending plan config variable', function () { - tests(false, false); + tests(JSON.stringify(spendingPlansConfig)); }); }); }); diff --git a/packages/relay/tests/lib/relay.spec.ts b/packages/relay/tests/lib/relay.spec.ts index 73122ee10..844655edd 100644 --- a/packages/relay/tests/lib/relay.spec.ts +++ b/packages/relay/tests/lib/relay.spec.ts @@ -20,7 +20,6 @@ import chai, { expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; -import findConfig from 'find-config'; import fs from 'fs'; import pino from 'pino'; import sinon from 'sinon'; @@ -107,7 +106,7 @@ describe('RelayImpl', () => { describe('when no configuration file is provided', () => { const nonExistingFile = 'nonExistingFile.json'; - overrideEnvsInMochaDescribe({ HBAR_SPENDING_PLANS_CONFIG_FILE: nonExistingFile }); + overrideEnvsInMochaDescribe({ HBAR_SPENDING_PLANS_CONFIG: nonExistingFile }); it('should not throw an error', async () => { expect((relay = new RelayImpl(logger, register))).to.not.throw; @@ -119,12 +118,9 @@ describe('RelayImpl', () => { }); describe('when a configuration file with invalid JSON is provided', () => { - let path: string | null; - overrideEnvsInMochaDescribe({ HBAR_SPENDING_PLANS_CONFIG: 'spendingPlansConfig.example.json' }); beforeEach(() => { - path = findConfig('spendingPlansConfig.example.json'); sinon.stub(fs, 'readFileSync').returns('invalid JSON'); });