core.go: The vdl "any" type is now generated as go *vdl.Value.
Previously we were generating as vdl.AnyRep, which was another
name for interface{}. There are multiple problems with using
interface{}:
1) Decoding into an "interface{}" requires that the type has
been registered with VDL, and uses our type name based
matching logic. This is error prone; if we happen to change
the package path, the type name changes. And if the type
isn't registered, we'll end up with a *vdl.Value anyways.
Now there's no ambiguity; you always get a *vdl.Value, which
can represent values of all vdl types.
2) Some Go values aren't valid in VDL. E.g. Go values that
contain channels, functions or unsafe pointers are all
invalid. Using *vdl.Value at our API boundaries forces the
callers to make an informed decision.
This is the main portion of a 7-part CL, which removes
vdl.AnyRep, and uses *vdl.Value instead.
MultiPart: 1/7
Change-Id: Ie4f3ab6bce0363f82f53c2315a7435844f6ffe85
diff --git a/runtimes/google/ipc/benchmark/service.vdl.go b/runtimes/google/ipc/benchmark/service.vdl.go
index 982b669..97bc4d0 100644
--- a/runtimes/google/ipc/benchmark/service.vdl.go
+++ b/runtimes/google/ipc/benchmark/service.vdl.go
@@ -257,12 +257,12 @@
OutArgs: []ipc.ArgDesc{
{"", ``}, // []byte
},
- Tags: []vdl.AnyRep{access.Tag("Read")},
+ Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
},
{
Name: "EchoStream",
Doc: "// EchoStream returns the payload that it receives via the stream.",
- Tags: []vdl.AnyRep{access.Tag("Read")},
+ Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
},
},
}
diff --git a/runtimes/google/ipc/client.go b/runtimes/google/ipc/client.go
index c3e7136..eeb9ef5 100644
--- a/runtimes/google/ipc/client.go
+++ b/runtimes/google/ipc/client.go
@@ -306,7 +306,7 @@
return
}
-func mkDischargeImpetus(serverBlessings []string, method string, args []interface{}) security.DischargeImpetus {
+func mkDischargeImpetus(serverBlessings []string, method string, args []interface{}) (security.DischargeImpetus, error) {
var impetus security.DischargeImpetus
if len(serverBlessings) > 0 {
impetus.Server = make([]security.BlessingPattern, len(serverBlessings))
@@ -316,12 +316,16 @@
}
impetus.Method = method
if len(args) > 0 {
- impetus.Arguments = make([]vdl.AnyRep, len(args))
+ impetus.Arguments = make([]*vdl.Value, len(args))
for i, a := range args {
- impetus.Arguments[i] = vdl.AnyRep(a)
+ vArg, err := vdl.ValueFromReflect(reflect.ValueOf(a))
+ if err != nil {
+ return security.DischargeImpetus{}, err
+ }
+ impetus.Arguments[i] = vArg
}
}
- return impetus
+ return impetus, nil
}
// startCall ensures StartCall always returns verror.Standard.
@@ -785,7 +789,13 @@
// Fetch any discharges for third-party caveats on the client's blessings
// if this client owns a discharge-client.
if self := fc.flow.LocalBlessings(); self != nil && fc.dc != nil {
- fc.discharges = fc.dc.PrepareDischarges(fc.ctx, self.ThirdPartyCaveats(), mkDischargeImpetus(fc.server, method, args))
+ impetus, err := mkDischargeImpetus(fc.server, method, args)
+ if err != nil {
+ // TODO(toddw): Fix up the internal error.
+ berr := verror.New(verror.ErrBadProtocol, fc.ctx, fmt.Errorf("couldn't make discharge impetus: %v", err))
+ return fc.close(berr)
+ }
+ fc.discharges = fc.dc.PrepareDischarges(fc.ctx, self.ThirdPartyCaveats(), impetus)
}
// Encode the Blessings information for the client to authorize the flow.
var blessingsRequest ipc.BlessingsRequest
diff --git a/runtimes/google/ipc/discharges.go b/runtimes/google/ipc/discharges.go
index 7cb3155..c3db3fa 100644
--- a/runtimes/google/ipc/discharges.go
+++ b/runtimes/google/ipc/discharges.go
@@ -200,9 +200,9 @@
after.Method = before.Method
}
if r.ReportArguments && len(before.Arguments) > 0 {
- after.Arguments = make([]vdl.AnyRep, len(before.Arguments))
+ after.Arguments = make([]*vdl.Value, len(before.Arguments))
for i := range before.Arguments {
- after.Arguments[i] = before.Arguments[i]
+ after.Arguments[i] = vdl.CopyValue(before.Arguments[i])
}
}
return
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index 61d7773..811c8b9 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -921,7 +921,7 @@
},
{ // Require everything
Requirements: security.ThirdPartyRequirements{ReportServer: true, ReportMethod: true, ReportArguments: true},
- Impetus: security.DischargeImpetus{Server: []security.BlessingPattern{"server"}, Method: "Method", Arguments: []vdl.AnyRep{vdl.AnyRep("argument")}},
+ Impetus: security.DischargeImpetus{Server: []security.BlessingPattern{"server"}, Method: "Method", Arguments: []*vdl.Value{vdl.StringValue("argument")}},
},
{ // Require only the method name
Requirements: security.ThirdPartyRequirements{ReportMethod: true},
diff --git a/runtimes/google/ipc/reserved.go b/runtimes/google/ipc/reserved.go
index ad82471..d202b30 100644
--- a/runtimes/google/ipc/reserved.go
+++ b/runtimes/google/ipc/reserved.go
@@ -9,6 +9,7 @@
"v.io/core/veyron2/naming"
"v.io/core/veyron2/security"
"v.io/core/veyron2/services/security/access"
+ "v.io/core/veyron2/vdl"
"v.io/core/veyron2/vdl/vdlroot/src/signature"
"v.io/core/veyron2/vlog"
@@ -194,10 +195,10 @@
}
disp := i.dispNormal
call.M.Method = ipc.GlobMethod
- call.M.MethodTags = []interface{}{access.Resolve}
+ call.M.MethodTags = []*vdl.Value{vdl.ValueOf(access.Resolve)}
if naming.IsReserved(i.receiver) || (i.receiver == "" && naming.IsReserved(pattern)) {
disp = i.dispReserved
- call.M.MethodTags = []interface{}{access.Debug}
+ call.M.MethodTags = []*vdl.Value{vdl.ValueOf(access.Debug)}
}
if disp == nil {
return ipc.NewErrGlobNotImplemented(call.Context(), i.receiver)
@@ -346,7 +347,7 @@
func (c *mutableContext) Context() *context.T { return c.T }
func (c *mutableContext) Timestamp() time.Time { return c.M.Timestamp }
func (c *mutableContext) Method() string { return c.M.Method }
-func (c *mutableContext) MethodTags() []interface{} { return c.M.MethodTags }
+func (c *mutableContext) MethodTags() []*vdl.Value { return c.M.MethodTags }
func (c *mutableContext) Name() string { return c.M.Suffix }
func (c *mutableContext) Suffix() string { return c.M.Suffix }
func (c *mutableContext) LocalPrincipal() security.Principal { return c.M.LocalPrincipal }
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index 85a6f35..84fad16 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -18,6 +18,7 @@
"v.io/core/veyron2/options"
"v.io/core/veyron2/security"
"v.io/core/veyron2/services/security/access"
+ "v.io/core/veyron2/vdl"
"v.io/core/veyron2/verror"
"v.io/core/veyron2/vlog"
"v.io/core/veyron2/vom"
@@ -921,7 +922,7 @@
ackBlessings bool
blessings security.Blessings
method, suffix string
- tags []interface{}
+ tags []*vdl.Value
discharges map[string]security.Discharge
starttime time.Time
endStreamArgs bool // are the stream args at EOF?
@@ -1213,8 +1214,8 @@
ipc.ServerContext
}
-func (debugContext) MethodTags() []interface{} {
- return []interface{}{access.Debug}
+func (debugContext) MethodTags() []*vdl.Value {
+ return []*vdl.Value{vdl.ValueOf(access.Debug)}
}
// Send implements the ipc.Stream method.
@@ -1259,7 +1260,7 @@
//nologcall
return fs.method
}
-func (fs *flowServer) MethodTags() []interface{} {
+func (fs *flowServer) MethodTags() []*vdl.Value {
//nologcall
return fs.tags
}
diff --git a/security/agent/client.go b/security/agent/client.go
index ef426df..dc47c95 100644
--- a/security/agent/client.go
+++ b/security/agent/client.go
@@ -132,11 +132,11 @@
}
func (c *client) MintDischarge(forCaveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge ...security.Caveat) (security.Discharge, error) {
- var discharge security.Discharge
+ var discharge security.WireDischarge
if err := c.caller.call("MintDischarge", results(&discharge), forCaveat, caveatOnDischarge, additionalCaveatsOnDischarge); err != nil {
return nil, err
}
- return discharge, nil
+ return security.NewDischarge(discharge)
}
func (c *client) PublicKey() security.PublicKey {
diff --git a/security/agent/server/server.go b/security/agent/server/server.go
index b76b845..c397152 100644
--- a/security/agent/server/server.go
+++ b/security/agent/server/server.go
@@ -21,7 +21,6 @@
"v.io/core/veyron2/ipc"
"v.io/core/veyron2/options"
"v.io/core/veyron2/security"
- "v.io/core/veyron2/vdl"
"v.io/core/veyron2/verror"
"v.io/core/veyron2/vlog"
)
@@ -300,8 +299,12 @@
return a.principal.Sign(message)
}
-func (a agentd) MintDischarge(_ ipc.ServerContext, forCaveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (vdl.AnyRep, error) {
- return a.principal.MintDischarge(forCaveat, caveatOnDischarge, additionalCaveatsOnDischarge...)
+func (a agentd) MintDischarge(_ ipc.ServerContext, forCaveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (security.WireDischarge, error) {
+ d, err := a.principal.MintDischarge(forCaveat, caveatOnDischarge, additionalCaveatsOnDischarge...)
+ if err != nil {
+ return nil, err
+ }
+ return security.MarshalDischarge(d), nil
}
func (a keymgr) newKey(in_memory bool) (id []byte, data *keyData, err error) {
diff --git a/security/agent/server/wire.vdl b/security/agent/server/wire.vdl
index a1996c6..d1736d1 100644
--- a/security/agent/server/wire.vdl
+++ b/security/agent/server/wire.vdl
@@ -38,7 +38,7 @@
Bless(key []byte, wit security.WireBlessings, extension string, caveat security.Caveat, additionalCaveats []security.Caveat) (security.WireBlessings | error)
BlessSelf(name string, caveats []security.Caveat) (security.WireBlessings | error)
Sign(message []byte) (security.Signature | error)
- MintDischarge(forCaveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (any | error)
+ MintDischarge(forCaveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (security.WireDischarge | error)
PublicKey() ([]byte | error)
BlessingsByName(name security.BlessingPattern) ([]security.WireBlessings | error)
BlessingsInfo(blessings security.WireBlessings) (map[string][]security.Caveat | error)
diff --git a/security/agent/server/wire.vdl.go b/security/agent/server/wire.vdl.go
index 3414e1c..9d0933a 100644
--- a/security/agent/server/wire.vdl.go
+++ b/security/agent/server/wire.vdl.go
@@ -9,7 +9,6 @@
"v.io/core/veyron2"
"v.io/core/veyron2/context"
"v.io/core/veyron2/ipc"
- "v.io/core/veyron2/vdl"
// VDL user imports
"v.io/core/veyron2/security"
@@ -21,7 +20,7 @@
Bless(ctx *context.T, key []byte, wit security.WireBlessings, extension string, caveat security.Caveat, additionalCaveats []security.Caveat, opts ...ipc.CallOpt) (security.WireBlessings, error)
BlessSelf(ctx *context.T, name string, caveats []security.Caveat, opts ...ipc.CallOpt) (security.WireBlessings, error)
Sign(ctx *context.T, message []byte, opts ...ipc.CallOpt) (security.Signature, error)
- MintDischarge(ctx *context.T, forCaveat security.Caveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat, opts ...ipc.CallOpt) (vdl.AnyRep, error)
+ MintDischarge(ctx *context.T, forCaveat security.Caveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat, opts ...ipc.CallOpt) (security.WireDischarge, error)
PublicKey(*context.T, ...ipc.CallOpt) ([]byte, error)
BlessingsByName(ctx *context.T, name security.BlessingPattern, opts ...ipc.CallOpt) ([]security.WireBlessings, error)
BlessingsInfo(ctx *context.T, blessings security.WireBlessings, opts ...ipc.CallOpt) (map[string][]security.Caveat, error)
@@ -98,7 +97,7 @@
return
}
-func (c implAgentClientStub) MintDischarge(ctx *context.T, i0 security.Caveat, i1 security.Caveat, i2 []security.Caveat, opts ...ipc.CallOpt) (o0 vdl.AnyRep, err error) {
+func (c implAgentClientStub) MintDischarge(ctx *context.T, i0 security.Caveat, i1 security.Caveat, i2 []security.Caveat, opts ...ipc.CallOpt) (o0 security.WireDischarge, err error) {
var call ipc.Call
if call, err = c.c(ctx).StartCall(ctx, c.name, "MintDischarge", []interface{}{i0, i1, i2}, opts...); err != nil {
return
@@ -307,7 +306,7 @@
Bless(ctx ipc.ServerContext, key []byte, wit security.WireBlessings, extension string, caveat security.Caveat, additionalCaveats []security.Caveat) (security.WireBlessings, error)
BlessSelf(ctx ipc.ServerContext, name string, caveats []security.Caveat) (security.WireBlessings, error)
Sign(ctx ipc.ServerContext, message []byte) (security.Signature, error)
- MintDischarge(ctx ipc.ServerContext, forCaveat security.Caveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (vdl.AnyRep, error)
+ MintDischarge(ctx ipc.ServerContext, forCaveat security.Caveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (security.WireDischarge, error)
PublicKey(ipc.ServerContext) ([]byte, error)
BlessingsByName(ctx ipc.ServerContext, name security.BlessingPattern) ([]security.WireBlessings, error)
BlessingsInfo(ctx ipc.ServerContext, blessings security.WireBlessings) (map[string][]security.Caveat, error)
@@ -336,7 +335,7 @@
Bless(ctx ipc.ServerContext, key []byte, wit security.WireBlessings, extension string, caveat security.Caveat, additionalCaveats []security.Caveat) (security.WireBlessings, error)
BlessSelf(ctx ipc.ServerContext, name string, caveats []security.Caveat) (security.WireBlessings, error)
Sign(ctx ipc.ServerContext, message []byte) (security.Signature, error)
- MintDischarge(ctx ipc.ServerContext, forCaveat security.Caveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (vdl.AnyRep, error)
+ MintDischarge(ctx ipc.ServerContext, forCaveat security.Caveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (security.WireDischarge, error)
PublicKey(ipc.ServerContext) ([]byte, error)
BlessingsByName(ctx ipc.ServerContext, name security.BlessingPattern) ([]security.WireBlessings, error)
BlessingsInfo(ctx ipc.ServerContext, blessings security.WireBlessings) (map[string][]security.Caveat, error)
@@ -398,7 +397,7 @@
return s.impl.Sign(ctx, i0)
}
-func (s implAgentServerStub) MintDischarge(ctx ipc.ServerContext, i0 security.Caveat, i1 security.Caveat, i2 []security.Caveat) (vdl.AnyRep, error) {
+func (s implAgentServerStub) MintDischarge(ctx ipc.ServerContext, i0 security.Caveat, i1 security.Caveat, i2 []security.Caveat) (security.WireDischarge, error) {
return s.impl.MintDischarge(ctx, i0, i1, i2)
}
@@ -514,7 +513,7 @@
{"additionalCaveatsOnDischarge", ``}, // []security.Caveat
},
OutArgs: []ipc.ArgDesc{
- {"", ``}, // vdl.AnyRep
+ {"", ``}, // security.WireDischarge
},
},
{
diff --git a/services/mgmt/debug/dispatcher_test.go b/services/mgmt/debug/dispatcher_test.go
index 09e8f6b..8c59e3c 100644
--- a/services/mgmt/debug/dispatcher_test.go
+++ b/services/mgmt/debug/dispatcher_test.go
@@ -19,6 +19,7 @@
"v.io/core/veyron2/services/mgmt/logreader"
"v.io/core/veyron2/services/mgmt/stats"
vtracesvc "v.io/core/veyron2/services/mgmt/vtrace"
+ "v.io/core/veyron2/vdl"
"v.io/core/veyron2/verror"
"v.io/core/veyron2/vtrace"
@@ -127,8 +128,8 @@
if err != nil {
t.Errorf("Value failed: %v", err)
}
- if expected := int64(123); v != expected {
- t.Errorf("unexpected result. Got %v, want %v", v, expected)
+ if want := vdl.Int64Value(123); !vdl.EqualValue(v, want) {
+ t.Errorf("unexpected result. got %v, want %v", v, want)
}
}
diff --git a/services/mgmt/device/impl/instance_reaping.go b/services/mgmt/device/impl/instance_reaping.go
index 50aa130..d59c927 100644
--- a/services/mgmt/device/impl/instance_reaping.go
+++ b/services/mgmt/device/impl/instance_reaping.go
@@ -1,6 +1,7 @@
package impl
import (
+ "fmt"
"path/filepath"
"sync"
"syscall"
@@ -9,6 +10,7 @@
"v.io/core/veyron2/context"
"v.io/core/veyron2/naming"
"v.io/core/veyron2/services/mgmt/stats"
+ "v.io/core/veyron2/vdl"
"v.io/core/veyron2/vlog"
)
@@ -161,7 +163,14 @@
c <- ptuple
return
}
- pid := int(v.(int64))
+ // Convert the stat value from *vdl.Value into an int pid.
+ var pid int
+ if err := vdl.Convert(&pid, v); err != nil {
+ ptuple.err = fmt.Errorf("__debug/stats/system/pid isn't an integer: %v", err)
+ vlog.Errorf(ptuple.err.Error())
+ c <- ptuple
+ return
+ }
ptuple.pid = pid
// Update the instance info.
diff --git a/services/mgmt/device/impl/instance_reaping_test.go b/services/mgmt/device/impl/instance_reaping_test.go
index bd2a50e..17f376a 100644
--- a/services/mgmt/device/impl/instance_reaping_test.go
+++ b/services/mgmt/device/impl/instance_reaping_test.go
@@ -12,6 +12,7 @@
"v.io/core/veyron2/naming"
"v.io/core/veyron2/services/mgmt/application"
"v.io/core/veyron2/services/mgmt/stats"
+ "v.io/core/veyron2/vdl"
"v.io/core/veyron/lib/flags/consts"
"v.io/core/veyron/lib/modules"
@@ -79,9 +80,9 @@
if err != nil {
t.Fatalf("Value() failed: %v\n", err)
}
- pid, ok := v.(int64)
- if !ok {
- t.Fatalf("pid returned from stats interface is not an int")
+ var pid int
+ if err := vdl.Convert(&pid, v); err != nil {
+ t.Fatalf("pid returned from stats interface is not an int: %v", err)
}
verifyAppState(t, root, appID, instance1ID, "started")
@@ -111,7 +112,7 @@
if err != nil {
t.Fatalf("Value() failed: %v\n", err)
}
- return int(v.(int64))
+ return int(v.Int())
}
func TestReapReconciliation(t *testing.T) {
diff --git a/services/mgmt/device/impl/proxy_invoker.go b/services/mgmt/device/impl/proxy_invoker.go
index 340ca7c..96b7359 100644
--- a/services/mgmt/device/impl/proxy_invoker.go
+++ b/services/mgmt/device/impl/proxy_invoker.go
@@ -8,6 +8,7 @@
"v.io/core/veyron2/ipc"
"v.io/core/veyron2/naming"
"v.io/core/veyron2/services/security/access"
+ "v.io/core/veyron2/vdl"
"v.io/core/veyron2/vdl/vdlroot/src/signature"
)
@@ -36,13 +37,15 @@
var _ ipc.Invoker = (*proxyInvoker)(nil)
-func (p *proxyInvoker) Prepare(method string, numArgs int) (argptrs, tags []interface{}, err error) {
+func (p *proxyInvoker) Prepare(method string, numArgs int) (argptrs []interface{}, tags []*vdl.Value, _ error) {
+ // TODO(toddw): Change argptrs to be filled in with *vdl.Value, to avoid
+ // unnecessary type lookups.
argptrs = make([]interface{}, numArgs)
for i, _ := range argptrs {
var x interface{}
argptrs[i] = &x
}
- tags = []interface{}{p.access}
+ tags = []*vdl.Value{vdl.ValueOf(p.access)}
return
}
diff --git a/services/mgmt/repository/repository.vdl.go b/services/mgmt/repository/repository.vdl.go
index a460dca..b2aab89 100644
--- a/services/mgmt/repository/repository.vdl.go
+++ b/services/mgmt/repository/repository.vdl.go
@@ -205,7 +205,7 @@
{"Profiles", ``}, // []string
{"Envelope", ``}, // application.Envelope
},
- Tags: []vdl.AnyRep{access.Tag("Write")},
+ Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
},
{
Name: "Remove",
@@ -213,7 +213,7 @@
InArgs: []ipc.ArgDesc{
{"Profile", ``}, // string
},
- Tags: []vdl.AnyRep{access.Tag("Write")},
+ Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
},
},
}
@@ -395,7 +395,7 @@
OutArgs: []ipc.ArgDesc{
{"", ``}, // profile.Specification
},
- Tags: []vdl.AnyRep{access.Tag("Read")},
+ Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
},
{
Name: "Put",
@@ -403,12 +403,12 @@
InArgs: []ipc.ArgDesc{
{"Specification", ``}, // profile.Specification
},
- Tags: []vdl.AnyRep{access.Tag("Write")},
+ Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
},
{
Name: "Remove",
Doc: "// Remove removes the profile specification for the profile\n// identified through the object name suffix.",
- Tags: []vdl.AnyRep{access.Tag("Write")},
+ Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
},
},
}
diff --git a/services/mgmt/stats/impl/stats.go b/services/mgmt/stats/impl/stats.go
index 6585162..5df5f0d 100644
--- a/services/mgmt/stats/impl/stats.go
+++ b/services/mgmt/stats/impl/stats.go
@@ -3,6 +3,7 @@
package impl
import (
+ "reflect"
"time"
libstats "v.io/core/veyron/lib/stats"
@@ -69,7 +70,7 @@
c := watchtypes.Change{
Name: v.Key,
State: watchtypes.Exists,
- Value: v.Value,
+ Value: vdl.ValueOf(v.Value),
}
changes = append(changes, c)
}
@@ -94,18 +95,21 @@
}
// Value returns the value of the receiver object.
-func (i *statsService) Value(ctx ipc.ServerContext) (vdl.AnyRep, error) {
+func (i *statsService) Value(ctx ipc.ServerContext) (*vdl.Value, error) {
vlog.VI(1).Infof("%v.Value()", i.suffix)
- v, err := libstats.Value(i.suffix)
- switch err {
- case libstats.ErrNotFound:
+ rv, err := libstats.Value(i.suffix)
+ switch {
+ case err == libstats.ErrNotFound:
return nil, verror.New(verror.ErrNoExist, ctx.Context(), i.suffix)
- case libstats.ErrNoValue:
+ case err == libstats.ErrNoValue:
return nil, stats.NewErrNoValue(ctx.Context(), i.suffix)
- case nil:
- return v, nil
- default:
+ case err != nil:
return nil, verror.New(errOperationFailed, ctx.Context(), i.suffix)
}
+ vv, err := vdl.ValueFromReflect(reflect.ValueOf(rv))
+ if err != nil {
+ return nil, verror.New(verror.ErrInternal, ctx.Context(), i.suffix, err)
+ }
+ return vv, nil
}
diff --git a/services/mgmt/stats/impl/stats_test.go b/services/mgmt/stats/impl/stats_test.go
index fbc4fe9..f036846 100644
--- a/services/mgmt/stats/impl/stats_test.go
+++ b/services/mgmt/stats/impl/stats_test.go
@@ -12,6 +12,7 @@
"v.io/core/veyron2/security"
"v.io/core/veyron2/services/mgmt/stats"
"v.io/core/veyron2/services/watch/types"
+ "v.io/core/veyron2/vdl"
libstats "v.io/core/veyron/lib/stats"
"v.io/core/veyron/lib/stats/histogram"
@@ -106,7 +107,7 @@
t.Fatalf("expected more stream values")
}
got := iterator.Value()
- expected := types.Change{Name: "testing/foo/bar", Value: int64(10), ResumeMarker: noRM}
+ expected := types.Change{Name: "testing/foo/bar", Value: vdl.Int64Value(10), ResumeMarker: noRM}
if !reflect.DeepEqual(got, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", got, expected)
}
@@ -117,7 +118,7 @@
t.Fatalf("expected more stream values")
}
got = iterator.Value()
- expected = types.Change{Name: "testing/foo/bar", Value: int64(15), ResumeMarker: noRM}
+ expected = types.Change{Name: "testing/foo/bar", Value: vdl.Int64Value(15), ResumeMarker: noRM}
if !reflect.DeepEqual(got, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", got, expected)
}
@@ -128,7 +129,7 @@
t.Fatalf("expected more stream values")
}
got = iterator.Value()
- expected = types.Change{Name: "testing/foo/bar", Value: int64(17), ResumeMarker: noRM}
+ expected = types.Change{Name: "testing/foo/bar", Value: vdl.Int64Value(17), ResumeMarker: noRM}
if !reflect.DeepEqual(got, expected) {
t.Errorf("unexpected result. Got %#v, want %#v", got, expected)
}
@@ -146,8 +147,8 @@
if err != nil {
t.Errorf("unexpected error: %v", err)
}
- if expected := int64(17); value != expected {
- t.Errorf("unexpected result. Got %v, want %v", value, expected)
+ if want := vdl.Int64Value(17); !vdl.EqualValue(value, want) {
+ t.Errorf("unexpected result. Got %v, want %v", value, want)
}
}
@@ -158,7 +159,7 @@
if err != nil {
t.Errorf("unexpected error: %v", err)
}
- want := istats.HistogramValue{
+ want := vdl.ValueOf(istats.HistogramValue{
Count: 10,
Sum: 45,
Min: 0,
@@ -170,9 +171,9 @@
istats.HistogramBucket{LowBound: 7, Count: 3},
istats.HistogramBucket{LowBound: 15, Count: 0},
},
- }
- if !reflect.DeepEqual(value, want) {
- t.Errorf("unexpected result. Got %#v, want %#v", value, want)
+ })
+ if !vdl.EqualValue(value, want) {
+ t.Errorf("unexpected result. Got %v, want %v", value, want)
}
}
}
diff --git a/tools/debug/debug_v23_test.go b/tools/debug/debug_v23_test.go
index dee8b6a..5bf53a0 100644
--- a/tools/debug/debug_v23_test.go
+++ b/tools/debug/debug_v23_test.go
@@ -136,7 +136,7 @@
i.Errorf("Timed out waiting for output")
case got := <-lineChan:
// Expect one ReadLog call to have occurred.
- want := "latency-ms: {Count:1"
+ want := "}}{Count: 1"
if !strings.Contains(got, want) {
i.Errorf("wanted but could not find %q in output\n%s", want, got)
}
diff --git a/tools/debug/impl.go b/tools/debug/impl.go
index a4f9473..6c5d215 100644
--- a/tools/debug/impl.go
+++ b/tools/debug/impl.go
@@ -1,7 +1,6 @@
package main
import (
- "bytes"
"fmt"
"os"
"os/exec"
@@ -14,7 +13,6 @@
"v.io/core/veyron/lib/glob"
"v.io/core/veyron/lib/signals"
"v.io/core/veyron/services/mgmt/pprof/client"
- istats "v.io/core/veyron/services/mgmt/stats"
"v.io/core/veyron2"
"v.io/core/veyron2/context"
"v.io/core/veyron2/naming"
@@ -26,6 +24,7 @@
"v.io/core/veyron2/services/watch"
watchtypes "v.io/core/veyron2/services/watch/types"
"v.io/core/veyron2/uniqueid"
+ "v.io/core/veyron2/vdl"
"v.io/core/veyron2/vtrace"
"v.io/lib/cmdline"
)
@@ -330,7 +329,12 @@
errors <- fmt.Errorf("%s: %v", name, err)
return
}
- output <- fmt.Sprintf("%s: %v", name, formatValue(v))
+ fv, err := formatValue(v)
+ if err != nil {
+ errors <- fmt.Errorf("%s: %v", name, err)
+ // fv is still valid, so dump it out too.
+ }
+ output <- fmt.Sprintf("%s: %v", name, fv)
}
var cmdStatsWatch = &cmdline.Command{
@@ -402,7 +406,12 @@
iterator := stream.RecvStream()
for iterator.Advance() {
v := iterator.Value()
- results <- fmt.Sprintf("%s: %s", naming.Join(name, v.Name), formatValue(v.Value))
+ fv, err := formatValue(v.Value)
+ if err != nil {
+ errors <- fmt.Errorf("%s: %v", name, err)
+ // fv is still valid, so dump it out too.
+ }
+ results <- fmt.Sprintf("%s: %s", naming.Join(name, v.Name), fv)
}
if err = iterator.Err(); err != nil {
errors <- fmt.Errorf("%s: %v", name, err)
@@ -414,22 +423,24 @@
}
}
-func formatValue(value interface{}) string {
- var buf bytes.Buffer
+func formatValue(value *vdl.Value) (string, error) {
+ var ret string
if showType {
- fmt.Fprintf(&buf, "%T: ", value)
+ ret += value.Type().String() + ": "
}
if raw {
- if v, ok := value.(istats.HistogramValue); ok {
- // Bypass HistogramValue.String()
- type hist istats.HistogramValue
- value = hist(v)
- }
- fmt.Fprintf(&buf, "%+v", value)
- return buf.String()
+ return ret + value.String(), nil
}
- fmt.Fprintf(&buf, "%v", value)
- return buf.String()
+ // Convert the *vdl.Value into an interface{}, so that things like histograms
+ // get pretty-printed.
+ var pretty interface{}
+ err := vdl.Convert(&pretty, value)
+ if err != nil {
+ // If we can't convert, just print the raw value, but still return an error.
+ err = fmt.Errorf("couldn't pretty-print, consider setting -raw: %v", err)
+ pretty = value
+ }
+ return ret + fmt.Sprint(pretty), err
}
var cmdPProfRun = &cmdline.Command{