<commit_before>package buildkite

import (
	"fmt"
	"time"
)

// BuildsService handles communication with the build related
// methods of the buildkite API.
//
// buildkite API docs: https://buildkite.com/docs/api/builds
type BuildsService struct {
	client *Client
}

// Author of a commit (used in CreateBuild)
type Author struct {
	Name  string `json:"name,omitempty" yaml:"name,omitempty"`
	Email string `json:"email,omitempty" yaml:"email,omitempty"`
}

// CreateBuild - Create a build.
type CreateBuild struct {
	Commit  string `json:"commit" yaml:"commit"`
	Branch  string `json:"branch" yaml:"branch"`
	Message string `json:"message" yaml:"message"`

	// Optional fields
	Author                      Author            `json:"author,omitempty" yaml:"author,omitempty"`
	Env                         map[string]string `json:"env,omitempty" yaml:"env,omitempty"`
	MetaData                    map[string]string `json:"meta_data,omitempty" yaml:"meta_data,omitempty"`
	IgnorePipelineBranchFilters bool              `json:"ignore_pipeline_branch_filters,omitempty" yaml:"ignore_pipeline_branch_filters,omitempty"`
	PullRequestBaseBranch       string            `json:"pull_request_base_branch,omitempty" yaml:"pull_request_base_branch,omitempty"`
	PullRequestID               int64             `json:"pull_request_id,omitempty" yaml:"pull_request_id,omitempty"`
	PullRequestRepository       string            `json:"pull_request_repository,omitempty" yaml:"pull_request_repository,omitempty"`
}

// Creator represents who created a build
type Creator struct {
	AvatarURL string     `json:"avatar_url" yaml:"avatar_url"`
	CreatedAt *Timestamp `json:"created_at" yaml:"created_at"`
	Email     string     `json:"email" yaml:"email"`
	ID        string     `json:"id" yaml:"id"`
	Name      string     `json:"name" yaml:"name"`
}

// PullRequest represents a Github PR
type PullRequest struct {
	ID         *string `json:"id,omitempty" yaml:"id,omitempty"`
	Base       *string `json:"base,omitempty" yaml:"base,omitempty"`
	Repository *string `json:"repository,omitempty" yaml:"repository,omitempty"`
}

// Build represents a build which has run in buildkite
type Build struct {
	ID          *string                `json:"id,omitempty" yaml:"id,omitempty"`
	URL         *string                `json:"url,omitempty" yaml:"url,omitempty"`
	WebURL      *string                `json:"web_url,omitempty" yaml:"web_url,omitempty"`
	Number      *int                   `json:"number,omitempty" yaml:"number,omitempty"`
	State       *string                `json:"state,omitempty" yaml:"state,omitempty"`
	Blocked     *bool                  `json:"blocked,omitempty" yaml:"blocked,omitempty"`
	Message     *string                `json:"message,omitempty" yaml:"message,omitempty"`
	Commit      *string                `json:"commit,omitempty" yaml:"commit,omitempty"`
	Branch      *string                `json:"branch,omitempty" yaml:"branch,omitempty"`
	Env         map[string]interface{} `json:"env,omitempty" yaml:"env,omitempty"`
	CreatedAt   *Timestamp             `json:"created_at,omitempty" yaml:"created_at,omitempty"`
	ScheduledAt *Timestamp             `json:"scheduled_at,omitempty" yaml:"scheduled_at,omitempty"`
	StartedAt   *Timestamp             `json:"started_at,omitempty" yaml:"started_at,omitempty"`
	FinishedAt  *Timestamp             `json:"finished_at,omitempty" yaml:"finished_at,omitempty"`
	MetaData    interface{}            `json:"meta_data,omitempty" yaml:"meta_data,omitempty"`
	Creator     *Creator               `json:"creator,omitempty" yaml:"creator,omitempty"`
	Source      *string                `json:"source,omitempty" yaml:"source,omitempty"`

	// jobs run during the build
	Jobs []*Job `json:"jobs,omitempty" yaml:"jobs,omitempty"`

	// the pipeline this build is associated with
	Pipeline *Pipeline `json:"pipeline,omitempty" yaml:"pipeline,omitempty"`

	// the pull request this build is associated with
	PullRequest *PullRequest `json:"pull_request,omitempty" yaml:"pull_request,omitempty"`
}

// BuildsListOptions specifies the optional parameters to the
// BuildsService.List method.
type BuildsListOptions struct {

	// Filters the results by the user who created the build
	Creator string `url:"creator,omitempty"`

	// Filters the results by builds created on or after the given time
	CreatedFrom time.Time `url:"created_from,omitempty"`

	// Filters the results by builds created before the given time
	CreatedTo time.Time `url:"created_to,omitempty"`

	// Filters the results by builds finished on or after the given time
	FinishedFrom time.Time `url:"finished_from,omitempty"`

	// State of builds to list.  Possible values are: running, scheduled, passed,
	// failed, canceled, skipped and not_run. Default is "".
	State []string `url:"state,brackets,omitempty"`

	// Branch filter by the name of the branch. Default is "".
	Branch string `url:"branch,omitempty"`

	// Filters the results by builds for the specific commit SHA (full, not shortened). Default is "".
	Commit string `url:"commit,omitempty"`

	// Include all retried jobs in each build’s jobs list
	IncludeRetriedJobs bool `url:"include_retried_jobs,omitempty"`

	ListOptions
}

// Cancel - Trigger a cancel for the target build
//
// buildkite API docs: https://buildkite.com/docs/apis/rest-api/builds#cancel-a-build
func (bs *BuildsService) Cancel(org, pipeline, build string) (*Build, error) {
	u := fmt.Sprintf("v2/organizations/%s/pipelines/%s/builds/%s/cancel", org, pipeline, build)
	req, err := bs.client.NewRequest("PUT", u, nil)
	if err != nil {
		return nil, err
	}
	result := Build{}
	_, err = bs.client.Do(req, &result)
	if err != nil {
		return nil, err
	}
	return &result, nil
}

// Create - Create a pipeline
//
// buildkite API docs: https://buildkite.com/docs/api/builds#create-a-build
func (bs *BuildsService) Create(org string, pipeline string, b *CreateBuild) (*Build, *Response, error) {
	u := fmt.Sprintf("v2/organizations/%s/pipelines/%s/builds", org, pipeline)

	req, err := bs.client.NewRequest("POST", u, b)
	if err != nil {
		return nil, nil, err
	}

	build := new(Build)
	resp, err := bs.client.Do(req, build)
	if err != nil {
		return nil, resp, err
	}

	return build, resp, err
}

// Get fetches a build.
//
// buildkite API docs: https://buildkite.com/docs/api/builds#get-a-build
func (bs *BuildsService) Get(org string, pipeline string, id string, opt *BuildsListOptions) (*Build, *Response, error) {
	u := fmt.Sprintf("v2/organizations/%s/pipelines/%s/builds/%s", org, pipeline, id)

	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}
	fmt.Println(u)

	req, err := bs.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	build := new(Build)
	resp, err := bs.client.Do(req, build)
	if err != nil {
		return nil, resp, err
	}

	return build, resp, err
}

// List the builds for the current user.
//
// buildkite API docs: https://buildkite.com/docs/api/builds#list-all-builds
func (bs *BuildsService) List(opt *BuildsListOptions) ([]Build, *Response, error) {
	var u string

	u = fmt.Sprintf("v2/builds")

	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := bs.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	orgs := new([]Build)
	resp, err := bs.client.Do(req, orgs)
	if err != nil {
		return nil, resp, err
	}

	return *orgs, resp, err
}

// ListByOrg lists the builds within the specified orginisation.
//
// buildkite API docs: https://buildkite.com/docs/api/builds#list-builds-for-an-organization
func (bs *BuildsService) ListByOrg(org string, opt *BuildsListOptions) ([]Build, *Response, error) {
	var u string

	u = fmt.Sprintf("v2/organizations/%s/builds", org)

	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := bs.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	orgs := new([]Build)
	resp, err := bs.client.Do(req, orgs)
	if err != nil {
		return nil, resp, err
	}

	return *orgs, resp, err
}

// ListByPipeline lists the builds for a pipeline within the specified originisation.
//
// buildkite API docs: https://buildkite.com/docs/api/builds#list-builds-for-a-pipeline
func (bs *BuildsService) ListByPipeline(org string, pipeline string, opt *BuildsListOptions) ([]Build, *Response, error) {
	var u string

	u = fmt.Sprintf("v2/organizations/%s/pipelines/%s/builds", org, pipeline)

	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := bs.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	orgs := new([]Build)
	resp, err := bs.client.Do(req, orgs)
	if err != nil {
		return nil, resp, err
	}

	return *orgs, resp, err
}

// Rebuild triggers a rebuild for the target build
//
// buildkite API docs: https://buildkite.com/docs/apis/rest-api/builds#rebuild-a-build
func (bs *BuildsService) Rebuild(org, pipeline, build string) (*Build, error) {
	u := fmt.Sprintf("v2/organizations/%s/pipelines/%s/builds/%s/rebuild", org, pipeline, build)
	req, err := bs.client.NewRequest("PUT", u, nil)
	if err != nil {
		return nil, err
	}
	result := Build{}
	_, err = bs.client.Do(req, &result)
	if err != nil {
		return nil, err
	}
	return &result, nil
}
<commit_msg>builds.go: remove fmt.Println of URL from development/debug.<commit_after>package buildkite

import (
	"fmt"
	"time"
)

// BuildsService handles communication with the build related
// methods of the buildkite API.
//
// buildkite API docs: https://buildkite.com/docs/api/builds
type BuildsService struct {
	client *Client
}

// Author of a commit (used in CreateBuild)
type Author struct {
	Name  string `json:"name,omitempty" yaml:"name,omitempty"`
	Email string `json:"email,omitempty" yaml:"email,omitempty"`
}

// CreateBuild - Create a build.
type CreateBuild struct {
	Commit  string `json:"commit" yaml:"commit"`
	Branch  string `json:"branch" yaml:"branch"`
	Message string `json:"message" yaml:"message"`

	// Optional fields
	Author                      Author            `json:"author,omitempty" yaml:"author,omitempty"`
	Env                         map[string]string `json:"env,omitempty" yaml:"env,omitempty"`
	MetaData                    map[string]string `json:"meta_data,omitempty" yaml:"meta_data,omitempty"`
	IgnorePipelineBranchFilters bool              `json:"ignore_pipeline_branch_filters,omitempty" yaml:"ignore_pipeline_branch_filters,omitempty"`
	PullRequestBaseBranch       string            `json:"pull_request_base_branch,omitempty" yaml:"pull_request_base_branch,omitempty"`
	PullRequestID               int64             `json:"pull_request_id,omitempty" yaml:"pull_request_id,omitempty"`
	PullRequestRepository       string            `json:"pull_request_repository,omitempty" yaml:"pull_request_repository,omitempty"`
}

// Creator represents who created a build
type Creator struct {
	AvatarURL string     `json:"avatar_url" yaml:"avatar_url"`
	CreatedAt *Timestamp `json:"created_at" yaml:"created_at"`
	Email     string     `json:"email" yaml:"email"`
	ID        string     `json:"id" yaml:"id"`
	Name      string     `json:"name" yaml:"name"`
}

// PullRequest represents a Github PR
type PullRequest struct {
	ID         *string `json:"id,omitempty" yaml:"id,omitempty"`
	Base       *string `json:"base,omitempty" yaml:"base,omitempty"`
	Repository *string `json:"repository,omitempty" yaml:"repository,omitempty"`
}

