Update CTS roller to generate reftest/idl test sources

These sources need to be generated in Dawn's source tree
so that Chromium's //third_party/webgpu-cts DEP can be
removed.

Bug: chromium:1333969
Change-Id: I03c8cba691bcbfac00839f0cdd40fab6198ec83f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/91060
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
Austin Eng 2022-06-10 16:25:43 +00:00 committed by Dawn LUCI CQ
parent 6cc677761d
commit 9d14b164bf
3 changed files with 105 additions and 11 deletions

View File

@ -39,6 +39,8 @@ import (
"dawn.googlesource.com/dawn/tools/src/resultsdb" "dawn.googlesource.com/dawn/tools/src/resultsdb"
"go.chromium.org/luci/auth" "go.chromium.org/luci/auth"
"go.chromium.org/luci/auth/client/authcli" "go.chromium.org/luci/auth/client/authcli"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) )
func init() { func init() {
@ -49,6 +51,7 @@ const (
depsRelPath = "DEPS" depsRelPath = "DEPS"
tsSourcesRelPath = "third_party/gn/webgpu-cts/ts_sources.txt" tsSourcesRelPath = "third_party/gn/webgpu-cts/ts_sources.txt"
resourceFilesRelPath = "third_party/gn/webgpu-cts/resource_files.txt" resourceFilesRelPath = "third_party/gn/webgpu-cts/resource_files.txt"
webTestsPath = "webgpu-cts/webtests"
refMain = "refs/heads/main" refMain = "refs/heads/main"
noExpectations = `# Clear all expectations to obtain full list of results` noExpectations = `# Clear all expectations to obtain full list of results`
) )
@ -230,6 +233,9 @@ func (r *roller) roll(ctx context.Context) error {
ex = rebuilt ex = rebuilt
} }
// Map of relative file path to content of generated files
generatedFiles := map[string]string{}
// Regenerate the typescript dependency list // Regenerate the typescript dependency list
tsSources, err := r.genTSDepList(ctx) tsSources, err := r.genTSDepList(ctx)
if err != nil { if err != nil {
@ -242,6 +248,31 @@ func (r *roller) roll(ctx context.Context) error {
return fmt.Errorf("failed to generate resource_files.txt: %v", err) return fmt.Errorf("failed to generate resource_files.txt: %v", err)
} }
// Regenerate web tests HTML files
if err := r.genWebTestSources(ctx, generatedFiles); err != nil {
return fmt.Errorf("failed to generate web tests: %v", err)
}
deletedFiles := []string{}
if currentWebTestFiles, err := r.dawn.ListFiles(ctx, dawnHash, webTestsPath); err != nil {
// If there's an error, allow NotFound. It means the directory did not exist, so no files
// need to be deleted.
if e, ok := status.FromError(err); !ok || e.Code() != codes.NotFound {
return fmt.Errorf("listing current web tests failed: %v", err)
}
for _, f := range currentWebTestFiles {
// If the file is not generated in this revision, and it is an .html file,
// mark it for deletion.
if !strings.HasSuffix(f, ".html") {
continue
}
if _, exists := generatedFiles[f]; !exists {
deletedFiles = append(deletedFiles, f)
}
}
}
// Look for an existing gerrit change to update // Look for an existing gerrit change to update
existingRolls, err := r.findExistingRolls() existingRolls, err := r.findExistingRolls()
if err != nil { if err != nil {
@ -276,15 +307,15 @@ func (r *roller) roll(ctx context.Context) error {
// Update the DEPS, and ts-sources file. // Update the DEPS, and ts-sources file.
// Update the expectations with the re-formatted content, and updated // Update the expectations with the re-formatted content, and updated
//timestamp. // timestamp.
updateExpectationUpdateTimestamp(&ex) updateExpectationUpdateTimestamp(&ex)
generatedFiles[depsRelPath] = updatedDEPS
generatedFiles[common.RelativeExpectationsPath] = ex.String()
generatedFiles[tsSourcesRelPath] = tsSources
generatedFiles[resourceFilesRelPath] = resources
msg := r.rollCommitMessage(oldCTSHash, newCTSHash, ctsLog, changeID) msg := r.rollCommitMessage(oldCTSHash, newCTSHash, ctsLog, changeID)
ps, err := r.gerrit.EditFiles(changeID, msg, map[string]string{ ps, err := r.gerrit.EditFiles(changeID, msg, generatedFiles, deletedFiles)
depsRelPath: updatedDEPS,
common.RelativeExpectationsPath: ex.String(),
tsSourcesRelPath: tsSources,
resourceFilesRelPath: resources,
})
if err != nil { if err != nil {
return fmt.Errorf("failed to update change '%v': %v", changeID, err) return fmt.Errorf("failed to update change '%v': %v", changeID, err)
} }
@ -349,7 +380,7 @@ func (r *roller) roll(ctx context.Context) error {
updateExpectationUpdateTimestamp(&newExpectations) updateExpectationUpdateTimestamp(&newExpectations)
ps, err = r.gerrit.EditFiles(changeID, msg, map[string]string{ ps, err = r.gerrit.EditFiles(changeID, msg, map[string]string{
common.RelativeExpectationsPath: newExpectations.String(), common.RelativeExpectationsPath: newExpectations.String(),
}) }, nil)
if err != nil { if err != nil {
return fmt.Errorf("failed to update change '%v': %v", changeID, err) return fmt.Errorf("failed to update change '%v': %v", changeID, err)
} }
@ -416,7 +447,11 @@ func (r *roller) rollCommitMessage(
msg.WriteString(" commits)") msg.WriteString(" commits)")
} }
msg.WriteString("\n\n") msg.WriteString("\n\n")
msg.WriteString("Update expectations and ts_sources") msg.WriteString("Update:\n")
msg.WriteString(" - expectations.txt\n")
msg.WriteString(" - ts_sources.txt\n")
msg.WriteString(" - resource_files.txt\n")
msg.WriteString(" - webtest .html files\n")
msg.WriteString("\n\n") msg.WriteString("\n\n")
msg.WriteString("https://chromium.googlesource.com/external/github.com/gpuweb/cts/+log/") msg.WriteString("https://chromium.googlesource.com/external/github.com/gpuweb/cts/+log/")
msg.WriteString(oldCTSHash[:12]) msg.WriteString(oldCTSHash[:12])
@ -627,3 +662,38 @@ func (r *roller) genResourceFilesList(ctx context.Context) (string, error) {
} }
return strings.Join(files, "\n") + "\n", nil return strings.Join(files, "\n") + "\n", nil
} }
// genWebTestSources populates a map of generated webtest file names to contents, for the CTS checkout at r.ctsDir
func (r *roller) genWebTestSources(ctx context.Context, generatedFiles map[string]string) error {
htmlSearchDir := filepath.Join(r.ctsDir, "src", "webgpu")
return filepath.Walk(htmlSearchDir,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !strings.HasSuffix(info.Name(), ".html") || info.IsDir() {
return nil
}
relPath, err := filepath.Rel(htmlSearchDir, path)
if err != nil {
return err
}
data, err := os.ReadFile(path)
if err != nil {
return err
}
contents := string(data)
// Find the index after the starting html tag.
i := strings.Index(contents, "<html")
i = i + strings.Index(contents[i:], ">")
i = i + 1
// Insert a base tag so the fetched resources will come from the generated CTS JavaScript sources.
contents = contents[:i] + "\n" + ` <base ref="/gen/third_party/dawn/webgpu-cts/src/webgpu" />` + contents[i:]
generatedFiles[filepath.Join(webTestsPath, relPath)] = contents
return nil
})
}

