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

package prometheus

import "github.com/prometheus/procfs"

type processCollector struct {
	pid             int
	collectFn       func(chan<- Metric)
	pidFn           func() (int, error)
	cpuTotal        *Desc
	openFDs, maxFDs *Desc
	vsize, rss      *Desc
	startTime       *Desc
}

// NewProcessCollector returns a collector which exports the current state of
// process metrics including CPU, memory and file descriptor usage as well as
// the process start time for the given process ID under the given namespace.
//
// Currently, the collector depends on a Linux-style proc filesystem and
// therefore only exports metrics for Linux.
func NewProcessCollector(pid int, namespace string) Collector {
	return NewProcessCollectorPIDFn(
		func() (int, error) { return pid, nil },
		namespace,
	)
}

// NewProcessCollectorPIDFn works like NewProcessCollector but the process ID is
// determined on each collect anew by calling the given pidFn function.
func NewProcessCollectorPIDFn(
	pidFn func() (int, error),
	namespace string,
) Collector {
	ns := ""
	if len(namespace) > 0 {
		ns = namespace + "_"
	}

	c := processCollector{
		pidFn:     pidFn,
		collectFn: func(chan<- Metric) {},

		cpuTotal: NewDesc(
			ns+"process_cpu_seconds_total",
			"Total user and system CPU time spent in seconds.",
			nil, nil,
		),
		openFDs: NewDesc(
			ns+"process_open_fds",
			"Number of open file descriptors.",
			nil, nil,
		),
		maxFDs: NewDesc(
			ns+"process_max_fds",
			"Maximum number of open file descriptors.",
			nil, nil,
		),
		vsize: NewDesc(
			ns+"process_virtual_memory_bytes",
			"Virtual memory size in bytes.",
			nil, nil,
		),
		rss: NewDesc(
			ns+"process_resident_memory_bytes",
			"Resident memory size in bytes.",
			nil, nil,
		),
		startTime: NewDesc(
			ns+"process_start_time_seconds",
			"Start time of the process since unix epoch in seconds.",
			nil, nil,
		),
	}

	// Set up process metric collection if supported by the runtime.
	if _, err := procfs.NewStat(); err == nil {
		c.collectFn = c.processCollect
	}

	return &c
}

// Describe returns all descriptions of the collector.
func (c *processCollector) Describe(ch chan<- *Desc) {
	ch <- c.cpuTotal
	ch <- c.openFDs
	ch <- c.maxFDs
	ch <- c.vsize
	ch <- c.rss
	ch <- c.startTime
}

// Collect returns the current state of all metrics of the collector.
func (c *processCollector) Collect(ch chan<- Metric) {
	c.collectFn(ch)
}

// TODO(ts): Bring back error reporting by reverting 7faf9e7 as soon as the
// client allows users to configure the error behavior.
func (c *processCollector) processCollect(ch chan<- Metric) {
	pid, err := c.pidFn()
	if err != nil {
		return
	}

	p, err := procfs.NewProc(pid)
	if err != nil {
		return
	}

	if stat, err := p.NewStat(); err == nil {
		ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
		ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
		ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
		if startTime, err := stat.StartTime(); err == nil {
			ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
		}
	}

	if fds, err := p.FileDescriptorsLen(); err == nil {
		ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
	}

	if limits, err := p.NewLimits(); err == nil {
		ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
	}
}
<commit_msg>Type processCollector: Remove unused field 'pid'<commit_after>// Copyright 2015 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package prometheus

import "github.com/prometheus/procfs"

type processCollector struct {
	collectFn       func(chan<- Metric)
	pidFn           func() (int, error)
	cpuTotal        *Desc
	openFDs, maxFDs *Desc
	vsize, rss      *Desc
	startTime       *Desc
}

// NewProcessCollector returns a collector which exports the current state of
// process metrics including CPU, memory and file descriptor usage as well as
// the process start time for the given process ID under the given namespace.
//
// Currently, the collector depends on a Linux-style proc filesystem and
// therefore only exports metrics for Linux.
func NewProcessCollector(pid int, namespace string) Collector {
	return NewProcessCollectorPIDFn(
		func() (int, error) { return pid, nil },
		namespace,
	)
}

// NewProcessCollectorPIDFn works like NewProcessCollector but the process ID is
// determined on each collect anew by calling the given pidFn function.
func NewProcessCollectorPIDFn(
	pidFn func() (int, error),
	namespace string,
) Collector {
	ns := ""
	if len(namespace) > 0 {
		ns = namespace + "_"
	}

	c := processCollector{
		pidFn:     pidFn,
		collectFn: func(chan<- Metric) {},

		cpuTotal: NewDesc(
			ns+"process_cpu_seconds_total",
			"Total user and system CPU time spent in seconds.",
			nil, nil,
		),
		openFDs: NewDesc(
			ns+"process_open_fds",
			"Number of open file descriptors.",
			nil, nil,
		),
		maxFDs: NewDesc(
			ns+"process_max_fds",
			"Maximum number of open file descriptors.",
			nil, nil,
		),
		vsize: NewDesc(
			ns+"process_virtual_memory_bytes",
			"Virtual memory size in bytes.",
			nil, nil,
		),
		rss: NewDesc(
			ns+"process_resident_memory_bytes",
			"Resident memory size in bytes.",
			nil, nil,
		),
		startTime: NewDesc(
			ns+"process_start_time_seconds",
			"Start time of the process since unix epoch in seconds.",
			nil, nil,
		),
	}

	// Set up process metric collection if supported by the runtime.
	if _, err := procfs.NewStat(); err == nil {
		c.collectFn = c.processCollect
	}

	return &c
}

// Describe returns all descriptions of the collector.
func (c *processCollector) Describe(ch chan<- *Desc) {
	ch <- c.cpuTotal
	ch <- c.openFDs
	ch <- c.maxFDs
	ch <- c.vsize
	ch <- c.rss
	ch <- c.startTime
}

// Collect returns the current state of all metrics of the collector.
func (c *processCollector) Collect(ch chan<- Metric) {
	c.collectFn(ch)
}

// TODO(ts): Bring back error reporting by reverting 7faf9e7 as soon as the
// client allows users to configure the error behavior.
func (c *processCollector) processCollect(ch chan<- Metric) {
	pid, err := c.pidFn()
	if err != nil {
		return
	}

	p, err := procfs.NewProc(pid)
	if err != nil {
		return
	}

	if stat, err := p.NewStat(); err == nil {
		ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
		ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
		ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
		if startTime, err := stat.StartTime(); err == nil {
			ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
		}
	}

	if fds, err := p.FileDescriptorsLen(); err == nil {
		ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
	}

	if limits, err := p.NewLimits(); err == nil {
		ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
	}
}
<|endoftext|>


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

package prometheus

import "github.com/prometheus/procfs"

type processCollector struct {
	pid             int
	collectFn       func(chan<- Metric)
	pidFn           func() (int, error)
	cpuTotal        Counter
	openFDs, maxFDs Gauge
	vsize, rss      Gauge
	startTime       Gauge
}

// NewProcessCollector returns a collector which exports the current state of
// process metrics including cpu, memory and file descriptor usage as well as
// the process start time for the given process id under the given namespace.
func NewProcessCollector(pid int, namespace string) Collector {
	return NewProcessCollectorPIDFn(
		func() (int, error) { return pid, nil },
		namespace,
	)
}

// NewProcessCollectorPIDFn returns a collector which exports the current state
// of process metrics including cpu, memory and file descriptor usage as well
// as the process start time under the given namespace. The given pidFn is
// called on each collect and is used to determine the process to export
// metrics for.
func NewProcessCollectorPIDFn(
	pidFn func() (int, error),
	namespace string,
) Collector {
	c := processCollector{
		pidFn:     pidFn,
		collectFn: func(chan<- Metric) {},

		cpuTotal: NewCounter(CounterOpts{
			Namespace: namespace,
			Name:      "process_cpu_seconds_total",
			Help:      "Total user and system CPU time spent in seconds.",
		}),
		openFDs: NewGauge(GaugeOpts{
			Namespace: namespace,
			Name:      "process_open_fds",
			Help:      "Number of open file descriptors.",
		}),
		maxFDs: NewGauge(GaugeOpts{
			Namespace: namespace,
			Name:      "process_max_fds",
			Help:      "Maximum number of open file descriptors.",
		}),
		vsize: NewGauge(GaugeOpts{
			Namespace: namespace,
			Name:      "process_virtual_memory_bytes",
			Help:      "Virtual memory size in bytes.",
		}),
		rss: NewGauge(GaugeOpts{
			Namespace: namespace,
			Name:      "process_resident_memory_bytes",
			Help:      "Resident memory size in bytes.",
		}),
		startTime: NewGauge(GaugeOpts{
			Namespace: namespace,
			Name:      "process_start_time_seconds",
			Help:      "Start time of the process since unix epoch in seconds.",
		}),
	}

	// Set up process metric collection if supported by the runtime.
	if _, err := procfs.NewStat(); err == nil {
		c.collectFn = c.processCollect
	}

	return &c
}

// Describe returns all descriptions of the collector.
func (c *processCollector) Describe(ch chan<- *Desc) {
	ch <- c.cpuTotal.Desc()
	ch <- c.openFDs.Desc()
	ch <- c.maxFDs.Desc()
	ch <- c.vsize.Desc()
	ch <- c.rss.Desc()
	ch <- c.startTime.Desc()
}

// Collect returns the current state of all metrics of the collector.
func (c *processCollector) Collect(ch chan<- Metric) {
	c.collectFn(ch)
}

// TODO(ts): Bring back error reporting by reverting 7faf9e7 as soon as the
// client allows users to configure the error behavior.
func (c *processCollector) processCollect(ch chan<- Metric) {
	pid, err := c.pidFn()
	if err != nil {
		return
	}

	p, err := procfs.NewProc(pid)
	if err != nil {
		return
	}

	if stat, err := p.NewStat(); err == nil {
		c.cpuTotal.Set(stat.CPUTime())
		ch <- c.cpuTotal
		c.vsize.Set(float64(stat.VirtualMemory()))
		ch <- c.vsize
		c.rss.Set(float64(stat.ResidentMemory()))
		ch <- c.rss

		if startTime, err := stat.StartTime(); err == nil {
			c.startTime.Set(startTime)
			ch <- c.startTime
		}
	}

	if fds, err := p.FileDescriptorsLen(); err == nil {
		c.openFDs.Set(float64(fds))
		ch <- c.openFDs
	}

	if limits, err := p.NewLimits(); err == nil {
		c.maxFDs.Set(float64(limits.OpenFiles))
		ch <- c.maxFDs
	}
}
<commit_msg>Convert process collector to const metrics<commit_after>// Copyright 2015 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package prometheus

import "github.com/prometheus/procfs"

type processCollector struct {
	pid             int
	collectFn       func(chan<- Metric)
	pidFn           func() (int, error)
	cpuTotal        *Desc
	openFDs, maxFDs *Desc
	vsize, rss      *Desc
	startTime       *Desc
}

// NewProcessCollector returns a collector which exports the current state of
// process metrics including cpu, memory and file descriptor usage as well as
// the process start time for the given process id under the given namespace.
func NewProcessCollector(pid int, namespace string) Collector {
	return NewProcessCollectorPIDFn(
		func() (int, error) { return pid, nil },
		namespace,
	)
}

