Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ lint:
$(GOPATH)/bin/golangci-lint run ./...

test:
go test -race -cover ./...
go test -race -cover ./cmd/... ./pkg/...

test-e2e: $(MYGOBIN)/ginkgo $(MYGOBIN)/kind
kind delete cluster --name=cli-utils-e2e && kind create cluster --name=cli-utils-e2e
$(GOPATH)/bin/ginkgo ./test/e2e/...

vet:
go vet ./...
Expand All @@ -62,6 +66,9 @@ build-with-race-detector:
.PHONY: verify-kapply-e2e
verify-kapply-e2e: test-examples-e2e-kapply

$(MYGOBIN)/ginkgo:
go get github.com/onsi/ginkgo/ginkgo@v1.14.2

$(MYGOBIN)/mdrip:
go install github.com/monopole/mdrip

Expand All @@ -77,14 +84,7 @@ test-examples-e2e-kapply: $(MYGOBIN)/mdrip $(MYGOBIN)/kind
)

$(MYGOBIN)/kind:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
wget -O ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-$(shell uname)-amd64; \
chmod +x ./kind; \
mv ./kind $(MYGOBIN); \
rm -rf $$d; \
)
go get sigs.k8s.io/kind@v0.9.0

.PHONY: nuke
nuke: clean
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ require (
github.com/google/uuid v1.1.1
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/onsi/ginkgo v1.13.0 // indirect
github.com/onsi/ginkgo v1.14.2
github.com/onsi/gomega v1.10.1
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.6.0 // indirect
github.com/spf13/cobra v1.0.0
Expand Down
5 changes: 2 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y=
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
Expand Down Expand Up @@ -388,7 +388,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
Expand Down
16 changes: 16 additions & 0 deletions test/e2e/e2e_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

package e2e

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestE2e(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "E2e Suite")
}
208 changes: 208 additions & 0 deletions test/e2e/e2e_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

package e2e

import (
"context"
"fmt"
"time"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
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/types"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/scheme"
"sigs.k8s.io/cli-utils/pkg/apply"
"sigs.k8s.io/cli-utils/pkg/apply/event"
"sigs.k8s.io/cli-utils/pkg/common"
"sigs.k8s.io/cli-utils/pkg/inventory"
"sigs.k8s.io/cli-utils/pkg/provider"
"sigs.k8s.io/cli-utils/pkg/util/factory"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
)

var _ = Describe("Applier", func() {

var c client.Client

BeforeSuite(func() {
cfg, err := ctrl.GetConfig()
Expect(err).NotTo(HaveOccurred())

mapper, err := apiutil.NewDynamicRESTMapper(cfg)
Expect(err).NotTo(HaveOccurred())

c, err = client.New(cfg, client.Options{
Scheme: scheme.Scheme,
Mapper: mapper,
})
Expect(err).NotTo(HaveOccurred())
})

var namespaceName string
var namespace *v1.Namespace
var inventoryName string

BeforeEach(func() {
namespaceName = randomString("e2e-test-")
namespace = &v1.Namespace{
TypeMeta: metav1.TypeMeta{
APIVersion: v1.SchemeGroupVersion.String(),
Kind: "Namespace",
},
ObjectMeta: metav1.ObjectMeta{
Name: namespaceName,
},
}
inventoryName = randomString("test-inv-")
err := c.Create(context.TODO(), namespace)
Expect(err).ToNot(HaveOccurred())
})

AfterEach(func() {
err := c.Delete(context.TODO(), namespace)
Expect(err).ToNot(HaveOccurred())
})

It("Apply and destroy", func() {
By("Apply resources")
applier := newApplier()
err := applier.Initialize()
Expect(err).NotTo(HaveOccurred())

inv := inventory.WrapInventoryInfoObj(inventoryManifest(inventoryName, namespaceName))

resources := []*unstructured.Unstructured{
deploymentManifest(namespaceName),
}

applyCh := applier.Run(context.TODO(), inv, resources, apply.Options{
ReconcileTimeout: 2 * time.Minute,
EmitStatusEvents: true,
})

for e := range applyCh {
Expect(e.Type).NotTo(Equal(event.ErrorType))
}

By("Verify inventory")
var cm v1.ConfigMap
err = c.Get(context.TODO(), types.NamespacedName{
Name: inventoryName,
Namespace: namespaceName,
}, &cm)
Expect(err).ToNot(HaveOccurred())

data := cm.Data
Expect(len(data)).To(Equal(1))

By("Destroy resources")
destroyer := newDestroyer()
err = destroyer.Initialize()
Expect(err).NotTo(HaveOccurred())

destroyCh := destroyer.Run(inv)

for e := range destroyCh {
Expect(e.Type).NotTo(Equal(event.ErrorType))
}
})
})

func inventoryManifest(name, namespace string) *unstructured.Unstructured {
cm := &v1.ConfigMap{
TypeMeta: metav1.TypeMeta{
APIVersion: v1.SchemeGroupVersion.String(),
Kind: "ConfigMap",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: map[string]string{
common.InventoryLabel: "test",
},
},
}
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(cm)
if err != nil {
panic(err)
}
return &unstructured.Unstructured{
Object: u,
}
}

func deploymentManifest(namespace string) *unstructured.Unstructured {
dep := &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
APIVersion: appsv1.SchemeGroupVersion.String(),
Kind: "Deployment",
},
ObjectMeta: metav1.ObjectMeta{
Name: "nginx-deployment",
Namespace: namespace,
},
Spec: appsv1.DeploymentSpec{
Replicas: func() *int32 { r := int32(4); return &r }(),
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "nginx",
},
},
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": "nginx",
},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: "nginx",
Image: "nginx:1.19.6",
},
},
},
},
},
}
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(dep)
if err != nil {
panic(err)
}
return &unstructured.Unstructured{
Object: u,
}
}

func newApplier() *apply.Applier {
return apply.NewApplier(newProvider())
}

func newDestroyer() *apply.Destroyer {
return apply.NewDestroyer(newProvider())
}

func newProvider() provider.Provider {
kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
matchVersionKubeConfigFlags := util.NewMatchVersionFlags(&factory.CachingRESTClientGetter{
Delegate: kubeConfigFlags,
})
f := util.NewFactory(matchVersionKubeConfigFlags)
return provider.NewProvider(f)
}

func randomString(prefix string) string {
seed := time.Now().UTC().UnixNano()
randomSuffix := common.RandomStr(seed)
return fmt.Sprintf("%s%s", prefix, randomSuffix)
}