blob: 090ffa62d73c4e32f9fa0cc6f2ef4a1d3e22eee3 [file] [log] [blame]
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The following enables go generate to generate the doc.go file.
//go:generate go run $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help
package main
import (
"bytes"
"fmt"
"io"
"os"
"strings"
"v.io/v23/vdl"
"v.io/v23/vdl/vdltest"
"v.io/v23/vom"
"v.io/x/lib/cmdline"
"v.io/x/lib/textutil"
"v.io/x/ref/lib/vdl/codegen"
"v.io/x/ref/lib/vdl/codegen/vdlgen"
)
var cmdGen = &cmdline.Command{
Runner: cmdline.RunnerFunc(runGen),
Name: "vomtestgen",
Short: "generates test data for the vomtest package",
Long: `
Command vomtestgen generates test cases for the vomtest package. The following
file is generated:
data81_gen.vdl - Golden file containing test cases.
This tool does not run the vdl tool on the generated *.vdl files; you must do
that yourself, typically via "jiri go install".
Instead of running this tool manually, it is typically invoked via:
$ jiri run go generate v.io/v23/vom/vomtest
`,
}
func main() {
cmdGen.Flags.StringVar(&flagData81, "data81", "data81_gen.vdl", "Name of the generated data file for version 81.")
cmdline.Main(cmdGen)
}
var (
flagData81 string
)
func runGen(_ *cmdline.Env, _ []string) error {
entries := vdltest.AllPassFunc(func(e vdltest.Entry) bool {
return e.IsCanonical
})
writeFileVomTest(flagData81, "data81", vdltest.ToEntryValues(entries))
return nil
}
// This tool is only used to generate test cases for the vdltest package, so the
// strategy is to panic on any error, to make the code simpler.
func panicOnError(err error) {
if err != nil {
panic(err)
}
}
func createFile(name string) (*os.File, func()) {
file, err := os.Create(name)
panicOnError(err)
return file, func() { panicOnError(file.Close()) }
}
func writef(w io.Writer, format string, args ...interface{}) {
_, err := fmt.Fprintf(w, format, args...)
panicOnError(err)
}
func writeHeader(w io.Writer) {
writef(w, `// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file was auto-generated by v.io/v23/vom/vomtest/internal/vomtestgen
// Run the following to re-generate:
// $ jiri run go generate v.io/v23/vom/vomtest
package vomtest
`)
}
func writeFileVomTest(fileName, constName string, entries []vdltest.EntryValue) {
// We skip all random entries for now, since they may contain multiple set and
// map elements, which would cause non-deterministic output.
//
// TODO(toddw): Determine a better strategy.
var filtered []vdltest.EntryValue
for _, e := range entries {
if e.Label != "Random" {
filtered = append(filtered, e)
}
}
skipped := len(entries) - len(filtered)
entries = filtered
fmt.Printf("Writing %s:\t%d entries (%d skipped)\n", fileName, len(entries), skipped)
file, cleanup := createFile(fileName)
defer cleanup()
writeHeader(file)
imports := codegen.Imports{
{Path: "v.io/v23/vdl/vdltest", Local: "vdltest"},
}
writef(file, "%s\n\n", vdlgen.Imports(imports))
comment := textutil.PrefixLineWriter(file, "// ")
panicOnError(vdltest.PrintEntryStats(comment, entries...))
panicOnError(comment.Flush())
writef(file, "\nconst %[1]s = []TestCase {\n", constName)
for _, e := range entries {
source := vdlgen.TypedConst(e.Source, "v.io/v23/vom/vomtest", imports)
hexVersion, hexType, hexValue, vomDump := toVomHex(vom.Version81, e.Source)
writef(file, `%[1]s
{
%#[2]q,
%[3]s,
%[4]q,
%[5]q, %[6]q, %[7]q,
},
`, vomDump, e.Label+" "+source, source, hexVersion+hexType+hexValue, hexVersion, hexType, hexValue)
}
writef(file, "}\n")
}
func toVomHex(version vom.Version, value *vdl.Value) (_, _, _, _ string) {
var buf, bufType bytes.Buffer
encType := vom.NewVersionedTypeEncoder(version, &bufType)
enc := vom.NewVersionedEncoderWithTypeEncoder(version, &buf, encType)
panicOnError(enc.Encode(value))
versionByte, _ := buf.ReadByte() // Read the version byte.
if bufType.Len() > 0 {
bufType.ReadByte() // Remove the version byte.
}
vomBytes := append([]byte{versionByte}, bufType.Bytes()...)
vomBytes = append(vomBytes, buf.Bytes()...)
dump, err := vom.Dump(vomBytes)
panicOnError(err)
const pre = "\t// "
vomDump := pre + strings.Replace(dump, "\n", "\n"+pre, -1)
if strings.HasSuffix(vomDump, "\n"+pre) {
vomDump = vomDump[:len(vomDump)-len("\n"+pre)]
}
return fmt.Sprintf("%x", versionByte), fmt.Sprintf("%x", bufType.Bytes()), fmt.Sprintf("%x", buf.Bytes()), vomDump
}