Skip to content

Commit 7200533

Browse files
authored
Merge pull request #5497 from redis/latest
Update main from latest
2 parents da35010 + 0f5adeb commit 7200533

11 files changed

Lines changed: 279 additions & 24 deletions

File tree

.github/workflows/tests.yml

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,40 @@ jobs:
7373
desktop:
7474
- 'redisinsight/desktop/**'
7575
76+
# Check common conditions that trigger all test suites
77+
should-run-all-tests:
78+
runs-on: ubuntu-latest
79+
outputs:
80+
result: ${{ steps.check.outputs.result }}
81+
steps:
82+
- id: check
83+
env:
84+
PRERELEASE_CONDITION: ${{ inputs.pre_release == true }}
85+
run: |
86+
OTHER_CONDITIONS="${{ github.event_name == 'workflow_dispatch' ||
87+
startsWith(github.ref_name, 'feature/') ||
88+
startsWith(github.ref_name, 'bugfix/') ||
89+
startsWith(github.ref_name, 'ric/') ||
90+
startsWith(github.ref_name, 'release/') ||
91+
github.ref_name == 'latest' ||
92+
contains(github.event.pull_request.labels.*.name, 'run-all-tests') }}"
93+
94+
if [[ "$PRERELEASE_CONDITION" == "true" ]] || [[ "$OTHER_CONDITIONS" == "true" ]]; then
95+
echo "result=true" >> $GITHUB_OUTPUT
96+
else
97+
echo "result=false" >> $GITHUB_OUTPUT
98+
fi
99+
76100
lint:
77101
uses: ./.github/workflows/lint.yml
78102
secrets: inherit
79103

80104
frontend-tests:
81-
needs: [changes, lint]
105+
needs: [changes, lint, should-run-all-tests]
82106
if: |
107+
needs.should-run-all-tests.outputs.result == 'true' ||
83108
startsWith(github.ref_name, 'fe/') ||
84109
startsWith(github.ref_name, 'fe-be/') ||
85-
startsWith(github.ref_name, 'feature/') ||
86-
startsWith(github.ref_name, 'bugfix/') ||
87-
startsWith(github.ref_name, 'ric/') ||
88-
contains(github.event.pull_request.labels.*.name, 'run-all-tests') ||
89110
contains(github.event.pull_request.labels.*.name, 'run-frontend-tests')
90111
uses: ./.github/workflows/tests-frontend.yml
91112
secrets: inherit
@@ -99,14 +120,11 @@ jobs:
99120
type: unit
100121

101122
backend-tests:
102-
needs: [changes, lint]
123+
needs: [changes, lint, should-run-all-tests]
103124
if: |
125+
needs.should-run-all-tests.outputs.result == 'true' ||
104126
startsWith(github.ref_name, 'be/') ||
105127
startsWith(github.ref_name, 'fe-be/') ||
106-
startsWith(github.ref_name, 'feature/') ||
107-
startsWith(github.ref_name, 'bugfix/') ||
108-
startsWith(github.ref_name, 'ric/') ||
109-
contains(github.event.pull_request.labels.*.name, 'run-all-tests') ||
110128
contains(github.event.pull_request.labels.*.name, 'run-backend-tests')
111129
uses: ./.github/workflows/tests-backend.yml
112130
secrets: inherit
@@ -120,14 +138,11 @@ jobs:
120138
type: unit
121139

122140
integration-tests:
123-
needs: [changes, lint]
141+
needs: [changes, lint, should-run-all-tests]
124142
if: |
143+
needs.should-run-all-tests.outputs.result == 'true' ||
125144
startsWith(github.ref_name, 'be/') ||
126145
startsWith(github.ref_name, 'fe-be/') ||
127-
startsWith(github.ref_name, 'feature/') ||
128-
startsWith(github.ref_name, 'bugfix/') ||
129-
startsWith(github.ref_name, 'ric/') ||
130-
contains(github.event.pull_request.labels.*.name, 'run-all-tests') ||
131146
contains(github.event.pull_request.labels.*.name, 'run-integration-tests')
132147
uses: ./.github/workflows/tests-integration.yml
133148
secrets: inherit

