golang.org/x/build@v0.0.0-20240506185731-218518f32b70/internal/task/vscodego_test.go (about) 1 // Copyright 2024 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package task 6 7 import ( 8 "bytes" 9 "context" 10 "os" 11 "path/filepath" 12 "strings" 13 "testing" 14 15 "github.com/google/go-cmp/cmp" 16 "github.com/google/go-cmp/cmp/cmpopts" 17 "golang.org/x/build/internal/workflow" 18 ) 19 20 func TestVSCodeGoReleaseTask_buildVSCGO(t *testing.T) { 21 mustHaveShell(t) 22 23 tests := []struct { 24 name string 25 revision string 26 wantBuildError bool 27 }{ 28 { 29 name: "success", 30 revision: "release", 31 }, 32 { 33 name: "broken build", 34 revision: "master", // broken 35 wantBuildError: true, 36 }, 37 } 38 39 for _, test := range tests { 40 t.Run(test.name, func(t *testing.T) { 41 repo := NewFakeRepo(t, "vscode-go") 42 t1 := repo.Commit(map[string]string{ 43 "go.mod": "module github.com/golang/vscode-go\n", 44 "go.sum": "\n", 45 "vscgo/main.go": "package main\nfunc main() { println(\"v1\") }\n", 46 }) 47 repo.Branch("release", t1) 48 49 _ = repo.Commit(map[string]string{ 50 "vscgo/broken.go": "package broken\n", // broken at master 51 }) 52 53 gerrit := NewFakeGerrit(t, repo) 54 scratchDir := t.TempDir() 55 56 // fakeGo will record the invocation command in the fake output. 57 const fakeGo = `#!/bin/bash -eu 58 59 function find_output_value() { 60 # returns -o flag value. 61 while [[ $# -gt 0 ]]; do 62 case "$1" in 63 -o) 64 if [[ $# -gt 1 ]]; then 65 echo "$2" 66 shift 2 67 else 68 echo "Error: No argument provided after '-o'" 69 exit 1 70 fi 71 ;; 72 *) 73 shift 74 ;; 75 esac 76 done 77 } 78 79 case "$1" in 80 "build") 81 if [[ -f "vscgo/broken.go" ]]; then 82 echo build broken 83 exit 1 84 fi 85 out=$(find_output_value "$@") 86 echo "GOOS=${GOOS} GOARCH=${GOARCH} $0 $@" > "${out}" 87 exit 0 88 ;; 89 *) 90 echo unexpected command $@ 91 ;; 92 esac 93 ` 94 95 releaseTask := &VSCodeGoReleaseTask{ 96 CloudBuild: NewFakeCloudBuild(t, gerrit, "vscode-go", nil, fakeGo), 97 ScratchFS: &ScratchFS{BaseURL: "file://" + scratchDir}, 98 Revision: test.revision, 99 } 100 101 wd := releaseTask.NewDefinition() 102 w, err := workflow.Start(wd, map[string]interface{}{ 103 vscgoVersionParam.Name: "v0.0.0", 104 }) 105 if err != nil { 106 t.Fatal(err) 107 } 108 109 ctx, cancel := context.WithCancel(context.Background()) 110 defer cancel() 111 112 outputs, err := w.Run(ctx, &verboseListener{t: t, onStall: cancel}) 113 if err != nil { 114 if test.wantBuildError { 115 return // expected build error. 116 } 117 t.Fatal(err) 118 } 119 buildArtifacts, ok := outputs["build artifacts"].([]goBuildArtifact) 120 if !ok { 121 t.Fatalf("unexpected build artifacts: %T (%+v): ", outputs, outputs) 122 } 123 var want []goBuildArtifact 124 for _, p := range vscgoPlatforms { 125 want = append(want, goBuildArtifact{ 126 Platform: p.Platform, 127 }) 128 } 129 sortSlice := cmpopts.SortSlices(func(x, y goBuildArtifact) bool { return x.Platform < y.Platform }) 130 ignoreFilename := cmpopts.IgnoreFields(goBuildArtifact{}, "Filename") 131 if diff := cmp.Diff(buildArtifacts, want, sortSlice, ignoreFilename); diff != "" { 132 t.Fatal(diff) 133 } 134 // HACK: Reading directly from the scratch filesystem. 135 // XXX: is there a better way?? 136 envMap := make(map[string][]string) 137 for _, p := range vscgoPlatforms { 138 envMap[p.Platform] = p.Env 139 } 140 for _, a := range buildArtifacts { 141 data, err := os.ReadFile(filepath.Join(scratchDir, w.ID.String(), a.Filename)) 142 if err != nil { 143 t.Errorf("%v: %v", a.Platform, err) 144 } 145 envs := envMap[a.Platform] 146 if !bytes.Contains(data, []byte(strings.Join(envs, " "))) { 147 t.Errorf("%v: unexpected contents: %s", a.Platform, data) 148 } 149 150 } 151 }) 152 } 153 }