<commit_before>package analysisflags

import (
	"flag"
	"fmt"
	"log"
	"sort"
	"strings"

	"golang.org/x/tools/go/analysis"
)

const help = `PROGNAME is a tool for static analysis of Go programs.

PROGNAME examines Go source code and reports suspicious constructs,
such as Printf calls whose arguments do not align with the format
string. It uses heuristics that do not guarantee all reports are
genuine problems, but it can find errors not caught by the compilers.
`

// Help implements the help subcommand for a multichecker or unitchecker
// style command. The optional args specify the analyzers to describe.
// Help calls log.Fatal if no such analyzer exists.
func Help(progname string, analyzers []*analysis.Analyzer, args []string) {
	// No args: show summary of all analyzers.
	if len(args) == 0 {
		fmt.Println(strings.Replace(help, "PROGNAME", progname, -1))
		fmt.Println("Registered analyzers:")
		fmt.Println()
		sort.Slice(analyzers, func(i, j int) bool {
			return analyzers[i].Name < analyzers[j].Name
		})
		for _, a := range analyzers {
			title := strings.Split(a.Doc, "\n\n")[0]
			fmt.Printf("    %-12s %s\n", a.Name, title)
		}
		fmt.Println("\nBy default all analyzers are run.")
		fmt.Println("To select specific analyzers, use the -NAME flag for each one,")
		fmt.Println(" or -NAME=false to run all analyzers not explicitly disabled.")

		// Show only the core command-line flags.
		fmt.Println("\nCore flags:")
		fmt.Println()
		fs := flag.NewFlagSet("", flag.ExitOnError)
		flag.VisitAll(func(f *flag.Flag) {
			if !strings.Contains(f.Name, ".") {
				fs.Var(f.Value, f.Name, f.Usage)
			}
		})
		fs.PrintDefaults()

		fmt.Printf("\nTo see details and flags of a specific analyzer, run '%s help name'.\n", progname)

		return
	}

	// Show help on specific analyzer(s).
outer:
	for _, arg := range args {
		for _, a := range analyzers {
			if a.Name == arg {
				paras := strings.Split(a.Doc, "\n\n")
				title := paras[0]
				fmt.Printf("%s: %s\n", a.Name, title)

				// Show only the flags relating to this analysis,
				// properly prefixed.
				first := true
				fs := flag.NewFlagSet(a.Name, flag.ExitOnError)
				a.Flags.VisitAll(func(f *flag.Flag) {
					if first {
						first = false
						fmt.Println("\nAnalyzer flags:")
						fmt.Println()
					}
					fs.Var(f.Value, a.Name+"."+f.Name, f.Usage)
				})
				fs.PrintDefaults()

				if len(paras) > 1 {
					fmt.Printf("\n%s\n", strings.Join(paras[1:], "\n\n"))
				}

				continue outer
			}
		}
		log.Fatalf("Analyzer %q not registered", arg)
	}
}
<commit_msg>cmd/vet: print help to stdout only<commit_after>package analysisflags

import (
	"flag"
	"fmt"
	"log"
	"os"
	"sort"
	"strings"

	"golang.org/x/tools/go/analysis"
)

const help = `PROGNAME is a tool for static analysis of Go programs.

PROGNAME examines Go source code and reports suspicious constructs,
such as Printf calls whose arguments do not align with the format
string. It uses heuristics that do not guarantee all reports are
genuine problems, but it can find errors not caught by the compilers.
`

// Help implements the help subcommand for a multichecker or unitchecker
// style command. The optional args specify the analyzers to describe.
// Help calls log.Fatal if no such analyzer exists.
func Help(progname string, analyzers []*analysis.Analyzer, args []string) {
	// No args: show summary of all analyzers.
	if len(args) == 0 {
		fmt.Println(strings.Replace(help, "PROGNAME", progname, -1))
		fmt.Println("Registered analyzers:")
		fmt.Println()
		sort.Slice(analyzers, func(i, j int) bool {
			return analyzers[i].Name < analyzers[j].Name
		})
		for _, a := range analyzers {
			title := strings.Split(a.Doc, "\n\n")[0]
			fmt.Printf("    %-12s %s\n", a.Name, title)
		}
		fmt.Println("\nBy default all analyzers are run.")
		fmt.Println("To select specific analyzers, use the -NAME flag for each one,")
		fmt.Println(" or -NAME=false to run all analyzers not explicitly disabled.")

		// Show only the core command-line flags.
		fmt.Println("\nCore flags:")
		fmt.Println()
		fs := flag.NewFlagSet("", flag.ExitOnError)
		flag.VisitAll(func(f *flag.Flag) {
			if !strings.Contains(f.Name, ".") {
				fs.Var(f.Value, f.Name, f.Usage)
			}
		})
		fs.SetOutput(os.Stdout)
		fs.PrintDefaults()

		fmt.Printf("\nTo see details and flags of a specific analyzer, run '%s help name'.\n", progname)

		return
	}

	// Show help on specific analyzer(s).
outer:
	for _, arg := range args {
		for _, a := range analyzers {
			if a.Name == arg {
				paras := strings.Split(a.Doc, "\n\n")
				title := paras[0]
				fmt.Printf("%s: %s\n", a.Name, title)

				// Show only the flags relating to this analysis,
				// properly prefixed.
				first := true
				fs := flag.NewFlagSet(a.Name, flag.ExitOnError)
				a.Flags.VisitAll(func(f *flag.Flag) {
					if first {
						first = false
						fmt.Println("\nAnalyzer flags:")
						fmt.Println()
					}
					fs.Var(f.Value, a.Name+"."+f.Name, f.Usage)
				})
				fs.SetOutput(os.Stdout)
				fs.PrintDefaults()

				if len(paras) > 1 {
					fmt.Printf("\n%s\n", strings.Join(paras[1:], "\n\n"))
				}

				continue outer
			}
		}
		log.Fatalf("Analyzer %q not registered", arg)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"github.com/streadway/amqp"
	"koding/tools/amqputil"
	"log"
)

type Consumer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
	tag     string
}

type Producer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
}

type JoinMsg struct {
	RoutingKey string `json:"routingKey"`
	Username   string `json:"username"`
}

type LeaveMsg struct {
	RoutingKey string `json:"routingKey"`
}

var authPairs map[string]string
var producer *Producer

func main() {
	log.Println("notification worker started")

	authPairs = make(map[string]string)

	var err error
	producer, err = createProducer()
	if err != nil {
		log.Println(err)
	}

	startRouting()

	select {}
}

func startRouting() {
	c := &Consumer{
		conn:    nil,
		channel: nil,
		tag:     "",
	}

	var err error

	log.Printf("creating consumer connections")
	c.conn = amqputil.CreateConnection("notification")
	c.channel = amqputil.CreateChannel(c.conn)

	err = c.channel.ExchangeDeclare("notification-control", "fanout", false, true, false, false, nil)
	if err != nil {
		log.Fatal("exchange.declare: %s", err)
	}

	err = c.channel.ExchangeDeclare("notification", "topic", false, true, false, false, nil)
	if err != nil {
		log.Fatal("exchange.declare: %s", err)
	}

	if _, err := c.channel.QueueDeclare("authWorker", false, true, false, false, nil); err != nil {
		log.Fatal("queue.declare: %s", err)
	}

	if err := c.channel.QueueBind("authWorker", "", "notification-control", false, nil); err != nil {
		log.Fatal("queue.bind: %s", err)
	}

	authStream, err := c.channel.Consume("authWorker", "", true, false, false, false, nil)
	if err != nil {
		log.Fatal("basic.consume: %s", err)
	}

	log.Println("routing started...")
	go func() {
		for msg := range authStream {
			log.Printf("got %dB message data: [%v]-[%s] %s",
				len(msg.Body),
				msg.DeliveryTag,
				msg.RoutingKey,
				msg.Body)

			switch msg.RoutingKey {
			case "auth.join":
				var join JoinMsg
				err := json.Unmarshal(msg.Body, &join)
				if err != nil {
					log.Print("bad json incoming msg: ", err)
				}

				authPairs[join.RoutingKey] = join.Username

				log.Println("Auth pairs:", authPairs) // this is just for debug

				go consumeFromUser(c, join.Username, join.RoutingKey)
			case "auth.leave":
				var leave LeaveMsg
				err := json.Unmarshal(msg.Body, &leave)
				if err != nil {
					log.Print("bad json incoming msg: ", err)
				}

				// delete user from the authPairs map and cancel it from consuming
				delete(authPairs, leave.RoutingKey)

				err = c.channel.Cancel(authPairs[leave.RoutingKey], false)
				if err != nil {
					log.Fatal("basic.cancel: %s", err)
				}

				log.Println("Auth pairs:", authPairs) // this is just for debug
			default:
				log.Println("routing key is not defined: ", msg.RoutingKey)
			}
		}

	}()

}

func consumeFromUser(c *Consumer, username, routingKey string) {
	if _, err := c.channel.QueueDeclare("", false, true, true, false, nil); err != nil {
		log.Fatal("queue.declare: %s", err)
	}

	if err := c.channel.QueueBind("", "chris", "notification", false, nil); err != nil {
		log.Fatal("queue.bind: %s", err)
	}

	messages, err := c.channel.Consume("", "", true, false, false, false, nil)
	if err != nil {
		log.Fatal("basic.consume: %s", err)
	}

	for msg := range messages {
		log.Printf("messages stream got %dB message data: [%v] %s",
			len(msg.Body),
			msg.DeliveryTag,
			msg.Body)

		publishToBroker(msg.Body, routingKey)
	}

}

func publishToBroker(data []byte, routingKey string) {
	msg := amqp.Publishing{
		Headers:         amqp.Table{},
		ContentType:     "text/plain",
		ContentEncoding: "",
		Body:            data,
		DeliveryMode:    1, // 1=non-persistent, 2=persistent
		Priority:        0, // 0-9
	}

	log.Println("publishing data ", string(data))
	err := producer.channel.Publish("broker", routingKey, false, false, msg)
	if err != nil {
		log.Printf("error while publishing proxy message: %s", err)
	}

}

func createProducer() (*Producer, error) {
	p := &Producer{
		conn:    nil,
		channel: nil,
	}

	log.Printf("creating publisher connections")

	p.conn = amqputil.CreateConnection("deneme")
	p.channel = amqputil.CreateChannel(p.conn)

	return p, nil
}
<commit_msg>notification-worker: dafuq is wrong with me<commit_after>package main

import (
	"encoding/json"
	"github.com/streadway/amqp"
	"koding/tools/amqputil"
	"log"
)

type Consumer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
	tag     string
}

type Producer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
}

type JoinMsg struct {
	RoutingKey string `json:"routingKey"`
	Username   string `json:"username"`
}

type LeaveMsg struct {
	RoutingKey string `json:"routingKey"`
}

var authPairs map[string]string
var producer *Producer

func main() {
	log.Println("notification worker started")

	authPairs = make(map[string]string)

	var err error
	producer, err = createProducer()
	if err != nil {
		log.Println(err)
	}

	startRouting()

	select {}
}

func startRouting() {
	c := &Consumer{
		conn:    nil,
		channel: nil,
		tag:     "",
	}

	var err error

	log.Printf("creating consumer connections")
	c.conn = amqputil.CreateConnection("notification")
	c.channel = amqputil.CreateChannel(c.conn)

	err = c.channel.ExchangeDeclare("notification-control", "fanout", false, true, false, false, nil)
	if err != nil {
		log.Fatal("exchange.declare: %s", err)
	}

	err = c.channel.ExchangeDeclare("notification", "topic", false, true, false, false, nil)
	if err != nil {
		log.Fatal("exchange.declare: %s", err)
	}

	if _, err := c.channel.QueueDeclare("authWorker", false, true, false, false, nil); err != nil {
		log.Fatal("queue.declare: %s", err)
	}

	if err := c.channel.QueueBind("authWorker", "", "notification-control", false, nil); err != nil {
		log.Fatal("queue.bind: %s", err)
	}

	authStream, err := c.channel.Consume("authWorker", "", true, false, false, false, nil)
	if err != nil {
		log.Fatal("basic.consume: %s", err)
	}

	log.Println("routing started...")
	go func() {
		for msg := range authStream {
			log.Printf("got %dB message data: [%v]-[%s] %s",
				len(msg.Body),
				msg.DeliveryTag,
				msg.RoutingKey,
				msg.Body)

			switch msg.RoutingKey {
			case "auth.join":
				var join JoinMsg
				err := json.Unmarshal(msg.Body, &join)
				if err != nil {
					log.Print("bad json incoming msg: ", err)
				}

				authPairs[join.RoutingKey] = join.Username

				log.Println("Auth pairs:", authPairs) // this is just for debug

				go consumeFromUser(c, join.Username, join.RoutingKey)
			case "auth.leave":
				var leave LeaveMsg
				err := json.Unmarshal(msg.Body, &leave)
				if err != nil {
					log.Print("bad json incoming msg: ", err)
				}

				// delete user from the authPairs map and cancel it from consuming
				delete(authPairs, leave.RoutingKey)

				err = c.channel.Cancel(authPairs[leave.RoutingKey], false)
				if err != nil {
					log.Fatal("basic.cancel: %s", err)
				}

				log.Println("Auth pairs:", authPairs) // this is just for debug
			default:
				log.Println("routing key is not defined: ", msg.RoutingKey)
			}
		}

	}()

}

