<commit_before>// Copyright © 2015 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"os"
	"strconv"
	"strings"

	. "github.com/TheThingsNetwork/ttn/core"
	"github.com/TheThingsNetwork/ttn/core/adapters/http"
	"github.com/TheThingsNetwork/ttn/core/adapters/http/broadcast"
	"github.com/TheThingsNetwork/ttn/core/adapters/semtech"
	"github.com/TheThingsNetwork/ttn/core/components"
	"github.com/apex/log"
	"github.com/apex/log/handlers/text"
)

func main() {
	// Parse options
	brokers, tcpPort, udpPort := parseOptions()

	// Create Logging Context
	log.SetHandler(text.New(os.Stdout))
	log.SetLevel(log.DebugLevel)
	ctx := log.WithFields(log.Fields{
		"component": "Router",
	})

	// Instantiate all components
	gtwAdapter, err := semtech.NewAdapter(uint(udpPort), ctx.WithField("tag", "Gateway Adapter"))
	if err != nil {
		panic(err)
	}

	pktAdapter, err := http.NewAdapter(uint(tcpPort), http.JSONPacketParser{}, ctx.WithField("tag", "Broker Adapter"))
	if err != nil {
		panic(err)
	}

	brkAdapter, err := broadcast.NewAdapter(pktAdapter, brokers, ctx.WithField("tag", "Broker Adapter"))
	if err != nil {
		panic(err)
	}

	router, err := components.NewRouter(ctx.WithField("tag", "Router"))
	if err != nil {
		panic(err)
	}

	// Bring the service to life

	// Listen uplink
	go func() {
		for {
			packet, an, err := gtwAdapter.Next()
			if err != nil {
				fmt.Println(err)
				continue
			}
			go func(packet Packet, an AckNacker) {
				if err := router.HandleUp(packet, an, brkAdapter); err != nil {
					fmt.Println(err)
				}
			}(packet, an)
		}
	}()

	// Listen broker registrations
	go func() {
		for {
			reg, an, err := brkAdapter.NextRegistration()
			if err != nil {
				fmt.Println(err)
				continue
			}
			go func(reg Registration, an AckNacker) {
				if err := router.Register(reg, an); err != nil {
					fmt.Println(err)
				}
			}(reg, an)
		}
	}()

	<-make(chan bool)
}

func parseOptions() (brokers []Recipient, tcpPort uint64, udpPort uint64) {
	var brokersFlag string
	var udpPortFlag string
	var tcpPortFlag string
	flag.StringVar(&brokersFlag, "brokers", "", `Broker addresses to which broadcast packets.
 	For instance: 10.10.3.34:8080,thethingsnetwork.broker.com:3000
 	`)
	flag.StringVar(&udpPortFlag, "udp-port", "", "UDP port on which the router should listen to.")
	flag.StringVar(&tcpPortFlag, "tcp-port", "", "TCP port on which the router should listen to.")
	flag.Parse()

	var err error
	tcpPort, err = strconv.ParseUint(tcpPortFlag, 10, 64)
	if err != nil {
		panic(err)
	}
	udpPort, err = strconv.ParseUint(udpPortFlag, 10, 64)
	if err != nil {
		panic(err)
	}
	if brokersFlag == "" {
		panic("Need to provide at least one broker address")
	}

	brokersStr := strings.Split(brokersFlag, ",")
	for i := range brokersStr {
		brokers = append(brokers, Recipient{
			Address: strings.Trim(brokersStr[i], " "),
			Id:      i,
		})

	}
	return
}
<commit_msg>Add decent CLI interaction to Router<commit_after>// Copyright © 2015 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"os"
	"strconv"
	"strings"

	. "github.com/TheThingsNetwork/ttn/core"
	"github.com/TheThingsNetwork/ttn/core/adapters/http"
	"github.com/TheThingsNetwork/ttn/core/adapters/http/broadcast"
	"github.com/TheThingsNetwork/ttn/core/adapters/semtech"
	"github.com/TheThingsNetwork/ttn/core/components"
	"github.com/apex/log"
	"github.com/apex/log/handlers/text"
)

func main() {
	// Create Logging Context
	log.SetHandler(text.New(os.Stdout))
	log.SetLevel(log.DebugLevel)
	ctx := log.WithFields(log.Fields{
		"component": "Router",
	})

	// Parse options
	brokers, tcpPort, udpPort := parseOptions()

	// Instantiate all components
	gtwAdapter, err := semtech.NewAdapter(uint(udpPort), ctx.WithField("tag", "Gateway Adapter"))
	if err != nil {
		ctx.WithError(err).Fatal("Could not start Gateway Adapter")
	}

	pktAdapter, err := http.NewAdapter(uint(tcpPort), http.JSONPacketParser{}, ctx.WithField("tag", "Broker Adapter"))
	if err != nil {
		ctx.WithError(err).Fatal("Could not start Broker Adapter")
	}

	brkAdapter, err := broadcast.NewAdapter(pktAdapter, brokers, ctx.WithField("tag", "Broker Adapter"))
	if err != nil {
		ctx.WithError(err).Fatal("Could not start Broker Adapter")
	}

	router, err := components.NewRouter(ctx.WithField("tag", "Router"))
	if err != nil {
		ctx.WithError(err).Fatal("Could not start Router")
	}

	// Bring the service to life

	// Listen uplink
	go func() {
		for {
			packet, an, err := gtwAdapter.Next()
			if err != nil {
				fmt.Println(err)
				continue
			}
			go func(packet Packet, an AckNacker) {
				if err := router.HandleUp(packet, an, brkAdapter); err != nil {
					fmt.Println(err)
				}
			}(packet, an)
		}
	}()

	// Listen broker registrations
	go func() {
		for {
			reg, an, err := brkAdapter.NextRegistration()
			if err != nil {
				fmt.Println(err)
				continue
			}
			go func(reg Registration, an AckNacker) {
				if err := router.Register(reg, an); err != nil {
					fmt.Println(err)
				}
			}(reg, an)
		}
	}()

	<-make(chan bool)
}

func parseOptions() (brokers []Recipient, tcpPort uint64, udpPort uint64) {
	var brokersFlag string
	var udpPortFlag string
	var tcpPortFlag string

	flags := flag.NewFlagSet(os.Args[0], flag.ExitOnError)

	flags.StringVar(&brokersFlag, "brokers", "", `Broker addresses to which broadcast packets.
 	For instance: 10.10.3.34:8080,thethingsnetwork.broker.com:3000`)
	flags.StringVar(&udpPortFlag, "udp-port", "", "UDP port on which the router should listen to.")
	flags.StringVar(&tcpPortFlag, "tcp-port", "", "TCP port on which the router should listen to.")

	flags.Parse(os.Args[1:])

	var err error

	if tcpPortFlag == "" {
		log.Fatal("No TCP listen port supplied using the -tcp-port flag")
	}
	tcpPort, err = strconv.ParseUint(tcpPortFlag, 10, 64)
	if err != nil {
		log.Fatal("Could not parse the value for -tcp-port")
	}

	if udpPortFlag == "" {
		log.Fatal("No UDP listen port supplied using the -udp-port flag.")
	}
	udpPort, err = strconv.ParseUint(udpPortFlag, 10, 64)
	if err != nil {
		log.Fatal("Could not parse the value for -udp-port")
	}

	if brokersFlag == "" {
		log.Fatal("No broker address is supplied using -brokers flag.")
	}
	brokersStr := strings.Split(brokersFlag, ",")
	for i := range brokersStr {
		brokers = append(brokers, Recipient{
			Address: strings.Trim(brokersStr[i], " "),
			Id:      i,
		})

	}
	return
}
<|endoftext|>


<commit_before>package convert

import (
	"bytes"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"os/exec"
	"syscall"

	"golang.org/x/sync/errgroup"
)

// Process starts a mandoc process to convert manpages to HTML.
type Process struct {
	mandocConn    *net.UnixConn
	mandocProcess *os.Process
	stopWait      chan bool
}

func NewProcess() (*Process, error) {
	p := &Process{}
	return p, p.initMandoc()
}

func (p *Process) Kill() error {
	if p.mandocProcess == nil {
		return nil
	}
	p.stopWait <- true
	return p.mandocProcess.Kill()
}

func (p *Process) initMandoc() error {
	// TODO: get mandoc version, error if mandoc is not installed

	// TODO: remove once mandoc patch landed upstream
	return nil

	l, err := net.ListenUnix("unix", &net.UnixAddr{Net: "unix"})
	if err != nil {
		return err
	}
	f, err := l.File()
	if err != nil {
		return err
	}

	cmd := exec.Command("mandoc", "-Thtml", "-Ofragment", "-u", "/invalid")
	cmd.ExtraFiles = []*os.File{f}
	cmd.Env = []string{"MANDOC_UNIX_SOCKFD=3"} // go dup2()s each file in ExtraFiles
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Start(); err != nil {
		return err
	}
	p.stopWait = make(chan bool)
	go func() {
		wait := make(chan error, 1)
		go func() {
			wait <- cmd.Wait()
		}()
		select {
		case <-p.stopWait:
			return
		case err := <-wait:
			log.Fatalf("mandoc unexpectedly exited: %v", err)
		}
	}()

	p.mandocProcess = cmd.Process

	conn, err := net.DialUnix("unix", nil, l.Addr().(*net.UnixAddr))
	if err != nil {
		return err
	}

	p.mandocConn = conn
	return nil
}

func (p *Process) mandoc(r io.Reader) (stdout string, stderr string, err error) {
	if p.mandocConn != nil {
		return p.mandocUnix(r)
	} else {
		return p.mandocFork(r)
	}
}

func (p *Process) mandocFork(r io.Reader) (stdout string, stderr string, err error) {
	var stdoutb, stderrb bytes.Buffer
	cmd := exec.Command("mandoc", "-Ofragment", "-Thtml")
	cmd.Stdin = r
	cmd.Stdout = &stdoutb
	cmd.Stderr = &stderrb
	if err := cmd.Run(); err != nil {
		return "", "", err
	}
	return stdoutb.String(), stderrb.String(), nil
}

func (p *Process) mandocUnix(r io.Reader) (stdout string, stderr string, err error) {
	manr, manw, err := os.Pipe()
	if err != nil {
		return "", "", err
	}
	defer manr.Close()
	defer manw.Close()

	outr, outw, err := os.Pipe()
	if err != nil {
		return "", "", err
	}
	defer outr.Close()
	defer outw.Close()

	errr, errw, err := os.Pipe()
	if err != nil {
		return "", "", err
	}
	defer errr.Close()
	defer errw.Close()

	scm := syscall.UnixRights(int(manr.Fd()), int(outw.Fd()), int(errw.Fd()))
	if _, _, err := p.mandocConn.WriteMsgUnix(nil, scm, nil); err != nil {
		return "", "", err
	}
	manr.Close()
	outw.Close()
	errw.Close()

	if _, err := io.Copy(manw, r); err != nil {
		return "", "", err
	}
	if err := manw.Close(); err != nil {
		return "", "", err
	}
	var eg errgroup.Group
	var stdoutb, stderrb []byte

	eg.Go(func() error {
		var err error
		stdoutb, err = ioutil.ReadAll(outr)
		return err
	})

	eg.Go(func() error {
		var err error
		stderrb, err = ioutil.ReadAll(errr)
		return err
	})

	return string(stdoutb), string(stderrb), eg.Wait()
}
<commit_msg>mandoc: asynchronously write input<commit_after>package convert

import (
	"bytes"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"os/exec"
	"syscall"

	"golang.org/x/sync/errgroup"
)

// Process starts a mandoc process to convert manpages to HTML.
type Process struct {
	mandocConn    *net.UnixConn
	mandocProcess *os.Process
	stopWait      chan bool
}

func NewProcess() (*Process, error) {
	p := &Process{}
	return p, p.initMandoc()
}

func (p *Process) Kill() error {
	if p.mandocProcess == nil {
		return nil
	}
	p.stopWait <- true
	return p.mandocProcess.Kill()
}

func (p *Process) initMandoc() error {
	// TODO: get mandoc version, error if mandoc is not installed

	// TODO: remove once mandoc patch landed upstream
	return nil

	l, err := net.ListenUnix("unix", &net.UnixAddr{Net: "unix"})
	if err != nil {
		return err
	}
	f, err := l.File()
	if err != nil {
		return err
	}

	cmd := exec.Command("mandoc", "-Thtml", "-Ofragment", "-u", "/invalid")
	cmd.ExtraFiles = []*os.File{f}
	cmd.Env = []string{"MANDOC_UNIX_SOCKFD=3"} // go dup2()s each file in ExtraFiles
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Start(); err != nil {
		return err
	}
	p.stopWait = make(chan bool)
	go func() {
		wait := make(chan error, 1)
		go func() {
			wait <- cmd.Wait()
		}()
		select {
		case <-p.stopWait:
			return
		case err := <-wait:
			log.Fatalf("mandoc unexpectedly exited: %v", err)
		}
	}()

	p.mandocProcess = cmd.Process

	conn, err := net.DialUnix("unix", nil, l.Addr().(*net.UnixAddr))
	if err != nil {
		return err
	}

	p.mandocConn = conn
	return nil
}

