Skip to content

Commit f77bc88

Browse files
authored
Cost opt e2e (#3212)
* Add cost-opt scenario and fixtures * Add cost-opt e2e tests * Refactor broken layout * Add cost-opt scenario to demo and pr env deployments * Increase max_connections postgres in docker compose
1 parent 7c86304 commit f77bc88

20 files changed

+3596
-20
lines changed

.github/workflows/ci.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,7 @@ jobs:
978978
photofinish run multi-tenant -u "http://$TRENTO_DEMO_IP/api/collect" "$TRENTO_API_KEY"
979979
photofinish run hana-scale-up-angi -u "http://$TRENTO_DEMO_IP/api/collect" "$TRENTO_API_KEY"
980980
photofinish run java-system -u "http://$TRENTO_DEMO_IP/api/collect" "$TRENTO_API_KEY"
981+
photofinish run hana-scale-up-cost-opt -u "http://$TRENTO_DEMO_IP/api/collect" "$TRENTO_API_KEY"
981982
982983
obs-commit-image:
983984
name: Commit to OBS to generate container image

.github/workflows/pr_env.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ jobs:
164164
photofinish run multi-tenant -u "https://$TRENTO_PR_ENV_URL/api/v1/collect"
165165
photofinish run hana-scale-up-angi -u "https://$TRENTO_PR_ENV_URL/api/collect"
166166
photofinish run java-system -u "https://$TRENTO_PR_ENV_URL/api/collect"
167+
photofinish run hana-scale-up-cost-opt -u "https://$TRENTO_PR_ENV_URL/api/collect"
167168
comment_pr:
168169
name: Comment on the PR with the environment URL
169170
runs-on: ubuntu-20.04

.photofinish.toml

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ directories = ["./test/fixtures/scenarios/hana-diskless-sbd"]
1818

1919
directories = ["./test/fixtures/scenarios/hana-scale-up-angi"]
2020

21+
[hana-scale-up-cost-opt]
22+
23+
directories = ["./test/fixtures/scenarios/hana-scale-up-cost-opt"]
24+
2125
[aws-landscape]
2226

2327
directories = ["./test/fixtures/scenarios/aws-landscape"]

assets/js/pages/HostsList/HostsList.jsx

+12-16
Original file line numberDiff line numberDiff line change
@@ -119,22 +119,18 @@ function HostsList() {
119119
filter: (filter, key) => (element) =>
120120
element[key].some((sid) => filter.includes(sid)),
121121
render: (sids, { sap_systems }) => {
122-
const sidsArray = uniqBy(sap_systems, getInstanceID).map(
123-
(instance, index) => {
124-
const instanceID = getInstanceID(instance);
125-
return [
126-
index > 0 && <br />,
127-
<SapSystemLink
128-
key={`${instanceID}-${instance?.id}`}
129-
systemType={instance?.type}
130-
sapSystemId={instanceID}
131-
>
132-
{instance?.sid}
133-
</SapSystemLink>,
134-
];
135-
}
136-
);
137-
return sidsArray;
122+
const sidsArray = uniqBy(sap_systems, getInstanceID);
123+
return sidsArray.map((instance, index) => (
124+
<span key={`${sids[index]}-${instance?.id}`}>
125+
<SapSystemLink
126+
key={`${getInstanceID(instance)}-${instance?.id}`}
127+
systemType={instance?.type}
128+
sapSystemId={getInstanceID(instance)}
129+
>
130+
{instance?.sid}
131+
</SapSystemLink>{' '}
132+
</span>
133+
));
138134
},
139135
},
140136
{

assets/js/pages/HostsList/HostsList.test.jsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,9 @@ describe('HostsLists component', () => {
7272
cluster
7373
);
7474
expect(table.querySelector('td:nth-child(6)')).toHaveTextContent(sid);
75-
expect(table.querySelector('td:nth-child(6) > a')).toHaveAttribute(
76-
'href',
77-
`/${systemType}/${instanceID}`
78-
);
75+
expect(
76+
table.querySelector('td:nth-child(6) > span a')
77+
).toHaveAttribute('href', `/${systemType}/${instanceID}`);
7978
expect(table.querySelector('td:nth-child(7)')).toHaveTextContent(
8079
version
8180
);

docker-compose.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ services:
5454
- host.docker.internal:host-gateway
5555
postgres:
5656
image: postgres:15
57+
command: -c 'max_connections=200'
5758
environment:
5859
POSTGRES_USER: postgres
5960
POSTGRES_PASSWORD: postgres

test/e2e/cypress/e2e/hana_cluster_details.cy.js

+115
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
import { capitalize } from 'lodash';
77
import {
88
availableHanaCluster,
9+
availableHanaClusterCostOpt,
910
availableAngiCluster,
1011
} from '../fixtures/hana-cluster-details/available_hana_cluster';
1112

@@ -233,6 +234,120 @@ context('HANA cluster details', () => {
233234
});
234235
});
235236

237+
describe('HANA cluster details in a cost optimized scenario should be consistent with the state of the cluster', () => {
238+
before(() => {
239+
cy.loadScenario('hana-scale-up-cost-opt');
240+
cy.visit(`/clusters/${availableHanaClusterCostOpt.id}`);
241+
cy.url().should('include', `/clusters/${availableHanaClusterCostOpt.id}`);
242+
});
243+
244+
after(() => {
245+
availableHanaClusterCostOpt.hosts.forEach(({ id }) => {
246+
cy.deregisterHost(id);
247+
});
248+
});
249+
250+
it(`should have name ${availableHanaClusterCostOpt.name} in header`, () => {
251+
cy.get('h1').contains(availableHanaClusterCostOpt.name);
252+
});
253+
254+
it(`should have provider ${availableHanaClusterCostOpt.provider}`, () => {
255+
cy.get('.tn-cluster-details')
256+
.contains('Provider')
257+
.next()
258+
.contains(availableHanaClusterCostOpt.provider);
259+
});
260+
261+
it('should have all cost optimized SID`s and correct database links', () => {
262+
cy.get('.tn-cluster-details')
263+
.contains('SID')
264+
.parent()
265+
.within(() => {
266+
availableHanaClusterCostOpt.sids.forEach((sid, index) => {
267+
cy.contains(sid).should(
268+
'have.attr',
269+
'href',
270+
`/databases/${availableHanaClusterCostOpt.systemID[index]}`
271+
);
272+
});
273+
});
274+
});
275+
276+
it(`should have cluster cost optimized type ${availableHanaClusterCostOpt.clusterType}`, () => {
277+
cy.get('.tn-cluster-details')
278+
.contains('Cluster type')
279+
.next()
280+
.contains(availableHanaClusterCostOpt.clusterType);
281+
});
282+
283+
it(`should have architecture type ${availableHanaClusterCostOpt.clusterType}`, () => {
284+
cy.get('.tn-cluster-details')
285+
.contains('Cluster type')
286+
.next()
287+
.find('svg')
288+
.trigger('mouseover');
289+
290+
cy.contains('span', availableHanaClusterCostOpt.architectureType).should(
291+
'exist'
292+
);
293+
});
294+
295+
it(`should have log replication mode ${availableHanaClusterCostOpt.hanaSystemReplicationMode}`, () => {
296+
cy.get('.tn-cluster-details')
297+
.contains('HANA log replication mode')
298+
.next()
299+
.contains(availableHanaClusterCostOpt.hanaSystemReplicationMode);
300+
});
301+
302+
it(`should have fencing type ${availableHanaClusterCostOpt.fencingType}`, () => {
303+
cy.get('.tn-cluster-details')
304+
.contains('Fencing type')
305+
.next()
306+
.contains(availableHanaClusterCostOpt.fencingType);
307+
});
308+
309+
it(`should have HANA secondary sync state ${availableHanaClusterCostOpt.hanaSecondarySyncState}`, () => {
310+
cy.get('.tn-cluster-details')
311+
.contains('HANA secondary sync state')
312+
.next()
313+
.contains(availableHanaClusterCostOpt.hanaSecondarySyncState);
314+
});
315+
316+
it(`should have maintenance mode ${availableHanaClusterCostOpt.maintenanceMode}`, () => {
317+
cy.get('.tn-cluster-details')
318+
.contains('Cluster maintenance')
319+
.next()
320+
.contains('False');
321+
});
322+
323+
it(`should have hana log operation mode ${availableHanaClusterCostOpt.hanaSystemReplicationOperationMode}`, () => {
324+
cy.get('.tn-cluster-details')
325+
.contains('HANA log operation mode')
326+
.next()
327+
.contains(
328+
availableHanaClusterCostOpt.hanaSystemReplicationOperationMode
329+
);
330+
});
331+
332+
it(`should have cib last written ${availableHanaClusterCostOpt.cibLastWritten}`, () => {
333+
cy.get('.tn-cluster-details')
334+
.contains('CIB last written')
335+
.next()
336+
.contains(availableHanaClusterCostOpt.cibLastWritten);
337+
});
338+
339+
it('should display both SID`s in the clusters overview page', () => {
340+
cy.visit('/clusters');
341+
cy.url().should('include', '/clusters');
342+
cy.get('.container').eq(0).as('clustersTable');
343+
cy.get('@clustersTable').find('tr').eq(7).find('td').eq(2).as('sidCell');
344+
345+
availableHanaClusterCostOpt.sids.forEach((sid) => {
346+
cy.get('@sidCell').should('contain', sid);
347+
});
348+
});
349+
});
350+
236351
describe('Angi architecture', () => {
237352
before(() => {
238353
cy.loadScenario('hana-scale-up-angi');

test/e2e/cypress/fixtures/hana-cluster-details/available_hana_cluster.js

+30
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,36 @@ export const availableHanaCluster = {
218218
],
219219
};
220220

221+
export const availableHanaClusterCostOpt = {
222+
id: 'ee7ea205-d5cc-5bbd-a345-10cad2aae2d7',
223+
name: 'hana_cost_opt',
224+
sids: ['HDC', 'QAS'],
225+
systemID: [
226+
'35fce256-f5c8-5f96-bb58-022d6d2729e7',
227+
'57399859-155b-56f1-ae38-492283a8d758',
228+
],
229+
clusterType: 'HANA Scale Up Cost Opt.',
230+
architectureType: 'Classic',
231+
provider: 'Azure',
232+
hanaSystemReplicationMode: 'sync',
233+
fencingType: 'external/sbd',
234+
maintenanceMode: false,
235+
hanaSecondarySyncState: 'SOK',
236+
sapHanaSRHealthState: 4,
237+
cibLastWritten: 'Mon Aug 26 14:52:19 2024',
238+
hanaSystemReplicationOperationMode: 'logreplay',
239+
hosts: [
240+
{
241+
id: '2372b24f-3d7a-5d01-9b1a-a2c4c95c53d4',
242+
},
243+
{
244+
id: 'fa7a5602-232b-5389-96a6-f5f5de6ff9a2',
245+
},
246+
],
247+
sites: [],
248+
sbd: [],
249+
};
250+
221251
export const availableAngiCluster = {
222252
id: '69851bfe-5364-5ea8-93e1-cbe14268ccaf',
223253
name: 'hana_angi',

0 commit comments

Comments
 (0)