Skip to content
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

Set default boolean values #122

Merged
merged 3 commits into from
Nov 4, 2021
Merged

Set default boolean values #122

merged 3 commits into from
Nov 4, 2021

Conversation

kim-tsao
Copy link
Contributor

What does this PR do?:

  • Updates the parser to set defaults on nil boolean fields after workspace contents are merged.

  • Updates the parser tests to include coverage for overriding unset/set values, and merging values for all boolean properties including the RootRequired field in the 2.2 spec.

Which issue(s) this PR fixes:

devfile/api#615

PR acceptance criteria:

Testing and documentation do not need to be complete in order for this PR to be approved. We just need to ensure tracking issues are opened.

  • Open new test/doc issues under the devfile/api repo
  • Check each criteria if:
  • There is a separate tracking issue. Add the issue link under the criteria
    or
  • test/doc updates are made as part of this PR
  • If unchecked, explain why it's not needed

These changes ensure clients do not encounter nil boolean values when using a parsed object, similar to the expected content before boolean pointers were introduced.

How to test changes / Special notes to the reviewer:

@openshift-ci openshift-ci bot requested review from elsony and yangcao77 October 27, 2021 20:22
@kim-tsao kim-tsao requested review from maysunfaisal and removed request for elsony October 27, 2021 20:22
@kim-tsao kim-tsao marked this pull request as draft October 27, 2021 20:25
@kim-tsao kim-tsao marked this pull request as ready for review October 27, 2021 20:25
@@ -281,6 +281,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool
d.Data.SetDevfileWorkspaceSpecContent(*mergedContent)
// remove parent from flatterned devfile
d.Data.SetParent(nil)
setDefaults(d)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put it at the end of this if block instead, it will be more neat and clear that the default values are being set before returning the flatternedDevfile

if flattenedDevfile {
err = parseParentAndPlugin(d, resolveCtx, tool)
if err != nil {
return DevfileObj{}, err
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseParentAndPlugin is called from two places; parseDevfile and parseFromKubeCRD which is why I opted to place the call in one common place

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay I understand, KubeCRD is just another way to specify a parent. and you are right parseDevfile is also being called multiple times because we are going to recursively call it to resolve nested parents case.

But you want all defaults to be set after all flattening is done, not being set multiple times in the middle of all merging & overriding. so it should be called at the end of the very top level. basically this function, which is directly called by ParseDevfileAndValidate:

func ParseDevfile(args ParserArgs) (d DevfileObj, err error) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can make the changes but that means I can't reuse the existing tests since they call the internal functions. I will have to create new test cases to call ParseDevfile

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes please. or you can only create unit test for setDefaults. leave the parser test to the new test suite we discussed about for consumer's view testing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have some existing coverage by default in the library tests because the common api test utils randomly generates the boolean fields (it's missing the new RootRequired property which I'll open a new issue for). There's a verify function that validates the expected output but it's like a black box, where if there are no errors, we can assume everything is working fine. I can undo the changes to the parser_test file add additional coverage for parent overrides in this issue which I opened as a result of our previous discussion about unit vs function tests: devfile/api#655

command := commands[i]
if command.Exec != nil {
exec := command.Exec
if exec.HotReloadCapable == nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw the getters in devfile/api already done the nil checks, and set it to proper value. why we are doing this deplicated nil checks here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I debated about that, but ultimately decided that it might be worth the extra nil check to avoid making unnecessary function calls which may impact performance if the commands/components are nil most of the time. This is the unfortunate the side effect of having a common API that tries to satisfy different client use cases.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally prefer directly call those functions, as it will make the code more clean. And those functions calls won't increase any complexity, but might need time to build the stack. So depends on you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a quick test to see what execution times were by running the library tests with and without the nil checks and the results are negligible. There's a slight degradation but it's in the order of milliseconds, so I'll incorporate these changes.


//set defaults on the commands
for i := range commands {
command := commands[i]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick question on a glance, since command is just a new variable; will the d DevfileObj still have those changes? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, command references the same address location of the underlying command. e.g. The first ApplyCommand is referenced by d while the second is referenced by command
image

…checks. Remove expected default values from parse_test.go
@@ -281,6 +288,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool
d.Data.SetDevfileWorkspaceSpecContent(*mergedContent)
// remove parent from flatterned devfile
d.Data.SetParent(nil)
//setDefaults(d)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should remove this comment?

@@ -133,6 +135,27 @@ func Test_parseParentAndPluginFromURI(t *testing.T) {
},
},
},
{
Name: "image",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those image components are basically identical, except for those boolean values. Can you create a function to generate the image component and accept the boolean value as a param? and call that func directly instead of re-defining it in each test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, optimizations can be made in other components too. I'll try to get those updated as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some common functions for other components in: https://github.com/devfile/library/blob/main/pkg/testingutil/devfile.go , you can add image component in that file as well

for those tests that need more flexibility on component content can stay with the definition in unit test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created some utils and I was able to extend it so other properties could be set. If you agree with this, I think we should look at cleaning up some areas of our test cases in a similar manner since it produces a more readable file

Copy link
Collaborator

@yangcao77 yangcao77 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes lgtm

@openshift-ci openshift-ci bot added the lgtm label Nov 4, 2021
@openshift-ci
Copy link

openshift-ci bot commented Nov 4, 2021

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: kim-tsao, yangcao77

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kim-tsao kim-tsao merged commit 49d635c into devfile:main Nov 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants