Skip to content

Commit 3cc5960

Browse files
committed
Upstream e2e tests for windows
1 parent 07631c4 commit 3cc5960

File tree

14 files changed

+233
-24
lines changed

14 files changed

+233
-24
lines changed

Makefile

+8
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ EXP_DIR := exp
4848
GO_INSTALL = ./scripts/go_install.sh
4949
E2E_DATA_DIR ?= $(ROOT_DIR)/test/e2e/data
5050
KUBETEST_CONF_PATH ?= $(abspath $(E2E_DATA_DIR)/kubetest/conformance.yaml)
51+
KUBETEST_WINDOWS_CONF_PATH ?= $(abspath $(E2E_DATA_DIR)/kubetest/upstream-windows.yaml)
52+
KUBETEST_REPO_LIST_PATH ?= $(abspath $(E2E_DATA_DIR)/kubetest/repo-list.yaml)
5153

5254
# set --output-base used for conversion-gen which needs to be different for in GOPATH and outside GOPATH dev
5355
ifneq ($(abspath $(ROOT_DIR)),$(GOPATH)/src/sigs.k8s.io/cluster-api-provider-azure)
@@ -127,6 +129,7 @@ E2E_CONF_FILE ?= $(ROOT_DIR)/test/e2e/config/azure-dev.yaml
127129
E2E_CONF_FILE_ENVSUBST := $(ROOT_DIR)/test/e2e/config/azure-dev-envsubst.yaml
128130
SKIP_CLEANUP ?= false
129131
SKIP_CREATE_MGMT_CLUSTER ?= false
132+
WIN_REPO_LIST ?= https://raw.githubusercontent.com/kubernetes-sigs/windows-testing/master/images/image-repo-list
130133

131134
# Build time versioning details.
132135
LDFLAGS := $(shell hack/version.sh)
@@ -196,6 +199,11 @@ test-conformance: ## Run conformance test on workload cluster.
196199
test-conformance-fast: ## Run conformance test on workload cluster using a subset of the conformance suite in parallel.
197200
$(MAKE) test-conformance CONFORMANCE_E2E_ARGS="-kubetest.config-file=$(KUBETEST_FAST_CONF_PATH) -kubetest.ginkgo-nodes=5 $(E2E_ARGS)"
198201

202+
.PHONY: test-windows-upstream
203+
test-windows-upstream: ## Run windows upstream tests on workload cluster.
204+
curl --retry $(CURL_RETRIES) $(WIN_REPO_LIST) -o $(KUBETEST_REPO_LIST_PATH)
205+
$(MAKE) test-conformance CONFORMANCE_E2E_ARGS="-kubetest.config-file=$(KUBETEST_WINDOWS_CONF_PATH) -kubetest.repo-list-file=$(KUBETEST_REPO_LIST_PATH) $(E2E_ARGS)"
206+
199207
$(KUBE_APISERVER) $(ETCD): ## install test asset kubectl, kube-apiserver, etcd
200208
source ./scripts/fetch_ext_bins.sh && fetch_tools
201209

docs/book/src/developers/development.md