func consumeFromUser(c *Consumer, username, routingKey string) {
	if _, err := c.channel.QueueDeclare("", false, true, true, false, nil); err != nil {
		log.Fatal("queue.declare: %s", err)
	}

	if err := c.channel.QueueBind("", username, "notification", false, nil); err != nil {
		log.Fatal("queue.bind: %s", err)
	}

	messages, err := c.channel.Consume("", "", true, false, false, false, nil)
	if err != nil {
		log.Fatal("basic.consume: %s", err)
	}

	for msg := range messages {
		log.Printf("messages stream got %dB message data: [%v] %s",
			len(msg.Body),
			msg.DeliveryTag,
			msg.Body)

		publishToBroker(msg.Body, routingKey)
	}

}

func publishToBroker(data []byte, routingKey string) {
	msg := amqp.Publishing{
		Headers:         amqp.Table{},
		ContentType:     "text/plain",
		ContentEncoding: "",
		Body:            data,
		DeliveryMode:    1, // 1=non-persistent, 2=persistent
		Priority:        0, // 0-9
	}

	log.Println("publishing data ", string(data))
	err := producer.channel.Publish("broker", routingKey, false, false, msg)
	if err != nil {
		log.Printf("error while publishing proxy message: %s", err)
	}

}

func createProducer() (*Producer, error) {
	p := &Producer{
		conn:    nil,
		channel: nil,
	}

	log.Printf("creating publisher connections")

	p.conn = amqputil.CreateConnection("deneme")
	p.channel = amqputil.CreateChannel(p.conn)

	return p, nil
}
<|endoftext|>


<commit_before>// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

package execplugin

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"runtime"
	"strings"

	"github.com/google/shlex"

	"github.com/pkg/errors"
	"sigs.k8s.io/kustomize/api/internal/plugins/utils"
	"sigs.k8s.io/kustomize/api/resmap"
	"sigs.k8s.io/yaml"
)

const (
	tmpConfigFilePrefix = "kust-plugin-config-"
)

// ExecPlugin record the name and args of an executable
// It triggers the executable generator and transformer
type ExecPlugin struct {
	// absolute path of the executable
	path string

	// Optional command line arguments to the executable
	// pulled from specially named fields in cfg.
	// This is for executables that don't want to parse YAML.
	args []string

	// Plugin configuration data.
	cfg []byte

	// PluginHelpers
	h *resmap.PluginHelpers
}

func NewExecPlugin(p string) *ExecPlugin {
	return &ExecPlugin{path: p}
}

func (p *ExecPlugin) ErrIfNotExecutable() error {
	f, err := os.Stat(p.path)
	if err != nil {
		return err
	}
	// In Windows, it is not possible to determine whether a
	// file is executable through file mode.
	if f.Mode()&0111 == 0000 && runtime.GOOS != "windows" {
		return fmt.Errorf("unexecutable plugin at: %s", p.path)
	}
	return nil
}

func (p *ExecPlugin) Path() string {
	return p.path
}

func (p *ExecPlugin) Args() []string {
	return p.args
}

func (p *ExecPlugin) Cfg() []byte {
	return p.cfg
}

func (p *ExecPlugin) Config(h *resmap.PluginHelpers, config []byte) error {
	p.h = h
	p.cfg = config
	return p.processOptionalArgsFields()
}

type argsConfig struct {
	ArgsOneLiner string `json:"argsOneLiner,omitempty" yaml:"argsOneLiner,omitempty"`
	ArgsFromFile string `json:"argsFromFile,omitempty" yaml:"argsFromFile,omitempty"`
}

func (p *ExecPlugin) processOptionalArgsFields() error {
	var c argsConfig
	yaml.Unmarshal(p.cfg, &c)
	if c.ArgsOneLiner != "" {
		p.args, _ = shlex.Split(c.ArgsOneLiner)
	}
	if c.ArgsFromFile != "" {
		content, err := p.h.Loader().Load(c.ArgsFromFile)
		if err != nil {
			return err
		}
		for _, x := range strings.Split(string(content), "\n") {
			x := strings.TrimLeft(x, " ")
			if x != "" {
				p.args = append(p.args, x)
			}
		}
	}
	return nil
}

func (p *ExecPlugin) Generate() (resmap.ResMap, error) {
	output, err := p.invokePlugin(nil)
	if err != nil {
		return nil, err
	}
	rm, err := p.h.ResmapFactory().NewResMapFromBytes(output)
	if err != nil {
		return nil, err
	}
	return utils.UpdateResourceOptions(rm)
}

func (p *ExecPlugin) Transform(rm resmap.ResMap) error {
	// add ResIds as annotations to all objects so that we can add them back
	inputRM, err := utils.GetResMapWithIDAnnotation(rm)
	if err != nil {
		return err
	}

	// encode the ResMap so it can be fed to the plugin
	resources, err := inputRM.AsYaml()
	if err != nil {
		return err
	}

	// invoke the plugin with resources as the input
	output, err := p.invokePlugin(resources)
	if err != nil {
		return fmt.Errorf("%v %s", err, string(output))
	}

	// update the original ResMap based on the output
	return utils.UpdateResMapValues(p.path, p.h, output, rm)
}

// invokePlugin writes plugin config to a temp file, then
// passes the full temp file path as the first arg to a process
// running the plugin binary.  Process output is returned.
func (p *ExecPlugin) invokePlugin(input []byte) ([]byte, error) {
	f, err := ioutil.TempFile("", tmpConfigFilePrefix)
	if err != nil {
		return nil, errors.Wrap(
			err, "creating tmp plugin config file")
	}
	_, err = f.Write(p.cfg)
	if err != nil {
		return nil, errors.Wrap(
			err, "writing plugin config to "+f.Name())
	}
	err = f.Close()
	if err != nil {
		return nil, errors.Wrap(
			err, "closing plugin config file "+f.Name())
	}
	//nolint:gosec
	cmd := exec.Command(
		p.path, append([]string{f.Name()}, p.args...)...)
	cmd.Env = p.getEnv()
	cmd.Stdin = bytes.NewReader(input)
	cmd.Stderr = os.Stderr
	if _, err := os.Stat(p.h.Loader().Root()); err == nil {
		cmd.Dir = p.h.Loader().Root()
	}
	result, err := cmd.Output()
	if err != nil {
		return nil, errors.Wrapf(
			err, "failure in plugin configured via %s; %v",
			f.Name(), err.Error())
	}
	return result, os.Remove(f.Name())
}

func (p *ExecPlugin) getEnv() []string {
	env := os.Environ()
	env = append(env,
		"KUSTOMIZE_PLUGIN_CONFIG_STRING="+string(p.cfg),
		"KUSTOMIZE_PLUGIN_CONFIG_ROOT="+p.h.Loader().Root())
	return env
}
<commit_msg>Add a comment about the behavior in Windows<commit_after>// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

package execplugin

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"runtime"
	"strings"

	"github.com/google/shlex"

	"github.com/pkg/errors"
	"sigs.k8s.io/kustomize/api/internal/plugins/utils"
	"sigs.k8s.io/kustomize/api/resmap"
	"sigs.k8s.io/yaml"
)

const (
	tmpConfigFilePrefix = "kust-plugin-config-"
)

// ExecPlugin record the name and args of an executable
// It triggers the executable generator and transformer
type ExecPlugin struct {
	// absolute path of the executable
	path string

	// Optional command line arguments to the executable
	// pulled from specially named fields in cfg.
	// This is for executables that don't want to parse YAML.
	args []string

	// Plugin configuration data.
	cfg []byte

	// PluginHelpers
	h *resmap.PluginHelpers
}

func NewExecPlugin(p string) *ExecPlugin {
	return &ExecPlugin{path: p}
}

func (p *ExecPlugin) ErrIfNotExecutable() error {
	f, err := os.Stat(p.path)
	if err != nil {
		return err
	}
	// In Windows, it is not possible to determine whether a
	// file is executable through file mode.
	// TODO: provide for setting the executable FileMode bit on Windows
	// The (fs *fileStat) Mode() (m FileMode) {} function in
	// https://golang.org/src/os/types_windows.go
	// lacks the ability to set the FileMode executable bit in response
	// to file data on Windows.
	if f.Mode()&0111 == 0000 && runtime.GOOS != "windows" {
		return fmt.Errorf("unexecutable plugin at: %s", p.path)
	}
	return nil
}

func (p *ExecPlugin) Path() string {
	return p.path
}

func (p *ExecPlugin) Args() []string {
	return p.args
}

func (p *ExecPlugin) Cfg() []byte {
	return p.cfg
}

func (p *ExecPlugin) Config(h *resmap.PluginHelpers, config []byte) error {
	p.h = h
	p.cfg = config
	return p.processOptionalArgsFields()
}

type argsConfig struct {
	ArgsOneLiner string `json:"argsOneLiner,omitempty" yaml:"argsOneLiner,omitempty"`
	ArgsFromFile string `json:"argsFromFile,omitempty" yaml:"argsFromFile,omitempty"`
}

func (p *ExecPlugin) processOptionalArgsFields() error {
	var c argsConfig
	yaml.Unmarshal(p.cfg, &c)
	if c.ArgsOneLiner != "" {
		p.args, _ = shlex.Split(c.ArgsOneLiner)
	}
	if c.ArgsFromFile != "" {
		content, err := p.h.Loader().Load(c.ArgsFromFile)
		if err != nil {
			return err
		}
		for _, x := range strings.Split(string(content), "\n") {
			x := strings.TrimLeft(x, " ")
			if x != "" {
				p.args = append(p.args, x)
			}
		}
	}
	return nil
}

func (p *ExecPlugin) Generate() (resmap.ResMap, error) {
	output, err := p.invokePlugin(nil)
	if err != nil {
		return nil, err
	}
	rm, err := p.h.ResmapFactory().NewResMapFromBytes(output)
	if err != nil {
		return nil, err
	}
	return utils.UpdateResourceOptions(rm)
}

func (p *ExecPlugin) Transform(rm resmap.ResMap) error {
	// add ResIds as annotations to all objects so that we can add them back
	inputRM, err := utils.GetResMapWithIDAnnotation(rm)
	if err != nil {
		return err
	}

	// encode the ResMap so it can be fed to the plugin
	resources, err := inputRM.AsYaml()
	if err != nil {
		return err
	}

	// invoke the plugin with resources as the input
	output, err := p.invokePlugin(resources)
	if err != nil {
		return fmt.Errorf("%v %s", err, string(output))
	}

	// update the original ResMap based on the output
	return utils.UpdateResMapValues(p.path, p.h, output, rm)
}

// invokePlugin writes plugin config to a temp file, then
// passes the full temp file path as the first arg to a process
// running the plugin binary.  Process output is returned.
func (p *ExecPlugin) invokePlugin(input []byte) ([]byte, error) {
	f, err := ioutil.TempFile("", tmpConfigFilePrefix)
	if err != nil {
		return nil, errors.Wrap(
			err, "creating tmp plugin config file")
	}
	_, err = f.Write(p.cfg)
	if err != nil {
		return nil, errors.Wrap(
			err, "writing plugin config to "+f.Name())
	}
	err = f.Close()
	if err != nil {
		return nil, errors.Wrap(
			err, "closing plugin config file "+f.Name())
	}
	//nolint:gosec
	cmd := exec.Command(
		p.path, append([]string{f.Name()}, p.args...)...)
	cmd.Env = p.getEnv()
	cmd.Stdin = bytes.NewReader(input)
	cmd.Stderr = os.Stderr
	if _, err := os.Stat(p.h.Loader().Root()); err == nil {
		cmd.Dir = p.h.Loader().Root()
	}
	result, err := cmd.Output()
	if err != nil {
		return nil, errors.Wrapf(
			err, "failure in plugin configured via %s; %v",
			f.Name(), err.Error())
	}
	return result, os.Remove(f.Name())
}