// NewProcessCollectorPIDFn returns a collector which exports the current state
// of process metrics including cpu, memory and file descriptor usage as well
// as the process start time under the given namespace. The given pidFn is
// called on each collect and is used to determine the process to export
// metrics for.
func NewProcessCollectorPIDFn(
	pidFn func() (int, error),
	namespace string,
) Collector {
	c := processCollector{
		pidFn:     pidFn,
		collectFn: func(chan<- Metric) {},

		cpuTotal: NewDesc(
			namespace+"_process_cpu_seconds_total",
			"Total user and system CPU time spent in seconds.",
			nil, nil,
		),
		openFDs: NewDesc(
			namespace+"_process_open_fds",
			"Number of open file descriptors.",
			nil, nil,
		),
		maxFDs: NewDesc(
			namespace+"_process_max_fds",
			"Maximum number of open file descriptors.",
			nil, nil,
		),
		vsize: NewDesc(
			namespace+"_process_virtual_memory_bytes",
			"Virtual memory size in bytes.",
			nil, nil,
		),
		rss: NewDesc(
			namespace+"_process_resident_memory_bytes",
			"Resident memory size in bytes.",
			nil, nil,
		),
		startTime: NewDesc(
			namespace+"_process_start_time_seconds",
			"Start time of the process since unix epoch in seconds.",
			nil, nil,
		),
	}

	// Set up process metric collection if supported by the runtime.
	if _, err := procfs.NewStat(); err == nil {
		c.collectFn = c.processCollect
	}

	return &c
}

// Describe returns all descriptions of the collector.
func (c *processCollector) Describe(ch chan<- *Desc) {
	ch <- c.cpuTotal
	ch <- c.openFDs
	ch <- c.maxFDs
	ch <- c.vsize
	ch <- c.rss
	ch <- c.startTime
}

// Collect returns the current state of all metrics of the collector.
func (c *processCollector) Collect(ch chan<- Metric) {
	c.collectFn(ch)
}

// TODO(ts): Bring back error reporting by reverting 7faf9e7 as soon as the
// client allows users to configure the error behavior.
func (c *processCollector) processCollect(ch chan<- Metric) {
	pid, err := c.pidFn()
	if err != nil {
		return
	}

	p, err := procfs.NewProc(pid)
	if err != nil {
		return
	}

	if stat, err := p.NewStat(); err == nil {
		ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
		ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
		ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
		if startTime, err := stat.StartTime(); err == nil {
			ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
		}
	}

	if fds, err := p.FileDescriptorsLen(); err == nil {
		ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
	}

	if limits, err := p.NewLimits(); err == nil {
		ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
	}
}
<|endoftext|>


<commit_before>package slack

import (
	"errors"
	"net/url"
)

// User contains all the information of a user group
type UserGroup struct {
	ID                string      `json:"id"`
  Name              string      `json:"name"`
  TeamId            string      `json:"team_id"`
  IsUserGroup       bool        `json:"is_usergroup"`
  Description       string      `json:"description"`
  Handle            string      `json:"handle"`
  IsExternal        bool        `json:"is_external"`
  AutoType          string      `json:"auto_type"`
  CreatedBy         string      `json:"created_by"`
  UpdatedBy         string      `json:"updated_by"`
  DeletedBy         string      `json:"deleted_by"`
  Prefs             struct{
    Channels        []string    `json:"channels"`
    Groups          []string    `json:"groups"`
  }                             `json:"prefs"`
  Users             []string
  UserCount         int         `json:"user_count"`
}

type userGroupResponseFull struct {
  UserGroups   []UserGroup             `json:"usergroups"`
  UserGroup    UserGroup               `json:"usergroup"`
	SlackResponse
}

func userGroupRequest(path string, values url.Values, debug bool) (*userGroupResponseFull, error) {
	response := &userGroupResponseFull{}
	err := post(path, values, response, debug)
	if err != nil {
		return nil, err
	}
	if !response.Ok {
		return nil, errors.New(response.Error)
	}
	return response, nil
}

// GetUserGroups returns a list of user groups for the team
func (api *Client) GetUserGroups() ([]UserGroup, error){
  values := url.Values{
		"token": {api.config.token},
	}
	response, err := userGroupRequest("usergroups.list", values, api.debug)
	if err != nil {
		return nil, err
	}
	return response.UserGroups, nil
}

func (api *Client) UpdateUserGroup(userGroup UserGroup) (UserGroup, error){
  values := url.Values{
		"token": {api.config.token},
    "usergroup": {userGroup.ID},
	}

  if userGroup.Name != ""{
    values["name"] = []string{userGroup.Name}
  }

  if userGroup.Handle != ""{
    values["handle"] = []string{userGroup.Handle}
  }

  if userGroup.Description != ""{
    values["description"] = []string{userGroup.Description}
  }

	response, err := userGroupRequest("usergroups.update", values, api.debug)
	if err != nil {
		return UserGroup{}, err
	}
	return response.UserGroup, nil
}

func (api *Client) UpdateUserGroupMembers(userGroup string, members string) (UserGroup, error){
  values := url.Values{
		"token": {api.config.token},
    "usergroup": {userGroup.ID},
    "users": {members}
	}

	response, err := userGroupRequest("usergroups.users.update", values, api.debug)
	if err != nil {
		return UserGroup{}, err
	}
	return response.UserGroup, nil
}
<commit_msg>Gofmt<commit_after>package slack

import (
	"errors"
	"net/url"
)

// User contains all the information of a user group
type UserGroup struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	TeamId      string `json:"team_id"`
	IsUserGroup bool   `json:"is_usergroup"`
	Description string `json:"description"`
	Handle      string `json:"handle"`
	IsExternal  bool   `json:"is_external"`
	AutoType    string `json:"auto_type"`
	CreatedBy   string `json:"created_by"`
	UpdatedBy   string `json:"updated_by"`
	DeletedBy   string `json:"deleted_by"`
	Prefs       struct {
		Channels []string `json:"channels"`
		Groups   []string `json:"groups"`
	} `json:"prefs"`
	Users     []string
	UserCount int `json:"user_count"`
}

type userGroupResponseFull struct {
	UserGroups []UserGroup `json:"usergroups"`
	UserGroup  UserGroup   `json:"usergroup"`
	SlackResponse
}

func userGroupRequest(path string, values url.Values, debug bool) (*userGroupResponseFull, error) {
	response := &userGroupResponseFull{}
	err := post(path, values, response, debug)
	if err != nil {
		return nil, err
	}
	if !response.Ok {
		return nil, errors.New(response.Error)
	}
	return response, nil
}

// GetUserGroups returns a list of user groups for the team
func (api *Client) GetUserGroups() ([]UserGroup, error) {
	values := url.Values{
		"token": {api.config.token},
	}
	response, err := userGroupRequest("usergroups.list", values, api.debug)
	if err != nil {
		return nil, err
	}
	return response.UserGroups, nil
}

func (api *Client) UpdateUserGroup(userGroup UserGroup) (UserGroup, error) {
	values := url.Values{
		"token":     {api.config.token},
		"usergroup": {userGroup.ID},
	}

	if userGroup.Name != "" {
		values["name"] = []string{userGroup.Name}
	}

	if userGroup.Handle != "" {
		values["handle"] = []string{userGroup.Handle}
	}

	if userGroup.Description != "" {
		values["description"] = []string{userGroup.Description}
	}

	response, err := userGroupRequest("usergroups.update", values, api.debug)
	if err != nil {
		return UserGroup{}, err
	}
	return response.UserGroup, nil
}

func (api *Client) UpdateUserGroupMembers(userGroup string, members string) (UserGroup, error) {
	values := url.Values{
		"token":     {api.config.token},
		"usergroup": {userGroup.ID},
		"users":     {members},
	}

	response, err := userGroupRequest("usergroups.users.update", values, api.debug)
	if err != nil {
		return UserGroup{}, err
	}
	return response.UserGroup, nil
}
<|endoftext|>


<commit_before>package dokodemo_test

import (
	"net"
	"testing"

	testdispatcher "github.com/v2ray/v2ray-core/app/dispatcher/testing"
	v2net "github.com/v2ray/v2ray-core/common/net"
	v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
	netassert "github.com/v2ray/v2ray-core/common/net/testing/assert"
	. "github.com/v2ray/v2ray-core/proxy/dokodemo"
	v2testing "github.com/v2ray/v2ray-core/testing"
	"github.com/v2ray/v2ray-core/testing/assert"
)

func TestDokodemoTCP(t *testing.T) {
	v2testing.Current(t)

	testPacketDispatcher := testdispatcher.NewTestPacketDispatcher(nil)

	data2Send := "Data to be sent to remote."

	dokodemo := NewDokodemoDoor(&Config{
		Address: v2net.IPAddress([]byte{1, 2, 3, 4}),
		Port:    128,
		Network: v2net.TCPNetwork.AsList(),
		Timeout: 600,
	}, testPacketDispatcher)

	port := v2nettesting.PickPort()
	err := dokodemo.Listen(port)
	assert.Error(err).IsNil()
	netassert.Port(port).Equals(dokodemo.Port())

	tcpClient, err := net.DialTCP("tcp", nil, &net.TCPAddr{
		IP:   []byte{127, 0, 0, 1},
		Port: int(port),
		Zone: "",
	})
	assert.Error(err).IsNil()

	tcpClient.Write([]byte(data2Send))
	tcpClient.CloseWrite()

	lastPacket := <-testPacketDispatcher.LastPacket

	response := make([]byte, 1024)
	nBytes, err := tcpClient.Read(response)
	assert.Error(err).IsNil()
	tcpClient.Close()

	assert.StringLiteral("Processed: " + data2Send).Equals(string(response[:nBytes]))
	assert.Bool(lastPacket.Destination().IsTCP()).IsTrue()
	netassert.Address(lastPacket.Destination().Address()).Equals(v2net.IPAddress([]byte{1, 2, 3, 4}))
	netassert.Port(lastPacket.Destination().Port()).Equals(128)
}

func TestDokodemoUDP(t *testing.T) {
	v2testing.Current(t)

	testPacketDispatcher := testdispatcher.NewTestPacketDispatcher(nil)

	data2Send := "Data to be sent to remote."

	dokodemo := NewDokodemoDoor(&Config{
		Address: v2net.IPAddress([]byte{5, 6, 7, 8}),
		Port:    256,
		Network: v2net.UDPNetwork.AsList(),
		Timeout: 600,
	}, testPacketDispatcher)

	port := v2nettesting.PickPort()
	err := dokodemo.Listen(port)
	assert.Error(err).IsNil()
	netassert.Port(port).Equals(dokodemo.Port())

	udpClient, err := net.DialUDP("udp", nil, &net.UDPAddr{
		IP:   []byte{127, 0, 0, 1},
		Port: int(port),
		Zone: "",
	})
	assert.Error(err).IsNil()

	udpClient.Write([]byte(data2Send))
	udpClient.Close()

	lastPacket := <-testPacketDispatcher.LastPacket

	assert.StringLiteral(data2Send).Equals(string(lastPacket.Chunk().Value))
	assert.Bool(lastPacket.Destination().IsUDP()).IsTrue()
	netassert.Address(lastPacket.Destination().Address()).Equals(v2net.IPAddress([]byte{5, 6, 7, 8}))
	netassert.Port(lastPacket.Destination().Port()).Equals(256)
}
<commit_msg>close dokodemo after testing<commit_after>package dokodemo_test

import (
	"net"
	"testing"

	testdispatcher "github.com/v2ray/v2ray-core/app/dispatcher/testing"
	v2net "github.com/v2ray/v2ray-core/common/net"
	v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
	netassert "github.com/v2ray/v2ray-core/common/net/testing/assert"
	. "github.com/v2ray/v2ray-core/proxy/dokodemo"
	v2testing "github.com/v2ray/v2ray-core/testing"
	"github.com/v2ray/v2ray-core/testing/assert"
)

func TestDokodemoTCP(t *testing.T) {
	v2testing.Current(t)

	testPacketDispatcher := testdispatcher.NewTestPacketDispatcher(nil)

	data2Send := "Data to be sent to remote."

	dokodemo := NewDokodemoDoor(&Config{
		Address: v2net.IPAddress([]byte{1, 2, 3, 4}),
		Port:    128,
		Network: v2net.TCPNetwork.AsList(),
		Timeout: 600,
	}, testPacketDispatcher)
	defer dokodemo.Close()

	port := v2nettesting.PickPort()
	err := dokodemo.Listen(port)
	assert.Error(err).IsNil()
	netassert.Port(port).Equals(dokodemo.Port())

	tcpClient, err := net.DialTCP("tcp", nil, &net.TCPAddr{
		IP:   []byte{127, 0, 0, 1},
		Port: int(port),
		Zone: "",
	})
	assert.Error(err).IsNil()

	tcpClient.Write([]byte(data2Send))
	tcpClient.CloseWrite()

	lastPacket := <-testPacketDispatcher.LastPacket

	response := make([]byte, 1024)
	nBytes, err := tcpClient.Read(response)
	assert.Error(err).IsNil()
	tcpClient.Close()

	assert.StringLiteral("Processed: " + data2Send).Equals(string(response[:nBytes]))
	assert.Bool(lastPacket.Destination().IsTCP()).IsTrue()
	netassert.Address(lastPacket.Destination().Address()).Equals(v2net.IPAddress([]byte{1, 2, 3, 4}))
	netassert.Port(lastPacket.Destination().Port()).Equals(128)
}

func TestDokodemoUDP(t *testing.T) {
	v2testing.Current(t)

	testPacketDispatcher := testdispatcher.NewTestPacketDispatcher(nil)

	data2Send := "Data to be sent to remote."

	dokodemo := NewDokodemoDoor(&Config{
		Address: v2net.IPAddress([]byte{5, 6, 7, 8}),
		Port:    256,
		Network: v2net.UDPNetwork.AsList(),
		Timeout: 600,
	}, testPacketDispatcher)
	defer dokodemo.Close()

	port := v2nettesting.PickPort()
	err := dokodemo.Listen(port)
	assert.Error(err).IsNil()
	netassert.Port(port).Equals(dokodemo.Port())

	udpClient, err := net.DialUDP("udp", nil, &net.UDPAddr{
		IP:   []byte{127, 0, 0, 1},
		Port: int(port),
		Zone: "",
	})
	assert.Error(err).IsNil()

	udpClient.Write([]byte(data2Send))
	udpClient.Close()

	lastPacket := <-testPacketDispatcher.LastPacket

	assert.StringLiteral(data2Send).Equals(string(lastPacket.Chunk().Value))
	assert.Bool(lastPacket.Destination().IsUDP()).IsTrue()
	netassert.Address(lastPacket.Destination().Address()).Equals(v2net.IPAddress([]byte{5, 6, 7, 8}))
	netassert.Port(lastPacket.Destination().Port()).Equals(256)
}
<|endoftext|>


<commit_before>package godns

import (
	"testing"
)

func TestGetCurrentIP(t *testing.T) {
	conf := &Settings{IPUrl: "http://members.3322.org/dyndns/getip"}
	ip, _ := GetCurrentIP(conf)

	if ip == "" {
		t.Log("IP is empty...")
	} else {
		t.Log("IP is:" + ip)
	}
}

func TestCheckSettings(t *testing.T) {
	settingError := &Settings{}
	if err := CheckSettings(settingError); err == nil {
		t.Error("setting is invalid, should return error")
	}

	settingDNSPod := &Settings{Provider: "DNSPod", LoginToken: "aaa"}
	if err := CheckSettings(settingDNSPod); err == nil {
		t.Log("setting with login token, passed")
	} else {
		t.Error("setting with login token, should be passed")
	}

	settingHE := &Settings{Provider: "HE", Password: ""}
	if err := CheckSettings(settingHE); err != nil {
		t.Log("HE setting without password, passed")
	} else {
		t.Error("HE setting without password, should be faild")
	}
}
<commit_msg>add test case<commit_after>package godns

import (
	"testing"
)

func TestGetCurrentIP(t *testing.T) {
	conf := &Settings{IPUrl: "http://members.3322.org/dyndns/getip"}
	ip, _ := GetCurrentIP(conf)

	if ip == "" {
		t.Log("IP is empty...")
	} else {
		t.Log("IP is:" + ip)
	}

	conf = &Settings{Socks5Proxy: "localhost:8899", IPUrl: "http://members.3322.org/dyndns/getip"}
	ip, err := GetCurrentIP(conf)

	if ip != "" && err == nil {
		t.Error("should return error")
	}
}

func TestCheckSettings(t *testing.T) {
	settingError := &Settings{}
	if err := CheckSettings(settingError); err == nil {
		t.Error("setting is invalid, should return error")
	}

	settingDNSPod := &Settings{Provider: "DNSPod", LoginToken: "aaa"}
	if err := CheckSettings(settingDNSPod); err == nil {
		t.Log("setting with login token, passed")
	} else {
		t.Error("setting with login token, should be passed")
	}

	settingHE := &Settings{Provider: "HE", Password: ""}
	if err := CheckSettings(settingHE); err != nil {
		t.Log("HE setting without password, passed")
	} else {
		t.Error("HE setting without password, should be faild")
	}
}
<|endoftext|>


<commit_before>package ostential
import (
	"os"
	"sort"
	"syscall"
	"os/user"
	"io/ioutil"
	"encoding/json"
	"html/template"
)

type vagrantMachine struct {
	            UUID     string
	            UUIDHTML template.HTML // !
	Vagrantfile_pathHTML template.HTML // !

	Local_data_path      string
	Name                 string
	Provider             string
	State                string
	Vagrantfile_path     string

// 	Vagrantfile_name *[]string   // unused
// 	Updated_at         *string   // unused
// 	Extra_data         *struct { // unused
//		Box *struct{
//			Name     *string
//			Provider *string
//			Version  * string
//		}
//	}
}

type vagrantMachines struct {
	List []vagrantMachine
}

// satisfying sort.Interface interface
func (ms vagrantMachines) Len() int {
	return len(ms.List)
}

// satisfying sort.Interface interface
func (ms vagrantMachines) Swap(i, j int) {
	ms.List[i], ms.List[j] = ms.List[j], ms.List[i]
}

// satisfying sort.Interface interface
func (ms vagrantMachines) Less(i, j int) bool {
	return ms.List[i].UUID < ms.List[j].UUID
}

func vagrantmachines() (*vagrantMachines, error) {
	currentUser, _ := user.Current()
	lock_filename  := currentUser.HomeDir + "/.vagrant.d/data/machine-index/index.lock"
	index_filename := currentUser.HomeDir + "/.vagrant.d/data/machine-index/index"

	lock_file, err := os.Open(lock_filename);
	if err != nil {
		return nil, err
	}
	if err := syscall.Flock(int(lock_file.Fd()), syscall.LOCK_EX); err != nil {
		return nil, err
	}
	defer syscall.Flock(int(lock_file.Fd()), syscall.LOCK_UN)

	text, err := ioutil.ReadFile(index_filename)
	if err != nil {
		return nil, err
	}

	status := new(struct {
		Machines *map[string]vagrantMachine // the key is UUID
		Version int // unused
	})
	if err := json.Unmarshal(text, status); err != nil {
		return nil, err
	}
	machines := new(vagrantMachines)
	if status.Machines != nil {
		for uuid, machine := range *status.Machines {
			machine.UUID                 = uuid
			machine.UUIDHTML             = tooltipable(7, uuid)
			machine.Vagrantfile_pathHTML = tooltipable(50, machine.Vagrantfile_path)
			// (*status.Machines)[uuid] = machine
			machines.List = append(machines.List, machine)
		}
	}
	sort.Stable(machines)
	return machines, nil
}
<commit_msg>unused is unused<commit_after>package ostential
import (
	"os"
	"sort"
	"syscall"
	"os/user"
	"io/ioutil"
	"encoding/json"
	"html/template"
)

type vagrantMachine struct {
	            UUID     string
	            UUIDHTML template.HTML // !
	Vagrantfile_pathHTML template.HTML // !

	Local_data_path      string
	Name                 string
	Provider             string
	State                string
	Vagrantfile_path     string

// 	Vagrantfile_name *[]string   // unused
// 	Updated_at         *string   // unused
// 	Extra_data         *struct { // unused
//		Box *struct{
//			Name     *string
//			Provider *string
//			Version  *string
//		}
//	}
}

type vagrantMachines struct {
	List []vagrantMachine
}

// satisfying sort.Interface interface
func (ms vagrantMachines) Len() int {
	return len(ms.List)
}

// satisfying sort.Interface interface
func (ms vagrantMachines) Swap(i, j int) {
	ms.List[i], ms.List[j] = ms.List[j], ms.List[i]
}

// satisfying sort.Interface interface
func (ms vagrantMachines) Less(i, j int) bool {
	return ms.List[i].UUID < ms.List[j].UUID
}

func vagrantmachines() (*vagrantMachines, error) {
	currentUser, _ := user.Current()
	lock_filename  := currentUser.HomeDir + "/.vagrant.d/data/machine-index/index.lock"
	index_filename := currentUser.HomeDir + "/.vagrant.d/data/machine-index/index"

	lock_file, err := os.Open(lock_filename);
	if err != nil {
		return nil, err
	}
	if err := syscall.Flock(int(lock_file.Fd()), syscall.LOCK_EX); err != nil {
		return nil, err
	}
	defer syscall.Flock(int(lock_file.Fd()), syscall.LOCK_UN)

	text, err := ioutil.ReadFile(index_filename)
	if err != nil {
		return nil, err
	}

	status := new(struct {
		Machines *map[string]vagrantMachine // the key is UUID
		// Version int // unused
	})
	if err := json.Unmarshal(text, status); err != nil {
		return nil, err
	}
	machines := new(vagrantMachines)
	if status.Machines != nil {
		for uuid, machine := range *status.Machines {
			machine.UUID                 = uuid
			machine.UUIDHTML             = tooltipable(7, uuid)
			machine.Vagrantfile_pathHTML = tooltipable(50, machine.Vagrantfile_path)
			// (*status.Machines)[uuid] = machine
			machines.List = append(machines.List, machine)
		}
	}
	sort.Stable(machines)
	return machines, nil
}
<|endoftext|>


<commit_before>// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>.  All rights reserved.

package log4go

import (
	"io"
	"os"
	"fmt"
)

var stdout io.Writer = os.Stdout

// This is the standard writer that prints to standard output.
type ConsoleLogWriter chan *LogRecord

// This creates a new ConsoleLogWriter
func NewConsoleLogWriter() ConsoleLogWriter {
	records := make(ConsoleLogWriter, LogBufferLength)
	go records.run(stdout)
	return records
}

func (w ConsoleLogWriter) run(out io.Writer) {
	var timestr string
	var timestrAt int64

	for rec := range w {
		if at := rec.Created.UnixNano() / 1e9; at != timestrAt {
			timestr, timestrAt = rec.Created.Format("01/02/06 15:04:05"), at
		}
		fmt.Fprint(out, "[", timestr, "] [", levelStrings[rec.Level], "] ", rec.Message, "\n")
	}
}

