<commit_before>package npm

import (
	"fmt"
	"net/url"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/ssut/pocketnpm/db"
	"github.com/ssut/pocketnpm/log"
	pbar "gopkg.in/cheggaaa/pb.v1"
)

type MirrorClient struct {
	db        *db.PocketBase
	config    *MirrorConfig
	npmClient *NPMClient
}

// NewMirrorClient creates an instance of MirrorClient
func NewMirrorClient(db *db.PocketBase, config *MirrorConfig) *MirrorClient {
	// Fix relative path
	config.Path, _ = filepath.Abs(config.Path)
	// Check for directory exists or not
	// If not, try to create an empty directory for it
	if _, err := os.Stat(config.Path); os.IsNotExist(err) {
		log.Debugf("Directory does not exist: %s", config.Path)
		err = os.MkdirAll(config.Path, 0755)
		if err != nil {
			log.Fatalf("Failed to create directory: %s", config.Path)
		} else {
			log.Debugf("Directory has been created: %s", config.Path)
		}
	}

	npmClient := NewNPMClient(config.Registry, config.Path)
	client := &MirrorClient{
		config:    config,
		db:        db,
		npmClient: npmClient,
	}

	return client
}

func (c *MirrorClient) initDocument(allDocs *AllDocsResponse) {
	packages := make([]*db.BarePackage, allDocs.TotalRows)

	for i, doc := range allDocs.Rows {
		packages[i] = &db.BarePackage{
			ID:       doc.ID,
			Revision: doc.Value.Revision,
		}
	}

	log.Debug("Putting packages..")
	c.db.PutPackages(packages)
	c.db.SetSequence(allDocs.Sequence)
	log.Debug("Succeed")
}

func (c *MirrorClient) FirstRun() {
	allDocs := c.npmClient.GetAllDocs()
	log.Infof("Total documents found: %d", allDocs.TotalRows)

	log.Debug("Store all documents by given properties")
	c.initDocument(allDocs)
}

func (c *MirrorClient) Start() {
	// Load all packages with its revision
	packages := c.db.GetIncompletePackages()

	log.Debugf("Packages to queue: %d", len(packages))

	// Array of workers
	var workers = make([]*MirrorWorker, c.config.MaxConnections)
	// Initialize channels
	// workQueue has a buffer size of 100
	var workQueue = make(chan *db.BarePackage, 100)
	var workerQueue = make(chan chan *db.BarePackage, c.config.MaxConnections)
	var resultQueue = make(chan *MirrorWorkResult)
	// WaitGroup
	var wg sync.WaitGroup

	// Create mirror workers
	log.Debugf("Starting %d workers", c.config.MaxConnections)
	for i := 0; i < c.config.MaxConnections; i++ {
		workers[i] = NewMirrorWorker(i, c.npmClient, workerQueue, resultQueue, &wg)
		workers[i].Start()
	}

	// Result handler
	go func(db *db.PocketBase, wg *sync.WaitGroup) {
		for {
			result, done := <-resultQueue
			if !done {
				return
			}

			if result.Deleted {
				path := getLocalPath(c.config.Path, result.Package.ID)
				os.RemoveAll(path)
				db.DeletePackage(result.Package.ID)
				log.WithFields(logrus.Fields{
					"worker": result.WorkerID,
				}).Info("Deleted: %s", result.Package.ID)
				continue
			}

			var files []*url.URL
			for _, dist := range result.Distributions {
				if !dist.Completed {
					continue
				}
				file, _ := url.Parse(dist.Tarball)
				files = append(files, file)
			}
			succeed := db.PutCompleted(result.Package, result.Document, result.DocumentRevision, files)
			wg.Done()
			if succeed {
				log.WithFields(logrus.Fields{
					"sameRev": result.Package.Revision == result.DocumentRevision,
					"files":   len(result.Distributions),
					"worker":  result.WorkerID,
				}).Infof("Mirrored: %s", result.Package.ID)
			} else {
				log.Errorf("Failed to mirror: %s", result.Package.ID)
			}
		}
	}(c.db, &wg)

	// Start dispatcher
	go func() {
		for {
			select {
			case work := <-workQueue:
				// here we received a work request
				// goroutine won't be created until the acquired worker is released
				worker := <-workerQueue
				// dispatch work request
				worker <- work
			}
		}
	}()

	// Dispatch all packages
	for _, pkg := range packages {
		wg.Add(1)
		workQueue <- pkg
	}
	log.Debug("Successfully dispatched all queues")

	// Wait for jobs to be finished
	wg.Wait()

	// Wait for all workers complete
	for _, worker := range workers {
		wg.Add(1)
		worker.Stop()
	}
	wg.Wait()
	log.Info("Done")
}

func (c *MirrorClient) Update() {
	interval := time.Duration(c.config.Interval) * time.Second
	for {
		// Load changes
		since := c.db.GetSequence()
		changes := c.npmClient.GetChangesSince(since)
		if since == changes.LastSequence {
			log.Info("Update: currently up to date. no packages will be updated")
			time.Sleep(interval)
			continue
		}

		updates := map[string]*db.BarePackage{}
		for _, pkg := range changes.Results {
			name := pkg.ID
			rev := pkg.Changes[0].Revision
			currentRev := c.db.GetRevision(name)

			if currentRev == "" || currentRev != rev {
				updates[name] = &db.BarePackage{
					ID:       name,
					Revision: rev,
				}
			}
		}

		i := 0
		packages := make([]*db.BarePackage, len(updates))
		for _, pkg := range updates {
			packages[i] = pkg
			i++
		}

		log.Infof("Update: %d packages will be updated", len(packages))

		// Put all packages
		c.db.PutPackages(packages)
		// Update sequence
		c.db.SetSequence(changes.LastSequence)
		log.Debugf("Update: Sequence has been set to %d (was %d)", changes.LastSequence, since)

		// Start worker
		c.Start()
		log.Info("Update: finish")

		time.Sleep(interval)
	}
}

func (c *MirrorClient) initialize() {
	if !c.db.IsInitialized() {
		log.Debug("Database has not been initialized. Init..")
		c.db.Init()
	} else {
		log.Debug("Database has already been initialized.")
	}

	if !c.db.IsInitialized() {
		log.Fatal("Failed to initialize database")
	}
}

func (c *MirrorClient) Run(onetime bool) {
	c.initialize()

	log.Debug("Loading stats..")
	stats := c.db.GetStats()
	log.WithFields(logrus.Fields{
		"Packages":  stats.Packages,
		"Marks":     stats.Marks,
		"Documents": stats.Documents,
		"Files":     stats.Files,
	}).Debug("Status for database")

	seq := c.db.GetSequence()

	if seq == 0 {
		log.WithFields(logrus.Fields{
			"sequence": seq,
			"marked":   0,
		}).Info("State marked as first run")
		c.FirstRun()
		c.Start()
	}

	markedCount := c.db.GetCountOfMarks(true)

	if seq > 0 && markedCount < stats.Packages {
		log.WithFields(logrus.Fields{
			"sequence": seq,
			"marked":   markedCount,
		}).Info("Continue")
		c.Start()
	}

	if onetime {
		return
	}

	seq = c.db.GetSequence()

	if seq > 0 && markedCount == stats.Packages {
		log.WithFields(logrus.Fields{
			"sequence": seq,
			"marked":   markedCount,
		}).Info("State marked as run for updates")
		go c.Update()
	}

	exit := make(chan struct{}, 1)
	<-exit
}

func (c *MirrorClient) Check() {
	c.initialize()

	// Load all files
	log.Infof("Loading all files")
	files := c.db.GetAllFiles()

	var errs []string

	count := len(files)
	log.Infof("Checking files for %d packages", count)
	bar := pbar.StartNew(count)

	// Check file exists
	for name, items := range files {
		bar.Total += int64(len(items))
		for _, item := range items {
			path := getLocalPath(c.config.Path, item.Path)
			if _, err := os.Stat(path); os.IsNotExist(err) {
				errstr := fmt.Sprintf("%s: %s", name, path)
				errs = append(errs, errstr)
			}

			bar.Increment()
		}
		bar.Increment()
	}
	bar.Finish()

	// Write errors
	log.Debugf("Creating missing report of file checks: report.txt")
	out, _ := os.Create("report.log")
	defer out.Close()
	out.WriteString(strings.Join(errs[:], "\n"))
}
<commit_msg>mirror: fix it never stops<commit_after>package npm

import (
	"fmt"
	"net/url"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/ssut/pocketnpm/db"
	"github.com/ssut/pocketnpm/log"
	pbar "gopkg.in/cheggaaa/pb.v1"
)

type MirrorClient struct {
	db        *db.PocketBase
	config    *MirrorConfig
	npmClient *NPMClient
}

// NewMirrorClient creates an instance of MirrorClient
func NewMirrorClient(db *db.PocketBase, config *MirrorConfig) *MirrorClient {
	// Fix relative path
	config.Path, _ = filepath.Abs(config.Path)
	// Check for directory exists or not
	// If not, try to create an empty directory for it
	if _, err := os.Stat(config.Path); os.IsNotExist(err) {
		log.Debugf("Directory does not exist: %s", config.Path)
		err = os.MkdirAll(config.Path, 0755)
		if err != nil {
			log.Fatalf("Failed to create directory: %s", config.Path)
		} else {
			log.Debugf("Directory has been created: %s", config.Path)
		}
	}

	npmClient := NewNPMClient(config.Registry, config.Path)
	client := &MirrorClient{
		config:    config,
		db:        db,
		npmClient: npmClient,
	}

	return client
}

func (c *MirrorClient) initDocument(allDocs *AllDocsResponse) {
	packages := make([]*db.BarePackage, allDocs.TotalRows)

	for i, doc := range allDocs.Rows {
		packages[i] = &db.BarePackage{
			ID:       doc.ID,
			Revision: doc.Value.Revision,
		}
	}

	log.Debug("Putting packages..")
	c.db.PutPackages(packages)
	c.db.SetSequence(allDocs.Sequence)
	log.Debug("Succeed")
}

func (c *MirrorClient) FirstRun() {
	allDocs := c.npmClient.GetAllDocs()
	log.Infof("Total documents found: %d", allDocs.TotalRows)

	log.Debug("Store all documents by given properties")
	c.initDocument(allDocs)
}

