<commit_before>package opts // import "github.com/docker/docker/opts"

import (
	"fmt"
	"strings"
	"testing"
)

func TestParseHost(t *testing.T) {
	invalid := []string{
		"something with spaces",
		"://",
		"unknown://",
		"tcp://:port",
		"tcp://invalid:port",
		"tcp://:5555/",
		"tcp://:5555/p",
		"tcp://0.0.0.0:5555/",
		"tcp://0.0.0.0:5555/p",
		"tcp://[::1]:/",
		"tcp://[::1]:5555/",
		"tcp://[::1]:5555/p",
		" tcp://:5555/path ",
	}

	valid := map[string]string{
		"":                         DefaultHost,
		" ":                        DefaultHost,
		"  ":                       DefaultHost,
		"fd://":                    "fd://",
		"fd://something":           "fd://something",
		"tcp://host:":              fmt.Sprintf("tcp://host:%d", DefaultHTTPPort),
		"tcp://":                   DefaultTCPHost,
		"tcp://:":                  DefaultTCPHost,
		"tcp://:5555":              fmt.Sprintf("tcp://%s:5555", DefaultHTTPHost),
		"tcp://[::1]:":             fmt.Sprintf(`tcp://[::1]:%d`, DefaultHTTPPort),
		"tcp://[::1]:5555":         `tcp://[::1]:5555`,
		"tcp://0.0.0.0:5555":       "tcp://0.0.0.0:5555",
		"tcp://192.168:5555":       "tcp://192.168:5555",
		"tcp://192.168.0.1:5555":   "tcp://192.168.0.1:5555",
		"tcp://0.0.0.0:1234567890": "tcp://0.0.0.0:1234567890", // yeah it's valid :P
		"tcp://docker.com:5555":    "tcp://docker.com:5555",
		"unix://":                  "unix://" + DefaultUnixSocket,
		"unix://path/to/socket":    "unix://path/to/socket",
		"npipe://":                 "npipe://" + DefaultNamedPipe,
		"npipe:////./pipe/foo":     "npipe:////./pipe/foo",
	}

	for _, value := range invalid {
		if _, err := ParseHost(false, false, value); err == nil {
			t.Errorf("Expected an error for %v, got [nil]", value)
		}
	}

	for value, expected := range valid {
		if actual, err := ParseHost(false, false, value); err != nil || actual != expected {
			t.Errorf("Expected for %v [%v], got [%v, %v]", value, expected, actual, err)
		}
	}
}

func TestParseDockerDaemonHost(t *testing.T) {
	invalids := map[string]string{
		"tcp:a.b.c.d":                   `parse "tcp://tcp:a.b.c.d": invalid port ":a.b.c.d" after host`,
		"tcp:a.b.c.d/path":              `parse "tcp://tcp:a.b.c.d/path": invalid port ":a.b.c.d" after host`,
		"udp://127.0.0.1":               "Invalid bind address format: udp://127.0.0.1",
		"udp://127.0.0.1:5555":          "Invalid bind address format: udp://127.0.0.1:5555",
		"tcp://unix:///run/docker.sock": "Invalid proto, expected tcp: unix:///run/docker.sock",
		" tcp://:5555/path ":            "Invalid bind address format:  tcp://:5555/path ",
		"":                              "Invalid bind address format: ",
		":5555/path":                    "invalid bind address (:5555/path): should not contain a path element",
		"0.0.0.1:5555/path":             "invalid bind address (0.0.0.1:5555/path): should not contain a path element",
		"[::1]:5555/path":               "invalid bind address ([::1]:5555/path): should not contain a path element",
		"[0:0:0:0:0:0:0:1]:5555/path":   "invalid bind address ([0:0:0:0:0:0:0:1]:5555/path): should not contain a path element",
		"tcp://:5555/path":              "invalid bind address (:5555/path): should not contain a path element",
		"localhost:5555/path":           "invalid bind address (localhost:5555/path): should not contain a path element",
	}
	valids := map[string]string{
		":":                       DefaultTCPHost,
		":5555":                   fmt.Sprintf("tcp://%s:5555", DefaultHTTPHost),
		"0.0.0.1:":                fmt.Sprintf("tcp://0.0.0.1:%d", DefaultHTTPPort),
		"0.0.0.1:5555":            "tcp://0.0.0.1:5555",
		"[::1]:":                  fmt.Sprintf("tcp://[::1]:%d", DefaultHTTPPort),
		"[::1]:5555":              "tcp://[::1]:5555",
		"[0:0:0:0:0:0:0:1]:":      fmt.Sprintf("tcp://[0:0:0:0:0:0:0:1]:%d", DefaultHTTPPort),
		"[0:0:0:0:0:0:0:1]:5555":  "tcp://[0:0:0:0:0:0:0:1]:5555",
		"localhost":               fmt.Sprintf("tcp://localhost:%d", DefaultHTTPPort),
		"localhost:":              fmt.Sprintf("tcp://localhost:%d", DefaultHTTPPort),
		"localhost:5555":          "tcp://localhost:5555",
		"fd://":                   "fd://",
		"fd://something":          "fd://something",
		"npipe://":                "npipe://" + DefaultNamedPipe,
		"npipe:////./pipe/foo":    "npipe:////./pipe/foo",
		"tcp://":                  DefaultTCPHost,
		"tcp://:5555":             fmt.Sprintf("tcp://%s:5555", DefaultHTTPHost),
		"tcp://[::1]:":            fmt.Sprintf("tcp://[::1]:%d", DefaultHTTPPort),
		"tcp://[::1]:5555":        "tcp://[::1]:5555",
		"unix://":                 "unix://" + DefaultUnixSocket,
		"unix:///run/docker.sock": "unix:///run/docker.sock",
	}
	for invalidAddr, expectedError := range invalids {
		if addr, err := parseDaemonHost(invalidAddr); err == nil || err.Error() != expectedError {
			t.Errorf("tcp %v address expected error %q return, got %q and addr %v", invalidAddr, expectedError, err, addr)
		}
	}
	for validAddr, expectedAddr := range valids {
		if addr, err := parseDaemonHost(validAddr); err != nil || addr != expectedAddr {
			t.Errorf("%v -> expected %v, got (%v) addr (%v)", validAddr, expectedAddr, err, addr)
		}
	}
}

func TestParseTCP(t *testing.T) {
	var (
		defaultHTTPHost = "tcp://127.0.0.1:8888"
	)
	invalids := map[string]string{
		"tcp:a.b.c.d":                 `parse "tcp://tcp:a.b.c.d": invalid port ":a.b.c.d" after host`,
		"tcp:a.b.c.d/path":            `parse "tcp://tcp:a.b.c.d/path": invalid port ":a.b.c.d" after host`,
		"udp://127.0.0.1":             "Invalid proto, expected tcp: udp://127.0.0.1",
		"udp://127.0.0.1:5555":        "Invalid proto, expected tcp: udp://127.0.0.1:5555",
		":5555/path":                  "invalid bind address (:5555/path): should not contain a path element",
		"0.0.0.1:5555/path":           "invalid bind address (0.0.0.1:5555/path): should not contain a path element",
		"[::1]:5555/path":             "invalid bind address ([::1]:5555/path): should not contain a path element",
		"[0:0:0:0:0:0:0:1]:5555/path": "invalid bind address ([0:0:0:0:0:0:0:1]:5555/path): should not contain a path element",
		"tcp://:5555/path":            "invalid bind address (tcp://:5555/path): should not contain a path element",
		"localhost:5555/path":         "invalid bind address (localhost:5555/path): should not contain a path element",
	}
	valids := map[string]string{
		"":                       defaultHTTPHost,
		"0.0.0.1":                "tcp://0.0.0.1:8888",
		"0.0.0.1:":               "tcp://0.0.0.1:8888",
		"0.0.0.1:5555":           "tcp://0.0.0.1:5555",
		":":                      "tcp://127.0.0.1:8888",
		":5555":                  "tcp://127.0.0.1:5555",
		"::1":                    "tcp://[::1]:8888",
		"[::1]:":                 "tcp://[::1]:8888",
		"[::1]:5555":             "tcp://[::1]:5555",
		"[0:0:0:0:0:0:0:1]:":     "tcp://[0:0:0:0:0:0:0:1]:8888",
		"[0:0:0:0:0:0:0:1]:5555": "tcp://[0:0:0:0:0:0:0:1]:5555",
		"localhost":              "tcp://localhost:8888",
		"localhost:":             "tcp://localhost:8888",
		"localhost:5555":         "tcp://localhost:5555",
		"tcp://":                 defaultHTTPHost,
		"tcp://:":                defaultHTTPHost,
		"tcp://:5555":            "tcp://127.0.0.1:5555",
	}
	for invalidAddr, expectedError := range invalids {
		if addr, err := ParseTCPAddr(invalidAddr, defaultHTTPHost); err == nil || err.Error() != expectedError {
			t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr)
		}
	}
	for validAddr, expectedAddr := range valids {
		if addr, err := ParseTCPAddr(validAddr, defaultHTTPHost); err != nil || addr != expectedAddr {
			t.Errorf("%v -> expected %v, got %v and addr %v", validAddr, expectedAddr, err, addr)
		}
	}
}