func (p *ExecPlugin) getEnv() []string {
	env := os.Environ()
	env = append(env,
		"KUSTOMIZE_PLUGIN_CONFIG_STRING="+string(p.cfg),
		"KUSTOMIZE_PLUGIN_CONFIG_ROOT="+p.h.Loader().Root())
	return env
}
<|endoftext|>


<commit_before>package etcdstoreadapter_test

import (
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	. "github.com/onsi/gomega"

	"github.com/cloudfoundry/storeadapter/storerunner/etcdstorerunner"

	"os"
	"os/signal"
	"testing"
)

var etcdRunner *etcdstorerunner.ETCDClusterRunner

func TestStoreAdapter(t *testing.T) {
	registerSignalHandler()
	RegisterFailHandler(Fail)

	etcdPort := 5000 + (config.GinkgoConfig.ParallelNode-1)*10
	etcdRunner = etcdstorerunner.NewETCDClusterRunner(etcdPort, 1)

	etcdRunner.Start()

	RunSpecs(t, "ETCD Store Adapter Suite")

	stopStores()
}

var _ = BeforeEach(func() {
	etcdRunner.Reset()
})

func stopStores() {
	etcdRunner.Stop()
}

func registerSignalHandler() {
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, os.Kill)

		select {
		case <-c:
			stopStores()
			os.Exit(0)
		}
	}()
}
<commit_msg>bump default eventually timeout for etcd<commit_after>package etcdstoreadapter_test

import (
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	. "github.com/onsi/gomega"

	"github.com/cloudfoundry/storeadapter/storerunner/etcdstorerunner"

	"os"
	"os/signal"
	"testing"
	"time"
)

var etcdRunner *etcdstorerunner.ETCDClusterRunner

func TestStoreAdapter(t *testing.T) {
	registerSignalHandler()
	RegisterFailHandler(Fail)

	SetDefaultEventuallyTimeout(5 * time.Second)

	etcdPort := 5000 + (config.GinkgoConfig.ParallelNode-1)*10
	etcdRunner = etcdstorerunner.NewETCDClusterRunner(etcdPort, 1)

	etcdRunner.Start()

	RunSpecs(t, "ETCD Store Adapter Suite")

	stopStores()
}

var _ = BeforeEach(func() {
	etcdRunner.Reset()
})

func stopStores() {
	etcdRunner.Stop()
}

func registerSignalHandler() {
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, os.Kill)

		select {
		case <-c:
			stopStores()
			os.Exit(0)
		}
	}()
}
<|endoftext|>


<commit_before>package scheduler

import (
	log "github.com/Sirupsen/logrus"

	"github.com/codedellemc/scaleio-framework/scaleio-scheduler/config"
	sched "github.com/codedellemc/scaleio-framework/scaleio-scheduler/mesos/sched"
	mesos "github.com/codedellemc/scaleio-framework/scaleio-scheduler/mesos/v1"
)

func (s *ScaleIOScheduler) subscribed(event *sched.Event) {
	sub := event.GetSubscribed()
	s.Framework.Id = sub.FrameworkId
	log.Infoln("[EVENT] Received SUBSCRIBED. FrameworkID:", sub.FrameworkId.GetValue())
}

func (s *ScaleIOScheduler) offers(event *sched.Event) {
	offers := event.GetOffers().GetOffers()
	log.Infoln("[EVENT] Received", len(offers), "OFFERS")

	//TODO do a better job at selecting the MDM nodes if not preconfigured
	//loop through offers and build "State" object.
	//TODO retrieve pri, sec, tb from zookeeper. Use libkv.
	for _, offer := range offers {
		if doesExecutorExistOnHost(offer) {
			log.Debugln("Skipping node as it already has an executor on it.")
			continue
		}

		node := findScaleIONodeByHostname(s.Server.State.ScaleIO.Nodes, offer.GetHostname())
		if node != nil {
			log.Errorln("Found existing node by Hostname:", offer.GetHostname())
			continue
		}

		ID := s.getNextNodeID()
		persona := s.getNodeType(ID)
		log.Debugln("Creating new metadata node. ID:", ID, "Persona:", persona)
		s.Server.State.ScaleIO.Nodes = append(s.Server.State.ScaleIO.Nodes,
			prepareScaleIONode(offer, persona, ID))
	}
	//TODO save pri, sec, tb to zookeeper. Use libkv.

	//setup executors
	for _, offer := range offers {
		log.Debugln("Offer:", offer)

		cpuResources := filterResources(offer.Resources, func(res *mesos.Resource) bool {
			return res.GetName() == "cpus"
		})
		cpus := 0.0
		for _, res := range cpuResources {
			cpus += res.GetScalar().GetValue()
		}

		memResources := filterResources(offer.Resources, func(res *mesos.Resource) bool {
			return res.GetName() == "mem"
		})
		mems := 0.0
		for _, res := range memResources {
			mems += res.GetScalar().GetValue()
		}

		log.Infoln("Received Offer <", offer.GetId().GetValue(), ",", offer.GetHostname(),
			"> with cpus=", cpus, " mem=", mems)

		// account for executor resources if there's an executor already running on the slave
		if doesExecutorExistOnHost(offer) {
			log.Debugln("Skipping agent as it already has an executor on it. Decline offer.")
			message := generateDeclineCall(s.Config, offer)
			s.send(message)
			continue
		}

		//find node based on state
		node := findScaleIONodeByHostname(s.Server.State.ScaleIO.Nodes, offer.GetHostname())
		if node == nil {
			log.Errorln("Unable to find node by Hostname:", offer.GetHostname())
			message := generateDeclineCall(s.Config, offer)
			s.send(message)
			continue
		}

		//if node is an MDM node
		if IsNodeAnMDMNode(node) {
			if config.CPUPerMdmExecutor >= (cpus*s.Config.ExecutorCPUFactor) ||
				config.MemPerMdmExecutor >= (mems*s.Config.ExecutorMemoryFactor) {
				log.Warnln("Does not have enough resources to install ScaleIO (MDM) on node",
					offer.GetId().GetValue(), ",", offer.GetHostname())
				log.Warnln("CPU Required:", config.CPUPerMdmExecutor, "CPU Available:", cpus*s.Config.ExecutorCPUFactor)
				log.Warnln("MEM Required:", config.MemPerMdmExecutor, "MEM Available:", mems*s.Config.ExecutorMemoryFactor)
				message := generateDeclineCall(s.Config, offer)
				s.send(message)
				continue
			}
		} else {
			if config.CPUPerNonExecutor >= cpus || config.MemPerNonExecutor >= mems {
				log.Warnln("Does not have enough resources to install ScaleIO (Non-MDM) on node",
					offer.GetId().GetValue(), ",", offer.GetHostname())
				log.Warnln("CPU Required:", config.CPUPerMdmExecutor, "CPU Available:", cpus*s.Config.ExecutorCPUFactor)
				log.Warnln("MEM Required:", config.MemPerMdmExecutor, "MEM Available:", mems*s.Config.ExecutorMemoryFactor)
				message := generateDeclineCall(s.Config, offer)
				s.send(message)
				continue
			}
		}

		//generate accept call to launch executor
		message := generateAcceptCall(s.Config, offer, node)
		s.send(message)
	}
}

func (s *ScaleIOScheduler) rescind(event *sched.Event) {
	rescind := event.GetRescind()
	log.Infoln("[EVENT] Received RESCIND:", rescind.String())
}

func (s *ScaleIOScheduler) update(event *sched.Event) {
	update := event.GetUpdate().GetStatus()
	log.Infoln("[EVENT] Received STATUS:", update.String())

	ackRequired := len(update.Uuid) > 0
	if ackRequired {
		message := generateAcknowledgeCall(s.Framework, update)
		s.send(message)
	} else {
		log.Infoln("Not sending ACK, update is not from slave")
	}
}

func (s *ScaleIOScheduler) message(event *sched.Event) {
	message := event.GetMessage()
	log.Infoln("[EVENT] Received MESSAGE:", message.String())
}

func (s *ScaleIOScheduler) failure(event *sched.Event) {
	log.Infoln("[EVENT] Received FAILURE")
	fail := event.GetFailure()
	if fail.ExecutorId != nil {
		log.Infoln(
			"Executor", fail.ExecutorId.GetValue(), "terminated",
			"with status", fail.GetStatus(),
			"on agent", fail.GetAgentId().GetValue(),
		)
	} else {
		if fail.GetAgentId() != nil {
			log.Infoln("Agent", fail.GetAgentId().GetValue(), "failed")
		}
	}
}

func (s *ScaleIOScheduler) error(event *sched.Event) {
	err := event.GetError().GetMessage()
	log.Infoln("[EVENT] Received ERROR:", err)
}

func (s *ScaleIOScheduler) heartbeat(event *sched.Event) {
	log.Infoln("[EVENT] Received HEARTBEAT")
}
<commit_msg>Use the correct provided config value<commit_after>package scheduler

import (
	log "github.com/Sirupsen/logrus"

	sched "github.com/codedellemc/scaleio-framework/scaleio-scheduler/mesos/sched"
	mesos "github.com/codedellemc/scaleio-framework/scaleio-scheduler/mesos/v1"
)

func (s *ScaleIOScheduler) subscribed(event *sched.Event) {
	sub := event.GetSubscribed()
	s.Framework.Id = sub.FrameworkId
	log.Infoln("[EVENT] Received SUBSCRIBED. FrameworkID:", sub.FrameworkId.GetValue())
}

func (s *ScaleIOScheduler) offers(event *sched.Event) {
	offers := event.GetOffers().GetOffers()
	log.Infoln("[EVENT] Received", len(offers), "OFFERS")

	//TODO do a better job at selecting the MDM nodes if not preconfigured
	//loop through offers and build "State" object.
	//TODO retrieve pri, sec, tb from zookeeper. Use libkv.
	for _, offer := range offers {
		if doesExecutorExistOnHost(offer) {
			log.Debugln("Skipping node as it already has an executor on it.")
			continue
		}

		node := findScaleIONodeByHostname(s.Server.State.ScaleIO.Nodes, offer.GetHostname())
		if node != nil {
			log.Errorln("Found existing node by Hostname:", offer.GetHostname())
			continue
		}

		ID := s.getNextNodeID()
		persona := s.getNodeType(ID)
		log.Debugln("Creating new metadata node. ID:", ID, "Persona:", persona)
		s.Server.State.ScaleIO.Nodes = append(s.Server.State.ScaleIO.Nodes,
			prepareScaleIONode(offer, persona, ID))
	}
	//TODO save pri, sec, tb to zookeeper. Use libkv.

	//setup executors
	for _, offer := range offers {
		log.Debugln("Offer:", offer)

		cpuResources := filterResources(offer.Resources, func(res *mesos.Resource) bool {
			return res.GetName() == "cpus"
		})
		cpus := 0.0
		for _, res := range cpuResources {
			cpus += res.GetScalar().GetValue()
		}

		memResources := filterResources(offer.Resources, func(res *mesos.Resource) bool {
			return res.GetName() == "mem"
		})
		mems := 0.0
		for _, res := range memResources {
			mems += res.GetScalar().GetValue()
		}

		log.Infoln("Received Offer <", offer.GetId().GetValue(), ",", offer.GetHostname(),
			"> with cpus=", cpus, " mem=", mems)

		// account for executor resources if there's an executor already running on the slave
		if doesExecutorExistOnHost(offer) {
			log.Debugln("Skipping agent as it already has an executor on it. Decline offer.")
			message := generateDeclineCall(s.Config, offer)
			s.send(message)
			continue
		}

		//find node based on state
		node := findScaleIONodeByHostname(s.Server.State.ScaleIO.Nodes, offer.GetHostname())
		if node == nil {
			log.Errorln("Unable to find node by Hostname:", offer.GetHostname())
			message := generateDeclineCall(s.Config, offer)
			s.send(message)
			continue
		}

		//if node is an MDM node
		if IsNodeAnMDMNode(node) {
			if s.Config.ExecutorMdmCPU >= (cpus*s.Config.ExecutorCPUFactor) ||
				s.Config.ExecutorMdmMemory >= (mems*s.Config.ExecutorMemoryFactor) {
				log.Warnln("Does not have enough resources to install ScaleIO (MDM) on node",
					offer.GetId().GetValue(), ",", offer.GetHostname())
				log.Warnln("CPU Required:", s.Config.ExecutorMdmCPU, "CPU Available:", cpus*s.Config.ExecutorCPUFactor)
				log.Warnln("MEM Required:", s.Config.ExecutorMdmMemory, "MEM Available:", mems*s.Config.ExecutorMemoryFactor)
				message := generateDeclineCall(s.Config, offer)
				s.send(message)
				continue
			}
		} else {
			if s.Config.ExecutorNonCPU >= cpus || s.Config.ExecutorNonMemory >= mems {
				log.Warnln("Does not have enough resources to install ScaleIO (Non-MDM) on node",
					offer.GetId().GetValue(), ",", offer.GetHostname())
				log.Warnln("CPU Required:", s.Config.ExecutorNonCPU, "CPU Available:", cpus*s.Config.ExecutorCPUFactor)
				log.Warnln("MEM Required:", s.Config.ExecutorNonMemory, "MEM Available:", mems*s.Config.ExecutorMemoryFactor)
				message := generateDeclineCall(s.Config, offer)
				s.send(message)
				continue
			}
		}

		//generate accept call to launch executor
		message := generateAcceptCall(s.Config, offer, node)
		s.send(message)
	}
}

