-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added warnings and tests for hardware profiles #3657
base: main
Are you sure you want to change the base?
added warnings and tests for hardware profiles #3657
Conversation
a244f6b
to
6f9c516
Compare
6f9c516
to
ab511bc
Compare
ab511bc
to
9125256
Compare
/retest |
9125256
to
723e629
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #3657 +/- ##
==========================================
+ Coverage 84.15% 84.36% +0.21%
==========================================
Files 1453 1472 +19
Lines 33866 34004 +138
Branches 9384 9474 +90
==========================================
+ Hits 28500 28688 +188
+ Misses 5366 5316 -50
... and 102 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
ahhh time to add more tests for the code coverage 🤣 |
frontend/src/__tests__/cypress/cypress/pages/hardwareProfile.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides the comments I left, one important note is missing. You need to automatically disable the invalid hardware profiles and disable the toggle to prevent them from re-enable it before resolving the invalid values.
![Screenshot 2025-01-20 at 4 53 03 PM](https://private-user-images.githubusercontent.com/37624318/405012248-1d3b12a5-a115-4804-9dca-358d12cc768f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1ODg2NzUsIm5iZiI6MTczOTU4ODM3NSwicGF0aCI6Ii8zNzYyNDMxOC80MDUwMTIyNDgtMWQzYjEyYTUtYTExNS00ODA0LTlkY2EtMzU4ZDEyY2M3NjhmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE1VDAyNTkzNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQ0YjI0ZmNiOGUxN2MwYzgwNjExOWNmMzM4NTBkMzhiMTVlZDIyOTI2MTdlYzhiYzliMWRmYTM1ODRjMWEwN2QmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.oTh1szFDqDgqX8tydV_OBHytIEXI_W-wHxgUMAXKIHg)
Other than that, it works well, good job! Most of my comments are about code quality because we want to make it reusable and easier to maintain in the future. :) Let me know if you have any questions with any of my comments and I am happy to help and walk you through it.
frontend/src/pages/hardwareProfiles/HardwareProfilesTableRow.tsx
Outdated
Show resolved
Hide resolved
I haven't finished testing all the scenarios yet. I will do another round of review after you address the comments I left above and test it overall again. 😄 |
e934b0d
to
2ebd5a8
Compare
@DaoDaoNoCode made the requested changes. However, for some methods, I had to fall back to Edit: May be related to this: https://issues.redhat.com/browse/RHOAIENG-18118 |
@rsun19 , Here's a possibility that you might be using old hardwareProfile CRD, Juntao added new field |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM most of the parts. There are still 2 major things.
- The use of the types - We should try to avoid redundant types and make best use of the available/existing types, so it could be easier to maintain/add features in the future.
- For "Incomplete" hardware profiles (Hardware profiles that miss CPU/Memory), we should not block them from enabling because that's still valid, just not recommended. If you want we can have a talk when you are online, so we can walk through all the comments together to make it work as expected.
frontend/src/pages/hardwareProfiles/HardwareProfileEnableToggle.tsx
Outdated
Show resolved
Hide resolved
frontend/src/pages/hardwareProfiles/manage/ManageNodeResourceSection.tsx
Outdated
Show resolved
Hide resolved
frontend/src/pages/hardwareProfiles/manage/ManageNodeResourceSection.tsx
Outdated
Show resolved
Hide resolved
2ebd5a8
to
46b5431
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: Gkrumbach07 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/hold |
4899f28
to
27a4312
Compare
New changes are detected. LGTM label has been removed. |
27a4312
to
5eed089
Compare
/retest |
5eed089
to
3e8d3d3
Compare
3e8d3d3
to
86494e3
Compare
@@ -683,3 +683,8 @@ export type IntegrationAppStatus = { | |||
variablesValidationTimestamp?: string; | |||
error: string; | |||
}; | |||
|
|||
export type WarningNotification = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep this type within the scope of hardware profiles. so move it under one of those folders in a types.ts
folder
hardwareProfile.spec.enabled && | ||
(typeof hardwareProfileWarningMessage === 'undefined' || | ||
hardwareProfileWarningMessage.message.includes(HARDWARE_PROFILES_MISSING_CPU_MEMORY_MESSAGE)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would keep is enabled separate from the warning. Just use warning to additionally disable the hardware profile
return HardwareProfileBannerWarningTitles.SOME_INCOMPLETE; | ||
}; | ||
|
||
export const generateWarningMessage = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesnt need to be exported if not used outside this file
|
||
export const isHardwareProfileOOTB = (hardwareProfile: HardwareProfileKind): boolean => | ||
hardwareProfile.metadata.labels?.['opendatahub.io/ootb'] === 'true'; | ||
|
||
export const generateWarningTitle = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesnt need to be exported unless used outside this file
export const hardwareProfileWarning = ( | ||
hardwareProfile: HardwareProfileKind, | ||
): WarningNotification | undefined => { | ||
const identifiers = hardwareProfile.spec.identifiers ?? []; | ||
let parentWarningMessage = ''; | ||
const isDefaultProfile = isHardwareProfileOOTB(hardwareProfile); | ||
if (!hasCPUandMemory(identifiers)) { | ||
parentWarningMessage = HARDWARE_PROFILES_MISSING_CPU_MEMORY_MESSAGE; | ||
} | ||
for (const identifier of identifiers) { | ||
try { | ||
if (identifier.minCount.toString().at(0) === '-') { | ||
parentWarningMessage = `Minimum allowed ${ | ||
identifier.resourceType ?? identifier.displayName | ||
} cannot be negative.`; | ||
continue; | ||
} | ||
if (identifier.maxCount.toString().at(0) === '-') { | ||
parentWarningMessage = `Maximum allowed ${ | ||
identifier.resourceType ?? identifier.displayName | ||
} cannot be negative.`; | ||
continue; | ||
} | ||
if (identifier.defaultCount.toString().at(0) === '-') { | ||
parentWarningMessage = `Default count for ${ | ||
identifier.resourceType ?? identifier.displayName | ||
} cannot be negative.`; | ||
continue; | ||
} | ||
const [minCount] = splitValueUnit( | ||
identifier.minCount.toString(), | ||
determineUnit(identifier), | ||
true, | ||
); | ||
const [maxCount] = splitValueUnit( | ||
identifier.maxCount.toString(), | ||
determineUnit(identifier), | ||
true, | ||
); | ||
const [defaultCount] = splitValueUnit( | ||
identifier.defaultCount.toString(), | ||
determineUnit(identifier), | ||
true, | ||
); | ||
if (!Number.isInteger(minCount)) { | ||
parentWarningMessage = `Minimum count for ${ | ||
identifier.resourceType ?? identifier.displayName | ||
} cannot be a decimal.`; | ||
} | ||
if (!Number.isInteger(maxCount)) { | ||
parentWarningMessage = `Maximum count for ${ | ||
identifier.resourceType ?? identifier.displayName | ||
} cannot be a decimal.`; | ||
} | ||
if (!Number.isInteger(defaultCount)) { | ||
parentWarningMessage = `Default count for ${ | ||
identifier.resourceType ?? identifier.displayName | ||
} cannot be a decimal.`; | ||
} | ||
if (minCount > maxCount) { | ||
parentWarningMessage = `Minimum allowed ${ | ||
identifier.resourceType ?? identifier.displayName | ||
} cannot exceed maximum allowed ${identifier.resourceType ?? identifier.displayName}.`; | ||
} else if (defaultCount < minCount || defaultCount > maxCount) { | ||
parentWarningMessage = `The default count for ${ | ||
identifier.resourceType ?? identifier.displayName | ||
} must be between the minimum allowed ${ | ||
identifier.resourceType ?? identifier.displayName | ||
} and maximum allowed ${identifier.resourceType ?? identifier.displayName}.`; | ||
} | ||
} catch (e) { | ||
parentWarningMessage = `The resource count for ${ | ||
identifier.resourceType ?? identifier.displayName | ||
} has an invalid unit.`; | ||
} | ||
} | ||
|
||
return parentWarningMessage | ||
? { | ||
title: `${!hasCPUandMemory(identifiers) ? 'Incomplete' : 'Invalid'} ${ | ||
isDefaultProfile === true ? 'default hardware' : 'hardware' | ||
} profile`, | ||
message: `${parentWarningMessage} ${ | ||
isDefaultProfile | ||
? HARDWARE_PROFILES_DEFAULT_WARNING_MESSAGE | ||
: 'Edit the profile to make the profile valid.' | ||
}`, | ||
} | ||
: undefined; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function should basically validate the hardware profile. It looks like you are returning only one error becuase parentWarningMessage keeps getting overwritten.
I think this function should return an array of all the warnings with the profile. so...
enum HardwareProfileWarningType {
HARDWARE_PROFILES_DEFAULT_WARNING,
HARDWARE_PROFILES_MISSING_CPU_MEMORY,
OTHER
}
type HardwareProfileWarning = {
title: string,
message: string
type: HardwareProfileWarningType
}
export const validateProfileWarning = ( hardwareProfile: HardwareProfileKind): HardwareProfileWarning[] => {
// same func body but instead add to this array and return that
}
export const generateWarningForHardwareProfiles = ( | ||
hardwareProfiles: HardwareProfileKind[], | ||
): WarningNotification | undefined => { | ||
const hasInvalid = hardwareProfiles.some((profile) => { | ||
const warning = hardwareProfileWarning(profile); | ||
return ( | ||
typeof warning !== 'undefined' && | ||
!warning.message.includes(HARDWARE_PROFILES_MISSING_CPU_MEMORY_MESSAGE) | ||
); | ||
}); | ||
const hasEnabled = hardwareProfiles.some((profile) => profile.spec.enabled); | ||
const allInvalid = hardwareProfiles.every((profile) => { | ||
const warning = hardwareProfileWarning(profile); | ||
return ( | ||
typeof warning !== 'undefined' && | ||
!warning.message.includes(HARDWARE_PROFILES_MISSING_CPU_MEMORY_MESSAGE) | ||
); | ||
}); | ||
const allIncomplete = hardwareProfiles.every((profile) => { | ||
const warning = hardwareProfileWarning(profile); | ||
return ( | ||
typeof warning !== 'undefined' && | ||
warning.message.includes(HARDWARE_PROFILES_MISSING_CPU_MEMORY_MESSAGE) | ||
); | ||
}); | ||
const hasInvalidIncludingIncompleteProfiles = hardwareProfiles.some( | ||
(profile) => typeof hardwareProfileWarning(profile) !== 'undefined', | ||
); | ||
if (hardwareProfiles.length === 0 || (!hasInvalidIncludingIncompleteProfiles && hasEnabled)) { | ||
return undefined; | ||
} | ||
return { | ||
title: generateWarningTitle(hasEnabled, allInvalid, hasInvalid, allIncomplete), | ||
message: generateWarningMessage(hasEnabled, allInvalid, hasInvalid, allIncomplete), | ||
}; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now this function after updating the other func (hardwareProfileWarning) you can instead look for the specific warnings like
const warnings = hardwareProfileWarning(profile);
const invalid === warnings.some(warning => warning.type === HARDWARE_PROFILES_MISSING_CPU_MEMORY)
RHOAIENG-17841
Description
Invalid inputs will now show warnings in the UI
How Has This Been Tested?
You can directly insert hardware profiles in the cluster dashboard. Input invalid values as specified in the jira issue and mockups.
Test Impact
I added unit tests and cypress tests
Request review criteria:
Self checklist (all need to be checked):
If you have UI changes:
After the PR is posted & before it merges:
main