<commit_before>package clock

import (
	"time"
)

type mockTimer struct {
	c       chan time.Time
	release chan bool

	lock   chan struct{}
	clock  Clock
	active bool
	target time.Time
}

var _ Timer = new(mockTimer)

func (m *mockTimer) setInactive() {
	// If a release was sent in the meantime, that means a new timer
	// was started or that we already stopped manually
	select {
	case m.lock <- struct{}{}:
		defer func() { <-m.lock }()
	case <-m.release:
		return
	}
	m.active = false
}

func (m *mockTimer) wait() {
	select {
	case <-m.clock.After(m.target.Sub(m.clock.Now())):
		m.setInactive()
		m.c <- m.clock.Now()
	case <-m.release:
	}
}

func (m *mockTimer) Chan() <-chan time.Time {
	return m.c
}

func (m *mockTimer) Reset(d time.Duration) bool {
	var wasActive bool
	m.lock <- struct{}{}
	defer func() { <-m.lock }()

	wasActive, m.active = m.active, true
	m.target = m.clock.Now().Add(d)

	if wasActive {
		m.release <- true
	}
	go m.wait()

	return wasActive
}

func (m *mockTimer) Stop() bool {
	var wasActive bool
	m.lock <- struct{}{}
	defer func() { <-m.lock }()

	wasActive, m.active = m.active, false
	if wasActive {
		m.release <- true
	}

	return wasActive
}

// NewMockTimer creates a new Timer using the provided Clock. You should not use this
// directly outside of unit tests; use Clock.NewTimer().
func NewMockTimer(c Clock) Timer {
	return &mockTimer{
		c:       make(chan time.Time, 1),
		release: make(chan bool),
		lock:    make(chan struct{}, 1),
		clock:   c,
	}
}
<commit_msg>fix race in NewTimer()<commit_after>package clock

import (
	"time"
)

type mockTimer struct {
	c       chan time.Time
	release chan bool

	lock    chan struct{}
	clock   Clock
	active  bool
	trigger <-chan time.Time
}

var _ Timer = new(mockTimer)

func (m *mockTimer) setInactive() {
	// If a release was sent in the meantime, that means a new timer
	// was started or that we already stopped manually
	select {
	case m.lock <- struct{}{}:
		defer func() { <-m.lock }()
	case <-m.release:
		return
	}
	m.active = false
}

func (m *mockTimer) wait() {
	select {
	case <-m.trigger:
		m.setInactive()
		m.c <- m.clock.Now()
	case <-m.release:
	}
}

func (m *mockTimer) Chan() <-chan time.Time {
	return m.c
}

func (m *mockTimer) Reset(d time.Duration) bool {
	var wasActive bool
	m.lock <- struct{}{}
	defer func() { <-m.lock }()

	wasActive, m.active = m.active, true
	m.trigger = m.clock.After(d)

	if wasActive {
		m.release <- true
	}
	go m.wait()

	return wasActive
}

func (m *mockTimer) Stop() bool {
	var wasActive bool
	m.lock <- struct{}{}
	defer func() { <-m.lock }()

	wasActive, m.active = m.active, false
	if wasActive {
		m.release <- true
	}

	return wasActive
}

// NewMockTimer creates a new Timer using the provided Clock. You should not use this
// directly outside of unit tests; use Clock.NewTimer().
func NewMockTimer(c Clock) Timer {
	return &mockTimer{
		c:       make(chan time.Time, 1),
		release: make(chan bool),
		lock:    make(chan struct{}, 1),
		clock:   c,
	}
}
<|endoftext|>


<commit_before>package r2router

import (
	"encoding/json"
	"fmt"
	"net/http"
	"sort"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

type Counter struct {
	Count int64
	Tot   time.Duration
	Max   time.Duration
	Min   time.Duration
	Avg   time.Duration
}

func (c *Counter) Accumulate(start time.Time, end time.Time) {
	d := int64(end.Sub(start))
	tot := atomic.AddInt64((*int64)(&c.Tot), d)
	count := atomic.AddInt64((*int64)(&c.Count), 1)
	atomic.StoreInt64((*int64)(&c.Avg), tot/count)
	max := int64(c.Max)
	if d > max {
		atomic.CompareAndSwapInt64((*int64)(&c.Max), max, d)
	}
	min := int64(c.Min)
	if d < min {
		atomic.CompareAndSwapInt64((*int64)(&c.Min), min, d)
	}

}

type Timer struct {
	Since  time.Time
	routes map[string]*Counter
	mux    sync.Mutex
}

func NewTimer() *Timer {
	t := &Timer{}
	t.Since = time.Now()
	t.routes = make(map[string]*Counter)
	return t
}

func (t *Timer) Get(name string) *Counter {
	if c, exist := t.routes[name]; exist {
		return c
	}
	t.mux.Lock()
	t.routes[name] = &Counter{}
	t.mux.Unlock()
	return t.routes[name]
}

type Stat struct {
	Route string        `json:"route"`
	Count int64         `json:"count"`
	Tot   time.Duration `json:"tot"`
	Max   time.Duration `json:"max"`
	Min   time.Duration `json:"min"`
	Avg   time.Duration `json:"avg"`
}

type Stats struct {
	Generated time.Time `json:"generated"`
	UpTime    string    `json:"upTime"`
	Result    []*Stat   `json:"result"`
	SortBy    string    `json:"sortBy"`
}

// Implements sort interface
func (s *Stats) Len() int {
	return len(s.Result)
}

func (s *Stats) Swap(i, j int) {
	s.Result[j], s.Result[i] = s.Result[i], s.Result[j]
}

func (s *Stats) Less(i, j int) bool {
	switch s.SortBy {
	case "count":
		return s.Result[i].Count < s.Result[j].Count
	case "tot":
		return s.Result[i].Tot < s.Result[j].Tot
	case "max":
		return s.Result[i].Max < s.Result[j].Max
	default:
		return s.Result[i].Avg < s.Result[j].Avg
	}
}

// For serving statistics
func (t *Timer) ServeHTTP(w http.ResponseWriter, req *http.Request) {

	req.ParseForm()
	sortBy := req.Form.Get("sort")

	stats := &Stats{}
	stats.SortBy = strings.ToLower(sortBy)
	stats.Generated = time.Now()
	stats.UpTime = fmt.Sprintf("%s", stats.Generated.Sub(t.Since))
	// Read access OK for map?
	stats.Result = make([]*Stat, 0, len(t.routes))
	for k, v := range t.routes {
		stat := &Stat{}
		stat.Route = k
		stat.Count = v.Count
		stat.Tot = v.Tot
		stat.Avg = v.Avg
		stat.Max = v.Max
		stat.Min = v.Min
		stats.Result = append(stats.Result, stat)
	}
	sort.Sort(sort.Reverse(stats))
	jsonData, _ := json.Marshal(stats)
	w.Write(jsonData)
}
<commit_msg>Fix, start min with a big number else never recorded<commit_after>package r2router

import (
	"encoding/json"
	"fmt"
	"net/http"
	"sort"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

type Counter struct {
	Count int64
	Tot   time.Duration
	Max   time.Duration
	Min   time.Duration
	Avg   time.Duration
}

func (c *Counter) Accumulate(start time.Time, end time.Time) {
	d := int64(end.Sub(start))
	tot := atomic.AddInt64((*int64)(&c.Tot), d)
	count := atomic.AddInt64((*int64)(&c.Count), 1)
	atomic.StoreInt64((*int64)(&c.Avg), tot/count)
	max := int64(c.Max)
	if d > max {
		atomic.CompareAndSwapInt64((*int64)(&c.Max), max, d)
	}
	min := int64(c.Min)
	if d < min {
		atomic.CompareAndSwapInt64((*int64)(&c.Min), min, d)
	}

}

type Timer struct {
	Since  time.Time
	routes map[string]*Counter
	mux    sync.Mutex
}

func NewTimer() *Timer {
	t := &Timer{}
	t.Since = time.Now()
	t.routes = make(map[string]*Counter)
	return t
}

func (t *Timer) Get(name string) *Counter {
	if c, exist := t.routes[name]; exist {
		return c
	}
	t.mux.Lock()
	t.routes[name] = &Counter{}
	t.routes[name].Min = 1 << 63 - 1
	t.mux.Unlock()
	return t.routes[name]
}

type Stat struct {
	Route string        `json:"route"`
	Count int64         `json:"count"`
	Tot   time.Duration `json:"tot"`
	Max   time.Duration `json:"max"`
	Min   time.Duration `json:"min"`
	Avg   time.Duration `json:"avg"`
}

type Stats struct {
	Generated time.Time `json:"generated"`
	UpTime    string    `json:"upTime"`
	Result    []*Stat   `json:"result"`
	SortBy    string    `json:"sortBy"`
}

// Implements sort interface
func (s *Stats) Len() int {
	return len(s.Result)
}

func (s *Stats) Swap(i, j int) {
	s.Result[j], s.Result[i] = s.Result[i], s.Result[j]
}

func (s *Stats) Less(i, j int) bool {
	switch s.SortBy {
	case "count":
		return s.Result[i].Count < s.Result[j].Count
	case "tot":
		return s.Result[i].Tot < s.Result[j].Tot
	case "max":
		return s.Result[i].Max < s.Result[j].Max
	default:
		return s.Result[i].Avg < s.Result[j].Avg
	}
}

// For serving statistics
func (t *Timer) ServeHTTP(w http.ResponseWriter, req *http.Request) {

	req.ParseForm()
	sortBy := req.Form.Get("sort")

	stats := &Stats{}
	stats.SortBy = strings.ToLower(sortBy)
	stats.Generated = time.Now()
	stats.UpTime = fmt.Sprintf("%s", stats.Generated.Sub(t.Since))
	// Read access OK for map?
	stats.Result = make([]*Stat, 0, len(t.routes))
	for k, v := range t.routes {
		stat := &Stat{}
		stat.Route = k
		stat.Count = v.Count
		stat.Tot = v.Tot
		stat.Avg = v.Avg
		stat.Max = v.Max
		stat.Min = v.Min
		stats.Result = append(stats.Result, stat)
	}
	sort.Sort(sort.Reverse(stats))
	jsonData, _ := json.Marshal(stats)
	w.Write(jsonData)
}
<|endoftext|>


<commit_before>package db_test

import (
	"database/sql"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"github.com/BurntSushi/migration"
	_ "github.com/lib/pq"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gexec"
	"github.com/tedsuo/ifrit"

	. "github.com/concourse/atc/db"
	"github.com/concourse/atc/db/migrations"
	"github.com/concourse/atc/postgresrunner"
)

var _ = Describe("SQL DB", func() {
	var postgresPort int
	var dbConn *sql.DB

	var dbProcess ifrit.Process
	var dbDir string

	BeforeSuite(func() {
		postgresPort = 5433 + GinkgoParallelNode()

		dbProcess = ifrit.Envoke(postgresrunner.Runner{
			Addr: fmt.Sprintf("127.0.0.1:%d", postgresPort),
		})
	})

	AfterSuite(func() {
		dbProcess.Signal(os.Interrupt)
		Eventually(dbProcess.Wait()).Should(Receive())
	})

	BeforeEach(func() {
		var err error

		createdb := exec.Command("createdb", "-U", "postgres", "-p", fmt.Sprintf("%d", postgresPort), "testdb")
		createS, err := gexec.Start(createdb, GinkgoWriter, GinkgoWriter)
		Ω(err).ShouldNot(HaveOccurred())
		Eventually(createS, 10*time.Second).Should(gexec.Exit(0))

		dbDir, err = ioutil.TempDir("", "dbDir")
		Ω(err).ShouldNot(HaveOccurred())

		err = exec.Command("cp", "-a", "../db/", dbDir+"/").Run()
		Ω(err).ShouldNot(HaveOccurred())

		dbstring := fmt.Sprintf("user=postgres dbname=testdb sslmode=disable port=%d", postgresPort)

		dbConn, err = migration.Open("postgres", dbstring, migrations.Migrations)
		Ω(err).ShouldNot(HaveOccurred())

		err = ioutil.WriteFile(filepath.Join(dbDir, "dbconf.yml"), []byte(fmt.Sprintf(`development:
  driver: postgres
  open: `+dbstring)), 0644)
		Ω(err).ShouldNot(HaveOccurred())

		db = NewSQL(dbConn)
	})

	AfterEach(func() {
		err := dbConn.Close()
		Ω(err).ShouldNot(HaveOccurred())

		dropdb := exec.Command("dropdb", "-U", "postgres", "-p", fmt.Sprintf("%d", postgresPort), "testdb")
		dropS, err := gexec.Start(dropdb, GinkgoWriter, GinkgoWriter)
		Ω(err).ShouldNot(HaveOccurred())
		Eventually(dropS, 10*time.Second).Should(gexec.Exit(0))

		err = os.RemoveAll(dbDir)
		Ω(err).ShouldNot(HaveOccurred())
	})

	itIsADB()
})
<commit_msg>wait a bit longer for postgres to go away<commit_after>package db_test

import (
	"database/sql"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"github.com/BurntSushi/migration"
	_ "github.com/lib/pq"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gexec"
	"github.com/tedsuo/ifrit"

	. "github.com/concourse/atc/db"
	"github.com/concourse/atc/db/migrations"
	"github.com/concourse/atc/postgresrunner"
)

var _ = Describe("SQL DB", func() {
	var postgresPort int
	var dbConn *sql.DB

	var dbProcess ifrit.Process
	var dbDir string

	BeforeSuite(func() {
		postgresPort = 5433 + GinkgoParallelNode()

		dbProcess = ifrit.Envoke(postgresrunner.Runner{
			Addr: fmt.Sprintf("127.0.0.1:%d", postgresPort),
		})
	})

	AfterSuite(func() {
		dbProcess.Signal(os.Interrupt)
		Eventually(dbProcess.Wait(), 10*time.Second).Should(Receive())
	})

	BeforeEach(func() {
		var err error

		createdb := exec.Command("createdb", "-U", "postgres", "-p", fmt.Sprintf("%d", postgresPort), "testdb")
		createS, err := gexec.Start(createdb, GinkgoWriter, GinkgoWriter)
		Ω(err).ShouldNot(HaveOccurred())
		Eventually(createS, 10*time.Second).Should(gexec.Exit(0))

		dbDir, err = ioutil.TempDir("", "dbDir")
		Ω(err).ShouldNot(HaveOccurred())

		err = exec.Command("cp", "-a", "../db/", dbDir+"/").Run()
		Ω(err).ShouldNot(HaveOccurred())

		dbstring := fmt.Sprintf("user=postgres dbname=testdb sslmode=disable port=%d", postgresPort)

		dbConn, err = migration.Open("postgres", dbstring, migrations.Migrations)
		Ω(err).ShouldNot(HaveOccurred())

		err = ioutil.WriteFile(filepath.Join(dbDir, "dbconf.yml"), []byte(fmt.Sprintf(`development:
  driver: postgres
  open: `+dbstring)), 0644)
		Ω(err).ShouldNot(HaveOccurred())

		db = NewSQL(dbConn)
	})

	AfterEach(func() {
		err := dbConn.Close()
		Ω(err).ShouldNot(HaveOccurred())

		dropdb := exec.Command("dropdb", "-U", "postgres", "-p", fmt.Sprintf("%d", postgresPort), "testdb")
		dropS, err := gexec.Start(dropdb, GinkgoWriter, GinkgoWriter)
		Ω(err).ShouldNot(HaveOccurred())
		Eventually(dropS, 10*time.Second).Should(gexec.Exit(0))

		err = os.RemoveAll(dbDir)
		Ω(err).ShouldNot(HaveOccurred())
	})

	itIsADB()
})
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/vmware/govmomi"
    "github.com/vmware/govmomi/find"
	"github.com/vmware/govmomi/vim25/mo"
	"github.com/vmware/govmomi/vim25/types"
    "strings"
)

func resourceVirtualMachine() *schema.Resource {
	return &schema.Resource{
		Create: resourceVirtualMachineCreate,
		Read:   resourceVirtualMachineRead,
		Delete: resourceVirtualMachineDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
                ForceNew: true,
			},
			"image": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
                ForceNew: true,
			},

			"datacenter": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"folder": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"host": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
                Computed: true,
			},
			"resource_pool": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
                Computed: true,
            },

			"linked_clone": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
                Default: false,
                ForceNew: true,
			},
			"cpus": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
                Computed: true,
			},
			"memory": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
                Computed: true,
			},
			"domain": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
            "ip_address": &schema.Schema{
                Type:     schema.TypeString,
                Optional: true,
                Computed: true,
            },
            "subnet_mask": &schema.Schema{
                Type:     schema.TypeString,
                Optional: true,
            },
            "configuration_parameters": &schema.Schema{
				Type:     schema.TypeMap,
				Optional: true,
                ForceNew: true,
			},
			"power_on": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
                Default:  true,
			},
        },
	}
}

func resourceVirtualMachineCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*govmomi.Client)

    dc_name := d.Get("datacenter").(string)
    if dc_name == "" {
        finder := find.NewFinder(client, false)
        dc, err := finder.DefaultDatacenter()
        if err != nil {
            return fmt.Errorf("Error reading default datacenter: %s", err)
        }
        var dc_mo mo.Datacenter
        err = client.Properties(dc.Reference(), []string{"name"}, &dc_mo)
        if err != nil {
            return fmt.Errorf("Error reading datacenter name: %s", err)
        }
        dc_name = dc_mo.Name
        d.Set("datacenter", dc_name)
    }

	image_name := d.Get("image").(string)
    image_ref, err := client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%s/vm/%s", dc_name, image_name))
	if err != nil {
		return fmt.Errorf("Error reading vm: %s", err)
	}
    if image_ref == nil {
        return fmt.Errorf("Cannot find image %s", image_name)
    }
    image := image_ref.(*govmomi.VirtualMachine)

    var image_mo mo.VirtualMachine
    err = client.Properties(image.Reference(), []string{"parent", "config.template", "resourcePool", "snapshot", "guest.guestFamily"}, &image_mo)
    if err != nil {
        return fmt.Errorf("Error reading base VM properties: %s", err)
    }

	var folder_ref govmomi.Reference
    var folder *govmomi.Folder
    if d.Get("folder").(string) != "" {
        folder_ref, err = client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%v/vm/%v", dc_name, d.Get("folder").(string)))
        if err != nil {
            return fmt.Errorf("Error reading folder: %s", err)
        }
        if folder_ref == nil {
            return fmt.Errorf("Cannot find folder %s", d.Get("folder").(string))
        }

        folder = folder_ref.(*govmomi.Folder)
    } else {
        folder = govmomi.NewFolder(client, *image_mo.Parent)
    }

    host_name := d.Get("host").(string)
    if host_name == "" {
        if image_mo.Config.Template == true {
            return fmt.Errorf("Image is a template, 'host' is a required")
        } else {
            var pool_mo mo.ResourcePool
            err = client.Properties(*image_mo.ResourcePool, []string{"owner"}, &pool_mo)
            if err != nil {
                return fmt.Errorf("Error reading resource pool of base VM: %s", err)
            }

            if strings.Contains(pool_mo.Owner.Value, "domain-s") {
                var host_mo mo.ComputeResource
                err = client.Properties(pool_mo.Owner, []string{"name"}, &host_mo)
                if err != nil {
                    return fmt.Errorf("Error reading host of base VM: %s", err)
                }
                host_name = host_mo.Name
            } else if strings.Contains(pool_mo.Owner.Value, "domain-c") {
                var cluster_mo mo.ClusterComputeResource
                err = client.Properties(pool_mo.Owner, []string{"name"}, &cluster_mo)
                if err != nil {
                    return fmt.Errorf("Error reading cluster of base VM: %s", err)
                }
                host_name = cluster_mo.Name
            } else {
                return fmt.Errorf("Unknown compute resource format of base VM: %s", pool_mo.Owner.Value)
            }
        }
    }

    pool_name := d.Get("resource_pool").(string)
    pool_ref, err := client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%v/host/%v/Resources/%v", dc_name, host_name, pool_name))
    if err != nil {
        return fmt.Errorf("Error reading resource pool: %s", err)
    }
    if pool_ref == nil {
        return fmt.Errorf("Cannot find resource pool %s", pool_name)
    }

	var relocateSpec types.VirtualMachineRelocateSpec
    var pool_mor types.ManagedObjectReference
    pool_mor = pool_ref.Reference()
    relocateSpec.Pool = &pool_mor

	if d.Get("linked_clone").(bool) {
		relocateSpec.DiskMoveType = "createNewChildDiskBacking"
	}
    var confSpec types.VirtualMachineConfigSpec
    if d.Get("cpus") != nil {
        confSpec.NumCPUs = d.Get("cpus").(int)
    }
    if d.Get("memory") != nil {
        confSpec.MemoryMB = int64(d.Get("memory").(int))
    }

    params := d.Get("configuration_parameters").(map[string]interface{})
    var ov []types.BaseOptionValue
    if len(params) > 0 {
        for k, v := range params {
            key := k
            value := v
            o := types.OptionValue{
                Key:   key,
                Value: &value,
            }
            ov = append(ov, &o)
        }
        confSpec.ExtraConfig = ov
    }

	cloneSpec := types.VirtualMachineCloneSpec{
		Location: relocateSpec,
        Config:   &confSpec,
        PowerOn:  d.Get("power_on").(bool),
	}
    if d.Get("linked_clone").(bool) {
        if image_mo.Snapshot == nil {
            return fmt.Errorf("`linked_clone=true`, but image VM has no snapshots")
        }
        cloneSpec.Snapshot = image_mo.Snapshot.CurrentSnapshot
    }

    domain := d.Get("domain").(string)
    ip_address := d.Get("ip_address").(string)
    if domain != "" {
        if image_mo.Guest == nil {
            return fmt.Errorf("Base image OS family is unknown")
        }
        if image_mo.Guest.GuestFamily != "linuxGuest" {
            return fmt.Errorf("Guest customization is supported only for Linux. Base image OS family is: %s", image_mo.Guest.GuestFamily)
        }
        customizationSpec := types.CustomizationSpec{
            GlobalIPSettings: types.CustomizationGlobalIPSettings{},
            Identity: &types.CustomizationLinuxPrep{
                HostName: &types.CustomizationVirtualMachineName{},
                Domain: domain,
            },
            NicSettingMap: []types.CustomizationAdapterMapping {
                {
                    Adapter: types.CustomizationIPSettings{},
                },
            },
        }
        if ip_address != "" {
            mask := d.Get("subnet_mask").(string)
            if mask == "" {
                return fmt.Errorf("'subnet_mask' must be set, if static 'ip_address' is specified")
            }
            customizationSpec.NicSettingMap[0].Adapter.Ip = &types.CustomizationFixedIp{
                IpAddress: ip_address,
            }
            customizationSpec.NicSettingMap[0].Adapter.SubnetMask = d.Get("subnet_mask").(string)

        } else {
            customizationSpec.NicSettingMap[0].Adapter.Ip = &types.CustomizationDhcpIpGenerator{}
        }
        cloneSpec.Customization = &customizationSpec
    } else if ip_address != "" {
        return fmt.Errorf("'domain' must be set, if static 'ip_address' is specified")
    }

	task, err := image.Clone(folder, d.Get("name").(string), cloneSpec)
	if err != nil {
		return fmt.Errorf("Error clonning vm: %s", err)
	}
	info, err := task.WaitForResult(nil)
	if err != nil {
		return fmt.Errorf("Error clonning vm: %s", err)
	}

	vm_mor := info.Result.(types.ManagedObjectReference)
    d.SetId(vm_mor.Value)
    vm := govmomi.NewVirtualMachine(client, vm_mor)
    // workaround for https://github.com/vmware/govmomi/issues/218
    if ip_address=="" && d.Get("power_on").(bool) {
        ip, err := vm.WaitForIP()
        if err != nil {
            log.Printf("[ERROR] Cannot read ip address: %s", err)
        } else {
            d.Set("ip_address", ip)
        }
    }

    return nil
}