func (p *Process) mandoc(r io.Reader) (stdout string, stderr string, err error) {
	if p.mandocConn != nil {
		return p.mandocUnix(r)
	} else {
		return p.mandocFork(r)
	}
}

func (p *Process) mandocFork(r io.Reader) (stdout string, stderr string, err error) {
	var stdoutb, stderrb bytes.Buffer
	cmd := exec.Command("mandoc", "-Ofragment", "-Thtml")
	cmd.Stdin = r
	cmd.Stdout = &stdoutb
	cmd.Stderr = &stderrb
	if err := cmd.Run(); err != nil {
		return "", "", err
	}
	return stdoutb.String(), stderrb.String(), nil
}

func (p *Process) mandocUnix(r io.Reader) (stdout string, stderr string, err error) {
	manr, manw, err := os.Pipe()
	if err != nil {
		return "", "", err
	}
	defer manr.Close()
	defer manw.Close()

	outr, outw, err := os.Pipe()
	if err != nil {
		return "", "", err
	}
	defer outr.Close()
	defer outw.Close()

	errr, errw, err := os.Pipe()
	if err != nil {
		return "", "", err
	}
	defer errr.Close()
	defer errw.Close()

	scm := syscall.UnixRights(int(manr.Fd()), int(outw.Fd()), int(errw.Fd()))
	if _, _, err := p.mandocConn.WriteMsgUnix(nil, scm, nil); err != nil {
		return "", "", err
	}
	manr.Close()
	outw.Close()
	errw.Close()

	var eg errgroup.Group

	eg.Go(func() error {
		if _, err := io.Copy(manw, r); err != nil {
			return err
		}
		return manw.Close()
	})

	var stdoutb, stderrb []byte

	eg.Go(func() error {
		var err error
		stdoutb, err = ioutil.ReadAll(outr)
		return err
	})

	eg.Go(func() error {
		var err error
		stderrb, err = ioutil.ReadAll(errr)
		return err
	})

	return string(stdoutb), string(stderrb), eg.Wait()
}
<|endoftext|>


<commit_before>/*

	patchtree is a simple library that knows how to interpret a folder
	structure of jd diffs and apply them on top of a base.

		test/
		  base.json
		  after_move/
		    modification.patch
		  sanitization/
		    modification.patch
		    hidden/
		      modification.patch
		    nonempty/
		      modification.patch

	Given a path relative ot the current binary, it walks backwards up the
	folder, ensuring that a modification.patch exists in each directory until
	it finds a base.json. Then it applies forward all of the
	modification.patches to give you the final composed json blob result.

*/
package patchtree

import (
	"errors"
	jd "github.com/jkomoros/jd/lib"
	"os"
	"path/filepath"
	"strings"
)

const BASE_JSON = "base.json"
const PATCH = "modification.patch"

//JSON returns the patched json blob impplied by that directory structure or
//an error if something doesn't work. See the package doc for more.
func JSON(path string) ([]byte, error) {

	if strings.HasSuffix(path, "/") {
		path = strings.TrimSuffix(path, "/")
	}

	result, err := processDirectory(path)

	if err != nil {
		return nil, err
	}

	return []byte(result.Json()), nil

}

//MustJSON is the same as JSON, but if it would have returned an error, panics istead.
func MustJSON(path string) []byte {
	result, err := JSON(path)
	if err != nil {
		panic(err)
	}
	return result
}

//ExpandTree expands all of the nodes in the patchtree, applying the chains of
//modification and created an node.expanded.json in each node. Used in a
//workflow to modify base.json: run this commeand, then modify base.json, then
//run ContractTree.
func ExpandTree(rootPath string) error {
	return errors.New("Not yet implemented")
}

//ContractTree goes through each node in the parse tree and where it finds a
//node.expanded,json, re-derives and overwrites the "modification.patch". Used
//as part of a workflow to modify base.json: run ExpandTree, modify base.json,
//then ContractTree.
func ContractTree(rootPath string) error {
	return errors.New("Not yet implemented")
}

func processDirectory(path string) (jd.JsonNode, error) {

	//If no more path pieces error
	if path == "" || path == "/" || path == "./" {
		return nil, errors.New("Didn't find a base.json anywhere in the given directory structure")
	}

	//TODO: check if the directory exists...

	baseJsonPath := filepath.Clean(path + "/" + BASE_JSON)

	if _, err := os.Stat(baseJsonPath); err == nil {
		//Found the directory with base.json!
		node, err := jd.ReadJsonFile(baseJsonPath)
		if err != nil {
			return nil, errors.New(path + " had error reading base.json: " + err.Error())
		}
		return node, nil
	}

	modificationPatchPath := filepath.Clean(path + "/" + PATCH)

	if _, err := os.Stat(modificationPatchPath); err == nil {

		//Recurse, with the sub-directory.
		baseJson, err := processDirectory(filepath.Dir(path))

		if err != nil {
			return nil, err
		}

		diff, err := jd.ReadDiffFile(modificationPatchPath)

		if err != nil {
			return nil, errors.New("Error reading diff file at " + modificationPatchPath + ": " + err.Error())
		}

		composed, err := baseJson.Patch(diff)

		if err != nil {
			return nil, errors.New(path + " had error diffing " + err.Error())
		}

		return composed, nil
	}

	//Path had neither base.json or modification.patch, which is an error
	return nil, errors.New("In " + path + " didn't have either " + BASE_JSON + " or " + PATCH)

}
<commit_msg>started implementing patchtree.ExpandTree(). Part of #607.<commit_after>/*

	patchtree is a simple library that knows how to interpret a folder
	structure of jd diffs and apply them on top of a base.

		test/
		  base.json
		  after_move/
		    modification.patch
		  sanitization/
		    modification.patch
		    hidden/
		      modification.patch
		    nonempty/
		      modification.patch

	Given a path relative ot the current binary, it walks backwards up the
	folder, ensuring that a modification.patch exists in each directory until
	it finds a base.json. Then it applies forward all of the
	modification.patches to give you the final composed json blob result.

*/
package patchtree

import (
	"errors"
	jd "github.com/jkomoros/jd/lib"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

const BASE_JSON = "base.json"
const PATCH = "modification.patch"

//JSON returns the patched json blob impplied by that directory structure or
//an error if something doesn't work. See the package doc for more.
func JSON(path string) ([]byte, error) {

	if strings.HasSuffix(path, "/") {
		path = strings.TrimSuffix(path, "/")
	}

	result, err := processDirectory(path)

	if err != nil {
		return nil, err
	}

	return []byte(result.Json()), nil

}

//MustJSON is the same as JSON, but if it would have returned an error, panics istead.
func MustJSON(path string) []byte {
	result, err := JSON(path)
	if err != nil {
		panic(err)
	}
	return result
}

//ExpandTree expands all of the nodes in the patchtree, applying the chains of
//modification and created an node.expanded.json in each node. Used in a
//workflow to modify base.json: run this commeand, then modify base.json, then
//run ContractTree.
func ExpandTree(rootPath string) error {

	baseJsonPath := filepath.Clean(rootPath + "/" + BASE_JSON)

	if _, err := os.Stat(baseJsonPath); os.IsNotExist(err) {
		return errors.New("Base json file did not exist: " + err.Error())
	}

	node, err := jd.ReadJsonFile(baseJsonPath)

	if err != nil {
		return errors.New("Couldn't parse base json file: " + err.Error())
	}

	files, err := ioutil.ReadDir(rootPath)

	if err != nil {
		return errors.New("Couldn't read base directory: " + err.Error())
	}

	for _, file := range files {
		if !file.IsDir() {
			continue
		}
		if err := expandTreeProcessDirectory(filepath.Clean(rootPath+"/"+file.Name()), node); err != nil {
			return errors.New("Couldn't process file: " + err.Error())
		}
	}

	return nil

}

func expandTreeProcessDirectory(directory string, node jd.JsonNode) error {
	return errors.New("Subdirectories not yet implemented")
}

//ContractTree goes through each node in the parse tree and where it finds a
//node.expanded,json, re-derives and overwrites the "modification.patch". Used
//as part of a workflow to modify base.json: run ExpandTree, modify base.json,
//then ContractTree.
func ContractTree(rootPath string) error {
	return errors.New("Not yet implemented")
}

func processDirectory(path string) (jd.JsonNode, error) {

	//If no more path pieces error
	if path == "" || path == "/" || path == "./" {
		return nil, errors.New("Didn't find a base.json anywhere in the given directory structure")
	}

	//TODO: check if the directory exists...

	baseJsonPath := filepath.Clean(path + "/" + BASE_JSON)

	if _, err := os.Stat(baseJsonPath); err == nil {
		//Found the directory with base.json!
		node, err := jd.ReadJsonFile(baseJsonPath)
		if err != nil {
			return nil, errors.New(path + " had error reading base.json: " + err.Error())
		}
		return node, nil
	}

	modificationPatchPath := filepath.Clean(path + "/" + PATCH)

	if _, err := os.Stat(modificationPatchPath); err == nil {

		//Recurse, with the sub-directory.
		baseJson, err := processDirectory(filepath.Dir(path))

		if err != nil {
			return nil, err
		}

		diff, err := jd.ReadDiffFile(modificationPatchPath)

		if err != nil {
			return nil, errors.New("Error reading diff file at " + modificationPatchPath + ": " + err.Error())
		}

		composed, err := baseJson.Patch(diff)

		if err != nil {
			return nil, errors.New(path + " had error diffing " + err.Error())
		}

		return composed, nil
	}

	//Path had neither base.json or modification.patch, which is an error
	return nil, errors.New("In " + path + " didn't have either " + BASE_JSON + " or " + PATCH)

}
<|endoftext|>


<commit_before>// Copyright 2015 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 save

import (
	"errors"

	"github.com/jacobsa/comeback/internal/state"
	"github.com/jacobsa/timeutil"

	"golang.org/x/net/context"
)

// Attempt to fill in fsNode.Scores fields for files arriving on nodesIn based
// on the contents of a state.ScoreMap. Update the score map for nodes where
// this wasn't successful based on the results arriving on downstreamResults.
func consultScoreMapForNodes(
	ctx context.Context,
	scoreMap state.ScoreMap,
	clock timeutil.Clock,
	nodesIn <-chan *fsNode,
	nodesOut chan<- *fsNode,
	downstreamResults <-chan *fsNode) (err error) {
	// TODO(jacobsa): Make sure to consult score_map_saver.go. We don't need the
	// bit that talks to the blob store (added in abd1800) if we kill blob store
	// internal asynchronicity, though.
	err = errors.New("TODO")
	return
}
<commit_msg>Split consultScoreMapForNodes in half.<commit_after>// Copyright 2015 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 save

import (
	"errors"

	"github.com/jacobsa/comeback/internal/state"
	"github.com/jacobsa/timeutil"

	"golang.org/x/net/context"
)

// Attempt to fill in fsNode.Scores fields for files arriving on nodesIn based
// on the contents of a state.ScoreMap.
func consultScoreMap(
	ctx context.Context,
	scoreMap state.ScoreMap,
	clock timeutil.Clock,
	nodesIn <-chan *fsNode,
	nodesOut chan<- *fsNode) (err error) {
	// TODO(jacobsa): Make sure to consult score_map_saver.go. We don't need the
	// bit that talks to the blob store (added in abd1800) if we kill blob store
	// internal asynchronicity, though.
	err = errors.New("TODO")
	return
}

// For each incoming file node n that consultScoreMap did not mark as having
// hit in its score map, update the score map based on n.Scores.
func updateScoreMap(
	ctx context.Context,
	scoreMap state.ScoreMap,
	nodes <-chan *fsNode) (err error) {
	// TODO(jacobsa): Make sure to consult score_map_saver.go.
	err = errors.New("TODO")
	return
}
<|endoftext|>


<commit_before>// Copyright 2012 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package repository

const (
	AddKey = iota
	RemoveKey
	AddMember
	RemoveMember
	AddGroup
	RemoveGroup
	AddProject
	RemoveProject
	Commit
)

// Change encapsulates a change that will be requested to the gitosis file.
//
// The kind is an integer, but you should not send a magic number. Try sending
// one of the package's constant, and Args represent the args for the kind of
// change. If the change provide any response, it will be sent though the
// response channel (a string channel). Example:
//
//     args := map[string]string{
//         "key":    "my-key",
//         "member": "gopher",
//     }
//     change := Change{Kind: AddKey, Args: args}
//
// The change in the code above says:
//
//     "add the key my-key to the member gopher"
//
// For this kind of change, the key file name will be sent in the channel
// Response.
type Change struct {
	Kind     int
	Args     map[string]string
	Response chan string
}

// Ag is the Agent instance that should be used to send changes to gitosis repository.
//
// Sample of code:
//
//     import "github.com/globocom/tsuru/repository"
//
//     func sendChange() {
//         change := repository.Change{
//             Kind:     repository.AddKey,
//             Args:     map[string]string{"key": "the-key", "member": "gopher"},
//             Response: make(chan string),
//         }
//         repository.Ag.Process(change)
//         resp := <-change.Response
//         // do something with the response
//     }
var Ag *Agent

// RunAgent starts the agent loop, so it keep looking for changes to be
// processed.
func RunAgent() {
	gitosisManager, err := newGitosisManager()
	if err != nil {
		panic(err)
	}
	Ag = newAgent(gitosisManager)
	go Ag.loop()
}

// Agent listens for changes and process them.
type Agent struct {
	changes chan Change
	mngr    manager
}

// newAgent returns an instance of a new Agent.
func newAgent(m manager) *Agent {
	return &Agent{
		changes: make(chan Change),
		mngr:    m,
	}
}

// Process sends a change to the agent queue.
func (a *Agent) Process(change Change) {
	a.changes <- change
}

// loop loops "forever" processing changes that come in the agent queue.
func (a *Agent) loop() {
	for change := range a.changes {
		switch change.Kind {
		case AddKey:
			go func(ch Change) {
				keyfile, _ := a.mngr.buildAndStoreKeyFile(change.Args["member"], change.Args["key"])
				ch.Response <- keyfile
			}(change)
		case RemoveKey:
			go func(ch Change) {
				err := a.mngr.deleteKeyFile(change.Args["key"])
				a.done(ch.Response, err)
			}(change)
		case AddMember:
			go func(ch Change) {
				err := a.mngr.addMember(ch.Args["group"], ch.Args["member"])
				a.done(ch.Response, err)
			}(change)
		case RemoveMember:
			go func(ch Change) {
				err := a.mngr.removeMember(ch.Args["group"], ch.Args["member"])
				a.done(ch.Response, err)
			}(change)
		case AddGroup:
			go func(ch Change) {
				err := a.mngr.addGroup(ch.Args["group"])
				a.done(ch.Response, err)
			}(change)
		case RemoveGroup:
			go func(ch Change) {
				err := a.mngr.removeGroup(ch.Args["group"])
				a.done(ch.Response, err)
			}(change)
		case AddProject:
			go func(ch Change) {
				err := a.mngr.addProject(ch.Args["group"], ch.Args["project"])
				a.done(ch.Response, err)
			}(change)
		case RemoveProject:
			go func(ch Change) {
				err := a.mngr.removeProject(ch.Args["group"], ch.Args["project"])
				a.done(ch.Response, err)
			}(change)
		case Commit:
			go func(ch Change) {
				err := a.mngr.commit(ch.Args["message"])
				a.done(ch.Response, err)
			}(change)
		}
	}
}

func (a *Agent) done(ch chan string, err error) {
	if ch != nil {
		if err != nil {
			ch <- "fail: " + err.Error()
		} else {
			ch <- "success"
		}
	}
}
<commit_msg>repository: fix data race in repository agent<commit_after>// Copyright 2012 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package repository

const (
	AddKey = iota
	RemoveKey
	AddMember
	RemoveMember
	AddGroup
	RemoveGroup
	AddProject
	RemoveProject
	Commit
)

// Change encapsulates a change that will be requested to the gitosis file.
//
// The kind is an integer, but you should not send a magic number. Try sending
// one of the package's constant, and Args represent the args for the kind of
// change. If the change provide any response, it will be sent though the
// response channel (a string channel). Example:
//
//     args := map[string]string{
//         "key":    "my-key",
//         "member": "gopher",
//     }
//     change := Change{Kind: AddKey, Args: args}
//
// The change in the code above says:
//
//     "add the key my-key to the member gopher"
//
// For this kind of change, the key file name will be sent in the channel
// Response.
type Change struct {
	Kind     int
	Args     map[string]string
	Response chan string
}

// Ag is the Agent instance that should be used to send changes to gitosis repository.
//
// Sample of code:
//
//     import "github.com/globocom/tsuru/repository"
//
//     func sendChange() {
//         change := repository.Change{
//             Kind:     repository.AddKey,
//             Args:     map[string]string{"key": "the-key", "member": "gopher"},
//             Response: make(chan string),
//         }
//         repository.Ag.Process(change)
//         resp := <-change.Response
//         // do something with the response
//     }
var Ag *Agent

// RunAgent starts the agent loop, so it keep looking for changes to be
// processed.
func RunAgent() {
	gitosisManager, err := newGitosisManager()
	if err != nil {
		panic(err)
	}
	Ag = newAgent(gitosisManager)
	go Ag.loop()
}

// Agent listens for changes and process them.
type Agent struct {
	changes chan Change
	mngr    manager
}

// newAgent returns an instance of a new Agent.
func newAgent(m manager) *Agent {
	return &Agent{
		changes: make(chan Change),
		mngr:    m,
	}
}

// Process sends a change to the agent queue.
func (a *Agent) Process(change Change) {
	a.changes <- change
}

// loop loops "forever" processing changes that come in the agent queue.
func (a *Agent) loop() {
	for change := range a.changes {
		switch change.Kind {
		case AddKey:
			go func(ch Change) {
				keyfile, _ := a.mngr.buildAndStoreKeyFile(change.Args["member"], change.Args["key"])
				ch.Response <- keyfile
			}(change)
		case RemoveKey:
			go func(ch Change) {
				err := a.mngr.deleteKeyFile(ch.Args["key"])
				a.done(ch.Response, err)
			}(change)
		case AddMember:
			go func(ch Change) {
				err := a.mngr.addMember(ch.Args["group"], ch.Args["member"])
				a.done(ch.Response, err)
			}(change)
		case RemoveMember:
			go func(ch Change) {
				err := a.mngr.removeMember(ch.Args["group"], ch.Args["member"])
				a.done(ch.Response, err)
			}(change)
		case AddGroup:
			go func(ch Change) {
				err := a.mngr.addGroup(ch.Args["group"])
				a.done(ch.Response, err)
			}(change)
		case RemoveGroup:
			go func(ch Change) {
				err := a.mngr.removeGroup(ch.Args["group"])
				a.done(ch.Response, err)
			}(change)
		case AddProject:
			go func(ch Change) {
				err := a.mngr.addProject(ch.Args["group"], ch.Args["project"])
				a.done(ch.Response, err)
			}(change)
		case RemoveProject:
			go func(ch Change) {
				err := a.mngr.removeProject(ch.Args["group"], ch.Args["project"])
				a.done(ch.Response, err)
			}(change)
		case Commit:
			go func(ch Change) {
				err := a.mngr.commit(ch.Args["message"])
				a.done(ch.Response, err)
			}(change)
		}
	}
}

func (a *Agent) done(ch chan string, err error) {
	if ch != nil {
		if err != nil {
			ch <- "fail: " + err.Error()
		} else {
			ch <- "success"
		}
	}
}
<|endoftext|>


<commit_before>package qmp

import (
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/pkg/errors"

	"github.com/lxc/lxd/lxd/revert"
	"github.com/lxc/lxd/shared"
)

// Status returns the current VM status.
func (m *Monitor) Status() (string, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			Status string `json:"status"`
		} `json:"return"`
	}

	// Query the status.
	err := m.run("query-status", nil, &resp)
	if err != nil {
		return "", err
	}

	return resp.Return.Status, nil
}