// This is the ConsoleLogWriter's output method.  This will block if the output
// buffer is full.
func (w ConsoleLogWriter) LogWrite(rec *LogRecord) {
	w <- rec
}

// Close stops the logger from sending messages to standard output.  Attempts to
// send log messages to this logger after a Close have undefined behavior.
func (w ConsoleLogWriter) Close() {
	close(w)
}
<commit_msg>On Close termlog waits for all messages to be written and flushes stdout<commit_after>// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>.  All rights reserved.

package log4go

import (
	"io"
	"os"
	"fmt"
	"time"
)

var stdout io.Writer = os.Stdout

// This is the standard writer that prints to standard output.
type ConsoleLogWriter chan *LogRecord

// This creates a new ConsoleLogWriter
func NewConsoleLogWriter() ConsoleLogWriter {
	records := make(ConsoleLogWriter, LogBufferLength)
	go records.run(stdout)
	return records
}

func (w ConsoleLogWriter) run(out io.Writer) {
	var timestr string
	var timestrAt int64

	for rec := range w {
		if at := rec.Created.UnixNano() / 1e9; at != timestrAt {
			timestr, timestrAt = rec.Created.Format("01/02/06 15:04:05"), at
		}
		fmt.Fprint(out, "[", timestr, "] [", levelStrings[rec.Level], "] ", rec.Message, "\n")
	}
}

// This is the ConsoleLogWriter's output method.  This will block if the output
// buffer is full.
func (w ConsoleLogWriter) LogWrite(rec *LogRecord) {
	w <- rec
}

// Close stops the logger from sending messages to standard output.  Attempts to
// send log messages to this logger after a Close have undefined behavior.
func (w ConsoleLogWriter) Close() {
	for len(w) > 0 {
		time.Sleep(5 * time.Millisecond)
	}
	close(w)
	os.Stdout.Sync()
}
<|endoftext|>


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

package libsacloud

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

package libsacloud

// Version バージョン
const Version = "2.8.2"
<|endoftext|>


<commit_before>// Copyright 2011 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.

// Package crypto collects common cryptographic constants.
package crypto

import (
	"hash"
)

// Hash identifies a cryptographic hash function that is implemented in another
// package.
type Hash uint

const (
	MD4       Hash = 1 + iota // import code.google.com/p/go.crypto/md4
	MD5                       // import crypto/md5
	SHA1                      // import crypto/sha1
	SHA224                    // import crypto/sha256
	SHA256                    // import crypto/sha256
	SHA384                    // import crypto/sha512
	SHA512                    // import crypto/sha512
	MD5SHA1                   // no implementation; MD5+SHA1 used for TLS RSA
	RIPEMD160                 // import code.google.com/p/go.crypto/ripemd160
	maxHash
)

var digestSizes = []uint8{
	MD4:       16,
	MD5:       16,
	SHA1:      20,
	SHA224:    28,
	SHA256:    32,
	SHA384:    48,
	SHA512:    64,
	MD5SHA1:   36,
	RIPEMD160: 20,
}

// Size returns the length, in bytes, of a digest resulting from the given hash
// function. It doesn't require that the hash function in question be linked
// into the program.
func (h Hash) Size() int {
	if h > 0 && h < maxHash {
		return int(digestSizes[h])
	}
	panic("crypto: Size of unknown hash function")
}

var hashes = make([]func() hash.Hash, maxHash)

// New returns a new hash.Hash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() hash.Hash {
	if h > 0 && h < maxHash {
		f := hashes[h]
		if f != nil {
			return f()
		}
	}
	panic("crypto: requested hash function is unavailable")
}

// Available reports whether the given hash function is linked into the binary.
func (h Hash) Available() bool {
	return h < maxHash && hashes[h] != nil
}

// RegisterHash registers a function that returns a new instance of the given
// hash function. This is intended to be called from the init function in
// packages that implement hash functions.
func RegisterHash(h Hash, f func() hash.Hash) {
	if h >= maxHash {
		panic("crypto: RegisterHash of unknown hash function")
	}
	hashes[h] = f
}

// PublicKey represents a public key using an unspecified algorithm.
type PublicKey interface{}

// PrivateKey represents a private key using an unspecified algorithm.
type PrivateKey interface{}
<commit_msg>crypto: include hash number in panic message.<commit_after>// Copyright 2011 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.

// Package crypto collects common cryptographic constants.
package crypto

import (
	"hash"
	"strconv"
)

// Hash identifies a cryptographic hash function that is implemented in another
// package.
type Hash uint

const (
	MD4       Hash = 1 + iota // import code.google.com/p/go.crypto/md4
	MD5                       // import crypto/md5
	SHA1                      // import crypto/sha1
	SHA224                    // import crypto/sha256
	SHA256                    // import crypto/sha256
	SHA384                    // import crypto/sha512
	SHA512                    // import crypto/sha512
	MD5SHA1                   // no implementation; MD5+SHA1 used for TLS RSA
	RIPEMD160                 // import code.google.com/p/go.crypto/ripemd160
	maxHash
)

var digestSizes = []uint8{
	MD4:       16,
	MD5:       16,
	SHA1:      20,
	SHA224:    28,
	SHA256:    32,
	SHA384:    48,
	SHA512:    64,
	MD5SHA1:   36,
	RIPEMD160: 20,
}

// Size returns the length, in bytes, of a digest resulting from the given hash
// function. It doesn't require that the hash function in question be linked
// into the program.
func (h Hash) Size() int {
	if h > 0 && h < maxHash {
		return int(digestSizes[h])
	}
	panic("crypto: Size of unknown hash function")
}

var hashes = make([]func() hash.Hash, maxHash)

// New returns a new hash.Hash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() hash.Hash {
	if h > 0 && h < maxHash {
		f := hashes[h]
		if f != nil {
			return f()
		}
	}
	panic("crypto: requested hash function #" + strconv.Itoa(int(h)) + " is unavailable")
}

// Available reports whether the given hash function is linked into the binary.
func (h Hash) Available() bool {
	return h < maxHash && hashes[h] != nil
}

// RegisterHash registers a function that returns a new instance of the given
// hash function. This is intended to be called from the init function in
// packages that implement hash functions.
func RegisterHash(h Hash, f func() hash.Hash) {
	if h >= maxHash {
		panic("crypto: RegisterHash of unknown hash function")
	}
	hashes[h] = f
}

// PublicKey represents a public key using an unspecified algorithm.
type PublicKey interface{}

// PrivateKey represents a private key using an unspecified algorithm.
type PrivateKey interface{}
<|endoftext|>


<commit_before>package onthefly

import (
	"fmt"
	"strconv"
)

func NewTinySVG(x, y, w, h int) (*Page, *Tag) {
	page := NewPage("", `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">`)
	svg := page.root.AddNewTag("svg")
	svg.AddAttrib("xmlns", "http://www.w3.org/2000/svg")
	svg.AddAttrib("version", "1.1")
	svg.AddAttrib("baseProfile", "tiny")
	sx := strconv.Itoa(x)
	sy := strconv.Itoa(y)
	sw := strconv.Itoa(w)
	sh := strconv.Itoa(h)
	svg.AddAttrib("viewBox", sx+" "+sy+" "+sw+" "+sh)
	return page, svg
}

func (svg *Tag) AddRect(x, y, w, h int) *Tag {
	sx := strconv.Itoa(x)
	sy := strconv.Itoa(y)
	sw := strconv.Itoa(w)
	sh := strconv.Itoa(h)
	rect := svg.AddNewTag("rect")
	rect.AddAttrib("x", sx)
	rect.AddAttrib("y", sy)
	rect.AddAttrib("width", sw)
	rect.AddAttrib("height", sh)
	return rect
}

// Add a box/rectangle, given x and y position, radius and a color
func (svg *Tag) Box(x, y, w, h int, color string) *Tag {
	sx := strconv.Itoa(x)
	sy := strconv.Itoa(y)
	sw := strconv.Itoa(w)
	sh := strconv.Itoa(h)
	rect := svg.AddNewTag("rect")
	rect.AddAttrib("x", sx)
	rect.AddAttrib("y", sy)
	rect.AddAttrib("width", sw)
	rect.AddAttrib("height", sh)
	rect.Fill(color)
	return rect
}

// Add a circle, given x and y position, radius and a color
func (svg *Tag) Circle(x, y, radius int, color string) *Tag {
	sx := strconv.Itoa(x)
	sy := strconv.Itoa(y)
	sradius := strconv.Itoa(radius)
	circle := svg.AddNewTag("circle")
	circle.AddAttrib("cx", sx)
	circle.AddAttrib("cy", sy)
	circle.AddAttrib("r", sradius)
	circle.Fill(color)
	return circle
}

func (svg *Tag) AddCircle(x, y, radius int) *Tag {
	sx := strconv.Itoa(x)
	sy := strconv.Itoa(y)
	sradius := strconv.Itoa(radius)
	circle := svg.AddNewTag("circle")
	circle.AddAttrib("cx", sx)
	circle.AddAttrib("cy", sy)
	circle.AddAttrib("r", sradius)
	return circle
}

func (rect *Tag) Fill(color string) {
	rect.AddAttrib("fill", color)
}

// Converts r, g and b which are integers in the range from 0..255
// to a color-string on the form "#nnnnnn".
func ColorString(r, g, b int) string {
	rs := strconv.FormatInt(int64(r), 16)
	gs := strconv.FormatInt(int64(g), 16)
	bs := strconv.FormatInt(int64(b), 16)
	if len(rs) == 1 {
		rs = "0" + rs
	}
	if len(gs) == 1 {
		gs = "0" + gs
	}
	if len(bs) == 1 {
		bs = "0" + bs
	}
	return "#" + rs + gs + bs
}

// Creates a rectangle that is 1 wide with the given color
// Note that the size of the "pixel" depends on how large the viewBox is
func (svg *Tag) Pixel(x, y, r, g, b int) *Tag {
	color := ColorString(r, g, b)
	rect := svg.Box(x, y, 1, 1, color)
	return rect
}

func (svg *Tag) AlphaDot(cx, cy, r, g, b int, a float32) *Tag {
	color := fmt.Sprintf("rgba(%d, %d, %d, %f)", r, g, b, a)
	circle := svg.AddCircle(cx, cy, 1)
	circle.Fill(color)
	return circle
}

func (svg *Tag) Dot(cx, cy, r, g, b int) *Tag {
	color := ColorString(r, g, b)
	circle := svg.AddCircle(cx, cy, 1)
	circle.Fill(color)
	return circle
}

func SampleSVG1() *Page {
	page, svg := NewTinySVG(0, 0, 30, 30)
	desc := svg.AddNewTag("desc")
	desc.AddContent("Sample SVG file 1")
	rect := svg.AddRect(10, 10, 10, 10)
	rect.Fill("green")
	svg.Pixel(10, 10, 255, 0, 0)
	svg.AlphaDot(5, 5, 0, 0, 255, 0.5)
	return page
}

func SampleSVG2() *Page {
	w := 160
	h := 90
	stepx := 8
	stepy := 8
	page, svg := NewTinySVG(0, 0, w, h)
	desc := svg.AddNewTag("desc")
	desc.AddContent("Sample SVG file 2")
	increase := 0
	decrease := 0
	for y := stepy; y < h; y += stepy {
		for x := stepx; x < w; x += stepx {
			increase = int((float32(x) / float32(w)) * 255.0)
			decrease = 255 - increase
			svg.Dot(x, y, 255, decrease, increase)
		}
	}
	return page
}
<commit_msg>Refactoring. Added Trinagle method.<commit_after>package onthefly

