<commit_before>package chain

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"os"
	"strings"
)

// Chain contains sentence fragments that can be recombined.
type Chain struct {
	Nodes     []*Node
	PrefixLen int `json:"prefix_len"`
}

// Build creates a new chain from newline delimited text.
func (c *Chain) Build(r io.Reader) {
	br := bufio.NewReader(r)
	p := prefix(make([]string, c.PrefixLen))
	var s string
	for {
		if _, err := fmt.Fscan(br, &s); err != nil {
			break
		}
		key := p.key()
		c.appendFragment(key, s)
		p.shift(s)
	}
}

// Generate creates multiple paragraphs.
func (c *Chain) Generate() string {
	n := paragraphCount()
	paragraphs := make([]string, n, n)
	for i := 0; i < n; i++ {
		paragraphs = append(paragraphs, c.GenerateParagraph())
	}
	return strings.TrimLeft(strings.Join(paragraphs, "\n\n"), "\n ")
}

// GenerateParagraph creates a single paragraph.
func (c *Chain) GenerateParagraph() string {
	p := make(prefix, c.PrefixLen)
	n := wordCount()

	var words []string
	for {
		choices := c.fragmentsFor(p.key())
		if choices == nil {
			break
		}
		next := choices[rand.Intn(len(choices))]
		words = append(words, next)
		p.shift(next)
		if len(choices) > n && (completesSentence(next) || len(choices) > n+10) {
			break
		}
	}
	return strings.Join(words, " ")
}

// ToFile marshalls a chain to a file in JSON format.
func (c *Chain) ToFile(path string) error {
	bytes, err := json.Marshal(c)
	if err != nil {
		return err
	}

	return ioutil.WriteFile(path, bytes, 0644)
}

// findNode sifts through all the nodes in a chain, looking for a particular key.
// This is used primarily in two contexts: building a chain, and generating output.
// When building a chain, each new word that is encountered must be appended as a
// possible choice following a particular key (one or more words).
// When generating new output, each chosen word becomes the new anchoring point which
// decides what other words may follow.
func (c *Chain) findNode(key string) *Node {
	for _, n := range c.Nodes {
		if n.Key == key {
			return n
		}
	}
	return nil
}

// fragments returns the possible words that may follow a key.
func (c *Chain) fragmentsFor(key string) []string {
	node := c.findNode(key)
	if node == nil {
		return nil
	}
	return node.Fragments
}

// appendFragment adds a word to the list of possible choices following key.
func (c *Chain) appendFragment(key, fragment string) {
	node := c.findNode(key)
	if node == nil {
		node = new(Node)
		node.Key = key
		c.Nodes = append(c.Nodes, node)
	}
	node.Fragments = append(node.Fragments, fragment)
}

// NewChain creates an empty chain.
// The prefix of each node will be prefixLen words long.
func NewChain(prefixLen int) *Chain {
	return &Chain{[]*Node{}, prefixLen}
}

// FromFile unmarshalls a stored JSON chain.
func FromFile(path string) (*Chain, error) {
	if _, err := os.Stat(path); err != nil {
		return nil, err
	}
	bytes, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	c := new(Chain)

	if err := json.Unmarshal(bytes, c); err != nil {
		return nil, err
	}
	return c, nil
}

// wordCount represents paragraph sizes of unsurprising length.
// The paragraphs are intended to be used in fake comments, and
// paragraphs that are somewhere in this range don't seem particularly
// short, nor particularly long.
func wordCount() int {
	numbers := []int{13, 21, 34, 55, 89, 144}
	return numbers[rand.Intn(len(numbers))]
}

// paragraphCount suggests a reasonable comment size.
func paragraphCount() int {
	numbers := []int{1, 2, 2, 3, 3, 3, 4, 4, 5}
	return numbers[rand.Intn(len(numbers))]
}

// completesSentence determines whether or not a fragment ends with punctuation.
func completesSentence(s string) bool {
	return strings.LastIndexAny(s, "?!.") == len(s)-1
}
<commit_msg>Fix bug in deciding when to stop the chain<commit_after>package chain

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"os"
	"strings"
)

// Chain contains sentence fragments that can be recombined.
type Chain struct {
	Nodes     []*Node
	PrefixLen int `json:"prefix_len"`
}

// Build creates a new chain from newline delimited text.
func (c *Chain) Build(r io.Reader) {
	br := bufio.NewReader(r)
	p := prefix(make([]string, c.PrefixLen))
	var s string
	for {
		if _, err := fmt.Fscan(br, &s); err != nil {
			break
		}
		key := p.key()
		c.appendFragment(key, s)
		p.shift(s)
	}
}

// Generate creates multiple paragraphs.
func (c *Chain) Generate() string {
	n := paragraphCount()
	paragraphs := make([]string, n, n)
	for i := 0; i < n; i++ {
		paragraphs = append(paragraphs, c.GenerateParagraph())
	}
	return strings.TrimLeft(strings.Join(paragraphs, "\n\n"), "\n ")
}

// GenerateParagraph creates a single paragraph.
func (c *Chain) GenerateParagraph() string {
	p := make(prefix, c.PrefixLen)
	n := wordCount()

	var words []string
	for {
		choices := c.fragmentsFor(p.key())
		if choices == nil {
			break
		}
		current := choices[rand.Intn(len(choices))]
		words = append(words, current)
		p.shift(current)
		if len(words) > n && (completesSentence(current) || len(words) > n+500) {
			break
		}
	}
	return strings.Join(words, " ")
}

// ToFile marshalls a chain to a file in JSON format.
func (c *Chain) ToFile(path string) error {
	bytes, err := json.Marshal(c)
	if err != nil {
		return err
	}

	return ioutil.WriteFile(path, bytes, 0644)
}

// findNode sifts through all the nodes in a chain, looking for a particular key.
// This is used primarily in two contexts: building a chain, and generating output.
// When building a chain, each new word that is encountered must be appended as a
// possible choice following a particular key (one or more words).
// When generating new output, each chosen word becomes the new anchoring point which
// decides what other words may follow.
func (c *Chain) findNode(key string) *Node {
	for _, n := range c.Nodes {
		if n.Key == key {
			return n
		}
	}
	return nil
}

// fragments returns the possible words that may follow a key.
func (c *Chain) fragmentsFor(key string) []string {
	node := c.findNode(key)
	if node == nil {
		return nil
	}
	return node.Fragments
}

// appendFragment adds a word to the list of possible choices following key.
func (c *Chain) appendFragment(key, fragment string) {
	node := c.findNode(key)
	if node == nil {
		node = new(Node)
		node.Key = key
		c.Nodes = append(c.Nodes, node)
	}
	node.Fragments = append(node.Fragments, fragment)
}

// NewChain creates an empty chain.
// The prefix of each node will be prefixLen words long.
func NewChain(prefixLen int) *Chain {
	return &Chain{[]*Node{}, prefixLen}
}

// FromFile unmarshalls a stored JSON chain.
func FromFile(path string) (*Chain, error) {
	if _, err := os.Stat(path); err != nil {
		return nil, err
	}
	bytes, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	c := new(Chain)

	if err := json.Unmarshal(bytes, c); err != nil {
		return nil, err
	}
	return c, nil
}

// wordCount represents paragraph sizes of unsurprising length.
// The paragraphs are intended to be used in fake comments, and
// paragraphs that are somewhere in this range don't seem particularly
// short, nor particularly long.
func wordCount() int {
	numbers := []int{13, 21, 34, 55, 89, 144}
	return numbers[rand.Intn(len(numbers))]
}

// paragraphCount suggests a reasonable comment size.
func paragraphCount() int {
	numbers := []int{1, 2, 2, 3, 3, 3, 4, 4, 5}
	return numbers[rand.Intn(len(numbers))]
}

// completesSentence determines whether or not a fragment ends with punctuation.
func completesSentence(s string) bool {
	return strings.LastIndexAny(s, "?!.") == len(s)-1
}
<|endoftext|>


<commit_before><commit_msg>makeBarOnCompleteFiller<commit_after><|endoftext|>


<commit_before>package router

import (
	"bytes"
	"fmt"
	"sync"
)

type Routes struct {
	sync.RWMutex
	ourself    *Peer
	peers      *Peers
	unicast    map[PeerName]PeerName
	broadcast  map[PeerName][]PeerName
	actionChan chan<- RoutesAction
}

func NewRoutes(ourself *Peer, peers *Peers) *Routes {
	routes := &Routes{
		ourself:   ourself,
		peers:     peers,
		unicast:   make(map[PeerName]PeerName),
		broadcast: make(map[PeerName][]PeerName)}
	routes.unicast[ourself.Name] = UnknownPeerName
	routes.broadcast[ourself.Name] = []PeerName{}
	return routes
}

func (routes *Routes) Start() {
	actionChan := make(chan RoutesAction, ChannelSize)
	routes.actionChan = actionChan
	go routes.actorLoop(actionChan)
}

func (routes *Routes) Unicast(name PeerName) (PeerName, bool) {
	routes.RLock()
	defer routes.RUnlock()
	hop, found := routes.unicast[name]
	return hop, found
}

func (routes *Routes) Broadcast(name PeerName) []PeerName {
	routes.RLock()
	defer routes.RUnlock()
	hops, found := routes.broadcast[name]
	if !found {
		return []PeerName{}
	}
	return hops
}

func (routes *Routes) String() string {
	var buf bytes.Buffer
	routes.RLock()
	defer routes.RUnlock()
	fmt.Fprintln(&buf, "unicast:")
	for name, hop := range routes.unicast {
		fmt.Fprintf(&buf, "%s -> %s\n", name, hop)
	}
	fmt.Sprintln(&buf, "broadcast:")
	for name, hops := range routes.broadcast {
		fmt.Fprintf(&buf, "%s -> %v\n", name, hops)
	}
	return buf.String()
}

// ACTOR client API

type RoutesAction func()

// Async.
func (routes *Routes) Recalculate() {
	routes.actionChan <- func() {
		unicast := routes.calculateUnicast()
		broadcast := routes.calculateBroadcast()
		routes.Lock()
		routes.unicast = unicast
		routes.broadcast = broadcast
		routes.Unlock()
	}
}

// ACTOR server

func (routes *Routes) actorLoop(actionChan <-chan RoutesAction) {
	for {
		(<-actionChan)()
	}
}

// Calculate all the routes for the question: if *we* want to send a
// packet to Peer X, what is the next hop?
//
// When we sniff a packet, we determine the destination peer
// ourself. Consequently, we can relay the packet via any
// arbitrary peers - the intermediate peers do not have to have
// any knowledge of the MAC address at all. Thus there's no need
// to exchange knowledge of MAC addresses, nor any constraints on
// the routes that we construct.
func (routes *Routes) calculateUnicast() map[PeerName]PeerName {
	_, unicast := routes.ourself.Routes(nil, true)
	return unicast
}

// Calculate all the routes for the question: if we receive a
// broadcast originally from Peer X, which peers should we pass the
// frames on to?
//
// When the topology is stable, and thus all peers perform route
// calculations based on the same data, the algorithm ensures that
// broadcasts reach every peer exactly once.
//
// This is largely due to properties of the Peer.Routes algorithm. In
// particular:
//
// ForAll X,Y,Z in Peers.
//     X.Routes(Y) <= X.Routes(Z) \/
//     X.Routes(Z) <= X.Routes(Y)
// ForAll X,Y,Z in Peers.
//     Y =/= Z /\ X.Routes(Y) <= X.Routes(Z) =>
//     X.Routes(Y) u [P | Y.HasSymmetricConnectionTo(P)] <= X.Routes(Z)
// where <= is the subset relationship on keys of the returned map.
func (routes *Routes) calculateBroadcast() map[PeerName][]PeerName {
	broadcast := make(map[PeerName][]PeerName)
	ourself := routes.ourself

	routes.peers.ForEach(func(peer *Peer) {
		hops := []PeerName{}
		if found, reached := peer.Routes(ourself, true); found {
			// This is rather similar to the inner loop on
			// peer.Routes(...); the main difference is in the
			// locking.
			for _, conn := range ourself.Connections() {
				if !conn.Established() {
					continue
				}
				remoteName := conn.Remote().Name
				if _, found := reached[remoteName]; found {
					continue
				}
				if remoteConn, found := conn.Remote().ConnectionTo(ourself.Name); found && remoteConn.Established() {
					hops = append(hops, remoteName)
				}
			}
		}
		broadcast[peer.Name] = hops
	})
	return broadcast
}
<commit_msg>oops broke this in 45740b1419508d442ec681893eb8f4c2aac93736<commit_after>package router

import (
	"bytes"
	"fmt"
	"sync"
)

type Routes struct {
	sync.RWMutex
	ourself    *Peer
	peers      *Peers
	unicast    map[PeerName]PeerName
	broadcast  map[PeerName][]PeerName
	actionChan chan<- RoutesAction
}

