blob: f273d6e8e0df5e2768974719084a22d9d95fc9ef [file] [log] [blame] [edit]
// Copyright 2015 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 is the input file for VOM test data, in the VDL config file format. The
// purpose of this file is to make it easy to add VOM test cases for each
// generated language.
//
// In order to add new test cases, simply add new values to the list below.
// Test types are defined in the types/vomtype.vdl file in this directory; they
// can't appear in this file since they're not allowed in VDL config files.
//
// To re-generate the tests:
// 0) If your PATH does not include $JIRI_ROOT/release/go/bin, then prefix
// commands 2 and 3 with PATH=$JIRI_ROOT/release/go/bin:$PATH
// This way, the new binaries are run without overwriting existing dev tools.
// 1) jiri go install v.io/x/ref/cmd/{vdl,vomtestgen}
// 2) jiri run vomtestgen
// 3) jiri run vdl generate v.io/v23/vom/...
//
// Running "vomtestgen" against this file produces the vomdata.vdl file, and
// running "vdl generate" against the resulting package produces the VOM test
// data in each generated language.
config = x
import (
t "v.io/v23/vom/testdata/types"
)
const bytes8 = []byte{0, 0, 0, 0, 0, 0, 0, 0}
const bytes256 = []byte(string(bytes8)+string(bytes8)+string(bytes8)+string(bytes8)+string(bytes8)+string(bytes8)+string(bytes8)+string(bytes8))
const bytes2048 = []byte(string(bytes256)+string(bytes256)+string(bytes256)+string(bytes256)+string(bytes256)+string(bytes256)+string(bytes256)+string(bytes256))
const bytes64k = []byte(string(bytes2048)+string(bytes2048)+string(bytes2048)+string(bytes2048)+string(bytes2048)+string(bytes2048)+string(bytes2048)+string(bytes2048))
const bytes128k = []byte(string(bytes64k)+string(bytes64k))
// encodeDecodeData is a slice of values, where each value is used to generate a
// TestCase in the Tests slice in vomdata.vdl. That file is then generated into
// language-specific files to serve as test cases for the vom implementations in
// each language.
//
// Each TestCase includes the value itself, along with the "golden" hex
// representation of the vom encoding of the value, generated from the Go
// implementation. Tests in each language take each TestCase and check that
// encoding the value creates byte-wise identical hex bytes as the golden bytes,
// and decoding from the golden bytes produces an identical value. This is a
// very strict form of a round-trip encoding/decoding test; not only are we
// ensuring that round-trip encoding/decoding works, we also ensure that the
// generated encoding is byte-wise identical in each language.
//
// The vomdata.vdl file also includes comments describing each component of the
// hex encoding, generated via vom.Dump. The comments should be checked
// manually to ensure that the generated hex bytes are indeed correct, as per
// the vom specification.
const encodeDecodeData = []any{
// Values of simple unnamed types.
bool(true), bool(false),
string(""), string("abc"),
[]byte(""), []byte{255, 0, 1}, []byte("adef"),
byte(0), byte(127), byte(255),
uint16(0), uint16(1), uint16(2), uint16(63), uint16(64),
uint16(127), uint16(128), uint16(255), uint16(256),
uint16(0x7ffe), uint16(0x7fff), uint16(0xfffe), uint16(0xffff),
uint32(0),
uint32(0x7ffffe), uint32(0x7fffff),
uint32(0xfffffe), uint32(0xffffff),
uint32(0x7ffffffe), uint32(0x7fffffff),
uint32(0xfffffffe), uint32(0xffffffff),
uint64(0),
uint64(0x7ffffffffe), uint64(0x7fffffffff),
uint64(0xfffffffffe), uint64(0xffffffffff),
uint64(0x7ffffffffffe), uint64(0x7fffffffffff),
uint64(0xfffffffffffe), uint64(0xffffffffffff),
uint64(0x7ffffffffffffe), uint64(0x7fffffffffffff),
uint64(0xfffffffffffffe), uint64(0xffffffffffffff),
uint64(0x7ffffffffffffffe), uint64(0x7fffffffffffffff),
uint64(0xfffffffffffffffe), uint64(0xffffffffffffffff),
int16(0), int16(1), int16(2), int16(63), int16(64),
int16(127), int16(128), int16(255), int16(256),
int16(0x7ffe), int16(0x7fff),
int32(0),
int32(0x7ffffe), int32(0x7fffff),
int32(0xfffffe), int32(0xffffff),
int32(0x7ffffffe), int32(0x7fffffff),
int64(0),
int64(1), int64(2),
int64(0x7ffffffffe), int64(0x7fffffffff),
int64(0xfffffffffe), int64(0xffffffffff),
int64(0x7ffffffffffe), int64(0x7fffffffffff),
int64(0xfffffffffffe), int64(0xffffffffffff),
int64(0x7ffffffffffffe), int64(0x7fffffffffffff),
int64(0xfffffffffffffe), int64(0xffffffffffffff),
int64(0x7ffffffffffffffe), int64(0x7fffffffffffffff),
int16(-1), int16(-2), int16(-64), int16(-65),
int16(-128), int16(-129), int16(-256), int16(-257),
int16(-0x7fff), int16(-0x8000),
int32(-0x7fffff), int32(-0x800000),
int32(-0xffffff), int32(-0x1000000),
int32(-0x7fffffff), int32(-0x80000000),
int64(-1), int64(-2),
int64(-0x7fffffffff), int64(-0x8000000000),
int64(-0xffffffffff), int64(-0x10000000000),
int64(-0x7fffffffffff), int64(-0x800000000000),
int64(-0xffffffffffff), int64(-0x1000000000000),
int64(-0x7fffffffffffff), int64(-0x80000000000000),
int64(-0xffffffffffffff), int64(-0x100000000000000),
int64(-0x7fffffffffffffff), int64(-0x8000000000000000),
float32(0), float32(32.5), float32(-32.5),
float64(0), float64(64.5), float64(-64.5),
// Values of simple named types.
t.NBool(true), t.NBool(false),
t.NString(""), t.NString("abc"),
t.NByteSlice{}, t.NByteSlice{255, 0, 1}, t.NByteSlice("abc"),
t.NByteArray{}, t.NByteArray{255, 0, 1}, t.NByteArray("abcd"),
t.NByte(0), t.NByte(127), t.NByte(255),
t.NUint16(0), t.NUint16(0xffff),
t.NUint32(0), t.NUint32(0xffffffff),
t.NUint64(0), t.NUint64(0xffffffffffffffff),
t.NInt16(0), t.NInt16(0x7fff), t.NInt16(-0x8000),
t.NInt32(0), t.NInt32(0x7fffffff), t.NInt32(-0x80000000),
t.NInt64(0), t.NInt64(0x7fffffffffffffff), t.NInt64(-0x8000000000000000),
t.NFloat32(0), t.NFloat32(32.5), t.NFloat32(-32.5),
t.NFloat64(0), t.NFloat64(64.5), t.NFloat64(-64.5),
// Values of composite types.
//
// TODO(toddw): Add more than 1 entry to the set and map values, after
// accounting for possible ordering differences.
t.NArray2Uint64{1, 2},
[]uint64{1, 2}, t.NListUint64{1, 2},
set[uint64]{1}, t.NSetUint64{1},
map[uint64]string{1:"abc"}, t.NMapUint64String{1:"abc"},
t.NStruct{A: true, B: "abc", C: 123 },
?t.NStruct(nil), // ?t.NStruct{}, ?t.NStruct{A: true, B: "abc", C: 123}, // TODO(bprosnitz) Figure out how to support top-level nil tests
// Values of special types.
// TODO(toddw): Add tests for embedded Any, etc.
t.NEnum.A, t.NEnum.B, t.NEnum.C,
t.NUnion{A: true}, t.NUnion{A: false},
t.NUnion{B: ""}, t.NUnion{B: "abc"},
t.NUnion{C: 0}, t.NUnion{C: 123}, t.NUnion{C: -123},
// Values of nested custom types.
t.MBool(true), t.MBool(false),
t.MStruct{A: true, B: t.NBool(true), C: t.MBool(true)},
t.MStruct{D: nil}, t.MStruct{D: {}}, t.MStruct{D: {true, "abc", 123}},
t.MStruct{F: "abc"}, t.MStruct{F: t.MBool(true)}, t.MStruct{F: ?t.NStruct{B: "abc"}},
t.MList{t.NListUint64{4, 2}, t.NListUint64{}, t.NListUint64{99}},
// TODO(bprosnitz) Add more than one entry to the map, after we have
// support for testing reordered bytes.
t.MMap{t.NFloat32(4.5): t.NListUint64{2,3}},
// Values of recursive types.
t.RecA{t.RecA{},t.RecA{t.RecA{}}},
t.RecX{t.RecY{},t.RecY{t.RecX{}, t.RecX{}}},
t.Rec1{t.Rec2{t.Rec3{t.Rec4{t.Rec1{}}}}},
t.RecStruct{?t.RecStruct{}}, t.RecStruct{?t.RecStruct{?t.RecStruct{}}},
t.Rec1234All{t.Rec1234A{[]t.Rec1234A{t.Rec1234A{}},[]t.Rec1234{t.Rec1234{R1:t.Rec1{}}}},t.Rec1234B{[]t.Rec1234B{t.Rec1234B{}},[]t.Rec1234{t.Rec1234{R2:t.Rec2{t.Rec3{}}}}}},
// Values of typeobject types.
typeobject(any),
typeobject(bool),
typeobject(uint16),typeobject(uint32),typeobject(uint64),
typeobject(int16),typeobject(int32),typeobject(int64),
typeobject(int16),typeobject(int32),typeobject(int64),
typeobject(float32),typeobject(float64),
typeobject(t.NBool),
typeobject(t.NUint16),typeobject(t.NUint32),typeobject(t.NUint64),
typeobject(t.NInt16),typeobject(t.NInt32),typeobject(t.NInt64),
typeobject(t.NFloat32),typeobject(t.NFloat64),
typeobject(t.NArray2Uint64),
typeobject([]uint64), typeobject(t.NListUint64),
typeobject(set[uint64]), typeobject(t.NSetUint64),
typeobject(map[uint64]string), typeobject(t.NMapUint64String),
typeobject(t.NStruct),
typeobject(t.NEnum), typeobject(t.NUnion),
[]typeobject{typeobject(any), typeobject(bool)},
// Regression tests to ensure "any" typed struct fields with zero values are
// encoded and decoded correctly. https://v.io/c/12030
t.StructAny{nil}, t.StructAny{false},
t.StructAny{int16(0)}, t.StructAny{int32(0)}, t.StructAny{int64(0)},
t.StructAny{uint16(0)}, t.StructAny{uint32(0)}, t.StructAny{uint64(0)},
t.StructAny{float32(0)}, t.StructAny{float64(0)},
t.StructAny{""}, t.StructAny{[]byte{}},
t.StructAny{t.FoodEnum.Bean},
t.StructAny{t.NListUint64{}}, t.StructAny{t.NByteArray{}}, t.StructAny{t.NArray2Uint64{}},
t.StructAny{t.NSetUint64{}}, t.StructAny{t.NMapUint64String{}},
t.StructAny{t.NStruct{}}, t.StructAny{t.NUnion{A: false}},
t.StructAny{?t.NStruct(nil)}, t.StructAny{?t.NStruct{}},
t.StructAny{t.StructMap{}}, t.StructAny{t.StructMap{{0: 0}}},
t.StructAny{typeobject(any)},
?t.StructAny(nil), //?t.StructAny{nil}, ?t.StructAny{false}, // TODO(bprosnitz) Think about how to handle top-level nil
//?t.StructAny{t.StructMap{}}, ?t.StructAny{t.StructMap{{0: 0}}},
// Non-zero values inside anys in structs.
t.StructAny{true}, t.StructAny{byte(1)},
t.StructAny{int16(1)}, t.StructAny{int32(1)}, t.StructAny{int64(1)},
t.StructAny{uint16(1)}, t.StructAny{uint32(1)}, t.StructAny{uint64(1)},
t.StructAny{float32(1)}, t.StructAny{float64(1)},
t.StructAny{"A"}, t.StructAny{[]byte("A")},
t.StructAny{t.FoodEnum.Cherry},
t.StructAny{t.NListUint64{1}}, t.StructAny{t.NByteArray("Abcd")}, t.StructAny{t.NArray2Uint64{0, 1}},
t.StructAny{t.NSetUint64{1}}, t.StructAny{t.NMapUint64String{1: "A"}},
t.StructAny{t.NStruct{A: true}}, t.StructAny{t.NUnion{A: true}},
t.StructAny{typeobject(bool)},
// Top-level anys (may be handled differently than anys in structs)
any(nil),
// Zero-values:
any(false), any(byte(0)),
any(int16(0)), any(int32(0)), any(int64(0)),
any(uint16(0)), any(uint32(0)), any(uint64(0)),
any(float32(0)), any(float64(0)),
any(""), any([]byte{}),
any(t.FoodEnum.Bean),
any(t.NListUint64{}), any(t.NByteArray{}), any(t.NArray2Uint64{}),
any(t.NSetUint64{}), any(t.NMapUint64String{}),
any(t.NStruct{}), any(t.NUnion{A: false}),
any(typeobject(any)),
// Non-zero values.
any(true), any(byte(1)),
any(int16(1)), any(int32(1)), any(int64(1)),
any(uint16(1)), any(uint32(1)), any(uint64(1)),
any(float32(1)), any(float64(1)),
any("A"), any([]byte("A")),
any(t.FoodEnum.Cherry),
any(t.NListUint64{1}), any(t.NByteArray("Abcd")), any(t.NArray2Uint64{0, 1}),
any(t.NSetUint64{1}), any(t.NMapUint64String{1: "A"}),
any(t.NStruct{A: true}), any(t.NUnion{A: true}),
any(typeobject(bool)),
t.StructManyTypes{}, // Test zero values in structs
t.StructManyTypes{
Bool: true,
AByte: 1,
Int16: 1,
Int32: 1,
Int64: 1,
Uint16: 1,
Uint32: 1,
Uint64: 1,
String: "A",
Bytes: []byte("A"),
Float32: 1,
Float64: 1,
FoodEnum: Cherry,
NListUint64: t.NListUint64{1},
NByteArray: t.NByteArray("Abcd"),
NArray2Uint64: t.NArray2Uint64{0, 1},
NSetUint64: t.NSetUint64{1},
NMapUint64String: t.NMapUint64String{1: "A"},
NStruct: t.NStruct{
A: true,
},
NUnion: t.NUnion{
A: true,
},
TypeObject: typeobject(bool),
},
// Ensure that message with multiple type ids (including repeats) are represented
// properly.
t.AnySlice{
t.NInt16(1),
t.NInt32(2),
t.NInt64(3),
t.NInt32(4),
},
[]t.StructAny{
t.StructAny{t.NInt16(1)},
t.StructAny{t.NInt32(2)},
t.StructAny{t.NInt64(3)},
t.StructAny{t.NInt32(4)},
},
}
const encodeDecodeDataMin81 = []any{
int8(0), int8(-128), int8(127),
t.NInt8(0), t.NInt8(-128), t.NInt8(127),
any(int8(0)), any(int8(1)), typeobject(int8),
t.MInt8Slice{-128, -1, 0, 127},
t.StructAny{int8(1)},
}
// compatData is used to generate CompatTests in vomdata.vdl, and is used to
// test vom type compatibility. The mapping is from test name to a slice of
// types that must be mutually compatible with each other. Types with different
// test names must be incompatible with each other.
const compatData = map[string][]typeobject{
"bool": {
typeobject(bool), typeobject(t.NBool), typeobject(t.MBool),
},
"number": {
typeobject(uint16),typeobject(uint32),typeobject(uint64),
typeobject(int16),typeobject(int32),typeobject(int64),
typeobject(float32),typeobject(float64),
typeobject(t.NUint16),typeobject(t.NUint32),typeobject(t.NUint64),
typeobject(t.NInt16),typeobject(t.NInt32),typeobject(t.NInt64),
typeobject(t.NFloat32),typeobject(t.NFloat64),
},
"string/[]byte/enum": {
typeobject(string),typeobject(t.NString),
typeobject([]byte),typeobject(t.NByteSlice),typeobject(t.NByteArray),
typeobject(t.NEnum),
},
"number list/array": { // number lists
typeobject([]int32),typeobject(t.NArray2Uint64),typeobject(t.NListUint64),
},
"string list/array": { // string lists
typeobject([]string),typeobject(t.ListString),typeobject(t.Array3String),typeobject(t.Array4String),
},
"struct A": { // structs with themselves (1 common field)
typeobject(t.NStruct),typeobject(t.AbcStruct),typeobject(t.AdeStruct),
},
"struct Z": { // structs with themselves (a different common field)
typeobject(t.XyzStruct),typeobject(t.YzStruct),typeobject(t.ZStruct),
},
"map[string]X/struct": { // maps and structs (all fields have compatible types)
typeobject(t.MapOnlyStruct),typeobject(t.StructOnlyMap),
},
"map[string]bool/set[string]/struct": { // maps, sets, and structs (elem/field are bool)
typeobject(t.MapSetStruct),typeobject(t.SetStructMap),typeobject(t.MapStructSet),
},
"map[X]bool/set[X]": { // maps and sets (non-string keys)
typeobject(t.SetOnlyMap),typeobject(t.MapOnlySet), typeobject(t.SometimesSetMap),
},
"union B": {
typeobject(t.NUnion),typeobject(t.BdeUnion),
},
"typeobject": {
typeobject(typeobject),
},
}
// convertData is used to generate ConvertTests in vomdata.vdl, and is used to
// test vom value convertibility. The mapping is from test name to a slice of
// ordered ConvertGroups. All values within the same ConvertGroup must be
// convertible to each other. Values in ConvertGroups with a larger index will
// return an error when conversion is attempted to the primary type of
// ConvertGroups with a lower index.
const convertData = map[string][]t.ConvertGroup{
"bool": {
{
"bool",
typeobject(bool),
{
true,
t.NBool(true),
t.MBool(true),
},
},
},
"number": {
{
"byte",
typeobject(byte),
{
byte(3),uint16(3),int32(3),float64(3),int64(3),
},
},
{
"uint16",
typeobject(uint16),
{
uint16(256),int32(256),float64(256),int64(256),
},
},
{
"int32",
typeobject(int32),
{
int32(-5),float64(-5),int64(-5),
// int8(-5), // TODO(bprosnitz) In order to add int8, we need VOM support in java because it uses VOM for conversion.
},
},
{
"float64",
typeobject(float64),
{
float64(3.3),
},
},
{
"int64",
typeobject(int64),
{
int64(-0x8000000000000000),
},
},
},
"string and enum": {
{
"enum (A)",
typeobject(t.NEnum),
{
"A",
t.NString("A"),
t.NEnum.A,
},
},
{
"enum (brie)",
typeobject(t.BrieEnum),
{
"Brie",
t.NString("Brie"),
t.BrieEnum.Brie,
t.FoodEnum.Brie,
},
},
{
"string",
typeobject(t.NString),
{
"Cherry",
t.NString("Cherry"),
t.FoodEnum.Cherry,
},
},
},
"struct, map, and set": {
{
"map[uint32]uint32",
typeobject(t.MapOnlyA),
{
t.MapOnlyA{
4: 0,
6: 7,
},
t.MapOnlyA2{
4: 0,
6: 7.0,
},
},
},
{
"map[bool]string",
typeobject(t.MapOnlyB),
{
t.MapOnlyB{
true: "hello",
},
t.MapOnlyB2{
true: "hello",
},
},
},
{
"set[bool]",
typeobject(t.SetOnlyA),
{
t.SetOnlyA{
true,
false,
},
t.SetOnlyA2{
true,
false,
},
},
},
{
"set[int16]",
typeobject(t.SetOnlyB),
{
t.SetOnlyB{
4,
6,
},
t.SetOnlyB2{
4,
6,
},
},
},
{
"structABC",
typeobject(t.AbcStruct),
{
t.AbcStruct{
A: true,
B: "",
C: 0,
},
t.AdeStruct{
A: true,
D: nil,
E: typeobject(any),
},
t.NStruct{
A: true,
},
},
},
{
"structYz",
typeobject(t.YzStruct),
{
t.XyzStruct{
Z: "ahoy",
},
t.YzStruct{
Z: "ahoy",
},
t.ZStruct{
Z: "ahoy",
},
},
},
{
"struct+map",
typeobject(t.MapOnlyStruct),
{
t.StructOnlyMap{
"Key1": 4,
"Key2": 5,
},
t.MapOnlyStruct{
Key1: 4,
Key2: 5,
},
},
},
{
"map+set",
typeobject(t.MapOnlySet),
{
t.MapOnlySet{
3.14,
8,
},
t.SometimesSetMap{
3.14: true,
8: true,
},
t.SetOnlyMap{
3.14: true,
8: true,
},
},
},
{ // questionable because it works...
"map-set",
typeobject(t.SetOnlyMap),
{
t.SometimesSetMap{
3.14: "cannot be a set anymore",
8: true,
},
},
},
{
"struct+map+set",
typeobject(t.MapStructSet),
{
t.MapStructSet{
"Feat",
"Tire",
"Eel",
},
t.SetStructMap{
"Feat": true,
"Tire": true,
"Eel": true,
},
t.MapSetStruct{
Feat: true,
Tire: true,
Eel: true,
},
},
},
},
"array/list": {
{
"[3]string",
typeobject(t.Array3String),
{
t.Array3String{
"A",
"B",
"C",
},
[]string{
"A",
"B",
"C",
},
// I really want to check [3]string to [4]string...
},
},
{
"[4]string",
typeobject(t.Array4String),
{
t.Array4String{
"D",
"E",
"F",
"G",
},
},
},
{
"ByteArray",
typeobject(t.NByteArray),
{
t.NByteArray{
5,
2,
0,
4,
},
[]byte{
5,
2,
0,
4,
},
// I really want to omit some of these bytes...
},
},
},
"typeobject": {
{
"typeobject(any)",
typeobject(typeobject),
{
typeobject(any),
},
},
},
"union": {
{
"BdeUnion",
typeobject(t.BdeUnion),
{
t.BdeUnion{
B: "bde",
},
t.NUnion{
B: "bde",
},
},
},
{
"BdeUnion fail",
typeobject(t.NUnion),
{
t.NUnion{
A: true,
},
},
},
},
}
const x = t.VomdataStruct{
EncodeDecodeData: map[byte][]any{
0x80: encodeDecodeData,
0x81: encodeDecodeDataMin81,
},
CompatData: compatData,
ConvertData: convertData,
}