func (s *ScaleIOScheduler) rescind(event *sched.Event) {
	rescind := event.GetRescind()
	log.Infoln("[EVENT] Received RESCIND:", rescind.String())
}

func (s *ScaleIOScheduler) update(event *sched.Event) {
	update := event.GetUpdate().GetStatus()
	log.Infoln("[EVENT] Received STATUS:", update.String())

	ackRequired := len(update.Uuid) > 0
	if ackRequired {
		message := generateAcknowledgeCall(s.Framework, update)
		s.send(message)
	} else {
		log.Infoln("Not sending ACK, update is not from slave")
	}
}

func (s *ScaleIOScheduler) message(event *sched.Event) {
	message := event.GetMessage()
	log.Infoln("[EVENT] Received MESSAGE:", message.String())
}

func (s *ScaleIOScheduler) failure(event *sched.Event) {
	log.Infoln("[EVENT] Received FAILURE")
	fail := event.GetFailure()
	if fail.ExecutorId != nil {
		log.Infoln(
			"Executor", fail.ExecutorId.GetValue(), "terminated",
			"with status", fail.GetStatus(),
			"on agent", fail.GetAgentId().GetValue(),
		)
	} else {
		if fail.GetAgentId() != nil {
			log.Infoln("Agent", fail.GetAgentId().GetValue(), "failed")
		}
	}
}

func (s *ScaleIOScheduler) error(event *sched.Event) {
	err := event.GetError().GetMessage()
	log.Infoln("[EVENT] Received ERROR:", err)
}

func (s *ScaleIOScheduler) heartbeat(event *sched.Event) {
	log.Infoln("[EVENT] Received HEARTBEAT")
}
<|endoftext|>


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

// Google's Omaha application update protocol, version 3.
//
// Omaha is a poll based protocol using XML. Requests are made by clients to
// check for updates or report events of an update process. Responses are given
// by the server to provide update information, if any, or to simply
// acknowledge the receipt of event status.
//
// https://github.com/google/omaha/blob/master/doc/ServerProtocolV3.md
package omaha

import (
	"encoding/xml"
	"io"
)

// Request sent by the Omaha client
type Request struct {
	XMLName       xml.Name      `xml:"request" json:"-"`
	OS            *OS           `xml:"os"`
	Apps          []*AppRequest `xml:"app"`
	Protocol      string        `xml:"protocol,attr"`
	InstallSource string        `xml:"installsource,attr,omitempty"`
	IsMachine     string        `xml:"ismachine,attr,omitempty"`
	RequestID     string        `xml:"requestid,attr,omitempty"`
	SessionID     string        `xml:"sessionid,attr,omitempty"`
	TestSource    string        `xml:"testsource,attr,omitempty"`
	UserID        string        `xml:"userid,attr,omitempty"`
	Version       string        `xml:"version,attr,omitempty"`

	// update engine extension, duplicates the version attribute.
	UpdaterVersion string `xml:"updaterversion,attr,omitempty"`
}

func NewRequest() *Request {
	return &Request{
		Protocol: "3.0",
		// TODO(marineam) set a default client Version
		OS: &OS{
			Platform: LocalPlatform(),
			Arch:     LocalArch(),
			// TODO(marineam): Version and ServicePack
		},
	}
}

// ParseRequest verifies and returns the parsed Request document.
// The MIME Content-Type header may be provided to sanity check its
// value; if blank it is assumed to be XML in UTF-8.
func ParseRequest(contentType string, body io.Reader) (*Request, error) {
	if err := checkContentType(contentType); err != nil {
		return nil, err
	}

	r := &Request{}
	if err := parseReqOrResp(body, r); err != nil {
		return nil, err
	}

	return r, nil
}

func (r *Request) AddApp(id, version string) *AppRequest {
	a := &AppRequest{ID: id, Version: version}
	r.Apps = append(r.Apps, a)
	return a
}

func (r *Request) GetApp(id string) *AppRequest {
	for _, app := range r.Apps {
		if app.ID == id {
			return app
		}
	}
	return nil
}

type AppRequest struct {
	Ping        *PingRequest    `xml:"ping"`
	UpdateCheck *UpdateRequest  `xml:"updatecheck"`
	Events      []*EventRequest `xml:"event" json:",omitempty"`
	ID          string          `xml:"appid,attr,omitempty"`
	Client      string          `xml:"client,attr,omitempty"`
	InstallAge  string          `xml:"installage,attr,omitempty"`
	Lang        string          `xml:"lang,attr,omitempty"`
	NextVersion string          `xml:"nextversion,attr,omitempty"`
	Version     string          `xml:"version,attr,omitempty"`

	// update engine extensions
	Board     string `xml:"board,attr,omitempty"`
	DeltaOK   bool   `xml:"delta_okay,attr,omitempty"`
	FromTrack string `xml:"from_track,attr,omitempty"`
	Track     string `xml:"track,attr,omitempty"`

	// coreos update engine extensions
	AlephVersion string `xml:"alephversion,attr,omitempty"`
	BootID       string `xml:"bootid,attr,omitempty"`
	MachineID    string `xml:"machineid,attr,omitempty"`
	OEM          string `xml:"oem,attr,omitempty"`
	OEMVersion   string `xml:"oemversion,attr,omitempty"`
}

func (a *AppRequest) AddUpdateCheck() *UpdateRequest {
	a.UpdateCheck = &UpdateRequest{}
	return a.UpdateCheck
}

func (a *AppRequest) AddPing() *PingRequest {
	a.Ping = &PingRequest{Active: 1}
	return a.Ping
}

func (a *AppRequest) AddEvent() *EventRequest {
	event := &EventRequest{}
	a.Events = append(a.Events, event)
	return event
}

type UpdateRequest struct {
	TargetVersionPrefix string `xml:"targetversionprefix,attr,omitempty"`
}

type PingRequest struct {
	Active               int  `xml:"active,attr,omitempty"`
	LastActiveReportDays *int `xml:"a,attr,omitempty"`
	LastReportDays       int  `xml:"r,attr,omitempty"`
}

type EventRequest struct {
	Type            EventType   `xml:"eventtype,attr"`
	Result          EventResult `xml:"eventresult,attr"`
	ErrorCode       string      `xml:"errorcode,attr,omitempty"`
	NextVersion     string      `xml:"nextversion,attr,omitempty"`
	PreviousVersion string      `xml:"previousversion,attr,omitempty"`
}

// Response sent by the Omaha server
type Response struct {
	XMLName  xml.Name       `xml:"response" json:"-"`
	DayStart DayStart       `xml:"daystart"`
	Apps     []*AppResponse `xml:"app"`
	Protocol string         `xml:"protocol,attr"`
	Server   string         `xml:"server,attr"`
}

func NewResponse() *Response {
	return &Response{
		Protocol: "3.0",
		Server:   "go-omaha",
		DayStart: DayStart{ElapsedSeconds: "0"},
	}
}

// ParseResponse verifies and returns the parsed Response document.
// The MIME Content-Type header may be provided to sanity check its
// value; if blank it is assumed to be XML in UTF-8.
func ParseResponse(contentType string, body io.Reader) (*Response, error) {
	if err := checkContentType(contentType); err != nil {
		return nil, err
	}

	r := &Response{}
	if err := parseReqOrResp(body, r); err != nil {
		return nil, err
	}

	return r, nil
}

type DayStart struct {
	ElapsedSeconds string `xml:"elapsed_seconds,attr"`
}

func (r *Response) AddApp(id string, status AppStatus) *AppResponse {
	a := &AppResponse{ID: id, Status: status}
	r.Apps = append(r.Apps, a)
	return a
}

func (r *Response) GetApp(id string) *AppResponse {
	for _, app := range r.Apps {
		if app.ID == id {
			return app
		}
	}
	return nil
}

type AppResponse struct {
	Ping        *PingResponse    `xml:"ping"`
	UpdateCheck *UpdateResponse  `xml:"updatecheck"`
	Events      []*EventResponse `xml:"event" json:",omitempty"`
	ID          string           `xml:"appid,attr,omitempty"`
	Status      AppStatus        `xml:"status,attr,omitempty"`
}

func (a *AppResponse) AddUpdateCheck(status UpdateStatus) *UpdateResponse {
	a.UpdateCheck = &UpdateResponse{Status: status}
	return a.UpdateCheck
}

func (a *AppResponse) AddPing() *PingResponse {
	a.Ping = &PingResponse{"ok"}
	return a.Ping
}

func (a *AppResponse) AddEvent() *EventResponse {
	event := &EventResponse{"ok"}
	a.Events = append(a.Events, event)
	return event
}

type UpdateResponse struct {
	URLs     []*URL       `xml:"urls>url" json:",omitempty"`
	Manifest *Manifest    `xml:"manifest"`
	Status   UpdateStatus `xml:"status,attr,omitempty"`
}

func (u *UpdateResponse) AddURL(codebase string) *URL {
	url := &URL{CodeBase: codebase}
	u.URLs = append(u.URLs, url)
	return url
}

func (u *UpdateResponse) AddManifest(version string) *Manifest {
	u.Manifest = &Manifest{Version: version}
	return u.Manifest
}

type PingResponse struct {
	Status string `xml:"status,attr"` // Always "ok".
}

type EventResponse struct {
	Status string `xml:"status,attr"` // Always "ok".
}

type OS struct {
	Platform    string `xml:"platform,attr,omitempty"`
	Version     string `xml:"version,attr,omitempty"`
	ServicePack string `xml:"sp,attr,omitempty"`
	Arch        string `xml:"arch,attr,omitempty"`
}

type URL struct {
	CodeBase string `xml:"codebase,attr"`
}

type Manifest struct {
	Packages []*Package `xml:"packages>package"`
	Actions  []*Action  `xml:"actions>action"`
	Version  string     `xml:"version,attr"`
}

func (m *Manifest) AddPackage() *Package {
	p := &Package{}
	m.Packages = append(m.Packages, p)
	return p
}

func (m *Manifest) AddPackageFromPath(path string) (*Package, error) {
	p := &Package{}
	if err := p.FromPath(path); err != nil {
		return nil, err
	}
	m.Packages = append(m.Packages, p)
	return p, nil
}

func (m *Manifest) AddAction(event string) *Action {
	a := &Action{Event: event}
	m.Actions = append(m.Actions, a)
	return a
}

