Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
35f72c5a
Commit
35f72c5a
authored
Aug 10, 2018
by
Antoine Pelisse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dry-run: Create integration test
parent
5f364a0b
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
851 additions
and
0 deletions
+851
-0
BUILD
test/integration/BUILD
+1
-0
BUILD
test/integration/dryrun/BUILD
+57
-0
OWNERS
test/integration/dryrun/OWNERS
+7
-0
dryrun_test.go
test/integration/dryrun/dryrun_test.go
+759
-0
main_test.go
test/integration/dryrun/main_test.go
+27
-0
No files found.
test/integration/BUILD
View file @
35f72c5a
...
...
@@ -43,6 +43,7 @@ filegroup(
"//test/integration/daemonset:all-srcs",
"//test/integration/defaulttolerationseconds:all-srcs",
"//test/integration/deployment:all-srcs",
"//test/integration/dryrun:all-srcs",
"//test/integration/etcd:all-srcs",
"//test/integration/evictions:all-srcs",
"//test/integration/examples:all-srcs",
...
...
test/integration/dryrun/BUILD
0 → 100644
View file @
35f72c5a
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
)
go_test(
name = "go_default_test",
size = "large",
srcs = [
"dryrun_test.go",
"main_test.go",
],
tags = [
"etcd",
"integration",
],
deps = [
"//cmd/kube-apiserver/app:go_default_library",
"//cmd/kube-apiserver/app/options:go_default_library",
"//pkg/master:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/options:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
"//staging/src/k8s.io/client-go/discovery/cached:go_default_library",
"//staging/src/k8s.io/client-go/dynamic:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//staging/src/k8s.io/client-go/restmapper:go_default_library",
"//test/integration/framework:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
test/integration/dryrun/OWNERS
0 → 100644
View file @
35f72c5a
approvers:
- apelisse
- deads2k
reviewers:
- deads2k
- liggitt
- lavalamp
test/integration/dryrun/dryrun_test.go
0 → 100644
View file @
35f72c5a
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
dryrun
import
(
"encoding/json"
"io/ioutil"
"net"
"net/http"
"os"
"strings"
"testing"
"time"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/features"
genericapiserveroptions
"k8s.io/apiserver/pkg/server/options"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting
"k8s.io/apiserver/pkg/util/feature/testing"
cacheddiscovery
"k8s.io/client-go/discovery/cached"
"k8s.io/client-go/dynamic"
clientset
"k8s.io/client-go/kubernetes"
restclient
"k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
"k8s.io/kubernetes/cmd/kube-apiserver/app"
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
"k8s.io/kubernetes/test/integration/framework"
// install all APIs
_
"k8s.io/kubernetes/pkg/master"
// TODO what else is needed
)
// dryrun data for all persisted objects.
var
dryrunData
=
map
[
schema
.
GroupVersionResource
]
struct
{
stub
string
// Valid JSON stub to use during create
}{
// k8s.io/kubernetes/pkg/api/v1
gvr
(
""
,
"v1"
,
"configmaps"
)
:
{
stub
:
`{"data": {"foo": "bar"}, "metadata": {"name": "cm1"}}`
,
},
gvr
(
""
,
"v1"
,
"services"
)
:
{
stub
:
`{"metadata": {"name": "service1"}, "spec": {"externalName": "service1name", "ports": [{"port": 10000, "targetPort": 11000}], "selector": {"test": "data"}}}`
,
},
gvr
(
""
,
"v1"
,
"podtemplates"
)
:
{
stub
:
`{"metadata": {"name": "pt1name"}, "template": {"metadata": {"labels": {"pt": "01"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container9"}]}}}`
,
},
gvr
(
""
,
"v1"
,
"pods"
)
:
{
stub
:
`{"metadata": {"name": "pod1"}, "spec": {"containers": [{"image": "fedora:latest", "name": "container7", "resources": {"limits": {"cpu": "1M"}, "requests": {"cpu": "1M"}}}]}}`
,
},
gvr
(
""
,
"v1"
,
"endpoints"
)
:
{
stub
:
`{"metadata": {"name": "ep1name"}, "subsets": [{"addresses": [{"hostname": "bar-001", "ip": "192.168.3.1"}], "ports": [{"port": 8000}]}]}`
,
},
gvr
(
""
,
"v1"
,
"resourcequotas"
)
:
{
stub
:
`{"metadata": {"name": "rq1name"}, "spec": {"hard": {"cpu": "5M"}}}`
,
},
gvr
(
""
,
"v1"
,
"limitranges"
)
:
{
stub
:
`{"metadata": {"name": "lr1name"}, "spec": {"limits": [{"type": "Pod"}]}}`
,
},
gvr
(
""
,
"v1"
,
"namespaces"
)
:
{
stub
:
`{"metadata": {"name": "namespace2"}, "spec": {"finalizers": ["kubernetes"]}}`
,
},
gvr
(
""
,
"v1"
,
"nodes"
)
:
{
stub
:
`{"metadata": {"name": "node1"}, "spec": {"unschedulable": true}}`
,
},
gvr
(
""
,
"v1"
,
"persistentvolumes"
)
:
{
stub
:
`{"metadata": {"name": "pv1name"}, "spec": {"accessModes": ["ReadWriteOnce"], "capacity": {"storage": "3M"}, "hostPath": {"path": "/tmp/test/"}}}`
,
},
gvr
(
""
,
"v1"
,
"events"
)
:
{
stub
:
`{"involvedObject": {"namespace": "dryrunnamespace"}, "message": "some data here", "metadata": {"name": "event1"}}`
,
},
gvr
(
""
,
"v1"
,
"persistentvolumeclaims"
)
:
{
stub
:
`{"metadata": {"name": "pvc1"}, "spec": {"accessModes": ["ReadWriteOnce"], "resources": {"limits": {"storage": "1M"}, "requests": {"storage": "2M"}}, "selector": {"matchLabels": {"pvc": "stuff"}}}}`
,
},
gvr
(
""
,
"v1"
,
"serviceaccounts"
)
:
{
stub
:
`{"metadata": {"name": "sa1name"}, "secrets": [{"name": "secret00"}]}`
,
},
gvr
(
""
,
"v1"
,
"secrets"
)
:
{
stub
:
`{"data": {"key": "ZGF0YSBmaWxl"}, "metadata": {"name": "secret1"}}`
,
},
gvr
(
""
,
"v1"
,
"replicationcontrollers"
)
:
{
stub
:
`{"metadata": {"name": "rc1"}, "spec": {"selector": {"new": "stuff"}, "template": {"metadata": {"labels": {"new": "stuff"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container8"}]}}}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/apps/v1beta1
gvr
(
"apps"
,
"v1beta1"
,
"statefulsets"
)
:
{
stub
:
`{"metadata": {"name": "ss1"}, "spec": {"selector": {"matchLabels": {"a": "b"}}, "template": {"metadata": {"labels": {"a": "b"}}}}}`
,
},
gvr
(
"apps"
,
"v1beta1"
,
"deployments"
)
:
{
stub
:
`{"metadata": {"name": "deployment2"}, "spec": {"selector": {"matchLabels": {"f": "z"}}, "template": {"metadata": {"labels": {"f": "z"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container6"}]}}}}`
,
},
gvr
(
"apps"
,
"v1beta1"
,
"controllerrevisions"
)
:
{
stub
:
`{"metadata":{"name":"crs1"},"data":{"name":"abc","namespace":"default","creationTimestamp":null,"Spec":{"Replicas":0,"Selector":{"matchLabels":{"foo":"bar"}},"Template":{"creationTimestamp":null,"labels":{"foo":"bar"},"Spec":{"Volumes":null,"InitContainers":null,"Containers":null,"RestartPolicy":"Always","TerminationGracePeriodSeconds":null,"ActiveDeadlineSeconds":null,"DNSPolicy":"ClusterFirst","NodeSelector":null,"ServiceAccountName":"","AutomountServiceAccountToken":null,"NodeName":"","SecurityContext":null,"ImagePullSecrets":null,"Hostname":"","Subdomain":"","Affinity":null,"SchedulerName":"","Tolerations":null,"HostAliases":null}},"VolumeClaimTemplates":null,"ServiceName":""},"Status":{"ObservedGeneration":null,"Replicas":0}},"revision":0}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/apps/v1beta2
gvr
(
"apps"
,
"v1beta2"
,
"statefulsets"
)
:
{
stub
:
`{"metadata": {"name": "ss2"}, "spec": {"selector": {"matchLabels": {"a": "b"}}, "template": {"metadata": {"labels": {"a": "b"}}}}}`
,
},
gvr
(
"apps"
,
"v1beta2"
,
"deployments"
)
:
{
stub
:
`{"metadata": {"name": "deployment3"}, "spec": {"selector": {"matchLabels": {"f": "z"}}, "template": {"metadata": {"labels": {"f": "z"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container6"}]}}}}`
,
},
gvr
(
"apps"
,
"v1beta2"
,
"daemonsets"
)
:
{
stub
:
`{"metadata": {"name": "ds5"}, "spec": {"selector": {"matchLabels": {"a": "b"}}, "template": {"metadata": {"labels": {"a": "b"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container6"}]}}}}`
,
},
gvr
(
"apps"
,
"v1beta2"
,
"replicasets"
)
:
{
stub
:
`{"metadata": {"name": "rs2"}, "spec": {"selector": {"matchLabels": {"g": "h"}}, "template": {"metadata": {"labels": {"g": "h"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container4"}]}}}}`
,
},
gvr
(
"apps"
,
"v1beta2"
,
"controllerrevisions"
)
:
{
stub
:
`{"metadata":{"name":"crs2"},"data":{"name":"abc","namespace":"default","creationTimestamp":null,"Spec":{"Replicas":0,"Selector":{"matchLabels":{"foo":"bar"}},"Template":{"creationTimestamp":null,"labels":{"foo":"bar"},"Spec":{"Volumes":null,"InitContainers":null,"Containers":null,"RestartPolicy":"Always","TerminationGracePeriodSeconds":null,"ActiveDeadlineSeconds":null,"DNSPolicy":"ClusterFirst","NodeSelector":null,"ServiceAccountName":"","AutomountServiceAccountToken":null,"NodeName":"","SecurityContext":null,"ImagePullSecrets":null,"Hostname":"","Subdomain":"","Affinity":null,"SchedulerName":"","Tolerations":null,"HostAliases":null}},"VolumeClaimTemplates":null,"ServiceName":""},"Status":{"ObservedGeneration":null,"Replicas":0}},"revision":0}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/apps/v1
gvr
(
"apps"
,
"v1"
,
"daemonsets"
)
:
{
stub
:
`{"metadata": {"name": "ds6"}, "spec": {"selector": {"matchLabels": {"a": "b"}}, "template": {"metadata": {"labels": {"a": "b"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container6"}]}}}}`
,
},
gvr
(
"apps"
,
"v1"
,
"deployments"
)
:
{
stub
:
`{"metadata": {"name": "deployment4"}, "spec": {"selector": {"matchLabels": {"f": "z"}}, "template": {"metadata": {"labels": {"f": "z"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container6"}]}}}}`
,
},
gvr
(
"apps"
,
"v1"
,
"statefulsets"
)
:
{
stub
:
`{"metadata": {"name": "ss3"}, "spec": {"selector": {"matchLabels": {"a": "b"}}, "template": {"metadata": {"labels": {"a": "b"}}}}}`
,
},
gvr
(
"apps"
,
"v1"
,
"replicasets"
)
:
{
stub
:
`{"metadata": {"name": "rs3"}, "spec": {"selector": {"matchLabels": {"g": "h"}}, "template": {"metadata": {"labels": {"g": "h"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container4"}]}}}}`
,
},
gvr
(
"apps"
,
"v1"
,
"controllerrevisions"
)
:
{
stub
:
`{"metadata":{"name":"crs3"},"data":{"name":"abc","namespace":"default","creationTimestamp":null,"Spec":{"Replicas":0,"Selector":{"matchLabels":{"foo":"bar"}},"Template":{"creationTimestamp":null,"labels":{"foo":"bar"},"Spec":{"Volumes":null,"InitContainers":null,"Containers":null,"RestartPolicy":"Always","TerminationGracePeriodSeconds":null,"ActiveDeadlineSeconds":null,"DNSPolicy":"ClusterFirst","NodeSelector":null,"ServiceAccountName":"","AutomountServiceAccountToken":null,"NodeName":"","SecurityContext":null,"ImagePullSecrets":null,"Hostname":"","Subdomain":"","Affinity":null,"SchedulerName":"","Tolerations":null,"HostAliases":null}},"VolumeClaimTemplates":null,"ServiceName":""},"Status":{"ObservedGeneration":null,"Replicas":0}},"revision":0}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/autoscaling/v1
gvr
(
"autoscaling"
,
"v1"
,
"horizontalpodautoscalers"
)
:
{
stub
:
`{"metadata": {"name": "hpa2"}, "spec": {"maxReplicas": 3, "scaleTargetRef": {"kind": "something", "name": "cross"}}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/autoscaling/v2beta1
gvr
(
"autoscaling"
,
"v2beta1"
,
"horizontalpodautoscalers"
)
:
{
stub
:
`{"metadata": {"name": "hpa1"}, "spec": {"maxReplicas": 3, "scaleTargetRef": {"kind": "something", "name": "cross"}}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/batch/v1
gvr
(
"batch"
,
"v1"
,
"jobs"
)
:
{
stub
:
`{"metadata": {"name": "job1"}, "spec": {"manualSelector": true, "selector": {"matchLabels": {"controller-uid": "uid1"}}, "template": {"metadata": {"labels": {"controller-uid": "uid1"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container1"}], "dnsPolicy": "ClusterFirst", "restartPolicy": "Never"}}}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/batch/v1beta1
gvr
(
"batch"
,
"v1beta1"
,
"cronjobs"
)
:
{
stub
:
`{"metadata": {"name": "cjv1beta1"}, "spec": {"jobTemplate": {"spec": {"template": {"metadata": {"labels": {"controller-uid": "uid0"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container0"}], "dnsPolicy": "ClusterFirst", "restartPolicy": "Never"}}}}, "schedule": "* * * * *"}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/batch/v2alpha1
gvr
(
"batch"
,
"v2alpha1"
,
"cronjobs"
)
:
{
stub
:
`{"metadata": {"name": "cjv2alpha1"}, "spec": {"jobTemplate": {"spec": {"template": {"metadata": {"labels": {"controller-uid": "uid0"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container0"}], "dnsPolicy": "ClusterFirst", "restartPolicy": "Never"}}}}, "schedule": "* * * * *"}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/certificates/v1beta1
gvr
(
"certificates.k8s.io"
,
"v1beta1"
,
"certificatesigningrequests"
)
:
{
stub
:
`{"metadata": {"name": "csr1"}, "spec": {"request": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQnlqQ0NBVE1DQVFBd2dZa3hDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJRXdwRFlXeHBabTl5Ym1saApNUll3RkFZRFZRUUhFdzFOYjNWdWRHRnBiaUJXYVdWM01STXdFUVlEVlFRS0V3cEhiMjluYkdVZ1NXNWpNUjh3CkhRWURWUVFMRXhaSmJtWnZjbTFoZEdsdmJpQlVaV05vYm05c2IyZDVNUmN3RlFZRFZRUURFdzUzZDNjdVoyOXYKWjJ4bExtTnZiVENCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBcFp0WUpDSEo0VnBWWEhmVgpJbHN0UVRsTzRxQzAzaGpYK1prUHl2ZFlkMVE0K3FiQWVUd1htQ1VLWUhUaFZSZDVhWFNxbFB6eUlCd2llTVpyCldGbFJRZGRaMUl6WEFsVlJEV3dBbzYwS2VjcWVBWG5uVUsrNWZYb1RJL1VnV3NocmU4dEoreC9UTUhhUUtSL0oKY0lXUGhxYVFoc0p1elpidkFkR0E4MEJMeGRNQ0F3RUFBYUFBTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUlobAo0UHZGcStlN2lwQVJnSTVaTStHWng2bXBDejQ0RFRvMEprd2ZSRGYrQnRyc2FDMHE2OGVUZjJYaFlPc3E0ZmtIClEwdUEwYVZvZzNmNWlKeENhM0hwNWd4YkpRNnpWNmtKMFRFc3VhYU9oRWtvOXNkcENvUE9uUkJtMmkvWFJEMkQKNmlOaDhmOHowU2hHc0ZxakRnRkh5RjNvK2xVeWorVUM2SDFRVzdibgotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0="}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/coordination/v1beta1
gvr
(
"coordination.k8s.io"
,
"v1beta1"
,
"leases"
)
:
{
stub
:
`{"metadata": {"name": "lease1"}, "spec": {"holderIdentity": "holder", "leaseDurationSeconds": 5}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/events/v1beta1
gvr
(
"events.k8s.io"
,
"v1beta1"
,
"events"
)
:
{
stub
:
`{"metadata": {"name": "event2"}, "regarding": {"namespace": "dryrunnamespace"}, "note": "some data here", "eventTime": "2017-08-09T15:04:05.000000Z", "reportingInstance": "node-xyz", "reportingController": "k8s.io/my-controller", "action": "DidNothing", "reason": "Laziness"}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/extensions/v1beta1
gvr
(
"extensions"
,
"v1beta1"
,
"daemonsets"
)
:
{
stub
:
`{"metadata": {"name": "ds1"}, "spec": {"selector": {"matchLabels": {"u": "t"}}, "template": {"metadata": {"labels": {"u": "t"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container5"}]}}}}`
,
},
gvr
(
"extensions"
,
"v1beta1"
,
"podsecuritypolicies"
)
:
{
stub
:
`{"metadata": {"name": "psp1"}, "spec": {"fsGroup": {"rule": "RunAsAny"}, "privileged": true, "runAsUser": {"rule": "RunAsAny"}, "seLinux": {"rule": "MustRunAs"}, "supplementalGroups": {"rule": "RunAsAny"}}}`
,
},
gvr
(
"extensions"
,
"v1beta1"
,
"ingresses"
)
:
{
stub
:
`{"metadata": {"name": "ingress1"}, "spec": {"backend": {"serviceName": "service", "servicePort": 5000}}}`
,
},
gvr
(
"extensions"
,
"v1beta1"
,
"networkpolicies"
)
:
{
stub
:
`{"metadata": {"name": "np1"}, "spec": {"podSelector": {"matchLabels": {"e": "f"}}}}`
,
},
gvr
(
"extensions"
,
"v1beta1"
,
"deployments"
)
:
{
stub
:
`{"metadata": {"name": "deployment1"}, "spec": {"selector": {"matchLabels": {"f": "z"}}, "template": {"metadata": {"labels": {"f": "z"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container6"}]}}}}`
,
},
gvr
(
"extensions"
,
"v1beta1"
,
"replicasets"
)
:
{
stub
:
`{"metadata": {"name": "rs1"}, "spec": {"selector": {"matchLabels": {"g": "h"}}, "template": {"metadata": {"labels": {"g": "h"}}, "spec": {"containers": [{"image": "fedora:latest", "name": "container4"}]}}}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/networking/v1
gvr
(
"networking.k8s.io"
,
"v1"
,
"networkpolicies"
)
:
{
stub
:
`{"metadata": {"name": "np2"}, "spec": {"podSelector": {"matchLabels": {"e": "f"}}}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/policy/v1beta1
gvr
(
"policy"
,
"v1beta1"
,
"poddisruptionbudgets"
)
:
{
stub
:
`{"metadata": {"name": "pdb1"}, "spec": {"selector": {"matchLabels": {"anokkey": "anokvalue"}}}}`
,
},
gvr
(
"policy"
,
"v1beta1"
,
"podsecuritypolicies"
)
:
{
stub
:
`{"metadata": {"name": "psp2"}, "spec": {"fsGroup": {"rule": "RunAsAny"}, "privileged": true, "runAsUser": {"rule": "RunAsAny"}, "seLinux": {"rule": "MustRunAs"}, "supplementalGroups": {"rule": "RunAsAny"}}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/storage/v1alpha1
gvr
(
"storage.k8s.io"
,
"v1alpha1"
,
"volumeattachments"
)
:
{
stub
:
`{"metadata": {"name": "va1"}, "spec": {"attacher": "gce", "nodeName": "localhost", "source": {"persistentVolumeName": "pv1"}}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/storage/v1beta1
gvr
(
"storage.k8s.io"
,
"v1beta1"
,
"volumeattachments"
)
:
{
stub
:
`{"metadata": {"name": "va2"}, "spec": {"attacher": "gce", "nodeName": "localhost", "source": {"persistentVolumeName": "pv2"}}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/storage/v1beta1
gvr
(
"storage.k8s.io"
,
"v1beta1"
,
"storageclasses"
)
:
{
stub
:
`{"metadata": {"name": "sc1"}, "provisioner": "aws"}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/storage/v1
gvr
(
"storage.k8s.io"
,
"v1"
,
"storageclasses"
)
:
{
stub
:
`{"metadata": {"name": "sc2"}, "provisioner": "aws"}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/settings/v1alpha1
gvr
(
"settings.k8s.io"
,
"v1alpha1"
,
"podpresets"
)
:
{
stub
:
`{"metadata": {"name": "podpre1"}, "spec": {"env": [{"name": "FOO"}]}}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/rbac/v1alpha1
gvr
(
"rbac.authorization.k8s.io"
,
"v1alpha1"
,
"roles"
)
:
{
stub
:
`{"metadata": {"name": "role1"}, "rules": [{"apiGroups": ["v1"], "resources": ["events"], "verbs": ["watch"]}]}`
,
},
gvr
(
"rbac.authorization.k8s.io"
,
"v1alpha1"
,
"clusterroles"
)
:
{
stub
:
`{"metadata": {"name": "drcrole1"}, "rules": [{"nonResourceURLs": ["/version"], "verbs": ["get"]}]}`
,
},
gvr
(
"rbac.authorization.k8s.io"
,
"v1alpha1"
,
"rolebindings"
)
:
{
stub
:
`{"metadata": {"name": "drroleb1"}, "roleRef": {"apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [{"apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]}`
,
},
gvr
(
"rbac.authorization.k8s.io"
,
"v1alpha1"
,
"clusterrolebindings"
)
:
{
stub
:
`{"metadata": {"name": "drcroleb1"}, "roleRef": {"apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [{"apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/rbac/v1beta1
gvr
(
"rbac.authorization.k8s.io"
,
"v1beta1"
,
"roles"
)
:
{
stub
:
`{"metadata": {"name": "drrole2"}, "rules": [{"apiGroups": ["v1"], "resources": ["events"], "verbs": ["watch"]}]}`
,
},
gvr
(
"rbac.authorization.k8s.io"
,
"v1beta1"
,
"clusterroles"
)
:
{
stub
:
`{"metadata": {"name": "drcrole2"}, "rules": [{"nonResourceURLs": ["/version"], "verbs": ["get"]}]}`
,
},
gvr
(
"rbac.authorization.k8s.io"
,
"v1beta1"
,
"rolebindings"
)
:
{
stub
:
`{"metadata": {"name": "drroleb2"}, "roleRef": {"apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [{"apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]}`
,
},
gvr
(
"rbac.authorization.k8s.io"
,
"v1beta1"
,
"clusterrolebindings"
)
:
{
stub
:
`{"metadata": {"name": "drcroleb2"}, "roleRef": {"apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [{"apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/rbac/v1
gvr
(
"rbac.authorization.k8s.io"
,
"v1"
,
"roles"
)
:
{
stub
:
`{"metadata": {"name": "drrole3"}, "rules": [{"apiGroups": ["v1"], "resources": ["events"], "verbs": ["watch"]}]}`
,
},
gvr
(
"rbac.authorization.k8s.io"
,
"v1"
,
"clusterroles"
)
:
{
stub
:
`{"metadata": {"name": "drcrole3"}, "rules": [{"nonResourceURLs": ["/version"], "verbs": ["get"]}]}`
,
},
gvr
(
"rbac.authorization.k8s.io"
,
"v1"
,
"rolebindings"
)
:
{
stub
:
`{"metadata": {"name": "drroleb3"}, "roleRef": {"apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [{"apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]}`
,
},
gvr
(
"rbac.authorization.k8s.io"
,
"v1"
,
"clusterrolebindings"
)
:
{
stub
:
`{"metadata": {"name": "drcroleb3"}, "roleRef": {"apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [{"apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/admissionregistration/v1alpha1
gvr
(
"admissionregistration.k8s.io"
,
"v1alpha1"
,
"initializerconfigurations"
)
:
{
stub
:
`{"metadata":{"name":"ic1"},"initializers":[{"name":"initializer.k8s.io","rules":[{"apiGroups":["group"],"apiVersions":["version"],"resources":["resource"]}],"failurePolicy":"Ignore"}]}`
,
},
// k8s.io/kubernetes/pkg/apis/admissionregistration/v1beta1
gvr
(
"admissionregistration.k8s.io"
,
"v1beta1"
,
"validatingwebhookconfigurations"
)
:
{
stub
:
`{"metadata":{"name":"hook1","creationTimestamp":null},"webhooks":[{"name":"externaladmissionhook.k8s.io","clientConfig":{"service":{"namespace":"ns","name":"n"},"caBundle":null},"rules":[{"operations":["CREATE"],"apiGroups":["group"],"apiVersions":["version"],"resources":["resource"]}],"failurePolicy":"Ignore"}]}`
,
},
gvr
(
"admissionregistration.k8s.io"
,
"v1beta1"
,
"mutatingwebhookconfigurations"
)
:
{
stub
:
`{"metadata":{"name":"hook1","creationTimestamp":null},"webhooks":[{"name":"externaladmissionhook.k8s.io","clientConfig":{"service":{"namespace":"ns","name":"n"},"caBundle":null},"rules":[{"operations":["CREATE"],"apiGroups":["group"],"apiVersions":["version"],"resources":["resource"]}],"failurePolicy":"Ignore"}]}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/scheduling/v1alpha1
gvr
(
"scheduling.k8s.io"
,
"v1alpha1"
,
"priorityclasses"
)
:
{
stub
:
`{"metadata":{"name":"pc1"},"Value":1000}`
,
},
// --
// k8s.io/kubernetes/pkg/apis/scheduling/v1beta1
gvr
(
"scheduling.k8s.io"
,
"v1beta1"
,
"priorityclasses"
)
:
{
stub
:
`{"metadata":{"name":"pc2"},"Value":1000}`
,
},
// --
// k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1
// depends on aggregator using the same ungrouped RESTOptionsGetter as the kube apiserver, not SimpleRestOptionsFactory in aggregator.go
gvr
(
"apiregistration.k8s.io"
,
"v1beta1"
,
"apiservices"
)
:
{
stub
:
`{"metadata": {"name": "dras1.foo.com"}, "spec": {"group": "foo.com", "version": "dras1", "groupPriorityMinimum":100, "versionPriority":10}}`
,
},
// --
// k8s.io/kube-aggregator/pkg/apis/apiregistration/v1
// depends on aggregator using the same ungrouped RESTOptionsGetter as the kube apiserver, not SimpleRestOptionsFactory in aggregator.go
gvr
(
"apiregistration.k8s.io"
,
"v1"
,
"apiservices"
)
:
{
stub
:
`{"metadata": {"name": "dras2.foo.com"}, "spec": {"group": "foo.com", "version": "dras2", "groupPriorityMinimum":100, "versionPriority":10}}`
,
},
// --
// k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1
gvr
(
"apiextensions.k8s.io"
,
"v1beta1"
,
"customresourcedefinitions"
)
:
{
stub
:
`{"metadata": {"name": "openshiftwebconsoleconfigs.webconsole.operator.openshift.io"},"spec": {"scope": "Cluster","group": "webconsole.operator.openshift.io","version": "v1alpha1","names": {"kind": "OpenShiftWebConsoleConfig","plural": "openshiftwebconsoleconfigs","singular": "openshiftwebconsoleconfig"}}}`
,
},
// --
}
// Only add kinds to this list when this a virtual resource with get and create verbs that doesn't actually
// store into it's kind. We've used this downstream for mappings before.
var
kindWhiteList
=
sets
.
NewString
()
// namespace used for all tests, do not change this
const
testNamespace
=
"dryrunnamespace"
func
DryRunCreateTest
(
t
*
testing
.
T
,
rsc
dynamic
.
ResourceInterface
,
obj
*
unstructured
.
Unstructured
,
gvResource
schema
.
GroupVersionResource
)
{
createdObj
,
err
:=
rsc
.
Create
(
obj
,
metav1
.
CreateOptions
{
DryRun
:
[]
string
{
metav1
.
DryRunAll
}})
if
err
!=
nil
{
t
.
Fatalf
(
"failed to dry-run create stub for %s: %#v"
,
gvResource
,
err
)
}
if
obj
.
GroupVersionKind
()
!=
createdObj
.
GroupVersionKind
()
{
t
.
Fatalf
(
"created object doesn't have the same gvk as original object: got %v, expected %v"
,
createdObj
.
GroupVersionKind
(),
obj
.
GroupVersionKind
())
}
if
_
,
err
:=
rsc
.
Get
(
obj
.
GetName
(),
metav1
.
GetOptions
{});
!
errors
.
IsNotFound
(
err
)
{
t
.
Fatalf
(
"object shouldn't exist: %v"
,
err
)
}
}
func
DryRunPatchTest
(
t
*
testing
.
T
,
rsc
dynamic
.
ResourceInterface
,
name
string
)
{
patch
:=
[]
byte
(
`{"metadata":{"annotations":{"patch": "true"}}}`
)
obj
,
err
:=
rsc
.
Patch
(
name
,
types
.
MergePatchType
,
patch
,
metav1
.
UpdateOptions
{
DryRun
:
[]
string
{
metav1
.
DryRunAll
}})
if
err
!=
nil
{
t
.
Fatalf
(
"failed to dry-run patch object: %v"
,
err
)
}
if
v
:=
obj
.
GetAnnotations
()[
"patch"
];
v
!=
"true"
{
t
.
Fatalf
(
"dry-run patched annotations should be returned, got: %v"
,
obj
.
GetAnnotations
())
}
obj
,
err
=
rsc
.
Get
(
obj
.
GetName
(),
metav1
.
GetOptions
{})
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get object: %v"
,
err
)
}
if
v
:=
obj
.
GetAnnotations
()[
"patch"
];
v
==
"true"
{
t
.
Fatalf
(
"dry-run patched annotations should not be persisted, got: %v"
,
obj
.
GetAnnotations
())
}
}
func
getReplicasOrFail
(
t
*
testing
.
T
,
obj
*
unstructured
.
Unstructured
)
int64
{
t
.
Helper
()
replicas
,
found
,
err
:=
unstructured
.
NestedInt64
(
obj
.
UnstructuredContent
(),
"spec"
,
"replicas"
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get int64 for replicas: %v"
,
err
)
}
if
!
found
{
t
.
Fatal
(
"object doesn't have spec.replicas"
)
}
return
replicas
}
func
setReplicasOrFail
(
t
*
testing
.
T
,
obj
*
unstructured
.
Unstructured
,
replicas
int64
)
{
m
,
found
,
err
:=
unstructured
.
NestedMap
(
obj
.
UnstructuredContent
(),
"spec"
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get spec: %v"
,
err
)
}
if
!
found
{
t
.
Fatal
(
"object doesn't have spec"
)
}
m
[
"replicas"
]
=
replicas
unstructured
.
SetNestedMap
(
obj
.
UnstructuredContent
(),
m
,
"spec"
)
}
func
DryRunScalePatchTest
(
t
*
testing
.
T
,
rsc
dynamic
.
ResourceInterface
,
name
string
)
{
obj
,
err
:=
rsc
.
Get
(
name
,
metav1
.
GetOptions
{},
"scale"
)
if
errors
.
IsNotFound
(
err
)
{
return
}
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get object: %v"
,
err
)
}
replicas
:=
getReplicasOrFail
(
t
,
obj
)
patch
:=
[]
byte
(
`{"spec":{"replicas":10}}`
)
patchedObj
,
err
:=
rsc
.
Patch
(
name
,
types
.
MergePatchType
,
patch
,
metav1
.
UpdateOptions
{
DryRun
:
[]
string
{
metav1
.
DryRunAll
}},
"scale"
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to dry-run patch object: %v"
,
err
)
}
if
newReplicas
:=
getReplicasOrFail
(
t
,
patchedObj
);
newReplicas
!=
10
{
t
.
Fatalf
(
"dry-run patch to replicas didn't return new value: %v"
,
newReplicas
)
}
persistedObj
,
err
:=
rsc
.
Get
(
name
,
metav1
.
GetOptions
{},
"scale"
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get scale sub-resource"
)
}
if
newReplicas
:=
getReplicasOrFail
(
t
,
persistedObj
);
newReplicas
!=
replicas
{
t
.
Fatalf
(
"number of replicas changed, expected %v, got %v"
,
replicas
,
newReplicas
)
}
}
func
DryRunScaleUpdateTest
(
t
*
testing
.
T
,
rsc
dynamic
.
ResourceInterface
,
name
string
)
{
obj
,
err
:=
rsc
.
Get
(
name
,
metav1
.
GetOptions
{},
"scale"
)
if
errors
.
IsNotFound
(
err
)
{
return
}
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get object: %v"
,
err
)
}
replicas
:=
getReplicasOrFail
(
t
,
obj
)
unstructured
.
SetNestedField
(
obj
.
Object
,
int64
(
10
),
"spec"
,
"replicas"
)
updatedObj
,
err
:=
rsc
.
Update
(
obj
,
metav1
.
UpdateOptions
{
DryRun
:
[]
string
{
metav1
.
DryRunAll
}},
"scale"
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to dry-run update scale sub-resource: %v"
,
err
)
}
if
newReplicas
:=
getReplicasOrFail
(
t
,
updatedObj
);
newReplicas
!=
10
{
t
.
Fatalf
(
"dry-run update to replicas didn't return new value: %v"
,
newReplicas
)
}
persistedObj
,
err
:=
rsc
.
Get
(
name
,
metav1
.
GetOptions
{},
"scale"
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get scale sub-resource"
)
}
if
newReplicas
:=
getReplicasOrFail
(
t
,
persistedObj
);
newReplicas
!=
replicas
{
t
.
Fatalf
(
"number of replicas changed, expected %v, got %v"
,
replicas
,
newReplicas
)
}
}
func
DryRunUpdateTest
(
t
*
testing
.
T
,
rsc
dynamic
.
ResourceInterface
,
name
string
)
{
var
err
error
var
obj
*
unstructured
.
Unstructured
for
i
:=
0
;
i
<
3
;
i
++
{
obj
,
err
=
rsc
.
Get
(
name
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
t
.
Fatalf
(
"failed to retrieve object: %v"
,
err
)
}
obj
.
SetAnnotations
(
map
[
string
]
string
{
"update"
:
"true"
})
obj
,
err
=
rsc
.
Update
(
obj
,
metav1
.
UpdateOptions
{
DryRun
:
[]
string
{
metav1
.
DryRunAll
}})
if
err
==
nil
||
!
errors
.
IsConflict
(
err
)
{
break
}
}
if
err
!=
nil
{
t
.
Fatalf
(
"failed to dry-run update resource: %v"
,
err
)
}
if
v
:=
obj
.
GetAnnotations
()[
"update"
];
v
!=
"true"
{
t
.
Fatalf
(
"dry-run updated annotations should be returned, got: %v"
,
obj
.
GetAnnotations
())
}
obj
,
err
=
rsc
.
Get
(
obj
.
GetName
(),
metav1
.
GetOptions
{})
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get object: %v"
,
err
)
}
if
v
:=
obj
.
GetAnnotations
()[
"update"
];
v
==
"true"
{
t
.
Fatalf
(
"dry-run updated annotations should not be persisted, got: %v"
,
obj
.
GetAnnotations
())
}
}
func
DryRunDeleteCollectionTest
(
t
*
testing
.
T
,
rsc
dynamic
.
ResourceInterface
,
name
string
)
{
err
:=
rsc
.
DeleteCollection
(
&
metav1
.
DeleteOptions
{
DryRun
:
[]
string
{
metav1
.
DryRunAll
}},
metav1
.
ListOptions
{})
if
err
!=
nil
{
t
.
Fatalf
(
"dry-run delete collection failed: %v"
,
err
)
}
obj
,
err
:=
rsc
.
Get
(
name
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get object: %v"
,
err
)
}
ts
:=
obj
.
GetDeletionTimestamp
()
if
ts
!=
nil
{
t
.
Fatalf
(
"object has a deletion timestamp after dry-run delete collection"
)
}
}
func
DryRunDeleteTest
(
t
*
testing
.
T
,
rsc
dynamic
.
ResourceInterface
,
name
string
)
{
err
:=
rsc
.
Delete
(
name
,
&
metav1
.
DeleteOptions
{
DryRun
:
[]
string
{
metav1
.
DryRunAll
}})
if
err
!=
nil
{
t
.
Fatalf
(
"dry-run delete failed: %v"
,
err
)
}
obj
,
err
:=
rsc
.
Get
(
name
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get object: %v"
,
err
)
}
ts
:=
obj
.
GetDeletionTimestamp
()
if
ts
!=
nil
{
t
.
Fatalf
(
"object has a deletion timestamp after dry-run delete"
)
}
}
// TestDryRun tests dry-run on all types.
func
TestDryRun
(
t
*
testing
.
T
)
{
certDir
,
_
:=
ioutil
.
TempDir
(
""
,
"test-integration-dryrun"
)
defer
os
.
RemoveAll
(
certDir
)
defer
utilfeaturetesting
.
SetFeatureGateDuringTest
(
t
,
utilfeature
.
DefaultFeatureGate
,
features
.
DryRun
,
true
)()
clientConfig
:=
startRealMasterOrDie
(
t
,
certDir
)
dClient
:=
dynamic
.
NewForConfigOrDie
(
clientConfig
)
kubeClient
:=
clientset
.
NewForConfigOrDie
(
clientConfig
)
if
_
,
err
:=
kubeClient
.
CoreV1
()
.
Namespaces
()
.
Create
(
&
v1
.
Namespace
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
testNamespace
}});
err
!=
nil
{
t
.
Fatal
(
err
)
}
discoveryClient
:=
cacheddiscovery
.
NewMemCacheClient
(
kubeClient
.
Discovery
())
restMapper
:=
restmapper
.
NewDeferredDiscoveryRESTMapper
(
discoveryClient
)
restMapper
.
Reset
()
serverResources
,
err
:=
kubeClient
.
Discovery
()
.
ServerResources
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
resourcesToTest
:=
getResourcesToTest
(
serverResources
,
false
,
t
)
for
_
,
resourceToTest
:=
range
resourcesToTest
{
t
.
Run
(
resourceToTest
.
gvr
.
String
(),
func
(
t
*
testing
.
T
)
{
gvk
:=
resourceToTest
.
gvk
gvResource
:=
resourceToTest
.
gvr
kind
:=
gvk
.
Kind
mapping
:=
&
meta
.
RESTMapping
{
Resource
:
resourceToTest
.
gvr
,
GroupVersionKind
:
resourceToTest
.
gvk
,
Scope
:
meta
.
RESTScopeRoot
,
}
if
resourceToTest
.
namespaced
{
mapping
.
Scope
=
meta
.
RESTScopeNamespace
}
if
kindWhiteList
.
Has
(
kind
)
{
t
.
Skip
(
"whitelisted"
)
}
testData
,
hasTest
:=
dryrunData
[
gvResource
]
if
!
hasTest
{
t
.
Fatalf
(
"no test data for %s. Please add a test for your new type to dryrunData."
,
gvResource
)
}
// we don't require GVK on the data we provide, so we fill it in here. We could, but that seems extraneous.
typeMetaAdder
:=
map
[
string
]
interface
{}{}
err
:=
json
.
Unmarshal
([]
byte
(
testData
.
stub
),
&
typeMetaAdder
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to unmarshal stub (%v): %v"
,
testData
.
stub
,
err
)
}
typeMetaAdder
[
"apiVersion"
]
=
mapping
.
GroupVersionKind
.
GroupVersion
()
.
String
()
typeMetaAdder
[
"kind"
]
=
mapping
.
GroupVersionKind
.
Kind
rsc
:=
dClient
.
Resource
(
mapping
.
Resource
)
.
Namespace
(
testNamespace
)
if
mapping
.
Scope
==
meta
.
RESTScopeRoot
{
rsc
=
dClient
.
Resource
(
mapping
.
Resource
)
}
obj
:=
&
unstructured
.
Unstructured
{
Object
:
typeMetaAdder
}
name
:=
obj
.
GetName
()
DryRunCreateTest
(
t
,
rsc
,
obj
,
gvResource
)
if
_
,
err
:=
rsc
.
Create
(
obj
,
metav1
.
CreateOptions
{});
err
!=
nil
{
t
.
Fatalf
(
"failed to create stub for %s: %#v"
,
gvResource
,
err
)
}
DryRunUpdateTest
(
t
,
rsc
,
name
)
DryRunPatchTest
(
t
,
rsc
,
name
)
DryRunScalePatchTest
(
t
,
rsc
,
name
)
DryRunScaleUpdateTest
(
t
,
rsc
,
name
)
if
resourceToTest
.
hasDeleteCollection
{
DryRunDeleteCollectionTest
(
t
,
rsc
,
name
)
}
DryRunDeleteTest
(
t
,
rsc
,
name
)
if
err
=
rsc
.
Delete
(
obj
.
GetName
(),
metav1
.
NewDeleteOptions
(
0
));
err
!=
nil
{
t
.
Fatalf
(
"deleting final object failed: %v"
,
err
)
}
})
}
}
func
startRealMasterOrDie
(
t
*
testing
.
T
,
certDir
string
)
*
restclient
.
Config
{
_
,
defaultServiceClusterIPRange
,
err
:=
net
.
ParseCIDR
(
"10.0.0.0/24"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
listener
,
_
,
err
:=
genericapiserveroptions
.
CreateListener
(
"tcp"
,
"127.0.0.1:0"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
kubeAPIServerOptions
:=
options
.
NewServerRunOptions
()
kubeAPIServerOptions
.
InsecureServing
.
BindPort
=
0
kubeAPIServerOptions
.
SecureServing
.
Listener
=
listener
kubeAPIServerOptions
.
SecureServing
.
ServerCert
.
CertDirectory
=
certDir
kubeAPIServerOptions
.
Etcd
.
StorageConfig
.
ServerList
=
[]
string
{
framework
.
GetEtcdURL
()}
kubeAPIServerOptions
.
Etcd
.
DefaultStorageMediaType
=
runtime
.
ContentTypeJSON
// force json we can easily interpret the result in etcd
kubeAPIServerOptions
.
ServiceClusterIPRange
=
*
defaultServiceClusterIPRange
kubeAPIServerOptions
.
Authorization
.
Modes
=
[]
string
{
"RBAC"
}
kubeAPIServerOptions
.
Admission
.
GenericAdmission
.
DisablePlugins
=
[]
string
{
"ServiceAccount"
}
completedOptions
,
err
:=
app
.
Complete
(
kubeAPIServerOptions
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
kubeAPIServerOptions
.
APIEnablement
.
RuntimeConfig
.
Set
(
"api/all=true"
)
kubeAPIServer
,
err
:=
app
.
CreateServerChain
(
completedOptions
,
wait
.
NeverStop
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
kubeClientConfig
:=
restclient
.
CopyConfig
(
kubeAPIServer
.
LoopbackClientConfig
)
go
func
()
{
// Catch panics that occur in this go routine so we get a comprehensible failure
defer
func
()
{
if
err
:=
recover
();
err
!=
nil
{
t
.
Errorf
(
"Unexpected panic trying to start API master: %#v"
,
err
)
}
}()
if
err
:=
kubeAPIServer
.
PrepareRun
()
.
Run
(
wait
.
NeverStop
);
err
!=
nil
{
t
.
Fatal
(
err
)
}
}()
lastHealth
:=
""
if
err
:=
wait
.
PollImmediate
(
time
.
Second
,
time
.
Minute
,
func
()
(
done
bool
,
err
error
)
{
// wait for the server to be healthy
result
:=
clientset
.
NewForConfigOrDie
(
kubeClientConfig
)
.
RESTClient
()
.
Get
()
.
AbsPath
(
"/healthz"
)
.
Do
()
content
,
_
:=
result
.
Raw
()
lastHealth
=
string
(
content
)
if
errResult
:=
result
.
Error
();
errResult
!=
nil
{
t
.
Log
(
errResult
)
return
false
,
nil
}
var
status
int
result
.
StatusCode
(
&
status
)
return
status
==
http
.
StatusOK
,
nil
});
err
!=
nil
{
t
.
Log
(
lastHealth
)
t
.
Fatal
(
err
)
}
// this test makes lots of requests, don't be slow
kubeClientConfig
.
QPS
=
99999
kubeClientConfig
.
Burst
=
9999
return
kubeClientConfig
}
func
gvr
(
g
,
v
,
r
string
)
schema
.
GroupVersionResource
{
return
schema
.
GroupVersionResource
{
Group
:
g
,
Version
:
v
,
Resource
:
r
}
}
type
resourceToTest
struct
{
gvk
schema
.
GroupVersionKind
gvr
schema
.
GroupVersionResource
namespaced
bool
hasDeleteCollection
bool
}
func
getResourcesToTest
(
serverResources
[]
*
metav1
.
APIResourceList
,
isOAPI
bool
,
t
*
testing
.
T
)
[]
resourceToTest
{
resourcesToTest
:=
[]
resourceToTest
{}
for
_
,
discoveryGroup
:=
range
serverResources
{
for
_
,
discoveryResource
:=
range
discoveryGroup
.
APIResources
{
// this is a subresource, skip it
if
strings
.
Contains
(
discoveryResource
.
Name
,
"/"
)
{
continue
}
hasCreate
:=
false
hasGet
:=
false
hasDeleteCollection
:=
false
for
_
,
verb
:=
range
discoveryResource
.
Verbs
{
if
string
(
verb
)
==
"get"
{
hasGet
=
true
}
if
string
(
verb
)
==
"create"
{
hasCreate
=
true
}
if
string
(
verb
)
==
"deletecollection"
{
hasDeleteCollection
=
true
}
}
if
!
(
hasCreate
&&
hasGet
)
{
continue
}
resourceGV
,
err
:=
schema
.
ParseGroupVersion
(
discoveryGroup
.
GroupVersion
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
gvk
:=
resourceGV
.
WithKind
(
discoveryResource
.
Kind
)
if
len
(
discoveryResource
.
Group
)
>
0
||
len
(
discoveryResource
.
Version
)
>
0
{
gvk
=
schema
.
GroupVersionKind
{
Group
:
discoveryResource
.
Group
,
Version
:
discoveryResource
.
Version
,
Kind
:
discoveryResource
.
Kind
,
}
}
gvr
:=
resourceGV
.
WithResource
(
discoveryResource
.
Name
)
resourcesToTest
=
append
(
resourcesToTest
,
resourceToTest
{
gvk
:
gvk
,
gvr
:
gvr
,
namespaced
:
discoveryResource
.
Namespaced
,
hasDeleteCollection
:
hasDeleteCollection
,
})
}
}
return
resourcesToTest
}
test/integration/dryrun/main_test.go
0 → 100644
View file @
35f72c5a
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
dryrun
import
(
"testing"
"k8s.io/kubernetes/test/integration/framework"
)
func
TestMain
(
m
*
testing
.
M
)
{
framework
.
EtcdMain
(
m
.
Run
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment