<commit_before>package asock // import "firepear.net/asock"

// Copyright (c) 2014,2015 Shawn Boyette <shawn@firepear.net>. All
// rights reserved.  Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import (
	"fmt"
	"net"
	"os"
	"sync"
	"time"
)

// Message levels control which messages will be sent to as.Msgr
const (
	All = iota
	Conn
	Error
	Fatal
)

// Asock is a handle on an asock instance. It contains the
// Msgr channel, which is the conduit for notifications from the
// instance.
type Asock struct {
	Msgr chan *Msg
	q    chan bool
	w    *sync.WaitGroup
	s    string       // socket name
	l    net.Listener // listener socket
	d    Dispatch     // dispatch table
	t    int          // timeout
	ml   int          // message level
}

// Dispatch is the dispatch table which drives asock's
// behavior. See the package Overview for more info.
type Dispatch map[string]func ([]string) ([]byte, error)

// Msg is the format which asock uses to communicate informational
// messages and errors to its host program. See the package Overview
// for more info.
type Msg struct {
	Conn int
	Req  int
	Code int
	Txt  string
	Err  error
}

// NewUnix returns an instance of Asock. It takes four arguments: the
// socket name; an instance of Dispatch; the connection timeout value,
// in seconds; and the desired messaging level.
//
// If the timeout value is zero, connections will never timeout. If
// the timeout is negative then connections will perform one read,
// send one response, and then be closed. These "one-shot" connections
// still set a timeout value, (e.g. -2 produces a connection which
// times out after 2 seconds.
//
// Valid message levels are: All, Conn, Error, Fatal
//
// If Asock's process is being run as root, the listener socket
// will be in /var/run; else it will be in /tmp.
func NewUnix(sn string, d Dispatch, t, ml int) (*Asock, error) {
	if os.Getuid() == 0 {
		sn = fmt.Sprintf("/var/run/%v.sock", sn)
	} else {
		sn = fmt.Sprintf("/tmp/%v.sock", sn)
	}
	l, err := net.ListenUnix("unix", &net.UnixAddr{Name: sn, Net: "unix"})
	if err != nil {
		return nil, err
	}
	if t == -20707 { // triggers the listener to die for failure testing
		t = 0
		l.SetDeadline(time.Now().Add(100 * time.Millisecond))
	}
	var w sync.WaitGroup
	q := make(chan bool, 1) // master off-switch channel
	m := make(chan *Msg, 32) // error reporting
	a := &Asock{m, q, &w, sn, l, d, t, ml}
	a.w.Add(1)
	go a.sockAccept()
	return a, nil
}

func NewTCP(addr string, d Dispatch, t, ml int) (*Asock, error) {
	tcpaddr, err := net.ResolveTCPAddr("tcp", addr)
	l, err := net.ListenTCP("tcp", tcpaddr)
	if err != nil {
		return nil, err
	}
	var w sync.WaitGroup
	q := make(chan bool, 1) // master off-switch channel
	m := make(chan *Msg, 32) // error reporting
	a := &Asock{m, q, &w, addr, l, d, t, ml}
	a.w.Add(1)
	go a.sockAccept()
	return a, nil
}

// genMsg creates messages and sends them to the Msgr channel.
func (a *Asock) genMsg(conn, req, code, ml int, txt string, err error) {
	// if this message's level is below the instance's level, don't
	// generate the message
	if ml < a.ml {
		return
	}
	select {
	case a.Msgr <- &Msg{conn, req, code, txt, err}:
	default:
	}
}

// Quit handles shutdown and cleanup for an asock instance,
// including waiting for any connections to terminate. When it
// returns, the Asock is fully shut down. See the package Overview
// for more info.
func (a *Asock) Quit() {
	a.q <- true
	a.l.Close()
	a.w.Wait()
	close(a.q)
	close(a.Msgr)
}
<commit_msg>split out/dedupe common constructor work<commit_after>package asock // import "firepear.net/asock"

// Copyright (c) 2014,2015 Shawn Boyette <shawn@firepear.net>. All
// rights reserved.  Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import (
	"fmt"
	"net"
	"os"
	"sync"
	"time"
)

// Message levels control which messages will be sent to as.Msgr
const (
	All = iota
	Conn
	Error
	Fatal
)

// Asock is a handle on an asock instance. It contains the
// Msgr channel, which is the conduit for notifications from the
// instance.
type Asock struct {
	Msgr chan *Msg
	q    chan bool
	w    *sync.WaitGroup
	s    string       // socket name
	l    net.Listener // listener socket
	d    Dispatch     // dispatch table
	t    int          // timeout
	ml   int          // message level
}

// Dispatch is the dispatch table which drives asock's
// behavior. See the package Overview for more info.
type Dispatch map[string]func ([]string) ([]byte, error)

// Msg is the format which asock uses to communicate informational
// messages and errors to its host program. See the package Overview
// for more info.
type Msg struct {
	Conn int
	Req  int
	Code int
	Txt  string
	Err  error
}

// NewTCP returns an instance of Asock which uses TCP networking. It
// takes four arguments: an "address:port" string; an instance of
// Dispatch; the connection timeout value, in seconds; and the desired
// messaging level.
//
// If the timeout value is zero, connections will never timeout. If
// the timeout is negative then connections will perform one read,
// send one response, and then be closed. These "one-shot" connections
// still set a timeout value, (e.g. -2 produces a connection which
// times out after 2 seconds.
//
// Valid message levels are: asock.All, asock.Conn, asock.Error, and
// asock.Fatal
func NewTCP(ap string, d Dispatch, t, ml int) (*Asock, error) {
	tcpaddr, err := net.ResolveTCPAddr("tcp", ap)
	l, err := net.ListenTCP("tcp", tcpaddr)
	if err != nil {
		return nil, err
	}
	return commonNew(ap, d, t, ml, l), nil
}

// NewUnix returns an instance of Asock which uses Unix domain
// networking. It takes four arguments: the socket name; an instance
// of Dispatch; the connection timeout value, in seconds; and the
// desired messaging level.
//
// If Asock's process is being run as root, the listener socket
// will be at /var/run/[socket_name]; else it will be in /tmp.
//
// Timeout and message level are the same as for NewTCP().
func NewUnix(sn string, d Dispatch, t, ml int) (*Asock, error) {
	if os.Getuid() == 0 {
		sn = fmt.Sprintf("/var/run/%v.sock", sn)
	} else {
		sn = fmt.Sprintf("/tmp/%v.sock", sn)
	}
	l, err := net.ListenUnix("unix", &net.UnixAddr{Name: sn, Net: "unix"})
	if err != nil {
		return nil, err
	}
	if t == -20707 { // triggers the listener to die for failure testing
		t = 0
		l.SetDeadline(time.Now().Add(100 * time.Millisecond))
	}
	return commonNew(sn, d, t, ml, l), nil
}

// commonNew does shared setup work for the constructors (mostly so
// that changes to Asock don't have to be mirrored)
func commonNew(s string, d Dispatch, t, ml int, l net.Listener) *Asock {
	var w sync.WaitGroup
	q := make(chan bool, 1) // master off-switch channel
	m := make(chan *Msg, 32) // error reporting
	a := &Asock{m, q, &w, s, l, d, t, ml}
	a.w.Add(1)
	go a.sockAccept()
	return a
}

// genMsg creates messages and sends them to the Msgr channel.
func (a *Asock) genMsg(conn, req, code, ml int, txt string, err error) {
	// if this message's level is below the instance's level, don't
	// generate the message
	if ml < a.ml {
		return
	}
	select {
	case a.Msgr <- &Msg{conn, req, code, txt, err}:
	default:
	}
}

// Quit handles shutdown and cleanup for an asock instance,
// including waiting for any connections to terminate. When it
// returns, the Asock is fully shut down. See the package Overview
// for more info.
func (a *Asock) Quit() {
	a.q <- true
	a.l.Close()
	a.w.Wait()
	close(a.q)
	close(a.Msgr)
}
<|endoftext|>


<commit_before>package commands

import (
	"encoding/json"
	"errors"
	"fmt"

	"github.com/concourse/concourse/atc"
	"github.com/concourse/concourse/fly/rc"
	yaml "gopkg.in/yaml.v2"
)

type GetTeamCommand struct {
	Team string `short:"n" long:"team" required:"true" description:"Get configuration of this team"`
	JSON bool   `short:"j" long:"json" description:"Print config as json instead of yaml"`
}

func (command *GetTeamCommand) Execute(args []string) error {
	asJSON := command.JSON
	teamName := command.Team

	target, err := rc.LoadTarget(Fly.Target, Fly.Verbose)
	if err != nil {
		return err
	}

	if err := target.Validate(); err != nil {
		return err
	}

	config, found, err := target.Team().Team(teamName)
	if err != nil {
		return err
	}

	if !found {
		return errors.New("team not found")
	}

	return dumpTeam(config, asJSON)
}

func dumpTeam(config atc.Team, asJSON bool) error {
	var payload []byte
	var err error
	if asJSON {
		payload, err = json.Marshal(config)
	} else {
		payload, err = yaml.Marshal(config)
	}
	if err != nil {
		return err
	}

	_, err = fmt.Printf("%s", payload)

	return err
}
<commit_msg>follows teams command<commit_after>package commands

import (
	"errors"
	"fmt"
	"os"
	"sort"
	"strings"

	"github.com/concourse/concourse/fly/commands/internal/displayhelpers"
	"github.com/concourse/concourse/fly/rc"
	"github.com/concourse/concourse/fly/ui"
	"github.com/fatih/color"
)

type GetTeamCommand struct {
	Team string `short:"n" long:"team" required:"true" description:"Get configuration of this team"`
	Json bool   `short:"j" long:"json" description:"Print config as json instead of yaml"`
}

func (command *GetTeamCommand) Execute(args []string) error {
	target, err := rc.LoadTarget(Fly.Target, Fly.Verbose)
	if err != nil {
		return err
	}

	if err := target.Validate(); err != nil {
		return err
	}

	team, found, err := target.Team().Team(command.Team)
	if err != nil {
		return err
	}

	if !found {
		return errors.New("team not found")
	}

	if command.Json {
		if err := displayhelpers.JsonPrint(team); err != nil {
			return err
		}
		return nil
	}

	headers := ui.TableRow{
		{Contents: "name/role", Color: color.New(color.Bold)},
		{Contents: "users", Color: color.New(color.Bold)},
		{Contents: "groups", Color: color.New(color.Bold)},
	}
	table := ui.Table{Headers: headers}
	for role, auth := range team.Auth {
		row := ui.TableRow{
			{Contents: fmt.Sprintf("%s/%s", team.Name, role)},
		}
		var usersCell, groupsCell ui.TableCell
		hasUsers := len(auth["users"]) != 0
		hasGroups := len(auth["groups"]) != 0

		if !hasUsers && !hasGroups {
			usersCell.Contents = "all"
			usersCell.Color = color.New(color.Faint)
		} else if !hasUsers {
			usersCell.Contents = "none"
			usersCell.Color = color.New(color.Faint)
		} else {
			usersCell.Contents = strings.Join(auth["users"], ",")
		}

		if hasGroups {
			groupsCell.Contents = strings.Join(auth["groups"], ",")
		} else {
			groupsCell.Contents = "none"
			groupsCell.Color = color.New(color.Faint)
		}

		row = append(row, usersCell)
		row = append(row, groupsCell)
		table.Data = append(table.Data, row)
	}
	sort.Sort(table.Data)
	return table.Render(os.Stdout, Fly.PrintTableHeaders)
}
<|endoftext|>


<commit_before>package croc

import (
	"net"
	"time"

	log "github.com/cihub/seelog"
	"github.com/schollz/peerdiscovery"
)

func init() {
	SetLogLevel("debug")
}

// Relay initiates a relay
func (c *Croc) Relay() error {
	// start relay
	go c.startRelay()

	// start server
	return c.startServer()
}

// Send will take an existing file or folder and send it through the croc relay
func (c *Croc) Send(fname string, codephrase string) (err error) {
	// start relay for listening
	go func() {
		d := c
		d.ServerPort = "8140"
		d.TcpPorts = []string{"27140", "27141"}
		go d.startRelay()
		go d.startServer()
		// e := c
		// time.Sleep(100 * time.Millisecond)
		// e.WebsocketAddress = "ws://127.0.0.1:8140"
		// go e.client(0, codephrase, fname)
	}()

	// start other client
	c.WebsocketAddress = "ws://127.0.0.1:8140"
	return c.client(0, codephrase, fname)
}