func resourceVirtualMachineRead(d *schema.ResourceData, meta interface{}) error {
    client := meta.(*govmomi.Client)
    vm_mor := types.ManagedObjectReference{Type: "VirtualMachine", Value: d.Id() }
    vm := govmomi.NewVirtualMachine(client, vm_mor)

    var vm_mo mo.VirtualMachine
    err := client.Properties(vm.Reference(), []string{"summary"}, &vm_mo)
    if err != nil {
        log.Printf("[INFO] Cannot read VM properties: %s", err)
        d.SetId("")
        return nil
    }
    d.Set("name", vm_mo.Summary.Config.Name)
    d.Set("cpus", vm_mo.Summary.Config.NumCpu)
    d.Set("memory", vm_mo.Summary.Config.MemorySizeMB)

    if vm_mo.Summary.Runtime.PowerState == "poweredOn" {
        d.Set("power_on", true)
    } else {
        d.Set("power_on", false)
    }

    if d.Get("power_on").(bool) {
        ip, err := vm.WaitForIP()
        if err != nil {
            log.Printf("[ERROR] Cannot read ip address: %s", err)
        } else {
            d.Set("ip_address", ip)
        }
    }

	return nil
}

func resourceVirtualMachineDelete(d *schema.ResourceData, meta interface{}) error {
    client := meta.(*govmomi.Client)
    vm_mor := types.ManagedObjectReference{Type: "VirtualMachine", Value: d.Id() }
    vm := govmomi.NewVirtualMachine(client, vm_mor)

    task, err := vm.PowerOff()
    if err != nil {
        return fmt.Errorf("Error powering vm off: %s", err)
    }
    task.WaitForResult(nil)

    task, err = vm.Destroy()
    if err != nil {
        return fmt.Errorf("Error deleting vm: %s", err)
    }
    _, err = task.WaitForResult(nil)
    if err != nil {
        return fmt.Errorf("Error deleting vm: %s", err)
    }

    return nil
}
<commit_msg>`gateway` parameter allows setting a gateway for a network adapter when static IP address is assigned (#20)<commit_after>package main

import (
	"fmt"
	"log"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/vmware/govmomi"
    "github.com/vmware/govmomi/find"
	"github.com/vmware/govmomi/vim25/mo"
	"github.com/vmware/govmomi/vim25/types"
    "strings"
)

func resourceVirtualMachine() *schema.Resource {
	return &schema.Resource{
		Create: resourceVirtualMachineCreate,
		Read:   resourceVirtualMachineRead,
		Delete: resourceVirtualMachineDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
                ForceNew: true,
			},
			"image": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
                ForceNew: true,
			},

			"datacenter": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"folder": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"host": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
                Computed: true,
			},
			"resource_pool": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
                Computed: true,
            },

			"linked_clone": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
                Default: false,
                ForceNew: true,
			},
			"cpus": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
                Computed: true,
			},
			"memory": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
                Computed: true,
			},
			"domain": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
            "ip_address": &schema.Schema{
                Type:     schema.TypeString,
                Optional: true,
                Computed: true,
            },
            "subnet_mask": &schema.Schema{
                Type:     schema.TypeString,
                Optional: true,
            },
            "gateway": &schema.Schema{
                Type:     schema.TypeString,
                Optional: true,
            },
            "configuration_parameters": &schema.Schema{
				Type:     schema.TypeMap,
				Optional: true,
                ForceNew: true,
			},
			"power_on": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
                Default:  true,
			},
        },
	}
}

func resourceVirtualMachineCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*govmomi.Client)

    dc_name := d.Get("datacenter").(string)
    if dc_name == "" {
        finder := find.NewFinder(client, false)
        dc, err := finder.DefaultDatacenter()
        if err != nil {
            return fmt.Errorf("Error reading default datacenter: %s", err)
        }
        var dc_mo mo.Datacenter
        err = client.Properties(dc.Reference(), []string{"name"}, &dc_mo)
        if err != nil {
            return fmt.Errorf("Error reading datacenter name: %s", err)
        }
        dc_name = dc_mo.Name
        d.Set("datacenter", dc_name)
    }

	image_name := d.Get("image").(string)
    image_ref, err := client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%s/vm/%s", dc_name, image_name))
	if err != nil {
		return fmt.Errorf("Error reading vm: %s", err)
	}
    if image_ref == nil {
        return fmt.Errorf("Cannot find image %s", image_name)
    }
    image := image_ref.(*govmomi.VirtualMachine)

    var image_mo mo.VirtualMachine
    err = client.Properties(image.Reference(), []string{"parent", "config.template", "resourcePool", "snapshot", "guest.guestFamily"}, &image_mo)
    if err != nil {
        return fmt.Errorf("Error reading base VM properties: %s", err)
    }

	var folder_ref govmomi.Reference
    var folder *govmomi.Folder
    if d.Get("folder").(string) != "" {
        folder_ref, err = client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%v/vm/%v", dc_name, d.Get("folder").(string)))
        if err != nil {
            return fmt.Errorf("Error reading folder: %s", err)
        }
        if folder_ref == nil {
            return fmt.Errorf("Cannot find folder %s", d.Get("folder").(string))
        }

        folder = folder_ref.(*govmomi.Folder)
    } else {
        folder = govmomi.NewFolder(client, *image_mo.Parent)
    }

    host_name := d.Get("host").(string)
    if host_name == "" {
        if image_mo.Config.Template == true {
            return fmt.Errorf("Image is a template, 'host' is a required")
        } else {
            var pool_mo mo.ResourcePool
            err = client.Properties(*image_mo.ResourcePool, []string{"owner"}, &pool_mo)
            if err != nil {
                return fmt.Errorf("Error reading resource pool of base VM: %s", err)
            }

            if strings.Contains(pool_mo.Owner.Value, "domain-s") {
                var host_mo mo.ComputeResource
                err = client.Properties(pool_mo.Owner, []string{"name"}, &host_mo)
                if err != nil {
                    return fmt.Errorf("Error reading host of base VM: %s", err)
                }
                host_name = host_mo.Name
            } else if strings.Contains(pool_mo.Owner.Value, "domain-c") {
                var cluster_mo mo.ClusterComputeResource
                err = client.Properties(pool_mo.Owner, []string{"name"}, &cluster_mo)
                if err != nil {
                    return fmt.Errorf("Error reading cluster of base VM: %s", err)
                }
                host_name = cluster_mo.Name
            } else {
                return fmt.Errorf("Unknown compute resource format of base VM: %s", pool_mo.Owner.Value)
            }
        }
    }

    pool_name := d.Get("resource_pool").(string)
    pool_ref, err := client.SearchIndex().FindByInventoryPath(fmt.Sprintf("%v/host/%v/Resources/%v", dc_name, host_name, pool_name))
    if err != nil {
        return fmt.Errorf("Error reading resource pool: %s", err)
    }
    if pool_ref == nil {
        return fmt.Errorf("Cannot find resource pool %s", pool_name)
    }

	var relocateSpec types.VirtualMachineRelocateSpec
    var pool_mor types.ManagedObjectReference
    pool_mor = pool_ref.Reference()
    relocateSpec.Pool = &pool_mor

	if d.Get("linked_clone").(bool) {
		relocateSpec.DiskMoveType = "createNewChildDiskBacking"
	}
    var confSpec types.VirtualMachineConfigSpec
    if d.Get("cpus") != nil {
        confSpec.NumCPUs = d.Get("cpus").(int)
    }
    if d.Get("memory") != nil {
        confSpec.MemoryMB = int64(d.Get("memory").(int))
    }

    params := d.Get("configuration_parameters").(map[string]interface{})
    var ov []types.BaseOptionValue
    if len(params) > 0 {
        for k, v := range params {
            key := k
            value := v
            o := types.OptionValue{
                Key:   key,
                Value: &value,
            }
            ov = append(ov, &o)
        }
        confSpec.ExtraConfig = ov
    }

	cloneSpec := types.VirtualMachineCloneSpec{
		Location: relocateSpec,
        Config:   &confSpec,
        PowerOn:  d.Get("power_on").(bool),
	}
    if d.Get("linked_clone").(bool) {
        if image_mo.Snapshot == nil {
            return fmt.Errorf("`linked_clone=true`, but image VM has no snapshots")
        }
        cloneSpec.Snapshot = image_mo.Snapshot.CurrentSnapshot
    }

    domain := d.Get("domain").(string)
    ip_address := d.Get("ip_address").(string)
    if domain != "" {
        if image_mo.Guest == nil {
            return fmt.Errorf("Base image OS family is unknown")
        }
        if image_mo.Guest.GuestFamily != "linuxGuest" {
            return fmt.Errorf("Guest customization is supported only for Linux. Base image OS family is: %s", image_mo.Guest.GuestFamily)
        }
        customizationSpec := types.CustomizationSpec{
            GlobalIPSettings: types.CustomizationGlobalIPSettings{},
            Identity: &types.CustomizationLinuxPrep{
                HostName: &types.CustomizationVirtualMachineName{},
                Domain: domain,
            },
            NicSettingMap: []types.CustomizationAdapterMapping {
                {
                    Adapter: types.CustomizationIPSettings{},
                },
            },
        }
        if ip_address != "" {
            mask := d.Get("subnet_mask").(string)
            if mask == "" {
                return fmt.Errorf("'subnet_mask' must be set, if static 'ip_address' is specified")
            }
            customizationSpec.NicSettingMap[0].Adapter.Ip = &types.CustomizationFixedIp{
                IpAddress: ip_address,
            }
            customizationSpec.NicSettingMap[0].Adapter.SubnetMask = d.Get("subnet_mask").(string)
            gateway := d.Get("gateway").(string)
            if gateway != "" {
                customizationSpec.NicSettingMap[0].Adapter.Gateway = []string{gateway}
            }
        } else {
            customizationSpec.NicSettingMap[0].Adapter.Ip = &types.CustomizationDhcpIpGenerator{}
        }
        cloneSpec.Customization = &customizationSpec
    } else if ip_address != "" {
        return fmt.Errorf("'domain' must be set, if static 'ip_address' is specified")
    }

	task, err := image.Clone(folder, d.Get("name").(string), cloneSpec)
	if err != nil {
		return fmt.Errorf("Error clonning vm: %s", err)
	}
	info, err := task.WaitForResult(nil)
	if err != nil {
		return fmt.Errorf("Error clonning vm: %s", err)
	}

	vm_mor := info.Result.(types.ManagedObjectReference)
    d.SetId(vm_mor.Value)
    vm := govmomi.NewVirtualMachine(client, vm_mor)
    // workaround for https://github.com/vmware/govmomi/issues/218
    if ip_address=="" && d.Get("power_on").(bool) {
        ip, err := vm.WaitForIP()
        if err != nil {
            log.Printf("[ERROR] Cannot read ip address: %s", err)
        } else {
            d.Set("ip_address", ip)
        }
    }

    return nil
}

