Change:
The test : is failing because it assumes the memory is the same across all nodes. A change in the configuration changed that assumption and the test started to fail. the test to assign the correct amount of memory to each of the nodes to fill them up. create a Windows cluster with 3 nodes. Two have 6gb of allocatable memory, 1 has 14gb of allocatable memory. Run the test above and it will fail because it tries to create 3 pods with 9 gb of memory. The first pod will land on the node with 14gb of memory but the other two pods won't be able to find a node with enough memory (9gb pod 6 gb nodes). fixes this in the configuration /sig windows <details</details<details</details<details</details<details</details<details</details<details</details
/triage accepted /priority important-long-term
The label(s) cannot be applied, because the repository doesn't have them. <detailsIn response to : /triage accepted /priority important-long-term 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
Please inform that Am I reasonable here or not. We need to update the in all the cases inside the (, and ) similar to what was done in PR, but now we need to update it in all cases. If you could please confirm that I am reasonable here then I can begin to make these changes in a PR.
sorry I could have been clearer in the issue. The test it's self needs to be updated to handle nodes that do not have consistent memory. The logic in the test is wrong if the nodes don't all have the same memory values: This results in pods that won't fit on some of the nodes and leaves the pods pending. The test should handle this situation by making sure pods filled up memory but can be scheduled across the nodes. Let me know of need more clarification.
So, here we have to fix the logic because the logic is wrong for the case when the nodes don't have the same memory values. Is the node memory value is equal to which gets assigned to variable in ?My understanding of tackling the issue : So, we need to change because it is the total memory and when it is fixed then the pods present will get appropriate memory limit by . So, if updating the logic for the value of is our focus, such that the it (memory limit) is changed according to the nodes, how can we achieve that ? Am I thinking reasonable here? If my understanding is correct till now then how we will be changing the code for assigning the memory value for a node such that each of the nodes get relevant amount of memory based on there need to work properly.
Yes, I think think the simplest thing to so would be get a list of windows nodes iterate though each one, looking up the allocatable memory for the node, creating a pod to fill that memory and assign it to that node for scheduling via , ensuring the scheduling was successful. Then once the nodes are all full deploy the pod that should go into pending (code should stay the same). pseudo code:
Do we have some examples in the repo where we do something similar for other nodes ? First we need to make function or is it already present ? Confirming : Also Do we need to run the whole code(After Modifying) inside in loop for every windows node and if even one return fails, the test fails.
I need some guidance. Could you please take a look on previous comment.
example of getting the nodes and memory total: no, basically need to replace some of the code in that function with the sudo code in
Why are we not deploying both the pods of in one loop only (if we want memory of pending pods memory same as nodes memory). Also after we deploys both the pods, do we will be running another loop similar to for checking the failure. I am not much sure about my changes, can I make a PR so that I can discuss about my code and make appropriate changes further ?
Sounds good
Does functions , and already exists or we have to make them because I am not able to find, have you used these names as short forms for other functions which do same as their names ?

Discussion:
"context" "encoding/json" "fmt" <del> "strconv" </del> "time" kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"

