1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

feat: Check production enabled live stage (#6952)

This commit is contained in:
Mateusz Kwasniewski 2024-04-26 13:38:25 +02:00 committed by GitHub
parent 514a18bf93
commit 49e84d3a91
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 49 additions and 10 deletions

View File

@ -9,8 +9,10 @@ import { FeatureLifecycleStore } from './feature-lifecycle-store';
import EnvironmentStore from '../project-environments/environment-store';
import EventService from '../events/event-service';
import FakeFeatureTagStore from '../../../test/fixtures/fake-feature-tag-store';
import { EventEmitter } from 'stream';
import FeatureTagStore from '../../db/feature-tag-store';
import { FeatureEnvironmentStore } from '../../db/feature-environment-store';
import FakeFeatureEnvironmentStore from '../../../test/fixtures/fake-feature-environment-store';
import EventEmitter from 'events';
export const createFeatureLifecycleService = (
db: Db,
@ -20,6 +22,11 @@ export const createFeatureLifecycleService = (
const eventStore = new EventStore(db, getLogger);
const featureLifecycleStore = new FeatureLifecycleStore(db);
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
);
const featureTagStore = new FeatureTagStore(
db,
config.eventBus,
@ -34,6 +41,7 @@ export const createFeatureLifecycleService = (
eventStore,
featureLifecycleStore,
environmentStore,
featureEnvironmentStore,
},
{
eventService,
@ -53,6 +61,7 @@ export const createFakeFeatureLifecycleService = (config: IUnleashConfig) => {
const eventStore = new FakeEventStore();
const featureLifecycleStore = new FakeFeatureLifecycleStore();
const environmentStore = new FakeEnvironmentStore();
const featureEnvironmentStore = new FakeFeatureEnvironmentStore();
const eventService = new EventService(
{ eventStore, featureTagStore: new FakeFeatureTagStore() },
config,
@ -62,6 +71,7 @@ export const createFakeFeatureLifecycleService = (config: IUnleashConfig) => {
eventStore,
featureLifecycleStore,
environmentStore,
featureEnvironmentStore,
},
{
eventService,
@ -74,5 +84,6 @@ export const createFakeFeatureLifecycleService = (config: IUnleashConfig) => {
featureLifecycleStore,
eventStore,
environmentStore,
featureEnvironmentStore,
};
};

View File

@ -15,13 +15,22 @@ import noLoggerProvider from '../../../test/fixtures/no-logger';
test('can insert and read lifecycle stages', async () => {
const eventBus = new EventEmitter();
const { featureLifecycleService, eventStore, environmentStore } =
createFakeFeatureLifecycleService({
flagResolver: { isEnabled: () => true },
eventBus,
getLogger: noLoggerProvider,
} as unknown as IUnleashConfig);
const {
featureLifecycleService,
eventStore,
environmentStore,
featureEnvironmentStore,
} = createFakeFeatureLifecycleService({
flagResolver: { isEnabled: () => true },
eventBus,
getLogger: noLoggerProvider,
} as unknown as IUnleashConfig);
const featureName = 'testFeature';
await featureEnvironmentStore.addEnvironmentToFeature(
featureName,
'my-prod-environment',
true,
);
function emitMetricsEvent(environment: string) {
eventBus.emit(CLIENT_METRICS, {

View File

@ -8,6 +8,7 @@ import {
type IAuditUser,
type IEnvironmentStore,
type IEventStore,
type IFeatureEnvironmentStore,
type IFlagResolver,
type IUnleashConfig,
} from '../../types';
@ -29,6 +30,8 @@ export class FeatureLifecycleService extends EventEmitter {
private environmentStore: IEnvironmentStore;
private featureEnvironmentStore: IFeatureEnvironmentStore;
private flagResolver: IFlagResolver;
private eventBus: EventEmitter;
@ -42,10 +45,12 @@ export class FeatureLifecycleService extends EventEmitter {
eventStore,
featureLifecycleStore,
environmentStore,
featureEnvironmentStore,
}: {
eventStore: IEventStore;
environmentStore: IEnvironmentStore;
featureLifecycleStore: IFeatureLifecycleStore;
featureEnvironmentStore: IFeatureEnvironmentStore;
},
{
eventService,
@ -62,6 +67,7 @@ export class FeatureLifecycleService extends EventEmitter {
this.eventStore = eventStore;
this.featureLifecycleStore = featureLifecycleStore;
this.environmentStore = environmentStore;
this.featureEnvironmentStore = featureEnvironmentStore;
this.flagResolver = flagResolver;
this.eventBus = eventBus;
this.eventService = eventService;
@ -140,7 +146,15 @@ export class FeatureLifecycleService extends EventEmitter {
}
await this.stageReceivedMetrics(features, 'pre-live');
if (env.type === 'production') {
await this.stageReceivedMetrics(features, 'live');
const featureEnv =
await this.featureEnvironmentStore.getAllByFeatures(
features,
env.name,
);
const enabledFeatures = featureEnv
.filter((feature) => feature.enabled)
.map((feature) => feature.featureName);
await this.stageReceivedMetrics(enabledFeatures, 'live');
}
} catch (e) {
this.logger.warn(

View File

@ -98,6 +98,7 @@ const expectFeatureStage = async (featureName: string, stage: StageName) => {
test('should return lifecycle stages', async () => {
await app.createFeature('my_feature_a');
await app.enableFeature('my_feature_a', 'default');
eventStore.emit(FEATURE_CREATED, { featureName: 'my_feature_a' });
await reachedStage('initial');
await expectFeatureStage('my_feature_a', 'initial');

View File

@ -233,12 +233,16 @@ export default class FakeFeatureEnvironmentStore
throw new Error('Method not implemented.');
}
getAllByFeatures(
async getAllByFeatures(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
features: string[],
// eslint-disable-next-line @typescript-eslint/no-unused-vars
environment?: string,
): Promise<IFeatureEnvironment[]> {
throw new Error('Method not implemented.');
return this.featureEnvironments.filter(
(featureEnv) =>
(environment ? featureEnv.environment === environment : true) &&
features.includes(featureEnv.featureName),
);
}
}