// Console fetches the File for a particular console.
func (m *Monitor) Console(target string) (*os.File, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			Label    string `json:"label"`
			Filename string `json:"filename"`
		} `json:"return"`
	}

	// Query the consoles.
	err := m.run("query-chardev", nil, &resp)
	if err != nil {
		return nil, err
	}

	// Look for the requested console.
	for _, v := range resp.Return {
		if v.Label == target {
			ptyPath := strings.TrimPrefix(v.Filename, "pty:")

			if !shared.PathExists(ptyPath) {
				continue
			}

			// Open the PTS device
			console, err := os.OpenFile(ptyPath, os.O_RDWR, 0600)
			if err != nil {
				return nil, err
			}

			return console, nil
		}
	}

	return nil, ErrMonitorBadConsole
}

// SendFile adds a new file descriptor to the QMP fd table associated to name.
func (m *Monitor) SendFile(name string, file *os.File) error {
	// Check if disconnected
	if m.disconnected {
		return ErrMonitorDisconnect
	}

	// Query the status.
	_, err := m.qmp.RunWithFile([]byte(fmt.Sprintf("{'execute': 'getfd', 'arguments': {'fdname': '%s'}}", name)), file)
	if err != nil {
		// Confirm the daemon didn't die.
		errPing := m.ping()
		if errPing != nil {
			return errPing
		}

		return err
	}

	return nil
}

// Migrate starts a migration stream.
func (m *Monitor) Migrate(uri string) error {
	// Query the status.
	args := map[string]string{"uri": uri}
	err := m.run("migrate", args, nil)
	if err != nil {
		return err
	}

	// Wait until it completes or fails.
	for {
		time.Sleep(1 * time.Second)

		// Prepare the response.
		var resp struct {
			Return struct {
				Status string `json:"status"`
			} `json:"return"`
		}

		err := m.run("query-migrate", nil, &resp)
		if err != nil {
			return err
		}

		if resp.Return.Status == "failed" {
			return fmt.Errorf("Migration call failed")
		}

		if resp.Return.Status == "completed" {
			break
		}
	}

	return nil
}

// MigrateIncoming starts the receiver of a migration stream.
func (m *Monitor) MigrateIncoming(uri string) error {
	// Query the status.
	args := map[string]string{"uri": uri}
	err := m.run("migrate-incoming", args, nil)
	if err != nil {
		return err
	}

	// Wait until it completes or fails.
	for {
		time.Sleep(1 * time.Second)

		// Preapre the response.
		var resp struct {
			Return struct {
				Status string `json:"status"`
			} `json:"return"`
		}

		err := m.run("query-migrate", nil, &resp)
		if err != nil {
			return err
		}

		if resp.Return.Status == "failed" {
			return fmt.Errorf("Migration call failed")
		}

		if resp.Return.Status == "completed" {
			break
		}
	}

	return nil
}

// Powerdown tells the VM to gracefully shutdown.
func (m *Monitor) Powerdown() error {
	return m.run("system_powerdown", nil, nil)
}

// Start tells QEMU to start the emulation.
func (m *Monitor) Start() error {
	return m.run("cont", nil, nil)
}

// Pause tells QEMU to temporarily stop the emulation.
func (m *Monitor) Pause() error {
	return m.run("stop", nil, nil)
}

// Quit tells QEMU to exit immediately.
func (m *Monitor) Quit() error {
	return m.run("quit", nil, nil)
}

// GetCPUs fetches the vCPU information for pinning.
func (m *Monitor) GetCPUs() ([]int, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			CPU int `json:"cpu-index"`
			PID int `json:"thread-id"`
		} `json:"return"`
	}

	// Query the consoles.
	err := m.run("query-cpus-fast", nil, &resp)
	if err != nil {
		return nil, err
	}

	// Make a slice of PIDs.
	pids := []int{}
	for _, cpu := range resp.Return {
		pids = append(pids, cpu.PID)
	}

	return pids, nil
}

// GetMemorySizeBytes returns the current size of the base memory in bytes.
func (m *Monitor) GetMemorySizeBytes() (int64, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			BaseMemory int64 `json:"base-memory"`
		} `json:"return"`
	}

	err := m.run("query-memory-size-summary", nil, &resp)
	if err != nil {
		return -1, err
	}

	return resp.Return.BaseMemory, nil
}

// GetMemoryBalloonSizeBytes returns effective size of the memory in bytes (considering the current balloon size).
func (m *Monitor) GetMemoryBalloonSizeBytes() (int64, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			Actual int64 `json:"actual"`
		} `json:"return"`
	}

	err := m.run("query-balloon", nil, &resp)
	if err != nil {
		return -1, err
	}

	return resp.Return.Actual, nil
}

// SetMemoryBalloonSizeBytes sets the size of the memory in bytes (which will resize the balloon as needed).
func (m *Monitor) SetMemoryBalloonSizeBytes(sizeBytes int64) error {
	args := map[string]int64{"value": sizeBytes}
	return m.run("balloon", args, nil)
}

// AddNIC adds a NIC device.
func (m *Monitor) AddNIC(netDev map[string]interface{}, device map[string]string) error {
	revert := revert.New()
	defer revert.Fail()

	if netDev != nil {
		err := m.run("netdev_add", netDev, nil)
		if err != nil {
			return errors.Wrapf(err, "Failed adding NIC netdev")
		}

		revert.Add(func() {
			netDevDel := map[string]interface{}{
				"id": netDev["id"],
			}

			err = m.run("netdev_del", netDevDel, nil)
			if err != nil {
				return
			}
		})
	}

	if device != nil {
		err := m.run("device_add", device, nil)
		if err != nil {
			return errors.Wrapf(err, "Failed adding NIC device")
		}
	}

	revert.Success()
	return nil
}

// RemoveNIC removes a NIC device.
func (m *Monitor) RemoveNIC(netDevID string, deviceID string) error {
	if deviceID != "" {
		deviceID := map[string]string{
			"id": deviceID,
		}

		err := m.run("device_del", deviceID, nil)
		if err != nil {
			// If the device has already been removed then all good.
			if err != nil && !strings.Contains(err.Error(), "not found") {
				return errors.Wrapf(err, "Failed removing NIC device")
			}
		}
	}

	if netDevID != "" {
		netDevID := map[string]string{
			"id": netDevID,
		}

		err := m.run("netdev_del", netDevID, nil)

		// Not all NICs need a netdev, so if its missing, its not a problem.
		if err != nil && !strings.Contains(err.Error(), "not found") {
			return errors.Wrapf(err, "Failed removing NIC netdev")
		}
	}

	return nil
}

// Reset VM.
func (m *Monitor) Reset() error {
	err := m.run("system_reset", nil, nil)
	if err != nil {
		return errors.Wrapf(err, "Failed resetting")
	}

	return nil
}

