github.com/creativeprojects/go-selfupdate@v1.2.0/mockdata_test.go (about)

     1  package selfupdate
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/sha256"
     6  	"fmt"
     7  	"os"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/stretchr/testify/require"
    12  	"golang.org/x/crypto/openpgp"
    13  )
    14  
    15  // mockSourceRepository creates a new *MockSource pre-populated with different versions and assets
    16  func mockSourceRepository(t *testing.T) *MockSource {
    17  
    18  	gzData, err := os.ReadFile("testdata/new_version.tar.gz")
    19  	require.NoError(t, err)
    20  
    21  	zipData, err := os.ReadFile("testdata/new_version.zip")
    22  	require.NoError(t, err)
    23  
    24  	releases := []SourceRelease{
    25  		&GitHubRelease{
    26  			name:         "v0.1.0",
    27  			tagName:      "v0.1.0",
    28  			url:          "v0.1.0",
    29  			prerelease:   true,
    30  			publishedAt:  time.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC),
    31  			releaseNotes: "first stable",
    32  			assets: []SourceAsset{
    33  				&GitHubAsset{
    34  					id:   1,
    35  					name: "resticprofile_0.1.0_linux_amd64.tar.gz",
    36  					url:  "resticprofile_0.1.0_linux_amd64.tar.gz",
    37  					size: len(gzData),
    38  				},
    39  				&GitHubAsset{
    40  					id:   2,
    41  					name: "resticprofile_0.1.0_darwin_amd64.tar.gz",
    42  					url:  "resticprofile_0.1.0_darwin_amd64.tar.gz",
    43  					size: len(gzData),
    44  				},
    45  				&GitHubAsset{
    46  					id:   3,
    47  					name: "resticprofile_0.1.0_windows_amd64.zip",
    48  					url:  "resticprofile_0.1.0_windows_amd64.zip",
    49  					size: len(zipData),
    50  				},
    51  				&GitHubAsset{
    52  					id:   31,
    53  					name: "resticprofile_0.1.0_darwin_arm64.tar.gz",
    54  					url:  "resticprofile_0.1.0_darwin_arm64.tar.gz",
    55  					size: len(gzData),
    56  				},
    57  			},
    58  		},
    59  		&GitHubRelease{
    60  			name:         "v0.10.0",
    61  			tagName:      "v0.10.0",
    62  			url:          "v0.10.0",
    63  			prerelease:   false,
    64  			publishedAt:  time.Date(2010, 1, 1, 0, 0, 0, 0, time.UTC),
    65  			releaseNotes: "latest stable",
    66  			assets: []SourceAsset{
    67  				&GitHubAsset{
    68  					id:   4,
    69  					name: "resticprofile_0.10.0_linux_amd64.tar.gz",
    70  					url:  "resticprofile_0.10.0_linux_amd64.tar.gz",
    71  					size: len(gzData),
    72  				},
    73  				&GitHubAsset{
    74  					id:   5,
    75  					name: "resticprofile_0.10.0_darwin_amd64.tar.gz",
    76  					url:  "resticprofile_0.10.0_darwin_amd64.tar.gz",
    77  					size: len(gzData),
    78  				},
    79  				&GitHubAsset{
    80  					id:   6,
    81  					name: "resticprofile_0.10.0_windows_amd64.zip",
    82  					url:  "resticprofile_0.10.0_windows_amd64.zip",
    83  					size: len(zipData),
    84  				},
    85  				&GitHubAsset{
    86  					id:   32,
    87  					name: "resticprofile_0.10.0_darwin_arm64.tar.gz",
    88  					url:  "resticprofile_0.10.0_darwin_arm64.tar.gz",
    89  					size: len(gzData),
    90  				},
    91  			},
    92  		},
    93  		&GitHubRelease{
    94  			name:         "v1.0.0-rc",
    95  			tagName:      "v1.0.0-rc",
    96  			url:          "v1.0.0-rc",
    97  			prerelease:   false,
    98  			publishedAt:  time.Date(2011, 1, 1, 0, 0, 0, 0, time.UTC),
    99  			releaseNotes: "release candidate",
   100  			assets: []SourceAsset{
   101  				&GitHubAsset{
   102  					id:   11,
   103  					name: "resticprofile_1.0.0-rc_linux_amd64.tar.gz",
   104  					url:  "resticprofile_1.0.0-rc_linux_amd64.tar.gz",
   105  					size: len(gzData),
   106  				},
   107  				&GitHubAsset{
   108  					id:   12,
   109  					name: "resticprofile_1.0.0-rc_darwin_amd64.tar.gz",
   110  					url:  "resticprofile_1.0.0-rc_darwin_amd64.tar.gz",
   111  					size: len(gzData),
   112  				},
   113  				&GitHubAsset{
   114  					id:   13,
   115  					name: "resticprofile_1.0.0-rc_windows_amd64.zip",
   116  					url:  "resticprofile_1.0.0-rc_windows_amd64.zip",
   117  					size: len(zipData),
   118  				},
   119  				&GitHubAsset{
   120  					id:   33,
   121  					name: "resticprofile_1.0.0-rc_darwin_arm64.tar.gz",
   122  					url:  "resticprofile_1.0.0-rc_darwin_arm64.tar.gz",
   123  					size: len(gzData),
   124  				},
   125  			},
   126  		},
   127  		&GitHubRelease{
   128  			name:         "v1.0.0",
   129  			tagName:      "v1.0.0",
   130  			url:          "v1.0.0",
   131  			prerelease:   false,
   132  			publishedAt:  time.Date(2011, 2, 1, 0, 0, 0, 0, time.UTC),
   133  			releaseNotes: "final v1",
   134  			assets: []SourceAsset{
   135  				&GitHubAsset{
   136  					id:   14,
   137  					name: "resticprofile_1.0.0_linux_amd64.tar.gz",
   138  					url:  "resticprofile_1.0.0_linux_amd64.tar.gz",
   139  					size: len(gzData),
   140  				},
   141  				&GitHubAsset{
   142  					id:   15,
   143  					name: "resticprofile_1.0.0_darwin_amd64.tar.gz",
   144  					url:  "resticprofile_1.0.0_darwin_amd64.tar.gz",
   145  					size: len(gzData),
   146  				},
   147  				&GitHubAsset{
   148  					id:   16,
   149  					name: "resticprofile_1.0.0_windows_amd64.zip",
   150  					url:  "resticprofile_1.0.0_windows_amd64.zip",
   151  					size: len(zipData),
   152  				},
   153  				&GitHubAsset{
   154  					id:   34,
   155  					name: "resticprofile_1.0.0_darwin_arm64.tar.gz",
   156  					url:  "resticprofile_1.0.0_darwin_arm64.tar.gz",
   157  					size: len(gzData),
   158  				},
   159  			},
   160  		},
   161  		&GitHubRelease{
   162  			name:         "v2.0.0-beta",
   163  			tagName:      "v2.0.0-beta",
   164  			url:          "v2.0.0-beta",
   165  			prerelease:   true,
   166  			publishedAt:  time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
   167  			releaseNotes: "beta",
   168  			assets: []SourceAsset{
   169  				&GitHubAsset{
   170  					id:   21,
   171  					name: "resticprofile_2.0.0-beta_linux_amd64.tar.gz",
   172  					url:  "resticprofile_2.0.0-beta_linux_amd64.tar.gz",
   173  					size: len(gzData),
   174  				},
   175  				&GitHubAsset{
   176  					id:   22,
   177  					name: "resticprofile_2.0.0-beta_darwin_amd64.tar.gz",
   178  					url:  "resticprofile_2.0.0-beta_darwin_amd64.tar.gz",
   179  					size: len(gzData),
   180  				},
   181  				&GitHubAsset{
   182  					id:   23,
   183  					name: "resticprofile_2.0.0-beta_windows_amd64.zip",
   184  					url:  "resticprofile_2.0.0-beta_windows_amd64.zip",
   185  					size: len(zipData),
   186  				},
   187  				&GitHubAsset{
   188  					id:   35,
   189  					name: "resticprofile_2.0.0-beta_darwin_arm64.tar.gz",
   190  					url:  "resticprofile_2.0.0-beta_darwin_arm64.tar.gz",
   191  					size: len(gzData),
   192  				},
   193  			},
   194  		},
   195  		&GitHubRelease{
   196  			name:         "v2.0.0",
   197  			tagName:      "v2.0.0",
   198  			url:          "v2.0.0",
   199  			draft:        true,
   200  			publishedAt:  time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC),
   201  			releaseNotes: "almost there",
   202  			assets: []SourceAsset{
   203  				&GitHubAsset{
   204  					id:   24,
   205  					name: "resticprofile_2.0.0_linux_amd64.tar.gz",
   206  					url:  "resticprofile_2.0.0_linux_amd64.tar.gz",
   207  					size: len(gzData),
   208  				},
   209  				&GitHubAsset{
   210  					id:   25,
   211  					name: "resticprofile_2.0.0_darwin_amd64.tar.gz",
   212  					url:  "resticprofile_2.0.0_darwin_amd64.tar.gz",
   213  					size: len(gzData),
   214  				},
   215  				&GitHubAsset{
   216  					id:   26,
   217  					name: "resticprofile_2.0.0_windows_amd64.zip",
   218  					url:  "resticprofile_2.0.0_windows_amd64.zip",
   219  					size: len(zipData),
   220  				},
   221  				&GitHubAsset{
   222  					id:   36,
   223  					name: "resticprofile_2.0.0_darwin_arm64.tar.gz",
   224  					url:  "resticprofile_2.0.0_darwin_arm64.tar.gz",
   225  					size: len(gzData),
   226  				},
   227  			},
   228  		},
   229  	}
   230  
   231  	files := map[int64][]byte{
   232  		1:  gzData,
   233  		2:  gzData,
   234  		3:  zipData,
   235  		4:  gzData,
   236  		5:  gzData,
   237  		6:  zipData,
   238  		11: gzData,
   239  		12: gzData,
   240  		13: zipData,
   241  		14: gzData,
   242  		15: gzData,
   243  		16: zipData,
   244  		21: gzData,
   245  		22: gzData,
   246  		23: zipData,
   247  		24: gzData,
   248  		25: gzData,
   249  		26: zipData,
   250  		31: gzData,
   251  		32: gzData,
   252  		33: gzData,
   253  		34: gzData,
   254  		35: gzData,
   255  		36: gzData,
   256  	}
   257  
   258  	// generates checksum files automatically
   259  	for i, release := range releases {
   260  		rel := release.(*GitHubRelease)
   261  		checksums := &bytes.Buffer{}
   262  		for _, asset := range rel.assets {
   263  			file, ok := files[asset.GetID()]
   264  			if !ok {
   265  				t.Errorf("file ID %d not found", asset.GetID())
   266  			}
   267  			hash := sha256.Sum256(file)
   268  			checksums.WriteString(fmt.Sprintf("%x  %s\n", hash, asset.GetName()))
   269  		}
   270  		id := int64(i*10 + 101)
   271  		rel.assets = append(rel.assets, &GitHubAsset{
   272  			id:   id,
   273  			name: "checksums.txt",
   274  		})
   275  		files[id] = checksums.Bytes()
   276  		t.Logf("file id %d contains checksums:\n%s\n", id, string(files[id]))
   277  	}
   278  
   279  	return NewMockSource(releases, files)
   280  }
   281  
   282  // mockPGPSourceRepository creates a variant of  mockSourceRepository where "checksums.txt" is signed with PGP
   283  func mockPGPSourceRepository(t *testing.T) (source *MockSource, PGPKeyRing []byte) {
   284  
   285  	source = mockSourceRepository(t)
   286  
   287  	var err error
   288  
   289  	var entity *openpgp.Entity
   290  	PGPKeyRing, entity = getTestPGPKeyRing(t)
   291  
   292  	for i, release := range source.releases {
   293  		rel := release.(*GitHubRelease)
   294  
   295  		id := int64(i*10 + 101)
   296  		signatureId := id + 1
   297  		shaSums := source.files[id]
   298  
   299  		// Create SHA256SUMS.asc (by signing SHA256SUMS)
   300  		signature := &bytes.Buffer{}
   301  		err = openpgp.ArmoredDetachSign(signature, entity, bytes.NewReader(shaSums), nil)
   302  		require.NoError(t, err)
   303  
   304  		rel.assets = append(rel.assets, &GitHubAsset{
   305  			id:   signatureId,
   306  			name: "checksums.txt.asc",
   307  		})
   308  		source.files[signatureId] = signature.Bytes()
   309  
   310  		t.Logf("file id %d contains PGP signature:\n%s\n", signatureId, string(source.files[signatureId]))
   311  	}
   312  
   313  	return
   314  }