// Build represents a build which has run in buildkite
type Build struct {
	ID          *string                `json:"id,omitempty" yaml:"id,omitempty"`
	URL         *string                `json:"url,omitempty" yaml:"url,omitempty"`
	WebURL      *string                `json:"web_url,omitempty" yaml:"web_url,omitempty"`
	Number      *int                   `json:"number,omitempty" yaml:"number,omitempty"`
	State       *string                `json:"state,omitempty" yaml:"state,omitempty"`
	Blocked     *bool                  `json:"blocked,omitempty" yaml:"blocked,omitempty"`
	Message     *string                `json:"message,omitempty" yaml:"message,omitempty"`
	Commit      *string                `json:"commit,omitempty" yaml:"commit,omitempty"`
	Branch      *string                `json:"branch,omitempty" yaml:"branch,omitempty"`
	Env         map[string]interface{} `json:"env,omitempty" yaml:"env,omitempty"`
	CreatedAt   *Timestamp             `json:"created_at,omitempty" yaml:"created_at,omitempty"`
	ScheduledAt *Timestamp             `json:"scheduled_at,omitempty" yaml:"scheduled_at,omitempty"`
	StartedAt   *Timestamp             `json:"started_at,omitempty" yaml:"started_at,omitempty"`
	FinishedAt  *Timestamp             `json:"finished_at,omitempty" yaml:"finished_at,omitempty"`
	MetaData    interface{}            `json:"meta_data,omitempty" yaml:"meta_data,omitempty"`
	Creator     *Creator               `json:"creator,omitempty" yaml:"creator,omitempty"`
	Source      *string                `json:"source,omitempty" yaml:"source,omitempty"`

	// jobs run during the build
	Jobs []*Job `json:"jobs,omitempty" yaml:"jobs,omitempty"`

	// the pipeline this build is associated with
	Pipeline *Pipeline `json:"pipeline,omitempty" yaml:"pipeline,omitempty"`

	// the pull request this build is associated with
	PullRequest *PullRequest `json:"pull_request,omitempty" yaml:"pull_request,omitempty"`
}

// BuildsListOptions specifies the optional parameters to the
// BuildsService.List method.
type BuildsListOptions struct {

	// Filters the results by the user who created the build
	Creator string `url:"creator,omitempty"`

	// Filters the results by builds created on or after the given time
	CreatedFrom time.Time `url:"created_from,omitempty"`

	// Filters the results by builds created before the given time
	CreatedTo time.Time `url:"created_to,omitempty"`

	// Filters the results by builds finished on or after the given time
	FinishedFrom time.Time `url:"finished_from,omitempty"`

	// State of builds to list.  Possible values are: running, scheduled, passed,
	// failed, canceled, skipped and not_run. Default is "".
	State []string `url:"state,brackets,omitempty"`

	// Branch filter by the name of the branch. Default is "".
	Branch string `url:"branch,omitempty"`

	// Filters the results by builds for the specific commit SHA (full, not shortened). Default is "".
	Commit string `url:"commit,omitempty"`

	// Include all retried jobs in each build’s jobs list
	IncludeRetriedJobs bool `url:"include_retried_jobs,omitempty"`

	ListOptions
}

// Cancel - Trigger a cancel for the target build
//
// buildkite API docs: https://buildkite.com/docs/apis/rest-api/builds#cancel-a-build
func (bs *BuildsService) Cancel(org, pipeline, build string) (*Build, error) {
	u := fmt.Sprintf("v2/organizations/%s/pipelines/%s/builds/%s/cancel", org, pipeline, build)
	req, err := bs.client.NewRequest("PUT", u, nil)
	if err != nil {
		return nil, err
	}
	result := Build{}
	_, err = bs.client.Do(req, &result)
	if err != nil {
		return nil, err
	}
	return &result, nil
}

// Create - Create a pipeline
//
// buildkite API docs: https://buildkite.com/docs/api/builds#create-a-build
func (bs *BuildsService) Create(org string, pipeline string, b *CreateBuild) (*Build, *Response, error) {
	u := fmt.Sprintf("v2/organizations/%s/pipelines/%s/builds", org, pipeline)

	req, err := bs.client.NewRequest("POST", u, b)
	if err != nil {
		return nil, nil, err
	}

	build := new(Build)
	resp, err := bs.client.Do(req, build)
	if err != nil {
		return nil, resp, err
	}

	return build, resp, err
}

// Get fetches a build.
//
// buildkite API docs: https://buildkite.com/docs/api/builds#get-a-build
func (bs *BuildsService) Get(org string, pipeline string, id string, opt *BuildsListOptions) (*Build, *Response, error) {
	u := fmt.Sprintf("v2/organizations/%s/pipelines/%s/builds/%s", org, pipeline, id)

	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := bs.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	build := new(Build)
	resp, err := bs.client.Do(req, build)
	if err != nil {
		return nil, resp, err
	}

	return build, resp, err
}

// List the builds for the current user.
//
// buildkite API docs: https://buildkite.com/docs/api/builds#list-all-builds
func (bs *BuildsService) List(opt *BuildsListOptions) ([]Build, *Response, error) {
	var u string

	u = fmt.Sprintf("v2/builds")

	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := bs.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	orgs := new([]Build)
	resp, err := bs.client.Do(req, orgs)
	if err != nil {
		return nil, resp, err
	}

	return *orgs, resp, err
}

// ListByOrg lists the builds within the specified orginisation.
//
// buildkite API docs: https://buildkite.com/docs/api/builds#list-builds-for-an-organization
func (bs *BuildsService) ListByOrg(org string, opt *BuildsListOptions) ([]Build, *Response, error) {
	var u string

	u = fmt.Sprintf("v2/organizations/%s/builds", org)

	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := bs.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	orgs := new([]Build)
	resp, err := bs.client.Do(req, orgs)
	if err != nil {
		return nil, resp, err
	}

	return *orgs, resp, err
}

// ListByPipeline lists the builds for a pipeline within the specified originisation.
//
// buildkite API docs: https://buildkite.com/docs/api/builds#list-builds-for-a-pipeline
func (bs *BuildsService) ListByPipeline(org string, pipeline string, opt *BuildsListOptions) ([]Build, *Response, error) {
	var u string

	u = fmt.Sprintf("v2/organizations/%s/pipelines/%s/builds", org, pipeline)

	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := bs.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	orgs := new([]Build)
	resp, err := bs.client.Do(req, orgs)
	if err != nil {
		return nil, resp, err
	}

	return *orgs, resp, err
}

// Rebuild triggers a rebuild for the target build
//
// buildkite API docs: https://buildkite.com/docs/apis/rest-api/builds#rebuild-a-build
func (bs *BuildsService) Rebuild(org, pipeline, build string) (*Build, error) {
	u := fmt.Sprintf("v2/organizations/%s/pipelines/%s/builds/%s/rebuild", org, pipeline, build)
	req, err := bs.client.NewRequest("PUT", u, nil)
	if err != nil {
		return nil, err
	}
	result := Build{}
	_, err = bs.client.Do(req, &result)
	if err != nil {
		return nil, err
	}
	return &result, nil
}
<|endoftext|>


<commit_before>package statgo

import (
	"fmt"
	"github.com/stretchr/testify/assert"
	"io"
	"io/ioutil"
	"net"
	"runtime"
	"sync"
	"testing"
	"time"
)

func TestHostInfo(t *testing.T) {
	s := NewStat()
	hi := s.HostInfos()
	assert.NotNil(t, s)
	assert.NotEmpty(t, hi.HostName, hi.OSName, hi.OSRelease, hi.OSVersion, hi.Platform)
	assert.True(t, hi.NCPUs > 0, hi.MaxCPUs > 0)

	t.Log(hi)
}

func TestCPU(t *testing.T) {
	s := NewStat()
	cpu := s.CPUStats()
	assert.NotNil(t, s)
	assert.NotNil(t, cpu)

	time.Sleep(100 * time.Millisecond)

	cpu = s.CPUStats()
	t.Log(cpu)
}

func TestCPULoad(t *testing.T) {
	s := NewStat()
	initialCPU := s.CPUStats()
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)
	var wg sync.WaitGroup
	wg.Add(cpuCount)
	doneChan := make(chan bool, cpuCount)
	for k := 0; k < cpuCount; k++ {
		go func() {
			defer wg.Done()
			var i uint64 = 2
			for {
				select {
				case <-doneChan:
					{
						return
					}
				default:
					{
					}
				}
				i = i * i
			}
		}()
	}
	s.CPUStats()
	testDuration := 5 * time.Second
	time.Sleep(testDuration)
	cpu := s.CPUStats()
	for k := 0; k < cpuCount; k++ {
		doneChan <- true
	}
	wg.Wait()

	//Assure that the Period of the stats is about the same as the Duration of the stats.
	assert.True(t, cpu.Period-testDuration < time.Second*2 || cpu.Period-testDuration > 2*time.Second)
	t.Log("CPU Idle %:", cpu.Idle)
	//The CPU should not be idle if we run cpuCount goroutines
	assert.True(t, cpu.Idle < 50.0)
	//The stats should have changed from the start till the finish of this test
	assert.True(t, cpu.Idle != initialCPU.Idle)
}

func TestFSInfos(t *testing.T) {
	s := NewStat()
	f := s.FSInfos()
	assert.True(t, len(f) > 0)

	for _, fs := range f {
		t.Log(fs)
	}
}

func TestInterfaceInfos(t *testing.T) {
	s := NewStat()
	interfaces := s.InteraceInfos()
	assert.True(t, len(interfaces) > 0)

	for _, i := range interfaces {
		t.Log(i)
	}
}

func TestVM(t *testing.T) {
	s := NewStat()
	m := s.MemStats()
	assert.NotNil(t, s)
	assert.NotNil(t, m)

	t.Log(m)
}

func TestDisksIO(t *testing.T) {
	s := NewStat()
	d := s.DiskIOStats()
	assert.NotNil(t, s)
	assert.NotNil(t, d)

	t.Log(d)
}

func TestNetIO(t *testing.T) {
	s := NewStat()
	n := s.NetIOStats()
	assert.NotNil(t, s)
	assert.NotNil(t, n)

	t.Log(n)
}

func getInterface(arr []*NetIOStats, names ...string) (*NetIOStats, error) {
	for _, ns := range arr {
		for _, name := range names {
			if ns.IntName == name {
				return ns, nil
			}
		}
	}
	return nil, fmt.Errorf("No interface not found matching any of %v", names)
}

func TestNetIOTXRX(t *testing.T) {
	s := NewStat()
	beforeNetIOArr := s.NetIOStats()
	beforeNetIO, err := getInterface(beforeNetIOArr, "lo", "lo0")
	if err != nil {
		t.Log(err)
		t.FailNow()
		return
	}
	ln, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		t.Log("Could not listen on port 8080", err)
		t.SkipNow()
		return
	}
	defer ln.Close()
	go func() {
		conn, err := ln.Accept()
		if err != nil {
			return
		}
		defer conn.Close()
		io.Copy(ioutil.Discard, conn)
	}()
	conn, err := net.Dial("tcp", "127.0.0.1:8080")
	if err != nil {
		t.Log("Could not connect to server:", err)
		t.SkipNow()
		return
	}
	defer conn.Close()
	conn.Write(make([]byte, 1024*1024))
	afterNetIOArr := s.NetIOStats()
	afterNetIO, err := getInterface(afterNetIOArr, "lo", "lo0")
	if err != nil {
		t.Log(err)
		t.SkipNow()
		return
	}
	t.Log("BeforeData:", beforeNetIO)
	t.Log("After 1MB data:", afterNetIO)
	assert.True(t, beforeNetIO.TX < afterNetIO.TX)
	assert.True(t, beforeNetIO.RX < afterNetIO.TX)
}

func TestProcess(t *testing.T) {
	s := NewStat()
	p := s.ProcessStats()
	assert.NotNil(t, s)
	assert.NotNil(t, p)

	t.Log(p)
}

func TestPages(t *testing.T) {
	s := NewStat()
	p := s.PageStats()
	assert.NotNil(t, s)
	assert.NotNil(t, p)

	t.Log(p)
}

func TestGoRoutineCleanup(t *testing.T) {
	var wg sync.WaitGroup

	s := NewStat()
	s.PageStats()

	wg.Add(1)
	go func() {
		defer wg.Done()
		s.free()
	}()

	wg.Wait()
}

func TestGoRoutines(t *testing.T) {
	// test for ticket #2
	// ping -s 20000 localhost, check for growing lo0 stats ([0] at least on OSX)

	t.Skip()
	var wg sync.WaitGroup
	s := NewStat()

	wg.Add(1)
	go func() {
		defer wg.Done()
		t.Log("1", s.NetIOStats()[0])
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		time.Sleep(2500 * time.Millisecond)
		t.Log("2", s.NetIOStats()[0])
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		time.Sleep(5 * time.Second)
		t.Log("4", s.NetIOStats()[0])
	}()
	wg.Wait()
}
<commit_msg>Formatting changes, as requested<commit_after>package statgo