func NewRoutes(ourself *Peer, peers *Peers) *Routes {
	routes := &Routes{
		ourself:   ourself,
		peers:     peers,
		unicast:   make(map[PeerName]PeerName),
		broadcast: make(map[PeerName][]PeerName)}
	routes.unicast[ourself.Name] = UnknownPeerName
	routes.broadcast[ourself.Name] = []PeerName{}
	return routes
}

func (routes *Routes) Start() {
	actionChan := make(chan RoutesAction, ChannelSize)
	routes.actionChan = actionChan
	go routes.actorLoop(actionChan)
}

func (routes *Routes) Unicast(name PeerName) (PeerName, bool) {
	routes.RLock()
	defer routes.RUnlock()
	hop, found := routes.unicast[name]
	return hop, found
}

func (routes *Routes) Broadcast(name PeerName) []PeerName {
	routes.RLock()
	defer routes.RUnlock()
	hops, found := routes.broadcast[name]
	if !found {
		return []PeerName{}
	}
	return hops
}

func (routes *Routes) String() string {
	var buf bytes.Buffer
	routes.RLock()
	defer routes.RUnlock()
	fmt.Fprintln(&buf, "unicast:")
	for name, hop := range routes.unicast {
		fmt.Fprintf(&buf, "%s -> %s\n", name, hop)
	}
	fmt.Fprintln(&buf, "broadcast:")
	for name, hops := range routes.broadcast {
		fmt.Fprintf(&buf, "%s -> %v\n", name, hops)
	}
	return buf.String()
}

// ACTOR client API

type RoutesAction func()

// Async.
func (routes *Routes) Recalculate() {
	routes.actionChan <- func() {
		unicast := routes.calculateUnicast()
		broadcast := routes.calculateBroadcast()
		routes.Lock()
		routes.unicast = unicast
		routes.broadcast = broadcast
		routes.Unlock()
	}
}

// ACTOR server

func (routes *Routes) actorLoop(actionChan <-chan RoutesAction) {
	for {
		(<-actionChan)()
	}
}

// Calculate all the routes for the question: if *we* want to send a
// packet to Peer X, what is the next hop?
//
// When we sniff a packet, we determine the destination peer
// ourself. Consequently, we can relay the packet via any
// arbitrary peers - the intermediate peers do not have to have
// any knowledge of the MAC address at all. Thus there's no need
// to exchange knowledge of MAC addresses, nor any constraints on
// the routes that we construct.
func (routes *Routes) calculateUnicast() map[PeerName]PeerName {
	_, unicast := routes.ourself.Routes(nil, true)
	return unicast
}

// Calculate all the routes for the question: if we receive a
// broadcast originally from Peer X, which peers should we pass the
// frames on to?
//
// When the topology is stable, and thus all peers perform route
// calculations based on the same data, the algorithm ensures that
// broadcasts reach every peer exactly once.
//
// This is largely due to properties of the Peer.Routes algorithm. In
// particular:
//
// ForAll X,Y,Z in Peers.
//     X.Routes(Y) <= X.Routes(Z) \/
//     X.Routes(Z) <= X.Routes(Y)
// ForAll X,Y,Z in Peers.
//     Y =/= Z /\ X.Routes(Y) <= X.Routes(Z) =>
//     X.Routes(Y) u [P | Y.HasSymmetricConnectionTo(P)] <= X.Routes(Z)
// where <= is the subset relationship on keys of the returned map.
func (routes *Routes) calculateBroadcast() map[PeerName][]PeerName {
	broadcast := make(map[PeerName][]PeerName)
	ourself := routes.ourself

	routes.peers.ForEach(func(peer *Peer) {
		hops := []PeerName{}
		if found, reached := peer.Routes(ourself, true); found {
			// This is rather similar to the inner loop on
			// peer.Routes(...); the main difference is in the
			// locking.
			for _, conn := range ourself.Connections() {
				if !conn.Established() {
					continue
				}
				remoteName := conn.Remote().Name
				if _, found := reached[remoteName]; found {
					continue
				}
				if remoteConn, found := conn.Remote().ConnectionTo(ourself.Name); found && remoteConn.Established() {
					hops = append(hops, remoteName)
				}
			}
		}
		broadcast[peer.Name] = hops
	})
	return broadcast
}
<|endoftext|>


<commit_before>package edward_test

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"strings"
	"testing"

	"github.com/pkg/errors"
	"github.com/theothertomelliott/gopsutil-nocgo/process"
	"github.com/yext/edward/edward"
	"github.com/yext/edward/home"
	"github.com/yext/edward/tracker"
)

// Path to the Edward executable as built
var edwardExecutable string

func TestMain(m *testing.M) {
	buildDir, err := ioutil.TempDir("", "edwardTest")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(buildDir)

	edwardExecutable = path.Join(buildDir, "edward")

	cmd := exec.Command("go", "build", "-o", edwardExecutable, "github.com/yext/edward")
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		log.Fatal(err)
	}

	// Set up edward home directory
	if err := home.EdwardConfig.Initialize(); err != nil {
		log.Fatal(err)
	}

	os.Exit(m.Run())
}

type testFollower struct {
	states     map[string]string
	stateOrder []string
	messages   []string
}

func newTestFollower() *testFollower {
	return &testFollower{
		states: make(map[string]string),
	}
}

func (f *testFollower) Handle(update tracker.Task) {
	var names []string
	for _, task := range update.Lineage() {
		if task.Name() != "" {
			names = append(names, task.Name())
		}
	}

	fullName := strings.Join(names, " > ")
	f.states[fullName] = update.State().String()
	if len(f.stateOrder) == 0 || f.stateOrder[len(f.stateOrder)-1] != fullName {
		f.stateOrder = append(f.stateOrder, fullName)
	}
	f.messages = append(f.messages, update.Messages()...)
}
func (f *testFollower) Done() {}

// getRunnerAndServiceProcesses returns all processes and children spawned by this test
func getRunnerAndServiceProcesses(t *testing.T) []*process.Process {
	var processes []*process.Process
	testProcess, err := process.NewProcess(int32(os.Getpid()))
	if err != nil {
		t.Fatal(err)
	}
	runners, err := testProcess.Children()
	if err != nil {
		t.Fatalf("No processes found")
	}
	processes = append(processes, runners...)
	for _, runner := range runners {
		services, err := runner.Children()
		if err != nil {
			t.Fatalf("No processes found")
		}
		processes = append(processes, services...)
	}
	return processes
}

// verifyAndStopRunners expects that there will be the specified number of runners in progress,
// and that the runners are behaving as expected (exactly one child service, etc).
// Once verified, it will kill the runners and their child services.
func verifyAndStopRunners(t *testing.T, client *edward.Client, serviceCount int) {
	testProcess, err := process.NewProcess(int32(os.Getpid()))
	if err != nil {
		t.Fatal(err)
	}
	children, err := testProcess.Children()
	if err != nil {
		if serviceCount != 0 {
			t.Fatalf("No processes found, expected %d", serviceCount)
		}
	}
	var verifiedCount int
	for _, child := range children {
		verified, err := verifyAndStopRunner(t, client, child)
		if err != nil {
			t.Fatal(err)
		}
		if verified {
			verifiedCount++
		}
	}
	if verifiedCount != serviceCount {
		t.Errorf("Expected %d tagged runners, got %d", serviceCount, verifiedCount)
	}
}

// verifyAndStopRunner will check that a runner process has exactly one child service,
// and then kill the service, expecting the runner to die.
func verifyAndStopRunner(t *testing.T, client *edward.Client, runner *process.Process) (bool, error) {
	cmdline, err := runner.CmdlineSlice()
	if err != nil {
		t.Logf("error getting command line, ignoring: %v", err)
		return false, nil
	}
	if len(cmdline) > 2 && strings.HasSuffix(cmdline[0], "edward") && cmdline[1] == "run" {
		fullCmd := strings.Join(cmdline, " ")
		for _, tag := range client.Tags {
			if !strings.Contains(fullCmd, fmt.Sprintf("--tag %s", tag)) {
				return false, nil
			}
		}
		services, err := runner.Children()
		if err != nil {
			t.Logf("error getting children, ignoring: %v", err)
			return false, nil
		}
		if len(services) != 1 {
			t.Errorf("Expected 1 child of runner (%s), got %v", cmdline, len(services))
		}
		for _, service := range services {
			if running, _ := service.IsRunning(); running {
				err = service.Kill()
				if err != nil {
					return false, errors.WithMessage(err, "killing service")
				}
			}
		}
		if running, _ := runner.IsRunning(); running {
			return true, nil
		}
		t.Error("Expected stopping children to kill runner process")
		err = runner.Kill()
		if err != nil {
			t.Fatal("Could not kill runner:", err)
		}
		return true, nil
	}
	return false, nil
}
<commit_msg>Remove check on number of children of a runner, since it runs other processes to tests ports, etc.<commit_after>package edward_test

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"strings"
	"testing"

	"github.com/pkg/errors"
	"github.com/theothertomelliott/gopsutil-nocgo/process"
	"github.com/yext/edward/edward"
	"github.com/yext/edward/home"
	"github.com/yext/edward/tracker"
)

// Path to the Edward executable as built
var edwardExecutable string

func TestMain(m *testing.M) {
	buildDir, err := ioutil.TempDir("", "edwardTest")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(buildDir)

	edwardExecutable = path.Join(buildDir, "edward")

	cmd := exec.Command("go", "build", "-o", edwardExecutable, "github.com/yext/edward")
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		log.Fatal(err)
	}

	// Set up edward home directory
	if err := home.EdwardConfig.Initialize(); err != nil {
		log.Fatal(err)
	}

	os.Exit(m.Run())
}

type testFollower struct {
	states     map[string]string
	stateOrder []string
	messages   []string
}

func newTestFollower() *testFollower {
	return &testFollower{
		states: make(map[string]string),
	}
}

func (f *testFollower) Handle(update tracker.Task) {
	var names []string
	for _, task := range update.Lineage() {
		if task.Name() != "" {
			names = append(names, task.Name())
		}
	}

	fullName := strings.Join(names, " > ")
	f.states[fullName] = update.State().String()
	if len(f.stateOrder) == 0 || f.stateOrder[len(f.stateOrder)-1] != fullName {
		f.stateOrder = append(f.stateOrder, fullName)
	}
	f.messages = append(f.messages, update.Messages()...)
}
func (f *testFollower) Done() {}

// getRunnerAndServiceProcesses returns all processes and children spawned by this test
func getRunnerAndServiceProcesses(t *testing.T) []*process.Process {
	var processes []*process.Process
	testProcess, err := process.NewProcess(int32(os.Getpid()))
	if err != nil {
		t.Fatal(err)
	}
	runners, err := testProcess.Children()
	if err != nil {
		t.Fatalf("No processes found")
	}
	processes = append(processes, runners...)
	for _, runner := range runners {
		services, err := runner.Children()
		if err != nil {
			t.Fatalf("No processes found")
		}
		processes = append(processes, services...)
	}
	return processes
}

// verifyAndStopRunners expects that there will be the specified number of runners in progress,
// and that the runners are behaving as expected (exactly one child service, etc).
// Once verified, it will kill the runners and their child services.
func verifyAndStopRunners(t *testing.T, client *edward.Client, serviceCount int) {
	testProcess, err := process.NewProcess(int32(os.Getpid()))
	if err != nil {
		t.Fatal(err)
	}
	children, err := testProcess.Children()
	if err != nil {
		if serviceCount != 0 {
			t.Fatalf("No processes found, expected %d", serviceCount)
		}
	}
	var verifiedChildren []*process.Process
	for _, child := range children {
		verified, err := verifyAndStopRunner(t, client, child)
		if err != nil {
			t.Fatal(err)
		}
		if verified {
			verifiedChildren = append(verifiedChildren, child)
		}
	}
	if len(verifiedChildren) != serviceCount {
		t.Errorf("Expected %d tagged runners, got %+v", serviceCount, verifiedChildren)
	}
}

// verifyAndStopRunner will check that a runner process has exactly one child service,
// and then kill the service, expecting the runner to die.
func verifyAndStopRunner(t *testing.T, client *edward.Client, runner *process.Process) (bool, error) {
	cmdline, err := runner.CmdlineSlice()
	if err != nil {
		t.Logf("error getting command line, ignoring: %v", err)
		return false, nil
	}
	if len(cmdline) > 2 && strings.HasSuffix(cmdline[0], "edward") && cmdline[1] == "run" {
		fullCmd := strings.Join(cmdline, " ")
		for _, tag := range client.Tags {
			if !strings.Contains(fullCmd, fmt.Sprintf("--tag %s", tag)) {
				return false, nil
			}
		}
		services, err := runner.Children()
		if err != nil {
			t.Logf("error getting children, ignoring: %v", err)
			return false, nil
		}
		for _, service := range services {
			if running, _ := service.IsRunning(); running {
				err = service.Kill()
				if err != nil {
					return false, errors.WithMessage(err, "killing service")
				}
			}
		}
		if running, _ := runner.IsRunning(); running {
			return true, nil
		}
		t.Error("Expected stopping children to kill runner process")
		err = runner.Kill()
		if err != nil {
			t.Fatal("Could not kill runner:", err)
		}
		return true, nil
	}
	return false, nil
}
<|endoftext|>


<commit_before>package services

import (
	"testing"

	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/pagination"
	th "github.com/rackspace/gophercloud/testhelper"
	fake "github.com/rackspace/gophercloud/testhelper/client"
)

func TestList(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleListCDNServiceSuccessfully(t)

	count := 0

	err := List(fake.ServiceClient(), &ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
		count++
		actual, err := ExtractServices(page)
		if err != nil {
			t.Errorf("Failed to extract services: %v", err)
			return false, err
		}

		expected := []Service{
			Service{
				ID:   "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0",
				Name: "mywebsite.com",
				Domains: []Domain{
					Domain{
						Domain: "www.mywebsite.com",
					},
				},
				Origins: []Origin{
					Origin{
						Origin: "mywebsite.com",
						Port:   80,
						SSL:    false,
					},
				},
				Caching: []CacheRule{
					CacheRule{
						Name: "default",
						TTL:  3600,
					},
					CacheRule{
						Name: "home",
						TTL:  17200,
						Rules: []TTLRule{
							TTLRule{
								Name:       "index",
								RequestURL: "/index.htm",
							},
						},
					},
					CacheRule{
						Name: "images",
						TTL:  12800,
						Rules: []TTLRule{
							TTLRule{
								Name:       "images",
								RequestURL: "*.png",
							},
						},
					},
				},
				Restrictions: []Restriction{
					Restriction{
						Name: "website only",
						Rules: []RestrictionRule{
							RestrictionRule{
								Name:     "mywebsite.com",
								Referrer: "www.mywebsite.com",
							},
						},
					},
				},
				FlavorID: "asia",
				Status:   "deployed",
				Errors:   []Error{},
				Links: []gophercloud.Link{
					gophercloud.Link{
						Href: "https://www.poppycdn.io/v1.0/services/96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0",
						Rel:  "self",
					},
					gophercloud.Link{
						Href: "mywebsite.com.cdn123.poppycdn.net",
						Rel:  "access_url",
					},
					gophercloud.Link{
						Href: "https://www.poppycdn.io/v1.0/flavors/asia",
						Rel:  "flavor",
					},
				},
			},
			Service{
				ID:   "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f1",
				Name: "myothersite.com",
				Domains: []Domain{
					Domain{
						Domain: "www.myothersite.com",
					},
				},
				Origins: []Origin{
					Origin{
						Origin: "44.33.22.11",
						Port:   80,
						SSL:    false,
					},
					Origin{
						Origin: "77.66.55.44",
						Port:   80,
						SSL:    false,
						Rules: []OriginRule{
							OriginRule{
								Name:       "videos",
								RequestURL: "^/videos/*.m3u",
							},
						},
					},
				},
				Caching: []CacheRule{
					CacheRule{
						Name: "default",
						TTL:  3600,
					},
				},
				Restrictions: []Restriction{},
				FlavorID:     "europe",
				Status:       "deployed",
				Links: []gophercloud.Link{
					gophercloud.Link{
						Href: "https://www.poppycdn.io/v1.0/services/96737ae3-cfc1-4c72-be88-5d0e7cc9a3f1",
						Rel:  "self",
					},
					gophercloud.Link{
						Href: "myothersite.com.poppycdn.net",
						Rel:  "access_url",
					},
					gophercloud.Link{
						Href: "https://www.poppycdn.io/v1.0/flavors/europe",
						Rel:  "flavor",
					},
				},
			},
		}

		th.CheckDeepEquals(t, expected, actual)

		return true, nil
	})
	th.AssertNoErr(t, err)

	if count != 1 {
		t.Errorf("Expected 1 page, got %d", count)
	}
}

func TestCreate(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleCreateCDNServiceSuccessfully(t)

	createOpts := CreateOpts{
		Name: "mywebsite.com",
		Domains: []Domain{
			Domain{
				Domain: "www.mywebsite.com",
			},
			Domain{
				Domain: "blog.mywebsite.com",
			},
		},
		Origins: []Origin{
			Origin{
				Origin: "mywebsite.com",
				Port:   80,
				SSL:    false,
			},
		},
		Restrictions: []Restriction{
			Restriction{
				Name: "website only",
				Rules: []RestrictionRule{
					RestrictionRule{
						Name:     "mywebsite.com",
						Referrer: "www.mywebsite.com",
					},
				},
			},
		},
		Caching: []CacheRule{
			CacheRule{
				Name: "default",
				TTL:  3600,
			},
		},
		FlavorID: "cdn",
	}

	expected := "https://global.cdn.api.rackspacecloud.com/v1.0/services/96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0"
	actual, err := Create(fake.ServiceClient(), createOpts).Extract()
	th.AssertNoErr(t, err)
	th.AssertEquals(t, expected, actual)
}

func TestGet(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleGetCDNServiceSuccessfully(t)

	expected := &Service{
		ID:   "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0",
		Name: "mywebsite.com",
		Domains: []Domain{
			Domain{
				Domain:   "www.mywebsite.com",
				Protocol: "http",
			},
		},
		Origins: []Origin{
			Origin{
				Origin: "mywebsite.com",
				Port:   80,
				SSL:    false,
			},
		},
		Caching: []CacheRule{
			CacheRule{
				Name: "default",
				TTL:  3600,
			},
			CacheRule{
				Name: "home",
				TTL:  17200,
				Rules: []TTLRule{
					TTLRule{
						Name:       "index",
						RequestURL: "/index.htm",
					},
				},
			},
			CacheRule{
				Name: "images",
				TTL:  12800,
				Rules: []TTLRule{
					TTLRule{
						Name:       "images",
						RequestURL: "*.png",
					},
				},
			},
		},
		Restrictions: []Restriction{
			Restriction{
				Name: "website only",
				Rules: []RestrictionRule{
					RestrictionRule{
						Name:     "mywebsite.com",
						Referrer: "www.mywebsite.com",
					},
				},
			},
		},
		FlavorID: "cdn",
		Status:   "deployed",
		Errors:   []Error{},
		Links: []gophercloud.Link{
			gophercloud.Link{
				Href: "https://global.cdn.api.rackspacecloud.com/v1.0/110011/services/96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0",
				Rel:  "self",
			},
			gophercloud.Link{
				Href: "blog.mywebsite.com.cdn1.raxcdn.com",
				Rel:  "access_url",
			},
			gophercloud.Link{
				Href: "https://global.cdn.api.rackspacecloud.com/v1.0/110011/flavors/cdn",
				Rel:  "flavor",
			},
		},
	}

	actual, err := Get(fake.ServiceClient(), "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0").Extract()
	th.AssertNoErr(t, err)
	th.AssertDeepEquals(t, expected, actual)
}

func TestSuccessfulUpdate(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleUpdateCDNServiceSuccessfully(t)

	expected := "https://www.poppycdn.io/v1.0/services/96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0"
	updateOpts := UpdateOpts{
		UpdateOpt{
			Op:   Replace,
			Path: "/origins/0",
			Value: map[string]interface{}{
				"origin": "44.33.22.11",
				"port":   80,
				"ssl":    false,
			},
		},
		UpdateOpt{
			Op:   Add,
			Path: "/domains/0",
			Value: map[string]interface{}{
				"domain": "added.mocksite4.com",
			},
		},
	}
	actual, err := Update(fake.ServiceClient(), "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0", updateOpts).Extract()
	th.AssertNoErr(t, err)
	th.AssertEquals(t, expected, actual)
}

func TestUnsuccessfulUpdate(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleUpdateCDNServiceSuccessfully(t)

	updateOpts := UpdateOpts{
		UpdateOpt{
			Op:   "Foo",
			Path: "/origins/0",
			Value: map[string]interface{}{
				"origin": "44.33.22.11",
				"port":   80,
				"ssl":    false,
			},
		},
		UpdateOpt{
			Op:   Add,
			Path: "/domains/0",
			Value: map[string]interface{}{
				"domain": "added.mocksite4.com",
			},
		},
		// Remove a single CacheRule
		Removal{
			Index: 8,
			Path:  PathCaching,
		},
		// Bulk removal
		Removal{
			All:  true,
			Path: PathCaching,
		},
		// Service name replacement
		NameReplacement{
			NewName: "differentServiceName",
		},
	}

	actual, err := Update(fake.ServiceClient(), "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0", ops).Extract()
	th.AssertNoErr(t, err)
	th.AssertEquals(t, expected, actual)
}

func TestDelete(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleDeleteCDNServiceSuccessfully(t)

	err := Delete(fake.ServiceClient(), "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0").ExtractErr()
	th.AssertNoErr(t, err)
}
<commit_msg>fix cdn service update unit test; sneaking this in<commit_after>package services

import (
	"testing"

	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/pagination"
	th "github.com/rackspace/gophercloud/testhelper"
	fake "github.com/rackspace/gophercloud/testhelper/client"
)

func TestList(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleListCDNServiceSuccessfully(t)

	count := 0

	err := List(fake.ServiceClient(), &ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
		count++
		actual, err := ExtractServices(page)
		if err != nil {
			t.Errorf("Failed to extract services: %v", err)
			return false, err
		}

		expected := []Service{
			Service{
				ID:   "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0",
				Name: "mywebsite.com",
				Domains: []Domain{
					Domain{
						Domain: "www.mywebsite.com",
					},
				},
				Origins: []Origin{
					Origin{
						Origin: "mywebsite.com",
						Port:   80,
						SSL:    false,
					},
				},
				Caching: []CacheRule{
					CacheRule{
						Name: "default",
						TTL:  3600,
					},
					CacheRule{
						Name: "home",
						TTL:  17200,
						Rules: []TTLRule{
							TTLRule{
								Name:       "index",
								RequestURL: "/index.htm",
							},
						},
					},
					CacheRule{
						Name: "images",
						TTL:  12800,
						Rules: []TTLRule{
							TTLRule{
								Name:       "images",
								RequestURL: "*.png",
							},
						},
					},
				},
				Restrictions: []Restriction{
					Restriction{
						Name: "website only",
						Rules: []RestrictionRule{
							RestrictionRule{
								Name:     "mywebsite.com",
								Referrer: "www.mywebsite.com",
							},
						},
					},
				},
				FlavorID: "asia",
				Status:   "deployed",
				Errors:   []Error{},
				Links: []gophercloud.Link{
					gophercloud.Link{
						Href: "https://www.poppycdn.io/v1.0/services/96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0",
						Rel:  "self",
					},
					gophercloud.Link{
						Href: "mywebsite.com.cdn123.poppycdn.net",
						Rel:  "access_url",
					},
					gophercloud.Link{
						Href: "https://www.poppycdn.io/v1.0/flavors/asia",
						Rel:  "flavor",
					},
				},
			},
			Service{
				ID:   "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f1",
				Name: "myothersite.com",
				Domains: []Domain{
					Domain{
						Domain: "www.myothersite.com",
					},
				},
				Origins: []Origin{
					Origin{
						Origin: "44.33.22.11",
						Port:   80,
						SSL:    false,
					},
					Origin{
						Origin: "77.66.55.44",
						Port:   80,
						SSL:    false,
						Rules: []OriginRule{
							OriginRule{
								Name:       "videos",
								RequestURL: "^/videos/*.m3u",
							},
						},
					},
				},
				Caching: []CacheRule{
					CacheRule{
						Name: "default",
						TTL:  3600,
					},
				},
				Restrictions: []Restriction{},
				FlavorID:     "europe",
				Status:       "deployed",
				Links: []gophercloud.Link{
					gophercloud.Link{
						Href: "https://www.poppycdn.io/v1.0/services/96737ae3-cfc1-4c72-be88-5d0e7cc9a3f1",
						Rel:  "self",
					},
					gophercloud.Link{
						Href: "myothersite.com.poppycdn.net",
						Rel:  "access_url",
					},
					gophercloud.Link{
						Href: "https://www.poppycdn.io/v1.0/flavors/europe",
						Rel:  "flavor",
					},
				},
			},
		}

		th.CheckDeepEquals(t, expected, actual)

		return true, nil
	})
	th.AssertNoErr(t, err)

	if count != 1 {
		t.Errorf("Expected 1 page, got %d", count)
	}
}

func TestCreate(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleCreateCDNServiceSuccessfully(t)

	createOpts := CreateOpts{
		Name: "mywebsite.com",
		Domains: []Domain{
			Domain{
				Domain: "www.mywebsite.com",
			},
			Domain{
				Domain: "blog.mywebsite.com",
			},
		},
		Origins: []Origin{
			Origin{
				Origin: "mywebsite.com",
				Port:   80,
				SSL:    false,
			},
		},
		Restrictions: []Restriction{
			Restriction{
				Name: "website only",
				Rules: []RestrictionRule{
					RestrictionRule{
						Name:     "mywebsite.com",
						Referrer: "www.mywebsite.com",
					},
				},
			},
		},
		Caching: []CacheRule{
			CacheRule{
				Name: "default",
				TTL:  3600,
			},
		},
		FlavorID: "cdn",
	}

	expected := "https://global.cdn.api.rackspacecloud.com/v1.0/services/96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0"
	actual, err := Create(fake.ServiceClient(), createOpts).Extract()
	th.AssertNoErr(t, err)
	th.AssertEquals(t, expected, actual)
}

