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 }