github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/thirdparty/cmdconfig/commands/cmdsource/cmdsource_test.go (about)

     1  // Copyright 2019 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package cmdsource
     5  
     6  import (
     7  	"bytes"
     8  	"os"
     9  	"path/filepath"
    10  	"testing"
    11  
    12  	"github.com/GoogleContainerTools/kpt/internal/printer/fake"
    13  	"github.com/GoogleContainerTools/kpt/internal/testutil"
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  func TestSourceCommand(t *testing.T) {
    18  	d, err := os.MkdirTemp("", "source-test")
    19  	if !assert.NoError(t, err) {
    20  		return
    21  	}
    22  	defer os.RemoveAll(d)
    23  
    24  	err = os.WriteFile(filepath.Join(d, "f1.yaml"), []byte(`
    25  kind: Deployment
    26  metadata:
    27    labels:
    28      app: nginx2
    29    name: foo
    30    annotations:
    31      app: nginx2
    32  spec:
    33    replicas: 1
    34  ---
    35  kind: Service
    36  metadata:
    37    name: foo
    38    annotations:
    39      app: nginx
    40  spec:
    41    selector:
    42      app: nginx
    43  `), 0600)
    44  	if !assert.NoError(t, err) {
    45  		return
    46  	}
    47  	err = os.WriteFile(filepath.Join(d, "f2.yaml"), []byte(`
    48  apiVersion: v1
    49  kind: Abstraction
    50  metadata:
    51    name: foo
    52    annotations:
    53      config.kubernetes.io/function: |
    54        container:
    55          image: gcr.io/example/reconciler:v1
    56      config.kubernetes.io/local-config: "true"
    57  spec:
    58    replicas: 3
    59  ---
    60  apiVersion: apps/v1
    61  kind: Deployment
    62  metadata:
    63    labels:
    64      app: nginx
    65    name: bar
    66    annotations:
    67      app: nginx
    68  spec:
    69    replicas: 3
    70  `), 0600)
    71  	if !assert.NoError(t, err) {
    72  		return
    73  	}
    74  
    75  	// fmt the files
    76  	b := &bytes.Buffer{}
    77  	r := GetSourceRunner(fake.CtxWithPrinter(b, nil), "")
    78  	r.Command.SetArgs([]string{d})
    79  	if !assert.NoError(t, r.Command.Execute()) {
    80  		return
    81  	}
    82  
    83  	if !assert.Equal(t, `apiVersion: config.kubernetes.io/v1
    84  kind: ResourceList
    85  items:
    86  - kind: Deployment
    87    metadata:
    88      labels:
    89        app: nginx2
    90      name: foo
    91      annotations:
    92        app: nginx2
    93        config.kubernetes.io/index: '0'
    94        config.kubernetes.io/path: 'f1.yaml'
    95        internal.config.kubernetes.io/index: '0'
    96        internal.config.kubernetes.io/path: 'f1.yaml'
    97        internal.config.kubernetes.io/seqindent: 'compact'
    98    spec:
    99      replicas: 1
   100  - kind: Service
   101    metadata:
   102      name: foo
   103      annotations:
   104        app: nginx
   105        config.kubernetes.io/index: '1'
   106        config.kubernetes.io/path: 'f1.yaml'
   107        internal.config.kubernetes.io/index: '1'
   108        internal.config.kubernetes.io/path: 'f1.yaml'
   109        internal.config.kubernetes.io/seqindent: 'compact'
   110    spec:
   111      selector:
   112        app: nginx
   113  - apiVersion: v1
   114    kind: Abstraction
   115    metadata:
   116      name: foo
   117      annotations:
   118        config.kubernetes.io/function: |
   119          container:
   120            image: gcr.io/example/reconciler:v1
   121        config.kubernetes.io/local-config: "true"
   122        config.kubernetes.io/index: '0'
   123        config.kubernetes.io/path: 'f2.yaml'
   124        internal.config.kubernetes.io/index: '0'
   125        internal.config.kubernetes.io/path: 'f2.yaml'
   126        internal.config.kubernetes.io/seqindent: 'compact'
   127    spec:
   128      replicas: 3
   129  - apiVersion: apps/v1
   130    kind: Deployment
   131    metadata:
   132      labels:
   133        app: nginx
   134      name: bar
   135      annotations:
   136        app: nginx
   137        config.kubernetes.io/index: '1'
   138        config.kubernetes.io/path: 'f2.yaml'
   139        internal.config.kubernetes.io/index: '1'
   140        internal.config.kubernetes.io/path: 'f2.yaml'
   141        internal.config.kubernetes.io/seqindent: 'compact'
   142    spec:
   143      replicas: 3
   144  `, b.String()) {
   145  		return
   146  	}
   147  }
   148  
   149  func TestSourceCommand_Unwrap(t *testing.T) {
   150  	d, err := os.MkdirTemp("", "source-test")
   151  	if !assert.NoError(t, err) {
   152  		return
   153  	}
   154  	defer os.RemoveAll(d)
   155  
   156  	err = os.WriteFile(filepath.Join(d, "f1.yaml"), []byte(`
   157  kind: Deployment
   158  metadata:
   159    labels:
   160      app: nginx2
   161    name: foo
   162    annotations:
   163      app: nginx2
   164  spec:
   165    replicas: 1
   166  ---
   167  kind: Service
   168  metadata:
   169    name: foo
   170    annotations:
   171      app: nginx
   172  spec:
   173    selector:
   174      app: nginx
   175  `), 0600)
   176  	if !assert.NoError(t, err) {
   177  		return
   178  	}
   179  	err = os.WriteFile(filepath.Join(d, "f2.yaml"), []byte(`
   180  apiVersion: v1
   181  kind: Abstraction
   182  metadata:
   183    name: foo
   184  spec:
   185    replicas: 3
   186  ---
   187  apiVersion: apps/v1
   188  kind: Deployment
   189  metadata:
   190    labels:
   191      app: nginx
   192    name: bar
   193    annotations:
   194      app: nginx
   195  spec:
   196    replicas: 3
   197  `), 0600)
   198  	if !assert.NoError(t, err) {
   199  		return
   200  	}
   201  
   202  	// fmt the files
   203  	b := &bytes.Buffer{}
   204  	r := GetSourceRunner(fake.CtxWithPrinter(b, nil), "")
   205  	r.Command.SetArgs([]string{d, "-o", "unwrap"})
   206  	if !assert.NoError(t, r.Command.Execute()) {
   207  		return
   208  	}
   209  
   210  	if !assert.Equal(t, `kind: Deployment
   211  metadata:
   212    labels:
   213      app: nginx2
   214    name: foo
   215    annotations:
   216      app: nginx2
   217  spec:
   218    replicas: 1
   219  ---
   220  kind: Service
   221  metadata:
   222    name: foo
   223    annotations:
   224      app: nginx
   225  spec:
   226    selector:
   227      app: nginx
   228  ---
   229  apiVersion: v1
   230  kind: Abstraction
   231  metadata:
   232    name: foo
   233  spec:
   234    replicas: 3
   235  ---
   236  apiVersion: apps/v1
   237  kind: Deployment
   238  metadata:
   239    labels:
   240      app: nginx
   241    name: bar
   242    annotations:
   243      app: nginx
   244  spec:
   245    replicas: 3
   246  `, b.String()) {
   247  		return
   248  	}
   249  }
   250  
   251  func TestSourceCommand_InvalidInput(t *testing.T) {
   252  	d, err := os.MkdirTemp("", "source-test")
   253  	if !assert.NoError(t, err) {
   254  		return
   255  	}
   256  	defer os.RemoveAll(d)
   257  
   258  	err = os.WriteFile(filepath.Join(d, "f1.yaml"), []byte(`
   259  kind: Deployment
   260  metadata:
   261    labels:
   262      app: nginx2
   263    name: foo
   264    annotations:
   265      app: nginx2
   266  spec:
   267    replicas: 1
   268  `), 0600)
   269  	if !assert.NoError(t, err) {
   270  		return
   271  	}
   272  
   273  	r := GetSourceRunner(fake.CtxWithDefaultPrinter(), "")
   274  	r.Command.SetArgs([]string{d, "-o", "foo/bar"})
   275  	err = r.Command.Execute()
   276  	if !assert.Error(t, err) {
   277  		t.FailNow()
   278  	}
   279  
   280  	if !assert.Equal(t, `invalid input for --output flag "foo/bar", must be "stdout" or "unwrap"`, err.Error()) {
   281  		t.FailNow()
   282  	}
   283  }
   284  
   285  func TestSourceCommand_DefaultDir(t *testing.T) {
   286  	d, err := os.MkdirTemp("", "source-test")
   287  	if !assert.NoError(t, err) {
   288  		return
   289  	}
   290  	defer os.RemoveAll(d)
   291  
   292  	err = os.WriteFile(filepath.Join(d, "f1.yaml"), []byte(`
   293  kind: Deployment
   294  metadata:
   295    labels:
   296      app: nginx2
   297    name: foo
   298    annotations:
   299      app: nginx2
   300  spec:
   301    replicas: 1
   302  ---
   303  kind: Service
   304  metadata:
   305    name: foo
   306    annotations:
   307      app: nginx
   308  spec:
   309    selector:
   310      app: nginx
   311  `), 0600)
   312  	if !assert.NoError(t, err) {
   313  		return
   314  	}
   315  	err = os.WriteFile(filepath.Join(d, "f2.yaml"), []byte(`
   316  apiVersion: v1
   317  kind: Abstraction
   318  metadata:
   319    name: foo
   320    annotations:
   321      config.kubernetes.io/function: |
   322        container:
   323          image: gcr.io/example/reconciler:v1
   324      config.kubernetes.io/local-config: "true"
   325  spec:
   326    replicas: 3
   327  ---
   328  apiVersion: apps/v1
   329  kind: Deployment
   330  metadata:
   331    labels:
   332      app: nginx
   333    name: bar
   334    annotations:
   335      app: nginx
   336  spec:
   337    replicas: 3
   338  `), 0600)
   339  	if !assert.NoError(t, err) {
   340  		return
   341  	}
   342  	revert := testutil.Chdir(t, d)
   343  	defer revert()
   344  
   345  	// fmt the files
   346  	b := &bytes.Buffer{}
   347  	r := GetSourceRunner(fake.CtxWithPrinter(b, nil), "")
   348  	r.Command.SetArgs([]string{})
   349  
   350  	if !assert.NoError(t, r.Command.Execute()) {
   351  		return
   352  	}
   353  
   354  	if !assert.Equal(t, `apiVersion: config.kubernetes.io/v1
   355  kind: ResourceList
   356  items:
   357  - kind: Deployment
   358    metadata:
   359      labels:
   360        app: nginx2
   361      name: foo
   362      annotations:
   363        app: nginx2
   364        config.kubernetes.io/index: '0'
   365        config.kubernetes.io/path: 'f1.yaml'
   366        internal.config.kubernetes.io/index: '0'
   367        internal.config.kubernetes.io/path: 'f1.yaml'
   368        internal.config.kubernetes.io/seqindent: 'compact'
   369    spec:
   370      replicas: 1
   371  - kind: Service
   372    metadata:
   373      name: foo
   374      annotations:
   375        app: nginx
   376        config.kubernetes.io/index: '1'
   377        config.kubernetes.io/path: 'f1.yaml'
   378        internal.config.kubernetes.io/index: '1'
   379        internal.config.kubernetes.io/path: 'f1.yaml'
   380        internal.config.kubernetes.io/seqindent: 'compact'
   381    spec:
   382      selector:
   383        app: nginx
   384  - apiVersion: v1
   385    kind: Abstraction
   386    metadata:
   387      name: foo
   388      annotations:
   389        config.kubernetes.io/function: |
   390          container:
   391            image: gcr.io/example/reconciler:v1
   392        config.kubernetes.io/local-config: "true"
   393        config.kubernetes.io/index: '0'
   394        config.kubernetes.io/path: 'f2.yaml'
   395        internal.config.kubernetes.io/index: '0'
   396        internal.config.kubernetes.io/path: 'f2.yaml'
   397        internal.config.kubernetes.io/seqindent: 'compact'
   398    spec:
   399      replicas: 3
   400  - apiVersion: apps/v1
   401    kind: Deployment
   402    metadata:
   403      labels:
   404        app: nginx
   405      name: bar
   406      annotations:
   407        app: nginx
   408        config.kubernetes.io/index: '1'
   409        config.kubernetes.io/path: 'f2.yaml'
   410        internal.config.kubernetes.io/index: '1'
   411        internal.config.kubernetes.io/path: 'f2.yaml'
   412        internal.config.kubernetes.io/seqindent: 'compact'
   413    spec:
   414      replicas: 3
   415  `, b.String()) {
   416  		return
   417  	}
   418  }
   419  
   420  func TestSourceCommandJSON(t *testing.T) {
   421  	d, err := os.MkdirTemp("", "source-test")
   422  	if !assert.NoError(t, err) {
   423  		return
   424  	}
   425  	defer os.RemoveAll(d)
   426  
   427  	err = os.WriteFile(filepath.Join(d, "f1.json"), []byte(`
   428  {
   429    "kind": "Deployment",
   430    "metadata": {
   431      "labels": {
   432        "app": "nginx2"
   433      },
   434      "name": "foo",
   435      "annotations": {
   436        "app": "nginx2"
   437      }
   438    },
   439    "spec": {
   440      "replicas": 1
   441    }
   442  }
   443  `), 0600)
   444  	if !assert.NoError(t, err) {
   445  		return
   446  	}
   447  	err = os.WriteFile(filepath.Join(d, "f2.json"), []byte(`
   448  {
   449    "apiVersion": "v1",
   450    "kind": "Abstraction",
   451    "metadata": {
   452      "name": "foo",
   453      "annotations": {
   454        "config.kubernetes.io/function": "container:\n  image: gcr.io/example/reconciler:v1\n",
   455        "config.kubernetes.io/local-config": "true"
   456      }
   457    },
   458    "spec": {
   459      "replicas": 3
   460    }
   461  }
   462  `), 0600)
   463  	if !assert.NoError(t, err) {
   464  		return
   465  	}
   466  
   467  	// fmt the files
   468  	b := &bytes.Buffer{}
   469  	r := GetSourceRunner(fake.CtxWithPrinter(b, nil), "")
   470  	r.Command.SetArgs([]string{d})
   471  
   472  	if !assert.NoError(t, r.Command.Execute()) {
   473  		return
   474  	}
   475  
   476  	//nolint:lll
   477  	expected := `apiVersion: config.kubernetes.io/v1
   478  kind: ResourceList
   479  items:
   480  - {"kind": "Deployment", "metadata": {"labels": {"app": "nginx2"}, "name": "foo", "annotations": {"app": "nginx2", config.kubernetes.io/index: '0', config.kubernetes.io/path: 'f1.json', internal.config.kubernetes.io/index: '0', internal.config.kubernetes.io/path: 'f1.json', internal.config.kubernetes.io/seqindent: 'compact'}}, "spec": {"replicas": 1}}
   481  - {"apiVersion": "v1", "kind": "Abstraction", "metadata": {"name": "foo", "annotations": {"config.kubernetes.io/function": "container:\n  image: gcr.io/example/reconciler:v1\n", "config.kubernetes.io/local-config": "true", config.kubernetes.io/index: '0', config.kubernetes.io/path: 'f2.json', internal.config.kubernetes.io/index: '0', internal.config.kubernetes.io/path: 'f2.json', internal.config.kubernetes.io/seqindent: 'compact'}}, "spec": {"replicas": 3}}
   482  `
   483  
   484  	if !assert.Equal(t, expected, b.String()) {
   485  		return
   486  	}
   487  }
   488  
   489  func TestSourceCommand_Symlink(t *testing.T) {
   490  	d, err := os.MkdirTemp("", "source-test")
   491  	defer os.RemoveAll(d)
   492  	if !assert.NoError(t, err) {
   493  		return
   494  	}
   495  
   496  	defer testutil.Chdir(t, d)()
   497  	err = os.MkdirAll(filepath.Join(d, "foo"), 0700)
   498  	assert.NoError(t, err)
   499  	err = os.Symlink("foo", "foo-link")
   500  	if !assert.NoError(t, err) {
   501  		return
   502  	}
   503  	err = os.WriteFile(filepath.Join(d, "foo", "f1.yaml"), []byte(`
   504  kind: Deployment
   505  metadata:
   506    labels:
   507      app: nginx2
   508    name: foo
   509    annotations:
   510      app: nginx2
   511  spec:
   512    replicas: 1
   513  ---
   514  kind: Service
   515  metadata:
   516    name: foo
   517    annotations:
   518      app: nginx
   519  spec:
   520    selector:
   521      app: nginx
   522  `), 0600)
   523  	if !assert.NoError(t, err) {
   524  		return
   525  	}
   526  	err = os.WriteFile(filepath.Join(d, "foo", "f2.yaml"), []byte(`
   527  apiVersion: v1
   528  kind: Abstraction
   529  metadata:
   530    name: foo
   531    annotations:
   532      config.kubernetes.io/function: |
   533        container:
   534          image: gcr.io/example/reconciler:v1
   535      config.kubernetes.io/local-config: "true"
   536  spec:
   537    replicas: 3
   538  ---
   539  apiVersion: apps/v1
   540  kind: Deployment
   541  metadata:
   542    labels:
   543      app: nginx
   544    name: bar
   545    annotations:
   546      app: nginx
   547  spec:
   548    replicas: 3
   549  `), 0600)
   550  	if !assert.NoError(t, err) {
   551  		return
   552  	}
   553  
   554  	// fmt the files
   555  	b := &bytes.Buffer{}
   556  	stderr := &bytes.Buffer{}
   557  	r := GetSourceRunner(fake.CtxWithPrinter(b, stderr), "")
   558  	r.Command.SetArgs([]string{"foo-link"})
   559  	if !assert.NoError(t, r.Command.Execute()) {
   560  		return
   561  	}
   562  
   563  	if !assert.Equal(t, `apiVersion: config.kubernetes.io/v1
   564  kind: ResourceList
   565  items:
   566  - kind: Deployment
   567    metadata:
   568      labels:
   569        app: nginx2
   570      name: foo
   571      annotations:
   572        app: nginx2
   573        config.kubernetes.io/index: '0'
   574        config.kubernetes.io/path: 'f1.yaml'
   575        internal.config.kubernetes.io/index: '0'
   576        internal.config.kubernetes.io/path: 'f1.yaml'
   577        internal.config.kubernetes.io/seqindent: 'compact'
   578    spec:
   579      replicas: 1
   580  - kind: Service
   581    metadata:
   582      name: foo
   583      annotations:
   584        app: nginx
   585        config.kubernetes.io/index: '1'
   586        config.kubernetes.io/path: 'f1.yaml'
   587        internal.config.kubernetes.io/index: '1'
   588        internal.config.kubernetes.io/path: 'f1.yaml'
   589        internal.config.kubernetes.io/seqindent: 'compact'
   590    spec:
   591      selector:
   592        app: nginx
   593  - apiVersion: v1
   594    kind: Abstraction
   595    metadata:
   596      name: foo
   597      annotations:
   598        config.kubernetes.io/function: |
   599          container:
   600            image: gcr.io/example/reconciler:v1
   601        config.kubernetes.io/local-config: "true"
   602        config.kubernetes.io/index: '0'
   603        config.kubernetes.io/path: 'f2.yaml'
   604        internal.config.kubernetes.io/index: '0'
   605        internal.config.kubernetes.io/path: 'f2.yaml'
   606        internal.config.kubernetes.io/seqindent: 'compact'
   607    spec:
   608      replicas: 3
   609  - apiVersion: apps/v1
   610    kind: Deployment
   611    metadata:
   612      labels:
   613        app: nginx
   614      name: bar
   615      annotations:
   616        app: nginx
   617        config.kubernetes.io/index: '1'
   618        config.kubernetes.io/path: 'f2.yaml'
   619        internal.config.kubernetes.io/index: '1'
   620        internal.config.kubernetes.io/path: 'f2.yaml'
   621        internal.config.kubernetes.io/seqindent: 'compact'
   622    spec:
   623      replicas: 3
   624  `, b.String()) {
   625  		return
   626  	}
   627  	assert.Contains(t, stderr.String(), "please note that the symlinks within the package are ignored")
   628  }