blob: 081968722484f006b2e2a2ba53a787f029c19d72 [file] [log] [blame]
Jiri Simsa2e7dd712014-07-11 16:19:47 -07001package impl
2
3import (
4 "os"
Jiri Simsa645f31b2014-08-21 14:11:13 -07005 "os/exec"
Jiri Simsa2e7dd712014-07-11 16:19:47 -07006 "path/filepath"
Jiri Simsa645f31b2014-08-21 14:11:13 -07007 "runtime"
Jiri Simsa2e7dd712014-07-11 16:19:47 -07008 "strings"
9 "testing"
10
Jiri Simsa6ac95222015-02-23 16:11:49 -080011 "v.io/v23"
12 "v.io/v23/context"
13 "v.io/v23/services/mgmt/build"
Cosmos Nicolaoud6c3c9c2014-09-30 15:42:53 -070014
Jiri Simsaffceefa2015-02-28 11:03:34 -080015 _ "v.io/x/ref/profiles"
Cosmos Nicolaou1381f8a2015-03-13 09:40:34 -070016 "v.io/x/ref/test"
Jiri Simsa2e7dd712014-07-11 16:19:47 -070017)
18
Suharsh Sivakumard19c95d2015-02-19 14:44:50 -080019//go:generate v23 test generate
Jiri Simsa2e7dd712014-07-11 16:19:47 -070020
Asim Shankar544af432014-08-21 16:17:48 -070021// findGoBinary returns the path to the given Go binary and
22// the GOROOT environment variable to use.
23func findGoBinary(t *testing.T, name string) (bin, goroot string) {
Jiri Simsa3d3491f2014-12-25 08:58:06 -080024 root := os.Getenv("VANADIUM_ROOT")
Jiri Simsa2e7dd712014-07-11 16:19:47 -070025 if root == "" {
Jiri Simsa3d3491f2014-12-25 08:58:06 -080026 t.Fatalf("VANADIUM_ROOT is not set")
Jiri Simsa2e7dd712014-07-11 16:19:47 -070027 }
Asim Shankar544af432014-08-21 16:17:48 -070028 envroot := filepath.Join(root, "environment", "go", runtime.GOOS, runtime.GOARCH, "go")
29 envbin := filepath.Join(envroot, "bin", name)
Jiri Simsa645f31b2014-08-21 14:11:13 -070030 if _, err := os.Stat(envbin); err == nil {
Asim Shankar544af432014-08-21 16:17:48 -070031 return envbin, envroot
Jiri Simsa645f31b2014-08-21 14:11:13 -070032 } else if !os.IsNotExist(err) {
33 t.Fatalf("Stat(%v) failed: %v", envbin, err)
34 }
35 pathbin, err := exec.LookPath(name)
36 if err != nil {
37 if err == exec.ErrNotFound {
38 t.Fatalf("%q does not exist and %q not found in PATH", envbin, name)
39 } else {
40 t.Fatalf("LookPath(%q) failed: %v", name, err)
41 }
42 }
Jiri Simsa4d0b5772014-12-16 16:33:18 -080043 return pathbin, os.Getenv("GOROOT")
Jiri Simsa645f31b2014-08-21 14:11:13 -070044}
45
46// startServer starts the build server.
Matt Rosencrantzfa3082c2015-01-22 21:39:04 -080047func startServer(t *testing.T, ctx *context.T) build.BuilderClientMethods {
Asim Shankar544af432014-08-21 16:17:48 -070048 gobin, goroot := findGoBinary(t, "go")
Jiri Simsa6ac95222015-02-23 16:11:49 -080049 server, err := v23.NewServer(ctx)
Jiri Simsa2e7dd712014-07-11 16:19:47 -070050 if err != nil {
51 t.Fatalf("NewServer() failed: %v", err)
52 }
Jiri Simsa6ac95222015-02-23 16:11:49 -080053 l := v23.GetListenSpec(ctx)
Suharsh Sivakumard68949c2015-01-26 10:32:23 -080054 endpoints, err := server.Listen(l)
Jiri Simsa2e7dd712014-07-11 16:19:47 -070055 if err != nil {
Suharsh Sivakumard68949c2015-01-26 10:32:23 -080056 t.Fatalf("Listen(%s) failed: %v", l, err)
Jiri Simsa2e7dd712014-07-11 16:19:47 -070057 }
58 unpublished := ""
Robin Thellend9bc8fcb2014-11-17 10:23:04 -080059 if err := server.Serve(unpublished, build.BuilderServer(NewBuilderService(gobin, goroot)), nil); err != nil {
Jiri Simsa2e7dd712014-07-11 16:19:47 -070060 t.Fatalf("Serve(%q) failed: %v", unpublished, err)
61 }
Cosmos Nicolaou28dabfc2014-12-15 22:51:07 -080062 name := "/" + endpoints[0].String()
Matt Rosencrantzfa3082c2015-01-22 21:39:04 -080063 return build.BuilderClient(name)
Jiri Simsa2e7dd712014-07-11 16:19:47 -070064}
65
Matt Rosencrantzfa3082c2015-01-22 21:39:04 -080066func invokeBuild(t *testing.T, ctx *context.T, client build.BuilderClientMethods, files []build.File) ([]byte, []build.File, error) {
Jiri Simsa8e32b2a2014-07-30 10:07:57 -070067 arch, opsys := getArch(), getOS()
Matt Rosencrantzfa3082c2015-01-22 21:39:04 -080068 ctx, cancel := context.WithCancel(ctx)
Matt Rosencrantz9346b412014-12-18 15:59:19 -080069 defer cancel()
70 stream, err := client.Build(ctx, arch, opsys)
Jiri Simsa2e7dd712014-07-11 16:19:47 -070071 if err != nil {
Jiri Simsa8e32b2a2014-07-30 10:07:57 -070072 t.Errorf("Build(%v, %v) failed: %v", err, arch, opsys)
Jiri Simsa2f8bc272014-07-16 12:29:15 -070073 return nil, nil, err
Jiri Simsa2e7dd712014-07-11 16:19:47 -070074 }
Shyam Jayaraman97b9dca2014-07-31 13:30:46 -070075 sender := stream.SendStream()
Jiri Simsa2e7dd712014-07-11 16:19:47 -070076 for _, file := range files {
Shyam Jayaraman97b9dca2014-07-31 13:30:46 -070077 if err := sender.Send(file); err != nil {
Jiri Simsa2e7dd712014-07-11 16:19:47 -070078 t.Logf("Send() failed: %v", err)
Jiri Simsa2f8bc272014-07-16 12:29:15 -070079 return nil, nil, err
Jiri Simsa2e7dd712014-07-11 16:19:47 -070080 }
81 }
Shyam Jayaraman97b9dca2014-07-31 13:30:46 -070082 if err := sender.Close(); err != nil {
83 t.Logf("Close() failed: %v", err)
Jiri Simsa2f8bc272014-07-16 12:29:15 -070084 return nil, nil, err
85 }
86 bins := make([]build.File, 0)
Shyam Jayaraman97b9dca2014-07-31 13:30:46 -070087 rStream := stream.RecvStream()
88 for rStream.Advance() {
89 bins = append(bins, rStream.Value())
Jiri Simsa2e7dd712014-07-11 16:19:47 -070090 }
Shyam Jayaraman97b9dca2014-07-31 13:30:46 -070091 if err := rStream.Err(); err != nil {
Jiri Simsa1a7ce712014-07-24 13:23:45 -070092 t.Logf("Advance() failed: %v", err)
Shyam Jayaramanc4aed6e2014-07-22 14:25:06 -070093 return nil, nil, err
94 }
Jiri Simsa2e7dd712014-07-11 16:19:47 -070095 output, err := stream.Finish()
96 if err != nil {
97 t.Logf("Finish() failed: %v", err)
Jiri Simsa2f8bc272014-07-16 12:29:15 -070098 return nil, nil, err
Jiri Simsa2e7dd712014-07-11 16:19:47 -070099 }
Jiri Simsa2f8bc272014-07-16 12:29:15 -0700100 return output, bins, nil
Jiri Simsa2e7dd712014-07-11 16:19:47 -0700101}
102
103const mainSrc = `package main
104
105import "fmt"
106
107func main() {
108 fmt.Println("Hello World!")
109}
110`
111
112// TestSuccess checks that the build server successfully builds a
113// package that depends on the standard Go library.
114func TestSuccess(t *testing.T) {
Cosmos Nicolaou1381f8a2015-03-13 09:40:34 -0700115 ctx, shutdown := test.InitForTest()
Matt Rosencrantzfa3082c2015-01-22 21:39:04 -0800116 defer shutdown()
117
118 client := startServer(t, ctx)
Jiri Simsa2e7dd712014-07-11 16:19:47 -0700119
120 files := []build.File{
121 build.File{
122 Name: "test/main.go",
123 Contents: []byte(mainSrc),
124 },
125 }
Matt Rosencrantzfa3082c2015-01-22 21:39:04 -0800126 output, bins, err := invokeBuild(t, ctx, client, files)
Jiri Simsa2e7dd712014-07-11 16:19:47 -0700127 if err != nil {
128 t.FailNow()
129 }
130 if got, expected := strings.TrimSpace(string(output)), "test"; got != expected {
131 t.Fatalf("Unexpected output: got %v, expected %v", got, expected)
132 }
Jiri Simsa2f8bc272014-07-16 12:29:15 -0700133 if got, expected := len(bins), 1; got != expected {
134 t.Fatalf("Unexpected number of binaries: got %v, expected %v", got, expected)
135 }
Jiri Simsa2e7dd712014-07-11 16:19:47 -0700136}
137
Jiri Simsa5dcb4fa2014-07-23 18:10:36 -0700138const fooSrc = `package foo
139
140import "fmt"
141
142func foo() {
143 fmt.Println("Hello World!")
144}
145`
146
147// TestEmpty checks that the build server successfully builds a
148// package that does not produce a binary.
149func TestEmpty(t *testing.T) {
Cosmos Nicolaou1381f8a2015-03-13 09:40:34 -0700150 ctx, shutdown := test.InitForTest()
Matt Rosencrantzfa3082c2015-01-22 21:39:04 -0800151 defer shutdown()
152
153 client := startServer(t, ctx)
Jiri Simsa5dcb4fa2014-07-23 18:10:36 -0700154
155 files := []build.File{
156 build.File{
157 Name: "test/foo.go",
158 Contents: []byte(fooSrc),
159 },
160 }
Matt Rosencrantzfa3082c2015-01-22 21:39:04 -0800161 output, bins, err := invokeBuild(t, ctx, client, files)
Jiri Simsa5dcb4fa2014-07-23 18:10:36 -0700162 if err != nil {
163 t.FailNow()
164 }
165 if got, expected := strings.TrimSpace(string(output)), "test"; got != expected {
166 t.Fatalf("Unexpected output: got %v, expected %v", got, expected)
167 }
168 if got, expected := len(bins), 0; got != expected {
169 t.Fatalf("Unexpected number of binaries: got %v, expected %v", got, expected)
170 }
171}
172
Jiri Simsaf7091bc2014-12-12 13:48:28 -0800173const failSrc = `package main
174
175import "fmt"
176
177func main() {
178 ...
179}
180`
181
Jiri Simsa2e7dd712014-07-11 16:19:47 -0700182// TestFailure checks that the build server fails to build a package
183// consisting of an empty file.
184func TestFailure(t *testing.T) {
Cosmos Nicolaou1381f8a2015-03-13 09:40:34 -0700185 ctx, shutdown := test.InitForTest()
Matt Rosencrantzfa3082c2015-01-22 21:39:04 -0800186 defer shutdown()
187
188 client := startServer(t, ctx)
Jiri Simsa2e7dd712014-07-11 16:19:47 -0700189
190 files := []build.File{
191 build.File{
192 Name: "test/main.go",
Jiri Simsaf7091bc2014-12-12 13:48:28 -0800193 Contents: []byte(failSrc),
Jiri Simsa2e7dd712014-07-11 16:19:47 -0700194 },
195 }
Matt Rosencrantzfa3082c2015-01-22 21:39:04 -0800196 if output, _, err := invokeBuild(t, ctx, client, files); err == nil {
Jiri Simsaf7091bc2014-12-12 13:48:28 -0800197 t.Logf("%v", string(output))
Jiri Simsa2e7dd712014-07-11 16:19:47 -0700198 t.FailNow()
199 }
200}