Path: blob/main/components/local-app/pkg/selfupdate/selfupdate_test.go
2500 views
// Copyright (c) 2023 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package selfupdate56import (7"context"8"encoding/json"9"net/http"10"net/http/httptest"11"os"12"path/filepath"13"runtime"14"testing"1516"github.com/Masterminds/semver/v3"17"github.com/google/go-cmp/cmp"18"github.com/opencontainers/go-digest"19)2021func TestGenerateManifest(t *testing.T) {22type Expectation struct {23Error string24Manifest *Manifest25}26tests := []struct {27Name string28Expectation Expectation29Files []string30FilenameParser FilenameParserFunc31}{32{33Name: "happy path",34Expectation: Expectation{35Manifest: &Manifest{36Version: semver.MustParse("v1.0"),37Binaries: []Binary{38{39Filename: "gitpod-linux-amd64",40OS: "linux",41Arch: "amd64",42Digest: "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",43},44},45},46},47Files: []string{48"gitpod-linux-amd64",49"nonsense",50},51FilenameParser: DefaultFilenameParser,52},53}5455for _, test := range tests {56t.Run(test.Name, func(t *testing.T) {57var act Expectation5859loc, err := os.MkdirTemp("", "selfupdate")60if err != nil {61t.Fatal(err)62}63t.Cleanup(func() {64os.RemoveAll(loc)65})66for _, f := range test.Files {67err = os.WriteFile(filepath.Join(loc, f), []byte("test"), 0644)68if err != nil {69t.Fatal(err)70}71}7273res, err := GenerateManifest(semver.MustParse("v1.0"), loc, test.FilenameParser)74if err != nil {75act.Error = err.Error()76}77act.Manifest = res7879if diff := cmp.Diff(test.Expectation, act); diff != "" {80t.Errorf("GenerateManifest() mismatch (-want +got):\n%s", diff)81}82})83}84}8586func TestDownloadManifest(t *testing.T) {87marshal := func(mf *Manifest) []byte {88fc, err := json.Marshal(mf)89if err != nil {90t.Fatal(err)91}92return fc93}9495type Expectation struct {96Error string97Manifest *Manifest98}99tests := []struct {100Name string101Expectation func(url string) Expectation102Manifest []byte103}{104{105Name: "happy path",106Manifest: marshal(&Manifest{107Version: semver.MustParse("0.2.0"),108Binaries: []Binary{109{110Filename: "gitpod-linux-amd64",111OS: "linux",112Arch: "amd64",113Digest: "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",114},115},116}),117Expectation: func(url string) Expectation {118return Expectation{119Manifest: &Manifest{120Version: semver.MustParse("0.2.0"),121Binaries: []Binary{122{123URL: url + GitpodCLIBasePath + "/gitpod-linux-amd64",124Filename: "gitpod-linux-amd64",125OS: "linux",126Arch: "amd64",127Digest: "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",128},129},130},131}132},133},134{135Name: "not found",136Expectation: func(url string) Expectation {137return Expectation{138Error: "cannot download manifest from " + url + GitpodCLIBasePath + "/manifest.json: 404 Not Found",139}140},141},142}143144for _, test := range tests {145t.Run(test.Name, func(t *testing.T) {146mux := http.NewServeMux()147if test.Manifest != nil {148mux.Handle(filepath.Join(GitpodCLIBasePath, "/manifest.json"), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {149_, _ = w.Write(test.Manifest)150}))151}152srv := httptest.NewServer(mux)153t.Cleanup(func() { srv.Close() })154155var act Expectation156res, err := DownloadManifest(context.Background(), srv.URL)157if err != nil {158act.Error = err.Error()159}160act.Manifest = res161162if diff := cmp.Diff(test.Expectation(srv.URL), act); diff != "" {163t.Errorf("DownloadManifest() mismatch (-want +got):\n%s", diff)164}165})166}167}168169func TestReplaceSelf(t *testing.T) {170type File struct {171OS string172Arch string173Filename string174Content []byte175}176type Expectation struct {177Error string178}179tests := []struct {180Name string181Expectation Expectation182Files []File183}{184{185Name: "happy path",186Files: []File{187{188OS: runtime.GOOS,189Arch: runtime.GOARCH,190Filename: "gitpod-" + runtime.GOOS + "-" + runtime.GOARCH,191Content: []byte("#!/bin/sh"),192},193},194},195}196197for _, test := range tests {198t.Run(test.Name, func(t *testing.T) {199var mf Manifest200mf.Version = semver.MustParse("v1.0")201for _, f := range test.Files {202mf.Binaries = append(mf.Binaries, Binary{203OS: f.OS,204Arch: f.Arch,205Filename: f.Filename,206Digest: digest.FromBytes(f.Content),207})208}209210mux := http.NewServeMux()211mux.Handle(GitpodCLIBasePath+"/manifest.json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {212_ = json.NewEncoder(w).Encode(mf)213}))214for _, f := range test.Files {215mux.Handle(GitpodCLIBasePath+"/"+f.Filename, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {216_, _ = w.Write(f.Content)217}))218}219srv := httptest.NewServer(mux)220t.Cleanup(func() { srv.Close() })221222dlmf, err := DownloadManifest(context.Background(), srv.URL)223if err != nil {224t.Fatal(err)225}226227var act Expectation228229err = ReplaceSelf(context.Background(), dlmf)230if err != nil {231act.Error = err.Error()232}233234if diff := cmp.Diff(test.Expectation, act); diff != "" {235t.Errorf("ReplaceSelf() mismatch (-want +got):\n%s", diff)236}237})238}239}240241242