start adding unit tests for ironic.ValidateManagementAccess#647
Conversation
89806b8 to
d791e5b
Compare
|
/test-integration |
|
I would like to freeze non-essential changes for a few days to try to land #650 without having to rebase it, because rebasing will mean redoing the work from scratch. /hold |
d791e5b to
ba1e7d0
Compare
|
#655 has merged /hold cancel |
|
/test-integration |
ba1e7d0 to
28d2d40
Compare
|
I've rebased this on the work @andfasano did in #649 /test-integration |
28d2d40 to
4beff98
Compare
| hostName: "name", | ||
| provisioningID: "uuid", | ||
| ironic: testserver.New(t, "ironic").NotFound("/v1/nodes/name"). | ||
| ironic: testserver.NewIronic(t).NotFound("/v1/nodes/name"). |
There was a problem hiding this comment.
NotFound as a generic method is ok, an alternative could be to use WithNodeError, ie:
testserver.NewIronic(t).WithNodeError("name", http.StatusNotFound).WithNodeError("uuid", http.StatusNotFound)
On a second pass, noticed you've added also a NoNode, which could be even better for simplifying mock's usage since it requires just the node name
| bodyRaw, err := ioutil.ReadAll(r.Body) | ||
| if err != nil { | ||
| m.logRequest(r, fmt.Sprintf("ERROR: %s", err)) | ||
| http.Error(w, fmt.Sprintf("%s", err), 500) |
There was a problem hiding this comment.
Minor point, http.StatusInternalServerError could be more readable
| response := fmt.Sprintf("{\"uuid\": \"%s\", %s", uuid, strings.TrimLeft(body, "{")) | ||
|
|
||
| w.Header().Set("Content-Type", "application/json") | ||
| w.WriteHeader(201) |
| assert.Equal(t, "", result.ErrorMessage) | ||
| assert.NotEqual(t, "", host.Status.Provisioning.ID) | ||
| assert.Equal(t, ironic.CreatedNodes[0].UUID, host.Status.Provisioning.ID) | ||
| } |
There was a problem hiding this comment.
(Not blocking) I noticed that the three test cases have been split into three different test methods (TestValidateManagementAccessNoMAC, TestValidateManagementAccessMACOptional and TestValidateManagementAccessCreateNode) sharing a pretty similar setup code.
Maybe it's not worth in this case, but to transform the three methods in a list of cases in a single test method it could be useful to "upgrade" the makeHost() factory method to a proper host builder object with fluent interface, so that also the host could become a parameter of the cases list (and of course also the expectations code will need to be adjusted).
There was a problem hiding this comment.
Given that the ValidateManagementAccess is a pretty big method to be covered, the existing node and/or credentials change case will be added within this PR?
There was a problem hiding this comment.
The setup portions of the functions are similar, but the checks were different enough that it seemed like it would be clearer to just write separate functions this time, instead of having more complicated logic to decide which tests to apply in each case.
In terms of test coverage, I think this PR is big enough and I would like to merge it before finishing the tests for ValidateManagementAccess.
| } | ||
|
|
||
| // Implements provisioner.EventPublisher to swallow events for tests. | ||
| func nullEventPublisher(reason, message string) {} |
There was a problem hiding this comment.
Nice one, we could introduce a set of different hard-coded publishers (ie null, std) to be reused in all the tests to remove some other lines of code
| }) | ||
|
|
||
| // hackily add uuid to the json response by inserting it to the front of the string | ||
| response := fmt.Sprintf("{\"uuid\": \"%s\", %s", uuid, strings.TrimLeft(body, "{")) |
There was a problem hiding this comment.
Just as a confirmation, is it fine to return all the fields sent in the body request as a response? From a quick glance on the API here should be fine. Maybe in future we could need something more sophisticated, but for the current test seems ok
There was a problem hiding this comment.
Yes, my understanding is the API is supposed to return the node, which may include new fields (as with UUID here) and should include the data passed to us. A better implementation would extract the input into a nodes.Node, add the UUID, then marshal it back to JSON for the response, but I'm trying to keep things simple.
4beff98 to
2f1cebc
Compare
2f1cebc to
f1d8c9d
Compare
andfasano
left a comment
There was a problem hiding this comment.
Current changes look fine to me
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: andfasano, dhellmann The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Signed-off-by: Doug Hellmann <dhellmann@redhat.com>
Make the BMC access type registration function public so we can add fixture types in tests for the ironic provisioner. Signed-off-by: Doug Hellmann <dhellmann@redhat.com>
Add a testbmc type so the ironic tests that create hosts can use a test:// URL for the BMC address. Signed-off-by: Doug Hellmann <dhellmann@redhat.com>
Verify that ValidateManagementAccess() reports an error when the driver needs a bootMACAddress and the host does not have one. Signed-off-by: Doug Hellmann <dhellmann@redhat.com>
Verify that ValidateManagementAccess() does not report an error when the host has no boot MAC and the BMC does not require one. Signed-off-by: Doug Hellmann <dhellmann@redhat.com>
Add CreateNodes() method to IronicMock to simulate creating a node. Add a test for ValidateManagementAccess that triggers creating a node and verifies that the host status is updated with the UUID of the new node. Signed-off-by: Doug Hellmann <dhellmann@redhat.com>
Look at the node struct we're given and register the responses for both UUID and Name, based on which values are filled in. Signed-off-by: Doug Hellmann <dhellmann@redhat.com>
f1d8c9d to
c167d52
Compare
|
/test-integration Rebased to get the |
|
/cc @asalkeld |
| if node.UUID != "" { | ||
| m.ResponseJSON("/v1/nodes/"+node.UUID, node) | ||
| } | ||
| if node.Name != "" { |
There was a problem hiding this comment.
I have a couple of question on this change:
- Is it a valid case to have the UUID unset and Name set?
- When both UUID and Name are set, will the ServeMux.Handle panic?
There was a problem hiding this comment.
A real ironic service wouldn't have a node without a UUID, but in the tests we sometimes want the node to only be available via one or the other value to simulate the node having settings different from what the provisioner expects.
I'm not sure why the handler would panic? The endpoints are different (one looks up by UUID, the other by name).
There was a problem hiding this comment.
In case Name == UUID, but I think it's a trivial case
There was a problem hiding this comment.
Ah, yes, I didn't consider that. I think it's OK for the test to panic in that situation, since that doesn't seem like something we would expect to encounter in real data. I could add a test to protect against it, if you think it's worth it?
There was a problem hiding this comment.
I don't think it's worth it, and agree it's fine to panic in such situation
|
@asalkeld: adding LGTM is restricted to approvers and reviewers in OWNERS files. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
|
I'm also fine with the changes |
| func init() { | ||
| bmc.RegisterFactory("test", newTestBMCAccessDetails, []string{}) | ||
| bmc.RegisterFactory("test-needs-mac", newTestBMCAccessDetails, []string{}) | ||
| } |
There was a problem hiding this comment.
Would it be safer to register these explicitly in tests rather than it happening as a side-effect here?
There was a problem hiding this comment.
Probably. On the other hand, all of the rest of the registry stuff expects to be invoked from an init() function like this, the registry is global state without a way to reset right now, and I'm not sure what happens if the same name is registered more than once.
I would be happy to consider making the registry more accepting of dynamic use in a separate PR.
|
/lgtm |
No description provided.