import (
	"fmt"
	"strconv"
)

func NewTinySVG(x, y, w, h int) (*Page, *Tag) {
	page := NewPage("", `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">`)
	svg := page.root.AddNewTag("svg")
	svg.AddAttrib("xmlns", "http://www.w3.org/2000/svg")
	svg.AddAttrib("version", "1.1")
	svg.AddAttrib("baseProfile", "tiny")
	sx := strconv.Itoa(x)
	sy := strconv.Itoa(y)
	sw := strconv.Itoa(w)
	sh := strconv.Itoa(h)
	svg.AddAttrib("viewBox", sx+" "+sy+" "+sw+" "+sh)
	return page, svg
}

func (svg *Tag) AddRect(x, y, w, h int) *Tag {
	sx := strconv.Itoa(x)
	sy := strconv.Itoa(y)
	sw := strconv.Itoa(w)
	sh := strconv.Itoa(h)
	rect := svg.AddNewTag("rect")
	rect.AddAttrib("x", sx)
	rect.AddAttrib("y", sy)
	rect.AddAttrib("width", sw)
	rect.AddAttrib("height", sh)
	return rect
}

// Add a box/rectangle, given x and y position, width, height and color
func (svg *Tag) Box(x, y, w, h int, color string) *Tag {
	rect := svg.AddRect(x, y, w, h)
	rect.Fill(color)
	return rect
}

func (svg *Tag) AddCircle(x, y, radius int) *Tag {
	sx := strconv.Itoa(x)
	sy := strconv.Itoa(y)
	sradius := strconv.Itoa(radius)
	circle := svg.AddNewTag("circle")
	circle.AddAttrib("cx", sx)
	circle.AddAttrib("cy", sy)
	circle.AddAttrib("r", sradius)
	return circle
}

func (svg *Tag) Triangle(x1, y1, x2, y2, x3, y3 int, color string) *Tag {
	triangle := svg.AddNewTag("path")
	triangle.AddAttrib("d", fmt.Sprintf("M %d %d L %d %d L %d %d L %d %d", x1, y1, x2, y2, x3, y3, x1, y1))
	triangle.AddAttrib("fill", color)
	return triangle
}

// Add a circle, given x and y position, radius and color
func (svg *Tag) Circle(x, y, radius int, color string) *Tag {
	circle := svg.AddCircle(x, y, radius)
	circle.Fill(color)
	return circle
}

func (rect *Tag) Fill(color string) {
	rect.AddAttrib("fill", color)
}

// Converts r, g and b which are integers in the range from 0..255
// to a color-string on the form "#nnnnnn".
func ColorString(r, g, b int) string {
	rs := strconv.FormatInt(int64(r), 16)
	gs := strconv.FormatInt(int64(g), 16)
	bs := strconv.FormatInt(int64(b), 16)
	if len(rs) == 1 {
		rs = "0" + rs
	}
	if len(gs) == 1 {
		gs = "0" + gs
	}
	if len(bs) == 1 {
		bs = "0" + bs
	}
	return "#" + rs + gs + bs
}

// Creates a rectangle that is 1 wide with the given color
// Note that the size of the "pixel" depends on how large the viewBox is
func (svg *Tag) Pixel(x, y, r, g, b int) *Tag {
	color := ColorString(r, g, b)
	rect := svg.Box(x, y, 1, 1, color)
	return rect
}

func (svg *Tag) AlphaDot(cx, cy, r, g, b int, a float32) *Tag {
	color := fmt.Sprintf("rgba(%d, %d, %d, %f)", r, g, b, a)
	circle := svg.AddCircle(cx, cy, 1)
	circle.Fill(color)
	return circle
}

func (svg *Tag) Dot(cx, cy, r, g, b int) *Tag {
	color := ColorString(r, g, b)
	circle := svg.AddCircle(cx, cy, 1)
	circle.Fill(color)
	return circle
}

func SampleSVG1() *Page {
	page, svg := NewTinySVG(0, 0, 30, 30)
	desc := svg.AddNewTag("desc")
	desc.AddContent("Sample SVG file 1")
	rect := svg.AddRect(10, 10, 10, 10)
	rect.Fill("green")
	svg.Pixel(10, 10, 255, 0, 0)
	svg.AlphaDot(5, 5, 0, 0, 255, 0.5)
	return page
}

func SampleSVG2() *Page {
	w := 160
	h := 90
	stepx := 8
	stepy := 8
	page, svg := NewTinySVG(0, 0, w, h)
	desc := svg.AddNewTag("desc")
	desc.AddContent("Sample SVG file 2")
	increase := 0
	decrease := 0
	for y := stepy; y < h; y += stepy {
		for x := stepx; x < w; x += stepx {
			increase = int((float32(x) / float32(w)) * 255.0)
			decrease = 255 - increase
			svg.Dot(x, y, 255, decrease, increase)
		}
	}
	return page
}
<|endoftext|>


<commit_before>// Copyright 2016 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

// +build go1.3

package lxdclient

import (
	"fmt"
	"time"

	"github.com/juju/errors"
	"github.com/juju/testing"
	jc "github.com/juju/testing/checkers"
	gc "gopkg.in/check.v1"
)

type imageSuite struct {
	testing.IsolationSuite
	Stub              *testing.Stub
	remoteWithTrusty  *stubRemoteClient
	remoteWithNothing *stubRemoteClient
}

var _ = gc.Suite(&imageSuite{})

func (s *imageSuite) SetUpTest(c *gc.C) {
	s.IsolationSuite.SetUpTest(c)
	s.Stub = &testing.Stub{}
	s.remoteWithTrusty = &stubRemoteClient{
		stub: s.Stub,
		url:  "https://match",
		aliases: map[string]string{
			"trusty": "deadbeef",
		},
	}
	s.remoteWithNothing = &stubRemoteClient{
		stub:    s.Stub,
		url:     "https://missing",
		aliases: nil,
	}
}

type stubRemoteClient struct {
	stub    *testing.Stub
	url     string
	aliases map[string]string
}

var _ remoteClient = (*stubRemoteClient)(nil)

func (s *stubRemoteClient) URL() string {
	// Note we don't log calls to URL because they are not interesting, and
	// are generally just used for logging, etc.
	return s.url
}

func (s *stubRemoteClient) GetAlias(alias string) string {
	s.stub.AddCall("GetAlias", alias)
	if err := s.stub.NextErr(); err != nil {
		// GetAlias can't return an Err, but if we get an error, we'll
		// just treat that as a miss on the Alias lookup.
		return ""
	}
	return s.aliases[alias]
}

func (s *stubRemoteClient) CopyImage(imageTarget string, dest rawImageClient, aliases []string, callback func(string)) error {
	// We don't include the destination or the callback because they aren't
	// objects we can easily assert against.
	s.stub.AddCall("CopyImage", imageTarget, aliases)
	if err := s.stub.NextErr(); err != nil {
		return err
	}
	// This is to make this CopyImage act a bit like a real CopyImage. it
	// gives some Progress callbacks, and then sets the alias in the
	// target.
	if callback != nil {
		// The real one gives progress every 1%
		for i := 10; i <= 100; i += 10 {
			callback(fmt.Sprintf("%d%%", i))
			time.Sleep(1 * time.Microsecond)
		}
	}
	if stubDest, ok := dest.(*stubClient); ok {
		if stubDest.Aliases == nil {
			stubDest.Aliases = make(map[string]string)
		}
		for _, alias := range aliases {
			stubDest.Aliases[alias] = imageTarget
		}
	}
	return nil
}

func (s *stubRemoteClient) AsRemote() Remote {
	return Remote{
		Host:     s.url,
		Protocol: SimplestreamsProtocol,
	}
}

type stubConnector struct {
	stub          *testing.Stub
	remoteClients map[string]remoteClient
}

func MakeConnector(stub *testing.Stub, remotes ...remoteClient) *stubConnector {
	remoteMap := make(map[string]remoteClient)
	for _, remote := range remotes {
		remoteMap[remote.URL()] = remote
	}
	return &stubConnector{
		stub:          stub,
		remoteClients: remoteMap,
	}
}

func (s *stubConnector) connectToSource(remote Remote) (remoteClient, error) {
	s.stub.AddCall("connectToSource", remote.Host)
	if err := s.stub.NextErr(); err != nil {
		return nil, err
	}
	return s.remoteClients[remote.Host], nil
}

func (s *imageSuite) TestEnsureImageExistsAlreadyPresent(c *gc.C) {
	raw := &stubClient{
		stub: s.Stub,
		Aliases: map[string]string{
			"ubuntu-trusty": "dead-beef",
		},
	}
	client := &imageClient{
		raw: raw,
	}
	err := client.EnsureImageExists("trusty", nil, nil)
	c.Assert(err, jc.ErrorIsNil)
	s.Stub.CheckCall(c, 0, "GetAlias", "ubuntu-trusty")
}

func (s *imageSuite) TestEnsureImageExistsFirstRemote(c *gc.C) {
	connector := MakeConnector(s.Stub, s.remoteWithTrusty)
	raw := &stubClient{
		stub: s.Stub,
		// We don't have the image locally
		Aliases: nil,
	}
	client := &imageClient{
		raw:             raw,
		connectToSource: connector.connectToSource,
	}
	remotes := []Remote{s.remoteWithTrusty.AsRemote()}
	s.Stub.ResetCalls()
	err := client.EnsureImageExists("trusty", remotes, nil)
	c.Assert(err, jc.ErrorIsNil)
	// We didn't find it locally
	s.Stub.CheckCalls(c, []testing.StubCall{
		{ // Check if we already have 'ubuntu-trusty' locally
			FuncName: "GetAlias",
			Args:     []interface{}{"ubuntu-trusty"},
		},
		{ // We didn't so connect to the first remote
			FuncName: "connectToSource",
			Args:     []interface{}{"https://match"},
		},
		{ // And check if it has trusty (which it should)
			FuncName: "GetAlias",
			Args:     []interface{}{"trusty"},
		},
		{ // So Copy the Image
			FuncName: "CopyImage",
			Args:     []interface{}{"deadbeef", []string{"ubuntu-trusty"}},
		},
	})
	// We've updated the aliases
	c.Assert(raw.Aliases, gc.DeepEquals, map[string]string{
		"ubuntu-trusty": "deadbeef",
	})
}