// PCIClassInfo info about a device's class.
type PCIClassInfo struct {
	Class       int    `json:"class"`
	Description string `json:"desc"`
}

// PCIDevice represents a PCI device.
type PCIDevice struct {
	DevID    string       `json:"qdev_id"`
	Bus      int          `json:"bus"`
	Slot     int          `json:"slot"`
	Function int          `json:"function"`
	Devices  []PCIDevice  `json:"devices"`
	Class    PCIClassInfo `json:"class_info"`
	Bridge   PCIBridge    `json:"pci_bridge"`
}

// PCIBridge represents a PCI bridge.
type PCIBridge struct {
	Devices []PCIDevice `json:"devices"`
}

// QueryPCI returns info about PCI devices.
func (m *Monitor) QueryPCI() ([]PCIDevice, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			Devices []PCIDevice `json:"devices"`
		} `json:"return"`
	}

	err := m.run("query-pci", nil, &resp)
	if err != nil {
		return nil, errors.Wrapf(err, "Failed querying PCI devices")
	}

	if len(resp.Return) > 0 {
		return resp.Return[0].Devices, nil
	}

	return nil, nil
}
<commit_msg>lxd/instance/drivers/qmp: Extend commands<commit_after>package qmp

import (
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/pkg/errors"

	"github.com/lxc/lxd/lxd/revert"
	"github.com/lxc/lxd/shared"
)

// Status returns the current VM status.
func (m *Monitor) Status() (string, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			Status string `json:"status"`
		} `json:"return"`
	}

	// Query the status.
	err := m.run("query-status", nil, &resp)
	if err != nil {
		return "", err
	}

	return resp.Return.Status, nil
}

// Console fetches the File for a particular console.
func (m *Monitor) Console(target string) (*os.File, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			Label    string `json:"label"`
			Filename string `json:"filename"`
		} `json:"return"`
	}

	// Query the consoles.
	err := m.run("query-chardev", nil, &resp)
	if err != nil {
		return nil, err
	}

	// Look for the requested console.
	for _, v := range resp.Return {
		if v.Label == target {
			ptyPath := strings.TrimPrefix(v.Filename, "pty:")

			if !shared.PathExists(ptyPath) {
				continue
			}

			// Open the PTS device
			console, err := os.OpenFile(ptyPath, os.O_RDWR, 0600)
			if err != nil {
				return nil, err
			}

			return console, nil
		}
	}

	return nil, ErrMonitorBadConsole
}

// SendFile adds a new file descriptor to the QMP fd table associated to name.
func (m *Monitor) SendFile(name string, file *os.File) error {
	// Check if disconnected
	if m.disconnected {
		return ErrMonitorDisconnect
	}

	// Query the status.
	_, err := m.qmp.RunWithFile([]byte(fmt.Sprintf("{'execute': 'getfd', 'arguments': {'fdname': '%s'}}", name)), file)
	if err != nil {
		// Confirm the daemon didn't die.
		errPing := m.ping()
		if errPing != nil {
			return errPing
		}

		return err
	}

	return nil
}

// Migrate starts a migration stream.
func (m *Monitor) Migrate(uri string) error {
	// Query the status.
	args := map[string]string{"uri": uri}
	err := m.run("migrate", args, nil)
	if err != nil {
		return err
	}

	// Wait until it completes or fails.
	for {
		time.Sleep(1 * time.Second)

		// Prepare the response.
		var resp struct {
			Return struct {
				Status string `json:"status"`
			} `json:"return"`
		}

		err := m.run("query-migrate", nil, &resp)
		if err != nil {
			return err
		}

		if resp.Return.Status == "failed" {
			return fmt.Errorf("Migration call failed")
		}

		if resp.Return.Status == "completed" {
			break
		}
	}

	return nil
}

// MigrateIncoming starts the receiver of a migration stream.
func (m *Monitor) MigrateIncoming(uri string) error {
	// Query the status.
	args := map[string]string{"uri": uri}
	err := m.run("migrate-incoming", args, nil)
	if err != nil {
		return err
	}

	// Wait until it completes or fails.
	for {
		time.Sleep(1 * time.Second)

		// Preapre the response.
		var resp struct {
			Return struct {
				Status string `json:"status"`
			} `json:"return"`
		}

		err := m.run("query-migrate", nil, &resp)
		if err != nil {
			return err
		}

		if resp.Return.Status == "failed" {
			return fmt.Errorf("Migration call failed")
		}

		if resp.Return.Status == "completed" {
			break
		}
	}

	return nil
}

// Powerdown tells the VM to gracefully shutdown.
func (m *Monitor) Powerdown() error {
	return m.run("system_powerdown", nil, nil)
}

// Start tells QEMU to start the emulation.
func (m *Monitor) Start() error {
	return m.run("cont", nil, nil)
}

// Pause tells QEMU to temporarily stop the emulation.
func (m *Monitor) Pause() error {
	return m.run("stop", nil, nil)
}

// Quit tells QEMU to exit immediately.
func (m *Monitor) Quit() error {
	return m.run("quit", nil, nil)
}

// GetCPUs fetches the vCPU information for pinning.
func (m *Monitor) GetCPUs() ([]int, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			CPU int `json:"cpu-index"`
			PID int `json:"thread-id"`
		} `json:"return"`
	}

	// Query the consoles.
	err := m.run("query-cpus-fast", nil, &resp)
	if err != nil {
		return nil, err
	}

	// Make a slice of PIDs.
	pids := []int{}
	for _, cpu := range resp.Return {
		pids = append(pids, cpu.PID)
	}

	return pids, nil
}

// GetMemorySizeBytes returns the current size of the base memory in bytes.
func (m *Monitor) GetMemorySizeBytes() (int64, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			BaseMemory int64 `json:"base-memory"`
		} `json:"return"`
	}

	err := m.run("query-memory-size-summary", nil, &resp)
	if err != nil {
		return -1, err
	}

	return resp.Return.BaseMemory, nil
}

// GetMemoryBalloonSizeBytes returns effective size of the memory in bytes (considering the current balloon size).
func (m *Monitor) GetMemoryBalloonSizeBytes() (int64, error) {
	// Prepare the response.
	var resp struct {
		Return struct {
			Actual int64 `json:"actual"`
		} `json:"return"`
	}

	err := m.run("query-balloon", nil, &resp)
	if err != nil {
		return -1, err
	}

	return resp.Return.Actual, nil
}

// SetMemoryBalloonSizeBytes sets the size of the memory in bytes (which will resize the balloon as needed).
func (m *Monitor) SetMemoryBalloonSizeBytes(sizeBytes int64) error {
	args := map[string]int64{"value": sizeBytes}
	return m.run("balloon", args, nil)
}

// AddNIC adds a NIC device.
func (m *Monitor) AddNIC(netDev map[string]interface{}, device map[string]string) error {
	revert := revert.New()
	defer revert.Fail()

	if netDev != nil {
		err := m.run("netdev_add", netDev, nil)
		if err != nil {
			return errors.Wrapf(err, "Failed adding NIC netdev")
		}

		revert.Add(func() {
			netDevDel := map[string]interface{}{
				"id": netDev["id"],
			}

			err = m.run("netdev_del", netDevDel, nil)
			if err != nil {
				return
			}
		})
	}

	if device != nil {
		err := m.run("device_add", device, nil)
		if err != nil {
			return errors.Wrapf(err, "Failed adding NIC device")
		}
	}

	revert.Success()
	return nil
}

// RemoveNIC removes a NIC device.
func (m *Monitor) RemoveNIC(netDevID string, deviceID string) error {
	if deviceID != "" {
		deviceID := map[string]string{
			"id": deviceID,
		}

		err := m.run("device_del", deviceID, nil)
		if err != nil {
			// If the device has already been removed then all good.
			if err != nil && !strings.Contains(err.Error(), "not found") {
				return errors.Wrapf(err, "Failed removing NIC device")
			}
		}
	}

	if netDevID != "" {
		netDevID := map[string]string{
			"id": netDevID,
		}

		err := m.run("netdev_del", netDevID, nil)

		// Not all NICs need a netdev, so if its missing, its not a problem.
		if err != nil && !strings.Contains(err.Error(), "not found") {
			return errors.Wrapf(err, "Failed removing NIC netdev")
		}
	}

	return nil
}

// Reset VM.
func (m *Monitor) Reset() error {
	err := m.run("system_reset", nil, nil)
	if err != nil {
		return errors.Wrapf(err, "Failed resetting")
	}

	return nil
}

// PCIClassInfo info about a device's class.
type PCIClassInfo struct {
	Class       int    `json:"class"`
	Description string `json:"desc"`
}

// PCIDevice represents a PCI device.
type PCIDevice struct {
	DevID    string       `json:"qdev_id"`
	Bus      int          `json:"bus"`
	Slot     int          `json:"slot"`
	Function int          `json:"function"`
	Devices  []PCIDevice  `json:"devices"`
	Class    PCIClassInfo `json:"class_info"`
	Bridge   PCIBridge    `json:"pci_bridge"`
}

// PCIBridge represents a PCI bridge.
type PCIBridge struct {
	Devices []PCIDevice `json:"devices"`
}

// QueryPCI returns info about PCI devices.
func (m *Monitor) QueryPCI() ([]PCIDevice, error) {
	// Prepare the response.
	var resp struct {
		Return []struct {
			Devices []PCIDevice `json:"devices"`
		} `json:"return"`
	}

	err := m.run("query-pci", nil, &resp)
	if err != nil {
		return nil, errors.Wrapf(err, "Failed querying PCI devices")
	}

	if len(resp.Return) > 0 {
		return resp.Return[0].Devices, nil
	}

	return nil, nil
}

// MemoryStats represents memory stats.
type MemoryStats struct {
	HTLBPGAlloc     int `json:"stat-htlb-pgalloc"`
	SwapOut         int `json:"stat-swap-out"`
	AvailableMemory int `json:"stat-available-memory"`
	HTLBPGFail      int `json:"stat-htlb-pgfail"`
	FreeMemory      int `json:"stat-free-memory"`
	MinorFaults     int `json:"stat-minor-faults"`
	MajorFaults     int `json:"stat-major-faults"`
	TotalMemory     int `json:"stat-total-memory"`
	SwapIn          int `json:"stat-swap-in"`
	DiskCaches      int `json:"stat-disk-caches"`
}

// GetMemoryStats return memory stats.
func (m *Monitor) GetMemoryStats() (*MemoryStats, error) {
	// Prepare the response
	var resp struct {
		Return struct {
			Stats MemoryStats `json:"stats"`
		} `json:"return"`
	}

	args := map[string]string{
		"path":     "/machine/peripheral/qemu_balloon",
		"property": "guest-stats",
	}

	err := m.run("qom-get", args, &resp)
	if err != nil {
		return nil, errors.Wrapf(err, "Failed querying memory stats")
	}

	return &resp.Return.Stats, nil
}

// BlockStats represents block device stats.
type BlockStats struct {
	BytesWritten    int `json:"wr_bytes"`
	WritesCompleted int `json:"wr_operations"`
	BytesRead       int `json:"rd_bytes"`
	ReadsCompleted  int `json:"rd_operations"`
}

// GetBlockStats return block device stats.
func (m *Monitor) GetBlockStats() (map[string]BlockStats, error) {
	// Prepare the response
	var resp struct {
		Return []struct {
			Stats BlockStats `json:"stats"`
			QDev  string     `json:"qdev"`
		} `json:"return"`
	}

	err := m.run("query-blockstats", nil, &resp)
	if err != nil {
		return nil, errors.Wrapf(err, "Failed querying block stats")
	}

	out := make(map[string]BlockStats)

	for _, res := range resp.Return {
		out[res.QDev] = res.Stats
	}

	return out, nil
}
<|endoftext|>


<commit_before>package github_squares

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/ami-GS/soac"
	"strconv"
)

var colorMap map[string]byte = map[string]byte{
	"#d6e685": 156,
	"#8cc665": 112,
	"#44a340": 34,
	"#1e6823": 22,
	"#eeeeee": 237,
}

var Changer *soac.Changer

func init() {
	Changer = soac.NewChanger()
}

type Rect struct {
	color string
	count byte
	date  string
}

func GetData(reqUrl string) (results [7][54]Rect) {
	doc, _ := goquery.NewDocument(reqUrl)
	column := 0

	doc.Find("rect").Each(func(_ int, s *goquery.Selection) {
		yTmp, _ := s.Attr("y")
		y, _ := strconv.Atoi(yTmp)
		color, _ := s.Attr("fill")
		countTmp, _ := s.Attr("data-count")
		count, _ := strconv.Atoi(countTmp)
		date, _ := s.Attr("data-date")
		results[y/13][column] = Rect{color, byte(count), date}
		if y == 78 {
			column++
		}
	})
	return
}

func GetString(rects [7][54]Rect) (ans string) {
	for row := 0; row < 7; row++ {
		for col := 0; col < 54; col++ {
			if rects[row][col].date != "" {
				Changer.Set256(colorMap[rects[row][col].color])
				ans += Changer.Apply("■")
			} else {
				ans += " "
			}
		}
		ans += "\n"
	}
	return
}