redisinsight/api/src/modules/rdi/client/api/v1/api.rdi.client.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,9 @@ describe('ApiRdiClient', () => {
677677
expect(mockedAxios.get).toHaveBeenCalledWith(RdiUrl.GetStatistics);
678678
expect(result.status).toBe(RdiStatisticsStatus.Success);
679679
expect(result.data).toBeDefined();
680-
expect(result.data.sections).toHaveLength(5);
680+
// 2 sections: General info, Processing performance
681+
// (Target Connections, Data Streams, and Clients are filtered out because they have empty data)
682+
expect(result.data.sections).toHaveLength(2);
681683
});
682684

683685
it('should return fail status and error message when API call fails', async () => {

redisinsight/api/src/modules/rdi/client/api/v1/transformers/statistics.transformers.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,5 +410,50 @@ describe('statistics.transformers', () => {
410410
expect(result[3]).toBeInstanceOf(RdiStatisticsTableSection);
411411
expect(result[4]).toBeInstanceOf(RdiStatisticsTableSection);
412412
});
413+
414+
it('should filter out table sections with empty data', () => {
415+
const responseWithEmptyData: GetStatisticsResponse = {
416+
rdi_pipeline_status: {
417+
rdi_version: '1.0.0',
418+
address: '127.0.0.1:6379',
419+
run_status: 'started',
420+
sync_mode: 'cdc',
421+
},
422+
processing_performance: {
423+
total_batches: 100,
424+
batch_size_avg: 1.5,
425+
read_time_avg: 10,
426+
process_time_avg: 50,
427+
ack_time_avg: 0.5,
428+
total_time_avg: 60,
429+
rec_per_sec_avg: 1000,
430+
},
431+
data_streams: {
432+
streams: {},
433+
totals: {
434+
total: 0,
435+
pending: 0,
436+
inserted: 0,
437+
updated: 0,
438+
deleted: 0,
439+
filtered: 0,
440+
rejected: 0,
441+
deduplicated: 0,
442+
},
443+
},
444+
connections: {},
445+
clients: {},
446+
offsets: {},
447+
snapshot_status: '',
448+
};
449+
450+
const result = transformStatisticsResponse(responseWithEmptyData);
451+
452+
// Should only include General info and Processing performance (non-empty sections)
453+
// Target Connections, Data Streams, and Clients should be filtered out
454+
expect(result).toHaveLength(2);
455+
expect(result[0].name).toBe('General info');
456+
expect(result[1].name).toBe('Processing performance information');
457+
});
413458
});
414459
});

redisinsight/api/src/modules/rdi/client/api/v1/transformers/statistics.transformers.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import {
88
RdiStatisticsViewType,
99
} from 'src/modules/rdi/models';
1010
import { GetStatisticsResponse } from 'src/modules/rdi/client/api/v1/responses';
11-
import { generateColumns } from 'src/modules/rdi/utils/transformer.util';
11+
import {
12+
generateColumns,
13+
hasData,
14+
} from 'src/modules/rdi/utils/transformer.util';
1215