// Receive will receive something through the croc relay
func (c *Croc) Receive(codephrase string) (err error) {
	// try to discovery codephrase and server through peer network
	discovered, errDiscover := peerdiscovery.Discover(peerdiscovery.Settings{
		Limit:     1,
		TimeLimit: 1 * time.Second,
		Delay:     50 * time.Millisecond,
		Payload:   []byte(codephrase),
	})
	if errDiscover != nil {
		log.Debug(errDiscover)
	}
	if len(discovered) > 0 {
		log.Debugf("discovered %s on %s", discovered[0].Payload, discovered[0].Address)
		_, connectTimeout := net.DialTimeout("tcp", discovered[0].Address+":27140", 1*time.Second)
		if connectTimeout == nil {
			log.Debug("connected")
			c.WebsocketAddress = "ws://" + discovered[0].Address + ":8140"
			log.Debug(discovered[0].Address)
			codephrase = string(discovered[0].Payload)
		} else {
			log.Debug("but could not connect to ports")
		}
	} else {
		log.Debug("discovered no peers")
	}

	return c.client(1, codephrase)
}
<commit_msg>add peer discovery<commit_after>package croc

import (
	"net"
	"time"

	log "github.com/cihub/seelog"
	"github.com/schollz/peerdiscovery"
)

func init() {
	SetLogLevel("debug")
}

// Relay initiates a relay
func (c *Croc) Relay() error {
	// start relay
	go c.startRelay()

	// start server
	return c.startServer()
}

// Send will take an existing file or folder and send it through the croc relay
func (c *Croc) Send(fname string, codephrase string) (err error) {
	// start relay for listening
	runClientError := make(chan error)
	go func() {
		d := Init()
		d.ServerPort = "8140"
		d.TcpPorts = []string{"27140", "27141"}
		go d.startRelay()
		go d.startServer()
		e := Init()
		e.WebsocketAddress = "ws://127.0.0.1:8140"
		runClientError <- e.client(0, codephrase, fname)
	}()

	// start main client
	go func() {
		runClientError <- c.client(0, codephrase, fname)
	}()
	return <-runClientError
}

// Receive will receive something through the croc relay
func (c *Croc) Receive(codephrase string) (err error) {
	// try to discovery codephrase and server through peer network
	discovered, errDiscover := peerdiscovery.Discover(peerdiscovery.Settings{
		Limit:     1,
		TimeLimit: 1 * time.Second,
		Delay:     50 * time.Millisecond,
		Payload:   []byte(codephrase),
	})
	if errDiscover != nil {
		log.Debug(errDiscover)
	}
	if len(discovered) > 0 {
		log.Debugf("discovered %s on %s", discovered[0].Payload, discovered[0].Address)
		_, connectTimeout := net.DialTimeout("tcp", discovered[0].Address+":27140", 1*time.Second)
		if connectTimeout == nil {
			log.Debug("connected")
			c.WebsocketAddress = "ws://" + discovered[0].Address + ":8140"
			log.Debug(discovered[0].Address)
			codephrase = string(discovered[0].Payload)
		} else {
			log.Debug("but could not connect to ports")
		}
	} else {
		log.Debug("discovered no peers")
	}

	return c.client(1, codephrase)
}
<|endoftext|>


<commit_before>package main

const newID = 42

//go:noinline
func main() {
	c := newClientCopy(newID)
	setID(&c)
}

//go:noinline
func setID(c *client) {
	c.setID(newID + 1)
}

type client struct {
	id int
}

//go:noinline
func newClient(id int) client {
	return client{id: id}
}

//go:noinline
func (c *client) setID(id int) {
	c.id = id
}
<commit_msg>heapstack/value: add updateClientID<commit_after>package main

const newID = 42

//go:noinline
func main() {
	c := newClient(newID)
	updateClientID(&c)
}

//go:noinline
func updateClientID(c *client) {
	c.setID(newID + 1)
}

type client struct {
	id int
}

//go:noinline
func newClient(id int) client {
	return client{id: id}
}

//go:noinline
func (c *client) setID(id int) {
	c.id = id
}
<|endoftext|>


<commit_before>// +build ebpf

/*
 * Copyright (C) 2016 Red Hat, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy ofthe License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specificlanguage governing permissions and
 * limitations under the License.
 *
 */

package tests

import (
	"fmt"
	"testing"

	g "github.com/skydive-project/skydive/gremlin"
)

func TestFlowsEBPF(t *testing.T) {
	test := &Test{
		setupCmds: []Cmd{
			{"ovs-vsctl add-br br-ebpf", true},

			{"ip netns add src-vm", true},
			{"ip link add src-vm-eth0 type veth peer name ebpf-src-eth0 netns src-vm", true},
			{"ip link set src-vm-eth0 up", true},
			{"ip netns exec src-vm ip link set ebpf-src-eth0 up", true},
			{"ip netns exec src-vm ip address add 169.254.107.33/24 dev ebpf-src-eth0", true},

			{"ip netns add dst-vm", true},
			{"ip link add dst-vm-eth0 type veth peer name ebpf-dst-eth0 netns dst-vm", true},
			{"ip link set dst-vm-eth0 up", true},
			{"ip netns exec dst-vm ip link set ebpf-dst-eth0 up", true},
			{"ip netns exec dst-vm ip address add 169.254.107.34/24 dev ebpf-dst-eth0", true},

			{"ovs-vsctl add-port br-ebpf src-vm-eth0", true},
			{"ovs-vsctl add-port br-ebpf dst-vm-eth0", true},
		},

		injections: []TestInjection{{
			from:  g.G.V().Has("Name", "src-vm").Out().Has("Name", "ebpf-src-eth0"),
			to:    g.G.V().Has("Name", "dst-vm").Out().Has("Name", "ebpf-dst-eth0"),
			count: 10,
		}},

		tearDownCmds: []Cmd{
			{"ovs-vsctl del-br br-ebpf", true},
			{"ip link del dst-vm-eth0", true},
			{"ip link del src-vm-eth0", true},
			{"ip netns del src-vm", true},
			{"ip netns del dst-vm", true},
		},

		captures: []TestCapture{
			{gremlin: g.G.V().Has("Name", "ebpf-src-eth0"), kind: "ebpf"},
		},

		mode: Replay,

		checks: []CheckFunction{func(c *CheckContext) error {
			gremlin := c.gremlin.Flows().Has("Network", "169.254.107.33", "LayersPath", "Ethernet/IPv4/ICMPv4").Dedup()
			flows, err := c.gh.GetFlows(gremlin)
			if err != nil {
				return err
			}
			if len(flows) != 1 || flows[0].Metric.ABPackets != 10 {
				return fmt.Errorf("Expected one flow, got %+v", flows)
			}
			return nil
		}},
	}
	RunTest(t, test)
}

func TestFlowsVLANEBPF(t *testing.T) {
	test := &Test{
		setupCmds: []Cmd{
			{"ovs-vsctl add-br br-ebpf", true},

			{"ip netns add src-vm", true},
			{"ip link add src-vm-eth0 type veth peer name ebpf-src-eth0 netns src-vm", true},
			{"ip link set src-vm-eth0 up", true},
			{"ip netns exec src-vm ip link set ebpf-src-eth0 up", true},
			{"ip netns exec src-vm ip link add link ebpf-src-eth0 name vlan1 type vlan id 8", true},
			{"ip netns exec src-vm ip link set vlan1 up", true},
			{"ip netns exec src-vm ip link add link vlan1 name vlan0 type vlan id 2050", true},
			{"ip netns exec src-vm ip address add 169.254.107.33/24 dev vlan0", true},
			{"ip netns exec src-vm ip link set vlan0 up", true},

			{"ip netns add dst-vm", true},
			{"ip link add dst-vm-eth0 type veth peer name ebpf-dst-eth0 netns dst-vm", true},
			{"ip link set dst-vm-eth0 up", true},
			{"ip netns exec dst-vm ip link set ebpf-dst-eth0 up", true},
			{"ip netns exec dst-vm ip link add link ebpf-dst-eth0 name vlan1 type vlan id 8", true},
			{"ip netns exec dst-vm ip link set vlan1 up", true},
			{"ip netns exec dst-vm ip link add link vlan1 name vlan0 type vlan id 2050", true},
			{"ip netns exec dst-vm ip address add 169.254.107.34/24 dev vlan0", true},
			{"ip netns exec dst-vm ip link set vlan0 up", true},

			{"ovs-vsctl add-port br-ebpf src-vm-eth0", true},
			{"ovs-vsctl add-port br-ebpf dst-vm-eth0", true},
		},

		injections: []TestInjection{{
			from:  g.G.V().Has("Name", "src-vm").Out().Has("Name", "vlan0"),
			to:    g.G.V().Has("Name", "dst-vm").Out().Has("Name", "vlan0"),
			count: 10,
		}},

		tearDownCmds: []Cmd{
			{"ovs-vsctl del-br br-ebpf", true},
			{"ip netns exec src-vm ip link del vlan0", true},
			{"ip netns exec dst-vm ip link del vlan0", true},
			{"ip link del src-vm-eth0", true},
			{"ip link del dst-vm-eth0", true},
			{"ip netns del src-vm", true},
			{"ip netns del dst-vm", true},
		},

		captures: []TestCapture{
			{gremlin: g.G.V().Has("Name", "ebpf-src-eth0"), kind: "ebpf"},
		},

		mode: Replay,

		checks: []CheckFunction{func(c *CheckContext) error {
			gremlin := c.gremlin.Flows().Has("Network", "169.254.107.33", "LayersPath", "Ethernet/Dot1Q/Dot1Q/IPv4/ICMPv4").Dedup()
			flows, err := c.gh.GetFlows(gremlin)
			if err != nil {
				return err
			}
			if len(flows) != 1 || flows[0].Metric.ABPackets != 10 {
				return fmt.Errorf("Expected one flow, got %+v", flows)
			}
			return nil
		}},
	}
	RunTest(t, test)
}

func TestFlowsGREEBPF(t *testing.T) {
	test := testFlowTunnel(t, "br-greebpf", "gre", false, "192.168.0.1", "192.168.0.2",
		"172.16.0.1", "172.16.0.2", "192.168.0.0/24")
	for i := range test.captures {
		test.captures[i].kind = "ebpf"
	}
	RunTest(t, test)
}

func TestFlowsEBPFHashCnx(t *testing.T) {
	test := testFlowsHashCnx(t)
	for i := range test.captures {
		test.captures[i].kind = "ebpf"
	}
	RunTest(t, test)
}
<commit_msg>ebpf test : skip TestFlowsGREEBPF<commit_after>// +build ebpf

/*
 * Copyright (C) 2016 Red Hat, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy ofthe License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specificlanguage governing permissions and
 * limitations under the License.
 *
 */

package tests

import (
	"fmt"
	"testing"

	g "github.com/skydive-project/skydive/gremlin"
)

