Change:
// Tests can be run in parallel, so we need a different nodePort for // each test. <del> // We add 1 to FederatedSvcNodePortLast because IntnRange's range end // is not inclusive. nodePort := int32(rand.IntnRange(FederatedSvcNodePortFirst, FederatedSvcNodePortLast+1)) </del> <ins> // we add in a array all the "available" ports availablePorts := make([]int32, FederatedSvcNodePortLast-FederatedSvcNodePortFirst) for i := range availablePorts { availablePorts[i] = int32(FederatedSvcNodePortFirst + i) } var err error var service *v1.Service retry := 10 // the function should retry the service creation on different port only 10 time. // until the availablePort list is not empty, lets try to create the service for len(availablePorts) > 0 && retry > 0 { // select the Id of an available port i := rand.Intn(len(availablePorts)) By(fmt.Sprintf("try creating federated service %q in namespace %q with nodePort %d", name, namespace, availablePorts[i])) service, err = createServiceWithNodePort(clientset, namespace, name, availablePorts[i]) if err == nil { // check if service have been created properly in all clusters. // if the service is not present in one of the clusters, we should cleanup all services if err = checkServicesCreation(namespace, name, clusters); err == nil { // everything was created properly so returns the federated service. return service, nil } } // in case of error, cleanup everything if service != nil { if err = deleteService(clientset, namespace, name, nil); err != nil { framework.ExpectNoError(err, "Deleting service %q after a partial createService() error", service.Name) return nil, err } cleanupServiceShardsAndProviderResources(namespace, service, clusters) } // creation failed, lets try with another port // first remove from the availablePorts the port with which the creation failed availablePorts = append(availablePorts[:i], availablePorts[i+1:]...) retry-- } return nil, err } func createServiceWithNodePort(clientset *fedclientset.Clientset, namespace, name string, nodePort int32) (*v1.Service, error) { </ins> service := &v1.Service{ ObjectMeta: metav1.ObjectMeta{ Name:      name,

Discussion:
In order to support running tests in parallel, we randomized NodePort selection. There appears to be some evidence that this is not sufficient and is causing e2e test flakes: https://k8s-
Hi, As a need contributor, I'm interesting of solving this issue. I already check the current code, and propose to retry the service creation until success or all possible ports (between FederatedSvcNodePortFirst and FederatedSvcNodePortLast) have been tried. If this approach is fine for you, I can submit a PR soon.
How do you plan to check if the NodePorts are available? In our presubmit test environment, tests run across many instances of federation control planes in parallel, but share the same underlying clusters. So this approach might be viable depending on how and where you plan to check for these used NodePorts.
my approach for getting an available port is a "Dummy" approach: create a list of possible available port, get one of them randomly, then try to create the Service. If Service creation failed. try to use another possible available port, until service creation success or all possible available ports have been tested.
Sounds reasonable to me. Go for it. A couple of caveats: need to create a real list, you could just use the range boundaries. careful about service creation failure. You need to check if the service shard creation failed in the underlying clusters and rollback all those shards before retrying.
thanks for the caveats, I will do soon a PR.
Hi, what is the state of this issue? Is working in this issues with the others issues related to e2e tests?
has a PR to fix this issue -