func TestGet(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleGetCDNServiceSuccessfully(t)

	expected := &Service{
		ID:   "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0",
		Name: "mywebsite.com",
		Domains: []Domain{
			Domain{
				Domain:   "www.mywebsite.com",
				Protocol: "http",
			},
		},
		Origins: []Origin{
			Origin{
				Origin: "mywebsite.com",
				Port:   80,
				SSL:    false,
			},
		},
		Caching: []CacheRule{
			CacheRule{
				Name: "default",
				TTL:  3600,
			},
			CacheRule{
				Name: "home",
				TTL:  17200,
				Rules: []TTLRule{
					TTLRule{
						Name:       "index",
						RequestURL: "/index.htm",
					},
				},
			},
			CacheRule{
				Name: "images",
				TTL:  12800,
				Rules: []TTLRule{
					TTLRule{
						Name:       "images",
						RequestURL: "*.png",
					},
				},
			},
		},
		Restrictions: []Restriction{
			Restriction{
				Name: "website only",
				Rules: []RestrictionRule{
					RestrictionRule{
						Name:     "mywebsite.com",
						Referrer: "www.mywebsite.com",
					},
				},
			},
		},
		FlavorID: "cdn",
		Status:   "deployed",
		Errors:   []Error{},
		Links: []gophercloud.Link{
			gophercloud.Link{
				Href: "https://global.cdn.api.rackspacecloud.com/v1.0/110011/services/96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0",
				Rel:  "self",
			},
			gophercloud.Link{
				Href: "blog.mywebsite.com.cdn1.raxcdn.com",
				Rel:  "access_url",
			},
			gophercloud.Link{
				Href: "https://global.cdn.api.rackspacecloud.com/v1.0/110011/flavors/cdn",
				Rel:  "flavor",
			},
		},
	}

	actual, err := Get(fake.ServiceClient(), "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0").Extract()
	th.AssertNoErr(t, err)
	th.AssertDeepEquals(t, expected, actual)
}

func TestSuccessfulUpdate(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleUpdateCDNServiceSuccessfully(t)

	expected := "https://www.poppycdn.io/v1.0/services/96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0"
	updateOpts := UpdateOpts{
		Replacement{
			Value: OriginList{
				Origin{
					Origin: "44.33.22.11",
					Port:   80,
					SSL:    false,
				},
			},
			Index: 0,
		},
		Append{
			Value: DomainList{
				Domain{
					Domain: "added.mocksite4.com",
				},
			},
		},
	}
	actual, err := Update(fake.ServiceClient(), "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0", updateOpts).Extract()
	th.AssertNoErr(t, err)
	th.AssertEquals(t, expected, actual)
}

func TestDelete(t *testing.T) {
	th.SetupHTTP()
	defer th.TeardownHTTP()

	HandleDeleteCDNServiceSuccessfully(t)

	err := Delete(fake.ServiceClient(), "96737ae3-cfc1-4c72-be88-5d0e7cc9a3f0").ExtractErr()
	th.AssertNoErr(t, err)
}
<|endoftext|>


<commit_before>package cat

import (
	"net"
	"fmt"
	"io/ioutil"
	"net/http"
	. "os"
	"strings"
)

//Configs about cat is required to be correct.
//The client is able to complement some of the configs,
//but is incapable of validation.
//Fortunately invalid configs causes failure of cat's init,
//thus users can be immediately aware of config fault.
var (
	PROD        string = "http://cat.ctripcorp.com"
	FAT         string = "http://cat.fws.qa.nt.ctripcorp.com"
	UAT         string = "http://cat.uat.qa.nt.ctripcorp.com"
	CAT_HOST    string = FAT
	CAT_SERVERS []string
	DOMAIN      string = "900407"
	HOSTNAME    string = ""
	IP          string = ""
	TEMPFILE    string = ".cat"
)