View File

@ -168,10 +168,10 @@ func (g *Gerrit) CreateChange(project, branch, subject string, wip bool) (*Chang
return change, nil return change, nil
} }
// EditFiles replaces the content of the files in the given change. // EditFiles replaces the content of the files in the given change. It deletes deletedFiles.
// If newCommitMsg is not an empty string, then the commit message is replaced // If newCommitMsg is not an empty string, then the commit message is replaced
// with the string value. // with the string value.
func (g *Gerrit) EditFiles(changeID, newCommitMsg string, files map[string]string) (Patchset, error) { func (g *Gerrit) EditFiles(changeID, newCommitMsg string, files map[string]string, deletedFiles []string) (Patchset, error) {
if newCommitMsg != "" { if newCommitMsg != "" {
resp, err := g.client.Changes.ChangeCommitMessageInChangeEdit(changeID, &gerrit.ChangeEditMessageInput{ resp, err := g.client.Changes.ChangeCommitMessageInChangeEdit(changeID, &gerrit.ChangeEditMessageInput{
Message: newCommitMsg, Message: newCommitMsg,
@ -186,6 +186,12 @@ func (g *Gerrit) EditFiles(changeID, newCommitMsg string, files map[string]strin
return Patchset{}, g.maybeWrapError(err) return Patchset{}, g.maybeWrapError(err)
} }
} }
for _, path := range deletedFiles {
resp, err := g.client.Changes.DeleteFileInChangeEdit(changeID, path)
if err != nil && resp.StatusCode != 409 { // 409 no changes were made
return Patchset{}, g.maybeWrapError(err)
}
}
resp, err := g.client.Changes.PublishChangeEdit(changeID, "NONE") resp, err := g.client.Changes.PublishChangeEdit(changeID, "NONE")
if err != nil && resp.StatusCode != 409 { // 409 no changes were made if err != nil && resp.StatusCode != 409 { // 409 no changes were made

View File

@ -70,3 +70,21 @@ func (g *Gitiles) DownloadFile(ctx context.Context, ref, path string) (string, e
} }
return res.GetContents(), nil return res.GetContents(), nil
} }
// ListFiles lists the file paths in a project-relative path at the given reference.
func (g *Gitiles) ListFiles(ctx context.Context, ref, path string) ([]string, error) {
res, err := g.client.ListFiles(ctx, &gpb.ListFilesRequest{
Project: g.project,
Committish: ref,
Path: path,
})
if err != nil {
return []string{}, err
}
files := res.GetFiles()
paths := make([]string, len(files))
for i, f := range files {
paths[i] = f.GetPath()
}
return paths, nil
}