func ShowSquare(reqUrl string) {
	rects := GetData(reqUrl)
	str := GetString(rects)
	fmt.Println(str)
}
<commit_msg>only user name shoud be input<commit_after>package github_squares

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/ami-GS/soac"
	"strconv"
)

var colorMap map[string]byte = map[string]byte{
	"#d6e685": 156,
	"#8cc665": 112,
	"#44a340": 34,
	"#1e6823": 22,
	"#eeeeee": 237,
}

var Changer *soac.Changer

func init() {
	Changer = soac.NewChanger()
}

type Rect struct {
	color string
	count byte
	date  string
}

func GetData(reqUrl string) (results [7][54]Rect) {
	doc, _ := goquery.NewDocument(reqUrl)
	column := 0

	doc.Find("rect").Each(func(_ int, s *goquery.Selection) {
		yTmp, _ := s.Attr("y")
		y, _ := strconv.Atoi(yTmp)
		color, _ := s.Attr("fill")
		countTmp, _ := s.Attr("data-count")
		count, _ := strconv.Atoi(countTmp)
		date, _ := s.Attr("data-date")
		results[y/13][column] = Rect{color, byte(count), date}
		if y == 78 {
			column++
		}
	})
	return
}

func GetString(rects [7][54]Rect) (ans string) {
	for row := 0; row < 7; row++ {
		for col := 0; col < 54; col++ {
			if rects[row][col].date != "" {
				Changer.Set256(colorMap[rects[row][col].color])
				ans += Changer.Apply("■")
			} else {
				ans += " "
			}
		}
		ans += "\n"
	}
	return
}

func ShowSquare(userName string) {
	reqUrl := fmt.Sprintf("http://github.com/%s/", userName)
	rects := GetData(reqUrl)
	str := GetString(rects)
	fmt.Println(str)
}
<|endoftext|>


<commit_before>package gzreader

import (
	"bytes"
	"compress/gzip"
	"errors"
	"io"
	"log"
)

// Reader to reader, funk to funky
func NewCompressedReader(src io.Reader) *CompressedReader {

	var b bytes.Buffer
	gzipWriter, _ := gzip.NewWriterLevel(&b, gzip.BestSpeed)

	return &CompressedReader{src: src,
		gzipWriter:   gzipWriter,
		buf:          &b,
		readBytes:    0,
		writtenBytes: 0}
}

type CompressedReader struct {
	src        io.Reader
	gzipWriter *gzip.Writer
	buf        *bytes.Buffer

	readBytes    int64
	writtenBytes int64
}

func (r *CompressedReader) CompressionRatio() (float64, error) {

	if r.writtenBytes == 0 {
		return 0, errors.New("Compression ratio unknown.")
	}

	return 100 * float64(r.readBytes) / float64(r.writtenBytes), nil
}

func (r *CompressedReader) Read(p []byte) (n int, err error) {

	uncompressed := make([]byte, len(p))
	readLenUncompressed, err := r.src.Read(uncompressed)

	r.readBytes = r.readBytes + int64(readLenUncompressed)

	r.gzipWriter.Write(uncompressed[:readLenUncompressed])

	if err == io.EOF {
		r.gzipWriter.Close()
	}

	readLenCompressed, _ := r.buf.Read(p)

	r.writtenBytes = r.writtenBytes + int64(readLenCompressed)

	if ratio, err := r.CompressionRatio(); err != nil {
		log.Println("Compression ratio: %", ratio)
	}

	return readLenCompressed, err
}
<commit_msg>Remove unnecessary logging<commit_after>package gzreader

import (
	"bytes"
	"compress/gzip"
	"errors"
	"io"
)

// Reader to reader, funk to funky
func NewCompressedReader(src io.Reader) *CompressedReader {

	var b bytes.Buffer
	gzipWriter, _ := gzip.NewWriterLevel(&b, gzip.BestSpeed)

	return &CompressedReader{src: src,
		gzipWriter:   gzipWriter,
		buf:          &b,
		readBytes:    0,
		writtenBytes: 0}
}

type CompressedReader struct {
	src        io.Reader
	gzipWriter *gzip.Writer
	buf        *bytes.Buffer

	readBytes    int64
	writtenBytes int64
}

func (r *CompressedReader) CompressionRatio() (float64, error) {

	if r.writtenBytes == 0 {
		return 0, errors.New("Compression ratio unknown.")
	}

	return 100 * float64(r.readBytes) / float64(r.writtenBytes), nil
}

func (r *CompressedReader) Read(p []byte) (n int, err error) {

	uncompressed := make([]byte, len(p))
	readLenUncompressed, err := r.src.Read(uncompressed)

	r.readBytes = r.readBytes + int64(readLenUncompressed)

	r.gzipWriter.Write(uncompressed[:readLenUncompressed])

	if err == io.EOF {
		r.gzipWriter.Close()
	}

	readLenCompressed, _ := r.buf.Read(p)

	r.writtenBytes = r.writtenBytes + int64(readLenCompressed)

	return readLenCompressed, err
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"errors"
	"fmt"
	"log"
	"net"
	"net/rpc"
	"path/filepath"
	"sync"
	"sync/atomic"
	"time"
)

// Master manages persistent fuzzer state like input corpus and crashers.
type Master struct {
	mu           sync.Mutex
	idSeq        int
	slaves       map[int]*MasterSlave
	bootstrap    *PersistentSet
	corpus       *PersistentSet
	suppressions *PersistentSet
	crashers     *PersistentSet

	startTime     time.Time
	lastInput     time.Time
	statExecs     uint64
	statRestarts  uint64
	coverFullness float64
}

// MasterSlave represents master's view of a slave.
type MasterSlave struct {
	id       int
	procs    int
	pending  []MasterInput
	lastSync time.Time
}

// masterMain is entry function for master.
func masterMain(ln net.Listener) {
	m := &Master{}
	m.startTime = time.Now()
	m.lastInput = time.Now()
	m.suppressions = newPersistentSet(filepath.Join(*flagWorkdir, "suppressions"))
	m.crashers = newPersistentSet(filepath.Join(*flagWorkdir, "crashers"))
	m.corpus = newPersistentSet(filepath.Join(*flagWorkdir, "corpus"))
	m.bootstrap = newPersistentSet(*flagCorpus)
	if len(m.bootstrap.m) == 0 {
		m.bootstrap.add(Artifact{[]byte{}, 0})
	}

	m.slaves = make(map[int]*MasterSlave)
	go masterLoop(m)

	s := rpc.NewServer()
	s.Register(m)
	s.Accept(ln)
}

func masterLoop(m *Master) {
	for range time.NewTicker(3 * time.Second).C {
		if atomic.LoadUint32(&shutdown) != 0 {
			return
		}
		m.mu.Lock()
		// Nuke dead slaves.
		for id, s := range m.slaves {
			if time.Since(s.lastSync) < syncDeadline {
				continue
			}
			log.Printf("slave %v died", s.id)
			delete(m.slaves, id)
		}

		// Print stats line.
		uptime := time.Since(m.startTime)
		lastInput := time.Since(m.lastInput)
		restarts := uint64(0)
		if m.statExecs != 0 {
			restarts = m.statExecs / m.statRestarts
		}
		procs := 0
		for _, s := range m.slaves {
			procs += s.procs
		}
		log.Printf("slaves: %v, corpus: %v (%v ago), crashers: %v,"+
			" restarts: 1/%v, execs: %v (%.0f/sec), cover: %.2f%%, uptime: %v",
			procs, len(m.corpus.m), fmtDuration(lastInput), len(m.crashers.m),
			restarts, m.statExecs, float64(m.statExecs)*1e9/float64(uptime),
			m.coverFullness*100, fmtDuration(uptime))
		m.mu.Unlock()
	}
}

func fmtDuration(d time.Duration) string {
	if d.Hours() >= 1 {
		return fmt.Sprintf("%vh%vm", int(d.Hours()), int(d.Minutes())%60)
	} else if d.Minutes() >= 1 {
		return fmt.Sprintf("%vm%vs", int(d.Minutes()), int(d.Seconds())%60)
	} else {
		return fmt.Sprintf("%vs", int(d.Seconds()))
	}
}

type ConnectArgs struct {
	Procs int
}

type ConnectRes struct {
	ID     int
	Corpus []MasterInput
}

// MasterInput is description of input that is passed between master and slave.
type MasterInput struct {
	Data      []byte
	Prio      uint64
	Minimized bool
	Smashed   bool
}

// Connect attaches new slave to master.
func (m *Master) Connect(a *ConnectArgs, r *ConnectRes) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	m.idSeq++
	s := &MasterSlave{
		id:       m.idSeq,
		procs:    a.Procs,
		lastSync: time.Now(),
	}
	m.slaves[s.id] = s
	r.ID = s.id
	// Give the slave initial corpus.
	for _, a := range m.bootstrap.m {
		r.Corpus = append(r.Corpus, MasterInput{a.data, a.meta, false, false})
	}
	for _, a := range m.corpus.m {
		r.Corpus = append(r.Corpus, MasterInput{a.data, a.meta, true, true})
	}
	return nil
}

type NewInputArgs struct {
	ID   int
	Data []byte
	Prio uint64
}

// NewInput saves new interesting input on master.
func (m *Master) NewInput(a *NewInputArgs, r *int) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	s := m.slaves[a.ID]
	if s == nil {
		return errors.New("unknown slave")
	}

	art := Artifact{a.Data, a.Prio}
	if !m.corpus.add(art) {
		return nil
	}
	m.lastInput = time.Now()
	// Queue the input for sending to every slave.
	for _, s1 := range m.slaves {
		s1.pending = append(s1.pending, MasterInput{a.Data, a.Prio, true, s1 != s})
	}

	return nil
}

type NewCrasherArgs struct {
	Data        []byte
	Error       []byte
	Suppression []byte
	Hanging     bool
}

// NewCrasher saves new crasher input on master.
func (m *Master) NewCrasher(a *NewCrasherArgs, r *int) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	if !m.suppressions.add(Artifact{a.Suppression, 0}) || !m.crashers.add(Artifact{a.Data, 0}) {
		// Already have this.
		return nil
	}

	// Prepare quoted version of input to simplify creation of standalone reproducers.
	var buf bytes.Buffer
	for i := 0; i < len(a.Data); i += 20 {
		e := i + 20
		if e > len(a.Data) {
			e = len(a.Data)
		}
		fmt.Fprintf(&buf, "\t%q", a.Data[i:e])
		if e != len(a.Data) {
			fmt.Printf(" +")
		}
		fmt.Printf("\n")
	}
	m.crashers.addDescription(a.Data, buf.Bytes(), "quoted")
	m.crashers.addDescription(a.Data, a.Error, "output")

	return nil
}

type SyncArgs struct {
	ID            int
	Execs         uint64
	Restarts      uint64
	CoverFullness float64
}

type SyncRes struct {
	Inputs []MasterInput // new interesting inputs
}

// Sync is a periodic sync with a slave.
// Slave sends statitstics. Master returns new inputs.
func (m *Master) Sync(a *SyncArgs, r *SyncRes) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	s := m.slaves[a.ID]
	if s == nil {
		return errors.New("unknown slave")
	}
	m.statExecs += a.Execs
	m.statRestarts += a.Restarts
	if m.coverFullness < a.CoverFullness {
		m.coverFullness = a.CoverFullness
	}
	s.lastSync = time.Now()
	r.Inputs = s.pending
	s.pending = nil
	return nil
}
<commit_msg>fix formation of quoted crasher data<commit_after>package main

import (
	"bytes"
	"errors"
	"fmt"
	"log"
	"net"
	"net/rpc"
	"path/filepath"
	"sync"
	"sync/atomic"
	"time"
)

// Master manages persistent fuzzer state like input corpus and crashers.
type Master struct {
	mu           sync.Mutex
	idSeq        int
	slaves       map[int]*MasterSlave
	bootstrap    *PersistentSet
	corpus       *PersistentSet
	suppressions *PersistentSet
	crashers     *PersistentSet

	startTime     time.Time
	lastInput     time.Time
	statExecs     uint64
	statRestarts  uint64
	coverFullness float64
}

// MasterSlave represents master's view of a slave.
type MasterSlave struct {
	id       int
	procs    int
	pending  []MasterInput
	lastSync time.Time
}

// masterMain is entry function for master.
func masterMain(ln net.Listener) {
	m := &Master{}
	m.startTime = time.Now()
	m.lastInput = time.Now()
	m.suppressions = newPersistentSet(filepath.Join(*flagWorkdir, "suppressions"))
	m.crashers = newPersistentSet(filepath.Join(*flagWorkdir, "crashers"))
	m.corpus = newPersistentSet(filepath.Join(*flagWorkdir, "corpus"))
	m.bootstrap = newPersistentSet(*flagCorpus)
	if len(m.bootstrap.m) == 0 {
		m.bootstrap.add(Artifact{[]byte{}, 0})
	}

	m.slaves = make(map[int]*MasterSlave)
	go masterLoop(m)

	s := rpc.NewServer()
	s.Register(m)
	s.Accept(ln)
}

