github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/internal/util/cmdutil/cmdutil_test.go (about)

     1  // Copyright 2021 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package cmdutil
    16  
    17  import (
    18  	"bytes"
    19  	"path/filepath"
    20  	"sort"
    21  	"testing"
    22  
    23  	"github.com/GoogleContainerTools/kpt/internal/util/function"
    24  	"github.com/stretchr/testify/assert"
    25  	"sigs.k8s.io/kustomize/kyaml/kio"
    26  )
    27  
    28  func TestWriteFnOutput(t *testing.T) {
    29  	var tests = []struct {
    30  		name           string
    31  		dest           string
    32  		content        string
    33  		fromStdin      bool
    34  		writer         bytes.Buffer
    35  		expectedStdout string
    36  		expectedPkg    string
    37  	}{
    38  		{
    39  			name:   "wrapped output to stdout",
    40  			dest:   "stdout",
    41  			writer: bytes.Buffer{},
    42  			content: `apiVersion: config.kubernetes.io/v1
    43  kind: ResourceList
    44  items:
    45    - apiVersion: apps/v1
    46      kind: Deployment
    47      metadata:
    48        name: nginx-deployment
    49        annotations:
    50          internal.config.kubernetes.io/index: '0'
    51          internal.config.kubernetes.io/path: 'deployment.yaml'
    52    - apiVersion: v1
    53      kind: Service
    54      metadata:
    55        name: nginx-svc
    56        annotations:
    57          internal.config.kubernetes.io/index: '0'
    58          internal.config.kubernetes.io/path: 'svc.yaml'
    59  `,
    60  			expectedStdout: `apiVersion: config.kubernetes.io/v1
    61  kind: ResourceList
    62  items:
    63    - apiVersion: apps/v1
    64      kind: Deployment
    65      metadata:
    66        name: nginx-deployment
    67        annotations:
    68          internal.config.kubernetes.io/index: '0'
    69          internal.config.kubernetes.io/path: 'deployment.yaml'
    70    - apiVersion: v1
    71      kind: Service
    72      metadata:
    73        name: nginx-svc
    74        annotations:
    75          internal.config.kubernetes.io/index: '0'
    76          internal.config.kubernetes.io/path: 'svc.yaml'
    77  `,
    78  		},
    79  		{
    80  			name:   "unwrapped output to stdout",
    81  			dest:   "unwrap",
    82  			writer: bytes.Buffer{},
    83  			content: `apiVersion: config.kubernetes.io/v1
    84  kind: ResourceList
    85  items:
    86    - apiVersion: apps/v1
    87      kind: Deployment
    88      metadata:
    89        name: nginx-deployment
    90        annotations:
    91          internal.config.kubernetes.io/index: '0'
    92          internal.config.kubernetes.io/path: 'deployment.yaml'
    93    - apiVersion: v1
    94      kind: Service
    95      metadata:
    96        name: nginx-svc
    97        annotations:
    98          internal.config.kubernetes.io/index: '0'
    99          internal.config.kubernetes.io/path: 'svc.yaml'
   100  `,
   101  			expectedStdout: `apiVersion: apps/v1
   102  kind: Deployment
   103  metadata:
   104    name: nginx-deployment
   105  ---
   106  apiVersion: v1
   107  kind: Service
   108  metadata:
   109    name: nginx-svc
   110  `,
   111  		},
   112  		{
   113  			name: "output to another directory",
   114  			dest: "foo/bar",
   115  			content: `apiVersion: config.kubernetes.io/v1
   116  kind: ResourceList
   117  items:
   118    - apiVersion: apps/v1
   119      kind: Deployment
   120      metadata:
   121        name: nginx-deployment
   122        annotations:
   123          internal.config.kubernetes.io/index: '0'
   124          internal.config.kubernetes.io/path: 'deployment.yaml'
   125    - apiVersion: v1
   126      kind: Service
   127      metadata:
   128        name: nginx-svc
   129        annotations:
   130          internal.config.kubernetes.io/index: '0'
   131          internal.config.kubernetes.io/path: 'svc.yaml'
   132  `,
   133  			expectedPkg: `apiVersion: apps/v1
   134  kind: Deployment
   135  metadata:
   136    name: nginx-deployment
   137    annotations:
   138      config.kubernetes.io/path: 'foo/bar/deployment.yaml'
   139      internal.config.kubernetes.io/path: 'foo/bar/deployment.yaml'
   140  ---
   141  apiVersion: v1
   142  kind: Service
   143  metadata:
   144    name: nginx-svc
   145    annotations:
   146      config.kubernetes.io/path: 'foo/bar/svc.yaml'
   147      internal.config.kubernetes.io/path: 'foo/bar/svc.yaml'
   148  `,
   149  		},
   150  		{
   151  			name:      "wrapped output to stdout by default if input is from stdin",
   152  			fromStdin: true,
   153  			writer:    bytes.Buffer{},
   154  			content: `apiVersion: config.kubernetes.io/v1
   155  kind: ResourceList
   156  items:
   157    - apiVersion: apps/v1
   158      kind: Deployment
   159      metadata:
   160        name: nginx-deployment
   161        annotations:
   162          internal.config.kubernetes.io/index: '0'
   163          internal.config.kubernetes.io/path: 'deployment.yaml'
   164    - apiVersion: v1
   165      kind: Service
   166      metadata:
   167        name: nginx-svc
   168        annotations:
   169          internal.config.kubernetes.io/index: '0'
   170          internal.config.kubernetes.io/path: 'svc.yaml'
   171  `,
   172  			expectedStdout: `apiVersion: config.kubernetes.io/v1
   173  kind: ResourceList
   174  items:
   175    - apiVersion: apps/v1
   176      kind: Deployment
   177      metadata:
   178        name: nginx-deployment
   179        annotations:
   180          internal.config.kubernetes.io/index: '0'
   181          internal.config.kubernetes.io/path: 'deployment.yaml'
   182    - apiVersion: v1
   183      kind: Service
   184      metadata:
   185        name: nginx-svc
   186        annotations:
   187          internal.config.kubernetes.io/index: '0'
   188          internal.config.kubernetes.io/path: 'svc.yaml'
   189  `,
   190  		},
   191  		{
   192  			name:      "unwrapped output to stdout for input from stdin",
   193  			fromStdin: true,
   194  			dest:      "unwrap",
   195  			writer:    bytes.Buffer{},
   196  			content: `apiVersion: config.kubernetes.io/v1
   197  kind: ResourceList
   198  items:
   199    - apiVersion: apps/v1
   200      kind: Deployment
   201      metadata:
   202        name: nginx-deployment
   203        annotations:
   204          internal.config.kubernetes.io/index: '0'
   205          internal.config.kubernetes.io/path: 'deployment.yaml'
   206    - apiVersion: v1
   207      kind: Service
   208      metadata:
   209        name: nginx-svc
   210        annotations:
   211          internal.config.kubernetes.io/index: '0'
   212          internal.config.kubernetes.io/path: 'svc.yaml'
   213  `,
   214  			expectedStdout: `apiVersion: apps/v1
   215  kind: Deployment
   216  metadata:
   217    name: nginx-deployment
   218  ---
   219  apiVersion: v1
   220  kind: Service
   221  metadata:
   222    name: nginx-svc
   223  `,
   224  		},
   225  		{
   226  			name:      "output to directory for input from stdin",
   227  			fromStdin: true,
   228  			dest:      "foo/bar",
   229  			content: `apiVersion: config.kubernetes.io/v1
   230  kind: ResourceList
   231  items:
   232    - apiVersion: apps/v1
   233      kind: Deployment
   234      metadata:
   235        name: nginx-deployment
   236        annotations:
   237          internal.config.kubernetes.io/index: '0'
   238          internal.config.kubernetes.io/path: 'deployment.yaml'
   239    - apiVersion: v1
   240      kind: Service
   241      metadata:
   242        name: nginx-svc
   243        annotations:
   244          internal.config.kubernetes.io/index: '0'
   245          internal.config.kubernetes.io/path: 'svc.yaml'
   246  `,
   247  			expectedPkg: `apiVersion: apps/v1
   248  kind: Deployment
   249  metadata:
   250    name: nginx-deployment
   251    annotations:
   252      config.kubernetes.io/path: 'foo/bar/deployment.yaml'
   253      internal.config.kubernetes.io/path: 'foo/bar/deployment.yaml'
   254  ---
   255  apiVersion: v1
   256  kind: Service
   257  metadata:
   258    name: nginx-svc
   259    annotations:
   260      config.kubernetes.io/path: 'foo/bar/svc.yaml'
   261      internal.config.kubernetes.io/path: 'foo/bar/svc.yaml'
   262  `,
   263  		},
   264  	}
   265  	for i := range tests {
   266  		test := tests[i]
   267  		t.Run(test.name, func(t *testing.T) {
   268  			baseDir := t.TempDir()
   269  
   270  			if test.dest != "" && test.dest != Stdout && test.dest != Unwrap {
   271  				test.dest = filepath.Join(baseDir, test.dest)
   272  			}
   273  
   274  			// this method should create a directory and write the output if the dest is a directory path
   275  			err := WriteFnOutput(test.dest, test.content, test.fromStdin, &test.writer)
   276  			if !assert.NoError(t, err) {
   277  				t.FailNow()
   278  			}
   279  
   280  			actualStdout := test.writer.String()
   281  			if !assert.Equal(t, test.expectedStdout, actualStdout) {
   282  				t.FailNow()
   283  			}
   284  
   285  			// read the resources from output dir
   286  			in := &kio.LocalPackageReader{
   287  				PackagePath:       baseDir,
   288  				PreserveSeqIndent: true,
   289  				WrapBareSeqNode:   true,
   290  			}
   291  			out := &bytes.Buffer{}
   292  
   293  			err = kio.Pipeline{
   294  				Inputs:  []kio.Reader{in},
   295  				Outputs: []kio.Writer{&kio.ByteWriter{Writer: out}},
   296  			}.Execute()
   297  
   298  			if !assert.NoError(t, err) {
   299  				t.FailNow()
   300  			}
   301  
   302  			// verify that the resources in the output dir are as expected
   303  			if !assert.Equal(t, test.expectedPkg, out.String()) {
   304  				t.FailNow()
   305  			}
   306  		})
   307  	}
   308  }
   309  
   310  func TestListImages(t *testing.T) {
   311  	functions := parseFunctions(`{
   312    "apply-setters": {
   313      "v0.1": {
   314        "LatestPatchVersion": "v0.1.1",
   315        "Examples": {
   316          "apply-setters-simple": {
   317            "LocalExamplePath": "/apply-setters/v0.1/apply-setters-simple",
   318            "RemoteExamplePath": "https://github.com/GoogleContainerTools/kpt-functions-catalog/tree/apply-setters/v0.1/examples/apply-setters-simple",
   319            "RemoteSourcePath": "https://github.com/GoogleContainerTools/kpt-functions-catalog/tree/apply-setters/v0.1/functions/go/apply-setters"
   320          }
   321        }
   322      }
   323    },
   324    "gatekeeper": {
   325      "v0.1": {
   326        "LatestPatchVersion": "v0.1.3",
   327        "Examples": {
   328          "gatekeeper-warning-only": {
   329            "LocalExamplePath": "/gatekeeper/v0.1/gatekeeper-warning-only",
   330            "RemoteExamplePath": "https://github.com/GoogleContainerTools/kpt-functions-catalog/tree/gatekeeper/v0.1/examples/gatekeeper-warning-only",
   331            "RemoteSourcePath": "https://github.com/GoogleContainerTools/kpt-functions-catalog/tree/gatekeeper/v0.1/functions/go/gatekeeper"
   332          }
   333        }
   334      },
   335      "v0.2": {
   336        "LatestPatchVersion": "v0.2.1",
   337        "Examples": {
   338          "gatekeeper-warning-only": {
   339            "LocalExamplePath": "/gatekeeper/v0.2/gatekeeper-warning-only",
   340            "RemoteExamplePath": "https://github.com/GoogleContainerTools/kpt-functions-catalog/tree/gatekeeper/v0.2/examples/gatekeeper-warning-only",
   341            "RemoteSourcePath": "https://github.com/GoogleContainerTools/kpt-functions-catalog/tree/gatekeeper/v0.2/functions/go/gatekeeper"
   342          }
   343        }
   344      }
   345    }
   346  }`)
   347  	result := function.GetNames(functions)
   348  	sort.Strings(result)
   349  	assert.Equal(t, []string{"apply-setters:v0.1.1", "gatekeeper:v0.2.1"}, result)
   350  }