github.com/oam-dev/kubevela@v1.9.11/references/docgen/cluster_test.go (about)

     1  /*
     2  Copyright 2021 The KubeVela Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package docgen
    18  
    19  import (
    20  	"context"
    21  	"os"
    22  	"path/filepath"
    23  	"strings"
    24  	"time"
    25  
    26  	"cuelang.org/go/cue"
    27  	"github.com/google/go-cmp/cmp"
    28  	. "github.com/onsi/ginkgo/v2"
    29  	. "github.com/onsi/gomega"
    30  	corev1 "k8s.io/api/core/v1"
    31  	"k8s.io/apimachinery/pkg/api/errors"
    32  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    33  	"k8s.io/apimachinery/pkg/labels"
    34  	"k8s.io/apimachinery/pkg/selection"
    35  	"sigs.k8s.io/controller-runtime/pkg/client"
    36  	"sigs.k8s.io/yaml"
    37  
    38  	corev1beta1 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
    39  	"github.com/oam-dev/kubevela/apis/types"
    40  	"github.com/oam-dev/kubevela/pkg/oam/util"
    41  	"github.com/oam-dev/kubevela/pkg/utils/common"
    42  )
    43  
    44  const (
    45  	TestDir        = "testdata"
    46  	DeployName     = "deployments.testapps"
    47  	WebserviceName = "webservice.testapps"
    48  )
    49  
    50  var _ = Describe("DefinitionFiles", func() {
    51  
    52  	deployment := types.Capability{
    53  		Namespace:   "testdef",
    54  		Name:        DeployName,
    55  		Type:        types.TypeComponentDefinition,
    56  		CrdName:     "deployments.apps",
    57  		Description: "description not defined",
    58  		Category:    types.CUECategory,
    59  		Parameters: []types.Parameter{
    60  			{
    61  				Name:     "image",
    62  				Type:     cue.StringKind,
    63  				Default:  "",
    64  				Short:    "i",
    65  				Required: true,
    66  				Usage:    "Which image would you like to use for your service",
    67  			},
    68  			{
    69  				Name:    "port",
    70  				Type:    cue.IntKind,
    71  				Short:   "p",
    72  				Default: int64(8080),
    73  				Usage:   "Which port do you want customer traffic sent to",
    74  			},
    75  			{
    76  				Type: cue.ListKind,
    77  				Name: "env",
    78  			},
    79  		},
    80  		Labels: map[string]string{"usecase": "forplugintest"},
    81  	}
    82  
    83  	websvc := types.Capability{
    84  		Namespace:   "testdef",
    85  		Name:        WebserviceName,
    86  		Type:        types.TypeComponentDefinition,
    87  		Description: "description not defined",
    88  		Category:    types.CUECategory,
    89  		Parameters: []types.Parameter{
    90  			{
    91  				Name:     "image",
    92  				Type:     cue.StringKind,
    93  				Default:  "",
    94  				Short:    "i",
    95  				Required: true,
    96  				Usage:    "Which image would you like to use for your service",
    97  			}, {
    98  				Name:    "port",
    99  				Type:    cue.IntKind,
   100  				Short:   "p",
   101  				Default: int64(6379),
   102  				Usage:   "Which port do you want customer traffic sent to",
   103  			},
   104  			{
   105  				Name: "env", Type: cue.ListKind,
   106  			},
   107  		},
   108  		CrdName: "deployments.apps",
   109  		Labels:  map[string]string{"usecase": "forplugintest"},
   110  	}
   111  
   112  	req, _ := labels.NewRequirement("usecase", selection.Equals, []string{"forplugintest"})
   113  	selector := labels.NewSelector().Add(*req)
   114  	// Notice!!  DefinitionPath Object is Cluster Scope object
   115  	// which means objects created in other DefinitionNamespace will also affect here.
   116  	It("getcomponents", func() {
   117  		arg := common.Args{}
   118  		arg.SetClient(k8sClient)
   119  		workloadDefs, _, err := GetComponentsFromCluster(context.Background(), DefinitionNamespace, arg, selector)
   120  		Expect(err).Should(BeNil())
   121  		for i := range workloadDefs {
   122  			// CueTemplate should always be fulfilled, even those whose CueTemplateURI is assigend,
   123  			By("check CueTemplate is fulfilled")
   124  			Expect(workloadDefs[i].CueTemplate).ShouldNot(BeEmpty())
   125  			workloadDefs[i].CueTemplate = ""
   126  		}
   127  		Expect(cmp.Diff(workloadDefs, []types.Capability{deployment, websvc})).Should(BeEquivalentTo(""))
   128  	})
   129  	It("getall", func() {
   130  		arg := common.Args{}
   131  		arg.SetClient(k8sClient)
   132  		alldef, err := GetCapabilitiesFromCluster(context.Background(), DefinitionNamespace, arg, selector)
   133  		Expect(err).Should(BeNil())
   134  		for i := range alldef {
   135  			alldef[i].CueTemplate = ""
   136  		}
   137  		Expect(cmp.Diff(alldef, []types.Capability{deployment, websvc})).Should(BeEquivalentTo(""))
   138  	})
   139  })
   140  
   141  var _ = Describe("test GetCapabilityByName", func() {
   142  	var (
   143  		ctx        context.Context
   144  		c          common.Args
   145  		ns         string
   146  		defaultNS  string
   147  		cd1        corev1beta1.ComponentDefinition
   148  		cd2        corev1beta1.ComponentDefinition
   149  		component1 string
   150  		component2 string
   151  	)
   152  	BeforeEach(func() {
   153  		c = common.Args{}
   154  		c.SetClient(k8sClient)
   155  		ctx = context.Background()
   156  		ns = "cluster-test-ns-suffix"
   157  		defaultNS = types.DefaultKubeVelaNS
   158  		component1 = "cd1"
   159  		component2 = "cd2"
   160  
   161  		By("create namespace")
   162  		Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: ns}})).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   163  		Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: defaultNS}})).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   164  
   165  		By("create ComponentDefinition")
   166  		data, _ := os.ReadFile("testdata/componentDef.yaml")
   167  		yaml.Unmarshal(data, &cd1)
   168  		yaml.Unmarshal(data, &cd2)
   169  
   170  		cd1.Namespace = ns
   171  		cd1.Name = component1
   172  		Expect(k8sClient.Create(ctx, &cd1)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   173  
   174  		cd2.Namespace = defaultNS
   175  		cd2.Name = component2
   176  		Expect(k8sClient.Create(ctx, &cd2)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   177  	})
   178  
   179  	AfterEach(func() {
   180  		for _, obj := range []client.Object{&cd1, &cd2} {
   181  			key := client.ObjectKeyFromObject(obj)
   182  			Expect(k8sClient.Delete(ctx, obj)).Should(Succeed())
   183  			Eventually(func(g Gomega) {
   184  				g.Expect(k8sClient.Get(ctx, key, obj)).Should(Satisfy(errors.IsNotFound))
   185  			}, 10*time.Second).Should(Succeed())
   186  		}
   187  	})
   188  
   189  	It("get capability", func() {
   190  		By("ComponentDefinition is in the current namespace")
   191  		_, err := GetCapabilityByName(ctx, c, component1, ns, nil)
   192  		Expect(err).Should(BeNil())
   193  
   194  		By("ComponentDefinition is in the default namespace")
   195  		_, err = GetCapabilityByName(ctx, c, component2, ns, nil)
   196  		Expect(err).Should(BeNil())
   197  
   198  		By("capability cloud not be found")
   199  		_, err = GetCapabilityByName(ctx, c, "a-component-definition-not-existed", ns, nil)
   200  		Expect(err).Should(HaveOccurred())
   201  	})
   202  })
   203  
   204  var _ = Describe("test GetNamespacedCapabilitiesFromCluster", func() {
   205  	var (
   206  		ctx        context.Context
   207  		c          common.Args
   208  		ns         string
   209  		defaultNS  string
   210  		cd1        corev1beta1.ComponentDefinition
   211  		cd2        corev1beta1.ComponentDefinition
   212  		component1 string
   213  		component2 string
   214  	)
   215  	BeforeEach(func() {
   216  		c = common.Args{}
   217  		c.SetClient(k8sClient)
   218  		ctx = context.Background()
   219  		ns = "cluster-test-ns"
   220  		defaultNS = types.DefaultKubeVelaNS
   221  		component1 = "cd1"
   222  		component2 = "cd2"
   223  
   224  		By("create namespace")
   225  		Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: ns}})).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   226  		Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: defaultNS}})).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   227  
   228  		By("create ComponentDefinition")
   229  		data, _ := os.ReadFile("testdata/componentDef.yaml")
   230  		yaml.Unmarshal(data, &cd1)
   231  		yaml.Unmarshal(data, &cd2)
   232  		cd1.Namespace = ns
   233  		cd1.Name = component1
   234  		Expect(k8sClient.Create(ctx, &cd1)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   235  
   236  		cd2.Namespace = defaultNS
   237  		cd2.Name = component2
   238  		Expect(k8sClient.Create(ctx, &cd2)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   239  
   240  	})
   241  
   242  	AfterEach(func() {
   243  		for _, obj := range []client.Object{&cd1, &cd2} {
   244  			key := client.ObjectKeyFromObject(obj)
   245  			Expect(k8sClient.Delete(ctx, obj)).Should(Succeed())
   246  			Eventually(func(g Gomega) {
   247  				g.Expect(k8sClient.Get(ctx, key, obj)).Should(Satisfy(errors.IsNotFound))
   248  			}, 10*time.Second).Should(Succeed())
   249  		}
   250  	})
   251  
   252  	It("get namespaced capabilities", func() {
   253  		By("found all capabilities")
   254  		capabilities, err := GetNamespacedCapabilitiesFromCluster(ctx, ns, c, nil)
   255  		Expect(len(capabilities)).Should(Equal(2))
   256  		Expect(err).Should(BeNil())
   257  
   258  		By("found two capabilities with a bad namespace")
   259  		capabilities, err = GetNamespacedCapabilitiesFromCluster(ctx, "a-bad-ns", c, nil)
   260  		Expect(len(capabilities)).Should(Equal(1))
   261  		Expect(err).Should(BeNil())
   262  	})
   263  })
   264  
   265  var _ = Describe("test GetCapabilityFromDefinitionRevision", func() {
   266  	var (
   267  		ctx context.Context
   268  		c   common.Args
   269  	)
   270  
   271  	BeforeEach(func() {
   272  		c = common.Args{}
   273  		c.SetClient(k8sClient)
   274  		ctx = context.Background()
   275  
   276  		By("create namespace")
   277  		Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "rev-test-custom-ns"}})).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   278  		Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "rev-test-ns"}})).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   279  
   280  		// Load test DefinitionRevisions files into client
   281  		dir := filepath.Join("..", "..", "pkg", "definition", "testdata")
   282  		testFiles, err := os.ReadDir(dir)
   283  		Expect(err).Should(Succeed())
   284  		for _, file := range testFiles {
   285  			if !strings.HasSuffix(file.Name(), ".yaml") {
   286  				continue
   287  			}
   288  			content, err := os.ReadFile(filepath.Join(dir, file.Name()))
   289  			Expect(err).Should(Succeed())
   290  			def := &corev1beta1.DefinitionRevision{}
   291  			err = yaml.Unmarshal(content, def)
   292  			Expect(err).Should(Succeed())
   293  			client, err := c.GetClient()
   294  			Expect(err).Should(Succeed())
   295  			err = client.Create(context.TODO(), def)
   296  			Expect(err).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
   297  		}
   298  	})
   299  
   300  	It("non-existent defrev", func() {
   301  		_, err := GetCapabilityFromDefinitionRevision(ctx, c, nil, "rev-test-custom-ns", "not-a-name", 0)
   302  		Expect(err).ShouldNot(Succeed())
   303  	})
   304  
   305  	It("component type", func() {
   306  		_, err := GetCapabilityFromDefinitionRevision(ctx, c, nil, "rev-test-ns", "webservice", 0)
   307  		Expect(err).Should(Succeed())
   308  	})
   309  
   310  	It("trait type", func() {
   311  		_, err := GetCapabilityFromDefinitionRevision(ctx, c, nil, "rev-test-custom-ns", "affinity", 0)
   312  		Expect(err).Should(Succeed())
   313  	})
   314  })