func (c *MirrorClient) Start() {
	// Load all packages with its revision
	packages := c.db.GetIncompletePackages()

	log.Debugf("Packages to queue: %d", len(packages))

	// Array of workers
	var workers = make([]*MirrorWorker, c.config.MaxConnections)
	// Initialize channels
	// workQueue has a buffer size of 100
	var workQueue = make(chan *db.BarePackage, 100)
	var workerQueue = make(chan chan *db.BarePackage, c.config.MaxConnections)
	var resultQueue = make(chan *MirrorWorkResult)
	// WaitGroup
	var wg sync.WaitGroup

	// Create mirror workers
	log.Debugf("Starting %d workers", c.config.MaxConnections)
	for i := 0; i < c.config.MaxConnections; i++ {
		workers[i] = NewMirrorWorker(i, c.npmClient, workerQueue, resultQueue, &wg)
		workers[i].Start()
	}

	// Result handler
	go func(db *db.PocketBase, wg *sync.WaitGroup) {
		for {
			result, done := <-resultQueue
			if !done {
				wg.Done()
				return
			}

			if result.Deleted {
				path := getLocalPath(c.config.Path, result.Package.ID)
				os.RemoveAll(path)
				db.DeletePackage(result.Package.ID)
				log.WithFields(logrus.Fields{
					"worker": result.WorkerID,
				}).Info("Deleted: %s", result.Package.ID)
				wg.Done()
				continue
			}

			var files []*url.URL
			for _, dist := range result.Distributions {
				if !dist.Completed {
					continue
				}
				file, _ := url.Parse(dist.Tarball)
				files = append(files, file)
			}
			succeed := db.PutCompleted(result.Package, result.Document, result.DocumentRevision, files)
			wg.Done()
			if succeed {
				log.WithFields(logrus.Fields{
					"sameRev": result.Package.Revision == result.DocumentRevision,
					"files":   len(result.Distributions),
					"worker":  result.WorkerID,
				}).Infof("Mirrored: %s", result.Package.ID)
			} else {
				log.Errorf("Failed to mirror: %s", result.Package.ID)
			}
		}
	}(c.db, &wg)

	// Start dispatcher
	go func() {
		for {
			select {
			case work := <-workQueue:
				// here we received a work request
				// goroutine won't be created until the acquired worker is released
				worker := <-workerQueue
				// dispatch work request
				worker <- work
			}
		}
	}()

	// Dispatch all packages
	for _, pkg := range packages {
		wg.Add(1)
		workQueue <- pkg
	}
	log.Debug("Successfully dispatched all queues")

	// Wait for jobs to be finished
	wg.Wait()

	// Wait for all workers complete
	for _, worker := range workers {
		wg.Add(1)
		worker.Stop()
	}
	wg.Wait()
	log.Info("Done")
}

func (c *MirrorClient) Update() {
	interval := time.Duration(c.config.Interval) * time.Second
	for {
		// Load changes
		since := c.db.GetSequence()
		changes := c.npmClient.GetChangesSince(since)
		if since == changes.LastSequence {
			log.Info("Update: currently up to date. no packages will be updated")
			time.Sleep(interval)
			continue
		}

		updates := map[string]*db.BarePackage{}
		for _, pkg := range changes.Results {
			name := pkg.ID
			rev := pkg.Changes[0].Revision
			currentRev := c.db.GetRevision(name)

			if currentRev == "" || currentRev != rev {
				updates[name] = &db.BarePackage{
					ID:       name,
					Revision: rev,
				}
			}
		}

		i := 0
		packages := make([]*db.BarePackage, len(updates))
		for _, pkg := range updates {
			packages[i] = pkg
			i++
		}

		log.Infof("Update: %d packages will be updated", len(packages))

		// Put all packages
		c.db.PutPackages(packages)
		// Update sequence
		c.db.SetSequence(changes.LastSequence)
		log.Debugf("Update: Sequence has been set to %d (was %d)", changes.LastSequence, since)

		// Start worker
		c.Start()
		log.Info("Update: finish")

		time.Sleep(interval)
	}
}

func (c *MirrorClient) initialize() {
	if !c.db.IsInitialized() {
		log.Debug("Database has not been initialized. Init..")
		c.db.Init()
	} else {
		log.Debug("Database has already been initialized.")
	}

	if !c.db.IsInitialized() {
		log.Fatal("Failed to initialize database")
	}
}

func (c *MirrorClient) Run(onetime bool) {
	c.initialize()

	log.Debug("Loading stats..")
	stats := c.db.GetStats()
	log.WithFields(logrus.Fields{
		"Packages":  stats.Packages,
		"Marks":     stats.Marks,
		"Documents": stats.Documents,
		"Files":     stats.Files,
	}).Debug("Status for database")

	seq := c.db.GetSequence()

	if seq == 0 {
		log.WithFields(logrus.Fields{
			"sequence": seq,
			"marked":   0,
		}).Info("State marked as first run")
		c.FirstRun()
		c.Start()
	}

	markedCount := c.db.GetCountOfMarks(true)

	if seq > 0 && markedCount < stats.Packages {
		log.WithFields(logrus.Fields{
			"sequence": seq,
			"marked":   markedCount,
		}).Info("Continue")
		c.Start()
	}

	if onetime {
		return
	}

	seq = c.db.GetSequence()

	if seq > 0 && markedCount == stats.Packages {
		log.WithFields(logrus.Fields{
			"sequence": seq,
			"marked":   markedCount,
		}).Info("State marked as run for updates")
		go c.Update()
	}

	exit := make(chan struct{}, 1)
	<-exit
}

func (c *MirrorClient) Check() {
	c.initialize()

	// Load all files
	log.Infof("Loading all files")
	files := c.db.GetAllFiles()

	var errs []string

	count := len(files)
	log.Infof("Checking files for %d packages", count)
	bar := pbar.StartNew(count)

	// Check file exists
	for name, items := range files {
		bar.Total += int64(len(items))
		for _, item := range items {
			path := getLocalPath(c.config.Path, item.Path)
			if _, err := os.Stat(path); os.IsNotExist(err) {
				errstr := fmt.Sprintf("%s: %s", name, path)
				errs = append(errs, errstr)
			}

			bar.Increment()
		}
		bar.Increment()
	}
	bar.Finish()

	// Write errors
	log.Debugf("Creating missing report of file checks: report.txt")
	out, _ := os.Create("report.log")
	defer out.Close()
	out.WriteString(strings.Join(errs[:], "\n"))
}
<|endoftext|>


<commit_before>// Copyright 2016 The npyio 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 npyio

import (
	"io/ioutil"
	"testing"

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

func BenchmarkWriteDense(b *testing.B) {
	data := make([]float64, 1000)
	m := mat64.NewDense(100, 10, data)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, m)
	}
}