type Action struct {
	Event string `xml:"event,attr"`

	// update engine extensions for event="postinstall"
	DisplayVersion        string `xml:"DisplayVersion,attr,omitempty"`
	SHA256                string `xml:"sha256,attr,omitempty"`
	NeedsAdmin            bool   `xml:"needsadmin,attr,omitempty"`
	IsDeltaPayload        bool   `xml:"IsDeltaPayload,attr,omitempty"`
	DisablePayloadBackoff bool   `xml:"DisablePayloadBackoff,attr,omitempty"`
	MaxFailureCountPerURL uint   `xml:"MaxFailureCountPerUrl,attr,omitempty"`
	MetadataSignatureRsa  string `xml:"MetadataSignatureRsa,attr,omitempty"`
	MetadataSize          string `xml:"MetadataSize,attr,omitempty"`
	Deadline              string `xml:"deadline,attr,omitempty"`
	MoreInfo              string `xml:"MoreInfo,attr,omitempty"`
	Prompt                bool   `xml:"Prompt,attr,omitempty"`
}
<commit_msg>protocol: change IsMachine flag to int<commit_after>// Copyright 2013-2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Google's Omaha application update protocol, version 3.
//
// Omaha is a poll based protocol using XML. Requests are made by clients to
// check for updates or report events of an update process. Responses are given
// by the server to provide update information, if any, or to simply
// acknowledge the receipt of event status.
//
// https://github.com/google/omaha/blob/master/doc/ServerProtocolV3.md
package omaha

import (
	"encoding/xml"
	"io"
)

// Request sent by the Omaha client
type Request struct {
	XMLName       xml.Name      `xml:"request" json:"-"`
	OS            *OS           `xml:"os"`
	Apps          []*AppRequest `xml:"app"`
	Protocol      string        `xml:"protocol,attr"`
	InstallSource string        `xml:"installsource,attr,omitempty"`
	IsMachine     int           `xml:"ismachine,attr,omitempty"`
	RequestID     string        `xml:"requestid,attr,omitempty"`
	SessionID     string        `xml:"sessionid,attr,omitempty"`
	TestSource    string        `xml:"testsource,attr,omitempty"`
	UserID        string        `xml:"userid,attr,omitempty"`
	Version       string        `xml:"version,attr,omitempty"`

	// update engine extension, duplicates the version attribute.
	UpdaterVersion string `xml:"updaterversion,attr,omitempty"`
}

func NewRequest() *Request {
	return &Request{
		Protocol: "3.0",
		// TODO(marineam) set a default client Version
		OS: &OS{
			Platform: LocalPlatform(),
			Arch:     LocalArch(),
			// TODO(marineam): Version and ServicePack
		},
	}
}

// ParseRequest verifies and returns the parsed Request document.
// The MIME Content-Type header may be provided to sanity check its
// value; if blank it is assumed to be XML in UTF-8.
func ParseRequest(contentType string, body io.Reader) (*Request, error) {
	if err := checkContentType(contentType); err != nil {
		return nil, err
	}

	r := &Request{}
	if err := parseReqOrResp(body, r); err != nil {
		return nil, err
	}

	return r, nil
}

func (r *Request) AddApp(id, version string) *AppRequest {
	a := &AppRequest{ID: id, Version: version}
	r.Apps = append(r.Apps, a)
	return a
}

func (r *Request) GetApp(id string) *AppRequest {
	for _, app := range r.Apps {
		if app.ID == id {
			return app
		}
	}
	return nil
}

type AppRequest struct {
	Ping        *PingRequest    `xml:"ping"`
	UpdateCheck *UpdateRequest  `xml:"updatecheck"`
	Events      []*EventRequest `xml:"event" json:",omitempty"`
	ID          string          `xml:"appid,attr,omitempty"`
	Client      string          `xml:"client,attr,omitempty"`
	InstallAge  string          `xml:"installage,attr,omitempty"`
	Lang        string          `xml:"lang,attr,omitempty"`
	NextVersion string          `xml:"nextversion,attr,omitempty"`
	Version     string          `xml:"version,attr,omitempty"`

	// update engine extensions
	Board     string `xml:"board,attr,omitempty"`
	DeltaOK   bool   `xml:"delta_okay,attr,omitempty"`
	FromTrack string `xml:"from_track,attr,omitempty"`
	Track     string `xml:"track,attr,omitempty"`

	// coreos update engine extensions
	AlephVersion string `xml:"alephversion,attr,omitempty"`
	BootID       string `xml:"bootid,attr,omitempty"`
	MachineID    string `xml:"machineid,attr,omitempty"`
	OEM          string `xml:"oem,attr,omitempty"`
	OEMVersion   string `xml:"oemversion,attr,omitempty"`
}

func (a *AppRequest) AddUpdateCheck() *UpdateRequest {
	a.UpdateCheck = &UpdateRequest{}
	return a.UpdateCheck
}

func (a *AppRequest) AddPing() *PingRequest {
	a.Ping = &PingRequest{Active: 1}
	return a.Ping
}

func (a *AppRequest) AddEvent() *EventRequest {
	event := &EventRequest{}
	a.Events = append(a.Events, event)
	return event
}

type UpdateRequest struct {
	TargetVersionPrefix string `xml:"targetversionprefix,attr,omitempty"`
}

type PingRequest struct {
	Active               int  `xml:"active,attr,omitempty"`
	LastActiveReportDays *int `xml:"a,attr,omitempty"`
	LastReportDays       int  `xml:"r,attr,omitempty"`
}

type EventRequest struct {
	Type            EventType   `xml:"eventtype,attr"`
	Result          EventResult `xml:"eventresult,attr"`
	ErrorCode       string      `xml:"errorcode,attr,omitempty"`
	NextVersion     string      `xml:"nextversion,attr,omitempty"`
	PreviousVersion string      `xml:"previousversion,attr,omitempty"`
}

// Response sent by the Omaha server
type Response struct {
	XMLName  xml.Name       `xml:"response" json:"-"`
	DayStart DayStart       `xml:"daystart"`
	Apps     []*AppResponse `xml:"app"`
	Protocol string         `xml:"protocol,attr"`
	Server   string         `xml:"server,attr"`
}

func NewResponse() *Response {
	return &Response{
		Protocol: "3.0",
		Server:   "go-omaha",
		DayStart: DayStart{ElapsedSeconds: "0"},
	}
}

// ParseResponse verifies and returns the parsed Response document.
// The MIME Content-Type header may be provided to sanity check its
// value; if blank it is assumed to be XML in UTF-8.
func ParseResponse(contentType string, body io.Reader) (*Response, error) {
	if err := checkContentType(contentType); err != nil {
		return nil, err
	}

	r := &Response{}
	if err := parseReqOrResp(body, r); err != nil {
		return nil, err
	}

	return r, nil
}

type DayStart struct {
	ElapsedSeconds string `xml:"elapsed_seconds,attr"`
}

func (r *Response) AddApp(id string, status AppStatus) *AppResponse {
	a := &AppResponse{ID: id, Status: status}
	r.Apps = append(r.Apps, a)
	return a
}

func (r *Response) GetApp(id string) *AppResponse {
	for _, app := range r.Apps {
		if app.ID == id {
			return app
		}
	}
	return nil
}

type AppResponse struct {
	Ping        *PingResponse    `xml:"ping"`
	UpdateCheck *UpdateResponse  `xml:"updatecheck"`
	Events      []*EventResponse `xml:"event" json:",omitempty"`
	ID          string           `xml:"appid,attr,omitempty"`
	Status      AppStatus        `xml:"status,attr,omitempty"`
}

func (a *AppResponse) AddUpdateCheck(status UpdateStatus) *UpdateResponse {
	a.UpdateCheck = &UpdateResponse{Status: status}
	return a.UpdateCheck
}

func (a *AppResponse) AddPing() *PingResponse {
	a.Ping = &PingResponse{"ok"}
	return a.Ping
}

func (a *AppResponse) AddEvent() *EventResponse {
	event := &EventResponse{"ok"}
	a.Events = append(a.Events, event)
	return event
}

type UpdateResponse struct {
	URLs     []*URL       `xml:"urls>url" json:",omitempty"`
	Manifest *Manifest    `xml:"manifest"`
	Status   UpdateStatus `xml:"status,attr,omitempty"`
}

func (u *UpdateResponse) AddURL(codebase string) *URL {
	url := &URL{CodeBase: codebase}
	u.URLs = append(u.URLs, url)
	return url
}

func (u *UpdateResponse) AddManifest(version string) *Manifest {
	u.Manifest = &Manifest{Version: version}
	return u.Manifest
}

type PingResponse struct {
	Status string `xml:"status,attr"` // Always "ok".
}

type EventResponse struct {
	Status string `xml:"status,attr"` // Always "ok".
}

type OS struct {
	Platform    string `xml:"platform,attr,omitempty"`
	Version     string `xml:"version,attr,omitempty"`
	ServicePack string `xml:"sp,attr,omitempty"`
	Arch        string `xml:"arch,attr,omitempty"`
}

type URL struct {
	CodeBase string `xml:"codebase,attr"`
}

type Manifest struct {
	Packages []*Package `xml:"packages>package"`
	Actions  []*Action  `xml:"actions>action"`
	Version  string     `xml:"version,attr"`
}

func (m *Manifest) AddPackage() *Package {
	p := &Package{}
	m.Packages = append(m.Packages, p)
	return p
}

func (m *Manifest) AddPackageFromPath(path string) (*Package, error) {
	p := &Package{}
	if err := p.FromPath(path); err != nil {
		return nil, err
	}
	m.Packages = append(m.Packages, p)
	return p, nil
}

func (m *Manifest) AddAction(event string) *Action {
	a := &Action{Event: event}
	m.Actions = append(m.Actions, a)
	return a
}

type Action struct {
	Event string `xml:"event,attr"`

	// update engine extensions for event="postinstall"
	DisplayVersion        string `xml:"DisplayVersion,attr,omitempty"`
	SHA256                string `xml:"sha256,attr,omitempty"`
	NeedsAdmin            bool   `xml:"needsadmin,attr,omitempty"`
	IsDeltaPayload        bool   `xml:"IsDeltaPayload,attr,omitempty"`
	DisablePayloadBackoff bool   `xml:"DisablePayloadBackoff,attr,omitempty"`
	MaxFailureCountPerURL uint   `xml:"MaxFailureCountPerUrl,attr,omitempty"`
	MetadataSignatureRsa  string `xml:"MetadataSignatureRsa,attr,omitempty"`
	MetadataSize          string `xml:"MetadataSize,attr,omitempty"`
	Deadline              string `xml:"deadline,attr,omitempty"`
	MoreInfo              string `xml:"MoreInfo,attr,omitempty"`
	Prompt                bool   `xml:"Prompt,attr,omitempty"`
}
<|endoftext|>


<commit_before>package headlessChrome

import (
	"fmt"

	"github.com/integrii/interactive"
)

// Debug enables debug output for this package to console
var Debug bool

// ChromePath is the command to execute chrome
var ChromePath = `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`

// Args are the args that will be used to start chrome
var Args = []string{
	"--headless",
	"--disable-gpu",
	"--repl",
	// "--dump-dom",
	// "--window-size=1024,768",
	// "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",
	// "--verbose",
}

const expectedFirstLine = "Type a Javascript expression to evaluate or \"quit\" to exit."

// ChromeSession is an interactive console Session with a Chrome
// instance.
type ChromeSession struct {
	Session *interactive.Session
}

// Exit exits the running command out by ossuing a 'quit'
// to the chrome console
func (cs *ChromeSession) Exit() {
	cs.Session.Write(`quit`)
	cs.Session.Exit()
}

// Write writes to the Session
func (cs *ChromeSession) Write(s string) {
	cs.Session.Write(s)
}

// OutputPrinter prints all outputs from the output channel to the cli
func (cs *ChromeSession) OutputPrinter() {
	for l := range cs.Session.Output {
		fmt.Println(l)
	}
}

// forceClose issues a force kill to the command
func (cs *ChromeSession) forceClose() {
	cs.Session.ForceClose()
}

// ClickSelector calls a click() on the supplied selector
func (cs *ChromeSession) ClickSelector(s string) {
	cs.Write(`document.querySelector("` + s + `").click()`)
}

// ClickItemWithInnerHTML clicks an item that has the matching inner html
func (cs *ChromeSession) ClickItemWithInnerHTML(elementType string, s string) {
	cs.Write(`var spans = $("` + elementType + `").filter(function(idx) { return this.innerHTML.indexOf("` + s + `") == 0; }); spans[0].click()`)
}