func TestParseInvalidUnixAddrInvalid(t *testing.T) {
	if _, err := parseSimpleProtoAddr("unix", "tcp://127.0.0.1", "unix:///var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" {
		t.Fatalf("Expected an error, got %v", err)
	}
	if _, err := parseSimpleProtoAddr("unix", "unix://tcp://127.0.0.1", "/var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" {
		t.Fatalf("Expected an error, got %v", err)
	}
	if v, err := parseSimpleProtoAddr("unix", "", "/var/run/docker.sock"); err != nil || v != "unix:///var/run/docker.sock" {
		t.Fatalf("Expected an %v, got %v", v, "unix:///var/run/docker.sock")
	}
}

func TestValidateExtraHosts(t *testing.T) {
	valid := []string{
		`myhost:192.168.0.1`,
		`thathost:10.0.2.1`,
		`anipv6host:2003:ab34:e::1`,
		`ipv6local:::1`,
	}

	invalid := map[string]string{
		`myhost:192.notanipaddress.1`:  `invalid IP`,
		`thathost-nosemicolon10.0.0.1`: `bad format`,
		`anipv6host:::::1`:             `invalid IP`,
		`ipv6local:::0::`:              `invalid IP`,
	}

	for _, extrahost := range valid {
		if _, err := ValidateExtraHost(extrahost); err != nil {
			t.Fatalf("ValidateExtraHost(`"+extrahost+"`) should succeed: error %v", err)
		}
	}

	for extraHost, expectedError := range invalid {
		if _, err := ValidateExtraHost(extraHost); err == nil {
			t.Fatalf("ValidateExtraHost(`%q`) should have failed validation", extraHost)
		} else {
			if !strings.Contains(err.Error(), expectedError) {
				t.Fatalf("ValidateExtraHost(`%q`) error should contain %q", extraHost, expectedError)
			}
		}
	}
}
<commit_msg>opts: use subtests, and split checks<commit_after>package opts // import "github.com/docker/docker/opts"

import (
	"fmt"
	"strings"
	"testing"
)

func TestParseHost(t *testing.T) {
	invalid := []string{
		"something with spaces",
		"://",
		"unknown://",
		"tcp://:port",
		"tcp://invalid:port",
		"tcp://:5555/",
		"tcp://:5555/p",
		"tcp://0.0.0.0:5555/",
		"tcp://0.0.0.0:5555/p",
		"tcp://[::1]:/",
		"tcp://[::1]:5555/",
		"tcp://[::1]:5555/p",
		" tcp://:5555/path ",
	}

	valid := map[string]string{
		"":                         DefaultHost,
		" ":                        DefaultHost,
		"  ":                       DefaultHost,
		"fd://":                    "fd://",
		"fd://something":           "fd://something",
		"tcp://host:":              fmt.Sprintf("tcp://host:%d", DefaultHTTPPort),
		"tcp://":                   DefaultTCPHost,
		"tcp://:":                  DefaultTCPHost,
		"tcp://:5555":              fmt.Sprintf("tcp://%s:5555", DefaultHTTPHost),
		"tcp://[::1]:":             fmt.Sprintf(`tcp://[::1]:%d`, DefaultHTTPPort),
		"tcp://[::1]:5555":         `tcp://[::1]:5555`,
		"tcp://0.0.0.0:5555":       "tcp://0.0.0.0:5555",
		"tcp://192.168:5555":       "tcp://192.168:5555",
		"tcp://192.168.0.1:5555":   "tcp://192.168.0.1:5555",
		"tcp://0.0.0.0:1234567890": "tcp://0.0.0.0:1234567890", // yeah it's valid :P
		"tcp://docker.com:5555":    "tcp://docker.com:5555",
		"unix://":                  "unix://" + DefaultUnixSocket,
		"unix://path/to/socket":    "unix://path/to/socket",
		"npipe://":                 "npipe://" + DefaultNamedPipe,
		"npipe:////./pipe/foo":     "npipe:////./pipe/foo",
	}

	for _, value := range invalid {
		t.Run(value, func(t *testing.T) {
			_, err := ParseHost(false, false, value)
			if err == nil {
				t.Errorf("expected an error, got [nil]")
			}
		})
	}

	for value, expected := range valid {
		t.Run(value, func(t *testing.T) {
			actual, err := ParseHost(false, false, value)
			if err != nil {
				t.Errorf(`unexpected error: "%v"`, err)
			}
			if actual != expected {
				t.Errorf(`expected "%s", got "%s""`, expected, actual)
			}
		})
	}
}

func TestParseDockerDaemonHost(t *testing.T) {
	invalids := map[string]string{
		"tcp:a.b.c.d":                   `parse "tcp://tcp:a.b.c.d": invalid port ":a.b.c.d" after host`,
		"tcp:a.b.c.d/path":              `parse "tcp://tcp:a.b.c.d/path": invalid port ":a.b.c.d" after host`,
		"udp://127.0.0.1":               "Invalid bind address format: udp://127.0.0.1",
		"udp://127.0.0.1:5555":          "Invalid bind address format: udp://127.0.0.1:5555",
		"tcp://unix:///run/docker.sock": "Invalid proto, expected tcp: unix:///run/docker.sock",
		" tcp://:5555/path ":            "Invalid bind address format:  tcp://:5555/path ",
		"":                              "Invalid bind address format: ",
		":5555/path":                    "invalid bind address (:5555/path): should not contain a path element",
		"0.0.0.1:5555/path":             "invalid bind address (0.0.0.1:5555/path): should not contain a path element",
		"[::1]:5555/path":               "invalid bind address ([::1]:5555/path): should not contain a path element",
		"[0:0:0:0:0:0:0:1]:5555/path":   "invalid bind address ([0:0:0:0:0:0:0:1]:5555/path): should not contain a path element",
		"tcp://:5555/path":              "invalid bind address (:5555/path): should not contain a path element",
		"localhost:5555/path":           "invalid bind address (localhost:5555/path): should not contain a path element",
	}
	valids := map[string]string{
		":":                       DefaultTCPHost,
		":5555":                   fmt.Sprintf("tcp://%s:5555", DefaultHTTPHost),
		"0.0.0.1:":                fmt.Sprintf("tcp://0.0.0.1:%d", DefaultHTTPPort),
		"0.0.0.1:5555":            "tcp://0.0.0.1:5555",
		"[::1]:":                  fmt.Sprintf("tcp://[::1]:%d", DefaultHTTPPort),
		"[::1]:5555":              "tcp://[::1]:5555",
		"[0:0:0:0:0:0:0:1]:":      fmt.Sprintf("tcp://[0:0:0:0:0:0:0:1]:%d", DefaultHTTPPort),
		"[0:0:0:0:0:0:0:1]:5555":  "tcp://[0:0:0:0:0:0:0:1]:5555",
		"localhost":               fmt.Sprintf("tcp://localhost:%d", DefaultHTTPPort),
		"localhost:":              fmt.Sprintf("tcp://localhost:%d", DefaultHTTPPort),
		"localhost:5555":          "tcp://localhost:5555",
		"fd://":                   "fd://",
		"fd://something":          "fd://something",
		"npipe://":                "npipe://" + DefaultNamedPipe,
		"npipe:////./pipe/foo":    "npipe:////./pipe/foo",
		"tcp://":                  DefaultTCPHost,
		"tcp://:5555":             fmt.Sprintf("tcp://%s:5555", DefaultHTTPHost),
		"tcp://[::1]:":            fmt.Sprintf("tcp://[::1]:%d", DefaultHTTPPort),
		"tcp://[::1]:5555":        "tcp://[::1]:5555",
		"unix://":                 "unix://" + DefaultUnixSocket,
		"unix:///run/docker.sock": "unix:///run/docker.sock",
	}
	for invalidAddr, expectedError := range invalids {
		t.Run(invalidAddr, func(t *testing.T) {
			addr, err := parseDaemonHost(invalidAddr)
			if err == nil || err.Error() != expectedError {
				t.Errorf(`expected error "%s", got "%v"`, expectedError, err)
			}
			if addr != "" {
				t.Errorf(`expected addr to be empty, got "%s""`, addr)
			}
		})
	}
	for validAddr, expectedAddr := range valids {
		t.Run(validAddr, func(t *testing.T) {
			addr, err := parseDaemonHost(validAddr)
			if err != nil {
				t.Errorf(`unexpected error: "%v"`, err)
			}
			if addr != expectedAddr {
				t.Errorf(`expected "%s", got "%s""`, expectedAddr, addr)
			}
		})
	}
}

func TestParseTCP(t *testing.T) {
	var (
		defaultHTTPHost = "tcp://127.0.0.1:8888"
	)
	invalids := map[string]string{
		"tcp:a.b.c.d":                 `parse "tcp://tcp:a.b.c.d": invalid port ":a.b.c.d" after host`,
		"tcp:a.b.c.d/path":            `parse "tcp://tcp:a.b.c.d/path": invalid port ":a.b.c.d" after host`,
		"udp://127.0.0.1":             "Invalid proto, expected tcp: udp://127.0.0.1",
		"udp://127.0.0.1:5555":        "Invalid proto, expected tcp: udp://127.0.0.1:5555",
		":5555/path":                  "invalid bind address (:5555/path): should not contain a path element",
		"0.0.0.1:5555/path":           "invalid bind address (0.0.0.1:5555/path): should not contain a path element",
		"[::1]:5555/path":             "invalid bind address ([::1]:5555/path): should not contain a path element",
		"[0:0:0:0:0:0:0:1]:5555/path": "invalid bind address ([0:0:0:0:0:0:0:1]:5555/path): should not contain a path element",
		"tcp://:5555/path":            "invalid bind address (tcp://:5555/path): should not contain a path element",
		"localhost:5555/path":         "invalid bind address (localhost:5555/path): should not contain a path element",
	}
	valids := map[string]string{
		"":                       defaultHTTPHost,
		"0.0.0.1":                "tcp://0.0.0.1:8888",
		"0.0.0.1:":               "tcp://0.0.0.1:8888",
		"0.0.0.1:5555":           "tcp://0.0.0.1:5555",
		":":                      "tcp://127.0.0.1:8888",
		":5555":                  "tcp://127.0.0.1:5555",
		"::1":                    "tcp://[::1]:8888",
		"[::1]:":                 "tcp://[::1]:8888",
		"[::1]:5555":             "tcp://[::1]:5555",
		"[0:0:0:0:0:0:0:1]:":     "tcp://[0:0:0:0:0:0:0:1]:8888",
		"[0:0:0:0:0:0:0:1]:5555": "tcp://[0:0:0:0:0:0:0:1]:5555",
		"localhost":              "tcp://localhost:8888",
		"localhost:":             "tcp://localhost:8888",
		"localhost:5555":         "tcp://localhost:5555",
		"tcp://":                 defaultHTTPHost,
		"tcp://:":                defaultHTTPHost,
		"tcp://:5555":            "tcp://127.0.0.1:5555",
	}
	for invalidAddr, expectedError := range invalids {
		t.Run(invalidAddr, func(t *testing.T) {
			addr, err := ParseTCPAddr(invalidAddr, defaultHTTPHost)
			if err == nil || err.Error() != expectedError {
				t.Errorf(`expected error "%s", got "%v"`, expectedError, err)
			}
			if addr != "" {
				t.Errorf(`expected addr to be empty, got "%s""`, addr)
			}
		})
	}
	for validAddr, expectedAddr := range valids {
		t.Run(validAddr, func(t *testing.T) {
			addr, err := ParseTCPAddr(validAddr, defaultHTTPHost)
			if err != nil {
				t.Errorf(`unexpected error: "%v"`, err)
			}
			if addr != expectedAddr {
				t.Errorf(`expected "%s", got "%s""`, expectedAddr, addr)
			}
		})
	}
}

func TestParseInvalidUnixAddrInvalid(t *testing.T) {
	if _, err := parseSimpleProtoAddr("unix", "tcp://127.0.0.1", "unix:///var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" {
		t.Fatalf("Expected an error, got %v", err)
	}
	if _, err := parseSimpleProtoAddr("unix", "unix://tcp://127.0.0.1", "/var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" {
		t.Fatalf("Expected an error, got %v", err)
	}
	if v, err := parseSimpleProtoAddr("unix", "", "/var/run/docker.sock"); err != nil || v != "unix:///var/run/docker.sock" {
		t.Fatalf("Expected an %v, got %v", v, "unix:///var/run/docker.sock")
	}
}

func TestValidateExtraHosts(t *testing.T) {
	valid := []string{
		`myhost:192.168.0.1`,
		`thathost:10.0.2.1`,
		`anipv6host:2003:ab34:e::1`,
		`ipv6local:::1`,
	}

	invalid := map[string]string{
		`myhost:192.notanipaddress.1`:  `invalid IP`,
		`thathost-nosemicolon10.0.0.1`: `bad format`,
		`anipv6host:::::1`:             `invalid IP`,
		`ipv6local:::0::`:              `invalid IP`,
	}

	for _, extrahost := range valid {
		if _, err := ValidateExtraHost(extrahost); err != nil {
			t.Fatalf("ValidateExtraHost(`"+extrahost+"`) should succeed: error %v", err)
		}
	}

	for extraHost, expectedError := range invalid {
		if _, err := ValidateExtraHost(extraHost); err == nil {
			t.Fatalf("ValidateExtraHost(`%q`) should have failed validation", extraHost)
		} else {
			if !strings.Contains(err.Error(), expectedError) {
				t.Fatalf("ValidateExtraHost(`%q`) error should contain %q", extraHost, expectedError)
			}
		}
	}
}
<|endoftext|>


<commit_before>package testing

import (
	"context"
	"testing"

	csms "github.com/libp2p/go-conn-security-multistream"
	metrics "github.com/libp2p/go-libp2p-metrics"
	inet "github.com/libp2p/go-libp2p-net"
	pstore "github.com/libp2p/go-libp2p-peerstore"
	secio "github.com/libp2p/go-libp2p-secio"
	tptu "github.com/libp2p/go-libp2p-transport-upgrader"
	tcp "github.com/libp2p/go-tcp-transport"
	tu "github.com/libp2p/go-testutil"
	msmux "github.com/whyrusleeping/go-smux-multistream"
	yamux "github.com/whyrusleeping/go-smux-yamux"

	swarm "github.com/libp2p/go-libp2p-swarm"
)

type config struct {
	disableReuseport bool
	dialOnly         bool
}

// Option is an option that can be passed when constructing a test swarm.
type Option func(*testing.T, *config)

// OptDisableReuseport disables reuseport in this test swarm.
var OptDisableReuseport Option = func(_ *testing.T, c *config) {
	c.disableReuseport = true
}

// OptDialOnly prevents the test swarm from listening.
var OptDialOnly Option = func(_ *testing.T, c *config) {
	c.dialOnly = true
}

// GenUpgrader creates a new connection upgrader for use with this swarm.
func GenUpgrader(n *swarm.Swarm) *tptu.Upgrader {
	id := n.LocalPeer()
	pk := n.Peerstore().PrivKey(id)
	secMuxer := new(csms.SSMuxer)
	secMuxer.AddTransport(secio.ID, &secio.Transport{
		LocalID:    id,
		PrivateKey: pk,
	})

	stMuxer := msmux.NewBlankTransport()
	stMuxer.AddTransport("/yamux/1.0.0", yamux.DefaultTransport)

	return &tptu.Upgrader{
		Secure:  secMuxer,
		Muxer:   stMuxer,
		Filters: n.Filters,
	}

}

// GenSwarm generates a new test swarm.
func GenSwarm(t *testing.T, ctx context.Context, opts ...Option) *swarm.Swarm {
	var cfg config
	for _, o := range opts {
		o(t, &cfg)
	}

	p := tu.RandPeerNetParamsOrFatal(t)

	ps := pstore.NewPeerstore()
	ps.AddPubKey(p.ID, p.PubKey)
	ps.AddPrivKey(p.ID, p.PrivKey)
	s := swarm.NewSwarm(ctx, p.ID, ps, metrics.NewBandwidthCounter())

	tcpTransport := tcp.NewTCPTransport(GenUpgrader(s))
	tcpTransport.DisableReuseport = cfg.disableReuseport

	if err := s.AddTransport(tcpTransport); err != nil {
		t.Fatal(err)
	}

	if !cfg.dialOnly {
		if err := s.Listen(p.Addr); err != nil {
			t.Fatal(err)
		}

		s.Peerstore().AddAddrs(p.ID, s.ListenAddresses(), pstore.PermanentAddrTTL)
	}

	return s
}

// DivulgeAddresses adds swarm a's addresses to swarm b's peerstore.
func DivulgeAddresses(a, b inet.Network) {
	id := a.LocalPeer()
	addrs := a.Peerstore().Addrs(id)
	b.Peerstore().AddAddrs(id, addrs, pstore.PermanentAddrTTL)
}
<commit_msg>gx: update go-libp2p-peerstore<commit_after>package testing

import (
	"context"
	"testing"

	csms "github.com/libp2p/go-conn-security-multistream"
	metrics "github.com/libp2p/go-libp2p-metrics"
	inet "github.com/libp2p/go-libp2p-net"
	pstore "github.com/libp2p/go-libp2p-peerstore"
	pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem"
	secio "github.com/libp2p/go-libp2p-secio"
	tptu "github.com/libp2p/go-libp2p-transport-upgrader"
	tcp "github.com/libp2p/go-tcp-transport"
	tu "github.com/libp2p/go-testutil"
	msmux "github.com/whyrusleeping/go-smux-multistream"
	yamux "github.com/whyrusleeping/go-smux-yamux"

	swarm "github.com/libp2p/go-libp2p-swarm"
)

type config struct {
	disableReuseport bool
	dialOnly         bool
}

// Option is an option that can be passed when constructing a test swarm.
type Option func(*testing.T, *config)

// OptDisableReuseport disables reuseport in this test swarm.
var OptDisableReuseport Option = func(_ *testing.T, c *config) {
	c.disableReuseport = true
}

// OptDialOnly prevents the test swarm from listening.
var OptDialOnly Option = func(_ *testing.T, c *config) {
	c.dialOnly = true
}

// GenUpgrader creates a new connection upgrader for use with this swarm.
func GenUpgrader(n *swarm.Swarm) *tptu.Upgrader {
	id := n.LocalPeer()
	pk := n.Peerstore().PrivKey(id)
	secMuxer := new(csms.SSMuxer)
	secMuxer.AddTransport(secio.ID, &secio.Transport{
		LocalID:    id,
		PrivateKey: pk,
	})

	stMuxer := msmux.NewBlankTransport()
	stMuxer.AddTransport("/yamux/1.0.0", yamux.DefaultTransport)

	return &tptu.Upgrader{
		Secure:  secMuxer,
		Muxer:   stMuxer,
		Filters: n.Filters,
	}

}

// GenSwarm generates a new test swarm.
func GenSwarm(t *testing.T, ctx context.Context, opts ...Option) *swarm.Swarm {
	var cfg config
	for _, o := range opts {
		o(t, &cfg)
	}

	p := tu.RandPeerNetParamsOrFatal(t)

	ps := pstoremem.NewPeerstore()
	ps.AddPubKey(p.ID, p.PubKey)
	ps.AddPrivKey(p.ID, p.PrivKey)
	s := swarm.NewSwarm(ctx, p.ID, ps, metrics.NewBandwidthCounter())

	tcpTransport := tcp.NewTCPTransport(GenUpgrader(s))
	tcpTransport.DisableReuseport = cfg.disableReuseport

	if err := s.AddTransport(tcpTransport); err != nil {
		t.Fatal(err)
	}

	if !cfg.dialOnly {
		if err := s.Listen(p.Addr); err != nil {
			t.Fatal(err)
		}

		s.Peerstore().AddAddrs(p.ID, s.ListenAddresses(), pstore.PermanentAddrTTL)
	}

	return s
}

// DivulgeAddresses adds swarm a's addresses to swarm b's peerstore.
func DivulgeAddresses(a, b inet.Network) {
	id := a.LocalPeer()
	addrs := a.Peerstore().Addrs(id)
	b.Peerstore().AddAddrs(id, addrs, pstore.PermanentAddrTTL)
}
<|endoftext|>


<commit_before>package out

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"gopkg.in/yaml.v2"

	"github.com/pivotal-cf-experimental/pivnet-resource/concourse"
	"github.com/pivotal-cf-experimental/pivnet-resource/globs"
	"github.com/pivotal-cf-experimental/pivnet-resource/logger"
	"github.com/pivotal-cf-experimental/pivnet-resource/md5"
	"github.com/pivotal-cf-experimental/pivnet-resource/metadata"
	"github.com/pivotal-cf-experimental/pivnet-resource/out/validator"
	"github.com/pivotal-cf-experimental/pivnet-resource/pivnet"
	"github.com/pivotal-cf-experimental/pivnet-resource/s3"
	"github.com/pivotal-cf-experimental/pivnet-resource/uploader"
	"github.com/pivotal-cf-experimental/pivnet-resource/useragent"
)

const (
	defaultBucket = "pivotalnetwork"
	defaultRegion = "eu-west-1"
)

type OutCommand struct {
	binaryVersion   string
	logger          logger.Logger
	outDir          string
	sourcesDir      string
	logFilePath     string
	s3OutBinaryName string
}

type OutCommandConfig struct {
	BinaryVersion   string
	Logger          logger.Logger
	OutDir          string
	SourcesDir      string
	LogFilePath     string
	S3OutBinaryName string
}

func NewOutCommand(config OutCommandConfig) *OutCommand {
	return &OutCommand{
		binaryVersion:   config.BinaryVersion,
		logger:          config.Logger,
		outDir:          config.OutDir,
		sourcesDir:      config.SourcesDir,
		logFilePath:     config.LogFilePath,
		s3OutBinaryName: config.S3OutBinaryName,
	}
}

func (c *OutCommand) Run(input concourse.OutRequest) (concourse.OutResponse, error) {
	if c.outDir == "" {
		return concourse.OutResponse{}, fmt.Errorf("%s must be provided", "out dir")
	}

	err := validator.NewValidator(input).Validate()
	if err != nil {
		return concourse.OutResponse{}, err
	}

	c.logger.Debugf("Received input: %+v\n", input)

	var m metadata.Metadata
	if input.Params.MetadataFile != "" {
		metadataFilepath := filepath.Join(c.sourcesDir, input.Params.MetadataFile)
		metadataBytes, err := ioutil.ReadFile(metadataFilepath)
		if err != nil {
			return concourse.OutResponse{}, fmt.Errorf("metadata_file could not be read: %s", err.Error())
		}

		err = yaml.Unmarshal(metadataBytes, &m)
		if err != nil {
			return concourse.OutResponse{}, fmt.Errorf("metadata_file is invalid: %s", err.Error())
		}
	}

	globber := globs.NewGlobber(globs.GlobberConfig{
		FileGlob:   input.Params.FileGlob,
		SourcesDir: c.sourcesDir,
		Logger:     c.logger,
	})

	exactGlobs, err := globber.ExactGlobs()
	if err != nil {
		log.Fatalln(err)
	}

	var missingFiles []string
	for _, f := range m.ProductFiles {
		if !contains(exactGlobs, f.File) {
			missingFiles = append(missingFiles, f.File)
		}
	}

	if len(missingFiles) > 0 {
		return concourse.OutResponse{},
			fmt.Errorf("product_files were provided in metadata that match no globs: %v", missingFiles)
	}

	var endpoint string
	if input.Source.Endpoint != "" {
		endpoint = input.Source.Endpoint
	} else {
		endpoint = pivnet.Endpoint
	}

	productSlug := input.Source.ProductSlug

	clientConfig := pivnet.NewClientConfig{
		Endpoint:  endpoint,
		Token:     input.Source.APIToken,
		UserAgent: useragent.UserAgent(c.binaryVersion, "put", productSlug),
	}
	pivnetClient := pivnet.NewClient(
		clientConfig,
		c.logger,
	)

	productVersion := readStringContents(c.sourcesDir, input.Params.VersionFile)

	existingVersions, err := pivnetClient.ProductVersions(productSlug)
	if err != nil {
		return concourse.OutResponse{}, err
	}

	for _, v := range existingVersions {
		if v == productVersion {
			return concourse.OutResponse{}, fmt.Errorf("release already exists with version: %s", productVersion)
		}
	}

	config := pivnet.CreateReleaseConfig{
		ProductSlug:     productSlug,
		ReleaseType:     readStringContents(c.sourcesDir, input.Params.ReleaseTypeFile),
		EulaSlug:        readStringContents(c.sourcesDir, input.Params.EulaSlugFile),
		ProductVersion:  productVersion,
		Description:     readStringContents(c.sourcesDir, input.Params.DescriptionFile),
		ReleaseNotesURL: readStringContents(c.sourcesDir, input.Params.ReleaseNotesURLFile),
		ReleaseDate:     readStringContents(c.sourcesDir, input.Params.ReleaseDateFile),
	}

	release, err := pivnetClient.CreateRelease(config)
	if err != nil {
		log.Fatalln(err)
	}

	skipUpload := input.Params.FileGlob == "" && input.Params.FilepathPrefix == ""
	if skipUpload {
		c.logger.Debugf("File glob and s3_filepath_prefix not provided - skipping upload to s3")
	} else {
		bucket := input.Source.Bucket
		if bucket == "" {
			bucket = defaultBucket
		}

		region := input.Source.Region
		if region == "" {
			region = defaultRegion
		}

		logFile, err := os.OpenFile(c.logFilePath, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
		if err != nil {
			panic(err)
		}

		s3Client := s3.NewClient(s3.NewClientConfig{
			AccessKeyID:     input.Source.AccessKeyID,
			SecretAccessKey: input.Source.SecretAccessKey,
			RegionName:      region,
			Bucket:          bucket,

			Logger: c.logger,

			Stdout: os.Stdout,
			Stderr: logFile,

			OutBinaryPath: filepath.Join(c.outDir, c.s3OutBinaryName),
		})

		uploaderClient := uploader.NewClient(uploader.Config{
			FilepathPrefix: input.Params.FilepathPrefix,
			SourcesDir:     c.sourcesDir,

			Logger: c.logger,

			Transport: s3Client,
		})

		for _, exactGlob := range exactGlobs {
			fullFilepath := filepath.Join(c.sourcesDir, exactGlob)
			fileContentsMD5, err := md5.NewFileContentsSummer(fullFilepath).Sum()
			if err != nil {
				log.Fatalln(err)
			}

			remotePath, err := uploaderClient.UploadFile(exactGlob)
			if err != nil {
				return concourse.OutResponse{}, err
			}

			product, err := pivnetClient.FindProductForSlug(productSlug)
			if err != nil {
				log.Fatalln(err)
			}

			var description string
			for _, f := range m.ProductFiles {
				if f.File == exactGlob {
					c.logger.Debugf("exact glob %s matches metadata file: %s\n", exactGlob, f.File)
					description = f.Description
				} else {
					c.logger.Debugf("exact glob %s does not match metadata file: %s\n", exactGlob, f.File)
				}
			}

			filename := filepath.Base(exactGlob)
			c.logger.Debugf(
				"Creating product file: {product_slug: %s, filename: %s, aws_object_key: %s, file_version: %s, description: %s}\n",
				productSlug,
				filename,
				remotePath,
				release.Version,
				description,
			)

			productFile, err := pivnetClient.CreateProductFile(pivnet.CreateProductFileConfig{
				ProductSlug:  productSlug,
				Name:         filename,
				AWSObjectKey: remotePath,
				FileVersion:  release.Version,
				MD5:          fileContentsMD5,
				Description:  description,
			})
			if err != nil {
				return concourse.OutResponse{}, err
			}

			c.logger.Debugf(
				"Adding product file: {product_slug: %s, product_id: %d, filename: %s, product_file_id: %d, release_id: %d}\n",
				productSlug,
				product.ID,
				filename,
				productFile.ID,
				release.ID,
			)

			err = pivnetClient.AddProductFile(product.ID, release.ID, productFile.ID)
			if err != nil {
				log.Fatalln(err)
			}
		}

		if err != nil {
			log.Fatal(err)
		}
	}

	availability := readStringContents(c.sourcesDir, input.Params.AvailabilityFile)
	if availability != "Admins Only" {
		releaseUpdate := pivnet.Release{
			ID:           release.ID,
			Availability: availability,
		}
		release, err = pivnetClient.UpdateRelease(productSlug, releaseUpdate)
		if err != nil {
			log.Fatalln(err)
		}

		if availability == "Selected User Groups Only" {
			userGroupIDs := strings.Split(
				readStringContents(c.sourcesDir, input.Params.UserGroupIDsFile),
				",",
			)

			for _, userGroupIDString := range userGroupIDs {
				userGroupID, err := strconv.Atoi(userGroupIDString)
				if err != nil {
					log.Fatalln(err)
				}

				pivnetClient.AddUserGroup(productSlug, release.ID, userGroupID)
			}
		}
	}

	out := concourse.OutResponse{
		Version: concourse.Version{
			ProductVersion: release.Version,
		},
		Metadata: []concourse.Metadata{
			{Name: "release_type", Value: release.ReleaseType},
			{Name: "release_date", Value: release.ReleaseDate},
			{Name: "description", Value: release.Description},
			{Name: "release_notes_url", Value: release.ReleaseNotesURL},
			{Name: "eula_slug", Value: release.Eula.Slug},
			{Name: "availability", Value: release.Availability},
		},
	}

	return out, nil
}

func readStringContents(sourcesDir, file string) string {
	if file == "" {
		return ""
	}
	fullPath := filepath.Join(sourcesDir, file)
	contents, err := ioutil.ReadFile(fullPath)
	if err != nil {
		log.Fatal(err)
	}
	return string(contents)
}

func contains(s []string, e string) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}
<commit_msg>Out logs metadata contents once parsed.<commit_after>package out

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"gopkg.in/yaml.v2"

	"github.com/pivotal-cf-experimental/pivnet-resource/concourse"
	"github.com/pivotal-cf-experimental/pivnet-resource/globs"
	"github.com/pivotal-cf-experimental/pivnet-resource/logger"
	"github.com/pivotal-cf-experimental/pivnet-resource/md5"
	"github.com/pivotal-cf-experimental/pivnet-resource/metadata"
	"github.com/pivotal-cf-experimental/pivnet-resource/out/validator"
	"github.com/pivotal-cf-experimental/pivnet-resource/pivnet"
	"github.com/pivotal-cf-experimental/pivnet-resource/s3"
	"github.com/pivotal-cf-experimental/pivnet-resource/uploader"
	"github.com/pivotal-cf-experimental/pivnet-resource/useragent"
)

const (
	defaultBucket = "pivotalnetwork"
	defaultRegion = "eu-west-1"
)

type OutCommand struct {
	binaryVersion   string
	logger          logger.Logger
	outDir          string
	sourcesDir      string
	logFilePath     string
	s3OutBinaryName string
}

type OutCommandConfig struct {
	BinaryVersion   string
	Logger          logger.Logger
	OutDir          string
	SourcesDir      string
	LogFilePath     string
	S3OutBinaryName string
}

func NewOutCommand(config OutCommandConfig) *OutCommand {
	return &OutCommand{
		binaryVersion:   config.BinaryVersion,
		logger:          config.Logger,
		outDir:          config.OutDir,
		sourcesDir:      config.SourcesDir,
		logFilePath:     config.LogFilePath,
		s3OutBinaryName: config.S3OutBinaryName,
	}
}

func (c *OutCommand) Run(input concourse.OutRequest) (concourse.OutResponse, error) {
	if c.outDir == "" {
		return concourse.OutResponse{}, fmt.Errorf("%s must be provided", "out dir")
	}

	err := validator.NewValidator(input).Validate()
	if err != nil {
		return concourse.OutResponse{}, err
	}

	c.logger.Debugf("Received input: %+v\n", input)

	var m metadata.Metadata
	if input.Params.MetadataFile != "" {
		metadataFilepath := filepath.Join(c.sourcesDir, input.Params.MetadataFile)
		metadataBytes, err := ioutil.ReadFile(metadataFilepath)
		if err != nil {
			return concourse.OutResponse{}, fmt.Errorf("metadata_file could not be read: %s", err.Error())
		}

		err = yaml.Unmarshal(metadataBytes, &m)
		if err != nil {
			return concourse.OutResponse{}, fmt.Errorf("metadata_file is invalid: %s", err.Error())
		}
	}

	c.logger.Debugf("metadata file parsed; contents: %+v\n", m)

	globber := globs.NewGlobber(globs.GlobberConfig{
		FileGlob:   input.Params.FileGlob,
		SourcesDir: c.sourcesDir,
		Logger:     c.logger,
	})

	exactGlobs, err := globber.ExactGlobs()
	if err != nil {
		log.Fatalln(err)
	}

	var missingFiles []string
	for _, f := range m.ProductFiles {
		if !contains(exactGlobs, f.File) {
			missingFiles = append(missingFiles, f.File)
		}
	}

	if len(missingFiles) > 0 {
		return concourse.OutResponse{},
			fmt.Errorf("product_files were provided in metadata that match no globs: %v", missingFiles)
	}

	var endpoint string
	if input.Source.Endpoint != "" {
		endpoint = input.Source.Endpoint
	} else {
		endpoint = pivnet.Endpoint
	}

	productSlug := input.Source.ProductSlug

	clientConfig := pivnet.NewClientConfig{
		Endpoint:  endpoint,
		Token:     input.Source.APIToken,
		UserAgent: useragent.UserAgent(c.binaryVersion, "put", productSlug),
	}
	pivnetClient := pivnet.NewClient(
		clientConfig,
		c.logger,
	)

	productVersion := readStringContents(c.sourcesDir, input.Params.VersionFile)

	existingVersions, err := pivnetClient.ProductVersions(productSlug)
	if err != nil {
		return concourse.OutResponse{}, err
	}

	for _, v := range existingVersions {
		if v == productVersion {
			return concourse.OutResponse{}, fmt.Errorf("release already exists with version: %s", productVersion)
		}
	}

	config := pivnet.CreateReleaseConfig{
		ProductSlug:     productSlug,
		ReleaseType:     readStringContents(c.sourcesDir, input.Params.ReleaseTypeFile),
		EulaSlug:        readStringContents(c.sourcesDir, input.Params.EulaSlugFile),
		ProductVersion:  productVersion,
		Description:     readStringContents(c.sourcesDir, input.Params.DescriptionFile),
		ReleaseNotesURL: readStringContents(c.sourcesDir, input.Params.ReleaseNotesURLFile),
		ReleaseDate:     readStringContents(c.sourcesDir, input.Params.ReleaseDateFile),
	}

	release, err := pivnetClient.CreateRelease(config)
	if err != nil {
		log.Fatalln(err)
	}

	skipUpload := input.Params.FileGlob == "" && input.Params.FilepathPrefix == ""
	if skipUpload {
		c.logger.Debugf("File glob and s3_filepath_prefix not provided - skipping upload to s3")
	} else {
		bucket := input.Source.Bucket
		if bucket == "" {
			bucket = defaultBucket
		}

		region := input.Source.Region
		if region == "" {
			region = defaultRegion
		}

		logFile, err := os.OpenFile(c.logFilePath, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
		if err != nil {
			panic(err)
		}

		s3Client := s3.NewClient(s3.NewClientConfig{
			AccessKeyID:     input.Source.AccessKeyID,
			SecretAccessKey: input.Source.SecretAccessKey,
			RegionName:      region,
			Bucket:          bucket,

			Logger: c.logger,

			Stdout: os.Stdout,
			Stderr: logFile,

			OutBinaryPath: filepath.Join(c.outDir, c.s3OutBinaryName),
		})

		uploaderClient := uploader.NewClient(uploader.Config{
			FilepathPrefix: input.Params.FilepathPrefix,
			SourcesDir:     c.sourcesDir,

			Logger: c.logger,

			Transport: s3Client,
		})

		for _, exactGlob := range exactGlobs {
			fullFilepath := filepath.Join(c.sourcesDir, exactGlob)
			fileContentsMD5, err := md5.NewFileContentsSummer(fullFilepath).Sum()
			if err != nil {
				log.Fatalln(err)
			}

			remotePath, err := uploaderClient.UploadFile(exactGlob)
			if err != nil {
				return concourse.OutResponse{}, err
			}

			product, err := pivnetClient.FindProductForSlug(productSlug)
			if err != nil {
				log.Fatalln(err)
			}

			var description string
			for _, f := range m.ProductFiles {
				if f.File == exactGlob {
					c.logger.Debugf("exact glob %s matches metadata file: %s\n", exactGlob, f.File)
					description = f.Description
				} else {
					c.logger.Debugf("exact glob %s does not match metadata file: %s\n", exactGlob, f.File)
				}
			}

			filename := filepath.Base(exactGlob)
			c.logger.Debugf(
				"Creating product file: {product_slug: %s, filename: %s, aws_object_key: %s, file_version: %s, description: %s}\n",
				productSlug,
				filename,
				remotePath,
				release.Version,
				description,
			)

			productFile, err := pivnetClient.CreateProductFile(pivnet.CreateProductFileConfig{
				ProductSlug:  productSlug,
				Name:         filename,
				AWSObjectKey: remotePath,
				FileVersion:  release.Version,
				MD5:          fileContentsMD5,
				Description:  description,
			})
			if err != nil {
				return concourse.OutResponse{}, err
			}

			c.logger.Debugf(
				"Adding product file: {product_slug: %s, product_id: %d, filename: %s, product_file_id: %d, release_id: %d}\n",
				productSlug,
				product.ID,
				filename,
				productFile.ID,
				release.ID,
			)

			err = pivnetClient.AddProductFile(product.ID, release.ID, productFile.ID)
			if err != nil {
				log.Fatalln(err)
			}
		}

		if err != nil {
			log.Fatal(err)
		}
	}

	availability := readStringContents(c.sourcesDir, input.Params.AvailabilityFile)
	if availability != "Admins Only" {
		releaseUpdate := pivnet.Release{
			ID:           release.ID,
			Availability: availability,
		}
		release, err = pivnetClient.UpdateRelease(productSlug, releaseUpdate)
		if err != nil {
			log.Fatalln(err)
		}

		if availability == "Selected User Groups Only" {
			userGroupIDs := strings.Split(
				readStringContents(c.sourcesDir, input.Params.UserGroupIDsFile),
				",",
			)

			for _, userGroupIDString := range userGroupIDs {
				userGroupID, err := strconv.Atoi(userGroupIDString)
				if err != nil {
					log.Fatalln(err)
				}

				pivnetClient.AddUserGroup(productSlug, release.ID, userGroupID)
			}
		}
	}

	out := concourse.OutResponse{
		Version: concourse.Version{
			ProductVersion: release.Version,
		},
		Metadata: []concourse.Metadata{
			{Name: "release_type", Value: release.ReleaseType},
			{Name: "release_date", Value: release.ReleaseDate},
			{Name: "description", Value: release.Description},
			{Name: "release_notes_url", Value: release.ReleaseNotesURL},
			{Name: "eula_slug", Value: release.Eula.Slug},
			{Name: "availability", Value: release.Availability},
		},
	}

	return out, nil
}

func readStringContents(sourcesDir, file string) string {
	if file == "" {
		return ""
	}
	fullPath := filepath.Join(sourcesDir, file)
	contents, err := ioutil.ReadFile(fullPath)
	if err != nil {
		log.Fatal(err)
	}
	return string(contents)
}

func contains(s []string, e string) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package weed_server

import (
	"bytes"
	"crypto/md5"
	"hash"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"github.com/chrislusf/seaweedfs/weed/filer"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/operation"
	"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
	"github.com/chrislusf/seaweedfs/weed/security"
	"github.com/chrislusf/seaweedfs/weed/stats"
	"github.com/chrislusf/seaweedfs/weed/util"
)

func (fs *FilerServer) uploadReaderToChunks(w http.ResponseWriter, r *http.Request, reader io.Reader, chunkSize int32, fileName, contentType string, contentLength int64, so *operation.StorageOption) ([]*filer_pb.FileChunk, hash.Hash, int64, error, []byte) {
	var fileChunks []*filer_pb.FileChunk

	md5Hash := md5.New()
	var partReader = ioutil.NopCloser(io.TeeReader(reader, md5Hash))

	chunkOffset := int64(0)
	var smallContent []byte

	for {
		limitedReader := io.LimitReader(partReader, int64(chunkSize))

		data, err := ioutil.ReadAll(limitedReader)
		if err != nil {
			return nil, nil, 0, err, nil
		}
		if chunkOffset == 0 && !isAppend(r) {
			if len(data) < int(fs.option.SaveToFilerLimit) || strings.HasPrefix(r.URL.Path, filer.DirectoryEtcRoot) && len(data) < 4*1024 {
				smallContent = data
				chunkOffset += int64(len(data))
				break
			}
		}
		dataReader := util.NewBytesReader(data)

		// retry to assign a different file id
		var fileId, urlLocation string
		var auth security.EncodedJwt
		var assignErr, uploadErr error
		var uploadResult *operation.UploadResult
		for i := 0; i < 3; i++ {
			// assign one file id for one chunk
			fileId, urlLocation, auth, assignErr = fs.assignNewFileInfo(so)
			if assignErr != nil {
				return nil, nil, 0, assignErr, nil
			}

			// upload the chunk to the volume server
			uploadResult, uploadErr, _ = fs.doUpload(urlLocation, w, r, dataReader, fileName, contentType, nil, auth)
			if uploadErr != nil {
				time.Sleep(251 * time.Millisecond)
				continue
			}
			break
		}
		if uploadErr != nil {
			return nil, nil, 0, uploadErr, nil
		}

		// if last chunk exhausted the reader exactly at the border
		if uploadResult.Size == 0 {
			break
		}
		uploadedMd5 := util.Base64Md5ToBytes(uploadResult.ContentMd5)
		readedMd5 := md5Hash.Sum(nil)
		if !bytes.Equal(uploadedMd5, readedMd5) {
			glog.Errorf("md5 %x does not match %x uploaded chunk %s to the volume server", readedMd5, uploadedMd5, uploadResult.Name)
		}

		// Save to chunk manifest structure
		fileChunks = append(fileChunks, uploadResult.ToPbFileChunk(fileId, chunkOffset))

		glog.V(4).Infof("uploaded %s chunk %d to %s [%d,%d)", fileName, len(fileChunks), fileId, chunkOffset, chunkOffset+int64(uploadResult.Size))

		// reset variables for the next chunk
		chunkOffset = chunkOffset + int64(uploadResult.Size)

		// if last chunk was not at full chunk size, but already exhausted the reader
		if int64(uploadResult.Size) < int64(chunkSize) {
			break
		}
	}

	return fileChunks, md5Hash, chunkOffset, nil, smallContent
}

func (fs *FilerServer) doUpload(urlLocation string, w http.ResponseWriter, r *http.Request, limitedReader io.Reader, fileName string, contentType string, pairMap map[string]string, auth security.EncodedJwt) (*operation.UploadResult, error, []byte) {

	stats.FilerRequestCounter.WithLabelValues("chunkUpload").Inc()
	start := time.Now()
	defer func() {
		stats.FilerRequestHistogram.WithLabelValues("chunkUpload").Observe(time.Since(start).Seconds())
	}()

	uploadResult, err, data := operation.Upload(urlLocation, fileName, fs.option.Cipher, limitedReader, false, contentType, pairMap, auth)
	if uploadResult != nil && uploadResult.RetryCount > 0 {
		stats.FilerRequestCounter.WithLabelValues("chunkUploadRetry").Add(float64(uploadResult.RetryCount))
	}
	return uploadResult, err, data
}
<commit_msg>report error only for the first multipart upload<commit_after>package weed_server

import (
	"bytes"
	"crypto/md5"
	"hash"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"github.com/chrislusf/seaweedfs/weed/filer"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/operation"
	"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
	"github.com/chrislusf/seaweedfs/weed/security"
	"github.com/chrislusf/seaweedfs/weed/stats"
	"github.com/chrislusf/seaweedfs/weed/util"
)

func (fs *FilerServer) uploadReaderToChunks(w http.ResponseWriter, r *http.Request, reader io.Reader, chunkSize int32, fileName, contentType string, contentLength int64, so *operation.StorageOption) ([]*filer_pb.FileChunk, hash.Hash, int64, error, []byte) {
	var fileChunks []*filer_pb.FileChunk

	md5Hash := md5.New()
	var partReader = ioutil.NopCloser(io.TeeReader(reader, md5Hash))

	chunkOffset := int64(0)
	var smallContent []byte

	for {
		limitedReader := io.LimitReader(partReader, int64(chunkSize))

		data, err := ioutil.ReadAll(limitedReader)
		if err != nil {
			return nil, nil, 0, err, nil
		}
		if chunkOffset == 0 && !isAppend(r) {
			if len(data) < int(fs.option.SaveToFilerLimit) || strings.HasPrefix(r.URL.Path, filer.DirectoryEtcRoot) && len(data) < 4*1024 {
				smallContent = data
				chunkOffset += int64(len(data))
				break
			}
		}
		dataReader := util.NewBytesReader(data)

		// retry to assign a different file id
		var fileId, urlLocation string
		var auth security.EncodedJwt
		var assignErr, uploadErr error
		var uploadResult *operation.UploadResult
		for i := 0; i < 3; i++ {
			// assign one file id for one chunk
			fileId, urlLocation, auth, assignErr = fs.assignNewFileInfo(so)
			if assignErr != nil {
				return nil, nil, 0, assignErr, nil
			}

			// upload the chunk to the volume server
			uploadResult, uploadErr, _ = fs.doUpload(urlLocation, w, r, dataReader, fileName, contentType, nil, auth)
			if uploadErr != nil {
				time.Sleep(251 * time.Millisecond)
				continue
			}
			break
		}
		if uploadErr != nil {
			return nil, nil, 0, uploadErr, nil
		}

		// if last chunk exhausted the reader exactly at the border
		if uploadResult.Size == 0 {
			break
		}
		uploadedMd5 := util.Base64Md5ToBytes(uploadResult.ContentMd5)
		readedMd5 := md5Hash.Sum(nil)
		if !bytes.Equal(uploadedMd5, readedMd5) && chunkOffset == 0 {
			glog.Errorf("md5 %x does not match %x uploaded chunk %s to the volume server", readedMd5, uploadedMd5, uploadResult.Name)
		}

		// Save to chunk manifest structure
		fileChunks = append(fileChunks, uploadResult.ToPbFileChunk(fileId, chunkOffset))

		glog.V(4).Infof("uploaded %s chunk %d to %s [%d,%d)", fileName, len(fileChunks), fileId, chunkOffset, chunkOffset+int64(uploadResult.Size))

		// reset variables for the next chunk
		chunkOffset = chunkOffset + int64(uploadResult.Size)

		// if last chunk was not at full chunk size, but already exhausted the reader
		if int64(uploadResult.Size) < int64(chunkSize) {
			break
		}
	}

	return fileChunks, md5Hash, chunkOffset, nil, smallContent
}

func (fs *FilerServer) doUpload(urlLocation string, w http.ResponseWriter, r *http.Request, limitedReader io.Reader, fileName string, contentType string, pairMap map[string]string, auth security.EncodedJwt) (*operation.UploadResult, error, []byte) {

	stats.FilerRequestCounter.WithLabelValues("chunkUpload").Inc()
	start := time.Now()
	defer func() {
		stats.FilerRequestHistogram.WithLabelValues("chunkUpload").Observe(time.Since(start).Seconds())
	}()

	uploadResult, err, data := operation.Upload(urlLocation, fileName, fs.option.Cipher, limitedReader, false, contentType, pairMap, auth)
	if uploadResult != nil && uploadResult.RetryCount > 0 {
		stats.FilerRequestCounter.WithLabelValues("chunkUploadRetry").Add(float64(uploadResult.RetryCount))
	}
	return uploadResult, err, data
}
<|endoftext|>


<commit_before>// Copyright 2011-2014 Dmitry Chestnykh. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package captcha

import (
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"
	"io"
)

// idLen is a length of captcha id string.
// (20 bytes of 62-letter alphabet give ~119 bits.)
const idLen = 20

// idChars are characters allowed in captcha id.
var idChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")

// rngKey is a secret key used to deterministically derive seeds for
// PRNGs used in image and audio. Generated once during initialization.
var rngKey [32]byte

func init() {
	if _, err := io.ReadFull(rand.Reader, rngKey[:]); err != nil {
		panic("captcha: error reading random source: " + err.Error())
	}
}

// Purposes for seed derivation. The goal is to make deterministic PRNG produce
// different outputs for images and audio by using different derived seeds.
const (
	imageSeedPurpose = 0x01
	audioSeedPurpose = 0x02
)

// deriveSeed returns a 16-byte PRNG seed from rngKey, purpose, id and digits.
// Same purpose, id and digits will result in the same derived seed for this
// instance of running application.
//
//   out = HMAC(rngKey, purpose || id || 0x00 || digits)  (cut to 16 bytes)
//
func deriveSeed(purpose byte, id string, digits []byte) (out [16]byte) {
	var buf [sha256.Size]byte
	h := hmac.New(sha256.New, rngKey[:])
	h.Write([]byte{purpose})
	io.WriteString(h, id)
	h.Write([]byte{0})
	h.Write(digits)
	sum := h.Sum(buf[:0])
	copy(out[:], sum)
	return
}

// RandomDigits returns a byte slice of the given length containing
// pseudorandom numbers in range 0-9. The slice can be used as a captcha
// solution.
func RandomDigits(length int) []byte {
	return randomBytesMod(length, 10)
}

// randomBytes returns a byte slice of the given length read from CSPRNG.
func randomBytes(length int) (b []byte) {
	b = make([]byte, length)
	if _, err := io.ReadFull(rand.Reader, b); err != nil {
		panic("captcha: error reading random source: " + err.Error())
	}
	return
}

// randomBytesMod returns a byte slice of the given length, where each byte is
// a random number modulo mod.
func randomBytesMod(length int, mod byte) (b []byte) {
	b = make([]byte, length)
	maxrb := byte(256 - (256 % int(mod)))
	i := 0
	for {
		r := randomBytes(length + (length / 4))
		for _, c := range r {
			if c >= maxrb {
				// Skip this number to avoid modulo bias.
				continue
			}
			b[i] = c % mod
			i++
			if i == length {
				return
			}
		}
	}
	panic("unreachable")
}

// randomId returns a new random id string.
func randomId() string {
	b := randomBytesMod(idLen, byte(len(idChars)))
	for i, c := range b {
		b[i] = idChars[c]
	}
	return string(b)
}
<commit_msg>Fix condition; remove unreachable panic.<commit_after>// Copyright 2011-2014 Dmitry Chestnykh. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package captcha

import (
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"
	"io"
)

// idLen is a length of captcha id string.
// (20 bytes of 62-letter alphabet give ~119 bits.)
const idLen = 20

// idChars are characters allowed in captcha id.
var idChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")

// rngKey is a secret key used to deterministically derive seeds for
// PRNGs used in image and audio. Generated once during initialization.
var rngKey [32]byte

func init() {
	if _, err := io.ReadFull(rand.Reader, rngKey[:]); err != nil {
		panic("captcha: error reading random source: " + err.Error())
	}
}

// Purposes for seed derivation. The goal is to make deterministic PRNG produce
// different outputs for images and audio by using different derived seeds.
const (
	imageSeedPurpose = 0x01
	audioSeedPurpose = 0x02
)

// deriveSeed returns a 16-byte PRNG seed from rngKey, purpose, id and digits.
// Same purpose, id and digits will result in the same derived seed for this
// instance of running application.
//
//   out = HMAC(rngKey, purpose || id || 0x00 || digits)  (cut to 16 bytes)
//
func deriveSeed(purpose byte, id string, digits []byte) (out [16]byte) {
	var buf [sha256.Size]byte
	h := hmac.New(sha256.New, rngKey[:])
	h.Write([]byte{purpose})
	io.WriteString(h, id)
	h.Write([]byte{0})
	h.Write(digits)
	sum := h.Sum(buf[:0])
	copy(out[:], sum)
	return
}

// RandomDigits returns a byte slice of the given length containing
// pseudorandom numbers in range 0-9. The slice can be used as a captcha
// solution.
func RandomDigits(length int) []byte {
	return randomBytesMod(length, 10)
}

// randomBytes returns a byte slice of the given length read from CSPRNG.
func randomBytes(length int) (b []byte) {
	b = make([]byte, length)
	if _, err := io.ReadFull(rand.Reader, b); err != nil {
		panic("captcha: error reading random source: " + err.Error())
	}
	return
}

// randomBytesMod returns a byte slice of the given length, where each byte is
// a random number modulo mod.
func randomBytesMod(length int, mod byte) (b []byte) {
	b = make([]byte, length)
	maxrb := byte(256 - (256 % int(mod)))
	i := 0
	for {
		r := randomBytes(length + (length / 4))
		for _, c := range r {
			if c > maxrb {
				// Skip this number to avoid modulo bias.
				continue
			}
			b[i] = c % mod
			i++
			if i == length {
				return
			}
		}
	}
}

// randomId returns a new random id string.
func randomId() string {
	b := randomBytesMod(idLen, byte(len(idChars)))
	for i, c := range b {
		b[i] = idChars[c]
	}
	return string(b)
}
<|endoftext|>


<commit_before>// Copyright ©2015 The corridor Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package corridor

import (
	"math"
	"math/rand"
	"time"

	"github.com/gonum/matrix/mat64"
)

// mvnrnd generates pairs of bivariate normally distributed random numbers
// given an input mean vector and covariance matrix
func MvnRnd(mu *mat64.Dense, sigma *mat64.SymDense) (rndsmp *mat64.Dense) {

	// initialize vector slices
	o := make([]float64, 2)
	n := make([]float64, 2)

	// generate random numbers from normal distribution, prohibit [0,0]
	// combinations
	rand.Seed(time.Now().UnixNano())

	// enter loop
	for i := 0; i < 2; i++ {
		n[i] = rand.NormFloat64()
	}

	// convert to matrix type
	rnd := mat64.NewDense(2, 1, n)
	output := mat64.NewDense(2, 1, o)

	// perform cholesky decomposition on covariance matrix
	lower := mat64.NewTriDense(2, false, nil)
	lower.Cholesky(sigma, true)

	// compute output
	output.Mul(lower, rnd)
	output.Add(output, mu)

	//return final output
	return output
}

// fixrnd converts an input vector of bivariate normally distributed random
// numbers into a version where the values have been fixed to a [-1, 0 ,1]
// range
func FixRnd(rndsmp *mat64.Dense) (fixsmp *mat64.Dense) {

	// initialize vector slice
	o := make([]float64, 2)

	// write up down movement direction
	if rndsmp.At(0, 0) > 0.5 {
		o[0] = 1
	} else if rndsmp.At(0, 0) >= -0.5 && rndsmp.At(0, 0) <= 0.5 {
		o[0] = 0
	} else if rndsmp.At(0, 0) < -0.5 {
		o[0] = -1
	}

	// write left right movement direction
	if rndsmp.At(1, 0) > 0.5 {
		o[1] = 1
	} else if rndsmp.At(1, 0) >= -0.5 && rndsmp.At(1, 0) <= 0.5 {
		o[1] = 0
	} else if rndsmp.At(1, 0) < -0.5 {
		o[1] = -1
	}

	// convert to matrix type
	output := mat64.NewDense(1, 2, o)

	// return final output
	return output
}

// newrnd repeatedly generates a new random sample from mvrnd and then fixes
// it using fixrnd until the sample is comprised of a non [0, 0] case
func NewRnd(mu *mat64.Dense, sigma *mat64.SymDense) (newRand []int) {

	// initialize rndsmp and fixsmp and output variables
	rndsmp := mat64.NewDense(2, 1, nil)
	fixsmp := mat64.NewDense(1, 2, nil)

	// generate random vectors prohibiting zero-zero cases
	for {
		rndsmp = MvnRnd(mu, sigma)
		fixsmp = FixRnd(rndsmp)
		if fixsmp.At(0, 0) == 0 && fixsmp.At(0, 1) == 0 {
			continue
		} else {
			break
		}
	}

	// initialize output
	output := make([]int, 2)

	// write output values
	output[0] = int(fixsmp.At(0, 0))
	output[1] = int(fixsmp.At(0, 1))

	// return final output
	return output
}

// newmu generates a matrix representation of mu that reflects the
// spatial orentiation between the input current subscript and the
// destination subscript
func NewMu(curSubs, dstSubs []int) (mu *mat64.Dense) {

	// initialize vector slice
	muVec := make([]float64, 2)

	// assign row based parameter
	if curSubs[0]-dstSubs[0] < 0 {
		muVec[0] = 1
	} else if curSubs[0]-dstSubs[0] == 0 {
		muVec[0] = 0
	} else if curSubs[0]-dstSubs[0] > 0 {
		muVec[0] = -1
	}

	// assign column based parameter
	if curSubs[1]-dstSubs[1] < 0 {
		muVec[1] = 1
	} else if curSubs[1]-dstSubs[1] == 0 {
		muVec[1] = 0
	} else if curSubs[1]-dstSubs[1] > 0 {
		muVec[1] = -1
	}

	// initialize matrix output
	output := mat64.NewDense(2, 1, muVec)

	// return final output
	return output
}

// newsig generates a matrix representation of sigma that reflects the
// number of iterations in the sampling process as well as the distance
// from the basis euclidean solution
func NewSig(iterations int, randomness, distance float64) (sigma *mat64.SymDense) {

	// impose lower bound on distance
	if distance < 1 {
		distance = 1.0
	}

	// set numerator
	var num float64 = 1.0

	// initialize covariance
	var cov float64

	// compute covariance
	if distance == 1.0 {
		cov = 1.0
	} else {
		cov = math.Pow(distance, (num/randomness)) / math.Pow(float64(iterations), (num/randomness))
	}

	// initialize matrix output
	output := mat64.NewSymDense(2, nil)

	// set values
	output.SetSym(0, 0, cov)
	output.SetSym(0, 1, 0.0)
	output.SetSym(1, 0, 0.0)
	output.SetSym(1, 1, cov)

	// return final output
	return output
}

// newind generates a feasible new index value within the input search
// domain
func NewInd(curSubs []int, curDist float64, searchParameters *Parameters, searchDomain *Domain) (newSubscripts []int) {

	// initialize iteration counter
	var iterations int = 1

	// initialize output
	output := make([]int, 2)

	// generate and fix a bivariate normally distributed random vector
	// prohibit all zero cases and validate using the search domain
	for {

		// generate mu and sigma values
		mu := NewMu(curSubs, searchParameters.DstSubs)
		sigma := NewSig(iterations, searchParameters.RndCoef, curDist)

		// generate fixed random bivariate normally distributed numbers
		try := NewRnd(mu, sigma)

		// write output
		output[0] = curSubs[0] + try[0]
		output[1] = curSubs[1] + try[1]

		// test if currentIndex inside search domain
		if searchDomain.Matrix.At(output[0], output[1]) == 0.0 {
			iterations += 1
			continue
		} else if output[0] > searchDomain.Rows-1 || output[1] > searchDomain.Cols-1 || output[0] < 0 || output[1] < 0 {
			iterations += 1
			continue
		} else {
			break
		}
	}

	// return final output
	return output
}

// dirwlk generates a new directed walk connecting a source subscript to a
// destination subscript within the context of an input search domain
func DirWlk(searchDomain *Domain, searchParameters *Parameters, basisSolution *Basis) (subscripts [][]int, destinationTest bool) {

	// initialize chromosomal 2D slice with source subscript as first
	// element
	output := make([][]int, 1, searchDomain.MaxLen)
	output[0] = make([]int, 2)
	output[0][0] = searchParameters.SrcSubs[0]
	output[0][1] = searchParameters.SrcSubs[1]

	// initialize new tabu matrix
	tabu := mat64.NewDense(searchDomain.Rows, searchDomain.Cols, nil)
	tabu.Clone(searchDomain.Matrix)
	tabu.Set(searchParameters.SrcSubs[0], searchParameters.SrcSubs[1], 0.0)

	// initialize current subscripts, distance, try, and iteration counter
	curSubs := make([]int, 2)
	var curDist float64
	var try []int
	var dstTest bool

	// enter bounded for loop
	for i := 0; i < searchDomain.MaxLen; i++ {

		// get current subscripts
		curSubs = output[len(output)-1]

		// compute current distance
		curDist = basisSolution.Matrix.At(curSubs[0], curSubs[1])

		// generate new try
		try = NewInd(curSubs, curDist, searchParameters, searchDomain)

		// apply control conditions
		if try[0] == searchParameters.DstSubs[0] && try[1] == searchParameters.DstSubs[1] {
			output = append(output, try)
			break
		} else if tabu.At(try[0], try[1]) == 0.0 {
			continue
		} else {
			output = append(output, try)
			tabu.Set(try[0], try[1], 0.0)
		}
	}

	if output[len(output)-1][0] == searchParameters.DstSubs[0] && output[len(output)-1][1] == searchParameters.DstSubs[1] {
		dstTest = true
	} else {
		dstTest = false
	}

	// return final output
	return output, dstTest
}

// dirwlk generates a new directed walk connecting a source subscript to a
// destination subscript within the context of an input search domain
func MutWlk(searchDomain *Domain, searchParameters *Parameters, basisSolution *Basis) (subscripts [][]int, tabuTest bool) {

	// initialize chromosomal 2D slice with source subscript as first
	// element
	output := make([][]int, 1, searchDomain.MaxLen)
	output[0] = make([]int, 2)
	output[0][0] = searchParameters.SrcSubs[0]
	output[0][1] = searchParameters.SrcSubs[1]

	// initialize new tabu matrix
	tabu := mat64.NewDense(searchDomain.Rows, searchDomain.Cols, nil)
	tabu.Clone(searchDomain.Matrix)
	tabu.Set(searchParameters.SrcSubs[0], searchParameters.SrcSubs[1], 0.0)

	// initialize current subscripts, distance, try, and iteration counter
	curSubs := make([]int, 2)
	var curDist float64
	var try []int
	var test bool

	// enter bounded for loop
	for {

		// get current subscripts
		curSubs = output[len(output)-1]

		// compute current distance
		curDist = basisSolution.Matrix.At(curSubs[0], curSubs[1])

		// generate new try
		try = NewInd(curSubs, curDist, searchParameters, searchDomain)

		// apply control conditions
		if try[0] == searchParameters.DstSubs[0] && try[1] == searchParameters.DstSubs[1] {
			output = append(output, try)
			break
		} else if tabu.At(try[0], try[1]) == 0.0 {
			continue
		} else {
			output = append(output, try)
			tabu.Set(try[0], try[1], 0.0)
		}

		// validate tabu matrix
		test = ValidateSubDomain(try, searchParameters.DstSubs, tabu)

		// reset if tabu is invalid
		if test == false {
			break
		}
	}

	// return final output
	return output, test
}
<commit_msg>Fixed an issue with the way in which the randomly generated subscripts were being set during the tryInd routine.<commit_after>// Copyright ©2015 The corridor Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package corridor

import (
	"math"
	"math/rand"
	"time"

	"github.com/gonum/matrix/mat64"
)

// mvnrnd generates pairs of bivariate normally distributed random numbers
// given an input mean vector and covariance matrix
func MvnRnd(mu *mat64.Dense, sigma *mat64.SymDense) (rndsmp *mat64.Dense) {

	// initialize vector slices
	o := make([]float64, 2)
	n := make([]float64, 2)

	// generate random numbers from normal distribution, prohibit [0,0]
	// combinations
	rand.Seed(time.Now().UnixNano())

	// enter loop
	for i := 0; i < 2; i++ {
		n[i] = rand.NormFloat64()
	}

	// convert to matrix type
	rnd := mat64.NewDense(2, 1, n)
	output := mat64.NewDense(2, 1, o)

	// perform cholesky decomposition on covariance matrix
	lower := mat64.NewTriDense(2, false, nil)
	lower.Cholesky(sigma, true)

	// compute output
	output.Mul(lower, rnd)
	output.Add(output, mu)

	//return final output
	return output
}

// fixrnd converts an input vector of bivariate normally distributed random
// numbers into a version where the values have been fixed to a [-1, 0 ,1]
// range
func FixRnd(rndsmp *mat64.Dense) (fixsmp *mat64.Dense) {

	// initialize vector slice
	o := make([]float64, 2)

	// write up down movement direction
	if rndsmp.At(0, 0) > 1.0 {
		o[0] = 1
	} else if rndsmp.At(0, 0) >= -1.0 && rndsmp.At(0, 0) <= 1.0 {
		o[0] = 0
	} else if rndsmp.At(0, 0) < -1.0 {
		o[0] = -1
	}

	// write left right movement direction
	if rndsmp.At(1, 0) > 1.0 {
		o[1] = 1
	} else if rndsmp.At(1, 0) >= -1.0 && rndsmp.At(1, 0) <= 1.0 {
		o[1] = 0
	} else if rndsmp.At(1, 0) < -1.0 {
		o[1] = -1
	}

	// convert to matrix type
	output := mat64.NewDense(1, 2, o)

	// return final output
	return output
}

// newrnd repeatedly generates a new random sample from mvrnd and then fixes
// it using fixrnd until the sample is comprised of a non [0, 0] case
func NewRnd(mu *mat64.Dense, sigma *mat64.SymDense) (newRand []int) {

	// initialize rndsmp and fixsmp and output variables
	rndsmp := mat64.NewDense(2, 1, nil)
	fixsmp := mat64.NewDense(1, 2, nil)

	// generate random vectors prohibiting zero-zero cases
	for {
		rndsmp = MvnRnd(mu, sigma)
		fixsmp = FixRnd(rndsmp)
		if fixsmp.At(0, 0) == 0 && fixsmp.At(0, 1) == 0 {
			continue
		} else {
			break
		}
	}

	// initialize output
	output := make([]int, 2)

	// write output values
	output[0] = int(fixsmp.At(0, 0))
	output[1] = int(fixsmp.At(0, 1))

	// return final output
	return output
}

// newmu generates a matrix representation of mu that reflects the
// spatial orentiation between the input current subscript and the
// destination subscript
func NewMu(curSubs, dstSubs []int) (mu *mat64.Dense) {

	// initialize vector slice
	muVec := make([]float64, 2)

	// assign row based parameter
	if curSubs[0]-dstSubs[0] < 0 {
		muVec[0] = 1
	} else if curSubs[0]-dstSubs[0] == 0 {
		muVec[0] = 0
	} else if curSubs[0]-dstSubs[0] > 0 {
		muVec[0] = -1
	}

	// assign column based parameter
	if curSubs[1]-dstSubs[1] < 0 {
		muVec[1] = 1
	} else if curSubs[1]-dstSubs[1] == 0 {
		muVec[1] = 0
	} else if curSubs[1]-dstSubs[1] > 0 {
		muVec[1] = -1
	}

	// initialize matrix output
	output := mat64.NewDense(2, 1, muVec)

	// return final output
	return output
}

// newsig generates a matrix representation of sigma that reflects the
// number of iterations in the sampling process as well as the distance
// from the basis euclidean solution
func NewSig(iterations int, randomness, distance float64) (sigma *mat64.SymDense) {

	// impose lower bound on distance
	if distance < 1 {
		distance = 1.0
	}

	// set numerator
	var num float64 = 1.0

	// initialize covariance
	var cov float64

	// compute covariance
	if distance == 1.0 {
		cov = 1.0
	} else {
		cov = math.Pow(distance, (num/randomness)) / math.Pow(float64(iterations), (num/randomness))
	}

	// initialize matrix output
	output := mat64.NewSymDense(2, nil)

	// set values
	output.SetSym(0, 0, cov)
	output.SetSym(0, 1, 0.0)
	output.SetSym(1, 0, 0.0)
	output.SetSym(1, 1, cov)

	// return final output
	return output
}

// newind generates a feasible new index value within the input search
// domain
func NewInd(curSubs []int, curDist float64, searchParameters *Parameters, searchDomain *Domain) (newSubscripts []int) {

	// initialize iteration counter
	var iterations int = 1

	// initialize output
	output := make([]int, 2)

	// generate and fix a bivariate normally distributed random vector
	// prohibit all zero cases and validate using the search domain
	for {

		// generate mu and sigma values
		mu := NewMu(curSubs, searchParameters.DstSubs)
		sigma := NewSig(iterations, searchParameters.RndCoef, curDist)

		// generate fixed random bivariate normally distributed numbers
		try := NewRnd(mu, sigma)

		// write output
		output[0] = curSubs[0] + try[0]
		output[1] = curSubs[1] + try[1]

		// test if currentIndex inside search domain
		if searchDomain.Matrix.At(output[0], output[1]) == 0.0 {
			iterations += 1
			continue
		} else if output[0] > searchDomain.Rows-1 || output[1] > searchDomain.Cols-1 || output[0] < 0 || output[1] < 0 {
			iterations += 1
			continue
		} else {
			break
		}
	}

	// return final output
	return output
}

// dirwlk generates a new directed walk connecting a source subscript to a
// destination subscript within the context of an input search domain
func DirWlk(searchDomain *Domain, searchParameters *Parameters, basisSolution *Basis) (subscripts [][]int, destinationTest bool) {

	// initialize chromosomal 2D slice with source subscript as first
	// element
	output := make([][]int, 1, searchDomain.MaxLen)
	output[0] = make([]int, 2)
	output[0][0] = searchParameters.SrcSubs[0]
	output[0][1] = searchParameters.SrcSubs[1]

	// initialize new tabu matrix
	tabu := mat64.NewDense(searchDomain.Rows, searchDomain.Cols, nil)
	tabu.Clone(searchDomain.Matrix)
	tabu.Set(searchParameters.SrcSubs[0], searchParameters.SrcSubs[1], 0.0)

	// initialize current subscripts, distance, try, and iteration counter
	curSubs := make([]int, 2)
	var curDist float64
	var try []int
	var dstTest bool

	// enter bounded for loop
	for i := 0; i < searchDomain.MaxLen; i++ {

		// get current subscripts
		curSubs = output[len(output)-1]

		// compute current distance
		curDist = basisSolution.Matrix.At(curSubs[0], curSubs[1])

		// generate new try
		try = NewInd(curSubs, curDist, searchParameters, searchDomain)

		// apply control conditions
		if try[0] == searchParameters.DstSubs[0] && try[1] == searchParameters.DstSubs[1] {
			output = append(output, try)
			break
		} else if tabu.At(try[0], try[1]) == 0.0 {
			continue
		} else {
			output = append(output, try)
			tabu.Set(try[0], try[1], 0.0)
		}
	}

	if output[len(output)-1][0] == searchParameters.DstSubs[0] && output[len(output)-1][1] == searchParameters.DstSubs[1] {
		dstTest = true
	} else {
		dstTest = false
	}

	// return final output
	return output, dstTest
}

// dirwlk generates a new directed walk connecting a source subscript to a
// destination subscript within the context of an input search domain
func MutWlk(searchDomain *Domain, searchParameters *Parameters, basisSolution *Basis) (subscripts [][]int, tabuTest bool) {

	// initialize chromosomal 2D slice with source subscript as first
	// element
	output := make([][]int, 1, searchDomain.MaxLen)
	output[0] = make([]int, 2)
	output[0][0] = searchParameters.SrcSubs[0]
	output[0][1] = searchParameters.SrcSubs[1]

	// initialize new tabu matrix
	tabu := mat64.NewDense(searchDomain.Rows, searchDomain.Cols, nil)
	tabu.Clone(searchDomain.Matrix)
	tabu.Set(searchParameters.SrcSubs[0], searchParameters.SrcSubs[1], 0.0)

	// initialize current subscripts, distance, try, and iteration counter
	curSubs := make([]int, 2)
	var curDist float64
	var try []int
	var test bool

	// enter bounded for loop
	for {

		// get current subscripts
		curSubs = output[len(output)-1]

		// compute current distance
		curDist = basisSolution.Matrix.At(curSubs[0], curSubs[1])

		// generate new try
		try = NewInd(curSubs, curDist, searchParameters, searchDomain)

		// apply control conditions
		if try[0] == searchParameters.DstSubs[0] && try[1] == searchParameters.DstSubs[1] {
			output = append(output, try)
			break
		} else if tabu.At(try[0], try[1]) == 0.0 {
			continue
		} else {
			output = append(output, try)
			tabu.Set(try[0], try[1], 0.0)
		}

		// validate tabu matrix
		test = ValidateSubDomain(try, searchParameters.DstSubs, tabu)

		// reset if tabu is invalid
		if test == false {
			break
		}
	}

	// return final output
	return output, test
}
<|endoftext|>


<commit_before>/*

Reader interface definition and implementation.

*/

package bitio

import (
	"bufio"
	"io"
)

// Reader is the bit reader interface.
type Reader interface {
	// Reader is an io.Reader
	io.Reader

	// Reader is also an io.ByteReader.
	// ReadByte reads the next 8 bits and returns them as a byte.
	io.ByteReader

	// ReadBits reads n bits and returns them as the lowest n bits of u.
	ReadBits(n byte) (u uint64, err error)

	// ReadBool reads the next bit, and returns true if it is 1.
	ReadBool() (b bool, err error)

	// Align aligns the bit stream to a byte boundary,
	// so next read will read/use data from the next byte.
	// Returns the number of unread / skipped bits.
	Align() (skipped byte)
}

// An io.Reader and io.ByteReader at the same time.
type readerAndByteReader interface {
	io.Reader
	io.ByteReader
}

// reader is the bit reader implementation.
type reader struct {
	in    readerAndByteReader
	cache byte // unread bits are stored here
	bits  byte // number of unread bits in cache
}

// NewReader returns a new Reader using the specified io.Reader as the input (source).
func NewReader(in io.Reader) Reader {
	var bin readerAndByteReader
	bin, ok := in.(readerAndByteReader)
	if !ok {
		bin = bufio.NewReader(in)
	}
	return &reader{in: bin}
}

// Read implements io.Reader.
func (r *reader) Read(p []byte) (n int, err error) {
	// r.bits will be the same after reading 8 bits, so we don't need to update that.
	if r.bits == 0 {
		return r.in.Read(p)
	}

	for ; n < len(p); n++ {
		if p[n], err = r.readUnalignedByte(); err != nil {
			return
		}
	}

	return
}

func (r *reader) ReadBits(n byte) (u uint64, err error) {
	// Some optimization, frequent cases
	if n < r.bits {
		// cache has all needed bits, and there are some extra which will be left in cache
		shift := r.bits - n
		u = uint64(r.cache >> shift)
		r.cache &= 1<<shift - 1
		r.bits = shift
		return
	}

	if n > r.bits {
		// all cache bits needed, and it's not even enough so more will be read
		if r.bits > 0 {
			u = uint64(r.cache)
			n -= r.bits
		}
		// Read whole bytes
		for n >= 8 {
			if b, err := r.in.ReadByte(); err != nil {
				return 0, err
			} else {
				u = u<<8 + uint64(b)
				n -= 8
			}
		}
		// Read last fraction, if any
		if n > 0 {
			if r.cache, err = r.in.ReadByte(); err != nil {
				return 0, err
			}
			shift := 8 - n
			u = u<<n + uint64(r.cache>>shift)
			r.cache &= 1<<shift - 1
			r.bits = shift
		} else {
			r.bits = 0
		}
		return u, nil
	}

	// cache has exactly as many as needed
	r.bits = 0 // no need to clear cache, will be overridden on next read
	return uint64(r.cache), nil
}

// ReadByte implements io.ByteReader.
func (r *reader) ReadByte() (b byte, err error) {
	// r.bits will be the same after reading 8 bits, so we don't need to update that.
	if r.bits == 0 {
		return r.in.ReadByte()
	}
	return r.readUnalignedByte()
}

// readUnalignedByte reads the next 8 bits which are (may be) unaligned and returns them as a byte.
func (r *reader) readUnalignedByte() (b byte, err error) {
	// r.bits will be the same after reading 8 bits, so we don't need to update that.
	bits := r.bits
	b = r.cache << (8 - bits)
	r.cache, err = r.in.ReadByte()
	if err != nil {
		return 0, err
	}
	b |= r.cache >> bits
	r.cache &= 1<<bits - 1
	return
}

func (r *reader) ReadBool() (b bool, err error) {
	if r.bits == 0 {
		r.cache, err = r.in.ReadByte()
		if err != nil {
			return
		}
		b = (r.cache & 0x80) != 0
		r.cache, r.bits = r.cache&0x7f, 7
		return
	}

	r.bits--
	b = (r.cache & (1 << r.bits)) != 0
	r.cache &= 1<<r.bits - 1
	return
}

func (r *reader) Align() (skipped byte) {
	skipped = r.bits
	r.bits = 0 // no need to clear cache, will be overwritten on next read
	return
}
<commit_msg>Code formatting.<commit_after>/*

Reader interface definition and implementation.

*/

package bitio

import (
	"bufio"
	"io"
)

// Reader is the bit reader interface.
type Reader interface {
	// Reader is an io.Reader
	io.Reader

	// Reader is also an io.ByteReader.
	// ReadByte reads the next 8 bits and returns them as a byte.
	io.ByteReader

	// ReadBits reads n bits and returns them as the lowest n bits of u.
	ReadBits(n byte) (u uint64, err error)

	// ReadBool reads the next bit, and returns true if it is 1.
	ReadBool() (b bool, err error)

	// Align aligns the bit stream to a byte boundary,
	// so next read will read/use data from the next byte.
	// Returns the number of unread / skipped bits.
	Align() (skipped byte)
}

// An io.Reader and io.ByteReader at the same time.
type readerAndByteReader interface {
	io.Reader
	io.ByteReader
}

// reader is the bit reader implementation.
type reader struct {
	in    readerAndByteReader
	cache byte // unread bits are stored here
	bits  byte // number of unread bits in cache
}

// NewReader returns a new Reader using the specified io.Reader as the input (source).
func NewReader(in io.Reader) Reader {
	var bin readerAndByteReader
	bin, ok := in.(readerAndByteReader)
	if !ok {
		bin = bufio.NewReader(in)
	}
	return &reader{in: bin}
}

// Read implements io.Reader.
func (r *reader) Read(p []byte) (n int, err error) {
	// r.bits will be the same after reading 8 bits, so we don't need to update that.
	if r.bits == 0 {
		return r.in.Read(p)
	}

	for ; n < len(p); n++ {
		if p[n], err = r.readUnalignedByte(); err != nil {
			return
		}
	}

	return
}

func (r *reader) ReadBits(n byte) (u uint64, err error) {
	// Some optimization, frequent cases
	if n < r.bits {
		// cache has all needed bits, and there are some extra which will be left in cache
		shift := r.bits - n
		u = uint64(r.cache >> shift)
		r.cache &= 1<<shift - 1
		r.bits = shift
		return
	}

	if n > r.bits {
		// all cache bits needed, and it's not even enough so more will be read
		if r.bits > 0 {
			u = uint64(r.cache)
			n -= r.bits
		}
		// Read whole bytes
		for n >= 8 {
			if b, err := r.in.ReadByte(); err != nil {
				return 0, err
			}
			u = u<<8 + uint64(b)
			n -= 8
		}
		// Read last fraction, if any
		if n > 0 {
			if r.cache, err = r.in.ReadByte(); err != nil {
				return 0, err
			}
			shift := 8 - n
			u = u<<n + uint64(r.cache>>shift)
			r.cache &= 1<<shift - 1
			r.bits = shift
		} else {
			r.bits = 0
		}
		return u, nil
	}

	// cache has exactly as many as needed
	r.bits = 0 // no need to clear cache, will be overridden on next read
	return uint64(r.cache), nil
}

// ReadByte implements io.ByteReader.
func (r *reader) ReadByte() (b byte, err error) {
	// r.bits will be the same after reading 8 bits, so we don't need to update that.
	if r.bits == 0 {
		return r.in.ReadByte()
	}
	return r.readUnalignedByte()
}

// readUnalignedByte reads the next 8 bits which are (may be) unaligned and returns them as a byte.
func (r *reader) readUnalignedByte() (b byte, err error) {
	// r.bits will be the same after reading 8 bits, so we don't need to update that.
	bits := r.bits
	b = r.cache << (8 - bits)
	r.cache, err = r.in.ReadByte()
	if err != nil {
		return 0, err
	}
	b |= r.cache >> bits
	r.cache &= 1<<bits - 1
	return
}

func (r *reader) ReadBool() (b bool, err error) {
	if r.bits == 0 {
		r.cache, err = r.in.ReadByte()
		if err != nil {
			return
		}
		b = (r.cache & 0x80) != 0
		r.cache, r.bits = r.cache&0x7f, 7
		return
	}

	r.bits--
	b = (r.cache & (1 << r.bits)) != 0
	r.cache &= 1<<r.bits - 1
	return
}

func (r *reader) Align() (skipped byte) {
	skipped = r.bits
	r.bits = 0 // no need to clear cache, will be overwritten on next read
	return
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"image"
	"image/gif"
	"image/jpeg"
	"image/png"
	"log"
	"os"
	"strings"
)

type img struct {
	file   *os.File
	config image.Config
}

func (i *img) Load(path string) *img {
	file, err := os.Open(path)
	if err != nil {
		log.Fatal(err)
	}
	i.file = file

	var config image.Config
	switch i.Ext() {
	default:
		config, err = jpeg.DecodeConfig(file)
	case "gif":
		config, err = gif.DecodeConfig(file)
	case "png":
		config, err = png.DecodeConfig(file)
	}

	if err != nil {
		log.Fatal(err)
	}
	i.config = config

	return i
}

func (i *img) Name() string {
	stat, err := i.file.Stat()
	if err != nil {
		log.Fatal(err)
	}
	return stat.Name()
}

func (i *img) Ext() (ext string) {
	name := i.Name()
	ext = strings.Split(name, ".")[1]
	return ext
}

func (i *img) Size() int64 {
	stat, err := i.file.Stat()
	if err != nil {
		log.Fatal(err)
	}
	return stat.Size()
}

func (i *img) Width() int {
	return i.config.Width
}

func (i *img) Height() int {
	return i.config.Height
}

func (i *img) CloseFile() {
	i.file.Close()
}

func (i *img) Output() {
	var size int64
	var t string

	if i.Size() < 1000 {
		size = i.Size()
		t = "B"
	} else {
		size = i.Size() / 1000
		t = "KB"
	}

	fmt.Printf("width: %dpx\nheight: %dpx\nsize: %d%s\n", i.Width(), i.Height(), size, t)
}

func Run() {
	i := new(img)
	i.Load(os.Args[1])
	i.Output()
	i.CloseFile()
}

func main() {
	if len(os.Args) < 2 {
		fmt.Printf("Usage: %s <path/to/image>\n", os.Args[0])
		return
	}
	Run()
}
<commit_msg>simpler, smaller<commit_after>package main

import (
	"fmt"
	"image"
	"image/gif"
	"image/jpeg"
	"image/png"
	"os"
	"strings"
)

type img struct {
	file *os.File
	width, height int
	size int64
}

func (i *img) Load(path string) (file *os.File, err error) {
	file, err = os.Open(path)
	if err != nil {
		return nil, err
	}
	i.file = file

	stat, err := file.Stat()
	if err != nil {
		return file, err
	}

	i.size = stat.Size()

	var ext string = strings.Split(stat.Name(), ".")[1]
	var config image.Config

	switch ext {
	default:
		config, err = jpeg.DecodeConfig(file)
	case "gif":
		config, err = gif.DecodeConfig(file)
	case "png":
		config, err = png.DecodeConfig(file)
	}

	if err != nil {
		return file, err
	}

	i.width = config.Width
	i.height = config.Height
	return file, nil
}

func (i *img) Print() {
	var size int64
	var t string

	if i.size < 1000 {
		size = i.size
		t = "B"
	} else {
		size = i.size / 1000
		t = "KB"
	}

	fmt.Printf("width: %dpx\nheight: %dpx\nsize: %d%s\n", i.width, i.height, size, t)
}

func Run() {
	i := new(img)
	_, err := i.Load(os.Args[1])
	if err != nil {
		fmt.Println(err)
		return
	}
	defer i.file.Close()
	i.Print()
}

func main() {
	if len(os.Args) < 2 {
		fmt.Printf("Usage: %s <path/to/image>\n", os.Args[0])
		return
	}
	Run()
}
<|endoftext|>


<commit_before>package main

import (
	"cf"
	"cf/api"
	"cf/app"
	"cf/commands"
	"cf/configuration"
	"cf/manifest"
	"cf/net"
	"cf/requirements"
	"cf/terminal"
	"fileutils"
	"fmt"
	"github.com/codegangsta/cli"
	"os"
	"runtime/debug"
	"strings"
)

func main() {
	defer func() {
		err := recover()
		if err != nil {
			displayCrashDialog()
		}
	}()

	fileutils.SetTmpPathPrefix("cf")

	if os.Getenv("CF_COLOR") == "" {
		os.Setenv("CF_COLOR", "true")
	}

	termUI := terminal.NewUI()
	configRepo := configuration.NewConfigurationDiskRepository()
	config := loadConfig(termUI, configRepo)
	manifestRepo := manifest.NewManifestDiskRepository()
	repoLocator := api.NewRepositoryLocator(config, configRepo, map[string]net.Gateway{
		"auth":             net.NewUAAGateway(),
		"cloud-controller": net.NewCloudControllerGateway(),
		"uaa":              net.NewUAAGateway(),
	})

	cmdFactory := commands.NewFactory(termUI, config, configRepo, manifestRepo, repoLocator)
	reqFactory := requirements.NewFactory(termUI, config, repoLocator)
	cmdRunner := commands.NewRunner(cmdFactory, reqFactory)

	app, err := app.NewApp(cmdRunner)
	if err != nil {
		return
	}

	args := os.Args
	if len(args) == 2 && args[1][0] == '-' {
		args[1] = "help"
	}

	app.Run(args)
}

func init() {
	cli.AppHelpTemplate = `NAME:
   {{.Name}} - {{.Usage}}

USAGE:
   [environment variables] {{.Name}} [global options] command [arguments...] [command options]

VERSION:
   {{.Version}}

COMMANDS:
   {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Description}}
   {{end}}
GLOBAL OPTIONS:
   {{range .Flags}}{{.}}
   {{end}}
ENVIRONMENT VARIABLES:
   CF_HOME=path/to/config/ override default config directory
   CF_STAGING_TIMEOUT=15 max wait time for buildpack staging, in minutes
   CF_STARTUP_TIMEOUT=5 max wait time for app instance startup, in minutes
   CF_COLOR=false - will not colorize output
   CF_TRACE=true - print API request diagnostics to stdout
   CF_TRACE=path/to/trace.log - append API request diagnostics to a log file
   HTTP_PROXY=http://proxy.example.com:8080 - enable http proxying for API requests
`

	cli.CommandHelpTemplate = `NAME:
   {{.Name}} - {{.Description}}
{{with .ShortName}}
ALIAS:
   {{.}}
{{end}}
USAGE:
   {{.Usage}}{{with .Flags}}

OPTIONS:
   {{range .}}{{.}}
   {{end}}{{else}}
{{end}}`

}

func loadConfig(termUI terminal.UI, configRepo configuration.ConfigurationRepository) (config *configuration.Configuration) {
	config, err := configRepo.Get()
	if err != nil {
		termUI.Failed(fmt.Sprintf("Error loading config file: %s",err))
		configRepo.Delete()
		os.Exit(1)
		return
	}
	return
}

func displayCrashDialog() {
	formattedString := `

Aww shucks.

Something completely unexpected happened. This is a bug in %s.
Please file this bug : https://github.com/cloudfoundry/cli/issues
Tell us that you ran this command:

	%s

and got this stack trace:

%s
	`

	stackTrace := "\t" + strings.Replace(string(debug.Stack()), "\n", "\n\t", -1)
	println(fmt.Sprintf(formattedString, cf.Name(), strings.Join(os.Args, " "), stackTrace))
	os.Exit(1)
}
<commit_msg>Fix `cf -h` hack to permit `cf -v`<commit_after>package main

import (
	"cf"
	"cf/api"
	"cf/app"
	"cf/commands"
	"cf/configuration"
	"cf/manifest"
	"cf/net"
	"cf/requirements"
	"cf/terminal"
	"fileutils"
	"fmt"
	"github.com/codegangsta/cli"
	"os"
	"runtime/debug"
	"strings"
)

func main() {
	defer func() {
		err := recover()
		if err != nil {
			displayCrashDialog()
		}
	}()

	fileutils.SetTmpPathPrefix("cf")

	if os.Getenv("CF_COLOR") == "" {
		os.Setenv("CF_COLOR", "true")
	}

	termUI := terminal.NewUI()
	configRepo := configuration.NewConfigurationDiskRepository()
	config := loadConfig(termUI, configRepo)
	manifestRepo := manifest.NewManifestDiskRepository()
	repoLocator := api.NewRepositoryLocator(config, configRepo, map[string]net.Gateway{
		"auth":             net.NewUAAGateway(),
		"cloud-controller": net.NewCloudControllerGateway(),
		"uaa":              net.NewUAAGateway(),
	})

	cmdFactory := commands.NewFactory(termUI, config, configRepo, manifestRepo, repoLocator)
	reqFactory := requirements.NewFactory(termUI, config, repoLocator)
	cmdRunner := commands.NewRunner(cmdFactory, reqFactory)

	app, err := app.NewApp(cmdRunner)
	if err != nil {
		return
	}

	args := os.Args
	if len(args) == 2 && args[1][0] == '-' && args[1] != "-v" && args[1] != "--version" {
		args[1] = "help"
	}

	app.Run(args)
}

func init() {
	cli.AppHelpTemplate = `NAME:
   {{.Name}} - {{.Usage}}

USAGE:
   [environment variables] {{.Name}} [global options] command [arguments...] [command options]

VERSION:
   {{.Version}}

COMMANDS:
   {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Description}}
   {{end}}
GLOBAL OPTIONS:
   {{range .Flags}}{{.}}
   {{end}}
ENVIRONMENT VARIABLES:
   CF_HOME=path/to/config/ override default config directory
   CF_STAGING_TIMEOUT=15 max wait time for buildpack staging, in minutes
   CF_STARTUP_TIMEOUT=5 max wait time for app instance startup, in minutes
   CF_COLOR=false - will not colorize output
   CF_TRACE=true - print API request diagnostics to stdout
   CF_TRACE=path/to/trace.log - append API request diagnostics to a log file
   HTTP_PROXY=http://proxy.example.com:8080 - enable http proxying for API requests
`

	cli.CommandHelpTemplate = `NAME:
   {{.Name}} - {{.Description}}
{{with .ShortName}}
ALIAS:
   {{.}}
{{end}}
USAGE:
   {{.Usage}}{{with .Flags}}

OPTIONS:
   {{range .}}{{.}}
   {{end}}{{else}}
{{end}}`

}

func loadConfig(termUI terminal.UI, configRepo configuration.ConfigurationRepository) (config *configuration.Configuration) {
	config, err := configRepo.Get()
	if err != nil {
		termUI.Failed(fmt.Sprintf("Error loading config file: %s",err))
		configRepo.Delete()
		os.Exit(1)
		return
	}
	return
}

func displayCrashDialog() {
	formattedString := `

Aww shucks.

Something completely unexpected happened. This is a bug in %s.
Please file this bug : https://github.com/cloudfoundry/cli/issues
Tell us that you ran this command:

	%s

and got this stack trace:

%s
	`

	stackTrace := "\t" + strings.Replace(string(debug.Stack()), "\n", "\n\t", -1)
	println(fmt.Sprintf(formattedString, cf.Name(), strings.Join(os.Args, " "), stackTrace))
	os.Exit(1)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"github.com/codegangsta/cli"
	"io"
	"io/ioutil"
	"os"
	"regexp"
	"strings"
)

// getPattern returns the specified pattern or nil.
func getPattern(ctx *cli.Context) (*regexp.Regexp, error) {
	if !ctx.Args().Present() {
		return nil, fmt.Errorf("missing pattern")
	}
	exp := ctx.Args().First()
	// Assemble flags.
	fs := ""
	for _, f := range []string{"i", "m", "s", "U"} {
		if ctx.GlobalBool(f) {
			fs += f
		}
	}
	if fs != "" {
		exp = "(?" + fs + ")" + exp
	}

	return regexp.Compile(exp)
}

type namedReader struct {
	Name   *string
	Reader io.Reader
}

// getInput returns the input reader(s) or error.
func getInput(ctx *cli.Context, offset int) ([]namedReader, error) {
	if len(ctx.Args()) > offset {
		ms := ctx.Args()[offset:]
		ns := make([]namedReader, len(ms))
		for i, m := range ms {
			m := m
			f, err := os.Open(m)
			if err != nil {
				return nil, err
			}
			ns[i] = namedReader{&m, f}
		}
		return ns, nil
	} else {
		return []namedReader{{nil, os.Stdin}}, nil
	}
}

func writeln(ms [][]byte, w io.Writer, newline bool) error {
	for _, m := range ms {
		if _, err := w.Write(m); err != nil {
			return err
		}
		if newline {
			if _, err := w.Write([]byte("\n")); err != nil {
				return err
			}
		}
	}
	return nil
}

func doScan(multiline bool, r io.Reader, w io.Writer, proc func([]byte) [][]byte) error {
	if !multiline {
		// Line-by-line match.
		scn := bufio.NewScanner(r)
		for scn.Scan() {
			if err := writeln(proc(scn.Bytes()), w, true); err != nil {
				return err
			}
		}
	} else {
		// XXX: We could do a lot better job here.
		buf, err := ioutil.ReadAll(r)
		if err != nil {
			return err
		}
		return writeln(proc(buf), w, false)
	}
	return nil
}

func prefix(fname *string, line []byte) []byte {
	if fname == nil {
		return line
	}
	return append([]byte(*fname+": "), line...)
}

func match(exp *regexp.Regexp,
	invert, multiline, onlymatching, filenames bool,
	rs []namedReader, w io.Writer) error {
	if invert && onlymatching {
		return fmt.Errorf("incompatible flags: --invert and --onlymatching")
	}
	for _, r := range rs {
		if err := doScan(multiline, r.Reader, w, func(buf []byte) [][]byte {
			if onlymatching {
				ms := exp.FindAll(buf, -1)
				if filenames {
					for i, x := range ms {
						// Add filename.
						ms[i] = prefix(r.Name, x)
					}
				}
				return ms
			} else {
				if onlymatching != exp.Match(buf) {
					if filenames {
						return [][]byte{prefix(r.Name, buf)}
					} else {
						return [][]byte{buf}
					}
				}
			}
			return nil
		}); err != nil {
			return err
		}
	}
	return nil
}

func replace(exp *regexp.Regexp, repl string, multiline bool, rs []namedReader, w io.Writer) error {
	for _, r := range rs {
		if err := doScan(multiline, r.Reader, w, func(buf []byte) [][]byte {
			return [][]byte{exp.ReplaceAll(buf, []byte(repl))}
		}); err != nil {
			return err
		}
	}
	return nil
}

func split(exp *regexp.Regexp, fields []int, multiline bool, rs []namedReader, w io.Writer) error {
	for _, r := range rs {
		if err := doScan(multiline, r.Reader, w, func(buf []byte) [][]byte {
			parts := exp.Split(string(buf), -1)
			ms := make([]string, len(fields))
			for i, f := range fields {
				if f < len(parts) {
					ms[i] = parts[f]
				}
			}
			return [][]byte{[]byte(strings.Join(ms, ","))}
		}); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Fix invert<commit_after>package main

import (
	"bufio"
	"fmt"
	"github.com/codegangsta/cli"
	"io"
	"io/ioutil"
	"os"
	"regexp"
	"strings"
)

// getPattern returns the specified pattern or nil.
func getPattern(ctx *cli.Context) (*regexp.Regexp, error) {
	if !ctx.Args().Present() {
		return nil, fmt.Errorf("missing pattern")
	}
	exp := ctx.Args().First()
	// Assemble flags.
	fs := ""
	for _, f := range []string{"i", "m", "s", "U"} {
		if ctx.GlobalBool(f) {
			fs += f
		}
	}
	if fs != "" {
		exp = "(?" + fs + ")" + exp
	}

	return regexp.Compile(exp)
}

type namedReader struct {
	Name   *string
	Reader io.Reader
}

// getInput returns the input reader(s) or error.
func getInput(ctx *cli.Context, offset int) ([]namedReader, error) {
	if len(ctx.Args()) > offset {
		ms := ctx.Args()[offset:]
		ns := make([]namedReader, len(ms))
		for i, m := range ms {
			m := m
			f, err := os.Open(m)
			if err != nil {
				return nil, err
			}
			ns[i] = namedReader{&m, f}
		}
		return ns, nil
	} else {
		return []namedReader{{nil, os.Stdin}}, nil
	}
}

func writeln(ms [][]byte, w io.Writer, newline bool) error {
	for _, m := range ms {
		if _, err := w.Write(m); err != nil {
			return err
		}
		if newline {
			if _, err := w.Write([]byte("\n")); err != nil {
				return err
			}
		}
	}
	return nil
}

func doScan(multiline bool, r io.Reader, w io.Writer, proc func([]byte) [][]byte) error {
	if !multiline {
		// Line-by-line match.
		scn := bufio.NewScanner(r)
		for scn.Scan() {
			if err := writeln(proc(scn.Bytes()), w, true); err != nil {
				return err
			}
		}
	} else {
		// XXX: We could do a lot better job here.
		buf, err := ioutil.ReadAll(r)
		if err != nil {
			return err
		}
		return writeln(proc(buf), w, false)
	}
	return nil
}

func prefix(fname *string, line []byte) []byte {
	if fname == nil {
		return line
	}
	return append([]byte(*fname+": "), line...)
}

func match(exp *regexp.Regexp,
	invert, multiline, onlymatching, filenames bool,
	rs []namedReader, w io.Writer) error {
	if invert && onlymatching {
		return fmt.Errorf("incompatible flags: --invert and --onlymatching")
	}
	for _, r := range rs {
		if err := doScan(multiline, r.Reader, w, func(buf []byte) [][]byte {
			if onlymatching {
				ms := exp.FindAll(buf, -1)
				if filenames {
					for i, x := range ms {
						// Add filename.
						ms[i] = prefix(r.Name, x)
					}
				}
				return ms
			} else {
				if invert != exp.Match(buf) {
					if filenames {
						return [][]byte{prefix(r.Name, buf)}
					} else {
						return [][]byte{buf}
					}
				}
			}
			return nil
		}); err != nil {
			return err
		}
	}
	return nil
}

func replace(exp *regexp.Regexp, repl string, multiline bool, rs []namedReader, w io.Writer) error {
	for _, r := range rs {
		if err := doScan(multiline, r.Reader, w, func(buf []byte) [][]byte {
			return [][]byte{exp.ReplaceAll(buf, []byte(repl))}
		}); err != nil {
			return err
		}
	}
	return nil
}

func split(exp *regexp.Regexp, fields []int, multiline bool, rs []namedReader, w io.Writer) error {
	for _, r := range rs {
		if err := doScan(multiline, r.Reader, w, func(buf []byte) [][]byte {
			parts := exp.Split(string(buf), -1)
			ms := make([]string, len(fields))
			for i, f := range fields {
				if f < len(parts) {
					ms[i] = parts[f]
				}
			}
			return [][]byte{[]byte(strings.Join(ms, ","))}
		}); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>