+19-11
Original file line numberDiff line numberDiff line change
@@ -416,23 +416,31 @@ To run the Kubernetes Conformance test suite locally, you can run
416416
./scripts/ci-conformance.sh
417417
```
418418

419-
With the following environment variables defined, you can build a CAPZ cluster from the HEAD of Kubernetes main branch or release branch, and run the Conformance test suite against it:
419+
Optional settings are:
420420

421-
| Environment Variable | Value |
422-
|----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
423-
| `E2E_ARGS` | `-kubetest.use-ci-artifacts` |
421+
| Environment Variable | Default Value | Description |
422+
|----------------------|-----------------|-------------|
423+
| `WINDOWS` | `false` | Run conformance against Windows nodes |
424+
| `CONFORMANCE_NODES` | `1` |Number of parallel ginkgo nodes to run |
425+
426+
With the following environment variables defined, you can build a CAPZ cluster from the HEAD of Kubernetes main branch or release branch, and run the Conformance test suite against it. This is not enabled for Windows currently.
427+
428+
| Environment Variable | Value |
429+
|----------------------|--------|
430+
| `E2E_ARGS` | `-kubetest.use-ci-artifacts` |
424431
| `KUBERNETES_VERSION` | `latest` - extract Kubernetes version from https://dl.k8s.io/ci/latest.txt (main's HEAD)<br>`latest-1.21` - extract Kubernetes version from https://dl.k8s.io/ci/latest-1.21.txt (release branch's HEAD) |
425432

433+
426434
With the following environment variables defined, CAPZ runs `./scripts/ci-build-kubernetes.sh` as part of `./scripts/ci-conformance.sh`, which allows developers to build Kubernetes from source and run the Kubernetes Conformance test suite against a CAPZ cluster based on the custom build:
427435

428-
| Environment Variable | Value |
429-
|-------------------------|-------------------------------------------------------------------------|
430-
| `AZURE_STORAGE_ACCOUNT` | Your Azure storage account name |
431-
| `AZURE_STORAGE_KEY` | Your Azure storage key |
436+
| Environment Variable | Value |
437+
|-------------------------|------------|
438+
| `AZURE_STORAGE_ACCOUNT` | Your Azure storage account name |
439+
| `AZURE_STORAGE_KEY` | Your Azure storage key |
432440
| `JOB_NAME` | `test` (an enviroment variable used by CI, can be any non-empty string) |
433-
| `LOCAL_ONLY` | `false` |
434-
| `REGISTRY` | Your Registry |
435-
| `TEST_K8S` | `true` |
441+
| `LOCAL_ONLY` | `false` |
442+
| `REGISTRY` | Your Registry |
443+
| `TEST_K8S` | `true` |
436444

437445
#### Running custom test suites on CAPZ clusters
438446

scripts/ci-conformance.sh

+6-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export AZURE_CLIENT_SECRET_B64="$(echo -n "$AZURE_CLIENT_SECRET" | base64 | tr -
7676
export AZURE_LOCATION="${AZURE_LOCATION:-$(get_random_region)}"
7777
export AZURE_CONTROL_PLANE_MACHINE_TYPE="${AZURE_CONTROL_PLANE_MACHINE_TYPE:-"Standard_D2s_v3"}"
7878
export AZURE_NODE_MACHINE_TYPE="${AZURE_NODE_MACHINE_TYPE:-"Standard_D2s_v3"}"
79+
export WINDOWS="${WINDOWS:-false}"
7980

8081
# Generate SSH key.
8182
AZURE_SSH_PUBLIC_KEY_FILE=${AZURE_SSH_PUBLIC_KEY_FILE:-""}
@@ -93,4 +94,8 @@ cleanup() {
9394

9495
trap cleanup EXIT
9596

96-
make test-conformance
97+
if [[ "${WINDOWS}" == "true" ]]; then
98+
make test-windows-upstream
99+
else
100+
make test-conformance
101+
fi

templates/test/ci/cluster-template-prow-machine-pool-windows.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ spec:
290290
New-HnsNetwork -Type Overlay -AddressPrefix "192.168.255.0/30" -Gateway "192.168.255.1" -Name "External" -AdapterName "Ethernet 2" -SubnetPolicies @(@{Type = "VSID"; VSID = 9999; })
291291
path: C:/create-external-network.ps1
292292
permissions: "0744"
293+
- content: |
294+
# /tmp is assumed created and required for upstream e2e tests to pass
295+
New-Item -ItemType Directory -Force -Path C:\tmp\
296+
path: C:/create-temp-folder.ps1
297+
permissions: "0744"
293298
joinConfiguration:
294299
nodeRegistration:
295300
kubeletExtraArgs:
@@ -302,6 +307,7 @@ spec:
302307
- nssm set kubelet start SERVICE_AUTO_START
303308
preKubeadmCommands:
304309
- powershell c:/create-external-network.ps1
310+
- powershell C:/create-temp-folder.ps1
305311
users:
306312
- groups: Administrators
307313
name: capi

templates/test/ci/cluster-template-prow-windows.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,11 @@ spec:
298298
New-HnsNetwork -Type Overlay -AddressPrefix "192.168.255.0/30" -Gateway "192.168.255.1" -Name "External" -AdapterName "Ethernet 2" -SubnetPolicies @(@{Type = "VSID"; VSID = 9999; })
299299
path: C:/create-external-network.ps1
300300
permissions: "0744"
301+
- content: |
302+
# /tmp is assumed created and required for upstream e2e tests to pass
303+
New-Item -ItemType Directory -Force -Path C:\tmp\
304+
path: C:/create-temp-folder.ps1
305+
permissions: "0744"
301306
joinConfiguration:
302307
nodeRegistration:
303308
kubeletExtraArgs:
@@ -310,6 +315,7 @@ spec:
310315
- nssm set kubelet start SERVICE_AUTO_START
311316
preKubeadmCommands:
312317
- powershell c:/create-external-network.ps1
318+
- powershell C:/create-temp-folder.ps1
313319
users:
314320
- groups: Administrators
315321
name: capi

templates/test/ci/prow-machine-pool-windows/kustomization.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ patchesStrategicMerge:
88
- ../patches/tags.yaml
99
- ../patches/cluster-cni-windows.yaml
1010
- ../patches/controller-manager.yaml
11+
patchesJson6902:
12+
- target:
13+
group: bootstrap.cluster.x-k8s.io
14+
version: v1alpha4
15+
kind: KubeadmConfig
16+
name: ${CLUSTER_NAME}-mp-win
17+
namespace: default
18+
path: patches/windows-tmp-folder.yaml
1119
configMapGenerator:
1220
- name: cni-${CLUSTER_NAME}-flannel
1321
files:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
- op: add
2+
path: /spec/files/-
3+
value:
4+
content: |
5+
# /tmp is assumed created and required for upstream e2e tests to pass
6+
New-Item -ItemType Directory -Force -Path C:\tmp\
7+
path: C:/create-temp-folder.ps1
8+
permissions: "0744"
9+
- op: add
10+
path: /spec/preKubeadmCommands/-
11+
value:
12+
powershell C:/create-temp-folder.ps1

templates/test/ci/prow-windows/kustomization.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ patchesStrategicMerge:
88
- ../patches/tags.yaml
99
- ../patches/cluster-cni-windows.yaml
1010
- ../patches/controller-manager.yaml
11+
patchesJson6902:
12+
- target:
13+
group: bootstrap.cluster.x-k8s.io
14+
version: v1alpha4
15+
kind: KubeadmConfigTemplate
16+
name: ${CLUSTER_NAME}-md-win
17+
namespace: default
18+
path: patches/windows-tmp-folder.yaml
1119
configMapGenerator:
1220
- name: cni-${CLUSTER_NAME}-flannel
1321
files:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
- op: add
2+
path: /spec/template/spec/files/-
3+
value:
4+
content: |
5+
# /tmp is assumed created and required for upstream e2e tests to pass
6+
New-Item -ItemType Directory -Force -Path C:\tmp\
7+
path: C:/create-temp-folder.ps1
8+
permissions: "0744"
9+
- op: add
10+
path: /spec/template/spec/preKubeadmCommands/-
11+
value:
12+
powershell C:/create-temp-folder.ps1

test/e2e/conformance_test.go

+48-11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ import (
2424
"os"
2525
"path/filepath"
2626
"strconv"
27+
"strings"
28+
29+
"sigs.k8s.io/cluster-api-provider-azure/test/e2e/kubernetes/node"
30+
31+
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2732

2833
. "github.com/onsi/ginkgo"
2934
. "github.com/onsi/gomega"
@@ -75,18 +80,28 @@ var _ = Describe("Conformance Tests", func() {
7580

7681
kubernetesVersion := e2eConfig.GetVariable(capi_e2e.KubernetesVersion)
7782
flavor := clusterctl.DefaultFlavor
83+
if isWindows(kubetestConfigFilePath) {
84+
flavor = "windows"
85+
}
86+
7887
// clusters with CI artifacts or PR artifacts are based on a known CI version
7988
// PR artifacts will replace the CI artifacts during kubeadm init
8089
if useCIArtifacts || usePRArtifacts {
8190
kubernetesVersion, err = resolveCIVersion(kubernetesVersion)
8291
Expect(err).NotTo(HaveOccurred())
8392
Expect(os.Setenv("CI_VERSION", kubernetesVersion)).To(Succeed())
93+
94+
if useCIArtifacts {
95+
flavor = "conformance-ci-artifacts"
96+
} else if usePRArtifacts {
97+
flavor = "conformance-presubmit-artifacts"
98+
}
99+
100+
if isWindows(kubetestConfigFilePath) {
101+
flavor = flavor + "-windows"
102+
}
84103
}
85-
if useCIArtifacts {
86-
flavor = "conformance-ci-artifacts"
87-
} else if usePRArtifacts {
88-
flavor = "conformance-presubmit-artifacts"
89-
}
104+
90105
workerMachineCount, err := strconv.ParseInt(e2eConfig.GetVariable("CONFORMANCE_WORKER_MACHINE_COUNT"), 10, 64)
91106
Expect(err).NotTo(HaveOccurred())
92107
controlPlaneMachineCount, err := strconv.ParseInt(e2eConfig.GetVariable("CONFORMANCE_CONTROL_PLANE_MACHINE_COUNT"), 10, 64)
@@ -118,19 +133,37 @@ var _ = Describe("Conformance Tests", func() {
118133
b.RecordValue("cluster creation", runtime.Seconds())
119134
workloadProxy := bootstrapClusterProxy.GetWorkloadCluster(ctx, namespace.Name, clusterName)
120135

136+
// Windows requires a taint on control nodes nodes since not all conformance tests have ability to run
137+
if isWindows(kubetestConfigFilePath) {
138+
options := v1.ListOptions{
139+
LabelSelector: "kubernetes.io/os=linux",
140+
}
141+
142+
noScheduleTaint := &corev1.Taint{
143+
Key: "node-role.kubernetes.io/master",
144+
Value: "",
145+
Effect: "NoSchedule",
146+
}
147+
148+
err := node.TaintNode(workloadProxy.GetClientSet(), options, noScheduleTaint)
149+
Expect(err).NotTo(HaveOccurred())
150+
}
151+
121152
ginkgoNodes, err := strconv.Atoi(e2eConfig.GetVariable("CONFORMANCE_NODES"))
122153
Expect(err).NotTo(HaveOccurred())
123154

124155
runtime = b.Time("conformance suite", func() {
125-
kubetest.Run(context.Background(),
156+
err := kubetest.Run(context.Background(),
126157
kubetest.RunInput{
127-
ClusterProxy: workloadProxy,
128-
NumberOfNodes: int(workerMachineCount),
129-
ConfigFilePath: kubetestConfigFilePath,
130-
ConformanceImage: e2eConfig.GetVariable("CONFORMANCE_IMAGE"),
131-
GinkgoNodes: ginkgoNodes,
158+
ClusterProxy: workloadProxy,
159+
NumberOfNodes: int(workerMachineCount),
160+
ConfigFilePath: kubetestConfigFilePath,
161+
KubeTestRepoListPath: kubetestRepoListPath,
162+
ConformanceImage: e2eConfig.GetVariable("CONFORMANCE_IMAGE"),
163+
GinkgoNodes: ginkgoNodes,
132164
},
133165
)
166+
Expect(err).NotTo(HaveOccurred())
134167
})
135168
b.RecordValue("conformance suite run time", runtime.Seconds())
136169
}, 1)
@@ -144,3 +177,7 @@ var _ = Describe("Conformance Tests", func() {
144177
})
145178

146179
})
180+
181+
func isWindows(kubetestConfigFilePath string) bool {
182+
return strings.Contains(kubetestConfigFilePath, "windows")
183+
}

test/e2e/data/kubetest/repo-list.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
gcAuthenticatedRegistry: e2eprivate
2+
gcEtcdRegistry: k8sprow.azurecr.io/kubernetes-e2e-test-images
3+
privateRegistry: e2eteam
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
ginkgo.focus: \[Conformance\]|\[NodeConformance\]|\[sig-windows\]|\[sig-apps\].CronJob|\[sig-api-machinery\].ResourceQuota|\[sig-scheduling\].SchedulerPreemption
2+
ginkgo.skip: \[LinuxOnly\]|\[Serial\]|Guestbook.application.should.create.and.stop.a.working.application|device.plugin.for.Windows|Container.Lifecycle.Hook.when.create.a.pod.with.lifecycle.hook.should.execute(.*)http.hook.properly
3+
disable-log-dump: true
4+
ginkgo.progress: true
5+
ginkgo.slowSpecThreshold: 120.0
6+
ginkgo.flakeAttempts: 0
7+
ginkgo.trace: true
8+
ginkgo.v: true
9+
node-os-distro: windows

test/e2e/e2e_suite_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ var (
9292
// kubetestConfigFilePath is the path to the kubetest configuration file
9393
kubetestConfigFilePath string
9494

95+
// kubetestRepoListPath
96+
kubetestRepoListPath string
97+
9598
// useCIArtifacts specifies whether or not to use the latest build from the main branch of the Kubernetes repository
9699
useCIArtifacts bool
97100

@@ -242,7 +245,7 @@ func init() {
242245
flag.BoolVar(&skipCleanup, "e2e.skip-resource-cleanup", false, "if true, the resource cleanup after tests will be skipped")
243246
flag.BoolVar(&useExistingCluster, "e2e.use-existing-cluster", false, "if true, the test uses the current cluster instead of creating a new one (default discovery rules apply)")
244247
flag.StringVar(&kubetestConfigFilePath, "kubetest.config-file", "", "path to the kubetest configuration file")
245-
248+
flag.StringVar(&kubetestRepoListPath, "kubetest.repo-list-file", "", "path to the kubetest repo-list file")
246249
}
247250

248251
func TestE2E(t *testing.T) {

0 commit comments

Comments
 (0)