func cat_config_init() {
	var err error
	var resp *http.Response
	var metaServer string

	metaServer = fmt.Sprintf(CAT_HOST+"/cat/s/router?domain=%s", DOMAIN)
	resp, err = http.Get(metaServer)
	if err != nil {
		panic("Fail to access the cat meta server.")
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	CAT_SERVERS = strings.Split(string(body), ";")

	if DOMAIN == "" {
		panic("DOMAIN is required, set your appid to it.")
	}

	if HOSTNAME == "" {
		HOSTNAME, err = Hostname()
		if err != nil {
			panic("Fail to auto-get HOSTNAME, try config it manually.")
		}
	}

	if IP == "" {
		IP = cat_get_ip()
	}
}

func cat_get_ip() string{
	return ""
}
<commit_msg>remove net package<commit_after>package cat

import (
	"fmt"
	"io/ioutil"
	"net/http"
	. "os"
	"strings"
)

//Configs about cat is required to be correct.
//The client is able to complement some of the configs,
//but is incapable of validation.
//Fortunately invalid configs causes failure of cat's init,
//thus users can be immediately aware of config fault.
var (
	PROD        string = "http://cat.ctripcorp.com"
	FAT         string = "http://cat.fws.qa.nt.ctripcorp.com"
	UAT         string = "http://cat.uat.qa.nt.ctripcorp.com"
	CAT_HOST    string = FAT
	CAT_SERVERS []string
	DOMAIN      string = "900407"
	HOSTNAME    string = ""
	IP          string = ""
	TEMPFILE    string = ".cat"
)

func cat_config_init() {
	var err error
	var resp *http.Response
	var metaServer string

	metaServer = fmt.Sprintf(CAT_HOST+"/cat/s/router?domain=%s", DOMAIN)
	resp, err = http.Get(metaServer)
	if err != nil {
		panic("Fail to access the cat meta server.")
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	CAT_SERVERS = strings.Split(string(body), ";")

	if DOMAIN == "" {
		panic("DOMAIN is required, set your appid to it.")
	}

	if HOSTNAME == "" {
		HOSTNAME, err = Hostname()
		if err != nil {
			panic("Fail to auto-get HOSTNAME, try config it manually.")
		}
	}

	if IP == "" {
		IP = cat_get_ip()
	}
}

func cat_get_ip() string{
	return ""
}
<|endoftext|>


<commit_before>package main

const NGINX_BUILD_VERSION = "0.6.4"

// nginx
const (
	NGINX_VERSION             = "1.9.9"
	NGINX_DOWNLOAD_URL_PREFIX = "http://nginx.org/download"
)

// pcre
const (
	PCRE_VERSION             = "8.38"
	PCRE_DOWNLOAD_URL_PREFIX = "http://ftp.csx.cam.ac.uk/pub/software/programming/pcre"
)

// openssl
const (
	OPENSSL_VERSION             = "1.0.2e"
	OPENSSL_DOWNLOAD_URL_PREFIX = "http://www.openssl.org/source"
)

// zlib
const (
	ZLIB_VERSION             = "1.2.8"
	ZLIB_DOWNLOAD_URL_PREFIX = "http://zlib.net"
)

// openResty
const (
	OPENRESTY_VERSION             = "1.9.3.2"
	OPENRESTY_DOWNLOAD_URL_PREFIX = "http://openresty.org/download"
)

// tengine
const (
	TENGINE_VERSION             = "2.1.1"
	TENGINE_DOWNLOAD_URL_PREFIX = "http://tengine.taobao.org/download"
)

// component enumerations
const (
	COMPONENT_NGINX = iota
	COMPONENT_OPENRESTY
	COMPONENT_TENGINE
	COMPONENT_PCRE
	COMPONENT_OPENSSL
	COMPONENT_ZLIB
	COMPONENT_MAX
)
<commit_msg>bumped OpenResty version to 1.9.7.1.<commit_after>package main

const NGINX_BUILD_VERSION = "0.6.4"

// nginx
const (
	NGINX_VERSION             = "1.9.9"
	NGINX_DOWNLOAD_URL_PREFIX = "http://nginx.org/download"
)

// pcre
const (
	PCRE_VERSION             = "8.38"
	PCRE_DOWNLOAD_URL_PREFIX = "http://ftp.csx.cam.ac.uk/pub/software/programming/pcre"
)

// openssl
const (
	OPENSSL_VERSION             = "1.0.2e"
	OPENSSL_DOWNLOAD_URL_PREFIX = "http://www.openssl.org/source"
)

// zlib
const (
	ZLIB_VERSION             = "1.2.8"
	ZLIB_DOWNLOAD_URL_PREFIX = "http://zlib.net"
)

// openResty
const (
	OPENRESTY_VERSION             = "1.9.7.1"
	OPENRESTY_DOWNLOAD_URL_PREFIX = "http://openresty.org/download"
)

// tengine
const (
	TENGINE_VERSION             = "2.1.1"
	TENGINE_DOWNLOAD_URL_PREFIX = "http://tengine.taobao.org/download"
)

// component enumerations
const (
	COMPONENT_NGINX = iota
	COMPONENT_OPENRESTY
	COMPONENT_TENGINE
	COMPONENT_PCRE
	COMPONENT_OPENSSL
	COMPONENT_ZLIB
	COMPONENT_MAX
)
<|endoftext|>


<commit_before>// +build tools

package tools

import (
	_ "knative.dev/hack"
	_ "knative.dev/pkg/hack"

	_ "k8s.io/code-generator/cmd/deepcopy-gen"

	// For chaos testing the leaderelection stuff.
	_ "knative.dev/pkg/leaderelection/chaosduck"

	// To get the ingress CRD
	_ "knative.dev/networking/config"

	_ "knative.dev/networking/test/conformance/ingress"
	_ "knative.dev/networking/test/test_images/grpc-ping"
	_ "knative.dev/networking/test/test_images/httpproxy"
	_ "knative.dev/networking/test/test_images/retry"
	_ "knative.dev/networking/test/test_images/runtime"
	_ "knative.dev/networking/test/test_images/timeout"
	_ "knative.dev/networking/test/test_images/wsserver"
)
<commit_msg>Add missing license to tools.go (#661)<commit_after>// +build tools

/*
Copyright 2021 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 tools

import (
	_ "knative.dev/hack"
	_ "knative.dev/pkg/hack"

	_ "k8s.io/code-generator/cmd/deepcopy-gen"

	// For chaos testing the leaderelection stuff.
	_ "knative.dev/pkg/leaderelection/chaosduck"

	// To get the ingress CRD
	_ "knative.dev/networking/config"

	_ "knative.dev/networking/test/conformance/ingress"
	_ "knative.dev/networking/test/test_images/grpc-ping"
	_ "knative.dev/networking/test/test_images/httpproxy"
	_ "knative.dev/networking/test/test_images/retry"
	_ "knative.dev/networking/test/test_images/runtime"
	_ "knative.dev/networking/test/test_images/timeout"
	_ "knative.dev/networking/test/test_images/wsserver"
)
<|endoftext|>


<commit_before>package tw

import (
	"net/http"
	"net/url"

	"github.com/dghubble/oauth1"
	"github.com/dghubble/oauth1/twitter"
)

var conf *oauth1.Config

func init() {
	conf = &oauth1.Config{
		ConsumerKey:    CONSUMER_KEY,
		ConsumerSecret: CONSUMER_SECRET,
		CallbackURL:    "oob",
	}
}

func GetRequestToken() (*oauth1.RequestToken, *url.URL, error) {
	conf.Endpoint = twitter.AuthorizeEndpoint
	reqToken, err := conf.GetRequestToken()
	if err != nil {
		return nil, nil, err
	}
	url, err := conf.AuthorizationURL(reqToken)
	if err != nil {
		return nil, nil, err
	}
	return reqToken, url, nil
}

func GetAccessToken(reqToken *oauth1.RequestToken, pin string) (*oauth1.Token, error) {
	return conf.GetAccessToken(reqToken, pin)
}

// https://dev.twitter.com/rest/reference/get/account/verify_credentials
func VerifyCredentials(token *oauth1.Token) (*http.Response, error) {
	conf.Endpoint = twitter.AuthenticateEndpoint
	client := oauth1.NewClient(conf, token)
	return client.Get("https://api.twitter.com/1.1/account/verify_credentials.json")
}

// https://dev.twitter.com/rest/reference/post/statuses/update
func Tweet(tweet string, token *oauth1.Token) (*http.Response, error) {
	conf.Endpoint = twitter.AuthenticateEndpoint
	client := oauth1.NewClient(conf, token)
	return client.PostForm("https://api.twitter.com/1.1/statuses/update.json",
		url.Values{"status": []string{tweet}})
}
<commit_msg>[ADD] GetMentions, RemoveTweet<commit_after>package tw

import (
	"fmt"
	"net/http"
	"net/url"

	"github.com/dghubble/oauth1"
	"github.com/dghubble/oauth1/twitter"
)

const TWITTER_API = "https://api.twitter.com/1.1/"

var conf *oauth1.Config

func init() {
	conf = &oauth1.Config{
		ConsumerKey:    CONSUMER_KEY,
		ConsumerSecret: CONSUMER_SECRET,
		CallbackURL:    "oob",
	}
}

func GetRequestToken() (*oauth1.RequestToken, *url.URL, error) {
	conf.Endpoint = twitter.AuthorizeEndpoint
	reqToken, err := conf.GetRequestToken()
	if err != nil {
		return nil, nil, err
	}
	url, err := conf.AuthorizationURL(reqToken)
	if err != nil {
		return nil, nil, err
	}
	return reqToken, url, nil
}

func GetAccessToken(reqToken *oauth1.RequestToken, pin string) (*oauth1.Token, error) {
	return conf.GetAccessToken(reqToken, pin)
}

// https://dev.twitter.com/rest/reference/get/account/verify_credentials
func VerifyCredentials(token *oauth1.Token) (*http.Response, error) {
	conf.Endpoint = twitter.AuthenticateEndpoint
	client := oauth1.NewClient(conf, token)
	return client.Get(TWITTER_API + "account/verify_credentials.json")
}

// https://dev.twitter.com/rest/reference/post/statuses/update
func Tweet(tweet string, token *oauth1.Token) (*http.Response, error) {
	conf.Endpoint = twitter.AuthenticateEndpoint
	client := oauth1.NewClient(conf, token)
	return client.PostForm(TWITTER_API+"statuses/update.json",
		url.Values{"status": []string{tweet}})
}

// https://dev.twitter.com/rest/reference/get/statuses/mentions_timeline
func GetMentions(token *oauth1.Token) (*http.Response, error) {
	conf.Endpoint = twitter.AuthenticateEndpoint
	client := oauth1.NewClient(conf, token)
	return client.PostForm(TWITTER_API+"statuses/mentions_timeline.json", nil)
}

// https://dev.twitter.com/rest/reference/post/statuses/destroy/%3Aid
func RemoveTweet(id string, token *oauth1.Token) (*http.Response, error) {
	conf.Endpoint = twitter.AuthenticateEndpoint
	client := oauth1.NewClient(conf, token)
	return client.PostForm(TWITTER_API+fmt.Sprintf("statuses/destroy/%s.json", id), nil)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

type HTTPError struct {
	URL    string
	Code   int
	Status string
}

func (e *HTTPError) Error() string {
	return fmt.Sprintf("got %s fetching %s", e.Status, e.URL)
}

func doHTTP(url string, input io.Reader) (io.ReadCloser, error) {
	method := "GET"
	if input != nil {
		method = "POST"
	}
	rq, err := http.NewRequest(method, url, input)
	if err != nil {
		return nil, err
	}
	rq.Header.Set("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)")
	if input != nil {
		rq.Header.Set("Content-Type", "application/json")
	}
	rsp, err := http.DefaultClient.Do(rq)
	if err != nil {
		return nil, err
	}
	if rsp.StatusCode != http.StatusOK {
		rsp.Body.Close()
		err := &HTTPError{
			URL:    url,
			Code:   rsp.StatusCode,
			Status: rsp.Status,
		}
		return nil, err
	}
	return rsp.Body, nil
}

func tryHTTP(url string, baseDelay time.Duration, loops int,
	input io.Reader) (io.ReadCloser, error) {

	delay := baseDelay
	for {
		output, err := doHTTP(url, input)
		if err == nil {
			return output, nil
		}
		if h, ok := err.(*HTTPError); ok && h.Code == http.StatusNotFound {
			return nil, err
		}
		fmt.Printf("fetching failed with: %s\n", err)
		loops -= 1
		if loops <= 0 {
			return nil, err
		}
		time.Sleep(delay)
		delay *= 2
	}
}

func doJson(url string, baseDelay time.Duration, loops int, input interface{},
	output interface{}) error {

	var post io.Reader
	if input != nil {
		body := &bytes.Buffer{}
		err := json.NewEncoder(body).Encode(input)
		if err != nil {
			return err
		}
		post = body
	}
	result, err := tryHTTP(url, baseDelay, loops, post)
	if err != nil {
		return err
	}
	defer result.Close()
	return json.NewDecoder(result).Decode(output)
}

type SearchPaging struct {
	Range      int `json:"range"`
	StartIndex int `json:"startIndex"`
}

type SearchSorts struct {
	Direction string `json:"direction"`
	Type      string `json:"type"`
}

type SearchFilters struct {
	EnableFilter    bool          `json:"activeFiltre"`
	Functions       []int         `json:"fonctions"`
	Places          []int         `json:"lieux"`
	Keywords        string        `json:"motsCles"`
	Experience      []int         `json:"niveauxExperience"`
	Paging          SearchPaging  `json:"pagination"`
	MinSalary       int           `json:"salaireMinimum"`
	MaxSalary       int           `json:"salaireMaximum"`
	Sectors         []int         `json:"secteursActivite"`
	Sorts           []SearchSorts `json:"sorts"`
	ClientType      string        `json:"typeClient"`
	ContractTypes   []int         `json:"typesContrat"`
	ConventionTypes []int         `json:"typesConvention"`
}

func searchOffers(start, count, minSalary int, locations []int) ([]string, error) {
	filter := &SearchFilters{
		EnableFilter: true,
		Functions:    []int{},
		Places:       locations,
		Experience:   []int{},
		Paging: SearchPaging{
			Range:      count,
			StartIndex: start,
		},
		MinSalary: minSalary,
		MaxSalary: 1000,
		Sectors:   []int{},
		Sorts: []SearchSorts{
			{
				Direction: "DESCENDING",
				Type:      "DATE",
			},
		},
		ClientType:      "CADRE",
		ContractTypes:   []int{},
		ConventionTypes: []int{},
	}
	results := &struct {
		Results []struct {
			URI string `json:"@uriOffre"`
		} `json:"resultats"`
	}{}
	url := "https://cadres.apec.fr/cms/webservices/rechercheOffre/ids"
	err := doJson(url, 5*time.Second, 5, filter, results)
	if err != nil {
		return nil, err
	}
	ids := []string{}
	for _, uri := range results.Results {
		parts := strings.Split(uri.URI, "numeroOffre=")
		if len(parts) != 2 {
			return nil, fmt.Errorf("invalid offer identifier: %s", uri.URI)
		}
		ids = append(ids, parts[1])
	}
	return ids, nil
}

func getOffer(id string) ([]byte, error) {
	u := "https://cadres.apec.fr/cms/webservices/offre/public?numeroOffre=" + id
	output, err := tryHTTP(u, time.Second, 5, nil)
	if err != nil {
		if h, ok := err.(*HTTPError); ok && h.Code == http.StatusNotFound {
			return nil, nil
		}
		return nil, err
	}
	defer output.Close()
	return ioutil.ReadAll(output)
}

// enumerateOffers search offers satisfying the minSalary and locations
// constraints and repeatedly calls callback with slices of offers identifiers.
// The enumeration is not atomic, there is no guarantee a value is returned
// only once.
func enumerateOffers(minSalary int, locations []int, callback func([]string) error) error {
	start := 0
	overlap := 5
	count := 250
	delay := 5 * time.Second
	for ; ; time.Sleep(delay) {
		fmt.Printf("fetching from %d to %d\n", start, start+count)
		ids, err := searchOffers(start, count, minSalary, locations)
		if err != nil {
			return err
		}
		start += (count - overlap)
		err = callback(ids)
		if err != nil {
			return err
		}
		if len(ids) < count {
			break
		}
	}
	return nil
}

func crawlOffers(store *Store, ids []string) (int, error) {
	added := 0
	for _, id := range ids {
		ok, err := store.Has(id)
		if err != nil {
			return added, err
		}
		if ok {
			continue
		}
		fmt.Printf("fetching %s\n", id)
		data, err := getOffer(id)
		if err != nil {
			return added, err
		}
		time.Sleep(time.Second)
		if data == nil {
			fmt.Printf("could not find %s\n", id)
			continue
		}
		err = store.Put(id, data)
		if err != nil {
			return added, err
		}
		added += 1
	}
	return added, nil
}

func crawl(store *Store, minSalary int, locations []int) error {
	idsChan := make(chan []string)
	stopListing := make(chan bool)
	listingDone := make(chan error)
	crawlingDone := make(chan error)

	// List offers in one goroutine. This reduces the races between our
	// enumeration and possible web site updates.
	seen := map[string]bool{}
	go func() {
		pending := []string{}
		err := enumerateOffers(minSalary, locations, func(ids []string) error {
			for _, id := range ids {
				if !seen[id] {
					pending = append(pending, id)
				}
				seen[id] = true
			}
			select {
			case <-stopListing:
				return fmt.Errorf("offer enumeration was interrupted")
			case idsChan <- pending:
				pending = nil
			default:
			}
			return nil
		})
		close(idsChan)
		listingDone <- err
	}()

	// Crawl offers in another goroutine
	added := 0
	go func() {
		for ids := range idsChan {
			n, err := crawlOffers(store, ids)
			added += n
			if n < len(ids) {
				fmt.Printf("%d known offers ignored\n", len(ids)-n)
			}
			if err != nil {
				crawlingDone <- err
				break
			}
		}
		close(crawlingDone)
	}()

	// Shutdown everything cleanly
	crawlingErr := <-crawlingDone
	close(stopListing)
	listingErr := <-listingDone
	if listingErr != nil {
		return listingErr
	}
	if crawlingErr != nil {
		return crawlingErr
	}

	// Delete unseen offers
	deleted := 0
	ids, err := store.List()
	if err != nil {
		return err
	}
	now := time.Now()
	for _, id := range ids {
		if !seen[id] {
			fmt.Printf("deleting %s\n", id)
			store.Delete(id, now)
			deleted += 1
		}
	}
	fmt.Printf("%d added, %d deleted, %d total\n", added, deleted, store.Size())
	return nil
}

var (
	crawlCmd       = app.Command("crawl", "crawl APEC offers")
	crawlMinSalary = crawlCmd.Flag("min-salary", "minimum salary in kEUR").Default("0").Int()
	crawlLocations = crawlCmd.Flag("location", "offer location code").Ints()
)

func crawlFn(cfg *Config) error {
	store, err := OpenStore(cfg.Store())
	if err != nil {
		return err
	}
	var closeErr error
	defer func() {
		closeErr = store.Close()
	}()
	err = crawl(store, *crawlMinSalary, *crawlLocations)
	if err != nil {
		return err
	}
	return closeErr
}
<commit_msg>crawl: document HTTP wrappers and fix tryHTTP<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

type HTTPError struct {
	URL    string
	Code   int
	Status string
}

func (e *HTTPError) Error() string {
	return fmt.Sprintf("got %s fetching %s", e.Status, e.URL)
}

// doHTTP performs a single GET (or POST if input is not nil) and returns
// response data if any. It is the caller responsibility to close returned
// reader.
func doHTTP(url string, input io.Reader) (io.ReadCloser, error) {
	method := "GET"
	if input != nil {
		method = "POST"
	}
	rq, err := http.NewRequest(method, url, input)
	if err != nil {
		return nil, err
	}
	rq.Header.Set("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)")
	if input != nil {
		rq.Header.Set("Content-Type", "application/json")
	}
	rsp, err := http.DefaultClient.Do(rq)
	if err != nil {
		return nil, err
	}
	if rsp.StatusCode != http.StatusOK {
		rsp.Body.Close()
		err := &HTTPError{
			URL:    url,
			Code:   rsp.StatusCode,
			Status: rsp.Status,
		}
		return nil, err
	}
	return rsp.Body, nil
}

// tryHTTP performs a GET or POST with exponential backoff, with specified
// delay and maximum retry count.
func tryHTTP(url string, baseDelay time.Duration, loops int,
	input io.ReadSeeker) (io.ReadCloser, error) {

	delay := baseDelay
	for {
		if input != nil {
			_, err := input.Seek(0, 0)
			if err != nil {
				return nil, err
			}
		}
		output, err := doHTTP(url, input)
		if err == nil {
			return output, nil
		}
		if h, ok := err.(*HTTPError); ok && h.Code == http.StatusNotFound {
			return nil, err
		}
		fmt.Printf("fetching failed with: %s\n", err)
		loops -= 1
		if loops <= 0 {
			return nil, err
		}
		time.Sleep(delay)
		delay *= 2
	}
}

func doJson(url string, baseDelay time.Duration, loops int, input interface{},
	output interface{}) error {

	var post io.ReadSeeker
	if input != nil {
		body := &bytes.Buffer{}
		err := json.NewEncoder(body).Encode(input)
		if err != nil {
			return err
		}
		post = bytes.NewReader(body.Bytes())
	}
	result, err := tryHTTP(url, baseDelay, loops, post)
	if err != nil {
		return err
	}
	defer result.Close()
	return json.NewDecoder(result).Decode(output)
}

type SearchPaging struct {
	Range      int `json:"range"`
	StartIndex int `json:"startIndex"`
}

type SearchSorts struct {
	Direction string `json:"direction"`
	Type      string `json:"type"`
}

type SearchFilters struct {
	EnableFilter    bool          `json:"activeFiltre"`
	Functions       []int         `json:"fonctions"`
	Places          []int         `json:"lieux"`
	Keywords        string        `json:"motsCles"`
	Experience      []int         `json:"niveauxExperience"`
	Paging          SearchPaging  `json:"pagination"`
	MinSalary       int           `json:"salaireMinimum"`
	MaxSalary       int           `json:"salaireMaximum"`
	Sectors         []int         `json:"secteursActivite"`
	Sorts           []SearchSorts `json:"sorts"`
	ClientType      string        `json:"typeClient"`
	ContractTypes   []int         `json:"typesContrat"`
	ConventionTypes []int         `json:"typesConvention"`
}

func searchOffers(start, count, minSalary int, locations []int) ([]string, error) {
	filter := &SearchFilters{
		EnableFilter: true,
		Functions:    []int{},
		Places:       locations,
		Experience:   []int{},
		Paging: SearchPaging{
			Range:      count,
			StartIndex: start,
		},
		MinSalary: minSalary,
		MaxSalary: 1000,
		Sectors:   []int{},
		Sorts: []SearchSorts{
			{
				Direction: "DESCENDING",
				Type:      "DATE",
			},
		},
		ClientType:      "CADRE",
		ContractTypes:   []int{},
		ConventionTypes: []int{},
	}
	results := &struct {
		Results []struct {
			URI string `json:"@uriOffre"`
		} `json:"resultats"`
	}{}
	url := "https://cadres.apec.fr/cms/webservices/rechercheOffre/ids"
	err := doJson(url, 5*time.Second, 5, filter, results)
	if err != nil {
		return nil, err
	}
	ids := []string{}
	for _, uri := range results.Results {
		parts := strings.Split(uri.URI, "numeroOffre=")
		if len(parts) != 2 {
			return nil, fmt.Errorf("invalid offer identifier: %s", uri.URI)
		}
		ids = append(ids, parts[1])
	}
	return ids, nil
}

func getOffer(id string) ([]byte, error) {
	u := "https://cadres.apec.fr/cms/webservices/offre/public?numeroOffre=" + id
	output, err := tryHTTP(u, time.Second, 5, nil)
	if err != nil {
		if h, ok := err.(*HTTPError); ok && h.Code == http.StatusNotFound {
			return nil, nil
		}
		return nil, err
	}
	defer output.Close()
	return ioutil.ReadAll(output)
}

// enumerateOffers search offers satisfying the minSalary and locations
// constraints and repeatedly calls callback with slices of offers identifiers.
// The enumeration is not atomic, there is no guarantee a value is returned
// only once.
func enumerateOffers(minSalary int, locations []int, callback func([]string) error) error {
	start := 0
	overlap := 5
	count := 250
	delay := 5 * time.Second
	for ; ; time.Sleep(delay) {
		fmt.Printf("fetching from %d to %d\n", start, start+count)
		ids, err := searchOffers(start, count, minSalary, locations)
		if err != nil {
			return err
		}
		start += (count - overlap)
		err = callback(ids)
		if err != nil {
			return err
		}
		if len(ids) < count {
			break
		}
	}
	return nil
}

func crawlOffers(store *Store, ids []string) (int, error) {
	added := 0
	for _, id := range ids {
		ok, err := store.Has(id)
		if err != nil {
			return added, err
		}
		if ok {
			continue
		}
		fmt.Printf("fetching %s\n", id)
		data, err := getOffer(id)
		if err != nil {
			return added, err
		}
		time.Sleep(time.Second)
		if data == nil {
			fmt.Printf("could not find %s\n", id)
			continue
		}
		err = store.Put(id, data)
		if err != nil {
			return added, err
		}
		added += 1
	}
	return added, nil
}

func crawl(store *Store, minSalary int, locations []int) error {
	idsChan := make(chan []string)
	stopListing := make(chan bool)
	listingDone := make(chan error)
	crawlingDone := make(chan error)

	// List offers in one goroutine. This reduces the races between our
	// enumeration and possible web site updates.
	seen := map[string]bool{}
	go func() {
		pending := []string{}
		err := enumerateOffers(minSalary, locations, func(ids []string) error {
			for _, id := range ids {
				if !seen[id] {
					pending = append(pending, id)
				}
				seen[id] = true
			}
			select {
			case <-stopListing:
				return fmt.Errorf("offer enumeration was interrupted")
			case idsChan <- pending:
				pending = nil
			default:
			}
			return nil
		})
		close(idsChan)
		listingDone <- err
	}()

	// Crawl offers in another goroutine
	added := 0
	go func() {
		for ids := range idsChan {
			n, err := crawlOffers(store, ids)
			added += n
			if n < len(ids) {
				fmt.Printf("%d known offers ignored\n", len(ids)-n)
			}
			if err != nil {
				crawlingDone <- err
				break
			}
		}
		close(crawlingDone)
	}()

	// Shutdown everything cleanly
	crawlingErr := <-crawlingDone
	close(stopListing)
	listingErr := <-listingDone
	if listingErr != nil {
		return listingErr
	}
	if crawlingErr != nil {
		return crawlingErr
	}

	// Delete unseen offers
	deleted := 0
	ids, err := store.List()
	if err != nil {
		return err
	}
	now := time.Now()
	for _, id := range ids {
		if !seen[id] {
			fmt.Printf("deleting %s\n", id)
			store.Delete(id, now)
			deleted += 1
		}
	}
	fmt.Printf("%d added, %d deleted, %d total\n", added, deleted, store.Size())
	return nil
}

var (
	crawlCmd       = app.Command("crawl", "crawl APEC offers")
	crawlMinSalary = crawlCmd.Flag("min-salary", "minimum salary in kEUR").Default("0").Int()
	crawlLocations = crawlCmd.Flag("location", "offer location code").Ints()
)

func crawlFn(cfg *Config) error {
	store, err := OpenStore(cfg.Store())
	if err != nil {
		return err
	}
	var closeErr error
	defer func() {
		closeErr = store.Close()
	}()
	err = crawl(store, *crawlMinSalary, *crawlLocations)
	if err != nil {
		return err
	}
	return closeErr
}
<|endoftext|>


<commit_before>package routes

import (
	"concierge/controllers"
	"concierge/routes/middleware"

	"github.com/gin-gonic/gin"
)

//InitializeRoutes ...
func InitializeRoutes(router *gin.Engine) {

	// Handle the index route
	router.GET("/", func(c *gin.Context) {
		c.Redirect(302, "http://"+c.Request.Host+"/ingress")
	})

	authorized := router.Group("/")
	authorized.Use(middleware.Authorize)
	{
		authorized.GET("/ingress", controllers.ShowAllowedIngress)
		authorized.GET("/ingress/:ns/:name", controllers.IngressDetails)
		authorized.POST("/ingress/:ns/:name", controllers.WhiteListIP)
		authorized.POST("/ingress/:ns/:name/:id", controllers.DeleteIPFromIngress)
		authorized.GET("/users", controllers.GetUsers)
		authorized.GET("/users/add", controllers.AddUsersForm)
		authorized.POST("/users/add", controllers.AddUsers)
		authorized.GET("/users/edit/:id", controllers.UpdateUsersForm)
		authorized.POST("/users/edit/:id", controllers.UpdateUser)
		authorized.POST("/users/delete", controllers.DeleteUser)
		authorized.GET("/logout", func(c *gin.Context) {
			c.SetCookie("_oauth2_proxy", "", -1, "/", "https://"+c.Request.Host+"/", false, true)
			c.Redirect(302, "http://"+c.Request.Host+"/")
		})
	}

	router.GET("/cron", controllers.ClearExpiredLeases)
	cron := router.Group("/cron")
	cron.Use(middleware.Cron)
	{
		cron.POST("/", controllers.ClearExpiredLeases)
	}
}
<commit_msg>Fixing logout issue<commit_after>package routes

import (
	"concierge/controllers"
	"concierge/routes/middleware"

	"github.com/gin-gonic/gin"
)

//InitializeRoutes ...
func InitializeRoutes(router *gin.Engine) {

	// Handle the index route
	router.GET("/", func(c *gin.Context) {
		c.Redirect(302, "http://"+c.Request.Host+"/ingress")
	})

	authorized := router.Group("/")
	authorized.Use(middleware.Authorize)
	{
		authorized.GET("/ingress", controllers.ShowAllowedIngress)
		authorized.GET("/ingress/:ns/:name", controllers.IngressDetails)
		authorized.POST("/ingress/:ns/:name", controllers.WhiteListIP)
		authorized.POST("/ingress/:ns/:name/:id", controllers.DeleteIPFromIngress)
		authorized.GET("/users", controllers.GetUsers)
		authorized.GET("/users/add", controllers.AddUsersForm)
		authorized.POST("/users/add", controllers.AddUsers)
		authorized.GET("/users/edit/:id", controllers.UpdateUsersForm)
		authorized.POST("/users/edit/:id", controllers.UpdateUser)
		authorized.POST("/users/delete", controllers.DeleteUser)
		authorized.GET("/logout", func(c *gin.Context) {
			c.Redirect(302, "http://"+c.Request.Host+"/oauth2/sign_in")
		})
	}

	router.GET("/cron", controllers.ClearExpiredLeases)
	cron := router.Group("/cron")
	cron.Use(middleware.Cron)
	{
		cron.POST("/", controllers.ClearExpiredLeases)
	}
}
<|endoftext|>


<commit_before>//  Copyright (c) 2017 Couchbase, 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 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 vellum

import (
	"bytes"
)

// Iterator represents a means of visity key/value pairs in order.
type Iterator interface {

	// Current() returns the key/value pair currently pointed to.
	// The []byte of the key is ONLY guaranteed to be valid until
	// another call to Next/Seek/Close.  If you need it beyond that
	// point you MUST make a copy.
	Current() ([]byte, uint64)

	// Next() advances the iterator to the next key/value pair.
	// If no more key/value pairs exist, ErrIteratorDone is returned.
	Next() error

	// Seek() advances the iterator the specified key, or the next key
	// if it does not exist.
	// If no keys exist after that point, ErrIteratorDone is returned.
	Seek(key []byte) error

	// Reset resets the Iterator' internal state to allow for iterator
	// reuse (e.g. pooling).
	Reset(f *FST, startKeyInclusive, endKeyExclusive []byte, aut Automaton) error

	// Close() frees any resources held by this iterator.
	Close() error
}

// FSTIterator is a structure for iterating key/value pairs in this FST in
// lexicographic order.  Iterators should be constructed with the FSTIterator
// method on the parent FST structure.
type FSTIterator struct {
	f   *FST
	aut Automaton

	startKeyInclusive []byte
	endKeyExclusive   []byte

	statesStack    []fstState
	keysStack      []byte
	keysPosStack   []int
	valsStack      []uint64
	autStatesStack []int

	nextStart []byte
}

func newIterator(f *FST, startKeyInclusive, endKeyExclusive []byte,
	aut Automaton) (*FSTIterator, error) {

	rv := &FSTIterator{}
	err := rv.Reset(f, startKeyInclusive, endKeyExclusive, aut)
	if err != nil {
		return nil, err
	}
	return rv, nil
}

// Reset resets the Iterator' internal state to allow for iterator
// reuse (e.g. pooling).
func (i *FSTIterator) Reset(f *FST, startKeyInclusive, endKeyExclusive []byte, aut Automaton) error {
	if aut == nil {
		aut = alwaysMatchAutomaton
	}

	i.f = f
	i.startKeyInclusive = startKeyInclusive
	i.endKeyExclusive = endKeyExclusive
	i.aut = aut

	return i.pointTo(startKeyInclusive)
}

// pointTo attempts to point us to the specified location
func (i *FSTIterator) pointTo(key []byte) error {

	// tried to seek before start
	if bytes.Compare(key, i.startKeyInclusive) < 0 {
		key = i.startKeyInclusive
	}

	// trid to see past end
	if i.endKeyExclusive != nil && bytes.Compare(key, i.endKeyExclusive) > 0 {
		key = i.endKeyExclusive
	}

	// reset any state, pointTo always starts over
	i.statesStack = i.statesStack[:0]
	i.keysStack = i.keysStack[:0]
	i.keysPosStack = i.keysPosStack[:0]
	i.valsStack = i.valsStack[:0]
	i.autStatesStack = i.autStatesStack[:0]

	root, err := i.f.decoder.stateAt(i.f.decoder.getRoot(), nil)
	if err != nil {
		return err
	}

	autStart := i.aut.Start()

	maxQ := -1
	// root is always part of the path
	i.statesStack = append(i.statesStack, root)
	i.autStatesStack = append(i.autStatesStack, autStart)
	for j := 0; j < len(key); j++ {
		curr := i.statesStack[len(i.statesStack)-1]
		autCurr := i.autStatesStack[len(i.autStatesStack)-1]

		pos, nextAddr, nextVal := curr.TransitionFor(key[j])
		if nextAddr == noneAddr {
			// needed transition doesn't exist
			// find last trans before the one we needed
			for q := 0; q < curr.NumTransitions(); q++ {
				if curr.TransitionAt(q) < key[j] {
					maxQ = q
				}
			}
			break
		}
		autNext := i.aut.Accept(autCurr, key[j])

		next, err := i.f.decoder.stateAt(nextAddr, nil)
		if err != nil {
			return err
		}

		i.statesStack = append(i.statesStack, next)
		i.keysStack = append(i.keysStack, key[j])
		i.keysPosStack = append(i.keysPosStack, pos)
		i.valsStack = append(i.valsStack, nextVal)
		i.autStatesStack = append(i.autStatesStack, autNext)
		continue
	}

	if !i.statesStack[len(i.statesStack)-1].Final() || !i.aut.IsMatch(i.autStatesStack[len(i.autStatesStack)-1]) || bytes.Compare(i.keysStack, key) < 0 {
		return i.next(maxQ)
	}

	return nil
}

// Current returns the key and value currently pointed to by the iterator.
// If the iterator is not pointing at a valid value (because Iterator/Next/Seek)
// returned an error previously, it may return nil,0.
func (i *FSTIterator) Current() ([]byte, uint64) {
	curr := i.statesStack[len(i.statesStack)-1]
	if curr.Final() {
		var total uint64
		for _, v := range i.valsStack {
			total += v
		}
		total += curr.FinalOutput()
		return i.keysStack, total
	}
	return nil, 0
}

// Next advances this iterator to the next key/value pair.  If there is none
// or the advancement goes beyond the configured endKeyExclusive, then
// ErrIteratorDone is returned.
func (i *FSTIterator) Next() error {
	return i.next(-1)
}

func (i *FSTIterator) next(lastOffset int) error {

	// remember where we started
	if cap(i.nextStart) < len(i.keysStack) {
		i.nextStart = make([]byte, len(i.keysStack))
	} else {
		i.nextStart = i.nextStart[0:len(i.keysStack)]
	}
	copy(i.nextStart, i.keysStack)

	for true {
		curr := i.statesStack[len(i.statesStack)-1]
		autCurr := i.autStatesStack[len(i.autStatesStack)-1]

		if curr.Final() && i.aut.IsMatch(autCurr) &&
			bytes.Compare(i.keysStack, i.nextStart) > 0 {
			// in final state greater than start key
			return nil
		}

		nextOffset := lastOffset + 1
		if nextOffset < curr.NumTransitions() {
			t := curr.TransitionAt(nextOffset)
			autNext := i.aut.Accept(autCurr, t)
			if i.aut.CanMatch(autNext) {
				pos, nextAddr, v := curr.TransitionFor(t)
				// push onto stack
				next, err := i.f.decoder.stateAt(nextAddr, nil)
				if err != nil {
					return err
				}
				i.statesStack = append(i.statesStack, next)
				i.keysStack = append(i.keysStack, t)
				i.keysPosStack = append(i.keysPosStack, pos)
				i.valsStack = append(i.valsStack, v)
				i.autStatesStack = append(i.autStatesStack, autNext)
				lastOffset = -1

				// check to see if new keystack might have gone too far
				if i.endKeyExclusive != nil && bytes.Compare(i.keysStack, i.endKeyExclusive) >= 0 {
					return ErrIteratorDone
				}
			} else {
				lastOffset = nextOffset
			}

			continue
		}

		if len(i.statesStack) > 1 {
			// no transitions, and still room to pop
			i.statesStack = i.statesStack[:len(i.statesStack)-1]
			i.keysStack = i.keysStack[:len(i.keysStack)-1]
			lastOffset = i.keysPosStack[len(i.keysPosStack)-1]

			i.keysPosStack = i.keysPosStack[:len(i.keysPosStack)-1]
			i.valsStack = i.valsStack[:len(i.valsStack)-1]
			i.autStatesStack = i.autStatesStack[:len(i.autStatesStack)-1]
			continue
		} else {
			// stack len is 1 (root), can't go back further, we're done
			break
		}

	}

	return ErrIteratorDone
}

// Seek advances this iterator to the specified key/value pair.  If this key
// is not in the FST, Current() will return the next largest key.  If this
// seek operation would go past the last key, or outside the configured
// startKeyInclusive/endKeyExclusive then ErrIteratorDone is returned.
func (i *FSTIterator) Seek(key []byte) error {
	err := i.pointTo(key)
	if err != nil {
		return err
	}
	return nil
}

// Close will free any resources held by this iterator.
func (i *FSTIterator) Close() error {
	// at the moment we don't do anything, but wanted this for API completeness
	return nil
}
<commit_msg>FSTIterator.next() optimization by reusing fstState<commit_after>//  Copyright (c) 2017 Couchbase, 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 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 vellum

import (
	"bytes"
)

// Iterator represents a means of visity key/value pairs in order.
type Iterator interface {

	// Current() returns the key/value pair currently pointed to.
	// The []byte of the key is ONLY guaranteed to be valid until
	// another call to Next/Seek/Close.  If you need it beyond that
	// point you MUST make a copy.
	Current() ([]byte, uint64)

	// Next() advances the iterator to the next key/value pair.
	// If no more key/value pairs exist, ErrIteratorDone is returned.
	Next() error

	// Seek() advances the iterator the specified key, or the next key
	// if it does not exist.
	// If no keys exist after that point, ErrIteratorDone is returned.
	Seek(key []byte) error

	// Reset resets the Iterator' internal state to allow for iterator
	// reuse (e.g. pooling).
	Reset(f *FST, startKeyInclusive, endKeyExclusive []byte, aut Automaton) error

	// Close() frees any resources held by this iterator.
	Close() error
}

// FSTIterator is a structure for iterating key/value pairs in this FST in
// lexicographic order.  Iterators should be constructed with the FSTIterator
// method on the parent FST structure.
type FSTIterator struct {
	f   *FST
	aut Automaton

	startKeyInclusive []byte
	endKeyExclusive   []byte

	statesStack    []fstState
	keysStack      []byte
	keysPosStack   []int
	valsStack      []uint64
	autStatesStack []int

	nextStart []byte
}

func newIterator(f *FST, startKeyInclusive, endKeyExclusive []byte,
	aut Automaton) (*FSTIterator, error) {

	rv := &FSTIterator{}
	err := rv.Reset(f, startKeyInclusive, endKeyExclusive, aut)
	if err != nil {
		return nil, err
	}
	return rv, nil
}

// Reset resets the Iterator' internal state to allow for iterator
// reuse (e.g. pooling).
func (i *FSTIterator) Reset(f *FST, startKeyInclusive, endKeyExclusive []byte, aut Automaton) error {
	if aut == nil {
		aut = alwaysMatchAutomaton
	}

	i.f = f
	i.startKeyInclusive = startKeyInclusive
	i.endKeyExclusive = endKeyExclusive
	i.aut = aut

	return i.pointTo(startKeyInclusive)
}

// pointTo attempts to point us to the specified location
func (i *FSTIterator) pointTo(key []byte) error {

	// tried to seek before start
	if bytes.Compare(key, i.startKeyInclusive) < 0 {
		key = i.startKeyInclusive
	}

	// trid to see past end
	if i.endKeyExclusive != nil && bytes.Compare(key, i.endKeyExclusive) > 0 {
		key = i.endKeyExclusive
	}

	// reset any state, pointTo always starts over
	i.statesStack = i.statesStack[:0]
	i.keysStack = i.keysStack[:0]
	i.keysPosStack = i.keysPosStack[:0]
	i.valsStack = i.valsStack[:0]
	i.autStatesStack = i.autStatesStack[:0]

	root, err := i.f.decoder.stateAt(i.f.decoder.getRoot(), nil)
	if err != nil {
		return err
	}

	autStart := i.aut.Start()

	maxQ := -1
	// root is always part of the path
	i.statesStack = append(i.statesStack, root)
	i.autStatesStack = append(i.autStatesStack, autStart)
	for j := 0; j < len(key); j++ {
		curr := i.statesStack[len(i.statesStack)-1]
		autCurr := i.autStatesStack[len(i.autStatesStack)-1]

		pos, nextAddr, nextVal := curr.TransitionFor(key[j])
		if nextAddr == noneAddr {
			// needed transition doesn't exist
			// find last trans before the one we needed
			for q := 0; q < curr.NumTransitions(); q++ {
				if curr.TransitionAt(q) < key[j] {
					maxQ = q
				}
			}
			break
		}
		autNext := i.aut.Accept(autCurr, key[j])

		next, err := i.f.decoder.stateAt(nextAddr, nil)
		if err != nil {
			return err
		}

		i.statesStack = append(i.statesStack, next)
		i.keysStack = append(i.keysStack, key[j])
		i.keysPosStack = append(i.keysPosStack, pos)
		i.valsStack = append(i.valsStack, nextVal)
		i.autStatesStack = append(i.autStatesStack, autNext)
		continue
	}

	if !i.statesStack[len(i.statesStack)-1].Final() || !i.aut.IsMatch(i.autStatesStack[len(i.autStatesStack)-1]) || bytes.Compare(i.keysStack, key) < 0 {
		return i.next(maxQ)
	}

	return nil
}

// Current returns the key and value currently pointed to by the iterator.
// If the iterator is not pointing at a valid value (because Iterator/Next/Seek)
// returned an error previously, it may return nil,0.
func (i *FSTIterator) Current() ([]byte, uint64) {
	curr := i.statesStack[len(i.statesStack)-1]
	if curr.Final() {
		var total uint64
		for _, v := range i.valsStack {
			total += v
		}
		total += curr.FinalOutput()
		return i.keysStack, total
	}
	return nil, 0
}

// Next advances this iterator to the next key/value pair.  If there is none
// or the advancement goes beyond the configured endKeyExclusive, then
// ErrIteratorDone is returned.
func (i *FSTIterator) Next() error {
	return i.next(-1)
}

func (i *FSTIterator) next(lastOffset int) error {

	// remember where we started
	if cap(i.nextStart) < len(i.keysStack) {
		i.nextStart = make([]byte, len(i.keysStack))
	} else {
		i.nextStart = i.nextStart[0:len(i.keysStack)]
	}
	copy(i.nextStart, i.keysStack)

	for true {
		curr := i.statesStack[len(i.statesStack)-1]
		autCurr := i.autStatesStack[len(i.autStatesStack)-1]

		if curr.Final() && i.aut.IsMatch(autCurr) &&
			bytes.Compare(i.keysStack, i.nextStart) > 0 {
			// in final state greater than start key
			return nil
		}

		nextOffset := lastOffset + 1
		if nextOffset < curr.NumTransitions() {
			t := curr.TransitionAt(nextOffset)
			autNext := i.aut.Accept(autCurr, t)
			if i.aut.CanMatch(autNext) {
				pos, nextAddr, v := curr.TransitionFor(t)

				// the next slot in the statesStack might have an
				// fstState instance that we can reuse
				var nextPrealloc fstState
				if len(i.statesStack) < cap(i.statesStack) {
					nextPrealloc = i.statesStack[0:cap(i.statesStack)][len(i.statesStack)]
				}

				// push onto stack
				next, err := i.f.decoder.stateAt(nextAddr, nextPrealloc)
				if err != nil {
					return err
				}
				i.statesStack = append(i.statesStack, next)
				i.keysStack = append(i.keysStack, t)
				i.keysPosStack = append(i.keysPosStack, pos)
				i.valsStack = append(i.valsStack, v)
				i.autStatesStack = append(i.autStatesStack, autNext)
				lastOffset = -1

				// check to see if new keystack might have gone too far
				if i.endKeyExclusive != nil && bytes.Compare(i.keysStack, i.endKeyExclusive) >= 0 {
					return ErrIteratorDone
				}
			} else {
				lastOffset = nextOffset
			}

			continue
		}

		if len(i.statesStack) > 1 {
			// no transitions, and still room to pop
			i.statesStack = i.statesStack[:len(i.statesStack)-1]
			i.keysStack = i.keysStack[:len(i.keysStack)-1]
			lastOffset = i.keysPosStack[len(i.keysPosStack)-1]

			i.keysPosStack = i.keysPosStack[:len(i.keysPosStack)-1]
			i.valsStack = i.valsStack[:len(i.valsStack)-1]
			i.autStatesStack = i.autStatesStack[:len(i.autStatesStack)-1]
			continue
		} else {
			// stack len is 1 (root), can't go back further, we're done
			break
		}

	}

	return ErrIteratorDone
}

// Seek advances this iterator to the specified key/value pair.  If this key
// is not in the FST, Current() will return the next largest key.  If this
// seek operation would go past the last key, or outside the configured
// startKeyInclusive/endKeyExclusive then ErrIteratorDone is returned.
func (i *FSTIterator) Seek(key []byte) error {
	err := i.pointTo(key)
	if err != nil {
		return err
	}
	return nil
}

// Close will free any resources held by this iterator.
func (i *FSTIterator) Close() error {
	// at the moment we don't do anything, but wanted this for API completeness
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/SudoQ/crisp/service"
	"github.com/SudoQ/crisp/logging"
	"runtime"
)

var port string
var limit uint

func init() {
	flag.StringVar(&port, "port", "8080", "Port number of the crisp service")
	flag.StringVar(&port, "p", "8080", "Port number of the crisp service (shorthand)")

	flag.UintVar(&limit, "limit", 60, "Limit of requests per hour")
	flag.UintVar(&limit, "l", 60, "Limit of requests per hour (shorthand)")

	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	flag.Parse()

	if len(flag.Args()) != 1 {
		logging.Info(
			fmt.Sprintf("Usage: \n\t%s\n\t%s",
				"crisp [-p=port] [-l=limit] <url>",
				"crisp -f=<file>"))
		return
	}
	url := flag.Arg(0)
	srv := service.New(url, port, limit)

	logging.Info(srv.Info())
	srv.Run()
}
<commit_msg>Removed info<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/SudoQ/crisp/service"
	"github.com/SudoQ/crisp/logging"
	"runtime"
)

var port string
var limit uint

func init() {
	flag.StringVar(&port, "port", "8080", "Port number of the crisp service")
	flag.StringVar(&port, "p", "8080", "Port number of the crisp service (shorthand)")

	flag.UintVar(&limit, "limit", 60, "Limit of requests per hour")
	flag.UintVar(&limit, "l", 60, "Limit of requests per hour (shorthand)")

	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	flag.Parse()

	if len(flag.Args()) != 1 {
		logging.Info(
			fmt.Sprintf("Usage: \n\t%s\n\t%s",
				"crisp [-p=port] [-l=limit] <url>",
				"crisp -f=<file>"))
		return
	}
	url := flag.Arg(0)
	srv := service.New(url, port, limit)

	srv.Run()
}
<|endoftext|>


<commit_before>package cs

import (
	"log"

	"github.com/chazsmi/stock-service/config"
	proto "github.com/chazsmi/stock-service/proto"
	"github.com/gocql/gocql"
)

var (
	Session *gocql.Session
)

// Opens a Cassandra Session
func Init() {
	c, err := config.ReadReturn(config.File)
	if err != nil {
		log.Fatal(err)
	}
	cluster := gocql.NewCluster(c.CsCluster.Host)
	cluster.Keyspace = "stock"
	cluster.Port = c.CsCluster.Port
	cluster.Consistency = gocql.Quorum
	cluster.ProtoVersion = 4
	session, err := cluster.CreateSession()
	if err != nil {
		log.Fatal(err)
	}
	Session = session
}

func Get(sku string) (*proto.StockResponse, error) {
	var amount int32
	if err := Session.Query(`SELECT amount FROM items WHERE sku = ?`,
		sku).Consistency(gocql.One).Scan(&amount); err != nil {
		return &proto.StockResponse{Sku: "fail"}, err
	}
	return &proto.StockResponse{
		Sku:    sku,
		Amount: amount,
	}, nil
}
<commit_msg>Remove debug code<commit_after>package cs

import (
	"log"

	"github.com/chazsmi/stock-service/config"
	proto "github.com/chazsmi/stock-service/proto"
	"github.com/gocql/gocql"
)

var (
	Session *gocql.Session
)

// Opens a Cassandra Session
func Init() {
	c, err := config.ReadReturn(config.File)
	if err != nil {
		log.Fatal(err)
	}
	cluster := gocql.NewCluster(c.CsCluster.Host)
	cluster.Keyspace = "stock"
	cluster.Port = c.CsCluster.Port
	cluster.Consistency = gocql.Quorum
	cluster.ProtoVersion = 4
	session, err := cluster.CreateSession()
	if err != nil {
		log.Fatal(err)
	}
	Session = session
}

func Get(sku string) (*proto.StockResponse, error) {
	var amount int32
	if err := Session.Query(`SELECT amount FROM items WHERE sku = ?`,
		sku).Consistency(gocql.One).Scan(&amount); err != nil {
		return &proto.StockResponse{}, err
	}
	return &proto.StockResponse{
		Sku:    sku,
		Amount: amount,
	}, nil
}
<|endoftext|>


<commit_before>package banner

import (
	"../zcrypto/ztls"
	"net"
	"fmt"
	"time"
)

// Implements the net.Conn interface
type Conn struct {
	// Underlying network connection
	conn net.Conn
	tlsConn ztls.Conn
	isTls bool

	// Keep track of state / network operations
	operations []ConnectionState

	// Cache the deadlines so we can reapply after TLS handshake
	readDeadline time.Time
	writeDeadline time.Time

}

func (c *Conn) getUnderlyingConn() (net.Conn) {
	if c.isTls {
		return c.tlsConn
	}
	return c.net.Conn
}

// Layer in the regular conn methods
func (c *Conn) LocalAddr() net.Addr {
	return c.getUnderlyingConn().LocalAddr()
}

func (c *Conn) RemoteAddr() net.Addr {
	return c.getUnderlyingConn().RemoteAddr()
}

func (c *Conn) SetDeadline(t time.Time) {
	c.readDeadline = t
	c.writeDeadline = t
	return c.getUnderlyingConn().SetDeadline(t)
}

func (c *Conn) SetReadDeadline(t time.Time) error {
	c.readDeadline = t
	return c.getUnderlyingConn().SetReadDeadline(t)
}

func (c *Conn) SetWriteDeadline(t time.Time) error {
	c.writeDeadline = deadline
	return c.getUnderlyingConn().SetWriteDeadline(t)
}

// Delegate here, but record all the things
func (c *Conn) Write(b []byte) (int, error) {
	n, err := c.getUnderlyingConn().Write(b)
	ws := writeState{toSend: b, err: err}
	operations = append(operations, []ConnectionState{ws})
	return n, err
}

func (c *Conn) Read(b []byte) (int, error) {
	n, err := c.getUnderlyingConn().Read(b)
	rs := readState{response: b[0:n], err: err}
	operations = append(operations, []ConnectionState{rs})
	return n, err
}

// Extra method - Do a TLS Handshake and record progress
func (c *Conn) TlsHandshake() error {
	if isTls {
		return fmt.Errorf(
			"Attempted repeat handshake with remote host %s",
			c.RemoteAddr().String())
	}
	tlsConfig := new(ztls.Config)
	tlsConfig.InsecureSkipVerify = true
	tlsConfig.MinVersion = ztls.VersionSSL30
	c.tlsConn = ztls.Client(nconn, tlsConfig)
	c.tlsConn.SetReadDeadline(c.readDeadline)
	c.tlsConn.SetWriteDeadline(c.writeDeadline)
	c.isTls = true
	err := tlsConn.Handshake()
	return err
}

// Do a STARTTLS handshake
func (c *Conn) StarttlsHandshake() error {
	// Don't doublehandshake
	if isTls {
		return fmt.Errorf(
			"Attempt STARTTLS after TLS handshake with remote host %s",
			c.RemoteAddr().String())
	}
	// Send the STARTTLS message
	starttls := []byte("STARTTLS\r\n");
	ss := starttlsState{}
 	_, err := conn.Write(starttls);
	// Read the response on a successful send
	if err == nil {
		var n int
		buf := make([]byte, 256)
		n, err = conn.Read(buf)
		ss.response = buf[0:n]
	}
	// No matter what happened, record the state
	ss.err = err
	operations = append(operations, []ConnectionState{ss})
	// Stop if we failed already
	if err != nil {
		return err
	}
	// Successful so far, attempt to do the actual handshake
	return c.TlsHandshake()
}
<commit_msg>Add Heartbleed probe to banner.Conn<commit_after>package banner

import (
	"../zcrypto/ztls"
	"net"
	"fmt"
	"time"
)

// Implements the net.Conn interface
type Conn struct {
	// Underlying network connection
	conn net.Conn
	tlsConn ztls.Conn
	isTls bool

	// Keep track of state / network operations
	operations []ConnectionState

	// Cache the deadlines so we can reapply after TLS handshake
	readDeadline time.Time
	writeDeadline time.Time

}

func (c *Conn) getUnderlyingConn() (net.Conn) {
	if c.isTls {
		return c.tlsConn
	}
	return c.net.Conn
}

// Layer in the regular conn methods
func (c *Conn) LocalAddr() net.Addr {
	return c.getUnderlyingConn().LocalAddr()
}

func (c *Conn) RemoteAddr() net.Addr {
	return c.getUnderlyingConn().RemoteAddr()
}

func (c *Conn) SetDeadline(t time.Time) {
	c.readDeadline = t
	c.writeDeadline = t
	return c.getUnderlyingConn().SetDeadline(t)
}

func (c *Conn) SetReadDeadline(t time.Time) error {
	c.readDeadline = t
	return c.getUnderlyingConn().SetReadDeadline(t)
}

func (c *Conn) SetWriteDeadline(t time.Time) error {
	c.writeDeadline = deadline
	return c.getUnderlyingConn().SetWriteDeadline(t)
}

// Delegate here, but record all the things
func (c *Conn) Write(b []byte) (int, error) {
	n, err := c.getUnderlyingConn().Write(b)
	ws := writeState{toSend: b, err: err}
	operations = append(operations, []ConnectionState{ws})
	return n, err
}

func (c *Conn) Read(b []byte) (int, error) {
	n, err := c.getUnderlyingConn().Read(b)
	rs := readState{response: b[0:n], err: err}
	operations = append(operations, []ConnectionState{rs})
	return n, err
}

// Extra method - Do a TLS Handshake and record progress
func (c *Conn) TlsHandshake() error {
	if isTls {
		return fmt.Errorf(
			"Attempted repeat handshake with remote host %s",
			c.RemoteAddr().String())
	}
	tlsConfig := new(ztls.Config)
	tlsConfig.InsecureSkipVerify = true
	tlsConfig.MinVersion = ztls.VersionSSL30
	c.tlsConn = ztls.Client(nconn, tlsConfig)
	c.tlsConn.SetReadDeadline(c.readDeadline)
	c.tlsConn.SetWriteDeadline(c.writeDeadline)
	c.isTls = true
	err := tlsConn.Handshake()
	return err
}

// Do a STARTTLS handshake
func (c *Conn) StarttlsHandshake() error {
	// Don't doublehandshake
	if isTls {
		return fmt.Errorf(
			"Attempt STARTTLS after TLS handshake with remote host %s",
			c.RemoteAddr().String())
	}
	// Send the STARTTLS message
	starttls := []byte("STARTTLS\r\n");
	ss := starttlsState{}
 	_, err := conn.Write(starttls);
	// Read the response on a successful send
	if err == nil {
		var n int
		buf := make([]byte, 256)
		n, err = conn.Read(buf)
		ss.response = buf[0:n]
	}
	// No matter what happened, record the state
	ss.err = err
	operations = append(operations, []ConnectionState{ss})
	// Stop if we failed already
	if err != nil {
		return err
	}
	// Successful so far, attempt to do the actual handshake
	return c.TlsHandshake()
}

func (c *Conn) SendHeartbleedProbe(b []byte) (int, error) {
	if !isTls {
		return 0, fmt.Errorf(
			"Must perform TLS handshake before sending Heartbleed probe to %s",
			c.RemoteAddr().String())
	}
	return tlsConn.CheckHeartbleed(b)
}
<|endoftext|>


<commit_before>// Low level performance benchmarking using Go
package main

import (
	"fmt"
	// "testing"
)

func regularArray(maxNum int) {
	var i int = 2
	var j int

	var Data = make([]bool, maxNum+1)

	for i := 2; i <= maxNum; i++ {
		Data[i] = true
		fmt.Println(i)
	}
	i = 2
	for i; i <= maxNum; i++ {
		if Data[i] {
			for j = i + i; j <= maxNum; j += i {
				Data[j] = false
			}
		}
	}
	fmt.Println(Data)
}

func main() {
	fmt.Println("Low level performance using Go")
	// t := testing.Benchmark(regularArray(100000))
	regularArray(100000)
	// fmt.Println(t)
}<commit_msg>working with go<commit_after>// Low level performance benchmarking using Go
package main

import (
	"fmt",
	"testing"
)

func regularArray(maxNum int) {
	var i int = 2
	var j int

	var Data = make([]int,elems)
	// var Data [maxNum + 1]bool;
	for i := 2; i <= maxNum; i++ {
		Data[i] = true
		fmt.Println(i)
	}
	i = 2
	for i; i <= maxNum; i++ {
		if Data[i] {
			for j = i + i; j <= maxNum; j += i {
				Data[j] = false
			}
		}
	}
	fmt.Println(Data)
}

func main() {
	fmt.Println("Low level performance using Go")
	t := testing.Benchmark(regularArray(100000))
	regularArray(100000)
	fmt.Println("Time spent %f", t)
}<|endoftext|>