func masterLoop(m *Master) {
	for range time.NewTicker(3 * time.Second).C {
		if atomic.LoadUint32(&shutdown) != 0 {
			return
		}
		m.mu.Lock()
		// Nuke dead slaves.
		for id, s := range m.slaves {
			if time.Since(s.lastSync) < syncDeadline {
				continue
			}
			log.Printf("slave %v died", s.id)
			delete(m.slaves, id)
		}

		// Print stats line.
		uptime := time.Since(m.startTime)
		lastInput := time.Since(m.lastInput)
		restarts := uint64(0)
		if m.statExecs != 0 {
			restarts = m.statExecs / m.statRestarts
		}
		procs := 0
		for _, s := range m.slaves {
			procs += s.procs
		}
		log.Printf("slaves: %v, corpus: %v (%v ago), crashers: %v,"+
			" restarts: 1/%v, execs: %v (%.0f/sec), cover: %.2f%%, uptime: %v",
			procs, len(m.corpus.m), fmtDuration(lastInput), len(m.crashers.m),
			restarts, m.statExecs, float64(m.statExecs)*1e9/float64(uptime),
			m.coverFullness*100, fmtDuration(uptime))
		m.mu.Unlock()
	}
}

func fmtDuration(d time.Duration) string {
	if d.Hours() >= 1 {
		return fmt.Sprintf("%vh%vm", int(d.Hours()), int(d.Minutes())%60)
	} else if d.Minutes() >= 1 {
		return fmt.Sprintf("%vm%vs", int(d.Minutes()), int(d.Seconds())%60)
	} else {
		return fmt.Sprintf("%vs", int(d.Seconds()))
	}
}

type ConnectArgs struct {
	Procs int
}

type ConnectRes struct {
	ID     int
	Corpus []MasterInput
}

// MasterInput is description of input that is passed between master and slave.
type MasterInput struct {
	Data      []byte
	Prio      uint64
	Minimized bool
	Smashed   bool
}

// Connect attaches new slave to master.
func (m *Master) Connect(a *ConnectArgs, r *ConnectRes) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	m.idSeq++
	s := &MasterSlave{
		id:       m.idSeq,
		procs:    a.Procs,
		lastSync: time.Now(),
	}
	m.slaves[s.id] = s
	r.ID = s.id
	// Give the slave initial corpus.
	for _, a := range m.bootstrap.m {
		r.Corpus = append(r.Corpus, MasterInput{a.data, a.meta, false, false})
	}
	for _, a := range m.corpus.m {
		r.Corpus = append(r.Corpus, MasterInput{a.data, a.meta, true, true})
	}
	return nil
}

type NewInputArgs struct {
	ID   int
	Data []byte
	Prio uint64
}

// NewInput saves new interesting input on master.
func (m *Master) NewInput(a *NewInputArgs, r *int) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	s := m.slaves[a.ID]
	if s == nil {
		return errors.New("unknown slave")
	}

	art := Artifact{a.Data, a.Prio}
	if !m.corpus.add(art) {
		return nil
	}
	m.lastInput = time.Now()
	// Queue the input for sending to every slave.
	for _, s1 := range m.slaves {
		s1.pending = append(s1.pending, MasterInput{a.Data, a.Prio, true, s1 != s})
	}

	return nil
}

type NewCrasherArgs struct {
	Data        []byte
	Error       []byte
	Suppression []byte
	Hanging     bool
}

// NewCrasher saves new crasher input on master.
func (m *Master) NewCrasher(a *NewCrasherArgs, r *int) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	if !m.suppressions.add(Artifact{a.Suppression, 0}) || !m.crashers.add(Artifact{a.Data, 0}) {
		// Already have this.
		return nil
	}

	// Prepare quoted version of input to simplify creation of standalone reproducers.
	var buf bytes.Buffer
	for i := 0; i < len(a.Data); i += 20 {
		e := i + 20
		if e > len(a.Data) {
			e = len(a.Data)
		}
		fmt.Fprintf(&buf, "\t%q", a.Data[i:e])
		if e != len(a.Data) {
			fmt.Fprintf(&buf, " +")
		}
		fmt.Fprintf(&buf, "\n")
	}
	m.crashers.addDescription(a.Data, buf.Bytes(), "quoted")
	m.crashers.addDescription(a.Data, a.Error, "output")

	return nil
}

type SyncArgs struct {
	ID            int
	Execs         uint64
	Restarts      uint64
	CoverFullness float64
}

type SyncRes struct {
	Inputs []MasterInput // new interesting inputs
}

// Sync is a periodic sync with a slave.
// Slave sends statitstics. Master returns new inputs.
func (m *Master) Sync(a *SyncArgs, r *SyncRes) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	s := m.slaves[a.ID]
	if s == nil {
		return errors.New("unknown slave")
	}
	m.statExecs += a.Execs
	m.statRestarts += a.Restarts
	if m.coverFullness < a.CoverFullness {
		m.coverFullness = a.CoverFullness
	}
	s.lastSync = time.Now()
	r.Inputs = s.pending
	s.pending = nil
	return nil
}
<|endoftext|>


<commit_before>package clock

import "fmt"

// TestVersion is a test version.
const TestVersion = 2

// Clock handles times without dates.
//
// A Clock is able to add and subtract minutes to it.
//
// Two clocks that represent the same time are equal to each other.
type Clock struct {
	hour int
	min  int
}

// Time creates a Clock holding hours and minutes.
func Time(hour, minutes int) Clock {
	d, m := minutes/60, minutes%60
	if minutes < 0 {
		d -= 1
		m += 60
	}
	h := hour%24 + d
	if h < 0 {
		h += 24
	}
	return Clock{
		hour: h,
		min:  m,
	}
}

// String returns a string representing time such as "08:00".
func (c Clock) String() string {
	return fmt.Sprintf("%02d:%02d", c.hour, c.min)
}

// Add returns a Clock added by minutes.
// Add also handle subtraction by accepting negative values.
// Values of Clock type work with the == operator.
func (c Clock) Add(minutes int) Clock {
	s := c.min + minutes
	d, m := s/60, s%60
	return Time(c.hour+d, m)
}
<commit_msg>go/clock: refactor Time() referencing time package<commit_after>package clock

import "fmt"

// TestVersion is a test version.
const TestVersion = 2

const (
	minPerHour = 60
	hourPerDay = 24
)

// Clock handles times without dates.
//
// A Clock is able to add and subtract minutes to it.
//
// Two clocks that represent the same time are equal to each other.
type Clock struct {
	hour int
	min  int
}

// Time creates a Clock holding hours and minutes.
func Time(hour, minutes int) Clock {
	if minutes < 0 || minutes >= minPerHour {
		n := minutes / minPerHour
		hour += n
		minutes -= n * minPerHour

		if minutes < 0 {
			minutes += minPerHour
			hour--
		}
	}

	if hour < 0 || hour >= hourPerDay {
		hour %= hourPerDay

		if hour < 0 {
			hour += hourPerDay
		}
	}

	return Clock{
		hour: hour,
		min:  minutes,
	}
}

// String returns a string representing time such as "08:00".
func (c Clock) String() string {
	return fmt.Sprintf("%02d:%02d", c.hour, c.min)
}

// Add returns a Clock added by minutes.
// Add also handle subtraction by accepting negative values.
// Values of Clock type work with the == operator.
func (c Clock) Add(minutes int) Clock {
	s := c.min + minutes
	d, m := s/60, s%60
	return Time(c.hour+d, m)
}
<|endoftext|>


<commit_before>package logger

import (
	"fmt"
	"os"
	"sync"
	"time"

	logging "github.com/keybase/go-logging"
)

// LogFileConfig is the config structure for new style log files with rotation.
type LogFileConfig struct {
	// Path is the path of the log file to use
	Path string
	// MaxSize is the size of log file before rotation, 0 for infinite.
	MaxSize int64
	// MaxAge is th duration before log rotation, zero value for infinite.
	MaxAge time.Duration
}

// SetLogFileConfig sets the log file config to be used globally.
func SetLogFileConfig(lfc *LogFileConfig) error {
	globalLock.Lock()
	defer globalLock.Unlock()

	first := true
	var w = currentLogFileWriter
	if w != nil {
		first = false
		w.lock.Lock()
		defer w.lock.Unlock()
		w.Close()
	} else {
		w = &logFileWriter{}
	}
	w.config = *lfc

	err := w.Open(time.Now())
	if err != nil {
		return err
	}

	if first {
		fileBackend := logging.NewLogBackend(w, "", 0)
		logging.SetBackend(fileBackend)

		stderrIsTerminal = false
	}
	return nil
}

type logFileWriter struct {
	lock         sync.Mutex
	config       LogFileConfig
	file         *os.File
	currentSize  int64
	currentStart time.Time
}

func (lfw *logFileWriter) Open(at time.Time) error {
	var err error
	_, lfw.file, err = OpenLogFile(lfw.config.Path)
	if err != nil {
		return err
	}
	lfw.currentStart = at
	lfw.currentSize = 0
	fi, err := lfw.file.Stat()
	if err != nil {
		return err
	}
	lfw.currentSize = fi.Size()
	return nil
}

func (lfw *logFileWriter) Close() error {
	if lfw == nil {
		return nil
	}
	lfw.lock.Lock()
	defer lfw.lock.Unlock()
	if lfw.file == nil {
		return nil
	}
	return lfw.file.Close()
}

const zeroDuration time.Duration = 0

func (lfw *logFileWriter) Write(bs []byte) (int, error) {
	lfw.lock.Lock()
	defer lfw.lock.Unlock()
	n, err := lfw.file.Write(bs)
	if err != nil {
		return n, err
	}
	needRotation := false
	if lfw.config.MaxSize > 0 {
		lfw.currentSize += int64(n)
		needRotation = needRotation || lfw.currentSize > lfw.config.MaxSize
	}
	if lfw.config.MaxAge != zeroDuration {
		elapsed := time.Since(lfw.currentStart)
		needRotation = needRotation || elapsed > lfw.config.MaxAge
	}
	if !needRotation {
		return n, nil
	}
	// Close first because some systems don't like to rename otherwise.
	lfw.file.Close()
	lfw.file = nil
	now := time.Now()
	start := lfw.currentStart.Format("20060102T150405")
	end := now.Format("20060102T150405")
	tgt := fmt.Sprintf("%s-%s-%s", lfw.config.Path, start, end)
	// Handle the error further down
	err = os.Rename(lfw.config.Path, tgt)
	if err != nil {
		return n, err
	}
	err = lfw.Open(now)
	return n, err
}
<commit_msg>logger: Handle switching log file name multiple times<commit_after>package logger

import (
	"fmt"
	"os"
	"sync"
	"time"

	logging "github.com/keybase/go-logging"
)

// LogFileConfig is the config structure for new style log files with rotation.
type LogFileConfig struct {
	// Path is the path of the log file to use
	Path string
	// MaxSize is the size of log file before rotation, 0 for infinite.
	MaxSize int64
	// MaxAge is th duration before log rotation, zero value for infinite.
	MaxAge time.Duration
}

// SetLogFileConfig sets the log file config to be used globally.
func SetLogFileConfig(lfc *LogFileConfig) error {
	globalLock.Lock()
	defer globalLock.Unlock()

	first := true
	var w = currentLogFileWriter
	if w != nil {
		first = false
		w.lock.Lock()
		defer w.lock.Unlock()
		w.Close()
	} else {
		w = &logFileWriter{}
	}
	w.config = *lfc

	err := w.Open(time.Now())
	if err != nil {
		return err
	}

	if first {
		fileBackend := logging.NewLogBackend(w, "", 0)
		logging.SetBackend(fileBackend)

		stderrIsTerminal = false
		currentLogFileWriter = w
	}
	return nil
}

type logFileWriter struct {
	lock         sync.Mutex
	config       LogFileConfig
	file         *os.File
	currentSize  int64
	currentStart time.Time
}

func (lfw *logFileWriter) Open(at time.Time) error {
	var err error
	_, lfw.file, err = OpenLogFile(lfw.config.Path)
	if err != nil {
		return err
	}
	lfw.currentStart = at
	lfw.currentSize = 0
	fi, err := lfw.file.Stat()
	if err != nil {
		return err
	}
	lfw.currentSize = fi.Size()
	return nil
}

func (lfw *logFileWriter) Close() error {
	if lfw == nil {
		return nil
	}
	lfw.lock.Lock()
	defer lfw.lock.Unlock()
	if lfw.file == nil {
		return nil
	}
	return lfw.file.Close()
}

const zeroDuration time.Duration = 0

func (lfw *logFileWriter) Write(bs []byte) (int, error) {
	lfw.lock.Lock()
	defer lfw.lock.Unlock()
	n, err := lfw.file.Write(bs)
	if err != nil {
		return n, err
	}
	needRotation := false
	if lfw.config.MaxSize > 0 {
		lfw.currentSize += int64(n)
		needRotation = needRotation || lfw.currentSize > lfw.config.MaxSize
	}
	if lfw.config.MaxAge != zeroDuration {
		elapsed := time.Since(lfw.currentStart)
		needRotation = needRotation || elapsed > lfw.config.MaxAge
	}
	if !needRotation {
		return n, nil
	}
	// Close first because some systems don't like to rename otherwise.
	lfw.file.Close()
	lfw.file = nil
	now := time.Now()
	start := lfw.currentStart.Format("20060102T150405")
	end := now.Format("20060102T150405")
	tgt := fmt.Sprintf("%s-%s-%s", lfw.config.Path, start, end)
	// Handle the error further down
	err = os.Rename(lfw.config.Path, tgt)
	if err != nil {
		return n, err
	}
	err = lfw.Open(now)
	return n, err
}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "github.com/fuzxxl/nfc/2.0/nfc"
    "github.com/fuzxxl/freefare/0.3/freefare"
    "code.google.com/p/go-sqlite/go1/sqlite3"
    "time"
)

