Merge "v23: Added server option for lame duck timeout"
diff --git a/flow/message/.api b/flow/message/.api
index 69c0ff5..f292239 100644
--- a/flow/message/.api
+++ b/flow/message/.api
@@ -41,9 +41,11 @@
pkg message, type Release struct
pkg message, type Release struct, Counters map[uint64]uint64
pkg message, type Setup struct
+pkg message, type Setup struct, Mtu uint64
pkg message, type Setup struct, PeerLocalEndpoint naming.Endpoint
pkg message, type Setup struct, PeerNaClPublicKey *[32]byte
pkg message, type Setup struct, PeerRemoteEndpoint naming.Endpoint
+pkg message, type Setup struct, SharedTokens uint64
pkg message, type Setup struct, Versions version.RPCVersionRange
pkg message, type TearDown struct
pkg message, type TearDown struct, Message string
diff --git a/flow/message/message.go b/flow/message/message.go
index 2aceebc..1ba0f70 100644
--- a/flow/message/message.go
+++ b/flow/message/message.go
@@ -99,6 +99,8 @@
peerNaClPublicKeyOption
peerRemoteEndpointOption
peerLocalEndpointOption
+ mtuOption
+ sharedTokensOption
)
// data flags.
@@ -125,11 +127,15 @@
// Setup is the first message over the wire. It negotiates protocol version
// and encryption options for connection.
+// New fields to Setup must be added in order of creation. i.e. the order of the fields
+// should not be changed.
type Setup struct {
Versions version.RPCVersionRange
PeerNaClPublicKey *[32]byte
PeerRemoteEndpoint naming.Endpoint
PeerLocalEndpoint naming.Endpoint
+ Mtu uint64
+ SharedTokens uint64
uninterpretedOptions []option
}
@@ -167,6 +173,12 @@
data = appendSetupOption(peerLocalEndpointOption,
[]byte(m.PeerLocalEndpoint.String()), data)
}
+ if m.Mtu != 0 {
+ data = appendSetupOption(mtuOption, writeVarUint64(m.Mtu, nil), data)
+ }
+ if m.SharedTokens != 0 {
+ data = appendSetupOption(sharedTokensOption, writeVarUint64(m.SharedTokens, nil), data)
+ }
for _, o := range m.uninterpretedOptions {
data = appendSetupOption(o.opt, o.payload, data)
}
@@ -203,6 +215,18 @@
m.PeerRemoteEndpoint, err = v23.NewEndpoint(string(payload))
case peerLocalEndpointOption:
m.PeerLocalEndpoint, err = v23.NewEndpoint(string(payload))
+ case mtuOption:
+ if mtu, _, valid := readVarUint64(ctx, payload); valid {
+ m.Mtu = mtu
+ } else {
+ return NewErrInvalidSetupOption(ctx, opt, field)
+ }
+ case sharedTokensOption:
+ if t, _, valid := readVarUint64(ctx, payload); valid {
+ m.SharedTokens = t
+ } else {
+ return NewErrInvalidSetupOption(ctx, opt, field)
+ }
default:
m.uninterpretedOptions = append(m.uninterpretedOptions, option{opt, payload})
}
diff --git a/flow/message/message_test.go b/flow/message/message_test.go
index 5a2307d..8b829b7 100644
--- a/flow/message/message_test.go
+++ b/flow/message/message_test.go
@@ -60,6 +60,11 @@
PeerRemoteEndpoint: ep1,
PeerLocalEndpoint: ep2,
},
+ &message.Setup{
+ Versions: version.RPCVersionRange{Min: 3, Max: 5},
+ Mtu: 1 << 16,
+ SharedTokens: 1 << 20,
+ },
&message.Setup{},
})
}
diff --git a/rpc/.api b/rpc/.api
index d2b6325..5e36f82 100644
--- a/rpc/.api
+++ b/rpc/.api
@@ -8,10 +8,6 @@
pkg rpc, func NewGlobState(interface{}) *GlobState
pkg rpc, func ReflectInvoker(interface{}) (Invoker, error)
pkg rpc, func ReflectInvokerOrDie(interface{}) Invoker
-pkg rpc, func RegisterProtocol(string, DialerFunc, ResolverFunc, ListenerFunc, ...string) bool
-pkg rpc, func RegisterUnknownProtocol(string, DialerFunc, ResolverFunc, ListenerFunc) bool
-pkg rpc, func RegisteredProtocol(string) (DialerFunc, ResolverFunc, ListenerFunc, []string)
-pkg rpc, func RegisteredProtocols() []string
pkg rpc, func TypeCheckMethods(interface{}) map[string]error
pkg rpc, method (AddressChooserFunc) ChooseAddresses(string, []net.Addr) ([]net.Addr, error)
pkg rpc, method (ListenSpec) Copy() ListenSpec
@@ -48,7 +44,6 @@
pkg rpc, type ClientOpt interface, RPCClientOpt()
pkg rpc, type Describer interface { Describe__ }
pkg rpc, type Describer interface, Describe__() []InterfaceDesc
-pkg rpc, type DialerFunc func(ctx *context.T, protocol, address string, timeout time.Duration) (net.Conn, error)
pkg rpc, type Dispatcher interface { Lookup }
pkg rpc, type Dispatcher interface, Lookup(*context.T, string) (interface{}, security.Authorizer, error)
pkg rpc, type EmbedDesc struct
@@ -96,7 +91,6 @@
pkg rpc, type ListenSpec struct, Addrs ListenAddrs
pkg rpc, type ListenSpec struct, Proxy string
pkg rpc, type ListenSpec struct, embedded AddressChooser
-pkg rpc, type ListenerFunc func(ctx *context.T, protocol, address string) (net.Listener, error)
pkg rpc, type MethodDesc struct
pkg rpc, type MethodDesc struct, Doc string
pkg rpc, type MethodDesc struct, InArgs []ArgDesc
@@ -123,7 +117,6 @@
pkg rpc, type Request struct, NumPosArgs uint64
pkg rpc, type Request struct, Suffix string
pkg rpc, type Request struct, TraceRequest vtrace.Request
-pkg rpc, type ResolverFunc func(ctx *context.T, protocol, address string) (string, string, error)
pkg rpc, type Response struct
pkg rpc, type Response struct, AckBlessings bool
pkg rpc, type Response struct, EndStreamResults bool
diff --git a/rpc/registry.go b/rpc/registry.go
deleted file mode 100644
index 2dd9d35..0000000
--- a/rpc/registry.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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.
-
-package rpc
-
-import (
- "fmt"
- "net"
- "sync"
- "time"
-
- "v.io/v23/context"
- "v.io/v23/naming"
-)
-
-// This file is DEPRECATED. If you wish to add new protocols please you the
-// v23/flow.RegisterProtocol methods.
-// TODO(suharshs): Remove this file and corresponding protocols once the transition
-// to the new rpc implementation is complete.
-
-// DialerFunc is the function used to create net.Conn objects given a
-// protocol-specific string representation of an address.
-type DialerFunc func(ctx *context.T, protocol, address string, timeout time.Duration) (net.Conn, error)
-
-// ResolverFunc is the function used for protocol-specific address normalization.
-// e.g. the TCP resolve performs DNS resolution.
-type ResolverFunc func(ctx *context.T, protocol, address string) (string, string, error)
-
-// ListenerFunc is the function used to create net.Listener objects given a
-// protocol-specific string representation of the address a server will listen on.
-type ListenerFunc func(ctx *context.T, protocol, address string) (net.Listener, error)
-
-// RegisterProtocol makes available a Dialer, Resolver, and Listener to RegisteredNetwork.
-// If the protocol represents other actual protocols, you need to specify all the
-// actual protocols. E.g, "wsh" represents "tcp4", "tcp6", "ws4", and "ws6".
-//
-// Implementations of the Manager interface are expected to use this registry
-// in order to expand the reach of the types of network protocols they can
-// handle.
-//
-// Successive calls to RegisterProtocol replace the contents of a previous
-// call to it and returns trues if a previous value was replaced, false otherwise.
-func RegisterProtocol(protocol string, dialer DialerFunc, resolver ResolverFunc, listener ListenerFunc, p ...string) bool {
- // This is for handling the common case where protocol is a "singleton", to
- // make it easier to specify.
- if len(p) == 0 {
- p = []string{protocol}
- }
- registryLock.Lock()
- defer registryLock.Unlock()
- _, present := registry[protocol]
- registry[protocol] = registryEntry{dialer, resolver, listener, p}
- return present
-}
-
-// RegisterUnknownProtocol registers a Dialer, Resolver, and Listener for endpoints with
-// no specified protocol.
-//
-// The desired protocol provided in the first argument will be passed to the
-// Dialer and Listener as the actual protocol to use when dialing or listening.
-//
-// The protocol itself must have already been registered before RegisterUnknownProtocol
-// is called, otherwise we'll panic.
-func RegisterUnknownProtocol(protocol string, dialer DialerFunc, resolver ResolverFunc, listener ListenerFunc) bool {
- var p []string
- registryLock.RLock()
- r, present := registry[protocol]
- if !present {
- panic(fmt.Sprintf("%s not registered", protocol))
- }
- p = r.p
- registryLock.RUnlock()
- wrappedDialer := func(ctx *context.T, _, address string, timeout time.Duration) (net.Conn, error) {
- return dialer(ctx, protocol, address, timeout)
- }
- wrappedResolver := func(ctx *context.T, _, address string) (string, string, error) {
- return resolver(ctx, protocol, address)
- }
- wrappedListener := func(ctx *context.T, _, address string) (net.Listener, error) {
- return listener(ctx, protocol, address)
- }
- return RegisterProtocol(naming.UnknownProtocol, wrappedDialer, wrappedResolver, wrappedListener, p...)
-}
-
-// RegisteredProtocol returns the Dialer, Resolver, and Listener registered with a
-// previous call to RegisterProtocol.
-func RegisteredProtocol(protocol string) (DialerFunc, ResolverFunc, ListenerFunc, []string) {
- registryLock.RLock()
- e := registry[protocol]
- registryLock.RUnlock()
- return e.d, e.r, e.l, e.p
-}
-
-// RegisteredProtocols returns the list of protocols that have been previously
-// registered using RegisterProtocol. The underlying implementation will
-// support additional protocols such as those supported by the native RPC stack.
-func RegisteredProtocols() []string {
- registryLock.RLock()
- defer registryLock.RUnlock()
- p := make([]string, 0, len(registry))
- for k, _ := range registry {
- p = append(p, k)
- }
- return p
-}
-
-type registryEntry struct {
- d DialerFunc
- r ResolverFunc
- l ListenerFunc
- p []string
-}
-
-var (
- registryLock sync.RWMutex
- registry = make(map[string]registryEntry)
-)
diff --git a/rpc/version/.api b/rpc/version/.api
index 636365d..836c50c 100644
--- a/rpc/version/.api
+++ b/rpc/version/.api
@@ -3,6 +3,7 @@
pkg version, const RPCVersion11 RPCVersion
pkg version, const RPCVersion12 RPCVersion
pkg version, const RPCVersion13 RPCVersion
+pkg version, const RPCVersion14 RPCVersion
pkg version, const UnknownRPCVersion RPCVersion
pkg version, func CommonVersion(*context.T, RPCVersionRange, RPCVersionRange) (RPCVersion, error)
pkg version, func NewErrNoCompatibleVersion(*context.T, uint64, uint64, uint64, uint64) error
diff --git a/rpc/version/version.go b/rpc/version/version.go
index 01e27e8..c1b6d5a 100644
--- a/rpc/version/version.go
+++ b/rpc/version/version.go
@@ -43,6 +43,10 @@
// RPCVersion13 adds error messages in responses from proxies.
RPCVersion13
+
+ // RPCVersion14 adds the setup message to the channel binding during
+ // connection setup.
+ RPCVersion14
)
// RPCVersionRange allows you to optionally specify a range of versions to
diff --git a/security/ecdsa_go.go b/security/ecdsa_go.go
index 30ed8d8..bff1875 100644
--- a/security/ecdsa_go.go
+++ b/security/ecdsa_go.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !cgo noopenssl !linux,!openssl android !amd64,!openssl
+// +build go1.6 !cgo noopenssl !linux,!openssl android !amd64,!openssl
// See comments in ecdsa_openssl.go for an explanation of the choice of
// build tags.
diff --git a/security/ecdsa_openssl.go b/security/ecdsa_openssl.go
index e2914bc..e9573d7 100644
--- a/security/ecdsa_openssl.go
+++ b/security/ecdsa_openssl.go
@@ -2,21 +2,23 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !android,linux,amd64,cgo,!noopenssl openssl,cgo
+// +build !go1.6,!android,linux,amd64,cgo,!noopenssl openssl,cgo
// The purpose of this file is to improve performance, as demonstrated by
// benchmarks when linked against openssl-1.0.1f (with further improvements in
// openssl-1.0.2, at the time this comment was written).
// go test -bench ECDSA v.io/v23/security
//
-// See https://go-review.googlesource.com/#/c/8968/ for why the Go standard
-// library (as of Go 1.5) does not have performance on par with OpenSSL.
+// With Go 1.6, the Go standard library will have performance on-par with
+// OpenSSL for amd64 (see https://go-review.googlesource.com/#/c/8968/).
+// Prior to that however, using OpenSSL (via cgo) provides a significant
+// performance improvement.
//
// By default (without an explicit build tag), this is disabled for darwin
// since OpenSSL has been marked deprecated on OS X since version 10.7. The
// last openssl release on OS X was version 0.9.8 and compiling this file will
// show these deprecation warnings. Those sensitive to performance are
-// encouraged to compile a later version of OpenSSL and set the build tag.
+// encouraged to move to Go 1.6.
//
// Currently, this file is disabled for linux/arm as a temporary hack. In
// practice, linux/arm binaries are often cross-compiled on a linux/amd64 host.
diff --git a/security/ecdsa_openssl_test.go b/security/ecdsa_openssl_test.go
index 70408f6..cba249b 100644
--- a/security/ecdsa_openssl_test.go
+++ b/security/ecdsa_openssl_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !android,linux,amd64,cgo,!noopenssl openssl,cgo
+// +build !go1.6,!android,linux,amd64,cgo,!noopenssl openssl,cgo
package security
diff --git a/syncbase/featuretests/cr_v23_test.go b/syncbase/featuretests/cr_v23_test.go
index e5613f0..b7f84b1 100644
--- a/syncbase/featuretests/cr_v23_test.go
+++ b/syncbase/featuretests/cr_v23_test.go
@@ -33,6 +33,10 @@
// TODO(jlodhia): Add more rules based on value type and combination of key
// prefix and value type once its implemented.
func TestV23CRRuleConfig(t *testing.T) {
+ // TODO(jlodhia): Re-enable test after following issue is resolved.
+ // https://github.com/vanadium/issues/issues/1027
+ t.Skip()
+
v23test.SkipUnlessRunningIntegrationTests(t)
sh := v23test.NewShell(t, v23test.Opts{})
defer sh.Cleanup()
@@ -153,6 +157,10 @@
// 2) 5 rows written as a single batch on both syncbases resulting into a
// single conflict for the batch.
func TestV23CRAppResolved(t *testing.T) {
+ // TODO(jlodhia): Re-enable test after following issue is resolved.
+ // https://github.com/vanadium/issues/issues/1027
+ t.Skip()
+
v23test.SkipUnlessRunningIntegrationTests(t)
sh := v23test.NewShell(t, v23test.Opts{})
defer sh.Cleanup()
diff --git a/syncbase/featuretests/mgmt_v23_test.go b/syncbase/featuretests/mgmt_v23_test.go
deleted file mode 100644
index 1732142..0000000
--- a/syncbase/featuretests/mgmt_v23_test.go
+++ /dev/null
@@ -1,334 +0,0 @@
-// 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.
-
-package featuretests_test
-
-// TODO(ivanpi): Port and reenable.
-
-// +build ignore
-
-import (
- "errors"
- "fmt"
- "io/ioutil"
- "math/rand"
- "os"
- "path/filepath"
- "regexp"
- "strings"
- "time"
-
- _ "v.io/x/ref/runtime/factories/generic"
- "v.io/x/ref/test/v23tests"
-)
-
-var (
- hostname string
- errTimeout = errors.New("timeout")
-)
-
-func init() {
- name, err := os.Hostname()
- if err != nil {
- panic(fmt.Sprintf("Hostname() failed: %v", err))
- }
- hostname = name
-}
-
-// V23TestDeviceManager publishes and runs syncbased using the device manager
-// and verifies that the running instance of syncbased has appropriate
-// blessings.
-func V23TestDeviceManager(i *v23tests.T) {
- defer fmt.Fprintf(os.Stderr, "--------------- SHUTDOWN ---------------\n")
- var (
- workDir = i.NewTempDir("")
- binStagingDir = mkSubdir(i, workDir, "bin")
- dmInstallDir = filepath.Join(workDir, "dm")
-
- // Most vanadium command-line utilities will be run by a
- // principal that has "root:u:alice" as its blessing.
- // (Where "root" comes from i.Principal().BlessingStore().Default()).
- // Create those credentials and options to use to setup the
- // binaries with them.
- aliceCreds, _ = i.Shell().NewChildCredentials("u:alice")
- aliceOpts = i.Shell().DefaultStartOpts().ExternalProgram().WithCustomCredentials(aliceCreds)
-
- // Build all the command-line tools and set them up to run as alice.
- // applicationd/binaryd servers will be run by alice too.
- // TODO: applicationd/binaryd should run as a separate "service" role, as
- // alice is just a user.
- namespaceBin = i.BuildV23Pkg("v.io/x/ref/cmd/namespace").WithStartOpts(aliceOpts)
- deviceBin = i.BuildV23Pkg("v.io/x/ref/services/device/device").WithStartOpts(aliceOpts)
- binarydBin = i.BuildV23Pkg("v.io/x/ref/services/binary/binaryd").WithStartOpts(aliceOpts)
- applicationdBin = i.BuildV23Pkg("v.io/x/ref/services/application/applicationd").WithStartOpts(aliceOpts)
- syncbasedBin = i.BuildV23Pkg("v.io/x/ref/services/syncbase/syncbased")
-
- // The devicex script is not provided with any credentials, it
- // will generate its own. This means that on "devicex start"
- // the device will have no useful credentials and until "device
- // claim" is invoked (as alice), it will just sit around
- // waiting to be claimed.
- //
- // Other binaries, like applicationd and binaryd will be run by alice.
- deviceScriptPath = filepath.Join(os.Getenv("JIRI_ROOT"), "release", "go", "src", "v.io", "x", "ref", "services", "device", "devicex")
- deviceScript = i.BinaryFromPath(deviceScriptPath).WithEnv("V23_DEVICE_DIR=" + dmInstallDir)
-
- mtName = "devices/" + hostname // Name under which the device manager will publish itself.
- )
-
- // We also need some tools running with different sets of credentials...
-
- // Administration tasks will be performed with a blessing that represents a corporate
- // administrator (which is usually a role account)
- adminCreds, err := i.Shell().NewChildCredentials("r:admin")
- if err != nil {
- i.Fatalf("generating admin creds: %v", err)
- }
- adminOpts := i.Shell().DefaultStartOpts().ExternalProgram().WithCustomCredentials(adminCreds)
- adminDeviceBin := deviceBin.WithStartOpts(adminOpts)
- debugBin := i.BuildV23Pkg("v.io/x/ref/services/debug/debug").WithStartOpts(adminOpts)
-
- // A special set of credentials will be used to give two blessings to the device manager
- // when claiming it -- one blessing will be from the corporate administrator role who owns
- // the machine, and the other will be a manufacturer blessing. (This is a hack until
- // there's a way to separately supply a manufacturer blessing. Eventually, the claim
- // would really be done by the administrator, and the administrator's blessing would get
- // added to the manufacturer's blessing, which would already be present.)
- claimCreds, err := i.Shell().AddToChildCredentials(adminCreds, "m:orange:zphone5:ime-i007")
- if err != nil {
- i.Fatalf("adding the mfr blessing to admin creds: %v", err)
- }
- claimOpts := i.Shell().DefaultStartOpts().ExternalProgram().WithCustomCredentials(claimCreds)
- claimDeviceBin := deviceBin.WithStartOpts(claimOpts)
-
- // Another set of credentials be used to represent the application publisher, who
- // signs and pushes binaries
- pubCreds, err := i.Shell().NewChildCredentials("a:rovio")
- if err != nil {
- i.Fatalf("generating publisher creds: %v", err)
- }
- pubOpts := i.Shell().DefaultStartOpts().ExternalProgram().WithCustomCredentials(pubCreds)
- pubDeviceBin := deviceBin.WithStartOpts(pubOpts)
- applicationBin := i.BuildV23Pkg("v.io/x/ref/services/application/application").WithStartOpts(pubOpts)
-
- v23tests.RunRootMT(i, "--v23.tcp.address=127.0.0.1:0")
- buildAndCopyBinaries(
- i,
- binStagingDir,
- "v.io/x/ref/services/device/deviced",
- "v.io/x/ref/services/agent/agentd",
- "v.io/x/ref/services/device/suidhelper",
- "v.io/x/ref/services/device/inithelper")
-
- appDName := "applications"
- devicedAppName := filepath.Join(appDName, "deviced", "test")
-
- deviceScript.Start(
- "install",
- binStagingDir,
- "--single_user",
- "--origin="+devicedAppName,
- "--",
- "--v23.tcp.address=127.0.0.1:0",
- "--neighborhood-name="+fmt.Sprintf("%s-%d-%d", hostname, os.Getpid(), rand.Int()),
- ).WaitOrDie(os.Stdout, os.Stderr)
- deviceScript.Start("start").WaitOrDie(os.Stdout, os.Stderr)
- // Grab the endpoint for the claimable service from the device manager's
- // log.
- dmLog := filepath.Join(dmInstallDir, "dmroot/device-manager/logs/deviced.INFO")
- var claimableEP string
- expiry := time.Now().Add(30 * time.Second)
- for {
- if time.Now().After(expiry) {
- i.Fatalf("Timed out looking for claimable endpoint in %v", dmLog)
- }
- startLog, err := ioutil.ReadFile(dmLog)
- if err != nil {
- i.Logf("Couldn't read log %v: %v", dmLog, err)
- time.Sleep(time.Second)
- continue
- }
- re := regexp.MustCompile(`Unclaimed device manager endpoint: (.*)`)
- matches := re.FindSubmatch(startLog)
- if len(matches) == 0 {
- i.Logf("Couldn't find match in %v [%s]", dmLog, startLog)
- time.Sleep(time.Second)
- continue
- }
- if len(matches) < 2 {
- i.Fatalf("Wrong match in %v (%d) %v", dmLog, len(matches), string(matches[0]))
- }
- claimableEP = string(matches[len(matches)-1])
- break
- }
- // Claim the device as "root:u:alice:myworkstation".
- claimDeviceBin.Start("claim", claimableEP, "myworkstation").WaitOrDie(os.Stdout, os.Stderr)
-
- resolve := func(name string) string {
- resolver := func() (interface{}, error) {
- // Use Start, rather than Run, since it's ok for 'namespace resolve'
- // to fail with 'name doesn't exist'
- inv := namespaceBin.Start("resolve", name)
- // Cleanup after ourselves to avoid leaving a ton of invocations
- // lying around which obscure logging output.
- defer inv.Wait(nil, os.Stderr)
- if r := strings.TrimRight(inv.Output(), "\n"); len(r) > 0 {
- return r, nil
- }
- return nil, nil
- }
- return i.WaitFor(resolver, 100*time.Millisecond, time.Minute).(string)
- }
-
- // Wait for the device manager to publish its mount table entry.
- resolve(mtName)
- adminDeviceBin.Run("acl", "set", mtName+"/devmgr/device", "root:u:alice", "Read,Resolve,Write")
-
- // Verify the device's default blessing is as expected.
- mfrBlessing := "root:m:orange:zphone5:ime-i007:myworkstation"
- ownerBlessing := "root:r:admin:myworkstation"
- inv := debugBin.Start("stats", "read", mtName+"/devmgr/__debug/stats/security/principal/*/blessingstore/*")
- inv.ExpectSetEventuallyRE(".*Default Blessings[ ]+" + mfrBlessing + "," + ownerBlessing)
- inv.Wait(nil, os.Stderr)
-
- // Get the device's profile, which should be set to non-empty string
- inv = adminDeviceBin.Start("describe", mtName+"/devmgr/device")
-
- parts := inv.ExpectRE(`{Profiles:map\[(.*):{}\]}`, 1)
- inv.Wait(nil, os.Stderr)
- expectOneMatch := func(parts [][]string) string {
- if len(parts) != 1 || len(parts[0]) != 2 {
- loc := v23tests.Caller(1)
- i.Fatalf("%s: failed to match profile: %#v", loc, parts)
- }
- return parts[0][1]
- }
- deviceProfile := expectOneMatch(parts)
- if len(deviceProfile) == 0 {
- i.Fatalf("failed to get profile")
- }
-
- // Start a binaryd server that will serve the binary for the test
- // application to be installed on the device.
- binarydName := "binaries"
- binarydBin.Start(
- "--name=binaries",
- "--root-dir="+filepath.Join(workDir, "binstore"),
- "--v23.tcp.address=127.0.0.1:0",
- "--http=127.0.0.1:0")
- // Allow publishers to update binaries
- deviceBin.Run("acl", "set", binarydName, "root:a", "Write")
-
- // Start an applicationd server that will serve the application
- // envelope for the test application to be installed on the device.
- applicationdBin.Start(
- "--name="+appDName,
- "--store="+mkSubdir(i, workDir, "appstore"),
- "--v23.tcp.address=127.0.0.1:0",
- )
- // Allow publishers to create and update envelopes
- deviceBin.Run("acl", "set", appDName, "root:a", "Read,Write,Resolve")
-
- syncbasedName := appDName + "/syncbased"
- syncbasedBinName := binarydName + "/syncbased"
- syncbasedEnvelopeFilename := filepath.Join(workDir, "syncbased.envelope")
- syncbasedEnvelope := fmt.Sprintf("{\"Title\":\"syncbased\","+
- "\"Args\":[\"-v=0\", \"--name=syncbased\", \"--root-dir=%s\", \"--v23.tcp.address=127.0.0.1:0\"]}",
- mkSubdir(i, workDir, "syncbased"))
- ioutil.WriteFile(syncbasedEnvelopeFilename, []byte(syncbasedEnvelope), 0666)
- defer os.Remove(syncbasedEnvelopeFilename)
-
- output := applicationBin.Run("put", syncbasedName+"/0", deviceProfile, syncbasedEnvelopeFilename)
- if got, want := output, fmt.Sprintf("Application envelope added for profile %s.", deviceProfile); got != want {
- i.Fatalf("got %q, want %q", got, want)
- }
-
- // Publish the app.
- pubDeviceBin.Start("publish", "-from", filepath.Dir(syncbasedBin.Path()), "-readers", "root:r:admin", "syncbased").WaitOrDie(os.Stdout, os.Stderr)
- if got := namespaceBin.Run("glob", syncbasedBinName); len(got) == 0 {
- i.Fatalf("glob failed for %q", syncbasedBinName)
- }
-
- // Install the app on the device.
- inv = deviceBin.Start("install", mtName+"/devmgr/apps", syncbasedName)
- installationName := inv.ReadLine()
- inv.WaitOrDie(os.Stdout, os.Stderr)
- if installationName == "" {
- i.Fatalf("got empty installation name from install")
- }
-
- // Verify that the installation shows up when globbing the device manager.
- output = namespaceBin.Run("glob", mtName+"/devmgr/apps/syncbased/*")
- if got, want := output, installationName; got != want {
- i.Fatalf("got %q, want %q", got, want)
- }
-
- // Start an instance of the app, granting it blessing extension syncbased.
- inv = deviceBin.Start("instantiate", installationName, "syncbased")
- instanceName := inv.ReadLine()
- inv.WaitOrDie(os.Stdout, os.Stderr)
- if instanceName == "" {
- i.Fatalf("got empty instance name from new")
- }
- deviceBin.Start("run", instanceName).WaitOrDie(os.Stdout, os.Stderr)
-
- resolve(mtName + "/syncbased")
-
- // Verify that the instance shows up when globbing the device manager.
- output = namespaceBin.Run("glob", mtName+"/devmgr/apps/syncbased/*/*")
- if got, want := output, instanceName; got != want {
- i.Fatalf("got %q, want %q", got, want)
- }
-
- // Verify the app's blessings. We check the default blessing, as well as the
- // "..." blessing, which should be the default blessing plus a publisher blessing.
- userBlessing := "root:u:alice:syncbased"
- pubBlessing := "root:a:rovio:apps:published:syncbased"
- // Just to remind:
- // mfrBlessing = "root:m:orange:zphone5:ime-i007:myworkstation"
- // ownerBlessing = "root:r:admin:myworkstation"
- appBlessing := mfrBlessing + ":a:" + pubBlessing + "," + ownerBlessing + ":a:" + pubBlessing
- inv = debugBin.Start("stats", "read", instanceName+"/stats/security/principal/*/blessingstore/*")
- inv.ExpectSetEventuallyRE(".*Default Blessings[ ]+"+userBlessing+"$", "[.][.][.][ ]+"+userBlessing+","+appBlessing)
- inv.Wait(nil, os.Stderr)
-
- // Kill and delete the instance.
- deviceBin.Run("kill", instanceName)
- deviceBin.Run("delete", instanceName)
-
- // Shut down the device manager.
- deviceScript.Run("stop")
-
- // Wait for the mounttable entry to go away.
- resolveGone := func(name string) string {
- resolver := func() (interface{}, error) {
- inv := namespaceBin.Start("resolve", name)
- defer inv.Wait(nil, os.Stderr)
- if r := strings.TrimRight(inv.Output(), "\n"); len(r) == 0 {
- return r, nil
- }
- return nil, nil
- }
- return i.WaitFor(resolver, 100*time.Millisecond, time.Minute).(string)
- }
- resolveGone(mtName)
- deviceScript.Run("uninstall")
-}
-
-func buildAndCopyBinaries(i *v23tests.T, destinationDir string, packages ...string) {
- var args []string
- for _, pkg := range packages {
- args = append(args, i.BuildGoPkg(pkg).Path())
- }
- args = append(args, destinationDir)
- i.BinaryFromPath("/bin/cp").Start(args...).WaitOrDie(os.Stdout, os.Stderr)
-}
-
-func mkSubdir(i *v23tests.T, parent, child string) string {
- dir := filepath.Join(parent, child)
- if err := os.Mkdir(dir, 0755); err != nil {
- i.Fatalf("failed to create %q: %v", dir, err)
- }
- return dir
-}