Change:
Context: NodeSwap feature gate was recently . Currently, as per , swap is only supported with cgroup v2 - cgroup v1 is no longer supported. For this reason, we decided to fail kubelet if NodeSwap feature gate is enabled and the node runs with cgroup v1. This would help prevent any surprises for the user by failing as soon as possible. This effort is being implemented in this PR: The problem: Currently, swap jobs are running with cgroup v1. Swap tests were in a way that they first check on which environment they're being run (e.g. which cgroup version? is NodeSwap FG enabled? Which swapBehavior is defined? etc) and then expect the right behavior to take place. With v1, the tests expect the containers to be defined without swap access. While the tests pass, they are much less valuable, since all they check is that swap is disabled for v1 workloads. The tests would be much more valuable if they would run with v2, therefore actually ensure that proper swap limitations are configured. In addition, is dependent on these changes, since as of now the jobs immediately fail with this PR since kubelet fails on an environment with cgroup v1 and swap enabled. What needs to change: [x] CRI-O swap related jobs should be defined to run with cgroup v2 (e.g. ) [x] containerd swap related jobs should be defined to run with cgroup v2 (e.g. ). Future work: In the future, we might consider introducing more jobs to check swap. Ideally, both and would be tested, perhaps by periodic jobs.
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/sig node
/sig testing
/reopen
Reopened this issue. <detailsIn response to : /reopen Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details

Discussion:
// (e.g. the addition of a new field will cause the hash code to change) // Note that we assume input podTemplateSpecs contain non-empty labels func equalIgnoreHash(template1, template2 api.PodTemplateSpec) (bool, error) { <ins> // First, compare template.Labels (ignoring hash) labels1, labels2 := template1.Labels, template2.Labels </ins> // The podTemplateSpec must have a non-empty label so that label selectors can find them. // This is checked by validation (of resources contain a podTemplateSpec). <del> if len(template1.Labels) == 0 || len(template2.Labels) == 0 { </del> <ins> if len(labels1) == 0 || len(labels2) == 0 { </ins> return false, fmt.Errorf("Unexpected empty labels found in given template") } <del> hash1 := template1.Labels[extensions.DefaultDeploymentUniqueLabelKey] hash2 := template2.Labels[extensions.DefaultDeploymentUniqueLabelKey] // compare equality ignoring pod-template-hash template1.Labels[extensions.DefaultDeploymentUniqueLabelKey] = hash2 </del> <ins> if len(labels1) > len(labels2) { labels1, labels2 = labels2, labels1 } // We make sure len(labels2) >= len(labels1) for k, v := range labels2 { if labels1[k] != v && k != extensions.DefaultDeploymentUniqueLabelKey { return false, nil } } // Then, compare the templates without comparing their labels template1.Labels, template2.Labels = nil, nil </ins> result := api.Semantic.DeepEqual(template1, template2) <del> template1.Labels[extensions.DefaultDeploymentUniqueLabelKey] = hash1 </del> return result, nil }

} for _, test := range tests { <del> equal, err := equalIgnoreHash(test.former, test.latter) if err != nil { t.Errorf("In test case %q, returned unexpected error %v", test.test, err) } if equal != test.expected { t.Errorf("In test case %q, expected %v", test.test, test.expected) } equal, err = equalIgnoreHash(test.latter, test.former) if err != nil { t.Errorf("In test case %q (reverse order), returned unexpected error %v", test.test, err) } if equal != test.expected { t.Errorf("In test case %q (reverse order), expected %v", test.test, test.expected) </del> <ins> runTest := func(t1, t2 api.PodTemplateSpec, reversed bool) { // Set up t1Copy, err := api.Scheme.DeepCopy(t1) if err != nil { t.Errorf("Failed setting up the test: %v", err) } t2Copy, err := api.Scheme.DeepCopy(t2) if err != nil { t.Errorf("Failed setting up the test: %v", err) } reverseString := "" if reversed { reverseString = " (reverse order)" } // Run equal, err := equalIgnoreHash(t1, t2) // Check if err != nil { t.Errorf("In test case %q%s, expected no error, returned %v", test.test, reverseString, err) } if equal != test.expected { t.Errorf("In test case %q%s, expected %v", test.test, reverseString, test.expected) } if t1.Labels == nil || t2.Labels == nil { t.Errorf("In test case %q%s, unexpected labels becomes nil", test.test, reverseString) } if !reflect.DeepEqual(t1, t1Copy) || !reflect.DeepEqual(t2, t2Copy) { t.Errorf("In test case %q%s, unexpected input template modified", test.test, reverseString) } </ins> } <ins> runTest(test.former, test.latter, false) // Test the same case in reverse order runTest(test.latter, test.former, true) </ins> } }