import (
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"runtime"
	"sync"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestHostInfo(t *testing.T) {
	s := NewStat()
	hi := s.HostInfos()
	assert.NotNil(t, s)
	assert.NotEmpty(t, hi.HostName, hi.OSName, hi.OSRelease, hi.OSVersion, hi.Platform)
	assert.True(t, hi.NCPUs > 0, hi.MaxCPUs > 0)

	t.Log(hi)
}

func TestCPU(t *testing.T) {
	s := NewStat()
	cpu := s.CPUStats()
	assert.NotNil(t, s)
	assert.NotNil(t, cpu)

	time.Sleep(100 * time.Millisecond)

	cpu = s.CPUStats()
	t.Log(cpu)
}

func TestCPULoad(t *testing.T) {
	s := NewStat()
	initialCPU := s.CPUStats()
	cpuCount := runtime.NumCPU()
	runtime.GOMAXPROCS(cpuCount)
	var wg sync.WaitGroup
	wg.Add(cpuCount)
	doneChan := make(chan bool, cpuCount)
	for k := 0; k < cpuCount; k++ {
		go func() {
			defer wg.Done()
			var i uint64 = 2
			for {
				select {
				case <-doneChan:
					{
						return
					}
				default:
					{
					}
				}
				i = i * i
			}
		}()
	}
	s.CPUStats()
	testDuration := 5 * time.Second
	time.Sleep(testDuration)
	cpu := s.CPUStats()
	for k := 0; k < cpuCount; k++ {
		doneChan <- true
	}
	wg.Wait()

	//Assure that the Period of the stats is about the same as the Duration of the stats.
	assert.True(t, cpu.Period-testDuration < time.Second*2 || cpu.Period-testDuration > 2*time.Second)
	t.Log("CPU Idle %:", cpu.Idle)
	//The CPU should not be idle if we run cpuCount goroutines
	assert.True(t, cpu.Idle < 50.0)
	//The stats should have changed from the start till the finish of this test
	assert.True(t, cpu.Idle != initialCPU.Idle)
}

func TestFSInfos(t *testing.T) {
	s := NewStat()
	f := s.FSInfos()
	assert.True(t, len(f) > 0)

	for _, fs := range f {
		t.Log(fs)
	}
}

func TestInterfaceInfos(t *testing.T) {
	s := NewStat()
	interfaces := s.InteraceInfos()
	assert.True(t, len(interfaces) > 0)

	for _, i := range interfaces {
		t.Log(i)
	}
}

func TestVM(t *testing.T) {
	s := NewStat()
	m := s.MemStats()
	assert.NotNil(t, s)
	assert.NotNil(t, m)

	t.Log(m)
}

func TestDisksIO(t *testing.T) {
	s := NewStat()
	d := s.DiskIOStats()
	assert.NotNil(t, s)
	assert.NotNil(t, d)

	t.Log(d)
}

func TestNetIO(t *testing.T) {
	s := NewStat()
	n := s.NetIOStats()
	assert.NotNil(t, s)
	assert.NotNil(t, n)

	t.Log(n)
}

func getInterface(arr []*NetIOStats, names ...string) (*NetIOStats, error) {
	for _, ns := range arr {
		for _, name := range names {
			if ns.IntName == name {
				return ns, nil
			}
		}
	}
	return nil, fmt.Errorf("No interface not found matching any of %v", names)
}

func TestNetIOTXRX(t *testing.T) {
	s := NewStat()
	beforeNetIOArr := s.NetIOStats()
	beforeNetIO, err := getInterface(beforeNetIOArr, "lo", "lo0")
	if err != nil {
		t.Log(err)
		t.FailNow()
		return
	}
	ln, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		t.Log("Could not listen on port 8080", err)
		t.SkipNow()
		return
	}
	defer ln.Close()
	go func() {
		conn, err := ln.Accept()
		if err != nil {
			return
		}
		defer conn.Close()
		io.Copy(ioutil.Discard, conn)
	}()
	conn, err := net.Dial("tcp", "127.0.0.1:8080")
	if err != nil {
		t.Log("Could not connect to server:", err)
		t.SkipNow()
		return
	}
	defer conn.Close()
	conn.Write(make([]byte, 1024*1024))
	afterNetIOArr := s.NetIOStats()
	afterNetIO, err := getInterface(afterNetIOArr, "lo", "lo0")
	if err != nil {
		t.Log(err)
		t.SkipNow()
		return
	}
	t.Log("BeforeData:", beforeNetIO)
	t.Log("After 1MB data:", afterNetIO)
	assert.True(t, beforeNetIO.TX < afterNetIO.TX)
	assert.True(t, beforeNetIO.RX < afterNetIO.TX)
}

func TestProcess(t *testing.T) {
	s := NewStat()
	p := s.ProcessStats()
	assert.NotNil(t, s)
	assert.NotNil(t, p)

	t.Log(p)
}

func TestPages(t *testing.T) {
	s := NewStat()
	p := s.PageStats()
	assert.NotNil(t, s)
	assert.NotNil(t, p)

	t.Log(p)
}

func TestGoRoutineCleanup(t *testing.T) {
	var wg sync.WaitGroup

	s := NewStat()
	s.PageStats()

	wg.Add(1)
	go func() {
		defer wg.Done()
		s.free()
	}()

	wg.Wait()
}

func TestGoRoutines(t *testing.T) {
	// test for ticket #2
	// ping -s 20000 localhost, check for growing lo0 stats ([0] at least on OSX)

	t.Skip()
	var wg sync.WaitGroup
	s := NewStat()

	wg.Add(1)
	go func() {
		defer wg.Done()
		t.Log("1", s.NetIOStats()[0])
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		time.Sleep(2500 * time.Millisecond)
		t.Log("2", s.NetIOStats()[0])
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		time.Sleep(5 * time.Second)
		t.Log("4", s.NetIOStats()[0])
	}()
	wg.Wait()
}
<|endoftext|>


<commit_before>// Copyright 2013 SteelSeries ApS. All rights reserved.
// No license is given for the use of this source code.

// This package impliments a basic LISP interpretor for embedding in a go program for scripting.
// This file provides a repl

package golisp

import (
    "fmt"
)

func Repl() {
    prompt := "> "
    LoadHistoryFromFile(".golisp_history")
    for true {
        for true {
            input := *ReadLine(&prompt)
            if input != "" {
                AddHistory(input)
                code, err := Parse(input)
                if err != nil {
                    fmt.Printf("Error: %s\n", err)
                } else {
                    d, err := Eval(code, Global)
                    if err != nil {
                        fmt.Printf("Error in evaluation: %s\n", err)
                    } else {
                        fmt.Printf("==> %s\n", String(d))
                    }
                }
            }
        }
    }
}
<commit_msg>Added a startup message to the repl.<commit_after>// Copyright 2013 SteelSeries ApS. All rights reserved.
// No license is given for the use of this source code.

// This package impliments a basic LISP interpretor for embedding in a go program for scripting.
// This file provides a repl

package golisp

import (
    "fmt"
)

