Skip to content

Commit 4df14a5

Browse files
committed
tests/api,internal/frontend: add compare script
The tests/api/main.go script is updated to compare the frontend symbol history data with data in tests/api/testdata. For golang/go#37102 Change-Id: I5eb5fc367343ce386c7a2d2d7a53c0d3fad9da4f Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/339490 Trust: Julie Qiu <[email protected]> Run-TryBot: Julie Qiu <[email protected]> TryBot-Result: kokoro <[email protected]> Reviewed-by: Jonathan Amsterdam <[email protected]>
1 parent 2bed671 commit 4df14a5

File tree

4 files changed

+109
-7
lines changed

4 files changed

+109
-7
lines changed

internal/frontend/client.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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+
package frontend
6+
7+
import (
8+
"encoding/json"
9+
"fmt"
10+
"io/ioutil"
11+
"net/http"
12+
)
13+
14+
// A Client for interacting with the frontend. This is only used for tests.
15+
type Client struct {
16+
// URL of the frontend server host.
17+
url string
18+
19+
// Client used for HTTP requests.
20+
httpClient *http.Client
21+
}
22+
23+
// NewClient creates a new frontend client. This is only used for tests.
24+
func NewClient(url string) *Client {
25+
return &Client{
26+
url: url,
27+
httpClient: http.DefaultClient,
28+
}
29+
}
30+
31+
// GetVersions returns a VersionsDetails for the specified pkgPath.
32+
// This is only used for tests.
33+
func (c *Client) GetVersions(pkgPath string) (*VersionsDetails, error) {
34+
u := fmt.Sprintf("%s/%s?tab=versions&m=json", c.url, pkgPath)
35+
r, err := c.httpClient.Get(u)
36+
if err != nil {
37+
return nil, err
38+
}
39+
defer r.Body.Close()
40+
if r.StatusCode != http.StatusOK {
41+
return nil, fmt.Errorf(r.Status)
42+
}
43+
44+
body, err := ioutil.ReadAll(r.Body)
45+
if err != nil {
46+
return nil, err
47+
}
48+
49+
var vd VersionsDetails
50+
if err := json.Unmarshal(body, &vd); err != nil {
51+
return nil, fmt.Errorf("json.Unmarshal: %v", err)
52+
}
53+
return &vd, nil
54+
}