func resourceVirtualMachineRead(d *schema.ResourceData, meta interface{}) error {
    client := meta.(*govmomi.Client)
    vm_mor := types.ManagedObjectReference{Type: "VirtualMachine", Value: d.Id() }
    vm := govmomi.NewVirtualMachine(client, vm_mor)

    var vm_mo mo.VirtualMachine
    err := client.Properties(vm.Reference(), []string{"summary"}, &vm_mo)
    if err != nil {
        log.Printf("[INFO] Cannot read VM properties: %s", err)
        d.SetId("")
        return nil
    }
    d.Set("name", vm_mo.Summary.Config.Name)
    d.Set("cpus", vm_mo.Summary.Config.NumCpu)
    d.Set("memory", vm_mo.Summary.Config.MemorySizeMB)

    if vm_mo.Summary.Runtime.PowerState == "poweredOn" {
        d.Set("power_on", true)
    } else {
        d.Set("power_on", false)
    }

    if d.Get("power_on").(bool) {
        ip, err := vm.WaitForIP()
        if err != nil {
            log.Printf("[ERROR] Cannot read ip address: %s", err)
        } else {
            d.Set("ip_address", ip)
        }
    }

	return nil
}

func resourceVirtualMachineDelete(d *schema.ResourceData, meta interface{}) error {
    client := meta.(*govmomi.Client)
    vm_mor := types.ManagedObjectReference{Type: "VirtualMachine", Value: d.Id() }
    vm := govmomi.NewVirtualMachine(client, vm_mor)

    task, err := vm.PowerOff()
    if err != nil {
        return fmt.Errorf("Error powering vm off: %s", err)
    }
    task.WaitForResult(nil)

    task, err = vm.Destroy()
    if err != nil {
        return fmt.Errorf("Error deleting vm: %s", err)
    }
    _, err = task.WaitForResult(nil)
    if err != nil {
        return fmt.Errorf("Error deleting vm: %s", err)
    }

    return nil
}
<|endoftext|>


<commit_before>package resourceids

import (
	"fmt"
	"net/url"
	"strings"
)

// ResourceID represents a parsed long-form Azure Resource Manager ID
// with the Subscription ID, Resource Group and the Provider as top-
// level fields, and other key-value pairs available via a map in the
// Path field.
type ResourceID struct {
	SubscriptionID string
	ResourceGroup  string
	Provider       string
	Path           map[string]string
}

// ParseAzureResourceID converts a long-form Azure Resource Manager ID
// into a ResourceID.
func ParseAzureResourceID(id string) (*ResourceID, error) {
	idURL, err := url.ParseRequestURI(id)
	if err != nil {
		return nil, fmt.Errorf("parsing Azure ID: %s", err)
	}

	path := idURL.Path

	path = strings.TrimPrefix(path, "/")
	path = strings.TrimSuffix(path, "/")

	components := strings.Split(path, "/")

	// We should have an even number of key-value pairs.
	if len(components)%2 != 0 {
		return nil, fmt.Errorf("the number of path segments is not divisible by 2 in %q", path)
	}

	var subscriptionID string

	// Put the constituent key-value pairs into a map
	componentMap := make(map[string]string, len(components)/2)
	for current := 0; current < len(components); current += 2 {
		key := components[current]
		value := components[current+1]

		// Check key/value for empty strings.
		if key == "" || value == "" {
			return nil, fmt.Errorf("Key/Value cannot be empty strings. Key: '%s', Value: '%s'", key, value)
		}

		// Catch the subscriptionID before it can be overwritten by another "subscriptions"
		// value in the ID which is the case for the Service Bus subscription resource
		if key == "subscriptions" && subscriptionID == "" {
			subscriptionID = value
		} else {
			componentMap[key] = value
		}
	}

	// Build up a TargetResourceID from the map
	idObj := &ResourceID{}
	idObj.Path = componentMap

	if subscriptionID != "" {
		idObj.SubscriptionID = subscriptionID
	} else {
		return nil, fmt.Errorf("No subscription ID found in: %q", path)
	}

	if resourceGroup, ok := componentMap["resourceGroups"]; ok {
		idObj.ResourceGroup = resourceGroup
		delete(componentMap, "resourceGroups")
	} else if resourceGroup, ok := componentMap["resourcegroups"]; ok {
		// Some Azure APIs are weird and provide things in lower case...
		// However it's not clear whether the casing of other elements in the URI
		// matter, so we explicitly look for that case here.
		idObj.ResourceGroup = resourceGroup
		delete(componentMap, "resourcegroups")
	}

	// It is OK not to have a provider in the case of a resource group
	if provider, ok := componentMap["providers"]; ok {
		idObj.Provider = provider
		delete(componentMap, "providers")
	}

	return idObj, nil
}

// PopSegment retrieves a segment from the Path and returns it
// if found it removes it from the Path then return the value
// if not found, this returns nil
func (id *ResourceID) PopSegment(name string) (string, error) {
	val, ok := id.Path[name]
	if !ok {
		return "", fmt.Errorf("ID was missing the `%s` element", name)
	}

	delete(id.Path, name)
	return val, nil
}

// ValidateNoEmptySegments validates ...
func (id *ResourceID) ValidateNoEmptySegments(sourceId string) error {
	if len(id.Path) == 0 {
		return nil
	}

	return fmt.Errorf("ID contained more segments than required: %q, %v", sourceId, id.Path)
}
<commit_msg>Backport of id.Provider logic<commit_after>package resourceids

import (
	"fmt"
	"net/url"
	"strings"
)

// ResourceID represents a parsed long-form Azure Resource Manager ID
// with the Subscription ID, Resource Group and the Provider as top-
// level fields, and other key-value pairs available via a map in the
// Path field.
type ResourceID struct {
	SubscriptionID    string
	ResourceGroup     string
	Provider          string
	SecondaryProvider string
	Path              map[string]string
}

// ParseAzureResourceID converts a long-form Azure Resource Manager ID
// into a ResourceID.
func ParseAzureResourceID(id string) (*ResourceID, error) {
	idURL, err := url.ParseRequestURI(id)
	if err != nil {
		return nil, fmt.Errorf("parsing Azure ID: %s", err)
	}

	path := idURL.Path

	path = strings.TrimPrefix(path, "/")
	path = strings.TrimSuffix(path, "/")

	components := strings.Split(path, "/")

	// We should have an even number of key-value pairs.
	if len(components)%2 != 0 {
		return nil, fmt.Errorf("the number of path segments is not divisible by 2 in %q", path)
	}

	var subscriptionID string
	var provider string

	// Put the constituent key-value pairs into a map
	componentMap := make(map[string]string, len(components)/2)
	for current := 0; current < len(components); current += 2 {
		key := components[current]
		value := components[current+1]

		// Check key/value for empty strings.
		if key == "" || value == "" {
			return nil, fmt.Errorf("Key/Value cannot be empty strings. Key: '%s', Value: '%s'", key, value)
		}

		switch {
		case key == "subscriptions" && subscriptionID == "":
			// Catch the subscriptionID before it can be overwritten by another "subscriptions"
			// value in the ID which is the case for the Service Bus subscription resource
		case key == "providers" && provider == "":
			// Catch the provider before it can be overwritten by another "providers"
			// value in the ID which can be the case for the Role Assignment resource
			provider = value
		default:
			componentMap[key] = value
		}
	}

	// Build up a TargetResourceID from the map
	idObj := &ResourceID{}
	idObj.Path = componentMap

	if subscriptionID != "" {
		idObj.SubscriptionID = subscriptionID
	} else {
		return nil, fmt.Errorf("No subscription ID found in: %q", path)
	}

	if resourceGroup, ok := componentMap["resourceGroups"]; ok {
		idObj.ResourceGroup = resourceGroup
		delete(componentMap, "resourceGroups")
	} else if resourceGroup, ok := componentMap["resourcegroups"]; ok {
		// Some Azure APIs are weird and provide things in lower case...
		// However it's not clear whether the casing of other elements in the URI
		// matter, so we explicitly look for that case here.
		idObj.ResourceGroup = resourceGroup
		delete(componentMap, "resourcegroups")
	}

	// It is OK not to have a provider in the case of a resource group
	if provider != "" {
		idObj.Provider = provider
	}

	// It is OK not to have a secondaryProvider, but having a value for providers
	// in the map breaks the workings of the auto-generated ResourceIDs
	if secondaryProvider := componentMap["providers"]; secondaryProvider != "" {
		idObj.SecondaryProvider = secondaryProvider
		delete(componentMap, "providers")
	}

	return idObj, nil
}

// PopSegment retrieves a segment from the Path and returns it
// if found it removes it from the Path then return the value
// if not found, this returns nil
func (id *ResourceID) PopSegment(name string) (string, error) {
	val, ok := id.Path[name]
	if !ok {
		return "", fmt.Errorf("ID was missing the `%s` element", name)
	}

	delete(id.Path, name)
	return val, nil
}