// GetContentOfItemWithClasse fetches the content of the element with the specified classes
func (cs *ChromeSession) GetContentOfItemWithClasse(classes string) {
	cs.Write(`var x = document.getElementsByClassName("` + classes + `");x[0].innerHTML`)
}

// ClickItemWithClasses clicks on the first item it finds with the provided classes.
// Multiple classes are separated by spaces
func (cs *ChromeSession) ClickItemWithClasses(classes string) {
	cs.Write(`var x = document.getElementsByClassName("` + classes + `");x[0].click()`)
}

// NewBrowser starts a new chrome headless Session.
func NewBrowser(url string) (*ChromeSession, error) {
	var err error

	chromeSession := ChromeSession{}

	// add url as last arg and create new Session
	args := append(Args, url)
	chromeSession.Session, err = interactive.NewSession(ChromePath, args)

	return &chromeSession, err
}
<commit_msg>typo fix<commit_after>package headlessChrome

import (
	"fmt"

	"github.com/integrii/interactive"
)

// Debug enables debug output for this package to console
var Debug bool

// ChromePath is the command to execute chrome
var ChromePath = `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`

// Args are the args that will be used to start chrome
var Args = []string{
	"--headless",
	"--disable-gpu",
	"--repl",
	// "--dump-dom",
	// "--window-size=1024,768",
	// "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",
	// "--verbose",
}

const expectedFirstLine = "Type a Javascript expression to evaluate or \"quit\" to exit."

// ChromeSession is an interactive console Session with a Chrome
// instance.
type ChromeSession struct {
	Session *interactive.Session
}

// Exit exits the running command out by ossuing a 'quit'
// to the chrome console
func (cs *ChromeSession) Exit() {
	cs.Session.Write(`quit`)
	cs.Session.Exit()
}

// Write writes to the Session
func (cs *ChromeSession) Write(s string) {
	cs.Session.Write(s)
}

// OutputPrinter prints all outputs from the output channel to the cli
func (cs *ChromeSession) OutputPrinter() {
	for l := range cs.Session.Output {
		fmt.Println(l)
	}
}

// forceClose issues a force kill to the command
func (cs *ChromeSession) forceClose() {
	cs.Session.ForceClose()
}

// ClickSelector calls a click() on the supplied selector
func (cs *ChromeSession) ClickSelector(s string) {
	cs.Write(`document.querySelector("` + s + `").click()`)
}

// ClickItemWithInnerHTML clicks an item that has the matching inner html
func (cs *ChromeSession) ClickItemWithInnerHTML(elementType string, s string) {
	cs.Write(`var spans = $("` + elementType + `").filter(function(idx) { return this.innerHTML.indexOf("` + s + `") == 0; }); spans[0].click()`)
}

// GetContentOfItemWithClasses fetches the content of the element with the specified classes
func (cs *ChromeSession) GetContentOfItemWithClasses(classes string) {
	cs.Write(`var x = document.getElementsByClassName("` + classes + `");x[0].innerHTML`)
}

// ClickItemWithClasses clicks on the first item it finds with the provided classes.
// Multiple classes are separated by spaces
func (cs *ChromeSession) ClickItemWithClasses(classes string) {
	cs.Write(`var x = document.getElementsByClassName("` + classes + `");x[0].click()`)
}

// NewBrowser starts a new chrome headless Session.
func NewBrowser(url string) (*ChromeSession, error) {
	var err error

	chromeSession := ChromeSession{}

	// add url as last arg and create new Session
	args := append(Args, url)
	chromeSession.Session, err = interactive.NewSession(ChromePath, args)

	return &chromeSession, err
}
<|endoftext|>


<commit_before>package aiff

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
)

// parseChunk processes a chunk and stores the valuable information
// on the decoder if supported.
// Note that the audio chunk isn't processed using this approach.
func (d *Decoder) parseChunk(chunk *Chunk) error {
	if chunk == nil {
		return nil
	}

	switch chunk.ID {
	// common chunk parsing
	case COMMID:
		if err := d.parseCommChunk(uint32(chunk.Size)); err != nil {
			return err
		}
		// if we found the sound data before the COMM,
		// we need to rewind the reader so we can properly
		// set the clip reader.
		if d.rewindBytes > 0 {
			d.r.Seek(-d.rewindBytes, 1)
			d.rewindBytes = 0
		}
	// audio content, should be read a different way
	case SSNDID:
		chunk.Done()
	// Comments Chunk
	case COMTID:
		if err := d.parseCommentsChunk(chunk); err != nil {
			fmt.Println("failed to read comments", err)
		}
	// Apple/Logic specific chunk
	case bascID:
		if err := d.parseBascChunk(chunk); err != nil {
			fmt.Println("failed to read BASC chunk", err)
		}
	// Apple specific: packed struct AudioChannelLayout of CoreAudio
	case chanID:
		// See https://github.com/nu774/qaac/blob/ce73aac9bfba459c525eec5350da6346ebf547cf/chanmap.cpp
		// for format information
		chunk.Done()
	// Apple specific transient data
	case trnsID:
		// TODO extract ans store the transients
		// skip 72
		// nTransients uint32
		// transients := make([]uint32, nTransients)
		// for i := 0; i < nTransients; i ++ {
		// skip 4
		// binary.Read &transients[i]
		// skip 16
		// }
		chunk.Done()
	// Apple specific categorization
	case cateID:
		if err := d.parseCateChunk(chunk); err != nil {
			fmt.Println("failed to read CATE chunk", err)
		}
		chunk.Done()
	default:
		if Debug {
			fmt.Printf("skipping unknown chunk %q\n", string(chunk.ID[:]))
		}
		// if we read SSN but didn't read the COMM, we need to track location
		if d.SampleRate == 0 {
			d.rewindBytes += int64(chunk.Size)
		}
		chunk.Done()
	}
	return nil
}

// parseCommentsChunk processes the comments chunk and adds comments as strings
// to the decoder and drains the chunk.
func (d *Decoder) parseCommentsChunk(chunk *Chunk) error {
	if chunk.ID != COMTID {
		return fmt.Errorf("unexpected comments chunk ID: %q", chunk.ID)
	}
	commentsBody := make([]byte, chunk.Size)
	_, err := chunk.Read(commentsBody)
	if err != nil {
		return err
	}
	br := bytes.NewReader(commentsBody)
	var nbrComments uint16
	binary.Read(br, binary.BigEndian, &nbrComments)
	for i := 0; i < int(nbrComments); i++ {
		// TODO extract marker id and timestamp
		br.Seek(8, io.SeekCurrent)
		b, _ := br.ReadByte()
		textB := make([]byte, int(b))
		br.Read(textB)
		d.Comments = append(d.Comments, string(bytes.TrimRight(textB, "\x00")))
	}
	chunk.Done()
	return nil
}

// parseBascChunk processes the Apple specific BASC chunk
func (d *Decoder) parseBascChunk(chunk *Chunk) error {
	if chunk.ID != bascID {
		return fmt.Errorf("unexpected BASC chunk ID: %q", chunk.ID)
	}
	d.HasAppleInfo = true

	var version uint32
	binary.Read(chunk.R, binary.BigEndian, &version)
	binary.Read(chunk.R, binary.BigEndian, &d.AppleInfo.Beats)
	binary.Read(chunk.R, binary.BigEndian, &d.AppleInfo.Note)
	binary.Read(chunk.R, binary.BigEndian, &d.AppleInfo.Scale)
	binary.Read(chunk.R, binary.BigEndian, &d.AppleInfo.Numerator)
	binary.Read(chunk.R, binary.BigEndian, &d.AppleInfo.Denominator)
	chunk.ReadByte()
	var loopFlag uint16
	binary.Read(chunk.R, binary.BigEndian, &loopFlag)
	// 1  = loop; 2 = one shot
	if loopFlag == 1 {
		d.AppleInfo.IsLooping = true
	}
	chunk.Done()
	return nil
}

func (d *Decoder) parseCateChunk(chunk *Chunk) error {
	if chunk.ID != cateID {
		return fmt.Errorf("unexpected CATE chunk ID: %q", chunk.ID)
	}
	d.HasAppleInfo = true

	// skip 4
	tmp := make([]byte, 4)
	chunk.R.Read(tmp)

	tmp = make([]byte, 50)
	for i := 0; i < 3; i++ {
		chunk.R.Read(tmp)
		if tmp[0] > 0 {
			d.AppleInfo.Tags = append(d.AppleInfo.Tags, nullTermStr(tmp))
		}
	}

	// skip 64
	tmp = make([]byte, 64)
	chunk.R.Read(tmp)

	var numCategories uint32
	binary.Read(chunk.R, binary.BigEndian, &numCategories)
	tmp = tmp[:50]
	for i := 0; i < int(numCategories); i++ {
		chunk.R.Read(tmp)
		if tmp[0] > 0 {
			d.AppleInfo.Tags = append(d.AppleInfo.Tags, nullTermStr(tmp))
		}
	}

	chunk.Done()
	return nil
}
<commit_msg>better info to extract transients<commit_after>package aiff

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
)

// parseChunk processes a chunk and stores the valuable information
// on the decoder if supported.
// Note that the audio chunk isn't processed using this approach.
func (d *Decoder) parseChunk(chunk *Chunk) error {
	if chunk == nil {
		return nil
	}

	switch chunk.ID {
	// common chunk parsing
	case COMMID:
		if err := d.parseCommChunk(uint32(chunk.Size)); err != nil {
			return err
		}
		// if we found the sound data before the COMM,
		// we need to rewind the reader so we can properly
		// set the clip reader.
		if d.rewindBytes > 0 {
			d.r.Seek(-d.rewindBytes, 1)
			d.rewindBytes = 0
		}
	// audio content, should be read a different way
	case SSNDID:
		chunk.Done()
	// Comments Chunk
	case COMTID:
		if err := d.parseCommentsChunk(chunk); err != nil {
			fmt.Println("failed to read comments", err)
		}
	// Apple/Logic specific chunk
	case bascID:
		if err := d.parseBascChunk(chunk); err != nil {
			fmt.Println("failed to read BASC chunk", err)
		}
	// Apple specific: packed struct AudioChannelLayout of CoreAudio
	case chanID:
		// See https://github.com/nu774/qaac/blob/ce73aac9bfba459c525eec5350da6346ebf547cf/chanmap.cpp
		// for format information
		chunk.Done()
	// Apple specific transient data
	case trnsID:
		// TODO extract and store the transients
		/*
			var v1 uint16
			var sensitivity uint16 // 0 to 100 %
			var transientDivisions uint16 // 1 = whole note
			var v3 uint16
			var v5 uint16
			var v4 uint16
			var nbSlice uint16
			int loopSize = v4 * d.AppleInfo.Beats * 2
			for s := 0; s < nbSlice; s++{
				slicepos := 24 * s + 0x4c;
				var sv1 uint16
				var sv2 uint16
				var sampleBegin uint32
			}
		*/
		chunk.Done()
	// Apple specific categorization
	case cateID:
		if err := d.parseCateChunk(chunk); err != nil {
			fmt.Println("failed to read CATE chunk", err)
		}
		chunk.Done()
	default:
		if Debug {
			fmt.Printf("skipping unknown chunk %q\n", string(chunk.ID[:]))
		}
		// if we read SSN but didn't read the COMM, we need to track location
		if d.SampleRate == 0 {
			d.rewindBytes += int64(chunk.Size)
		}
		chunk.Done()
	}
	return nil
}

// parseCommentsChunk processes the comments chunk and adds comments as strings
// to the decoder and drains the chunk.
func (d *Decoder) parseCommentsChunk(chunk *Chunk) error {
	if chunk.ID != COMTID {
		return fmt.Errorf("unexpected comments chunk ID: %q", chunk.ID)
	}
	commentsBody := make([]byte, chunk.Size)
	_, err := chunk.Read(commentsBody)
	if err != nil {
		return err
	}
	br := bytes.NewReader(commentsBody)
	var nbrComments uint16
	binary.Read(br, binary.BigEndian, &nbrComments)
	for i := 0; i < int(nbrComments); i++ {
		// TODO extract marker id and timestamp
		br.Seek(8, io.SeekCurrent)
		b, _ := br.ReadByte()
		textB := make([]byte, int(b))
		br.Read(textB)
		d.Comments = append(d.Comments, string(bytes.TrimRight(textB, "\x00")))
	}
	chunk.Done()
	return nil
}