internal/frontend/symbol.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ func compareStringSlices(ss1, ss2 []string) int {
294294

295295
// ParseVersionsDetails returns a map of versionToNameToUnitSymbol based on
296296
// data from the proovided VersionDetails.
297-
func ParseVersionsDetails(vd VersionsDetails) (_ *internal.SymbolHistory, err error) {
297+
func ParseVersionsDetails(vd *VersionsDetails) (_ *internal.SymbolHistory, err error) {
298298
sh := internal.NewSymbolHistory()
299299
for _, vl := range vd.ThisModule {
300300
for _, vs := range vl.Versions {

internal/testing/integration/frontend_symbol_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func TestSymbols(t *testing.T) {
5555
if err := json.Unmarshal([]byte(body), &vd); err != nil {
5656
t.Fatalf("json.Unmarshal: %v\n %s", err, body)
5757
}
58-
sh, err := frontend.ParseVersionsDetails(vd)
58+
sh, err := frontend.ParseVersionsDetails(&vd)
5959
if err != nil {
6060
t.Fatal(err)
6161
}

tests/api/main.go

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@ import (
2222
"golang.org/x/mod/semver"
2323
"golang.org/x/pkgsite/internal"
2424
"golang.org/x/pkgsite/internal/derrors"
25+
"golang.org/x/pkgsite/internal/frontend"
2526
"golang.org/x/pkgsite/internal/proxy"
2627
"golang.org/x/pkgsite/internal/symbol"
2728
"golang.org/x/pkgsite/internal/version"
2829
)
2930

3031
var (
32+
frontendHost = flag.String("frontend", "http://localhost:8080",
33+
"Use the frontend host referred to by this URL for comparing data")
3134
proxyURL = flag.String("proxy", "https://proxy.golang.org",
3235
"Use the module proxy referred to by this URL for fetching packages")
3336
)
@@ -37,6 +40,8 @@ func main() {
3740
out := flag.CommandLine.Output()
3841
fmt.Fprintln(out, "api [cmd] [module path]:[package path suffix]")
3942
fmt.Fprintf(out, " generate: generates the API history for a package and writes to %s\n", testdataDir)
43+
fmt.Fprintf(out, " compare: compares the API history for a package in %s to %s\n", testdataDir, *frontendHost)
44+
fmt.Fprintln(out)
4045
flag.PrintDefaults()
4146
}
4247
flag.Parse()
@@ -48,7 +53,7 @@ func main() {
4853
ctx := context.Background()
4954
cmd := flag.Args()[0]
5055
pkgPath, modulePath := parsePath(flag.Args()[1])
51-
if err := run(ctx, cmd, pkgPath, modulePath, *proxyURL); err != nil {
56+
if err := run(ctx, cmd, pkgPath, modulePath, *frontendHost, *proxyURL); err != nil {
5257
log.Fatal(err)
5358
}
5459
}
@@ -61,10 +66,15 @@ func parsePath(arg string) (pkgPath, modulePath string) {
6166
return strings.Join(parts, "/"), parts[0]
6267
}
6368

64-
const tmpDir = "/tmp/api"
69+
const (
70+
testdataDir = "tests/api/testdata"
71+
tmpDir = "/tmp/api"
72+
)
6573

66-
func run(ctx context.Context, cmd, pkgPath, modulePath, proxyURL string) error {
74+
func run(ctx context.Context, cmd, pkgPath, modulePath, frontendHost, proxyURL string) error {
6775
switch cmd {
76+
case "compare":
77+
return compare(frontendHost, pkgPath)
6878
case "generate":
6979
return generate(ctx, pkgPath, modulePath, tmpDir, proxyURL)
7080
}
@@ -115,6 +125,46 @@ func generate(ctx context.Context, pkgPath, modulePath, tmpPath, proxyURL string
115125
return nil
116126
}
117127

128+
// compare compares data from the testdata directory with the frontend.
129+
func compare(frontendHost, pkgPath string) (err error) {
130+
defer derrors.Wrap(&err, "compare(ctx, %q, %q, %q)", frontendHost, pkgPath, testdataDir)
131+
files, err := symbol.LoadAPIFiles(pkgPath, testdataDir)
132+
if err != nil {
133+
return err
134+
}
135+
apiVersions, err := symbol.ParsePackageAPIInfo(files)
136+
if err != nil {
137+
return err
138+
}
139+
140+
// Parse API data from the frontend versions page.
141+
client := frontend.NewClient(frontendHost)
142+
vd, err := client.GetVersions(pkgPath)
143+
if err != nil {
144+
return err
145+
}
146+
147+
sh, err := frontend.ParseVersionsDetails(vd)
148+
if err != nil {
149+
return err
150+
}
151+
152+
// Compare the output of these two data sources.
153+
errors, err := symbol.CompareAPIVersions(pkgPath, apiVersions[pkgPath], sh)
154+
if err != nil {
155+
return err
156+
}
157+
if len(errors) == 0 {
158+
fmt.Printf("The APIs match for %s!\n", pkgPath)
159+
return nil
160+
}
161+
fmt.Printf("---------- Errors for %s\n", pkgPath)
162+
for _, e := range errors {
163+
fmt.Print(e)
164+
}
165+
return nil
166+
}
167+
118168
func fetchFeatureContext(ctx context.Context, proxyClient *proxy.Client,
119169
modulePath, pkgPath, ver, dirPath string) (_ map[string]map[string]bool, err error) {
120170
defer derrors.Wrap(&err, "fetchFeatureContext(ctx, proxyClient, %q, %q, %q, %q)",
@@ -149,8 +199,6 @@ func fetchFeatureContext(ctx context.Context, proxyClient *proxy.Client,
149199
return symbol.GenerateFeatureContexts(ctx, pkgPath, pkgDir)
150200
}
151201

152-
const testdataDir = "tests/api/testdata"
153-
154202
func writeFeatures(features []string, pkgPath, ver, outDir string) (err error) {
155203
defer derrors.Wrap(&err, "writeFeatures(%v, %q, %q, %q)", features, pkgPath, ver, outDir)
156204
if outDir == "" {

0 commit comments

Comments
 (0)