func TestFlowsEBPF(t *testing.T) {
	test := &Test{
		setupCmds: []Cmd{
			{"ovs-vsctl add-br br-ebpf", true},

			{"ip netns add src-vm", true},
			{"ip link add src-vm-eth0 type veth peer name ebpf-src-eth0 netns src-vm", true},
			{"ip link set src-vm-eth0 up", true},
			{"ip netns exec src-vm ip link set ebpf-src-eth0 up", true},
			{"ip netns exec src-vm ip address add 169.254.107.33/24 dev ebpf-src-eth0", true},

			{"ip netns add dst-vm", true},
			{"ip link add dst-vm-eth0 type veth peer name ebpf-dst-eth0 netns dst-vm", true},
			{"ip link set dst-vm-eth0 up", true},
			{"ip netns exec dst-vm ip link set ebpf-dst-eth0 up", true},
			{"ip netns exec dst-vm ip address add 169.254.107.34/24 dev ebpf-dst-eth0", true},

			{"ovs-vsctl add-port br-ebpf src-vm-eth0", true},
			{"ovs-vsctl add-port br-ebpf dst-vm-eth0", true},
		},

		injections: []TestInjection{{
			from:  g.G.V().Has("Name", "src-vm").Out().Has("Name", "ebpf-src-eth0"),
			to:    g.G.V().Has("Name", "dst-vm").Out().Has("Name", "ebpf-dst-eth0"),
			count: 10,
		}},

		tearDownCmds: []Cmd{
			{"ovs-vsctl del-br br-ebpf", true},
			{"ip link del dst-vm-eth0", true},
			{"ip link del src-vm-eth0", true},
			{"ip netns del src-vm", true},
			{"ip netns del dst-vm", true},
		},

		captures: []TestCapture{
			{gremlin: g.G.V().Has("Name", "ebpf-src-eth0"), kind: "ebpf"},
		},

		mode: Replay,

		checks: []CheckFunction{func(c *CheckContext) error {
			gremlin := c.gremlin.Flows().Has("Network", "169.254.107.33", "LayersPath", "Ethernet/IPv4/ICMPv4").Dedup()
			flows, err := c.gh.GetFlows(gremlin)
			if err != nil {
				return err
			}
			if len(flows) != 1 || flows[0].Metric.ABPackets != 10 {
				return fmt.Errorf("Expected one flow, got %+v", flows)
			}
			return nil
		}},
	}
	RunTest(t, test)
}

func TestFlowsVLANEBPF(t *testing.T) {
	test := &Test{
		setupCmds: []Cmd{
			{"ovs-vsctl add-br br-ebpf", true},

			{"ip netns add src-vm", true},
			{"ip link add src-vm-eth0 type veth peer name ebpf-src-eth0 netns src-vm", true},
			{"ip link set src-vm-eth0 up", true},
			{"ip netns exec src-vm ip link set ebpf-src-eth0 up", true},
			{"ip netns exec src-vm ip link add link ebpf-src-eth0 name vlan1 type vlan id 8", true},
			{"ip netns exec src-vm ip link set vlan1 up", true},
			{"ip netns exec src-vm ip link add link vlan1 name vlan0 type vlan id 2050", true},
			{"ip netns exec src-vm ip address add 169.254.107.33/24 dev vlan0", true},
			{"ip netns exec src-vm ip link set vlan0 up", true},

			{"ip netns add dst-vm", true},
			{"ip link add dst-vm-eth0 type veth peer name ebpf-dst-eth0 netns dst-vm", true},
			{"ip link set dst-vm-eth0 up", true},
			{"ip netns exec dst-vm ip link set ebpf-dst-eth0 up", true},
			{"ip netns exec dst-vm ip link add link ebpf-dst-eth0 name vlan1 type vlan id 8", true},
			{"ip netns exec dst-vm ip link set vlan1 up", true},
			{"ip netns exec dst-vm ip link add link vlan1 name vlan0 type vlan id 2050", true},
			{"ip netns exec dst-vm ip address add 169.254.107.34/24 dev vlan0", true},
			{"ip netns exec dst-vm ip link set vlan0 up", true},

			{"ovs-vsctl add-port br-ebpf src-vm-eth0", true},
			{"ovs-vsctl add-port br-ebpf dst-vm-eth0", true},
		},

		injections: []TestInjection{{
			from:  g.G.V().Has("Name", "src-vm").Out().Has("Name", "vlan0"),
			to:    g.G.V().Has("Name", "dst-vm").Out().Has("Name", "vlan0"),
			count: 10,
		}},

		tearDownCmds: []Cmd{
			{"ovs-vsctl del-br br-ebpf", true},
			{"ip netns exec src-vm ip link del vlan0", true},
			{"ip netns exec dst-vm ip link del vlan0", true},
			{"ip link del src-vm-eth0", true},
			{"ip link del dst-vm-eth0", true},
			{"ip netns del src-vm", true},
			{"ip netns del dst-vm", true},
		},

		captures: []TestCapture{
			{gremlin: g.G.V().Has("Name", "ebpf-src-eth0"), kind: "ebpf"},
		},

		mode: Replay,

		checks: []CheckFunction{func(c *CheckContext) error {
			gremlin := c.gremlin.Flows().Has("Network", "169.254.107.33", "LayersPath", "Ethernet/Dot1Q/Dot1Q/IPv4/ICMPv4").Dedup()
			flows, err := c.gh.GetFlows(gremlin)
			if err != nil {
				return err
			}
			if len(flows) != 1 || flows[0].Metric.ABPackets != 10 {
				return fmt.Errorf("Expected one flow, got %+v", flows)
			}
			return nil
		}},
	}
	RunTest(t, test)
}

func TestFlowsGREEBPF(t *testing.T) {
	t.Skip()

	test := testFlowTunnel(t, "br-greebpf", "gre", false, "192.168.0.1", "192.168.0.2",
		"172.16.0.1", "172.16.0.2", "192.168.0.0/24")
	for i := range test.captures {
		test.captures[i].kind = "ebpf"
	}
	RunTest(t, test)
}

func TestFlowsEBPFHashCnx(t *testing.T) {
	test := testFlowsHashCnx(t)
	for i := range test.captures {
		test.captures[i].kind = "ebpf"
	}
	RunTest(t, test)
}
<|endoftext|>


<commit_before>package main

import (
	"time"
)

import l4g "code.google.com/p/log4go"

func main() {
	log := l4g.NewLogger()
	log.AddFilter("stdout", l4g.DEBUG, l4g.NewConsoleLogWriter())
	log.Info("The time is now: %s", time.Now().Format("15:04:05 MST 2006/01/02"))
}
<commit_msg>Update ConsoleLogWriter_Manual.go<commit_after>package main

import (
	"time"
)

import l4g "github.com/fethican/log4go"

func main() {
	log := l4g.NewLogger()
	log.AddFilter("stdout", l4g.DEBUG, l4g.NewConsoleLogWriter())
	log.Info("The time is now: %s", time.Now().Format("15:04:05 MST 2006/01/02"))
}
<|endoftext|>


<commit_before>package helpers

import (
	"fmt"
	"time"

	"code.cloudfoundry.org/bbs"
	"code.cloudfoundry.org/bbs/models"
	"code.cloudfoundry.org/inigo/world"
	"code.cloudfoundry.org/lager"
	"code.cloudfoundry.org/routing-info/cfroutes"
	. "github.com/onsi/gomega"
)

const defaultDomain = "inigo"
const defaultLogGuid = "logGuid"

var defaultPreloadedRootFS = "preloaded:" + world.DefaultStack
var SecondaryPreloadedRootFS = "preloaded:" + world.PreloadedStacks[1]

const BogusPreloadedRootFS = "preloaded:bogus-rootfs"
const dockerRootFS = "docker:///cloudfoundry/diego-docker-app#latest"

const DefaultHost = "lrp-route"

var defaultRoutes = cfroutes.CFRoutes{{Hostnames: []string{DefaultHost}, Port: 8080}}.RoutingInfo()
var defaultPorts = []uint32{8080}

func defaultSetup(addresses world.ComponentAddresses) *models.Action {
	return models.WrapAction(&models.DownloadAction{
		From: fmt.Sprintf("http://%s/v1/static/%s", addresses.FileServer, "lrp.zip"),
		To:   "/tmp/diego",
		User: "vcap",
	})
}

var defaultAction = models.WrapAction(&models.RunAction{
	User: "vcap",
	Path: "/tmp/diego/go-server",
	Env:  []*models.EnvironmentVariable{{"PORT", "8080"}},
})

var defaultMonitor = models.WrapAction(&models.RunAction{
	User: "vcap",
	Path: "nc",
	Args: []string{"-z", "localhost", "8080"},
})

var defaultDeclartiveMonitor = &models.CheckDefinition{
	Checks: []*models.Check{
		{
			TcpCheck: &models.TCPCheck{
				Port: 8080,
			},
		},
	},
}

var dockerMonitor = models.WrapAction(&models.RunAction{
	User: "vcap",
	Path: "sh",
	Args: []string{"-c", "echo bogus | nc localhost 8080"},
})

func UpsertInigoDomain(logger lager.Logger, bbsClient bbs.InternalClient) {
	err := bbsClient.UpsertDomain(logger, defaultDomain, 0)
	Expect(err).NotTo(HaveOccurred())
}

func lrpCreateRequest(
	addresses world.ComponentAddresses,
	processGuid,
	logGuid,
	rootfs string,
	numInstances int,
	placementTags []string,
	action, monitor *models.Action,
) *models.DesiredLRP {
	return &models.DesiredLRP{
		ProcessGuid: processGuid,
		Domain:      defaultDomain,
		RootFs:      rootfs,
		Instances:   int32(numInstances),

		LogGuid: logGuid,

		Routes: &defaultRoutes,
		Ports:  defaultPorts,

		Setup:         defaultSetup(addresses),
		Action:        action,
		Monitor:       monitor,
		PlacementTags: placementTags,
		DiskMb:        1024,
	}
}

func DefaultLRPCreateRequest(addresses world.ComponentAddresses, processGuid, logGuid string, numInstances int) *models.DesiredLRP {
	return lrpCreateRequest(addresses, processGuid, logGuid, defaultPreloadedRootFS, numInstances, nil, defaultAction, defaultMonitor)
}

func DefaultDeclaritiveHealthcheckLRPCreateRequest(addresses world.ComponentAddresses, processGuid, logGuid string, numInstances int) *models.DesiredLRP {
	request := lrpCreateRequest(addresses, processGuid, logGuid, defaultPreloadedRootFS, numInstances, nil, defaultAction, nil)
	request.CheckDefinition = defaultDeclartiveMonitor
	request.StartTimeoutMs = int64(time.Minute / time.Millisecond)
	return request
}

func LRPCreateRequestWithPlacementTag(addresses world.ComponentAddresses, processGuid string, tags []string) *models.DesiredLRP {
	return lrpCreateRequest(addresses, processGuid, defaultLogGuid, defaultPreloadedRootFS, 1, tags, defaultAction, defaultMonitor)
}

func LRPCreateRequestWithRootFS(addresses world.ComponentAddresses, processGuid, rootfs string) *models.DesiredLRP {
	return lrpCreateRequest(addresses, processGuid, defaultLogGuid, rootfs, 1, nil, defaultAction, defaultMonitor)
}

func DockerLRPCreateRequest(addresses world.ComponentAddresses, processGuid string) *models.DesiredLRP {
	action := models.WrapAction(&models.RunAction{
		User: "vcap",
		Path: "dockerapp",
		Env:  []*models.EnvironmentVariable{{"PORT", "8080"}},
	})

	return lrpCreateRequest(addresses, processGuid, defaultLogGuid, dockerRootFS, 1, nil, action, dockerMonitor)
}

func CrashingLRPCreateRequest(addresses world.ComponentAddresses, processGuid string) *models.DesiredLRP {
	action := models.WrapAction(&models.RunAction{User: "vcap", Path: "false"})
	return lrpCreateRequest(addresses, processGuid, defaultLogGuid, defaultPreloadedRootFS, 1, nil, action, defaultMonitor)
}

func LightweightLRPCreateRequest(addresses world.ComponentAddresses, processGuid string) *models.DesiredLRP {
	action := models.WrapAction(&models.RunAction{
		User: "vcap",
		Path: "sh",
		Args: []string{
			"-c",
			"while true; do sleep 1; done",
		},
	})

	monitor := models.WrapAction(&models.RunAction{
		User: "vcap",
		Path: "sh",
		Args: []string{"-c", "echo all good"},
	})

	lrp := lrpCreateRequest(addresses, processGuid, defaultLogGuid, defaultPreloadedRootFS, 1, nil, action, monitor)
	lrp.MemoryMb = 128
	lrp.DiskMb = 1024
	return lrp
}

func TaskCreateRequest(taskGuid string, action models.ActionInterface) *models.Task {
	return taskCreateRequest(taskGuid, defaultPreloadedRootFS, action, 0, 0, nil)
}

func TaskCreateRequestWithTags(taskGuid string, action models.ActionInterface, tags []string) *models.Task {
	task := taskCreateRequest(taskGuid, defaultPreloadedRootFS, action, 0, 0, nil)
	task.PlacementTags = tags
	return task
}

func TaskCreateRequestWithMemory(taskGuid string, action models.ActionInterface, memoryMB int) *models.Task {
	return taskCreateRequest(taskGuid, defaultPreloadedRootFS, action, memoryMB, 0, nil)
}

