github.com/triarius/goreleaser@v1.12.5/internal/pipe/checksums/checksums_test.go (about)

     1  package checksums
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/triarius/goreleaser/internal/artifact"
    10  	"github.com/triarius/goreleaser/pkg/config"
    11  	"github.com/triarius/goreleaser/pkg/context"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestDescription(t *testing.T) {
    16  	require.NotEmpty(t, Pipe{}.String())
    17  }
    18  
    19  func TestPipe(t *testing.T) {
    20  	const binary = "binary"
    21  	const archive = binary + ".tar.gz"
    22  	const linuxPackage = binary + ".rpm"
    23  	const checksums = binary + "_bar_checksums.txt"
    24  	const sum = "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc  "
    25  
    26  	tests := map[string]struct {
    27  		ids  []string
    28  		want string
    29  	}{
    30  		"default": {
    31  			want: strings.Join([]string{
    32  				sum + binary,
    33  				sum + linuxPackage,
    34  				sum + archive,
    35  			}, "\n") + "\n",
    36  		},
    37  		"select ids": {
    38  			ids: []string{
    39  				"id-1",
    40  				"id-2",
    41  			},
    42  			want: strings.Join([]string{
    43  				sum + binary,
    44  				sum + archive,
    45  			}, "\n") + "\n",
    46  		},
    47  	}
    48  	for name, tt := range tests {
    49  		t.Run(name, func(t *testing.T) {
    50  			folder := t.TempDir()
    51  			file := filepath.Join(folder, binary)
    52  			require.NoError(t, os.WriteFile(file, []byte("some string"), 0o644))
    53  			ctx := context.New(
    54  				config.Project{
    55  					Dist:        folder,
    56  					ProjectName: binary,
    57  					Checksum: config.Checksum{
    58  						NameTemplate: "{{ .ProjectName }}_{{ .Env.FOO }}_checksums.txt",
    59  						Algorithm:    "sha256",
    60  						IDs:          tt.ids,
    61  					},
    62  				},
    63  			)
    64  			ctx.Git.CurrentTag = "1.2.3"
    65  			ctx.Env = map[string]string{"FOO": "bar"}
    66  			ctx.Artifacts.Add(&artifact.Artifact{
    67  				Name: binary,
    68  				Path: file,
    69  				Type: artifact.UploadableBinary,
    70  				Extra: map[string]interface{}{
    71  					artifact.ExtraID: "id-1",
    72  				},
    73  			})
    74  			ctx.Artifacts.Add(&artifact.Artifact{
    75  				Name: archive,
    76  				Path: file,
    77  				Type: artifact.UploadableArchive,
    78  				Extra: map[string]interface{}{
    79  					artifact.ExtraID: "id-2",
    80  				},
    81  			})
    82  			ctx.Artifacts.Add(&artifact.Artifact{
    83  				Name: linuxPackage,
    84  				Path: file,
    85  				Type: artifact.LinuxPackage,
    86  				Extra: map[string]interface{}{
    87  					artifact.ExtraID: "id-3",
    88  				},
    89  			})
    90  			require.NoError(t, Pipe{}.Run(ctx))
    91  			var artifacts []string
    92  			for _, a := range ctx.Artifacts.List() {
    93  				artifacts = append(artifacts, a.Name)
    94  				require.NoError(t, a.Refresh(), "refresh should not fail and yield same results as nothing changed")
    95  			}
    96  			require.Contains(t, artifacts, checksums, binary)
    97  			bts, err := os.ReadFile(filepath.Join(folder, checksums))
    98  			require.NoError(t, err)
    99  			require.Contains(t, tt.want, string(bts))
   100  		})
   101  	}
   102  }
   103  
   104  func TestRefreshModifying(t *testing.T) {
   105  	const binary = "binary"
   106  	folder := t.TempDir()
   107  	file := filepath.Join(folder, binary)
   108  	require.NoError(t, os.WriteFile(file, []byte("some string"), 0o644))
   109  	ctx := context.New(
   110  		config.Project{
   111  			Dist:        folder,
   112  			ProjectName: binary,
   113  			Checksum: config.Checksum{
   114  				NameTemplate: "{{ .ProjectName }}_{{ .Env.FOO }}_checksums.txt",
   115  				Algorithm:    "sha256",
   116  			},
   117  		},
   118  	)
   119  	ctx.Git.CurrentTag = "1.2.3"
   120  	ctx.Env = map[string]string{"FOO": "bar"}
   121  	ctx.Artifacts.Add(&artifact.Artifact{
   122  		Name: binary,
   123  		Path: file,
   124  		Type: artifact.UploadableBinary,
   125  	})
   126  	require.NoError(t, Pipe{}.Run(ctx))
   127  	checks := ctx.Artifacts.Filter(artifact.ByType(artifact.Checksum)).List()
   128  	require.Len(t, checks, 1)
   129  	previous, err := os.ReadFile(checks[0].Path)
   130  	require.NoError(t, err)
   131  	require.NoError(t, os.WriteFile(file, []byte("some other string"), 0o644))
   132  	require.NoError(t, checks[0].Refresh())
   133  	current, err := os.ReadFile(checks[0].Path)
   134  	require.NoError(t, err)
   135  	require.NotEqual(t, string(previous), string(current))
   136  }
   137  
   138  func TestPipeFileNotExist(t *testing.T) {
   139  	folder := t.TempDir()
   140  	ctx := context.New(
   141  		config.Project{
   142  			Dist: folder,
   143  			Checksum: config.Checksum{
   144  				NameTemplate: "checksums.txt",
   145  			},
   146  		},
   147  	)
   148  	ctx.Git.CurrentTag = "1.2.3"
   149  	ctx.Artifacts.Add(&artifact.Artifact{
   150  		Name: "nope",
   151  		Path: "/nope",
   152  		Type: artifact.UploadableBinary,
   153  	})
   154  	err := Pipe{}.Run(ctx)
   155  	require.Error(t, err)
   156  	require.Contains(t, err.Error(), "/nope: no such file or directory")
   157  }
   158  
   159  func TestPipeInvalidNameTemplate(t *testing.T) {
   160  	binFile, err := os.CreateTemp(t.TempDir(), "goreleasertest-bin")
   161  	require.NoError(t, err)
   162  	t.Cleanup(func() { require.NoError(t, binFile.Close()) })
   163  	_, err = binFile.WriteString("fake artifact")
   164  	require.NoError(t, err)
   165  
   166  	for template, eerr := range map[string]string{
   167  		"{{ .Pro }_checksums.txt": `template: tmpl:1: unexpected "}" in operand`,
   168  		"{{.Env.NOPE}}":           `template: tmpl:1:6: executing "tmpl" at <.Env.NOPE>: map has no entry for key "NOPE"`,
   169  	} {
   170  		t.Run(template, func(t *testing.T) {
   171  			folder := t.TempDir()
   172  			ctx := context.New(
   173  				config.Project{
   174  					Dist:        folder,
   175  					ProjectName: "name",
   176  					Checksum: config.Checksum{
   177  						NameTemplate: template,
   178  						Algorithm:    "sha256",
   179  					},
   180  				},
   181  			)
   182  			ctx.Git.CurrentTag = "1.2.3"
   183  			ctx.Artifacts.Add(&artifact.Artifact{
   184  				Name: "whatever",
   185  				Type: artifact.UploadableBinary,
   186  				Path: binFile.Name(),
   187  			})
   188  			err = Pipe{}.Run(ctx)
   189  			require.Error(t, err)
   190  			require.Equal(t, eerr, err.Error())
   191  		})
   192  	}
   193  }
   194  
   195  func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) {
   196  	folder := t.TempDir()
   197  	binFile, err := os.CreateTemp(folder, "goreleasertest-bin")
   198  	require.NoError(t, err)
   199  	t.Cleanup(func() { require.NoError(t, binFile.Close()) })
   200  	_, err = binFile.WriteString("fake artifact")
   201  	require.NoError(t, err)
   202  
   203  	file := filepath.Join(folder, "checksums.txt")
   204  	require.NoError(t, os.WriteFile(file, []byte("some string"), 0o000))
   205  	ctx := context.New(
   206  		config.Project{
   207  			Dist: folder,
   208  			Checksum: config.Checksum{
   209  				NameTemplate: "checksums.txt",
   210  				Algorithm:    "sha256",
   211  			},
   212  		},
   213  	)
   214  	ctx.Git.CurrentTag = "1.2.3"
   215  	ctx.Artifacts.Add(&artifact.Artifact{
   216  		Name: "whatever",
   217  		Type: artifact.UploadableBinary,
   218  		Path: binFile.Name(),
   219  	})
   220  	err = Pipe{}.Run(ctx)
   221  	require.Error(t, err)
   222  	require.Contains(t, err.Error(), "/checksums.txt: permission denied")
   223  }
   224  
   225  func TestPipeWhenNoArtifacts(t *testing.T) {
   226  	ctx := &context.Context{
   227  		Artifacts: artifact.New(),
   228  	}
   229  	require.NoError(t, Pipe{}.Run(ctx))
   230  	require.Len(t, ctx.Artifacts.List(), 0)
   231  }
   232  
   233  func TestDefault(t *testing.T) {
   234  	ctx := &context.Context{
   235  		Config: config.Project{
   236  			Checksum: config.Checksum{},
   237  		},
   238  	}
   239  	require.NoError(t, Pipe{}.Default(ctx))
   240  	require.Equal(
   241  		t,
   242  		"{{ .ProjectName }}_{{ .Version }}_checksums.txt",
   243  		ctx.Config.Checksum.NameTemplate,
   244  	)
   245  	require.Equal(t, "sha256", ctx.Config.Checksum.Algorithm)
   246  }
   247  
   248  func TestDefaultSet(t *testing.T) {
   249  	ctx := &context.Context{
   250  		Config: config.Project{
   251  			Checksum: config.Checksum{
   252  				NameTemplate: "checksums.txt",
   253  			},
   254  		},
   255  	}
   256  	require.NoError(t, Pipe{}.Default(ctx))
   257  	require.Equal(t, "checksums.txt", ctx.Config.Checksum.NameTemplate)
   258  }
   259  
   260  func TestPipeCheckSumsWithExtraFiles(t *testing.T) {
   261  	const binary = "binary"
   262  	const checksums = "checksums.txt"
   263  	const extraFileFooRelPath = "./testdata/foo.txt"
   264  	const extraFileBarRelPath = "./testdata/**/bar.txt"
   265  	const extraFileFoo = "foo.txt"
   266  	const extraFileBar = "bar.txt"
   267  
   268  	tests := map[string]struct {
   269  		extraFiles []config.ExtraFile
   270  		ids        []string
   271  		want       []string
   272  	}{
   273  		"default": {
   274  			extraFiles: nil,
   275  			want: []string{
   276  				binary,
   277  			},
   278  		},
   279  		"one extra file": {
   280  			extraFiles: []config.ExtraFile{
   281  				{Glob: extraFileFooRelPath},
   282  			},
   283  			want: []string{
   284  				extraFileFoo,
   285  			},
   286  		},
   287  		"multiple extra files": {
   288  			extraFiles: []config.ExtraFile{
   289  				{Glob: extraFileFooRelPath},
   290  				{Glob: extraFileBarRelPath},
   291  			},
   292  			want: []string{
   293  				extraFileFoo,
   294  				extraFileBar,
   295  			},
   296  		},
   297  		"one extra file with no builds": {
   298  			extraFiles: []config.ExtraFile{
   299  				{Glob: extraFileFooRelPath},
   300  			},
   301  			ids: []string{"yada yada yada"},
   302  			want: []string{
   303  				extraFileFoo,
   304  			},
   305  		},
   306  	}
   307  
   308  	for name, tt := range tests {
   309  		t.Run(name, func(t *testing.T) {
   310  			folder := t.TempDir()
   311  			file := filepath.Join(folder, binary)
   312  			require.NoError(t, os.WriteFile(file, []byte("some string"), 0o644))
   313  			ctx := context.New(
   314  				config.Project{
   315  					Dist:        folder,
   316  					ProjectName: binary,
   317  					Checksum: config.Checksum{
   318  						Algorithm:    "sha256",
   319  						NameTemplate: "checksums.txt",
   320  						ExtraFiles:   tt.extraFiles,
   321  						IDs:          tt.ids,
   322  					},
   323  				},
   324  			)
   325  
   326  			ctx.Artifacts.Add(&artifact.Artifact{
   327  				Name: binary,
   328  				Path: file,
   329  				Type: artifact.UploadableBinary,
   330  				Extra: map[string]interface{}{
   331  					artifact.ExtraID: "id-1",
   332  				},
   333  			})
   334  
   335  			require.NoError(t, Pipe{}.Run(ctx))
   336  
   337  			bts, err := os.ReadFile(filepath.Join(folder, checksums))
   338  
   339  			require.NoError(t, err)
   340  			for _, want := range tt.want {
   341  				if tt.extraFiles == nil {
   342  					require.Contains(t, string(bts), "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc  "+want)
   343  				} else {
   344  					require.Contains(t, string(bts), "3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  "+want)
   345  				}
   346  			}
   347  		})
   348  	}
   349  }
   350  
   351  func TestExtraFilesNoMatch(t *testing.T) {
   352  	dir := t.TempDir()
   353  	ctx := context.New(
   354  		config.Project{
   355  			Dist:        dir,
   356  			ProjectName: "fake",
   357  			Checksum: config.Checksum{
   358  				Algorithm:    "sha256",
   359  				NameTemplate: "checksums.txt",
   360  				ExtraFiles:   []config.ExtraFile{{Glob: "./nope/nope.txt"}},
   361  			},
   362  		},
   363  	)
   364  
   365  	ctx.Artifacts.Add(&artifact.Artifact{
   366  		Name: "fake",
   367  		Path: "fake-path",
   368  		Type: artifact.UploadableBinary,
   369  	})
   370  
   371  	require.NoError(t, Pipe{}.Default(ctx))
   372  	require.EqualError(t, Pipe{}.Run(ctx), `globbing failed for pattern ./nope/nope.txt: matching "./nope/nope.txt": file does not exist`)
   373  }
   374  
   375  func TestSkip(t *testing.T) {
   376  	t.Run("skip", func(t *testing.T) {
   377  		ctx := context.New(config.Project{
   378  			Checksum: config.Checksum{
   379  				Disable: true,
   380  			},
   381  		})
   382  		require.True(t, Pipe{}.Skip(ctx))
   383  	})
   384  
   385  	t.Run("dont skip", func(t *testing.T) {
   386  		require.False(t, Pipe{}.Skip(context.New(config.Project{})))
   387  	})
   388  }
   389  
   390  // TODO: add tests for LinuxPackage and UploadableSourceArchive