func BenchmarkWriteFloat32Slice(b *testing.B) {
	data := make([]float32, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteFloat64Slice(b *testing.B) {
	data := make([]float64, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteBoolSlice(b *testing.B) {
	data := make([]bool, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteUint8Slice(b *testing.B) {
	data := make([]uint8, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteUint16Slice(b *testing.B) {
	data := make([]uint16, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteUint32Slice(b *testing.B) {
	data := make([]uint32, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteUint64Slice(b *testing.B) {
	data := make([]uint64, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteUintSlice(b *testing.B) {
	data := make([]uint, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteInt8Slice(b *testing.B) {
	data := make([]int8, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteInt16Slice(b *testing.B) {
	data := make([]int16, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteInt32Slice(b *testing.B) {
	data := make([]int32, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteInt64Slice(b *testing.B) {
	data := make([]int64, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteIntSlice(b *testing.B) {
	data := make([]int, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteComplex64Slice(b *testing.B) {
	data := make([]complex64, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteComplex128Slice(b *testing.B) {
	data := make([]complex128, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteIntArray(b *testing.B) {
	var data [1000]int
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, &data)
	}
}

func BenchmarkWriteFloat64Array(b *testing.B) {
	var data [1000]float64
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, &data)
	}
}
<commit_msg>npyio: add bench for Read<commit_after>// Copyright 2016 The npyio 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 npyio

import (
	"bytes"
	"io/ioutil"
	"testing"

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

func BenchmarkWriteDense(b *testing.B) {
	data := make([]float64, 1000)
	m := mat64.NewDense(100, 10, data)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, m)
	}
}

func BenchmarkWriteFloat32Slice(b *testing.B) {
	data := make([]float32, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteFloat64Slice(b *testing.B) {
	data := make([]float64, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteBoolSlice(b *testing.B) {
	data := make([]bool, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteUint8Slice(b *testing.B) {
	data := make([]uint8, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteUint16Slice(b *testing.B) {
	data := make([]uint16, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteUint32Slice(b *testing.B) {
	data := make([]uint32, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteUint64Slice(b *testing.B) {
	data := make([]uint64, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteUintSlice(b *testing.B) {
	data := make([]uint, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteInt8Slice(b *testing.B) {
	data := make([]int8, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteInt16Slice(b *testing.B) {
	data := make([]int16, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteInt32Slice(b *testing.B) {
	data := make([]int32, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteInt64Slice(b *testing.B) {
	data := make([]int64, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteIntSlice(b *testing.B) {
	data := make([]int, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteComplex64Slice(b *testing.B) {
	data := make([]complex64, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteComplex128Slice(b *testing.B) {
	data := make([]complex128, 1000)
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, data)
	}
}

func BenchmarkWriteIntArray(b *testing.B) {
	var data [1000]int
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, &data)
	}
}

func BenchmarkWriteFloat64Array(b *testing.B) {
	var data [1000]float64
	w := ioutil.Discard
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		_ = Write(w, &data)
	}
}

type creader struct {
	buf []byte
	pos int
}

func (r *creader) Read(data []byte) (int, error) {
	n := copy(data, r.buf[r.pos:r.pos+len(data)])
	r.pos += n
	return n, nil
}

func (r *creader) reset() {
	r.pos = 0
}

func BenchmarkReadDense(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, mat64.NewDense(100, 10, make([]float64, 1000)))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var m mat64.Dense
		_ = Read(r, &m)
		r.reset()
	}
}

func BenchmarkReadFloat32Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]float32, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []float32
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadFloat64Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]float64, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []float64
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadBoolSlice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]bool, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []bool
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadUintSlice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]uint, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []uint
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadUint8Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]uint8, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []uint8
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadUint16Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]uint16, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []uint16
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadUint32Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]uint32, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []uint32
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadUint64Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]uint64, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []uint64
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadIntSlice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]int, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []int
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadInt8Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]int8, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []int8
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadInt16Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]int16, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []int16
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadInt32Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]int32, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []int32
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadInt64Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]int64, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []int64
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadComplex64Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]complex64, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []complex64
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadComplex128Slice(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]complex128, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data []complex128
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadIntArray(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]int, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data [1000]int
		_ = Read(r, &data)
		r.reset()
	}
}

func BenchmarkReadFloat64Array(b *testing.B) {
	buf := new(bytes.Buffer)
	_ = Write(buf, make([]float64, 1000))
	r := &creader{buf: buf.Bytes()}
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		var data [1000]float64
		_ = Read(r, &data)
		r.reset()
	}
}
<|endoftext|>


<commit_before>package docker

import (
	"errors"
	"fmt"
	"strings"
	"time"

	docker "github.com/fsouza/go-dockerclient"

	. "github.com/weaveworks/weave/common"
)

const (
	InitialInterval = 1 * time.Second
	MaxInterval     = 20 * time.Second
)

// An observer for container events
type ContainerObserver interface {
	ContainerStarted(ident string)
	ContainerDied(ident string)
}

type Client struct {
	*docker.Client
}

// NewClient creates a new Docker client and checks we can talk to Docker
func NewClient(apiPath string) (*Client, error) {
	if apiPath != "" && !strings.Contains(apiPath, "://") {
		apiPath = "tcp://" + apiPath
	}
	dc, err := docker.NewClient(apiPath)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func NewVersionedClient(apiPath string, apiVersionString string) (*Client, error) {
	if !strings.Contains(apiPath, "://") {
		apiPath = "tcp://" + apiPath
	}
	dc, err := docker.NewVersionedClient(apiPath, apiVersionString)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func NewVersionedClientFromEnv(apiVersionString string) (*Client, error) {
	dc, err := docker.NewVersionedClientFromEnv(apiVersionString)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func (c *Client) checkWorking() error {
	_, err := c.Version()
	return err
}

func (c *Client) Info() string {
	if env, err := c.Version(); err != nil {
		return fmt.Sprintf("Docker API error: %s", err)
	} else {
		return fmt.Sprintf("Docker API on %s: %v", c.Endpoint(), env)
	}
}

// AddObserver adds an observer for docker events
func (c *Client) AddObserver(ob ContainerObserver) error {
	go func() {
		retryInterval := InitialInterval
		for {
			events := make(chan *docker.APIEvents)
			if err := c.AddEventListener(events); err != nil {
				Log.Errorf("[docker] Unable to add listener to Docker API: %s - retrying in %ds", err, retryInterval/time.Second)
			} else {
				start := time.Now()
				for event := range events {
					switch event.Status {
					case "start":
						id := event.ID
						ob.ContainerStarted(id)
					case "die":
						id := event.ID
						ob.ContainerDied(id)
					}
				}
				if time.Since(start) > retryInterval {
					retryInterval = InitialInterval
				}
				Log.Errorf("[docker] Event listener channel closed - retrying subscription in %ds", retryInterval/time.Second)
			}
			time.Sleep(retryInterval)
			retryInterval = retryInterval * 3 / 2
			if retryInterval > MaxInterval {
				retryInterval = MaxInterval
			}
		}
	}()
	return nil
}

// IsContainerNotRunning returns true if we have checked with Docker that the ID is not running
func (c *Client) IsContainerNotRunning(idStr string) bool {
	container, err := c.InspectContainer(idStr)
	if err == nil {
		return !container.State.Running || container.State.Restarting
	}
	if _, notThere := err.(*docker.NoSuchContainer); notThere {
		return true
	}
	Log.Errorf("[docker] Could not check container status: %s", err)
	return false
}

// This is intended to find an IP address that we can reach the container on;
// if it is on the Docker bridge network then that address; if on the host network
// then localhost
func (c *Client) GetContainerIP(nameOrID string) (string, error) {
	Log.Debugf("Getting IP for container %s", nameOrID)
	info, err := c.InspectContainer(nameOrID)
	if err != nil {
		return "", err
	}
	if info.NetworkSettings.Networks != nil {
		Log.Debugln("Networks: ", info.NetworkSettings.Networks)
		if bridgeNetwork, ok := info.NetworkSettings.Networks["bridge"]; ok {
			return bridgeNetwork.IPAddress, nil
		} else if _, ok := info.NetworkSettings.Networks["host"]; ok {
			return "127.0.0.1", nil
		}
	} else if info.HostConfig.NetworkMode == "host" {
		return "127.0.0.1", nil
	}
	if info.NetworkSettings.IPAddress == "" {
		return "", errors.New("No IP address found for container " + nameOrID)
	}
	return info.NetworkSettings.IPAddress, nil
}
<commit_msg>Delay notifying observers about 'start' events<commit_after>package docker

import (
	"errors"
	"fmt"
	"strings"
	"time"

	docker "github.com/fsouza/go-dockerclient"

	. "github.com/weaveworks/weave/common"
)

const (
	InitialInterval = 1 * time.Second
	MaxInterval     = 20 * time.Second
)

// An observer for container events
type ContainerObserver interface {
	ContainerStarted(ident string)
	ContainerDied(ident string)
}

type Client struct {
	*docker.Client
}

type syncPair struct {
	stop chan struct{}
	done chan struct{}
}

type pendingStarts map[string]*syncPair

// NewClient creates a new Docker client and checks we can talk to Docker
func NewClient(apiPath string) (*Client, error) {
	if apiPath != "" && !strings.Contains(apiPath, "://") {
		apiPath = "tcp://" + apiPath
	}
	dc, err := docker.NewClient(apiPath)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func NewVersionedClient(apiPath string, apiVersionString string) (*Client, error) {
	if !strings.Contains(apiPath, "://") {
		apiPath = "tcp://" + apiPath
	}
	dc, err := docker.NewVersionedClient(apiPath, apiVersionString)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func NewVersionedClientFromEnv(apiVersionString string) (*Client, error) {
	dc, err := docker.NewVersionedClientFromEnv(apiVersionString)
	if err != nil {
		return nil, err
	}
	client := &Client{dc}

	return client, client.checkWorking()
}

func (c *Client) checkWorking() error {
	_, err := c.Version()
	return err
}

func (c *Client) Info() string {
	if env, err := c.Version(); err != nil {
		return fmt.Sprintf("Docker API error: %s", err)
	} else {
		return fmt.Sprintf("Docker API on %s: %v", c.Endpoint(), env)
	}
}

// AddObserver adds an observer for docker events
func (c *Client) AddObserver(ob ContainerObserver) error {
	go func() {
		pending := make(pendingStarts)
		retryInterval := InitialInterval
		for {
			events := make(chan *docker.APIEvents)
			if err := c.AddEventListener(events); err != nil {
				Log.Errorf("[docker] Unable to add listener to Docker API: %s - retrying in %ds", err, retryInterval/time.Second)
			} else {
				start := time.Now()
				for event := range events {
					switch event.Status {
					case "start":
						pending.finish(event.ID)
						pending.start(event.ID, c, ob)
					case "die":
						pending.finish(event.ID)
						ob.ContainerDied(event.ID)
					}
				}
				if time.Since(start) > retryInterval {
					retryInterval = InitialInterval
				}
				Log.Errorf("[docker] Event listener channel closed - retrying subscription in %ds", retryInterval/time.Second)
			}
			time.Sleep(retryInterval)
			retryInterval = retryInterval * 3 / 2
			if retryInterval > MaxInterval {
				retryInterval = MaxInterval
			}
		}
	}()
	return nil
}

// Docker sends a 'start' event before it has attempted to start the
// container.  Delay notifying the observer until the container has a
// pid, or we are told to stop when a 'die' event arrives.
//
// Note we always deliver the event, even if the container seems to
// have gone away.
func (pending pendingStarts) start(id string, c *Client, ob ContainerObserver) {
	sync := syncPair{make(chan struct{}), make(chan struct{})}
	pending[id] = &sync
	go func() {
		defer close(sync.done)
		defer ob.ContainerStarted(id)
		for {
			if container, err := c.InspectContainer(id); err != nil || container.State.Pid != 0 {
				return
			}
			select {
			case <-sync.stop:
				return
			case <-time.After(200 * time.Millisecond):
			}
		}
	}()
}

func (pending pendingStarts) finish(id string) {
	if sync, found := pending[id]; found {
		close(sync.stop)
		<-sync.done
		delete(pending, id)
	}
}

// IsContainerNotRunning returns true if we have checked with Docker that the ID is not running
func (c *Client) IsContainerNotRunning(idStr string) bool {
	container, err := c.InspectContainer(idStr)
	if err == nil {
		return !container.State.Running || container.State.Restarting
	}
	if _, notThere := err.(*docker.NoSuchContainer); notThere {
		return true
	}
	Log.Errorf("[docker] Could not check container status: %s", err)
	return false
}

// This is intended to find an IP address that we can reach the container on;
// if it is on the Docker bridge network then that address; if on the host network
// then localhost
func (c *Client) GetContainerIP(nameOrID string) (string, error) {
	Log.Debugf("Getting IP for container %s", nameOrID)
	info, err := c.InspectContainer(nameOrID)
	if err != nil {
		return "", err
	}
	if info.NetworkSettings.Networks != nil {
		Log.Debugln("Networks: ", info.NetworkSettings.Networks)
		if bridgeNetwork, ok := info.NetworkSettings.Networks["bridge"]; ok {
			return bridgeNetwork.IPAddress, nil
		} else if _, ok := info.NetworkSettings.Networks["host"]; ok {
			return "127.0.0.1", nil
		}
	} else if info.HostConfig.NetworkMode == "host" {
		return "127.0.0.1", nil
	}
	if info.NetworkSettings.IPAddress == "" {
		return "", errors.New("No IP address found for container " + nameOrID)
	}
	return info.NetworkSettings.IPAddress, nil
}
<|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 ssh implements an SSH server.

SSH is a transport security protocol, an authentication protocol and a
family of application protocols. The most typical application level
protocol is a remote shell and this is specifically implemented.  However,
the multiplexed nature of SSH is exposed to users that wish to support
others.

An SSH server is represented by a Server, which manages a number of
ServerConnections and handles authentication.

	var s Server
	s.PubKeyCallback = pubKeyAuth
	s.PasswordCallback = passwordAuth

	pemBytes, err := ioutil.ReadFile("id_rsa")
	if err != nil {
		panic("Failed to load private key")
	}
	err = s.SetRSAPrivateKey(pemBytes)
	if err != nil {
		panic("Failed to parse private key")
	}

Once a Server has been set up, connections can be attached.

	var sConn ServerConnection
	sConn.Server = &s
	err = sConn.Handshake(conn)
	if err != nil {
		panic("failed to handshake")
	}

An SSH connection multiplexes several channels, which must be accepted themselves:

	for {
		channel, err := sConn.Accept()
		if err != nil {
			panic("error from Accept")
		}

		...
	}

Accept reads from the connection, demultiplexes packets to their corresponding
channels and returns when a new channel request is seen. Some goroutine must
always be calling Accept; otherwise no messages will be forwarded to the
channels.

Channels have a type, depending on the application level protocol intended. In
the case of a shell, the type is "session" and ServerShell may be used to
present a simple terminal interface.

	if channel.ChannelType() != "session" {
		c.Reject(RejectUnknownChannelType, "unknown channel type")
		return
	}
	channel.Accept()

	shell := NewServerShell(channel, "> ")
	go func() {
		defer channel.Close()
		for {
			line, err := shell.ReadLine()
			if err != nil {
				break
			}
			println(line)
		}
		return
	}()
*/
package ssh
<commit_msg>exp/ssh: fix constant in package documentation<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 ssh implements an SSH server.

SSH is a transport security protocol, an authentication protocol and a
family of application protocols. The most typical application level
protocol is a remote shell and this is specifically implemented.  However,
the multiplexed nature of SSH is exposed to users that wish to support
others.

An SSH server is represented by a Server, which manages a number of
ServerConnections and handles authentication.

	var s Server
	s.PubKeyCallback = pubKeyAuth
	s.PasswordCallback = passwordAuth

	pemBytes, err := ioutil.ReadFile("id_rsa")
	if err != nil {
		panic("Failed to load private key")
	}
	err = s.SetRSAPrivateKey(pemBytes)
	if err != nil {
		panic("Failed to parse private key")
	}

Once a Server has been set up, connections can be attached.

	var sConn ServerConnection
	sConn.Server = &s
	err = sConn.Handshake(conn)
	if err != nil {
		panic("failed to handshake")
	}

An SSH connection multiplexes several channels, which must be accepted themselves:

	for {
		channel, err := sConn.Accept()
		if err != nil {
			panic("error from Accept")
		}

		...
	}

Accept reads from the connection, demultiplexes packets to their corresponding
channels and returns when a new channel request is seen. Some goroutine must
always be calling Accept; otherwise no messages will be forwarded to the
channels.

Channels have a type, depending on the application level protocol intended. In
the case of a shell, the type is "session" and ServerShell may be used to
present a simple terminal interface.

	if channel.ChannelType() != "session" {
		c.Reject(UnknownChannelType, "unknown channel type")
		return
	}
	channel.Accept()

	shell := NewServerShell(channel, "> ")
	go func() {
		defer channel.Close()
		for {
			line, err := shell.ReadLine()
			if err != nil {
				break
			}
			println(line)
		}
		return
	}()
*/
package ssh
<|endoftext|>


<commit_before>// Copyright 2010 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 image

var (
	// Black is an opaque black ColorImage.
	Black = ColorImage{Gray16Color{0}}
	// White is an opaque white ColorImage.
	White = ColorImage{Gray16Color{0xffff}}
	// Transparent is a fully transparent ColorImage.
	Transparent = ColorImage{Alpha16Color{0}}
	// Opaque is a fully opaque ColorImage.
	Opaque = ColorImage{Alpha16Color{0xffff}}
)

// A ColorImage is a practically infinite-sized Image of uniform Color.
// It implements both the Color and Image interfaces.
type ColorImage struct {
	C Color
}

func (c ColorImage) RGBA() (r, g, b, a uint32) {
	return c.C.RGBA()
}

func (c ColorImage) ColorModel() ColorModel {
	return ColorModelFunc(func(Color) Color { return c.C })
}

func (c ColorImage) Bounds() Rectangle { return Rectangle{ZP, Point{1e9, 1e9}} }

func (c ColorImage) At(x, y int) Color { return c.C }

// Opaque scans the entire image and returns whether or not it is fully opaque.
func (c ColorImage) Opaque() bool {
	_, _, _, a := c.C.RGBA()
	return a == 0xffff
}
<commit_msg>image: change a ColorImage's minimum point from (0, 0) to (-1e9, -1e9).<commit_after>// Copyright 2010 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 image

var (
	// Black is an opaque black ColorImage.
	Black = ColorImage{Gray16Color{0}}
	// White is an opaque white ColorImage.
	White = ColorImage{Gray16Color{0xffff}}
	// Transparent is a fully transparent ColorImage.
	Transparent = ColorImage{Alpha16Color{0}}
	// Opaque is a fully opaque ColorImage.
	Opaque = ColorImage{Alpha16Color{0xffff}}
)

// A ColorImage is a practically infinite-sized Image of uniform Color.
// It implements both the Color and Image interfaces.
type ColorImage struct {
	C Color
}

func (c ColorImage) RGBA() (r, g, b, a uint32) {
	return c.C.RGBA()
}

func (c ColorImage) ColorModel() ColorModel {
	return ColorModelFunc(func(Color) Color { return c.C })
}

func (c ColorImage) Bounds() Rectangle { return Rectangle{Point{-1e9, -1e9}, Point{1e9, 1e9}} }

func (c ColorImage) At(x, y int) Color { return c.C }

// Opaque scans the entire image and returns whether or not it is fully opaque.
func (c ColorImage) Opaque() bool {
	_, _, _, a := c.C.RGBA()
	return a == 0xffff
}
<|endoftext|>


<commit_before>package git

import (
	"io"
	"sort"

	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/object"
	"gopkg.in/src-d/go-git.v4/utils/diff"

	"github.com/sergi/go-diff/diffmatchpatch"
)

// References returns a slice of Commits for the file at "path", starting from
// the commit provided that contains the file from the provided path. The last
// commit into the returned slice is the commit where the file was created.
// If the provided commit does not contains the specified path, a nil slice is
// returned. The commits are sorted in commit order, newer to older.
//
// Caveats:
//
// - Moves and copies are not currently supported.
//
// - Cherry-picks are not detected unless there are no commits between them and
// therefore can appear repeated in the list. (see git path-id for hints on how
// to fix this).
func references(c *object.Commit, path string) ([]*object.Commit, error) {
	var result []*object.Commit
	seen := make(map[plumbing.Hash]struct{}, 0)
	if err := walkGraph(&result, &seen, c, path); err != nil {
		return nil, err
	}

	// TODO result should be returned without ordering
	sortCommits(result)

	// for merges of identical cherry-picks
	return removeComp(path, result, equivalent)
}

type commitSorterer struct {
	l []*object.Commit
}

func (s commitSorterer) Len() int {
	return len(s.l)
}

func (s commitSorterer) Less(i, j int) bool {
	return s.l[i].Committer.When.Before(s.l[j].Committer.When)
}

func (s commitSorterer) Swap(i, j int) {
	s.l[i], s.l[j] = s.l[j], s.l[i]
}

// SortCommits sorts a commit list by commit date, from older to newer.
func sortCommits(l []*object.Commit) {
	s := &commitSorterer{l}
	sort.Sort(s)
}

// Recursive traversal of the commit graph, generating a linear history of the
// path.
func walkGraph(result *[]*object.Commit, seen *map[plumbing.Hash]struct{}, current *object.Commit, path string) error {
	// check and update seen
	if _, ok := (*seen)[current.Hash]; ok {
		return nil
	}
	(*seen)[current.Hash] = struct{}{}

	// if the path is not in the current commit, stop searching.
	if _, err := current.File(path); err != nil {
		return nil
	}

	// optimization: don't traverse branches that does not
	// contain the path.
	parents := parentsContainingPath(path, current)

	switch len(parents) {
	// if the path is not found in any of its parents, the path was
	// created by this commit; we must add it to the revisions list and
	// stop searching. This includes the case when current is the
	// initial commit.
	case 0:
		*result = append(*result, current)
		return nil
	case 1: // only one parent contains the path
		// if the file contents has change, add the current commit
		different, err := differentContents(path, current, parents)
		if err != nil {
			return err
		}
		if len(different) == 1 {
			*result = append(*result, current)
		}
		// in any case, walk the parent
		return walkGraph(result, seen, parents[0], path)
	default: // more than one parent contains the path
		// TODO: detect merges that had a conflict, because they must be
		// included in the result here.
		for _, p := range parents {
			err := walkGraph(result, seen, p, path)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func parentsContainingPath(path string, c *object.Commit) []*object.Commit {
	// TODO: benchmark this method making git.object.Commit.parent public instead of using
	// an iterator
	var result []*object.Commit
	iter := c.Parents()
	for {
		parent, err := iter.Next()
		if err != nil {
			if err == io.EOF {
				return result
			}
			panic("unreachable")
		}
		if _, err := parent.File(path); err == nil {
			result = append(result, parent)
		}
	}
}

// Returns an slice of the commits in "cs" that has the file "path", but with different
// contents than what can be found in "c".
func differentContents(path string, c *object.Commit, cs []*object.Commit) ([]*object.Commit, error) {
	result := make([]*object.Commit, 0, len(cs))
	h, found := blobHash(path, c)
	if !found {
		return nil, object.ErrFileNotFound
	}
	for _, cx := range cs {
		if hx, found := blobHash(path, cx); found && h != hx {
			result = append(result, cx)
		}
	}
	return result, nil
}

// blobHash returns the hash of a path in a commit
func blobHash(path string, commit *object.Commit) (hash plumbing.Hash, found bool) {
	file, err := commit.File(path)
	if err != nil {
		var empty plumbing.Hash
		return empty, found
	}
	return file.Hash, true
}

type contentsComparatorFn func(path string, a, b *object.Commit) (bool, error)

// Returns a new slice of commits, with duplicates removed.  Expects a
// sorted commit list.  Duplication is defined according to "comp".  It
// will always keep the first commit of a series of duplicated commits.
func removeComp(path string, cs []*object.Commit, comp contentsComparatorFn) ([]*object.Commit, error) {
	result := make([]*object.Commit, 0, len(cs))
	if len(cs) == 0 {
		return result, nil
	}
	result = append(result, cs[0])
	for i := 1; i < len(cs); i++ {
		equals, err := comp(path, cs[i], cs[i-1])
		if err != nil {
			return nil, err
		}
		if !equals {
			result = append(result, cs[i])
		}
	}
	return result, nil
}

// Equivalent commits are commits whose patch is the same.
func equivalent(path string, a, b *object.Commit) (bool, error) {
	numParentsA := a.NumParents()
	numParentsB := b.NumParents()

	// the first commit is not equivalent to anyone
	// and "I think" merges can not be equivalent to anything
	if numParentsA != 1 || numParentsB != 1 {
		return false, nil
	}

	diffsA, err := patch(a, path)
	if err != nil {
		return false, err
	}
	diffsB, err := patch(b, path)
	if err != nil {
		return false, err
	}

	return sameDiffs(diffsA, diffsB), nil
}

func patch(c *object.Commit, path string) ([]diffmatchpatch.Diff, error) {
	// get contents of the file in the commit
	file, err := c.File(path)
	if err != nil {
		return nil, err
	}
	content, err := file.Contents()
	if err != nil {
		return nil, err
	}

	// get contents of the file in the first parent of the commit
	var contentParent string
	iter := c.Parents()
	parent, err := iter.Next()
	if err != nil {
		return nil, err
	}
	file, err = parent.File(path)
	if err != nil {
		contentParent = ""
	} else {
		contentParent, err = file.Contents()
		if err != nil {
			return nil, err
		}
	}

	// compare the contents of parent and child
	return diff.Do(content, contentParent), nil
}

func sameDiffs(a, b []diffmatchpatch.Diff) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if !sameDiff(a[i], b[i]) {
			return false
		}
	}
	return true
}

func sameDiff(a, b diffmatchpatch.Diff) bool {
	if a.Type != b.Type {
		return false
	}
	switch a.Type {
	case 0:
		return countLines(a.Text) == countLines(b.Text)
	case 1, -1:
		return a.Text == b.Text
	default:
		panic("unreachable")
	}
}
<commit_msg>references.go: fix Parents from commit iterator<commit_after>package git

import (
	"io"
	"sort"

	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/object"
	"gopkg.in/src-d/go-git.v4/utils/diff"

	"github.com/sergi/go-diff/diffmatchpatch"
)

// References returns a slice of Commits for the file at "path", starting from
// the commit provided that contains the file from the provided path. The last
// commit into the returned slice is the commit where the file was created.
// If the provided commit does not contains the specified path, a nil slice is
// returned. The commits are sorted in commit order, newer to older.
//
// Caveats:
//
// - Moves and copies are not currently supported.
//
// - Cherry-picks are not detected unless there are no commits between them and
// therefore can appear repeated in the list. (see git path-id for hints on how
// to fix this).
func references(c *object.Commit, path string) ([]*object.Commit, error) {
	var result []*object.Commit
	seen := make(map[plumbing.Hash]struct{}, 0)
	if err := walkGraph(&result, &seen, c, path); err != nil {
		return nil, err
	}

	// TODO result should be returned without ordering
	sortCommits(result)

	// for merges of identical cherry-picks
	return removeComp(path, result, equivalent)
}

type commitSorterer struct {
	l []*object.Commit
}

func (s commitSorterer) Len() int {
	return len(s.l)
}

func (s commitSorterer) Less(i, j int) bool {
	return s.l[i].Committer.When.Before(s.l[j].Committer.When)
}

func (s commitSorterer) Swap(i, j int) {
	s.l[i], s.l[j] = s.l[j], s.l[i]
}

// SortCommits sorts a commit list by commit date, from older to newer.
func sortCommits(l []*object.Commit) {
	s := &commitSorterer{l}
	sort.Sort(s)
}

// Recursive traversal of the commit graph, generating a linear history of the
// path.
func walkGraph(result *[]*object.Commit, seen *map[plumbing.Hash]struct{}, current *object.Commit, path string) error {
	// check and update seen
	if _, ok := (*seen)[current.Hash]; ok {
		return nil
	}
	(*seen)[current.Hash] = struct{}{}

	// if the path is not in the current commit, stop searching.
	if _, err := current.File(path); err != nil {
		return nil
	}

	// optimization: don't traverse branches that does not
	// contain the path.
	parents, err := parentsContainingPath(path, current)
	if err != nil {
		return err
	}
	switch len(parents) {
	// if the path is not found in any of its parents, the path was
	// created by this commit; we must add it to the revisions list and
	// stop searching. This includes the case when current is the
	// initial commit.
	case 0:
		*result = append(*result, current)
		return nil
	case 1: // only one parent contains the path
		// if the file contents has change, add the current commit
		different, err := differentContents(path, current, parents)
		if err != nil {
			return err
		}
		if len(different) == 1 {
			*result = append(*result, current)
		}
		// in any case, walk the parent
		return walkGraph(result, seen, parents[0], path)
	default: // more than one parent contains the path
		// TODO: detect merges that had a conflict, because they must be
		// included in the result here.
		for _, p := range parents {
			err := walkGraph(result, seen, p, path)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func parentsContainingPath(path string, c *object.Commit) ([]*object.Commit, error) {
	// TODO: benchmark this method making git.object.Commit.parent public instead of using
	// an iterator
	var result []*object.Commit
	iter := c.Parents()
	for {
		parent, err := iter.Next()
		if err == io.EOF {
			return result, nil
		}
		if err != nil {
			return nil, err
		}
		if _, err := parent.File(path); err == nil {
			result = append(result, parent)
		}
	}
}

// Returns an slice of the commits in "cs" that has the file "path", but with different
// contents than what can be found in "c".
func differentContents(path string, c *object.Commit, cs []*object.Commit) ([]*object.Commit, error) {
	result := make([]*object.Commit, 0, len(cs))
	h, found := blobHash(path, c)
	if !found {
		return nil, object.ErrFileNotFound
	}
	for _, cx := range cs {
		if hx, found := blobHash(path, cx); found && h != hx {
			result = append(result, cx)
		}
	}
	return result, nil
}

// blobHash returns the hash of a path in a commit
func blobHash(path string, commit *object.Commit) (hash plumbing.Hash, found bool) {
	file, err := commit.File(path)
	if err != nil {
		var empty plumbing.Hash
		return empty, found
	}
	return file.Hash, true
}

type contentsComparatorFn func(path string, a, b *object.Commit) (bool, error)

// Returns a new slice of commits, with duplicates removed.  Expects a
// sorted commit list.  Duplication is defined according to "comp".  It
// will always keep the first commit of a series of duplicated commits.
func removeComp(path string, cs []*object.Commit, comp contentsComparatorFn) ([]*object.Commit, error) {
	result := make([]*object.Commit, 0, len(cs))
	if len(cs) == 0 {
		return result, nil
	}
	result = append(result, cs[0])
	for i := 1; i < len(cs); i++ {
		equals, err := comp(path, cs[i], cs[i-1])
		if err != nil {
			return nil, err
		}
		if !equals {
			result = append(result, cs[i])
		}
	}
	return result, nil
}

// Equivalent commits are commits whose patch is the same.
func equivalent(path string, a, b *object.Commit) (bool, error) {
	numParentsA := a.NumParents()
	numParentsB := b.NumParents()

	// the first commit is not equivalent to anyone
	// and "I think" merges can not be equivalent to anything
	if numParentsA != 1 || numParentsB != 1 {
		return false, nil
	}

	diffsA, err := patch(a, path)
	if err != nil {
		return false, err
	}
	diffsB, err := patch(b, path)
	if err != nil {
		return false, err
	}

	return sameDiffs(diffsA, diffsB), nil
}

func patch(c *object.Commit, path string) ([]diffmatchpatch.Diff, error) {
	// get contents of the file in the commit
	file, err := c.File(path)
	if err != nil {
		return nil, err
	}
	content, err := file.Contents()
	if err != nil {
		return nil, err
	}

	// get contents of the file in the first parent of the commit
	var contentParent string
	iter := c.Parents()
	parent, err := iter.Next()
	if err != nil {
		return nil, err
	}
	file, err = parent.File(path)
	if err != nil {
		contentParent = ""
	} else {
		contentParent, err = file.Contents()
		if err != nil {
			return nil, err
		}
	}

	// compare the contents of parent and child
	return diff.Do(content, contentParent), nil
}

func sameDiffs(a, b []diffmatchpatch.Diff) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if !sameDiff(a[i], b[i]) {
			return false
		}
	}
	return true
}

func sameDiff(a, b diffmatchpatch.Diff) bool {
	if a.Type != b.Type {
		return false
	}
	switch a.Type {
	case 0:
		return countLines(a.Text) == countLines(b.Text)
	case 1, -1:
		return a.Text == b.Text
	default:
		panic("unreachable")
	}
}
<|endoftext|>


<commit_before>package observers

import (
	"sync/atomic"
	"time"

	"github.com/sirupsen/logrus"

	"github.com/ivan1993spb/snake-server/objects/watermelon"
	"github.com/ivan1993spb/snake-server/world"
)

const chanWatermelonObserverEventsBuffer = 64

const addWatermelonDelay = time.Second * 15

const addWatermelonsDuringTickLimit = 2

const oneWatermelonArea = 200

type WatermelonObserver struct {
	world  world.Interface
	logger logrus.FieldLogger

	watermelonCount    int32
	maxWatermelonCount int32
}

func NewWatermelonObserver(w world.Interface, logger logrus.FieldLogger) Observer {
	return &WatermelonObserver{
		world:  w,
		logger: logger,
	}
}

func (wo *WatermelonObserver) Observe(stop <-chan struct{}) {
	go wo.run(stop)
}

func (wo *WatermelonObserver) run(stop <-chan struct{}) {
	wo.init()

	go wo.listen(stop)
	go wo.schedule(stop)
}

func (wo *WatermelonObserver) init() {
	maxWatermelonCount := wo.calcMaxWatermelonCount()

	wo.logger.WithFields(logrus.Fields{
		"watermelon_count": maxWatermelonCount,
	}).Debug("watermelon observer")

	wo.maxWatermelonCount = maxWatermelonCount
}

// calcMaxWatermelonCount returns max possible watermelon count
func (wo *WatermelonObserver) calcMaxWatermelonCount() int32 {
	var size = int32(wo.world.Size())
	var maxWatermelonCount = size / oneWatermelonArea
	return maxWatermelonCount
}

func (wo *WatermelonObserver) listen(stop <-chan struct{}) {
	for event := range wo.world.Events(stop, chanWatermelonObserverEventsBuffer) {
		wo.handleEvent(event)
	}
}

func (wo *WatermelonObserver) handleEvent(event world.Event) {
	if event.Type != world.EventTypeObjectDelete {
		return
	}

	if _, ok := event.Payload.(*watermelon.Watermelon); ok {
		atomic.AddInt32(&wo.watermelonCount, -1)
	}
}

func (wo *WatermelonObserver) schedule(stop <-chan struct{}) {
	ticker := time.NewTicker(addWatermelonDelay)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			wo.addWatermelons()
		case <-stop:
			return
		}
	}
}

func (wo *WatermelonObserver) addWatermelons() {
	var watermelonsAdded = 0

	for {
		if atomic.LoadInt32(&wo.watermelonCount) >= wo.maxWatermelonCount {
			return
		}

		if watermelonsAdded >= addWatermelonsDuringTickLimit {
			return
		}

		if _, err := watermelon.NewWatermelon(wo.world); err != nil {
			wo.logger.WithError(err).Error("cannot create watermelon")
			return
		}

		atomic.AddInt32(&wo.watermelonCount, 1)
		watermelonsAdded++
	}
}
<commit_msg>Fix watermelon observer to listen in run goroutine<commit_after>package observers

import (
	"sync/atomic"
	"time"

	"github.com/sirupsen/logrus"

	"github.com/ivan1993spb/snake-server/objects/watermelon"
	"github.com/ivan1993spb/snake-server/world"
)

const chanWatermelonObserverEventsBuffer = 64

const addWatermelonDelay = time.Second * 15

const addWatermelonsDuringTickLimit = 2

const oneWatermelonArea = 200

type WatermelonObserver struct {
	world  world.Interface
	logger logrus.FieldLogger

	watermelonCount    int32
	maxWatermelonCount int32
}

func NewWatermelonObserver(w world.Interface, logger logrus.FieldLogger) Observer {
	return &WatermelonObserver{
		world:  w,
		logger: logger,
	}
}

func (wo *WatermelonObserver) Observe(stop <-chan struct{}) {
	go wo.run(stop)
}

func (wo *WatermelonObserver) run(stop <-chan struct{}) {
	wo.init()

	go wo.schedule(stop)

	wo.listen(stop)
}

func (wo *WatermelonObserver) init() {
	maxWatermelonCount := wo.calcMaxWatermelonCount()

	wo.logger.WithFields(logrus.Fields{
		"watermelon_count": maxWatermelonCount,
	}).Debug("watermelon observer")

	wo.maxWatermelonCount = maxWatermelonCount
}

// calcMaxWatermelonCount returns max possible watermelon count
func (wo *WatermelonObserver) calcMaxWatermelonCount() int32 {
	var size = int32(wo.world.Size())
	var maxWatermelonCount = size / oneWatermelonArea
	return maxWatermelonCount
}

func (wo *WatermelonObserver) listen(stop <-chan struct{}) {
	for event := range wo.world.Events(stop, chanWatermelonObserverEventsBuffer) {
		wo.handleEvent(event)
	}
}

func (wo *WatermelonObserver) handleEvent(event world.Event) {
	if event.Type != world.EventTypeObjectDelete {
		return
	}

	if _, ok := event.Payload.(*watermelon.Watermelon); ok {
		atomic.AddInt32(&wo.watermelonCount, -1)
	}
}

func (wo *WatermelonObserver) schedule(stop <-chan struct{}) {
	ticker := time.NewTicker(addWatermelonDelay)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			wo.addWatermelons()
		case <-stop:
			return
		}
	}
}

func (wo *WatermelonObserver) addWatermelons() {
	var watermelonsAdded = 0

	for {
		if atomic.LoadInt32(&wo.watermelonCount) >= wo.maxWatermelonCount {
			return
		}

		if watermelonsAdded >= addWatermelonsDuringTickLimit {
			return
		}

		if _, err := watermelon.NewWatermelon(wo.world); err != nil {
			wo.logger.WithError(err).Error("cannot create watermelon")
			return
		}

		atomic.AddInt32(&wo.watermelonCount, 1)
		watermelonsAdded++
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Jetstack cert-manager contributors.

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 certificate

import (
	"flag"
	"time"

	"github.com/jetstack/cert-manager/test/util/generate"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	corev1 "k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha1"
	cmutil "github.com/jetstack/cert-manager/pkg/util"
	"github.com/jetstack/cert-manager/test/e2e/framework"
	"github.com/jetstack/cert-manager/test/util"
)

var cloudflareEmail string
var cloudflareAPIKey string

func init() {
	flag.StringVar(&cloudflareEmail, "cloudflare-email", "", ""+
		"The cloud API email address. If not specified, DNS tests will be skipped")
	flag.StringVar(&cloudflareAPIKey, "cloudflare-api-key", "", ""+
		"The cloudflare API key. If not specified, DNS tests will be skipped")
}

var _ = framework.CertManagerDescribe("ACME Certificate (DNS01)", func() {
	f := framework.NewDefaultFramework("create-acme-certificate-dns01")

	issuerName := "test-acme-issuer"
	certificateName := "test-acme-certificate"
	certificateSecretName := "test-acme-certificate"
	cloudflareSecretName := "cloudflare-api-token"

	BeforeEach(func() {
		if cloudflareAPIKey == "" {
			framework.Skipf("Skipping DNS01 provider tests as cloudflare api key is blank")
			return
		}

		By("Verifying there is no existing ACME private key")
		_, err := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Get(testingACMEPrivateKey, metav1.GetOptions{})
		Expect(err).To(MatchError(apierrors.NewNotFound(corev1.Resource("secrets"), testingACMEPrivateKey)))
		By("Verifying there is no existing TLS certificate secret")
		_, err = f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Get(certificateSecretName, metav1.GetOptions{})
		Expect(err).To(MatchError(apierrors.NewNotFound(corev1.Resource("secrets"), certificateSecretName)))

		By("Creating the cloudflare api key fixture")
		cfSecret := &corev1.Secret{
			ObjectMeta: metav1.ObjectMeta{
				Name:      cloudflareSecretName,
				Namespace: f.Namespace.Name,
			},
			Data: map[string][]byte{
				"api-key": []byte(cloudflareAPIKey),
			},
		}
		_, err = f.KubeClientSet.CoreV1().Secrets(cfSecret.Namespace).Create(cfSecret)
		Expect(err).NotTo(HaveOccurred())

		By("Creating an Issuer")
		issuer := generate.Issuer(generate.IssuerConfig{
			Name:              issuerName,
			Namespace:         f.Namespace.Name,
			ACMESkipTLSVerify: true,
			// Hardcode this to the acme staging endpoint now due to issues with pebble dns resolution
			ACMEServer: "https://acme-staging-v02.api.letsencrypt.org/directory",
			// ACMEServer:         framework.TestContext.ACMEURL,
			ACMEEmail:          testingACMEEmail,
			ACMEPrivateKeyName: testingACMEPrivateKey,
			DNS01: &v1alpha1.ACMEIssuerDNS01Config{
				Providers: []v1alpha1.ACMEIssuerDNS01Provider{
					{
						Name: "cloudflare",
						Cloudflare: &v1alpha1.ACMEIssuerDNS01ProviderCloudflare{
							Email: cloudflareEmail,
							APIKey: v1alpha1.SecretKeySelector{
								LocalObjectReference: v1alpha1.LocalObjectReference{
									Name: cloudflareSecretName,
								},
								Key: "api-key",
							},
						},
					},
				},
			},
		})
		issuer, err = f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(issuer)
		Expect(err).NotTo(HaveOccurred())
		By("Waiting for Issuer to become Ready")
		err = util.WaitForIssuerCondition(f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name),
			issuerName,
			v1alpha1.IssuerCondition{
				Type:   v1alpha1.IssuerConditionReady,
				Status: v1alpha1.ConditionTrue,
			})
		Expect(err).NotTo(HaveOccurred())
		By("Verifying the ACME account URI is set")
		err = util.WaitForIssuerStatusFunc(f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name),
			issuerName,
			func(i *v1alpha1.Issuer) (bool, error) {
				if i.GetStatus().ACMEStatus().URI == "" {
					return false, nil
				}
				return true, nil
			})
		Expect(err).NotTo(HaveOccurred())
		By("Verifying ACME account private key exists")
		secret, err := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Get(testingACMEPrivateKey, metav1.GetOptions{})
		Expect(err).NotTo(HaveOccurred())
		if len(secret.Data) != 1 {
			Fail("Expected 1 key in ACME account private key secret, but there was %d", len(secret.Data))
		}
	})

	AfterEach(func() {
		By("Cleaning up")
		f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Delete(issuerName, nil)
		f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Delete(testingACMEPrivateKey, nil)
		f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Delete(cloudflareSecretName, nil)
		f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Delete(certificateSecretName, nil)
	})

	It("should obtain a signed certificate for a regular domain", func() {
		By("Creating a Certificate")

		certClient := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name)
		secretClient := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name)

		dnsName := cmutil.RandStringRunes(5) + "." + util.ACMECloudflareDomain
		cert := generate.Certificate(generate.CertificateConfig{
			Name:       certificateName,
			Namespace:  f.Namespace.Name,
			SecretName: certificateSecretName,
			IssuerName: issuerName,
			DNSNames:   []string{dnsName},
			SolverConfig: v1alpha1.SolverConfig{
				DNS01: &v1alpha1.DNS01SolverConfig{
					Provider: "cloudflare",
				},
			},
		})
		cert, err := certClient.Create(cert)
		Expect(err).NotTo(HaveOccurred())
		err = util.WaitCertificateIssuedValid(certClient, secretClient, certificateName, time.Minute*5)
		Expect(err).NotTo(HaveOccurred())
	})

	It("should obtain a signed certificate for a wildcard domain", func() {
		By("Creating a Certificate")

		certClient := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name)
		secretClient := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name)

		dnsName := cmutil.RandStringRunes(5) + "." + util.ACMECloudflareDomain
		cert := generate.Certificate(generate.CertificateConfig{
			Name:       certificateName,
			Namespace:  f.Namespace.Name,
			SecretName: certificateSecretName,
			IssuerName: issuerName,
			DNSNames:   []string{"*." + dnsName},
			SolverConfig: v1alpha1.SolverConfig{
				DNS01: &v1alpha1.DNS01SolverConfig{
					Provider: "cloudflare",
				},
			},
		})
		cert, err := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name).Create(cert)
		Expect(err).NotTo(HaveOccurred())
		err = util.WaitCertificateIssuedValid(certClient, secretClient, certificateName, time.Minute*5)
		Expect(err).NotTo(HaveOccurred())
	})

	It("should obtain a signed certificate for a wildcard and apex domain", func() {
		By("Creating a Certificate")

		certClient := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name)
		secretClient := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name)

		dnsName := cmutil.RandStringRunes(5) + "." + util.ACMECloudflareDomain
		cert := generate.Certificate(generate.CertificateConfig{
			Name:       certificateName,
			Namespace:  f.Namespace.Name,
			SecretName: certificateSecretName,
			IssuerName: issuerName,
			DNSNames:   []string{"*." + dnsName, dnsName},
			SolverConfig: v1alpha1.SolverConfig{
				DNS01: &v1alpha1.DNS01SolverConfig{
					Provider: "cloudflare",
				},
			},
		})
		cert, err := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name).Create(cert)
		Expect(err).NotTo(HaveOccurred())
		// use a longer timeout for this, as it requires performing 2 dns validations in serial
		err = util.WaitCertificateIssuedValid(certClient, secretClient, certificateName, time.Minute*10)
		Expect(err).NotTo(HaveOccurred())
	})
})
<commit_msg>Skip wildcard and apex domain e2e test pending #951<commit_after>/*
Copyright 2018 The Jetstack cert-manager contributors.

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 certificate

import (
	"flag"
	"time"

	"github.com/jetstack/cert-manager/test/util/generate"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	corev1 "k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha1"
	cmutil "github.com/jetstack/cert-manager/pkg/util"
	"github.com/jetstack/cert-manager/test/e2e/framework"
	"github.com/jetstack/cert-manager/test/util"
)

var cloudflareEmail string
var cloudflareAPIKey string

func init() {
	flag.StringVar(&cloudflareEmail, "cloudflare-email", "", ""+
		"The cloud API email address. If not specified, DNS tests will be skipped")
	flag.StringVar(&cloudflareAPIKey, "cloudflare-api-key", "", ""+
		"The cloudflare API key. If not specified, DNS tests will be skipped")
}

var _ = framework.CertManagerDescribe("ACME Certificate (DNS01)", func() {
	f := framework.NewDefaultFramework("create-acme-certificate-dns01")

	issuerName := "test-acme-issuer"
	certificateName := "test-acme-certificate"
	certificateSecretName := "test-acme-certificate"
	cloudflareSecretName := "cloudflare-api-token"

	BeforeEach(func() {
		if cloudflareAPIKey == "" {
			framework.Skipf("Skipping DNS01 provider tests as cloudflare api key is blank")
			return
		}

		By("Verifying there is no existing ACME private key")
		_, err := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Get(testingACMEPrivateKey, metav1.GetOptions{})
		Expect(err).To(MatchError(apierrors.NewNotFound(corev1.Resource("secrets"), testingACMEPrivateKey)))
		By("Verifying there is no existing TLS certificate secret")
		_, err = f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Get(certificateSecretName, metav1.GetOptions{})
		Expect(err).To(MatchError(apierrors.NewNotFound(corev1.Resource("secrets"), certificateSecretName)))

		By("Creating the cloudflare api key fixture")
		cfSecret := &corev1.Secret{
			ObjectMeta: metav1.ObjectMeta{
				Name:      cloudflareSecretName,
				Namespace: f.Namespace.Name,
			},
			Data: map[string][]byte{
				"api-key": []byte(cloudflareAPIKey),
			},
		}
		_, err = f.KubeClientSet.CoreV1().Secrets(cfSecret.Namespace).Create(cfSecret)
		Expect(err).NotTo(HaveOccurred())

		By("Creating an Issuer")
		issuer := generate.Issuer(generate.IssuerConfig{
			Name:              issuerName,
			Namespace:         f.Namespace.Name,
			ACMESkipTLSVerify: true,
			// Hardcode this to the acme staging endpoint now due to issues with pebble dns resolution
			ACMEServer: "https://acme-staging-v02.api.letsencrypt.org/directory",
			// ACMEServer:         framework.TestContext.ACMEURL,
			ACMEEmail:          testingACMEEmail,
			ACMEPrivateKeyName: testingACMEPrivateKey,
			DNS01: &v1alpha1.ACMEIssuerDNS01Config{
				Providers: []v1alpha1.ACMEIssuerDNS01Provider{
					{
						Name: "cloudflare",
						Cloudflare: &v1alpha1.ACMEIssuerDNS01ProviderCloudflare{
							Email: cloudflareEmail,
							APIKey: v1alpha1.SecretKeySelector{
								LocalObjectReference: v1alpha1.LocalObjectReference{
									Name: cloudflareSecretName,
								},
								Key: "api-key",
							},
						},
					},
				},
			},
		})
		issuer, err = f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(issuer)
		Expect(err).NotTo(HaveOccurred())
		By("Waiting for Issuer to become Ready")
		err = util.WaitForIssuerCondition(f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name),
			issuerName,
			v1alpha1.IssuerCondition{
				Type:   v1alpha1.IssuerConditionReady,
				Status: v1alpha1.ConditionTrue,
			})
		Expect(err).NotTo(HaveOccurred())
		By("Verifying the ACME account URI is set")
		err = util.WaitForIssuerStatusFunc(f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name),
			issuerName,
			func(i *v1alpha1.Issuer) (bool, error) {
				if i.GetStatus().ACMEStatus().URI == "" {
					return false, nil
				}
				return true, nil
			})
		Expect(err).NotTo(HaveOccurred())
		By("Verifying ACME account private key exists")
		secret, err := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Get(testingACMEPrivateKey, metav1.GetOptions{})
		Expect(err).NotTo(HaveOccurred())
		if len(secret.Data) != 1 {
			Fail("Expected 1 key in ACME account private key secret, but there was %d", len(secret.Data))
		}
	})

	AfterEach(func() {
		By("Cleaning up")
		f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Delete(issuerName, nil)
		f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Delete(testingACMEPrivateKey, nil)
		f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Delete(cloudflareSecretName, nil)
		f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Delete(certificateSecretName, nil)
	})

	It("should obtain a signed certificate for a regular domain", func() {
		By("Creating a Certificate")

		certClient := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name)
		secretClient := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name)

		dnsName := cmutil.RandStringRunes(5) + "." + util.ACMECloudflareDomain
		cert := generate.Certificate(generate.CertificateConfig{
			Name:       certificateName,
			Namespace:  f.Namespace.Name,
			SecretName: certificateSecretName,
			IssuerName: issuerName,
			DNSNames:   []string{dnsName},
			SolverConfig: v1alpha1.SolverConfig{
				DNS01: &v1alpha1.DNS01SolverConfig{
					Provider: "cloudflare",
				},
			},
		})
		cert, err := certClient.Create(cert)
		Expect(err).NotTo(HaveOccurred())
		err = util.WaitCertificateIssuedValid(certClient, secretClient, certificateName, time.Minute*5)
		Expect(err).NotTo(HaveOccurred())
	})

	It("should obtain a signed certificate for a wildcard domain", func() {
		By("Creating a Certificate")

		certClient := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name)
		secretClient := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name)

		dnsName := cmutil.RandStringRunes(5) + "." + util.ACMECloudflareDomain
		cert := generate.Certificate(generate.CertificateConfig{
			Name:       certificateName,
			Namespace:  f.Namespace.Name,
			SecretName: certificateSecretName,
			IssuerName: issuerName,
			DNSNames:   []string{"*." + dnsName},
			SolverConfig: v1alpha1.SolverConfig{
				DNS01: &v1alpha1.DNS01SolverConfig{
					Provider: "cloudflare",
				},
			},
		})
		cert, err := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name).Create(cert)
		Expect(err).NotTo(HaveOccurred())
		err = util.WaitCertificateIssuedValid(certClient, secretClient, certificateName, time.Minute*5)
		Expect(err).NotTo(HaveOccurred())
	})

	It("should obtain a signed certificate for a wildcard and apex domain", func() {
		// We skip this test for now, as it will always fail until we implement
		// 'serial' solving of ACME challenges.
		// See https://github.com/jetstack/cert-manager/issues/951 for more info.
		// This test **must** be enabled before a new release can be cut.
		Skip("Test disabled pending #951 being implemented")

		By("Creating a Certificate")

		certClient := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name)
		secretClient := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name)

		dnsName := cmutil.RandStringRunes(5) + "." + util.ACMECloudflareDomain
		cert := generate.Certificate(generate.CertificateConfig{
			Name:       certificateName,
			Namespace:  f.Namespace.Name,
			SecretName: certificateSecretName,
			IssuerName: issuerName,
			DNSNames:   []string{"*." + dnsName, dnsName},
			SolverConfig: v1alpha1.SolverConfig{
				DNS01: &v1alpha1.DNS01SolverConfig{
					Provider: "cloudflare",
				},
			},
		})
		cert, err := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name).Create(cert)
		Expect(err).NotTo(HaveOccurred())
		// use a longer timeout for this, as it requires performing 2 dns validations in serial
		err = util.WaitCertificateIssuedValid(certClient, secretClient, certificateName, time.Minute*10)
		Expect(err).NotTo(HaveOccurred())
	})
})
<|endoftext|>


<commit_before>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom

import (
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"fmt"
)

func NewTransaction(name string) error {
	params := transactionRequest{Name: name}
	req := NewJSON2Request("new-transaction", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func DeleteTransaction(name string) error {
	params := transactionRequest{Name: name}
	req := NewJSON2Request("delete-transaction", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func ListTransactions() ([]string, error) {
	type transactionResponse struct {
		Name string `json:"tx-name"`
	}

	type transactionsResponse struct {
		Transactions []transactionResponse `json:"transactions"`
	}

	req := NewJSON2Request("transactions", apiCounter(), nil)
	resp, err := walletRequest(req)
	if err != nil {
		return nil, err
	}
	if resp.Error != nil {
		return nil, resp.Error
	}

	r := make([]string, 0)
	txs := new(transactionsResponse)
	if err := json.Unmarshal(resp.JSONResult(), txs); err != nil {
		return nil, err
	}
	for _, tx := range txs.Transactions {
		r = append(r, tx.Name)
	}
	return r, nil
}

func AddTransactionInput(name, address string, amount uint64) error {
	if AddressStringType(address) != FactoidPub {
		return fmt.Errorf("%s is not a Factoid address", address)
	}

	params := transactionValueRequest{
		Name:    name,
		Address: address,
		Amount:  amount}
	req := NewJSON2Request("add-input", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func AddTransactionOutput(name, address string, amount uint64) error {
	if AddressStringType(address) != FactoidPub {
		return fmt.Errorf("%s is not a Factoid address", address)
	}

	params := transactionValueRequest{
		Name:    name,
		Address: address,
		Amount:  amount}
	req := NewJSON2Request("add-output", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func AddTransactionECOutput(name, address string, amount uint64) error {
	if AddressStringType(address) != ECPub {
		return fmt.Errorf("%s is not an Entry Credit address", address)
	}

	params := transactionValueRequest{
		Name:    name,
		Address: address,
		Amount:  amount}
	req := NewJSON2Request("add-ec-output", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func AddTransactionFee(name, address string) error {
	if AddressStringType(address) != FactoidPub {
		return fmt.Errorf("%s is not a Factoid address", address)
	}

	params := transactionValueRequest{
		Name:    name,
		Address: address}
	req := NewJSON2Request("add-fee", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func SubTransactionFee(name, address string) error {
	params := transactionValueRequest{
		Name:    name,
		Address: address}
	req := NewJSON2Request("sub-fee", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func SignTransaction(name string) error {
	params := transactionRequest{Name: name}
	req := NewJSON2Request("sign-transaction", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func ComposeTransaction(name string) ([]byte, error) {
	params := transactionRequest{Name: name}
	req := NewJSON2Request("compose-transaction", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return nil, err
	}
	if resp.Error != nil {
		return nil, resp.Error
	}

	return resp.JSONResult(), nil
}

func SendTransaction(name string) error {
	params := transactionRequest{Name: name}

	wreq := NewJSON2Request("compose-transaction", apiCounter(), params)
	wresp, err := walletRequest(wreq)
	if err != nil {
		return err
	}
	if wresp.Error != nil {
		return wresp.Error
	}

	freq := new(JSON2Request)
	json.Unmarshal(wresp.JSONResult(), freq)
	fresp, err := factomdRequest(freq)
	if err != nil {
		return err
	}
	if fresp.Error != nil {
		return fresp.Error
	}
	if err := DeleteTransaction(name); err != nil {
		return err
	}

	return nil
}

func SendFactoid(from, to string, ammount uint64) error {
	n := make([]byte, 16)
	if _, err := rand.Read(n); err != nil {
		return err
	}
	name := hex.EncodeToString(n)
	if err := NewTransaction(name); err != nil {
		return err
	}
	if err := AddTransactionInput(name, from, ammount); err != nil {
		return err
	}
	if err := AddTransactionOutput(name, to, ammount); err != nil {
		return err
	}
	if err := AddTransactionFee(name, from); err != nil {
		return err
	}
	if err := SignTransaction(name); err != nil {
		return err
	}
	if err := SendTransaction(name); err != nil {
		return err
	}

	return nil
}

func BuyEC(from, to string, ammount uint64) error {
	n := make([]byte, 16)
	if _, err := rand.Read(n); err != nil {
		return err
	}
	name := hex.EncodeToString(n)
	if err := NewTransaction(name); err != nil {
		return err
	}
	if err := AddTransactionInput(name, from, ammount); err != nil {
		return err
	}
	if err := AddTransactionECOutput(name, to, ammount); err != nil {
		return err
	}
	if err := AddTransactionFee(name, from); err != nil {
		return err
	}
	if err := SignTransaction(name); err != nil {
		return err
	}
	if err := SendTransaction(name); err != nil {
		return err
	}

	return nil
}
<commit_msg>updated listtransactions to return verbose tx info<commit_after>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom

import (
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"fmt"
)

func NewTransaction(name string) error {
	params := transactionRequest{Name: name}
	req := NewJSON2Request("new-transaction", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func DeleteTransaction(name string) error {
	params := transactionRequest{Name: name}
	req := NewJSON2Request("delete-transaction", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func ListTransactions() ([]string, error) {
	type transactionResponse struct {
		Name        string `json:"tx-name"`
		Transaction string `json:"transaction"`
	}

	type transactionsResponse struct {
		Transactions []transactionResponse `json:"transactions"`
	}

	req := NewJSON2Request("transactions", apiCounter(), nil)
	resp, err := walletRequest(req)
	if err != nil {
		return nil, err
	}
	if resp.Error != nil {
		return nil, resp.Error
	}

	r := make([]string, 0)
	txs := new(transactionsResponse)
	if err := json.Unmarshal(resp.JSONResult(), txs); err != nil {
		return nil, err
	}
	for _, tx := range txs.Transactions {
		r = append(r, tx.Name, tx.Transaction)
	}
	return r, nil
}

func AddTransactionInput(name, address string, amount uint64) error {
	if AddressStringType(address) != FactoidPub {
		return fmt.Errorf("%s is not a Factoid address", address)
	}

	params := transactionValueRequest{
		Name:    name,
		Address: address,
		Amount:  amount}
	req := NewJSON2Request("add-input", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func AddTransactionOutput(name, address string, amount uint64) error {
	if AddressStringType(address) != FactoidPub {
		return fmt.Errorf("%s is not a Factoid address", address)
	}

	params := transactionValueRequest{
		Name:    name,
		Address: address,
		Amount:  amount}
	req := NewJSON2Request("add-output", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func AddTransactionECOutput(name, address string, amount uint64) error {
	if AddressStringType(address) != ECPub {
		return fmt.Errorf("%s is not an Entry Credit address", address)
	}

	params := transactionValueRequest{
		Name:    name,
		Address: address,
		Amount:  amount}
	req := NewJSON2Request("add-ec-output", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func AddTransactionFee(name, address string) error {
	if AddressStringType(address) != FactoidPub {
		return fmt.Errorf("%s is not a Factoid address", address)
	}

	params := transactionValueRequest{
		Name:    name,
		Address: address}
	req := NewJSON2Request("add-fee", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func SubTransactionFee(name, address string) error {
	params := transactionValueRequest{
		Name:    name,
		Address: address}
	req := NewJSON2Request("sub-fee", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func SignTransaction(name string) error {
	params := transactionRequest{Name: name}
	req := NewJSON2Request("sign-transaction", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func ComposeTransaction(name string) ([]byte, error) {
	params := transactionRequest{Name: name}
	req := NewJSON2Request("compose-transaction", apiCounter(), params)

	resp, err := walletRequest(req)
	if err != nil {
		return nil, err
	}
	if resp.Error != nil {
		return nil, resp.Error
	}

	return resp.JSONResult(), nil
}

func SendTransaction(name string) error {
	params := transactionRequest{Name: name}

	wreq := NewJSON2Request("compose-transaction", apiCounter(), params)
	wresp, err := walletRequest(wreq)
	if err != nil {
		return err
	}
	if wresp.Error != nil {
		return wresp.Error
	}

	freq := new(JSON2Request)
	json.Unmarshal(wresp.JSONResult(), freq)
	fresp, err := factomdRequest(freq)
	if err != nil {
		return err
	}
	if fresp.Error != nil {
		return fresp.Error
	}
	if err := DeleteTransaction(name); err != nil {
		return err
	}

	return nil
}

func SendFactoid(from, to string, ammount uint64) error {
	n := make([]byte, 16)
	if _, err := rand.Read(n); err != nil {
		return err
	}
	name := hex.EncodeToString(n)
	if err := NewTransaction(name); err != nil {
		return err
	}
	if err := AddTransactionInput(name, from, ammount); err != nil {
		return err
	}
	if err := AddTransactionOutput(name, to, ammount); err != nil {
		return err
	}
	if err := AddTransactionFee(name, from); err != nil {
		return err
	}
	if err := SignTransaction(name); err != nil {
		return err
	}
	if err := SendTransaction(name); err != nil {
		return err
	}

	return nil
}

func BuyEC(from, to string, ammount uint64) error {
	n := make([]byte, 16)
	if _, err := rand.Read(n); err != nil {
		return err
	}
	name := hex.EncodeToString(n)
	if err := NewTransaction(name); err != nil {
		return err
	}
	if err := AddTransactionInput(name, from, ammount); err != nil {
		return err
	}
	if err := AddTransactionECOutput(name, to, ammount); err != nil {
		return err
	}
	if err := AddTransactionFee(name, from); err != nil {
		return err
	}
	if err := SignTransaction(name); err != nil {
		return err
	}
	if err := SendTransaction(name); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Pulcy.
//
// 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 service

import (
	"encoding/base64"

	k8s "github.com/YakLabs/k8s-client"
	retry "github.com/pulcy/vault-monkey/deps/github.com/giantswarm/retry-go"
)

// CreateOrUpdateKubernetesSecret extracts one or more secrets and updates fields in a Kubernetes secret.
func (c *AuthenticatedVaultClient) CreateOrUpdateKubernetesSecret(client *K8sClient, secretName string, secrets ...EnvSecret) error {
	namespace, err := getKubernetesNamespace()
	if err != nil {
		return maskAny(err)
	}

	// Get existing secret or initialize new one
	create := false
	secret, err := client.getKubernetesSecret(secretName)
	if err != nil {
		create = true
		secret.ObjectMeta = k8s.ObjectMeta{
			Name:      secretName,
			Namespace: namespace,
		}
	}
	if secret.Data == nil {
		secret.Data = make(map[string][]byte)
	}

	// Fetch secrets
	for _, envSec := range secrets {
		var value string
		op := func() error {
			var err error
			value, err = c.extractSecret(envSec.SecretPath, envSec.SecretField)
			if err != nil {
				return maskAny(err)
			}
			return nil
		}
		if err := retry.Do(op, retry.RetryChecker(IsVault), retry.MaxTries(3)); err != nil {
			return maskAny(err)
		}
		encodedValue := base64.StdEncoding.EncodeToString([]byte(value))
		secret.Data[envSec.EnvironmentKey] = []byte(encodedValue)
	}

	// Create/update secret
	if err := client.setKubernetesSecret(secretName, secret, create); err != nil {
		return maskAny(err)
	}

	return nil
}
<commit_msg>Fixed secret data encoding<commit_after>// Copyright (c) 2016 Pulcy.
//
// 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 service

import (
	k8s "github.com/YakLabs/k8s-client"
	retry "github.com/pulcy/vault-monkey/deps/github.com/giantswarm/retry-go"
)

// CreateOrUpdateKubernetesSecret extracts one or more secrets and updates fields in a Kubernetes secret.
func (c *AuthenticatedVaultClient) CreateOrUpdateKubernetesSecret(client *K8sClient, secretName string, secrets ...EnvSecret) error {
	namespace, err := getKubernetesNamespace()
	if err != nil {
		return maskAny(err)
	}

	// Get existing secret or initialize new one
	create := false
	secret, err := client.getKubernetesSecret(secretName)
	if err != nil {
		create = true
		secret.ObjectMeta = k8s.ObjectMeta{
			Name:      secretName,
			Namespace: namespace,
		}
	}
	if secret.Data == nil {
		secret.Data = make(map[string][]byte)
	}

	// Fetch secrets
	for _, envSec := range secrets {
		var value string
		op := func() error {
			var err error
			value, err = c.extractSecret(envSec.SecretPath, envSec.SecretField)
			if err != nil {
				return maskAny(err)
			}
			return nil
		}
		if err := retry.Do(op, retry.RetryChecker(IsVault), retry.MaxTries(3)); err != nil {
			return maskAny(err)
		}
		secret.Data[envSec.EnvironmentKey] = []byte(value)
	}

	// Create/update secret
	if err := client.setKubernetesSecret(secretName, secret, create); err != nil {
		return maskAny(err)
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"os"
	"os/exec"

	"github.com/antongulenko/http-isolation-proxy/services"
)

func main() {
	num_users := flag.Uint("users", 5, "Number of simulated people")
	bank := flag.String("bank", "localhost:9001", "Bank endpoint")
	var shops services.StringSlice
	flag.Var(&shops, "shop", "Shop endpoint(s)")
	flag.Parse()
	if len(shops) == 0 {
		log.Fatalln("Specify at least one -shop")
	}
	pool := NewPool(*bank, shops)
	pool.Start(int(*num_users))

	defer resetKeyboard()
	go readKeyboard(func(b byte) {
		switch b {
		case 65: // Up
			pool.StartOne()
		case 66: // Down
			pool.PauseOne()
		case 67: // Right
			pool.Start(10)
		case 68: // Left
			pool.Pause(10)
		case 10: // Enter
			pool.Terminate()
		}
	})
	pool.Wait()
}

func readKeyboard(ex func(b byte)) {
	exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
	exec.Command("stty", "-F", "/dev/tty", "-echo").Run()

	for {
		buf := make([]byte, 1)
		i, err := os.Stdin.Read(buf)
		if i == 1 && err == nil {
			ex(buf[0])
		}
	}
}

func resetKeyboard() {
	exec.Command("stty", "-F", "/dev/tty", "echo").Run()
}
<commit_msg>Added flag for automatic termination of experiment<commit_after>package main

import (
	"flag"
	"log"
	"os"
	"os/exec"
	"time"

	"github.com/antongulenko/http-isolation-proxy/services"
)

func main() {
	num_users := flag.Uint("users", 5, "Number of simulated people")
	bank := flag.String("bank", "localhost:9001", "Bank endpoint")
	timeout := flag.Duration("timeout", 0, "Timeout for automatically stopping load generation")
	var shops services.StringSlice
	flag.Var(&shops, "shop", "Shop endpoint(s)")
	flag.Parse()
	if len(shops) == 0 {
		log.Fatalln("Specify at least one -shop")
	}
	pool := NewPool(*bank, shops)
	pool.Start(int(*num_users))

	defer resetKeyboard()
	go readKeyboard(func(b byte) {
		switch b {
		case 65: // Up
			pool.StartOne()
		case 66: // Down
			pool.PauseOne()
		case 67: // Right
			pool.Start(10)
		case 68: // Left
			pool.Pause(10)
		case 10: // Enter
			pool.Terminate()
		}
	})
	if *timeout > 0 {
		services.L.Warnf("Terminating automatically after %v", timeout)
		time.AfterFunc(*timeout,
			func() {
				services.L.Warnf("Timer of %v expired. Terminating...", timeout)
				pool.Terminate()
			})
	}
	pool.Wait()
}

func readKeyboard(ex func(b byte)) {
	exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
	exec.Command("stty", "-F", "/dev/tty", "-echo").Run()

	for {
		buf := make([]byte, 1)
		i, err := os.Stdin.Read(buf)
		if i == 1 && err == nil {
			ex(buf[0])
		}
	}
}

func resetKeyboard() {
	exec.Command("stty", "-F", "/dev/tty", "echo").Run()
}
<|endoftext|>