func main() {
    c, err := sqlite3.Open("keys.db")
    if err != nil {
        panic(err);
    }
    row := make(sqlite3.RowMap)

    d, err := nfc.Open("");
    if err != nil {
        panic(err);
    }

    var tags []freefare.Tag
    for {
        tags, err = freefare.GetTags(d);
        if err != nil {
            panic(err);
        }
        if len(tags) > 0 {
            break;
        }
        time.Sleep(100 * time.Millisecond)
        //fmt.Println("...polling")
    }
    fmt.Println(tags);
    valid_found := false
    for i := 0; i < len(tags); i++ {
        tag := tags[i]
        uidstr := tag.UID()
        sql := "SELECT rowid, * FROM keys where uid=?"
        for s, err := c.Query(sql, uidstr); err == nil; err = s.Next() {
            var rowid int64
            s.Scan(&rowid, row)     // Assigns 1st column to rowid, the rest to row
            fmt.Println(rowid, row)
            valid_found = true
        }
    }
    if !valid_found {
        fmt.Println("NO ACCESS")
    }
}
<commit_msg>this used the old library<commit_after><|endoftext|>


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

// This file implements Sizes.

package types

// Sizes defines the sizing functions for package unsafe.
type Sizes interface {
	// Alignof returns the alignment of a variable of type T.
	// Alignof must implement the alignment guarantees required by the spec.
	Alignof(T Type) int64

	// Offsetsof returns the offsets of the given struct fields, in bytes.
	// Offsetsof must implement the offset guarantees required by the spec.
	Offsetsof(fields []*Var) []int64

	// Sizeof returns the size of a variable of type T.
	// Sizeof must implement the size guarantees required by the spec.
	Sizeof(T Type) int64
}

// StdSizes is a convenience type for creating commonly used Sizes.
// It makes the following simplifying assumptions:
//
// - The size of explicitly sized basic types (int16, etc.) is the
//   specified size.
// - The size of strings, functions, and interfaces is 2*WordSize.
// - The size of slices is 3*WordSize.
// - All other types have size WordSize.
// - Arrays and structs are aligned per spec definition; all other
//   types are naturally aligned with a maximum alignment MaxAlign.
//
// *StdSizes implements Sizes.
//
type StdSizes struct {
	WordSize int64 // word size in bytes - must be >= 4 (32bits)
	MaxAlign int64 // maximum alignment in bytes - must be >= 1
}

func (s *StdSizes) Alignof(T Type) int64 {
	// For arrays and structs, alignment is defined in terms
	// of alignment of the elements and fields, respectively.
	switch t := T.Underlying().(type) {
	case *Array:
		// spec: "For a variable x of array type: unsafe.Alignof(x)
		// is the same as unsafe.Alignof(x[0]), but at least 1."
		return s.Alignof(t.elt)
	case *Struct:
		// spec: "For a variable x of struct type: unsafe.Alignof(x)
		// is the largest of the values unsafe.Alignof(x.f) for each
		// field f of x, but at least 1."
		max := int64(1)
		for _, f := range t.fields {
			if a := s.Alignof(f.typ); a > max {
				max = a
			}
		}
		return max
	}
	a := s.Sizeof(T) // may be 0
	// spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
	if a < 1 {
		return 1
	}
	if a > s.MaxAlign {
		return s.MaxAlign
	}
	return a
}

func (s *StdSizes) Offsetsof(fields []*Var) []int64 {
	offsets := make([]int64, len(fields))
	var o int64
	for i, f := range fields {
		a := s.Alignof(f.typ)
		o = align(o, a)
		offsets[i] = o
		o += s.Sizeof(f.typ)
	}
	return offsets
}

func (s *StdSizes) Sizeof(T Type) int64 {
	switch t := T.Underlying().(type) {
	case *Basic:
		if z := t.size; z > 0 {
			return z
		}
		if t.kind == String {
			return s.WordSize * 2
		}
	case *Array:
		a := s.Alignof(t.elt)
		z := s.Sizeof(t.elt)
		return align(z, a) * t.len // may be 0
	case *Slice:
		return s.WordSize * 3
	case *Struct:
		n := t.NumFields()
		if n == 0 {
			return 0
		}
		offsets := t.offsets
		if t.offsets == nil {
			// compute offsets on demand
			offsets = stdSizes.Offsetsof(t.fields)
			t.offsets = offsets
		}
		return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
	case *Signature, *Interface:
		return s.WordSize * 2
	}
	return s.WordSize // catch-all
}

// stdSizes is used if Config.Sizes == nil.
var stdSizes = StdSizes{8, 8}

func (conf *Config) alignof(T Type) int64 {
	if s := conf.Sizes; s != nil {
		if a := s.Alignof(T); a >= 1 {
			return a
		}
		panic("Config.Sizes.Alignof returned an alignment < 1")
	}
	return stdSizes.Alignof(T)
}

func (conf *Config) offsetsof(T *Struct) []int64 {
	offsets := T.offsets
	if offsets == nil && T.NumFields() > 0 {
		// compute offsets on demand
		if s := conf.Sizes; s != nil {
			offsets = s.Offsetsof(T.fields)
			// sanity checks
			if len(offsets) != T.NumFields() {
				panic("Config.Sizes.Offsetsof returned the wrong number of offsets")
			}
			for _, o := range offsets {
				if o < 0 {
					panic("Config.Sizes.Offsetsof returned an offset < 0")
				}
			}
		} else {
			offsets = stdSizes.Offsetsof(T.fields)
		}
		T.offsets = offsets
	}
	return offsets
}

// offsetof returns the offset of the field specified via
// the index sequence relative to typ. All embedded fields
// must be structs (rather than pointer to structs).
func (conf *Config) offsetof(typ Type, index []int) int64 {
	var o int64
	for _, i := range index {
		s := typ.Underlying().(*Struct)
		o += conf.offsetsof(s)[i]
		typ = s.fields[i].typ
	}
	return o
}

func (conf *Config) sizeof(T Type) int64 {
	if s := conf.Sizes; s != nil {
		if z := s.Sizeof(T); z >= 0 {
			return z
		}
		panic("Config.Sizes.Sizeof returned a size < 0")
	}
	return stdSizes.Sizeof(T)
}

// align returns the smallest y >= x such that y % a == 0.
func align(x, a int64) int64 {
	y := x + a - 1
	return y - y%a
}
<commit_msg>go.tools/go/types: fix StdSizes.Sizeof computation<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements Sizes.

package types

// Sizes defines the sizing functions for package unsafe.
type Sizes interface {
	// Alignof returns the alignment of a variable of type T.
	// Alignof must implement the alignment guarantees required by the spec.
	Alignof(T Type) int64

	// Offsetsof returns the offsets of the given struct fields, in bytes.
	// Offsetsof must implement the offset guarantees required by the spec.
	Offsetsof(fields []*Var) []int64

	// Sizeof returns the size of a variable of type T.
	// Sizeof must implement the size guarantees required by the spec.
	Sizeof(T Type) int64
}

// StdSizes is a convenience type for creating commonly used Sizes.
// It makes the following simplifying assumptions:
//
// - The size of explicitly sized basic types (int16, etc.) is the
//   specified size.
// - The size of strings, functions, and interfaces is 2*WordSize.
// - The size of slices is 3*WordSize.
// - All other types have size WordSize.
// - Arrays and structs are aligned per spec definition; all other
//   types are naturally aligned with a maximum alignment MaxAlign.
//
// *StdSizes implements Sizes.
//
type StdSizes struct {
	WordSize int64 // word size in bytes - must be >= 4 (32bits)
	MaxAlign int64 // maximum alignment in bytes - must be >= 1
}

func (s *StdSizes) Alignof(T Type) int64 {
	// For arrays and structs, alignment is defined in terms
	// of alignment of the elements and fields, respectively.
	switch t := T.Underlying().(type) {
	case *Array:
		// spec: "For a variable x of array type: unsafe.Alignof(x)
		// is the same as unsafe.Alignof(x[0]), but at least 1."
		return s.Alignof(t.elt)
	case *Struct:
		// spec: "For a variable x of struct type: unsafe.Alignof(x)
		// is the largest of the values unsafe.Alignof(x.f) for each
		// field f of x, but at least 1."
		max := int64(1)
		for _, f := range t.fields {
			if a := s.Alignof(f.typ); a > max {
				max = a
			}
		}
		return max
	}
	a := s.Sizeof(T) // may be 0
	// spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
	if a < 1 {
		return 1
	}
	if a > s.MaxAlign {
		return s.MaxAlign
	}
	return a
}

func (s *StdSizes) Offsetsof(fields []*Var) []int64 {
	offsets := make([]int64, len(fields))
	var o int64
	for i, f := range fields {
		a := s.Alignof(f.typ)
		o = align(o, a)
		offsets[i] = o
		o += s.Sizeof(f.typ)
	}
	return offsets
}

func (s *StdSizes) Sizeof(T Type) int64 {
	switch t := T.Underlying().(type) {
	case *Basic:
		if z := t.size; z > 0 {
			return z
		}
		if t.kind == String {
			return s.WordSize * 2
		}
	case *Array:
		a := s.Alignof(t.elt)
		z := s.Sizeof(t.elt)
		return align(z, a) * t.len // may be 0
	case *Slice:
		return s.WordSize * 3
	case *Struct:
		n := t.NumFields()
		if n == 0 {
			return 0
		}
		offsets := t.offsets
		if t.offsets == nil {
			// compute offsets on demand
			offsets = s.Offsetsof(t.fields)
			t.offsets = offsets
		}
		return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
	case *Signature, *Interface:
		return s.WordSize * 2
	}
	return s.WordSize // catch-all
}

// stdSizes is used if Config.Sizes == nil.
var stdSizes = StdSizes{8, 8}

func (conf *Config) alignof(T Type) int64 {
	if s := conf.Sizes; s != nil {
		if a := s.Alignof(T); a >= 1 {
			return a
		}
		panic("Config.Sizes.Alignof returned an alignment < 1")
	}
	return stdSizes.Alignof(T)
}

func (conf *Config) offsetsof(T *Struct) []int64 {
	offsets := T.offsets
	if offsets == nil && T.NumFields() > 0 {
		// compute offsets on demand
		if s := conf.Sizes; s != nil {
			offsets = s.Offsetsof(T.fields)
			// sanity checks
			if len(offsets) != T.NumFields() {
				panic("Config.Sizes.Offsetsof returned the wrong number of offsets")
			}
			for _, o := range offsets {
				if o < 0 {
					panic("Config.Sizes.Offsetsof returned an offset < 0")
				}
			}
		} else {
			offsets = stdSizes.Offsetsof(T.fields)
		}
		T.offsets = offsets
	}
	return offsets
}

// offsetof returns the offset of the field specified via
// the index sequence relative to typ. All embedded fields
// must be structs (rather than pointer to structs).
func (conf *Config) offsetof(typ Type, index []int) int64 {
	var o int64
	for _, i := range index {
		s := typ.Underlying().(*Struct)
		o += conf.offsetsof(s)[i]
		typ = s.fields[i].typ
	}
	return o
}

func (conf *Config) sizeof(T Type) int64 {
	if s := conf.Sizes; s != nil {
		if z := s.Sizeof(T); z >= 0 {
			return z
		}
		panic("Config.Sizes.Sizeof returned a size < 0")
	}
	return stdSizes.Sizeof(T)
}

// align returns the smallest y >= x such that y % a == 0.
func align(x, a int64) int64 {
	y := x + a - 1
	return y - y%a
}
<|endoftext|>


<commit_before>package catcher

import (
	"fmt"
	"time"

	"github.com/AsynkronIT/protoactor-go/actor"
)

const (
	TEST_TIMEOUT = 3 * time.Millisecond
)

type Envelope struct {
	Sender  *actor.PID
	Target  *actor.PID
	Message interface{}
}

type Catcher struct {
	ChSystemInbound chan *Envelope
	ChUserInbound   chan *Envelope
	ChUserOutbound  chan *Envelope

	// One followed actor per catcher
	AssignedActor *actor.PID

	LoggingOn bool
}

func (catcher *Catcher) id() string {
	if catcher.AssignedActor != nil {
		return catcher.AssignedActor.String()
	}

	return "-"
}

func New() *Catcher {
	return &Catcher{
		ChSystemInbound: make(chan *Envelope, 10),

		// These are deliberately not buffered to make synchronization points
		ChUserInbound:  make(chan *Envelope),
		ChUserOutbound: make(chan *Envelope),
	}
}

func (catcher *Catcher) Spawn(props *actor.Props, prefix string, options ...Options) (*actor.PID, error) {
	var opt Options
	if len(options) == 0 {
		opt = OptDefault
	} else {
		opt = options[0]
	}

	if opt.EnableInboundInterception {
		props = props.WithMiddleware(catcher.InboundMiddleware)
	}

	if opt.EnableOutboundInterception {
		props = props.WithOutboundMiddleware(catcher.OutboundMiddleware)
	}

	pid, err := actor.SpawnPrefix(props, prefix)
	if err != nil {
		return nil, err
	}

	catcher.AssignedActor = pid
	return pid, nil
}