// parseBascChunk processes the Apple specific BASC chunk
func (d *Decoder) parseBascChunk(chunk *Chunk) error {
	if chunk.ID != bascID {
		return fmt.Errorf("unexpected BASC chunk ID: %q", chunk.ID)
	}
	d.HasAppleInfo = true

	var version uint32
	binary.Read(chunk.R, binary.BigEndian, &version)
	binary.Read(chunk.R, binary.BigEndian, &d.AppleInfo.Beats)
	binary.Read(chunk.R, binary.BigEndian, &d.AppleInfo.Note)
	binary.Read(chunk.R, binary.BigEndian, &d.AppleInfo.Scale)
	binary.Read(chunk.R, binary.BigEndian, &d.AppleInfo.Numerator)
	binary.Read(chunk.R, binary.BigEndian, &d.AppleInfo.Denominator)
	chunk.ReadByte()
	var loopFlag uint16
	binary.Read(chunk.R, binary.BigEndian, &loopFlag)
	// 1  = loop; 2 = one shot
	if loopFlag == 1 {
		d.AppleInfo.IsLooping = true
	}
	chunk.Done()
	return nil
}

func (d *Decoder) parseCateChunk(chunk *Chunk) error {
	if chunk.ID != cateID {
		return fmt.Errorf("unexpected CATE chunk ID: %q", chunk.ID)
	}
	d.HasAppleInfo = true

	// skip 4
	tmp := make([]byte, 4)
	chunk.R.Read(tmp)

	tmp = make([]byte, 50)
	// 4 main categories: instrument, instrument category, style, substyle
	for i := 0; i < 4; i++ {
		chunk.R.Read(tmp)
		if tmp[0] > 0 {
			d.AppleInfo.Tags = append(d.AppleInfo.Tags, nullTermStr(tmp))
		}
	}

	// skip 14
	tmp = make([]byte, 14)
	chunk.R.Read(tmp)

	var numDescriptors uint32
	binary.Read(chunk.R, binary.BigEndian, &numDescriptors)
	tmp = make([]byte, 50)
	for i := 0; i < int(numDescriptors); i++ {
		chunk.R.Read(tmp)
		if tmp[0] > 0 {
			d.AppleInfo.Tags = append(d.AppleInfo.Tags, nullTermStr(tmp))
		}
	}

	chunk.Done()
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// 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
//
// https://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 simple

import (
	"example.com/source"
)

type SourceHolder struct { // want SourceHolder:"inferred source"
	s source.Source
}
<commit_msg>remove tests that should have been deleted (#170)<commit_after><|endoftext|>


<commit_before>package main

import (
	"fmt"
	"strconv"
	_ "github.com/lib/pq"
	"github.com/mgierok/monujo/repository"
	"github.com/mgierok/monujo/repository/entity"
	"github.com/mgierok/monujo/console"
	"github.com/mgierok/monujo/log"
)

func Transactions() {
	portfolio := portfolio()

	transactions, err := repository.PortfolioTransactions(portfolio)
	log.PanicIfError(err)

	var data [][]interface{}

	for _, t := range transactions {
		data = append(data, []interface{}{
			t.TransactionId,
			t.PortfolioId,
			t.Date,
			t.Ticker,
			t.Price,
			t.Currency,
			t.Shares,
			t.Commision,
			t.ExchangeRate,
			t.Tax,
		})
	}

	header := []string{
		"Transaction ID",
		"Portfolio ID",
		"Date",
		"Ticker",
		"Price",
		"Currency",
		"Shares",
		"Commision",
		"Exchange Rate",
		"Tax",
	}

	console.DrawTable(header, data)
}

func portfolio() entity.Portfolio {
	fmt.Println("Choose portfolio")
	fmt.Println("")

	portfolios, err := repository.Portfolios()
	log.PanicIfError(err)

	header := []string{
		"Portfolio Id",
		"Portfolio Name",
	}

	var data [][]interface{}
	for _, p := range portfolios {
		data = append(data, []interface{}{p.PortfolioId, p.Name})
	}

	console.DrawTable(header, data)
	fmt.Println("")

	var input string
	fmt.Print("Portfolio ID: ")
	fmt.Scanln(&input)

	portfolioId, err := strconv.ParseInt(input, 10, 64)

	if nil != err {
		fmt.Printf("\n%s is not a valid portfolio ID\n\n", input)
		return portfolio()
	} else {
		for _, p := range portfolios {
			if p.PortfolioId == portfolioId {
				return p
			}
		}

		fmt.Printf("\n%s is not a valid portfolio ID\n\n", input)
		return portfolio()
	}
}
<commit_msg>action to remove specific transaction<commit_after>package main

import (
	"fmt"
	"strings"
	"strconv"
	_ "github.com/lib/pq"
	"github.com/mgierok/monujo/repository"
	"github.com/mgierok/monujo/repository/entity"
	"github.com/mgierok/monujo/console"
	"github.com/mgierok/monujo/log"
)

func Transactions() {
	portfolio := portfolio()

	transactions, err := repository.PortfolioTransactions(portfolio)
	log.PanicIfError(err)

	var data [][]interface{}

	for _, t := range transactions {
		data = append(data, []interface{}{
			t.TransactionId,
			t.PortfolioId,
			t.Date,
			t.Ticker,
			t.Price,
			t.Currency,
			t.Shares,
			t.Commision,
			t.ExchangeRate,
			t.Tax,
		})
	}

	header := []string{
		"Transaction ID",
		"Portfolio ID",
		"Date",
		"Ticker",
		"Price",
		"Currency",
		"Shares",
		"Commision",
		"Exchange Rate",
		"Tax",
	}

	console.DrawTable(header, data)
	fmt.Println("")

	if !careToDelete() {
		return;
	}

	transaction := transaction(transactions)
	err = repository.DeleteTransaction(transaction)
	log.PanicIfError(err)
	fmt.Println("Transaction has been removed")
}

func portfolio() entity.Portfolio {
	fmt.Println("Choose portfolio")
	fmt.Println("")

	portfolios, err := repository.Portfolios()
	log.PanicIfError(err)

	header := []string{
		"Portfolio Id",
		"Portfolio Name",
	}

	var data [][]interface{}
	for _, p := range portfolios {
		data = append(data, []interface{}{p.PortfolioId, p.Name})
	}

	console.DrawTable(header, data)
	fmt.Println("")

	var input string
	fmt.Print("Portfolio ID: ")
	fmt.Scanln(&input)

	portfolioId, err := strconv.ParseInt(input, 10, 64)

	if nil != err {
		fmt.Printf("\n%s is not a valid portfolio ID\n\n", input)
		return portfolio()
	} else {
		for _, p := range portfolios {
			if p.PortfolioId == portfolioId {
				return p
			}
		}

		fmt.Printf("\n%s is not a valid portfolio ID\n\n", input)
		return portfolio()
	}
}

func careToDelete() bool {
	var input string
	fmt.Println("Type 'Y' to delete one of the transactions or 'N' to abort")
	fmt.Scanln(&input)
	input = strings.ToUpper(input)

	if "Y" == input {
		return true
	} else if "N" == input {
		return false
	}

	return careToDelete()
}

func transaction(transactions entity.Transactions) entity.Transaction {
	var input string
	fmt.Print("Transaction ID: ")
	fmt.Scanln(&input)

	transactionId, err := strconv.ParseInt(input, 10, 64)

	if nil != err {
		fmt.Printf("\n%s is not a valid transaction ID\n\n", input)
		return transaction(transactions)
	} else {
		for _, t := range transactions {
			if t.TransactionId == transactionId {
				return t
			}
		}

		fmt.Printf("\n%s is not a valid transaction ID\n\n", input)
		return transaction(transactions)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"sync"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
)

const (
	namespace = "nginx" // For Prometheus metrics.
)

var (
	listeningAddress = flag.String("telemetry.address", ":9113", "Address on which to expose metrics.")
	metricsEndpoint  = flag.String("telemetry.endpoint", "/metrics", "Path under which to expose metrics.")
	nginxScrapeURI   = flag.String("nginx.scrape_uri", "http://localhost/nginx_status", "URI to nginx stub status page")
	insecure         = flag.Bool("insecure", true, "Ignore server certificate if using https")
)

// Exporter collects nginx stats from the given URI and exports them using
// the prometheus metrics package.
type Exporter struct {
	URI    string
	mutex  sync.RWMutex
	client *http.Client

	scrapeFailures       prometheus.Counter
	processedConnections *prometheus.Desc
	currentConnections   *prometheus.GaugeVec
	nginxUp              prometheus.Gauge
}

// NewExporter returns an initialized Exporter.
func NewExporter(uri string) *Exporter {
	return &Exporter{
		URI: uri,
		scrapeFailures: prometheus.NewCounter(prometheus.CounterOpts{
			Namespace: namespace,
			Name:      "exporter_scrape_failures_total",
			Help:      "Number of errors while scraping nginx.",
		}),
		processedConnections: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "connections_processed_total"),
			"Number of connections processed by nginx",
			[]string{"stage"},
			nil,
		),
		currentConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "connections_current",
			Help:      "Number of connections currently processed by nginx",
		},
			[]string{"state"},
		),
		nginxUp: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "up",
			Help:      "Whether the nginx is up.",
		}),
		client: &http.Client{
			Transport: &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: *insecure},
			},
		},
	}
}

// Describe describes all the metrics ever exported by the nginx exporter. It
// implements prometheus.Collector.
func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
	ch <- e.processedConnections
	e.currentConnections.Describe(ch)
	e.nginxUp.Describe(ch)
	e.scrapeFailures.Describe(ch)
}

func (e *Exporter) collect(ch chan<- prometheus.Metric) error {
	resp, err := e.client.Get(e.URI)
	if err != nil {
		e.nginxUp.Set(0)
		return fmt.Errorf("Error scraping nginx: %v", err)
	}
	e.nginxUp.Set(1)

	data, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if resp.StatusCode < 200 || resp.StatusCode >= 400 {
		if err != nil {
			data = []byte(err.Error())
		}
		return fmt.Errorf("Status %s (%d): %s", resp.Status, resp.StatusCode, data)
	}

	// Parsing results
	lines := strings.Split(string(data), "\n")
	if len(lines) != 5 {
		return fmt.Errorf("Unexpected number of lines in status: %v", lines)
	}

	// active connections
	parts := strings.Split(lines[0], ":")
	if len(parts) != 2 {
		return fmt.Errorf("Unexpected first line: %s", lines[0])
	}
	v, err := strconv.Atoi(strings.TrimSpace(parts[1]))
	if err != nil {
		return err
	}
	e.currentConnections.WithLabelValues("active").Set(float64(v))

	// processed connections
	parts = strings.Fields(lines[2])
	if len(parts) != 3 {
		return fmt.Errorf("Unexpected third line: %s", lines[2])
	}
	v, err = strconv.Atoi(strings.TrimSpace(parts[0]))
	if err != nil {
		return err
	}
	ch <- prometheus.MustNewConstMetric(e.processedConnections, prometheus.CounterValue, float64(v), "accepted")
	v, err = strconv.Atoi(strings.TrimSpace(parts[1]))
	if err != nil {
		return err
	}
	ch <- prometheus.MustNewConstMetric(e.processedConnections, prometheus.CounterValue, float64(v), "handled")
	v, err = strconv.Atoi(strings.TrimSpace(parts[2]))
	if err != nil {
		return err
	}
	ch <- prometheus.MustNewConstMetric(e.processedConnections, prometheus.CounterValue, float64(v), "any")

	// current connections
	parts = strings.Fields(lines[3])
	if len(parts) != 6 {
		return fmt.Errorf("Unexpected fourth line: %s", lines[3])
	}
	v, err = strconv.Atoi(strings.TrimSpace(parts[1]))
	if err != nil {
		return err
	}
	e.currentConnections.WithLabelValues("reading").Set(float64(v))
	v, err = strconv.Atoi(strings.TrimSpace(parts[3]))
	if err != nil {
		return err
	}

	e.currentConnections.WithLabelValues("writing").Set(float64(v))
	v, err = strconv.Atoi(strings.TrimSpace(parts[5]))
	if err != nil {
		return err
	}
	e.currentConnections.WithLabelValues("waiting").Set(float64(v))
	return nil
}