// ValidateNoEmptySegments validates ...
func (id *ResourceID) ValidateNoEmptySegments(sourceId string) error {
	if len(id.Path) == 0 {
		return nil
	}

	return fmt.Errorf("ID contained more segments than required: %q, %v", sourceId, id.Path)
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package version

import (
	"fmt"

	"github.com/spf13/cobra"

	"k8s.io/kubeadm/kinder/pkg/constants"
)

// NewCommand returns a new cobra.Command for version
func NewCommand() *cobra.Command {
	cmd := &cobra.Command{
		Args:  cobra.NoArgs,
		Use:   "version",
		Short: "prints the kind CLI version",
		Long:  "prints the kind CLI version",
		RunE: func(cmd *cobra.Command, args []string) error {
			fmt.Printf("kinder version: %s\n", constants.KinderVersion)
			return nil
		},
	}
	return cmd
}
<commit_msg>minor fix to kinder version help<commit_after>/*
Copyright 2019 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package version

import (
	"fmt"

	"github.com/spf13/cobra"

	"k8s.io/kubeadm/kinder/pkg/constants"
)

// NewCommand returns a new cobra.Command for version
func NewCommand() *cobra.Command {
	cmd := &cobra.Command{
		Args:  cobra.NoArgs,
		Use:   "version",
		Short: "prints the kinder CLI version",
		Long:  "prints the kinder CLI version",
		RunE: func(cmd *cobra.Command, args []string) error {
			fmt.Printf("kinder version: %s\n", constants.KinderVersion)
			return nil
		},
	}
	return cmd
}
<|endoftext|>


<commit_before>package sarr

import "strings"

func isEqual(word1, word2 []string) bool {
	return useStd(word1, word2)
}

func useStd(word1, word2 []string) bool {
	return strings.Join(word1, "") == strings.Join(word2, "")
}
<commit_msg>solve 1662 use iteration<commit_after>package sarr

import "strings"

func isEqual(word1, word2 []string) bool {
	// return useStd(word1, word2)
	return useIter(word1, word2)
}

func useStd(word1, word2 []string) bool {
	return strings.Join(word1, "") == strings.Join(word2, "")
}

func useIter(word1, word2 []string) bool {
	n1, n2 := len(word1), len(word2)
	var i, j int
	var idx1, idx2 int
	for i < n1 && j < n2 {
		if word1[i][idx1] != word2[j][idx2] {
			return false
		}
		p1, p2 := len(word1[i]), len(word2[j])
		idx1, idx2 = idx1+1, idx2+1
		if idx1 == p1 {
			i++
			idx1 = 0
		}
		if idx2 == p2 {
			j++
			idx2 = 0
		}
	}
	return true
}
<|endoftext|>


<commit_before>package web

import (
	"net/http"
	"net/http/httptest"
	"reflect"
	"regexp"
	"testing"
	"time"
)

// These tests can probably be DRY'd up a bunch

func chHandler(ch chan string, s string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ch <- s
	})
}

var methods = []string{"CONNECT", "DELETE", "GET", "HEAD", "OPTIONS", "PATCH",
	"POST", "PUT", "TRACE", "OTHER"}

func TestMethods(t *testing.T) {
	t.Parallel()
	m := New()
	ch := make(chan string, 1)

	m.Connect("/", chHandler(ch, "CONNECT"))
	m.Delete("/", chHandler(ch, "DELETE"))
	m.Head("/", chHandler(ch, "HEAD"))
	m.Get("/", chHandler(ch, "GET"))
	m.Options("/", chHandler(ch, "OPTIONS"))
	m.Patch("/", chHandler(ch, "PATCH"))
	m.Post("/", chHandler(ch, "POST"))
	m.Put("/", chHandler(ch, "PUT"))
	m.Trace("/", chHandler(ch, "TRACE"))
	m.Handle("/", chHandler(ch, "OTHER"))

	for _, method := range methods {
		r, _ := http.NewRequest(method, "/", nil)
		w := httptest.NewRecorder()
		m.ServeHTTP(w, r)
		select {
		case val := <-ch:
			if val != method {
				t.Errorf("Got %q, expected %q", val, method)
			}
		case <-time.After(5 * time.Millisecond):
			t.Errorf("Timeout waiting for method %q", method)
		}
	}
}

type testPattern struct{}

func (t testPattern) Prefix() string {
	return ""
}

func (t testPattern) Match(r *http.Request, c *C) bool {
	return true
}
func (t testPattern) Run(r *http.Request, c *C) {
}

var _ Pattern = testPattern{}

func TestPatternTypes(t *testing.T) {
	t.Parallel()
	m := New()

	m.Get("/hello/carl", http.NotFound)
	m.Get("/hello/:name", http.NotFound)
	m.Get(regexp.MustCompile(`^/hello/(?P<name>.+)$`), http.NotFound)
	m.Get(testPattern{}, http.NotFound)
}

type testHandler chan string

func (t testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	t <- "http"
}
func (t testHandler) ServeHTTPC(c C, w http.ResponseWriter, r *http.Request) {
	t <- "httpc"
}

var testHandlerTable = map[string]string{
	"/a": "http fn",
	"/b": "http handler",
	"/c": "web fn",
	"/d": "web handler",
	"/e": "httpc",
}

func TestHandlerTypes(t *testing.T) {
	t.Parallel()
	m := New()
	ch := make(chan string, 1)

	m.Get("/a", func(w http.ResponseWriter, r *http.Request) {
		ch <- "http fn"
	})
	m.Get("/b", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ch <- "http handler"
	}))
	m.Get("/c", func(c C, w http.ResponseWriter, r *http.Request) {
		ch <- "web fn"
	})
	m.Get("/d", HandlerFunc(func(c C, w http.ResponseWriter, r *http.Request) {
		ch <- "web handler"
	}))
	m.Get("/e", testHandler(ch))

	for route, response := range testHandlerTable {
		r, _ := http.NewRequest("GET", route, nil)
		w := httptest.NewRecorder()
		m.ServeHTTP(w, r)
		select {
		case resp := <-ch:
			if resp != response {
				t.Errorf("Got %q, expected %q", resp, response)
			}
		case <-time.After(5 * time.Millisecond):
			t.Errorf("Timeout waiting for path %q", route)
		}

	}
}

// The idea behind this test is to comprehensively test if routes are being
// applied in the right order. We define a special pattern type that always
// matches so long as it's greater than or equal to the global test index. By
// incrementing this index, we can invalidate all routes up to some point, and
// therefore test the routing guarantee that Goji provides: for any path P, if
// both A and B match P, and if A was inserted before B, then Goji will route to
// A before it routes to B.
var rsRoutes = []string{
	"/",
	"/a",
	"/a",
	"/b",
	"/ab",
	"/",
	"/ba",
	"/b",
	"/a",
}

var rsTests = []struct {
	key     string
	results []int
}{
	{"/", []int{0, 5, 5, 5, 5, 5, -1, -1, -1, -1}},
	{"/a", []int{0, 1, 2, 5, 5, 5, 8, 8, 8, -1}},
	{"/b", []int{0, 3, 3, 3, 5, 5, 7, 7, -1, -1}},
	{"/ab", []int{0, 1, 2, 4, 4, 5, 8, 8, 8, -1}},
	{"/ba", []int{0, 3, 3, 3, 5, 5, 6, 7, -1, -1}},
	{"/c", []int{0, 5, 5, 5, 5, 5, -1, -1, -1, -1}},
	{"nope", []int{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
}

type rsPattern struct {
	i       int
	counter *int
	prefix  string
	ichan   chan int
}

func (rs rsPattern) Prefix() string {
	return rs.prefix
}
func (rs rsPattern) Match(_ *http.Request, _ *C) bool {
	return rs.i >= *rs.counter
}
func (rs rsPattern) Run(_ *http.Request, _ *C) {
}

func (rs rsPattern) ServeHTTP(_ http.ResponseWriter, _ *http.Request) {
	rs.ichan <- rs.i
}

var _ Pattern = rsPattern{}
var _ http.Handler = rsPattern{}

func TestRouteSelection(t *testing.T) {
	t.Parallel()
	m := New()
	counter := 0
	ichan := make(chan int, 1)
	m.NotFound(func(w http.ResponseWriter, r *http.Request) {
		ichan <- -1
	})

	for i, s := range rsRoutes {
		pat := rsPattern{
			i:       i,
			counter: &counter,
			prefix:  s,
			ichan:   ichan,
		}
		m.Get(pat, pat)
	}

	for _, test := range rsTests {
		var n int
		for counter, n = range test.results {
			r, _ := http.NewRequest("GET", test.key, nil)
			w := httptest.NewRecorder()
			m.ServeHTTP(w, r)
			actual := <-ichan
			if n != actual {
				t.Errorf("Expected %q @ %d to be %d, got %d",
					test.key, counter, n, actual)
			}
		}
	}
}

func TestNotFound(t *testing.T) {
	t.Parallel()
	m := New()

	r, _ := http.NewRequest("post", "/", nil)
	w := httptest.NewRecorder()
	m.ServeHTTP(w, r)
	if w.Code != 404 {
		t.Errorf("Expected 404, got %d", w.Code)
	}

	m.NotFound(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, "I'm a teapot!", http.StatusTeapot)
	})

	r, _ = http.NewRequest("POST", "/", nil)
	w = httptest.NewRecorder()
	m.ServeHTTP(w, r)
	if w.Code != http.StatusTeapot {
		t.Errorf("Expected a teapot, got %d", w.Code)
	}
}

func TestPrefix(t *testing.T) {
	t.Parallel()
	m := New()
	ch := make(chan string, 1)

	m.Handle("/hello/*", func(w http.ResponseWriter, r *http.Request) {
		ch <- r.URL.Path
	})

	r, _ := http.NewRequest("GET", "/hello/world", nil)
	w := httptest.NewRecorder()
	m.ServeHTTP(w, r)
	select {
	case val := <-ch:
		if val != "/hello/world" {
			t.Errorf("Got %q, expected /hello/world", val)
		}
	case <-time.After(5 * time.Millisecond):
		t.Errorf("Timeout waiting for hello")
	}
}

var validMethodsTable = map[string][]string{
	"/hello/carl":       {"DELETE", "GET", "HEAD", "PATCH", "POST", "PUT"},
	"/hello/bob":        {"DELETE", "GET", "HEAD", "PATCH", "PUT"},
	"/hola/carl":        {"DELETE", "GET", "HEAD", "PUT"},
	"/hola/bob":         {"DELETE"},
	"/does/not/compute": {},
}

func TestValidMethods(t *testing.T) {
	t.Parallel()
	m := New()
	ch := make(chan []string, 1)

	m.NotFound(func(c C, w http.ResponseWriter, r *http.Request) {
		if c.Env == nil {
			ch <- []string{}
			return
		}
		methods, ok := c.Env[ValidMethodsKey]
		if !ok {
			ch <- []string{}
			return
		}
		ch <- methods.([]string)
	})

	m.Get("/hello/carl", http.NotFound)
	m.Post("/hello/carl", http.NotFound)
	m.Head("/hello/bob", http.NotFound)
	m.Get("/hello/:name", http.NotFound)
	m.Put("/hello/:name", http.NotFound)
	m.Patch("/hello/:name", http.NotFound)
	m.Get("/:greet/carl", http.NotFound)
	m.Put("/:greet/carl", http.NotFound)
	m.Delete("/:greet/:anyone", http.NotFound)

	for path, eMethods := range validMethodsTable {
		r, _ := http.NewRequest("BOGUS", path, nil)
		m.ServeHTTP(httptest.NewRecorder(), r)
		aMethods := <-ch
		if !reflect.DeepEqual(eMethods, aMethods) {
			t.Errorf("For %q, expected %v, got %v", path, eMethods,
				aMethods)
		}
	}
}
<commit_msg>Improve test coverage slightly<commit_after>package web

import (
	"net/http"
	"net/http/httptest"
	"reflect"
	"regexp"
	"testing"
	"time"
)

// These tests can probably be DRY'd up a bunch

func chHandler(ch chan string, s string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ch <- s
	})
}

var methods = []string{"CONNECT", "DELETE", "GET", "HEAD", "OPTIONS", "PATCH",
	"POST", "PUT", "TRACE", "OTHER"}

func TestMethods(t *testing.T) {
	t.Parallel()
	m := New()
	ch := make(chan string, 1)

	m.Connect("/", chHandler(ch, "CONNECT"))
	m.Delete("/", chHandler(ch, "DELETE"))
	m.Head("/", chHandler(ch, "HEAD"))
	m.Get("/", chHandler(ch, "GET"))
	m.Options("/", chHandler(ch, "OPTIONS"))
	m.Patch("/", chHandler(ch, "PATCH"))
	m.Post("/", chHandler(ch, "POST"))
	m.Put("/", chHandler(ch, "PUT"))
	m.Trace("/", chHandler(ch, "TRACE"))
	m.Handle("/", chHandler(ch, "OTHER"))

	for _, method := range methods {
		r, _ := http.NewRequest(method, "/", nil)
		w := httptest.NewRecorder()
		m.ServeHTTP(w, r)
		select {
		case val := <-ch:
			if val != method {
				t.Errorf("Got %q, expected %q", val, method)
			}
		case <-time.After(5 * time.Millisecond):
			t.Errorf("Timeout waiting for method %q", method)
		}
	}
}

type testPattern struct{}

func (t testPattern) Prefix() string {
	return ""
}

func (t testPattern) Match(r *http.Request, c *C) bool {
	return true
}
func (t testPattern) Run(r *http.Request, c *C) {
}

var _ Pattern = testPattern{}

func TestPatternTypes(t *testing.T) {
	t.Parallel()
	m := New()

	m.Get("/hello/carl", http.NotFound)
	m.Get("/hello/:name", http.NotFound)
	m.Get(regexp.MustCompile(`^/hello/(?P<name>.+)$`), http.NotFound)
	m.Get(testPattern{}, http.NotFound)
}

type testHandler chan string

func (t testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	t <- "http"
}
func (t testHandler) ServeHTTPC(c C, w http.ResponseWriter, r *http.Request) {
	t <- "httpc"
}

var testHandlerTable = map[string]string{
	"/a": "http fn",
	"/b": "http handler",
	"/c": "web fn",
	"/d": "web handler",
	"/e": "httpc",
}

func TestHandlerTypes(t *testing.T) {
	t.Parallel()
	m := New()
	ch := make(chan string, 1)

	m.Get("/a", func(w http.ResponseWriter, r *http.Request) {
		ch <- "http fn"
	})
	m.Get("/b", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ch <- "http handler"
	}))
	m.Get("/c", func(c C, w http.ResponseWriter, r *http.Request) {
		ch <- "web fn"
	})
	m.Get("/d", HandlerFunc(func(c C, w http.ResponseWriter, r *http.Request) {
		ch <- "web handler"
	}))
	m.Get("/e", testHandler(ch))

	for route, response := range testHandlerTable {
		r, _ := http.NewRequest("GET", route, nil)
		w := httptest.NewRecorder()
		m.ServeHTTP(w, r)
		select {
		case resp := <-ch:
			if resp != response {
				t.Errorf("Got %q, expected %q", resp, response)
			}
		case <-time.After(5 * time.Millisecond):
			t.Errorf("Timeout waiting for path %q", route)
		}

	}
}

// The idea behind this test is to comprehensively test if routes are being
// applied in the right order. We define a special pattern type that always
// matches so long as it's greater than or equal to the global test index. By
// incrementing this index, we can invalidate all routes up to some point, and
// therefore test the routing guarantee that Goji provides: for any path P, if
// both A and B match P, and if A was inserted before B, then Goji will route to
// A before it routes to B.
var rsRoutes = []string{
	"/",
	"/a",
	"/a",
	"/b",
	"/ab",
	"/",
	"/ba",
	"/b",
	"/a",
}

var rsTests = []struct {
	key     string
	results []int
}{
	{"/", []int{0, 5, 5, 5, 5, 5, -1, -1, -1, -1}},
	{"/a", []int{0, 1, 2, 5, 5, 5, 8, 8, 8, -1}},
	{"/b", []int{0, 3, 3, 3, 5, 5, 7, 7, -1, -1}},
	{"/ab", []int{0, 1, 2, 4, 4, 5, 8, 8, 8, -1}},
	{"/ba", []int{0, 3, 3, 3, 5, 5, 6, 7, -1, -1}},
	{"/c", []int{0, 5, 5, 5, 5, 5, -1, -1, -1, -1}},
	{"nope", []int{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}},
}

type rsPattern struct {
	i       int
	counter *int
	prefix  string
	ichan   chan int
}

func (rs rsPattern) Prefix() string {
	return rs.prefix
}
func (rs rsPattern) Match(_ *http.Request, _ *C) bool {
	return rs.i >= *rs.counter
}
func (rs rsPattern) Run(_ *http.Request, _ *C) {
}

func (rs rsPattern) ServeHTTP(_ http.ResponseWriter, _ *http.Request) {
	rs.ichan <- rs.i
}

var _ Pattern = rsPattern{}
var _ http.Handler = rsPattern{}

func TestRouteSelection(t *testing.T) {
	t.Parallel()
	m := New()
	counter := 0
	ichan := make(chan int, 1)
	m.NotFound(func(w http.ResponseWriter, r *http.Request) {
		ichan <- -1
	})

	for i, s := range rsRoutes {
		pat := rsPattern{
			i:       i,
			counter: &counter,
			prefix:  s,
			ichan:   ichan,
		}
		m.Get(pat, pat)
	}

	for _, test := range rsTests {
		var n int
		for counter, n = range test.results {
			r, _ := http.NewRequest("GET", test.key, nil)
			w := httptest.NewRecorder()
			m.ServeHTTP(w, r)
			actual := <-ichan
			if n != actual {
				t.Errorf("Expected %q @ %d to be %d, got %d",
					test.key, counter, n, actual)
			}
		}
	}
}

func TestNotFound(t *testing.T) {
	t.Parallel()
	m := New()

	r, _ := http.NewRequest("post", "/", nil)
	w := httptest.NewRecorder()
	m.ServeHTTP(w, r)
	if w.Code != 404 {
		t.Errorf("Expected 404, got %d", w.Code)
	}

	m.NotFound(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, "I'm a teapot!", http.StatusTeapot)
	})

	r, _ = http.NewRequest("POST", "/", nil)
	w = httptest.NewRecorder()
	m.ServeHTTP(w, r)
	if w.Code != http.StatusTeapot {
		t.Errorf("Expected a teapot, got %d", w.Code)
	}
}

func TestPrefix(t *testing.T) {
	t.Parallel()
	m := New()
	ch := make(chan string, 1)

	m.Handle("/hello/*", func(w http.ResponseWriter, r *http.Request) {
		ch <- r.URL.Path
	})

	r, _ := http.NewRequest("GET", "/hello/world", nil)
	w := httptest.NewRecorder()
	m.ServeHTTP(w, r)
	select {
	case val := <-ch:
		if val != "/hello/world" {
			t.Errorf("Got %q, expected /hello/world", val)
		}
	case <-time.After(5 * time.Millisecond):
		t.Errorf("Timeout waiting for hello")
	}
}

var validMethodsTable = map[string][]string{
	"/hello/carl":       {"DELETE", "GET", "HEAD", "PATCH", "POST", "PUT"},
	"/hello/bob":        {"DELETE", "GET", "HEAD", "PATCH", "PUT"},
	"/hola/carl":        {"DELETE", "GET", "HEAD", "PUT"},
	"/hola/bob":         {"DELETE"},
	"/does/not/compute": {},
}

func TestValidMethods(t *testing.T) {
	t.Parallel()
	m := New()
	ch := make(chan []string, 1)

	m.NotFound(func(c C, w http.ResponseWriter, r *http.Request) {
		if c.Env == nil {
			ch <- []string{}
			return
		}
		methods, ok := c.Env[ValidMethodsKey]
		if !ok {
			ch <- []string{}
			return
		}
		ch <- methods.([]string)
	})

	m.Get("/hello/carl", http.NotFound)
	m.Post("/hello/carl", http.NotFound)
	m.Head("/hello/bob", http.NotFound)
	m.Get("/hello/:name", http.NotFound)
	m.Put("/hello/:name", http.NotFound)
	m.Patch("/hello/:name", http.NotFound)
	m.Get("/:greet/carl", http.NotFound)
	m.Put("/:greet/carl", http.NotFound)
	m.Delete("/:greet/:anyone", http.NotFound)

	for path, eMethods := range validMethodsTable {
		r, _ := http.NewRequest("BOGUS", path, nil)
		m.ServeHTTP(httptest.NewRecorder(), r)
		aMethods := <-ch
		if !reflect.DeepEqual(eMethods, aMethods) {
			t.Errorf("For %q, expected %v, got %v", path, eMethods,
				aMethods)
		}
	}

	// This should also work when c.Env has already been initalized
	m.Use(func(c *C, h http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			c.Env = make(map[string]interface{})
			h.ServeHTTP(w, r)
		})
	})
	for path, eMethods := range validMethodsTable {
		r, _ := http.NewRequest("BOGUS", path, nil)
		m.ServeHTTP(httptest.NewRecorder(), r)
		aMethods := <-ch
		if !reflect.DeepEqual(eMethods, aMethods) {
			t.Errorf("For %q, expected %v, got %v", path, eMethods,
				aMethods)
		}
	}
}
<|endoftext|>


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

package main

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
)

var cmdRun = &Command{
	UsageLine: "run [build flags] gofiles... [arguments...]",
	Short:     "compile and run Go program",
	Long: `
Run compiles and runs the main package comprising the named Go source files.

For more about build flags, see 'go help build'.

See also: go build.
	`,
}

func init() {
	cmdRun.Run = runRun // break init loop

	addBuildFlags(cmdRun)
}

func printStderr(args ...interface{}) (int, error) {
	return fmt.Fprint(os.Stderr, args...)
}

func runRun(cmd *Command, args []string) {
	var b builder
	b.init()
	b.print = printStderr
	i := 0
	for i < len(args) && strings.HasSuffix(args[i], ".go") {
		i++
	}
	files, cmdArgs := args[:i], args[i:]
	if len(files) == 0 {
		fatalf("go run: no go files listed")
	}
	p := goFilesPackage(files)
	if p.Error != nil {
		fatalf("%s", p.Error)
	}
	if p.Name != "main" {
		fatalf("go run: cannot run non-main package")
	}
	p.target = "" // must build - not up to date
	a1 := b.action(modeBuild, modeBuild, p)
	a := &action{f: (*builder).runProgram, args: cmdArgs, deps: []*action{a1}}
	b.do(a)
}

// runProgram is the action for running a binary that has already
// been compiled.  We ignore exit status.
func (b *builder) runProgram(a *action) error {
	if buildN || buildX {
		b.showcmd("", "%s %s", a.deps[0].target, strings.Join(a.args, " "))
		if buildN {
			return nil
		}
	}

	runStdin(a.deps[0].target, a.args)
	return nil
}

// runStdin is like run, but connects Stdin.
func runStdin(cmdargs ...interface{}) {
	cmdline := stringList(cmdargs...)
	cmd := exec.Command(cmdline[0], cmdline[1:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		errorf("%v", err)
	}
}
<commit_msg>cmd/go: do not ignore DepsErrors in 'go run'<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
)

var cmdRun = &Command{
	UsageLine: "run [build flags] gofiles... [arguments...]",
	Short:     "compile and run Go program",
	Long: `
Run compiles and runs the main package comprising the named Go source files.

For more about build flags, see 'go help build'.

See also: go build.
	`,
}

func init() {
	cmdRun.Run = runRun // break init loop

	addBuildFlags(cmdRun)
}

func printStderr(args ...interface{}) (int, error) {
	return fmt.Fprint(os.Stderr, args...)
}

func runRun(cmd *Command, args []string) {
	var b builder
	b.init()
	b.print = printStderr
	i := 0
	for i < len(args) && strings.HasSuffix(args[i], ".go") {
		i++
	}
	files, cmdArgs := args[:i], args[i:]
	if len(files) == 0 {
		fatalf("go run: no go files listed")
	}
	p := goFilesPackage(files)
	if p.Error != nil {
		fatalf("%s", p.Error)
	}
	for _, err := range p.DepsErrors {
		errorf("%s", err)
	}
	exitIfErrors()
	if p.Name != "main" {
		fatalf("go run: cannot run non-main package")
	}
	p.target = "" // must build - not up to date
	a1 := b.action(modeBuild, modeBuild, p)
	a := &action{f: (*builder).runProgram, args: cmdArgs, deps: []*action{a1}}
	b.do(a)
}

// runProgram is the action for running a binary that has already
// been compiled.  We ignore exit status.
func (b *builder) runProgram(a *action) error {
	if buildN || buildX {
		b.showcmd("", "%s %s", a.deps[0].target, strings.Join(a.args, " "))
		if buildN {
			return nil
		}
	}

	runStdin(a.deps[0].target, a.args)
	return nil
}

// runStdin is like run, but connects Stdin.
func runStdin(cmdargs ...interface{}) {
	cmdline := stringList(cmdargs...)
	cmd := exec.Command(cmdline[0], cmdline[1:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		errorf("%v", err)
	}
}
<|endoftext|>


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

package main

func init() {
	addBuildFlagsNX(cmdVet)
}

var cmdVet = &Command{
	Run:       runVet,
	UsageLine: "vet [-n] [-x] [packages]",
	Short:     "run go tool vet on packages",
	Long: `
Vet runs the Go vet command on the packages named by the import paths.

For more about vet, see 'godoc vet'.
For more about specifying packages, see 'go help packages'.

To run the vet tool with specific options, run 'go tool vet'.

The -n flag prints commands that would be executed.
The -x flag prints commands as they are executed.

See also: go fmt, go fix.
	`,
}

func runVet(cmd *Command, args []string) {
	for _, pkg := range packages(args) {
		// Use pkg.gofiles instead of pkg.Dir so that
		// the command only applies to this package,
		// not to packages in subdirectories.
		run(tool("vet"), relPaths(stringList(pkg.allgofiles, pkg.IgnoredGoFiles)))
	}
}
<commit_msg>cmd/go: fix vet<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

func init() {
	addBuildFlagsNX(cmdVet)
}

var cmdVet = &Command{
	Run:       runVet,
	UsageLine: "vet [-n] [-x] [packages]",
	Short:     "run go tool vet on packages",
	Long: `
Vet runs the Go vet command on the packages named by the import paths.

For more about vet, see 'godoc vet'.
For more about specifying packages, see 'go help packages'.

To run the vet tool with specific options, run 'go tool vet'.

The -n flag prints commands that would be executed.
The -x flag prints commands as they are executed.

See also: go fmt, go fix.
	`,
}

func runVet(cmd *Command, args []string) {
	for _, pkg := range packages(args) {
		// Use pkg.gofiles instead of pkg.Dir so that
		// the command only applies to this package,
		// not to packages in subdirectories.
		run(tool("vet"), relPaths(pkg.allgofiles))
	}
}
<|endoftext|>


<commit_before>package dalga

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/streadway/amqp"
)

const createTableSQL = "" +
	"CREATE TABLE `%s` (" +
	"  `routing_key` VARCHAR(255)    NOT NULL," +
	"  `body`        BLOB(767)       NOT NULL," + // 767 is the max index size
	"  `interval`    INT UNSIGNED    NOT NULL," + // 32-bit
	"  `next_run`    DATETIME        NOT NULL," +
	"" +
	"  PRIMARY KEY (`routing_key`, `body`(767))," +
	"  KEY `idx_next_run` (`next_run`)" +
	") ENGINE=InnoDB DEFAULT CHARSET=utf8"

var debugging = flag.Bool("d", false, "turn on debug messages")

func debug(args ...interface{}) {
	if *debugging || os.Getenv("DALGA_DEBUG") != "" {
		log.Println(args...)
	}
}

type Dalga struct {
	C                 *Config
	db                *sql.DB
	rabbit            *amqp.Connection
	channel           *amqp.Channel
	listener          net.Listener
	newJobs           chan *Job
	canceledJobs      chan *Job
	quitPublisher     chan bool
	publisherFinished chan bool
}

func NewDalga(config *Config) *Dalga {
	return &Dalga{
		C:                 config,
		newJobs:           make(chan *Job),
		canceledJobs:      make(chan *Job),
		quitPublisher:     make(chan bool),
		publisherFinished: make(chan bool),
	}
}

// Start starts the publisher and http server goroutines.
func (d *Dalga) Start() error {
	err := d.connectDB()
	if err != nil {
		return err
	}

	err = d.connectMQ()
	if err != nil {
		return err
	}

	server, err := d.makeServer()
	if err != nil {
		return err
	}

	go d.publisher()
	go server()

	return nil
}

// Run starts the dalga and waits until Shutdown() is called.
func (d *Dalga) Run() error {
	err := d.Start()
	if err != nil {
		return err
	}

	debug("Waiting a message from publisherFinished channel")
	<-d.publisherFinished
	debug("Received message from publisherFinished channel")

	return nil
}

func (d *Dalga) Shutdown() error {
	return d.listener.Close()
}

func (d *Dalga) connectDB() error {
	var err error
	d.db, err = d.newMySQLConnection()
	return err
}

func (d *Dalga) newMySQLConnection() (*sql.DB, error) {
	my := d.C.MySQL
	dsn := my.User + ":" + my.Password + "@" + "tcp(" + my.Host + ":" + my.Port + ")/" + my.Db + "?parseTime=true"

	db, err := sql.Open("mysql", dsn)
	if err != nil {
		return nil, err
	}

	err = db.Ping()
	if err != nil {
		return nil, err
	}

	log.Println("Connected to MySQL")
	return db, nil
}

func (d *Dalga) connectMQ() error {
	var err error
	rabbit := d.C.RabbitMQ
	uri := "amqp://" + rabbit.User + ":" + rabbit.Password + "@" + rabbit.Host + ":" + rabbit.Port + rabbit.VHost

	d.rabbit, err = amqp.Dial(uri)
	if err != nil {
		return err
	}

	d.channel, err = d.rabbit.Channel()
	log.Println("Connected to RabbitMQ")
	return err
}

func (d *Dalga) CreateTable() error {
	db, err := d.newMySQLConnection()
	if err != nil {
		return err
	}
	defer db.Close()

	sql := fmt.Sprintf(createTableSQL, d.C.MySQL.Table)
	_, err = db.Exec(sql)
	if err != nil {
		return err
	}

	return nil
}

func (d *Dalga) Schedule(routingKey string, body []byte, interval uint32) error {
	job := NewJob(routingKey, body, interval)

	err := d.insert(job)
	if err != nil {
		return err
	}

	// Wake up the publisher.
	//
	// publisher() may be sleeping for the next job on the queue
	// at the time we schedule a new Job. Let it wake up so it can
	// re-fetch the new Job from the front of the queue.
	//
	// The code below is an idiom for non-blocking send to a channel.
	select {
	case d.newJobs <- job:
		debug("Sent new job signal")
	default:
		debug("Did not send new job signal")
	}

	debug("Job is scheduled:", job)
	return nil
}

func (d *Dalga) Cancel(routingKey string, body []byte) error {
	err := d.delete(routingKey, body)
	if err != nil {
		return err
	}

	select {
	case d.canceledJobs <- &Job{RoutingKey: routingKey, Body: body}:
		debug("Sent cancel signal")
	default:
		debug("Did not send cancel signal")
	}

	debug("Job is cancelled:", job)
	return nil
}

// front returns the first job to be run in the queue.
func (d *Dalga) front() (*Job, error) {
	var interval uint32
	var j Job

	row := d.db.QueryRow("SELECT routing_key, body, `interval`, next_run " +
		"FROM " + d.C.MySQL.Table + " " +
		"ORDER BY next_run ASC LIMIT 1")

	err := row.Scan(&j.RoutingKey, &j.Body, &interval, &j.NextRun)
	if err != nil {
		return nil, err
	}

	j.Interval = time.Duration(interval) * time.Second
	return &j, nil
}

// publish sends a message to exchange defined in the config and
// updates the Job's next run time on the database.
func (d *Dalga) publish(j *Job) error {
	debug("publish", *j)

	// Update next run time
	_, err := d.db.Exec("UPDATE "+d.C.MySQL.Table+" "+
		"SET next_run=? "+
		"WHERE routing_key=? AND body=?",
		time.Now().UTC().Add(j.Interval), j.RoutingKey, j.Body)
	if err != nil {
		return err
	}

	// Send a message to RabbitMQ
	pub := func() error {
		return d.channel.Publish(d.C.RabbitMQ.Exchange, j.RoutingKey, false, false, amqp.Publishing{
			Headers: amqp.Table{
				"interval":     j.Interval.Seconds(),
				"published_at": time.Now().UTC().String(),
			},
			ContentType:  "application/octet-stream",
			Body:         j.Body,
			DeliveryMode: amqp.Persistent,
			Priority:     0,
			Expiration:   strconv.FormatUint(uint64(j.Interval.Seconds()), 10) + "000",
		})
	}

	err = pub()
	if err != nil {
		if strings.Contains(err.Error(), "channel/connection is not open") {
			// Retry again
			err = d.connectMQ()
			if err != nil {
				return err
			}
			pub()
		}
	}

	return nil
}

// insert puts the job to the waiting queue.
func (d *Dalga) insert(j *Job) error {
	interval := j.Interval.Seconds()
	_, err := d.db.Exec("INSERT INTO "+d.C.MySQL.Table+" "+
		"(routing_key, body, `interval`, next_run) "+
		"VALUES(?, ?, ?, ?) "+
		"ON DUPLICATE KEY UPDATE "+
		"next_run=DATE_ADD(next_run, INTERVAL (? - `interval`) SECOND), "+
		"`interval`=?",
		j.RoutingKey, j.Body, interval, j.NextRun, interval, interval)
	return err
}

// delete removes the job from the waiting queue.
func (d *Dalga) delete(routingKey string, body []byte) error {
	_, err := d.db.Exec("DELETE FROM "+d.C.MySQL.Table+" "+
		"WHERE routing_key=? AND body=?", routingKey, body)
	return err
}

// publisher runs a loop that reads the next Job from the queue and publishes it.
func (d *Dalga) publisher() {
	publish := func(j *Job) {
		err := d.publish(j)
		if err != nil {
			log.Println(err)
			time.Sleep(time.Duration(1) * time.Second)
		}
	}

	for {
		debug("---")

		select {
		case <-d.quitPublisher:
			debug("Came message from channel 1: quitPublisher")
			goto end
		default:
		}

		job, err := d.front()
		if err != nil {
			if strings.Contains(err.Error(), "no rows in result set") {
				debug("No waiting jobs in the queue")
				debug("Waiting wakeup signal")
				select {
				case job = <-d.newJobs:
				case <-d.quitPublisher:
					debug("Came message from channel 2: quitPublisher")
					goto end
				}

				debug("Got wakeup signal")
			} else {
				log.Println(err)
				time.Sleep(time.Duration(1) * time.Second)
				continue
			}
		}

	CheckNextRun:
		remaining := job.Remaining()
		debug("Next job:", job, "Remaining:", remaining)

		now := time.Now().UTC()
		if job.NextRun.After(now) {
			// Wait until the next Job time or
			// the webserver's /schedule handler wakes us up
			debug("Sleeping for job:", remaining)
			select {
			case <-time.After(remaining):
				debug("Job sleep time finished")
				publish(job)
			case newJob := <-d.newJobs:
				debug("A new job has been scheduled")
				if newJob.NextRun.Before(job.NextRun) {
					debug("The new job comes before out current job")
					job = newJob // Process the new job next
				}
				// Continue processing the current job without fetching from database
				goto CheckNextRun
			case canceledJob := <-d.canceledJobs:
				debug("A job has been cancelled")
				if job.Equals(canceledJob) {
					// The job we are waiting for has been canceled.
					// We need to fetch the next job in the queue.
					debug("The cancelled job is our current job")
					continue
				}
				// Continue to process our current job
				goto CheckNextRun
			case <-d.quitPublisher:
				debug("Came message from channel 3: quitPublisher")
				goto end
			}
		} else {
			publish(job)
		}
	}
end:
	d.publisherFinished <- true
}
<commit_msg>debug<commit_after>package dalga

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/streadway/amqp"
)

const createTableSQL = "" +
	"CREATE TABLE `%s` (" +
	"  `routing_key` VARCHAR(255)    NOT NULL," +
	"  `body`        BLOB(767)       NOT NULL," + // 767 is the max index size
	"  `interval`    INT UNSIGNED    NOT NULL," + // 32-bit
	"  `next_run`    DATETIME        NOT NULL," +
	"" +
	"  PRIMARY KEY (`routing_key`, `body`(767))," +
	"  KEY `idx_next_run` (`next_run`)" +
	") ENGINE=InnoDB DEFAULT CHARSET=utf8"

var debugging = flag.Bool("d", false, "turn on debug messages")

func debug(args ...interface{}) {
	if *debugging || os.Getenv("DALGA_DEBUG") != "" {
		log.Println(args...)
	}
}

type Dalga struct {
	C                 *Config
	db                *sql.DB
	rabbit            *amqp.Connection
	channel           *amqp.Channel
	listener          net.Listener
	newJobs           chan *Job
	canceledJobs      chan *Job
	quitPublisher     chan bool
	publisherFinished chan bool
}

func NewDalga(config *Config) *Dalga {
	return &Dalga{
		C:                 config,
		newJobs:           make(chan *Job),
		canceledJobs:      make(chan *Job),
		quitPublisher:     make(chan bool),
		publisherFinished: make(chan bool),
	}
}

// Start starts the publisher and http server goroutines.
func (d *Dalga) Start() error {
	err := d.connectDB()
	if err != nil {
		return err
	}

	err = d.connectMQ()
	if err != nil {
		return err
	}

	server, err := d.makeServer()
	if err != nil {
		return err
	}

	go d.publisher()
	go server()

	return nil
}

// Run starts the dalga and waits until Shutdown() is called.
func (d *Dalga) Run() error {
	err := d.Start()
	if err != nil {
		return err
	}

	debug("Waiting a message from publisherFinished channel")
	<-d.publisherFinished
	debug("Received message from publisherFinished channel")

	return nil
}

func (d *Dalga) Shutdown() error {
	return d.listener.Close()
}

func (d *Dalga) connectDB() error {
	var err error
	d.db, err = d.newMySQLConnection()
	return err
}

func (d *Dalga) newMySQLConnection() (*sql.DB, error) {
	my := d.C.MySQL
	dsn := my.User + ":" + my.Password + "@" + "tcp(" + my.Host + ":" + my.Port + ")/" + my.Db + "?parseTime=true"

	db, err := sql.Open("mysql", dsn)
	if err != nil {
		return nil, err
	}

	err = db.Ping()
	if err != nil {
		return nil, err
	}

	log.Println("Connected to MySQL")
	return db, nil
}

func (d *Dalga) connectMQ() error {
	var err error
	rabbit := d.C.RabbitMQ
	uri := "amqp://" + rabbit.User + ":" + rabbit.Password + "@" + rabbit.Host + ":" + rabbit.Port + rabbit.VHost

	d.rabbit, err = amqp.Dial(uri)
	if err != nil {
		return err
	}

	d.channel, err = d.rabbit.Channel()
	log.Println("Connected to RabbitMQ")
	return err
}

func (d *Dalga) CreateTable() error {
	db, err := d.newMySQLConnection()
	if err != nil {
		return err
	}
	defer db.Close()

	sql := fmt.Sprintf(createTableSQL, d.C.MySQL.Table)
	_, err = db.Exec(sql)
	if err != nil {
		return err
	}

	return nil
}

func (d *Dalga) Schedule(routingKey string, body []byte, interval uint32) error {
	job := NewJob(routingKey, body, interval)

	err := d.insert(job)
	if err != nil {
		return err
	}

	// Wake up the publisher.
	//
	// publisher() may be sleeping for the next job on the queue
	// at the time we schedule a new Job. Let it wake up so it can
	// re-fetch the new Job from the front of the queue.
	//
	// The code below is an idiom for non-blocking send to a channel.
	select {
	case d.newJobs <- job:
		debug("Sent new job signal")
	default:
		debug("Did not send new job signal")
	}

	debug("Job is scheduled:", job)
	return nil
}

func (d *Dalga) Cancel(routingKey string, body []byte) error {
	err := d.delete(routingKey, body)
	if err != nil {
		return err
	}

	select {
	case d.canceledJobs <- &Job{RoutingKey: routingKey, Body: body}:
		debug("Sent cancel signal")
	default:
		debug("Did not send cancel signal")
	}

	debug("Job is cancelled:", job)
	return nil
}

// front returns the first job to be run in the queue.
func (d *Dalga) front() (*Job, error) {
	var interval uint32
	var j Job

	row := d.db.QueryRow("SELECT routing_key, body, `interval`, next_run " +
		"FROM " + d.C.MySQL.Table + " " +
		"ORDER BY next_run ASC LIMIT 1")

	err := row.Scan(&j.RoutingKey, &j.Body, &interval, &j.NextRun)
	if err != nil {
		return nil, err
	}

	j.Interval = time.Duration(interval) * time.Second
	return &j, nil
}

// publish sends a message to exchange defined in the config and
// updates the Job's next run time on the database.
func (d *Dalga) publish(j *Job) error {
	debug("publish", *j)

	// Update next run time
	_, err := d.db.Exec("UPDATE "+d.C.MySQL.Table+" "+
		"SET next_run=? "+
		"WHERE routing_key=? AND body=?",
		time.Now().UTC().Add(j.Interval), j.RoutingKey, j.Body)
	if err != nil {
		return err
	}

	// Send a message to RabbitMQ
	pub := func() error {
		return d.channel.Publish(d.C.RabbitMQ.Exchange, j.RoutingKey, false, false, amqp.Publishing{
			Headers: amqp.Table{
				"interval":     j.Interval.Seconds(),
				"published_at": time.Now().UTC().String(),
			},
			ContentType:  "application/octet-stream",
			Body:         j.Body,
			DeliveryMode: amqp.Persistent,
			Priority:     0,
			Expiration:   strconv.FormatUint(uint64(j.Interval.Seconds()), 10) + "000",
		})
	}

	err = pub()
	if err != nil {
		if strings.Contains(err.Error(), "channel/connection is not open") {
			// Retry again
			err = d.connectMQ()
			if err != nil {
				return err
			}
			pub()
		}
	}

	return nil
}

// insert puts the job to the waiting queue.
func (d *Dalga) insert(j *Job) error {
	interval := j.Interval.Seconds()
	_, err := d.db.Exec("INSERT INTO "+d.C.MySQL.Table+" "+
		"(routing_key, body, `interval`, next_run) "+
		"VALUES(?, ?, ?, ?) "+
		"ON DUPLICATE KEY UPDATE "+
		"next_run=DATE_ADD(next_run, INTERVAL (? - `interval`) SECOND), "+
		"`interval`=?",
		j.RoutingKey, j.Body, interval, j.NextRun, interval, interval)
	return err
}

// delete removes the job from the waiting queue.
func (d *Dalga) delete(routingKey string, body []byte) error {
	_, err := d.db.Exec("DELETE FROM "+d.C.MySQL.Table+" "+
		"WHERE routing_key=? AND body=?", routingKey, body)
	return err
}

// publisher runs a loop that reads the next Job from the queue and publishes it.
func (d *Dalga) publisher() {
	publish := func(j *Job) {
		err := d.publish(j)
		if err != nil {
			log.Println(err)
			time.Sleep(time.Duration(1) * time.Second)
		}
	}

	for {
		debug("---")

		select {
		case <-d.quitPublisher:
			debug("Came message from channel 1: quitPublisher")
			goto end
		default:
		}

		job, err := d.front()
		if err != nil {
			if strings.Contains(err.Error(), "no rows in result set") {
				debug("No waiting jobs in the queue")
				debug("Waiting wakeup signal")
				select {
				case job = <-d.newJobs:
				case <-d.quitPublisher:
					debug("Came message from channel 2: quitPublisher")
					goto end
				}

				debug("Got wakeup signal")
			} else {
				log.Println(err)
				time.Sleep(time.Duration(1) * time.Second)
				continue
			}
		}

	CheckNextRun:
		remaining := job.Remaining()
		debug("Next job:", job, "Remaining:", remaining)

		now := time.Now().UTC()
		if job.NextRun.After(now) {
			// Wait until the next Job time or
			// the webserver's /schedule handler wakes us up
			debug("Sleeping for job:", remaining)
			select {
			case <-time.After(remaining):
				debug("Job sleep time finished")
				publish(job)
			case newJob := <-d.newJobs:
				debug("A new job has been scheduled")
				if newJob.NextRun.Before(job.NextRun) {
					debug("The new job comes before out current job")
					job = newJob // Process the new job next
				}
				// Continue processing the current job without fetching from database
				goto CheckNextRun
			case canceledJob := <-d.canceledJobs:
				debug("A job has been cancelled")
				if job.Equals(canceledJob) {
					// The job we are waiting for has been canceled.
					// We need to fetch the next job in the queue.
					debug("The cancelled job is our current job")
					continue
				}
				// Continue to process our current job
				goto CheckNextRun
			case <-d.quitPublisher:
				debug("Message received from quitPublisher channel")
				goto end
			}
		} else {
			publish(job)
		}
	}
end:
	d.publisherFinished <- true
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"
)

func main() {
	dashr_fs := http.FileServer(http.Dir("www-data"))
	http.Handle("/www-data/", http.StripPrefix("/www-data/", dashr_fs))

	ansible_fs := http.FileServer(http.Dir("dummy-ansible-files"))
	http.Handle("/dummy-ansible-files/", http.StripPrefix("/dummy-ansible-files/", ansible_fs))

	log.Println("Ansible Dashr @ localhost:8001")
	http.ListenAndServe(":8001", nil)
}
<commit_msg>dashr-go updated to use flags for paths and ports<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
)

func main() {
	dashr_ip := flag.String("fqdn", "127.0.0.1", "IP/FQDN to run HTTP listener at")
	dashr_port := flag.String("http", "8001", "port to run HTTP listener at")
	connection_string := fmt.Sprintf("%s:%s", *dashr_ip, *dashr_port)

	www_data := flag.String("www", "www-data", "path to ansible dashr static site content")
	www_data_uri := fmt.Sprintf("/%s/", *www_data)

	ansible_setup := flag.String("ansible", "dummy-ansible-files", "path to ansible setup root of Playbooks, Roles Dir")
	ansible_setup_uri := fmt.Sprintf("/%s/", *ansible_setup)

	dashr_config := flag.String("config", "config", "path to fetch/save Config used by Static Site Content")
	dashr_config_uri := fmt.Sprintf("/%s/", *dashr_config)

	dashr_fs := http.FileServer(http.Dir(*www_data))
	http.Handle(www_data_uri, http.StripPrefix(www_data_uri, dashr_fs))

	ansible_fs := http.FileServer(http.Dir(*ansible_setup))
	http.Handle(ansible_setup_uri, http.StripPrefix(ansible_setup_uri, ansible_fs))

	config_fs := http.FileServer(http.Dir(*dashr_config))
	http.Handle(dashr_config_uri, http.StripPrefix(dashr_config_uri, config_fs))

	log.Println("Ansible Dashr @", connection_string)
	http.ListenAndServe(connection_string, nil)
}
<|endoftext|>