func TaskCreateRequestWithRootFS(taskGuid, rootfs string, action models.ActionInterface) *models.Task {
	return taskCreateRequest(taskGuid, rootfs, action, 0, 0, nil)
}

func TaskCreateRequestWithMemoryAndDisk(taskGuid string, action models.ActionInterface, memoryMB, diskMB int) *models.Task {
	return taskCreateRequest(taskGuid, defaultPreloadedRootFS, action, memoryMB, diskMB, nil)
}

func TaskCreateRequestWithCertificateProperties(taskGuid string, action models.ActionInterface, certificateProperties *models.CertificateProperties) *models.Task {
	return taskCreateRequest(taskGuid, defaultPreloadedRootFS, action, 0, 0, certificateProperties)
}

func taskCreateRequest(taskGuid, rootFS string, action models.ActionInterface, memoryMB, diskMB int, certificateProperties *models.CertificateProperties) *models.Task {
	return &models.Task{
		TaskGuid: taskGuid,
		Domain:   defaultDomain,

		TaskDefinition: &models.TaskDefinition{
			RootFs:                rootFS,
			MemoryMb:              int32(memoryMB),
			DiskMb:                int32(diskMB),
			Action:                models.WrapAction(action),
			CertificateProperties: certificateProperties,
		},
	}
}
<commit_msg>Revert "Default to 1024 DiskMB for lrps"<commit_after>package helpers

import (
	"fmt"
	"time"

	"code.cloudfoundry.org/bbs"
	"code.cloudfoundry.org/bbs/models"
	"code.cloudfoundry.org/inigo/world"
	"code.cloudfoundry.org/lager"
	"code.cloudfoundry.org/routing-info/cfroutes"
	. "github.com/onsi/gomega"
)

const defaultDomain = "inigo"
const defaultLogGuid = "logGuid"

var defaultPreloadedRootFS = "preloaded:" + world.DefaultStack
var SecondaryPreloadedRootFS = "preloaded:" + world.PreloadedStacks[1]

const BogusPreloadedRootFS = "preloaded:bogus-rootfs"
const dockerRootFS = "docker:///cloudfoundry/diego-docker-app#latest"

const DefaultHost = "lrp-route"

var defaultRoutes = cfroutes.CFRoutes{{Hostnames: []string{DefaultHost}, Port: 8080}}.RoutingInfo()
var defaultPorts = []uint32{8080}

func defaultSetup(addresses world.ComponentAddresses) *models.Action {
	return models.WrapAction(&models.DownloadAction{
		From: fmt.Sprintf("http://%s/v1/static/%s", addresses.FileServer, "lrp.zip"),
		To:   "/tmp/diego",
		User: "vcap",
	})
}

var defaultAction = models.WrapAction(&models.RunAction{
	User: "vcap",
	Path: "/tmp/diego/go-server",
	Env:  []*models.EnvironmentVariable{{"PORT", "8080"}},
})

var defaultMonitor = models.WrapAction(&models.RunAction{
	User: "vcap",
	Path: "nc",
	Args: []string{"-z", "localhost", "8080"},
})

var defaultDeclartiveMonitor = &models.CheckDefinition{
	Checks: []*models.Check{
		{
			TcpCheck: &models.TCPCheck{
				Port: 8080,
			},
		},
	},
}

var dockerMonitor = models.WrapAction(&models.RunAction{
	User: "vcap",
	Path: "sh",
	Args: []string{"-c", "echo bogus | nc localhost 8080"},
})

func UpsertInigoDomain(logger lager.Logger, bbsClient bbs.InternalClient) {
	err := bbsClient.UpsertDomain(logger, defaultDomain, 0)
	Expect(err).NotTo(HaveOccurred())
}

func lrpCreateRequest(
	addresses world.ComponentAddresses,
	processGuid,
	logGuid,
	rootfs string,
	numInstances int,
	placementTags []string,
	action, monitor *models.Action,
) *models.DesiredLRP {
	return &models.DesiredLRP{
		ProcessGuid: processGuid,
		Domain:      defaultDomain,
		RootFs:      rootfs,
		Instances:   int32(numInstances),

		LogGuid: logGuid,

		Routes: &defaultRoutes,
		Ports:  defaultPorts,

		Setup:         defaultSetup(addresses),
		Action:        action,
		Monitor:       monitor,
		PlacementTags: placementTags,
	}
}

func DefaultLRPCreateRequest(addresses world.ComponentAddresses, processGuid, logGuid string, numInstances int) *models.DesiredLRP {
	return lrpCreateRequest(addresses, processGuid, logGuid, defaultPreloadedRootFS, numInstances, nil, defaultAction, defaultMonitor)
}

func DefaultDeclaritiveHealthcheckLRPCreateRequest(addresses world.ComponentAddresses, processGuid, logGuid string, numInstances int) *models.DesiredLRP {
	request := lrpCreateRequest(addresses, processGuid, logGuid, defaultPreloadedRootFS, numInstances, nil, defaultAction, nil)
	request.CheckDefinition = defaultDeclartiveMonitor
	request.StartTimeoutMs = int64(time.Minute / time.Millisecond)
	return request
}

func LRPCreateRequestWithPlacementTag(addresses world.ComponentAddresses, processGuid string, tags []string) *models.DesiredLRP {
	return lrpCreateRequest(addresses, processGuid, defaultLogGuid, defaultPreloadedRootFS, 1, tags, defaultAction, defaultMonitor)
}

func LRPCreateRequestWithRootFS(addresses world.ComponentAddresses, processGuid, rootfs string) *models.DesiredLRP {
	return lrpCreateRequest(addresses, processGuid, defaultLogGuid, rootfs, 1, nil, defaultAction, defaultMonitor)
}

func DockerLRPCreateRequest(addresses world.ComponentAddresses, processGuid string) *models.DesiredLRP {
	action := models.WrapAction(&models.RunAction{
		User: "vcap",
		Path: "dockerapp",
		Env:  []*models.EnvironmentVariable{{"PORT", "8080"}},
	})

	return lrpCreateRequest(addresses, processGuid, defaultLogGuid, dockerRootFS, 1, nil, action, dockerMonitor)
}

func CrashingLRPCreateRequest(addresses world.ComponentAddresses, processGuid string) *models.DesiredLRP {
	action := models.WrapAction(&models.RunAction{User: "vcap", Path: "false"})
	return lrpCreateRequest(addresses, processGuid, defaultLogGuid, defaultPreloadedRootFS, 1, nil, action, defaultMonitor)
}

func LightweightLRPCreateRequest(addresses world.ComponentAddresses, processGuid string) *models.DesiredLRP {
	action := models.WrapAction(&models.RunAction{
		User: "vcap",
		Path: "sh",
		Args: []string{
			"-c",
			"while true; do sleep 1; done",
		},
	})

	monitor := models.WrapAction(&models.RunAction{
		User: "vcap",
		Path: "sh",
		Args: []string{"-c", "echo all good"},
	})

	lrp := lrpCreateRequest(addresses, processGuid, defaultLogGuid, defaultPreloadedRootFS, 1, nil, action, monitor)
	lrp.MemoryMb = 128
	lrp.DiskMb = 1024
	return lrp
}

func TaskCreateRequest(taskGuid string, action models.ActionInterface) *models.Task {
	return taskCreateRequest(taskGuid, defaultPreloadedRootFS, action, 0, 0, nil)
}

func TaskCreateRequestWithTags(taskGuid string, action models.ActionInterface, tags []string) *models.Task {
	task := taskCreateRequest(taskGuid, defaultPreloadedRootFS, action, 0, 0, nil)
	task.PlacementTags = tags
	return task
}

func TaskCreateRequestWithMemory(taskGuid string, action models.ActionInterface, memoryMB int) *models.Task {
	return taskCreateRequest(taskGuid, defaultPreloadedRootFS, action, memoryMB, 0, nil)
}

func TaskCreateRequestWithRootFS(taskGuid, rootfs string, action models.ActionInterface) *models.Task {
	return taskCreateRequest(taskGuid, rootfs, action, 0, 0, nil)
}

func TaskCreateRequestWithMemoryAndDisk(taskGuid string, action models.ActionInterface, memoryMB, diskMB int) *models.Task {
	return taskCreateRequest(taskGuid, defaultPreloadedRootFS, action, memoryMB, diskMB, nil)
}

func TaskCreateRequestWithCertificateProperties(taskGuid string, action models.ActionInterface, certificateProperties *models.CertificateProperties) *models.Task {
	return taskCreateRequest(taskGuid, defaultPreloadedRootFS, action, 0, 0, certificateProperties)
}

func taskCreateRequest(taskGuid, rootFS string, action models.ActionInterface, memoryMB, diskMB int, certificateProperties *models.CertificateProperties) *models.Task {
	return &models.Task{
		TaskGuid: taskGuid,
		Domain:   defaultDomain,

		TaskDefinition: &models.TaskDefinition{
			RootFs:                rootFS,
			MemoryMb:              int32(memoryMB),
			DiskMb:                int32(diskMB),
			Action:                models.WrapAction(action),
			CertificateProperties: certificateProperties,
		},
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2014, Google, Inc.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//     http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// File: simpleserver.go

package main

import (
	"crypto/tls"
	"crypto/x509"
	"flag"
	"log"
	"net"

	"github.com/jlmucb/cloudproxy/apps/go/simpleclient"

	tao "github.com/jlmucb/cloudproxy/go/tao"
	"github.com/jlmucb/cloudproxy/go/tao/auth"
	taonet "github.com/jlmucb/cloudproxy/go/tao/net"
	"github.com/jlmucb/cloudproxy/go/util"
)

var simplecfg = flag.String("../simpledomain/tao.config", "../simpledomain/tao.config", "path to simple tao configuration")
var serverHost = flag.String("host", "localhost", "address for client/server")
var serverPort = flag.String("port", "8123", "port for client/server")
var serverAddr string

func HandleServiceRequest(ms *util.MessageStream, serverProgramData *taosupport.TaoProgramData,
	clientProgramName, req string) (bool, error) {
	return true, nil
}

func serviceThead(ms *util.MessageStream, clientProgramName string,
		  serverProgramData *taosupport.TaoProgramData) {

	for {
		log.Printf("clientServiceThead: ReadString\n")
		req, err := ms.ReadString()
		if err != nil {
			return
		}
		terminate, _ := HandleServiceRequest(ms, serverProgramData,
			          clientProgramName, req)
		if terminate {
			break
		}
	}
	log.Printf("simpleserver: client thread terminating\n")
}

func server(serverAddr string, serverProgramData *taosupport.TaoProgramData) {

	var sock net.Listener

	// Service client connections.
	for {
		conn, err := sock.Accept()
		if err != nil {
			log.Printf("server: can't accept connection: %s\n", err.Error())
			continue
		}
		var clientName string
		err = conn.(*tls.Conn).Handshake()
		if err != nil {
			log.Printf("server: TLS handshake failed\n")
			continue
		}
		peerCerts := conn.(*tls.Conn).ConnectionState().PeerCertificates
		if peerCerts == nil {
			log.Printf("server: can't get peer list\n")
			continue
		}
		peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0]
		if peerCert.Raw == nil {
			log.Printf("server: can't get peer cert\n")
			continue
		}
		if peerCert.Subject.OrganizationalUnit == nil {
			log.Printf("server: can't get peer name\n")
			continue
		}
		clientName = peerCert.Subject.OrganizationalUnit[0]
		if clientName == nil {
			log.Printf("server: can't get client name\n")
			continue
			}
		log.Printf("server, peer client name: %s\n", clientName)
		ms := util.NewMessageStream(conn)
		go serviceThead(ms, clientName, serverProgramData)
	}
}

func main() {

	var serverProgramData taosupport.TaoProgramData

	flag.Parse()
	serverAddr = *serverHost + ":" + *serverPort

	// Load domain info for this domain
	// This was initialized by TODO.
	if !TaoParadigm(*simplecfg, &serverProgramData) {
		log.Fatalln("simpleclient: Can't establish Tao")
	}

	err = server(serverAddr, &serverProgramData)
	if err != nil {
		log.Printf("simpleserver: server error\n")
	}
	log.Printf("simpleserver: done\n")
}
<commit_msg>small chanfes in server<commit_after>// Copyright (c) 2014, Google, Inc.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//     http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// File: simpleserver.go

package main

import (
	"crypto/tls"
	"crypto/x509"
	"flag"
	"log"
	"net"

	"github.com/jlmucb/cloudproxy/go/apps/simpleexample/taosupport"

	tao "github.com/jlmucb/cloudproxy/go/tao"
	"github.com/jlmucb/cloudproxy/go/util"
)

var simplecfg = flag.String("../simpledomain/tao.config", "../simpledomain/tao.config", "path to simple tao configuration")
var serverHost = flag.String("host", "localhost", "address for client/server")
var serverPort = flag.String("port", "8123", "port for client/server")
var serverAddr string

func HandleServiceRequest(ms *util.MessageStream, serverProgramData *taosupport.TaoProgramData,
	clientProgramName, req string) (bool, error) {
	return true, nil
}

func serviceThead(ms *util.MessageStream, clientProgramName string,
	serverProgramData *taosupport.TaoProgramData) {

	for {
		log.Printf("clientServiceThead: ReadString\n")
		req, err := ms.ReadString()
		if err != nil {
			return
		}
		terminate, _ := HandleServiceRequest(ms, serverProgramData,
			clientProgramName, req)
		if terminate {
			break
		}
	}
	log.Printf("simpleserver: client thread terminating\n")
}

func server(serverAddr string, serverProgramData *taosupport.TaoProgramData) {

	var sock net.Listener

	// Service client connections.
	for {
		conn, err := sock.Accept()
		if err != nil {
			log.Printf("server: can't accept connection: %s\n", err.Error())
			continue
		}
		var clientName string
		err = conn.(*tls.Conn).Handshake()
		if err != nil {
			log.Printf("server: TLS handshake failed\n")
			continue
		}
		peerCerts := conn.(*tls.Conn).ConnectionState().PeerCertificates
		if peerCerts == nil {
			log.Printf("server: can't get peer list\n")
			continue
		}
		peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0]
		if peerCert.Raw == nil {
			log.Printf("server: can't get peer cert\n")
			continue
		}
		if peerCert.Subject.OrganizationalUnit == nil {
			log.Printf("server: can't get peer name\n")
			continue
		}
		clientName = peerCert.Subject.OrganizationalUnit[0]
		if clientName == nil {
			log.Printf("server: can't get client name\n")
			continue
		}
		log.Printf("server, peer client name: %s\n", clientName)
		ms := util.NewMessageStream(conn)
		go serviceThead(ms, clientName, serverProgramData)
	}
}