func Repl() {
    fmt.Printf("Welcome to GoLisp\n")
    fmt.Printf("Copyright 2013 SteelSeries\n")
    fmt.Printf("Evaluate '(quit)' to exit.\n\n")
    prompt := "> "
    LoadHistoryFromFile(".golisp_history")
    for true {
        for true {
            input := *ReadLine(&prompt)
            if input != "" {
                AddHistory(input)
                code, err := Parse(input)
                if err != nil {
                    fmt.Printf("Error: %s\n", err)
                } else {
                    d, err := Eval(code, Global)
                    if err != nil {
                        fmt.Printf("Error in evaluation: %s\n", err)
                    } else {
                        fmt.Printf("==> %s\n", String(d))
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/gcfg"
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/keep94/gohue"
	"github.com/keep94/maybe"
	"os"
	"os/user"
	"strconv"
	"math/rand"
	"time"
)

type Config struct {
	MeetHue struct {
		IPAddress   string
		Username    string
		Flag        bool
		LightsCount int
	}
}

func handle_err(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func set_color_func(color gohue.Color, lights_count int, bridge *gohue.Context) func(*cli.Context) {
	return func(c *cli.Context) {
			props := gohue.LightProperties{C: gohue.NewMaybeColor(color), TransitionTime: maybe.NewUint16(0)}
			for i := 1; i <= lights_count; i++ {
				bridge.Set(i, &props)
			}
		}
}

func main() {
	rand.Seed(time.Now().UTC().UnixNano())

	usr, err := user.Current()
	handle_err(err)

	var cfg Config
	err = gcfg.ReadFileInto(&cfg, usr.HomeDir+"/.lights.ini")
	handle_err(err)

	app := cli.NewApp()
	app.Name = "lights"
	app.Usage = "make an explosive entrance"

	bridge := gohue.NewContext(cfg.MeetHue.IPAddress, cfg.MeetHue.Username)

	lights_count := cfg.MeetHue.LightsCount

	var red = cli.Command{
		Name:      "red",
		ShortName: "r",
		Usage:     "set all lights to red",
		Action: set_color_func(gohue.Red, lights_count, bridge),
	}

	var blue = cli.Command{
		Name:      "blue",
		ShortName: "b",
		Usage:     "set all lights to blue",
		Action: set_color_func(gohue.Blue, lights_count, bridge),
	}

	var white = cli.Command{
		Name:      "white",
		ShortName: "w",
		Usage:     "set all lights to white",
		Action: set_color_func(gohue.White, lights_count, bridge),
	}

	var random = cli.Command{
		Name:      "random",
		ShortName: "rnd",
		Usage:     "random color",
		Action: func(c *cli.Context) {
			for i := 1; i <= lights_count; i++ {
				x := rand.Float64()
				y := rand.Float64()
				props := gohue.LightProperties{C: gohue.NewMaybeColor(gohue.NewColor(x, y)), TransitionTime: maybe.NewUint16(0)}
				bridge.Set(i, &props)
			}
		},
	}

	var popo = cli.Command{
		Name:      "police",
		ShortName: "popo",
		Usage:     "popo scheme",
		Action: func(c *cli.Context) {
			for {
				red.Action(c)
				time.Sleep(250 * time.Millisecond)
				blue.Action(c)
				time.Sleep(250 * time.Millisecond)
			}
		},
	}

	var command_on = cli.Command{
		Name:      "off",
		ShortName: "0",
		Usage:     "turn off all lights",
		Action: func(c *cli.Context) {
			props := gohue.LightProperties{On: maybe.NewBool(false), TransitionTime: maybe.NewUint16(0)}
			for i := 1; i <= lights_count; i++ {
				bridge.Set(i, &props)
			}
		},
	}

	var command_off = cli.Command{
		Name:      "on",
		ShortName: "1",
		Usage:     "turn on all lights",
		Action: func(c *cli.Context) {
			props := gohue.LightProperties{On: maybe.NewBool(true)}
			for i := 1; i <= lights_count; i++ {
				bridge.Set(i, &props)
			}
		},
	}

	var command_brightness = cli.Command{
		Name:      "brightness",
		ShortName: "bri",
		Usage:     "turn on all lights",
		Action: func(c *cli.Context) {
			bright, _ := strconv.ParseUint(c.Args().First(), 10, 8)
			props := gohue.LightProperties{Bri: maybe.NewUint8(uint8(bright)), TransitionTime: maybe.NewUint16(0)}
			for i := 1; i <= lights_count; i++ {
				bridge.Set(i, &props)
			}
		},
	}

	app.Commands = []cli.Command{
		command_on,
		command_off,
		command_brightness,
		red,
		white,
		blue,
		random,
		popo,
	}

	app.Run(os.Args)
}
<commit_msg>When using 'random', all lights should have the same color.<commit_after>package main

import (
	"code.google.com/p/gcfg"
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/keep94/gohue"
	"github.com/keep94/maybe"
	"os"
	"os/user"
	"strconv"
	"math/rand"
	"time"
)

type Config struct {
	MeetHue struct {
		IPAddress   string
		Username    string
		Flag        bool
		LightsCount int
	}
}

func handle_err(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func set_color_func(color gohue.Color, lights_count int, bridge *gohue.Context) func(*cli.Context) {
	return func(c *cli.Context) {
			props := gohue.LightProperties{C: gohue.NewMaybeColor(color), TransitionTime: maybe.NewUint16(0)}
			for i := 1; i <= lights_count; i++ {
				bridge.Set(i, &props)
			}
		}
}

func main() {
	rand.Seed(time.Now().UTC().UnixNano())

	usr, err := user.Current()
	handle_err(err)

	var cfg Config
	err = gcfg.ReadFileInto(&cfg, usr.HomeDir+"/.lights.ini")
	handle_err(err)

	app := cli.NewApp()
	app.Name = "lights"
	app.Usage = "make an explosive entrance"

	bridge := gohue.NewContext(cfg.MeetHue.IPAddress, cfg.MeetHue.Username)

	lights_count := cfg.MeetHue.LightsCount

	var red = cli.Command{
		Name:      "red",
		ShortName: "r",
		Usage:     "set all lights to red",
		Action: set_color_func(gohue.Red, lights_count, bridge),
	}

	var blue = cli.Command{
		Name:      "blue",
		ShortName: "b",
		Usage:     "set all lights to blue",
		Action: set_color_func(gohue.Blue, lights_count, bridge),
	}

	var white = cli.Command{
		Name:      "white",
		ShortName: "w",
		Usage:     "set all lights to white",
		Action: set_color_func(gohue.White, lights_count, bridge),
	}

	var random = cli.Command{
		Name:      "random",
		ShortName: "rnd",
		Usage:     "random color",
		Action: func(c *cli.Context) {
			x := rand.Float64()
			y := rand.Float64()
			set_color_func(gohue.NewColor(x, y), lights_count, bridge)(c)
		},
	}

	var popo = cli.Command{
		Name:      "police",
		ShortName: "popo",
		Usage:     "popo scheme",
		Action: func(c *cli.Context) {
			for {
				red.Action(c)
				time.Sleep(250 * time.Millisecond)
				blue.Action(c)
				time.Sleep(250 * time.Millisecond)
			}
		},
	}

	var command_on = cli.Command{
		Name:      "off",
		ShortName: "0",
		Usage:     "turn off all lights",
		Action: func(c *cli.Context) {
			props := gohue.LightProperties{On: maybe.NewBool(false), TransitionTime: maybe.NewUint16(0)}
			for i := 1; i <= lights_count; i++ {
				bridge.Set(i, &props)
			}
		},
	}

	var command_off = cli.Command{
		Name:      "on",
		ShortName: "1",
		Usage:     "turn on all lights",
		Action: func(c *cli.Context) {
			props := gohue.LightProperties{On: maybe.NewBool(true)}
			for i := 1; i <= lights_count; i++ {
				bridge.Set(i, &props)
			}
		},
	}

	var command_brightness = cli.Command{
		Name:      "brightness",
		ShortName: "bri",
		Usage:     "turn on all lights",
		Action: func(c *cli.Context) {
			bright, _ := strconv.ParseUint(c.Args().First(), 10, 8)
			props := gohue.LightProperties{Bri: maybe.NewUint8(uint8(bright)), TransitionTime: maybe.NewUint16(0)}
			for i := 1; i <= lights_count; i++ {
				bridge.Set(i, &props)
			}
		},
	}

	app.Commands = []cli.Command{
		command_on,
		command_off,
		command_brightness,
		red,
		white,
		blue,
		random,
		popo,
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package vsock

import (
	"crypto/tls"
	"net"
	"net/http"
	"strings"
	"time"

	"github.com/mdlayher/vsock"

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

// Dial connects to a remote vsock.
func Dial(cid, port uint32) (net.Conn, error) {
	return vsock.Dial(cid, port)
}

// Listen listens for a connection.
func Listen(port uint32) (net.Listener, error) {
	return vsock.Listen(port)
}

// HTTPClient provides an HTTP client for using over vsock.
func HTTPClient(vsockID int, tlsClientCert string, tlsClientKey string, tlsServerCert string) (*http.Client, error) {
	client := &http.Client{}

	// Get the TLS configuration.
	tlsConfig, err := shared.GetTLSConfigMem(tlsClientCert, tlsClientKey, "", tlsServerCert, false)
	if err != nil {
		return nil, err
	}

	client.Transport = &http.Transport{
		TLSClientConfig: tlsConfig,
		// Setup a VM socket dialer.
		Dial: func(network, addr string) (net.Conn, error) {
			var conn net.Conn
			var err error

			// Retry for up to 1s at 100ms interval to handle various failures.
			for i := 0; i < 10; i++ {
				conn, err = Dial(uint32(vsockID), shared.DefaultPort)
				if err == nil {
					break
				} else {
					// Handle some fatal errors.
					msg := err.Error()
					if strings.Contains(msg, "connection timed out") {
						break
					} else if strings.Contains(msg, "connection refused") {
						break
					}

					// Retry the rest.
				}

				time.Sleep(100 * time.Millisecond)
			}
			if err != nil {
				return nil, err
			}

			tlsConn := tls.Client(conn, tlsConfig)

			// Validate the connection.
			err = tlsConn.Handshake()
			if err != nil {
				conn.Close()
				return nil, err
			}

			return tlsConn, nil
		},
		DisableKeepAlives: true,
	}

	// Setup redirect policy.
	client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		// Replicate the headers.
		req.Header = via[len(via)-1].Header

		return nil
	}

	return client, nil
}
<commit_msg>lxd/vsock: Retry timeouts once<commit_after>package vsock

import (
	"crypto/tls"
	"net"
	"net/http"
	"strings"
	"time"

	"github.com/mdlayher/vsock"

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

// Dial connects to a remote vsock.
func Dial(cid, port uint32) (net.Conn, error) {
	return vsock.Dial(cid, port)
}

// Listen listens for a connection.
func Listen(port uint32) (net.Listener, error) {
	return vsock.Listen(port)
}

// HTTPClient provides an HTTP client for using over vsock.
func HTTPClient(vsockID int, tlsClientCert string, tlsClientKey string, tlsServerCert string) (*http.Client, error) {
	client := &http.Client{}

	// Get the TLS configuration.
	tlsConfig, err := shared.GetTLSConfigMem(tlsClientCert, tlsClientKey, "", tlsServerCert, false)
	if err != nil {
		return nil, err
	}

	client.Transport = &http.Transport{
		TLSClientConfig: tlsConfig,
		// Setup a VM socket dialer.
		Dial: func(network, addr string) (net.Conn, error) {
			var conn net.Conn
			var err error

			// Retry for up to 1s at 100ms interval to handle various failures.
			for i := 0; i < 10; i++ {
				conn, err = Dial(uint32(vsockID), shared.DefaultPort)
				if err == nil {
					break
				} else {
					// Handle some fatal errors.
					msg := err.Error()
					if strings.Contains(msg, "connection timed out") {
						// Retry once.
						conn, err = Dial(uint32(vsockID), shared.DefaultPort)
						break
					} else if strings.Contains(msg, "connection refused") {
						break
					}

					// Retry the rest.
				}

				time.Sleep(100 * time.Millisecond)
			}
			if err != nil {
				return nil, err
			}

			tlsConn := tls.Client(conn, tlsConfig)

			// Validate the connection.
			err = tlsConn.Handshake()
			if err != nil {
				conn.Close()
				return nil, err
			}

			return tlsConn, nil
		},
		DisableKeepAlives: true,
	}

	// Setup redirect policy.
	client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		// Replicate the headers.
		req.Header = via[len(via)-1].Header

		return nil
	}

	return client, nil
}
<|endoftext|>


<commit_before>/*
 *
 * k6 - a next-generation load testing tool
 * Copyright (C) 2016 Load Impact
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package stats

import (
	"errors"
	"fmt"
	"sort"
	"strconv"
	"strings"
	"time"
)

const (
	counterString = `"counter"`
	gaugeString   = `"gauge"`
	trendString   = `"trend"`
	rateString    = `"rate"`

	defaultString = `"default"`
	timeString    = `"time"`
)

// Possible values for MetricType.
const (
	Counter = MetricType(iota) // A counter that sums its data points
	Gauge                      // A gauge that displays the latest value
	Trend                      // A trend, min/max/avg/med are interesting
	Rate                       // A rate, displays % of values that aren't 0
)

// Possible values for ValueType.
const (
	Default = ValueType(iota) // Values are presented as-is
	Time                      // Values are timestamps (nanoseconds)
)

// The serialized metric type is invalid.
var ErrInvalidMetricType = errors.New("Invalid metric type")

// The serialized value type is invalid.
var ErrInvalidValueType = errors.New("Invalid value type")

// A MetricType specifies the type of a metric.
type MetricType int

// MarshalJSON serializes a MetricType as a human readable string.
func (t MetricType) MarshalJSON() ([]byte, error) {
	switch t {
	case Counter:
		return []byte(counterString), nil
	case Gauge:
		return []byte(gaugeString), nil
	case Trend:
		return []byte(trendString), nil
	case Rate:
		return []byte(rateString), nil
	default:
		return nil, ErrInvalidMetricType
	}
}

// UnmarshalJSON deserializes a MetricType from a string representation.
func (t *MetricType) UnmarshalJSON(data []byte) error {
	switch string(data) {
	case counterString:
		*t = Counter
	case gaugeString:
		*t = Gauge
	case trendString:
		*t = Trend
	case rateString:
		*t = Rate
	default:
		return ErrInvalidMetricType
	}

	return nil
}

func (t MetricType) String() string {
	switch t {
	case Counter:
		return counterString
	case Gauge:
		return gaugeString
	case Trend:
		return trendString
	case Rate:
		return rateString
	default:
		return "[INVALID]"
	}
}

// The type of values a metric contains.
type ValueType int

// MarshalJSON serializes a ValueType as a human readable string.
func (t ValueType) MarshalJSON() ([]byte, error) {
	switch t {
	case Default:
		return []byte(defaultString), nil
	case Time:
		return []byte(timeString), nil
	default:
		return nil, ErrInvalidValueType
	}
}

// UnmarshalJSON deserializes a ValueType from a string representation.
func (t *ValueType) UnmarshalJSON(data []byte) error {
	switch string(data) {
	case defaultString:
		*t = Default
	case timeString:
		*t = Time
	default:
		return ErrInvalidValueType
	}

	return nil
}

func (t ValueType) String() string {
	switch t {
	case Default:
		return defaultString
	case Time:
		return timeString
	default:
		return "[INVALID]"
	}
}

// A Sample is a single measurement.
type Sample struct {
	Metric *Metric
	Time   time.Time
	Tags   map[string]string
	Value  float64
}

// A Metric defines the shape of a set of data.
type Metric struct {
	Name     string     `json:"-"`
	Type     MetricType `json:"type"`
	Contains ValueType  `json:"contains"`

	// Filled in by the API when requested, the server side cannot count on its presence.
	Sample map[string]float64 `json:"sample"`

	// Set to true if the metric has failed a threshold.
	Tainted bool
}

func New(name string, typ MetricType, t ...ValueType) *Metric {
	vt := Default
	if len(t) > 0 {
		vt = t[0]
	}
	return &Metric{Name: name, Type: typ, Contains: vt}
}

func (m Metric) NewSink() Sink {
	switch m.Type {
	case Counter:
		return &CounterSink{}
	case Gauge:
		return &GaugeSink{}
	case Trend:
		return &TrendSink{}
	case Rate:
		return &RateSink{}
	default:
		return nil
	}
}

func (m Metric) Humanize() string {
	sample := m.Sample
	switch len(sample) {
	case 0:
		return ""
	case 1:
		for _, v := range sample {
			return m.HumanizeValue(v)
		}
		return ""
	default:
		parts := make([]string, 0, len(m.Sample))
		for key, val := range m.Sample {
			parts = append(parts, fmt.Sprintf("%s=%s", key, m.HumanizeValue(val)))
		}
		sort.Strings(parts)
		return strings.Join(parts, ", ")
	}
}

func (m Metric) HumanizeValue(v float64) string {
	switch m.Type {
	case Rate:
		return strconv.FormatFloat(100*v, 'f', 2, 64) + "%"
	default:
		switch m.Contains {
		case Time:
			d := time.Duration(v)
			switch {
			case d > time.Minute:
				d -= d % (1 * time.Second)
			case d > time.Second:
				d -= d % (10 * time.Millisecond)
			case d > time.Millisecond:
				d -= d % (10 * time.Microsecond)
			case d > time.Microsecond:
				d -= d % (10 * time.Nanosecond)
			}
			return d.String()
		default:
			return strconv.FormatFloat(v, 'f', -1, 64)
		}
	}
}

func (m Metric) GetID() string {
	return m.Name
}

func (m *Metric) SetID(id string) error {
	m.Name = id
	return nil
}
<commit_msg>[refactor] Dropping unused field<commit_after>/*
 *
 * k6 - a next-generation load testing tool
 * Copyright (C) 2016 Load Impact
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package stats

import (
	"errors"
	"fmt"
	"sort"
	"strconv"
	"strings"
	"time"
)

const (
	counterString = `"counter"`
	gaugeString   = `"gauge"`
	trendString   = `"trend"`
	rateString    = `"rate"`

	defaultString = `"default"`
	timeString    = `"time"`
)

// Possible values for MetricType.
const (
	Counter = MetricType(iota) // A counter that sums its data points
	Gauge                      // A gauge that displays the latest value
	Trend                      // A trend, min/max/avg/med are interesting
	Rate                       // A rate, displays % of values that aren't 0
)

// Possible values for ValueType.
const (
	Default = ValueType(iota) // Values are presented as-is
	Time                      // Values are timestamps (nanoseconds)
)

// The serialized metric type is invalid.
var ErrInvalidMetricType = errors.New("Invalid metric type")

// The serialized value type is invalid.
var ErrInvalidValueType = errors.New("Invalid value type")

// A MetricType specifies the type of a metric.
type MetricType int

// MarshalJSON serializes a MetricType as a human readable string.
func (t MetricType) MarshalJSON() ([]byte, error) {
	switch t {
	case Counter:
		return []byte(counterString), nil
	case Gauge:
		return []byte(gaugeString), nil
	case Trend:
		return []byte(trendString), nil
	case Rate:
		return []byte(rateString), nil
	default:
		return nil, ErrInvalidMetricType
	}
}

// UnmarshalJSON deserializes a MetricType from a string representation.
func (t *MetricType) UnmarshalJSON(data []byte) error {
	switch string(data) {
	case counterString:
		*t = Counter
	case gaugeString:
		*t = Gauge
	case trendString:
		*t = Trend
	case rateString:
		*t = Rate
	default:
		return ErrInvalidMetricType
	}

	return nil
}

func (t MetricType) String() string {
	switch t {
	case Counter:
		return counterString
	case Gauge:
		return gaugeString
	case Trend:
		return trendString
	case Rate:
		return rateString
	default:
		return "[INVALID]"
	}
}

// The type of values a metric contains.
type ValueType int

// MarshalJSON serializes a ValueType as a human readable string.
func (t ValueType) MarshalJSON() ([]byte, error) {
	switch t {
	case Default:
		return []byte(defaultString), nil
	case Time:
		return []byte(timeString), nil
	default:
		return nil, ErrInvalidValueType
	}
}

// UnmarshalJSON deserializes a ValueType from a string representation.
func (t *ValueType) UnmarshalJSON(data []byte) error {
	switch string(data) {
	case defaultString:
		*t = Default
	case timeString:
		*t = Time
	default:
		return ErrInvalidValueType
	}

	return nil
}

func (t ValueType) String() string {
	switch t {
	case Default:
		return defaultString
	case Time:
		return timeString
	default:
		return "[INVALID]"
	}
}

// A Sample is a single measurement.
type Sample struct {
	Metric *Metric
	Time   time.Time
	Tags   map[string]string
	Value  float64
}

// A Metric defines the shape of a set of data.
type Metric struct {
	Name     string     `json:"-"`
	Type     MetricType `json:"type"`
	Contains ValueType  `json:"contains"`

	// Filled in by the API when requested, the server side cannot count on its presence.
	Sample map[string]float64 `json:"sample"`
}

func New(name string, typ MetricType, t ...ValueType) *Metric {
	vt := Default
	if len(t) > 0 {
		vt = t[0]
	}
	return &Metric{Name: name, Type: typ, Contains: vt}
}

func (m Metric) NewSink() Sink {
	switch m.Type {
	case Counter:
		return &CounterSink{}
	case Gauge:
		return &GaugeSink{}
	case Trend:
		return &TrendSink{}
	case Rate:
		return &RateSink{}
	default:
		return nil
	}
}

func (m Metric) Humanize() string {
	sample := m.Sample
	switch len(sample) {
	case 0:
		return ""
	case 1:
		for _, v := range sample {
			return m.HumanizeValue(v)
		}
		return ""
	default:
		parts := make([]string, 0, len(m.Sample))
		for key, val := range m.Sample {
			parts = append(parts, fmt.Sprintf("%s=%s", key, m.HumanizeValue(val)))
		}
		sort.Strings(parts)
		return strings.Join(parts, ", ")
	}
}

func (m Metric) HumanizeValue(v float64) string {
	switch m.Type {
	case Rate:
		return strconv.FormatFloat(100*v, 'f', 2, 64) + "%"
	default:
		switch m.Contains {
		case Time:
			d := time.Duration(v)
			switch {
			case d > time.Minute:
				d -= d % (1 * time.Second)
			case d > time.Second:
				d -= d % (10 * time.Millisecond)
			case d > time.Millisecond:
				d -= d % (10 * time.Microsecond)
			case d > time.Microsecond:
				d -= d % (10 * time.Nanosecond)
			}
			return d.String()
		default:
			return strconv.FormatFloat(v, 'f', -1, 64)
		}
	}
}

func (m Metric) GetID() string {
	return m.Name
}

func (m *Metric) SetID(id string) error {
	m.Name = id
	return nil
}
<|endoftext|>


<commit_before>package main

import "fmt"

type rect struct {
	width, height int
}

func (r *rect) area() int {
	return r.width * r.height
}

func (r rect) perim() int {
	return 2*r.width + 2*r.height
}

func main() {
	r := rect{width: 5, height: 7}
	fmt.Println("area: ", r.area())
	fmt.Println("perim: ", r.perim())

	rp := &r
	fmt.Println("area: ", rp.area())
	fmt.Println("perim: ", rp.perim())

}
<commit_msg>methods<commit_after>package main

import "fmt"

type rect struct {
	width, height int
}

func (r *rect) area() int {
	r.width = 2
	return r.width * r.height
}

func (r rect) perim() int {
	r.width = 10
	return 2*r.width + 2*r.height
}

func main() {
	r := rect{width: 5, height: 7}
	fmt.Println("area: ", r.area())
	fmt.Println("perim: ", r.perim())

	rp := &r
	fmt.Println("area: ", rp.area())
	fmt.Println("perim: ", rp.perim())

}
<|endoftext|>


<commit_before>package schedule

import (
	"time"
	"math/rand"

	"github.com/golang/glog"

	"github.com/asobti/kube-monkey/chaos"
	"github.com/asobti/kube-monkey/config"
	"github.com/asobti/kube-monkey/calendar"
	"github.com/asobti/kube-monkey/deployments"
)

type Schedule struct {
	entries []*chaos.Chaos
}

func (s *Schedule) Entries() []*chaos.Chaos {
	return s.entries
}

func (s *Schedule) Add(entry *chaos.Chaos) {
	s.entries = append(s.entries, entry)
}

func (s *Schedule) Print() {
	glog.V(3).Info("********** Today's schedule **********")
	if len(s.entries) == 0 {
		glog.V(3).Info("No terminations scheduled")
	} else {
		glog.V(3).Info("\tDeployment\t\tTermination time\n")
		glog.V(3).Info("\t----------\t\t----------------\n")
		for _, chaos := range s.entries {
			glog.V(3).Info("\t%s\t\t%s\n", chaos.Deployment().Name(), chaos.KillAt())
		}
	}

	glog.V(3).Info("********** End of schedule **********")
}

func New() (*Schedule, error) {
	glog.V(2).Info("Generating schedule for terminations")
	deployments, err := deployments.EligibleDeployments()
	if err != nil {
		return nil, err
	}

	schedule := &Schedule{
		entries: []*chaos.Chaos{},
	}

	for _, dep := range deployments {
		killtime := CalculateKillTime()

		if ShouldScheduleChaos(dep.Mtbf()) {
			schedule.Add(chaos.New(killtime, dep))
		}
	}

	return schedule, nil
}

func CalculateKillTime() time.Time {
	if config.DebugEnabled() && config.DebugScheduleImmediateKill() {
		r := rand.New(rand.NewSource(time.Now().UnixNano()))
		// calculate a second-offset in the next minute
		secOffset := r.Intn(60)
		return time.Now().Add(time.Duration(secOffset) * time.Second)
	} else {
		return calendar.RandomTimeInRange(config.StartHour(), config.EndHour(), config.Timezone())
	}
}

func ShouldScheduleChaos(mtbf int) bool {
	if config.DebugEnabled() && config.DebugForceShouldKill() {
		return true
	}

	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	var probability float64 = 1 / float64(mtbf)
	return probability > r.Float64()
}
<commit_msg>Fix Schedule Output<commit_after>package schedule

import (
	"time"
	"math/rand"

	"github.com/golang/glog"

	"github.com/asobti/kube-monkey/chaos"
	"github.com/asobti/kube-monkey/config"
	"github.com/asobti/kube-monkey/calendar"
	"github.com/asobti/kube-monkey/deployments"
)

type Schedule struct {
	entries []*chaos.Chaos
}

func (s *Schedule) Entries() []*chaos.Chaos {
	return s.entries
}

func (s *Schedule) Add(entry *chaos.Chaos) {
	s.entries = append(s.entries, entry)
}

func (s *Schedule) Print() {
	glog.V(3).Info("\t********** Today's schedule **********")
	if len(s.entries) == 0 {
		glog.V(3).Info("No terminations scheduled")
	} else {
		glog.V(3).Info("\tDeployment\t\tTermination time\n")
		glog.V(3).Info("\t----------\t\t----------------\n")
		for _, chaos := range s.entries {
			glog.V(3).Infof("\t%s\t\t%s\n", chaos.Deployment().Name(), chaos.KillAt())
		}
	}

	glog.V(3).Info("\t********** End of schedule **********")
}

func New() (*Schedule, error) {
	glog.V(2).Info("Generating schedule for terminations")
	deployments, err := deployments.EligibleDeployments()
	if err != nil {
		return nil, err
	}

	schedule := &Schedule{
		entries: []*chaos.Chaos{},
	}

	for _, dep := range deployments {
		killtime := CalculateKillTime()

		if ShouldScheduleChaos(dep.Mtbf()) {
			schedule.Add(chaos.New(killtime, dep))
		}
	}

	return schedule, nil
}

func CalculateKillTime() time.Time {
	if config.DebugEnabled() && config.DebugScheduleImmediateKill() {
		r := rand.New(rand.NewSource(time.Now().UnixNano()))
		// calculate a second-offset in the next minute
		secOffset := r.Intn(60)
		return time.Now().Add(time.Duration(secOffset) * time.Second)
	} else {
		return calendar.RandomTimeInRange(config.StartHour(), config.EndHour(), config.Timezone())
	}
}

func ShouldScheduleChaos(mtbf int) bool {
	if config.DebugEnabled() && config.DebugForceShouldKill() {
		return true
	}

	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	var probability float64 = 1 / float64(mtbf)
	return probability > r.Float64()
}
<|endoftext|>


<commit_before>package v3_helpers

import (
	"github.com/cloudfoundry-incubator/cf-test-helpers/workflowhelpers"
	. "github.com/cloudfoundry/cf-acceptance-tests/cats_suite_helpers"
)

type Entity struct {
	AppName       string `json:"app_name"`
	AppGuid       string `json:"app_guid"`
	State         string `json:"state"`
	BuildpackName string `json:"buildpack_name"`
	BuildpackGuid string `json:"buildpack_guid"`
	ParentAppName string `json:"parent_app_name"`
	ParentAppGuid string `json:"parent_app_guid"`
	ProcessType   string `json:"process_type"`
	TaskGuid      string `json:"task_guid"`
}
type AppUsageEvent struct {
	Entity `json:"entity"`
}

type AppUsageEvents struct {
	Resources []AppUsageEvent `struct:"resources"`
}

func UsageEventsInclude(events []AppUsageEvent, event AppUsageEvent) bool {
	found := false
	for _, e := range events {
		found = event.Entity.ParentAppName == e.Entity.ParentAppName &&
			event.Entity.ParentAppGuid == e.Entity.ParentAppGuid &&
			event.Entity.ProcessType == e.Entity.ProcessType &&
			event.Entity.State == e.Entity.State &&
			event.Entity.AppGuid == e.Entity.AppGuid &&
			event.Entity.TaskGuid == e.Entity.TaskGuid
		if found {
			break
		}
	}
	return found
}

func LastPageUsageEvents(TestSetup *workflowhelpers.ReproducibleTestSuiteSetup) []AppUsageEvent {
	var response AppUsageEvents

	workflowhelpers.AsUser(TestSetup.AdminUserContext(), Config.DefaultTimeoutDuration(), func() {
		workflowhelpers.ApiRequest("GET", "/v2/app_usage_events?order-direction=desc&page=1", &response, Config.DefaultTimeoutDuration())
	})

	return response.Resources
}
<commit_msg>Update v3 test helper to request 150 app usage events per page<commit_after>package v3_helpers

import (
	"github.com/cloudfoundry-incubator/cf-test-helpers/workflowhelpers"
	. "github.com/cloudfoundry/cf-acceptance-tests/cats_suite_helpers"
)

type Entity struct {
	AppName       string `json:"app_name"`
	AppGuid       string `json:"app_guid"`
	State         string `json:"state"`
	BuildpackName string `json:"buildpack_name"`
	BuildpackGuid string `json:"buildpack_guid"`
	ParentAppName string `json:"parent_app_name"`
	ParentAppGuid string `json:"parent_app_guid"`
	ProcessType   string `json:"process_type"`
	TaskGuid      string `json:"task_guid"`
}
type AppUsageEvent struct {
	Entity `json:"entity"`
}

type AppUsageEvents struct {
	Resources []AppUsageEvent `struct:"resources"`
}

func UsageEventsInclude(events []AppUsageEvent, event AppUsageEvent) bool {
	found := false
	for _, e := range events {
		found = event.Entity.ParentAppName == e.Entity.ParentAppName &&
			event.Entity.ParentAppGuid == e.Entity.ParentAppGuid &&
			event.Entity.ProcessType == e.Entity.ProcessType &&
			event.Entity.State == e.Entity.State &&
			event.Entity.AppGuid == e.Entity.AppGuid &&
			event.Entity.TaskGuid == e.Entity.TaskGuid
		if found {
			break
		}
	}
	return found
}

func LastPageUsageEvents(TestSetup *workflowhelpers.ReproducibleTestSuiteSetup) []AppUsageEvent {
	var response AppUsageEvents

	workflowhelpers.AsUser(TestSetup.AdminUserContext(), Config.DefaultTimeoutDuration(), func() {
		workflowhelpers.ApiRequest("GET", "/v2/app_usage_events?results-per-page=150&order-direction=desc&page=1", &response, Config.DefaultTimeoutDuration())
	})

	return response.Resources
}
<|endoftext|>


<commit_before>package cache

import (
	"io/ioutil"
	"os"
	"strings"
	"testing"
)

// Get the count of documents and total size of the documents in docDir
func getCacheInfo(docDir string) (int64, int) {
	var size int64
	var count int

	list, _ := ioutil.ReadDir(docDir)
	for _, file := range list {
		if strings.HasSuffix(file.Name(), ".html") == true {
			stat, _ := os.Stat(docDir + "/" + file.Name())
			size += stat.Size()
			count++
		}
	}
	return size, count
}

func TestInitCache(t *testing.T) {
	const docDir = "../docs"

	if err := InitCache(docDir); err != nil {
		t.Fatal("Failed to initialize document cache in", docDir)
	}

	//Ensure we recieved an initialized Doc structure
	if Docs == nil {
		t.Fatal("Document structure should not be nil")
	}
	//Ensure the cache was actually filled by Docs.BuildCache()
	if Docs.docs == nil {
		t.Fatal("Document cache should not be nil")
	}

	expectedSize, expectedCount := getCacheInfo(docDir)

	//Ensure we get the corrent size and count of the documents
	if Docs.size != expectedSize {
		t.Fatalf("Inconsistent size of documents in cache %s. Got %d should be %d",
			docDir, Docs.size, expectedSize)
	}

	if Docs.count != expectedCount {
		t.Fatalf("Inconsistent count of documents in cache %s. Got %d should be %d",
			docDir, Docs.count, expectedCount)
	}
}

//Simply create a dummy document
func CreateDocument(docDir string, docName string) {
	file, _ := os.Create(docDir + "/" + "test.html")
	defer file.Close()
	file.WriteString(string("test"))
}

func TestGetDoc(t *testing.T) {
	const docDir = "../docs"
	const docName = "index.html"
	const testName = "test.html"

	// Test getting document from the cache
	if Docs.GetDoc(docName) == nil {
		t.Fatalf("Failed to get existing document %s in cache built from %s", docName, docDir)
	}

	// Test reading a new document off disk
	CreateDocument(docDir, testName)
	if Docs.GetDoc("test.html") == nil {
		os.Remove(docDir + "/" + testName)
		t.Fatalf("Failed to get document test.html from cache %s: %s", docDir)
	}
	os.Remove(docDir + "/" + testName)

	// Test trying to get a non-existant document
	if Docs.GetDoc("not_there.html") != nil {
		t.Fatalf("GetDoc() returned non-nil when looking for non-existant document")
	}
}

func TestRefreshDoc(t *testing.T) {
	const docName = "index.html"

	if err := Docs.RefreshDoc(docName); err != nil {
		t.Fatalf("Failed to refresh document %s in %s", docName, Docs.Path)
	}
}
<commit_msg>Added more tests to cache/cache_test.go (92.6% coverage)<commit_after>package cache

import (
	"io/ioutil"
	"log"
	"os"
	"strings"
	"testing"
)

// Get the count of documents and total size of the documents in docDir
func getCacheInfo(docDir string) (int64, int) {
	var size int64
	var count int

	list, _ := ioutil.ReadDir(docDir)
	for _, file := range list {
		if strings.HasSuffix(file.Name(), ".html") == true {
			stat, _ := os.Stat(docDir + "/" + file.Name())
			size += stat.Size()
			count++
		}
	}
	return size, count
}

func TestInitCache(t *testing.T) {
	const docDir = "../docs"
	const badDocDir = "../ducks"
	const badDoc = "bad.txt"

	if err := InitCache(badDocDir); err == nil {
		t.Fatal("Recieved no error when attempting to build cache from bogus directory")
	}

	//Create a bogus document in the cache directory to test that we ignore bad documents
	CreateDocument(docDir, badDoc)

	if err := InitCache(docDir); err != nil {
		t.Fatal("Failed to initialize document cache in", docDir)
	}
	os.Remove(docDir + "/" + badDoc)

	//Ensure we recieved an initialized Doc structure
	if Docs == nil {
		t.Fatal("Document structure should not be nil")
	}
	//Ensure the cache was actually filled by Docs.BuildCache()
	if Docs.docs == nil {
		t.Fatal("Document cache should not be nil")
	}

	//Ensure we have all of the documents are in the cache and they aren't nil
	var expectDocs = []string{"404.html", "index.html", "link1.html", "link2.html"}

	for _, name := range expectDocs {
		if Docs.Exists(name) != true {
			t.Fatal("Non-existent document on disk or cache", name)
		}
	}

	expectedSize, expectedCount := getCacheInfo(docDir)

	//Ensure we get the corrent size and count of the documents
	if Docs.size != expectedSize {
		t.Fatalf("Inconsistent size of documents in cache %s. Got %d should be %d",
			docDir, Docs.size, expectedSize)
	}

	if Docs.count != expectedCount {
		t.Fatalf("Inconsistent count of documents in cache %s. Got %d should be %d",
			docDir, Docs.count, expectedCount)
	}
}

func TestCacheDoc(t *testing.T) {
	const badDoc = "bad.html"
	if Docs.CacheDoc(badDoc) == nil {
		t.Fatal("Did not recieve error when attempting to cache non-existent document")
	}
}

//Simply create a dummy document
func CreateDocument(docDir string, docName string) {
	file, _ := os.Create(docDir + "/" + docName)
	defer file.Close()
	file.WriteString(string("test"))
	log.Println("Created dummy document", docDir+"/"+docName)
}

func TestGetDoc(t *testing.T) {
	const docDir = "../docs"
	const docName = "index.html"
	const testName = "test.html"

	// Test getting document from the cache
	if Docs.GetDoc(docName) == nil {
		t.Fatalf("Failed to get existing document %s in cache built from %s", docName, docDir)
	}

	// Test reading a new document off disk
	CreateDocument(docDir, testName)
	if Docs.GetDoc("test.html") == nil {
		os.Remove(docDir + "/" + testName)
		t.Fatalf("Failed to get document test.html from cache %s: %s", docDir)
	}
	os.Remove(docDir + "/" + testName)

	// Test trying to get a non-existant document
	if Docs.GetDoc("not_there.html") != nil {
		t.Fatalf("GetDoc() returned non-nil when looking for non-existant document")
	}
}

func TestRefreshDoc(t *testing.T) {
	const docName = "index.html"
	const badDoc = "notthere.html"

	//Ensure we can refresh an existing document
	if err := Docs.RefreshDoc(docName); err != nil {
		t.Fatalf("Failed to refresh document %s in %s", docName, Docs.Path)
	}

	//Ensure we get an error if we try to refresh a phantom document
	if err := Docs.RefreshDoc(badDoc); err == nil {
		t.Fatal("Did not recieve error when attempting to refresh non-existent document")
	}
}
<|endoftext|>


<commit_before>package blocks

import (
	"bytes"
	"encoding/json"
	"log"
	"net/http"
)

func Post(b *Block) {

	type postRule struct {
		Endpoint string
	}

	rule := &postRule{}

	unmarshal(<-b.Routes["set_rule"], &rule)

	// TODO check the endpoint for happiness
	for {
		select {
		case msg := <-b.AddChan:
			updateOutChans(msg, b)
		case <-b.QuitChan:
			quit(b)
			return
		case msg := <-b.InChan:
			// TODO maybe check the response ?
			postBody, err := json.Marshal(msg)
			if err != nil {
				log.Fatal(err.Error())
			}

			// TODO the content-type here is heavily borked but we're using a hack
			resp, err := http.Post(rule.Endpoint, "application/x-www-form-urlencoded", bytes.NewReader(postBody))
			defer resp.Body.Close()
			if err != nil {
				log.Println(err.Error())
			}
		}
	}
}
<commit_msg>little bug in post maybe<commit_after>package blocks

import (
	"bytes"
	"encoding/json"
	"log"
	"net/http"
)

func Post(b *Block) {

	type postRule struct {
		Endpoint string
	}

	rule := &postRule{}

	unmarshal(<-b.Routes["set_rule"], &rule)

	// TODO check the endpoint for happiness
	for {
		select {
		case msg := <-b.AddChan:
			updateOutChans(msg, b)
		case <-b.QuitChan:
			quit(b)
			return
		case msg := <-b.InChan:
			// TODO maybe check the response ?
			postBody, err := json.Marshal(msg)
			if err != nil {
				log.Fatal(err.Error())
			}

			// TODO the content-type here is heavily borked but we're using a hack
			resp, err := http.Post(rule.Endpoint, "application/x-www-form-urlencoded", bytes.NewReader(postBody))
			if err != nil {
				log.Println(err.Error())
			}
			defer resp.Body.Close()
		}
	}
}
<|endoftext|>


<commit_before>package nlp

import (
	"fmt"

	"github.com/gonum/matrix"
	"github.com/gonum/matrix/mat64"
)

// TruncatedSVD implements the Singular Value Decomposition factorisation of matrices.
// This produces an approximation of the input matrix at a lower rank.  This is a core
// component of LSA (Latent Semantic Analsis)
type TruncatedSVD struct {
	transform mat64.Matrix

	// K is the number of dimensions to which the output, transformed, matrix should be
	// truncated to.  The matrix output by the FitTransform() and Transform() methods will
	// be n rows by min(m, n, K) columns, where n is the number of columns in the original,
	// input matrix and min(m, n, K) is the lowest value of m, n, K where m is the number of
	// rows in the original, input matrix.
	K int
}

// NewTruncatedSVD creates a new TruncatedSVD transformer with K (the truncated
// dimensionality) being set to the specified value k
func NewTruncatedSVD(k int) *TruncatedSVD {
	return &TruncatedSVD{K: k}
}

// Fit performs the SVD factorisation on the input training data matrix, mat and
// stores the output term matrix as a transform to apply to matrices in the Transform matrix.
func (t *TruncatedSVD) Fit(mat mat64.Matrix) Transformer {
	t.FitTransform(mat)
	return t
}

// Transform applies the transform decomposed from the training data matrix in Fit()
// to the input matrix.  The resulting output matrix will be the closest approximation
// to the input matrix at a reduced rank.  The returned matrix is a dense matrix type.
func (t *TruncatedSVD) Transform(mat mat64.Matrix) (mat64.Matrix, error) {
	var product mat64.Dense

	product.Product(t.transform.T(), mat)

	return &product, nil
}

// FitTransform is approximately equivalent to calling Fit() followed by Transform()
// on the same matrix.  This is a useful shortcut where separate trianing data is not being
// used to fit the model i.e. the model is fitted on the fly to the test data.
// The returned matrix is a dense matrix type.
func (t *TruncatedSVD) FitTransform(mat mat64.Matrix) (mat64.Matrix, error) {
	var svd mat64.SVD
	if ok := svd.Factorize(mat, matrix.SVDThin); !ok {
		return nil, fmt.Errorf("Failed SVD Factorisation of working matrix")
	}
	s, u, v := t.extractSVD(&svd)

	m, n := mat.Dims()
	min := minimum(t.K, m, n)

	// truncate U and V matrices to k << min(m, n)
	uk := u.Slice(0, m, 0, min)
	vk := v.Slice(0, n, 0, min)

	t.transform = uk

	// multiply Sigma by transpose of V.  As sigma is a symmetrical (square) diagonal matrix it is
	// more efficient to simply multiply each element from the array of diagonal values with each
	// element from the matrix V rather than multiplying out the non-zero values from off the diagonal.
	var product mat64.Dense
	product.Apply(func(i, j int, v float64) float64 {
		return (v * s[i])
	}, vk.T())

	return &product, nil
}

func minimum(k, m, n int) int {
	return min(k, min(m, n))
}

func min(m, n int) int {
	if m < n {
		return m
	}
	return n
}

func (t *TruncatedSVD) extractSVD(svd *mat64.SVD) (s []float64, u, v *mat64.Dense) {
	var um, vm mat64.Dense
	um.UFromSVD(svd)
	vm.VFromSVD(svd)
	s = svd.Values(nil)
	return s, &um, &vm
}
<commit_msg>renamed transform to Components and made visible<commit_after>package nlp

import (
	"fmt"

	"github.com/gonum/matrix"
	"github.com/gonum/matrix/mat64"
)

// TruncatedSVD implements the Singular Value Decomposition factorisation of matrices.
// This produces an approximation of the input matrix at a lower rank.  This is a core
// component of LSA (Latent Semantic Analsis)
type TruncatedSVD struct {
	// Components is the truncated term matrix (matrix U of the Singular Value Decomposition
	// (A=USV^T)).  The matrix will be of size m, k where m = the number of unique terms
	// in the training data and k = the number of elements to truncate to (specified by
	// attribute K) or m or n (the number of documents in the training data) whichever of
	// the 3 values is smaller.
	Components mat64.Matrix

	// K is the number of dimensions to which the output, transformed, matrix should be
	// truncated to.  The matrix output by the FitTransform() and Transform() methods will
	// be n rows by min(m, n, K) columns, where n is the number of columns in the original,
	// input matrix and min(m, n, K) is the lowest value of m, n, K where m is the number of
	// rows in the original, input matrix.
	K int
}

// NewTruncatedSVD creates a new TruncatedSVD transformer with K (the truncated
// dimensionality) being set to the specified value k
func NewTruncatedSVD(k int) *TruncatedSVD {
	return &TruncatedSVD{K: k}
}

// Fit performs the SVD factorisation on the input training data matrix, mat and
// stores the output term matrix as a transform to apply to matrices in the Transform matrix.
func (t *TruncatedSVD) Fit(mat mat64.Matrix) Transformer {
	t.FitTransform(mat)
	return t
}

// Transform applies the transform decomposed from the training data matrix in Fit()
// to the input matrix.  The resulting output matrix will be the closest approximation
// to the input matrix at a reduced rank.  The returned matrix is a dense matrix type.
func (t *TruncatedSVD) Transform(mat mat64.Matrix) (mat64.Matrix, error) {
	var product mat64.Dense

	product.Mul(t.Components.T(), mat)

	return &product, nil
}

// FitTransform is approximately equivalent to calling Fit() followed by Transform()
// on the same matrix.  This is a useful shortcut where separate trianing data is not being
// used to fit the model i.e. the model is fitted on the fly to the test data.
// The returned matrix is a dense matrix type.
func (t *TruncatedSVD) FitTransform(mat mat64.Matrix) (mat64.Matrix, error) {
	var svd mat64.SVD
	if ok := svd.Factorize(mat, matrix.SVDThin); !ok {
		return nil, fmt.Errorf("Failed SVD Factorisation of working matrix")
	}
	s, u, v := t.extractSVD(&svd)

	m, n := mat.Dims()
	min := minimum(t.K, m, n)

	// truncate U and V matrices to k << min(m, n)
	uk := u.Slice(0, m, 0, min)
	vk := v.Slice(0, n, 0, min)

	t.Components = uk

	// multiply Sigma by transpose of V.  As sigma is a symmetrical (square) diagonal matrix it is
	// more efficient to simply multiply each element from the array of diagonal values with each
	// element from the matrix V rather than multiplying out the non-zero values from off the diagonal.
	var product mat64.Dense
	product.Apply(func(i, j int, v float64) float64 {
		return (v * s[i])
	}, vk.T())

	return &product, nil
}

func minimum(k, m, n int) int {
	return min(k, min(m, n))
}

func min(m, n int) int {
	if m < n {
		return m
	}
	return n
}

func (t *TruncatedSVD) extractSVD(svd *mat64.SVD) (s []float64, u, v *mat64.Dense) {
	var um, vm mat64.Dense
	um.UFromSVD(svd)
	vm.VFromSVD(svd)
	s = svd.Values(nil)
	return s, &um, &vm
}
<|endoftext|>


<commit_before>package storage

import (
	"fmt"

	"github.com/docker/distribution"
	ctxu "github.com/docker/distribution/context"
	"github.com/docker/distribution/digest"
	"github.com/docker/distribution/manifest"
	"github.com/docker/libtrust"
	"golang.org/x/net/context"
)

type manifestStore struct {
	repository *repository

	revisionStore *revisionStore
	tagStore      *tagStore
}

var _ distribution.ManifestService = &manifestStore{}

func (ms *manifestStore) Exists(ctx context.Context, dgst digest.Digest) (bool, error) {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).Exists")
	return ms.revisionStore.exists(dgst)
}

func (ms *manifestStore) Get(ctx context.Context, dgst digest.Digest) (*manifest.SignedManifest, error) {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).Get")
	return ms.revisionStore.get(dgst)
}

func (ms *manifestStore) Put(ctx context.Context, manifest *manifest.SignedManifest) error {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).Put")

	// TODO(stevvooe): Add check here to see if the revision is already
	// present in the repository. If it is, we should merge the signatures, do
	// a shallow verify (or a full one, doesn't matter) and return an error
	// indicating what happened.

	// Verify the manifest.
	if err := ms.verifyManifest(manifest); err != nil {
		return err
	}

	// Store the revision of the manifest
	revision, err := ms.revisionStore.put(manifest)
	if err != nil {
		return err
	}

	// Now, tag the manifest
	return ms.tagStore.tag(manifest.Tag, revision)
}

// Delete removes the revision of the specified manfiest.
func (ms *manifestStore) Delete(ctx context.Context, dgst digest.Digest) error {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).Delete - unsupported")
	return fmt.Errorf("deletion of manifests not supported")
}

func (ms *manifestStore) Tags(ctx context.Context) ([]string, error) {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).Tags")
	return ms.tagStore.tags()
}

func (ms *manifestStore) ExistsByTag(ctx context.Context, tag string) (bool, error) {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).ExistsByTag")
	return ms.tagStore.exists(tag)
}

func (ms *manifestStore) GetByTag(ctx context.Context, tag string) (*manifest.SignedManifest, error) {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).GetByTag")
	dgst, err := ms.tagStore.resolve(tag)
	if err != nil {
		return nil, err
	}

	return ms.revisionStore.get(dgst)
}

// verifyManifest ensures that the manifest content is valid from the
// perspective of the registry. It ensures that the signature is valid for the
// enclosed payload. As a policy, the registry only tries to store valid
// content, leaving trust policies of that content up to consumers.
func (ms *manifestStore) verifyManifest(mnfst *manifest.SignedManifest) error {
	var errs distribution.ErrManifestVerification
	if mnfst.Name != ms.repository.Name() {
		// TODO(stevvooe): This needs to be an exported error
		errs = append(errs, fmt.Errorf("repository name does not match manifest name"))
	}

	if _, err := manifest.Verify(mnfst); err != nil {
		switch err {
		case libtrust.ErrMissingSignatureKey, libtrust.ErrInvalidJSONContent, libtrust.ErrMissingSignatureKey:
			errs = append(errs, distribution.ErrManifestUnverified{})
		default:
			if err.Error() == "invalid signature" { // TODO(stevvooe): This should be exported by libtrust
				errs = append(errs, distribution.ErrManifestUnverified{})
			} else {
				errs = append(errs, err)
			}
		}
	}

	for _, fsLayer := range mnfst.FSLayers {
		exists, err := ms.repository.Layers().Exists(fsLayer.BlobSum)
		if err != nil {
			errs = append(errs, err)
		}

		if !exists {
			errs = append(errs, distribution.ErrUnknownLayer{FSLayer: fsLayer})
		}
	}

	if len(errs) != 0 {
		// TODO(stevvooe): These need to be recoverable by a caller.
		return errs
	}

	return nil
}
<commit_msg>UPSTREAM(docker/distribution): manifest deletions<commit_after>package storage

import (
	"fmt"

	"github.com/docker/distribution"
	ctxu "github.com/docker/distribution/context"
	"github.com/docker/distribution/digest"
	"github.com/docker/distribution/manifest"
	"github.com/docker/libtrust"
	"golang.org/x/net/context"
)

type manifestStore struct {
	repository *repository

	revisionStore *revisionStore
	tagStore      *tagStore
}

var _ distribution.ManifestService = &manifestStore{}

func (ms *manifestStore) Exists(ctx context.Context, dgst digest.Digest) (bool, error) {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).Exists")
	return ms.revisionStore.exists(dgst)
}

func (ms *manifestStore) Get(ctx context.Context, dgst digest.Digest) (*manifest.SignedManifest, error) {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).Get")
	return ms.revisionStore.get(dgst)
}

func (ms *manifestStore) Put(ctx context.Context, manifest *manifest.SignedManifest) error {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).Put")

	// TODO(stevvooe): Add check here to see if the revision is already
	// present in the repository. If it is, we should merge the signatures, do
	// a shallow verify (or a full one, doesn't matter) and return an error
	// indicating what happened.

	// Verify the manifest.
	if err := ms.verifyManifest(manifest); err != nil {
		return err
	}

	// Store the revision of the manifest
	revision, err := ms.revisionStore.put(manifest)
	if err != nil {
		return err
	}

	// Now, tag the manifest
	return ms.tagStore.tag(manifest.Tag, revision)
}

// Delete removes the revision of the specified manfiest.
func (ms *manifestStore) Delete(ctx context.Context, dgst digest.Digest) error {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).Delete")
	return ms.revisionStore.delete(dgst)
}

func (ms *manifestStore) Tags(ctx context.Context) ([]string, error) {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).Tags")
	return ms.tagStore.tags()
}

func (ms *manifestStore) ExistsByTag(ctx context.Context, tag string) (bool, error) {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).ExistsByTag")
	return ms.tagStore.exists(tag)
}

func (ms *manifestStore) GetByTag(ctx context.Context, tag string) (*manifest.SignedManifest, error) {
	ctxu.GetLogger(ms.repository.ctx).Debug("(*manifestStore).GetByTag")
	dgst, err := ms.tagStore.resolve(tag)
	if err != nil {
		return nil, err
	}

	return ms.revisionStore.get(dgst)
}

// verifyManifest ensures that the manifest content is valid from the
// perspective of the registry. It ensures that the signature is valid for the
// enclosed payload. As a policy, the registry only tries to store valid
// content, leaving trust policies of that content up to consumers.
func (ms *manifestStore) verifyManifest(mnfst *manifest.SignedManifest) error {
	var errs distribution.ErrManifestVerification
	if mnfst.Name != ms.repository.Name() {
		// TODO(stevvooe): This needs to be an exported error
		errs = append(errs, fmt.Errorf("repository name does not match manifest name"))
	}

	if _, err := manifest.Verify(mnfst); err != nil {
		switch err {
		case libtrust.ErrMissingSignatureKey, libtrust.ErrInvalidJSONContent, libtrust.ErrMissingSignatureKey:
			errs = append(errs, distribution.ErrManifestUnverified{})
		default:
			if err.Error() == "invalid signature" { // TODO(stevvooe): This should be exported by libtrust
				errs = append(errs, distribution.ErrManifestUnverified{})
			} else {
				errs = append(errs, err)
			}
		}
	}

	for _, fsLayer := range mnfst.FSLayers {
		exists, err := ms.repository.Layers().Exists(fsLayer.BlobSum)
		if err != nil {
			errs = append(errs, err)
		}

		if !exists {
			errs = append(errs, distribution.ErrUnknownLayer{FSLayer: fsLayer})
		}
	}

	if len(errs) != 0 {
		// TODO(stevvooe): These need to be recoverable by a caller.
		return errs
	}

	return nil
}
<|endoftext|>


<commit_before>package warnings

import (
	"fmt"
	"time"

	"github.com/pkg/errors"

	"github.com/lxc/lxd/lxd/db"
)

// ResolveWarningsByLocalNodeOlderThan resolves all warnings which are older than the provided time.
func ResolveWarningsByLocalNodeOlderThan(cluster *db.Cluster, date time.Time) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrapf(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarnings()
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != localName {
				continue
			}

			if w.LastSeenDate.Before(date) {
				err = tx.UpdateWarningStatus(w.UUID, db.WarningStatusResolved)
				if err != nil {
					return err
				}
			}
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to resolve warnings")
	}

	return nil
}

// ResolveWarningsByLocalNodeAndType resolves warnings with the local node and type code.
// Returns error if no local node name.
func ResolveWarningsByLocalNodeAndType(cluster *db.Cluster, typeCode db.WarningType) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrapf(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	return ResolveWarningsByNodeAndType(cluster, localName, typeCode)
}

// ResolveWarningsByNodeAndType resolves warnings with the given node and type code.
func ResolveWarningsByNodeAndType(cluster *db.Cluster, nodeName string, typeCode db.WarningType) error {
	err := cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarningsByType(typeCode)
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != nodeName {
				continue
			}

			err = tx.UpdateWarningStatus(w.UUID, db.WarningStatusResolved)
			if err != nil {
				return err
			}
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to resolve warnings")
	}

	return nil
}

// ResolveWarningsByNodeAndProjectAndType resolves warnings with the given node, project and type code.
func ResolveWarningsByNodeAndProjectAndType(cluster *db.Cluster, nodeName string, projectName string, typeCode db.WarningType) error {
	err := cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarningsByType(typeCode)
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != nodeName || w.Project != projectName {
				continue
			}

			err = tx.UpdateWarningStatus(w.UUID, db.WarningStatusResolved)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to resolve warnings")
	}

	return nil
}

// ResolveWarningsByLocalNodeAndProjectAndType resolves warnings with the given project and type code.
func ResolveWarningsByLocalNodeAndProjectAndType(cluster *db.Cluster, projectName string, typeCode db.WarningType) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	return ResolveWarningsByNodeAndProjectAndType(cluster, localName, projectName, typeCode)
}

// ResolveWarningsByNodeAndProjectAndTypeAndEntity resolves warnings with the given node, project, type code, and entity.
func ResolveWarningsByNodeAndProjectAndTypeAndEntity(cluster *db.Cluster, nodeName string, projectName string, typeCode db.WarningType, entityTypeCode int, entityID int) error {
	err := cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarningsByType(typeCode)
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != nodeName || w.Project != projectName || w.EntityTypeCode != entityTypeCode || entityID != entityID {
				continue
			}

			err = tx.UpdateWarningStatus(w.UUID, db.WarningStatusResolved)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to resolve warnings")
	}

	return nil
}

// ResolveWarningsByLocalNodeAndProjectAndTypeAndEntity resolves warnings with the given project, type code, and entity.
func ResolveWarningsByLocalNodeAndProjectAndTypeAndEntity(cluster *db.Cluster, projectName string, typeCode db.WarningType, entityTypeCode int, entityID int) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	return ResolveWarningsByNodeAndProjectAndTypeAndEntity(cluster, localName, projectName, typeCode, entityTypeCode, entityID)
}

// DeleteWarningsByNodeAndProjectAndEntity deletes warnings with the given node, project, and entity.
func DeleteWarningsByNodeAndProjectAndEntity(cluster *db.Cluster, nodeName string, projectName string, entityTypeCode int, entityID int) error {
	err := cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarnings()
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != nodeName || w.Project != projectName || w.EntityTypeCode != entityTypeCode || entityID != entityID {
				continue
			}

			err = tx.DeleteWarning(w.UUID)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to resolve warnings")
	}

	return nil
}

// DeleteWarningsByLocalNodeAndProjectAndEntity deletes warnings with the given project, and entity.
func DeleteWarningsByLocalNodeAndProjectAndEntity(cluster *db.Cluster, projectName string, entityTypeCode int, entityID int) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	return DeleteWarningsByNodeAndProjectAndEntity(cluster, localName, projectName, entityTypeCode, entityID)
}

// DeleteWarningsByNodeAndProjectAndTypeAndEntity deletes warnings with the given node, project, type code, and entity.
func DeleteWarningsByNodeAndProjectAndTypeAndEntity(cluster *db.Cluster, nodeName string, projectName string, typeCode db.WarningType, entityTypeCode int, entityID int) error {
	err := cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarningsByType(typeCode)
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != nodeName || w.Project != projectName || w.EntityTypeCode != entityTypeCode || entityID != entityID {
				continue
			}

			err = tx.DeleteWarning(w.UUID)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to delete warnings")
	}

	return nil
}

// DeleteWarningsByLocalNodeAndProjectAndTypeAndEntity resolves warnings with the given project, type code, and entity.
func DeleteWarningsByLocalNodeAndProjectAndTypeAndEntity(cluster *db.Cluster, projectName string, typeCode db.WarningType, entityTypeCode int, entityID int) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	return DeleteWarningsByNodeAndProjectAndTypeAndEntity(cluster, localName, projectName, typeCode, entityTypeCode, entityID)
}
<commit_msg>lxd/warnings: Fix entityID logic bugs in resolve and delete functions<commit_after>package warnings

import (
	"fmt"
	"time"

	"github.com/pkg/errors"

	"github.com/lxc/lxd/lxd/db"
)

// ResolveWarningsByLocalNodeOlderThan resolves all warnings which are older than the provided time.
func ResolveWarningsByLocalNodeOlderThan(cluster *db.Cluster, date time.Time) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrapf(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarnings()
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != localName {
				continue
			}

			if w.LastSeenDate.Before(date) {
				err = tx.UpdateWarningStatus(w.UUID, db.WarningStatusResolved)
				if err != nil {
					return err
				}
			}
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to resolve warnings")
	}

	return nil
}

// ResolveWarningsByLocalNodeAndType resolves warnings with the local node and type code.
// Returns error if no local node name.
func ResolveWarningsByLocalNodeAndType(cluster *db.Cluster, typeCode db.WarningType) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrapf(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	return ResolveWarningsByNodeAndType(cluster, localName, typeCode)
}

// ResolveWarningsByNodeAndType resolves warnings with the given node and type code.
func ResolveWarningsByNodeAndType(cluster *db.Cluster, nodeName string, typeCode db.WarningType) error {
	err := cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarningsByType(typeCode)
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != nodeName {
				continue
			}

			err = tx.UpdateWarningStatus(w.UUID, db.WarningStatusResolved)
			if err != nil {
				return err
			}
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to resolve warnings")
	}

	return nil
}

// ResolveWarningsByNodeAndProjectAndType resolves warnings with the given node, project and type code.
func ResolveWarningsByNodeAndProjectAndType(cluster *db.Cluster, nodeName string, projectName string, typeCode db.WarningType) error {
	err := cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarningsByType(typeCode)
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != nodeName || w.Project != projectName {
				continue
			}

			err = tx.UpdateWarningStatus(w.UUID, db.WarningStatusResolved)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to resolve warnings")
	}

	return nil
}

// ResolveWarningsByLocalNodeAndProjectAndType resolves warnings with the given project and type code.
func ResolveWarningsByLocalNodeAndProjectAndType(cluster *db.Cluster, projectName string, typeCode db.WarningType) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	return ResolveWarningsByNodeAndProjectAndType(cluster, localName, projectName, typeCode)
}

// ResolveWarningsByNodeAndProjectAndTypeAndEntity resolves warnings with the given node, project, type code, and entity.
func ResolveWarningsByNodeAndProjectAndTypeAndEntity(cluster *db.Cluster, nodeName string, projectName string, typeCode db.WarningType, entityTypeCode int, entityID int) error {
	err := cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarningsByType(typeCode)
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != nodeName || w.Project != projectName || w.EntityTypeCode != entityTypeCode || w.EntityID != entityID {
				continue
			}

			err = tx.UpdateWarningStatus(w.UUID, db.WarningStatusResolved)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to resolve warnings")
	}

	return nil
}

// ResolveWarningsByLocalNodeAndProjectAndTypeAndEntity resolves warnings with the given project, type code, and entity.
func ResolveWarningsByLocalNodeAndProjectAndTypeAndEntity(cluster *db.Cluster, projectName string, typeCode db.WarningType, entityTypeCode int, entityID int) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	return ResolveWarningsByNodeAndProjectAndTypeAndEntity(cluster, localName, projectName, typeCode, entityTypeCode, entityID)
}

// DeleteWarningsByNodeAndProjectAndEntity deletes warnings with the given node, project, and entity.
func DeleteWarningsByNodeAndProjectAndEntity(cluster *db.Cluster, nodeName string, projectName string, entityTypeCode int, entityID int) error {
	err := cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarnings()
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != nodeName || w.Project != projectName || w.EntityTypeCode != entityTypeCode || w.EntityID != entityID {
				continue
			}

			err = tx.DeleteWarning(w.UUID)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to resolve warnings")
	}

	return nil
}

// DeleteWarningsByLocalNodeAndProjectAndEntity deletes warnings with the given project, and entity.
func DeleteWarningsByLocalNodeAndProjectAndEntity(cluster *db.Cluster, projectName string, entityTypeCode int, entityID int) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	return DeleteWarningsByNodeAndProjectAndEntity(cluster, localName, projectName, entityTypeCode, entityID)
}

// DeleteWarningsByNodeAndProjectAndTypeAndEntity deletes warnings with the given node, project, type code, and entity.
func DeleteWarningsByNodeAndProjectAndTypeAndEntity(cluster *db.Cluster, nodeName string, projectName string, typeCode db.WarningType, entityTypeCode int, entityID int) error {
	err := cluster.Transaction(func(tx *db.ClusterTx) error {
		warnings, err := tx.GetWarningsByType(typeCode)
		if err != nil {
			return err
		}

		for _, w := range warnings {
			if w.Node != nodeName || w.Project != projectName || w.EntityTypeCode != entityTypeCode || w.EntityID != entityID {
				continue
			}

			err = tx.DeleteWarning(w.UUID)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed to delete warnings")
	}

	return nil
}

// DeleteWarningsByLocalNodeAndProjectAndTypeAndEntity resolves warnings with the given project, type code, and entity.
func DeleteWarningsByLocalNodeAndProjectAndTypeAndEntity(cluster *db.Cluster, projectName string, typeCode db.WarningType, entityTypeCode int, entityID int) error {
	var err error
	var localName string

	err = cluster.Transaction(func(tx *db.ClusterTx) error {
		localName, err = tx.GetLocalNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return errors.Wrap(err, "Failed getting local member name")
	}

	if localName == "" {
		return fmt.Errorf("Local member name not available")
	}

	return DeleteWarningsByNodeAndProjectAndTypeAndEntity(cluster, localName, projectName, typeCode, entityTypeCode, entityID)
}
<|endoftext|>