1316
export const transformProcessingPerformance = (
1417
data: GetStatisticsResponse['processing_performance'],
@@ -192,11 +195,14 @@ export const transformConnectionsStatistics = (
192195
export const transformStatisticsResponse = (
193196
data: GetStatisticsResponse,
194197
): RdiStatisticsSection[] => {
195-
return [
198+
const sections = [
196199
transformGeneralInfo(data.rdi_pipeline_status),
197200
transformProcessingPerformance(data.processing_performance),
198201
transformConnectionsStatistics(data.connections),
199202
transformDataStreamsStatistics(data.data_streams),
200203
transformClientStatistics(data.clients),
201204
];
205+
206+
// Filter out sections with no data
207+
return sections.filter(hasData);
202208
};

redisinsight/api/src/modules/rdi/client/api/v2/api.v2.rdi.client.spec.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,9 @@ describe('ApiV2RdiClient', () => {
327327
const result = await client.getStatistics();
328328

329329
expect(result.status).toBe(RdiStatisticsStatus.Success);
330-
expect(result.data?.sections).toHaveLength(6);
330+
// 4 sections: General info, Processing performance, Target Connections, Component Status
331+
// (Data Streams and Clients are filtered out because they have empty data)
332+
expect(result.data?.sections).toHaveLength(4);
331333
expect(result.data?.sections[3].name).toBe('Component Status');
332334
});
333335

@@ -345,7 +347,9 @@ describe('ApiV2RdiClient', () => {
345347
const result = await client.getStatistics();
346348

347349
expect(result.status).toBe(RdiStatisticsStatus.Success);
348-
expect(result.data?.sections).toHaveLength(5);
350+
// 3 sections: General info, Processing performance, Target Connections
351+
// (Data Streams and Clients are filtered out because they have empty data)
352+
expect(result.data?.sections).toHaveLength(3);
349353
expect(result.data?.sections.map((s) => s.name)).not.toContain(
350354
'Component Status',
351355
);

redisinsight/api/src/modules/rdi/client/api/v2/transformers/metrics-collections.transformer.spec.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,5 +423,56 @@ describe('metrics-collections.transformer', () => {
423423
expect(result).toHaveLength(5);
424424
expect(result.map((s) => s.name)).not.toContain('Component Status');
425425
});
426+
427+
it('should filter out table sections with empty data', () => {
428+
const metricsWithEmptyData: ProcessorMetricsResponse = {
429+
name: 'processor_metrics',
430+
component: 'processor',
431+
metrics: {
432+
processing_performance: {
433+
total_batches: 100,
434+
batch_size_avg: 1.5,
435+
read_time_avg: 10,
436+
transform_time_avg: 5,
437+
write_time_avg: 3,
438+
process_time_avg: 50,
439+
ack_time_avg: 0.5,
440+
total_time_avg: 60,
441+
rec_per_sec_avg: 1000,
442+
},
443+
data_streams: {
444+
streams: {},
445+
totals: {
446+
total: 0,
447+
pending: 0,
448+
inserted: 0,
449+
updated: 0,
450+
deleted: 0,
451+
filtered: 0,
452+
rejected: 0,
453+
deduplicated: 0,
454+
},
455+
},
456+
rdi_pipeline_status: {
457+
rdi_version: '1.0.0',
458+
address: '127.0.0.1:6379',
459+
run_status: 'started',
460+
sync_mode: 'cdc',
461+
},
462+
connections: {},
463+
clients: {},
464+
},
465+
};
466+
467+
const response: GetMetricsCollectionResponse = [metricsWithEmptyData];
468+
469+
const result = transformMetricsCollectionResponse(response);
470+
471+
// Should only include General info and Processing performance (non-empty sections)
472+
// Target Connections, Data Streams, and Clients should be filtered out
473+
expect(result).toHaveLength(2);
474+
expect(result[0].name).toBe('General info');
475+
expect(result[1].name).toBe('Processing performance information');
476+
});
426477
});
427478
});

redisinsight/api/src/modules/rdi/client/api/v2/transformers/metrics-collections.transformer.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import {
1212
GetStatusResponse,
1313
ProcessorMetricsResponse,
1414
} from 'src/modules/rdi/client/api/v2/responses';
15-
import { generateColumns } from 'src/modules/rdi/utils/transformer.util';
15+
import {
16+
generateColumns,
17+
hasData,
18+
} from 'src/modules/rdi/utils/transformer.util';
1619

1720
type ProcessingPerformance =
1821
ProcessorMetricsResponse['metrics']['processing_performance'];
@@ -128,5 +131,6 @@ export const transformMetricsCollectionResponse = (
128131
),
129132
);
130133

