Skip to content

Commit fe37833

Browse files
Merge pull request #3704 from openshift-trt/trt-2756
TRT-2756: Test-details links in on-demand staging environment point to localhost
2 parents efaa0a6 + 0867d36 commit fe37833

3 files changed

Lines changed: 91 additions & 121 deletions

File tree

pkg/sippyserver/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ func (s *Server) jsonComponentReportTestDetailsFromBigQuery(w http.ResponseWrite
10771077
failureResponse(w, http.StatusBadRequest, err.Error())
10781078
return
10791079
}
1080-
baseURL := api.GetBaseURL(req)
1080+
baseURL := api.GetBaseFrontendURL(req)
10811081
outputs, errs := componentreadiness.GetTestDetails(req.Context(), s.crDataProvider, s.db, reqOptions, allReleases, baseURL)
10821082
if len(errs) > 0 {
10831083
log.Warningf("%d errors were encountered while querying component test details from big query:", len(errs))

sippy-ng/src/component_readiness/CompReadyUtils.js

Lines changed: 13 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -796,113 +796,23 @@ export function generateTestReport(
796796
return sortQueryParams(retUrl)
797797
}
798798

799-
// Helper function to compare query parameters between two URLs
800-
export function compareUrlQueryParams(newURL, oldURL) {
801-
// Extract query parameters from both URLs
802-
const [, queryString1] = newURL.split('?')
803-
const [, queryString2] = oldURL.split('?')
804-
805-
if (!queryString1 || !queryString2) {
806-
console.log('One or both URLs do not have query parameters')
807-
return
808-
}
809-
810-
// Parse query parameters
811-
const params1 = new URLSearchParams(queryString1)
812-
const params2 = new URLSearchParams(queryString2)
813-
814-
// Convert to objects for easier comparison
815-
const paramsObjNew = {}
816-
const paramsObjOld = {}
817-
818-
for (const [key, value] of params1.entries()) {
819-
paramsObjNew[key] = value
820-
}
821-
822-
for (const [key, value] of params2.entries()) {
823-
paramsObjOld[key] = value
824-
}
825-
826-
// Find differences
827-
const differences = {
828-
onlyInNew: {},
829-
onlyInOld: {},
830-
differentValues: {},
831-
}
832-
833-
// Check for params in url1 but not in url2 or with different values
834-
for (const key in paramsObjNew) {
835-
if (!(key in paramsObjOld)) {
836-
differences.onlyInNew[key] = paramsObjNew[key]
837-
} else if (paramsObjNew[key] !== paramsObjOld[key]) {
838-
differences.differentValues[key] = {
839-
newURL: paramsObjNew[key],
840-
oldURL: paramsObjOld[key],
841-
}
842-
}
843-
}
844-
845-
// Check for params in old but not in new
846-
for (const key in paramsObjOld) {
847-
if (!(key in paramsObjNew)) {
848-
differences.onlyInOld[key] = paramsObjOld[key]
849-
}
850-
}
851-
852-
// Log differences
853-
if (Object.keys(differences.onlyInNew).length > 0) {
854-
console.log(
855-
'Parameters only in new URL from server:',
856-
differences.onlyInNew
857-
)
858-
}
859-
860-
if (Object.keys(differences.onlyInOld).length > 0) {
861-
console.log(
862-
'Parameters only in old URL from frontend:',
863-
differences.onlyInOld
864-
)
865-
}
866-
867-
if (Object.keys(differences.differentValues).length > 0) {
868-
console.log(
869-
'Parameters with different values:',
870-
differences.differentValues
871-
)
872-
}
873-
874-
if (
875-
Object.keys(differences.onlyInNew).length === 0 &&
876-
Object.keys(differences.onlyInOld).length === 0 &&
877-
Object.keys(differences.differentValues).length === 0
878-
) {
879-
console.log('Both URLs have identical query parameters')
880-
}
881-
882-
return differences
883-
}
884-
885-
// Convert API URL to UI URL
886-
// API URL format: http://localhost:8080/api/component_readiness/test_details?...
887-
// UI URL format: http://localhost:3000/sippy-ng/component_readiness/test_details?...
799+
// Convert API URL to a relative UI URL by stripping any scheme+host and
800+
// swapping the /api/ prefix for /sippy-ng/. Producing a relative path
801+
// avoids the bug where the backend embeds localhost (or another internal
802+
// host) as the origin in HATEOAS links.
888803
export function convertApiUrlToUiUrl(apiUrl) {
889-
console.log('convertApiUrlToUiUrl input:', apiUrl)
890-
let result
891-
// Handle the most specific case first
892-
if (apiUrl.includes('/api/component_readiness/')) {
893-
result = apiUrl.replace(
804+
const apiIndex = apiUrl.indexOf('/api/')
805+
if (apiIndex === -1) {
806+
return apiUrl
807+
}
808+
const pathAndQuery = apiUrl.substring(apiIndex)
809+
if (pathAndQuery.startsWith('/api/component_readiness/')) {
810+
return pathAndQuery.replace(
894811
'/api/component_readiness/',
895812
'/sippy-ng/component_readiness/'
896813
)
897-
} else if (apiUrl.startsWith('/api/')) {
898-
// Handle general /api/ prefix (for relative URLs)
899-
result = apiUrl.replace('/api/', '/sippy-ng/')
900-
} else {
901-
// Fallback: return as-is
902-
result = apiUrl
903814
}
904-
console.log('convertApiUrlToUiUrl output:', result)
905-
return result
815+
return pathAndQuery.replace('/api/', '/sippy-ng/')
906816
}
907817

908818
// Extracts the test_details link from HATEOAS links. Prefers the plain
@@ -949,27 +859,10 @@ export function generateTestDetailsReportLink(
949859
`&capability=${regressedTest.capability}` +
950860
`&testName=${safeTestName}`
951861

952-
const sortedGeneratedUrl = sortQueryParams(generatedUrl)
953862
const testDetailsUrl = getTestDetailsLink(regressedTest.links, viewName)
954863
if (testDetailsUrl) {
955-
// Compare the query parameters between the two URLs
956-
console.log(
957-
'Comparing query parameters between provided URL and generated URL:'
958-
)
959-
compareUrlQueryParams(testDetailsUrl, sortedGeneratedUrl)
960-
961-
// We are assuming the API query params are identical to the UI query params, but we have to adjust the host port and prefix from
962-
// http://localhost:8080/api/ to http://localhost:3000/sippy-ng/
963-
// This hack allows us to keep the param generation logic in one place. (server side)
964-
console.log('testDetailsUrl', testDetailsUrl)
965-
const modifiedUrl = convertApiUrlToUiUrl(testDetailsUrl)
966-
console.log('modifiedUrl', modifiedUrl)
967-
return modifiedUrl
864+
return convertApiUrlToUiUrl(testDetailsUrl)
968865
}
969-
console.log(
970-
'WARNING: report had no test details url, using old generated url: ' +
971-
generatedUrl
972-
)
973866

974867
return generatedUrl
975868
}

sippy-ng/src/component_readiness/CompReadyUtils.test.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
//import HelloWorld from './HelloWorld'
22
import {
3+
convertApiUrlToUiUrl,
34
dateEndFormat,
45
dateFormat,
56
formatLongDate,
7+
generateTestDetailsReportLink,
68
getTestDetailsLink,
79
} from './CompReadyUtils'
810

@@ -82,3 +84,78 @@ describe('getTestDetailsLink', () => {
8284
expect(getTestDetailsLink(links)).toBe('/api/plain')
8385
})
8486
})
87+
88+
describe('convertApiUrlToUiUrl', () => {
89+
test('rewrites /api/component_readiness/ to /sippy-ng/component_readiness/', () => {
90+
expect(
91+
convertApiUrlToUiUrl(
92+
'http://localhost:8080/api/component_readiness/test_details?testId=foo'
93+
)
94+
).toBe('/sippy-ng/component_readiness/test_details?testId=foo')
95+
})
96+
97+
test('rewrites generic /api/ prefix to /sippy-ng/', () => {
98+
expect(
99+
convertApiUrlToUiUrl('https://sippy.dptools.openshift.org/api/other/path')
100+
).toBe('/sippy-ng/other/path')
101+
})
102+
103+
test('returns non-/api/ URLs unchanged', () => {
104+
expect(
105+
convertApiUrlToUiUrl('/sippy-ng/component_readiness/test_details?x=1')
106+
).toBe('/sippy-ng/component_readiness/test_details?x=1')
107+
})
108+
109+
test('handles relative /api/ paths without a host', () => {
110+
expect(
111+
convertApiUrlToUiUrl('/api/component_readiness/test_details?a=b')
112+
).toBe('/sippy-ng/component_readiness/test_details?a=b')
113+
})
114+
})
115+
116+
describe('generateTestDetailsReportLink', () => {
117+
const filterVals = '?baseRelease=4.18&baseStartTime=2024-01-01'
118+
const expandEnvironment = (env) => `&environment=${env}`
119+
120+
test('returns server link converted to UI URL when HATEOAS link is present', () => {
121+
const regressedTest = {
122+
test_id: 'test-123',
123+
test_name: 'my test',
124+
component: 'Networking',
125+
capability: 'cap1',
126+
variants: { Architecture: 'amd64' },
127+
base_stats: { release: '4.18' },
128+
links: {
129+
test_details:
130+
'http://localhost:8080/api/component_readiness/test_details?testId=test-123&component=Networking',
131+
},
132+
}
133+
const result = generateTestDetailsReportLink(
134+
regressedTest,
135+
filterVals,
136+
expandEnvironment
137+
)
138+
expect(result).toBe(
139+
'/sippy-ng/component_readiness/test_details?testId=test-123&component=Networking'
140+
)
141+
})
142+
143+
test('falls back to generated URL when no HATEOAS link exists', () => {
144+
const regressedTest = {
145+
test_id: 'test-123',
146+
test_name: 'my test',
147+
component: 'Networking',
148+
capability: 'cap1',
149+
variants: { Architecture: 'amd64' },
150+
base_stats: { release: '4.18' },
151+
links: {},
152+
}
153+
const result = generateTestDetailsReportLink(
154+
regressedTest,
155+
filterVals,
156+
expandEnvironment
157+
)
158+
expect(result).toContain('/sippy-ng/component_readiness/test_details')
159+
expect(result).toContain('testId=test-123')
160+
})
161+
})

0 commit comments

Comments
 (0)