github.com/tabboud/distgo@v1.18.0/integration_test/integration_test.go (about)

     1  // Copyright 2016 Palantir Technologies, Inc.
     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 integration_test
    16  
    17  import (
    18  	"fmt"
    19  	"io/ioutil"
    20  	"os"
    21  	"os/exec"
    22  	"path"
    23  	"strings"
    24  	"testing"
    25  
    26  	"github.com/nmiyake/pkg/dirs"
    27  	"github.com/nmiyake/pkg/gofiles"
    28  	"github.com/palantir/godel/framework/pluginapitester"
    29  	"github.com/palantir/godel/pkg/products/v2/products"
    30  	"github.com/stretchr/testify/assert"
    31  	"github.com/stretchr/testify/require"
    32  )
    33  
    34  func TestRun(t *testing.T) {
    35  	cli, err := products.Bin("dist-plugin")
    36  	require.NoError(t, err)
    37  
    38  	tmpDir, cleanup, err := dirs.TempDir(".", "")
    39  	require.NoError(t, err)
    40  	defer cleanup()
    41  	err = ioutil.WriteFile(path.Join(tmpDir, ".gitignore"), []byte(`*
    42  */
    43  `), 0644)
    44  	require.NoError(t, err)
    45  
    46  	wd, err := os.Getwd()
    47  	require.NoError(t, err)
    48  
    49  	for i, tc := range []struct {
    50  		name          string
    51  		filesToCreate []gofiles.GoFileSpec
    52  		config        string
    53  		args          []string
    54  		wantStdout    string
    55  	}{
    56  		{
    57  			name: "Run runs program",
    58  			filesToCreate: []gofiles.GoFileSpec{
    59  				{
    60  					RelPath: "main.go",
    61  					Src: `package main
    62  
    63  import "fmt"
    64  
    65  func main() {
    66  	fmt.Println("Hello, world!")
    67  }
    68  `,
    69  				},
    70  			},
    71  			config: `
    72  products:
    73    hello:
    74      build:
    75        main-pkg: .
    76  `,
    77  			args: []string{
    78  				"hello",
    79  			},
    80  			wantStdout: "Hello, world!\n",
    81  		},
    82  		{
    83  			name: "Run uses trailing arguments",
    84  			filesToCreate: []gofiles.GoFileSpec{
    85  				{
    86  					RelPath: "main.go",
    87  					Src: `package main
    88  
    89  import (
    90  	"fmt"
    91  	"os"
    92  )
    93  
    94  func main() {
    95  	fmt.Println(os.Args[1:])
    96  }
    97  `,
    98  				},
    99  			},
   100  			config: `
   101  products:
   102    hello:
   103      build:
   104        main-pkg: .
   105  `,
   106  			args: []string{
   107  				"hello",
   108  				"arg1",
   109  				"arg2",
   110  				"arg3",
   111  			},
   112  			wantStdout: "[arg1 arg2 arg3]\n",
   113  		},
   114  		{
   115  			name: "Run uses trailing arguments and supports flags",
   116  			filesToCreate: []gofiles.GoFileSpec{
   117  				{
   118  					RelPath: "main.go",
   119  					Src: `package main
   120  
   121  import (
   122  	"fmt"
   123  	"os"
   124  )
   125  
   126  func main() {
   127  	fmt.Println(os.Args[1:])
   128  }
   129  `,
   130  				},
   131  			},
   132  			config: `
   133  products:
   134    hello:
   135      build:
   136        main-pkg: .
   137  `,
   138  			args: []string{
   139  				"hello",
   140  				"--",
   141  				"--foo-arg",
   142  				"flag:",
   143  				"arg3",
   144  			},
   145  			wantStdout: "[--foo-arg flag: arg3]\n",
   146  		},
   147  	} {
   148  		projectDir, err := ioutil.TempDir(tmpDir, "")
   149  		require.NoError(t, err)
   150  
   151  		_, err = gofiles.Write(projectDir, tc.filesToCreate)
   152  		require.NoError(t, err, "Case %d", i)
   153  
   154  		configFile := path.Join(projectDir, "config.yml")
   155  		err = ioutil.WriteFile(configFile, []byte(tc.config), 0644)
   156  		require.NoError(t, err)
   157  
   158  		var output []byte
   159  		func() {
   160  			err := os.Chdir(projectDir)
   161  			defer func() {
   162  				err := os.Chdir(wd)
   163  				require.NoError(t, err)
   164  			}()
   165  			require.NoError(t, err)
   166  
   167  			args := []string{"--config", "config.yml", "run"}
   168  			args = append(args, tc.args...)
   169  			cmd := exec.Command(cli, args...)
   170  			output, err = cmd.CombinedOutput()
   171  			require.NoError(t, err, "Case %d: %s\nOutput: %s", i, tc.name, string(output))
   172  		}()
   173  
   174  		content := string(output)[strings.Index(string(output), "\n")+1:]
   175  		assert.Equal(t, tc.wantStdout, content, "Case %d: %s", i, tc.name)
   176  	}
   177  }
   178  
   179  func TestRunWithStdin(t *testing.T) {
   180  	cli, err := products.Bin("dist-plugin")
   181  	require.NoError(t, err)
   182  
   183  	wd, err := os.Getwd()
   184  	require.NoError(t, err)
   185  
   186  	tmpDir, cleanup, err := dirs.TempDir(".", "")
   187  	require.NoError(t, err)
   188  	defer cleanup()
   189  	err = ioutil.WriteFile(path.Join(tmpDir, ".gitignore"), []byte(`*
   190  */
   191  `), 0644)
   192  	require.NoError(t, err)
   193  
   194  	projectDir, err := ioutil.TempDir(tmpDir, "")
   195  	require.NoError(t, err)
   196  
   197  	filesToCreate := []gofiles.GoFileSpec{
   198  		{
   199  			RelPath: "main.go",
   200  			Src: `package main
   201  
   202  import (
   203  	"bufio"
   204  	"fmt"
   205  	"os"
   206  )
   207  
   208  func main() {
   209  	reader := bufio.NewReader(os.Stdin)
   210  	text, _ := reader.ReadString('\n')
   211  	fmt.Printf("read: %q", text)
   212  }
   213  `,
   214  		},
   215  	}
   216  	config := `
   217  products:
   218    hello:
   219      build:
   220        main-pkg: .
   221  `
   222  	runArgs := []string{
   223  		"hello",
   224  	}
   225  
   226  	stdInContent := "output passed to stdin\n"
   227  
   228  	_, err = gofiles.Write(projectDir, filesToCreate)
   229  	require.NoError(t, err)
   230  
   231  	configFile := path.Join(projectDir, "config.yml")
   232  	err = ioutil.WriteFile(configFile, []byte(config), 0644)
   233  	require.NoError(t, err)
   234  
   235  	var output []byte
   236  	func() {
   237  		err := os.Chdir(projectDir)
   238  		defer func() {
   239  			err := os.Chdir(wd)
   240  			require.NoError(t, err)
   241  		}()
   242  		require.NoError(t, err)
   243  
   244  		args := []string{"--config", "config.yml", "run"}
   245  		args = append(args, runArgs...)
   246  		cmd := exec.Command(cli, args...)
   247  
   248  		stdinPipe, err := cmd.StdinPipe()
   249  		require.NoError(t, err)
   250  		_, err = stdinPipe.Write([]byte(stdInContent))
   251  		require.NoError(t, err)
   252  
   253  		output, err = cmd.CombinedOutput()
   254  		require.NoError(t, err, "Output: %s", string(output))
   255  	}()
   256  
   257  	content := string(output)[strings.Index(string(output), "\n")+1:]
   258  	assert.Equal(t, fmt.Sprintf("read: %q", stdInContent), content)
   259  }
   260  
   261  func TestUpgradeConfig(t *testing.T) {
   262  	pluginPath, err := products.Bin("dist-plugin")
   263  	require.NoError(t, err)
   264  	pluginProvider := pluginapitester.NewPluginProvider(pluginPath)
   265  
   266  	pluginapitester.RunUpgradeConfigTest(t,
   267  		pluginProvider,
   268  		nil,
   269  		[]pluginapitester.UpgradeConfigTestCase{
   270  			{
   271  				Name: "legacy configuration is upgraded",
   272  				ConfigFiles: map[string]string{
   273  					"godel/config/dist.yml": `
   274  products:
   275    foo:
   276      build:
   277        main-pkg: ./foo/main/foo
   278        output-dir: foo/build/bin
   279        version-var: github.com/palantir/foo/main.version
   280        script: |
   281                # print output
   282                echo "Running build script"
   283        os-archs:
   284          - os: linux
   285            arch: amd64
   286      dist:
   287        input-dir: foo/dist/input
   288        output-dir: foo/build/distributions
   289        input-products:
   290          - bar
   291        dist-type:
   292          type: bin
   293          info:
   294            omit-init-sh: true
   295        script: |
   296                 # move bin directory into service directory
   297                 mkdir $DIST_DIR/service
   298                 mv $DIST_DIR/bin $DIST_DIR/service/bin
   299      docker:
   300        - repository: test/foo
   301          tag: snapshot
   302          context-dir: foo/dist/docker
   303          dependencies:
   304           - product: foo
   305             type: bin
   306             target-file: foo-latest.tgz
   307        - repository: test/foo-other
   308          tag: snapshot
   309          context-dir: other/foo/dist/docker
   310          dependencies:
   311           - product: foo
   312             type: bin
   313             target-file: foo-latest.tgz
   314    bar:
   315      build:
   316        main-pkg: ./bar/main/bar
   317        output-dir: bar/build/bin
   318        version-var: github.com/palantir/bar/main.version
   319        os-archs:
   320          - os: darwin
   321            arch: amd64
   322          - os: linux
   323            arch: amd64
   324      dist:
   325        input-dir: bar/dist/bar
   326        output-dir: bar/build/distributions
   327        dist-type:
   328          type: bin
   329          info:
   330            omit-init-sh: true
   331        script: |
   332                 if [ "$IS_SNAPSHOT" == "1" ]; then
   333                   echo "snapshot"
   334                 fi
   335                 # move bin directory into service directory
   336                 mv $DIST_DIR/bin/darwin-amd64 $DIST_DIR/service/bin/darwin-amd64
   337                 mv $DIST_DIR/bin/linux-amd64 $DIST_DIR/service/bin/linux-amd64
   338                 rm -rf $DIST_DIR/bin
   339    baz:
   340      build:
   341        main-pkg: ./baz/main/baz
   342        os-archs:
   343          - os: darwin
   344            arch: amd64
   345          - os: linux
   346            arch: amd64
   347  group-id: com.palantir.group
   348  `,
   349  				},
   350  				Legacy:     true,
   351  				WantOutput: "Upgraded configuration for dist-plugin.yml\n",
   352  				WantFiles: map[string]string{
   353  					"godel/config/dist-plugin.yml": `products:
   354    bar:
   355      build:
   356        output-dir: bar/build/bin
   357        main-pkg: ./bar/main/bar
   358        version-var: github.com/palantir/bar/main.version
   359        os-archs:
   360        - os: darwin
   361          arch: amd64
   362        - os: linux
   363          arch: amd64
   364      dist:
   365        output-dir: bar/build/distributions
   366        disters:
   367          bin:
   368            type: bin
   369            input-dir:
   370              path: bar/dist/bar
   371              exclude:
   372                names:
   373                - \.gitkeep
   374            script: |
   375              #!/bin/bash
   376              ### START: auto-generated back-compat code for "IS_SNAPSHOT" variable ###
   377              IS_SNAPSHOT=0
   378              if [[ $VERSION =~ .+g[-+.]?[a-fA-F0-9]{3,}$ ]]; then IS_SNAPSHOT=1; fi
   379              ### END: auto-generated back-compat code for "IS_SNAPSHOT" variable ###
   380              if [ "$IS_SNAPSHOT" == "1" ]; then
   381                echo "snapshot"
   382              fi
   383              # move bin directory into service directory
   384              mv $DIST_WORK_DIR/bin/darwin-amd64 $DIST_WORK_DIR/service/bin/darwin-amd64
   385              mv $DIST_WORK_DIR/bin/linux-amd64 $DIST_WORK_DIR/service/bin/linux-amd64
   386              rm -rf $DIST_WORK_DIR/bin
   387      publish: {}
   388    baz:
   389      build:
   390        main-pkg: ./baz/main/baz
   391        os-archs:
   392        - os: darwin
   393          arch: amd64
   394        - os: linux
   395          arch: amd64
   396      dist:
   397        disters:
   398          os-arch-bin:
   399            type: os-arch-bin
   400            config:
   401              os-archs:
   402              - os: darwin
   403                arch: amd64
   404              - os: linux
   405                arch: amd64
   406      publish: {}
   407    foo:
   408      build:
   409        output-dir: foo/build/bin
   410        main-pkg: ./foo/main/foo
   411        version-var: github.com/palantir/foo/main.version
   412        script: |
   413          #!/bin/bash
   414          # print output
   415          echo "Running build script"
   416        os-archs:
   417        - os: linux
   418          arch: amd64
   419      dist:
   420        output-dir: foo/build/distributions
   421        disters:
   422          bin:
   423            type: bin
   424            input-dir:
   425              path: foo/dist/input
   426              exclude:
   427                names:
   428                - \.gitkeep
   429            script: |
   430              #!/bin/bash
   431              # move bin directory into service directory
   432              mkdir $DIST_WORK_DIR/service
   433              mv $DIST_WORK_DIR/bin $DIST_WORK_DIR/service/bin
   434      publish: {}
   435      docker:
   436        docker-builders:
   437          docker-image-0:
   438            type: default
   439            context-dir: foo/dist/docker
   440            input-dists:
   441            - foo.bin
   442            input-dist-output-paths:
   443              foo.bin:
   444              - foo-latest.tgz
   445            tag-templates:
   446              default: '{{Repository}}test/foo:snapshot'
   447          docker-image-1:
   448            type: default
   449            context-dir: other/foo/dist/docker
   450            input-dists:
   451            - foo.bin
   452            input-dist-output-paths:
   453              foo.bin:
   454              - foo-latest.tgz
   455            tag-templates:
   456              default: '{{Repository}}test/foo-other:snapshot'
   457      dependencies:
   458      - bar
   459  product-defaults:
   460    publish:
   461      group-id: com.palantir.group
   462  `,
   463  				},
   464  			},
   465  			{
   466  				Name: "legacy configuration dist block is not upgraded if os-archs not specified for build",
   467  				ConfigFiles: map[string]string{
   468  					"godel/config/dist.yml": `
   469  products:
   470    foo:
   471      build:
   472        main-pkg: ./foo/main/foo
   473        output-dir: foo/build/bin
   474        version-var: github.com/palantir/foo/main.version
   475  `,
   476  				},
   477  				Legacy:     true,
   478  				WantOutput: "Upgraded configuration for dist-plugin.yml\n",
   479  				WantFiles: map[string]string{
   480  					"godel/config/dist-plugin.yml": `products:
   481    foo:
   482      build:
   483        output-dir: foo/build/bin
   484        main-pkg: ./foo/main/foo
   485        version-var: github.com/palantir/foo/main.version
   486  `,
   487  				},
   488  			},
   489  			{
   490  				Name: "legacy configuration with no Docker tag is upgraded",
   491  				ConfigFiles: map[string]string{
   492  					"godel/config/dist.yml": `
   493  products:
   494    foo:
   495      build:
   496        main-pkg: ./foo
   497        os-archs:
   498          - os: linux
   499            arch: amd64
   500      dist:
   501        dist-type:
   502          type: bin
   503      docker:
   504      - repository: repo/foo
   505        context-dir: foo-docker
   506  `,
   507  				},
   508  				Legacy:     true,
   509  				WantOutput: "Upgraded configuration for dist-plugin.yml\n",
   510  				WantFiles: map[string]string{
   511  					"godel/config/dist-plugin.yml": `products:
   512    foo:
   513      build:
   514        main-pkg: ./foo
   515        os-archs:
   516        - os: linux
   517          arch: amd64
   518      dist:
   519        disters:
   520          bin:
   521            type: bin
   522      docker:
   523        docker-builders:
   524          docker-image-0:
   525            type: default
   526            context-dir: foo-docker
   527            tag-templates:
   528              default: '{{Repository}}repo/foo:{{Version}}'
   529  `,
   530  				},
   531  			},
   532  			{
   533  				Name: "valid v0 configuration is not modified",
   534  				ConfigFiles: map[string]string{
   535  					"godel/config/dist-plugin.yml": `
   536  products:
   537    # comment
   538    test:
   539      build:
   540        main-pkg: ./cmd/test
   541        output-dir: build
   542        build-args-script: |
   543                           YEAR=$(date +%Y)
   544                           echo "-ldflags"
   545                           echo "-X"
   546                           echo "main.year=$YEAR"
   547        version-var: main.version
   548        environment:
   549          foo: bar
   550          baz: 1
   551          bool: TRUE
   552        os-archs:
   553          - os: "darwin"
   554            arch: "amd64"
   555          - os: "linux"
   556            arch: "amd64"
   557      dist:
   558        output-dir: dist
   559        disters:
   560          primary:
   561            type: bin
   562            input-dir:
   563              path: foo/input
   564              exclude:
   565                names:
   566                - .gitkeep
   567      publish:
   568        group-id: com.test.foo
   569        info:
   570          bintray:
   571            config:
   572              username: username
   573              password: password
   574  script-includes: |
   575                   #!/usr/bin/env bash
   576  exclude:
   577    names:
   578      - ".*test"
   579    paths:
   580      - "vendor"
   581  `,
   582  				},
   583  				WantOutput: ``,
   584  				WantFiles: map[string]string{
   585  					"godel/config/dist-plugin.yml": `
   586  products:
   587    # comment
   588    test:
   589      build:
   590        main-pkg: ./cmd/test
   591        output-dir: build
   592        build-args-script: |
   593                           YEAR=$(date +%Y)
   594                           echo "-ldflags"
   595                           echo "-X"
   596                           echo "main.year=$YEAR"
   597        version-var: main.version
   598        environment:
   599          foo: bar
   600          baz: 1
   601          bool: TRUE
   602        os-archs:
   603          - os: "darwin"
   604            arch: "amd64"
   605          - os: "linux"
   606            arch: "amd64"
   607      dist:
   608        output-dir: dist
   609        disters:
   610          primary:
   611            type: bin
   612            input-dir:
   613              path: foo/input
   614              exclude:
   615                names:
   616                - .gitkeep
   617      publish:
   618        group-id: com.test.foo
   619        info:
   620          bintray:
   621            config:
   622              username: username
   623              password: password
   624  script-includes: |
   625                   #!/usr/bin/env bash
   626  exclude:
   627    names:
   628      - ".*test"
   629    paths:
   630      - "vendor"
   631  `,
   632  				},
   633  			},
   634  			{
   635  				Name: "valid v0 configuration with string input-dir not modified",
   636  				ConfigFiles: map[string]string{
   637  					"godel/config/dist-plugin.yml": `
   638  products:
   639    # comment
   640    test:
   641      dist:
   642        disters:
   643          type: bin
   644          input-dir: bar/input
   645  `,
   646  				},
   647  				WantOutput: ``,
   648  				WantFiles: map[string]string{
   649  					"godel/config/dist-plugin.yml": `
   650  products:
   651    # comment
   652    test:
   653      dist:
   654        disters:
   655          type: bin
   656          input-dir: bar/input
   657  `,
   658  				},
   659  			},
   660  		},
   661  	)
   662  }