func main() {

	var serverProgramData taosupport.TaoProgramData

	flag.Parse()
	serverAddr = *serverHost + ":" + *serverPort

	// Load domain info for this domain
	// This was initialized by TODO.
	if !TaoParadigm(*simplecfg, &serverProgramData) {
		log.Fatalln("simpleserver: Can't establish Tao")
	}

	err = server(serverAddr, &serverProgramData)
	if err != nil {
		log.Printf("simpleserver: server error\n")
	}
	log.Printf("simpleserver: done\n")
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Vitess Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package vstreamer

import (
	"flag"
	"fmt"
	"os"
	"testing"

	"vitess.io/vitess/go/vt/vttablet/tabletserver/vstreamer/testenv"
)

var (
	engine *Engine
	env    *testenv.Env
)

func TestMain(m *testing.M) {
	flag.Parse() // Do not remove this comment, import into google3 depends on it

	if testing.Short() {
		os.Exit(m.Run())
	}

	exitCode := func() int {
		var err error
		env, err = testenv.Init()
		if err != nil {
			fmt.Fprintf(os.Stderr, "%v", err)
			return 1
		}
		defer env.Close()

		// engine cannot be initialized in testenv because it introduces
		// circular dependencies.
		engine = NewEngine(env.SrvTopo, env.SchemaEngine)
		engine.InitDBConfig(env.Dbcfgs.DbaWithDB())
		engine.Open(env.KeyspaceName, env.Cells[0])
		defer engine.Close()

		return m.Run()
	}()
	os.Exit(exitCode)
}
<commit_msg>tests: HeartbeatTime=10s to reduce flakyness<commit_after>/*
Copyright 2019 The Vitess Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package vstreamer

import (
	"flag"
	"fmt"
	"os"
	"testing"
	"time"

	"vitess.io/vitess/go/vt/vttablet/tabletserver/vstreamer/testenv"
)

var (
	engine *Engine
	env    *testenv.Env
)

func TestMain(m *testing.M) {
	flag.Parse() // Do not remove this comment, import into google3 depends on it

	if testing.Short() {
		os.Exit(m.Run())
	}

	exitCode := func() int {
		var err error
		env, err = testenv.Init()
		if err != nil {
			fmt.Fprintf(os.Stderr, "%v", err)
			return 1
		}
		defer env.Close()

		// engine cannot be initialized in testenv because it introduces
		// circular dependencies.
		engine = NewEngine(env.SrvTopo, env.SchemaEngine)
		engine.InitDBConfig(env.Dbcfgs.DbaWithDB())
		engine.Open(env.KeyspaceName, env.Cells[0])
		defer engine.Close()

		// GH actions machines sometimes exhibit multi-second delays on replication.
		// So, give a generously high value for heartbeat time for all tests.
		saveHeartbeat := HeartbeatTime
		defer func() { HeartbeatTime = saveHeartbeat }()
		HeartbeatTime = 10 * time.Second

		return m.Run()
	}()
	os.Exit(exitCode)
}
<|endoftext|>


<commit_before>// Copyright (C) 2014 Daniel Harrison

package hfile

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"sort"

	"github.com/edsrzf/mmap-go"
	"github.com/golang/snappy"
)

type Reader struct {
	CollectionConfig

	mmap mmap.MMap

	majorVersion uint32
	minorVersion uint32

	Header
	index []Block

	scannerCache  chan *Scanner
	iteratorCache chan *Iterator
}

type Header struct {
	offset int

	fileInfoOffset             uint64
	dataIndexOffset            uint64
	dataIndexCount             uint32
	metaIndexOffset            uint64
	metaIndexCount             uint32
	totalUncompressedDataBytes uint64
	EntryCount                 uint32
	compressionCodec           uint32
}

type Block struct {
	offset        uint64
	size          uint32
	firstKeyBytes []byte
}

func NewReader(name, path string, lock, debug bool) (*Reader, error) {
	return NewReaderFromConfig(CollectionConfig{name, path, path, lock, debug})
}

func NewReaderFromConfig(cfg CollectionConfig) (*Reader, error) {
	f, err := os.OpenFile(cfg.LocalPath, os.O_RDONLY, 0)

	if err != nil {
		return nil, fmt.Errorf("[Reader] Error opening file (%s): %v", cfg.LocalPath, err)
	}

	hfile := new(Reader)
	hfile.CollectionConfig = cfg

	hfile.mmap, err = mmap.Map(f, mmap.RDONLY, 0)

	if err != nil {
		return nil, err
	}

	fi, err := f.Stat()
	if err != nil {
		return nil, err
	}

	if hfile.InMem {
		mb := 1024.0 * 1024.0
		log.Printf("[Reader.NewReader] locking %s (%.02fmb)...\n", hfile.Name, float64(fi.Size())/mb)
		if err = hfile.mmap.Lock(); err != nil {
			log.Printf("[Reader.NewReader] error locking %s: %s\n", hfile.Name, err.Error())
			return nil, err
		}
		log.Printf("[Reader.NewReader] locked %s.\n", hfile.Name)
	} else if hfile.Debug {
		log.Printf("[Reader.NewReader] Not locking %s...\n", hfile.Name)
	}

	v := binary.BigEndian.Uint32(hfile.mmap[len(hfile.mmap)-4:])
	hfile.majorVersion = v & 0x00ffffff
	hfile.minorVersion = v >> 24

	err = hfile.readHeader(hfile.mmap)
	if err != nil {
		return nil, err
	}

	err = hfile.loadIndex(hfile.mmap)
	if err != nil {
		return hfile, err
	}
	hfile.scannerCache = make(chan *Scanner, 5)
	hfile.iteratorCache = make(chan *Iterator, 5)
	return hfile, nil
}

func (r *Reader) PrintDebugInfo(out io.Writer, includeStartKeys int) {
	fmt.Fprintln(out, "entries: ", r.EntryCount)
	fmt.Fprintf(out, "compressed: %v (codec: %d)\n", r.compressionCodec != CompressionNone, r.compressionCodec)
	fmt.Fprintln(out, "blocks: ", len(r.index))
	for i, blk := range r.index {
		if i > includeStartKeys {
			fmt.Fprintf(out, "\t... and %d more\n", len(r.index)-i)
			return
		}
		fmt.Fprintf(out, "\t#%d: %s\n", i, hex.EncodeToString(blk.firstKeyBytes))
	}
}

func (r *Reader) readHeader(mmap mmap.MMap) error {
	if r.majorVersion != 1 || r.minorVersion != 0 {
		return fmt.Errorf("wrong version: %d.%d", r.majorVersion, r.minorVersion)
	}

	r.Header.offset = len(mmap) - 60
	buf := bytes.NewReader(mmap[r.Header.offset:])

	headerMagic := make([]byte, 8)
	buf.Read(headerMagic)
	if bytes.Compare(headerMagic, TrailerMagic) != 0 {
		return errors.New("bad header magic")
	}

	binary.Read(buf, binary.BigEndian, &r.fileInfoOffset)
	binary.Read(buf, binary.BigEndian, &r.dataIndexOffset)
	binary.Read(buf, binary.BigEndian, &r.dataIndexCount)
	binary.Read(buf, binary.BigEndian, &r.metaIndexOffset)
	binary.Read(buf, binary.BigEndian, &r.metaIndexCount)
	binary.Read(buf, binary.BigEndian, &r.totalUncompressedDataBytes)
	binary.Read(buf, binary.BigEndian, &r.EntryCount)
	binary.Read(buf, binary.BigEndian, &r.compressionCodec)
	return nil
}

func (r *Reader) loadIndex(mmap mmap.MMap) error {

	dataIndexEnd := r.metaIndexOffset
	if r.metaIndexOffset == 0 {
		dataIndexEnd = uint64(r.Header.offset)
	}

	i := r.dataIndexOffset

	if bytes.Compare(mmap[i:i+8], IndexMagic) != 0 {
		return errors.New("bad data index magic")
	}
	i += 8

	for i < dataIndexEnd {
		dataBlock := Block{}

		dataBlock.offset = binary.BigEndian.Uint64(mmap[i:])
		i += uint64(binary.Size(dataBlock.offset))

		dataBlock.size = binary.BigEndian.Uint32(mmap[i:])
		i += uint64(binary.Size(dataBlock.size))

		firstKeyLen, s := binary.Uvarint(mmap[i:])
		if s < 1 || firstKeyLen < 1 {
			return fmt.Errorf("Failed to read key length, err %d", s)
		}
		i += uint64(s)

		dataBlock.firstKeyBytes = mmap[i : i+firstKeyLen]
		i += firstKeyLen

		r.index = append(r.index, dataBlock)
	}

	return nil
}

func After(a, b []byte) bool {
	return bytes.Compare(a, b) > 0
}

func (b *Block) IsAfter(key []byte) bool {
	return After(b.firstKeyBytes, key)
}

func (r *Reader) FirstKey() ([]byte, error) {
	if len(r.index) < 1 {
		return nil, fmt.Errorf("empty collection has no first key")
	}
	return r.index[0].firstKeyBytes, nil
}

func (r *Reader) FindBlock(from int, key []byte) int {
	remaining := len(r.index) - from - 1
	if r.Debug {
		log.Printf("[Reader.findBlock] cur %d, remaining %d\n", from, remaining)
	}

	if remaining <= 0 {
		if r.Debug {
			log.Println("[Reader.findBlock] last block")
		}
		return from // s.cur is the last block, so it is only choice.
	}

	if r.index[from+1].IsAfter(key) {
		if r.Debug {
			log.Println("[Reader.findBlock] next block is past key")
		}
		return from
	}

	offset := sort.Search(remaining, func(i int) bool {
		return r.index[from+i+1].IsAfter(key)
	})

	return from + offset
}

func (r *Reader) GetBlockBuf(i int, dst []byte) ([]byte, error) {
	var err error

	block := r.index[i]

	switch r.compressionCodec {
	case CompressionNone:
		dst = r.mmap[block.offset : block.offset+uint64(block.size)]
	case CompressionSnappy:
		uncompressedByteSize := binary.BigEndian.Uint32(r.mmap[block.offset : block.offset+4])
		if uncompressedByteSize != block.size {
			return nil, errors.New("mismatched uncompressed block size")
		}
		compressedByteSize := binary.BigEndian.Uint32(r.mmap[block.offset+4 : block.offset+8])
		compressedBytes := r.mmap[block.offset+8 : block.offset+8+uint64(compressedByteSize)]
		dst, err = snappy.Decode(dst, compressedBytes)
		if err != nil {
			return nil, err
		}
	default:
		return nil, errors.New("Unsupported compression codec " + string(r.compressionCodec))
	}

	if bytes.Compare(dst[0:8], DataMagic) != 0 {
		return nil, errors.New("bad data block magic")
	}

	return dst, nil
}

func (r *Reader) GetScanner() *Scanner {
	select {
	case s := <-r.scannerCache:
		return s
	default:
		return NewScanner(r)
	}
}

func (r *Reader) GetIterator() *Iterator {
	select {
	case i := <-r.iteratorCache:
		return i
	default:
		return NewIterator(r)
	}
}
<commit_msg>try cockroach's csnappy<commit_after>// Copyright (C) 2014 Daniel Harrison

package hfile

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"sort"

	"github.com/edsrzf/mmap-go"
	//"github.com/golang/snappy"
	"github.com/cockroachdb/c-snappy"
)

type Reader struct {
	CollectionConfig

	mmap mmap.MMap

	majorVersion uint32
	minorVersion uint32

	Header
	index []Block

	scannerCache  chan *Scanner
	iteratorCache chan *Iterator
}

type Header struct {
	offset int

	fileInfoOffset             uint64
	dataIndexOffset            uint64
	dataIndexCount             uint32
	metaIndexOffset            uint64
	metaIndexCount             uint32
	totalUncompressedDataBytes uint64
	EntryCount                 uint32
	compressionCodec           uint32
}

type Block struct {
	offset        uint64
	size          uint32
	firstKeyBytes []byte
}

func NewReader(name, path string, lock, debug bool) (*Reader, error) {
	return NewReaderFromConfig(CollectionConfig{name, path, path, lock, debug})
}

func NewReaderFromConfig(cfg CollectionConfig) (*Reader, error) {
	f, err := os.OpenFile(cfg.LocalPath, os.O_RDONLY, 0)

	if err != nil {
		return nil, fmt.Errorf("[Reader] Error opening file (%s): %v", cfg.LocalPath, err)
	}

	hfile := new(Reader)
	hfile.CollectionConfig = cfg

	hfile.mmap, err = mmap.Map(f, mmap.RDONLY, 0)

	if err != nil {
		return nil, err
	}

	fi, err := f.Stat()
	if err != nil {
		return nil, err
	}

	if hfile.InMem {
		mb := 1024.0 * 1024.0
		log.Printf("[Reader.NewReader] locking %s (%.02fmb)...\n", hfile.Name, float64(fi.Size())/mb)
		if err = hfile.mmap.Lock(); err != nil {
			log.Printf("[Reader.NewReader] error locking %s: %s\n", hfile.Name, err.Error())
			return nil, err
		}
		log.Printf("[Reader.NewReader] locked %s.\n", hfile.Name)
	} else if hfile.Debug {
		log.Printf("[Reader.NewReader] Not locking %s...\n", hfile.Name)
	}

	v := binary.BigEndian.Uint32(hfile.mmap[len(hfile.mmap)-4:])
	hfile.majorVersion = v & 0x00ffffff
	hfile.minorVersion = v >> 24

	err = hfile.readHeader(hfile.mmap)
	if err != nil {
		return nil, err
	}

	err = hfile.loadIndex(hfile.mmap)
	if err != nil {
		return hfile, err
	}
	hfile.scannerCache = make(chan *Scanner, 5)
	hfile.iteratorCache = make(chan *Iterator, 5)
	return hfile, nil
}

func (r *Reader) PrintDebugInfo(out io.Writer, includeStartKeys int) {
	fmt.Fprintln(out, "entries: ", r.EntryCount)
	fmt.Fprintf(out, "compressed: %v (codec: %d)\n", r.compressionCodec != CompressionNone, r.compressionCodec)
	fmt.Fprintln(out, "blocks: ", len(r.index))
	for i, blk := range r.index {
		if i > includeStartKeys {
			fmt.Fprintf(out, "\t... and %d more\n", len(r.index)-i)
			return
		}
		fmt.Fprintf(out, "\t#%d: %s\n", i, hex.EncodeToString(blk.firstKeyBytes))
	}
}

func (r *Reader) readHeader(mmap mmap.MMap) error {
	if r.majorVersion != 1 || r.minorVersion != 0 {
		return fmt.Errorf("wrong version: %d.%d", r.majorVersion, r.minorVersion)
	}

	r.Header.offset = len(mmap) - 60
	buf := bytes.NewReader(mmap[r.Header.offset:])

	headerMagic := make([]byte, 8)
	buf.Read(headerMagic)
	if bytes.Compare(headerMagic, TrailerMagic) != 0 {
		return errors.New("bad header magic")
	}

	binary.Read(buf, binary.BigEndian, &r.fileInfoOffset)
	binary.Read(buf, binary.BigEndian, &r.dataIndexOffset)
	binary.Read(buf, binary.BigEndian, &r.dataIndexCount)
	binary.Read(buf, binary.BigEndian, &r.metaIndexOffset)
	binary.Read(buf, binary.BigEndian, &r.metaIndexCount)
	binary.Read(buf, binary.BigEndian, &r.totalUncompressedDataBytes)
	binary.Read(buf, binary.BigEndian, &r.EntryCount)
	binary.Read(buf, binary.BigEndian, &r.compressionCodec)
	return nil
}

func (r *Reader) loadIndex(mmap mmap.MMap) error {

	dataIndexEnd := r.metaIndexOffset
	if r.metaIndexOffset == 0 {
		dataIndexEnd = uint64(r.Header.offset)
	}

	i := r.dataIndexOffset

	if bytes.Compare(mmap[i:i+8], IndexMagic) != 0 {
		return errors.New("bad data index magic")
	}
	i += 8

	for i < dataIndexEnd {
		dataBlock := Block{}

		dataBlock.offset = binary.BigEndian.Uint64(mmap[i:])
		i += uint64(binary.Size(dataBlock.offset))

		dataBlock.size = binary.BigEndian.Uint32(mmap[i:])
		i += uint64(binary.Size(dataBlock.size))

		firstKeyLen, s := binary.Uvarint(mmap[i:])
		if s < 1 || firstKeyLen < 1 {
			return fmt.Errorf("Failed to read key length, err %d", s)
		}
		i += uint64(s)

		dataBlock.firstKeyBytes = mmap[i : i+firstKeyLen]
		i += firstKeyLen

		r.index = append(r.index, dataBlock)
	}

	return nil
}

func After(a, b []byte) bool {
	return bytes.Compare(a, b) > 0
}

func (b *Block) IsAfter(key []byte) bool {
	return After(b.firstKeyBytes, key)
}

func (r *Reader) FirstKey() ([]byte, error) {
	if len(r.index) < 1 {
		return nil, fmt.Errorf("empty collection has no first key")
	}
	return r.index[0].firstKeyBytes, nil
}

func (r *Reader) FindBlock(from int, key []byte) int {
	remaining := len(r.index) - from - 1
	if r.Debug {
		log.Printf("[Reader.findBlock] cur %d, remaining %d\n", from, remaining)
	}

	if remaining <= 0 {
		if r.Debug {
			log.Println("[Reader.findBlock] last block")
		}
		return from // s.cur is the last block, so it is only choice.
	}

	if r.index[from+1].IsAfter(key) {
		if r.Debug {
			log.Println("[Reader.findBlock] next block is past key")
		}
		return from
	}

	offset := sort.Search(remaining, func(i int) bool {
		return r.index[from+i+1].IsAfter(key)
	})

	return from + offset
}

func (r *Reader) GetBlockBuf(i int, dst []byte) ([]byte, error) {
	var err error

	block := r.index[i]

	switch r.compressionCodec {
	case CompressionNone:
		dst = r.mmap[block.offset : block.offset+uint64(block.size)]
	case CompressionSnappy:
		uncompressedByteSize := binary.BigEndian.Uint32(r.mmap[block.offset : block.offset+4])
		if uncompressedByteSize != block.size {
			return nil, errors.New("mismatched uncompressed block size")
		}
		compressedByteSize := binary.BigEndian.Uint32(r.mmap[block.offset+4 : block.offset+8])
		compressedBytes := r.mmap[block.offset+8 : block.offset+8+uint64(compressedByteSize)]
		dst, err = snappy.Decode(dst, compressedBytes)
		if err != nil {
			return nil, err
		}
	default:
		return nil, errors.New("Unsupported compression codec " + string(r.compressionCodec))
	}

	if bytes.Compare(dst[0:8], DataMagic) != 0 {
		return nil, errors.New("bad data block magic")
	}

	return dst, nil
}

func (r *Reader) GetScanner() *Scanner {
	select {
	case s := <-r.scannerCache:
		return s
	default:
		return NewScanner(r)
	}
}

func (r *Reader) GetIterator() *Iterator {
	select {
	case i := <-r.iteratorCache:
		return i
	default:
		return NewIterator(r)
	}
}
<|endoftext|>


<commit_before>/**********************************************************\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: http://www.hprose.com/                 |
|                   http://www.hprose.org/                 |
|                                                          |
\**********************************************************/
/**********************************************************\
 *                                                        *
 * hprose/stream_client.go                                *
 *                                                        *
 * hprose stream client for Go.                           *
 *                                                        *
 * LastModified: May 25, 2015                             *
 * Authors: Ma Bingyao <andot@hprose.com>                 *
 *          Ore_Ash <nanohugh@gmail.com>                  *
 *                                                        *
\**********************************************************/

package hprose

import (
	"net"
	"sync"
	"time"
)

// StreamClient is base struct for TcpClient and UnixClient
type StreamClient struct {
	*BaseClient
	timeout      interface{}
	readBuffer   interface{}
	readTimeout  interface{}
	writeBuffer  interface{}
	writeTimeout interface{}
}

func newStreamClient(trans Transporter) (client *StreamClient) {
	client = new(StreamClient)
	client.BaseClient = NewBaseClient(trans)
	return
}

type streamConnStatus int

const (
	free = streamConnStatus(iota)
	using
	closing
)

// StreamConnEntry is the connection entry in connection pool
type StreamConnEntry struct {
	uri          string
	conn         net.Conn
	status       streamConnStatus
	lastUsedTime time.Time
}

// NewStreamConnEntry is the constructor for StreamConnEntry
func NewStreamConnEntry(uri string) (entry *StreamConnEntry) {
	entry = new(StreamConnEntry)
	entry.uri = uri
	entry.status = using
	entry.lastUsedTime = time.Now()
	return
}

// Get the connection
func (connEntry *StreamConnEntry) Get() net.Conn {
	return connEntry.conn
}

// Set the connection
func (connEntry *StreamConnEntry) Set(conn net.Conn) {
	if conn != nil {
		connEntry.conn = conn
	}
}

// Close the connection
func (connEntry *StreamConnEntry) Close() {
	connEntry.status = closing
}

// StreamConnPool is the connection pool
type StreamConnPool struct {
	sync.Mutex
	pool    []*StreamConnEntry
	timer   *time.Ticker
	timeout time.Duration
}

// NewStreamConnPool is the constructor for StreamConnPool
func NewStreamConnPool(num int) (pool *StreamConnPool) {
	pool = new(StreamConnPool)
	pool.pool = make([]*StreamConnEntry, 0, num)
	return
}

func freeConns(conns []net.Conn) {
	for _, conn := range conns {
		conn.Close()
	}
}

// Timeout return the timeout of the connection in pool
func (connPool *StreamConnPool) Timeout() time.Duration {
	return connPool.timeout
}

// SetTimeout for connection in pool
func (connPool *StreamConnPool) SetTimeout(d time.Duration) {
	if connPool.timer != nil {
		connPool.timer.Stop()
		connPool.timer = nil
	}
	connPool.timeout = d
	if d > 0 {
		connPool.timer = time.NewTicker(d)
		go connPool.closeTimeoutConns()
	}
}

func (connPool *StreamConnPool) closeTimeoutConns() {
	for t := range connPool.timer.C {
		connPool.Lock()
		defer connPool.Unlock()
		conns := make([]net.Conn, 0, len(connPool.pool))
		for _, entry := range connPool.pool {
			if entry.uri != "" &&
				entry.status == free &&
				entry.conn != nil &&
				t.After(entry.lastUsedTime.Add(connPool.timeout)) {
				conns = append(conns, entry.conn)
				entry.conn = nil
				entry.uri = ""
			}
		}
		go freeConns(conns)
	}
}

// Get the StreamConnEntry in StreamConnPool
func (connPool *StreamConnPool) Get(uri string) *StreamConnEntry {
	connPool.Lock()
	defer connPool.Unlock()
	for _, entry := range connPool.pool {
		if entry.status == free {
			if entry.uri == uri {
				entry.status = using
				return entry
			} else if entry.uri == "" {
				entry.status = using
				entry.uri = uri
				return entry
			}
		}
	}
	entry := NewStreamConnEntry(uri)
	connPool.pool = append(connPool.pool, entry)
	return entry
}

// Close the specify uri connections in StreamConnPool
func (connPool *StreamConnPool) Close(uri string) {
	connPool.Lock()
	defer connPool.Unlock()
	conns := make([]net.Conn, 0, len(connPool.pool))
	for _, entry := range connPool.pool {
		if entry.uri == uri {
			if entry.status == free {
				conns = append(conns, entry.conn)
				entry.conn = nil
				entry.uri = ""
			} else {
				entry.Close()
			}
		}
	}
	go freeConns(conns)
}

// Free the entry to pool
func (connPool *StreamConnPool) Free(entry *StreamConnEntry) {
	if entry.status == closing {
		if entry.conn != nil {
			go entry.conn.Close()
			entry.conn = nil
		}
		entry.uri = ""
	}
	entry.lastUsedTime = time.Now()
	entry.status = free
}

// SetReadBuffer sets the size of the operating system's receive buffer associated with the connection.
func (client *StreamClient) SetReadBuffer(bytes int) {
	client.readBuffer = bytes
}

// SetReadTimeout for stream client
func (client *StreamClient) SetReadTimeout(d time.Duration) {
	client.readTimeout = d
}

// SetWriteBuffer sets the size of the operating system's transmit buffer associated with the connection.
func (client *StreamClient) SetWriteBuffer(bytes int) {
	client.writeBuffer = bytes
}

// SetWriteTimeout for stream client
func (client *StreamClient) SetWriteTimeout(d time.Duration) {
	client.writeTimeout = d
}
<commit_msg>Fixed dead lock<commit_after>/**********************************************************\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: http://www.hprose.com/                 |
|                   http://www.hprose.org/                 |
|                                                          |
\**********************************************************/
/**********************************************************\
 *                                                        *
 * hprose/stream_client.go                                *
 *                                                        *
 * hprose stream client for Go.                           *
 *                                                        *
 * LastModified: May 25, 2015                             *
 * Authors: Ma Bingyao <andot@hprose.com>                 *
 *          Ore_Ash <nanohugh@gmail.com>                  *
 *                                                        *
\**********************************************************/

package hprose

import (
	"net"
	"sync"
	"time"
)

// StreamClient is base struct for TcpClient and UnixClient
type StreamClient struct {
	*BaseClient
	timeout      interface{}
	readBuffer   interface{}
	readTimeout  interface{}
	writeBuffer  interface{}
	writeTimeout interface{}
}

func newStreamClient(trans Transporter) (client *StreamClient) {
	client = new(StreamClient)
	client.BaseClient = NewBaseClient(trans)
	return
}

type streamConnStatus int

const (
	free = streamConnStatus(iota)
	using
	closing
)

// StreamConnEntry is the connection entry in connection pool
type StreamConnEntry struct {
	uri          string
	conn         net.Conn
	status       streamConnStatus
	lastUsedTime time.Time
}

// NewStreamConnEntry is the constructor for StreamConnEntry
func NewStreamConnEntry(uri string) (entry *StreamConnEntry) {
	entry = new(StreamConnEntry)
	entry.uri = uri
	entry.status = using
	entry.lastUsedTime = time.Now()
	return
}

// Get the connection
func (connEntry *StreamConnEntry) Get() net.Conn {
	return connEntry.conn
}

// Set the connection
func (connEntry *StreamConnEntry) Set(conn net.Conn) {
	if conn != nil {
		connEntry.conn = conn
	}
}

// Close the connection
func (connEntry *StreamConnEntry) Close() {
	connEntry.status = closing
}

// StreamConnPool is the connection pool
type StreamConnPool struct {
	sync.Mutex
	pool    []*StreamConnEntry
	timer   *time.Ticker
	timeout time.Duration
}

// NewStreamConnPool is the constructor for StreamConnPool
func NewStreamConnPool(num int) (pool *StreamConnPool) {
	pool = new(StreamConnPool)
	pool.pool = make([]*StreamConnEntry, 0, num)
	return
}

func freeConns(conns []net.Conn) {
	for _, conn := range conns {
		conn.Close()
	}
}

// Timeout return the timeout of the connection in pool
func (connPool *StreamConnPool) Timeout() time.Duration {
	return connPool.timeout
}

// SetTimeout for connection in pool
func (connPool *StreamConnPool) SetTimeout(d time.Duration) {
	if connPool.timer != nil {
		connPool.timer.Stop()
		connPool.timer = nil
	}
	connPool.timeout = d
	if d > 0 {
		connPool.timer = time.NewTicker(d)
		go connPool.closeTimeoutConns()
	}
}

func (connPool *StreamConnPool) closeTimeoutConns() {
	for t := range connPool.timer.C {
		func() {
			connPool.Lock()
			defer connPool.Unlock()
			conns := make([]net.Conn, 0, len(connPool.pool))
			for _, entry := range connPool.pool {
				if entry.uri != "" &&
					entry.status == free &&
					entry.conn != nil &&
					t.After(entry.lastUsedTime.Add(connPool.timeout)) {
					conns = append(conns, entry.conn)
					entry.conn = nil
					entry.uri = ""
				}
			}
			go freeConns(conns)
		}()
	}
}

// Get the StreamConnEntry in StreamConnPool
func (connPool *StreamConnPool) Get(uri string) *StreamConnEntry {
	connPool.Lock()
	defer connPool.Unlock()
	for _, entry := range connPool.pool {
		if entry.status == free {
			if entry.uri == uri {
				entry.status = using
				return entry
			} else if entry.uri == "" {
				entry.status = using
				entry.uri = uri
				return entry
			}
		}
	}
	entry := NewStreamConnEntry(uri)
	connPool.pool = append(connPool.pool, entry)
	return entry
}

// Close the specify uri connections in StreamConnPool
func (connPool *StreamConnPool) Close(uri string) {
	connPool.Lock()
	defer connPool.Unlock()
	conns := make([]net.Conn, 0, len(connPool.pool))
	for _, entry := range connPool.pool {
		if entry.uri == uri {
			if entry.status == free {
				conns = append(conns, entry.conn)
				entry.conn = nil
				entry.uri = ""
			} else {
				entry.Close()
			}
		}
	}
	go freeConns(conns)
}

// Free the entry to pool
func (connPool *StreamConnPool) Free(entry *StreamConnEntry) {
	if entry.status == closing {
		if entry.conn != nil {
			go entry.conn.Close()
			entry.conn = nil
		}
		entry.uri = ""
	}
	entry.lastUsedTime = time.Now()
	entry.status = free
}

// SetReadBuffer sets the size of the operating system's receive buffer associated with the connection.
func (client *StreamClient) SetReadBuffer(bytes int) {
	client.readBuffer = bytes
}

// SetReadTimeout for stream client
func (client *StreamClient) SetReadTimeout(d time.Duration) {
	client.readTimeout = d
}

// SetWriteBuffer sets the size of the operating system's transmit buffer associated with the connection.
func (client *StreamClient) SetWriteBuffer(bytes int) {
	client.writeBuffer = bytes
}

// SetWriteTimeout for stream client
func (client *StreamClient) SetWriteTimeout(d time.Duration) {
	client.writeTimeout = d
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package version

import (
	"fmt"
	"os"
	"strings"

	"github.com/blang/semver/v4"
	"k8s.io/client-go/discovery"
)

const (
	// KubernetesMinVersionKey is the environment variable that can be used to override
	// the Kubernetes minimum version required by Knative.
	KubernetesMinVersionKey = "KUBERNETES_MIN_VERSION"

	defaultMinimumVersion = "v1.17.0"
)

func getMinimumVersion() string {
	if v := os.Getenv(KubernetesMinVersionKey); v != "" {
		return v
	}
	return defaultMinimumVersion
}

// CheckMinimumVersion checks if the currently installed version of
// Kubernetes is compatible with the minimum version required.
// Returns an error if its not.
//
// A Kubernetes discovery client can be passed in as the versioner
// like `CheckMinimumVersion(kubeClient.Discovery())`.
func CheckMinimumVersion(versioner discovery.ServerVersionInterface) error {
	v, err := versioner.ServerVersion()
	if err != nil {
		return err
	}

	currentVersion, err := semver.Make(normalizeVersion(v.GitVersion))
	if err != nil {
		return err
	}
	minimumVersion, err := semver.Make(normalizeVersion(getMinimumVersion()))
	if err != nil {
		return err
	}

	// If no specific pre-release requirement is set, we default to "-0" to always allow
	// pre-release versions of the same Major.Minor.Patch version.
	if len(minimumVersion.Pre) == 0 {
		minimumVersion.Pre = []semver.PRVersion{{VersionNum: 0}}
	}

	// Compare returns 1 if the first version is greater than the
	// second version.
	if currentVersion.LT(minimumVersion) {
		if len(currentVersion.Pre) > 0 {
			return fmt.Errorf("pre-release kubernetes version %q is not compatible, need at least %q (this can be overridden with the env var %q); note pre-release version is smaller than the corresponding release version (e.g. 1.x.y-z < 1.x.y), using 1.x.y-0 as the minimum version is likely to help in this case",
				currentVersion, minimumVersion, KubernetesMinVersionKey)
		}
		return fmt.Errorf("kubernetes version %q is not compatible, need at least %q (this can be overridden with the env var %q)",
			currentVersion, minimumVersion, KubernetesMinVersionKey)
	}
	return nil
}

func normalizeVersion(v string) string {
	if strings.HasPrefix(v, "v") {
		// No need to account for unicode widths.
		return v[1:]
	}
	return v
}
<commit_msg>Comment k8s version to update docs when changed (#1980)<commit_after>/*
Copyright 2019 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package version

import (
	"fmt"
	"os"
	"strings"

	"github.com/blang/semver/v4"
	"k8s.io/client-go/discovery"
)

const (
	// KubernetesMinVersionKey is the environment variable that can be used to override
	// the Kubernetes minimum version required by Knative.
	KubernetesMinVersionKey = "KUBERNETES_MIN_VERSION"

	// NOTE: If you are changing this line, please also update the minimum kubernetes
	// version listed here:
	// https://github.com/knative/docs/blob/master/docs/install/any-kubernetes-cluster.md#before-you-begin
	defaultMinimumVersion = "v1.17.0"
)

func getMinimumVersion() string {
	if v := os.Getenv(KubernetesMinVersionKey); v != "" {
		return v
	}
	return defaultMinimumVersion
}

// CheckMinimumVersion checks if the currently installed version of
// Kubernetes is compatible with the minimum version required.
// Returns an error if its not.
//
// A Kubernetes discovery client can be passed in as the versioner
// like `CheckMinimumVersion(kubeClient.Discovery())`.
func CheckMinimumVersion(versioner discovery.ServerVersionInterface) error {
	v, err := versioner.ServerVersion()
	if err != nil {
		return err
	}

	currentVersion, err := semver.Make(normalizeVersion(v.GitVersion))
	if err != nil {
		return err
	}
	minimumVersion, err := semver.Make(normalizeVersion(getMinimumVersion()))
	if err != nil {
		return err
	}

	// If no specific pre-release requirement is set, we default to "-0" to always allow
	// pre-release versions of the same Major.Minor.Patch version.
	if len(minimumVersion.Pre) == 0 {
		minimumVersion.Pre = []semver.PRVersion{{VersionNum: 0}}
	}

	// Compare returns 1 if the first version is greater than the
	// second version.
	if currentVersion.LT(minimumVersion) {
		if len(currentVersion.Pre) > 0 {
			return fmt.Errorf("pre-release kubernetes version %q is not compatible, need at least %q (this can be overridden with the env var %q); note pre-release version is smaller than the corresponding release version (e.g. 1.x.y-z < 1.x.y), using 1.x.y-0 as the minimum version is likely to help in this case",
				currentVersion, minimumVersion, KubernetesMinVersionKey)
		}
		return fmt.Errorf("kubernetes version %q is not compatible, need at least %q (this can be overridden with the env var %q)",
			currentVersion, minimumVersion, KubernetesMinVersionKey)
	}
	return nil
}

func normalizeVersion(v string) string {
	if strings.HasPrefix(v, "v") {
		// No need to account for unicode widths.
		return v[1:]
	}
	return v
}
<|endoftext|>


<commit_before>package version

const (
	// Version is the current File Browser version.
	Version = "v2.0.1"
)
<commit_msg>chore: setting untracked version [ci skip]<commit_after>package version

const (
	// Version is the current File Browser version.
	Version = "(untracked)"
)
<|endoftext|>


<commit_before>package version

import "fmt"

const (
	// VersionMajor is for an API incompatible changes
	VersionMajor = 2
	// VersionMinor is for functionality in a backwards-compatible manner
	VersionMinor = 0
	// VersionPatch is for backwards-compatible bug fixes
	VersionPatch = 2

	// VersionDev indicates development branch. Releases will be empty string.
	VersionDev = "-dev"
)

// Version is the specification version that the package types support.
var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
<commit_msg>release v3.0.0<commit_after>package version

import "fmt"

const (
	// VersionMajor is for an API incompatible changes
	VersionMajor = 3
	// VersionMinor is for functionality in a backwards-compatible manner
	VersionMinor = 0
	// VersionPatch is for backwards-compatible bug fixes
	VersionPatch = 0

	// VersionDev indicates development branch. Releases will be empty string.
	VersionDev = ""
)

// Version is the specification version that the package types support.
var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
<|endoftext|>


<commit_before>// Copyright 2016 The Linux Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package version

import "fmt"

const (
	// VersionMajor is for an API incompatible changes
	VersionMajor = 0
	// VersionMinor is for functionality in a backwards-compatible manner
	VersionMinor = 3
	// VersionPatch is for backwards-compatible bug fixes
	VersionPatch = 0

	// VersionDev indicates development branch. Releases will be empty string.
	VersionDev = "-dev"
)

// Version is the specification version that the package types support.
var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
<commit_msg>version: bump to v1.0.0-rc1<commit_after>// Copyright 2016 The Linux Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package version

import "fmt"

const (
	// VersionMajor is for an API incompatible changes
	VersionMajor = 1
	// VersionMinor is for functionality in a backwards-compatible manner
	VersionMinor = 0
	// VersionPatch is for backwards-compatible bug fixes
	VersionPatch = 0

	// VersionDev indicates development branch. Releases will be empty string.
	VersionDev = "-rc1"
)

// Version is the specification version that the package types support.
var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
<|endoftext|>


<commit_before>package LevenshteinTrie

import (
	"fmt"
	"sort"
	"unicode/utf8"
)

func Min(a ...int) int {
	min := int(^uint(0) >> 1) // largest int
	for _, i := range a {
		if i < min {
			min = i
		}
	}
	return min
}
func Max(a ...int) int {
	max := int(0)
	for _, i := range a {
		if i > max {
			max = i
		}
	}
	return max
}

type TrieNode struct {
	letter   rune //Equivalent to int32
	children map[rune]*TrieNode
	final    bool
	text     string
}

func (t *TrieNode) String() string {
	s := fmt.Sprintf("%s\n", t.letter)
	for _, v := range t.children {
		s += fmt.Sprintf("-%s\n", v)
	}
	return s
}

func NewTrie() *TrieNode {
	return &TrieNode{children: make(map[rune]*TrieNode)}
}

func (root *TrieNode) InsertText(text string) {
	if root == nil {
		return
	}

	currNode := root //Starts at root
	for i, w := 0, 0; i < len(text); i += w {
		runeValue, width := utf8.DecodeRuneInString(text[i:])
		final := false
		if width+i == len(text) {
			final = true
		}
		w = width

		currNode = NewTrieNode(currNode, runeValue, final, text)
	}
}

func NewTrieNode(t *TrieNode, runeValue rune, final bool, text string) *TrieNode {
	node, exists := t.children[runeValue]
	if !exists {
		node = &TrieNode{letter: runeValue, children: make(map[rune]*TrieNode)}
		t.children[runeValue] = node
	}
	if final {
		node.final = true
		node.text = text
	}
	return node
}

func (t *TrieNode) SearchSuffix(query string) []string {
	var curr *TrieNode
	var ok bool

	curr = t
	//first, find the end of the prefix
	for _, letter := range query {
		if curr != nil {
			curr, ok = curr.children[letter]
			if ok {
				//do nothing
			}

		} else {
			return nil
		}
	}

	candidates := getsuffixr(curr)

	return candidates
}

func getsuffixr(n *TrieNode) []string {
	if n == nil {
		return nil
	}

	candidates := make([]string, 0)
	if n.final == true {
		candidates = append(candidates, n.text)
	}

	for _, childNode := range n.children {
		candidates = append(candidates, getsuffixr(childNode)...)
	}
	return candidates
}

type QueryResult struct {
	Val      string
	Distance int
}

func (q QueryResult) String() string {
	return fmt.Sprintf("Val: %s\n", q.Val)
}

type ByDistance []QueryResult

func (a ByDistance) Len() int           { return len(a) }
func (a ByDistance) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByDistance) Less(i, j int) bool { return a[i].Distance < a[j].Distance }

func (n *TrieNode) SearchLevenshtein(text string, distance int) []QueryResult {

	//initialize the first row for the dynamic programming alg
	l := utf8.RuneCount([]byte(text))
	currentRow := make([]int, l+1)

	for i := 0; i < len(currentRow); i++ {
		currentRow[i] = i
	}

	candidates := make([]QueryResult, 0)

	for letter, childNode := range n.children {
		candidates = append(candidates, searchlevr(childNode, currentRow, letter, []rune(text), distance)...)
	}

	sort.Sort(ByDistance(candidates))
	return candidates
}

func searchlevr(n *TrieNode, prevRow []int, letter rune, text []rune, maxDistance int) []QueryResult {
	columns := len(prevRow)
	currentRow := make([]int, columns)

	currentRow[0] = prevRow[0] + 1

	for col := 1; col < columns; col++ {
		if text[col-1] == letter {
			currentRow[col] = prevRow[col-1]
			continue
		}
		insertCost := currentRow[col-1] + 1
		deleteCost := prevRow[col] + 1
		replaceCost := prevRow[col-1] + 1

		currentRow[col] = Min(insertCost, deleteCost, replaceCost)
	}

	candidates := make([]QueryResult, 0)

	distance := currentRow[len(currentRow)-1]
	if distance <= maxDistance && n.final == true {
		candidates = append(candidates, QueryResult{Val: n.text, Distance: distance})
	}
	mi := Min(currentRow[1:]...)
	if mi <= maxDistance {
		for l, childNode := range n.children {
			candidates = append(candidates, searchlevr(childNode, currentRow, l, text, maxDistance)...)
		}
	}
	return candidates
}
<commit_msg>printing changes<commit_after>package LevenshteinTrie

import (
	"fmt"
	"sort"
	"unicode/utf8"
)

func Min(a ...int) int {
	min := int(^uint(0) >> 1) // largest int
	for _, i := range a {
		if i < min {
			min = i
		}
	}
	return min
}
func Max(a ...int) int {
	max := int(0)
	for _, i := range a {
		if i > max {
			max = i
		}
	}
	return max
}

type TrieNode struct {
	letter   rune //Equivalent to int32
	children map[rune]*TrieNode
	final    bool
	text     string
}

func (t *TrieNode) String() string {
	s := fmt.Sprintf("%#U\n", t.letter)
	for _, v := range t.children {
		s += fmt.Sprintf("-%#U\n", v)
	}
	return s
}

func NewTrie() *TrieNode {
	return &TrieNode{children: make(map[rune]*TrieNode)}
}

func (root *TrieNode) InsertText(text string) {
	if root == nil {
		return
	}

	currNode := root //Starts at root
	for i, w := 0, 0; i < len(text); i += w {
		runeValue, width := utf8.DecodeRuneInString(text[i:])
		final := false
		if width+i == len(text) {
			final = true
		}
		w = width

		currNode = NewTrieNode(currNode, runeValue, final, text)
	}
}

func NewTrieNode(t *TrieNode, runeValue rune, final bool, text string) *TrieNode {
	node, exists := t.children[runeValue]
	if !exists {
		node = &TrieNode{letter: runeValue, children: make(map[rune]*TrieNode)}
		t.children[runeValue] = node
	}
	if final {
		node.final = true
		node.text = text
	}
	return node
}

func (t *TrieNode) SearchSuffix(query string) []string {
	var curr *TrieNode
	var ok bool

	curr = t
	//first, find the end of the prefix
	for _, letter := range query {
		if curr != nil {
			curr, ok = curr.children[letter]
			if ok {
				//do nothing
			}

		} else {
			return nil
		}
	}

	candidates := getsuffixr(curr)

	return candidates
}

func getsuffixr(n *TrieNode) []string {
	if n == nil {
		return nil
	}

	candidates := make([]string, 0)
	if n.final == true {
		candidates = append(candidates, n.text)
	}

	for _, childNode := range n.children {
		candidates = append(candidates, getsuffixr(childNode)...)
	}
	return candidates
}

type QueryResult struct {
	Val      string
	Distance int
}

func (q QueryResult) String() string {
	return fmt.Sprintf("Val: %s, Dist: %d\n", q.Val, q.Distance)
}

type ByDistance []QueryResult

func (a ByDistance) Len() int           { return len(a) }
func (a ByDistance) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByDistance) Less(i, j int) bool { return a[i].Distance < a[j].Distance }

func (n *TrieNode) SearchLevenshtein(text string, distance int) []QueryResult {

	//initialize the first row for the dynamic programming alg
	l := utf8.RuneCount([]byte(text))
	currentRow := make([]int, l+1)

	for i := 0; i < len(currentRow); i++ {
		currentRow[i] = i
	}

	candidates := make([]QueryResult, 0)

	for letter, childNode := range n.children {
		candidates = append(candidates, searchlevr(childNode, currentRow, letter, []rune(text), distance)...)
	}

	sort.Sort(ByDistance(candidates))
	return candidates
}

func searchlevr(n *TrieNode, prevRow []int, letter rune, text []rune, maxDistance int) []QueryResult {
	columns := len(prevRow)
	currentRow := make([]int, columns)

	currentRow[0] = prevRow[0] + 1

	for col := 1; col < columns; col++ {
		if text[col-1] == letter {
			currentRow[col] = prevRow[col-1]
			continue
		}
		insertCost := currentRow[col-1] + 1
		deleteCost := prevRow[col] + 1
		replaceCost := prevRow[col-1] + 1

		currentRow[col] = Min(insertCost, deleteCost, replaceCost)
	}

	candidates := make([]QueryResult, 0)

	distance := currentRow[len(currentRow)-1]
	if distance <= maxDistance && n.final == true {
		candidates = append(candidates, QueryResult{Val: n.text, Distance: distance})
	}
	mi := Min(currentRow[1:]...)
	if mi <= maxDistance {
		for l, childNode := range n.children {
			candidates = append(candidates, searchlevr(childNode, currentRow, l, text, maxDistance)...)
		}
	}
	return candidates
}
<|endoftext|>