func (catcher *Catcher) ShouldReceive(sender *actor.PID, msg interface{}) string {
	select {
	case envelope := <-catcher.ChUserInbound:
		if msg == nil { // Any massage will suffice
			return ""
		} else {
			return assertInboundMessage(envelope, msg, sender)
		}
	case <-time.After(TEST_TIMEOUT):
		return "Timeout while waiting for a message"
	}
}

func (catcher *Catcher) ShouldReceiveSysMsg(msg interface{}) string {
	for {
		select {
		case envelope := <-catcher.ChSystemInbound:
			if msg == nil { // Any message is ok
				return ""
			} else {
				// Ignore unmatching messages
				// This is important. Otherwise we would always have to check for
				// for the Start message first. And potentially for other intermediate messages.
				match := assertInboundMessage(envelope, msg, nil)
				if match == "" {
					return ""
				}
			}
		case <-time.After(TEST_TIMEOUT):
			return "Timeout while waiting for a system message"
		}
	}
}

func (catcher *Catcher) ShouldSend(receiver *actor.PID, msg interface{}) string {
	select {
	case envelope := <-catcher.ChUserOutbound:
		if msg == nil { // Any message wil suffice
			return ""
		} else {
			return assertOutboundMessage(envelope, msg, receiver)
		}
	case <-time.After(TEST_TIMEOUT):
		return "Timeout while waiting for sending"
	}
}

func (catcher *Catcher) ShouldNotSendOrReceive(pid *actor.PID) string {
	select {
	case envelope := <-catcher.ChUserOutbound:
		return fmt.Sprintf("Got outbound message: %#v", envelope.Message)
	case envelope := <-catcher.ChUserInbound:
		return fmt.Sprintf("Got inbound message: %#v", envelope.Message)
	case <-time.After(TEST_TIMEOUT):
		return ""
	}
}
<commit_msg>Keep configuration options in a catcher for later use<commit_after>package catcher

import (
	"fmt"
	"time"

	"github.com/AsynkronIT/protoactor-go/actor"
)

const (
	TEST_TIMEOUT = 3 * time.Millisecond
)

type Envelope struct {
	Sender  *actor.PID
	Target  *actor.PID
	Message interface{}
}

type Catcher struct {
	ChSystemInbound chan *Envelope
	ChUserInbound   chan *Envelope
	ChUserOutbound  chan *Envelope

	// One followed actor per catcher
	AssignedActor *actor.PID

	LoggingOn bool
	options   Options
}

func (catcher *Catcher) id() string {
	if catcher.AssignedActor != nil {
		return catcher.AssignedActor.String()
	}

	return "-"
}

func New() *Catcher {
	return &Catcher{
		ChSystemInbound: make(chan *Envelope, 10),

		// These are deliberately not buffered to make synchronization points
		ChUserInbound:  make(chan *Envelope),
		ChUserOutbound: make(chan *Envelope),
	}
}

func (catcher *Catcher) Spawn(props *actor.Props, prefix string, options ...Options) (*actor.PID, error) {
	var opt Options
	if len(options) == 0 {
		opt = OptDefault
	} else {
		opt = options[0]
	}
	catcher.options = opt

	if opt.EnableInboundInterception {
		props = props.WithMiddleware(catcher.InboundMiddleware)
	}

	if opt.EnableOutboundInterception {
		props = props.WithOutboundMiddleware(catcher.OutboundMiddleware)
	}

	pid, err := actor.SpawnPrefix(props, prefix)
	if err != nil {
		return nil, err
	}

	catcher.AssignedActor = pid
	return pid, nil
}

func (catcher *Catcher) ShouldReceive(sender *actor.PID, msg interface{}) string {
	select {
	case envelope := <-catcher.ChUserInbound:
		if msg == nil { // Any massage will suffice
			return ""
		} else {
			return assertInboundMessage(envelope, msg, sender)
		}
	case <-time.After(TEST_TIMEOUT):
		return "Timeout while waiting for a message"
	}
}

func (catcher *Catcher) ShouldReceiveSysMsg(msg interface{}) string {
	for {
		select {
		case envelope := <-catcher.ChSystemInbound:
			if msg == nil { // Any message is ok
				return ""
			} else {
				// Ignore unmatching messages
				// This is important. Otherwise we would always have to check for
				// for the Start message first. And potentially for other intermediate messages.
				match := assertInboundMessage(envelope, msg, nil)
				if match == "" {
					return ""
				}
			}
		case <-time.After(TEST_TIMEOUT):
			return "Timeout while waiting for a system message"
		}
	}
}

func (catcher *Catcher) ShouldSend(receiver *actor.PID, msg interface{}) string {
	select {
	case envelope := <-catcher.ChUserOutbound:
		if msg == nil { // Any message wil suffice
			return ""
		} else {
			return assertOutboundMessage(envelope, msg, receiver)
		}
	case <-time.After(TEST_TIMEOUT):
		return "Timeout while waiting for sending"
	}
}

func (catcher *Catcher) ShouldNotSendOrReceive(pid *actor.PID) string {
	select {
	case envelope := <-catcher.ChUserOutbound:
		return fmt.Sprintf("Got outbound message: %#v", envelope.Message)
	case envelope := <-catcher.ChUserInbound:
		return fmt.Sprintf("Got inbound message: %#v", envelope.Message)
	case <-time.After(TEST_TIMEOUT):
		return ""
	}
}
<|endoftext|>


<commit_before>package handlers

import (
	"net/http"

	"github.com/TheTree/service-xboxlive/contexts"
	"gopkg.in/gin-gonic/gin.v1"
)

type GamertagHandler struct {
	ctx *contexts.ServiceContext
}

func (hdl GamertagHandler) Get(c *gin.Context) {
	gamertag := c.Param("gamertag")
	identity := hdl.ctx.XboxLiveStore.GetByGT(gamertag)

	if identity != nil {
		c.JSON(http.StatusOK, identity)
	} else {
		c.Status(http.StatusNotFound)
	}
}

func NewGamertagHandler(rg *gin.RouterGroup, ctx *contexts.ServiceContext) *GamertagHandler {
	hdl := &GamertagHandler{}
	hdl.ctx = ctx

	rg = rg.Group("gamertag")
	rg.GET("/:gamertag", hdl.Get)

	return hdl
}
<commit_msg>added some comments<commit_after>package handlers

import (
	"net/http"

	"github.com/TheTree/service-xboxlive/contexts"
	"gopkg.in/gin-gonic/gin.v1"
)

type GamertagHandler struct {
	ctx *contexts.ServiceContext
}

func (hdl GamertagHandler) Get(c *gin.Context) {
	gamertag := c.Param("gamertag")
	identity := hdl.ctx.XboxLiveStore.GetByGT(gamertag)

	if identity != nil {
		c.JSON(http.StatusOK, identity)
		return
	}

	// Request from xbox live
}

func NewGamertagHandler(rg *gin.RouterGroup, ctx *contexts.ServiceContext) *GamertagHandler {
	hdl := &GamertagHandler{}
	hdl.ctx = ctx

	rg = rg.Group("gamertag")
	rg.GET("/:gamertag", hdl.Get)

	return hdl
}
<|endoftext|>


<commit_before>package main

// Copyright 2015 MediaMath <http://www.mediamath.com>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import "testing"

func TestGetGoshMapFromArgs(t *testing.T) {
	goshMap, _ := getMap([]string{"foo/bar,git@github.com/MediaMath/foo.git", "salt,git@github.com/MediaMath/salt.git"})

	if len(goshMap) != 2 {
		t.Errorf("|%v|", goshMap)
	}

	if goshMap["foo/bar"] != "git@github.com/MediaMath/foo.git" {
		t.Errorf("|%v|", goshMap)
	}

	if goshMap["salt"] != "git@github.com/MediaMath/salt.git" {
		t.Errorf("|%v|", goshMap)
	}

}

func TestGetGoshMapMixOfImpliedAndExplicit(t *testing.T) {
	goshMap, _ := getMap([]string{"foo/bar/baz", "salt,git@github.com/MediaMath/salt.git"})

	if len(goshMap) != 2 {
		t.Errorf("|%v|", goshMap)
	}

	if goshMap["foo/bar/baz"] != "git@github.com:foo/bar.git" {
		t.Errorf("|%v|", goshMap)
	}

	if goshMap["salt"] != "git@github.com/MediaMath/salt.git" {
		t.Errorf("|%v|", goshMap)
	}
}

func TestImpliedGithubRepo(t *testing.T) {
	implied, _ := impliedGithubRepo("github.com/MediaMath/foo")

	if implied != "git@github.com:MediaMath/foo.git" {
		t.Errorf("Got:%v", implied)
	}

}

func TestImpliedNoHostProducesGithubUrl(t *testing.T) {
	implied, _ := impliedGithubRepo("bar/foo")

	if implied != "git@github.com:bar/foo.git" {
		t.Errorf("Got:%v", implied)
	}
}

func TestImpliedSubpackage(t *testing.T) {
	impliedWithHost, _ := impliedGithubRepo("github.com/bar/foo/baz")

	if impliedWithHost != "git@github.com:bar/foo.git" {
		t.Errorf("Got:%v", impliedWithHost)
	}

	impliedNoHost, _ := impliedGithubRepo("bar/foo/baz")

	if impliedNoHost != "git@github.com:bar/foo.git" {
		t.Errorf("Got:%v", impliedNoHost)
	}

	impliedDeep, _ := impliedGithubRepo("bar/foo/baz/goose/gander")

	if impliedDeep != "git@github.com:bar/foo.git" {
		t.Errorf("Got:%v", impliedDeep)
	}
}

func TestNonGithubHostFails(t *testing.T) {
	if _, norepo := impliedGithubRepo("foo.com/bar/baz"); norepo == nil {
		t.Errorf("Didnt get error on norepo")
	}
}

func TestSingleParamImplicationFails(t *testing.T) {
	if _, singleParam := impliedGithubRepo("foo"); singleParam == nil {
		t.Errorf("Didnt get error on only host")
	}
}
<commit_msg>update test as per code review<commit_after>package main

// Copyright 2015 MediaMath <http://www.mediamath.com>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import "testing"

func TestGetGoshMapFromArgs(t *testing.T) {
	goshMap, _ := getMap([]string{"foo/bar,git@github.com/MediaMath/foo.git", "salt,git@github.com/MediaMath/salt.git"})

	if len(goshMap) != 2 {
		t.Errorf("Map does not have appropriate number of items |%v|", goshMap)
	}

	if goshMap["foo/bar"] != "git@github.com/MediaMath/foo.git" {
		t.Errorf("Incorrect url for foo/bar", goshMap["foo/bar"])
	}

	if goshMap["salt"] != "git@github.com/MediaMath/salt.git" {
		t.Errorf("Incorrect url for salt", goshMap["salt"])
	}

}

func TestGetGoshMapMixOfImpliedAndExplicit(t *testing.T) {
	goshMap, _ := getMap([]string{"foo/bar/baz", "salt,git@github.com/MediaMath/salt.git"})

	if len(goshMap) != 2 {
		t.Errorf("Map does not have appropriate number of items |%v|", goshMap)
	}

	if goshMap["foo/bar/baz"] != "git@github.com/MediaMath/foo.git" {
		t.Errorf("Incorrect url for foo/bar/baz", goshMap["foo/bar"])
	}

	if goshMap["salt"] != "git@github.com/MediaMath/salt.git" {
		t.Errorf("Incorrect url for salt", goshMap["salt"])
	}
}

func TestImpliedGithubRepo(t *testing.T) {
	implied, _ := impliedGithubRepo("github.com/MediaMath/foo")

	if implied != "git@github.com:MediaMath/foo.git" {
		t.Errorf("Got:%v", implied)
	}

}

func TestImpliedNoHostProducesGithubUrl(t *testing.T) {
	implied, _ := impliedGithubRepo("bar/foo")

	if implied != "git@github.com:bar/foo.git" {
		t.Errorf("Got:%v", implied)
	}
}

func TestImpliedSubpackage(t *testing.T) {
	impliedWithHost, _ := impliedGithubRepo("github.com/bar/foo/baz")

	if impliedWithHost != "git@github.com:bar/foo.git" {
		t.Errorf("Got:%v", impliedWithHost)
	}

	impliedNoHost, _ := impliedGithubRepo("bar/foo/baz")

	if impliedNoHost != "git@github.com:bar/foo.git" {
		t.Errorf("Got:%v", impliedNoHost)
	}

	impliedDeep, _ := impliedGithubRepo("bar/foo/baz/goose/gander")

	if impliedDeep != "git@github.com:bar/foo.git" {
		t.Errorf("Got:%v", impliedDeep)
	}
}

func TestNonGithubHostFails(t *testing.T) {
	if _, norepo := impliedGithubRepo("foo.com/bar/baz"); norepo == nil {
		t.Errorf("Didnt get error on norepo")
	}
}

func TestSingleParamImplicationFails(t *testing.T) {
	if _, singleParam := impliedGithubRepo("foo"); singleParam == nil {
		t.Errorf("Didnt get error on only host")
	}
}
<|endoftext|>