-
Notifications
You must be signed in to change notification settings - Fork 6
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
e2e, persistent-ip: Add primary-UDN tests #72
Conversation
This will enable the network-segmentation feature on OVNK, needed in order to run VM workloads with primary UDN. Signed-off-by: Ram Lavi <[email protected]>
cf5b99e
to
932079d
Compare
@qinqon I eventually did not parametize the generateVM function, as it also needs the nad.Name which is not static (randomized)... so this is the only place where we use If(role ==...). I can live with that, tell me what you think though. |
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.
just nits
test/e2e/persistentips_test.go
Outdated
@@ -40,6 +40,8 @@ import ( | |||
"sigs.k8s.io/controller-runtime/pkg/client" | |||
) | |||
|
|||
const networkInterfaceName = "multus" |
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 is both the VMI interface/network logical name and the field at VMI status to look for so and is just for secondaries so let's name this
secondaryLogicalNetworkInterfaceName
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.
fixed
test/e2e/persistentips_test.go
Outdated
vmi *kubevirtv1.VirtualMachineInstance | ||
nad *nadv1.NetworkAttachmentDefinition | ||
td testenv.TestData | ||
getIPsFunc func(vmi *kubevirtv1.VirtualMachineInstance) ([]string, error) |
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.
Let's call this ipsFrom
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.
done
test/e2e/persistentips_test.go
Outdated
@@ -312,3 +317,7 @@ func removeFinalizersPatch() ([]byte, error) { | |||
} | |||
return json.Marshal(patch) | |||
} | |||
|
|||
func getIPsFromVMIStatus(vmi *kubevirtv1.VirtualMachineInstance) ([]string, error) { |
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 is just for secondaries since it passes the secondary network interface name let's call this secondaryNetworkVMIStatusIPs
so we have
ipsFrom: secondaryNetworkVMIStatusIPs
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.
done
test/e2e/persistentips_test.go
Outdated
|
||
type testParams struct { | ||
role string | ||
getIPsFunc func(vmi *kubevirtv1.VirtualMachineInstance) ([]string, error) |
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.
let's rename this to ipsFrom
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.
DONE
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.
Thank you.
@@ -3,7 +3,7 @@ | |||
set -xe | |||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" | |||
|
|||
KIND_ARGS="${KIND_ARGS:--ic -ikv -i6 -mne}" | |||
KIND_ARGS="${KIND_ARGS:--ic -ikv -i6 -mne -nse}" |
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.
do we want this on all lanes, or we want to add an additional lane, and test it there ?
I'm inclined to say we want the latter.
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.
hmm.. regardless of the question whether we want to run the tests in a parallel lane, I don't think we should only enable it when we want to test it.
It's a feature that is planned to be enabled by default, so I don't see a good reason why not to add it for all the cluster lanes.
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 also dont see why to add another lane tbh, we should not over test
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.
OK, let's roll with it.
test/e2e/persistentips_test.go
Outdated
|
||
Expect(vmi.Status.Interfaces).NotTo(BeEmpty()) | ||
Expect(vmi.Status.Interfaces[0].IPs).NotTo(BeEmpty()) | ||
Expect(testenv.ThisVMI(vmi)()).Should(testenv.MatchIPs(params.getIPsFunc, Not(BeEmpty()))) |
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 honestly fail to understand how is this simpler than what we had before.
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.
It's not simpler. It's adding another dimension in order to accommodate the primary UDN tests..
test/e2e/persistentips_test.go
Outdated
@@ -112,8 +128,7 @@ var _ = Describe("Persistent IPs", func() { | |||
WithTimeout(5 * time.Minute). | |||
Should(testenv.ContainConditionVMIReady()) | |||
|
|||
Expect(testenv.ThisVMI(vmi)()).Should(testenv.MatchIPsAtInterfaceByName(networkInterfaceName, ConsistOf(vmiIPsBeforeMigration))) | |||
|
|||
Expect(testenv.ThisVMI(vmi)()).Should(testenv.MatchIPs(params.getIPsFunc, ConsistOf(vmiIPsBeforeMigration))) |
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.
looking at this now, I think the condition was wrong before, and you're taking it a step further in the wrong direction.
I would expect to see something like:
Expect(testenv.VMIPs(vmi)()).To(ConsistOf(vmiIPsBeforeMigration))
meaning, IMHO the IP extraction should go in the expect body, rather than in a transformation applied in the matcher.
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 think the reason this convoluted way of checking (original code):
Expect(testenv.ThisVMI(vmi)()).Should(testenv.MatchIPs(getIPsFunc, ConsistOf(vmiIPsBeforeMigration)))
is done so that we won't have to re-get the VMI instance.
Changing it to what you want needs to look like this:
Expect(testenv.Client.Get(context.Background(), client.ObjectKeyFromObject(vmi), vmi)).To(Succeed())
Expect(testenv.VMIPs(vmi)()).To(ConsistOf(vmiIPsBeforeMigration))
otherwise the VMI object in the test is not refreshed with the post-migration entity.
would you like this PR to include this refactorment? I kinda feel it should have a separate PR (which is why I didn't refactor it here) - but I don't mind doing it on this PR.
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.
OK, I hate how this looks now, but this can be addressed in a follow up.
Just saying: this looks a lot more complex than it should be.
Hiding re-fetching the VM behind a function so I can save an eventually, is also not good IMHO.
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.
+1. Will tackle in follow up PR
test/e2e/persistentips_test.go
Outdated
|
||
Expect(vmi.Status.Interfaces).NotTo(BeEmpty()) | ||
Expect(vmi.Status.Interfaces[0].IPs).NotTo(BeEmpty()) | ||
IPs, err := params.getIPsFunc(vmi) |
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.
nit: ips, not IPs.
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.
fixed
test/e2e/persistentips_test.go
Outdated
@@ -311,3 +339,7 @@ func removeFinalizersPatch() ([]byte, error) { | |||
} | |||
return json.Marshal(patch) | |||
} | |||
|
|||
func getIPsFromVMIStatus(vmi *kubevirtv1.VirtualMachineInstance) ([]string, error) { |
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 don't get this function. All it does in wrap another function, and IIUC it can't error.
Hence, why do you have an error in the func's signature ?
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.
Since the same test portfolio is run for both secondary/primary UDN, we could either copy the entire tests for primary UDN (making a lot of duplicate code), OR try to join them. The main change is the way both tests retrieve the IPs from the VMI:
For secondary: retrieve the IPs from the VMI.Status
For primary UDN: retrieve the IPs from the pod's network-status annotation.
So right now you're right - it's seems like a unneeded generalization of the function.
But what we eventually need is a general ipsFrom
function, that will satisfy both options.
BTW once the IPs could be retrieved from the VMI.status also for primary UDNs then we could remove this complexity.
I will adjust the commit message to better explain this.
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 still don't get it.
Why does the function's signature return an error ?
Will a follow up commit change this to throw an error ? If so, why don't you update the function's signature to return an error when it is needed ?
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.
ACK, I'll introduce the error return param in the relevant commit.
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.
DONE. It's now in a separate commit. PTAL
test/env/getter.go
Outdated
err := Client.List(context.Background(), pods, | ||
client.InNamespace(namespace), | ||
client.MatchingLabels(labelSelector), | ||
client.MatchingFields(fieldSelector)) |
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.
let's be consistent; either everything in one line, or one item per line.
err := Client.List(context.Background(), pods, | |
client.InNamespace(namespace), | |
client.MatchingLabels(labelSelector), | |
client.MatchingFields(fieldSelector)) | |
err := Client.List( | |
context.Background(), | |
pods, | |
client.InNamespace(namespace), | |
client.MatchingLabels(labelSelector), | |
client.MatchingFields(fieldSelector), | |
) |
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.
DONE
test/env/getter.go
Outdated
} | ||
|
||
if len(pods.Items) == 0 { | ||
return nil, fmt.Errorf("failed to lookup pod") |
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.
maybe consider printing the selectors.
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.
Added.
test/env/getter.go
Outdated
if node := vmi.Status.NodeName; node != "" { | ||
const nodeName = "spec.nodeName" | ||
fieldSelectors[nodeName] = node | ||
} |
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.
is this needed ? Trying to wrap my head around how could we reach this sorry state, and I just can't find it. Minus KubeVirt bugs of course.
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 thought it was necessary because it's migration and we can two running pods, just on different nodes, but since we're also using the vmi label selector using the VMI.UID, then I guess it's redundant.
I don't know of any kubevirt bug it is meant to cover, so removing.
test/env/getter.go
Outdated
return netStatus, nil | ||
} | ||
|
||
func getDefaultNetworkStatus(vmi *kubevirtv1.VirtualMachineInstance) (*nadv1.NetworkStatus, error) { |
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.
Do you mean cluster default network here ? In primary UDN we can have have a different primary network than the cluster default network.
Also, please drop the get.
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 mean the network status with the default: true
in it.
Removed the get
test/env/getter.go
Outdated
return nil, fmt.Errorf("primary IPs not found") | ||
} | ||
|
||
func GetIPsFromNetworkStatusAnnotation(vmi *kubevirtv1.VirtualMachineInstance) ([]string, error) { |
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.
func GetIPsFromNetworkStatusAnnotation(vmi *kubevirtv1.VirtualMachineInstance) ([]string, error) { | |
func IPsFromNetworkStatusAnnotation(vmi *kubevirtv1.VirtualMachineInstance) ([]string, error) { |
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.
DONE
932079d
to
c2d54f7
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.
nits on naming.
test/env/getter.go
Outdated
func IPsFromNetworkStatusAnnotation(vmi *kubevirtv1.VirtualMachineInstance) ([]string, error) { | ||
defNetworkStatus, err := defaultNetworkStatus(vmi) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return defNetworkStatus.IPs, nil | ||
} |
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.
Move this function to the test, and call it defaultNetworkStatusAnnotationIPs
so the test reads
ipsFrom: defaultNetworkStatusAnnotationIPs
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.
c2d54f7
to
169064a
Compare
@RamLavi I would like to remove the other "if role == secondary" from the test by exposing the VMI build functios to the test struct, I know we say we were not going to do so, but it do not feel right, what do you think ? |
I'm game, I'll create a NewVMI function with options.. |
Currently GenerateLayer2WithSubnetNAD is creating NADs for secondary roles (which is the default). Add role input param to the function in order to support primary role that will be used in future commits. Signed-off-by: Ram Lavi <[email protected]>
169064a
to
e075b19
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.
Another nit I forgot.
/lgtm |
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.
Thanks for the commit split. It makes it easier to review.
We're nearly there.
We can tackle the matchers in a follow-up PR.
@@ -3,7 +3,7 @@ | |||
set -xe | |||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" | |||
|
|||
KIND_ARGS="${KIND_ARGS:--ic -ikv -i6 -mne}" | |||
KIND_ARGS="${KIND_ARGS:--ic -ikv -i6 -mne -nse}" |
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.
OK, let's roll with it.
test/e2e/persistentips_test.go
Outdated
|
||
Expect(vmi.Status.Interfaces).NotTo(BeEmpty()) | ||
Expect(vmi.Status.Interfaces[0].IPs).NotTo(BeEmpty()) | ||
Expect(testenv.ThisVMI(vmi)()).Should(testenv.MatchIPs(ipsFrom, Not(BeEmpty()))) |
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.
wouldn't this be the same as
Expect(...).NotTo(testenv.MatchIPs(ipsFrom, BeEmpty()))
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 think so, but both options seem equally convoluted. Let's tackle it in a follow up PR as you suggest
test/e2e/persistentips_test.go
Outdated
@@ -311,3 +339,7 @@ func removeFinalizersPatch() ([]byte, error) { | |||
} | |||
return json.Marshal(patch) | |||
} | |||
|
|||
func getIPsFromVMIStatus(vmi *kubevirtv1.VirtualMachineInstance) ([]string, error) { |
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 still don't get it.
Why does the function's signature return an error ?
Will a follow up commit change this to throw an error ? If so, why don't you update the function's signature to return an error when it is needed ?
test/e2e/persistentips_test.go
Outdated
@@ -112,8 +128,7 @@ var _ = Describe("Persistent IPs", func() { | |||
WithTimeout(5 * time.Minute). | |||
Should(testenv.ContainConditionVMIReady()) | |||
|
|||
Expect(testenv.ThisVMI(vmi)()).Should(testenv.MatchIPsAtInterfaceByName(networkInterfaceName, ConsistOf(vmiIPsBeforeMigration))) | |||
|
|||
Expect(testenv.ThisVMI(vmi)()).Should(testenv.MatchIPs(params.getIPsFunc, ConsistOf(vmiIPsBeforeMigration))) |
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.
OK, I hate how this looks now, but this can be addressed in a follow up.
Just saying: this looks a lot more complex than it should be.
Hiding re-fetching the VM behind a function so I can save an eventually, is also not good IMHO.
In the current tests (where we only run persistent ip tests for secondary interfaces), the ips of the VMI is extracted via vmi.status. This is done both directly and via the matchers in testenv library. In order for the test suite to support running the same tests on primary UDN VMs, this function needs to be generalized in the following ways: 1. it should align all the IP retrievals to use this new function (right now the IPs are retrieved both directly accessing vmi.status and via a function). 2. it should move the function retrieving the IPs to a first-class functions variable, so that the way IPS are retrieved can be generalized. 3. it should only have the common parameters needed to get the IPs (which is the VMI object). Moving get the IP extraction to a general function, so that it could be consumed uniformly. Doing this will allow to more easily retrieve the IP in other cases such as primary UDN, where the IP is currently retrieved in another way. This will be added in future commits. Signed-off-by: Ram Lavi <[email protected]>
In the current tests (where we only run persistent ip tests for secondary interfaces), the VMI is created using the GenerateAlpineWithMultusVMI function. In order for the test suite to support running the same tests on primary UDN VMIs, refactoring the function to use VMI factory function. Moreover, the NAD Name is changed to be static, as it allows it to be consumed before runtime, as a test parameter for both the NAD and VMI creation. This shouldn't interfere with the tests operations as the NADs are created in different namespaces. Signed-off-by: Ram Lavi <[email protected]>
Expand the current test to run in a DescribeTableSubtree context. This is in preparation of adding more interface types in future commits. This commit does not add tests, nor change their operation. Signed-off-by: Ram Lavi <[email protected]>
e075b19
to
5461a44
Compare
Introducing the functions needed in order to run the current test suite for primary UDN interfaces: - defaultNetworkStatusAnnotationIPs - as the getIP function for primary UDN. - vmiWithPasst - as the vmi Generating function for primary UDN. These will be introduced as parameter functions when primary-UDN Entry is introduced in future commit. Moreover, since the function getting the IPs for primary-UDN case needs to return error, this is added to the general function signature. Signed-off-by: Ram Lavi <[email protected]>
Add a new test subtree entry for primary UDN interfaces, checking persistentIPs on workload with primary UDN. Signed-off-by: Ram Lavi <[email protected]>
5461a44
to
a873dfb
Compare
Change: fixed dco issue |
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.
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: maiqueb 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 cancel |
version: 2 | ||
ethernets: | ||
eth0: | ||
dhcp4: true` |
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.
btw this is not required as far as i remember for our machines right ?
going to try and drop it during the effort to convert to managedTap
What this PR does / why we need it:
Since the same test portfolio is run for both secondary/primary UDN, we could either copy the entire tests for primary UDN (making a lot of duplicate code), OR try to join them. This PR is choosing the latter, joining both options (secondary and primary UDNs) to the same test suite.
The main change between the two is the way both tests retrieve the IPs from the VMI:
For secondary: retrieve the IPs from the VMI.Status
For primary UDN: retrieve the IPs from the pod's network-status annotation (this may change in future iterations).
This PR:
With this change, we now cover ipam-extentions operation on VMI/VMs using primary-UDN.
Which issue(s) this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close the issue(s) when PR gets merged):Fixes #
Special notes for your reviewer:
Release note: