Skip to content

Commit

Permalink
fix #692: add version information to all resources
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolaferraro authored and lburgazzoli committed Jul 8, 2019
1 parent efa72a4 commit 1a5ca8c
Show file tree
Hide file tree
Showing 16 changed files with 359 additions and 5 deletions.
180 changes: 180 additions & 0 deletions e2e/test_support.go
Expand Up @@ -23,6 +23,8 @@ package e2e

import (
"context"
"errors"
"fmt"
"time"

"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
Expand All @@ -35,6 +37,7 @@ import (
projectv1 "github.com/openshift/api/project/v1"
"github.com/spf13/cobra"
"io/ioutil"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -121,6 +124,16 @@ func integrationPodPhase(ns string, name string) func() v1.PodPhase {
}
}

func integrationPodImage(ns string, name string) func() string {
return func() string {
pod := integrationPod(ns, name)()
if pod == nil || len(pod.Spec.Containers) == 0 {
return ""
}
return pod.Spec.Containers[0].Image
}
}

func integrationPod(ns string, name string) func() *v1.Pod {
return func() *v1.Pod {
lst := v1.PodList{
Expand All @@ -145,6 +158,86 @@ func integrationPod(ns string, name string) func() *v1.Pod {
}
}

func integration(ns string, name string) func() *v1alpha1.Integration {
return func() *v1alpha1.Integration {
it := v1alpha1.NewIntegration(ns, name)
key := k8sclient.ObjectKey{
Namespace: ns,
Name: name,
}
if err := testClient.Get(testContext, key, &it); err != nil && !k8serrors.IsNotFound(err) {
panic(err)
} else if err != nil && k8serrors.IsNotFound(err) {
return nil
}
return &it
}
}

func integrationVersion(ns string, name string) func() string {
return func() string {
it := integration(ns, name)()
if it == nil {
return ""
}
return it.Status.Version
}
}

func setIntegrationVersion(ns string, name string, version string) error {
it := integration(ns, name)()
if it == nil {
return fmt.Errorf("no integration named %s found", name)
}
it.Status.Version = version
return testClient.Status().Update(testContext, it)
}

func setIntegrationPhase(ns string, name string, phase v1alpha1.IntegrationPhase) error {
it := integration(ns, name)()
if it == nil {
return fmt.Errorf("no integration named %s found", name)
}
it.Status.Phase = phase
return testClient.Status().Update(testContext, it)
}

func kits(ns string) func() []v1alpha1.IntegrationKit {
return func() []v1alpha1.IntegrationKit {
lst := v1alpha1.NewIntegrationKitList()
opts := k8sclient.ListOptions{
Namespace: ns,
}
if err := testClient.List(testContext, &opts, &lst); err != nil {
panic(err)
}
return lst.Items
}
}

func kitsWithVersion(ns string, version string) func() int {
return func() int {
count := 0
for _, k := range kits(ns)() {
if k.Status.Version == version {
count++
}
}
return count
}
}

func setAllKitsVersion(ns string, version string) error {
for _, k := range kits(ns)() {
kit := k
kit.Status.Version = version
if err := testClient.Status().Update(testContext, &kit); err != nil {
return err
}
}
return nil
}

func operatorImage(ns string) func() string {
return func() string {
pod := operatorPod(ns)()
Expand Down Expand Up @@ -200,6 +293,44 @@ func build(ns string, name string) func() *v1alpha1.Build {
}
}

func platform(ns string) func() *v1alpha1.IntegrationPlatform {
return func() *v1alpha1.IntegrationPlatform {
lst := v1alpha1.NewIntegrationPlatformList()
opts := k8sclient.ListOptions{
Namespace: ns,
}
if err := testClient.List(testContext, &opts, &lst); err != nil {
panic(err)
}
if len(lst.Items) == 0 {
return nil
}
if len(lst.Items) > 1 {
panic("multiple integration platforms found in namespace " + ns)
}
return &lst.Items[0]
}
}

func setPlatformVersion(ns string, version string) error {
p := platform(ns)()
if p == nil {
return errors.New("no platform found")
}
p.Status.Version = version
return testClient.Status().Update(testContext, p)
}

func platformVersion(ns string) func() string {
return func() string {
p := platform(ns)()
if p == nil {
return ""
}
return p.Status.Version
}
}

func operatorPod(ns string) func() *v1.Pod {
return func() *v1.Pod {
lst := v1.PodList{
Expand All @@ -224,6 +355,55 @@ func operatorPod(ns string) func() *v1.Pod {
}
}

func operatorTryPodForceKill(ns string) {
pod := operatorPod(ns)()
if pod != nil {
opts := func(options *k8sclient.DeleteOptions) {
zero := int64(0)
options.GracePeriodSeconds = &zero
}
if err := testClient.Delete(testContext, pod, opts); err != nil {
log.Error(err, "cannot forcefully kill the pod")
}
}
}

func scaleOperator(ns string, replicas int32) error {
lst := appsv1.DeploymentList{
TypeMeta: metav1.TypeMeta{
Kind: "Deployment",
APIVersion: appsv1.SchemeGroupVersion.String(),
},
}
opts := k8sclient.ListOptions{
LabelSelector: labels.SelectorFromSet(labels.Set{
"camel.apache.org/component": "operator",
}),
Namespace: ns,
}
if err := testClient.List(testContext, &opts, &lst); err != nil {
return err
}
if len(lst.Items) == 0 {
return errors.New("camel k operator not found")
} else if len(lst.Items) > 1 {
return errors.New("too many camel k operators")
}

operatorDeployment := lst.Items[0]
operatorDeployment.Spec.Replicas = &replicas
err := testClient.Update(testContext, &operatorDeployment)
if err != nil {
return err
}

if replicas == 0 {
// speedup scale down by killing the pod
operatorTryPodForceKill(ns)
}
return nil
}

/*
Namespace testing functions
*/
Expand Down
93 changes: 93 additions & 0 deletions e2e/upgrade_test.go
@@ -0,0 +1,93 @@
// +build integration

// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"

/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 e2e

import (
"testing"
"time"

"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
"github.com/apache/camel-k/pkg/util/defaults"
. "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
)

func TestPlatformUpgrade(t *testing.T) {
withNewTestNamespace(func(ns string) {
RegisterTestingT(t)
Expect(kamel("install", "-n", ns).Execute()).Should(BeNil())
Eventually(platformVersion(ns)).Should(Equal(defaults.Version))

// Scale the operator down to zero
Expect(scaleOperator(ns, 0)).Should(BeNil())
Eventually(operatorPod(ns)).Should(BeNil())

// Change the version to an older one
Expect(setPlatformVersion(ns, "an.older.one")).Should(BeNil())
Eventually(platformVersion(ns)).Should(Equal("an.older.one"))

// Scale the operator up
Expect(scaleOperator(ns, 1)).Should(BeNil())
Eventually(operatorPod(ns)).ShouldNot(BeNil())

// Check the platform version change
Eventually(platformVersion(ns)).Should(Equal(defaults.Version))
})
}

func TestIntegrationUpgrade(t *testing.T) {
withNewTestNamespace(func(ns string) {
RegisterTestingT(t)
Expect(kamel("install", "-n", ns).Execute()).Should(BeNil())
Eventually(platformVersion(ns)).Should(Equal(defaults.Version))

// Run an integration
Expect(kamel("run", "-n", ns, "files/js.js").Execute()).Should(BeNil())
Eventually(integrationPodPhase(ns, "js"), 5*time.Minute).Should(Equal(v1.PodRunning))
initialImage := integrationPodImage(ns, "js")()

// Scale the operator down to zero
Expect(scaleOperator(ns, 0)).Should(BeNil())
Eventually(operatorPod(ns)).Should(BeNil())

// Change the version to an older one
Expect(setIntegrationVersion(ns, "js", "an.older.one")).Should(BeNil())
Expect(setAllKitsVersion(ns, "an.older.one")).Should(BeNil())
Eventually(integrationVersion(ns, "js")).Should(Equal("an.older.one"))
Eventually(kitsWithVersion(ns, "an.older.one")).Should(Equal(1))
Eventually(kitsWithVersion(ns, defaults.Version)).Should(Equal(0))

// Scale the operator up
Expect(scaleOperator(ns, 1)).Should(BeNil())
Eventually(operatorPod(ns)).ShouldNot(BeNil())

// Clear the integration phase
Expect(setIntegrationPhase(ns, "js", v1alpha1.IntegrationPhaseNone)).Should(BeNil())

// Check the integration version change
Eventually(integrationVersion(ns, "js")).Should(Equal(defaults.Version))
Eventually(kitsWithVersion(ns, "an.older.one")).Should(Equal(1)) // old one is not recycled
Eventually(kitsWithVersion(ns, defaults.Version)).Should(Equal(1))
Eventually(integrationPodImage(ns, "js")).ShouldNot(Equal(initialImage)) // rolling deployment triggered
Eventually(integrationPodPhase(ns, "js"), 5*time.Minute).Should(Equal(v1.PodRunning))
})
}
4 changes: 3 additions & 1 deletion go.mod
Expand Up @@ -57,14 +57,16 @@ require (
go.uber.org/atomic v1.3.2 // indirect
go.uber.org/multierr v1.1.0
go.uber.org/zap v1.9.1 // indirect
golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a // indirect
golang.org/x/sys v0.0.0-20190312061237-fead79001313 // indirect
google.golang.org/appengine v1.5.0 // indirect
gopkg.in/yaml.v2 v2.2.2
k8s.io/api v0.0.0-20190222213804-5cb15d344471
k8s.io/apiextensions-apiserver v0.0.0-20190228180357-d002e88f6236 // indirect
k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628
k8s.io/client-go v0.0.0-20190228174230-b40b2a5939e4
k8s.io/klog v0.3.0 // indirect
k8s.io/klog v0.3.1 // indirect
k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22 // indirect
sigs.k8s.io/controller-runtime v0.1.10
sigs.k8s.io/testing_frameworks v0.1.1 // indirect
Expand Down
12 changes: 10 additions & 2 deletions go.sum
Expand Up @@ -272,6 +272,8 @@ golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
Expand All @@ -285,6 +287,8 @@ golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
Expand All @@ -302,6 +306,9 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5 h1:mzjBh+S5frKOsOBobWIMAbXavqjmgO17k/2puhcFR94=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjWsBSzdaQiKzUyf3DTTc=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
Expand Down Expand Up @@ -355,10 +362,11 @@ k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628 h1:UYfHH+KEF88OTg+GojQUwF
k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
k8s.io/client-go v0.0.0-20190228174230-b40b2a5939e4 h1:aE8wOCKuoRs2aU0OP/Rz8SXiAB0FTTku3VtGhhrkSmc=
k8s.io/client-go v0.0.0-20190228174230-b40b2a5939e4/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6 h1:4s3/R4+OYYYUKptXPhZKjQ04WJ6EhQQVFdjOFvCazDk=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68=
k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22 h1:f0BTap/vrgs21vVbJ1ySdsNtcivpA1x4ut6Wla9HKKw=
k8s.io/kube-openapi v0.0.0-20190510232812-a01b7d5d6c22/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw=
sigs.k8s.io/controller-runtime v0.1.10 h1:amLOmcekVdnsD1uIpmgRqfTbQWJ2qxvQkcdeFhcotn4=
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/camel/v1alpha1/integration_types.go
Expand Up @@ -49,6 +49,7 @@ type IntegrationStatus struct {
CamelVersion string `json:"camelVersion,omitempty"`
RuntimeVersion string `json:"runtimeVersion,omitempty"`
Configuration []ConfigurationSpec `json:"configuration,omitempty"`
Version string `json:"version,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/camel/v1alpha1/integrationkit_types.go
Expand Up @@ -43,6 +43,7 @@ type IntegrationKitStatus struct {
Failure *Failure `json:"failure,omitempty"`
CamelVersion string `json:"camelVersion,omitempty"`
RuntimeVersion string `json:"runtimeVersion,omitempty"`
Version string `json:"version,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down

0 comments on commit 1a5ca8c

Please sign in to comment.