Merge "namespace: parallelize Glob."
diff --git a/lib/exec/child.go b/lib/exec/child.go
index 80ebfd2..7158ef7 100644
--- a/lib/exec/child.go
+++ b/lib/exec/child.go
@@ -5,6 +5,7 @@
"errors"
"io"
"os"
+ "strconv"
"sync"
)
@@ -62,7 +63,7 @@
// SetReady writes a 'ready' status to its parent.
func (c *ChildHandle) SetReady() error {
- _, err := c.statusPipe.Write([]byte(readyStatus))
+ _, err := c.statusPipe.Write([]byte(readyStatus + strconv.Itoa(os.Getpid())))
c.statusPipe.Close()
return err
}
diff --git a/lib/exec/parent.go b/lib/exec/parent.go
index 612020f..e4d40db 100644
--- a/lib/exec/parent.go
+++ b/lib/exec/parent.go
@@ -7,6 +7,7 @@
"io"
"os"
"os/exec"
+ "strconv"
"strings"
"sync"
"syscall"
@@ -34,6 +35,7 @@
waitDone bool
waitErr error
waitLock sync.Mutex
+ callbackPid int
}
// ParentHandleOpt is an option for NewParentHandle.
@@ -187,7 +189,12 @@
// waitForStatus has closed the channel, but we may not
// have read the message from it yet.
case st := <-c:
- if st == readyStatus {
+ if strings.HasPrefix(st, readyStatus) {
+ pid, err := strconv.Atoi(st[len(readyStatus):])
+ if err != nil {
+ return err
+ }
+ p.callbackPid = pid
return nil
}
if strings.HasPrefix(st, failedStatus) {
@@ -253,6 +260,12 @@
return 0
}
+// ChildPid returns the pid of a child process as reported by its status
+// callback.
+func (p *ParentHandle) ChildPid() int {
+ return p.callbackPid
+}
+
// Exists returns true if the child process exists and can be signal'ed
func (p *ParentHandle) Exists() bool {
if p.c.Process != nil {
diff --git a/lib/filelocker/locker_test.go b/lib/filelocker/locker_test.go
index b58bfe2..cf483a7 100644
--- a/lib/filelocker/locker_test.go
+++ b/lib/filelocker/locker_test.go
@@ -42,7 +42,7 @@
func testLockChild(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
// Lock the file
- unlocker, err := Lock(args[1])
+ unlocker, err := Lock(args[0])
if err != nil {
return fmt.Errorf("Lock failed: %v", err)
}
diff --git a/lib/flags/flags.go b/lib/flags/flags.go
index b2c767e..241420c 100644
--- a/lib/flags/flags.go
+++ b/lib/flags/flags.go
@@ -5,6 +5,7 @@
"fmt"
"os"
"strings"
+ "sync"
"v.io/core/veyron/lib/flags/consts"
)
@@ -236,12 +237,40 @@
return f
}
+var (
+ defaultProtocol = "wsh" // GUARDED_BY listenMu
+ defaultHostPort = ":0" // GUARDED_BY listenMu
+ listenMu sync.RWMutex
+)
+
+// SetDefaultProtocol sets the default protocol used when --veyron.tcp.protocol is
+// not provided. It must be called before flags are parsed for it to take effect.
+func SetDefaultProtocol(protocol string) {
+ listenMu.Lock()
+ defaultProtocol = protocol
+ listenMu.Unlock()
+}
+
+// SetDefaultHostPort sets the default host and port used when --veyron.tcp.address
+// is not provided. It must be called before flags are parsed for it to take effect.
+func SetDefaultHostPort(s string) {
+ listenMu.Lock()
+ defaultHostPort = s
+ listenMu.Unlock()
+}
+
// createAndRegisterListenFlags creates and registers the ListenFlags
// group with the supplied flag.FlagSet.
func createAndRegisterListenFlags(fs *flag.FlagSet) *ListenFlags {
+ listenMu.RLock()
+ defer listenMu.RUnlock()
+ var ipHostPortFlag IPHostPortFlag
+ if err := ipHostPortFlag.Set(defaultHostPort); err != nil {
+ panic(err)
+ }
f := &ListenFlags{
- protocol: TCPProtocolFlag{"wsh"},
- addresses: ipHostPortFlagVar{validator: IPHostPortFlag{Port: "0"}},
+ protocol: TCPProtocolFlag{defaultProtocol},
+ addresses: ipHostPortFlagVar{validator: ipHostPortFlag},
}
f.addresses.flags = f
diff --git a/lib/modules/core/core_test.go b/lib/modules/core/core_test.go
index a0e03e8..9f2b0b5 100644
--- a/lib/modules/core/core_test.go
+++ b/lib/modules/core/core_test.go
@@ -55,7 +55,7 @@
}
func testArgs(args ...string) []string {
- var targs = []string{"--", "--veyron.tcp.address=127.0.0.1:0"}
+ var targs = []string{"--veyron.tcp.address=127.0.0.1:0"}
return append(targs, args...)
}
diff --git a/lib/modules/core/echo.go b/lib/modules/core/echo.go
index 92160b9..8ba8f5f 100644
--- a/lib/modules/core/echo.go
+++ b/lib/modules/core/echo.go
@@ -50,13 +50,6 @@
ctx, shutdown := veyron2.Init()
defer shutdown()
- fl, args, err := parseListenFlags(args)
- if err != nil {
- return fmt.Errorf("failed to parse args: %s", err)
- }
- if err := checkArgs(args, 2, "<message> <name>"); err != nil {
- return err
- }
id, mp := args[0], args[1]
disp := &treeDispatcher{id: id}
server, err := veyron2.NewServer(ctx)
@@ -64,7 +57,7 @@
return err
}
defer server.Stop()
- eps, err := server.Listen(initListenSpec(fl))
+ eps, err := server.Listen(veyron2.GetListenSpec(ctx))
if err != nil {
return err
}
@@ -83,7 +76,6 @@
ctx, shutdown := veyron2.Init()
defer shutdown()
- args = args[1:]
name := args[0]
args = args[1:]
client := veyron2.GetClient(ctx)
diff --git a/lib/modules/core/mounttable.go b/lib/modules/core/mounttable.go
index 6046c91..00acb04 100644
--- a/lib/modules/core/mounttable.go
+++ b/lib/modules/core/mounttable.go
@@ -34,11 +34,7 @@
ctx, shutdown := veyron2.Init()
defer shutdown()
- fl, args, err := parseListenFlags(args)
- if err != nil {
- return fmt.Errorf("failed to parse args: %s", err)
- }
- lspec := initListenSpec(fl)
+ lspec := veyron2.GetListenSpec(ctx)
server, err := veyron2.NewServer(ctx, options.ServesMountTable(true))
if err != nil {
return fmt.Errorf("root failed: %v", err)
@@ -74,7 +70,6 @@
defer shutdown()
details := false
- args = args[1:] // skip over command name
if len(args) > 0 && args[0] == "-l" {
details = true
args = args[1:]
diff --git a/lib/modules/core/proxy.go b/lib/modules/core/proxy.go
index 79d826b..691d1ca 100644
--- a/lib/modules/core/proxy.go
+++ b/lib/modules/core/proxy.go
@@ -22,18 +22,17 @@
ctx, shutdown := veyron2.Init()
defer shutdown()
- fl, args, err := parseListenFlags(args)
- if err != nil {
- return fmt.Errorf("failed to parse args: %s", err)
- }
expected := len(args)
rid, err := naming.NewRoutingID()
if err != nil {
return err
}
- lf := fl.ListenFlags()
- proxy, err := proxy.New(rid, veyron2.GetPrincipal(ctx), lf.Addrs[0].Protocol, lf.Addrs[0].Address, "")
+ listenSpec := veyron2.GetListenSpec(ctx)
+ protocol := listenSpec.Addrs[0].Protocol
+ addr := listenSpec.Addrs[0].Address
+
+ proxy, err := proxy.New(rid, veyron2.GetPrincipal(ctx), protocol, addr, "")
if err != nil {
return err
}
diff --git a/lib/modules/core/test_identityd.go b/lib/modules/core/test_identityd.go
index f1bc19a..87fe38a 100644
--- a/lib/modules/core/test_identityd.go
+++ b/lib/modules/core/test_identityd.go
@@ -10,7 +10,6 @@
"v.io/core/veyron2"
- "v.io/core/veyron/lib/flags"
"v.io/core/veyron/lib/modules"
"v.io/core/veyron/services/identity/auditor"
@@ -23,46 +22,40 @@
)
var (
- ifs *flag.FlagSet = flag.NewFlagSet("test_identityd", flag.ContinueOnError)
-
- googleDomain = ifs.String("google_domain", "", "An optional domain name. When set, only email addresses from this domain are allowed to authenticate via Google OAuth")
- host = ifs.String("host", "localhost", "Hostname the HTTP server listens on. This can be the name of the host running the webserver, but if running behind a NAT or load balancer, this should be the host name that clients will connect to. For example, if set to 'x.com', Veyron identities will have the IssuerName set to 'x.com' and clients can expect to find the root name and public key of the signer at 'x.com/blessing-root'.")
- httpaddr = ifs.String("httpaddr", "localhost:0", "Address on which the HTTP server listens on.")
- tlsconfig = ifs.String("tlsconfig", "", "Comma-separated list of TLS certificate and private key files. This must be provided.")
-
- ifl *flags.Flags = flags.CreateAndRegister(ifs, flags.Listen)
+ host = flag.CommandLine.String("host", "localhost", "Hostname the HTTP server listens on. This can be the name of the host running the webserver, but if running behind a NAT or load balancer, this should be the host name that clients will connect to. For example, if set to 'x.com', Veyron identities will have the IssuerName set to 'x.com' and clients can expect to find the root name and public key of the signer at 'x.com/blessing-root'.")
+ httpaddr = flag.CommandLine.String("httpaddr", "localhost:0", "Address on which the HTTP server listens on.")
+ tlsconfig = flag.CommandLine.String("tlsconfig", "", "Comma-separated list of TLS certificate and private key files. This must be provided.")
)
func init() {
- modules.RegisterChild(TestIdentitydCommand, usage(ifs), startTestIdentityd)
+ modules.RegisterChild(TestIdentitydCommand, usage(flag.CommandLine), startTestIdentityd)
}
func startTestIdentityd(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
- if err := parseFlags(ifl, args); err != nil {
- return fmt.Errorf("failed to parse args: %s", err)
- }
-
// Duration to use for tls cert and blessing duration.
duration := 365 * 24 * time.Hour
+ ctx, shutdown := veyron2.Init()
+ defer shutdown()
+
// If no tlsconfig has been provided, generate new cert and key and use them.
- if ifs.Lookup("tlsconfig").Value.String() == "" {
+ if flag.CommandLine.Lookup("tlsconfig").Value.String() == "" {
certFile, keyFile, err := util.WriteCertAndKey(*host, duration)
if err != nil {
return fmt.Errorf("Could not write cert and key: %v", err)
}
- if err := ifs.Set("tlsconfig", certFile+","+keyFile); err != nil {
+ if err := flag.CommandLine.Set("tlsconfig", certFile+","+keyFile); err != nil {
return fmt.Errorf("Could not set tlsconfig: %v", err)
}
}
// Pick a free port if httpaddr flag is not set.
- // We can't use :0 here, because the identity server calles
- // http.ListenAndServeTLS, which block, leaving us with no way to tell
+ // We can't use :0 here, because the identity server calls
+ // http.ListenAndServeTLS, which blocks, leaving us with no way to tell
// what port the server is running on. Hence, we must pass in an
// actual port so we know where the server is running.
- if ifs.Lookup("httpaddr").Value.String() == ifs.Lookup("httpaddr").DefValue {
- if err := ifs.Set("httpaddr", "localhost:"+freePort()); err != nil {
+ if flag.CommandLine.Lookup("httpaddr").Value.String() == flag.CommandLine.Lookup("httpaddr").DefValue {
+ if err := flag.CommandLine.Set("httpaddr", "localhost:"+freePort()); err != nil {
return fmt.Errorf("Could not set httpaddr: %v", err)
}
}
@@ -74,7 +67,6 @@
params := blesser.OAuthBlesserParams{
OAuthProvider: oauthProvider,
BlessingDuration: duration,
- DomainRestriction: *googleDomain,
RevocationManager: revocationManager,
}
@@ -84,12 +76,10 @@
reader,
revocationManager,
params,
- caveats.NewMockCaveatSelector())
+ caveats.NewMockCaveatSelector(),
+ nil)
- l := initListenSpec(ifl)
-
- ctx, shutdown := veyron2.Init()
- defer shutdown()
+ l := veyron2.GetListenSpec(ctx)
_, veyronEPs, externalHttpaddress := s.Listen(ctx, &l, *host, *httpaddr, *tlsconfig)
diff --git a/lib/modules/core/util.go b/lib/modules/core/util.go
index 3d16bb7..08c53f3 100644
--- a/lib/modules/core/util.go
+++ b/lib/modules/core/util.go
@@ -4,36 +4,8 @@
"flag"
"fmt"
"strings"
-
- "v.io/core/veyron2/ipc"
-
- "v.io/core/veyron/lib/flags"
)
-func parseFlags(fl *flags.Flags, args []string) error {
- if len(args) == 0 {
- return nil
- }
- return fl.Parse(args[1:], nil)
-}
-
-// parseListenFlags parses the given args using just the flags and env vars
-// defined in the veyron/lib/flags package.
-func parseListenFlags(args []string) (*flags.Flags, []string, error) {
- fs := flag.NewFlagSet("modules/core", flag.ContinueOnError)
- fl := flags.CreateAndRegister(fs, flags.Listen)
- err := parseFlags(fl, args)
- return fl, fl.Args(), err
-}
-
-func initListenSpec(fl *flags.Flags) ipc.ListenSpec {
- lf := fl.ListenFlags()
- return ipc.ListenSpec{
- Addrs: ipc.ListenAddrs(lf.Addrs),
- Proxy: lf.ListenProxy,
- }
-}
-
// checkArgs checks for the expected number of args in args. A negative
// value means at least that number of args are expected.
func checkArgs(args []string, expected int, usage string) error {
diff --git a/lib/modules/core/wspr.go b/lib/modules/core/wspr.go
index 42db213..8e38a84 100644
--- a/lib/modules/core/wspr.go
+++ b/lib/modules/core/wspr.go
@@ -5,7 +5,6 @@
"fmt"
"io"
- "v.io/core/veyron/lib/flags"
"v.io/core/veyron/lib/modules"
"v.io/wspr/veyron/services/wsprd/wspr"
@@ -13,29 +12,19 @@
)
var (
- // TODO(sadovsky): We should restructure things so that we can avoid
- // duplicating code between subprocess command impls and actual main()'s.
- fs *flag.FlagSet = flag.NewFlagSet("wspr", flag.ContinueOnError)
-
- port *int = fs.Int("port", 0, "Port to listen on.")
- identd *string = fs.String("identd", "", "identd server name. Must be set.")
-
- fl *flags.Flags = flags.CreateAndRegister(fs, flags.Listen)
+ port *int = flag.CommandLine.Int("port", 0, "Port to listen on.")
+ identd *string = flag.CommandLine.String("identd", "", "identd server name. Must be set.")
)
func init() {
- modules.RegisterChild(WSPRCommand, usage(fs), startWSPR)
+ modules.RegisterChild(WSPRCommand, usage(flag.CommandLine), startWSPR)
}
func startWSPR(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
- if err := parseFlags(fl, args); err != nil {
- return fmt.Errorf("failed to parse args: %s", err)
- }
-
ctx, shutdown := veyron2.Init()
defer shutdown()
- l := initListenSpec(fl)
+ l := veyron2.GetListenSpec(ctx)
proxy := wspr.NewWSPR(ctx, *port, &l, *identd, nil)
defer proxy.Shutdown()
diff --git a/lib/modules/examples_test.go b/lib/modules/examples_test.go
index cb97b64..e4ab42a 100644
--- a/lib/modules/examples_test.go
+++ b/lib/modules/examples_test.go
@@ -36,9 +36,8 @@
h, _ := sh.Start("echo", nil, "a", "b")
h.Shutdown(os.Stdout, os.Stderr)
// Output:
- // 0: echo
- // 1: a
- // 2: b
+ // 0: a
+ // 1: b
}
func ExampleDispatchAndExit() {
@@ -51,7 +50,6 @@
h, _ := sh.Start("echo", nil, "c", "d")
h.Shutdown(os.Stdout, os.Stderr)
// Output:
- // 0: echo
- // 1: c
- // 2: d
+ // 0: c
+ // 1: d
}
diff --git a/lib/modules/func.go b/lib/modules/func.go
index 5c5bc4c..24f1fde 100644
--- a/lib/modules/func.go
+++ b/lib/modules/func.go
@@ -88,7 +88,7 @@
cenv := envSliceToMap(env)
vlog.VI(1).Infof("Start: %q args: %v", fh.name, args)
vlog.VI(2).Infof("Start: %q env: %v", fh.name, cenv)
- err := main(stdin, stdout, stderr, cenv, args...)
+ err := main(stdin, stdout, stderr, cenv, args[1:]...)
if err != nil {
fmt.Fprintf(stderr, "%s\n", err)
}
diff --git a/lib/modules/modules_test.go b/lib/modules/modules_test.go
index 277fb2f..a5c989d 100644
--- a/lib/modules/modules_test.go
+++ b/lib/modules/modules_test.go
@@ -62,7 +62,7 @@
}
func PrintFromEnv(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
- for _, a := range args[1:] {
+ for _, a := range args {
if v := env[a]; len(v) > 0 {
fmt.Fprintf(stdout, "%s\n", a+"="+v)
} else {
@@ -286,7 +286,7 @@
var stdoutBuf bytes.Buffer
var stderrBuf bytes.Buffer
sh.Cleanup(&stdoutBuf, &stderrBuf)
- stdoutOutput, stderrOutput := "stdout: "+command+"\n", "stderr: "+command+"\n"
+ var stdoutOutput, stderrOutput string
for _, a := range args {
stdoutOutput += fmt.Sprintf("stdout: %s\n", a)
stderrOutput += fmt.Sprintf("stderr: %s\n", a)
diff --git a/lib/modules/registry.go b/lib/modules/registry.go
index 8331f9c..f473d14 100644
--- a/lib/modules/registry.go
+++ b/lib/modules/registry.go
@@ -200,8 +200,8 @@
}
}(os.Getppid())
- args := append([]string{command}, flag.Args()...)
- return m.main(os.Stdin, os.Stdout, os.Stderr, envSliceToMap(os.Environ()), args...)
+ flag.Parse()
+ return m.main(os.Stdin, os.Stdout, os.Stderr, envSliceToMap(os.Environ()), flag.Args()...)
}
// WaitForEOF returns when a read on its io.Reader parameter returns io.EOF
diff --git a/lib/modules/shell.go b/lib/modules/shell.go
index cc14137..85f8194 100644
--- a/lib/modules/shell.go
+++ b/lib/modules/shell.go
@@ -190,14 +190,12 @@
if err != nil {
return nil, err
}
- // We store this blessing as the one to use with a pattern that matches
- // the root's name.
- // TODO(cnicolaou,caprita): at some point there will be a nicer API
- // for getting the name of a blessing.
- ctx := security.NewContext(&security.ContextParams{LocalPrincipal: root})
- rootName := root.BlessingStore().Default().ForContext(ctx)[0]
- if _, err := p.BlessingStore().Set(blessingFromChild, security.BlessingPattern(rootName)); err != nil {
- return nil, err
+ // We store this blessing as the one to use with the patterns that match
+ // the root's names.
+ for rootName, _ := range root.BlessingsInfo(root.BlessingStore().Default()) {
+ if _, err := p.BlessingStore().Set(blessingFromChild, security.BlessingPattern(rootName)); err != nil {
+ return nil, err
+ }
}
if err := p.AddToRoots(blessingFromChild); err != nil {
diff --git a/lib/testutil/glob.go b/lib/testutil/glob.go
index 84d7ec7..0c6fd23 100644
--- a/lib/testutil/glob.go
+++ b/lib/testutil/glob.go
@@ -35,5 +35,6 @@
if ferr := call.Finish(&err); ferr != nil {
err = ferr
}
+
return results, err
}
diff --git a/lib/testutil/integration/testdata/integration_test.go b/lib/testutil/integration/testdata/integration_test.go
new file mode 100644
index 0000000..97308d7
--- /dev/null
+++ b/lib/testutil/integration/testdata/integration_test.go
@@ -0,0 +1,28 @@
+package testdata
+
+import (
+ "testing"
+
+ "v.io/core/veyron/lib/modules"
+ "v.io/core/veyron/lib/testutil/integration"
+ _ "v.io/core/veyron/profiles"
+)
+
+func TestHelperProcess(t *testing.T) {
+ modules.DispatchInTest()
+}
+
+func TestBinaryFromPath(t *testing.T) {
+ env := integration.NewTestEnvironment(t)
+ defer env.Cleanup()
+
+ bash := env.BinaryFromPath("/bin/bash")
+ if want, got := "hello world\n", bash.Start("-c", "echo hello world").Output(); want != got {
+ t.Fatalf("unexpected output, want %s, got %s", want, got)
+ }
+
+ // TODO(sjr): revive this once stderr handling is fixed.
+ // if want, got := "hello world\n", bash.Start("-c", "echo hello world 1>&2").ErrorOutput(); want != got {
+ // t.Fatalf("unexpected output, want %s, got %s", want, got)
+ // }
+}
diff --git a/lib/testutil/integration/util.go b/lib/testutil/integration/util.go
index 208fad1..8f5b314 100644
--- a/lib/testutil/integration/util.go
+++ b/lib/testutil/integration/util.go
@@ -79,6 +79,12 @@
// Cleanup cleans up the environment and deletes all its artifacts.
Cleanup()
+ // BinaryFromPath returns a new TestBinary that, when started, will
+ // execute the executable or script at the given path.
+ //
+ // E.g. env.BinaryFromPath("/bin/bash").Start("-c", "echo hello world").Output() -> "hello world"
+ BinaryFromPath(path string) TestBinary
+
// BuildGoPkg expects a Go package path that identifies a "main"
// package and returns a TestBinary representing the newly built
// binary.
@@ -355,9 +361,12 @@
writeStringOrDie(e.t, file, fmt.Sprintf("Root mounttable endpoint: %s\n", e.RootMT()))
shellPath := "/bin/sh"
+ if shellPathFromEnv := os.Getenv("SHELL"); shellPathFromEnv != "" {
+ shellPath = shellPathFromEnv
+ }
proc, err := os.StartProcess(shellPath, []string{}, &attr)
if err != nil {
- e.t.Fatalf("StartProcess(%v) failed: %v", shellPath, err)
+ e.t.Fatalf("StartProcess(%q) failed: %v", shellPath, err)
}
// Wait until user exits the shell
@@ -369,6 +378,15 @@
writeStringOrDie(e.t, file, fmt.Sprintf("<< Exited shell: %s\n", state.String()))
}
+func (e *integrationTestEnvironment) BinaryFromPath(path string) TestBinary {
+ return &integrationTestBinary{
+ env: e,
+ envVars: nil,
+ path: path,
+ cleanupFunc: func() {},
+ }
+}
+
func (e *integrationTestEnvironment) BuildGoPkg(binary_path string) TestBinary {
e.t.Logf("building %s...", binary_path)
if cached_binary := e.builtBinaries[binary_path]; cached_binary != nil {
@@ -503,7 +521,7 @@
// returns a handle for the started command along with the object name
// of the mount table.
func startRootMT(shell *modules.Shell) (modules.Handle, string, error) {
- handle, err := shell.Start(core.RootMTCommand, nil, "--", "--veyron.tcp.address=127.0.0.1:0")
+ handle, err := shell.Start(core.RootMTCommand, nil, "--veyron.tcp.address=127.0.0.1:0")
if err != nil {
return nil, "", err
}
diff --git a/profiles/genericinit.go b/profiles/genericinit.go
index b071c31..936cd2f 100644
--- a/profiles/genericinit.go
+++ b/profiles/genericinit.go
@@ -24,7 +24,9 @@
func init() {
veyron2.RegisterProfileInit(Init)
stream.RegisterUnknownProtocol("wsh", websocket.HybridDial, websocket.HybridListener)
- commonFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime)
+ flags.SetDefaultProtocol("tcp")
+ flags.SetDefaultHostPort("127.0.0.1:0")
+ commonFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime, flags.Listen)
}
func Init(ctx *context.T) (veyron2.Runtime, *context.T, veyron2.Shutdown, error) {
@@ -34,13 +36,17 @@
ac := appcycle.New()
+ lf := commonFlags.ListenFlags()
+ listenSpec := ipc.ListenSpec{
+ Addrs: ipc.ListenAddrs(lf.Addrs),
+ AddressChooser: internal.IPAddressChooser,
+ Proxy: lf.ListenProxy,
+ }
+
runtime, ctx, shutdown, err := grt.Init(ctx,
ac,
nil,
- &ipc.ListenSpec{
- Addrs: ipc.ListenAddrs{{"tcp", "127.0.0.1:0"}},
- AddressChooser: internal.IPAddressChooser,
- },
+ &listenSpec,
commonFlags.RuntimeFlags(),
nil)
if err != nil {
diff --git a/runtimes/google/ipc/benchmark/RESULTS.txt b/runtimes/google/ipc/benchmark/RESULTS.txt
index b884698..95a44bf 100644
--- a/runtimes/google/ipc/benchmark/RESULTS.txt
+++ b/runtimes/google/ipc/benchmark/RESULTS.txt
@@ -8,1525 +8,1599 @@
continuously in the same process.
================================================================================
-Date: 01/06/2015
+Date: 02/02/2015
Platform: Intel(R) Xeon(R) CPU E5-2689 0 @ 2.60GHz, 66114888KB Memory
-Benchmark____1B 2000 5135719 ns/op 0.00 MB/s
+Benchmark____1B 5000 1941933 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 6 Avg: 4.50
+ Count: 5000 Min: 1 Max: 4 Avg: 1.35
------------------------------------------------------------
- [ 4, 5) 1077 53.9% 53.9% #####
- [ 5, 6) 843 42.2% 96.0% ####
- [ 6, inf) 80 4.0% 100.0%
-Benchmark____1B-2 2000 4968273 ns/op 0.00 MB/s
+ [ 1, 2) 3792 75.8% 75.8% ########
+ [ 2, 3) 734 14.7% 90.5% #
+ [ 3, 4) 397 7.9% 98.5% #
+ [ 4, inf) 77 1.5% 100.0%
+Benchmark____1B-2 5000 1744191 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 6 Avg: 4.32
+ Count: 5000 Min: 1 Max: 3 Avg: 1.17
------------------------------------------------------------
- [ 4, 5) 1364 68.2% 68.2% #######
- [ 5, 6) 628 31.4% 99.6% ###
- [ 6, inf) 8 0.4% 100.0%
-Benchmark___10B 2000 5207706 ns/op 0.00 MB/s
+ [ 1, 2) 4518 90.4% 90.4% #########
+ [ 2, 3) 91 1.8% 92.2%
+ [ 3, inf) 391 7.8% 100.0% #
+Benchmark___10B 5000 2015671 ns/op 0.01 MB/s
--- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 7 Avg: 4.58
+ Count: 5000 Min: 1 Max: 9 Avg: 1.39
------------------------------------------------------------
- [ 4, 5) 1380 69.0% 69.0% #######
- [ 5, 6) 137 6.9% 75.9% #
- [ 6, 7) 424 21.2% 97.1% ##
- [ 7, inf) 59 3.0% 100.0%
-Benchmark___10B-2 2000 5012485 ns/op 0.00 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 7 Avg: 4.35
- ------------------------------------------------------------
- [ 4, 5) 1541 77.1% 77.1% ########
- [ 5, 6) 221 11.1% 88.1% #
- [ 6, 7) 236 11.8% 99.9% #
- [ 7, inf) 2 0.1% 100.0%
-Benchmark__100B 2000 5313342 ns/op 0.04 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 10 Avg: 4.62
- ------------------------------------------------------------
- [ 4, 5) 1505 75.2% 75.2% ########
- [ 5, 6) 122 6.1% 81.4% #
- [ 6, 7) 56 2.8% 84.2%
- [ 7, 8) 259 13.0% 97.1% #
- [ 8, 9) 57 2.9% 100.0%
- [ 9, 10) 0 0.0% 100.0%
- [ 10, inf) 1 0.1% 100.0%
-Benchmark__100B-2 2000 4997534 ns/op 0.04 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 7 Avg: 4.34
- ------------------------------------------------------------
- [ 4, 5) 1649 82.5% 82.5% ########
- [ 5, 6) 18 0.9% 83.4%
- [ 6, 7) 332 16.6% 100.0% ##
- [ 7, inf) 1 0.1% 100.0%
-Benchmark___1KB 2000 5247848 ns/op 0.38 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 9 Avg: 4.62
- ------------------------------------------------------------
- [ 4, 5) 1626 81.3% 81.3% ########
- [ 5, 6) 67 3.4% 84.7%
- [ 6, 7) 12 0.6% 85.2%
- [ 7, 8) 64 3.2% 88.5%
- [ 8, 9) 196 9.8% 98.2% #
- [ 9, inf) 35 1.8% 100.0%
-Benchmark___1KB-2 2000 4925061 ns/op 0.41 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 7 Avg: 4.31
- ------------------------------------------------------------
- [ 4, 5) 1720 86.0% 86.0% #########
- [ 5, 6) 12 0.6% 86.6%
- [ 6, 7) 198 9.9% 96.5% #
- [ 7, inf) 70 3.5% 100.0%
-Benchmark__10KB 2000 5498704 ns/op 3.64 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 11 Avg: 4.79
- ------------------------------------------------------------
- [ 4, 5) 1577 78.9% 78.9% ########
- [ 5, 6) 94 4.7% 83.6%
- [ 6, 7) 47 2.4% 85.9%
- [ 7, 8) 0 0.0% 85.9%
- [ 8, 9) 89 4.5% 90.4%
- [ 9, 10) 123 6.2% 96.5% #
- [ 10, 12) 70 3.5% 100.0%
+ [ 1, 2) 4554 91.1% 91.1% #########
+ [ 2, 3) 17 0.3% 91.4%
+ [ 3, 4) 102 2.0% 93.5%
+ [ 4, 5) 21 0.4% 93.9%
+ [ 5, 6) 60 1.2% 95.1%
+ [ 6, 8) 180 3.6% 98.7%
+ [ 8, 10) 66 1.3% 100.0%
+ [ 10, 12) 0 0.0% 100.0%
[ 12, inf) 0 0.0% 100.0%
-Benchmark__10KB-2 2000 5046850 ns/op 3.96 MB/s
+Benchmark___10B-2 5000 1830436 ns/op 0.01 MB/s
--- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 9 Avg: 4.42
+ Count: 5000 Min: 1 Max: 6 Avg: 1.20
------------------------------------------------------------
- [ 4, 5) 1689 84.5% 84.5% ########
- [ 5, 6) 50 2.5% 87.0%
- [ 6, 7) 0 0.0% 87.0%
- [ 7, 8) 251 12.6% 99.5% #
- [ 8, 9) 7 0.4% 99.9%
- [ 9, inf) 3 0.2% 100.0%
-Benchmark_100KB 1000 7995692 ns/op 25.01 MB/s
+ [ 1, 2) 4731 94.6% 94.6% #########
+ [ 2, 3) 21 0.4% 95.0%
+ [ 3, 4) 0 0.0% 95.0%
+ [ 4, 5) 47 0.9% 96.0%
+ [ 5, 6) 161 3.2% 99.2%
+ [ 6, inf) 40 0.8% 100.0%
+Benchmark__100B 3000 2140626 ns/op 0.09 MB/s
--- Histogram (unit: ms)
- Count: 1000 Min: 6 Max: 13 Avg: 7.50
+ Count: 3000 Min: 1 Max: 15 Avg: 1.47
------------------------------------------------------------
- [ 6, 7) 685 68.5% 68.5% #######
- [ 7, 8) 55 5.5% 74.0% #
- [ 8, 9) 17 1.7% 75.7%
- [ 9, 10) 0 0.0% 75.7%
- [ 10, 11) 0 0.0% 75.7%
- [ 11, 12) 63 6.3% 82.0% #
- [ 12, 14) 180 18.0% 100.0% ##
- [ 14, inf) 0 0.0% 100.0%
-Benchmark_100KB-2 1000 6064046 ns/op 32.98 MB/s
+ [ 1, 2) 2811 93.7% 93.7% #########
+ [ 2, 3) 6 0.2% 93.9%
+ [ 3, 4) 5 0.2% 94.1%
+ [ 4, 5) 17 0.6% 94.6%
+ [ 5, 7) 36 1.2% 95.8%
+ [ 7, 9) 19 0.6% 96.5%
+ [ 9, 11) 38 1.3% 97.7%
+ [ 11, 14) 62 2.1% 99.8%
+ [ 14, 18) 6 0.2% 100.0%
+ [ 18, 22) 0 0.0% 100.0%
+ [ 22, 27) 0 0.0% 100.0%
+ [ 27, 33) 0 0.0% 100.0%
+ [ 33, 41) 0 0.0% 100.0%
+ [ 41, 50) 0 0.0% 100.0%
+ [ 50, inf) 0 0.0% 100.0%
+Benchmark__100B-2 5000 1852904 ns/op 0.11 MB/s
--- Histogram (unit: ms)
- Count: 1000 Min: 5 Max: 9 Avg: 5.77
+ Count: 5000 Min: 1 Max: 11 Avg: 1.21
------------------------------------------------------------
- [ 5, 6) 762 76.2% 76.2% ########
- [ 6, 7) 3 0.3% 76.5%
- [ 7, 8) 0 0.0% 76.5%
- [ 8, 9) 173 17.3% 93.8% ##
- [ 9, inf) 62 6.2% 100.0% #
-
-Benchmark____1_chunk_____1B 2000 5445727 ns/op 0.00 MB/s
+ [ 1, 2) 4803 96.1% 96.1% ##########
+ [ 2, 3) 20 0.4% 96.5%
+ [ 3, 4) 0 0.0% 96.5%
+ [ 4, 5) 0 0.0% 96.5%
+ [ 5, 6) 0 0.0% 96.5%
+ [ 6, 8) 160 3.2% 99.7%
+ [ 8, 10) 9 0.2% 99.8%
+ [ 10, 12) 8 0.2% 100.0%
+ [ 12, 15) 0 0.0% 100.0%
+ [ 15, 18) 0 0.0% 100.0%
+ [ 18, inf) 0 0.0% 100.0%
+Benchmark___1KB 3000 2231959 ns/op 0.90 MB/s
--- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 7 Avg: 4.87
+ Count: 3000 Min: 1 Max: 19 Avg: 1.53
------------------------------------------------------------
- [ 4, 5) 664 33.2% 33.2% ###
- [ 5, 6) 940 47.0% 80.2% #####
- [ 6, 7) 395 19.8% 100.0% ##
- [ 7, inf) 1 0.1% 100.0%
-Benchmark____1_chunk_____1B-2 2000 5178446 ns/op 0.00 MB/s
+ [ 1, 2) 2875 95.8% 95.8% ##########
+ [ 2, 3) 1 0.0% 95.9%
+ [ 3, 4) 0 0.0% 95.9%
+ [ 4, 5) 0 0.0% 95.9%
+ [ 5, 7) 8 0.3% 96.1%
+ [ 7, 9) 21 0.7% 96.8%
+ [ 9, 12) 0 0.0% 96.8%
+ [ 12, 15) 29 1.0% 97.8%
+ [ 15, 19) 56 1.9% 99.7%
+ [ 19, 24) 10 0.3% 100.0%
+ [ 24, 30) 0 0.0% 100.0%
+ [ 30, 38) 0 0.0% 100.0%
+ [ 38, 48) 0 0.0% 100.0%
+ [ 48, 60) 0 0.0% 100.0%
+ [ 60, 74) 0 0.0% 100.0%
+ [ 74, 91) 0 0.0% 100.0%
+ [ 91, inf) 0 0.0% 100.0%
+Benchmark___1KB-2 3000 2078680 ns/op 0.96 MB/s
--- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 6 Avg: 4.46
+ Count: 3000 Min: 1 Max: 12 Avg: 1.35
------------------------------------------------------------
- [ 4, 5) 1130 56.5% 56.5% ######
- [ 5, 6) 825 41.2% 97.8% ####
- [ 6, inf) 45 2.2% 100.0%
-Benchmark____1_chunk____10B 2000 5545419 ns/op 0.00 MB/s
+ [ 1, 2) 2699 90.0% 90.0% #########
+ [ 2, 3) 213 7.1% 97.1% #
+ [ 3, 4) 0 0.0% 97.1%
+ [ 4, 5) 0 0.0% 97.1%
+ [ 5, 6) 0 0.0% 97.1%
+ [ 6, 8) 0 0.0% 97.1%
+ [ 8, 10) 20 0.7% 97.7%
+ [ 10, 13) 68 2.3% 100.0%
+ [ 13, 16) 0 0.0% 100.0%
+ [ 16, 20) 0 0.0% 100.0%
+ [ 20, 24) 0 0.0% 100.0%
+ [ 24, inf) 0 0.0% 100.0%
+Benchmark__10KB 3000 2548055 ns/op 7.85 MB/s
--- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 7 Avg: 4.89
+ Count: 3000 Min: 1 Max: 24 Avg: 1.73
------------------------------------------------------------
- [ 4, 5) 985 49.2% 49.2% #####
- [ 5, 6) 473 23.7% 72.9% ##
- [ 6, 7) 321 16.1% 89.0% ##
- [ 7, inf) 221 11.1% 100.0% #
-Benchmark____1_chunk____10B-2 2000 5217440 ns/op 0.00 MB/s
+ [ 1, 2) 2665 88.8% 88.8% #########
+ [ 2, 3) 196 6.5% 95.4% #
+ [ 3, 4) 0 0.0% 95.4%
+ [ 4, 5) 0 0.0% 95.4%
+ [ 5, 7) 0 0.0% 95.4%
+ [ 7, 9) 42 1.4% 96.8%
+ [ 9, 12) 0 0.0% 96.8%
+ [ 12, 16) 30 1.0% 97.8%
+ [ 16, 21) 19 0.6% 98.4%
+ [ 21, 27) 48 1.6% 100.0%
+ [ 27, 35) 0 0.0% 100.0%
+ [ 35, 44) 0 0.0% 100.0%
+ [ 44, 56) 0 0.0% 100.0%
+ [ 56, 71) 0 0.0% 100.0%
+ [ 71, 89) 0 0.0% 100.0%
+ [ 89, 111) 0 0.0% 100.0%
+ [111, inf) 0 0.0% 100.0%
+Benchmark__10KB-2 3000 2242089 ns/op 8.92 MB/s
--- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 6 Avg: 4.55
+ Count: 3000 Min: 1 Max: 14 Avg: 1.53
------------------------------------------------------------
- [ 4, 5) 1311 65.5% 65.5% #######
- [ 5, 6) 279 14.0% 79.5% #
- [ 6, inf) 410 20.5% 100.0% ##
-Benchmark____1_chunk___100B 2000 5607749 ns/op 0.04 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 9 Avg: 5.00
- ------------------------------------------------------------
- [ 4, 5) 981 49.1% 49.1% #####
- [ 5, 6) 614 30.7% 79.8% ###
- [ 6, 7) 10 0.5% 80.2%
- [ 7, 8) 216 10.8% 91.1% #
- [ 8, 9) 178 8.9% 100.0% #
- [ 9, inf) 1 0.1% 100.0%
-Benchmark____1_chunk___100B-2 2000 5221803 ns/op 0.04 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 7 Avg: 4.48
- ------------------------------------------------------------
- [ 4, 5) 1421 71.0% 71.0% #######
- [ 5, 6) 223 11.2% 82.2% #
- [ 6, 7) 329 16.4% 98.7% ##
- [ 7, inf) 27 1.4% 100.0%
-Benchmark____1_chunk____1KB 2000 5499778 ns/op 0.36 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 10 Avg: 4.74
- ------------------------------------------------------------
- [ 4, 5) 1456 72.8% 72.8% #######
- [ 5, 6) 214 10.7% 83.5% #
- [ 6, 7) 12 0.6% 84.1%
- [ 7, 8) 72 3.6% 87.7%
- [ 8, 9) 205 10.2% 98.0% #
- [ 9, 10) 40 2.0% 100.0%
- [ 10, inf) 1 0.1% 100.0%
-Benchmark____1_chunk____1KB-2 2000 5131389 ns/op 0.39 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 7 Avg: 4.41
- ------------------------------------------------------------
- [ 4, 5) 1621 81.1% 81.1% ########
- [ 5, 6) 89 4.5% 85.5%
- [ 6, 7) 149 7.5% 93.0% #
- [ 7, inf) 141 7.1% 100.0% #
-Benchmark____1_chunk___10KB 2000 5747560 ns/op 3.48 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 11 Avg: 5.12
- ------------------------------------------------------------
- [ 4, 5) 1023 51.2% 51.2% #####
- [ 5, 6) 598 29.9% 81.1% ###
- [ 6, 7) 78 3.9% 85.0%
- [ 7, 8) 1 0.1% 85.0%
- [ 8, 9) 72 3.6% 88.6%
- [ 9, 10) 164 8.2% 96.8% #
- [ 10, 12) 64 3.2% 100.0%
- [ 12, inf) 0 0.0% 100.0%
-Benchmark____1_chunk___10KB-2 2000 5240887 ns/op 3.82 MB/s
---- Histogram (unit: ms)
- Count: 2000 Min: 4 Max: 10 Avg: 4.55
- ------------------------------------------------------------
- [ 4, 5) 1515 75.8% 75.8% ########
- [ 5, 6) 208 10.4% 86.2% #
- [ 6, 7) 0 0.0% 86.2%
- [ 7, 8) 231 11.6% 97.7% #
- [ 8, 9) 29 1.5% 99.2%
- [ 9, 10) 16 0.8% 100.0%
- [ 10, inf) 1 0.1% 100.0%
-Benchmark____1_chunk__100KB 1000 8096470 ns/op 24.70 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 6 Max: 13 Avg: 7.54
- ------------------------------------------------------------
- [ 6, 7) 687 68.7% 68.7% #######
- [ 7, 8) 64 6.4% 75.1% #
- [ 8, 9) 1 0.1% 75.2%
- [ 9, 10) 0 0.0% 75.2%
- [ 10, 11) 0 0.0% 75.2%
- [ 11, 12) 24 2.4% 77.6%
- [ 12, 14) 224 22.4% 100.0% ##
- [ 14, inf) 0 0.0% 100.0%
-Benchmark____1_chunk__100KB-2 1000 6401830 ns/op 31.24 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 5 Max: 11 Avg: 5.91
- ------------------------------------------------------------
- [ 5, 6) 748 74.8% 74.8% #######
- [ 6, 7) 14 1.4% 76.2%
- [ 7, 8) 1 0.1% 76.3%
- [ 8, 9) 106 10.6% 86.9% #
- [ 9, 10) 81 8.1% 95.0% #
- [ 10, 11) 46 4.6% 99.6%
- [ 11, inf) 4 0.4% 100.0%
-Benchmark___10_chunk_____1B 1000 7091901 ns/op 0.00 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 5 Max: 14 Avg: 6.78
- ------------------------------------------------------------
- [ 5, 6) 28 2.8% 2.8%
- [ 6, 7) 819 81.9% 84.7% ########
- [ 7, 8) 10 1.0% 85.7%
- [ 8, 9) 25 2.5% 88.2%
- [ 9, 10) 0 0.0% 88.2%
- [ 10, 12) 30 3.0% 91.2%
- [ 12, 14) 86 8.6% 99.8% #
- [ 14, 16) 2 0.2% 100.0%
- [ 16, 19) 0 0.0% 100.0%
- [ 19, inf) 0 0.0% 100.0%
-Benchmark___10_chunk_____1B-2 1000 6297751 ns/op 0.00 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 5 Max: 11 Avg: 5.68
- ------------------------------------------------------------
- [ 5, 6) 759 75.9% 75.9% ########
- [ 6, 7) 118 11.8% 87.7% #
- [ 7, 8) 0 0.0% 87.7%
- [ 8, 9) 14 1.4% 89.1%
- [ 9, 10) 40 4.0% 93.1%
- [ 10, 11) 51 5.1% 98.2% #
- [ 11, inf) 18 1.8% 100.0%
-Benchmark___10_chunk____10B 1000 7358008 ns/op 0.03 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 6 Max: 16 Avg: 6.88
- ------------------------------------------------------------
- [ 6, 7) 845 84.5% 84.5% ########
- [ 7, 8) 9 0.9% 85.4%
- [ 8, 9) 28 2.8% 88.2%
- [ 9, 10) 0 0.0% 88.2%
- [ 10, 11) 0 0.0% 88.2%
- [ 11, 13) 29 2.9% 91.1%
- [ 13, 15) 86 8.6% 99.7% #
- [ 15, 17) 3 0.3% 100.0%
- [ 17, 20) 0 0.0% 100.0%
- [ 20, 23) 0 0.0% 100.0%
- [ 23, inf) 0 0.0% 100.0%
-Benchmark___10_chunk____10B-2 1000 6307487 ns/op 0.03 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 5 Max: 12 Avg: 5.67
- ------------------------------------------------------------
- [ 5, 6) 779 77.9% 77.9% ########
- [ 6, 7) 103 10.3% 88.2% #
- [ 7, 8) 2 0.2% 88.4%
- [ 8, 9) 9 0.9% 89.3%
- [ 9, 10) 40 4.0% 93.3%
- [ 10, 11) 32 3.2% 96.5%
- [ 11, 13) 35 3.5% 100.0%
- [ 13, inf) 0 0.0% 100.0%
-Benchmark___10_chunk___100B 1000 7583639 ns/op 0.26 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 6 Max: 16 Avg: 6.96
- ------------------------------------------------------------
- [ 6, 7) 833 83.3% 83.3% ########
- [ 7, 8) 27 2.7% 86.0%
- [ 8, 9) 22 2.2% 88.2%
- [ 9, 10) 5 0.5% 88.7%
- [ 10, 11) 0 0.0% 88.7%
- [ 11, 13) 26 2.6% 91.3%
- [ 13, 15) 68 6.8% 98.1% #
- [ 15, 17) 19 1.9% 100.0%
- [ 17, 20) 0 0.0% 100.0%
- [ 20, 23) 0 0.0% 100.0%
- [ 23, inf) 0 0.0% 100.0%
-Benchmark___10_chunk___100B-2 1000 6213319 ns/op 0.32 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 5 Max: 11 Avg: 5.56
- ------------------------------------------------------------
- [ 5, 6) 831 83.1% 83.1% ########
- [ 6, 7) 58 5.8% 88.9% #
- [ 7, 8) 0 0.0% 88.9%
- [ 8, 9) 0 0.0% 88.9%
- [ 9, 10) 58 5.8% 94.7% #
- [ 10, 11) 52 5.2% 99.9% #
- [ 11, inf) 1 0.1% 100.0%
-Benchmark___10_chunk____1KB 1000 7839146 ns/op 2.55 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 6 Max: 17 Avg: 7.15
- ------------------------------------------------------------
- [ 6, 7) 793 79.3% 79.3% ########
- [ 7, 8) 60 6.0% 85.3% #
- [ 8, 9) 4 0.4% 85.7%
- [ 9, 10) 26 2.6% 88.3%
- [ 10, 11) 1 0.1% 88.4%
- [ 11, 13) 0 0.0% 88.4%
- [ 13, 15) 31 3.1% 91.5%
- [ 15, 18) 85 8.5% 100.0% #
- [ 18, 21) 0 0.0% 100.0%
- [ 21, 25) 0 0.0% 100.0%
- [ 25, 29) 0 0.0% 100.0%
- [ 29, inf) 0 0.0% 100.0%
-Benchmark___10_chunk____1KB-2 1000 6437679 ns/op 3.11 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 5 Max: 13 Avg: 5.79
- ------------------------------------------------------------
- [ 5, 6) 757 75.7% 75.7% ########
- [ 6, 7) 129 12.9% 88.6% #
- [ 7, 8) 1 0.1% 88.7%
- [ 8, 9) 0 0.0% 88.7%
- [ 9, 10) 17 1.7% 90.4%
- [ 10, 12) 51 5.1% 95.5% #
- [ 12, 14) 45 4.5% 100.0%
- [ 14, 16) 0 0.0% 100.0%
- [ 16, inf) 0 0.0% 100.0%
-Benchmark___10_chunk___10KB 1000 10124684 ns/op 19.75 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 8 Max: 20 Avg: 9.76
- ------------------------------------------------------------
- [ 8, 9) 746 74.6% 74.6% #######
- [ 9, 10) 6 0.6% 75.2%
- [ 10, 11) 53 5.3% 80.5% #
- [ 11, 12) 3 0.3% 80.8%
- [ 12, 13) 0 0.0% 80.8%
- [ 13, 15) 0 0.0% 80.8%
- [ 15, 17) 56 5.6% 86.4% #
- [ 17, 20) 135 13.5% 99.9% #
- [ 20, 23) 1 0.1% 100.0%
- [ 23, 27) 0 0.0% 100.0%
- [ 27, 32) 0 0.0% 100.0%
- [ 32, 38) 0 0.0% 100.0%
+ [ 1, 2) 2328 77.6% 77.6% ########
+ [ 2, 3) 581 19.4% 97.0% ##
+ [ 3, 4) 0 0.0% 97.0%
+ [ 4, 5) 0 0.0% 97.0%
+ [ 5, 6) 0 0.0% 97.0%
+ [ 6, 8) 0 0.0% 97.0%
+ [ 8, 10) 0 0.0% 97.0%
+ [ 10, 13) 45 1.5% 98.5%
+ [ 13, 16) 46 1.5% 100.0%
+ [ 16, 20) 0 0.0% 100.0%
+ [ 20, 25) 0 0.0% 100.0%
+ [ 25, 31) 0 0.0% 100.0%
+ [ 31, 38) 0 0.0% 100.0%
[ 38, inf) 0 0.0% 100.0%
-Benchmark___10_chunk___10KB-2 1000 7345578 ns/op 27.23 MB/s
+Benchmark_100KB 2000 5112233 ns/op 39.12 MB/s
--- Histogram (unit: ms)
- Count: 1000 Min: 5 Max: 14 Avg: 6.95
+ Count: 2000 Min: 3 Max: 26 Avg: 4.49
------------------------------------------------------------
- [ 5, 6) 153 15.3% 15.3% ##
- [ 6, 7) 616 61.6% 76.9% ######
- [ 7, 8) 43 4.3% 81.2%
- [ 8, 9) 2 0.2% 81.4%
- [ 9, 10) 1 0.1% 81.5%
- [ 10, 12) 73 7.3% 88.8% #
- [ 12, 14) 104 10.4% 99.2% #
- [ 14, 16) 8 0.8% 100.0%
- [ 16, 19) 0 0.0% 100.0%
- [ 19, inf) 0 0.0% 100.0%
-Benchmark___10_chunk__100KB 200 31538364 ns/op 63.41 MB/s
+ [ 3, 4) 1819 91.0% 91.0% #########
+ [ 4, 5) 0 0.0% 91.0%
+ [ 5, 6) 0 0.0% 91.0%
+ [ 6, 7) 0 0.0% 91.0%
+ [ 7, 9) 44 2.2% 93.2%
+ [ 9, 11) 1 0.1% 93.2%
+ [ 11, 14) 0 0.0% 93.2%
+ [ 14, 18) 0 0.0% 93.2%
+ [ 18, 23) 45 2.2% 95.5%
+ [ 23, 29) 91 4.5% 100.0%
+ [ 29, 37) 0 0.0% 100.0%
+ [ 37, 46) 0 0.0% 100.0%
+ [ 46, 58) 0 0.0% 100.0%
+ [ 58, 73) 0 0.0% 100.0%
+ [ 73, 91) 0 0.0% 100.0%
+ [ 91, 113) 0 0.0% 100.0%
+ [113, inf) 0 0.0% 100.0%
+Benchmark_100KB-2 2000 3661880 ns/op 54.62 MB/s
--- Histogram (unit: ms)
- Count: 200 Min: 24 Max: 37 Avg: 31.07
+ Count: 2000 Min: 2 Max: 19 Avg: 3.00
------------------------------------------------------------
- [ 24, 25) 5 2.5% 2.5%
- [ 25, 26) 60 30.0% 32.5% ###
- [ 26, 27) 2 1.0% 33.5%
- [ 27, 28) 0 0.0% 33.5%
- [ 28, 29) 0 0.0% 33.5%
- [ 29, 31) 0 0.0% 33.5%
- [ 31, 33) 0 0.0% 33.5%
- [ 33, 36) 129 64.5% 98.0% ######
- [ 36, 39) 4 2.0% 100.0%
- [ 39, 43) 0 0.0% 100.0%
- [ 43, 48) 0 0.0% 100.0%
- [ 48, 54) 0 0.0% 100.0%
- [ 54, 61) 0 0.0% 100.0%
- [ 61, inf) 0 0.0% 100.0%
-Benchmark___10_chunk__100KB-2 500 19099352 ns/op 104.72 MB/s
+ [ 2, 3) 1657 82.9% 82.9% ########
+ [ 3, 4) 143 7.2% 90.0% #
+ [ 4, 5) 67 3.4% 93.4%
+ [ 5, 6) 1 0.1% 93.4%
+ [ 6, 8) 0 0.0% 93.4%
+ [ 8, 10) 0 0.0% 93.4%
+ [ 10, 13) 13 0.7% 94.1%
+ [ 13, 16) 48 2.4% 96.5%
+ [ 16, 20) 71 3.6% 100.0%
+ [ 20, 25) 0 0.0% 100.0%
+ [ 25, 31) 0 0.0% 100.0%
+ [ 31, 38) 0 0.0% 100.0%
+ [ 38, 47) 0 0.0% 100.0%
+ [ 47, 58) 0 0.0% 100.0%
+ [ 58, 72) 0 0.0% 100.0%
+ [ 72, 89) 0 0.0% 100.0%
+ [ 89, inf) 0 0.0% 100.0%
+
+Benchmark____1_chunk_____1B 3000 2154678 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 500 Min: 14 Max: 27 Avg: 18.58
+ Count: 3000 Min: 1 Max: 4 Avg: 1.42
------------------------------------------------------------
- [ 14, 15) 53 10.6% 10.6% #
- [ 15, 16) 109 21.8% 32.4% ##
- [ 16, 17) 15 3.0% 35.4%
- [ 17, 18) 0 0.0% 35.4%
- [ 18, 19) 2 0.4% 35.8%
- [ 19, 21) 161 32.2% 68.0% ###
- [ 21, 23) 141 28.2% 96.2% ###
- [ 23, 26) 18 3.6% 99.8%
- [ 26, 29) 1 0.2% 100.0%
- [ 29, 33) 0 0.0% 100.0%
- [ 33, 38) 0 0.0% 100.0%
- [ 38, 44) 0 0.0% 100.0%
- [ 44, 51) 0 0.0% 100.0%
- [ 51, inf) 0 0.0% 100.0%
-Benchmark__100_chunk_____1B 500 19824819 ns/op 0.01 MB/s
+ [ 1, 2) 2069 69.0% 69.0% #######
+ [ 2, 3) 599 20.0% 88.9% ##
+ [ 3, 4) 331 11.0% 100.0% #
+ [ 4, inf) 1 0.0% 100.0%
+Benchmark____1_chunk_____1B-2 5000 1907902 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 500 Min: 16 Max: 34 Avg: 19.44
+ Count: 5000 Min: 1 Max: 4 Avg: 1.21
------------------------------------------------------------
- [ 16, 17) 272 54.4% 54.4% #####
- [ 17, 18) 15 3.0% 57.4%
- [ 18, 19) 2 0.4% 57.8%
- [ 19, 20) 38 7.6% 65.4% #
- [ 20, 22) 33 6.6% 72.0% #
- [ 22, 24) 23 4.6% 76.6%
- [ 24, 27) 41 8.2% 84.8% #
- [ 27, 30) 64 12.8% 97.6% #
- [ 30, 34) 11 2.2% 99.8%
- [ 34, 39) 1 0.2% 100.0%
- [ 39, 45) 0 0.0% 100.0%
- [ 45, 53) 0 0.0% 100.0%
- [ 53, 63) 0 0.0% 100.0%
- [ 63, 75) 0 0.0% 100.0%
- [ 75, 89) 0 0.0% 100.0%
- [ 89, 106) 0 0.0% 100.0%
- [106, inf) 0 0.0% 100.0%
-Benchmark__100_chunk_____1B-2 500 14793583 ns/op 0.01 MB/s
+ [ 1, 2) 4345 86.9% 86.9% #########
+ [ 2, 3) 275 5.5% 92.4% #
+ [ 3, 4) 377 7.5% 99.9% #
+ [ 4, inf) 3 0.1% 100.0%
+Benchmark____1_chunk____10B 3000 2234222 ns/op 0.01 MB/s
--- Histogram (unit: ms)
- Count: 500 Min: 11 Max: 23 Avg: 14.28
+ Count: 3000 Min: 1 Max: 7 Avg: 1.44
------------------------------------------------------------
- [ 11, 12) 15 3.0% 3.0%
- [ 12, 13) 210 42.0% 45.0% ####
- [ 13, 14) 107 21.4% 66.4% ##
- [ 14, 15) 19 3.8% 70.2%
- [ 15, 16) 1 0.2% 70.4%
- [ 16, 18) 23 4.6% 75.0%
- [ 18, 20) 91 18.2% 93.2% ##
- [ 20, 23) 31 6.2% 99.4% #
- [ 23, 26) 3 0.6% 100.0%
- [ 26, 30) 0 0.0% 100.0%
- [ 30, 35) 0 0.0% 100.0%
- [ 35, 41) 0 0.0% 100.0%
- [ 41, inf) 0 0.0% 100.0%
-Benchmark__100_chunk____10B 300 24818102 ns/op 0.08 MB/s
+ [ 1, 2) 2603 86.8% 86.8% #########
+ [ 2, 3) 65 2.2% 88.9%
+ [ 3, 4) 77 2.6% 91.5%
+ [ 4, 5) 50 1.7% 93.2%
+ [ 5, 6) 87 2.9% 96.1%
+ [ 6, 7) 117 3.9% 100.0%
+ [ 7, inf) 1 0.0% 100.0%
+Benchmark____1_chunk____10B-2 5000 1920770 ns/op 0.01 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 20 Max: 35 Avg: 24.38
+ Count: 5000 Min: 1 Max: 5 Avg: 1.21
------------------------------------------------------------
- [ 20, 21) 7 2.3% 2.3%
- [ 21, 22) 145 48.3% 50.7% #####
- [ 22, 23) 29 9.7% 60.3% #
- [ 23, 24) 4 1.3% 61.7%
- [ 24, 26) 25 8.3% 70.0% #
- [ 26, 28) 4 1.3% 71.3%
- [ 28, 30) 24 8.0% 79.3% #
- [ 30, 33) 43 14.3% 93.7% #
- [ 33, 37) 19 6.3% 100.0% #
- [ 37, 42) 0 0.0% 100.0%
- [ 42, 48) 0 0.0% 100.0%
- [ 48, 55) 0 0.0% 100.0%
- [ 55, 63) 0 0.0% 100.0%
- [ 63, 73) 0 0.0% 100.0%
- [ 73, 85) 0 0.0% 100.0%
- [ 85, inf) 0 0.0% 100.0%
-Benchmark__100_chunk____10B-2 500 15081537 ns/op 0.13 MB/s
+ [ 1, 2) 4571 91.4% 91.4% #########
+ [ 2, 3) 106 2.1% 93.5%
+ [ 3, 4) 23 0.5% 94.0%
+ [ 4, 5) 284 5.7% 99.7% #
+ [ 5, inf) 16 0.3% 100.0%
+Benchmark____1_chunk___100B 3000 2296619 ns/op 0.09 MB/s
--- Histogram (unit: ms)
- Count: 500 Min: 11 Max: 25 Avg: 14.57
+ Count: 3000 Min: 1 Max: 12 Avg: 1.49
------------------------------------------------------------
- [ 11, 12) 1 0.2% 0.2%
- [ 12, 13) 182 36.4% 36.6% ####
- [ 13, 14) 143 28.6% 65.2% ###
- [ 14, 15) 23 4.6% 69.8%
- [ 15, 17) 7 1.4% 71.2%
- [ 17, 19) 51 10.2% 81.4% #
- [ 19, 21) 55 11.0% 92.4% #
- [ 21, 24) 34 6.8% 99.2% #
- [ 24, 28) 4 0.8% 100.0%
- [ 28, 32) 0 0.0% 100.0%
- [ 32, 37) 0 0.0% 100.0%
- [ 37, 43) 0 0.0% 100.0%
- [ 43, 51) 0 0.0% 100.0%
- [ 51, 60) 0 0.0% 100.0%
- [ 60, inf) 0 0.0% 100.0%
-Benchmark__100_chunk___100B 300 27491526 ns/op 0.73 MB/s
+ [ 1, 2) 2680 89.3% 89.3% #########
+ [ 2, 3) 98 3.3% 92.6%
+ [ 3, 4) 10 0.3% 92.9%
+ [ 4, 5) 53 1.8% 94.7%
+ [ 5, 6) 2 0.1% 94.8%
+ [ 6, 8) 57 1.9% 96.7%
+ [ 8, 10) 55 1.8% 98.5%
+ [ 10, 13) 45 1.5% 100.0%
+ [ 13, 16) 0 0.0% 100.0%
+ [ 16, 20) 0 0.0% 100.0%
+ [ 20, 24) 0 0.0% 100.0%
+ [ 24, inf) 0 0.0% 100.0%
+Benchmark____1_chunk___100B-2 5000 1971568 ns/op 0.10 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 23 Max: 38 Avg: 26.94
+ Count: 5000 Min: 1 Max: 7 Avg: 1.26
------------------------------------------------------------
- [ 23, 24) 104 34.7% 34.7% ###
- [ 24, 25) 67 22.3% 57.0% ##
- [ 25, 26) 10 3.3% 60.3%
- [ 26, 27) 8 2.7% 63.0%
- [ 27, 29) 23 7.7% 70.7% #
- [ 29, 31) 0 0.0% 70.7%
- [ 31, 33) 22 7.3% 78.0% #
- [ 33, 36) 57 19.0% 97.0% ##
- [ 36, 40) 9 3.0% 100.0%
- [ 40, 45) 0 0.0% 100.0%
- [ 45, 51) 0 0.0% 100.0%
- [ 51, 58) 0 0.0% 100.0%
- [ 58, 66) 0 0.0% 100.0%
- [ 66, 76) 0 0.0% 100.0%
- [ 76, 88) 0 0.0% 100.0%
- [ 88, inf) 0 0.0% 100.0%
-Benchmark__100_chunk___100B-2 500 15897395 ns/op 1.26 MB/s
+ [ 1, 2) 4521 90.4% 90.4% #########
+ [ 2, 3) 257 5.1% 95.6% #
+ [ 3, 4) 0 0.0% 95.6%
+ [ 4, 5) 0 0.0% 95.6%
+ [ 5, 6) 66 1.3% 96.9%
+ [ 6, 7) 155 3.1% 100.0%
+ [ 7, inf) 1 0.0% 100.0%
+Benchmark____1_chunk____1KB 3000 2399265 ns/op 0.83 MB/s
--- Histogram (unit: ms)
- Count: 500 Min: 12 Max: 24 Avg: 15.40
+ Count: 3000 Min: 1 Max: 17 Avg: 1.56
------------------------------------------------------------
- [ 12, 13) 5 1.0% 1.0%
- [ 13, 14) 226 45.2% 46.2% #####
- [ 14, 15) 107 21.4% 67.6% ##
- [ 15, 16) 16 3.2% 70.8%
- [ 16, 17) 0 0.0% 70.8%
- [ 17, 19) 12 2.4% 73.2%
- [ 19, 21) 92 18.4% 91.6% ##
- [ 21, 24) 35 7.0% 98.6% #
- [ 24, 27) 7 1.4% 100.0%
- [ 27, 31) 0 0.0% 100.0%
- [ 31, 36) 0 0.0% 100.0%
- [ 36, 42) 0 0.0% 100.0%
- [ 42, inf) 0 0.0% 100.0%
-Benchmark__100_chunk____1KB 200 30390593 ns/op 6.58 MB/s
+ [ 1, 2) 2695 89.8% 89.8% #########
+ [ 2, 3) 146 4.9% 94.7%
+ [ 3, 4) 3 0.1% 94.8%
+ [ 4, 5) 1 0.0% 94.8%
+ [ 5, 7) 42 1.4% 96.2%
+ [ 7, 9) 0 0.0% 96.2%
+ [ 9, 12) 43 1.4% 97.7%
+ [ 12, 15) 42 1.4% 99.1%
+ [ 15, 19) 28 0.9% 100.0%
+ [ 19, 24) 0 0.0% 100.0%
+ [ 24, 30) 0 0.0% 100.0%
+ [ 30, 37) 0 0.0% 100.0%
+ [ 37, 46) 0 0.0% 100.0%
+ [ 46, 57) 0 0.0% 100.0%
+ [ 57, 70) 0 0.0% 100.0%
+ [ 70, 86) 0 0.0% 100.0%
+ [ 86, inf) 0 0.0% 100.0%
+Benchmark____1_chunk____1KB-2 5000 2143186 ns/op 0.93 MB/s
--- Histogram (unit: ms)
- Count: 200 Min: 25 Max: 41 Avg: 29.77
+ Count: 5000 Min: 1 Max: 12 Avg: 1.47
------------------------------------------------------------
- [ 25, 26) 68 34.0% 34.0% ###
- [ 26, 27) 26 13.0% 47.0% #
- [ 27, 28) 8 4.0% 51.0%
- [ 28, 29) 9 4.5% 55.5%
- [ 29, 31) 18 9.0% 64.5% #
- [ 31, 33) 1 0.5% 65.0%
- [ 33, 36) 24 12.0% 77.0% #
- [ 36, 39) 39 19.5% 96.5% ##
- [ 39, 43) 7 3.5% 100.0%
- [ 43, 48) 0 0.0% 100.0%
- [ 48, 54) 0 0.0% 100.0%
- [ 54, 61) 0 0.0% 100.0%
- [ 61, 70) 0 0.0% 100.0%
- [ 70, 81) 0 0.0% 100.0%
- [ 81, 94) 0 0.0% 100.0%
- [ 94, 110) 0 0.0% 100.0%
- [110, inf) 0 0.0% 100.0%
-Benchmark__100_chunk____1KB-2 500 17949156 ns/op 11.14 MB/s
+ [ 1, 2) 3732 74.6% 74.6% #######
+ [ 2, 3) 1100 22.0% 96.6% ##
+ [ 3, 4) 0 0.0% 96.6%
+ [ 4, 5) 0 0.0% 96.6%
+ [ 5, 6) 0 0.0% 96.6%
+ [ 6, 8) 52 1.0% 97.7%
+ [ 8, 10) 62 1.2% 98.9%
+ [ 10, 13) 54 1.1% 100.0%
+ [ 13, 16) 0 0.0% 100.0%
+ [ 16, 20) 0 0.0% 100.0%
+ [ 20, 24) 0 0.0% 100.0%
+ [ 24, inf) 0 0.0% 100.0%
+Benchmark____1_chunk___10KB 3000 2829279 ns/op 7.07 MB/s
--- Histogram (unit: ms)
- Count: 500 Min: 14 Max: 26 Avg: 17.41
+ Count: 3000 Min: 1 Max: 26 Avg: 2.72
------------------------------------------------------------
- [ 14, 15) 120 24.0% 24.0% ##
- [ 15, 16) 169 33.8% 57.8% ###
- [ 16, 17) 28 5.6% 63.4% #
- [ 17, 18) 6 1.2% 64.6%
- [ 18, 19) 2 0.4% 65.0%
- [ 19, 21) 19 3.8% 68.8%
- [ 21, 23) 87 17.4% 86.2% ##
- [ 23, 26) 66 13.2% 99.4% #
- [ 26, 29) 3 0.6% 100.0%
- [ 29, 33) 0 0.0% 100.0%
- [ 33, 38) 0 0.0% 100.0%
- [ 38, 44) 0 0.0% 100.0%
- [ 44, inf) 0 0.0% 100.0%
-Benchmark__100_chunk___10KB 100 51722516 ns/op 38.67 MB/s
+ [ 1, 2) 2 0.1% 0.1%
+ [ 2, 3) 2859 95.3% 95.4% ##########
+ [ 3, 4) 0 0.0% 95.4%
+ [ 4, 5) 0 0.0% 95.4%
+ [ 5, 7) 0 0.0% 95.4%
+ [ 7, 9) 27 0.9% 96.3%
+ [ 9, 12) 5 0.2% 96.4%
+ [ 12, 16) 5 0.2% 96.6%
+ [ 16, 21) 37 1.2% 97.8%
+ [ 21, 27) 65 2.2% 100.0%
+ [ 27, 35) 0 0.0% 100.0%
+ [ 35, 45) 0 0.0% 100.0%
+ [ 45, 58) 0 0.0% 100.0%
+ [ 58, 74) 0 0.0% 100.0%
+ [ 74, 94) 0 0.0% 100.0%
+ [ 94, 118) 0 0.0% 100.0%
+ [118, inf) 0 0.0% 100.0%
+Benchmark____1_chunk___10KB-2 3000 2402468 ns/op 8.32 MB/s
--- Histogram (unit: ms)
- Count: 100 Min: 42 Max: 57 Avg: 51.22
+ Count: 3000 Min: 1 Max: 13 Avg: 2.00
------------------------------------------------------------
- [ 42, 43) 1 1.0% 1.0%
- [ 43, 44) 0 0.0% 1.0%
- [ 44, 45) 14 14.0% 15.0% #
- [ 45, 46) 1 1.0% 16.0%
- [ 46, 48) 2 2.0% 18.0%
- [ 48, 50) 0 0.0% 18.0%
- [ 50, 52) 17 17.0% 35.0% ##
- [ 52, 55) 58 58.0% 93.0% ######
- [ 55, 59) 7 7.0% 100.0% #
- [ 59, 64) 0 0.0% 100.0%
- [ 64, 70) 0 0.0% 100.0%
- [ 70, 77) 0 0.0% 100.0%
- [ 77, 85) 0 0.0% 100.0%
- [ 85, 95) 0 0.0% 100.0%
- [ 95, 107) 0 0.0% 100.0%
- [107, inf) 0 0.0% 100.0%
-Benchmark__100_chunk___10KB-2 300 28968863 ns/op 69.04 MB/s
+ [ 1, 2) 879 29.3% 29.3% ###
+ [ 2, 3) 2021 67.4% 96.7% #######
+ [ 3, 4) 0 0.0% 96.7%
+ [ 4, 5) 0 0.0% 96.7%
+ [ 5, 6) 0 0.0% 96.7%
+ [ 6, 8) 0 0.0% 96.7%
+ [ 8, 10) 24 0.8% 97.5%
+ [ 10, 13) 49 1.6% 99.1%
+ [ 13, 16) 27 0.9% 100.0%
+ [ 16, 20) 0 0.0% 100.0%
+ [ 20, 25) 0 0.0% 100.0%
+ [ 25, 31) 0 0.0% 100.0%
+ [ 31, inf) 0 0.0% 100.0%
+Benchmark____1_chunk__100KB 2000 5417885 ns/op 36.91 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 22 Max: 34 Avg: 28.47
+ Count: 2000 Min: 3 Max: 29 Avg: 4.65
------------------------------------------------------------
- [ 22, 23) 30 10.0% 10.0% #
- [ 23, 24) 18 6.0% 16.0% #
- [ 24, 25) 6 2.0% 18.0%
- [ 25, 26) 0 0.0% 18.0%
- [ 26, 27) 0 0.0% 18.0%
- [ 27, 29) 63 21.0% 39.0% ##
- [ 29, 31) 102 34.0% 73.0% ###
- [ 31, 34) 77 25.7% 98.7% ###
- [ 34, 37) 4 1.3% 100.0%
- [ 37, 41) 0 0.0% 100.0%
- [ 41, 46) 0 0.0% 100.0%
- [ 46, 52) 0 0.0% 100.0%
- [ 52, inf) 0 0.0% 100.0%
-Benchmark__100_chunk__100KB 30 251752470 ns/op 79.44 MB/s
+ [ 3, 4) 1730 86.5% 86.5% #########
+ [ 4, 5) 54 2.7% 89.2%
+ [ 5, 6) 0 0.0% 89.2%
+ [ 6, 7) 0 0.0% 89.2%
+ [ 7, 9) 27 1.4% 90.6%
+ [ 9, 11) 45 2.2% 92.8%
+ [ 11, 14) 0 0.0% 92.8%
+ [ 14, 18) 0 0.0% 92.8%
+ [ 18, 23) 69 3.5% 96.2%
+ [ 23, 30) 75 3.8% 100.0%
+ [ 30, 38) 0 0.0% 100.0%
+ [ 38, 48) 0 0.0% 100.0%
+ [ 48, 61) 0 0.0% 100.0%
+ [ 61, 77) 0 0.0% 100.0%
+ [ 77, 97) 0 0.0% 100.0%
+ [ 97, 122) 0 0.0% 100.0%
+ [122, inf) 0 0.0% 100.0%
+Benchmark____1_chunk__100KB-2 2000 3784105 ns/op 52.85 MB/s
--- Histogram (unit: ms)
- Count: 30 Min: 243 Max: 257 Avg: 251.23
+ Count: 2000 Min: 2 Max: 20 Avg: 3.10
------------------------------------------------------------
- [243, 244) 5 16.7% 16.7% ##
- [244, 245) 1 3.3% 20.0%
- [245, 246) 4 13.3% 33.3% #
- [246, 247) 0 0.0% 33.3%
- [247, 249) 0 0.0% 33.3%
- [249, 251) 0 0.0% 33.3%
- [251, 253) 0 0.0% 33.3%
- [253, 256) 14 46.7% 80.0% #####
- [256, 260) 6 20.0% 100.0% ##
- [260, 264) 0 0.0% 100.0%
- [264, 269) 0 0.0% 100.0%
- [269, 275) 0 0.0% 100.0%
- [275, 283) 0 0.0% 100.0%
- [283, 292) 0 0.0% 100.0%
- [292, inf) 0 0.0% 100.0%
-Benchmark__100_chunk__100KB-2 50 131868524 ns/op 151.67 MB/s
+ [ 2, 3) 1356 67.8% 67.8% #######
+ [ 3, 4) 448 22.4% 90.2% ##
+ [ 4, 5) 57 2.9% 93.1%
+ [ 5, 6) 0 0.0% 93.1%
+ [ 6, 8) 0 0.0% 93.1%
+ [ 8, 10) 0 0.0% 93.1%
+ [ 10, 13) 55 2.8% 95.8%
+ [ 13, 16) 59 3.0% 98.8%
+ [ 16, 20) 24 1.2% 100.0%
+ [ 20, 25) 1 0.1% 100.0%
+ [ 25, 31) 0 0.0% 100.0%
+ [ 31, 39) 0 0.0% 100.0%
+ [ 39, 49) 0 0.0% 100.0%
+ [ 49, 61) 0 0.0% 100.0%
+ [ 61, 75) 0 0.0% 100.0%
+ [ 75, 92) 0 0.0% 100.0%
+ [ 92, inf) 0 0.0% 100.0%
+Benchmark___10_chunk_____1B 2000 3738398 ns/op 0.01 MB/s
--- Histogram (unit: ms)
- Count: 50 Min: 127 Max: 137 Avg: 131.44
+ Count: 2000 Min: 2 Max: 30 Avg: 3.18
------------------------------------------------------------
- [127, 128) 3 6.0% 6.0% #
- [128, 129) 13 26.0% 32.0% ###
- [129, 130) 9 18.0% 50.0% ##
- [130, 131) 1 2.0% 52.0%
- [131, 132) 1 2.0% 54.0%
- [132, 134) 2 4.0% 58.0%
- [134, 136) 14 28.0% 86.0% ###
- [136, 138) 7 14.0% 100.0% #
- [138, 141) 0 0.0% 100.0%
- [141, 144) 0 0.0% 100.0%
- [144, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk_____1B 50 147894706 ns/op 0.01 MB/s
+ [ 2, 3) 1091 54.6% 54.6% #####
+ [ 3, 4) 828 41.4% 96.0% ####
+ [ 4, 5) 0 0.0% 96.0%
+ [ 5, 6) 0 0.0% 96.0%
+ [ 6, 8) 1 0.1% 96.0%
+ [ 8, 11) 0 0.0% 96.0%
+ [ 11, 14) 19 1.0% 97.0%
+ [ 14, 18) 0 0.0% 97.0%
+ [ 18, 23) 19 1.0% 97.9%
+ [ 23, 30) 41 2.1% 100.0%
+ [ 30, 39) 1 0.1% 100.0%
+ [ 39, 50) 0 0.0% 100.0%
+ [ 50, 64) 0 0.0% 100.0%
+ [ 64, 81) 0 0.0% 100.0%
+ [ 81, 103) 0 0.0% 100.0%
+ [103, 130) 0 0.0% 100.0%
+ [130, inf) 0 0.0% 100.0%
+Benchmark___10_chunk_____1B-2 3000 2838899 ns/op 0.01 MB/s
--- Histogram (unit: ms)
- Count: 50 Min: 123 Max: 195 Avg: 147.42
+ Count: 3000 Min: 2 Max: 17 Avg: 2.42
+ ------------------------------------------------------------
+ [ 2, 3) 2705 90.2% 90.2% #########
+ [ 3, 4) 206 6.9% 97.0% #
+ [ 4, 5) 1 0.0% 97.1%
+ [ 5, 6) 0 0.0% 97.1%
+ [ 6, 8) 0 0.0% 97.1%
+ [ 8, 10) 0 0.0% 97.1%
+ [ 10, 12) 4 0.1% 97.2%
+ [ 12, 15) 43 1.4% 98.6%
+ [ 15, 19) 41 1.4% 100.0%
+ [ 19, 24) 0 0.0% 100.0%
+ [ 24, 30) 0 0.0% 100.0%
+ [ 30, 37) 0 0.0% 100.0%
+ [ 37, 45) 0 0.0% 100.0%
+ [ 45, 55) 0 0.0% 100.0%
+ [ 55, 67) 0 0.0% 100.0%
+ [ 67, inf) 0 0.0% 100.0%
+Benchmark___10_chunk____10B 2000 3750396 ns/op 0.05 MB/s
+--- Histogram (unit: ms)
+ Count: 2000 Min: 2 Max: 31 Avg: 3.15
+ ------------------------------------------------------------
+ [ 2, 3) 1179 59.0% 59.0% ######
+ [ 3, 4) 747 37.4% 96.3% ####
+ [ 4, 5) 0 0.0% 96.3%
+ [ 5, 6) 0 0.0% 96.3%
+ [ 6, 8) 0 0.0% 96.3%
+ [ 8, 11) 0 0.0% 96.3%
+ [ 11, 14) 18 0.9% 97.2%
+ [ 14, 18) 0 0.0% 97.2%
+ [ 18, 24) 19 1.0% 98.2%
+ [ 24, 31) 32 1.6% 99.8%
+ [ 31, 40) 5 0.2% 100.0%
+ [ 40, 51) 0 0.0% 100.0%
+ [ 51, 65) 0 0.0% 100.0%
+ [ 65, 83) 0 0.0% 100.0%
+ [ 83, 106) 0 0.0% 100.0%
+ [106, 134) 0 0.0% 100.0%
+ [134, inf) 0 0.0% 100.0%
+Benchmark___10_chunk____10B-2 3000 2669872 ns/op 0.07 MB/s
+--- Histogram (unit: ms)
+ Count: 3000 Min: 2 Max: 14 Avg: 2.37
+ ------------------------------------------------------------
+ [ 2, 3) 2712 90.4% 90.4% #########
+ [ 3, 4) 208 6.9% 97.3% #
+ [ 4, 5) 0 0.0% 97.3%
+ [ 5, 6) 0 0.0% 97.3%
+ [ 6, 7) 0 0.0% 97.3%
+ [ 7, 9) 0 0.0% 97.3%
+ [ 9, 11) 0 0.0% 97.3%
+ [ 11, 14) 52 1.7% 99.1%
+ [ 14, 17) 28 0.9% 100.0%
+ [ 17, 21) 0 0.0% 100.0%
+ [ 21, 26) 0 0.0% 100.0%
+ [ 26, 32) 0 0.0% 100.0%
+ [ 32, inf) 0 0.0% 100.0%
+Benchmark___10_chunk___100B 2000 3830903 ns/op 0.52 MB/s
+--- Histogram (unit: ms)
+ Count: 2000 Min: 2 Max: 43 Avg: 3.34
+ ------------------------------------------------------------
+ [ 2, 3) 880 44.0% 44.0% ####
+ [ 3, 4) 1052 52.6% 96.6% #####
+ [ 4, 5) 3 0.2% 96.8%
+ [ 5, 7) 0 0.0% 96.8%
+ [ 7, 9) 0 0.0% 96.8%
+ [ 9, 12) 0 0.0% 96.8%
+ [ 12, 16) 17 0.9% 97.6%
+ [ 16, 21) 0 0.0% 97.6%
+ [ 21, 28) 17 0.9% 98.5%
+ [ 28, 37) 27 1.4% 99.8%
+ [ 37, 48) 4 0.2% 100.0%
+ [ 48, 63) 0 0.0% 100.0%
+ [ 63, 82) 0 0.0% 100.0%
+ [ 82, 106) 0 0.0% 100.0%
+ [106, 138) 0 0.0% 100.0%
+ [138, 178) 0 0.0% 100.0%
+ [178, inf) 0 0.0% 100.0%
+Benchmark___10_chunk___100B-2 3000 2793961 ns/op 0.72 MB/s
+--- Histogram (unit: ms)
+ Count: 3000 Min: 2 Max: 21 Avg: 2.41
+ ------------------------------------------------------------
+ [ 2, 3) 2717 90.6% 90.6% #########
+ [ 3, 4) 211 7.0% 97.6% #
+ [ 4, 5) 0 0.0% 97.6%
+ [ 5, 6) 0 0.0% 97.6%
+ [ 6, 8) 0 0.0% 97.6%
+ [ 8, 10) 0 0.0% 97.6%
+ [ 10, 13) 0 0.0% 97.6%
+ [ 13, 16) 48 1.6% 99.2%
+ [ 16, 20) 11 0.4% 99.6%
+ [ 20, 25) 13 0.4% 100.0%
+ [ 25, 32) 0 0.0% 100.0%
+ [ 32, 40) 0 0.0% 100.0%
+ [ 40, 50) 0 0.0% 100.0%
+ [ 50, 62) 0 0.0% 100.0%
+ [ 62, 77) 0 0.0% 100.0%
+ [ 77, 95) 0 0.0% 100.0%
+ [ 95, inf) 0 0.0% 100.0%
+Benchmark___10_chunk____1KB 2000 4349817 ns/op 4.60 MB/s
+--- Histogram (unit: ms)
+ Count: 2000 Min: 3 Max: 48 Avg: 4.07
+ ------------------------------------------------------------
+ [ 3, 4) 1907 95.4% 95.4% ##########
+ [ 4, 5) 11 0.6% 95.9%
+ [ 5, 6) 12 0.6% 96.5%
+ [ 6, 8) 0 0.0% 96.5%
+ [ 8, 10) 0 0.0% 96.5%
+ [ 10, 13) 0 0.0% 96.5%
+ [ 13, 17) 0 0.0% 96.5%
+ [ 17, 22) 21 1.1% 97.6%
+ [ 22, 29) 0 0.0% 97.6%
+ [ 29, 38) 21 1.1% 98.6%
+ [ 38, 50) 28 1.4% 100.0%
+ [ 50, 66) 0 0.0% 100.0%
+ [ 66, 87) 0 0.0% 100.0%
+ [ 87, 114) 0 0.0% 100.0%
+ [114, 148) 0 0.0% 100.0%
+ [148, 192) 0 0.0% 100.0%
+ [192, inf) 0 0.0% 100.0%
+Benchmark___10_chunk____1KB-2 2000 3167146 ns/op 6.31 MB/s
+--- Histogram (unit: ms)
+ Count: 2000 Min: 2 Max: 22 Avg: 2.53
+ ------------------------------------------------------------
+ [ 2, 3) 1734 86.7% 86.7% #########
+ [ 3, 4) 210 10.5% 97.2% #
+ [ 4, 5) 7 0.4% 97.6%
+ [ 5, 6) 0 0.0% 97.6%
+ [ 6, 8) 0 0.0% 97.6%
+ [ 8, 10) 0 0.0% 97.6%
+ [ 10, 13) 0 0.0% 97.6%
+ [ 13, 17) 13 0.7% 98.2%
+ [ 17, 21) 17 0.9% 99.1%
+ [ 21, 27) 19 1.0% 100.0%
+ [ 27, 34) 0 0.0% 100.0%
+ [ 34, 42) 0 0.0% 100.0%
+ [ 42, 52) 0 0.0% 100.0%
+ [ 52, 65) 0 0.0% 100.0%
+ [ 65, 81) 0 0.0% 100.0%
+ [ 81, 100) 0 0.0% 100.0%
+ [100, inf) 0 0.0% 100.0%
+Benchmark___10_chunk___10KB 1000 6486765 ns/op 30.83 MB/s
+--- Histogram (unit: ms)
+ Count: 1000 Min: 4 Max: 50 Avg: 5.74
+ ------------------------------------------------------------
+ [ 4, 5) 821 82.1% 82.1% ########
+ [ 5, 6) 128 12.8% 94.9% #
+ [ 6, 7) 3 0.3% 95.2%
+ [ 7, 9) 1 0.1% 95.3%
+ [ 9, 11) 0 0.0% 95.3%
+ [ 11, 14) 0 0.0% 95.3%
+ [ 14, 18) 8 0.8% 96.1%
+ [ 18, 23) 0 0.0% 96.1%
+ [ 23, 30) 3 0.3% 96.4%
+ [ 30, 39) 5 0.5% 96.9%
+ [ 39, 51) 31 3.1% 100.0%
+ [ 51, 67) 0 0.0% 100.0%
+ [ 67, 88) 0 0.0% 100.0%
+ [ 88, 115) 0 0.0% 100.0%
+ [115, 150) 0 0.0% 100.0%
+ [150, 195) 0 0.0% 100.0%
+ [195, inf) 0 0.0% 100.0%
+Benchmark___10_chunk___10KB-2 2000 4310677 ns/op 46.40 MB/s
+--- Histogram (unit: ms)
+ Count: 2000 Min: 2 Max: 24 Avg: 3.84
+ ------------------------------------------------------------
+ [ 2, 3) 3 0.2% 0.2%
+ [ 3, 4) 1762 88.1% 88.2% #########
+ [ 4, 5) 33 1.7% 89.9%
+ [ 5, 6) 124 6.2% 96.1% #
+ [ 6, 8) 0 0.0% 96.1%
+ [ 8, 10) 0 0.0% 96.1%
+ [ 10, 13) 0 0.0% 96.1%
+ [ 13, 17) 0 0.0% 96.1%
+ [ 17, 22) 33 1.7% 97.8%
+ [ 22, 28) 45 2.2% 100.0%
+ [ 28, 35) 0 0.0% 100.0%
+ [ 35, 44) 0 0.0% 100.0%
+ [ 44, 55) 0 0.0% 100.0%
+ [ 55, 69) 0 0.0% 100.0%
+ [ 69, 86) 0 0.0% 100.0%
+ [ 86, 107) 0 0.0% 100.0%
+ [107, inf) 0 0.0% 100.0%
+Benchmark___10_chunk__100KB 300 29183306 ns/op 68.53 MB/s
+--- Histogram (unit: ms)
+ Count: 300 Min: 21 Max: 71 Avg: 28.66
+ ------------------------------------------------------------
+ [ 21, 22) 186 62.0% 62.0% ######
+ [ 22, 23) 31 10.3% 72.3% #
+ [ 23, 24) 5 1.7% 74.0%
+ [ 24, 26) 1 0.3% 74.3%
+ [ 26, 28) 0 0.0% 74.3%
+ [ 28, 31) 23 7.7% 82.0% #
+ [ 31, 35) 1 0.3% 82.3%
+ [ 35, 41) 0 0.0% 82.3%
+ [ 41, 49) 0 0.0% 82.3%
+ [ 49, 59) 25 8.3% 90.7% #
+ [ 59, 72) 28 9.3% 100.0% #
+ [ 72, 89) 0 0.0% 100.0%
+ [ 89, 111) 0 0.0% 100.0%
+ [111, 140) 0 0.0% 100.0%
+ [140, 178) 0 0.0% 100.0%
+ [178, 228) 0 0.0% 100.0%
+ [228, inf) 0 0.0% 100.0%
+Benchmark___10_chunk__100KB-2 500 16030525 ns/op 124.76 MB/s
+--- Histogram (unit: ms)
+ Count: 500 Min: 11 Max: 38 Avg: 15.56
+ ------------------------------------------------------------
+ [ 11, 12) 88 17.6% 17.6% ##
+ [ 12, 13) 295 59.0% 76.6% ######
+ [ 13, 14) 14 2.8% 79.4%
+ [ 14, 15) 1 0.2% 79.6%
+ [ 15, 17) 6 1.2% 80.8%
+ [ 17, 20) 9 1.8% 82.6%
+ [ 20, 23) 0 0.0% 82.6%
+ [ 23, 27) 0 0.0% 82.6%
+ [ 27, 32) 37 7.4% 90.0% #
+ [ 32, 39) 50 10.0% 100.0% #
+ [ 39, 48) 0 0.0% 100.0%
+ [ 48, 59) 0 0.0% 100.0%
+ [ 59, 72) 0 0.0% 100.0%
+ [ 72, 89) 0 0.0% 100.0%
+ [ 89, 110) 0 0.0% 100.0%
+ [110, 137) 0 0.0% 100.0%
+ [137, inf) 0 0.0% 100.0%
+
+Benchmark__100_chunk_____1B 500 14799281 ns/op 0.01 MB/s
+--- Histogram (unit: ms)
+ Count: 500 Min: 14 Max: 16 Avg: 14.23
+ ------------------------------------------------------------
+ [ 14, 15) 386 77.2% 77.2% ########
+ [ 15, 16) 113 22.6% 99.8% ##
+ [ 16, inf) 1 0.2% 100.0%
+Benchmark__100_chunk_____1B-2 1000 10135511 ns/op 0.02 MB/s
+--- Histogram (unit: ms)
+ Count: 1000 Min: 8 Max: 11 Avg: 9.63
+ ------------------------------------------------------------
+ [ 8, 9) 11 1.1% 1.1%
+ [ 9, 10) 432 43.2% 44.3% ####
+ [ 10, 11) 477 47.7% 92.0% #####
+ [ 11, inf) 80 8.0% 100.0% #
+Benchmark__100_chunk____10B 500 15137229 ns/op 0.13 MB/s
+--- Histogram (unit: ms)
+ Count: 500 Min: 14 Max: 18 Avg: 14.73
+ ------------------------------------------------------------
+ [ 14, 15) 148 29.6% 29.6% ###
+ [ 15, 16) 339 67.8% 97.4% #######
+ [ 16, 17) 12 2.4% 99.8%
+ [ 17, 18) 0 0.0% 99.8%
+ [ 18, inf) 1 0.2% 100.0%
+Benchmark__100_chunk____10B-2 1000 10731944 ns/op 0.19 MB/s
+--- Histogram (unit: ms)
+ Count: 1000 Min: 8 Max: 12 Avg: 10.26
+ ------------------------------------------------------------
+ [ 8, 9) 12 1.2% 1.2%
+ [ 9, 10) 159 15.9% 17.1% ##
+ [ 10, 11) 421 42.1% 59.2% ####
+ [ 11, 12) 375 37.5% 96.7% ####
+ [ 12, inf) 33 3.3% 100.0%
+Benchmark__100_chunk___100B 500 15355974 ns/op 1.30 MB/s
+--- Histogram (unit: ms)
+ Count: 500 Min: 14 Max: 17 Avg: 14.83
+ ------------------------------------------------------------
+ [ 14, 15) 128 25.6% 25.6% ###
+ [ 15, 16) 330 66.0% 91.6% #######
+ [ 16, 17) 41 8.2% 99.8% #
+ [ 17, inf) 1 0.2% 100.0%
+Benchmark__100_chunk___100B-2 1000 10757797 ns/op 1.86 MB/s
+--- Histogram (unit: ms)
+ Count: 1000 Min: 8 Max: 13 Avg: 10.25
+ ------------------------------------------------------------
+ [ 8, 9) 32 3.2% 3.2%
+ [ 9, 10) 217 21.7% 24.9% ##
+ [ 10, 11) 363 36.3% 61.2% ####
+ [ 11, 12) 253 25.3% 86.5% ###
+ [ 12, 13) 127 12.7% 99.2% #
+ [ 13, inf) 8 0.8% 100.0%
+Benchmark__100_chunk____1KB 500 17505005 ns/op 11.43 MB/s
+--- Histogram (unit: ms)
+ Count: 500 Min: 15 Max: 19 Avg: 17.03
+ ------------------------------------------------------------
+ [ 15, 16) 51 10.2% 10.2% #
+ [ 16, 17) 112 22.4% 32.6% ##
+ [ 17, 18) 115 23.0% 55.6% ##
+ [ 18, 19) 216 43.2% 98.8% ####
+ [ 19, inf) 6 1.2% 100.0%
+Benchmark__100_chunk____1KB-2 1000 11660590 ns/op 17.15 MB/s
+--- Histogram (unit: ms)
+ Count: 1000 Min: 8 Max: 14 Avg: 11.15
+ ------------------------------------------------------------
+ [ 8, 9) 11 1.1% 1.1%
+ [ 9, 10) 158 15.8% 16.9% ##
+ [ 10, 11) 183 18.3% 35.2% ##
+ [ 11, 12) 270 27.0% 62.2% ###
+ [ 12, 13) 123 12.3% 74.5% #
+ [ 13, 14) 206 20.6% 95.1% ##
+ [ 14, inf) 49 4.9% 100.0%
+Benchmark__100_chunk___10KB 200 37914384 ns/op 52.75 MB/s
+--- Histogram (unit: ms)
+ Count: 200 Min: 35 Max: 42 Avg: 37.35
+ ------------------------------------------------------------
+ [ 35, 36) 9 4.5% 4.5%
+ [ 36, 37) 4 2.0% 6.5%
+ [ 37, 38) 120 60.0% 66.5% ######
+ [ 38, 39) 52 26.0% 92.5% ###
+ [ 39, 40) 8 4.0% 96.5%
+ [ 40, 41) 5 2.5% 99.0%
+ [ 41, 43) 2 1.0% 100.0%
+ [ 43, inf) 0 0.0% 100.0%
+Benchmark__100_chunk___10KB-2 300 20888999 ns/op 95.74 MB/s
+--- Histogram (unit: ms)
+ Count: 300 Min: 18 Max: 23 Avg: 20.38
+ ------------------------------------------------------------
+ [ 18, 19) 15 5.0% 5.0% #
+ [ 19, 20) 11 3.7% 8.7%
+ [ 20, 21) 135 45.0% 53.7% #####
+ [ 21, 22) 125 41.7% 95.3% ####
+ [ 22, 23) 13 4.3% 99.7%
+ [ 23, inf) 1 0.3% 100.0%
+Benchmark__100_chunk__100KB 30 215706680 ns/op 92.72 MB/s
+--- Histogram (unit: ms)
+ Count: 30 Min: 210 Max: 220 Avg: 215.20
+ ------------------------------------------------------------
+ [210, 211) 1 3.3% 3.3%
+ [211, 212) 2 6.7% 10.0% #
+ [212, 213) 0 0.0% 10.0%
+ [213, 214) 9 30.0% 40.0% ###
+ [214, 215) 4 13.3% 53.3% #
+ [215, 217) 4 13.3% 66.7% #
+ [217, 219) 1 3.3% 70.0%
+ [219, 221) 9 30.0% 100.0% ###
+ [221, 224) 0 0.0% 100.0%
+ [224, 227) 0 0.0% 100.0%
+ [227, inf) 0 0.0% 100.0%
+Benchmark__100_chunk__100KB-2 100 113221561 ns/op 176.64 MB/s
+--- Histogram (unit: ms)
+ Count: 100 Min: 108 Max: 120 Avg: 112.75
+ ------------------------------------------------------------
+ [108, 109) 2 2.0% 2.0%
+ [109, 110) 7 7.0% 9.0% #
+ [110, 111) 3 3.0% 12.0%
+ [111, 112) 16 16.0% 28.0% ##
+ [112, 113) 20 20.0% 48.0% ##
+ [113, 115) 29 29.0% 77.0% ###
+ [115, 117) 20 20.0% 97.0% ##
+ [117, 120) 2 2.0% 99.0%
+ [120, 123) 1 1.0% 100.0%
+ [123, 127) 0 0.0% 100.0%
+ [127, 132) 0 0.0% 100.0%
+ [132, 138) 0 0.0% 100.0%
+ [138, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk_____1B 50 127031961 ns/op 0.02 MB/s
+--- Histogram (unit: ms)
+ Count: 50 Min: 123 Max: 131 Avg: 126.56
------------------------------------------------------------
[123, 124) 1 2.0% 2.0%
- [124, 125) 0 0.0% 2.0%
- [125, 126) 0 0.0% 2.0%
- [126, 128) 0 0.0% 2.0%
- [128, 131) 0 0.0% 2.0%
- [131, 135) 1 2.0% 4.0%
- [135, 140) 20 40.0% 44.0% ####
- [140, 147) 19 38.0% 82.0% ####
- [147, 156) 1 2.0% 84.0%
- [156, 169) 0 0.0% 84.0%
- [169, 186) 2 4.0% 88.0%
- [186, 209) 6 12.0% 100.0% #
- [209, 239) 0 0.0% 100.0%
- [239, 279) 0 0.0% 100.0%
- [279, 333) 0 0.0% 100.0%
- [333, 404) 0 0.0% 100.0%
- [404, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk_____1B-2 100 112701633 ns/op 0.02 MB/s
+ [124, 125) 1 2.0% 4.0%
+ [125, 126) 11 22.0% 26.0% ##
+ [126, 127) 19 38.0% 64.0% ####
+ [127, 128) 6 12.0% 76.0% #
+ [128, 130) 8 16.0% 92.0% ##
+ [130, 132) 4 8.0% 100.0% #
+ [132, 134) 0 0.0% 100.0%
+ [134, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk_____1B-2 100 82251965 ns/op 0.02 MB/s
--- Histogram (unit: ms)
- Count: 100 Min: 109 Max: 128 Avg: 112.17
+ Count: 100 Min: 75 Max: 93 Avg: 81.77
------------------------------------------------------------
- [109, 110) 4 4.0% 4.0%
- [110, 111) 17 17.0% 21.0% ##
- [111, 112) 31 31.0% 52.0% ###
- [112, 113) 16 16.0% 68.0% ##
- [113, 115) 21 21.0% 89.0% ##
- [115, 117) 4 4.0% 93.0%
- [117, 120) 5 5.0% 98.0% #
- [120, 123) 1 1.0% 99.0%
- [123, 127) 0 0.0% 99.0%
- [127, 132) 1 1.0% 100.0%
- [132, 139) 0 0.0% 100.0%
- [139, 147) 0 0.0% 100.0%
- [147, 157) 0 0.0% 100.0%
- [157, 169) 0 0.0% 100.0%
- [169, 184) 0 0.0% 100.0%
- [184, 202) 0 0.0% 100.0%
- [202, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk____10B 30 210652536 ns/op 0.09 MB/s
+ [ 75, 76) 3 3.0% 3.0%
+ [ 76, 77) 10 10.0% 13.0% #
+ [ 77, 78) 6 6.0% 19.0% #
+ [ 78, 79) 5 5.0% 24.0% #
+ [ 79, 81) 17 17.0% 41.0% ##
+ [ 81, 83) 17 17.0% 58.0% ##
+ [ 83, 86) 27 27.0% 85.0% ###
+ [ 86, 89) 6 6.0% 91.0% #
+ [ 89, 93) 8 8.0% 99.0% #
+ [ 93, 98) 1 1.0% 100.0%
+ [ 98, 104) 0 0.0% 100.0%
+ [104, 112) 0 0.0% 100.0%
+ [112, 122) 0 0.0% 100.0%
+ [122, 134) 0 0.0% 100.0%
+ [134, 148) 0 0.0% 100.0%
+ [148, 165) 0 0.0% 100.0%
+ [165, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk____10B 50 126841430 ns/op 0.16 MB/s
--- Histogram (unit: ms)
- Count: 30 Min: 205 Max: 216 Avg: 210.23
+ Count: 50 Min: 121 Max: 130 Avg: 126.34
------------------------------------------------------------
- [205, 206) 1 3.3% 3.3%
- [206, 207) 3 10.0% 13.3% #
- [207, 208) 4 13.3% 26.7% #
- [208, 209) 3 10.0% 36.7% #
- [209, 210) 0 0.0% 36.7%
- [210, 212) 6 20.0% 56.7% ##
- [212, 214) 10 33.3% 90.0% ###
- [214, 217) 3 10.0% 100.0% #
- [217, 220) 0 0.0% 100.0%
- [220, 224) 0 0.0% 100.0%
- [224, 228) 0 0.0% 100.0%
- [228, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk____10B-2 100 121674848 ns/op 0.16 MB/s
+ [121, 122) 1 2.0% 2.0%
+ [122, 123) 0 0.0% 2.0%
+ [123, 124) 1 2.0% 4.0%
+ [124, 125) 0 0.0% 4.0%
+ [125, 126) 7 14.0% 18.0% #
+ [126, 128) 31 62.0% 80.0% ######
+ [128, 130) 9 18.0% 98.0% ##
+ [130, 132) 1 2.0% 100.0%
+ [132, 135) 0 0.0% 100.0%
+ [135, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk____10B-2 100 80662645 ns/op 0.25 MB/s
--- Histogram (unit: ms)
- Count: 100 Min: 113 Max: 132 Avg: 121.15
+ Count: 100 Min: 73 Max: 93 Avg: 80.11
------------------------------------------------------------
- [113, 114) 4 4.0% 4.0%
- [114, 115) 9 9.0% 13.0% #
- [115, 116) 5 5.0% 18.0% #
- [116, 117) 3 3.0% 21.0%
- [117, 119) 7 7.0% 28.0% #
- [119, 121) 14 14.0% 42.0% #
- [121, 124) 24 24.0% 66.0% ##
- [124, 127) 25 25.0% 91.0% ###
- [127, 131) 8 8.0% 99.0% #
- [131, 136) 1 1.0% 100.0%
- [136, 143) 0 0.0% 100.0%
- [143, 151) 0 0.0% 100.0%
- [151, 161) 0 0.0% 100.0%
- [161, 173) 0 0.0% 100.0%
- [173, 188) 0 0.0% 100.0%
- [188, 206) 0 0.0% 100.0%
- [206, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk___100B 30 238543410 ns/op 0.84 MB/s
+ [ 73, 74) 2 2.0% 2.0%
+ [ 74, 75) 3 3.0% 5.0%
+ [ 75, 76) 10 10.0% 15.0% #
+ [ 76, 77) 12 12.0% 27.0% #
+ [ 77, 79) 19 19.0% 46.0% ##
+ [ 79, 81) 13 13.0% 59.0% #
+ [ 81, 84) 20 20.0% 79.0% ##
+ [ 84, 88) 12 12.0% 91.0% #
+ [ 88, 92) 6 6.0% 97.0% #
+ [ 92, 98) 3 3.0% 100.0%
+ [ 98, 105) 0 0.0% 100.0%
+ [105, 113) 0 0.0% 100.0%
+ [113, 123) 0 0.0% 100.0%
+ [123, 136) 0 0.0% 100.0%
+ [136, 152) 0 0.0% 100.0%
+ [152, 171) 0 0.0% 100.0%
+ [171, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk___100B 50 130500666 ns/op 1.53 MB/s
--- Histogram (unit: ms)
- Count: 30 Min: 230 Max: 250 Avg: 238.03
+ Count: 50 Min: 125 Max: 141 Avg: 129.98
------------------------------------------------------------
- [230, 231) 3 10.0% 10.0% #
- [231, 232) 0 0.0% 10.0%
- [232, 233) 1 3.3% 13.3%
- [233, 234) 2 6.7% 20.0% #
- [234, 236) 5 16.7% 36.7% ##
- [236, 238) 4 13.3% 50.0% #
- [238, 241) 5 16.7% 66.7% ##
- [241, 245) 7 23.3% 90.0% ##
- [245, 249) 2 6.7% 96.7% #
- [249, 255) 1 3.3% 100.0%
- [255, 262) 0 0.0% 100.0%
- [262, 270) 0 0.0% 100.0%
- [270, 280) 0 0.0% 100.0%
- [280, 293) 0 0.0% 100.0%
- [293, 309) 0 0.0% 100.0%
- [309, 328) 0 0.0% 100.0%
- [328, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk___100B-2 50 138412318 ns/op 1.44 MB/s
+ [125, 126) 1 2.0% 2.0%
+ [126, 127) 1 2.0% 4.0%
+ [127, 128) 1 2.0% 6.0%
+ [128, 129) 6 12.0% 18.0% #
+ [129, 131) 27 54.0% 72.0% #####
+ [131, 133) 8 16.0% 88.0% ##
+ [133, 136) 4 8.0% 96.0% #
+ [136, 139) 1 2.0% 98.0%
+ [139, 143) 1 2.0% 100.0%
+ [143, 148) 0 0.0% 100.0%
+ [148, 154) 0 0.0% 100.0%
+ [154, 161) 0 0.0% 100.0%
+ [161, 170) 0 0.0% 100.0%
+ [170, 181) 0 0.0% 100.0%
+ [181, 194) 0 0.0% 100.0%
+ [194, 210) 0 0.0% 100.0%
+ [210, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk___100B-2 100 82993437 ns/op 2.41 MB/s
--- Histogram (unit: ms)
- Count: 50 Min: 126 Max: 149 Avg: 137.94
+ Count: 100 Min: 72 Max: 93 Avg: 82.49
------------------------------------------------------------
- [126, 127) 1 2.0% 2.0%
- [127, 128) 0 0.0% 2.0%
- [128, 129) 0 0.0% 2.0%
- [129, 130) 0 0.0% 2.0%
- [130, 132) 3 6.0% 8.0% #
- [132, 134) 6 12.0% 20.0% #
- [134, 137) 11 22.0% 42.0% ##
- [137, 141) 12 24.0% 66.0% ##
- [141, 146) 14 28.0% 94.0% ###
- [146, 152) 3 6.0% 100.0% #
- [152, 160) 0 0.0% 100.0%
- [160, 169) 0 0.0% 100.0%
- [169, 181) 0 0.0% 100.0%
- [181, 196) 0 0.0% 100.0%
- [196, 214) 0 0.0% 100.0%
- [214, 236) 0 0.0% 100.0%
- [236, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk____1KB 30 276508870 ns/op 7.23 MB/s
+ [ 72, 73) 1 1.0% 1.0%
+ [ 73, 74) 0 0.0% 1.0%
+ [ 74, 75) 0 0.0% 1.0%
+ [ 75, 76) 1 1.0% 2.0%
+ [ 76, 78) 10 10.0% 12.0% #
+ [ 78, 80) 14 14.0% 26.0% #
+ [ 80, 83) 15 15.0% 41.0% ##
+ [ 83, 87) 48 48.0% 89.0% #####
+ [ 87, 92) 7 7.0% 96.0% #
+ [ 92, 98) 4 4.0% 100.0%
+ [ 98, 105) 0 0.0% 100.0%
+ [105, 114) 0 0.0% 100.0%
+ [114, 125) 0 0.0% 100.0%
+ [125, 138) 0 0.0% 100.0%
+ [138, 155) 0 0.0% 100.0%
+ [155, 175) 0 0.0% 100.0%
+ [175, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk____1KB 50 152120390 ns/op 13.15 MB/s
--- Histogram (unit: ms)
- Count: 30 Min: 264 Max: 299 Avg: 275.97
+ Count: 50 Min: 145 Max: 161 Avg: 151.72
------------------------------------------------------------
- [264, 265) 1 3.3% 3.3%
- [265, 266) 0 0.0% 3.3%
- [266, 267) 1 3.3% 6.7%
- [267, 269) 3 10.0% 16.7% #
- [269, 271) 5 16.7% 33.3% ##
- [271, 274) 7 23.3% 56.7% ##
- [274, 278) 2 6.7% 63.3% #
- [278, 283) 7 23.3% 86.7% ##
- [283, 289) 1 3.3% 90.0%
- [289, 297) 1 3.3% 93.3%
- [297, 307) 2 6.7% 100.0% #
- [307, 320) 0 0.0% 100.0%
- [320, 337) 0 0.0% 100.0%
- [337, 358) 0 0.0% 100.0%
- [358, 385) 0 0.0% 100.0%
- [385, 419) 0 0.0% 100.0%
- [419, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk____1KB-2 50 156292302 ns/op 12.80 MB/s
---- Histogram (unit: ms)
- Count: 50 Min: 144 Max: 169 Avg: 155.82
- ------------------------------------------------------------
- [144, 145) 1 2.0% 2.0%
- [145, 146) 0 0.0% 2.0%
+ [145, 146) 1 2.0% 2.0%
[146, 147) 1 2.0% 4.0%
- [147, 148) 0 0.0% 4.0%
- [148, 150) 3 6.0% 10.0% #
- [150, 152) 5 10.0% 20.0% #
- [152, 155) 14 28.0% 48.0% ###
- [155, 159) 12 24.0% 72.0% ##
- [159, 164) 8 16.0% 88.0% ##
- [164, 170) 6 12.0% 100.0% #
- [170, 178) 0 0.0% 100.0%
- [178, 188) 0 0.0% 100.0%
- [188, 201) 0 0.0% 100.0%
- [201, 217) 0 0.0% 100.0%
- [217, 237) 0 0.0% 100.0%
- [237, 261) 0 0.0% 100.0%
- [261, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk___10KB 20 468904636 ns/op 42.65 MB/s
+ [147, 148) 1 2.0% 6.0%
+ [148, 149) 2 4.0% 10.0%
+ [149, 151) 17 34.0% 44.0% ###
+ [151, 153) 8 16.0% 60.0% ##
+ [153, 156) 16 32.0% 92.0% ###
+ [156, 159) 2 4.0% 96.0%
+ [159, 163) 2 4.0% 100.0%
+ [163, 168) 0 0.0% 100.0%
+ [168, 174) 0 0.0% 100.0%
+ [174, 181) 0 0.0% 100.0%
+ [181, 190) 0 0.0% 100.0%
+ [190, 201) 0 0.0% 100.0%
+ [201, 214) 0 0.0% 100.0%
+ [214, 230) 0 0.0% 100.0%
+ [230, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk____1KB-2 100 91860277 ns/op 21.77 MB/s
--- Histogram (unit: ms)
- Count: 20 Min: 458 Max: 491 Avg: 468.40
+ Count: 100 Min: 80 Max: 106 Avg: 91.33
------------------------------------------------------------
- [458, 459) 2 10.0% 10.0% #
- [459, 460) 2 10.0% 20.0% #
- [460, 461) 2 10.0% 30.0% #
- [461, 463) 1 5.0% 35.0% #
- [463, 465) 1 5.0% 40.0% #
- [465, 468) 2 10.0% 50.0% #
- [468, 472) 2 10.0% 60.0% #
- [472, 477) 6 30.0% 90.0% ###
- [477, 483) 0 0.0% 90.0%
- [483, 491) 1 5.0% 95.0% #
- [491, 501) 1 5.0% 100.0% #
- [501, 513) 0 0.0% 100.0%
- [513, 529) 0 0.0% 100.0%
- [529, 549) 0 0.0% 100.0%
- [549, 575) 0 0.0% 100.0%
- [575, 608) 0 0.0% 100.0%
- [608, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk___10KB-2 30 263653358 ns/op 75.86 MB/s
+ [ 80, 81) 2 2.0% 2.0%
+ [ 81, 82) 2 2.0% 4.0%
+ [ 82, 83) 3 3.0% 7.0%
+ [ 83, 84) 4 4.0% 11.0%
+ [ 84, 86) 10 10.0% 21.0% #
+ [ 86, 88) 11 11.0% 32.0% #
+ [ 88, 91) 14 14.0% 46.0% #
+ [ 91, 95) 19 19.0% 65.0% ##
+ [ 95, 100) 26 26.0% 91.0% ###
+ [100, 107) 9 9.0% 100.0% #
+ [107, 115) 0 0.0% 100.0%
+ [115, 125) 0 0.0% 100.0%
+ [125, 138) 0 0.0% 100.0%
+ [138, 154) 0 0.0% 100.0%
+ [154, 174) 0 0.0% 100.0%
+ [174, 199) 0 0.0% 100.0%
+ [199, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk___10KB 20 337020835 ns/op 59.34 MB/s
--- Histogram (unit: ms)
- Count: 30 Min: 242 Max: 275 Avg: 263.13
+ Count: 20 Min: 331 Max: 342 Avg: 336.50
------------------------------------------------------------
- [242, 243) 2 6.7% 6.7% #
- [243, 244) 0 0.0% 6.7%
- [244, 245) 0 0.0% 6.7%
- [245, 247) 0 0.0% 6.7%
- [247, 249) 0 0.0% 6.7%
- [249, 252) 0 0.0% 6.7%
- [252, 256) 3 10.0% 16.7% #
- [256, 261) 5 16.7% 33.3% ##
- [261, 267) 8 26.7% 60.0% ###
- [267, 275) 11 36.7% 96.7% ####
- [275, 285) 1 3.3% 100.0%
- [285, 297) 0 0.0% 100.0%
- [297, 313) 0 0.0% 100.0%
- [313, 333) 0 0.0% 100.0%
- [333, 359) 0 0.0% 100.0%
- [359, 392) 0 0.0% 100.0%
- [392, inf) 0 0.0% 100.0%
-Benchmark___1K_chunk__100KB 3 2573103606 ns/op 77.73 MB/s
+ [331, 332) 1 5.0% 5.0% #
+ [332, 333) 2 10.0% 15.0% #
+ [333, 334) 1 5.0% 20.0% #
+ [334, 335) 3 15.0% 35.0% ##
+ [335, 336) 2 10.0% 45.0% #
+ [336, 338) 2 10.0% 55.0% #
+ [338, 340) 5 25.0% 80.0% ###
+ [340, 343) 4 20.0% 100.0% ##
+ [343, 346) 0 0.0% 100.0%
+ [346, 350) 0 0.0% 100.0%
+ [350, 354) 0 0.0% 100.0%
+ [354, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk___10KB-2 50 177497001 ns/op 112.68 MB/s
+--- Histogram (unit: ms)
+ Count: 50 Min: 172 Max: 183 Avg: 176.96
+ ------------------------------------------------------------
+ [172, 173) 4 8.0% 8.0% #
+ [173, 174) 2 4.0% 12.0%
+ [174, 175) 8 16.0% 28.0% ##
+ [175, 176) 4 8.0% 36.0% #
+ [176, 177) 2 4.0% 40.0%
+ [177, 179) 9 18.0% 58.0% ##
+ [179, 181) 18 36.0% 94.0% ####
+ [181, 184) 3 6.0% 100.0% #
+ [184, 187) 0 0.0% 100.0%
+ [187, 191) 0 0.0% 100.0%
+ [191, 195) 0 0.0% 100.0%
+ [195, inf) 0 0.0% 100.0%
+Benchmark___1K_chunk__100KB 3 2185333858 ns/op 91.52 MB/s
--- Histogram (unit: s)
Count: 3 Min: 2 Max: 2 Avg: 2.00
------------------------------------------------------------
[ 2, inf) 3 100.0% 100.0% ##########
-Benchmark___1K_chunk__100KB-2 5 1337696624 ns/op 149.51 MB/s
+Benchmark___1K_chunk__100KB-2 5 1140505127 ns/op 175.36 MB/s
--- Histogram (unit: s)
Count: 5 Min: 1 Max: 1 Avg: 1.00
------------------------------------------------------------
[ 1, inf) 5 100.0% 100.0% ##########
-Benchmark__per_chunk____1B 50000 192129 ns/op 0.01 MB/s
-Benchmark__per_chunk____1B-2 50000 131601 ns/op 0.02 MB/s
-Benchmark__per_chunk___10B 20000 372009 ns/op 0.05 MB/s
-Benchmark__per_chunk___10B-2 30000 222774 ns/op 0.09 MB/s
-Benchmark__per_chunk__100B 20000 434465 ns/op 0.46 MB/s
-Benchmark__per_chunk__100B-2 30000 238245 ns/op 0.84 MB/s
-Benchmark__per_chunk___1KB 20000 464091 ns/op 4.31 MB/s
-Benchmark__per_chunk___1KB-2 30000 253694 ns/op 7.88 MB/s
-Benchmark__per_chunk__10KB 10000 650380 ns/op 30.75 MB/s
-Benchmark__per_chunk__10KB-2 20000 357218 ns/op 55.99 MB/s
-Benchmark__per_chunk_100KB 3000 2728670 ns/op 73.30 MB/s
-Benchmark__per_chunk_100KB-2 5000 1380520 ns/op 144.87 MB/s
+Benchmark__per_chunk____1B 50000 127847 ns/op 0.02 MB/s
+Benchmark__per_chunk____1B-2 100000 81496 ns/op 0.02 MB/s
+Benchmark__per_chunk___10B 50000 125213 ns/op 0.16 MB/s
+Benchmark__per_chunk___10B-2 100000 79532 ns/op 0.25 MB/s
+Benchmark__per_chunk__100B 50000 126242 ns/op 1.58 MB/s
+Benchmark__per_chunk__100B-2 100000 77971 ns/op 2.57 MB/s
+Benchmark__per_chunk___1KB 50000 148314 ns/op 13.48 MB/s
+Benchmark__per_chunk___1KB-2 100000 87787 ns/op 22.78 MB/s
+Benchmark__per_chunk__10KB 20000 323521 ns/op 61.82 MB/s
+Benchmark__per_chunk__10KB-2 50000 172500 ns/op 115.94 MB/s
+Benchmark__per_chunk_100KB 3000 2065561 ns/op 96.83 MB/s
+Benchmark__per_chunk_100KB-2 10000 1062338 ns/op 188.26 MB/s
-Benchmark___10B_mux__100_chunks___10B 300 26348223 ns/op 0.00 MB/s
+Benchmark___10B_mux__100_chunks___10B 500 16428840 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 9 Max: 30 Avg: 25.79
+ Count: 500 Min: 8 Max: 18 Avg: 16.03
------------------------------------------------------------
- [ 9, 10) 19 6.3% 6.3% #
- [ 10, 11) 5 1.7% 8.0%
- [ 11, 12) 0 0.0% 8.0%
- [ 12, 13) 0 0.0% 8.0%
- [ 13, 15) 0 0.0% 8.0%
- [ 15, 17) 0 0.0% 8.0%
- [ 17, 20) 1 0.3% 8.3%
- [ 20, 24) 10 3.3% 11.7%
- [ 24, 29) 233 77.7% 89.3% ########
- [ 29, 35) 32 10.7% 100.0% #
- [ 35, 42) 0 0.0% 100.0%
- [ 42, 51) 0 0.0% 100.0%
- [ 51, 62) 0 0.0% 100.0%
- [ 62, 75) 0 0.0% 100.0%
- [ 75, 92) 0 0.0% 100.0%
- [ 92, 112) 0 0.0% 100.0%
- [112, inf) 0 0.0% 100.0%
-Benchmark___10B_mux__100_chunks___10B-2 1000 9053248 ns/op 0.00 MB/s
+ [ 8, 9) 4 0.8% 0.8%
+ [ 9, 10) 0 0.0% 0.8%
+ [ 10, 11) 0 0.0% 0.8%
+ [ 11, 12) 1 0.2% 1.0%
+ [ 12, 13) 3 0.6% 1.6%
+ [ 13, 15) 5 1.0% 2.6%
+ [ 15, 17) 403 80.6% 83.2% ########
+ [ 17, 19) 84 16.8% 100.0% ##
+ [ 19, 22) 0 0.0% 100.0%
+ [ 22, 25) 0 0.0% 100.0%
+ [ 25, inf) 0 0.0% 100.0%
+Benchmark___10B_mux__100_chunks___10B-2 2000 4039798 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 1000 Min: 4 Max: 17 Avg: 8.54
+ Count: 2000 Min: 1 Max: 10 Avg: 3.55
------------------------------------------------------------
- [ 4, 5) 3 0.3% 0.3%
- [ 5, 6) 48 4.8% 5.1%
- [ 6, 7) 166 16.6% 21.7% ##
- [ 7, 8) 206 20.6% 42.3% ##
- [ 8, 9) 179 17.9% 60.2% ##
- [ 9, 11) 186 18.6% 78.8% ##
- [ 11, 13) 111 11.1% 89.9% #
- [ 13, 16) 96 9.6% 99.5% #
- [ 16, 19) 5 0.5% 100.0%
- [ 19, 23) 0 0.0% 100.0%
- [ 23, 28) 0 0.0% 100.0%
- [ 28, 34) 0 0.0% 100.0%
- [ 34, 41) 0 0.0% 100.0%
- [ 41, inf) 0 0.0% 100.0%
-Benchmark___10B_mux__100_chunks__100B 300 29202434 ns/op 0.00 MB/s
+ [ 1, 2) 104 5.2% 5.2% #
+ [ 2, 3) 588 29.4% 34.6% ###
+ [ 3, 4) 397 19.9% 54.5% ##
+ [ 4, 5) 375 18.8% 73.2% ##
+ [ 5, 6) 278 13.9% 87.1% #
+ [ 6, 8) 208 10.4% 97.5% #
+ [ 8, 10) 48 2.4% 99.9%
+ [ 10, 12) 2 0.1% 100.0%
+ [ 12, 15) 0 0.0% 100.0%
+ [ 15, inf) 0 0.0% 100.0%
+Benchmark___10B_mux__100_chunks__100B 500 16959639 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 9 Max: 34 Avg: 28.80
+ Count: 500 Min: 10 Max: 19 Avg: 16.44
------------------------------------------------------------
- [ 9, 10) 4 1.3% 1.3%
- [ 10, 11) 10 3.3% 4.7%
- [ 11, 12) 6 2.0% 6.7%
- [ 12, 13) 0 0.0% 6.7%
- [ 13, 15) 0 0.0% 6.7%
- [ 15, 17) 0 0.0% 6.7%
- [ 17, 20) 0 0.0% 6.7%
- [ 20, 24) 0 0.0% 6.7%
- [ 24, 29) 20 6.7% 13.3% #
- [ 29, 35) 260 86.7% 100.0% #########
- [ 35, 43) 0 0.0% 100.0%
- [ 43, 53) 0 0.0% 100.0%
- [ 53, 66) 0 0.0% 100.0%
- [ 66, 82) 0 0.0% 100.0%
- [ 82, 102) 0 0.0% 100.0%
- [102, 126) 0 0.0% 100.0%
- [126, inf) 0 0.0% 100.0%
-Benchmark___10B_mux__100_chunks__100B-2 1000 10238260 ns/op 0.00 MB/s
+ [ 10, 11) 3 0.6% 0.6%
+ [ 11, 12) 0 0.0% 0.6%
+ [ 12, 13) 3 0.6% 1.2%
+ [ 13, 14) 1 0.2% 1.4%
+ [ 14, 15) 77 15.4% 16.8% ##
+ [ 15, 17) 122 24.4% 41.2% ##
+ [ 17, 19) 286 57.2% 98.4% ######
+ [ 19, 21) 8 1.6% 100.0%
+ [ 21, 24) 0 0.0% 100.0%
+ [ 24, inf) 0 0.0% 100.0%
+Benchmark___10B_mux__100_chunks__100B-2 2000 4129118 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 1000 Min: 5 Max: 21 Avg: 9.74
+ Count: 2000 Min: 1 Max: 12 Avg: 3.64
------------------------------------------------------------
- [ 5, 6) 39 3.9% 3.9%
- [ 6, 7) 118 11.8% 15.7% #
- [ 7, 8) 123 12.3% 28.0% #
- [ 8, 9) 141 14.1% 42.1% #
- [ 9, 11) 217 21.7% 63.8% ##
- [ 11, 13) 152 15.2% 79.0% ##
- [ 13, 16) 157 15.7% 94.7% ##
- [ 16, 19) 50 5.0% 99.7% #
- [ 19, 23) 3 0.3% 100.0%
- [ 23, 28) 0 0.0% 100.0%
- [ 28, 34) 0 0.0% 100.0%
- [ 34, 41) 0 0.0% 100.0%
- [ 41, 50) 0 0.0% 100.0%
- [ 50, 61) 0 0.0% 100.0%
- [ 61, 74) 0 0.0% 100.0%
- [ 74, 90) 0 0.0% 100.0%
- [ 90, inf) 0 0.0% 100.0%
-Benchmark___10B_mux__100_chunks___1KB 300 30121503 ns/op 0.00 MB/s
+ [ 1, 2) 77 3.9% 3.9%
+ [ 2, 3) 693 34.6% 38.5% ###
+ [ 3, 4) 407 20.4% 58.9% ##
+ [ 4, 5) 308 15.4% 74.2% ##
+ [ 5, 6) 182 9.1% 83.4% #
+ [ 6, 8) 213 10.7% 94.0% #
+ [ 8, 10) 91 4.5% 98.6%
+ [ 10, 13) 29 1.5% 100.0%
+ [ 13, 16) 0 0.0% 100.0%
+ [ 16, 20) 0 0.0% 100.0%
+ [ 20, 24) 0 0.0% 100.0%
+ [ 24, inf) 0 0.0% 100.0%
+Benchmark___10B_mux__100_chunks___1KB 500 19240324 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 9 Max: 38 Avg: 29.57
+ Count: 500 Min: 13 Max: 24 Avg: 18.60
------------------------------------------------------------
- [ 9, 10) 7 2.3% 2.3%
- [ 10, 11) 13 4.3% 6.7%
- [ 11, 12) 5 1.7% 8.3%
- [ 12, 13) 3 1.0% 9.3%
- [ 13, 15) 3 1.0% 10.3%
- [ 15, 18) 0 0.0% 10.3%
- [ 18, 21) 0 0.0% 10.3%
- [ 21, 25) 0 0.0% 10.3%
- [ 25, 31) 33 11.0% 21.3% #
- [ 31, 38) 235 78.3% 99.7% ########
- [ 38, 47) 1 0.3% 100.0%
- [ 47, 58) 0 0.0% 100.0%
- [ 58, 72) 0 0.0% 100.0%
- [ 72, 90) 0 0.0% 100.0%
- [ 90, 113) 0 0.0% 100.0%
- [113, 141) 0 0.0% 100.0%
- [141, inf) 0 0.0% 100.0%
-Benchmark___10B_mux__100_chunks___1KB-2 1000 11123358 ns/op 0.00 MB/s
+ [ 13, 14) 1 0.2% 0.2%
+ [ 14, 15) 0 0.0% 0.2%
+ [ 15, 16) 0 0.0% 0.2%
+ [ 16, 17) 152 30.4% 30.6% ###
+ [ 17, 18) 75 15.0% 45.6% ##
+ [ 18, 20) 58 11.6% 57.2% #
+ [ 20, 22) 179 35.8% 93.0% ####
+ [ 22, 25) 35 7.0% 100.0% #
+ [ 25, 28) 0 0.0% 100.0%
+ [ 28, 32) 0 0.0% 100.0%
+ [ 32, 36) 0 0.0% 100.0%
+ [ 36, inf) 0 0.0% 100.0%
+Benchmark___10B_mux__100_chunks___1KB-2 2000 4765628 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 1000 Min: 4 Max: 22 Avg: 10.61
+ Count: 2000 Min: 1 Max: 15 Avg: 4.29
------------------------------------------------------------
- [ 4, 5) 21 2.1% 2.1%
- [ 5, 6) 66 6.6% 8.7% #
- [ 6, 7) 110 11.0% 19.7% #
- [ 7, 8) 88 8.8% 28.5% #
- [ 8, 10) 175 17.5% 46.0% ##
- [ 10, 12) 152 15.2% 61.2% ##
- [ 12, 15) 168 16.8% 78.0% ##
- [ 15, 18) 150 15.0% 93.0% ##
- [ 18, 22) 69 6.9% 99.9% #
- [ 22, 27) 1 0.1% 100.0%
+ [ 1, 2) 49 2.5% 2.5%
+ [ 2, 3) 573 28.7% 31.1% ###
+ [ 3, 4) 411 20.6% 51.7% ##
+ [ 4, 5) 262 13.1% 64.8% #
+ [ 5, 7) 369 18.4% 83.2% ##
+ [ 7, 9) 150 7.5% 90.7% #
+ [ 9, 11) 87 4.4% 95.1%
+ [ 11, 14) 90 4.5% 99.6%
+ [ 14, 18) 9 0.5% 100.0%
+ [ 18, 22) 0 0.0% 100.0%
+ [ 22, 27) 0 0.0% 100.0%
[ 27, 33) 0 0.0% 100.0%
[ 33, 41) 0 0.0% 100.0%
- [ 41, 51) 0 0.0% 100.0%
- [ 51, 63) 0 0.0% 100.0%
- [ 63, 77) 0 0.0% 100.0%
- [ 77, 94) 0 0.0% 100.0%
- [ 94, inf) 0 0.0% 100.0%
-Benchmark___10B_mux__100_chunks__10KB 200 44810613 ns/op 0.00 MB/s
+ [ 41, 50) 0 0.0% 100.0%
+ [ 50, inf) 0 0.0% 100.0%
+Benchmark___10B_mux__100_chunks__10KB 200 38595003 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 200 Min: 9 Max: 57 Avg: 44.30
+ Count: 200 Min: 8 Max: 43 Avg: 38.09
------------------------------------------------------------
- [ 9, 10) 1 0.5% 0.5%
- [ 10, 11) 9 4.5% 5.0%
- [ 11, 12) 1 0.5% 5.5%
- [ 12, 14) 11 5.5% 11.0% #
- [ 14, 16) 7 3.5% 14.5%
- [ 16, 19) 2 1.0% 15.5%
- [ 19, 23) 0 0.0% 15.5%
- [ 23, 29) 0 0.0% 15.5%
- [ 29, 36) 0 0.0% 15.5%
- [ 36, 46) 21 10.5% 26.0% #
- [ 46, 59) 148 74.0% 100.0% #######
- [ 59, 76) 0 0.0% 100.0%
- [ 76, 98) 0 0.0% 100.0%
- [ 98, 126) 0 0.0% 100.0%
- [126, 163) 0 0.0% 100.0%
- [163, 210) 0 0.0% 100.0%
- [210, inf) 0 0.0% 100.0%
-Benchmark___10B_mux__100_chunks__10KB-2 300 23793028 ns/op 0.00 MB/s
+ [ 8, 9) 2 1.0% 1.0%
+ [ 9, 10) 0 0.0% 1.0%
+ [ 10, 11) 0 0.0% 1.0%
+ [ 11, 13) 0 0.0% 1.0%
+ [ 13, 15) 0 0.0% 1.0%
+ [ 15, 18) 0 0.0% 1.0%
+ [ 18, 22) 0 0.0% 1.0%
+ [ 22, 27) 0 0.0% 1.0%
+ [ 27, 33) 2 1.0% 2.0%
+ [ 33, 41) 125 62.5% 64.5% ######
+ [ 41, 51) 71 35.5% 100.0% ####
+ [ 51, 64) 0 0.0% 100.0%
+ [ 64, 81) 0 0.0% 100.0%
+ [ 81, 102) 0 0.0% 100.0%
+ [102, 129) 0 0.0% 100.0%
+ [129, 163) 0 0.0% 100.0%
+ [163, inf) 0 0.0% 100.0%
+Benchmark___10B_mux__100_chunks__10KB-2 500 13282699 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 4 Max: 41 Avg: 23.28
+ Count: 500 Min: 1 Max: 27 Avg: 12.81
------------------------------------------------------------
- [ 4, 5) 1 0.3% 0.3%
- [ 5, 6) 3 1.0% 1.3%
- [ 6, 7) 2 0.7% 2.0%
- [ 7, 9) 9 3.0% 5.0%
- [ 9, 11) 9 3.0% 8.0%
- [ 11, 14) 21 7.0% 15.0% #
- [ 14, 18) 19 6.3% 21.3% #
- [ 18, 23) 51 17.0% 38.3% ##
- [ 23, 29) 108 36.0% 74.3% ####
- [ 29, 37) 70 23.3% 97.7% ##
- [ 37, 48) 7 2.3% 100.0%
- [ 48, 62) 0 0.0% 100.0%
- [ 62, 79) 0 0.0% 100.0%
- [ 79, 101) 0 0.0% 100.0%
- [101, 130) 0 0.0% 100.0%
- [130, 166) 0 0.0% 100.0%
- [166, inf) 0 0.0% 100.0%
-Benchmark___10B_mux___1K_chunks___10B 100 131543346 ns/op 0.00 MB/s
+ [ 1, 2) 12 2.4% 2.4%
+ [ 2, 3) 87 17.4% 19.8% ##
+ [ 3, 4) 19 3.8% 23.6%
+ [ 4, 5) 19 3.8% 27.4%
+ [ 5, 7) 23 4.6% 32.0%
+ [ 7, 9) 25 5.0% 37.0% #
+ [ 9, 12) 31 6.2% 43.2% #
+ [ 12, 16) 45 9.0% 52.2% #
+ [ 16, 21) 130 26.0% 78.2% ###
+ [ 21, 28) 109 21.8% 100.0% ##
+ [ 28, 36) 0 0.0% 100.0%
+ [ 36, 46) 0 0.0% 100.0%
+ [ 46, 59) 0 0.0% 100.0%
+ [ 59, 75) 0 0.0% 100.0%
+ [ 75, 95) 0 0.0% 100.0%
+ [ 95, 120) 0 0.0% 100.0%
+ [120, inf) 0 0.0% 100.0%
+Benchmark___10B_mux___1K_chunks___10B 100 89458344 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 100 Min: 12 Max: 215 Avg: 131.05
+ Count: 100 Min: 21 Max: 141 Avg: 88.95
------------------------------------------------------------
- [ 12, 13) 1 1.0% 1.0%
- [ 13, 14) 0 0.0% 1.0%
- [ 14, 16) 0 0.0% 1.0%
- [ 16, 18) 0 0.0% 1.0%
- [ 18, 22) 2 2.0% 3.0%
- [ 22, 27) 0 0.0% 3.0%
- [ 27, 35) 2 2.0% 5.0%
- [ 35, 46) 0 0.0% 5.0%
- [ 46, 63) 3 3.0% 8.0%
- [ 63, 87) 18 18.0% 26.0% ##
- [ 87, 121) 21 21.0% 47.0% ##
- [121, 170) 16 16.0% 63.0% ##
- [170, 240) 37 37.0% 100.0% ####
- [240, 339) 0 0.0% 100.0%
- [339, 481) 0 0.0% 100.0%
- [481, 684) 0 0.0% 100.0%
- [684, inf) 0 0.0% 100.0%
-Benchmark___10B_mux___1K_chunks___10B-2 300 26865810 ns/op 0.00 MB/s
+ [ 21, 22) 1 1.0% 1.0%
+ [ 22, 23) 0 0.0% 1.0%
+ [ 23, 24) 0 0.0% 1.0%
+ [ 24, 26) 0 0.0% 1.0%
+ [ 26, 29) 2 2.0% 3.0%
+ [ 29, 33) 1 1.0% 4.0%
+ [ 33, 39) 1 1.0% 5.0%
+ [ 39, 48) 5 5.0% 10.0% #
+ [ 48, 60) 12 12.0% 22.0% #
+ [ 60, 77) 18 18.0% 40.0% ##
+ [ 77, 101) 21 21.0% 61.0% ##
+ [101, 134) 33 33.0% 94.0% ###
+ [134, 180) 6 6.0% 100.0% #
+ [180, 243) 0 0.0% 100.0%
+ [243, 330) 0 0.0% 100.0%
+ [330, 449) 0 0.0% 100.0%
+ [449, inf) 0 0.0% 100.0%
+Benchmark___10B_mux___1K_chunks___10B-2 2000 5537208 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 5 Max: 108 Avg: 26.37
+ Count: 2000 Min: 1 Max: 46 Avg: 5.05
------------------------------------------------------------
- [ 5, 6) 18 6.0% 6.0% #
- [ 6, 7) 10 3.3% 9.3%
- [ 7, 8) 22 7.3% 16.7% #
- [ 8, 10) 50 16.7% 33.3% ##
- [ 10, 13) 62 20.7% 54.0% ##
- [ 13, 17) 43 14.3% 68.3% #
- [ 17, 23) 21 7.0% 75.3% #
- [ 23, 31) 5 1.7% 77.0%
- [ 31, 42) 5 1.7% 78.7%
- [ 42, 58) 4 1.3% 80.0%
- [ 58, 79) 19 6.3% 86.3% #
- [ 79, 108) 40 13.3% 99.7% #
- [108, 148) 1 0.3% 100.0%
- [148, 203) 0 0.0% 100.0%
- [203, 278) 0 0.0% 100.0%
- [278, 380) 0 0.0% 100.0%
- [380, inf) 0 0.0% 100.0%
-Benchmark___10B_mux___1K_chunks__100B 50 160157465 ns/op 0.00 MB/s
+ [ 1, 2) 36 1.8% 1.8%
+ [ 2, 3) 785 39.2% 41.1% ####
+ [ 3, 4) 580 29.0% 70.0% ###
+ [ 4, 6) 266 13.3% 83.4% #
+ [ 6, 8) 59 3.0% 86.3%
+ [ 8, 11) 48 2.4% 88.7%
+ [ 11, 15) 76 3.8% 92.5%
+ [ 15, 20) 37 1.9% 94.4%
+ [ 20, 27) 54 2.7% 97.1%
+ [ 27, 36) 36 1.8% 98.9%
+ [ 36, 48) 23 1.2% 100.0%
+ [ 48, 64) 0 0.0% 100.0%
+ [ 64, 85) 0 0.0% 100.0%
+ [ 85, 112) 0 0.0% 100.0%
+ [112, 146) 0 0.0% 100.0%
+ [146, 190) 0 0.0% 100.0%
+ [190, inf) 0 0.0% 100.0%
+Benchmark___10B_mux___1K_chunks__100B 100 95560922 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 50 Min: 73 Max: 233 Avg: 159.76
+ Count: 100 Min: 4 Max: 154 Avg: 95.10
------------------------------------------------------------
- [ 73, 74) 1 2.0% 2.0%
- [ 74, 75) 0 0.0% 2.0%
- [ 75, 76) 0 0.0% 2.0%
- [ 76, 78) 0 0.0% 2.0%
- [ 78, 81) 2 4.0% 6.0%
- [ 81, 86) 3 6.0% 12.0% #
- [ 86, 93) 2 4.0% 16.0%
- [ 93, 103) 4 8.0% 24.0% #
- [103, 117) 4 8.0% 32.0% #
- [117, 138) 5 10.0% 42.0% #
- [138, 167) 8 16.0% 58.0% ##
- [167, 208) 2 4.0% 62.0%
- [208, 265) 19 38.0% 100.0% ####
- [265, 346) 0 0.0% 100.0%
- [346, 460) 0 0.0% 100.0%
- [460, 619) 0 0.0% 100.0%
- [619, inf) 0 0.0% 100.0%
-Benchmark___10B_mux___1K_chunks__100B-2 200 38107608 ns/op 0.00 MB/s
+ [ 4, 5) 1 1.0% 1.0%
+ [ 5, 6) 0 0.0% 1.0%
+ [ 6, 7) 0 0.0% 1.0%
+ [ 7, 9) 1 1.0% 2.0%
+ [ 9, 12) 0 0.0% 2.0%
+ [ 12, 17) 0 0.0% 2.0%
+ [ 17, 24) 2 2.0% 4.0%
+ [ 24, 34) 0 0.0% 4.0%
+ [ 34, 48) 2 2.0% 6.0%
+ [ 48, 68) 18 18.0% 24.0% ##
+ [ 68, 96) 25 25.0% 49.0% ###
+ [ 96, 135) 35 35.0% 84.0% ####
+ [135, 190) 16 16.0% 100.0% ##
+ [190, 266) 0 0.0% 100.0%
+ [266, 373) 0 0.0% 100.0%
+ [373, 522) 0 0.0% 100.0%
+ [522, inf) 0 0.0% 100.0%
+Benchmark___10B_mux___1K_chunks__100B-2 2000 5772039 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 200 Min: 4 Max: 124 Avg: 37.60
+ Count: 2000 Min: 1 Max: 48 Avg: 5.29
------------------------------------------------------------
- [ 4, 5) 1 0.5% 0.5%
- [ 5, 6) 9 4.5% 5.0%
- [ 6, 7) 2 1.0% 6.0%
- [ 7, 9) 9 4.5% 10.5%
- [ 9, 12) 28 14.0% 24.5% #
- [ 12, 16) 36 18.0% 42.5% ##
- [ 16, 22) 40 20.0% 62.5% ##
- [ 22, 31) 13 6.5% 69.0% #
- [ 31, 43) 6 3.0% 72.0%
- [ 43, 60) 3 1.5% 73.5%
- [ 60, 84) 5 2.5% 76.0%
- [ 84, 117) 44 22.0% 98.0% ##
- [117, 163) 4 2.0% 100.0%
- [163, 226) 0 0.0% 100.0%
- [226, 313) 0 0.0% 100.0%
- [313, 432) 0 0.0% 100.0%
- [432, inf) 0 0.0% 100.0%
-Benchmark___10B_mux___1K_chunks___1KB 100 163950952 ns/op 0.00 MB/s
+ [ 1, 2) 19 1.0% 1.0%
+ [ 2, 3) 754 37.7% 38.7% ####
+ [ 3, 4) 569 28.5% 67.1% ###
+ [ 4, 6) 329 16.4% 83.6% ##
+ [ 6, 8) 56 2.8% 86.4%
+ [ 8, 11) 45 2.2% 88.6%
+ [ 11, 15) 34 1.7% 90.3%
+ [ 15, 21) 75 3.8% 94.1%
+ [ 21, 28) 75 3.8% 97.8%
+ [ 28, 38) 24 1.2% 99.0%
+ [ 38, 51) 20 1.0% 100.0%
+ [ 51, 67) 0 0.0% 100.0%
+ [ 67, 88) 0 0.0% 100.0%
+ [ 88, 116) 0 0.0% 100.0%
+ [116, 152) 0 0.0% 100.0%
+ [152, 198) 0 0.0% 100.0%
+ [198, inf) 0 0.0% 100.0%
+Benchmark___10B_mux___1K_chunks___1KB 100 104839465 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 100 Min: 9 Max: 265 Avg: 163.45
+ Count: 100 Min: 9 Max: 179 Avg: 104.38
------------------------------------------------------------
- [ 9, 10) 2 2.0% 2.0%
- [ 10, 11) 0 0.0% 2.0%
- [ 11, 13) 0 0.0% 2.0%
- [ 13, 16) 1 1.0% 3.0%
- [ 16, 20) 1 1.0% 4.0%
- [ 20, 26) 0 0.0% 4.0%
- [ 26, 35) 1 1.0% 5.0%
- [ 35, 48) 3 3.0% 8.0%
- [ 48, 67) 0 0.0% 8.0%
- [ 67, 94) 9 9.0% 17.0% #
- [ 94, 134) 21 21.0% 38.0% ##
- [134, 192) 28 28.0% 66.0% ###
- [192, 276) 34 34.0% 100.0% ###
- [276, 398) 0 0.0% 100.0%
- [398, 574) 0 0.0% 100.0%
- [574, 829) 0 0.0% 100.0%
- [829, inf) 0 0.0% 100.0%
-Benchmark___10B_mux___1K_chunks___1KB-2 200 43634458 ns/op 0.00 MB/s
+ [ 9, 10) 3 3.0% 3.0%
+ [ 10, 11) 0 0.0% 3.0%
+ [ 11, 12) 1 1.0% 4.0%
+ [ 12, 14) 1 1.0% 5.0%
+ [ 14, 17) 0 0.0% 5.0%
+ [ 17, 22) 0 0.0% 5.0%
+ [ 22, 29) 0 0.0% 5.0%
+ [ 29, 39) 3 3.0% 8.0%
+ [ 39, 54) 3 3.0% 11.0%
+ [ 54, 75) 9 9.0% 20.0% #
+ [ 75, 105) 35 35.0% 55.0% ####
+ [105, 148) 20 20.0% 75.0% ##
+ [148, 208) 25 25.0% 100.0% ###
+ [208, 293) 0 0.0% 100.0%
+ [293, 413) 0 0.0% 100.0%
+ [413, 583) 0 0.0% 100.0%
+ [583, inf) 0 0.0% 100.0%
+Benchmark___10B_mux___1K_chunks___1KB-2 1000 7235554 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 200 Min: 4 Max: 137 Avg: 43.13
+ Count: 1000 Min: 1 Max: 55 Avg: 6.74
------------------------------------------------------------
- [ 4, 5) 7 3.5% 3.5%
- [ 5, 6) 15 7.5% 11.0% #
- [ 6, 7) 2 1.0% 12.0%
- [ 7, 9) 9 4.5% 16.5%
- [ 9, 12) 20 10.0% 26.5% #
- [ 12, 17) 22 11.0% 37.5% #
- [ 17, 24) 27 13.5% 51.0% #
- [ 24, 33) 17 8.5% 59.5% #
- [ 33, 46) 14 7.0% 66.5% #
- [ 46, 64) 9 4.5% 71.0%
- [ 64, 90) 13 6.5% 77.5% #
- [ 90, 126) 35 17.5% 95.0% ##
- [126, 176) 10 5.0% 100.0% #
- [176, 245) 0 0.0% 100.0%
- [245, 340) 0 0.0% 100.0%
- [340, 473) 0 0.0% 100.0%
- [473, inf) 0 0.0% 100.0%
-Benchmark___10B_mux___1K_chunks__10KB 100 93479160 ns/op 0.00 MB/s
+ [ 1, 2) 10 1.0% 1.0%
+ [ 2, 3) 240 24.0% 25.0% ##
+ [ 3, 4) 272 27.2% 52.2% ###
+ [ 4, 6) 265 26.5% 78.7% ###
+ [ 6, 8) 44 4.4% 83.1%
+ [ 8, 11) 30 3.0% 86.1%
+ [ 11, 15) 22 2.2% 88.3%
+ [ 15, 21) 38 3.8% 92.1%
+ [ 21, 29) 20 2.0% 94.1%
+ [ 29, 39) 32 3.2% 97.3%
+ [ 39, 53) 25 2.5% 99.8%
+ [ 53, 71) 2 0.2% 100.0%
+ [ 71, 95) 0 0.0% 100.0%
+ [ 95, 126) 0 0.0% 100.0%
+ [126, 167) 0 0.0% 100.0%
+ [167, 221) 0 0.0% 100.0%
+ [221, inf) 0 0.0% 100.0%
+Benchmark___10B_mux___1K_chunks__10KB 100 72299884 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 100 Min: 8 Max: 138 Avg: 92.97
+ Count: 100 Min: 8 Max: 122 Avg: 71.77
------------------------------------------------------------
[ 8, 9) 1 1.0% 1.0%
[ 9, 10) 0 0.0% 1.0%
[ 10, 11) 0 0.0% 1.0%
[ 11, 13) 0 0.0% 1.0%
[ 13, 16) 0 0.0% 1.0%
- [ 16, 21) 3 3.0% 4.0%
- [ 21, 28) 3 3.0% 7.0%
- [ 28, 37) 2 2.0% 9.0%
- [ 37, 50) 3 3.0% 12.0%
- [ 50, 68) 12 12.0% 24.0% #
- [ 68, 93) 12 12.0% 36.0% #
- [ 93, 128) 55 55.0% 91.0% ######
- [128, 177) 9 9.0% 100.0% #
- [177, 244) 0 0.0% 100.0%
- [244, 337) 0 0.0% 100.0%
- [337, 466) 0 0.0% 100.0%
- [466, inf) 0 0.0% 100.0%
-Benchmark___10B_mux___1K_chunks__10KB-2 100 54432420 ns/op 0.00 MB/s
+ [ 16, 20) 4 4.0% 5.0%
+ [ 20, 26) 0 0.0% 5.0%
+ [ 26, 35) 4 4.0% 9.0%
+ [ 35, 47) 11 11.0% 20.0% #
+ [ 47, 64) 12 12.0% 32.0% #
+ [ 64, 87) 42 42.0% 74.0% ####
+ [ 87, 119) 24 24.0% 98.0% ##
+ [119, 163) 2 2.0% 100.0%
+ [163, 223) 0 0.0% 100.0%
+ [223, 306) 0 0.0% 100.0%
+ [306, 420) 0 0.0% 100.0%
+ [420, inf) 0 0.0% 100.0%
+Benchmark___10B_mux___1K_chunks__10KB-2 200 36957063 ns/op 0.00 MB/s
--- Histogram (unit: ms)
- Count: 100 Min: 5 Max: 89 Avg: 53.92
+ Count: 200 Min: 2 Max: 72 Avg: 36.49
------------------------------------------------------------
- [ 5, 6) 1 1.0% 1.0%
- [ 6, 7) 2 2.0% 3.0%
- [ 7, 8) 1 1.0% 4.0%
- [ 8, 10) 2 2.0% 6.0%
- [ 10, 13) 3 3.0% 9.0%
- [ 13, 17) 1 1.0% 10.0%
- [ 17, 22) 6 6.0% 16.0% #
- [ 22, 29) 2 2.0% 18.0%
- [ 29, 39) 8 8.0% 26.0% #
- [ 39, 53) 12 12.0% 38.0% #
- [ 53, 72) 38 38.0% 76.0% ####
- [ 72, 97) 24 24.0% 100.0% ##
- [ 97, 131) 0 0.0% 100.0%
- [131, 177) 0 0.0% 100.0%
- [177, 239) 0 0.0% 100.0%
- [239, 322) 0 0.0% 100.0%
- [322, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux__100_chunks___10B 300 26012216 ns/op 0.08 MB/s
+ [ 2, 3) 8 4.0% 4.0%
+ [ 3, 4) 5 2.5% 6.5%
+ [ 4, 5) 6 3.0% 9.5%
+ [ 5, 7) 3 1.5% 11.0%
+ [ 7, 10) 6 3.0% 14.0%
+ [ 10, 14) 6 3.0% 17.0%
+ [ 14, 19) 8 4.0% 21.0%
+ [ 19, 26) 12 6.0% 27.0% #
+ [ 26, 35) 31 15.5% 42.5% ##
+ [ 35, 47) 48 24.0% 66.5% ##
+ [ 47, 63) 52 26.0% 92.5% ###
+ [ 63, 85) 15 7.5% 100.0% #
+ [ 85, 114) 0 0.0% 100.0%
+ [114, 153) 0 0.0% 100.0%
+ [153, 205) 0 0.0% 100.0%
+ [205, 274) 0 0.0% 100.0%
+ [274, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux__100_chunks___10B 500 17595461 ns/op 0.11 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 8 Max: 32 Avg: 25.48
+ Count: 500 Min: 7 Max: 35 Avg: 17.11
------------------------------------------------------------
- [ 8, 9) 2 0.7% 0.7%
- [ 9, 10) 0 0.0% 0.7%
- [ 10, 11) 0 0.0% 0.7%
- [ 11, 12) 10 3.3% 4.0%
- [ 12, 14) 0 0.0% 4.0%
- [ 14, 16) 1 0.3% 4.3%
- [ 16, 19) 0 0.0% 4.3%
- [ 19, 23) 9 3.0% 7.3%
- [ 23, 28) 202 67.3% 74.7% #######
- [ 28, 34) 76 25.3% 100.0% ###
- [ 34, 42) 0 0.0% 100.0%
- [ 42, 52) 0 0.0% 100.0%
- [ 52, 64) 0 0.0% 100.0%
- [ 64, 79) 0 0.0% 100.0%
- [ 79, 98) 0 0.0% 100.0%
- [ 98, 122) 0 0.0% 100.0%
- [122, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux__100_chunks___10B-2 1000 7943170 ns/op 0.25 MB/s
---- Histogram (unit: ms)
- Count: 1000 Min: 4 Max: 22 Avg: 7.46
- ------------------------------------------------------------
- [ 4, 5) 10 1.0% 1.0%
- [ 5, 6) 233 23.3% 24.3% ##
- [ 6, 7) 284 28.4% 52.7% ###
- [ 7, 8) 126 12.6% 65.3% #
- [ 8, 10) 155 15.5% 80.8% ##
- [ 10, 12) 87 8.7% 89.5% #
- [ 12, 15) 82 8.2% 97.7% #
- [ 15, 18) 19 1.9% 99.6%
- [ 18, 22) 3 0.3% 99.9%
- [ 22, 27) 1 0.1% 100.0%
- [ 27, 33) 0 0.0% 100.0%
- [ 33, 41) 0 0.0% 100.0%
- [ 41, 51) 0 0.0% 100.0%
- [ 51, 63) 0 0.0% 100.0%
- [ 63, 77) 0 0.0% 100.0%
- [ 77, 94) 0 0.0% 100.0%
- [ 94, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux__100_chunks__100B 300 26131776 ns/op 0.08 MB/s
---- Histogram (unit: ms)
- Count: 300 Min: 8 Max: 35 Avg: 25.63
- ------------------------------------------------------------
- [ 8, 9) 1 0.3% 0.3%
- [ 9, 10) 0 0.0% 0.3%
- [ 10, 11) 0 0.0% 0.3%
- [ 11, 12) 0 0.0% 0.3%
- [ 12, 14) 0 0.0% 0.3%
- [ 14, 17) 0 0.0% 0.3%
- [ 17, 20) 1 0.3% 0.7%
- [ 20, 24) 126 42.0% 42.7% ####
- [ 24, 29) 86 28.7% 71.3% ###
- [ 29, 36) 86 28.7% 100.0% ###
- [ 36, 45) 0 0.0% 100.0%
- [ 45, 56) 0 0.0% 100.0%
- [ 56, 69) 0 0.0% 100.0%
+ [ 7, 8) 1 0.2% 0.2%
+ [ 8, 9) 1 0.2% 0.4%
+ [ 9, 10) 0 0.0% 0.4%
+ [ 10, 11) 0 0.0% 0.4%
+ [ 11, 13) 4 0.8% 1.2%
+ [ 13, 16) 380 76.0% 77.2% ########
+ [ 16, 19) 43 8.6% 85.8% #
+ [ 19, 23) 2 0.4% 86.2%
+ [ 23, 28) 14 2.8% 89.0%
+ [ 28, 35) 54 10.8% 99.8% #
+ [ 35, 44) 1 0.2% 100.0%
+ [ 44, 55) 0 0.0% 100.0%
+ [ 55, 69) 0 0.0% 100.0%
[ 69, 86) 0 0.0% 100.0%
- [ 86, 107) 0 0.0% 100.0%
- [107, 134) 0 0.0% 100.0%
- [134, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux__100_chunks__100B-2 1000 8434636 ns/op 0.24 MB/s
+ [ 86, 108) 0 0.0% 100.0%
+ [108, 135) 0 0.0% 100.0%
+ [135, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux__100_chunks___10B-2 2000 4157817 ns/op 0.48 MB/s
--- Histogram (unit: ms)
- Count: 1000 Min: 4 Max: 23 Avg: 7.96
+ Count: 2000 Min: 1 Max: 22 Avg: 3.67
------------------------------------------------------------
- [ 4, 5) 6 0.6% 0.6%
- [ 5, 6) 165 16.5% 17.1% ##
- [ 6, 7) 286 28.6% 45.7% ###
- [ 7, 8) 152 15.2% 60.9% ##
- [ 8, 10) 151 15.1% 76.0% ##
- [ 10, 12) 97 9.7% 85.7% #
- [ 12, 15) 91 9.1% 94.8% #
- [ 15, 18) 43 4.3% 99.1%
- [ 18, 22) 7 0.7% 99.8%
- [ 22, 27) 2 0.2% 100.0%
+ [ 1, 2) 29 1.5% 1.5%
+ [ 2, 3) 804 40.2% 41.7% ####
+ [ 3, 4) 550 27.5% 69.2% ###
+ [ 4, 5) 289 14.5% 83.6% #
+ [ 5, 7) 160 8.0% 91.6% #
+ [ 7, 9) 31 1.6% 93.2%
+ [ 9, 12) 63 3.2% 96.3%
+ [ 12, 16) 32 1.6% 97.9%
+ [ 16, 21) 36 1.8% 99.7%
+ [ 21, 27) 6 0.3% 100.0%
[ 27, 34) 0 0.0% 100.0%
- [ 34, 42) 0 0.0% 100.0%
- [ 42, 52) 0 0.0% 100.0%
- [ 52, 64) 0 0.0% 100.0%
- [ 64, 79) 0 0.0% 100.0%
- [ 79, 97) 0 0.0% 100.0%
- [ 97, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux__100_chunks___1KB 200 31946178 ns/op 0.06 MB/s
+ [ 34, 43) 0 0.0% 100.0%
+ [ 43, 54) 0 0.0% 100.0%
+ [ 54, 67) 0 0.0% 100.0%
+ [ 67, 84) 0 0.0% 100.0%
+ [ 84, 104) 0 0.0% 100.0%
+ [104, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux__100_chunks__100B 500 18203976 ns/op 0.11 MB/s
--- Histogram (unit: ms)
- Count: 200 Min: 9 Max: 44 Avg: 31.49
+ Count: 500 Min: 8 Max: 39 Avg: 17.78
------------------------------------------------------------
- [ 9, 10) 12 6.0% 6.0% #
- [ 10, 11) 1 0.5% 6.5%
- [ 11, 12) 0 0.0% 6.5%
- [ 12, 14) 4 2.0% 8.5%
- [ 14, 16) 0 0.0% 8.5%
- [ 16, 19) 2 1.0% 9.5%
- [ 19, 23) 0 0.0% 9.5%
- [ 23, 28) 13 6.5% 16.0% #
- [ 28, 34) 93 46.5% 62.5% #####
- [ 34, 42) 71 35.5% 98.0% ####
- [ 42, 52) 4 2.0% 100.0%
- [ 52, 65) 0 0.0% 100.0%
- [ 65, 82) 0 0.0% 100.0%
- [ 82, 103) 0 0.0% 100.0%
- [103, 130) 0 0.0% 100.0%
- [130, 164) 0 0.0% 100.0%
- [164, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux__100_chunks___1KB-2 1000 11688416 ns/op 0.17 MB/s
+ [ 8, 9) 1 0.2% 0.2%
+ [ 9, 10) 0 0.0% 0.2%
+ [ 10, 11) 0 0.0% 0.2%
+ [ 11, 12) 0 0.0% 0.2%
+ [ 12, 14) 5 1.0% 1.2%
+ [ 14, 17) 405 81.0% 82.2% ########
+ [ 17, 20) 21 4.2% 86.4%
+ [ 20, 24) 1 0.2% 86.6%
+ [ 24, 30) 8 1.6% 88.2%
+ [ 30, 37) 54 10.8% 99.0% #
+ [ 37, 46) 5 1.0% 100.0%
+ [ 46, 58) 0 0.0% 100.0%
+ [ 58, 73) 0 0.0% 100.0%
+ [ 73, 92) 0 0.0% 100.0%
+ [ 92, 116) 0 0.0% 100.0%
+ [116, 146) 0 0.0% 100.0%
+ [146, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux__100_chunks__100B-2 2000 4271254 ns/op 0.47 MB/s
--- Histogram (unit: ms)
- Count: 1000 Min: 4 Max: 28 Avg: 11.20
+ Count: 2000 Min: 1 Max: 26 Avg: 3.79
------------------------------------------------------------
- [ 4, 5) 5 0.5% 0.5%
- [ 5, 6) 69 6.9% 7.4% #
- [ 6, 7) 75 7.5% 14.9% #
- [ 7, 8) 121 12.1% 27.0% #
- [ 8, 10) 171 17.1% 44.1% ##
- [ 10, 12) 134 13.4% 57.5% #
- [ 12, 15) 172 17.2% 74.7% ##
- [ 15, 19) 170 17.0% 91.7% ##
- [ 19, 24) 79 7.9% 99.6% #
- [ 24, 30) 4 0.4% 100.0%
- [ 30, 38) 0 0.0% 100.0%
- [ 38, 48) 0 0.0% 100.0%
- [ 48, 60) 0 0.0% 100.0%
- [ 60, 75) 0 0.0% 100.0%
- [ 75, 94) 0 0.0% 100.0%
+ [ 1, 2) 31 1.6% 1.6%
+ [ 2, 3) 761 38.1% 39.6% ####
+ [ 3, 4) 550 27.5% 67.1% ###
+ [ 4, 5) 316 15.8% 82.9% ##
+ [ 5, 7) 166 8.3% 91.2% #
+ [ 7, 9) 25 1.2% 92.5%
+ [ 9, 12) 65 3.2% 95.7%
+ [ 12, 16) 48 2.4% 98.1%
+ [ 16, 21) 22 1.1% 99.2%
+ [ 21, 27) 16 0.8% 100.0%
+ [ 27, 35) 0 0.0% 100.0%
+ [ 35, 45) 0 0.0% 100.0%
+ [ 45, 58) 0 0.0% 100.0%
+ [ 58, 74) 0 0.0% 100.0%
+ [ 74, 94) 0 0.0% 100.0%
[ 94, 118) 0 0.0% 100.0%
[118, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux__100_chunks__10KB 200 48210454 ns/op 0.04 MB/s
+Benchmark___1KB_mux__100_chunks___1KB 300 20682669 ns/op 0.10 MB/s
--- Histogram (unit: ms)
- Count: 200 Min: 9 Max: 61 Avg: 47.74
+ Count: 300 Min: 13 Max: 41 Avg: 20.18
------------------------------------------------------------
- [ 9, 10) 1 0.5% 0.5%
- [ 10, 11) 0 0.0% 0.5%
- [ 11, 12) 0 0.0% 0.5%
- [ 12, 14) 14 7.0% 7.5% #
- [ 14, 16) 9 4.5% 12.0%
- [ 16, 19) 5 2.5% 14.5%
- [ 19, 23) 2 1.0% 15.5%
- [ 23, 29) 0 0.0% 15.5%
- [ 29, 37) 0 0.0% 15.5%
- [ 37, 47) 7 3.5% 19.0%
- [ 47, 60) 159 79.5% 98.5% ########
- [ 60, 78) 3 1.5% 100.0%
- [ 78, 101) 0 0.0% 100.0%
- [101, 131) 0 0.0% 100.0%
- [131, 170) 0 0.0% 100.0%
- [170, 222) 0 0.0% 100.0%
- [222, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux__100_chunks__10KB-2 300 24547213 ns/op 0.08 MB/s
+ [ 13, 14) 1 0.3% 0.3%
+ [ 14, 15) 2 0.7% 1.0%
+ [ 15, 16) 0 0.0% 1.0%
+ [ 16, 17) 0 0.0% 1.0%
+ [ 17, 19) 245 81.7% 82.7% ########
+ [ 19, 22) 8 2.7% 85.3%
+ [ 22, 25) 5 1.7% 87.0%
+ [ 25, 29) 0 0.0% 87.0%
+ [ 29, 34) 1 0.3% 87.3%
+ [ 34, 41) 28 9.3% 96.7% #
+ [ 41, 50) 10 3.3% 100.0%
+ [ 50, 61) 0 0.0% 100.0%
+ [ 61, 75) 0 0.0% 100.0%
+ [ 75, 92) 0 0.0% 100.0%
+ [ 92, 114) 0 0.0% 100.0%
+ [114, 141) 0 0.0% 100.0%
+ [141, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux__100_chunks___1KB-2 2000 4950276 ns/op 0.40 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 4 Max: 42 Avg: 24.07
+ Count: 2000 Min: 1 Max: 26 Avg: 4.46
------------------------------------------------------------
- [ 4, 5) 1 0.3% 0.3%
- [ 5, 6) 8 2.7% 3.0%
- [ 6, 7) 1 0.3% 3.3%
- [ 7, 9) 6 2.0% 5.3%
- [ 9, 11) 14 4.7% 10.0%
- [ 11, 14) 24 8.0% 18.0% #
- [ 14, 18) 13 4.3% 22.3%
- [ 18, 23) 37 12.3% 34.7% #
- [ 23, 29) 67 22.3% 57.0% ##
- [ 29, 37) 120 40.0% 97.0% ####
- [ 37, 48) 9 3.0% 100.0%
- [ 48, 62) 0 0.0% 100.0%
- [ 62, 80) 0 0.0% 100.0%
- [ 80, 103) 0 0.0% 100.0%
- [103, 132) 0 0.0% 100.0%
- [132, 169) 0 0.0% 100.0%
- [169, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux___1K_chunks___10B 100 131862174 ns/op 0.02 MB/s
+ [ 1, 2) 12 0.6% 0.6%
+ [ 2, 3) 546 27.3% 27.9% ###
+ [ 3, 4) 517 25.9% 53.8% ###
+ [ 4, 5) 354 17.7% 71.5% ##
+ [ 5, 7) 341 17.1% 88.5% ##
+ [ 7, 9) 60 3.0% 91.5%
+ [ 9, 12) 37 1.9% 93.4%
+ [ 12, 16) 76 3.8% 97.2%
+ [ 16, 21) 20 1.0% 98.2%
+ [ 21, 27) 37 1.9% 100.0%
+ [ 27, 35) 0 0.0% 100.0%
+ [ 35, 45) 0 0.0% 100.0%
+ [ 45, 58) 0 0.0% 100.0%
+ [ 58, 74) 0 0.0% 100.0%
+ [ 74, 94) 0 0.0% 100.0%
+ [ 94, 118) 0 0.0% 100.0%
+ [118, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux__100_chunks__10KB 200 39416624 ns/op 0.05 MB/s
--- Histogram (unit: ms)
- Count: 100 Min: 10 Max: 209 Avg: 131.34
+ Count: 200 Min: 14 Max: 57 Avg: 38.98
------------------------------------------------------------
- [ 10, 11) 1 1.0% 1.0%
- [ 11, 12) 1 1.0% 2.0%
- [ 12, 14) 0 0.0% 2.0%
- [ 14, 16) 0 0.0% 2.0%
- [ 16, 20) 1 1.0% 3.0%
- [ 20, 25) 0 0.0% 3.0%
- [ 25, 33) 0 0.0% 3.0%
- [ 33, 44) 0 0.0% 3.0%
- [ 44, 60) 4 4.0% 7.0%
- [ 60, 83) 16 16.0% 23.0% ##
- [ 83, 117) 18 18.0% 41.0% ##
- [117, 165) 24 24.0% 65.0% ##
- [165, 234) 35 35.0% 100.0% ####
- [234, 332) 0 0.0% 100.0%
- [332, 471) 0 0.0% 100.0%
- [471, 669) 0 0.0% 100.0%
- [669, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux___1K_chunks___10B-2 300 23370846 ns/op 0.09 MB/s
+ [ 14, 15) 2 1.0% 1.0%
+ [ 15, 16) 0 0.0% 1.0%
+ [ 16, 17) 0 0.0% 1.0%
+ [ 17, 19) 2 1.0% 2.0%
+ [ 19, 21) 0 0.0% 2.0%
+ [ 21, 24) 0 0.0% 2.0%
+ [ 24, 28) 0 0.0% 2.0%
+ [ 28, 33) 4 2.0% 4.0%
+ [ 33, 40) 130 65.0% 69.0% #######
+ [ 40, 49) 16 8.0% 77.0% #
+ [ 49, 61) 46 23.0% 100.0% ##
+ [ 61, 76) 0 0.0% 100.0%
+ [ 76, 96) 0 0.0% 100.0%
+ [ 96, 122) 0 0.0% 100.0%
+ [122, 155) 0 0.0% 100.0%
+ [155, 198) 0 0.0% 100.0%
+ [198, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux__100_chunks__10KB-2 500 13370112 ns/op 0.15 MB/s
--- Histogram (unit: ms)
- Count: 300 Min: 4 Max: 101 Avg: 22.88
+ Count: 500 Min: 1 Max: 35 Avg: 12.88
------------------------------------------------------------
- [ 4, 5) 1 0.3% 0.3%
- [ 5, 6) 24 8.0% 8.3% #
- [ 6, 7) 49 16.3% 24.7% ##
- [ 7, 9) 48 16.0% 40.7% ##
- [ 9, 12) 26 8.7% 49.3% #
- [ 12, 16) 53 17.7% 67.0% ##
- [ 16, 22) 36 12.0% 79.0% #
- [ 22, 30) 5 1.7% 80.7%
- [ 30, 41) 4 1.3% 82.0%
- [ 41, 56) 3 1.0% 83.0%
- [ 56, 77) 21 7.0% 90.0% #
- [ 77, 105) 30 10.0% 100.0% #
- [105, 143) 0 0.0% 100.0%
- [143, 195) 0 0.0% 100.0%
- [195, 266) 0 0.0% 100.0%
- [266, 362) 0 0.0% 100.0%
- [362, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux___1K_chunks__100B 50 138026822 ns/op 0.01 MB/s
+ [ 1, 2) 6 1.2% 1.2%
+ [ 2, 3) 94 18.8% 20.0% ##
+ [ 3, 4) 29 5.8% 25.8% #
+ [ 4, 6) 22 4.4% 30.2%
+ [ 6, 8) 15 3.0% 33.2%
+ [ 8, 11) 55 11.0% 44.2% #
+ [ 11, 15) 31 6.2% 50.4% #
+ [ 15, 20) 174 34.8% 85.2% ###
+ [ 20, 26) 14 2.8% 88.0%
+ [ 26, 34) 54 10.8% 98.8% #
+ [ 34, 44) 6 1.2% 100.0%
+ [ 44, 57) 0 0.0% 100.0%
+ [ 57, 73) 0 0.0% 100.0%
+ [ 73, 94) 0 0.0% 100.0%
+ [ 94, 120) 0 0.0% 100.0%
+ [120, 153) 0 0.0% 100.0%
+ [153, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux___1K_chunks___10B 100 95315574 ns/op 0.02 MB/s
--- Histogram (unit: ms)
- Count: 50 Min: 22 Max: 222 Avg: 137.50
+ Count: 100 Min: 23 Max: 150 Avg: 94.81
------------------------------------------------------------
- [ 22, 23) 1 2.0% 2.0%
- [ 23, 24) 1 2.0% 4.0%
- [ 24, 26) 0 0.0% 4.0%
- [ 26, 28) 0 0.0% 4.0%
- [ 28, 32) 0 0.0% 4.0%
- [ 32, 37) 0 0.0% 4.0%
- [ 37, 45) 0 0.0% 4.0%
- [ 45, 56) 2 4.0% 8.0%
- [ 56, 72) 2 4.0% 12.0%
- [ 72, 96) 7 14.0% 26.0% #
- [ 96, 130) 11 22.0% 48.0% ##
- [130, 178) 10 20.0% 68.0% ##
- [178, 247) 16 32.0% 100.0% ###
- [247, 345) 0 0.0% 100.0%
- [345, 485) 0 0.0% 100.0%
- [485, 684) 0 0.0% 100.0%
- [684, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux___1K_chunks__100B-2 200 29916622 ns/op 0.07 MB/s
+ [ 23, 24) 1 1.0% 1.0%
+ [ 24, 25) 0 0.0% 1.0%
+ [ 25, 26) 0 0.0% 1.0%
+ [ 26, 28) 1 1.0% 2.0%
+ [ 28, 31) 0 0.0% 2.0%
+ [ 31, 36) 1 1.0% 3.0%
+ [ 36, 42) 2 2.0% 5.0%
+ [ 42, 51) 5 5.0% 10.0% #
+ [ 51, 64) 7 7.0% 17.0% #
+ [ 64, 82) 17 17.0% 34.0% ##
+ [ 82, 107) 24 24.0% 58.0% ##
+ [107, 141) 38 38.0% 96.0% ####
+ [141, 189) 4 4.0% 100.0%
+ [189, 255) 0 0.0% 100.0%
+ [255, 346) 0 0.0% 100.0%
+ [346, 472) 0 0.0% 100.0%
+ [472, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux___1K_chunks___10B-2 2000 5107260 ns/op 0.39 MB/s
--- Histogram (unit: ms)
- Count: 200 Min: 5 Max: 117 Avg: 29.41
+ Count: 2000 Min: 1 Max: 46 Avg: 4.61
------------------------------------------------------------
- [ 5, 6) 8 4.0% 4.0%
- [ 6, 7) 19 9.5% 13.5% #
- [ 7, 8) 15 7.5% 21.0% #
- [ 8, 10) 31 15.5% 36.5% ##
- [ 10, 13) 25 12.5% 49.0% #
- [ 13, 17) 37 18.5% 67.5% ##
- [ 17, 23) 15 7.5% 75.0% #
- [ 23, 32) 4 2.0% 77.0%
- [ 32, 44) 2 1.0% 78.0%
- [ 44, 60) 0 0.0% 78.0%
- [ 60, 83) 4 2.0% 80.0%
- [ 83, 114) 38 19.0% 99.0% ##
- [114, 157) 2 1.0% 100.0%
- [157, 216) 0 0.0% 100.0%
- [216, 297) 0 0.0% 100.0%
- [297, 408) 0 0.0% 100.0%
- [408, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux___1K_chunks___1KB 50 165938483 ns/op 0.01 MB/s
+ [ 1, 2) 15 0.8% 0.8%
+ [ 2, 3) 792 39.6% 40.4% ####
+ [ 3, 4) 669 33.5% 73.8% ###
+ [ 4, 6) 289 14.5% 88.2% #
+ [ 6, 8) 28 1.4% 89.7%
+ [ 8, 11) 23 1.2% 90.8%
+ [ 11, 15) 34 1.7% 92.5%
+ [ 15, 20) 36 1.8% 94.3%
+ [ 20, 27) 71 3.6% 97.9%
+ [ 27, 36) 37 1.9% 99.7%
+ [ 36, 48) 6 0.3% 100.0%
+ [ 48, 64) 0 0.0% 100.0%
+ [ 64, 85) 0 0.0% 100.0%
+ [ 85, 112) 0 0.0% 100.0%
+ [112, 146) 0 0.0% 100.0%
+ [146, 190) 0 0.0% 100.0%
+ [190, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux___1K_chunks__100B 100 94447578 ns/op 0.02 MB/s
--- Histogram (unit: ms)
- Count: 50 Min: 19 Max: 292 Avg: 165.50
+ Count: 100 Min: 2 Max: 149 Avg: 93.96
------------------------------------------------------------
- [ 19, 20) 1 2.0% 2.0%
- [ 20, 21) 0 0.0% 2.0%
- [ 21, 23) 0 0.0% 2.0%
- [ 23, 26) 0 0.0% 2.0%
- [ 26, 30) 0 0.0% 2.0%
- [ 30, 36) 0 0.0% 2.0%
- [ 36, 45) 0 0.0% 2.0%
- [ 45, 58) 1 2.0% 4.0%
- [ 58, 77) 0 0.0% 4.0%
- [ 77, 105) 10 20.0% 24.0% ##
- [105, 147) 11 22.0% 46.0% ##
- [147, 208) 14 28.0% 74.0% ###
- [208, 296) 13 26.0% 100.0% ###
- [296, 425) 0 0.0% 100.0%
- [425, 612) 0 0.0% 100.0%
- [612, 884) 0 0.0% 100.0%
- [884, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux___1K_chunks___1KB-2 200 44332653 ns/op 0.05 MB/s
+ [ 2, 3) 1 1.0% 1.0%
+ [ 3, 4) 0 0.0% 1.0%
+ [ 4, 5) 0 0.0% 1.0%
+ [ 5, 7) 0 0.0% 1.0%
+ [ 7, 10) 2 2.0% 3.0%
+ [ 10, 15) 0 0.0% 3.0%
+ [ 15, 22) 1 1.0% 4.0%
+ [ 22, 32) 2 2.0% 6.0%
+ [ 32, 46) 7 7.0% 13.0% #
+ [ 46, 65) 9 9.0% 22.0% #
+ [ 65, 92) 20 20.0% 42.0% ##
+ [ 92, 130) 40 40.0% 82.0% ####
+ [130, 184) 18 18.0% 100.0% ##
+ [184, 259) 0 0.0% 100.0%
+ [259, 364) 0 0.0% 100.0%
+ [364, 511) 0 0.0% 100.0%
+ [511, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux___1K_chunks__100B-2 2000 5333802 ns/op 0.37 MB/s
--- Histogram (unit: ms)
- Count: 200 Min: 5 Max: 136 Avg: 43.85
+ Count: 2000 Min: 1 Max: 55 Avg: 4.84
------------------------------------------------------------
- [ 5, 6) 10 5.0% 5.0% #
- [ 6, 7) 1 0.5% 5.5%
- [ 7, 8) 2 1.0% 6.5%
- [ 8, 10) 14 7.0% 13.5% #
- [ 10, 13) 22 11.0% 24.5% #
- [ 13, 18) 23 11.5% 36.0% #
- [ 18, 25) 24 12.0% 48.0% #
- [ 25, 34) 21 10.5% 58.5% #
- [ 34, 47) 19 9.5% 68.0% #
- [ 47, 65) 9 4.5% 72.5%
- [ 65, 90) 10 5.0% 77.5% #
- [ 90, 125) 38 19.0% 96.5% ##
- [125, 174) 7 3.5% 100.0%
- [174, 242) 0 0.0% 100.0%
- [242, 336) 0 0.0% 100.0%
- [336, 466) 0 0.0% 100.0%
- [466, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux___1K_chunks__10KB 100 97935953 ns/op 0.02 MB/s
+ [ 1, 2) 16 0.8% 0.8%
+ [ 2, 3) 766 38.3% 39.1% ####
+ [ 3, 4) 670 33.5% 72.6% ###
+ [ 4, 6) 318 15.9% 88.5% ##
+ [ 6, 8) 36 1.8% 90.3%
+ [ 8, 11) 12 0.6% 90.9%
+ [ 11, 15) 26 1.3% 92.2%
+ [ 15, 21) 46 2.3% 94.5%
+ [ 21, 29) 65 3.2% 97.8%
+ [ 29, 39) 34 1.7% 99.5%
+ [ 39, 53) 7 0.4% 99.8%
+ [ 53, 71) 4 0.2% 100.0%
+ [ 71, 95) 0 0.0% 100.0%
+ [ 95, 126) 0 0.0% 100.0%
+ [126, 167) 0 0.0% 100.0%
+ [167, 221) 0 0.0% 100.0%
+ [221, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux___1K_chunks___1KB 100 106144273 ns/op 0.02 MB/s
--- Histogram (unit: ms)
- Count: 100 Min: 10 Max: 161 Avg: 97.40
+ Count: 100 Min: 6 Max: 173 Avg: 105.63
------------------------------------------------------------
- [ 10, 11) 1 1.0% 1.0%
- [ 11, 12) 0 0.0% 1.0%
- [ 12, 13) 0 0.0% 1.0%
- [ 13, 15) 1 1.0% 2.0%
- [ 15, 18) 0 0.0% 2.0%
- [ 18, 23) 0 0.0% 2.0%
- [ 23, 30) 1 1.0% 3.0%
- [ 30, 40) 4 4.0% 7.0%
- [ 40, 54) 4 4.0% 11.0%
- [ 54, 74) 17 17.0% 28.0% ##
- [ 74, 102) 20 20.0% 48.0% ##
- [102, 141) 45 45.0% 93.0% #####
- [141, 196) 7 7.0% 100.0% #
- [196, 273) 0 0.0% 100.0%
- [273, 381) 0 0.0% 100.0%
- [381, 531) 0 0.0% 100.0%
- [531, inf) 0 0.0% 100.0%
-Benchmark___1KB_mux___1K_chunks__10KB-2 100 59656535 ns/op 0.03 MB/s
+ [ 6, 7) 1 1.0% 1.0%
+ [ 7, 8) 0 0.0% 1.0%
+ [ 8, 9) 0 0.0% 1.0%
+ [ 9, 11) 0 0.0% 1.0%
+ [ 11, 14) 1 1.0% 2.0%
+ [ 14, 19) 3 3.0% 5.0%
+ [ 19, 26) 1 1.0% 6.0%
+ [ 26, 36) 4 4.0% 10.0%
+ [ 36, 51) 4 4.0% 14.0%
+ [ 51, 72) 8 8.0% 22.0% #
+ [ 72, 102) 24 24.0% 46.0% ##
+ [102, 144) 26 26.0% 72.0% ###
+ [144, 204) 28 28.0% 100.0% ###
+ [204, 288) 0 0.0% 100.0%
+ [288, 406) 0 0.0% 100.0%
+ [406, 573) 0 0.0% 100.0%
+ [573, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux___1K_chunks___1KB-2 1000 7132495 ns/op 0.28 MB/s
--- Histogram (unit: ms)
- Count: 100 Min: 5 Max: 111 Avg: 59.16
+ Count: 1000 Min: 1 Max: 43 Avg: 6.64
------------------------------------------------------------
- [ 5, 6) 2 2.0% 2.0%
- [ 6, 7) 0 0.0% 2.0%
- [ 7, 8) 0 0.0% 2.0%
- [ 8, 10) 0 0.0% 2.0%
- [ 10, 13) 2 2.0% 4.0%
- [ 13, 17) 3 3.0% 7.0%
- [ 17, 23) 2 2.0% 9.0%
- [ 23, 31) 9 9.0% 18.0% #
- [ 31, 43) 5 5.0% 23.0% #
- [ 43, 59) 17 17.0% 40.0% ##
- [ 59, 81) 47 47.0% 87.0% #####
- [ 81, 111) 12 12.0% 99.0% #
- [111, 152) 1 1.0% 100.0%
- [152, 208) 0 0.0% 100.0%
- [208, 285) 0 0.0% 100.0%
- [285, 390) 0 0.0% 100.0%
- [390, inf) 0 0.0% 100.0%
+ [ 1, 2) 24 2.4% 2.4%
+ [ 2, 3) 286 28.6% 31.0% ###
+ [ 3, 4) 272 27.2% 58.2% ###
+ [ 4, 6) 217 21.7% 79.9% ##
+ [ 6, 8) 44 4.4% 84.3%
+ [ 8, 11) 15 1.5% 85.8%
+ [ 11, 15) 11 1.1% 86.9%
+ [ 15, 20) 19 1.9% 88.8%
+ [ 20, 27) 14 1.4% 90.2%
+ [ 27, 36) 87 8.7% 98.9% #
+ [ 36, 48) 11 1.1% 100.0%
+ [ 48, 63) 0 0.0% 100.0%
+ [ 63, 82) 0 0.0% 100.0%
+ [ 82, 107) 0 0.0% 100.0%
+ [107, 139) 0 0.0% 100.0%
+ [139, 181) 0 0.0% 100.0%
+ [181, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux___1K_chunks__10KB 100 75825411 ns/op 0.03 MB/s
+--- Histogram (unit: ms)
+ Count: 100 Min: 3 Max: 130 Avg: 75.35
+ ------------------------------------------------------------
+ [ 3, 4) 1 1.0% 1.0%
+ [ 4, 5) 0 0.0% 1.0%
+ [ 5, 6) 0 0.0% 1.0%
+ [ 6, 8) 0 0.0% 1.0%
+ [ 8, 11) 0 0.0% 1.0%
+ [ 11, 16) 0 0.0% 1.0%
+ [ 16, 22) 4 4.0% 5.0%
+ [ 22, 31) 0 0.0% 5.0%
+ [ 31, 44) 7 7.0% 12.0% #
+ [ 44, 62) 14 14.0% 26.0% #
+ [ 62, 87) 38 38.0% 64.0% ####
+ [ 87, 121) 29 29.0% 93.0% ###
+ [121, 169) 7 7.0% 100.0% #
+ [169, 235) 0 0.0% 100.0%
+ [235, 326) 0 0.0% 100.0%
+ [326, 452) 0 0.0% 100.0%
+ [452, inf) 0 0.0% 100.0%
+Benchmark___1KB_mux___1K_chunks__10KB-2 200 38383294 ns/op 0.05 MB/s
+--- Histogram (unit: ms)
+ Count: 200 Min: 1 Max: 81 Avg: 37.88
+ ------------------------------------------------------------
+ [ 1, 2) 1 0.5% 0.5%
+ [ 2, 3) 10 5.0% 5.5% #
+ [ 3, 4) 4 2.0% 7.5%
+ [ 4, 6) 3 1.5% 9.0%
+ [ 6, 9) 9 4.5% 13.5%
+ [ 9, 13) 3 1.5% 15.0%
+ [ 13, 18) 12 6.0% 21.0% #
+ [ 18, 25) 7 3.5% 24.5%
+ [ 25, 35) 37 18.5% 43.0% ##
+ [ 35, 48) 46 23.0% 66.0% ##
+ [ 48, 66) 48 24.0% 90.0% ##
+ [ 66, 90) 20 10.0% 100.0% #
+ [ 90, 123) 0 0.0% 100.0%
+ [123, 167) 0 0.0% 100.0%
+ [167, 226) 0 0.0% 100.0%
+ [226, 305) 0 0.0% 100.0%
+ [305, inf) 0 0.0% 100.0%
diff --git a/runtimes/google/ipc/client_test.go b/runtimes/google/ipc/client_test.go
index b91f8c0..548db9a 100644
--- a/runtimes/google/ipc/client_test.go
+++ b/runtimes/google/ipc/client_test.go
@@ -36,17 +36,12 @@
return ctx, shutdown
}
-func testArgs(args ...string) []string {
- var targs = []string{"--", "--veyron.tcp.address=127.0.0.1:0"}
- return append(targs, args...)
-}
-
func runMountTable(t *testing.T, ctx *context.T) (*modules.Shell, func()) {
sh, err := modules.NewShell(ctx, nil)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
- root, err := sh.Start(core.RootMTCommand, nil, testArgs()...)
+ root, err := sh.Start(core.RootMTCommand, nil)
if err != nil {
t.Fatalf("unexpected error for root mt: %s", err)
}
@@ -109,7 +104,7 @@
sh, fn := runMountTable(t, ctx)
defer fn()
- srv, err := sh.Start(core.EchoServerCommand, nil, testArgs("echoServer", "echoServer")...)
+ srv, err := sh.Start(core.EchoServerCommand, nil, "echoServer", "echoServer")
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
@@ -172,7 +167,7 @@
defer shutdown()
veyron2.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))
- name := args[1]
+ name := args[0]
call, err := veyron2.GetClient(ctx).StartCall(ctx, name, "Ping", nil)
if err != nil {
fmt.Errorf("unexpected error: %s", err)
@@ -334,7 +329,7 @@
// backoff of some minutes.
startServer := func() {
time.Sleep(10 * time.Millisecond)
- srv, _ := sh.Start(core.EchoServerCommand, nil, testArgs("message", name)...)
+ srv, _ := sh.Start(core.EchoServerCommand, nil, "message", name)
s := expect.NewSession(t, srv.Stdout(), time.Minute)
s.ExpectVar("PID")
s.ExpectVar("NAME")
@@ -495,7 +490,7 @@
t.Fatalf("unexpected error: %s", err)
}
defer sh.Cleanup(os.Stderr, os.Stderr)
- server, err := sh.Start(core.EchoServerCommand, nil, "--", "--veyron.tcp.address=127.0.0.1:0", "mymessage", "")
+ server, err := sh.Start(core.EchoServerCommand, nil, "--veyron.tcp.address=127.0.0.1:0", "mymessage", "")
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
@@ -536,7 +531,7 @@
// Resurrect the server with the same address, verify client
// re-establishes the connection. This is racy if another
// process grabs the port.
- server, err = sh.Start(core.EchoServerCommand, nil, "--", "--veyron.tcp.address="+ep.Address, "mymessage again", "")
+ server, err = sh.Start(core.EchoServerCommand, nil, "--veyron.tcp.address="+ep.Address, "mymessage again", "")
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index 2db17e4..3e85647 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -6,6 +6,7 @@
"fmt"
"io"
"net"
+ "os"
"path/filepath"
"reflect"
"runtime"
@@ -758,7 +759,7 @@
type dischargeTestServer struct {
p security.Principal
impetus []security.DischargeImpetus
- traceid []uniqueid.ID
+ traceid []uniqueid.Id
}
func (s *dischargeTestServer) Discharge(ctx ipc.ServerContext, cav vdl.AnyRep, impetus security.DischargeImpetus) (vdl.AnyRep, error) {
@@ -767,7 +768,7 @@
return nil, fmt.Errorf("discharges not issued")
}
-func (s *dischargeTestServer) Release() ([]security.DischargeImpetus, []uniqueid.ID) {
+func (s *dischargeTestServer) Release() ([]security.DischargeImpetus, []uniqueid.Id) {
impetus, traceid := s.impetus, s.traceid
s.impetus, s.traceid = nil, nil
return impetus, traceid
@@ -1745,6 +1746,10 @@
}
func init() {
- testutil.Init()
vdl.Register(fakeTimeCaveat(0))
}
+
+func TestMain(m *testing.M) {
+ testutil.Init()
+ os.Exit(m.Run())
+}
diff --git a/runtimes/google/ipc/proxy_test.go b/runtimes/google/ipc/proxy_test.go
new file mode 100644
index 0000000..08123c6
--- /dev/null
+++ b/runtimes/google/ipc/proxy_test.go
@@ -0,0 +1,330 @@
+package ipc_test
+
+import (
+ "fmt"
+ "os"
+ "reflect"
+ "sort"
+ "strings"
+ "testing"
+ "time"
+
+ "v.io/core/veyron2/context"
+ "v.io/core/veyron2/ipc"
+ "v.io/core/veyron2/naming"
+ "v.io/core/veyron2/security"
+ verror "v.io/core/veyron2/verror2"
+ "v.io/core/veyron2/vtrace"
+
+ "v.io/core/veyron/lib/expect"
+ "v.io/core/veyron/lib/flags"
+ "v.io/core/veyron/lib/modules"
+ "v.io/core/veyron/lib/modules/core"
+ tsecurity "v.io/core/veyron/lib/testutil/security"
+ _ "v.io/core/veyron/profiles"
+ iipc "v.io/core/veyron/runtimes/google/ipc"
+ imanager "v.io/core/veyron/runtimes/google/ipc/stream/manager"
+ "v.io/core/veyron/runtimes/google/ipc/stream/vc"
+ inaming "v.io/core/veyron/runtimes/google/naming"
+ tnaming "v.io/core/veyron/runtimes/google/testing/mocks/naming"
+ ivtrace "v.io/core/veyron/runtimes/google/vtrace"
+)
+
+func testContext() *context.T {
+ ctx, _ := context.WithTimeout(testContextWithoutDeadline(), 20*time.Second)
+ return ctx
+}
+
+func testContextWithoutDeadline() *context.T {
+ ctx, _ := context.RootContext()
+ ctx, err := ivtrace.Init(ctx, flags.VtraceFlags{})
+ if err != nil {
+ panic(err)
+ }
+ ctx, _ = vtrace.SetNewTrace(ctx)
+ return ctx
+}
+
+type testServer struct{}
+
+func (*testServer) Echo(ctx ipc.ServerContext, arg string) string {
+ return fmt.Sprintf("method:%q,suffix:%q,arg:%q", ctx.Method(), ctx.Suffix(), arg)
+}
+
+type testServerAuthorizer struct{}
+
+func (testServerAuthorizer) Authorize(c security.Context) error {
+ return nil
+}
+
+type testServerDisp struct{ server interface{} }
+
+func (t testServerDisp) Lookup(suffix string) (interface{}, security.Authorizer, error) {
+ return t.server, testServerAuthorizer{}, nil
+}
+
+type proxyHandle struct {
+ ns naming.Namespace
+ sh *modules.Shell
+ proxy modules.Handle
+ name string
+}
+
+func (h *proxyHandle) Start(t *testing.T, ctx *context.T, args ...string) error {
+ sh, err := modules.NewShell(nil, nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
+ h.sh = sh
+ p, err := sh.Start(core.ProxyServerCommand, nil, args...)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
+ h.proxy = p
+ s := expect.NewSession(t, p.Stdout(), time.Minute)
+ s.ReadLine()
+ h.name = s.ExpectVar("PROXY_NAME")
+ if len(h.name) == 0 {
+ t.Fatalf("failed to get PROXY_NAME from proxyd")
+ }
+ return h.ns.Mount(ctx, "proxy", h.name, time.Hour)
+}
+
+func (h *proxyHandle) Stop(ctx *context.T) error {
+ defer h.sh.Cleanup(os.Stderr, os.Stderr)
+ if err := h.proxy.Shutdown(os.Stderr, os.Stderr); err != nil {
+ return err
+ }
+ if len(h.name) == 0 {
+ return nil
+ }
+ return h.ns.Unmount(ctx, "proxy", h.name)
+}
+
+func TestProxyOnly(t *testing.T) {
+ listenSpec := ipc.ListenSpec{Proxy: "proxy"}
+ testProxy(t, listenSpec)
+}
+
+func TestProxy(t *testing.T) {
+ proxyListenSpec := ipc.ListenSpec{Addrs: ipc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
+ proxyListenSpec.Proxy = "proxy"
+ testProxy(t, proxyListenSpec)
+}
+
+func TestWSProxy(t *testing.T) {
+ proxyListenSpec := ipc.ListenSpec{Addrs: ipc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
+ proxyListenSpec.Proxy = "proxy"
+ // The proxy uses websockets only, but the server is using tcp.
+ testProxy(t, proxyListenSpec, "--veyron.tcp.protocol=ws")
+}
+
+func testProxy(t *testing.T, spec ipc.ListenSpec, args ...string) {
+ sm := imanager.InternalNew(naming.FixedRoutingID(0x555555555))
+ defer sm.Shutdown()
+ ns := tnaming.NewSimpleNamespace()
+ client, err := iipc.InternalNewClient(sm, ns, vc.LocalPrincipal{tsecurity.NewPrincipal("client")})
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer client.Close()
+ ctx := testContext()
+ server, err := iipc.InternalNewServer(ctx, sm, ns, nil, vc.LocalPrincipal{tsecurity.NewPrincipal("server")})
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer server.Stop()
+
+ // If no address is specified then we'll only 'listen' via
+ // the proxy.
+ hasLocalListener := len(spec.Addrs) > 0 && len(spec.Addrs[0].Address) != 0
+
+ name := "mountpoint/server/suffix"
+ makeCall := func() (string, error) {
+ ctx, _ := context.WithDeadline(testContext(), time.Now().Add(5*time.Second))
+ // Let's fail fast so that the tests don't take as long to run.
+ call, err := client.StartCall(ctx, name, "Echo", []interface{}{"batman"})
+ if err != nil {
+ // proxy is down, we should return here/.... prepend
+ // the error with a well known string so that we can test for that.
+ return "", fmt.Errorf("RESOLVE: %s", err)
+ }
+ var result string
+ if err = call.Finish(&result); err != nil {
+ return "", err
+ }
+ return result, nil
+ }
+ proxy := &proxyHandle{ns: ns}
+ if err := proxy.Start(t, ctx, args...); err != nil {
+ t.Fatal(err)
+ }
+ defer proxy.Stop(ctx)
+ addrs := verifyMount(t, ctx, ns, spec.Proxy)
+ if len(addrs) != 1 {
+ t.Fatalf("failed to lookup proxy")
+ }
+
+ eps, err := server.Listen(spec)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := server.ServeDispatcher("mountpoint/server", testServerDisp{&testServer{}}); err != nil {
+ t.Fatal(err)
+ }
+
+ // Proxy connections are started asynchronously, so we need to wait..
+ waitForMountTable := func(ch chan int, expect int) {
+ then := time.Now().Add(time.Minute)
+ for {
+ me, err := ns.Resolve(ctx, name)
+ if err == nil && len(me.Servers) == expect {
+ ch <- 1
+ return
+ }
+ if time.Now().After(then) {
+ t.Fatalf("timed out")
+ }
+ time.Sleep(100 * time.Millisecond)
+ }
+ }
+ waitForServerStatus := func(ch chan int, proxy string) {
+ then := time.Now().Add(time.Minute)
+ for {
+ status := server.Status()
+ if len(status.Proxies) == 1 && status.Proxies[0].Proxy == proxy {
+ ch <- 2
+ return
+ }
+ if time.Now().After(then) {
+ t.Fatalf("timed out")
+ }
+ time.Sleep(100 * time.Millisecond)
+ }
+ }
+ proxyEP, _ := naming.SplitAddressName(addrs[0])
+ proxiedEP, err := inaming.NewEndpoint(proxyEP)
+ if err != nil {
+ t.Fatalf("unexpected error for %q: %s", proxyEP, err)
+ }
+ proxiedEP.RID = naming.FixedRoutingID(0x555555555)
+ expectedNames := []string{naming.JoinAddressName(proxiedEP.String(), "suffix")}
+ if hasLocalListener {
+ expectedNames = append(expectedNames, naming.JoinAddressName(eps[0].String(), "suffix"))
+ }
+
+ // Proxy connetions are created asynchronously, so we wait for the
+ // expected number of endpoints to appear for the specified service name.
+ ch := make(chan int, 2)
+ go waitForMountTable(ch, len(expectedNames))
+ go waitForServerStatus(ch, spec.Proxy)
+ select {
+ case <-time.After(time.Minute):
+ t.Fatalf("timedout waiting for two entries in the mount table and server status")
+ case i := <-ch:
+ select {
+ case <-time.After(time.Minute):
+ t.Fatalf("timedout waiting for two entries in the mount table or server status")
+ case j := <-ch:
+ if !((i == 1 && j == 2) || (i == 2 && j == 1)) {
+ t.Fatalf("unexpected return values from waiters")
+ }
+ }
+ }
+
+ status := server.Status()
+ if got, want := status.Proxies[0].Endpoint, proxiedEP; !reflect.DeepEqual(got, want) {
+ t.Fatalf("got %q, want %q", got, want)
+ }
+
+ got := []string{}
+ for _, s := range verifyMount(t, ctx, ns, name) {
+ got = append(got, s)
+ }
+ sort.Strings(got)
+ sort.Strings(expectedNames)
+ if !reflect.DeepEqual(got, expectedNames) {
+ t.Errorf("got %v, want %v", got, expectedNames)
+ }
+
+ if hasLocalListener {
+ // Listen will publish both the local and proxied endpoint with the
+ // mount table, given that we're trying to test the proxy, we remove
+ // the local endpoint from the mount table entry! We have to remove both
+ // the tcp and the websocket address.
+ sep := eps[0].String()
+ ns.Unmount(ctx, "mountpoint/server", sep)
+ }
+
+ addrs = verifyMount(t, ctx, ns, name)
+ if len(addrs) != 1 {
+ t.Fatalf("failed to lookup proxy: addrs %v", addrs)
+ }
+
+ // Proxied endpoint should be published and RPC should succeed (through proxy)
+ const expected = `method:"Echo",suffix:"suffix",arg:"batman"`
+ if result, err := makeCall(); result != expected || err != nil {
+ t.Fatalf("Got (%v, %v) want (%v, nil)", result, err, expected)
+ }
+ // Proxy dies, calls should fail and the name should be unmounted.
+ if err := proxy.Stop(ctx); err != nil {
+ t.Fatal(err)
+ }
+
+ if result, err := makeCall(); err == nil || (!strings.HasPrefix(err.Error(), "RESOLVE") && !strings.Contains(err.Error(), "EOF")) {
+ t.Fatalf(`Got (%v, %v) want ("", "RESOLVE: <err>" or "EOF") as proxy is down`, result, err)
+ }
+
+ for {
+ if _, err := ns.Resolve(ctx, name); err != nil {
+ break
+ }
+ time.Sleep(10 * time.Millisecond)
+ }
+ verifyMountMissing(t, ctx, ns, name)
+
+ status = server.Status()
+ if len(status.Proxies) != 1 || status.Proxies[0].Proxy != spec.Proxy || !verror.Is(status.Proxies[0].Error, verror.NoServers.ID) {
+ t.Fatalf("proxy status is incorrect: %v", status.Proxies)
+ }
+
+ // Proxy restarts, calls should eventually start succeeding.
+ if err := proxy.Start(t, ctx, args...); err != nil {
+ t.Fatal(err)
+ }
+
+ retries := 0
+ for {
+ if result, err := makeCall(); err == nil {
+ if result != expected {
+ t.Errorf("Got (%v, %v) want (%v, nil)", result, err, expected)
+ }
+ break
+ } else {
+ retries++
+ if retries > 10 {
+ t.Fatalf("Failed after 10 attempts: err: %s", err)
+ }
+ }
+ }
+}
+
+func verifyMount(t *testing.T, ctx *context.T, ns naming.Namespace, name string) []string {
+ me, err := ns.Resolve(ctx, name)
+ if err != nil {
+ t.Errorf("%s not found in mounttable", name)
+ return nil
+ }
+ return me.Names()
+}
+
+func verifyMountMissing(t *testing.T, ctx *context.T, ns naming.Namespace, name string) {
+ if me, err := ns.Resolve(ctx, name); err == nil {
+ names := me.Names()
+ t.Errorf("%s not supposed to be found in mounttable; got %d servers instead: %v", name, len(names), names)
+ }
+}
+
+func TestHelperProcess(t *testing.T) {
+ modules.DispatchInTest()
+}
diff --git a/runtimes/google/ipc/resolve_test.go b/runtimes/google/ipc/resolve_test.go
index ece505c..d7b5261 100644
--- a/runtimes/google/ipc/resolve_test.go
+++ b/runtimes/google/ipc/resolve_test.go
@@ -17,7 +17,7 @@
)
func startMT(t *testing.T, sh *modules.Shell) string {
- h, err := sh.Start(core.RootMTCommand, nil, "--", "--veyron.tcp.address=127.0.0.1:0")
+ h, err := sh.Start(core.RootMTCommand, nil, "--veyron.tcp.address=127.0.0.1:0")
if err != nil {
t.Fatalf("unexpected error for root mt: %s", err)
}
diff --git a/runtimes/google/ipc/results_store_test.go b/runtimes/google/ipc/results_store_test.go
index 5c31331..c41bdec 100644
--- a/runtimes/google/ipc/results_store_test.go
+++ b/runtimes/google/ipc/results_store_test.go
@@ -8,8 +8,6 @@
"v.io/core/veyron/lib/testutil"
)
-func init() { testutil.Init() }
-
func randomKeys() []uint64 {
n := (testutil.Rand.Intn(256*10) / 10) + 256
k := make([]uint64, n)
diff --git a/runtimes/google/ipc/server_test.go b/runtimes/google/ipc/server_test.go
index d83367a..728a4bf 100644
--- a/runtimes/google/ipc/server_test.go
+++ b/runtimes/google/ipc/server_test.go
@@ -1,12 +1,9 @@
package ipc
import (
- "fmt"
"net"
- "os"
"reflect"
"sort"
- "strings"
"testing"
"time"
@@ -18,9 +15,6 @@
verror "v.io/core/veyron2/verror2"
"v.io/core/veyron2/vlog"
- "v.io/core/veyron/lib/expect"
- "v.io/core/veyron/lib/modules"
- "v.io/core/veyron/lib/modules/core"
"v.io/core/veyron/lib/netstate"
tsecurity "v.io/core/veyron/lib/testutil/security"
imanager "v.io/core/veyron/runtimes/google/ipc/stream/manager"
@@ -90,252 +84,6 @@
}
}
-type proxyHandle struct {
- ns naming.Namespace
- sh *modules.Shell
- proxy modules.Handle
- name string
-}
-
-func (h *proxyHandle) Start(t *testing.T, args ...string) error {
- sh, err := modules.NewShell(nil, nil)
- if err != nil {
- t.Fatalf("unexpected error: %s", err)
- }
- h.sh = sh
- p, err := sh.Start(core.ProxyServerCommand, nil, args...)
- if err != nil {
- t.Fatalf("unexpected error: %s", err)
- }
- h.proxy = p
- s := expect.NewSession(t, p.Stdout(), time.Minute)
- s.ReadLine()
- h.name = s.ExpectVar("PROXY_NAME")
- if len(h.name) == 0 {
- t.Fatalf("failed to get PROXY_NAME from proxyd")
- }
- return h.ns.Mount(testContext(), "proxy", h.name, time.Hour)
-}
-
-func (h *proxyHandle) Stop() error {
- defer h.sh.Cleanup(os.Stderr, os.Stderr)
- if err := h.proxy.Shutdown(os.Stderr, os.Stderr); err != nil {
- return err
- }
- if len(h.name) == 0 {
- return nil
- }
- return h.ns.Unmount(testContext(), "proxy", h.name)
-}
-
-func TestProxyOnly(t *testing.T) {
- listenSpec := ipc.ListenSpec{Proxy: "proxy"}
- testProxy(t, listenSpec, "--", "--veyron.tcp.address=127.0.0.1:0")
-}
-
-func TestProxy(t *testing.T) {
- proxyListenSpec := listenSpec
- proxyListenSpec.Proxy = "proxy"
- testProxy(t, proxyListenSpec, "--", "--veyron.tcp.address=127.0.0.1:0")
-}
-
-func TestWSProxy(t *testing.T) {
- proxyListenSpec := listenSpec
- proxyListenSpec.Proxy = "proxy"
- // The proxy uses websockets only, but the server is using tcp.
- testProxy(t, proxyListenSpec, "--", "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0")
-}
-
-func testProxy(t *testing.T, spec ipc.ListenSpec, args ...string) {
- sm := imanager.InternalNew(naming.FixedRoutingID(0x555555555))
- defer sm.Shutdown()
- ns := tnaming.NewSimpleNamespace()
- client, err := InternalNewClient(sm, ns, vc.LocalPrincipal{tsecurity.NewPrincipal("client")})
- if err != nil {
- t.Fatal(err)
- }
- defer client.Close()
- ctx := testContext()
- server, err := testInternalNewServer(ctx, sm, ns, vc.LocalPrincipal{tsecurity.NewPrincipal("server")})
- if err != nil {
- t.Fatal(err)
- }
- defer server.Stop()
-
- // If no address is specified then we'll only 'listen' via
- // the proxy.
- hasLocalListener := len(spec.Addrs) > 0 && len(spec.Addrs[0].Address) != 0
-
- name := "mountpoint/server/suffix"
- makeCall := func() (string, error) {
- ctx, _ := context.WithDeadline(testContext(), time.Now().Add(5*time.Second))
- // Let's fail fast so that the tests don't take as long to run.
- call, err := client.StartCall(ctx, name, "Echo", []interface{}{"batman"})
- if err != nil {
- // proxy is down, we should return here/.... prepend
- // the error with a well known string so that we can test for that.
- return "", fmt.Errorf("RESOLVE: %s", err)
- }
- var result string
- if err = call.Finish(&result); err != nil {
- return "", err
- }
- return result, nil
- }
- proxy := &proxyHandle{ns: ns}
- if err := proxy.Start(t, args...); err != nil {
- t.Fatal(err)
- }
- defer proxy.Stop()
- addrs := verifyMount(t, ns, spec.Proxy)
- if len(addrs) != 1 {
- t.Fatalf("failed to lookup proxy")
- }
-
- eps, err := server.Listen(spec)
- if err != nil {
- t.Fatal(err)
- }
- if err := server.ServeDispatcher("mountpoint/server", testServerDisp{&testServer{}}); err != nil {
- t.Fatal(err)
- }
-
- // Proxy connections are started asynchronously, so we need to wait..
- waitForMountTable := func(ch chan int, expect int) {
- then := time.Now().Add(time.Minute)
- for {
- me, err := ns.Resolve(testContext(), name)
- if err == nil && len(me.Servers) == expect {
- ch <- 1
- return
- }
- if time.Now().After(then) {
- t.Fatalf("timed out")
- }
- time.Sleep(100 * time.Millisecond)
- }
- }
- waitForServerStatus := func(ch chan int, proxy string) {
- then := time.Now().Add(time.Minute)
- for {
- status := server.Status()
- if len(status.Proxies) == 1 && status.Proxies[0].Proxy == proxy {
- ch <- 2
- return
- }
- if time.Now().After(then) {
- t.Fatalf("timed out")
- }
- time.Sleep(100 * time.Millisecond)
- }
- }
- proxyEP, _ := naming.SplitAddressName(addrs[0])
- proxiedEP, err := inaming.NewEndpoint(proxyEP)
- if err != nil {
- t.Fatalf("unexpected error for %q: %s", proxyEP, err)
- }
- proxiedEP.RID = naming.FixedRoutingID(0x555555555)
- expectedNames := []string{naming.JoinAddressName(proxiedEP.String(), "suffix")}
- if hasLocalListener {
- expectedNames = append(expectedNames, naming.JoinAddressName(eps[0].String(), "suffix"))
- }
-
- // Proxy connetions are created asynchronously, so we wait for the
- // expected number of endpoints to appear for the specified service name.
- ch := make(chan int, 2)
- go waitForMountTable(ch, len(expectedNames))
- go waitForServerStatus(ch, spec.Proxy)
- select {
- case <-time.After(time.Minute):
- t.Fatalf("timedout waiting for two entries in the mount table and server status")
- case i := <-ch:
- select {
- case <-time.After(time.Minute):
- t.Fatalf("timedout waiting for two entries in the mount table or server status")
- case j := <-ch:
- if !((i == 1 && j == 2) || (i == 2 && j == 1)) {
- t.Fatalf("unexpected return values from waiters")
- }
- }
- }
-
- status := server.Status()
- if got, want := status.Proxies[0].Endpoint, proxiedEP; !reflect.DeepEqual(got, want) {
- t.Fatalf("got %q, want %q", got, want)
- }
-
- got := []string{}
- for _, s := range verifyMount(t, ns, name) {
- got = append(got, s)
- }
- sort.Strings(got)
- sort.Strings(expectedNames)
- if !reflect.DeepEqual(got, expectedNames) {
- t.Errorf("got %v, want %v", got, expectedNames)
- }
-
- if hasLocalListener {
- // Listen will publish both the local and proxied endpoint with the
- // mount table, given that we're trying to test the proxy, we remove
- // the local endpoint from the mount table entry! We have to remove both
- // the tcp and the websocket address.
- sep := eps[0].String()
- ns.Unmount(testContext(), "mountpoint/server", sep)
- }
-
- addrs = verifyMount(t, ns, name)
- if len(addrs) != 1 {
- t.Fatalf("failed to lookup proxy: addrs %v", addrs)
- }
-
- // Proxied endpoint should be published and RPC should succeed (through proxy)
- const expected = `method:"Echo",suffix:"suffix",arg:"batman"`
- if result, err := makeCall(); result != expected || err != nil {
- t.Fatalf("Got (%v, %v) want (%v, nil)", result, err, expected)
- }
- // Proxy dies, calls should fail and the name should be unmounted.
- if err := proxy.Stop(); err != nil {
- t.Fatal(err)
- }
-
- if result, err := makeCall(); err == nil || (!strings.HasPrefix(err.Error(), "RESOLVE") && !strings.Contains(err.Error(), "EOF")) {
- t.Fatalf(`Got (%v, %v) want ("", "RESOLVE: <err>" or "EOF") as proxy is down`, result, err)
- }
-
- for {
- if _, err := ns.Resolve(testContext(), name); err != nil {
- break
- }
- time.Sleep(10 * time.Millisecond)
- }
- verifyMountMissing(t, ns, name)
-
- status = server.Status()
- if len(status.Proxies) != 1 || status.Proxies[0].Proxy != spec.Proxy || !verror.Is(status.Proxies[0].Error, verror.NoServers.ID) {
- t.Fatalf("proxy status is incorrect: %v", status.Proxies)
- }
-
- // Proxy restarts, calls should eventually start succeeding.
- if err := proxy.Start(t, args...); err != nil {
- t.Fatal(err)
- }
-
- retries := 0
- for {
- if result, err := makeCall(); err == nil {
- if result != expected {
- t.Errorf("Got (%v, %v) want (%v, nil)", result, err, expected)
- }
- break
- } else {
- retries++
- if retries > 10 {
- t.Fatalf("Failed after 10 attempts: err: %s", err)
- }
- }
- }
-}
-
func TestServerArgs(t *testing.T) {
sm := imanager.InternalNew(naming.FixedRoutingID(0x555555555))
defer sm.Shutdown()
@@ -382,11 +130,12 @@
}
func TestServerStatus(t *testing.T) {
+ ctx := testContext()
sm := imanager.InternalNew(naming.FixedRoutingID(0x555555555))
defer sm.Shutdown()
ns := tnaming.NewSimpleNamespace()
principal := vc.LocalPrincipal{tsecurity.NewPrincipal("testServerStatus")}
- server, err := testInternalNewServer(testContext(), sm, ns, principal)
+ server, err := testInternalNewServer(ctx, sm, ns, principal)
if err != nil {
t.Fatal(err)
}
@@ -414,12 +163,12 @@
progress := make(chan error)
client, err := InternalNewClient(sm, ns, principal)
- makeCall := func() {
- call, err := client.StartCall(testContext(), "test", "Hang", nil)
+ makeCall := func(ctx *context.T) {
+ call, err := client.StartCall(ctx, "test", "Hang", nil)
progress <- err
progress <- call.Finish()
}
- go makeCall()
+ go makeCall(ctx)
// Wait for RPC to start
if err := <-progress; err != nil {
@@ -473,6 +222,7 @@
sm := imanager.InternalNew(naming.FixedRoutingID(0x555555555))
defer sm.Shutdown()
ns := tnaming.NewSimpleNamespace()
+ ctx := testContext()
expectBadState := func(err error) {
if !verror.Is(err, verror.BadState.ID) {
@@ -486,7 +236,7 @@
}
}
- server, err := testInternalNewServer(testContext(), sm, ns)
+ server, err := testInternalNewServer(ctx, sm, ns)
expectNoError(err)
defer server.Stop()
@@ -873,8 +623,3 @@
}
}
-
-// Required by modules framework.
-func TestHelperProcess(t *testing.T) {
- modules.DispatchInTest()
-}
diff --git a/runtimes/google/ipc/signature_test.go b/runtimes/google/ipc/signature_test.go
index bd54d06..7dcc056 100644
--- a/runtimes/google/ipc/signature_test.go
+++ b/runtimes/google/ipc/signature_test.go
@@ -17,8 +17,6 @@
_ "v.io/core/veyron/profiles"
)
-func init() { testutil.Init() }
-
func startSigServer(ctx *context.T, sig sigImpl) (string, func(), error) {
server, err := veyron2.NewServer(ctx)
if err != nil {
diff --git a/runtimes/google/ipc/stream/benchmark/RESULTS.txt b/runtimes/google/ipc/stream/benchmark/RESULTS.txt
index b60e4ed..85c78ee 100644
--- a/runtimes/google/ipc/stream/benchmark/RESULTS.txt
+++ b/runtimes/google/ipc/stream/benchmark/RESULTS.txt
@@ -1,72 +1,82 @@
-Date: 01/06/2015
+Date: 01/30/2015
Platform: Intel(R) Xeon(R) CPU E5-2689 0 @ 2.60GHz, 66114888KB Memory
$ v23 go test -bench=. -cpu=1 -benchtime=5s \
v.io/core/veyron/runtimes/google/ipc/stream/benchmark
-Benchmark_dial_VIF 500000 15356 ns/op
+Benchmark_dial_VIF 500000 14292 ns/op
--- Histogram (unit: s)
- Count: 500000 Min: 4 Max: 15644 Avg: 14.66
+ Count: 500000 Min: 4 Max: 16455 Avg: 13.58
------------------------------------------------------------
- [ 4, 5) 47181 9.4% 9.4% #
- [ 5, 6) 314973 63.0% 72.4% ######
- [ 6, 9) 123582 24.7% 97.1% ##
- [ 9, 15) 10991 2.2% 99.3%
- [ 15, 28) 2038 0.4% 99.8%
- [ 28, 53) 129 0.0% 99.8%
- [ 53, 100) 53 0.0% 99.8%
- [ 100, 190) 12 0.0% 99.8%
- [ 190, 362) 0 0.0% 99.8%
- [ 362, 690) 1 0.0% 99.8%
- [ 690, 1315) 38 0.0% 99.8%
- [ 1315, 2505) 165 0.0% 99.8%
- [ 2505, 4771) 487 0.1% 99.9%
- [ 4771, 9086) 326 0.1% 100.0%
- [ 9086, 17301) 24 0.0% 100.0%
- [17301, 32941) 0 0.0% 100.0%
- [32941, inf) 0 0.0% 100.0%
-Benchmark_dial_VIF_TLS 500 12681088 ns/op
+ [ 4, 5) 139232 27.8% 27.8% ###
+ [ 5, 6) 257818 51.6% 79.4% #####
+ [ 6, 9) 92644 18.5% 97.9% ##
+ [ 9, 15) 5963 1.2% 99.1%
+ [ 15, 28) 3162 0.6% 99.8%
+ [ 28, 53) 171 0.0% 99.8%
+ [ 53, 101) 67 0.0% 99.8%
+ [ 101, 193) 1 0.0% 99.8%
+ [ 193, 370) 0 0.0% 99.8%
+ [ 370, 708) 0 0.0% 99.8%
+ [ 708, 1354) 57 0.0% 99.8%
+ [ 1354, 2589) 152 0.0% 99.9%
+ [ 2589, 4949) 393 0.1% 99.9%
+ [ 4949, 9457) 322 0.1% 100.0%
+ [ 9457, 18069) 18 0.0% 100.0%
+ [18069, 34520) 0 0.0% 100.0%
+ [34520, inf) 0 0.0% 100.0%
+Benchmark_dial_VIF_TLS 500 12594281 ns/op
--- Histogram (unit: ms)
- Count: 500 Min: 12 Max: 16 Avg: 12.31
+ Count: 500 Min: 12 Max: 14 Avg: 12.31
------------------------------------------------------------
- [ 12, 13) 357 71.4% 71.4% #######
- [ 13, 14) 133 26.6% 98.0% ###
- [ 14, 15) 7 1.4% 99.4%
- [ 15, 16) 2 0.4% 99.8%
- [ 16, inf) 1 0.2% 100.0%
-Benchmark_dial_VC_TLS 500 16224331 ns/op
+ [ 12, 13) 352 70.4% 70.4% #######
+ [ 13, 14) 141 28.2% 98.6% ###
+ [ 14, inf) 7 1.4% 100.0%
+Benchmark_dial_VC_TLS 500 16116072 ns/op
--- Histogram (unit: ms)
- Count: 500 Min: 15 Max: 22 Avg: 15.60
+ Count: 500 Min: 15 Max: 22 Avg: 15.53
------------------------------------------------------------
- [ 15, 16) 279 55.8% 55.8% ######
- [ 16, 17) 152 30.4% 86.2% ###
- [ 17, 18) 62 12.4% 98.6% #
- [ 18, 19) 6 1.2% 99.8%
- [ 19, 20) 0 0.0% 99.8%
+ [ 15, 16) 313 62.6% 62.6% ######
+ [ 16, 17) 121 24.2% 86.8% ##
+ [ 17, 18) 60 12.0% 98.8% #
+ [ 18, 19) 3 0.6% 99.4%
+ [ 19, 20) 2 0.4% 99.8%
[ 20, 21) 0 0.0% 99.8%
[ 21, 23) 1 0.2% 100.0%
[ 23, inf) 0 0.0% 100.0%
-Benchmark_throughput_TCP_1Conn 1000000 10963 ns/op 4669.96 MB/s
-Benchmark_throughput_TCP_2Conns 1000000 9739 ns/op 5257.14 MB/s
-Benchmark_throughput_TCP_4Conns 500000 11896 ns/op 4303.82 MB/s
-Benchmark_throughput_TCP_8Conns 500000 12867 ns/op 3979.12 MB/s
-Benchmark_throughput_Pipe_1Conn 300000 28233 ns/op 1813.43 MB/s
-Benchmark_throughput_Pipe_2Conns 500000 25339 ns/op 2020.60 MB/s
-Benchmark_throughput_Pipe_4Conns 300000 26626 ns/op 1922.90 MB/s
-Benchmark_throughput_Pipe_8Conns 500000 27340 ns/op 1872.67 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_1Flow 200000 32590 ns/op 1571.02 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_2Flow 200000 32731 ns/op 1564.24 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_8Flow 200000 41289 ns/op 1240.03 MB/s
-Benchmark_throughput_Flow_1VIF_2VC_2Flow 200000 33878 ns/op 1511.30 MB/s
-Benchmark_throughput_Flow_1VIF_2VC_8Flow 200000 40923 ns/op 1251.10 MB/s
-Benchmark_throughput_Flow_2VIF_4VC_8Flow 200000 42293 ns/op 1210.60 MB/s
-Benchmark_throughput_TLS_1Conn 20000 426157 ns/op 120.14 MB/s
-Benchmark_throughput_TLS_2Conns 20000 421319 ns/op 121.52 MB/s
-Benchmark_throughput_TLS_4Conns 20000 425284 ns/op 120.39 MB/s
-Benchmark_throughput_TLS_8Conns 20000 426533 ns/op 120.04 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_1FlowTLS 20000 474126 ns/op 107.99 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_2FlowTLS 20000 472005 ns/op 108.47 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_8FlowTLS 20000 484625 ns/op 105.65 MB/s
-Benchmark_throughput_Flow_1VIF_2VC_2FlowTLS 20000 483762 ns/op 105.84 MB/s
-Benchmark_throughput_Flow_1VIF_2VC_8FlowTLS 20000 485164 ns/op 105.53 MB/s
-Benchmark_throughput_Flow_2VIF_4VC_8FlowTLS 20000 493864 ns/op 103.67 MB/s
+Benchmark_throughput_TCP_1Conn 1000000 9197 ns/op 5566.89 MB/s
+Benchmark_throughput_TCP_2Conns 1000000 9083 ns/op 5636.56 MB/s
+Benchmark_throughput_TCP_4Conns 1000000 9855 ns/op 5194.81 MB/s
+Benchmark_throughput_TCP_8Conns 500000 12541 ns/op 4082.43 MB/s
+Benchmark_throughput_WS_1Conn 30000 206804 ns/op 247.58 MB/s
+Benchmark_throughput_WS_2Conns 30000 211842 ns/op 241.69 MB/s
+Benchmark_throughput_WS_4Conns 30000 209994 ns/op 243.82 MB/s
+Benchmark_throughput_WS_8Conns 30000 217110 ns/op 235.83 MB/s
+Benchmark_throughput_WSH_TCP_1Conn 1000000 9322 ns/op 5491.85 MB/s
+Benchmark_throughput_WSH_TCP_2Conns 1000000 9370 ns/op 5463.77 MB/s
+Benchmark_throughput_WSH_TCP_4Conns 1000000 9466 ns/op 5408.50 MB/s
+Benchmark_throughput_WSH_TCP_8Conns 500000 12526 ns/op 4087.22 MB/s
+Benchmark_throughput_WSH_WS_1Conn 30000 207833 ns/op 246.35 MB/s
+Benchmark_throughput_WSH_WS_2Conns 30000 208567 ns/op 245.48 MB/s
+Benchmark_throughput_WSH_WS_4Conns 30000 211562 ns/op 242.01 MB/s
+Benchmark_throughput_WSH_WS_8Conns 30000 216454 ns/op 236.54 MB/s
+Benchmark_throughput_Pipe_1Conn 500000 20169 ns/op 2538.54 MB/s
+Benchmark_throughput_Pipe_2Conns 500000 19935 ns/op 2568.29 MB/s
+Benchmark_throughput_Pipe_4Conns 300000 19893 ns/op 2573.76 MB/s
+Benchmark_throughput_Pipe_8Conns 1000000 20235 ns/op 2530.22 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_1Flow 300000 28014 ns/op 1827.66 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_2Flow 300000 27495 ns/op 1862.09 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_8Flow 200000 35584 ns/op 1438.84 MB/s
+Benchmark_throughput_Flow_1VIF_2VC_2Flow 300000 27665 ns/op 1850.66 MB/s
+Benchmark_throughput_Flow_1VIF_2VC_8Flow 200000 34974 ns/op 1463.94 MB/s
+Benchmark_throughput_Flow_2VIF_4VC_8Flow 200000 37642 ns/op 1360.15 MB/s
+Benchmark_throughput_TLS_1Conn 20000 415149 ns/op 123.33 MB/s
+Benchmark_throughput_TLS_2Conns 20000 416008 ns/op 123.07 MB/s
+Benchmark_throughput_TLS_4Conns 20000 421083 ns/op 121.59 MB/s
+Benchmark_throughput_TLS_8Conns 20000 423079 ns/op 121.02 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_1FlowTLS 20000 466212 ns/op 109.82 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_2FlowTLS 20000 466104 ns/op 109.85 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_8FlowTLS 20000 476604 ns/op 107.43 MB/s
+Benchmark_throughput_Flow_1VIF_2VC_2FlowTLS 20000 466818 ns/op 109.68 MB/s
+Benchmark_throughput_Flow_1VIF_2VC_8FlowTLS 20000 477094 ns/op 107.32 MB/s
+Benchmark_throughput_Flow_2VIF_4VC_8FlowTLS 20000 476370 ns/op 107.48 MB/s
diff --git a/runtimes/google/ipc/stream/benchmark/throughput_test.go b/runtimes/google/ipc/stream/benchmark/throughput_test.go
index 76ad57d..f97b6e9 100644
--- a/runtimes/google/ipc/stream/benchmark/throughput_test.go
+++ b/runtimes/google/ipc/stream/benchmark/throughput_test.go
@@ -7,6 +7,21 @@
func Benchmark_throughput_TCP_4Conns(b *testing.B) { benchmarkTCP(b, 4) }
func Benchmark_throughput_TCP_8Conns(b *testing.B) { benchmarkTCP(b, 8) }
+func Benchmark_throughput_WS_1Conn(b *testing.B) { benchmarkWS(b, 1) }
+func Benchmark_throughput_WS_2Conns(b *testing.B) { benchmarkWS(b, 2) }
+func Benchmark_throughput_WS_4Conns(b *testing.B) { benchmarkWS(b, 4) }
+func Benchmark_throughput_WS_8Conns(b *testing.B) { benchmarkWS(b, 8) }
+
+func Benchmark_throughput_WSH_TCP_1Conn(b *testing.B) { benchmarkWSH(b, "tcp", 1) }
+func Benchmark_throughput_WSH_TCP_2Conns(b *testing.B) { benchmarkWSH(b, "tcp", 2) }
+func Benchmark_throughput_WSH_TCP_4Conns(b *testing.B) { benchmarkWSH(b, "tcp", 4) }
+func Benchmark_throughput_WSH_TCP_8Conns(b *testing.B) { benchmarkWSH(b, "tcp", 8) }
+
+func Benchmark_throughput_WSH_WS_1Conn(b *testing.B) { benchmarkWSH(b, "ws", 1) }
+func Benchmark_throughput_WSH_WS_2Conns(b *testing.B) { benchmarkWSH(b, "ws", 2) }
+func Benchmark_throughput_WSH_WS_4Conns(b *testing.B) { benchmarkWSH(b, "ws", 4) }
+func Benchmark_throughput_WSH_WS_8Conns(b *testing.B) { benchmarkWSH(b, "ws", 8) }
+
func Benchmark_throughput_Pipe_1Conn(b *testing.B) { benchmarkPipe(b, 1) }
func Benchmark_throughput_Pipe_2Conns(b *testing.B) { benchmarkPipe(b, 2) }
func Benchmark_throughput_Pipe_4Conns(b *testing.B) { benchmarkPipe(b, 4) }
diff --git a/runtimes/google/ipc/stream/benchmark/throughput_ws.go b/runtimes/google/ipc/stream/benchmark/throughput_ws.go
new file mode 100644
index 0000000..aa07582
--- /dev/null
+++ b/runtimes/google/ipc/stream/benchmark/throughput_ws.go
@@ -0,0 +1,60 @@
+package benchmark
+
+import (
+ "io"
+ "net"
+ "testing"
+
+ "v.io/core/veyron/lib/websocket"
+)
+
+// benchmarkWS sets up nConns WS connections and measures throughput.
+func benchmarkWS(b *testing.B, nConns int) {
+ rchan := make(chan net.Conn, nConns)
+ wchan := make(chan net.Conn, nConns)
+ ln, err := websocket.Listener("ws", "127.0.0.1:0")
+ if err != nil {
+ b.Fatalf("websocket.Listener failed: %v", err)
+ return
+ }
+ defer ln.Close()
+ // One goroutine to dial nConns connections.
+ go func() {
+ for i := 0; i < nConns; i++ {
+ conn, err := websocket.Dial("ws", ln.Addr().String(), 0)
+ if err != nil {
+ b.Fatalf("websocket.Dial(%q, %q) failed: %v", "ws", ln.Addr(), err)
+ wchan <- nil
+ return
+ }
+ wchan <- conn
+ }
+ close(wchan)
+ }()
+ // One goroutine to accept nConns connections.
+ go func() {
+ for i := 0; i < nConns; i++ {
+ conn, err := ln.Accept()
+ if err != nil {
+ b.Fatalf("Accept failed: %v", err)
+ rchan <- nil
+ return
+ }
+ rchan <- conn
+ }
+ close(rchan)
+ }()
+
+ var readers []io.ReadCloser
+ var writers []io.WriteCloser
+ for r := range rchan {
+ readers = append(readers, r)
+ }
+ for w := range wchan {
+ writers = append(writers, w)
+ }
+ if b.Failed() {
+ return
+ }
+ (&throughputTester{b: b, readers: readers, writers: writers}).Run()
+}
diff --git a/runtimes/google/ipc/stream/benchmark/throughput_wsh.go b/runtimes/google/ipc/stream/benchmark/throughput_wsh.go
new file mode 100644
index 0000000..58066a9
--- /dev/null
+++ b/runtimes/google/ipc/stream/benchmark/throughput_wsh.go
@@ -0,0 +1,75 @@
+package benchmark
+
+import (
+ "io"
+ "net"
+ "testing"
+
+ "v.io/core/veyron/lib/websocket"
+)
+
+// benchmarkWS sets up nConns WS connections and measures throughput.
+func benchmarkWSH(b *testing.B, protocol string, nConns int) {
+ rchan := make(chan net.Conn, nConns)
+ wchan := make(chan net.Conn, nConns)
+ ln, err := websocket.HybridListener("wsh", "127.0.0.1:0")
+ if err != nil {
+ b.Fatalf("websocket.HybridListener failed: %v", err)
+ return
+ }
+ defer ln.Close()
+ // One goroutine to dial nConns connections.
+ go func() {
+ for i := 0; i < nConns; i++ {
+ var conn net.Conn
+ var err error
+ switch protocol {
+ case "tcp":
+ conn, err = net.Dial("tcp", ln.Addr().String())
+ case "ws":
+ conn, err = websocket.Dial("ws", ln.Addr().String(), 0)
+ }
+ if err != nil {
+ b.Fatalf("Dial(%q, %q) failed: %v", protocol, ln.Addr(), err)
+ wchan <- nil
+ return
+ }
+ if protocol == "tcp" {
+ // Write a dummy byte since wsh waits for magic byte forever.
+ conn.Write([]byte("."))
+ }
+ wchan <- conn
+ }
+ close(wchan)
+ }()
+ // One goroutine to accept nConns connections.
+ go func() {
+ for i := 0; i < nConns; i++ {
+ conn, err := ln.Accept()
+ if err != nil {
+ b.Fatalf("Accept failed: %v", err)
+ rchan <- nil
+ return
+ }
+ if protocol == "tcp" {
+ // Read a dummy byte.
+ conn.Read(make([]byte, 1))
+ }
+ rchan <- conn
+ }
+ close(rchan)
+ }()
+
+ var readers []io.ReadCloser
+ var writers []io.WriteCloser
+ for r := range rchan {
+ readers = append(readers, r)
+ }
+ for w := range wchan {
+ writers = append(writers, w)
+ }
+ if b.Failed() {
+ return
+ }
+ (&throughputTester{b: b, readers: readers, writers: writers}).Run()
+}
diff --git a/runtimes/google/ipc/stream/crypto/tls.go b/runtimes/google/ipc/stream/crypto/tls.go
index da35acc..fafa18c 100644
--- a/runtimes/google/ipc/stream/crypto/tls.go
+++ b/runtimes/google/ipc/stream/crypto/tls.go
@@ -166,6 +166,7 @@
}
func (c *tlsCrypter) Decrypt(ciphertext *iobuf.Slice) (*iobuf.Slice, error) {
+ defer ciphertext.Release()
if ciphertext.Size() == 0 {
return ciphertext, nil
}
diff --git a/runtimes/google/ipc/stream/manager/manager.go b/runtimes/google/ipc/stream/manager/manager.go
index f76a522..7b2b05c 100644
--- a/runtimes/google/ipc/stream/manager/manager.go
+++ b/runtimes/google/ipc/stream/manager/manager.go
@@ -138,6 +138,7 @@
if !retry || verror.ErrorID(err) != verror.Aborted {
return vc, err
}
+ vf.Close()
m.vifs.Delete(vf)
vlog.VI(2).Infof("VIF %v is closed, removing from cache", vf)
}
diff --git a/runtimes/google/ipc/stream/manager/manager_test.go b/runtimes/google/ipc/stream/manager/manager_test.go
index e1fb7b4..861b3f4 100644
--- a/runtimes/google/ipc/stream/manager/manager_test.go
+++ b/runtimes/google/ipc/stream/manager/manager_test.go
@@ -555,7 +555,7 @@
func runServer(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
server := InternalNew(naming.FixedRoutingID(0x55555555))
- _, ep, err := server.Listen(args[1], args[2])
+ _, ep, err := server.Listen(args[0], args[1])
if err != nil {
fmt.Fprintln(stderr, err)
return err
diff --git a/runtimes/google/ipc/stream/proxy/proxy.go b/runtimes/google/ipc/stream/proxy/proxy.go
index a498b4b..2b79f97 100644
--- a/runtimes/google/ipc/stream/proxy/proxy.go
+++ b/runtimes/google/ipc/stream/proxy/proxy.go
@@ -46,15 +46,18 @@
// process encapsulates the physical network connection and the routing table
// associated with the process at the other end of the network connection.
type process struct {
- Conn net.Conn
+ proxy *Proxy
+ conn net.Conn
+ pool *iobuf.Pool
+ reader *iobuf.Reader
isSetup bool
ctrlCipher crypto.ControlCipher
- Queue *upcqueue.T
+ queue *upcqueue.T
mu sync.RWMutex
routingTable map[id.VC]*destination
nextVCI id.VC
servers map[id.VC]*vc.VC // servers wishing to be proxied create a VC that terminates at the proxy
- BQ bqueue.T // Flow control for messages sent on behalf of servers.
+ bq bqueue.T // Flow control for messages sent on behalf of servers.
}
// destination is an entry in the routingtable of a process.
@@ -70,6 +73,7 @@
}
func (s *server) RoutingID() naming.RoutingID { return s.VC.RemoteAddr().RoutingID() }
+
func (s *server) Close(err error) {
if vc := s.Process.RemoveServerVC(s.VC.VCI()); vc != nil {
if err != nil {
@@ -80,6 +84,7 @@
s.Process.SendCloseVC(s.VC.VCI(), err)
}
}
+
func (s *server) String() string {
return fmt.Sprintf("RoutingID %v on process %v (VCI:%v Blessings:%v)", s.RoutingID(), s.Process, s.VC.VCI(), s.VC.RemoteBlessings())
}
@@ -102,6 +107,7 @@
proxyLog().Infof("Started proxying server: %v", server)
return nil
}
+
func (m *servermap) Remove(server *server) {
key := server.RoutingID()
m.mu.Lock()
@@ -111,6 +117,7 @@
}
m.mu.Unlock()
}
+
func (m *servermap) Process(rid naming.RoutingID) *process {
m.mu.Lock()
defer m.mu.Unlock()
@@ -119,6 +126,7 @@
}
return nil
}
+
func (m *servermap) List() []string {
m.mu.Lock()
defer m.mu.Unlock()
@@ -168,220 +176,36 @@
}
func (p *Proxy) acceptProcess(conn net.Conn) {
+ pool := iobuf.NewPool(0)
process := &process{
- Conn: conn,
+ proxy: p,
+ conn: conn,
+ pool: pool,
+ reader: iobuf.NewReader(pool, conn),
ctrlCipher: &crypto.NullControlCipher{},
- Queue: upcqueue.New(),
+ queue: upcqueue.New(),
routingTable: make(map[id.VC]*destination),
servers: make(map[id.VC]*vc.VC),
- BQ: drrqueue.New(vc.MaxPayloadSizeBytes),
+ bq: drrqueue.New(vc.MaxPayloadSizeBytes),
}
- go writeLoop(process)
- go serverVCsLoop(process)
- go p.readLoop(process)
-}
-func writeLoop(process *process) {
- defer processLog().Infof("Exited writeLoop for %v", process)
- defer process.Close()
- for {
- item, err := process.Queue.Get(nil)
- if err != nil {
- if err != upcqueue.ErrQueueIsClosed {
- processLog().Infof("upcqueue.Get failed on %v: %v", process, err)
- }
- return
- }
- if err = message.WriteTo(process.Conn, item.(message.T), process.ctrlCipher); err != nil {
- processLog().Infof("message.WriteTo on %v failed: %v", process, err)
- return
- }
- }
-}
-func serverVCsLoop(process *process) {
- for {
- w, bufs, err := process.BQ.Get(nil)
- if err != nil {
- return
- }
- vci, fid := unpackIDs(w.ID())
- if vc := process.ServerVC(vci); vc != nil {
- queueDataMessages(bufs, vc, fid, process.Queue)
- if len(bufs) == 0 {
- m := &message.Data{VCI: vci, Flow: fid}
- m.SetClose()
- process.Queue.Put(m)
- w.Shutdown(true)
- }
- continue
- }
- releaseBufs(0, bufs)
- }
-}
-func releaseBufs(start int, bufs []*iobuf.Slice) {
- for i := start; i < len(bufs); i++ {
- bufs[i].Release()
- }
-}
-func queueDataMessages(bufs []*iobuf.Slice, vc *vc.VC, fid id.Flow, q *upcqueue.T) {
- for ix, b := range bufs {
- m := &message.Data{VCI: vc.VCI(), Flow: fid}
- var err error
- if m.Payload, err = vc.Encrypt(fid, b); err != nil {
- msgLog().Infof("vc.Encrypt failed. VC:%v Flow:%v Error:%v", vc, fid, err)
- releaseBufs(ix+1, bufs)
- return
- }
- if err = q.Put(m); err != nil {
- msgLog().Infof("Failed to enqueue data message %v: %v", m, err)
- m.Release()
- releaseBufs(ix+1, bufs)
- return
- }
- }
-}
-func (p *Proxy) startProcess(process *process) {
p.mu.Lock()
p.processes[process] = struct{}{}
p.mu.Unlock()
+
+ go process.serverVCsLoop()
+ go process.writeLoop()
+ go process.readLoop()
+
processLog().Infof("Started process %v", process)
}
-func (p *Proxy) stopProcess(process *process) {
- process.Close()
+
+func (p *Proxy) removeProcess(process *process) {
p.mu.Lock()
delete(p.processes, process)
p.mu.Unlock()
- processLog().Infof("Stopped process %v", process)
}
-func (p *Proxy) readLoop(process *process) {
- p.startProcess(process)
- defer p.stopProcess(process)
- reader := iobuf.NewReader(iobuf.NewPool(0), process.Conn)
- defer reader.Close()
- for {
- msg, err := message.ReadFrom(reader, process.ctrlCipher)
- if err != nil {
- processLog().Infof("Read on %v failed: %v", process, err)
- return
- }
- msgLog().Infof("Received msg: %T = %v", msg, msg)
- switch m := msg.(type) {
- case *message.Data:
- if vc := process.ServerVC(m.VCI); vc != nil {
- if err := vc.DispatchPayload(m.Flow, m.Payload); err != nil {
- processLog().Infof("Ignoring data message %v from process %v: %v", m, process, err)
- }
- if m.Close() {
- vc.ShutdownFlow(m.Flow)
- }
- break
- }
- srcVCI := m.VCI
- if d := process.Route(srcVCI); d != nil {
- m.VCI = d.VCI
- if err := d.Process.Queue.Put(m); err != nil {
- process.RemoveRoute(srcVCI)
- process.SendCloseVC(srcVCI, fmt.Errorf("proxy failed to forward data message: %v", err))
- }
- break
- }
- process.SendCloseVC(srcVCI, errNoRoutingTableEntry)
- case *message.OpenFlow:
- if vc := process.ServerVC(m.VCI); vc != nil {
- if err := vc.AcceptFlow(m.Flow); err != nil {
- processLog().Infof("OpenFlow %+v on process %v failed: %v", m, process, err)
- cm := &message.Data{VCI: m.VCI, Flow: m.Flow}
- cm.SetClose()
- process.Queue.Put(cm)
- }
- vc.ReleaseCounters(m.Flow, m.InitialCounters)
- break
- }
- srcVCI := m.VCI
- if d := process.Route(srcVCI); d != nil {
- m.VCI = d.VCI
- if err := d.Process.Queue.Put(m); err != nil {
- process.RemoveRoute(srcVCI)
- process.SendCloseVC(srcVCI, fmt.Errorf("proxy failed to forward open flow message: %v", err))
- }
- break
- }
- process.SendCloseVC(srcVCI, errNoRoutingTableEntry)
- case *message.CloseVC:
- if vc := process.RemoveServerVC(m.VCI); vc != nil {
- vc.Close(m.Error)
- break
- }
- srcVCI := m.VCI
- if d := process.Route(srcVCI); d != nil {
- m.VCI = d.VCI
- d.Process.Queue.Put(m)
- d.Process.RemoveRoute(d.VCI)
- }
- process.RemoveRoute(srcVCI)
- case *message.AddReceiveBuffers:
- p.routeCounters(process, m.Counters)
- case *message.OpenVC:
- dstrid := m.DstEndpoint.RoutingID()
- if naming.Compare(dstrid, p.rid) || naming.Compare(dstrid, naming.NullRoutingID) {
- // VC that terminates at the proxy.
- // See protocol.vdl for details on the protocol between the server and the proxy.
- vcObj := process.NewServerVC(m)
- // route counters after creating the VC so counters to vc are not lost.
- p.routeCounters(process, m.Counters)
- if vcObj != nil {
- server := &server{Process: process, VC: vcObj}
- go p.runServer(server, vcObj.HandshakeAcceptedVC(vc.LocalPrincipal{p.principal}))
- }
- break
- }
- dstprocess := p.servers.Process(dstrid)
- if dstprocess == nil {
- process.SendCloseVC(m.VCI, fmt.Errorf("no server with routing id %v is being proxied", dstrid))
- p.routeCounters(process, m.Counters)
- break
- }
- srcVCI := m.VCI
- dstVCI := dstprocess.AllocVCI()
- startRoutingVC(srcVCI, dstVCI, process, dstprocess)
- // Forward the OpenVC message.
- // Typically, an OpenVC message is accompanied with Counters for the new VC.
- // Keep that in the forwarded message and route the remaining counters separately.
- counters := m.Counters
- m.Counters = message.NewCounters()
- for cid, bytes := range counters {
- if cid.VCI() == srcVCI {
- m.Counters.Add(dstVCI, cid.Flow(), bytes)
- delete(counters, cid)
- }
- }
- m.VCI = dstVCI
- dstprocess.Queue.Put(m)
- p.routeCounters(process, counters)
- case *message.HopSetup:
- // Set up the hop. This takes over the process during negotiation.
- if process.isSetup {
- // Already performed authentication. We don't do it again.
- processLog().Infof("Process %v is already setup", process)
- return
- }
- var blessings security.Blessings
- if p.principal != nil {
- blessings = p.principal.BlessingStore().Default()
- }
- c, err := vif.AuthenticateAsServer(process.Conn, nil, p.principal, blessings, nil, m)
- if err != nil {
- processLog().Infof("Process %v failed to authenticate: %s", process, err)
- return
- }
- process.ctrlCipher = c
- process.isSetup = true
- default:
- processLog().Infof("Closing %v because of unrecognized message %T", process, m)
- return
- }
- }
-}
+
func (p *Proxy) runServer(server *server, c <-chan vc.HandshakeResult) {
hr := <-c
if hr.Error != nil {
@@ -439,6 +263,7 @@
// Wait for this flow to be closed.
<-conn.Closed()
}
+
func (p *Proxy) routeCounters(process *process, counters message.Counters) {
// Since each VC can be routed to a different process, split up the
// Counters into one message per VC.
@@ -453,13 +278,14 @@
if d := process.Route(srcVCI); d != nil {
c := message.NewCounters()
c.Add(d.VCI, cid.Flow(), bytes)
- if err := d.Process.Queue.Put(&message.AddReceiveBuffers{Counters: c}); err != nil {
+ if err := d.Process.queue.Put(&message.AddReceiveBuffers{Counters: c}); err != nil {
process.RemoveRoute(srcVCI)
process.SendCloseVC(srcVCI, fmt.Errorf("proxy failed to forward receive buffers: %v", err))
}
}
}
}
+
func startRoutingVC(srcVCI, dstVCI id.VC, srcProcess, dstProcess *process) {
dstProcess.AddRoute(dstVCI, &destination{VCI: srcVCI, Process: srcProcess})
srcProcess.AddRoute(srcVCI, &destination{VCI: dstVCI, Process: dstProcess})
@@ -477,13 +303,210 @@
func (p *Proxy) Shutdown() {
p.ln.Close()
p.mu.Lock()
- defer p.mu.Unlock()
- for process, _ := range p.processes {
+ processes := p.processes
+ p.processes = nil
+ p.mu.Unlock()
+ for process, _ := range processes {
process.Close()
}
}
+
+func (p *process) serverVCsLoop() {
+ for {
+ w, bufs, err := p.bq.Get(nil)
+ if err != nil {
+ return
+ }
+ vci, fid := unpackIDs(w.ID())
+ if vc := p.ServerVC(vci); vc != nil {
+ queueDataMessages(bufs, vc, fid, p.queue)
+ if len(bufs) == 0 {
+ m := &message.Data{VCI: vci, Flow: fid}
+ m.SetClose()
+ p.queue.Put(m)
+ w.Shutdown(true)
+ }
+ continue
+ }
+ releaseBufs(0, bufs)
+ }
+}
+
+func releaseBufs(start int, bufs []*iobuf.Slice) {
+ for _, buf := range bufs[start:] {
+ buf.Release()
+ }
+}
+
+func queueDataMessages(bufs []*iobuf.Slice, vc *vc.VC, fid id.Flow, q *upcqueue.T) {
+ for ix, b := range bufs {
+ m := &message.Data{VCI: vc.VCI(), Flow: fid}
+ var err error
+ if m.Payload, err = vc.Encrypt(fid, b); err != nil {
+ msgLog().Infof("vc.Encrypt failed. VC:%v Flow:%v Error:%v", vc, fid, err)
+ releaseBufs(ix+1, bufs)
+ return
+ }
+ if err = q.Put(m); err != nil {
+ msgLog().Infof("Failed to enqueue data message %v: %v", m, err)
+ m.Release()
+ releaseBufs(ix+1, bufs)
+ return
+ }
+ }
+}
+
+func (p *process) writeLoop() {
+ defer processLog().Infof("Exited writeLoop for %v", p)
+ defer p.Close()
+
+ for {
+ item, err := p.queue.Get(nil)
+ if err != nil {
+ if err != upcqueue.ErrQueueIsClosed {
+ processLog().Infof("upcqueue.Get failed on %v: %v", p, err)
+ }
+ return
+ }
+ if err = message.WriteTo(p.conn, item.(message.T), p.ctrlCipher); err != nil {
+ processLog().Infof("message.WriteTo on %v failed: %v", p, err)
+ return
+ }
+ }
+}
+
+func (p *process) readLoop() {
+ defer processLog().Infof("Exited readLoop for %v", p)
+ defer p.Close()
+
+ for {
+ msg, err := message.ReadFrom(p.reader, p.ctrlCipher)
+ if err != nil {
+ processLog().Infof("Read on %v failed: %v", p, err)
+ return
+ }
+ msgLog().Infof("Received msg: %T = %v", msg, msg)
+ switch m := msg.(type) {
+ case *message.Data:
+ if vc := p.ServerVC(m.VCI); vc != nil {
+ if err := vc.DispatchPayload(m.Flow, m.Payload); err != nil {
+ processLog().Infof("Ignoring data message %v from process %v: %v", m, p, err)
+ }
+ if m.Close() {
+ vc.ShutdownFlow(m.Flow)
+ }
+ break
+ }
+ srcVCI := m.VCI
+ if d := p.Route(srcVCI); d != nil {
+ m.VCI = d.VCI
+ if err := d.Process.queue.Put(m); err != nil {
+ m.Release()
+ p.RemoveRoute(srcVCI)
+ p.SendCloseVC(srcVCI, fmt.Errorf("proxy failed to forward data message: %v", err))
+ }
+ break
+ }
+ p.SendCloseVC(srcVCI, errNoRoutingTableEntry)
+ case *message.OpenFlow:
+ if vc := p.ServerVC(m.VCI); vc != nil {
+ if err := vc.AcceptFlow(m.Flow); err != nil {
+ processLog().Infof("OpenFlow %+v on process %v failed: %v", m, p, err)
+ cm := &message.Data{VCI: m.VCI, Flow: m.Flow}
+ cm.SetClose()
+ p.queue.Put(cm)
+ }
+ vc.ReleaseCounters(m.Flow, m.InitialCounters)
+ break
+ }
+ srcVCI := m.VCI
+ if d := p.Route(srcVCI); d != nil {
+ m.VCI = d.VCI
+ if err := d.Process.queue.Put(m); err != nil {
+ p.RemoveRoute(srcVCI)
+ p.SendCloseVC(srcVCI, fmt.Errorf("proxy failed to forward open flow message: %v", err))
+ }
+ break
+ }
+ p.SendCloseVC(srcVCI, errNoRoutingTableEntry)
+ case *message.CloseVC:
+ if vc := p.RemoveServerVC(m.VCI); vc != nil {
+ vc.Close(m.Error)
+ break
+ }
+ srcVCI := m.VCI
+ if d := p.Route(srcVCI); d != nil {
+ m.VCI = d.VCI
+ d.Process.queue.Put(m)
+ d.Process.RemoveRoute(d.VCI)
+ }
+ p.RemoveRoute(srcVCI)
+ case *message.AddReceiveBuffers:
+ p.proxy.routeCounters(p, m.Counters)
+ case *message.OpenVC:
+ dstrid := m.DstEndpoint.RoutingID()
+ if naming.Compare(dstrid, p.proxy.rid) || naming.Compare(dstrid, naming.NullRoutingID) {
+ // VC that terminates at the proxy.
+ // See protocol.vdl for details on the protocol between the server and the proxy.
+ vcObj := p.NewServerVC(m)
+ // route counters after creating the VC so counters to vc are not lost.
+ p.proxy.routeCounters(p, m.Counters)
+ if vcObj != nil {
+ server := &server{Process: p, VC: vcObj}
+ go p.proxy.runServer(server, vcObj.HandshakeAcceptedVC(vc.LocalPrincipal{p.proxy.principal}))
+ }
+ break
+ }
+ dstprocess := p.proxy.servers.Process(dstrid)
+ if dstprocess == nil {
+ p.SendCloseVC(m.VCI, fmt.Errorf("no server with routing id %v is being proxied", dstrid))
+ p.proxy.routeCounters(p, m.Counters)
+ break
+ }
+ srcVCI := m.VCI
+ dstVCI := dstprocess.AllocVCI()
+ startRoutingVC(srcVCI, dstVCI, p, dstprocess)
+ // Forward the OpenVC message.
+ // Typically, an OpenVC message is accompanied with Counters for the new VC.
+ // Keep that in the forwarded message and route the remaining counters separately.
+ counters := m.Counters
+ m.Counters = message.NewCounters()
+ for cid, bytes := range counters {
+ if cid.VCI() == srcVCI {
+ m.Counters.Add(dstVCI, cid.Flow(), bytes)
+ delete(counters, cid)
+ }
+ }
+ m.VCI = dstVCI
+ dstprocess.queue.Put(m)
+ p.proxy.routeCounters(p, counters)
+ case *message.HopSetup:
+ // Set up the hop. This takes over the process during negotiation.
+ if p.isSetup {
+ // Already performed authentication. We don't do it again.
+ processLog().Infof("Process %v is already setup", p)
+ return
+ }
+ var blessings security.Blessings
+ if p.proxy.principal != nil {
+ blessings = p.proxy.principal.BlessingStore().Default()
+ }
+ c, err := vif.AuthenticateAsServer(p.conn, p.reader, nil, p.proxy.principal, blessings, nil, m)
+ if err != nil {
+ processLog().Infof("Process %v failed to authenticate: %s", p, err)
+ return
+ }
+ p.ctrlCipher = c
+ p.isSetup = true
+ default:
+ processLog().Infof("Closing %v because of unrecognized message %T", p, m)
+ return
+ }
+ }
+}
+
func (p *process) String() string {
- r := p.Conn.RemoteAddr()
+ r := p.conn.RemoteAddr()
return fmt.Sprintf("(%s, %s)", r.Network(), r)
}
func (p *process) Route(vci id.VC) *destination {
@@ -520,10 +543,15 @@
if err != nil {
estr = err.Error()
}
- p.Queue.Put(&message.CloseVC{VCI: vci, Error: estr})
+ p.queue.Put(&message.CloseVC{VCI: vci, Error: estr})
}
+
func (p *process) Close() {
p.mu.Lock()
+ if p.routingTable == nil {
+ p.mu.Unlock()
+ return
+ }
rt := p.routingTable
p.routingTable = nil
for _, vc := range p.servers {
@@ -533,15 +561,19 @@
for _, d := range rt {
d.Process.SendCloseVC(d.VCI, errProcessVanished)
}
- p.BQ.Close()
- p.Queue.Close()
- p.Conn.Close()
+ p.bq.Close()
+ p.queue.Close()
+ p.conn.Close()
+
+ p.proxy.removeProcess(p)
}
+
func (p *process) ServerVC(vci id.VC) *vc.VC {
p.mu.Lock()
defer p.mu.Unlock()
return p.servers[vci]
}
+
func (p *process) NewServerVC(m *message.OpenVC) *vc.VC {
p.mu.Lock()
defer p.mu.Unlock()
@@ -558,7 +590,7 @@
VCI: m.VCI,
LocalEP: m.DstEndpoint,
RemoteEP: m.SrcEndpoint,
- Pool: iobuf.NewPool(0),
+ Pool: p.pool,
ReserveBytes: message.HeaderSizeBytes,
Helper: p,
Version: version,
@@ -567,6 +599,7 @@
proxyLog().Infof("Registered VC %v from server on process %v", vc, p)
return vc
}
+
func (p *process) RemoveServerVC(vci id.VC) *vc.VC {
p.mu.Lock()
defer p.mu.Unlock()
@@ -581,22 +614,24 @@
// Make process implement vc.Helper
func (p *process) NotifyOfNewFlow(vci id.VC, fid id.Flow, bytes uint) {
msg := &message.OpenFlow{VCI: vci, Flow: fid, InitialCounters: uint32(bytes)}
- if err := p.Queue.Put(msg); err != nil {
+ if err := p.queue.Put(msg); err != nil {
processLog().Infof("Failed to send OpenFlow(%+v) on process %v: %v", msg, p, err)
}
}
+
func (p *process) AddReceiveBuffers(vci id.VC, fid id.Flow, bytes uint) {
if bytes == 0 {
return
}
msg := &message.AddReceiveBuffers{Counters: message.NewCounters()}
msg.Counters.Add(vci, fid, uint32(bytes))
- if err := p.Queue.Put(msg); err != nil {
+ if err := p.queue.Put(msg); err != nil {
processLog().Infof("Failed to send AddReceiveBuffers(%+v) on process %v: %v", msg, p, err)
}
}
+
func (p *process) NewWriter(vci id.VC, fid id.Flow) (bqueue.Writer, error) {
- return p.BQ.NewWriter(packIDs(vci, fid), 0, vc.DefaultBytesBufferedPerFlow)
+ return p.bq.NewWriter(packIDs(vci, fid), 0, vc.DefaultBytesBufferedPerFlow)
}
// Convenience functions to assist with the logging convention.
diff --git a/runtimes/google/ipc/stream/proxy/proxy_test.go b/runtimes/google/ipc/stream/proxy/proxy_test.go
index 8fd3b8c..9d23ab4 100644
--- a/runtimes/google/ipc/stream/proxy/proxy_test.go
+++ b/runtimes/google/ipc/stream/proxy/proxy_test.go
@@ -4,6 +4,7 @@
"bytes"
"fmt"
"io"
+ "os"
"reflect"
"strings"
"testing"
@@ -19,7 +20,10 @@
"v.io/core/veyron/runtimes/google/ipc/stream/vc"
)
-func init() { testutil.Init() }
+func TestMain(m *testing.M) {
+ testutil.Init()
+ os.Exit(m.Run())
+}
func TestProxy(t *testing.T) {
proxy, err := proxy.New(naming.FixedRoutingID(0xbbbbbbbbbbbbbbbb), nil, "tcp", "127.0.0.1:0", "")
diff --git a/runtimes/google/ipc/stream/vc/vc.go b/runtimes/google/ipc/stream/vc/vc.go
index d273830..d690fef 100644
--- a/runtimes/google/ipc/stream/vc/vc.go
+++ b/runtimes/google/ipc/stream/vc/vc.go
@@ -101,7 +101,7 @@
LocalEP naming.Endpoint // Endpoint of the local end of the VC.
RemoteEP naming.Endpoint // Endpoint of the remote end of the VC.
Pool *iobuf.Pool // Byte pool used for read and write buffer allocations.
- ReserveBytes uint // Number of bytes to reserve in iobuf.Slices.
+ ReserveBytes uint // Number of padding bytes to reserve for headers.
Helper Helper
Version version.IPCVersion
}
@@ -345,8 +345,8 @@
vc.flowMap = nil
if vc.listener != nil {
vc.listener.Close()
+ vc.listener = nil
}
- vc.listener = nil
vc.closeReason = reason
vc.mu.Unlock()
diff --git a/runtimes/google/ipc/stream/vc/vc_test.go b/runtimes/google/ipc/stream/vc/vc_test.go
index aa6e129..05f4edd 100644
--- a/runtimes/google/ipc/stream/vc/vc_test.go
+++ b/runtimes/google/ipc/stream/vc/vc_test.go
@@ -7,6 +7,7 @@
"fmt"
"io"
"net"
+ "os"
"reflect"
"runtime"
"strings"
@@ -29,7 +30,10 @@
"v.io/core/veyron2/security"
)
-func init() { testutil.Init() }
+func TestMain(m *testing.M) {
+ testutil.Init()
+ os.Exit(m.Run())
+}
const (
// Convenience alias to avoid conflicts between the package name "vc" and variables called "vc".
diff --git a/runtimes/google/ipc/stream/vif/auth.go b/runtimes/google/ipc/stream/vif/auth.go
index db659c2..312c3a6 100644
--- a/runtimes/google/ipc/stream/vif/auth.go
+++ b/runtimes/google/ipc/stream/vif/auth.go
@@ -5,7 +5,6 @@
"errors"
"fmt"
"io"
- "net"
"golang.org/x/crypto/nacl/box"
@@ -61,7 +60,7 @@
// including a hash of the HopSetup message in the encrypted stream. It is
// likely that this will be addressed in subsequent protocol versions (or it may
// not be addressed at all if IPCVersion6 becomes the only supported version).
-func AuthenticateAsClient(ctx *context.T, conn net.Conn, versions *version.Range, principal security.Principal, dc vc.DischargeClient) (crypto.ControlCipher, error) {
+func AuthenticateAsClient(ctx *context.T, writer io.Writer, reader *iobuf.Reader, versions *version.Range, principal security.Principal, dc vc.DischargeClient) (crypto.ControlCipher, error) {
if versions == nil {
versions = version.SupportedRange
}
@@ -82,13 +81,11 @@
if err != nil {
return nil, err
}
- if err := message.WriteTo(conn, &pub, nullCipher); err != nil {
+ if err := message.WriteTo(writer, &pub, nullCipher); err != nil {
return nil, err
}
// Read the server's public data.
- pool := iobuf.NewPool(0)
- reader := iobuf.NewReader(pool, conn)
pmsg, err := message.ReadFrom(reader, nullCipher)
if err != nil {
return nil, err
@@ -111,7 +108,7 @@
// Perform the authentication.
switch v {
case ipcversion.IPCVersion6:
- return authenticateAsClientIPC6(ctx, conn, reader, principal, dc, &pvt, &pub, ppub)
+ return authenticateAsClientIPC6(ctx, writer, reader, principal, dc, &pvt, &pub, ppub)
default:
return nil, errUnsupportedEncryptVersion
}
@@ -137,7 +134,7 @@
// based on the max common version.
//
// See AuthenticateAsClient for a description of the negotiation.
-func AuthenticateAsServer(conn net.Conn, versions *version.Range, principal security.Principal, lBlessings security.Blessings,
+func AuthenticateAsServer(writer io.Writer, reader *iobuf.Reader, versions *version.Range, principal security.Principal, lBlessings security.Blessings,
dc vc.DischargeClient, ppub *message.HopSetup) (crypto.ControlCipher, error) {
var err error
if versions == nil {
@@ -156,7 +153,7 @@
if err != nil {
return nil, err
}
- if err := message.WriteTo(conn, &pub, nullCipher); err != nil {
+ if err := message.WriteTo(writer, &pub, nullCipher); err != nil {
return nil, err
}
@@ -173,22 +170,20 @@
// Perform authentication.
switch v {
case ipcversion.IPCVersion6:
- return authenticateAsServerIPC6(conn, principal, lBlessings, dc, &pvt, &pub, ppub)
+ return authenticateAsServerIPC6(writer, reader, principal, lBlessings, dc, &pvt, &pub, ppub)
default:
return nil, errUnsupportedEncryptVersion
}
}
-func authenticateAsServerIPC6(conn net.Conn, principal security.Principal, lBlessings security.Blessings, dc vc.DischargeClient,
+func authenticateAsServerIPC6(writer io.Writer, reader *iobuf.Reader, principal security.Principal, lBlessings security.Blessings, dc vc.DischargeClient,
pvt *privateData, pub, ppub *message.HopSetup) (crypto.ControlCipher, error) {
box := ppub.NaclBox()
if box == nil {
return nil, errVersionNegotiationFailed
}
c := crypto.NewControlCipherIPC6(&box.PublicKey, &pvt.naclBoxPrivateKey, true)
- pool := iobuf.NewPool(0)
- reader := iobuf.NewReader(pool, conn)
- sconn := newSetupConn(conn, reader, c)
+ sconn := newSetupConn(writer, reader, c)
// TODO(jyh): act upon authentication results.
_, _, err := vc.AuthenticateAsServer(sconn, principal, lBlessings, dc, crypto.NewNullCrypter(), ipcversion.IPCVersion6)
if err != nil {
diff --git a/runtimes/google/ipc/stream/vif/vif.go b/runtimes/google/ipc/stream/vif/vif.go
index 3b51d61..1e5294e 100644
--- a/runtimes/google/ipc/stream/vif/vif.go
+++ b/runtimes/google/ipc/stream/vif/vif.go
@@ -37,8 +37,10 @@
// single physical interface, multiple Virtual Circuits (VCs) can be
// established over a single VIF.
type VIF struct {
+ // All reads must be performed through reader, and not directly through conn.
conn net.Conn
pool *iobuf.Pool
+ reader *iobuf.Reader
localEP naming.Endpoint
// control channel encryption.
@@ -72,6 +74,9 @@
// actually supported by this IPC implementation (which is always
// what you want outside of tests).
versions *version.Range
+
+ isClosedMu sync.Mutex
+ isClosed bool // GUARDED_BY(isClosedMu)
}
// ConnectorAndFlow represents a Flow and the Connector that can be used to
@@ -118,11 +123,13 @@
span.Annotatef("(%v, %v)", conn.RemoteAddr().Network(), conn.RemoteAddr())
defer span.Finish()
}
- c, err := AuthenticateAsClient(ctx, conn, versions, principal, dc)
+ pool := iobuf.NewPool(0)
+ reader := iobuf.NewReader(pool, conn)
+ c, err := AuthenticateAsClient(ctx, conn, reader, versions, principal, dc)
if err != nil {
return nil, err
}
- return internalNew(conn, rid, id.VC(vc.NumReservedVCs), versions, nil, nil, c)
+ return internalNew(conn, pool, reader, rid, id.VC(vc.NumReservedVCs), versions, nil, nil, c)
}
// InternalNewAcceptedVIF creates a new virtual interface over the provided
@@ -136,11 +143,12 @@
// placed inside veyron/runtimes/google. Code outside the
// veyron/runtimes/google/* packages should never call this method.
func InternalNewAcceptedVIF(conn net.Conn, rid naming.RoutingID, versions *version.Range, lopts ...stream.ListenerOpt) (*VIF, error) {
- var nc crypto.NullControlCipher
- return internalNew(conn, rid, id.VC(vc.NumReservedVCs)+1, versions, upcqueue.New(), lopts, &nc)
+ pool := iobuf.NewPool(0)
+ reader := iobuf.NewReader(pool, conn)
+ return internalNew(conn, pool, reader, rid, id.VC(vc.NumReservedVCs)+1, versions, upcqueue.New(), lopts, &crypto.NullControlCipher{})
}
-func internalNew(conn net.Conn, rid naming.RoutingID, initialVCI id.VC, versions *version.Range, acceptor *upcqueue.T, listenerOpts []stream.ListenerOpt, c crypto.ControlCipher) (*VIF, error) {
+func internalNew(conn net.Conn, pool *iobuf.Pool, reader *iobuf.Reader, rid naming.RoutingID, initialVCI id.VC, versions *version.Range, acceptor *upcqueue.T, listenerOpts []stream.ListenerOpt, c crypto.ControlCipher) (*VIF, error) {
// Some cloud providers (like Google Compute Engine) seem to blackhole
// inactive TCP connections, set a TCP keep alive to prevent that.
// See: https://developers.google.com/compute/docs/troubleshooting#communicatewithinternet
@@ -187,7 +195,8 @@
}
vif := &VIF{
conn: conn,
- pool: iobuf.NewPool(0),
+ pool: pool,
+ reader: reader,
ctrlCipher: c,
vcMap: newVCMap(),
acceptor: acceptor,
@@ -238,6 +247,14 @@
// underlying network connection after draining all pending writes on those
// VCs.
func (vif *VIF) Close() {
+ vif.isClosedMu.Lock()
+ if vif.isClosed {
+ vif.isClosedMu.Unlock()
+ return
+ }
+ vif.isClosed = true
+ vif.isClosedMu.Unlock()
+
vlog.VI(1).Infof("Closing VIF %s", vif)
// Stop accepting new VCs.
vif.StopAccepting()
@@ -323,14 +340,12 @@
func (vif *VIF) readLoop() {
defer vif.Close()
- reader := iobuf.NewReader(vif.pool, vif.conn)
- defer reader.Close()
defer vif.stopVCDispatchLoops()
for {
// vif.ctrlCipher is guarded by vif.writeMu. However, the only mutation
// to it is in handleMessage, which runs in the same goroutine, so a
// lock is not required here.
- msg, err := message.ReadFrom(reader, vif.ctrlCipher)
+ msg, err := message.ReadFrom(vif.reader, vif.ctrlCipher)
if err != nil {
vlog.VI(1).Infof("Exiting readLoop of VIF %s because of read error: %v", vif, err)
return
@@ -420,7 +435,7 @@
return errVersionNegotiationFailed
}
vif.writeMu.Lock()
- c, err := AuthenticateAsServer(vif.conn, vif.versions, principal, lBlessings, dischargeClient, m)
+ c, err := AuthenticateAsServer(vif.conn, vif.reader, vif.versions, principal, lBlessings, dischargeClient, m)
if err != nil {
vif.writeMu.Unlock()
return err
@@ -520,7 +535,7 @@
case vif.expressQ:
for _, b := range bufs {
if err := vif.writeSerializedMessage(b.Contents); err != nil {
- vlog.Errorf("Exiting writeLoop of VIF %s because Control message write failed: %s", vif, err)
+ vlog.VI(1).Infof("Exiting writeLoop of VIF %s because Control message write failed: %s", vif, err)
releaseBufs(bufs)
return
}
@@ -792,6 +807,9 @@
}
// Methods and type that implement vc.Helper
+//
+// We create a separate type for vc.Helper to hide the vc.Helper methods
+// from the exported method set of VIF.
type vcHelper struct{ vif *VIF }
func (h vcHelper) NotifyOfNewFlow(vci id.VC, fid id.Flow, bytes uint) {
diff --git a/runtimes/google/ipc/stream/vif/vif_test.go b/runtimes/google/ipc/stream/vif/vif_test.go
index edffeba..232f985 100644
--- a/runtimes/google/ipc/stream/vif/vif_test.go
+++ b/runtimes/google/ipc/stream/vif/vif_test.go
@@ -9,6 +9,7 @@
"fmt"
"io"
"net"
+ "os"
"reflect"
"runtime"
"sort"
@@ -27,7 +28,10 @@
"v.io/core/veyron2/naming"
)
-func init() { testutil.Init() }
+func TestMain(m *testing.M) {
+ testutil.Init()
+ os.Exit(m.Run())
+}
func newPrincipal(defaultBlessing string) vc.LocalPrincipal {
return vc.LocalPrincipal{tsecurity.NewPrincipal("defaultBlessing")}
@@ -261,10 +265,12 @@
if n, err := serverFlow.Read(buf); n != 0 || err == nil {
t.Fatal("Got (%d, %v) = %q, want (0, nil)", n, err, buf[:n])
}
+ server.Close()
}
func TestShutdownVCs(t *testing.T) {
client, server := NewClientServer()
+ defer server.Close()
defer client.Close()
testN := func(N int) error {
diff --git a/runtimes/google/ipc/testutil_test.go b/runtimes/google/ipc/testutil_test.go
index 1011dd6..01f9444 100644
--- a/runtimes/google/ipc/testutil_test.go
+++ b/runtimes/google/ipc/testutil_test.go
@@ -6,12 +6,8 @@
"v.io/core/veyron2/security"
"v.io/core/veyron2/verror2"
-
- "v.io/core/veyron/lib/testutil"
)
-func init() { testutil.Init() }
-
func makeResultPtrs(ins []interface{}) []interface{} {
outs := make([]interface{}, len(ins))
for ix, in := range ins {
diff --git a/runtimes/google/lib/iobuf/allocator.go b/runtimes/google/lib/iobuf/allocator.go
index 7c68de1..4483159 100644
--- a/runtimes/google/lib/iobuf/allocator.go
+++ b/runtimes/google/lib/iobuf/allocator.go
@@ -25,8 +25,7 @@
// contiguous iobuf. This can be used to reverse space for a header, for
// example.
func NewAllocator(pool *Pool, reserve uint) *Allocator {
- iobuf := pool.alloc(reserve)
- return &Allocator{pool: pool, reserve: reserve, index: reserve, iobuf: iobuf}
+ return &Allocator{pool: pool, reserve: reserve, index: reserve}
}
// Release releases the allocator.
@@ -34,15 +33,18 @@
if a.iobuf != nil {
a.iobuf.release()
a.iobuf = nil
- a.pool = nil
}
+ a.pool = nil
}
// Alloc allocates a new Slice.
func (a *Allocator) Alloc(bytes uint) *Slice {
if a.iobuf == nil {
- vlog.Info("iobuf.Allocator has already been closed")
- return nil
+ if a.pool == nil {
+ vlog.Info("iobuf.Allocator has already been closed")
+ return nil
+ }
+ a.iobuf = a.pool.alloc(a.reserve + bytes)
}
if uint(len(a.iobuf.Contents))-a.index < bytes {
a.allocIOBUF(bytes)
diff --git a/runtimes/google/lib/iobuf/iobuf.go b/runtimes/google/lib/iobuf/iobuf.go
index 2d55835..918ddba 100644
--- a/runtimes/google/lib/iobuf/iobuf.go
+++ b/runtimes/google/lib/iobuf/iobuf.go
@@ -59,7 +59,14 @@
allocated uint64 // Total number of iobufs allocated.
}
+const defaultMinSize = 1 << 12
+
+// NewPool creates a new pool. The pool will allocate iobufs in multiples of minSize.
+// If minSize is zero, the default value (4K) will be used.
func NewPool(minSize uint) *Pool {
+ if minSize == 0 {
+ minSize = defaultMinSize
+ }
return &Pool{minSize: minSize, freelist: []*buf{}}
}
@@ -72,9 +79,12 @@
// alloc allocates a new iobuf. The returned iobuf has at least <size> bytes of free space.
func (pool *Pool) alloc(size uint) *buf {
- if size < pool.minSize {
+ if size == 0 {
size = pool.minSize
+ } else if r := size % pool.minSize; r > 0 {
+ size += pool.minSize - r
}
+
pool.mutex.Lock()
defer pool.mutex.Unlock()
if pool.freelist == nil {
diff --git a/runtimes/google/rt/rt_test.go b/runtimes/google/rt/rt_test.go
index aaebf45..0935d28 100644
--- a/runtimes/google/rt/rt_test.go
+++ b/runtimes/google/rt/rt_test.go
@@ -151,7 +151,7 @@
if err != nil {
return err
}
- if _, err := sh.Start("principal", nil, args[1:]...); err != nil {
+ if _, err := sh.Start("principal", nil, args...); err != nil {
return err
}
// Cleanup copies the output of sh to these Writers.
diff --git a/runtimes/google/vtrace/store.go b/runtimes/google/vtrace/store.go
index b6ed2de..b3995b5 100644
--- a/runtimes/google/vtrace/store.go
+++ b/runtimes/google/vtrace/store.go
@@ -31,7 +31,7 @@
// of recently used items (the tail is the LRU traceStore).
// TODO(mattr): Use rwmutex.
mu sync.Mutex
- traces map[uniqueid.ID]*traceStore // GUARDED_BY(mu)
+ traces map[uniqueid.Id]*traceStore // GUARDED_BY(mu)
head *traceStore // GUARDED_BY(mu)
}
@@ -51,18 +51,18 @@
return &Store{
opts: opts,
collectRegexp: collectRegexp,
- traces: make(map[uniqueid.ID]*traceStore),
+ traces: make(map[uniqueid.Id]*traceStore),
head: head,
}, nil
}
-func (s *Store) ForceCollect(id uniqueid.ID) {
+func (s *Store) ForceCollect(id uniqueid.Id) {
s.mu.Lock()
s.forceCollectLocked(id)
s.mu.Unlock()
}
-func (s *Store) forceCollectLocked(id uniqueid.ID) *traceStore {
+func (s *Store) forceCollectLocked(id uniqueid.Id) *traceStore {
ts := s.traces[id]
if ts == nil {
ts = newTraceStore(id)
@@ -144,7 +144,7 @@
}
// method returns the collection method for the given trace.
-func (s *Store) method(id uniqueid.ID) vtrace.TraceMethod {
+func (s *Store) method(id uniqueid.Id) vtrace.TraceMethod {
s.mu.Lock()
defer s.mu.Unlock()
if ts := s.traces[id]; ts != nil {
@@ -169,7 +169,7 @@
// TraceRecord returns a TraceRecord for a given ID. Returns
// nil if the given id is not present.
-func (s *Store) TraceRecord(id uniqueid.ID) *vtrace.TraceRecord {
+func (s *Store) TraceRecord(id uniqueid.Id) *vtrace.TraceRecord {
s.mu.Lock()
defer s.mu.Unlock()
out := &vtrace.TraceRecord{}
@@ -181,15 +181,15 @@
}
type traceStore struct {
- id uniqueid.ID
- spans map[uniqueid.ID]*vtrace.SpanRecord
+ id uniqueid.Id
+ spans map[uniqueid.Id]*vtrace.SpanRecord
prev, next *traceStore
}
-func newTraceStore(id uniqueid.ID) *traceStore {
+func newTraceStore(id uniqueid.Id) *traceStore {
return &traceStore{
id: id,
- spans: make(map[uniqueid.ID]*vtrace.SpanRecord),
+ spans: make(map[uniqueid.Id]*vtrace.SpanRecord),
}
}
diff --git a/runtimes/google/vtrace/store_test.go b/runtimes/google/vtrace/store_test.go
index c24d120..ac0cf61 100644
--- a/runtimes/google/vtrace/store_test.go
+++ b/runtimes/google/vtrace/store_test.go
@@ -14,15 +14,15 @@
var nextid = uint64(1)
-func id() uniqueid.ID {
- var out uniqueid.ID
+func id() uniqueid.Id {
+ var out uniqueid.Id
binary.BigEndian.PutUint64(out[8:], nextid)
nextid++
return out
}
-func makeTraces(n int, st *Store) []uniqueid.ID {
- traces := make([]uniqueid.ID, n)
+func makeTraces(n int, st *Store) []uniqueid.Id {
+ traces := make([]uniqueid.Id, n)
for i := range traces {
curid := id()
traces[i] = curid
@@ -31,23 +31,23 @@
return traces
}
-func recordids(records ...vtrace.TraceRecord) map[uniqueid.ID]bool {
- out := make(map[uniqueid.ID]bool)
+func recordids(records ...vtrace.TraceRecord) map[uniqueid.Id]bool {
+ out := make(map[uniqueid.Id]bool)
for _, trace := range records {
out[trace.ID] = true
}
return out
}
-func traceids(traces ...uniqueid.ID) map[uniqueid.ID]bool {
- out := make(map[uniqueid.ID]bool)
+func traceids(traces ...uniqueid.Id) map[uniqueid.Id]bool {
+ out := make(map[uniqueid.Id]bool)
for _, trace := range traces {
out[trace] = true
}
return out
}
-func pretty(in map[uniqueid.ID]bool) []int {
+func pretty(in map[uniqueid.Id]bool) []int {
out := make([]int, 0, len(in))
for k, _ := range in {
out = append(out, int(k[15]))
@@ -56,7 +56,7 @@
return out
}
-func compare(t *testing.T, want map[uniqueid.ID]bool, records []vtrace.TraceRecord) {
+func compare(t *testing.T, want map[uniqueid.Id]bool, records []vtrace.TraceRecord) {
got := recordids(records...)
if !reflect.DeepEqual(want, got) {
t.Errorf("Got wrong traces. Got %v, want %v.", pretty(got), pretty(want))
@@ -92,11 +92,11 @@
}
func TestRegexp(t *testing.T) {
- traces := []uniqueid.ID{id(), id(), id()}
+ traces := []uniqueid.Id{id(), id(), id()}
type testcase struct {
pattern string
- results []uniqueid.ID
+ results []uniqueid.Id
}
tests := []testcase{
{".*", traces},
diff --git a/runtimes/google/vtrace/vtrace.go b/runtimes/google/vtrace/vtrace.go
index a9adefd..528d717 100644
--- a/runtimes/google/vtrace/vtrace.go
+++ b/runtimes/google/vtrace/vtrace.go
@@ -17,15 +17,15 @@
// A span represents an annotated period of time.
type span struct {
- id uniqueid.ID
- parent uniqueid.ID
+ id uniqueid.Id
+ parent uniqueid.Id
name string
- trace uniqueid.ID
+ trace uniqueid.Id
start time.Time
store *Store
}
-func newSpan(parent uniqueid.ID, name string, trace uniqueid.ID, store *Store) *span {
+func newSpan(parent uniqueid.Id, name string, trace uniqueid.Id, store *Store) *span {
id, err := uniqueid.Random()
if err != nil {
vlog.Errorf("vtrace: Couldn't generate Span ID, debug data may be lost: %v", err)
@@ -42,10 +42,10 @@
return s
}
-func (s *span) ID() uniqueid.ID { return s.id }
-func (s *span) Parent() uniqueid.ID { return s.parent }
+func (s *span) ID() uniqueid.Id { return s.id }
+func (s *span) Parent() uniqueid.Id { return s.parent }
func (s *span) Name() string { return s.name }
-func (s *span) Trace() uniqueid.ID { return s.trace }
+func (s *span) Trace() uniqueid.Id { return s.trace }
func (s *span) Annotate(msg string) {
s.store.annotate(s, msg)
}
diff --git a/security/agent/agentd/main.go b/security/agent/agentd/main.go
index ec7babd..fe26023 100644
--- a/security/agent/agentd/main.go
+++ b/security/agent/agentd/main.go
@@ -35,6 +35,10 @@
)
func main() {
+ os.Exit(Main())
+}
+
+func Main() int {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, `Usage: %s [agent options] command command_args...
@@ -45,26 +49,26 @@
`, os.Args[0], consts.VeyronCredentials)
flag.PrintDefaults()
}
- exitCode := 0
- defer func() {
- os.Exit(exitCode)
- }()
flag.Parse()
if len(flag.Args()) < 1 {
fmt.Fprintln(os.Stderr, "Need at least one argument.")
flag.Usage()
- exitCode = 1
- return
+ return 1
}
var restartOpts restartOptions
if err := restartOpts.parse(); err != nil {
fmt.Fprintln(os.Stderr, err)
flag.Usage()
- exitCode = 1
- return
+ return 1
}
- dir := flag.Lookup("veyron.credentials").Value.String()
+ var dir string
+ if f := flag.Lookup("veyron.credentials").Value; true {
+ dir = f.String()
+ // Clear out the flag value to prevent veyron2.Init from
+ // trying to load this password protected principal.
+ f.Set("")
+ }
if len(dir) == 0 {
vlog.Fatalf("The %v environment variable must be set to a directory", consts.VeyronCredentials)
}
@@ -74,6 +78,10 @@
vlog.Fatalf("failed to create new principal from dir(%s): %v", dir, err)
}
+ // Clear out the environment variable before veyron2.Init.
+ if err = os.Setenv(consts.VeyronCredentials, ""); err != nil {
+ vlog.Fatalf("setenv: %v", err)
+ }
ctx, shutdown := veyron2.Init()
defer shutdown()
@@ -84,9 +92,6 @@
if err = os.Setenv(agent.FdVarName, "3"); err != nil {
vlog.Fatalf("setenv: %v", err)
}
- if err = os.Setenv(consts.VeyronCredentials, ""); err != nil {
- vlog.Fatalf("setenv: %v", err)
- }
if *keypath == "" && passphrase != nil {
// If we're done with the passphrase, zero it out so it doesn't stay in memory
@@ -107,6 +112,7 @@
}
}
+ exitCode := 0
for {
// Run the client and wait for it to finish.
cmd := exec.Command(flag.Args()[0], flag.Args()[1:]...)
@@ -148,6 +154,7 @@
// right after cmd.Start().
sock.Close()
mgrSock.Close()
+ return exitCode
}
func newPrincipalFromDir(dir string) (security.Principal, []byte, error) {
diff --git a/security/agent/test.sh b/security/agent/test.sh
index f4aaeba..2d05ccd 100755
--- a/security/agent/test.sh
+++ b/security/agent/test.sh
@@ -21,9 +21,28 @@
shell_test::setup_server_test || shell_test::fail "line ${LINENO} failed to setup server test"
+
+ # Test passphrase use
export VEYRON_CREDENTIALS="$(shell::tmp_dir)"
+ local -r LOG_DIR="$(shell::tmp_dir)"
+ echo -n "agentd: passphrase..."
+ # Create the passphrase
+ echo "PASSWORD" | "${AGENTD_BIN}" echo "Hello" &>"${LOG_DIR}/1" || shell_test::fail "line ${LINENO}: agent failed to create passphrase protected principal: $(cat "${LOG_DIR}/1")"
+ # Use it successfully
+ echo "PASSWORD" | "${AGENTD_BIN}" echo "Hello" &>"${LOG_DIR}/2" || shell_test::fail "line ${LINENO}: agent failed to use passphrase protected principal: $(cat "${LOG_DIR}/2")"
+ # Wrong passphrase should fail
+ echo "BADPASSWORD" | "${AGENTD_BIN}" echo "Hello" &>"${LOG_DIR}/3" && shell_test::fail "line ${LINENO}: agent should have failed with wrong passphrase"
+ local -r NHELLOS="$(grep "Hello" "${LOG_DIR}"/* | wc -l)"
+ if [[ "${NHELLOS}" -ne 2 ]]; then
+ shell_test::fail "line ${LINENO}: expected 2 'Hello's, got "${NHELLOS}" in $(cat "${LOG_DIR}"/*)"
+ fi
+ echo "OK"
+
+
+
# Test all methods of the principal interface.
# (Errors are printed to STDERR)
+ export VEYRON_CREDENTIALS="$(shell::tmp_dir)"
echo -n "agentd: test_principal..."
"${AGENTD_BIN}" "${TESTPRINCIPAL_BIN}" >/dev/null || shell_test::fail "line ${LINENO}"
echo "OK"
diff --git a/services/identity/blesser/oauth.go b/services/identity/blesser/oauth.go
index c11c0e5..504173a 100644
--- a/services/identity/blesser/oauth.go
+++ b/services/identity/blesser/oauth.go
@@ -8,6 +8,7 @@
"v.io/core/veyron/services/identity"
"v.io/core/veyron/services/identity/oauth"
"v.io/core/veyron/services/identity/revocation"
+ "v.io/core/veyron/services/identity/util"
"v.io/core/veyron2/ipc"
"v.io/core/veyron2/security"
@@ -18,7 +19,7 @@
authcodeClient struct{ ID, Secret string }
accessTokenClients []oauth.AccessTokenClient
duration time.Duration
- domain string
+ emailClassifier *util.EmailClassifier
dischargerLocation string
revocationManager revocation.RevocationManager
}
@@ -29,8 +30,8 @@
OAuthProvider oauth.OAuthProvider
// The OAuth client IDs and names for the clients of the BlessUsingAccessToken RPCs.
AccessTokenClients []oauth.AccessTokenClient
- // If non-empty, only email addresses from this domain will be blessed.
- DomainRestriction string
+ // Determines prefixes used for blessing extensions based on email address.
+ EmailClassifier *util.EmailClassifier
// The object name of the discharger service. If this is empty then revocation caveats will not be granted.
DischargerLocation string
// The revocation manager that generates caveats and manages revocation.
@@ -45,13 +46,12 @@
//
// Blessings generated by this service carry a third-party revocation caveat if a
// RevocationManager is specified by the params or they carry an ExpiryCaveat that
-// expires after the duration specified by the params. If domain is non-empty, then
-// blessings are generated only for email addresses from that domain.
+// expires after the duration specified by the params.
func NewOAuthBlesserServer(p OAuthBlesserParams) identity.OAuthBlesserServerStub {
return identity.OAuthBlesserServer(&oauthBlesser{
oauthProvider: p.OAuthProvider,
duration: p.BlessingDuration,
- domain: p.DomainRestriction,
+ emailClassifier: p.EmailClassifier,
dischargerLocation: p.DischargerLocation,
revocationManager: p.RevocationManager,
accessTokenClients: p.AccessTokenClients,
@@ -69,15 +69,6 @@
func (b *oauthBlesser) bless(ctx ipc.ServerContext, email, clientName string) (security.WireBlessings, string, error) {
var noblessings security.WireBlessings
- if len(b.domain) > 0 && !strings.HasSuffix(email, "@"+b.domain) {
- return noblessings, "", fmt.Errorf("domain restrictions preclude blessings for %q", email)
- }
- // Append clientName (e.g., "android", "chrome") to the email and then bless under that.
- // Since blessings issued by this process do not have many caveats on them and typically
- // have a large expiry duration, we include the clientName in the extension so that
- // servers can explicitly distinguish these clients while specifying authorization policies
- // (say, via ACLs).
- extension := email + security.ChainSeparator + clientName
self := ctx.LocalPrincipal()
if self == nil {
return noblessings, "", fmt.Errorf("server error: no authentication happened")
@@ -92,6 +83,16 @@
if err != nil {
return noblessings, "", err
}
+ extension := strings.Join([]string{
+ b.emailClassifier.Classify(email),
+ email,
+ // Append clientName (e.g., "android", "chrome") to the email and then bless under that.
+ // Since blessings issued by this process do not have many caveats on them and typically
+ // have a large expiry duration, we include the clientName in the extension so that
+ // servers can explicitly distinguish these clients while specifying authorization policies
+ // (say, via ACLs).
+ clientName,
+ }, security.ChainSeparator)
blessing, err := self.Bless(ctx.RemoteBlessings().PublicKey(), ctx.LocalBlessings(), extension, caveat)
if err != nil {
return noblessings, "", err
diff --git a/services/identity/blesser/oauth_test.go b/services/identity/blesser/oauth_test.go
index 4b20fd8..12c3edc 100644
--- a/services/identity/blesser/oauth_test.go
+++ b/services/identity/blesser/oauth_test.go
@@ -29,7 +29,7 @@
t.Errorf("BlessUsingAccessToken failed: %v", err)
}
- wantExtension := oauth.MockEmail + security.ChainSeparator + oauth.MockClient
+ wantExtension := "users" + security.ChainSeparator + oauth.MockEmail + security.ChainSeparator + oauth.MockClient
if extension != wantExtension {
t.Errorf("got extension: %s, want: %s", extension, wantExtension)
}
diff --git a/services/identity/identityd/main.go b/services/identity/identityd/main.go
index ebdf5b6..bd1fa92 100644
--- a/services/identity/identityd/main.go
+++ b/services/identity/identityd/main.go
@@ -22,6 +22,7 @@
"v.io/core/veyron/services/identity/oauth"
"v.io/core/veyron/services/identity/revocation"
"v.io/core/veyron/services/identity/server"
+ "v.io/core/veyron/services/identity/util"
)
var (
@@ -32,7 +33,7 @@
googleConfigWeb = flag.String("google_config_web", "", "Path to JSON-encoded OAuth client configuration for the web application that renders the audit log for blessings provided by this provider.")
googleConfigChrome = flag.String("google_config_chrome", "", "Path to the JSON-encoded OAuth client configuration for Chrome browser applications that obtain blessings from this server (via the OAuthBlesser.BlessUsingAccessToken RPC) from this server.")
googleConfigAndroid = flag.String("google_config_android", "", "Path to the JSON-encoded OAuth client configuration for Android applications that obtain blessings from this server (via the OAuthBlesser.BlessUsingAccessToken RPC) from this server.")
- googleDomain = flag.String("google_domain", "", "An optional domain name. When set, only email addresses from this domain are allowed to authenticate via Google OAuth")
+ emailClassifier util.EmailClassifier
// Flags controlling the HTTP server
host = flag.String("host", defaultHost(), "Hostname the HTTP server listens on. This can be the name of the host running the webserver, but if running behind a NAT or load balancer, this should be the host name that clients will connect to. For example, if set to 'x.com', Veyron identities will have the IssuerName set to 'x.com' and clients can expect to find the root name and public key of the signer at 'x.com/blessing-root'.")
@@ -41,6 +42,7 @@
)
func main() {
+ flag.Var(&emailClassifier, "email_classifier", "A comma-separated list of <domain>=<prefix> pairs. For example 'google.com=internal,v.io=trusted'. When specified, then the blessings generated for email address of <domain> will use the extension <prefix>/<email> instead of the default extension of users/<email>.")
flag.Usage = usage
flag.Parse()
@@ -57,7 +59,7 @@
}
}
- googleoauth, err := oauth.NewGoogleOAuth(*googleConfigWeb, *googleDomain)
+ googleoauth, err := oauth.NewGoogleOAuth(*googleConfigWeb)
if err != nil {
vlog.Fatalf("Failed to setup GoogleOAuth: %v", err)
}
@@ -82,7 +84,8 @@
reader,
revocationManager,
googleOAuthBlesserParams(googleoauth, revocationManager),
- caveats.NewBrowserCaveatSelector())
+ caveats.NewBrowserCaveatSelector(),
+ &emailClassifier)
s.Serve(ctx, &listenSpec, *host, *httpaddr, *tlsconfig)
}
@@ -108,7 +111,7 @@
params := blesser.OAuthBlesserParams{
OAuthProvider: oauthProvider,
BlessingDuration: 365 * 24 * time.Hour,
- DomainRestriction: *googleDomain,
+ EmailClassifier: &emailClassifier,
RevocationManager: revocationManager,
}
if clientID, err := getOAuthClientID(*googleConfigChrome); err != nil {
diff --git a/services/identity/identityd_test/main.go b/services/identity/identityd_test/main.go
index d9c8a23..72dfa70 100644
--- a/services/identity/identityd_test/main.go
+++ b/services/identity/identityd_test/main.go
@@ -21,8 +21,6 @@
)
var (
- googleDomain = flag.String("google_domain", "", "An optional domain name. When set, only email addresses from this domain are allowed to authenticate via Google OAuth")
-
// Flags controlling the HTTP server
host = flag.String("host", "localhost", "Hostname the HTTP server listens on. This can be the name of the host running the webserver, but if running behind a NAT or load balancer, this should be the host name that clients will connect to. For example, if set to 'x.com', Veyron identities will have the IssuerName set to 'x.com' and clients can expect to find the root name and public key of the signer at 'x.com/blessing-root'.")
httpaddr = flag.String("httpaddr", "localhost:8125", "Address on which the HTTP server listens on.")
@@ -54,7 +52,6 @@
params := blesser.OAuthBlesserParams{
OAuthProvider: oauthProvider,
BlessingDuration: duration,
- DomainRestriction: *googleDomain,
RevocationManager: revocationManager,
}
@@ -68,7 +65,8 @@
reader,
revocationManager,
params,
- caveats.NewMockCaveatSelector())
+ caveats.NewMockCaveatSelector(),
+ nil)
s.Serve(ctx, &listenSpec, *host, *httpaddr, *tlsconfig)
}
diff --git a/services/identity/oauth/googleoauth.go b/services/identity/oauth/googleoauth.go
index 64baa4e..1cbf32c 100644
--- a/services/identity/oauth/googleoauth.go
+++ b/services/identity/oauth/googleoauth.go
@@ -6,7 +6,6 @@
"fmt"
"net/http"
"os"
- "strings"
"v.io/core/veyron2/vlog"
)
@@ -17,14 +16,13 @@
// Console for API access.
clientID, clientSecret string
scope, authURL, tokenURL string
- domain string
// URL used to verify google tokens.
// (From https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken
// and https://developers.google.com/accounts/docs/OAuth2UserAgent#validatetoken)
verifyURL string
}
-func NewGoogleOAuth(configFile, domainRestriction string) (OAuthProvider, error) {
+func NewGoogleOAuth(configFile string) (OAuthProvider, error) {
clientID, clientSecret, err := getOAuthClientIDAndSecret(configFile)
if err != nil {
return nil, err
@@ -36,7 +34,6 @@
authURL: "https://accounts.google.com/o/oauth2/auth",
tokenURL: "https://accounts.google.com/o/oauth2/token",
verifyURL: "https://www.googleapis.com/oauth2/v1/tokeninfo?",
- domain: domainRestriction,
}, nil
}
@@ -86,10 +83,6 @@
if gtoken.Audience != config.ClientId {
return "", fmt.Errorf("unexpected audience(%v) in GoogleIDToken", gtoken.Audience)
}
- if len(g.domain) > 0 && !strings.HasSuffix(gtoken.Email, "@"+g.domain) {
- return "", fmt.Errorf("domain restrictions preclude %q from using this service", gtoken.Email)
- }
-
return gtoken.Email, nil
}
diff --git a/services/identity/oauth/handler.go b/services/identity/oauth/handler.go
index e341a93..6fd22e1 100644
--- a/services/identity/oauth/handler.go
+++ b/services/identity/oauth/handler.go
@@ -70,8 +70,10 @@
// MacaroonBlessingService is the object name to which macaroons create by this HTTP
// handler can be exchanged for a blessing.
MacaroonBlessingService string
- // If non-empty, only email addressses from this domain will be blessed.
- DomainRestriction string
+ // EmailClassifier is used to decide the prefix used for blessing extensions.
+ // For example, if EmailClassifier.Classify("foo@bar.com") returns "guests",
+ // then the email foo@bar.com will receive the blessing "guests/foo@bar.com".
+ EmailClassifier *util.EmailClassifier
// OAuthProvider is used to authenticate and get a blessee email.
OAuthProvider OAuthProvider
// CaveatSelector is used to obtain caveats from the user when seeking a blessing.
@@ -318,10 +320,6 @@
util.HTTPBadRequest(w, r, err)
return
}
- if len(h.args.DomainRestriction) > 0 && !strings.HasSuffix(email, "@"+h.args.DomainRestriction) {
- util.HTTPBadRequest(w, r, fmt.Errorf("blessings for name %q are not allowed due to domain restriction", email))
- return
- }
outputMacaroon, err := h.csrfCop.NewToken(w, r, clientIDCookie, addCaveatsMacaroon{
ToolRedirectURL: inputMacaroon.RedirectURL,
ToolState: inputMacaroon.State,
@@ -355,9 +353,12 @@
util.HTTPBadRequest(w, r, fmt.Errorf("failed to create caveats: %v", err))
return
}
- name := inputMacaroon.Email
+ parts := []string{
+ h.args.EmailClassifier.Classify(inputMacaroon.Email),
+ inputMacaroon.Email,
+ }
if len(blessingExtension) > 0 {
- name = name + security.ChainSeparator + blessingExtension
+ parts = append(parts, blessingExtension)
}
if len(caveats) == 0 {
util.HTTPBadRequest(w, r, fmt.Errorf("server disallows attempts to bless with no caveats"))
@@ -366,7 +367,7 @@
m := BlessingMacaroon{
Creation: time.Now(),
Caveats: caveats,
- Name: name,
+ Name: strings.Join(parts, security.ChainSeparator),
}
macBytes, err := vom.Encode(m)
if err != nil {
diff --git a/services/identity/server/identityd.go b/services/identity/server/identityd.go
index 1aafdd1..b415f20 100644
--- a/services/identity/server/identityd.go
+++ b/services/identity/server/identityd.go
@@ -26,6 +26,7 @@
"v.io/core/veyron/services/identity/handlers"
"v.io/core/veyron/services/identity/oauth"
"v.io/core/veyron/services/identity/revocation"
+ "v.io/core/veyron/services/identity/util"
services "v.io/core/veyron/services/security"
"v.io/core/veyron/services/security/discharger"
)
@@ -49,6 +50,7 @@
revocationManager revocation.RevocationManager
oauthBlesserParams blesser.OAuthBlesserParams
caveatSelector caveats.CaveatSelector
+ emailClassifier *util.EmailClassifier
}
// NewIdentityServer returns a IdentityServer that:
@@ -56,7 +58,7 @@
// - auditor and blessingLogReader to audit the root principal and read audit logs
// - revocationManager to store revocation data and grant discharges
// - oauthBlesserParams to configure the identity.OAuthBlesser service
-func NewIdentityServer(oauthProvider oauth.OAuthProvider, auditor audit.Auditor, blessingLogReader auditor.BlessingLogReader, revocationManager revocation.RevocationManager, oauthBlesserParams blesser.OAuthBlesserParams, caveatSelector caveats.CaveatSelector) *identityd {
+func NewIdentityServer(oauthProvider oauth.OAuthProvider, auditor audit.Auditor, blessingLogReader auditor.BlessingLogReader, revocationManager revocation.RevocationManager, oauthBlesserParams blesser.OAuthBlesserParams, caveatSelector caveats.CaveatSelector, emailClassifier *util.EmailClassifier) *identityd {
return &identityd{
oauthProvider,
auditor,
@@ -64,6 +66,7 @@
revocationManager,
oauthBlesserParams,
caveatSelector,
+ emailClassifier,
}
}
@@ -107,6 +110,7 @@
MacaroonBlessingService: naming.JoinAddressName(published[0], macaroonService),
OAuthProvider: s.oauthProvider,
CaveatSelector: s.caveatSelector,
+ EmailClassifier: s.emailClassifier,
})
if err != nil {
vlog.Fatalf("Failed to create HTTP handler for oauth authentication: %v", err)
diff --git a/services/identity/util/classify.go b/services/identity/util/classify.go
new file mode 100644
index 0000000..33e2e95
--- /dev/null
+++ b/services/identity/util/classify.go
@@ -0,0 +1,70 @@
+package util
+
+import (
+ "fmt"
+ "strings"
+ "sync"
+)
+
+const defaultClass = "users"
+
+// EmailClassifier classifies/categorizes email addresses based on the domain.
+type EmailClassifier struct {
+ mu sync.RWMutex
+ m map[string]string
+}
+
+// Classify returns the classification of email.
+func (c *EmailClassifier) Classify(email string) string {
+ if c == nil {
+ return defaultClass
+ }
+ parts := strings.Split(email, "@")
+ if len(parts) != 2 {
+ return defaultClass
+ }
+ domain := parts[1]
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+ if class := c.m[domain]; len(class) > 0 {
+ return class
+ }
+ return defaultClass
+}
+
+// Set implements flag.Value.
+//
+// value should be a comma-separated list of <domain>=<class> pairs.
+func (c *EmailClassifier) Set(value string) error {
+ m := make(map[string]string)
+ for _, entry := range strings.Split(value, ",") {
+ pair := strings.Split(entry, "=")
+ if len(pair) != 2 {
+ return fmt.Errorf("invalid pair %q: must be in <domain>=<class> format", entry)
+ }
+ domain := strings.TrimSpace(pair[0])
+ class := strings.TrimSpace(pair[1])
+ if len(domain) == 0 {
+ return fmt.Errorf("empty domain in %q", entry)
+ }
+ if len(class) == 0 {
+ return fmt.Errorf("empty class in %q", entry)
+ }
+ m[domain] = class
+ }
+ c.mu.Lock()
+ c.m = m
+ c.mu.Unlock()
+ return nil
+}
+
+// Get implements flag.Getter.
+func (c *EmailClassifier) Get() interface{} {
+ return c
+}
+
+func (c *EmailClassifier) String() string {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+ return fmt.Sprintf("%v", c.m)
+}
diff --git a/services/identity/util/classify_test.go b/services/identity/util/classify_test.go
new file mode 100644
index 0000000..6077ee4
--- /dev/null
+++ b/services/identity/util/classify_test.go
@@ -0,0 +1,28 @@
+package util
+
+import (
+ "flag"
+ "testing"
+)
+
+func TestEmailClassifier(t *testing.T) {
+ fs := flag.NewFlagSet("TestEmailClassifier", flag.PanicOnError)
+ var c EmailClassifier
+ fs.Var(&c, "myflag", "my usage")
+ if err := fs.Parse([]string{"--myflag", "foo.com=internal,bar.com=external"}); err != nil {
+ t.Fatal(err)
+ }
+ tests := []struct {
+ in, out string
+ }{
+ {"batman@foo.com", "internal"},
+ {"bugsbunny@foo.com.com", "users"},
+ {"daffyduck@bar.com", "external"},
+ {"joker@other.com", "users"},
+ }
+ for _, test := range tests {
+ if got := c.Classify(test.in); got != test.out {
+ t.Errorf("%q: Got %q, want %q", test.in, got, test.out)
+ }
+ }
+}
diff --git a/services/identity/util/sql_config.go b/services/identity/util/sql_config.go
deleted file mode 100644
index f375d63..0000000
--- a/services/identity/util/sql_config.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package util
-
-import (
- "database/sql"
- "fmt"
- _ "github.com/go-sql-driver/mysql"
-)
-
-func DBFromConfigDatabase(database string) (*sql.DB, error) {
- db, err := sql.Open("mysql", database+"?parseTime=true")
- if err != nil {
- return nil, fmt.Errorf("failed to create database with database(%v): %v", database, err)
- }
- if err := db.Ping(); err != nil {
- return nil, err
- }
- return db, nil
-}
diff --git a/services/mgmt/application/impl/acl_test.go b/services/mgmt/application/impl/acl_test.go
index c16dd3f..2f5b710 100644
--- a/services/mgmt/application/impl/acl_test.go
+++ b/services/mgmt/application/impl/acl_test.go
@@ -42,7 +42,6 @@
}
func appRepository(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
- args = args[1:]
if len(args) < 2 {
vlog.Fatalf("repository expected at least name and store arguments and optionally ACL flags per TaggedACLMapFromFlag")
}
@@ -105,11 +104,7 @@
t.Fatal(err)
}
- crDir, crEnv := mgmttest.CredentialsForChild(ctx, "repo")
- defer os.RemoveAll(crDir)
-
- // Make server credentials derived from the test harness.
- _, nms := mgmttest.RunShellCommand(t, sh, crEnv, repoCmd, "repo", storedir)
+ _, nms := mgmttest.RunShellCommand(t, sh, nil, repoCmd, "repo", storedir)
pid := mgmttest.ReadPID(t, nms)
defer syscall.Kill(pid, syscall.SIGINT)
@@ -240,11 +235,7 @@
t.Fatal(err)
}
- crDir, crEnv := mgmttest.CredentialsForChild(ctx, "repo")
- defer os.RemoveAll(crDir)
-
- // Make a server with the same credential as test harness.
- _, nms := mgmttest.RunShellCommand(t, sh, crEnv, repoCmd, "repo", storedir)
+ _, nms := mgmttest.RunShellCommand(t, sh, nil, repoCmd, "repo", storedir)
pid := mgmttest.ReadPID(t, nms)
defer syscall.Kill(pid, syscall.SIGINT)
@@ -373,8 +364,6 @@
if err := idp.Bless(veyron2.GetPrincipal(ctx), "self"); err != nil {
t.Fatal(err)
}
- crDir, crEnv := mgmttest.CredentialsForChild(ctx, "repo")
- defer os.RemoveAll(crDir)
// Make an TAM for use on the command line.
expected := access.TaggedACLMap{
@@ -390,8 +379,7 @@
t.Fatal(err)
}
- // Start a server with the same credential as test harness.
- _, nms := mgmttest.RunShellCommand(t, sh, crEnv, repoCmd, "--veyron.acl.literal", b.String(), "repo", storedir)
+ _, nms := mgmttest.RunShellCommand(t, sh, nil, repoCmd, "--veyron.acl.literal", b.String(), "repo", storedir)
pid := mgmttest.ReadPID(t, nms)
defer syscall.Kill(pid, syscall.SIGINT)
diff --git a/services/mgmt/application/impl/dispatcher.go b/services/mgmt/application/impl/dispatcher.go
index a825137..6b13186 100644
--- a/services/mgmt/application/impl/dispatcher.go
+++ b/services/mgmt/application/impl/dispatcher.go
@@ -39,7 +39,7 @@
// (Re)set the root ACLs.
path := naming.Join("/acls", "data")
_, tag, err := getACL(store, path)
- if !verror.Is(err, ErrNotFound.ID) {
+ if err != nil && !verror.Is(err, ErrNotFound.ID) {
return nil, err
}
if err := setACL(store, path, acls, tag); err != nil {
diff --git a/services/mgmt/binary/impl/acl_test.go b/services/mgmt/binary/impl/acl_test.go
index 67e468b..7f81a0f 100644
--- a/services/mgmt/binary/impl/acl_test.go
+++ b/services/mgmt/binary/impl/acl_test.go
@@ -40,7 +40,6 @@
}
func binaryd(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
- args = args[1:]
if len(args) < 2 {
vlog.Fatalf("binaryd expected at least name and store arguments and optionally ACL flags per TaggedACLMapFromFlag")
}
diff --git a/services/mgmt/device/deviced/server.go b/services/mgmt/device/deviced/server.go
index 33d7919..7362b43 100644
--- a/services/mgmt/device/deviced/server.go
+++ b/services/mgmt/device/deviced/server.go
@@ -6,11 +6,13 @@
"v.io/lib/cmdline"
+ vexec "v.io/core/veyron/lib/exec"
"v.io/core/veyron/lib/signals"
_ "v.io/core/veyron/profiles/roaming"
"v.io/core/veyron/services/mgmt/device/config"
"v.io/core/veyron/services/mgmt/device/impl"
"v.io/core/veyron2"
+ "v.io/core/veyron2/mgmt"
"v.io/core/veyron2/vlog"
)
@@ -25,6 +27,17 @@
ctx, shutdown := veyron2.Init()
defer shutdown()
+ var testMode bool
+ // If this device manager was started by another device manager, it must
+ // be part of a self update to test that this binary works. In that
+ // case, we need to disable a lot of functionality.
+ if handle, err := vexec.GetChildHandle(); err == nil {
+ if _, err := handle.Config.Get(mgmt.ParentNameConfigKey); err == nil {
+ testMode = true
+ vlog.Infof("TEST MODE")
+ }
+ }
+
server, err := veyron2.NewServer(ctx)
if err != nil {
vlog.Errorf("NewServer() failed: %v", err)
@@ -50,16 +63,20 @@
// implementation detail).
var exitErr error
- dispatcher, err := impl.NewDispatcher(veyron2.GetPrincipal(ctx), configState, func() { exitErr = cmdline.ErrExitCode(*restartExitCode) })
+ dispatcher, err := impl.NewDispatcher(veyron2.GetPrincipal(ctx), configState, testMode, func() { exitErr = cmdline.ErrExitCode(*restartExitCode) })
if err != nil {
vlog.Errorf("Failed to create dispatcher: %v", err)
return err
}
- if err := server.ServeDispatcher(*publishAs, dispatcher); err != nil {
- vlog.Errorf("Serve(%v) failed: %v", *publishAs, err)
+ var publishName string
+ if testMode == false {
+ publishName = *publishAs
+ }
+ if err := server.ServeDispatcher(publishName, dispatcher); err != nil {
+ vlog.Errorf("Serve(%v) failed: %v", publishName, err)
return err
}
- vlog.VI(0).Infof("Device manager published as: %v", *publishAs)
+ vlog.VI(0).Infof("Device manager published as: %v", publishName)
impl.InvokeCallback(ctx, name)
// Wait until shutdown. Ignore duplicate signals (sent by agent and
diff --git a/services/mgmt/device/impl/app_service.go b/services/mgmt/device/impl/app_service.go
index 2d40769..383ab09 100644
--- a/services/mgmt/device/impl/app_service.go
+++ b/services/mgmt/device/impl/app_service.go
@@ -411,6 +411,10 @@
if _, err := newVersion(call.Context(), installationDir, envelope, ""); err != nil {
return "", err
}
+ if newOrigin, ok := config[mgmt.AppOriginConfigKey]; ok {
+ delete(config, mgmt.AppOriginConfigKey)
+ applicationVON = newOrigin
+ }
if err := saveOrigin(installationDir, applicationVON); err != nil {
return "", err
}
@@ -838,11 +842,16 @@
vlog.Errorf("WaitForReady(%v) failed: %v", childReadyTimeout, err)
return verror2.Make(ErrOperationFailed, nil)
}
+ pid := handle.ChildPid()
childName, err := listener.waitForValue(childReadyTimeout)
if err != nil {
return verror2.Make(ErrOperationFailed, nil)
}
- info.AppCycleMgrName, info.Pid = childName, handle.Pid()
+
+ // Because suidhelper uses Go's in-built support for setuid forking,
+ // handle.Pid() is the pid of suidhelper, not the pid of the app
+ // so use the pid returned in the app's ready status.
+ info.AppCycleMgrName, info.Pid = childName, pid
if err := saveInstanceInfo(instanceDir, info); err != nil {
return err
}
diff --git a/services/mgmt/device/impl/device_service.go b/services/mgmt/device/impl/device_service.go
index 629a283..0ff8ead 100644
--- a/services/mgmt/device/impl/device_service.go
+++ b/services/mgmt/device/impl/device_service.go
@@ -43,15 +43,16 @@
"os/exec"
"path/filepath"
"reflect"
+ "strconv"
"strings"
"sync"
- "time"
"v.io/core/veyron2"
"v.io/core/veyron2/context"
"v.io/core/veyron2/ipc"
"v.io/core/veyron2/mgmt"
"v.io/core/veyron2/naming"
+ "v.io/core/veyron2/security"
"v.io/core/veyron2/services/mgmt/application"
"v.io/core/veyron2/services/mgmt/binary"
"v.io/core/veyron2/services/mgmt/device"
@@ -60,7 +61,9 @@
"v.io/core/veyron2/vlog"
vexec "v.io/core/veyron/lib/exec"
+ "v.io/core/veyron/lib/flags/consts"
"v.io/core/veyron/lib/netstate"
+ vsecurity "v.io/core/veyron/security"
"v.io/core/veyron/services/mgmt/device/config"
"v.io/core/veyron/services/mgmt/profile"
)
@@ -102,6 +105,7 @@
config *config.State
disp *dispatcher
uat BlessingSystemAssociationStore
+ securityAgent *securityAgentState
}
// managerInfo holds state about a running device manager.
@@ -216,6 +220,7 @@
func (s *deviceService) revertDeviceManager(ctx *context.T) error {
if err := updateLink(s.config.Previous, s.config.CurrentLink); err != nil {
+ vlog.Errorf("updateLink failed: %v", err)
return err
}
if s.restartHandler != nil {
@@ -278,6 +283,61 @@
cfg.Set(mgmt.ParentNameConfigKey, listener.name())
cfg.Set(mgmt.ProtocolConfigKey, "tcp")
cfg.Set(mgmt.AddressConfigKey, "127.0.0.1:0")
+
+ var p security.Principal
+ var agentHandle []byte
+ if s.securityAgent != nil {
+ // TODO(rthellend): Cleanup principal
+ handle, conn, err := s.securityAgent.keyMgrAgent.NewPrincipal(ctx, false)
+ if err != nil {
+ vlog.Errorf("NewPrincipal() failed %v", err)
+ return verror2.Make(ErrOperationFailed, nil)
+ }
+ agentHandle = handle
+ var cancel func()
+ if p, cancel, err = agentPrincipal(ctx, conn); err != nil {
+ vlog.Errorf("agentPrincipal failed: %v", err)
+ return verror2.Make(ErrOperationFailed, nil)
+ }
+ defer cancel()
+
+ } else {
+ credentialsDir := filepath.Join(workspace, "credentials")
+ var err error
+ if p, err = vsecurity.CreatePersistentPrincipal(credentialsDir, nil); err != nil {
+ vlog.Errorf("CreatePersistentPrincipal(%v, nil) failed: %v", credentialsDir, err)
+ return verror2.Make(ErrOperationFailed, nil)
+ }
+ cmd.Env = append(cmd.Env, consts.VeyronCredentials+"="+credentialsDir)
+ }
+ dmPrincipal := veyron2.GetPrincipal(ctx)
+ dmBlessings, err := dmPrincipal.Bless(p.PublicKey(), dmPrincipal.BlessingStore().Default(), "testdm", security.UnconstrainedUse())
+ if err := p.BlessingStore().SetDefault(dmBlessings); err != nil {
+ vlog.Errorf("BlessingStore.SetDefault() failed: %v", err)
+ return verror2.Make(ErrOperationFailed, nil)
+ }
+ if _, err := p.BlessingStore().Set(dmBlessings, security.AllPrincipals); err != nil {
+ vlog.Errorf("BlessingStore.Set() failed: %v", err)
+ return verror2.Make(ErrOperationFailed, nil)
+ }
+ if err := p.AddToRoots(dmBlessings); err != nil {
+ vlog.Errorf("AddToRoots() failed: %v", err)
+ return verror2.Make(ErrOperationFailed, nil)
+ }
+
+ if s.securityAgent != nil {
+ file, err := s.securityAgent.keyMgrAgent.NewConnection(agentHandle)
+ if err != nil {
+ vlog.Errorf("NewConnection(%v) failed: %v", agentHandle, err)
+ return err
+ }
+ defer file.Close()
+
+ fd := len(cmd.ExtraFiles) + vexec.FileOffset
+ cmd.ExtraFiles = append(cmd.ExtraFiles, file)
+ cfg.Set(mgmt.SecurityAgentFDConfigKey, strconv.Itoa(fd))
+ }
+
handle := vexec.NewParentHandle(cmd, vexec.ConfigOpt{cfg})
// Start the child process.
if err := handle.Start(); err != nil {
@@ -296,35 +356,14 @@
}
childName, err := listener.waitForValue(childReadyTimeout)
if err != nil {
+ vlog.Errorf("waitForValue(%v) failed: %v", childReadyTimeout, err)
return verror2.Make(ErrOperationFailed, ctx)
}
- // Check that invoking Revert() succeeds.
+ // Check that invoking Stop() succeeds.
childName = naming.Join(childName, "device")
dmClient := device.DeviceClient(childName)
- linkOld, pathOld, err := s.getCurrentFileInfo()
- if err != nil {
- return verror2.Make(ErrOperationFailed, ctx)
- }
- // Since the resolution of mtime for files is seconds, the test sleeps
- // for a second to make sure it can check whether the current symlink is
- // updated.
- time.Sleep(time.Second)
- if err := dmClient.Revert(ctx); err != nil {
- return verror2.Make(ErrOperationFailed, ctx)
- }
- linkNew, pathNew, err := s.getCurrentFileInfo()
- if err != nil {
- return verror2.Make(ErrOperationFailed, ctx)
- }
- // Check that the new device manager updated the current symbolic link.
- if !linkOld.ModTime().Before(linkNew.ModTime()) {
- vlog.Errorf("New device manager test failed")
- return verror2.Make(ErrOperationFailed, ctx)
- }
- // Ensure that the current symbolic link points to the same script.
- if pathNew != pathOld {
- updateLink(pathOld, s.config.CurrentLink)
- vlog.Errorf("New device manager test failed")
+ if err := dmClient.Stop(ctx, 0); err != nil {
+ vlog.Errorf("Stop() failed: %v", err)
return verror2.Make(ErrOperationFailed, ctx)
}
if err := handle.Wait(childWaitTimeout); err != nil {
@@ -432,11 +471,10 @@
return err
}
- // TODO(rthellend): testDeviceManager always fails due to https://github.com/veyron/release-issues/issues/714
- // Uncomment when the bug is fixed.
- //if err := s.testDeviceManager(ctx, workspace, envelope); err != nil {
- // return err
- //}
+ if err := s.testDeviceManager(ctx, workspace, envelope); err != nil {
+ vlog.Errorf("testDeviceManager failed: %v", err)
+ return err
+ }
if err := updateLink(filepath.Join(workspace, "deviced.sh"), s.config.CurrentLink); err != nil {
return err
@@ -470,10 +508,12 @@
func (s *deviceService) Revert(call ipc.ServerContext) error {
if s.config.Previous == "" {
+ vlog.Errorf("Revert failed: no previous version")
return verror2.Make(ErrUpdateNoOp, call.Context())
}
updatingState := s.updating
if updatingState.testAndSetUpdating() {
+ vlog.Errorf("Revert failed: already in progress")
return verror2.Make(ErrOperationInProgress, call.Context())
}
err := s.revertDeviceManager(call.Context())
diff --git a/services/mgmt/device/impl/dispatcher.go b/services/mgmt/device/impl/dispatcher.go
index 5632858..7dc317e 100644
--- a/services/mgmt/device/impl/dispatcher.go
+++ b/services/mgmt/device/impl/dispatcher.go
@@ -34,6 +34,7 @@
updating *updatingState
securityAgent *securityAgentState
restartHandler func()
+ testMode bool
}
// dispatcher holds the state of the device manager dispatcher.
@@ -72,7 +73,7 @@
)
// NewDispatcher is the device manager dispatcher factory.
-func NewDispatcher(principal security.Principal, config *config.State, restartHandler func()) (*dispatcher, error) {
+func NewDispatcher(principal security.Principal, config *config.State, testMode bool, restartHandler func()) (ipc.Dispatcher, error) {
if err := config.Validate(); err != nil {
return nil, fmt.Errorf("invalid config %v: %v", config, err)
}
@@ -95,6 +96,7 @@
callback: newCallbackState(config.Name),
updating: newUpdatingState(),
restartHandler: restartHandler,
+ testMode: testMode,
},
config: config,
uat: uat,
@@ -121,6 +123,9 @@
}
}
}
+ if testMode {
+ return &testModeDispatcher{d}, nil
+ }
return d, nil
}
@@ -166,8 +171,17 @@
// TODO(rjkroege): Consider refactoring authorizer implementations to
// be shareable with other components.
-func newAuthorizer(principal security.Principal, dir string, locks *acls.Locks) (security.Authorizer, error) {
- rootTam, _, err := locks.GetPathACL(principal, dir)
+func (d *dispatcher) newAuthorizer() (security.Authorizer, error) {
+ if d.internal.testMode {
+ // In test mode, the device manager will not be able to read
+ // the ACLs, because they were signed with the key of the real
+ // device manager. It's not a problem because the
+ // testModeDispatcher overrides the authorizer anyway.
+ return nil, nil
+ }
+
+ dir := d.getACLDir()
+ rootTam, _, err := d.locks.GetPathACL(d.principal, dir)
if err != nil && os.IsNotExist(err) {
vlog.VI(1).Infof("GetPathACL(%s) failed: %v", dir, err)
@@ -194,7 +208,8 @@
i--
}
}
- auth, err := newAuthorizer(d.principal, d.getACLDir(), d.locks)
+
+ auth, err := d.newAuthorizer()
if err != nil {
return nil, nil, err
}
@@ -214,6 +229,7 @@
config: d.config,
disp: d,
uat: d.uat,
+ securityAgent: d.internal.securityAgent,
})
return receiver, auth, nil
case appsSuffix:
@@ -252,9 +268,6 @@
return invoker, auth, nil
}
}
- if err != nil {
- return nil, nil, err
- }
receiver := device.ApplicationServer(&appService{
callback: d.internal.callback,
config: d.config,
@@ -289,6 +302,27 @@
}
}
+// testModeDispatcher is a wrapper around the real dispatcher. It returns the
+// exact same object as the real dispatcher, but the authorizer only allows
+// calls to "device".Stop().
+type testModeDispatcher struct {
+ realDispatcher ipc.Dispatcher
+}
+
+func (d *testModeDispatcher) Lookup(suffix string) (interface{}, security.Authorizer, error) {
+ obj, _, err := d.realDispatcher.Lookup(suffix)
+ return obj, d, err
+}
+
+func (testModeDispatcher) Authorize(ctx security.Context) error {
+ if ctx.Suffix() == deviceSuffix && ctx.Method() == "Stop" {
+ vlog.Infof("testModeDispatcher.Authorize: Allow %q.%s()", ctx.Suffix(), ctx.Method())
+ return nil
+ }
+ vlog.Infof("testModeDispatcher.Authorize: Reject %q.%s()", ctx.Suffix(), ctx.Method())
+ return verror.Make(ErrInvalidSuffix, nil)
+}
+
func newAppSpecificAuthorizer(sec security.Authorizer, config *config.State, suffix []string) (security.Authorizer, error) {
// TODO(rjkroege): This does not support <appname>.Start() to start all
// instances. Correct this.
diff --git a/services/mgmt/device/impl/impl_test.go b/services/mgmt/device/impl/impl_test.go
index d146f15..72402e9 100644
--- a/services/mgmt/device/impl/impl_test.go
+++ b/services/mgmt/device/impl/impl_test.go
@@ -30,6 +30,7 @@
"v.io/core/veyron2"
"v.io/core/veyron2/context"
"v.io/core/veyron2/ipc"
+ "v.io/core/veyron2/mgmt"
"v.io/core/veyron2/naming"
"v.io/core/veyron2/security"
"v.io/core/veyron2/services/mgmt/application"
@@ -42,6 +43,7 @@
"v.io/core/veyron2/vlog"
"v.io/core/veyron/lib/expect"
+ "v.io/core/veyron/lib/flags/consts"
"v.io/core/veyron/lib/modules"
"v.io/core/veyron/lib/signals"
"v.io/core/veyron/lib/testutil"
@@ -77,13 +79,17 @@
modules.RegisterChild(execScriptCmd, "", execScript)
modules.RegisterChild(deviceManagerCmd, "", deviceManager)
modules.RegisterChild(appCmd, "", app)
- testutil.Init()
if modules.IsModulesProcess() {
return
}
}
+func TestMain(m *testing.M) {
+ testutil.Init()
+ os.Exit(m.Run())
+}
+
// TestHelperProcess is the entrypoint for the modules commands in a
// a test subprocess.
func TestHelperProcess(t *testing.T) {
@@ -105,7 +111,6 @@
// execScript launches the script passed as argument.
func execScript(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
- args = args[1:]
if want, got := 1, len(args); want != got {
vlog.Fatalf("execScript expected %d arguments, got %d instead", want, got)
}
@@ -132,7 +137,6 @@
func deviceManager(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
ctx, shutdown := testutil.InitForTest()
- args = args[1:]
if len(args) == 0 {
vlog.Fatalf("deviceManager expected at least an argument")
}
@@ -160,11 +164,13 @@
// script prepared by a previous version of the device manager.
if len(args) > 0 {
if want, got := 4, len(args); want != got {
- vlog.Fatalf("expected %d additional arguments, got %d instead", want, got)
+ vlog.Fatalf("expected %d additional arguments, got %d instead: %q", want, got, args)
}
configState.Root, configState.Helper, configState.Origin, configState.CurrentLink = args[0], args[1], args[2], args[3]
}
- dispatcher, err := impl.NewDispatcher(veyron2.GetPrincipal(ctx), configState, func() { fmt.Println("restart handler") })
+ blessings := fmt.Sprint(veyron2.GetPrincipal(ctx).BlessingStore().Default())
+ testMode := strings.HasSuffix(blessings, "/testdm")
+ dispatcher, err := impl.NewDispatcher(veyron2.GetPrincipal(ctx), configState, testMode, func() { fmt.Println("restart handler") })
if err != nil {
vlog.Fatalf("Failed to create device manager dispatcher: %v", err)
}
@@ -180,7 +186,7 @@
if val, present := env["PAUSE_BEFORE_STOP"]; present && val == "1" {
modules.WaitForEOF(stdin)
}
- if dispatcher.Leaking() {
+ if impl.DispatcherLeaking(dispatcher) {
vlog.Fatalf("device manager leaking resources")
}
return nil
@@ -253,7 +259,6 @@
veyron2.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))
- args = args[1:]
if expected, got := 1, len(args); expected != got {
vlog.Fatalf("Unexpected number of arguments: expected %d, got %d", expected, got)
}
@@ -363,9 +368,7 @@
// Set up a second version of the device manager. The information in the
// envelope will be used by the device manager to stage the next
// version.
- crDir, crEnv := mgmttest.CredentialsForChild(ctx, "child")
- defer os.RemoveAll(crDir)
- *envelope = envelopeFromShell(sh, crEnv, deviceManagerCmd, application.DeviceManagerTitle, "v2DM")
+ *envelope = envelopeFromShell(sh, nil, deviceManagerCmd, application.DeviceManagerTitle, "v2DM")
updateDevice(t, ctx, "factoryDM")
// Current link should have been updated to point to v2.
@@ -407,9 +410,7 @@
}
// Create a third version of the device manager and issue an update.
- crDir, crEnv = mgmttest.CredentialsForChild(ctx, "child")
- defer os.RemoveAll(crDir)
- *envelope = envelopeFromShell(sh, crEnv, deviceManagerCmd, application.DeviceManagerTitle, "v3DM")
+ *envelope = envelopeFromShell(sh, nil, deviceManagerCmd, application.DeviceManagerTitle, "v3DM")
updateDevice(t, ctx, "v2DM")
scriptPathV3 := evalLink()
@@ -566,12 +567,9 @@
// Create a script wrapping the test target that implements suidhelper.
helperPath := generateSuidHelperScript(t, root)
- crDir, crEnv := mgmttest.CredentialsForChild(ctx, "devicemanager")
- defer os.RemoveAll(crDir)
-
// Set up the device manager. Since we won't do device manager updates,
// don't worry about its application envelope and current link.
- dmh, dms := mgmttest.RunShellCommand(t, sh, crEnv, deviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
+ dmh, dms := mgmttest.RunShellCommand(t, sh, nil, deviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
mgmttest.ReadPID(t, dms)
// Create the local server that the app uses to let us know it's ready.
@@ -584,8 +582,17 @@
*envelope = envelopeFromShell(sh, []string{testEnvVarName + "=env-val-envelope"}, appCmd, "google naps", fmt.Sprintf("--%s=flag-val-envelope", testFlagName), "appV1")
// Install the app. The config-specified flag value for testFlagName
- // should override the value specified in the envelope above.
- appID := installApp(t, ctx, device.Config{testFlagName: "flag-val-install"})
+ // should override the value specified in the envelope above, and the
+ // config-specified value for origin should override the value in the
+ // Install rpc argument.
+ mtName, ok := sh.GetVar(consts.NamespaceRootPrefix)
+ if !ok {
+ t.Fatalf("failed to get namespace root var from shell")
+ }
+ // This rooted name should be equivalent to the relative name "ar", but
+ // we want to test that the config override for origin works.
+ rootedAppRepoName := naming.Join(mtName, "ar")
+ appID := installApp(t, ctx, device.Config{testFlagName: "flag-val-install", mgmt.AppOriginConfigKey: rootedAppRepoName})
installationDebug := debug(t, ctx, appID)
// We spot-check a couple pieces of information we expect in the debug
// output.
@@ -593,7 +600,7 @@
// logic that assumes too much about the format? This may be one
// argument in favor of making the output of Debug a struct instead of
// free-form string.
- if !strings.Contains(installationDebug, "Origin: ar") {
+ if !strings.Contains(installationDebug, fmt.Sprintf("Origin: %v", rootedAppRepoName)) {
t.Fatalf("debug response doesn't contain expected info: %v", installationDebug)
}
if !strings.Contains(installationDebug, "Config: map[random_test_flag:flag-val-install]") {
@@ -802,15 +809,12 @@
root, cleanup := mgmttest.SetupRootDir(t, "devicemanager")
defer cleanup()
- crDir, crEnv := mgmttest.CredentialsForChild(ctx, "devicemanager")
- defer os.RemoveAll(crDir)
-
// Create a script wrapping the test target that implements suidhelper.
helperPath := generateSuidHelperScript(t, root)
// Set up the device manager. Since we won't do device manager updates,
// don't worry about its application envelope and current link.
- _, dms := mgmttest.RunShellCommand(t, sh, crEnv, deviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
+ _, dms := mgmttest.RunShellCommand(t, sh, nil, deviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
pid := mgmttest.ReadPID(t, dms)
defer syscall.Kill(pid, syscall.SIGINT)
@@ -896,12 +900,9 @@
t.Fatal(err)
}
- crDir, crEnv := mgmttest.CredentialsForChild(ctx, "devicemanager")
- defer os.RemoveAll(crDir)
-
// Set up the device manager. Since we won't do device manager updates,
// don't worry about its application envelope and current link.
- _, dms := mgmttest.RunShellCommand(t, sh, crEnv, deviceManagerCmd, "dm", root, "unused_helper", "unused_app_repo_name", "unused_curr_link")
+ _, dms := mgmttest.RunShellCommand(t, sh, nil, deviceManagerCmd, "dm", root, "unused_helper", "unused_app_repo_name", "unused_curr_link")
pid := mgmttest.ReadPID(t, dms)
defer syscall.Kill(pid, syscall.SIGINT)
@@ -1042,15 +1043,12 @@
root, cleanup := mgmttest.SetupRootDir(t, "devicemanager")
defer cleanup()
- crDir, crEnv := mgmttest.CredentialsForChild(ctx, "devicemanager")
- defer os.RemoveAll(crDir)
-
// Create a script wrapping the test target that implements suidhelper.
helperPath := generateSuidHelperScript(t, root)
// Set up the device manager. Since we won't do device manager updates,
// don't worry about its application envelope and current link.
- _, dms := mgmttest.RunShellCommand(t, sh, crEnv, deviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
+ _, dms := mgmttest.RunShellCommand(t, sh, nil, deviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
pid := mgmttest.ReadPID(t, dms)
defer syscall.Kill(pid, syscall.SIGINT)
@@ -1212,15 +1210,12 @@
root, cleanup := mgmttest.SetupRootDir(t, "devicemanager")
defer cleanup()
- crDir, crEnv := mgmttest.CredentialsForChild(ctx, "devicemanager")
- defer os.RemoveAll(crDir)
-
// Create a script wrapping the test target that implements suidhelper.
helperPath := generateSuidHelperScript(t, root)
// Set up the device manager. Since we won't do device manager updates,
// don't worry about its application envelope and current link.
- _, dms := mgmttest.RunShellCommand(t, sh, crEnv, deviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
+ _, dms := mgmttest.RunShellCommand(t, sh, nil, deviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
pid := mgmttest.ReadPID(t, dms)
defer syscall.Kill(pid, syscall.SIGINT)
@@ -1298,10 +1293,8 @@
if err := idp.Bless(veyron2.GetPrincipal(otherCtx), "other"); err != nil {
t.Fatal(err)
}
- crFile, crEnv := mgmttest.CredentialsForChild(ctx, "devicemanager")
- defer os.RemoveAll(crFile)
- _, dms := mgmttest.RunShellCommand(t, sh, crEnv, deviceManagerCmd, "dm", root, "unused_helper", "unused_app_repo_name", "unused_curr_link")
+ _, dms := mgmttest.RunShellCommand(t, sh, nil, deviceManagerCmd, "dm", root, "unused_helper", "unused_app_repo_name", "unused_curr_link")
pid := mgmttest.ReadPID(t, dms)
defer syscall.Kill(pid, syscall.SIGINT)
@@ -1408,13 +1401,10 @@
t.Fatal(err)
}
- crDir, crEnv := mgmttest.CredentialsForChild(ctx, "devicemanager")
- defer os.RemoveAll(crDir)
-
// Create a script wrapping the test target that implements suidhelper.
helperPath := generateSuidHelperScript(t, root)
- _, dms := mgmttest.RunShellCommand(t, sh, crEnv, deviceManagerCmd, "-mocksetuid", "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
+ _, dms := mgmttest.RunShellCommand(t, sh, nil, deviceManagerCmd, "-mocksetuid", "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
pid := mgmttest.ReadPID(t, dms)
defer syscall.Kill(pid, syscall.SIGINT)
diff --git a/services/mgmt/device/impl/only_for_test.go b/services/mgmt/device/impl/only_for_test.go
index 082fc25..6f92afc 100644
--- a/services/mgmt/device/impl/only_for_test.go
+++ b/services/mgmt/device/impl/only_for_test.go
@@ -2,9 +2,11 @@
import (
"flag"
+ "fmt"
"os"
"path/filepath"
+ "v.io/core/veyron2/ipc"
"v.io/core/veyron2/services/mgmt/device"
"v.io/core/veyron2/vlog"
)
@@ -20,8 +22,15 @@
return len(c.channels) > 0
}
-func (d *dispatcher) Leaking() bool {
- return d.internal.callback.leaking()
+func DispatcherLeaking(d ipc.Dispatcher) bool {
+ switch obj := d.(type) {
+ case *dispatcher:
+ return obj.internal.callback.leaking()
+ case *testModeDispatcher:
+ return obj.realDispatcher.(*dispatcher).internal.callback.leaking()
+ default:
+ panic(fmt.Sprintf("unexpected type: %T", d))
+ }
}
func init() {
diff --git a/services/mgmt/device/impl/util.go b/services/mgmt/device/impl/util.go
index 596ef71..54d90d2 100644
--- a/services/mgmt/device/impl/util.go
+++ b/services/mgmt/device/impl/util.go
@@ -29,7 +29,7 @@
vlog.Errorf("Download(%v) failed: %v", name, err)
return verror2.Make(ErrOperationFailed, nil)
}
- path, perm := filepath.Join(workspace, fileName), os.FileMode(755)
+ path, perm := filepath.Join(workspace, fileName), os.FileMode(0755)
if err := ioutil.WriteFile(path, data, perm); err != nil {
vlog.Errorf("WriteFile(%v, %v) failed: %v", path, perm, err)
return verror2.Make(ErrOperationFailed, nil)
diff --git a/services/mgmt/lib/testutil/modules.go b/services/mgmt/lib/testutil/modules.go
index 23aa53e..dcfecf4 100644
--- a/services/mgmt/lib/testutil/modules.go
+++ b/services/mgmt/lib/testutil/modules.go
@@ -31,7 +31,7 @@
// StartRootMT sets up a root mount table for tests.
func StartRootMT(t *testing.T, sh *modules.Shell) (string, modules.Handle) {
- h, err := sh.Start(core.RootMTCommand, nil, "--", "--veyron.tcp.address=127.0.0.1:0")
+ h, err := sh.Start(core.RootMTCommand, nil, "--veyron.tcp.address=127.0.0.1:0")
if err != nil {
t.Fatalf("failed to start root mount table: %s", err)
}
diff --git a/services/mgmt/repository/repository.vdl.go b/services/mgmt/repository/repository.vdl.go
index 1812a12..f90a688 100644
--- a/services/mgmt/repository/repository.vdl.go
+++ b/services/mgmt/repository/repository.vdl.go
@@ -14,6 +14,8 @@
"v.io/core/veyron2/services/security/access"
+ "v.io/core/veyron2/services/security/access/object"
+
// The non-user imports are prefixed with "__" to prevent collisions.
__veyron2 "v.io/core/veyron2"
__context "v.io/core/veyron2/context"
@@ -188,7 +190,7 @@
}
func (s implApplicationServerStub) Describe__() []__ipc.InterfaceDesc {
- return []__ipc.InterfaceDesc{ApplicationDesc, repository.ApplicationDesc, access.ObjectDesc}
+ return []__ipc.InterfaceDesc{ApplicationDesc, repository.ApplicationDesc, object.ObjectDesc}
}
// ApplicationDesc describes the Application interface.
diff --git a/services/mgmt/vtrace/impl/vtrace.go b/services/mgmt/vtrace/impl/vtrace.go
index 3aa22dd..066f7b2 100644
--- a/services/mgmt/vtrace/impl/vtrace.go
+++ b/services/mgmt/vtrace/impl/vtrace.go
@@ -10,7 +10,7 @@
type vtraceService struct{}
-func (v *vtraceService) Trace(ctx ipc.ServerContext, id uniqueid.ID) (vtrace.TraceRecord, error) {
+func (v *vtraceService) Trace(ctx ipc.ServerContext, id uniqueid.Id) (vtrace.TraceRecord, error) {
store := vtrace.GetStore(ctx.Context())
tr := store.TraceRecord(id)
if tr == nil {
diff --git a/tools/application/doc.go b/tools/application/doc.go
index 31b8cfa..26deafa 100644
--- a/tools/application/doc.go
+++ b/tools/application/doc.go
@@ -38,9 +38,19 @@
directory to use for storing security credentials
-veyron.namespace.root=[/ns.dev.v.io:8101]
local namespace root; can be repeated to provided multiple roots
+ -veyron.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -veyron.tcp.address=
+ address to listen on
+ -veyron.tcp.protocol=tcp
+ protocol to listen with
-veyron.vtrace.cache_size=1024
The number of vtrace traces to store in memory.
- -veyron.vtrace.dump_on_shutdown=false
+ -veyron.vtrace.collect_regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -veyron.vtrace.dump_on_shutdown=true
If true, dump all stored traces on runtime shutdown.
-veyron.vtrace.sample_rate=0
Rate (from 0.0 to 1.0) to sample vtrace traces.
@@ -62,11 +72,12 @@
Add the given envelope to the application for the given profiles.
Usage:
- application put <application> <profiles> <envelope>
+ application put <application> <profiles> [<envelope>]
<application> is the full name of the application. <profiles> is a
comma-separated list of profiles. <envelope> is the file that contains a
-JSON-encoded envelope.
+JSON-encoded envelope. If this file is not provided, the user will be prompted
+to enter the data manually.
Application Remove
diff --git a/tools/binary/doc.go b/tools/binary/doc.go
index 3807988..cac49eb 100644
--- a/tools/binary/doc.go
+++ b/tools/binary/doc.go
@@ -36,9 +36,19 @@
directory to use for storing security credentials
-veyron.namespace.root=[/ns.dev.v.io:8101]
local namespace root; can be repeated to provided multiple roots
+ -veyron.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -veyron.tcp.address=
+ address to listen on
+ -veyron.tcp.protocol=tcp
+ protocol to listen with
-veyron.vtrace.cache_size=1024
The number of vtrace traces to store in memory.
- -veyron.vtrace.dump_on_shutdown=false
+ -veyron.vtrace.collect_regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -veyron.vtrace.dump_on_shutdown=true
If true, dump all stored traces on runtime shutdown.
-veyron.vtrace.sample_rate=0
Rate (from 0.0 to 1.0) to sample vtrace traces.
diff --git a/tools/build/doc.go b/tools/build/doc.go
index bd39613..d58afb3 100644
--- a/tools/build/doc.go
+++ b/tools/build/doc.go
@@ -33,9 +33,19 @@
directory to use for storing security credentials
-veyron.namespace.root=[/ns.dev.v.io:8101]
local namespace root; can be repeated to provided multiple roots
+ -veyron.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -veyron.tcp.address=
+ address to listen on
+ -veyron.tcp.protocol=tcp
+ protocol to listen with
-veyron.vtrace.cache_size=1024
The number of vtrace traces to store in memory.
- -veyron.vtrace.dump_on_shutdown=false
+ -veyron.vtrace.collect_regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -veyron.vtrace.dump_on_shutdown=true
If true, dump all stored traces on runtime shutdown.
-veyron.vtrace.sample_rate=0
Rate (from 0.0 to 1.0) to sample vtrace traces.
diff --git a/tools/debug/doc.go b/tools/debug/doc.go
index 3bf5c2f..248ac28 100644
--- a/tools/debug/doc.go
+++ b/tools/debug/doc.go
@@ -37,9 +37,19 @@
directory to use for storing security credentials
-veyron.namespace.root=[/ns.dev.v.io:8101]
local namespace root; can be repeated to provided multiple roots
+ -veyron.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -veyron.tcp.address=
+ address to listen on
+ -veyron.tcp.protocol=tcp
+ protocol to listen with
-veyron.vtrace.cache_size=1024
The number of vtrace traces to store in memory.
- -veyron.vtrace.dump_on_shutdown=false
+ -veyron.vtrace.collect_regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -veyron.vtrace.dump_on_shutdown=true
If true, dump all stored traces on runtime shutdown.
-veyron.vtrace.sample_rate=0
Rate (from 0.0 to 1.0) to sample vtrace traces.
@@ -173,7 +183,7 @@
$ debug pprof run a/b/c heap --text $ debug pprof run a/b/c profile -gv
The debug pprof run flags are:
- -pprofcmd=veyron go tool pprof
+ -pprofcmd=v23 go tool pprof
The pprof command to use.
Debug Pprof Proxy
diff --git a/tools/debug/impl.go b/tools/debug/impl.go
index a846c55..4d423ba 100644
--- a/tools/debug/impl.go
+++ b/tools/debug/impl.go
@@ -72,7 +72,7 @@
}
func doFetchTrace(ctx *context.T, wg *sync.WaitGroup, client vtracesvc.StoreClientStub,
- id uniqueid.ID, traces chan *vtrace.TraceRecord, errors chan error) {
+ id uniqueid.Id, traces chan *vtrace.TraceRecord, errors chan error) {
defer wg.Done()
trace, err := client.Trace(ctx, id)
diff --git a/tools/mgmt/device/doc.go b/tools/mgmt/device/doc.go
index b760e71..c8f4780 100644
--- a/tools/mgmt/device/doc.go
+++ b/tools/mgmt/device/doc.go
@@ -75,21 +75,23 @@
Install the given application.
Usage:
- device install <device> <application> [<config override>]
+ device install [flags] <device> <application>
<device> is the veyron object name of the device manager's app service.
<application> is the veyron object name of the application.
-<config override> is an optional JSON-encoded device.Config object, of the form:
- '{"flag1":"value1","flag2":"value2"}'.
+The device install flags are:
+ -config={}
+ JSON-encoded device.Config object, of the form:
+ '{"flag1":"value1","flag2":"value2"}'
Device Install-Local
Install the given application, specified using a local path.
Usage:
- device install-local <device> <title> [ENV=VAL ...] binary [--flag=val ...]
+ device install-local [flags] <device> <title> [ENV=VAL ...] binary [--flag=val ...]
<device> is the veyron object name of the device manager's app service.
@@ -98,6 +100,11 @@
This is followed by an arbitrary number of environment variable settings, the
local path for the binary to install, and arbitrary flag settings.
+The device install-local flags are:
+ -config={}
+ JSON-encoded device.Config object, of the form:
+ '{"flag1":"value1","flag2":"value2"}'
+
Device Start
Start an instance of the given application.
diff --git a/tools/mgmt/device/impl/impl.go b/tools/mgmt/device/impl/impl.go
index 8762b8a..2600b4e 100644
--- a/tools/mgmt/device/impl/impl.go
+++ b/tools/mgmt/device/impl/impl.go
@@ -17,29 +17,43 @@
Name: "install",
Short: "Install the given application.",
Long: "Install the given application.",
- ArgsName: "<device> <application> [<config override>]",
+ ArgsName: "<device> <application>",
ArgsLong: `
<device> is the veyron object name of the device manager's app service.
<application> is the veyron object name of the application.
+`,
+}
-<config override> is an optional JSON-encoded device.Config object, of the form:
- '{"flag1":"value1","flag2":"value2"}'.`,
+type configFlag device.Config
+
+func (c *configFlag) String() string {
+ jsonConfig, _ := json.Marshal(c)
+ return string(jsonConfig)
+}
+func (c *configFlag) Set(s string) error {
+ if err := json.Unmarshal([]byte(s), c); err != nil {
+ return fmt.Errorf("Unmarshal(%v) failed: %v", s, err)
+ }
+ return nil
+}
+
+var configOverride configFlag = configFlag{}
+
+func init() {
+ cmdInstall.Flags.Var(&configOverride, "config", "JSON-encoded device.Config object, of the form: '{\"flag1\":\"value1\",\"flag2\":\"value2\"}'")
}
func runInstall(cmd *cmdline.Command, args []string) error {
- if expectedMin, expectedMax, got := 2, 3, len(args); expectedMin > got || expectedMax < got {
- return cmd.UsageErrorf("install: incorrect number of arguments, expected between %d and %d, got %d", expectedMin, expectedMax, got)
+ if expected, got := 2, len(args); expected != got {
+ return cmd.UsageErrorf("install: incorrect number of arguments, expected %d, got %d", expected, got)
}
deviceName, appName := args[0], args[1]
- var cfg device.Config
- if len(args) > 2 {
- jsonConfig := args[2]
- if err := json.Unmarshal([]byte(jsonConfig), &cfg); err != nil {
- return fmt.Errorf("Unmarshal(%v) failed: %v", jsonConfig, err)
- }
- }
- appID, err := device.ApplicationClient(deviceName).Install(gctx, appName, cfg)
+ appID, err := device.ApplicationClient(deviceName).Install(gctx, appName, device.Config(configOverride))
+ // Reset the value for any future invocations of "install" or
+ // "install-local" (we run more than one command per process in unit
+ // tests).
+ configOverride = configFlag{}
if err != nil {
return fmt.Errorf("Install failed: %v", err)
}
diff --git a/tools/mgmt/device/impl/impl_test.go b/tools/mgmt/device/impl/impl_test.go
index 435d185..09e0a83 100644
--- a/tools/mgmt/device/impl/impl_test.go
+++ b/tools/mgmt/device/impl/impl_test.go
@@ -190,35 +190,35 @@
expectedTape interface{}
}{
{
- []string{"install", "blech"},
+ []string{"blech"},
nil,
true,
nil,
nil,
},
{
- []string{"install", "blech1", "blech2", "blech3", "blech4"},
+ []string{"blech1", "blech2", "blech3", "blech4"},
nil,
true,
nil,
nil,
},
{
- []string{"install", deviceName, appNameNoFetch, "not-valid-json"},
+ []string{deviceName, appNameNoFetch, "not-valid-json"},
nil,
true,
nil,
nil,
},
{
- []string{"install", deviceName, appNameNoFetch},
+ []string{deviceName, appNameNoFetch},
nil,
false,
InstallResponse{appId, nil},
InstallStimulus{"Install", appNameNoFetch, nil, application.Envelope{}, 0},
},
{
- []string{"install", deviceName, appNameNoFetch},
+ []string{deviceName, appNameNoFetch},
cfg,
false,
InstallResponse{appId, nil},
@@ -231,8 +231,9 @@
if err != nil {
t.Fatalf("test case %d: Marshal(%v) failed: %v", i, c.config, err)
}
- c.args = append(c.args, string(jsonConfig))
+ c.args = append([]string{fmt.Sprintf("--config=%s", string(jsonConfig))}, c.args...)
}
+ c.args = append([]string{"install"}, c.args...)
err := cmd.Execute(c.args)
if c.shouldErr {
if err == nil {
diff --git a/tools/mgmt/device/impl/local_install.go b/tools/mgmt/device/impl/local_install.go
index a8b8fb9..1598559 100644
--- a/tools/mgmt/device/impl/local_install.go
+++ b/tools/mgmt/device/impl/local_install.go
@@ -23,9 +23,6 @@
"v.io/lib/cmdline"
)
-// TODO(caprita): Add a way to provide an origin for the app, so we can do
-// updates after it's been installed.
-
var cmdInstallLocal = &cmdline.Command{
Run: runInstallLocal,
Name: "install-local",
@@ -41,6 +38,10 @@
local path for the binary to install, and arbitrary flag settings.`,
}
+func init() {
+ cmdInstallLocal.Flags.Var(&configOverride, "config", "JSON-encoded device.Config object, of the form: '{\"flag1\":\"value1\",\"flag2\":\"value2\"}'")
+}
+
type openAuthorizer struct{}
func (openAuthorizer) Authorize(security.Context) error { return nil }
@@ -226,7 +227,11 @@
objects["application"] = repository.ApplicationServer(envelopeInvoker(envelope))
appName := naming.Join(name, "application")
- appID, err := device.ApplicationClient(deviceName).Install(gctx, appName, nil)
+ appID, err := device.ApplicationClient(deviceName).Install(gctx, appName, device.Config(configOverride))
+ // Reset the value for any future invocations of "install" or
+ // "install-local" (we run more than one command per process in unit
+ // tests).
+ configOverride = configFlag{}
if err != nil {
return fmt.Errorf("Install failed: %v", err)
}
diff --git a/tools/mgmt/device/impl/local_install_test.go b/tools/mgmt/device/impl/local_install_test.go
index 7abb65f..9a65931 100644
--- a/tools/mgmt/device/impl/local_install_test.go
+++ b/tools/mgmt/device/impl/local_install_test.go
@@ -2,6 +2,7 @@
import (
"bytes"
+ "encoding/json"
"fmt"
"os"
"reflect"
@@ -10,6 +11,7 @@
"v.io/core/veyron2/naming"
"v.io/core/veyron2/services/mgmt/application"
+ "v.io/core/veyron2/services/mgmt/device"
"v.io/core/veyron/tools/mgmt/device/impl"
)
@@ -35,18 +37,19 @@
stderrSubstr string
}{
{
- []string{"install-local", deviceName}, "incorrect number of arguments",
+ []string{deviceName}, "incorrect number of arguments",
},
{
- []string{"install-local", deviceName, appTitle}, "missing binary",
+ []string{deviceName, appTitle}, "missing binary",
},
{
- []string{"install-local", deviceName, appTitle, "a=b"}, "missing binary",
+ []string{deviceName, appTitle, "a=b"}, "missing binary",
},
{
- []string{"install-local", deviceName, appTitle, "foo"}, "binary foo not found",
+ []string{deviceName, appTitle, "foo"}, "binary foo not found",
},
} {
+ c.args = append([]string{"install-local"}, c.args...)
if err := cmd.Execute(c.args); err == nil {
t.Fatalf("test case %d: wrongly failed to receive a non-nil error.", i)
} else {
@@ -69,20 +72,37 @@
t.Fatalf("Failed to stat %v: %v", binary, err)
}
binarySize := fi.Size()
+ cfg := device.Config{"someflag": "somevalue"}
for i, c := range []struct {
args []string
+ config device.Config
expectedTape interface{}
}{
{
- []string{"install-local", deviceName, appTitle, binary},
+ []string{deviceName, appTitle, binary},
+ nil,
InstallStimulus{"Install", appNameAfterFetch, nil, application.Envelope{Title: appTitle, Binary: binaryNameAfterFetch}, binarySize},
},
{
- []string{"install-local", deviceName, appTitle, "ENV1=V1", "ENV2=V2", binary, "FLAG1=V1", "FLAG2=V2"},
+ []string{deviceName, appTitle, binary},
+ cfg,
+ InstallStimulus{"Install", appNameAfterFetch, cfg, application.Envelope{Title: appTitle, Binary: binaryNameAfterFetch}, binarySize},
+ },
+ {
+ []string{deviceName, appTitle, "ENV1=V1", "ENV2=V2", binary, "FLAG1=V1", "FLAG2=V2"},
+ nil,
InstallStimulus{"Install", appNameAfterFetch, nil, application.Envelope{Title: appTitle, Binary: binaryNameAfterFetch, Env: []string{"ENV1=V1", "ENV2=V2"}, Args: []string{"FLAG1=V1", "FLAG2=V2"}}, binarySize},
},
} {
tape.SetResponses([]interface{}{InstallResponse{appId, nil}})
+ if c.config != nil {
+ jsonConfig, err := json.Marshal(c.config)
+ if err != nil {
+ t.Fatalf("test case %d: Marshal(%v) failed: %v", i, c.config, err)
+ }
+ c.args = append([]string{fmt.Sprintf("--config=%s", string(jsonConfig))}, c.args...)
+ }
+ c.args = append([]string{"install-local"}, c.args...)
if err := cmd.Execute(c.args); err != nil {
t.Fatalf("test case %d: %v", i, err)
}
diff --git a/tools/mgmt/test.sh b/tools/mgmt/test.sh
index 7a28463..7cf1f9e 100755
--- a/tools/mgmt/test.sh
+++ b/tools/mgmt/test.sh
@@ -116,14 +116,15 @@
local -r APPLICATIOND_NAME="applicationd"
local -r DEVICED_APP_NAME="${APPLICATIOND_NAME}/deviced/test"
- BIN_STAGING_DIR=$(shell::tmp_dir)
+ BIN_STAGING_DIR="${WORKDIR}/bin"
+ mkdir -p "${BIN_STAGING_DIR}"
cp "${AGENTD_BIN}" "${SUIDHELPER_BIN}" "${INITHELPER_BIN}" "${DEVICEMANAGER_BIN}" "${BIN_STAGING_DIR}"
shell_test::setup_server_test
# Install and start device manager.
- DM_INSTALL_DIR=$(shell::tmp_dir)
+ DM_INSTALL_DIR="${WORKDIR}/dm"
- export VANADIUM_DEVICE_DIR="${DM_INSTALL_DIR}/dm"
+ export VANADIUM_DEVICE_DIR="${DM_INSTALL_DIR}"
if [[ "${WITH_SUID}" == "--with_suid" ]]; then
"${DEVICE_SCRIPT}" install "${BIN_STAGING_DIR}" --origin="${DEVICED_APP_NAME}" -- --veyron.tcp.address=127.0.0.1:0
@@ -170,7 +171,7 @@
# the device ("alice/myworkstation") can talk to it.
local -r BINARYD_NAME="binaryd"
shell_test::start_server "${VRUN}" --name=myworkstation/binaryd "${BINARYD_BIN}" --name="${BINARYD_NAME}" \
- --root_dir="$(shell::tmp_dir)/binstore" --veyron.tcp.address=127.0.0.1:0 --http=127.0.0.1:0 \
+ --root_dir="${WORKDIR}/binstore" --veyron.tcp.address=127.0.0.1:0 --http=127.0.0.1:0 \
|| shell_test::fail "line ${LINENO} failed to start binaryd"
# Upload a binary to the binary server. The binary we upload is binaryd
@@ -185,8 +186,9 @@
# Start an application server under the blessing "alice/myworkstation/applicationd" so that
# the device ("alice/myworkstation") can talk to it.
+ mkdir -p "${WORKDIR}/appstore"
shell_test::start_server "${VRUN}" --name=myworkstation/applicationd "${APPLICATIOND_BIN}" --name="${APPLICATIOND_NAME}" \
- --store="$(shell::tmp_dir)" --veyron.tcp.address=127.0.0.1:0 \
+ --store="${WORKDIR}/appstore" --veyron.tcp.address=127.0.0.1:0 \
|| shell_test::fail "line ${LINENO} failed to start applicationd"
# Upload an envelope for our test app.
diff --git a/tools/mounttable/doc.go b/tools/mounttable/doc.go
index 15c9ec0..3b89c09 100644
--- a/tools/mounttable/doc.go
+++ b/tools/mounttable/doc.go
@@ -36,9 +36,19 @@
directory to use for storing security credentials
-veyron.namespace.root=[/ns.dev.v.io:8101]
local namespace root; can be repeated to provided multiple roots
+ -veyron.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -veyron.tcp.address=
+ address to listen on
+ -veyron.tcp.protocol=tcp
+ protocol to listen with
-veyron.vtrace.cache_size=1024
The number of vtrace traces to store in memory.
- -veyron.vtrace.dump_on_shutdown=false
+ -veyron.vtrace.collect_regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -veyron.vtrace.dump_on_shutdown=true
If true, dump all stored traces on runtime shutdown.
-veyron.vtrace.sample_rate=0
Rate (from 0.0 to 1.0) to sample vtrace traces.
diff --git a/tools/namespace/doc.go b/tools/namespace/doc.go
index 7aee2a4..44bcaf5 100644
--- a/tools/namespace/doc.go
+++ b/tools/namespace/doc.go
@@ -42,9 +42,19 @@
directory to use for storing security credentials
-veyron.namespace.root=[/ns.dev.v.io:8101]
local namespace root; can be repeated to provided multiple roots
+ -veyron.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -veyron.tcp.address=
+ address to listen on
+ -veyron.tcp.protocol=tcp
+ protocol to listen with
-veyron.vtrace.cache_size=1024
The number of vtrace traces to store in memory.
- -veyron.vtrace.dump_on_shutdown=false
+ -veyron.vtrace.collect_regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -veyron.vtrace.dump_on_shutdown=true
If true, dump all stored traces on runtime shutdown.
-veyron.vtrace.sample_rate=0
Rate (from 0.0 to 1.0) to sample vtrace traces.
diff --git a/tools/naming/simulator/shell_functions.go b/tools/naming/simulator/shell_functions.go
index 552635b..5a8f899 100644
--- a/tools/naming/simulator/shell_functions.go
+++ b/tools/naming/simulator/shell_functions.go
@@ -43,11 +43,11 @@
}
func mountServer(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
- if err := checkArgs(args[1:], -3, "<mount point> <server> <ttl> [M][R]"); err != nil {
+ if err := checkArgs(args, -3, "<mount point> <server> <ttl> [M][R]"); err != nil {
return err
}
var opts []naming.MountOpt
- for _, arg := range args[4:] {
+ for _, arg := range args[3:] {
for _, c := range arg {
switch c {
case 'R':
@@ -57,7 +57,7 @@
}
}
}
- mp, server, ttlstr := args[1], args[2], args[3]
+ mp, server, ttlstr := args[0], args[1], args[2]
ttl, err := time.ParseDuration(ttlstr)
if err != nil {
return fmt.Errorf("failed to parse time from %q", ttlstr)
@@ -71,7 +71,7 @@
}
func namespaceCache(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
- if err := checkArgs(args[1:], 1, "on|off"); err != nil {
+ if err := checkArgs(args, 1, "on|off"); err != nil {
return err
}
disable := true
@@ -90,10 +90,10 @@
type resolver func(ctx *context.T, name string, opts ...naming.ResolveOpt) (me *naming.MountEntry, err error)
func resolve(fn resolver, stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
- if err := checkArgs(args[1:], 1, "<name>"); err != nil {
+ if err := checkArgs(args, 1, "<name>"); err != nil {
return err
}
- name := args[1]
+ name := args[0]
me, err := fn(ctx, name)
if err != nil {
fmt.Fprintf(stdout, "RN=0\n")
diff --git a/tools/profile/doc.go b/tools/profile/doc.go
index 2a79b38..e50d9cb 100644
--- a/tools/profile/doc.go
+++ b/tools/profile/doc.go
@@ -37,9 +37,19 @@
directory to use for storing security credentials
-veyron.namespace.root=[/ns.dev.v.io:8101]
local namespace root; can be repeated to provided multiple roots
+ -veyron.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -veyron.tcp.address=
+ address to listen on
+ -veyron.tcp.protocol=tcp
+ protocol to listen with
-veyron.vtrace.cache_size=1024
The number of vtrace traces to store in memory.
- -veyron.vtrace.dump_on_shutdown=false
+ -veyron.vtrace.collect_regexp=
+ Spans and annotations that match this regular expression will trigger trace
+ collection.
+ -veyron.vtrace.dump_on_shutdown=true
If true, dump all stored traces on runtime shutdown.
-veyron.vtrace.sample_rate=0
Rate (from 0.0 to 1.0) to sample vtrace traces.
diff --git a/tools/profile/main.go b/tools/profile/main.go
index e9b7573..65f7187 100644
--- a/tools/profile/main.go
+++ b/tools/profile/main.go
@@ -1,5 +1,5 @@
// The following enables go generate to generate the doc.go file.
-//go:generate go run $VANADIUM_ROOT/tools/go/src/tools/lib/cmdline/testdata/gendoc.go .
+//go:generate go run $VANADIUM_ROOT/release/go/src/v.io/lib/cmdline/testdata/gendoc.go .
package main
diff --git a/tools/servicerunner/main.go b/tools/servicerunner/main.go
index 3e0b345..0631399 100644
--- a/tools/servicerunner/main.go
+++ b/tools/servicerunner/main.go
@@ -55,19 +55,12 @@
}
func main() {
- ctx, shutdown := veyron2.Init()
-
if modules.IsModulesProcess() {
- // TODO(suharshs): This is a hack and we should find a better way to parse flags in the modules.
- // This is needed because the modules commands call veyron2.Init and multiple runtimes cannot
- // be initialized simultaneously.
- // In addition the modules read their args from flag.Args() (all flags after "--") which means
- // the flags must still be parsed before calling modules.Dispatch(). Thus moving veyron2.Init
- // below this clause solves nothing.
- shutdown()
panicOnError(modules.Dispatch())
return
}
+
+ ctx, shutdown := veyron2.Init()
defer shutdown()
vars := map[string]string{}
@@ -78,7 +71,7 @@
}
defer sh.Cleanup(os.Stderr, os.Stderr)
- h, err := sh.Start(core.RootMTCommand, nil, "--", "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0")
+ h, err := sh.Start(core.RootMTCommand, nil, "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0")
panicOnError(err)
panicOnError(updateVars(h, vars, "MT_NAME"))
@@ -90,15 +83,15 @@
// NOTE(sadovsky): The proxyd binary requires --protocol and --address flags
// while the proxyd command instead uses ListenSpec flags.
- h, err = sh.Start(core.ProxyServerCommand, nil, "--", "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0", "test/proxy")
+ h, err = sh.Start(core.ProxyServerCommand, nil, "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0", "test/proxy")
panicOnError(err)
panicOnError(updateVars(h, vars, "PROXY_NAME"))
- h, err = sh.Start(core.WSPRCommand, nil, "--", "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0", "--veyron.proxy=test/proxy", "--identd=test/identd")
+ h, err = sh.Start(core.WSPRCommand, nil, "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0", "--veyron.proxy=test/proxy", "--identd=test/identd")
panicOnError(err)
panicOnError(updateVars(h, vars, "WSPR_ADDR"))
- h, err = sh.Start(core.TestIdentitydCommand, nil, "--", "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0", "--veyron.proxy=test/proxy", "--host=localhost", "--httpaddr=localhost:0")
+ h, err = sh.Start(core.TestIdentitydCommand, nil, "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0", "--veyron.proxy=test/proxy", "--host=localhost", "--httpaddr=localhost:0")
panicOnError(err)
panicOnError(updateVars(h, vars, "TEST_IDENTITYD_NAME", "TEST_IDENTITYD_HTTP_ADDR"))
diff --git a/tools/vrpc/doc.go b/tools/vrpc/doc.go
index f5ff56d..df0d470 100644
--- a/tools/vrpc/doc.go
+++ b/tools/vrpc/doc.go
@@ -36,6 +36,13 @@
directory to use for storing security credentials
-veyron.namespace.root=[/ns.dev.v.io:8101]
local namespace root; can be repeated to provided multiple roots
+ -veyron.proxy=
+ object name of proxy service to use to export services across network
+ boundaries
+ -veyron.tcp.address=
+ address to listen on
+ -veyron.tcp.protocol=tcp
+ protocol to listen with
-veyron.vtrace.cache_size=1024
The number of vtrace traces to store in memory.
-veyron.vtrace.collect_regexp=