// Collect fetches the stats from configured nginx location and delivers them
// as Prometheus metrics. It implements prometheus.Collector.
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
	e.mutex.Lock() // To protect metrics from concurrent collects.
	defer e.mutex.Unlock()
	if err := e.collect(ch); err != nil {
		log.Errorf("Error scraping nginx: %s", err)
		e.scrapeFailures.Inc()
		e.scrapeFailures.Collect(ch)
	}
	e.currentConnections.Collect(ch)
	e.nginxUp.Collect(ch)
	return
}

func main() {
	flag.Parse()

	exporter := NewExporter(*nginxScrapeURI)
	prometheus.MustRegister(exporter)

	log.Infof("Starting Server: %s", *listeningAddress)
	http.Handle(*metricsEndpoint, prometheus.Handler())
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`
			<title>Nginx Exporter</title>

Nginx Exporter

<a href="` + *metricsEndpoint + `">Metrics

			`))
	})
	http.HandleFunc("/-/healthy", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(200)
		w.Write([]byte("ok"))
	})
	log.Fatal(http.ListenAndServe(*listeningAddress, nil))
}
<commit_msg>Fix compile error (#39)<commit_after>package main

import (
	"crypto/tls"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"sync"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/prometheus/common/log"
)

const (
	namespace = "nginx" // For Prometheus metrics.
)

var (
	listeningAddress = flag.String("telemetry.address", ":9113", "Address on which to expose metrics.")
	metricsEndpoint  = flag.String("telemetry.endpoint", "/metrics", "Path under which to expose metrics.")
	nginxScrapeURI   = flag.String("nginx.scrape_uri", "http://localhost/nginx_status", "URI to nginx stub status page")
	insecure         = flag.Bool("insecure", true, "Ignore server certificate if using https")
)

// Exporter collects nginx stats from the given URI and exports them using
// the prometheus metrics package.
type Exporter struct {
	URI    string
	mutex  sync.RWMutex
	client *http.Client

	scrapeFailures       prometheus.Counter
	processedConnections *prometheus.Desc
	currentConnections   *prometheus.GaugeVec
	nginxUp              prometheus.Gauge
}

// NewExporter returns an initialized Exporter.
func NewExporter(uri string) *Exporter {
	return &Exporter{
		URI: uri,
		scrapeFailures: prometheus.NewCounter(prometheus.CounterOpts{
			Namespace: namespace,
			Name:      "exporter_scrape_failures_total",
			Help:      "Number of errors while scraping nginx.",
		}),
		processedConnections: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "connections_processed_total"),
			"Number of connections processed by nginx",
			[]string{"stage"},
			nil,
		),
		currentConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "connections_current",
			Help:      "Number of connections currently processed by nginx",
		},
			[]string{"state"},
		),
		nginxUp: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "up",
			Help:      "Whether the nginx is up.",
		}),
		client: &http.Client{
			Transport: &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: *insecure},
			},
		},
	}
}

// Describe describes all the metrics ever exported by the nginx exporter. It
// implements prometheus.Collector.
func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
	ch <- e.processedConnections
	e.currentConnections.Describe(ch)
	e.nginxUp.Describe(ch)
	e.scrapeFailures.Describe(ch)
}

func (e *Exporter) collect(ch chan<- prometheus.Metric) error {
	resp, err := e.client.Get(e.URI)
	if err != nil {
		e.nginxUp.Set(0)
		return fmt.Errorf("Error scraping nginx: %v", err)
	}
	e.nginxUp.Set(1)

	data, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if resp.StatusCode < 200 || resp.StatusCode >= 400 {
		if err != nil {
			data = []byte(err.Error())
		}
		return fmt.Errorf("Status %s (%d): %s", resp.Status, resp.StatusCode, data)
	}

	// Parsing results
	lines := strings.Split(string(data), "\n")
	if len(lines) != 5 {
		return fmt.Errorf("Unexpected number of lines in status: %v", lines)
	}

	// active connections
	parts := strings.Split(lines[0], ":")
	if len(parts) != 2 {
		return fmt.Errorf("Unexpected first line: %s", lines[0])
	}
	v, err := strconv.Atoi(strings.TrimSpace(parts[1]))
	if err != nil {
		return err
	}
	e.currentConnections.WithLabelValues("active").Set(float64(v))

	// processed connections
	parts = strings.Fields(lines[2])
	if len(parts) != 3 {
		return fmt.Errorf("Unexpected third line: %s", lines[2])
	}
	v, err = strconv.Atoi(strings.TrimSpace(parts[0]))
	if err != nil {
		return err
	}
	ch <- prometheus.MustNewConstMetric(e.processedConnections, prometheus.CounterValue, float64(v), "accepted")
	v, err = strconv.Atoi(strings.TrimSpace(parts[1]))
	if err != nil {
		return err
	}
	ch <- prometheus.MustNewConstMetric(e.processedConnections, prometheus.CounterValue, float64(v), "handled")
	v, err = strconv.Atoi(strings.TrimSpace(parts[2]))
	if err != nil {
		return err
	}
	ch <- prometheus.MustNewConstMetric(e.processedConnections, prometheus.CounterValue, float64(v), "any")

	// current connections
	parts = strings.Fields(lines[3])
	if len(parts) != 6 {
		return fmt.Errorf("Unexpected fourth line: %s", lines[3])
	}
	v, err = strconv.Atoi(strings.TrimSpace(parts[1]))
	if err != nil {
		return err
	}
	e.currentConnections.WithLabelValues("reading").Set(float64(v))
	v, err = strconv.Atoi(strings.TrimSpace(parts[3]))
	if err != nil {
		return err
	}

	e.currentConnections.WithLabelValues("writing").Set(float64(v))
	v, err = strconv.Atoi(strings.TrimSpace(parts[5]))
	if err != nil {
		return err
	}
	e.currentConnections.WithLabelValues("waiting").Set(float64(v))
	return nil
}

// Collect fetches the stats from configured nginx location and delivers them
// as Prometheus metrics. It implements prometheus.Collector.
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
	e.mutex.Lock() // To protect metrics from concurrent collects.
	defer e.mutex.Unlock()
	if err := e.collect(ch); err != nil {
		log.Errorf("Error scraping nginx: %s", err)
		e.scrapeFailures.Inc()
		e.scrapeFailures.Collect(ch)
	}
	e.currentConnections.Collect(ch)
	e.nginxUp.Collect(ch)
	return
}

func main() {
	flag.Parse()

	exporter := NewExporter(*nginxScrapeURI)
	prometheus.MustRegister(exporter)

	log.Infof("Starting Server: %s", *listeningAddress)
	http.Handle(*metricsEndpoint, promhttp.Handler())
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`
			<title>Nginx Exporter</title>

Nginx Exporter

<a href="` + *metricsEndpoint + `">Metrics

			`))
	})
	http.HandleFunc("/-/healthy", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(200)
		w.Write([]byte("ok"))
	})
	log.Fatal(http.ListenAndServe(*listeningAddress, nil))
}
<|endoftext|>


<commit_before>package main

import (
	"dns"
	"os"
	"flag"
        "log"
	"fmt"
        "time"
        "runtime"
        "runtime/pprof"
)

func main() {
	queries := flag.Int("queries", 20, "number of concurrent queries to perform")
	maxproc := flag.Int("maxproc", 4, "set GOMAXPROCS to this value")
        looptime := flag.Int("time", 2, "number of seconds to query")
        reflect := flag.Bool("reflect", false, "enable reflection")
        nameserver := flag.String("ns", "127.0.0.1:53", "the nameserver to query")
        cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [qtype] [qclass] [name]", os.Args[0])
		flag.PrintDefaults()
	}
        queries_send := int64(0)
        qid := uint16(1)
        qtype := uint16(dns.TypeMX)
	qclass := uint16(dns.ClassINET) // Default qclass
	qname := "miek.nl"
	flag.Parse()
        if *cpuprofile != "" {
                f, err := os.Create(*cpuprofile)
                if err != nil {
                        log.Fatal(err)
                }
                pprof.StartCPUProfile(f)
                defer pprof.StopCPUProfile()
        }
        runtime.GOMAXPROCS(*maxproc)
        start := time.Nanoseconds()
        fmt.Printf("Starting %d query functions. GOMAXPROCS set to %d. *reflection set to %v*\n", *queries, *maxproc, *reflect)
        fmt.Printf("Querying %s\n", *nameserver)
        for i := 0; i < *queries; i++ {
                go func() {
                        pktbuf := make([]byte, dns.DefaultMsgSize)
                        m := new(dns.Msg)
                        m.Question = make([]dns.Question, 1)
                        m.Question[0] = dns.Question{qname, qtype, qclass}
                        qbuf, _ := m.Pack()
                        c := dns.NewClient()
                        if err := c.Dial(*nameserver); err != nil {
                                return
                        }
                        defer c.Close()
                        r := new(dns.Msg)
                        for {
                                // set Id
                                dns.RawSetId(qbuf, 0, qid)
                                n, err := c.ExchangeBuffer(qbuf, *nameserver, pktbuf)
                                if err != nil {
                                        log.Print(err)
                                        continue
                                }
                                if *reflect {
                                        r.Unpack(pktbuf[:n])
                                }
                                queries_send++
                                qid++
                        }
                }()
        }

        t := time.NewTicker(int64(*looptime) * 1e9)
wait:
        for {
                select {
                case <-t.C:
                        // time is up
                        break wait
                }
        }
        delta := float32(time.Nanoseconds() - start) / 1e9
        fmt.Printf("%d queries in %.4f s (%.4f qps)\n", queries_send, delta, float32(queries_send)/delta)
}
<commit_msg>minor additions<commit_after>package main

import (
	"dns"
	"os"
	"flag"
        "log"
	"fmt"
        "time"
        "runtime"
        "runtime/pprof"
)

func main() {
	queries := flag.Int("queries", 20, "number of concurrent queries to perform")
	maxproc := flag.Int("maxproc", 4, "set GOMAXPROCS to this value")
        looptime := flag.Int("time", 2, "number of seconds to query")
        reflect := flag.Bool("reflect", false, "enable reflection")
        nameserver := flag.String("ns", "127.0.0.1:53", "the nameserver to query")
        cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file")
        qname := flag.String("qname", "miek.nl", "which qname to use")

	flag.Usage = func() {
		flag.PrintDefaults()
	}
        queries_send := int64(0)
        qid := uint16(1)
        qtype := dns.TypeMX
	qclass := uint16(dns.ClassINET) // Default qclass
	flag.Parse()
        if *cpuprofile != "" {
                f, err := os.Create(*cpuprofile)
                if err != nil {
                        log.Fatal(err)
                }
                pprof.StartCPUProfile(f)
                defer pprof.StopCPUProfile()
        }
        runtime.GOMAXPROCS(*maxproc)
        start := time.Nanoseconds()
        fmt.Printf("Starting %d query functions. GOMAXPROCS set to %d. *reflection set to %v*\n", *queries, *maxproc, *reflect)
        fmt.Printf("Querying %s\n", *nameserver)
        for i := 0; i < *queries; i++ {
                go func() {
                        pktbuf := make([]byte, dns.DefaultMsgSize)
                        m := new(dns.Msg)
                        m.Question = make([]dns.Question, 1)
                        m.Question[0] = dns.Question{*qname, qtype, qclass}
                        qbuf, _ := m.Pack()
                        c := dns.NewClient()
                        if err := c.Dial(*nameserver); err != nil {
                                return
                        }
                        defer c.Close()
                        r := new(dns.Msg)
                        for {
                                // set Id
                                dns.RawSetId(qbuf, 0, qid)
                                n, err := c.ExchangeBuffer(qbuf, *nameserver, pktbuf)
                                if err != nil {
                                        log.Print(err)
                                        continue
                                }
                                if *reflect {
                                        r.Unpack(pktbuf[:n])
                                }
                                queries_send++
                                qid++
                        }
                }()
        }

        t := time.NewTicker(int64(*looptime) * 1e9)
wait:
        for {
                select {
                case <-t.C:
                        // time is up
                        break wait
                }
        }
        delta := float32(time.Nanoseconds() - start) / 1e9
        fmt.Printf("%d queries in %.4f s (%.4f qps)\n", queries_send, delta, float32(queries_send)/delta)
}
<|endoftext|>