// Deploys `allocatablePods + 1` pods, each with a memory limit of `1/allocatablePods` of the total allocatable // memory, then confirms that the last pod failed because of failedScheduling func overrideAllocatableMemoryTest(f *framework.Framework, allocatablePods int) { <del> const ( podType = "memory_limit_test_pod" ) totalAllocatable := getTotalAllocatableMemory(f) memValue := totalAllocatable.Value() memPerPod := memValue / int64(allocatablePods) ginkgo.By(fmt.Sprintf("Deploying %d pods with mem limit %v, then one additional pod", allocatablePods, memPerPod)) // these should all work pods := newMemLimitTestPods(allocatablePods, imageutils.GetPauseImageName(), podType, strconv.FormatInt(memPerPod, 10)) f.PodClient().CreateBatch(pods) failurePods := newMemLimitTestPods(1, imageutils.GetPauseImageName(), podType, strconv.FormatInt(memPerPod, 10)) f.PodClient().Create(failurePods[0]) gomega.Eventually(func() bool { eventList, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(context.TODO(), metav1.ListOptions{}) framework.ExpectNoError(err) for _, e := range eventList.Items { // Look for an event that shows FailedScheduling if e.Type == "Warning" && e.Reason == "FailedScheduling" && e.InvolvedObject.Name == failurePods[0].ObjectMeta.Name { framework.Logf("Found %+v event with message %+v", e.Reason, e.Message) return true } } return false }, 3*time.Minute, 10*time.Second).Should(gomega.Equal(true)) } // newMemLimitTestPods creates a list of pods (specification) for test. func newMemLimitTestPods(numPods int, imageName, podType string, memoryLimit string) []*v1.Pod { var pods []*v1.Pod memLimitQuantity, err := resource.ParseQuantity(memoryLimit) </del> <ins> selector := labels.Set{"kubernetes.io/os": "windows"}.AsSelector() nodeList, err := f.ClientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{ LabelSelector: selector.String(), }) </ins> framework.ExpectNoError(err) <del> for i := 0; i < numPods; i++ { podName := "test-" + string(uuid.NewUUID()) pod := v1.Pod{ </del> <ins> for _, node := range nodeList.Items { status := node.Status podName := "mem-test-" + string(uuid.NewUUID()) pod := &v1.Pod{ </ins> ObjectMeta: metav1.ObjectMeta{ Name: podName, <del> Labels: map[string]string{ "type": podType, "name": podName, }, </del> }, Spec: v1.PodSpec{ <del> // Restart policy is always (default). </del> Containers: []v1.Container{ { <del> Image: imageName, </del> Name:  podName, <ins> Image: imageutils.GetPauseImageName(), </ins> Resources: v1.ResourceRequirements{ Limits: v1.ResourceList{ <del> v1.ResourceMemory: memLimitQuantity, </del> <ins> v1.ResourceMemory: status.Allocatable[v1.ResourceMemory], </ins> }, }, },

NodeSelector: map[string]string{ "kubernetes.io/os": "windows", }, <ins> NodeName: node.Name, </ins> }, } <del> pods = append(pods, &pod) </del> <ins> _, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(context.TODO(), pod, metav1.CreateOptions{}) framework.ExpectNoError(err) } podName := "mem-failure-pod" failurePod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: podName, }, Spec: v1.PodSpec{ Containers: []v1.Container{ { Name:  podName, Image: imageutils.GetPauseImageName(), Resources: v1.ResourceRequirements{ Limits: v1.ResourceList{ v1.ResourceMemory: *resource.NewQuantity(1024*1024*1024, resource.BinarySI), }, }, }, }, NodeSelector: map[string]string{ "kubernetes.io/os": "windows", }, }, </ins> } <ins> failurePod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(context.TODO(), failurePod, metav1.CreateOptions{}) framework.ExpectNoError(err) gomega.Eventually(func() bool { eventList, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(context.TODO(), metav1.ListOptions{}) framework.ExpectNoError(err) for _, e := range eventList.Items { // Look for an event that shows FailedScheduling if e.Type == "Warning" && e.Reason == "FailedScheduling" && e.InvolvedObject.Name == failurePod.ObjectMeta.Name { framework.Logf("Found %+v event with message %+v", e.Reason, e.Message) return true } } return false }, 3*time.Minute, 10*time.Second).Should(gomega.Equal(true)) </ins> <del> return pods </del> } // getNodeMemory populates a nodeMemory struct with information from the first

return nodeMem } <del> // getTotalAllocatableMemory gets the sum of all agent node's allocatable memory func getTotalAllocatableMemory(f *framework.Framework) *resource.Quantity { selector := labels.Set{"kubernetes.io/os": "windows"}.AsSelector() nodeList, err := f.ClientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{ LabelSelector: selector.String(), }) framework.ExpectNoError(err) ginkgo.By("Summing allocatable memory across all agent nodes") totalAllocatable := resource.NewQuantity(0, resource.BinarySI) for _, node := range nodeList.Items { status := node.Status totalAllocatable.Add(status.Allocatable[v1.ResourceMemory]) } return totalAllocatable } </del> // modified from https://github.com/kubernetes/kubernetes/blob/master/test/e2e/framework/kubelet/config.go#L110 // the proxy version was causing and non proxy used a value that isn't set by e2e func decodeConfigz(contentsBytes []byte) (*kubeletconfig.KubeletConfiguration, error) {