github.com/oam-dev/kubevela@v1.9.11/references/appfile/app_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 appfile
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  	"sigs.k8s.io/yaml"
    26  
    27  	"github.com/oam-dev/kubevela/apis/types"
    28  	"github.com/oam-dev/kubevela/references/appfile/template"
    29  )
    30  
    31  func TestApplication(t *testing.T) {
    32  	yamlNormal := `name: myapp
    33  services:
    34    frontend:
    35      image: inanimate/echo-server
    36      env:
    37        PORT: 8080
    38      autoscaling:
    39        max: 10
    40        min: 1
    41      rollout:
    42        strategy: canary
    43        step: 5
    44    backend:
    45      type: cloneset
    46      image: "back:v1"
    47  `
    48  	yamlNoService := `name: myapp`
    49  	yamlNoName := `services:
    50    frontend:
    51      image: inanimate/echo-server
    52      env:
    53        PORT: 8080`
    54  	yamlTraitNotMap := `name: myapp
    55  services:
    56    frontend:
    57      image: inanimate/echo-server
    58      env:
    59        PORT: 8080
    60      autoscaling: 10`
    61  
    62  	cases := map[string]struct {
    63  		raw             string
    64  		InValid         bool
    65  		InvalidReason   error
    66  		ExpName         string
    67  		ExpComponents   []string
    68  		WantWorkload    string
    69  		ExpWorkload     map[string]interface{}
    70  		ExpWorkloadType string
    71  		ExpTraits       map[string]map[string]interface{}
    72  	}{
    73  		"normal case backend": {
    74  			raw:           yamlNormal,
    75  			ExpName:       "myapp",
    76  			ExpComponents: []string{"backend", "frontend"},
    77  			WantWorkload:  "backend",
    78  			ExpWorkload: map[string]interface{}{
    79  				"image": "back:v1",
    80  			},
    81  			ExpWorkloadType: "cloneset",
    82  			ExpTraits:       map[string]map[string]interface{}{},
    83  		},
    84  		"normal case frontend": {
    85  			raw:           yamlNormal,
    86  			ExpName:       "myapp",
    87  			ExpComponents: []string{"backend", "frontend"},
    88  			WantWorkload:  "frontend",
    89  			ExpWorkload: map[string]interface{}{
    90  				"image": "inanimate/echo-server",
    91  				"env": map[string]interface{}{
    92  					"PORT": float64(8080),
    93  				},
    94  			},
    95  			ExpWorkloadType: "webservice",
    96  			ExpTraits: map[string]map[string]interface{}{
    97  				"autoscaling": {
    98  					"max": float64(10),
    99  					"min": float64(1),
   100  				},
   101  				"rollout": {
   102  					"strategy": "canary",
   103  					"step":     float64(5),
   104  				},
   105  			},
   106  		},
   107  		"no component": {
   108  			raw:           yamlNoService,
   109  			ExpName:       "myapp",
   110  			InValid:       true,
   111  			InvalidReason: errors.New("at least one service is required"),
   112  		},
   113  		"no name": {
   114  			raw:           yamlNoName,
   115  			ExpName:       "",
   116  			InValid:       true,
   117  			InvalidReason: errors.New("name is required"),
   118  		},
   119  		"trait must be map": {
   120  			raw: yamlTraitNotMap,
   121  			ExpTraits: map[string]map[string]interface{}{
   122  				"autoscaling": {},
   123  			},
   124  			ExpName:       "myapp",
   125  			InValid:       true,
   126  			InvalidReason: fmt.Errorf("trait autoscaling in 'frontend' must be map"),
   127  		},
   128  	}
   129  
   130  	for caseName, c := range cases {
   131  		tm := template.NewFakeTemplateManager()
   132  		for k := range c.ExpTraits {
   133  			tm.Templates[k] = &template.Template{
   134  				Captype: types.TypeTrait,
   135  			}
   136  		}
   137  		app := NewApplication(nil, tm)
   138  		err := yaml.Unmarshal([]byte(c.raw), &app)
   139  		assert.NoError(t, err, caseName)
   140  		err = Validate(app)
   141  		if c.InValid {
   142  			assert.Equal(t, c.InvalidReason, err)
   143  			continue
   144  		}
   145  		assert.Equal(t, c.ExpName, app.Name, caseName)
   146  		workloadType, workload := GetWorkload(app, c.WantWorkload)
   147  		assert.Equal(t, c.ExpWorkload, workload, caseName)
   148  		assert.Equal(t, c.ExpWorkloadType, workloadType, caseName)
   149  		traits, err := GetTraits(app, c.WantWorkload)
   150  		assert.NoError(t, err, caseName)
   151  		assert.Equal(t, c.ExpTraits, traits, caseName)
   152  	}
   153  }