func (s *imageSuite) TestEnsureImageExistsUnableToConnect(c *gc.C) {
	connector := MakeConnector(s.Stub, s.remoteWithTrusty)
	raw := &stubClient{
		stub: s.Stub,
		// We don't have the image locally
		Aliases: nil,
	}
	client := &imageClient{
		raw:             raw,
		connectToSource: connector.connectToSource,
	}
	badRemote := Remote{
		Host:     "https://nosuch-remote.invalid",
		Protocol: SimplestreamsProtocol,
	}
	s.Stub.ResetCalls()
	s.Stub.SetErrors(nil, errors.Errorf("unable-to-connect"))
	remotes := []Remote{badRemote, s.remoteWithTrusty.AsRemote()}
	err := client.EnsureImageExists("trusty", remotes, nil)
	c.Assert(err, jc.ErrorIsNil)
	// We didn't find it locally
	s.Stub.CheckCalls(c, []testing.StubCall{
		{ // Check if we already have 'ubuntu-trusty' locally
			FuncName: "GetAlias",
			Args:     []interface{}{"ubuntu-trusty"},
		},
		{ // We didn't so connect to the first remote
			FuncName: "connectToSource",
			Args:     []interface{}{"https://nosuch-remote.invalid"},
		},
		{ // Connect failed to first, so connect to second and copy
			FuncName: "connectToSource",
			Args:     []interface{}{"https://match"},
		},
		{ // And check if it has trusty (which it should)
			FuncName: "GetAlias",
			Args:     []interface{}{"trusty"},
		},
		{ // So Copy the Image
			FuncName: "CopyImage",
			Args:     []interface{}{"deadbeef", []string{"ubuntu-trusty"}},
		},
	})
	// We've updated the aliases
	c.Assert(raw.Aliases, gc.DeepEquals, map[string]string{
		"ubuntu-trusty": "deadbeef",
	})
}

func (s *imageSuite) TestEnsureImageExistsNotPresentInFirstRemote(c *gc.C) {
	connector := MakeConnector(s.Stub, s.remoteWithNothing, s.remoteWithTrusty)
	raw := &stubClient{
		stub: s.Stub,
		// We don't have the image locally
		Aliases: nil,
	}
	client := &imageClient{
		raw:             raw,
		connectToSource: connector.connectToSource,
	}
	s.Stub.ResetCalls()
	remotes := []Remote{s.remoteWithNothing.AsRemote(), s.remoteWithTrusty.AsRemote()}
	err := client.EnsureImageExists("trusty", remotes, nil)
	c.Assert(err, jc.ErrorIsNil)
	// We didn't find it locally
	s.Stub.CheckCalls(c, []testing.StubCall{
		{ // Check if we already have 'ubuntu-trusty' locally
			FuncName: "GetAlias",
			Args:     []interface{}{"ubuntu-trusty"},
		},
		{ // We didn't so connect to the first remote
			FuncName: "connectToSource",
			Args:     []interface{}{s.remoteWithNothing.URL()},
		},
		{ // Lookup the Alias
			FuncName: "GetAlias",
			Args:     []interface{}{"trusty"},
		},
		{ // It wasn't found, so connect to second and look there
			FuncName: "connectToSource",
			Args:     []interface{}{s.remoteWithTrusty.URL()},
		},
		{ // And check if it has trusty (which it should)
			FuncName: "GetAlias",
			Args:     []interface{}{"trusty"},
		},
		{ // So Copy the Image
			FuncName: "CopyImage",
			Args:     []interface{}{"deadbeef", []string{"ubuntu-trusty"}},
		},
	})
	// We've updated the aliases
	c.Assert(raw.Aliases, gc.DeepEquals, map[string]string{
		"ubuntu-trusty": "deadbeef",
	})
}

func (s *imageSuite) TestEnsureImageExistsCallbackIncludesSourceURL(c *gc.C) {
	var calls []string
	callback := func(message string) {
		calls = append(calls, message)
	}
	connector := MakeConnector(s.Stub, s.remoteWithTrusty)
	raw := &stubClient{
		stub: s.Stub,
		// We don't have the image locally
		Aliases: nil,
	}
	client := &imageClient{
		raw:             raw,
		connectToSource: connector.connectToSource,
	}
	remotes := []Remote{s.remoteWithTrusty.AsRemote()}
	err := client.EnsureImageExists("trusty", remotes, callback)
	c.Assert(err, jc.ErrorIsNil)
	c.Check(len(calls), jc.GreaterThan, 0)
	c.Check(calls[0], gc.Matches, "copying image for ubuntu-trusty from https://match: \\d+%")
}
<commit_msg>Fix a data race in EnsureImageExistsCallbackIncludesSourceURL<commit_after>// Copyright 2016 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

// +build go1.3

package lxdclient

import (
	"fmt"
	"time"

	"github.com/juju/errors"
	"github.com/juju/testing"
	jc "github.com/juju/testing/checkers"
	gc "gopkg.in/check.v1"
)

type imageSuite struct {
	testing.IsolationSuite
	Stub              *testing.Stub
	remoteWithTrusty  *stubRemoteClient
	remoteWithNothing *stubRemoteClient
}

var _ = gc.Suite(&imageSuite{})

func (s *imageSuite) SetUpTest(c *gc.C) {
	s.IsolationSuite.SetUpTest(c)
	s.Stub = &testing.Stub{}
	s.remoteWithTrusty = &stubRemoteClient{
		stub: s.Stub,
		url:  "https://match",
		aliases: map[string]string{
			"trusty": "deadbeef",
		},
	}
	s.remoteWithNothing = &stubRemoteClient{
		stub:    s.Stub,
		url:     "https://missing",
		aliases: nil,
	}
}

type stubRemoteClient struct {
	stub    *testing.Stub
	url     string
	aliases map[string]string
}

var _ remoteClient = (*stubRemoteClient)(nil)

func (s *stubRemoteClient) URL() string {
	// Note we don't log calls to URL because they are not interesting, and
	// are generally just used for logging, etc.
	return s.url
}

func (s *stubRemoteClient) GetAlias(alias string) string {
	s.stub.AddCall("GetAlias", alias)
	if err := s.stub.NextErr(); err != nil {
		// GetAlias can't return an Err, but if we get an error, we'll
		// just treat that as a miss on the Alias lookup.
		return ""
	}
	return s.aliases[alias]
}

func (s *stubRemoteClient) CopyImage(imageTarget string, dest rawImageClient, aliases []string, callback func(string)) error {
	// We don't include the destination or the callback because they aren't
	// objects we can easily assert against.
	s.stub.AddCall("CopyImage", imageTarget, aliases)
	if err := s.stub.NextErr(); err != nil {
		return err
	}
	// This is to make this CopyImage act a bit like a real CopyImage. it
	// gives some Progress callbacks, and then sets the alias in the
	// target.
	if callback != nil {
		// The real one gives progress every 1%
		for i := 10; i <= 100; i += 10 {
			callback(fmt.Sprintf("%d%%", i))
			time.Sleep(1 * time.Microsecond)
		}
	}
	if stubDest, ok := dest.(*stubClient); ok {
		if stubDest.Aliases == nil {
			stubDest.Aliases = make(map[string]string)
		}
		for _, alias := range aliases {
			stubDest.Aliases[alias] = imageTarget
		}
	}
	return nil
}

func (s *stubRemoteClient) AsRemote() Remote {
	return Remote{
		Host:     s.url,
		Protocol: SimplestreamsProtocol,
	}
}

type stubConnector struct {
	stub          *testing.Stub
	remoteClients map[string]remoteClient
}

func MakeConnector(stub *testing.Stub, remotes ...remoteClient) *stubConnector {
	remoteMap := make(map[string]remoteClient)
	for _, remote := range remotes {
		remoteMap[remote.URL()] = remote
	}
	return &stubConnector{
		stub:          stub,
		remoteClients: remoteMap,
	}
}

func (s *stubConnector) connectToSource(remote Remote) (remoteClient, error) {
	s.stub.AddCall("connectToSource", remote.Host)
	if err := s.stub.NextErr(); err != nil {
		return nil, err
	}
	return s.remoteClients[remote.Host], nil
}

func (s *imageSuite) TestEnsureImageExistsAlreadyPresent(c *gc.C) {
	raw := &stubClient{
		stub: s.Stub,
		Aliases: map[string]string{
			"ubuntu-trusty": "dead-beef",
		},
	}
	client := &imageClient{
		raw: raw,
	}
	err := client.EnsureImageExists("trusty", nil, nil)
	c.Assert(err, jc.ErrorIsNil)
	s.Stub.CheckCall(c, 0, "GetAlias", "ubuntu-trusty")
}

func (s *imageSuite) TestEnsureImageExistsFirstRemote(c *gc.C) {
	connector := MakeConnector(s.Stub, s.remoteWithTrusty)
	raw := &stubClient{
		stub: s.Stub,
		// We don't have the image locally
		Aliases: nil,
	}
	client := &imageClient{
		raw:             raw,
		connectToSource: connector.connectToSource,
	}
	remotes := []Remote{s.remoteWithTrusty.AsRemote()}
	s.Stub.ResetCalls()
	err := client.EnsureImageExists("trusty", remotes, nil)
	c.Assert(err, jc.ErrorIsNil)
	// We didn't find it locally
	s.Stub.CheckCalls(c, []testing.StubCall{
		{ // Check if we already have 'ubuntu-trusty' locally
			FuncName: "GetAlias",
			Args:     []interface{}{"ubuntu-trusty"},
		},
		{ // We didn't so connect to the first remote
			FuncName: "connectToSource",
			Args:     []interface{}{"https://match"},
		},
		{ // And check if it has trusty (which it should)
			FuncName: "GetAlias",
			Args:     []interface{}{"trusty"},
		},
		{ // So Copy the Image
			FuncName: "CopyImage",
			Args:     []interface{}{"deadbeef", []string{"ubuntu-trusty"}},
		},
	})
	// We've updated the aliases
	c.Assert(raw.Aliases, gc.DeepEquals, map[string]string{
		"ubuntu-trusty": "deadbeef",
	})
}

func (s *imageSuite) TestEnsureImageExistsUnableToConnect(c *gc.C) {
	connector := MakeConnector(s.Stub, s.remoteWithTrusty)
	raw := &stubClient{
		stub: s.Stub,
		// We don't have the image locally
		Aliases: nil,
	}
	client := &imageClient{
		raw:             raw,
		connectToSource: connector.connectToSource,
	}
	badRemote := Remote{
		Host:     "https://nosuch-remote.invalid",
		Protocol: SimplestreamsProtocol,
	}
	s.Stub.ResetCalls()
	s.Stub.SetErrors(nil, errors.Errorf("unable-to-connect"))
	remotes := []Remote{badRemote, s.remoteWithTrusty.AsRemote()}
	err := client.EnsureImageExists("trusty", remotes, nil)
	c.Assert(err, jc.ErrorIsNil)
	// We didn't find it locally
	s.Stub.CheckCalls(c, []testing.StubCall{
		{ // Check if we already have 'ubuntu-trusty' locally
			FuncName: "GetAlias",
			Args:     []interface{}{"ubuntu-trusty"},
		},
		{ // We didn't so connect to the first remote
			FuncName: "connectToSource",
			Args:     []interface{}{"https://nosuch-remote.invalid"},
		},
		{ // Connect failed to first, so connect to second and copy
			FuncName: "connectToSource",
			Args:     []interface{}{"https://match"},
		},
		{ // And check if it has trusty (which it should)
			FuncName: "GetAlias",
			Args:     []interface{}{"trusty"},
		},
		{ // So Copy the Image
			FuncName: "CopyImage",
			Args:     []interface{}{"deadbeef", []string{"ubuntu-trusty"}},
		},
	})
	// We've updated the aliases
	c.Assert(raw.Aliases, gc.DeepEquals, map[string]string{
		"ubuntu-trusty": "deadbeef",
	})
}

