golang.org/x/build@v0.0.0-20240506185731-218518f32b70/cmd/coordinator/buildstatus_test.go (about)

     1  // Copyright 2021 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  //go:build linux || darwin
     6  
     7  package main
     8  
     9  import (
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/google/go-cmp/cmp"
    14  	"golang.org/x/build/buildenv"
    15  	"golang.org/x/build/dashboard"
    16  	"golang.org/x/build/internal/buildgo"
    17  	"golang.org/x/build/internal/coordinator/pool"
    18  )
    19  
    20  // TestParseOutputAndHeader tests header parsing by parseOutputAndHeader.
    21  func TestParseOutputAndHeader(t *testing.T) {
    22  	for _, tc := range []struct {
    23  		name         string
    24  		input        []byte
    25  		wantMetadata string
    26  		wantHeader   string
    27  		wantOut      []byte
    28  	}{
    29  		{
    30  			name: "standard",
    31  			input: []byte(`
    32  XXXBANNERXXX:Testing packages.
    33  ok	archive/tar	0.015s
    34  ok	archive/zip	0.406s
    35  ok	bufio	0.075s
    36  `),
    37  			wantMetadata: "",
    38  			wantHeader:   "##### Testing packages.",
    39  			wantOut: []byte(`ok	archive/tar	0.015s
    40  ok	archive/zip	0.406s
    41  ok	bufio	0.075s
    42  `),
    43  		},
    44  		{
    45  			name: "header only",
    46  			input: []byte(`
    47  XXXBANNERXXX:Testing packages.
    48  `),
    49  			wantMetadata: "",
    50  			wantHeader:   "##### Testing packages.",
    51  			wantOut:      []byte(``),
    52  		},
    53  		{
    54  			name: "header only missing trailing newline",
    55  			input: []byte(`
    56  XXXBANNERXXX:Testing packages.`),
    57  			wantMetadata: "",
    58  			wantHeader:   "##### Testing packages.",
    59  			wantOut:      []byte(``),
    60  		},
    61  		{
    62  			name: "no banner",
    63  			input: []byte(`ok	archive/tar	0.015s
    64  ok	archive/zip	0.406s
    65  ok	bufio	0.075s
    66  `),
    67  			wantMetadata: "",
    68  			wantHeader:   "",
    69  			wantOut: []byte(`ok	archive/tar	0.015s
    70  ok	archive/zip	0.406s
    71  ok	bufio	0.075s
    72  `),
    73  		},
    74  		{
    75  			name: "no newline",
    76  			input: []byte(`XXXBANNERXXX:Testing packages.
    77  ok	archive/tar	0.015s
    78  ok	archive/zip	0.406s
    79  ok	bufio	0.075s
    80  `),
    81  			wantMetadata: "",
    82  			wantHeader:   "",
    83  			wantOut: []byte(`XXXBANNERXXX:Testing packages.
    84  ok	archive/tar	0.015s
    85  ok	archive/zip	0.406s
    86  ok	bufio	0.075s
    87  `),
    88  		},
    89  		{
    90  			name: "wrong banner",
    91  			input: []byte(`
    92  ##### Testing packages.
    93  ok	archive/tar	0.015s
    94  ok	archive/zip	0.406s
    95  ok	bufio	0.075s
    96  `),
    97  			wantMetadata: "",
    98  			wantHeader:   "",
    99  			wantOut: []byte(`
   100  ##### Testing packages.
   101  ok	archive/tar	0.015s
   102  ok	archive/zip	0.406s
   103  ok	bufio	0.075s
   104  `),
   105  		},
   106  		{
   107  			name: "metadata",
   108  			input: []byte(`
   109  XXXBANNERXXX:Test execution environment.
   110  # GOARCH: amd64
   111  # CPU: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz
   112  
   113  XXXBANNERXXX:Testing packages.
   114  ok	archive/tar	0.015s
   115  ok	archive/zip	0.406s
   116  ok	bufio	0.075s
   117  `),
   118  			wantMetadata: `##### Test execution environment.
   119  # GOARCH: amd64
   120  # CPU: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz`,
   121  			wantHeader: "##### Testing packages.",
   122  			wantOut: []byte(`ok	archive/tar	0.015s
   123  ok	archive/zip	0.406s
   124  ok	bufio	0.075s
   125  `),
   126  		},
   127  		{
   128  			name: "metadata missing separator newline",
   129  			input: []byte(`
   130  XXXBANNERXXX:Test execution environment.
   131  # GOARCH: amd64
   132  # CPU: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz
   133  XXXBANNERXXX:Testing packages.
   134  ok	archive/tar	0.015s
   135  ok	archive/zip	0.406s
   136  ok	bufio	0.075s
   137  `),
   138  			wantMetadata: `##### Test execution environment.
   139  # GOARCH: amd64
   140  # CPU: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz`,
   141  			wantHeader: "##### Testing packages.",
   142  			wantOut: []byte(`ok	archive/tar	0.015s
   143  ok	archive/zip	0.406s
   144  ok	bufio	0.075s
   145  `),
   146  		},
   147  		{
   148  			name: "metadata missing second banner",
   149  			input: []byte(`
   150  XXXBANNERXXX:Test execution environment.
   151  # GOARCH: amd64
   152  # CPU: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz
   153  `),
   154  			wantMetadata: "",
   155  			wantHeader:   "",
   156  			wantOut: []byte(`
   157  XXXBANNERXXX:Test execution environment.
   158  # GOARCH: amd64
   159  # CPU: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz
   160  `),
   161  		},
   162  		{
   163  			name: "metadata missing body",
   164  			input: []byte(`
   165  XXXBANNERXXX:Test execution environment.
   166  # GOARCH: amd64
   167  # CPU: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz
   168  
   169  XXXBANNERXXX:Testing packages.
   170  `),
   171  			wantMetadata: `##### Test execution environment.
   172  # GOARCH: amd64
   173  # CPU: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz`,
   174  			wantHeader: "##### Testing packages.",
   175  			wantOut:    []byte(``),
   176  		},
   177  		{
   178  			name: "metadata missing body and newline",
   179  			input: []byte(`
   180  XXXBANNERXXX:Test execution environment.
   181  # GOARCH: amd64
   182  # CPU: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz
   183  
   184  XXXBANNERXXX:Testing packages.`),
   185  			wantMetadata: `##### Test execution environment.
   186  # GOARCH: amd64
   187  # CPU: Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz`,
   188  			wantHeader: "##### Testing packages.",
   189  			wantOut:    []byte(``),
   190  		},
   191  	} {
   192  		t.Run(tc.name, func(t *testing.T) {
   193  			gotMetadata, gotHeader, gotOut := parseOutputAndHeader(tc.input)
   194  			if gotMetadata != tc.wantMetadata {
   195  				t.Errorf("parseOutputAndBanner(%q) got metadata %q want metadata %q", string(tc.input), gotMetadata, tc.wantMetadata)
   196  			}
   197  			if gotHeader != tc.wantHeader {
   198  				t.Errorf("parseOutputAndBanner(%q) got header %q want header %q", string(tc.input), gotHeader, tc.wantHeader)
   199  			}
   200  			if string(gotOut) != string(tc.wantOut) {
   201  				t.Errorf("parseOutputAndBanner(%q) got out %q want out %q", string(tc.input), string(gotOut), string(tc.wantOut))
   202  			}
   203  		})
   204  	}
   205  }
   206  
   207  func TestModulesEnv(t *testing.T) {
   208  	// modulesEnv looks at pool.NewGCEConfiguration().BuildEnv().IsProd for
   209  	// special behavior in dev mode. Temporarily override the environment
   210  	// to force testing of the prod configuration.
   211  	old := pool.NewGCEConfiguration().BuildEnv()
   212  	defer pool.NewGCEConfiguration().SetBuildEnv(old)
   213  	pool.NewGCEConfiguration().SetBuildEnv(&buildenv.Environment{
   214  		IsProd: true,
   215  	})
   216  
   217  	// In testing we never initialize
   218  	// pool.NewGCEConfiguration().GKENodeHostname(), so we get this odd
   219  	// concatenation back.
   220  	const gkeModuleProxy = "http://:30157"
   221  
   222  	testCases := []struct {
   223  		desc string
   224  		st   *buildStatus
   225  		want []string
   226  	}{
   227  		{
   228  			desc: "ec2-builder-repo-non-go",
   229  			st: &buildStatus{
   230  				BuilderRev: buildgo.BuilderRev{SubName: "bar"},
   231  				conf: &dashboard.BuildConfig{
   232  					TestHostConf: &dashboard.HostConfig{
   233  						IsReverse: false,
   234  						IsEC2:     true,
   235  					},
   236  				},
   237  			},
   238  			want: []string{"GOPROXY=https://proxy.golang.org"},
   239  		},
   240  		{
   241  			desc: "builder-repo-non-go",
   242  			st: &buildStatus{
   243  				BuilderRev: buildgo.BuilderRev{SubName: "bar"},
   244  				conf: &dashboard.BuildConfig{
   245  					TestHostConf: &dashboard.HostConfig{
   246  						IsReverse: false,
   247  						IsEC2:     false,
   248  					},
   249  				},
   250  			},
   251  			want: []string{"GOPROXY=" + gkeModuleProxy},
   252  		},
   253  		{
   254  			desc: "reverse-builder-repo-non-go",
   255  			st: &buildStatus{
   256  				BuilderRev: buildgo.BuilderRev{SubName: "bar"},
   257  				conf: &dashboard.BuildConfig{
   258  					TestHostConf: &dashboard.HostConfig{
   259  						IsReverse: true,
   260  						IsEC2:     false,
   261  					},
   262  				},
   263  			},
   264  			want: []string{"GOPROXY=https://proxy.golang.org"},
   265  		},
   266  		{
   267  			desc: "reverse-builder-repo-go",
   268  			st: &buildStatus{
   269  				BuilderRev: buildgo.BuilderRev{SubName: ""}, // go
   270  				conf: &dashboard.BuildConfig{
   271  					TestHostConf: &dashboard.HostConfig{
   272  						IsReverse: true,
   273  						IsEC2:     false,
   274  					},
   275  				},
   276  			},
   277  			want: []string{"GOPROXY=off"},
   278  		},
   279  		{
   280  			desc: "builder-repo-go",
   281  			st: &buildStatus{
   282  				BuilderRev: buildgo.BuilderRev{SubName: ""}, // go
   283  				conf: &dashboard.BuildConfig{
   284  					TestHostConf: &dashboard.HostConfig{
   285  						IsReverse: false,
   286  						IsEC2:     false,
   287  					},
   288  				},
   289  			},
   290  			want: []string{"GOPROXY=off"},
   291  		},
   292  		{
   293  			desc: "builder-repo-go-outbound-network-allowed",
   294  			st: &buildStatus{
   295  				BuilderRev: buildgo.BuilderRev{SubName: ""}, // go
   296  				conf: &dashboard.BuildConfig{
   297  					Name: "test-longtest",
   298  					TestHostConf: &dashboard.HostConfig{
   299  						IsReverse: false,
   300  						IsEC2:     false,
   301  					},
   302  				},
   303  			},
   304  			want: []string{"GOPROXY=" + gkeModuleProxy},
   305  		},
   306  		{
   307  			desc: "reverse-builder-repo-go-outbound-network-allowed",
   308  			st: &buildStatus{
   309  				BuilderRev: buildgo.BuilderRev{SubName: ""}, // go
   310  				conf: &dashboard.BuildConfig{
   311  					Name: "test-longtest",
   312  					TestHostConf: &dashboard.HostConfig{
   313  						IsReverse: true,
   314  						IsEC2:     false,
   315  					},
   316  				},
   317  			},
   318  			want: []string{"GOPROXY=https://proxy.golang.org"},
   319  		},
   320  	}
   321  	for _, tc := range testCases {
   322  		t.Run(tc.desc, func(t *testing.T) {
   323  			got := tc.st.modulesEnv()
   324  			if diff := cmp.Diff(tc.want, got); diff != "" {
   325  				t.Errorf("buildStatus.modulesEnv() mismatch (-want, +got)\n%s", diff)
   326  			}
   327  		})
   328  	}
   329  }
   330  
   331  // Test that go120DistTestNames remaps both 1.20 (old) and 1.21 (new)
   332  // dist test names to old, and doesn't forget the original name (raw).
   333  func TestGo120DistTestNames(t *testing.T) {
   334  	for _, tc := range [...]struct {
   335  		name string
   336  		in   string
   337  		want string
   338  	}{
   339  		{
   340  			name: "empty",
   341  			in:   "",
   342  			want: "",
   343  		},
   344  		{
   345  			name: "old to old",
   346  			in:   "go_test:archive/tar go_test:cmd/go api reboot test:0_2 test:1_2",
   347  			want: "go_test:archive/tar go_test:cmd/go api reboot test:0_2 test:1_2",
   348  		},
   349  		{
   350  			name: "new to old",
   351  			in:   "        archive/tar         cmd/go cmd/api:check cmd/internal/bootstrap_test cmd/internal/testdir:0_2 cmd/internal/testdir:1_2",
   352  			want: "go_test:archive/tar go_test:cmd/go     api                  reboot                        test:0_2                 test:1_2",
   353  		},
   354  		{
   355  			name: "more special cases",
   356  			in:   "crypto/x509:nolibgcc fmt:moved_goroot flag:race net:race os:race",
   357  			want: "nolibgcc:crypto/x509     moved_goroot      race     race    race",
   358  		},
   359  		{
   360  			name: "unhandled special case",
   361  			in:   "something:something",
   362  			want: "something:something",
   363  		},
   364  	} {
   365  		t.Run(tc.name, func(t *testing.T) {
   366  			got := go120DistTestNames(strings.Fields(tc.in))
   367  			var want []distTestName
   368  			for _, old := range strings.Fields(tc.want) {
   369  				want = append(want, distTestName{Old: old})
   370  			}
   371  			for i, raw := range strings.Fields(tc.in) {
   372  				want[i].Raw = raw
   373  			}
   374  			if diff := cmp.Diff(want, got); diff != "" {
   375  				t.Errorf("go120DistTestNames mismatch (-want +got):\n%s", diff)
   376  			}
   377  		})
   378  	}
   379  }