131-
return sections;
134+
// Filter out sections with no data
135+
return sections.filter(hasData);
132136
};

redisinsight/api/src/modules/rdi/utils/transformer.util.spec.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1+
import {
2+
RdiStatisticsBlocksSection,
3+
RdiStatisticsInfoSection,
4+
RdiStatisticsTableSection,
5+
RdiStatisticsViewType,
6+
} from 'src/modules/rdi/models';
17
import {
28
generateHeaderFromFieldName,
39
generateColumns,
10+
hasData,
411
} from './transformer.util';
512

613
describe('transformer.util', () => {
@@ -219,4 +226,96 @@ describe('transformer.util', () => {
219226
]);
220227
});
221228
});
229+
230+
describe('hasData', () => {
231+
describe('table sections', () => {
232+
it('should return true when table section has columns and data', () => {
233+
const section: RdiStatisticsTableSection = {
234+
name: 'Test',
235+
view: RdiStatisticsViewType.Table,
236+
columns: [{ id: 'name', header: 'Name' }],
237+
data: [{ name: 'test' }],
238+
};
239+
240+
expect(hasData(section)).toBe(true);
241+
});
242+
243+
it('should return false when table section has empty columns', () => {
244+
const section: RdiStatisticsTableSection = {
245+
name: 'Test',
246+
view: RdiStatisticsViewType.Table,
247+
columns: [],
248+
data: [{ name: 'test' }],
249+
};
250+
251+
expect(hasData(section)).toBe(false);
252+
});
253+
254+
it('should return false when table section has empty data', () => {
255+
const section: RdiStatisticsTableSection = {
256+
name: 'Test',
257+
view: RdiStatisticsViewType.Table,
258+
columns: [{ id: 'name', header: 'Name' }],
259+
data: [],
260+
};
261+
262+
expect(hasData(section)).toBe(false);
263+
});
264+
265+
it('should return false when table section has both empty columns and data', () => {
266+
const section: RdiStatisticsTableSection = {
267+
name: 'Test',
268+
view: RdiStatisticsViewType.Table,
269+
columns: [],
270+
data: [],
271+
};
272+
273+
expect(hasData(section)).toBe(false);
274+
});
275+
});
276+
277+
describe('blocks sections', () => {
278+
it('should return true when blocks section has data', () => {
279+
const section: RdiStatisticsBlocksSection = {
280+
name: 'Test',
281+
view: RdiStatisticsViewType.Blocks,
282+
data: [{ label: 'Count', value: 10, units: 'Total' }],
283+
};
284+
285+
expect(hasData(section)).toBe(true);
286+
});
287+
288+
it('should return false when blocks section has empty data', () => {
289+
const section: RdiStatisticsBlocksSection = {
290+
name: 'Test',
291+
view: RdiStatisticsViewType.Blocks,
292+
data: [],
293+
};
294+
295+
expect(hasData(section)).toBe(false);
296+
});
297+
});
298+
299+
describe('info sections', () => {
300+
it('should return true for info sections regardless of data', () => {
301+
const section: RdiStatisticsInfoSection = {
302+
name: 'Test',
303+
view: RdiStatisticsViewType.Info,
304+
data: [],
305+
};
306+
307+
expect(hasData(section)).toBe(true);
308+
});
309+
310+
it('should return true for info sections with data', () => {
311+
const section: RdiStatisticsInfoSection = {
312+
name: 'Test',
313+
view: RdiStatisticsViewType.Info,
314+
data: [{ label: 'Version', value: '1.0.0' }],
315+
};
316+
317+
expect(hasData(section)).toBe(true);
318+
});
319+
});
320+
});
222321
});

0 commit comments

Comments
 (0)