func (s *imageSuite) TestEnsureImageExistsNotPresentInFirstRemote(c *gc.C) {
	connector := MakeConnector(s.Stub, s.remoteWithNothing, s.remoteWithTrusty)
	raw := &stubClient{
		stub: s.Stub,
		// We don't have the image locally
		Aliases: nil,
	}
	client := &imageClient{
		raw:             raw,
		connectToSource: connector.connectToSource,
	}
	s.Stub.ResetCalls()
	remotes := []Remote{s.remoteWithNothing.AsRemote(), s.remoteWithTrusty.AsRemote()}
	err := client.EnsureImageExists("trusty", remotes, nil)
	c.Assert(err, jc.ErrorIsNil)
	// We didn't find it locally
	s.Stub.CheckCalls(c, []testing.StubCall{
		{ // Check if we already have 'ubuntu-trusty' locally
			FuncName: "GetAlias",
			Args:     []interface{}{"ubuntu-trusty"},
		},
		{ // We didn't so connect to the first remote
			FuncName: "connectToSource",
			Args:     []interface{}{s.remoteWithNothing.URL()},
		},
		{ // Lookup the Alias
			FuncName: "GetAlias",
			Args:     []interface{}{"trusty"},
		},
		{ // It wasn't found, so connect to second and look there
			FuncName: "connectToSource",
			Args:     []interface{}{s.remoteWithTrusty.URL()},
		},
		{ // And check if it has trusty (which it should)
			FuncName: "GetAlias",
			Args:     []interface{}{"trusty"},
		},
		{ // So Copy the Image
			FuncName: "CopyImage",
			Args:     []interface{}{"deadbeef", []string{"ubuntu-trusty"}},
		},
	})
	// We've updated the aliases
	c.Assert(raw.Aliases, gc.DeepEquals, map[string]string{
		"ubuntu-trusty": "deadbeef",
	})
}

func (s *imageSuite) TestEnsureImageExistsCallbackIncludesSourceURL(c *gc.C) {
	calls := make(chan string, 20)
	callback := func(message string) {
		calls <- message
	}
	connector := MakeConnector(s.Stub, s.remoteWithTrusty)
	raw := &stubClient{
		stub: s.Stub,
		// We don't have the image locally
		Aliases: nil,
	}
	client := &imageClient{
		raw:             raw,
		connectToSource: connector.connectToSource,
	}
	remotes := []Remote{s.remoteWithTrusty.AsRemote()}
	err := client.EnsureImageExists("trusty", remotes, callback)
	c.Assert(err, jc.ErrorIsNil)
	select {
	case message := <-calls:
		c.Check(message, gc.Matches, "copying image for ubuntu-trusty from https://match: \\d+%")
	default:
		c.Fatalf("no messages received")
	}
}
<|endoftext|>


<commit_before>// errchk $G $D/$F.go

// Copyright 2009 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.

// Used to crash the compiler.
// http://code.google.com/p/go/issues/detail?id=158

package main

type A struct {
	a A;
}			// ERROR "recursive"
func foo()		{ new(A).bar() }
func (a A) bar()	{}
<commit_msg>Tweak test to work with both 6g and gccgo.<commit_after>// errchk $G $D/$F.go

// Copyright 2009 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.

// Used to crash the compiler.
// http://code.google.com/p/go/issues/detail?id=158

package main

type A struct {	a A }	// ERROR "recursive"
func foo()		{ new(A).bar() }
func (a A) bar()	{}
<|endoftext|>


<commit_before>// run

// Copyright 2012 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.

// gc used to overflow a counter when a variable was
// mentioned 256 times, and generate stack corruption.

package main

func main() {
	F(1)
}

func F(arg int) {
	var X int64
	_ = X // used once
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 32 times
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 64 times
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 96 times
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 128 times
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 200 times
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 256 times
	if arg != 0 {
		panic("argument was changed")
	}
}
<commit_msg>test: fix broken test TBR=bradfitz<commit_after>// run

// Copyright 2012 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.

// gc used to overflow a counter when a variable was
// mentioned 256 times, and generate stack corruption.

package main

func main() {
	F(1)
}

