blob: 16e5234f7233cc6001e348d602635f42f3dde1ab [file] [log] [blame]
// Queries a Gold instance and downloads all positive images for each tests.
// Stores metadata in the meta.json output file.
package main
import (
"flag"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"go.skia.org/infra/go/common"
"go.skia.org/infra/go/fileutil"
"go.skia.org/infra/go/httputils"
"go.skia.org/infra/go/sklog"
"go.skia.org/infra/go/util"
"go.skia.org/infra/golden/go/search/export"
)
const (
// Default query that will get all tests.
DEFAULT_QUERY = "fdiffmax=-1&fref=false&frgbamax=255&frgbamin=0&head=true&include=false&limit=50&match=name&metric=combined&neg=false&offset=0&pos=true&query=source_type%3Dgm&sort=desc&unt=false&nodiff=true"
// Default URL for the Gold instance we want to query.
GOLD_URL = "https://gold.skia.org"
// Search endpoint of Gold.
SEARCH_PATH = "/json/export"
// Template for image file names. Generally the digest is filled in.
IMG_FILENAME_TMPL = "%s.png"
// Name of the output metameta data file.
META_DATA_FILE = "meta.json"
)
var (
baseURL = flag.String("base_url", GOLD_URL, "Query URL to retrieve meta data.")
indexFile = flag.String("index_file", "./"+META_DATA_FILE, "Path of the index file.")
outputDir = flag.String("output_dir", "", "Directory where images should be written. If empty no images will be written.")
)
func main() {
common.Init()
// We need at least the index file or an output directory.
if *outputDir == "" && *indexFile == "" {
sklog.Fatal("No index file or output directory specified.")
}
// If the index file is empty write it to output directory.
useIndexPath := *indexFile
if useIndexPath == "" {
useIndexPath = filepath.Join(*outputDir, META_DATA_FILE)
}
// Set up the http client.
client := httputils.DefaultClientConfig().Client()
// load the test meta data from Gold.
testRecords, err := loadMetaData(client, *baseURL, DEFAULT_QUERY, META_DATA_FILE)
if err != nil {
sklog.Fatalf("Error loading meta data: %s", err)
}
sklog.Infoln("Meta data loaded from Gold.")
// Write the index file to disk.
if err := export.WriteTestRecordsFile(testRecords, useIndexPath); err != nil {
sklog.Fatalf("Error writing index file: %s", err)
}
sklog.Infoln("Index file written to disk.")
// If an output directory was given, download the images referenced in the index file.
if *outputDir != "" {
if err := downloadImages(*outputDir, client, testRecords); err != nil {
sklog.Fatalf("Error downloading images: %s", err)
}
}
sklog.Infof("Success. Knowledge data written to %s", *outputDir)
}
// loadMetaData makes a query to a Gold instance and parses the JSON response.
func loadMetaData(client *http.Client, baseURL, query, metaDataFileName string) ([]*export.TestRecord, error) {
url := strings.TrimRight(baseURL, "/") + SEARCH_PATH + "?" + query
sklog.Infof("Requesting url: %s", url)
resp, err := client.Get(url)
if err != nil {
return nil, err
}
defer util.Close(resp.Body)
return export.ReadTestRecords(resp.Body)
}
// downloadImages downloads all images referenced in the meta data to disk.
// One directory is created for each test.
func downloadImages(baseDir string, client *http.Client, testRecs []*export.TestRecord) error {
for _, testRec := range testRecs {
testDir := filepath.Join(baseDir, string(testRec.TestName))
absDirPath, err := fileutil.EnsureDirExists(testDir)
if err != nil {
sklog.Errorf("Error creating directory '%s'. Skipping. Got error: %s", testDir, err)
continue
}
for _, digestRec := range testRec.Digests {
// Download the image and then write it to disk.
resp, err := client.Get(digestRec.URL)
if err != nil {
sklog.Errorf("Error retrieving file '%s'. Got error: %s", digestRec.URL, err)
continue
}
defer util.Close(resp.Body)
// Write the image to disk.
imgFileName := fmt.Sprintf(IMG_FILENAME_TMPL, digestRec.Digest)
fileName := filepath.Join(absDirPath, imgFileName)
func(outputFileName string, reader io.Reader) {
f, err := os.Create(outputFileName)
if err != nil {
sklog.Errorf("Error opening output file '%s'. Got error: %s", outputFileName, err)
return
}
defer util.Close(f)
if _, err := io.Copy(f, reader); err != nil {
sklog.Errorf("Error saving file '%s'. Got error: %s", outputFileName, err)
return
}
sklog.Infof("Downloaded %s sucessfully.", outputFileName)
}(fileName, resp.Body)
}
}
return nil
}