Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 1 | package impl |
| 2 | |
| 3 | import ( |
| 4 | "os" |
Jiri Simsa | 645f31b | 2014-08-21 14:11:13 -0700 | [diff] [blame] | 5 | "os/exec" |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 6 | "path/filepath" |
Jiri Simsa | 645f31b | 2014-08-21 14:11:13 -0700 | [diff] [blame] | 7 | "runtime" |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 8 | "strings" |
| 9 | "testing" |
| 10 | |
Jiri Simsa | 6ac9522 | 2015-02-23 16:11:49 -0800 | [diff] [blame] | 11 | "v.io/v23" |
| 12 | "v.io/v23/context" |
| 13 | "v.io/v23/services/mgmt/build" |
Cosmos Nicolaou | d6c3c9c | 2014-09-30 15:42:53 -0700 | [diff] [blame] | 14 | |
Jiri Simsa | ffceefa | 2015-02-28 11:03:34 -0800 | [diff] [blame] | 15 | _ "v.io/x/ref/profiles" |
Cosmos Nicolaou | 1381f8a | 2015-03-13 09:40:34 -0700 | [diff] [blame] | 16 | "v.io/x/ref/test" |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 17 | ) |
| 18 | |
Suharsh Sivakumar | d19c95d | 2015-02-19 14:44:50 -0800 | [diff] [blame] | 19 | //go:generate v23 test generate |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 20 | |
Asim Shankar | 544af43 | 2014-08-21 16:17:48 -0700 | [diff] [blame] | 21 | // findGoBinary returns the path to the given Go binary and |
| 22 | // the GOROOT environment variable to use. |
| 23 | func findGoBinary(t *testing.T, name string) (bin, goroot string) { |
Jiri Simsa | 3d3491f | 2014-12-25 08:58:06 -0800 | [diff] [blame] | 24 | root := os.Getenv("VANADIUM_ROOT") |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 25 | if root == "" { |
Jiri Simsa | 3d3491f | 2014-12-25 08:58:06 -0800 | [diff] [blame] | 26 | t.Fatalf("VANADIUM_ROOT is not set") |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 27 | } |
Asim Shankar | 544af43 | 2014-08-21 16:17:48 -0700 | [diff] [blame] | 28 | envroot := filepath.Join(root, "environment", "go", runtime.GOOS, runtime.GOARCH, "go") |
| 29 | envbin := filepath.Join(envroot, "bin", name) |
Jiri Simsa | 645f31b | 2014-08-21 14:11:13 -0700 | [diff] [blame] | 30 | if _, err := os.Stat(envbin); err == nil { |
Asim Shankar | 544af43 | 2014-08-21 16:17:48 -0700 | [diff] [blame] | 31 | return envbin, envroot |
Jiri Simsa | 645f31b | 2014-08-21 14:11:13 -0700 | [diff] [blame] | 32 | } 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 Simsa | 4d0b577 | 2014-12-16 16:33:18 -0800 | [diff] [blame] | 43 | return pathbin, os.Getenv("GOROOT") |
Jiri Simsa | 645f31b | 2014-08-21 14:11:13 -0700 | [diff] [blame] | 44 | } |
| 45 | |
| 46 | // startServer starts the build server. |
Matt Rosencrantz | fa3082c | 2015-01-22 21:39:04 -0800 | [diff] [blame] | 47 | func startServer(t *testing.T, ctx *context.T) build.BuilderClientMethods { |
Asim Shankar | 544af43 | 2014-08-21 16:17:48 -0700 | [diff] [blame] | 48 | gobin, goroot := findGoBinary(t, "go") |
Jiri Simsa | 6ac9522 | 2015-02-23 16:11:49 -0800 | [diff] [blame] | 49 | server, err := v23.NewServer(ctx) |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 50 | if err != nil { |
| 51 | t.Fatalf("NewServer() failed: %v", err) |
| 52 | } |
Jiri Simsa | 6ac9522 | 2015-02-23 16:11:49 -0800 | [diff] [blame] | 53 | l := v23.GetListenSpec(ctx) |
Suharsh Sivakumar | d68949c | 2015-01-26 10:32:23 -0800 | [diff] [blame] | 54 | endpoints, err := server.Listen(l) |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 55 | if err != nil { |
Suharsh Sivakumar | d68949c | 2015-01-26 10:32:23 -0800 | [diff] [blame] | 56 | t.Fatalf("Listen(%s) failed: %v", l, err) |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 57 | } |
| 58 | unpublished := "" |
Robin Thellend | 9bc8fcb | 2014-11-17 10:23:04 -0800 | [diff] [blame] | 59 | if err := server.Serve(unpublished, build.BuilderServer(NewBuilderService(gobin, goroot)), nil); err != nil { |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 60 | t.Fatalf("Serve(%q) failed: %v", unpublished, err) |
| 61 | } |
Cosmos Nicolaou | 28dabfc | 2014-12-15 22:51:07 -0800 | [diff] [blame] | 62 | name := "/" + endpoints[0].String() |
Matt Rosencrantz | fa3082c | 2015-01-22 21:39:04 -0800 | [diff] [blame] | 63 | return build.BuilderClient(name) |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 64 | } |
| 65 | |
Matt Rosencrantz | fa3082c | 2015-01-22 21:39:04 -0800 | [diff] [blame] | 66 | func invokeBuild(t *testing.T, ctx *context.T, client build.BuilderClientMethods, files []build.File) ([]byte, []build.File, error) { |
Jiri Simsa | 8e32b2a | 2014-07-30 10:07:57 -0700 | [diff] [blame] | 67 | arch, opsys := getArch(), getOS() |
Matt Rosencrantz | fa3082c | 2015-01-22 21:39:04 -0800 | [diff] [blame] | 68 | ctx, cancel := context.WithCancel(ctx) |
Matt Rosencrantz | 9346b41 | 2014-12-18 15:59:19 -0800 | [diff] [blame] | 69 | defer cancel() |
| 70 | stream, err := client.Build(ctx, arch, opsys) |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 71 | if err != nil { |
Jiri Simsa | 8e32b2a | 2014-07-30 10:07:57 -0700 | [diff] [blame] | 72 | t.Errorf("Build(%v, %v) failed: %v", err, arch, opsys) |
Jiri Simsa | 2f8bc27 | 2014-07-16 12:29:15 -0700 | [diff] [blame] | 73 | return nil, nil, err |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 74 | } |
Shyam Jayaraman | 97b9dca | 2014-07-31 13:30:46 -0700 | [diff] [blame] | 75 | sender := stream.SendStream() |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 76 | for _, file := range files { |
Shyam Jayaraman | 97b9dca | 2014-07-31 13:30:46 -0700 | [diff] [blame] | 77 | if err := sender.Send(file); err != nil { |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 78 | t.Logf("Send() failed: %v", err) |
Jiri Simsa | 2f8bc27 | 2014-07-16 12:29:15 -0700 | [diff] [blame] | 79 | return nil, nil, err |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 80 | } |
| 81 | } |
Shyam Jayaraman | 97b9dca | 2014-07-31 13:30:46 -0700 | [diff] [blame] | 82 | if err := sender.Close(); err != nil { |
| 83 | t.Logf("Close() failed: %v", err) |
Jiri Simsa | 2f8bc27 | 2014-07-16 12:29:15 -0700 | [diff] [blame] | 84 | return nil, nil, err |
| 85 | } |
| 86 | bins := make([]build.File, 0) |
Shyam Jayaraman | 97b9dca | 2014-07-31 13:30:46 -0700 | [diff] [blame] | 87 | rStream := stream.RecvStream() |
| 88 | for rStream.Advance() { |
| 89 | bins = append(bins, rStream.Value()) |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 90 | } |
Shyam Jayaraman | 97b9dca | 2014-07-31 13:30:46 -0700 | [diff] [blame] | 91 | if err := rStream.Err(); err != nil { |
Jiri Simsa | 1a7ce71 | 2014-07-24 13:23:45 -0700 | [diff] [blame] | 92 | t.Logf("Advance() failed: %v", err) |
Shyam Jayaraman | c4aed6e | 2014-07-22 14:25:06 -0700 | [diff] [blame] | 93 | return nil, nil, err |
| 94 | } |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 95 | output, err := stream.Finish() |
| 96 | if err != nil { |
| 97 | t.Logf("Finish() failed: %v", err) |
Jiri Simsa | 2f8bc27 | 2014-07-16 12:29:15 -0700 | [diff] [blame] | 98 | return nil, nil, err |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 99 | } |
Jiri Simsa | 2f8bc27 | 2014-07-16 12:29:15 -0700 | [diff] [blame] | 100 | return output, bins, nil |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | const mainSrc = `package main |
| 104 | |
| 105 | import "fmt" |
| 106 | |
| 107 | func 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. |
| 114 | func TestSuccess(t *testing.T) { |
Cosmos Nicolaou | 1381f8a | 2015-03-13 09:40:34 -0700 | [diff] [blame] | 115 | ctx, shutdown := test.InitForTest() |
Matt Rosencrantz | fa3082c | 2015-01-22 21:39:04 -0800 | [diff] [blame] | 116 | defer shutdown() |
| 117 | |
| 118 | client := startServer(t, ctx) |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 119 | |
| 120 | files := []build.File{ |
| 121 | build.File{ |
| 122 | Name: "test/main.go", |
| 123 | Contents: []byte(mainSrc), |
| 124 | }, |
| 125 | } |
Matt Rosencrantz | fa3082c | 2015-01-22 21:39:04 -0800 | [diff] [blame] | 126 | output, bins, err := invokeBuild(t, ctx, client, files) |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 127 | 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 Simsa | 2f8bc27 | 2014-07-16 12:29:15 -0700 | [diff] [blame] | 133 | if got, expected := len(bins), 1; got != expected { |
| 134 | t.Fatalf("Unexpected number of binaries: got %v, expected %v", got, expected) |
| 135 | } |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 136 | } |
| 137 | |
Jiri Simsa | 5dcb4fa | 2014-07-23 18:10:36 -0700 | [diff] [blame] | 138 | const fooSrc = `package foo |
| 139 | |
| 140 | import "fmt" |
| 141 | |
| 142 | func 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. |
| 149 | func TestEmpty(t *testing.T) { |
Cosmos Nicolaou | 1381f8a | 2015-03-13 09:40:34 -0700 | [diff] [blame] | 150 | ctx, shutdown := test.InitForTest() |
Matt Rosencrantz | fa3082c | 2015-01-22 21:39:04 -0800 | [diff] [blame] | 151 | defer shutdown() |
| 152 | |
| 153 | client := startServer(t, ctx) |
Jiri Simsa | 5dcb4fa | 2014-07-23 18:10:36 -0700 | [diff] [blame] | 154 | |
| 155 | files := []build.File{ |
| 156 | build.File{ |
| 157 | Name: "test/foo.go", |
| 158 | Contents: []byte(fooSrc), |
| 159 | }, |
| 160 | } |
Matt Rosencrantz | fa3082c | 2015-01-22 21:39:04 -0800 | [diff] [blame] | 161 | output, bins, err := invokeBuild(t, ctx, client, files) |
Jiri Simsa | 5dcb4fa | 2014-07-23 18:10:36 -0700 | [diff] [blame] | 162 | 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 Simsa | f7091bc | 2014-12-12 13:48:28 -0800 | [diff] [blame] | 173 | const failSrc = `package main |
| 174 | |
| 175 | import "fmt" |
| 176 | |
| 177 | func main() { |
| 178 | ... |
| 179 | } |
| 180 | ` |
| 181 | |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 182 | // TestFailure checks that the build server fails to build a package |
| 183 | // consisting of an empty file. |
| 184 | func TestFailure(t *testing.T) { |
Cosmos Nicolaou | 1381f8a | 2015-03-13 09:40:34 -0700 | [diff] [blame] | 185 | ctx, shutdown := test.InitForTest() |
Matt Rosencrantz | fa3082c | 2015-01-22 21:39:04 -0800 | [diff] [blame] | 186 | defer shutdown() |
| 187 | |
| 188 | client := startServer(t, ctx) |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 189 | |
| 190 | files := []build.File{ |
| 191 | build.File{ |
| 192 | Name: "test/main.go", |
Jiri Simsa | f7091bc | 2014-12-12 13:48:28 -0800 | [diff] [blame] | 193 | Contents: []byte(failSrc), |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 194 | }, |
| 195 | } |
Matt Rosencrantz | fa3082c | 2015-01-22 21:39:04 -0800 | [diff] [blame] | 196 | if output, _, err := invokeBuild(t, ctx, client, files); err == nil { |
Jiri Simsa | f7091bc | 2014-12-12 13:48:28 -0800 | [diff] [blame] | 197 | t.Logf("%v", string(output)) |
Jiri Simsa | 2e7dd71 | 2014-07-11 16:19:47 -0700 | [diff] [blame] | 198 | t.FailNow() |
| 199 | } |
| 200 | } |