func F(arg int) {
	var X int64
	_ = X // used once
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 32 times
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 64 times
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 96 times
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 128 times
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 200 times
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0
	X = 0 // used 256 times
	if arg != 1 {
		panic("argument was changed")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/dghubble/go-twitter/twitter"
	"github.com/dghubble/oauth1"
	"strconv"
	"strings"
	"time"
)

var (
	twitterBot *TwitterBot
)

// TwitterBot ...
type TwitterBot struct {
	ID      string
	ImgPath string
	Client  *twitter.Client
	Follows map[string]string
}

// NewTwitterBot ...
func NewTwitterBot(cfg *TwitterConfig) *TwitterBot {
	config := oauth1.NewConfig(cfg.ConsumerKey, cfg.ConsumerSecret)
	token := oauth1.NewToken(cfg.AccessToken, cfg.AccessSecret)
	httpClient := config.Client(oauth1.NoContext, token)
	client := twitter.NewClient(httpClient)
	bot := &TwitterBot{
		ID:      cfg.SelfID,
		ImgPath: cfg.ImgPath,
		Client:  client,
		Follows: map[string]string{
			"KanColle_STAFF": "294025417",
			"komatan":        "96604067",
			"maesanpicture":  "2381595966",
			"Strangestone":   "93332575",
			"kazuharukina":   "28787294",
		},
	}
	return bot
}

func hasHashTags(s string, tags []twitter.HashtagEntity) bool {
	for _, tag := range tags {
		if s == tag.Text {
			return true
		}
	}
	return false
}

func getMedias(tweet *twitter.Tweet) []twitter.MediaEntity {
	ee := tweet.ExtendedEntities
	if ee != nil {
		return ee.Media
	}
	return tweet.Entities.Media
}

func sendPics(medias []twitter.MediaEntity) {
	for _, media := range medias {
		switch media.Type {
		case "photo":
			go qqBot.SendPics(qqBot.SendGroupMsg, media.MediaURLHttps)
		}
	}
}

func logAllTrack(msg interface{}) {
	logger.Debug(msg)
}

func (t *TwitterBot) trackTweet(tweet *twitter.Tweet) {
	if tweet.RetweetedStatus != nil {
		// logger.Debugf("ignore retweet (%s):{%s}", tweet.User.Name, tweet.Text)
		return
	}
	flattenedText := strconv.Quote(tweet.Text)
	medias := getMedias(tweet)
	switch tweet.User.IDStr {
	case t.Follows["KanColle_STAFF"]:
		logger.Infof("(%s):{%s}", tweet.User.Name, flattenedText)
		err := redisClient.Get("forward_kancolle").Err()
		if err != nil {
			sendPics(medias)
			return
		}

		msg := tweet.Text
		if tweet.Truncated {
			msg = tweet.FullText
		}
		t := tweet.CreatedAt
		ct, err := tweet.CreatedAtTime()
		if err == nil {
			tz, err := time.LoadLocation("Asia/Tokyo")
			if err == nil {
				t = ct.In(tz).String()
			}
		}
		qqBot.SendGroupMsg(tweet.User.Name + "\n" + t + "\n\n" + msg)

	case t.Follows["komatan"]:
		if len(medias) == 0 {
			return
		}
		logger.Infof("(%s):{%s}", tweet.User.Name, flattenedText)
		sendPics(medias)

	case t.Follows["maesanpicture"]:
		if len(medias) == 0 {
			return
		}
		logger.Infof("(%s):{%s}", tweet.User.Name, flattenedText)
		if hasHashTags("毎日五月雨", tweet.Entities.Hashtags) {
			qqBot.SendGroupMsg(tweet.Text)
			sendPics(medias)
		}

	case t.Follows["Strangestone"]:
		if len(medias) == 0 {
			return
		}
		logger.Infof("(%s):{%s}", tweet.User.Name, flattenedText)
		if strings.HasPrefix(tweet.Text, "月曜日のたわわ") {
			qqBot.SendGroupMsg(tweet.Text)
			sendPics(medias)
		}

	case t.Follows["kazuharukina"]:
		if len(medias) == 0 {
			return
		}
		logger.Infof("(%s):{%s}", tweet.User.Name, flattenedText)
		if hasHashTags("和遥キナ毎日JK企画", tweet.Entities.Hashtags) {
			sendPics(medias)
		}

	default:
		// logger.Debugf("(%s):{%s}", tweet.User.Name, flattenedText)
	}
}

func (t *TwitterBot) selfProceedPics(medias []twitter.MediaEntity, action int) {
	for _, media := range medias {
		switch media.Type {
		case "photo":
			switch action {
			case 1:
				downloadFile(media.MediaURLHttps, t.ImgPath)
				go qqBot.SendPics(qqBot.SendSelfMsg, media.MediaURLHttps)
			case -1:
				removeFile(media.MediaURLHttps, t.ImgPath)
			}
		}
	}
}

func (t *TwitterBot) selfEvent(event *twitter.Event) {
	if event.Source.IDStr != t.ID {
		logger.Debugf("%s: (%s)", event.Event, event.Source.Name)
		return
	}
	switch event.Event {
	case "favorite":
		medias := getMedias(event.TargetObject)
		logger.Infof("favorite: (%s):{%s} %d medias", event.TargetObject.User.Name, strconv.Quote(event.TargetObject.Text), len(medias))
		go t.selfProceedPics(medias, 1)
	case "unfavorite":
		medias := getMedias(event.TargetObject)
		logger.Debugf("unfavorite: (%s):{%s} %d medias", event.TargetObject.User.Name, strconv.Quote(event.TargetObject.Text), len(medias))
		go t.selfProceedPics(medias, -1)
	default:
		logger.Debug(event.Event)
	}
}

func (t *TwitterBot) selfTweet(tweet *twitter.Tweet) {
	if qqBot.Config.GroupName != "" {
		if hasHashTags(qqBot.Config.GroupName, tweet.Entities.Hashtags) {
			if tweet.QuotedStatus != nil {
				logger.Infof("(%s):{%s}", qqBot.Config.GroupName, strconv.Quote(tweet.QuotedStatus.Text))
				sendPics(getMedias(tweet.QuotedStatus))
			} else {
				logger.Infof("(%s):{%s}", qqBot.Config.GroupName, strconv.Quote(tweet.Text))
				sendPics(getMedias(tweet))
			}
		}
	}
}

// Track ...
func (t *TwitterBot) Track() {
	follows := []string{}
	for _, value := range t.Follows {
		follows = append(follows, value)
	}
	for i := 1; ; i++ {
		demux := twitter.NewSwitchDemux()
		demux.Tweet = t.trackTweet
		filterParams := &twitter.StreamFilterParams{
			Follow: follows,
		}
		stream, err := t.Client.Streams.Filter(filterParams)
		if err != nil {
			logger.Error(err)
			time.Sleep(time.Duration(i) * time.Second)
		}
		demux.HandleChan(stream.Messages)
	}
}

// Self ...
func (t *TwitterBot) Self() {
	for i := 1; ; i++ {
		demux := twitter.NewSwitchDemux()
		demux.Event = t.selfEvent
		demux.Tweet = t.selfTweet
		userParams := &twitter.StreamUserParams{
			With: t.ID,
		}
		stream, err := t.Client.Streams.User(userParams)
		if err != nil {
			logger.Error(err)
			time.Sleep(time.Duration(i) * time.Second)
		}
		demux.HandleChan(stream.Messages)
	}
}
<commit_msg>log medias<commit_after>package main

import (
	"github.com/dghubble/go-twitter/twitter"
	"github.com/dghubble/oauth1"
	"strconv"
	"strings"
	"time"
)

var (
	twitterBot *TwitterBot
)

// TwitterBot ...
type TwitterBot struct {
	ID      string
	ImgPath string
	Client  *twitter.Client
	Follows map[string]string
}

// NewTwitterBot ...
func NewTwitterBot(cfg *TwitterConfig) *TwitterBot {
	config := oauth1.NewConfig(cfg.ConsumerKey, cfg.ConsumerSecret)
	token := oauth1.NewToken(cfg.AccessToken, cfg.AccessSecret)
	httpClient := config.Client(oauth1.NoContext, token)
	client := twitter.NewClient(httpClient)
	bot := &TwitterBot{
		ID:      cfg.SelfID,
		ImgPath: cfg.ImgPath,
		Client:  client,
		Follows: map[string]string{
			"KanColle_STAFF": "294025417",
			"komatan":        "96604067",
			"maesanpicture":  "2381595966",
			"Strangestone":   "93332575",
			"kazuharukina":   "28787294",
		},
	}
	return bot
}

func hasHashTags(s string, tags []twitter.HashtagEntity) bool {
	for _, tag := range tags {
		if s == tag.Text {
			return true
		}
	}
	return false
}

func getMedias(tweet *twitter.Tweet) []twitter.MediaEntity {
	ee := tweet.ExtendedEntities
	if ee != nil {
		return ee.Media
	}
	return tweet.Entities.Media
}

func sendPics(medias []twitter.MediaEntity) {
	for _, media := range medias {
		switch media.Type {
		case "photo":
			go qqBot.SendPics(qqBot.SendGroupMsg, media.MediaURLHttps)
		}
	}
}

func logAllTrack(msg interface{}) {
	logger.Debug(msg)
}

func (t *TwitterBot) trackTweet(tweet *twitter.Tweet) {
	if tweet.RetweetedStatus != nil {
		// logger.Debugf("ignore retweet (%s):{%s}", tweet.User.Name, tweet.Text)
		return
	}
	msg := tweet.Text
	if tweet.Truncated {
		msg = tweet.FullText
	}
	flattenedText := strconv.Quote(msg)

	medias := getMedias(tweet)
	switch tweet.User.IDStr {
	case t.Follows["KanColle_STAFF"]:
		logger.Infof("(%s):{%s} %d medias", tweet.User.Name, flattenedText, len(medias))

		err := redisClient.Get("forward_kancolle").Err()
		if err != nil {
			sendPics(medias)
			return
		}

		t := tweet.CreatedAt
		ct, err := tweet.CreatedAtTime()
		if err == nil {
			tz, err := time.LoadLocation("Asia/Tokyo")
			if err == nil {
				t = ct.In(tz).String()
			}
		}
		qqBot.SendGroupMsg(tweet.User.Name + "\n" + t + "\n\n" + msg)

	case t.Follows["komatan"]:
		if len(medias) == 0 {
			return
		}
		logger.Infof("(%s):{%s}", tweet.User.Name, flattenedText)
		sendPics(medias)

	case t.Follows["maesanpicture"]:
		if len(medias) == 0 {
			return
		}
		logger.Infof("(%s):{%s}", tweet.User.Name, flattenedText)
		if hasHashTags("毎日五月雨", tweet.Entities.Hashtags) {
			qqBot.SendGroupMsg(msg)
			sendPics(medias)
		}

	case t.Follows["Strangestone"]:
		if len(medias) == 0 {
			return
		}
		logger.Infof("(%s):{%s}", tweet.User.Name, flattenedText)
		if strings.HasPrefix(msg, "月曜日のたわわ") {
			qqBot.SendGroupMsg(msg)
			sendPics(medias)
		}

	case t.Follows["kazuharukina"]:
		if len(medias) == 0 {
			return
		}
		logger.Infof("(%s):{%s}", tweet.User.Name, flattenedText)
		if hasHashTags("和遥キナ毎日JK企画", tweet.Entities.Hashtags) {
			sendPics(medias)
		}

	default:
		// logger.Debugf("(%s):{%s}", tweet.User.Name, flattenedText)
	}
}

func (t *TwitterBot) selfProceedPics(medias []twitter.MediaEntity, action int) {
	for _, media := range medias {
		switch media.Type {
		case "photo":
			switch action {
			case 1:
				downloadFile(media.MediaURLHttps, t.ImgPath)
				go qqBot.SendPics(qqBot.SendSelfMsg, media.MediaURLHttps)
			case -1:
				removeFile(media.MediaURLHttps, t.ImgPath)
			}
		}
	}
}

func (t *TwitterBot) selfEvent(event *twitter.Event) {
	if event.Source.IDStr != t.ID {
		logger.Debugf("%s: (%s)", event.Event, event.Source.Name)
		return
	}
	switch event.Event {
	case "favorite":
		medias := getMedias(event.TargetObject)
		logger.Infof("favorite: (%s):{%s} %d medias", event.TargetObject.User.Name, strconv.Quote(event.TargetObject.Text), len(medias))
		go t.selfProceedPics(medias, 1)
	case "unfavorite":
		medias := getMedias(event.TargetObject)
		logger.Debugf("unfavorite: (%s):{%s} %d medias", event.TargetObject.User.Name, strconv.Quote(event.TargetObject.Text), len(medias))
		go t.selfProceedPics(medias, -1)
	default:
		logger.Debug(event.Event)
	}
}

func (t *TwitterBot) selfTweet(tweet *twitter.Tweet) {
	if qqBot.Config.GroupName != "" {
		if hasHashTags(qqBot.Config.GroupName, tweet.Entities.Hashtags) {
			if tweet.QuotedStatus != nil {
				logger.Infof("(%s):{%s}", qqBot.Config.GroupName, strconv.Quote(tweet.QuotedStatus.Text))
				sendPics(getMedias(tweet.QuotedStatus))
			} else {
				logger.Infof("(%s):{%s}", qqBot.Config.GroupName, strconv.Quote(tweet.Text))
				sendPics(getMedias(tweet))
			}
		}
	}
}

// Track ...
func (t *TwitterBot) Track() {
	follows := []string{}
	for _, value := range t.Follows {
		follows = append(follows, value)
	}
	for i := 1; ; i++ {
		demux := twitter.NewSwitchDemux()
		demux.Tweet = t.trackTweet
		filterParams := &twitter.StreamFilterParams{
			Follow: follows,
		}
		stream, err := t.Client.Streams.Filter(filterParams)
		if err != nil {
			logger.Error(err)
			time.Sleep(time.Duration(i) * time.Second)
		}
		demux.HandleChan(stream.Messages)
	}
}

// Self ...
func (t *TwitterBot) Self() {
	for i := 1; ; i++ {
		demux := twitter.NewSwitchDemux()
		demux.Event = t.selfEvent
		demux.Tweet = t.selfTweet
		userParams := &twitter.StreamUserParams{
			With: t.ID,
		}
		stream, err := t.Client.Streams.User(userParams)
		if err != nil {
			logger.Error(err)
			time.Sleep(time.Duration(i) * time.Second)
		}
		demux.HandleChan(stream.Messages)
	}
}
<|endoftext|>


<commit_before>package quickpgp

import (
	"fmt"
	"os"

	"golang.org/x/crypto/openpgp"
)

type readPasswordCallback func(filename string) (pass []byte, err error)

func readPrivateKeyFile(filename string, passPrompt readPasswordCallback) (e *openpgp.Entity, err error) {
	var krpriv *os.File

	if krpriv, err = os.Open(filename); err != nil {
		return nil, err
	}
	defer krpriv.Close()

	entityList, err := openpgp.ReadArmoredKeyRing(krpriv)
	if err != nil {
		return nil, fmt.Errorf("reading %s: %s", filename, err)
	}
	if len(entityList) != 1 {
		return nil, fmt.Errorf("%s must contain only one key", filename)
	}
	e = entityList[0]
	if e.PrivateKey == nil {
		return nil, fmt.Errorf("%s does not contain a private key", filename)
	}
	if e.PrivateKey.Encrypted {
		if passPrompt != nil {
			var pass []byte
			if pass, err = passPrompt(filename); err == nil {
				err = e.PrivateKey.Decrypt(pass)
			}
		} else {
			return nil, fmt.Errorf("%s is encrypted", filename)
		}
	}
	return e, err
}

func readPublicKeyFile(filename string) (openpgp.EntityList, error) {
	krpub, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	e, err := openpgp.ReadArmoredKeyRing(krpub)
	if err != nil {
		return nil, fmt.Errorf("reading %s: %s", filename, err)
	}
	return e, nil
}
<commit_msg>add the ability to read both armored and unarmored keyfiles<commit_after>package quickpgp

import (
	"fmt"
	"os"

	"golang.org/x/crypto/openpgp"
	"golang.org/x/crypto/openpgp/armor"
)

type readPasswordCallback func(filename string) (pass []byte, err error)

func readPrivateKeyFile(filename string, passPrompt readPasswordCallback) (e *openpgp.Entity, err error) {
	var krpriv *os.File

	if krpriv, err = os.Open(filename); err != nil {
		return nil, err
	}
	defer krpriv.Close()

	var entityList openpgp.EntityList

	keyFileReader := openpgp.ReadKeyRing
	if _, err = armor.Decode(krpriv); err == nil {
		keyFileReader = openpgp.ReadArmoredKeyRing
	}

	krpriv.Seek(0, 0)
	if entityList, err = keyFileReader(krpriv); err != nil {
		return nil, fmt.Errorf("reading %s: %s", filename, err)
	}
	if len(entityList) != 1 {
		return nil, fmt.Errorf("%s must contain only one key", filename)
	}
	e = entityList[0]
	if e.PrivateKey == nil {
		return nil, fmt.Errorf("%s does not contain a private key", filename)
	}
	if e.PrivateKey.Encrypted {
		if passPrompt != nil {
			var pass []byte
			if pass, err = passPrompt(filename); err == nil {
				err = e.PrivateKey.Decrypt(pass)
			}
		} else {
			return nil, fmt.Errorf("%s is encrypted", filename)
		}
	}
	return e, err
}

func readPublicKeyFile(filename string) (entityList openpgp.EntityList, err error) {
	var krpub *os.File

	if krpub, err = os.Open(filename); err != nil {
		return nil, err
	}
	defer krpub.Close()

	keyFileReader := openpgp.ReadKeyRing
	if _, err = armor.Decode(krpub); err == nil {
		keyFileReader = openpgp.ReadArmoredKeyRing
	}

	krpub.Seek(0, 0)
	if entityList, err = keyFileReader(krpub); err != nil {
		return nil, fmt.Errorf("reading %s: %s", filename, err)
	}
	return entityList, nil
}
<|endoftext|>


<commit_before>package sum

func basic(sum int, nums ...int) bool {
	for _, x := range nums {
		for _, y := range nums {
			s := x + y
			if sum == s {
				return true
			}
		}
	}
	return false
}

func better(sum int, nums ...int) bool {
	max := len(nums)
	var x, y, s int
	for ix := 0; ix < max; ix++ {
		x = nums[ix]
		for iy := ix + 1; iy < max; iy++ {
			y = nums[iy]
			s = x + y
			if sum == s {
				return true
			}
		}
	}
	return false
}
<commit_msg>sum: clean better<commit_after>package sum

func basic(sum int, nums ...int) bool {
	for _, x := range nums {
		for _, y := range nums {
			s := x + y
			if sum == s {
				return true
			}
		}
	}
	return false
}

func better(sum int, nums ...int) bool {
	max := len(nums)
	for ix := 0; ix < max; ix++ {
		x := nums[ix]
		for iy := ix + 1; iy < max; iy++ {
			y := nums[iy]
			s := x + y
			if sum == s {
				return true
			}
		}
	}
	return false
}
<|endoftext|>