<commit_before>package dnsimple

import (
	"fmt"
	"net/http"
	"reflect"
	"strings"
	"testing"
)

func TestRegistrarService_IsAvailable_available(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domains/example.com/check", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprint(w, `{"name":"example.com", "status":"available"}`)
	})

	available, err := client.Registrar.IsAvailable("example.com")

	if err != nil {
		t.Errorf("Registrar.IsAvailable check returned %v", err)
	}

	if !available {
		t.Errorf("Registrar.IsAvailable returned false, want true")
	}
}

func TestRegistrarService_IsAvailable_unavailable(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domains/example.com/check", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, `{"name":"example.com", "status":"unavailable"}`)
	})

	available, err := client.Registrar.IsAvailable("example.com")

	if err != nil {
		t.Errorf("Registrar.IsAvailable check returned %v", err)
	}

	if available {
		t.Errorf("Registrar.IsAvailable returned true, want false")
	}
}

func TestRegistrarService_IsAvailable_failed400(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domains/example.com/check", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprint(w, `{"message":"Invalid request"}`)
	})

	_, err := client.Registrar.IsAvailable("example.com")

	if err == nil {
		t.Errorf("Registrar.IsAvailable expected error to be returned")
	}

	if match := "400 Invalid request"; !strings.Contains(err.Error(), match) {
		t.Errorf("Registrar.IsAvailable returned %+v, should match %+v", err, match)
	}
}

func TestRegistrarService_Register(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domain_registrations", func(w http.ResponseWriter, r *http.Request) {
		want := make(map[string]interface{})
		want["domain"] = map[string]interface{}{"name": "example.com", "registrant_id": float64(21)}

		testMethod(t, r, "POST")
		testRequestJSON(t, r, want)

		w.WriteHeader(http.StatusCreated)
		fmt.Fprint(w, `{"domain": {"id":1, "name":"example.com"}}`)
	})

	domain, _, err := client.Registrar.Register("example.com", 21, nil)

	if err != nil {
		t.Errorf("Registrar.Register returned %v", err)
	}

	want := Domain{Id: 1, Name: "example.com"}
	if !reflect.DeepEqual(domain, want) {
		t.Fatalf("Registrar.Register returned %+v, want %+v", domain, want)
	}
}

func TestRegistrarService_Renew(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domain_renewals", func(w http.ResponseWriter, r *http.Request) {
		want := make(map[string]interface{})
		want["domain"] = map[string]interface{}{"name": "example.com", "renew_whois_privacy": true}

		testMethod(t, r, "POST")
		testRequestJSON(t, r, want)

		fmt.Fprint(w, `{"domain": {"id":1, "name":"example.com"}}`)
	})

	domain, _, err := client.Registrar.Renew("example.com", true)

	if err != nil {
		t.Errorf("Registrar.Renew returned %v", err)
	}

	want := Domain{Id: 1, Name: "example.com"}
	if !reflect.DeepEqual(domain, want) {
		t.Fatalf("Registrar.Renew returned %+v, want %+v", domain, want)
	}
}
<commit_msg>Test registration with extended attributes<commit_after>package dnsimple

import (
	"fmt"
	"net/http"
	"reflect"
	"strings"
	"testing"
)

func TestRegistrarService_IsAvailable_available(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domains/example.com/check", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprint(w, `{"name":"example.com", "status":"available"}`)
	})

	available, err := client.Registrar.IsAvailable("example.com")

	if err != nil {
		t.Errorf("Registrar.IsAvailable check returned %v", err)
	}

	if !available {
		t.Errorf("Registrar.IsAvailable returned false, want true")
	}
}

func TestRegistrarService_IsAvailable_unavailable(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domains/example.com/check", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, `{"name":"example.com", "status":"unavailable"}`)
	})

	available, err := client.Registrar.IsAvailable("example.com")

	if err != nil {
		t.Errorf("Registrar.IsAvailable check returned %v", err)
	}

	if available {
		t.Errorf("Registrar.IsAvailable returned true, want false")
	}
}

func TestRegistrarService_IsAvailable_failed400(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domains/example.com/check", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprint(w, `{"message":"Invalid request"}`)
	})

	_, err := client.Registrar.IsAvailable("example.com")

	if err == nil {
		t.Errorf("Registrar.IsAvailable expected error to be returned")
	}

	if match := "400 Invalid request"; !strings.Contains(err.Error(), match) {
		t.Errorf("Registrar.IsAvailable returned %+v, should match %+v", err, match)
	}
}

func TestRegistrarService_Register(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domain_registrations", func(w http.ResponseWriter, r *http.Request) {
		want := make(map[string]interface{})
		want["domain"] = map[string]interface{}{"name": "example.com", "registrant_id": float64(21)}

		testMethod(t, r, "POST")
		testRequestJSON(t, r, want)

		w.WriteHeader(http.StatusCreated)
		fmt.Fprint(w, `{"domain": {"id":1, "name":"example.com"}}`)
	})

	domain, _, err := client.Registrar.Register("example.com", 21, nil)

	if err != nil {
		t.Errorf("Registrar.Register returned %v", err)
	}

	want := Domain{Id: 1, Name: "example.com"}
	if !reflect.DeepEqual(domain, want) {
		t.Fatalf("Registrar.Register returned %+v, want %+v", domain, want)
	}
}

func TestRegistrarService_Register_withExtendedAttributes(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domain_registrations", func(w http.ResponseWriter, r *http.Request) {
		want := make(map[string]interface{})
		want["domain"] = map[string]interface{}{"name": "example.com", "registrant_id": float64(21)}
		want["extended_attribute"] = map[string]interface{}{"us_nexus": "C11", "us_purpose": "P3"}

		testMethod(t, r, "POST")
		testRequestJSON(t, r, want)

		w.WriteHeader(http.StatusCreated)
		fmt.Fprint(w, `{"domain": {"id":1, "name":"example.com"}}`)
	})

	domain, _, err := client.Registrar.Register("example.com", 21, map[string]string{"us_nexus": "C11", "us_purpose": "P3"})

	if err != nil {
		t.Errorf("Registrar.Register returned %v", err)
	}

	want := Domain{Id: 1, Name: "example.com"}
	if !reflect.DeepEqual(domain, want) {
		t.Fatalf("Registrar.Register returned %+v, want %+v", domain, want)
	}
}

func TestRegistrarService_Renew(t *testing.T) {
	setup()
	defer teardown()

	mux.HandleFunc("/v1/domain_renewals", func(w http.ResponseWriter, r *http.Request) {
		want := make(map[string]interface{})
		want["domain"] = map[string]interface{}{"name": "example.com", "renew_whois_privacy": true}

		testMethod(t, r, "POST")
		testRequestJSON(t, r, want)

		fmt.Fprint(w, `{"domain": {"id":1, "name":"example.com"}}`)
	})

	domain, _, err := client.Registrar.Renew("example.com", true)

	if err != nil {
		t.Errorf("Registrar.Renew returned %v", err)
	}

	want := Domain{Id: 1, Name: "example.com"}
	if !reflect.DeepEqual(domain, want) {
		t.Fatalf("Registrar.Renew returned %+v, want %+v", domain, want)
	}
}
<|endoftext|>


<commit_before>package blobstore_delegator

import (
	"fmt"
	bosherr "github.com/cloudfoundry/bosh-utils/errors"
	boshlog "github.com/cloudfoundry/bosh-utils/logger"
	boshretry "github.com/cloudfoundry/bosh-utils/retrystrategy"
	"time"

	httpblobprovider "github.com/cloudfoundry/bosh-agent/agent/httpblobprovider"
	"github.com/cloudfoundry/bosh-utils/blobstore"
	boshcrypto "github.com/cloudfoundry/bosh-utils/crypto"
)

type BlobstoreDelegatorImpl struct {
	h      httpblobprovider.HTTPBlobProvider
	b      blobstore.DigestBlobstore
	logger boshlog.Logger
}

func NewBlobstoreDelegator(hp httpblobprovider.HTTPBlobProvider, bp blobstore.DigestBlobstore, logger boshlog.Logger) *BlobstoreDelegatorImpl {
	return &BlobstoreDelegatorImpl{
		h:      hp,
		b:      bp,
		logger: logger,
	}
}

func (b *BlobstoreDelegatorImpl) Get(digest boshcrypto.Digest, signedURL, blobID string, headers map[string]string) (fileName string, err error) {
	if signedURL == "" {
		if blobID == "" {
			return "", fmt.Errorf("Both signedURL and blobID are blank which is invalid")
		}
		return b.b.Get(blobID, digest)
	}

	getBlobRetryable := boshretry.NewRetryable(func() (bool, error) {
		fileName, err = b.h.Get(signedURL, digest, headers)
		if err != nil {
			return true, bosherr.WrapError(err, "Failed to download blob")
		}
		return false, nil
	})

	attemptRetryStrategy := boshretry.NewAttemptRetryStrategy(3, 5 * time.Second, getBlobRetryable, b.logger)
	err = attemptRetryStrategy.Try()
	if err != nil {
		return "", err
	}

	return fileName, nil
}

func (b *BlobstoreDelegatorImpl) Write(signedURL, path string, headers map[string]string) (string, boshcrypto.MultipleDigest, error) {
	if signedURL == "" {
		return b.b.Create(path)
	}

	digest, err := b.h.Upload(signedURL, path, headers)
	return "", digest, err
}

func (b *BlobstoreDelegatorImpl) CleanUp(signedURL, fileName string) (err error) {
	if signedURL != "" {
		return fmt.Errorf("CleanUp is not supported for signed URLs")
	}
	return b.b.CleanUp(fileName)
}

func (b *BlobstoreDelegatorImpl) Delete(signedURL, blobID string) (err error) {
	if signedURL != "" {
		return fmt.Errorf("Delete is not supported for signed URLs")
	}
	return b.b.Delete(blobID)
}
<commit_msg>Fix code style according to go fmt<commit_after>package blobstore_delegator

import (
	"fmt"
	bosherr "github.com/cloudfoundry/bosh-utils/errors"
	boshlog "github.com/cloudfoundry/bosh-utils/logger"
	boshretry "github.com/cloudfoundry/bosh-utils/retrystrategy"
	"time"

	httpblobprovider "github.com/cloudfoundry/bosh-agent/agent/httpblobprovider"
	"github.com/cloudfoundry/bosh-utils/blobstore"
	boshcrypto "github.com/cloudfoundry/bosh-utils/crypto"
)

type BlobstoreDelegatorImpl struct {
	h      httpblobprovider.HTTPBlobProvider
	b      blobstore.DigestBlobstore
	logger boshlog.Logger
}

func NewBlobstoreDelegator(hp httpblobprovider.HTTPBlobProvider, bp blobstore.DigestBlobstore, logger boshlog.Logger) *BlobstoreDelegatorImpl {
	return &BlobstoreDelegatorImpl{
		h:      hp,
		b:      bp,
		logger: logger,
	}
}

func (b *BlobstoreDelegatorImpl) Get(digest boshcrypto.Digest, signedURL, blobID string, headers map[string]string) (fileName string, err error) {
	if signedURL == "" {
		if blobID == "" {
			return "", fmt.Errorf("Both signedURL and blobID are blank which is invalid")
		}
		return b.b.Get(blobID, digest)
	}

	getBlobRetryable := boshretry.NewRetryable(func() (bool, error) {
		fileName, err = b.h.Get(signedURL, digest, headers)
		if err != nil {
			return true, bosherr.WrapError(err, "Failed to download blob")
		}
		return false, nil
	})

	attemptRetryStrategy := boshretry.NewAttemptRetryStrategy(3, 5*time.Second, getBlobRetryable, b.logger)
	err = attemptRetryStrategy.Try()
	if err != nil {
		return "", err
	}

	return fileName, nil
}

func (b *BlobstoreDelegatorImpl) Write(signedURL, path string, headers map[string]string) (string, boshcrypto.MultipleDigest, error) {
	if signedURL == "" {
		return b.b.Create(path)
	}

	digest, err := b.h.Upload(signedURL, path, headers)
	return "", digest, err
}

func (b *BlobstoreDelegatorImpl) CleanUp(signedURL, fileName string) (err error) {
	if signedURL != "" {
		return fmt.Errorf("CleanUp is not supported for signed URLs")
	}
	return b.b.CleanUp(fileName)
}

func (b *BlobstoreDelegatorImpl) Delete(signedURL, blobID string) (err error) {
	if signedURL != "" {
		return fmt.Errorf("Delete is not supported for signed URLs")
	}
	return b.b.Delete(blobID)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/disintegration/imaging"
	"github.com/minotar/minecraft"
	"image"
	"image/png"
	"io"
)

const (
	HeadX      = 8
	HeadY      = 8
	HeadWidth  = 8
	HeadHeight = 8

	HelmX      = 40
	HelmY      = 8
	HelmWidth  = 8
	HelmHeight = 8

	TorsoX      = 20
	TorsoY      = 20
	TorsoWidth  = 8
	TorsoHeight = 12

	RaX      = 44
	RaY      = 20
	RaWidth  = 4
	RaHeight = 12

	RlX      = 4
	RlY      = 20
	RlWidth  = 4
	RlHeight = 12

	LaX      = 36
	LaY      = 52
	LaWidth  = 4
	LaHeight = 12

	LlX      = 20
	LlY      = 52
	LlWidth  = 4
	LlHeight = 12

	// The height of the 'bust' relative to the width of the body (16)
	BustHeight = 16
)

type mcSkin struct {
	Processed image.Image
	minecraft.Skin
}

func (skin *mcSkin) GetHead() error {
	skin.Processed = cropHead(skin.Image)
	return nil
}

func (skin *mcSkin) GetHelm() error {
	skin.Processed = cropHelm(skin.Image)
	return nil
}

func (skin *mcSkin) RenderUpperBody(all bool) error {
	// Check if 1.8 skin (the max Y bound should be 64)
	render18Skin := true
	bounds := skin.Image.Bounds()
	if bounds.Max.Y != 64 {
		render18Skin = false
	}

	UpperBodyHeight := HeadHeight + TorsoHeight
	UpperBodyShift := TorsoHeight
	if !all {
		//We will make a smaller UpperBody
		UpperBodyHeight = BustHeight
		UpperBodyShift = BustHeight - HeadHeight
	}

	helmImg := cropHelm(skin.Image)
	torsoImg := imaging.Crop(skin.Image, image.Rect(TorsoX, TorsoY, TorsoX+TorsoWidth, TorsoY+UpperBodyShift))
	raImg := imaging.Crop(skin.Image, image.Rect(RaX, RaY, RaX+RaWidth, RaY+UpperBodyShift))

	var laImg image.Image

	// If the skin is 1.8 then we will use the left arms and legs, otherwise flip the right ones and use them.
	if render18Skin {
		laImg = imaging.Crop(skin.Image, image.Rect(LaX, LaY, LaX+LaWidth, LaY+UpperBodyShift))
	} else {
		laImg = imaging.FlipH(raImg)
	}

	// Create a blank canvas for us to draw our bust on
	upperBodyImg := image.NewNRGBA(image.Rect(0, 0, LaWidth+TorsoWidth+RaWidth, UpperBodyHeight))
	// Helm
	fastDraw(upperBodyImg, helmImg.(*image.NRGBA), LaWidth, 0)
	// Torso
	fastDraw(upperBodyImg, torsoImg, LaWidth, HelmHeight)
	// Left Arm
	fastDraw(upperBodyImg, laImg.(*image.NRGBA), 0, HelmHeight)
	// Right Arm
	fastDraw(upperBodyImg, raImg, LaWidth+TorsoWidth, HelmHeight)

	skin.Processed = upperBodyImg
	return nil
}

func (skin *mcSkin) GetBust() error {
	// Go get the upper body but not all of it.
	err := skin.RenderUpperBody(false)
	if err != nil {
		return err
	}

	return nil
}

func (skin *mcSkin) GetBody() error {
	// Check if 1.8 skin (the max Y bound should be 64)
	render18Skin := true
	bounds := skin.Image.Bounds()
	if bounds.Max.Y != 64 {
		render18Skin = false
	}

	// Go get the upper body (all of it).
	err := skin.RenderUpperBody(true)
	if err != nil {
		return err
	}

	rlImg := imaging.Crop(skin.Image, image.Rect(RlX, RlY, RlX+RlWidth, RlY+RlHeight))

	var llImg image.Image

	// If the skin is 1.8 then we will use the left arms and legs, otherwise flip the right ones and use them.
	if render18Skin {
		llImg = imaging.Crop(skin.Image, image.Rect(LlX, LlY, LlX+LlWidth, LlY+LlHeight))
	} else {
		llImg = imaging.FlipH(rlImg)
	}

	// Create a blank canvas for us to draw our body on
	bodyImg := image.NewNRGBA(image.Rect(0, 0, LaWidth+TorsoWidth+RaWidth, HeadHeight+TorsoHeight+LlHeight))
	// Upper Body
	fastDraw(bodyImg, skin.Processed.(*image.NRGBA), 0, 0)
	// Left Leg
	fastDraw(bodyImg, llImg.(*image.NRGBA), LaWidth, HelmHeight+TorsoHeight)
	// Right Leg
	fastDraw(bodyImg, rlImg, LaWidth+LlWidth, HelmHeight+TorsoHeight)

	skin.Processed = bodyImg
	return nil
}

func (skin *mcSkin) WritePNG(w io.Writer) error {
	return png.Encode(w, skin.Processed)
}

func (skin *mcSkin) WriteSkin(w io.Writer) error {
	return png.Encode(w, skin.Image)
}

func (skin *mcSkin) Resize(width uint) {
	skin.Processed = imaging.Resize(skin.Processed, int(width), 0, imaging.NearestNeighbor)
}

func cropHead(img image.Image) image.Image {
	return imaging.Crop(img, image.Rect(HeadX, HeadY, HeadX+HeadWidth, HeadY+HeadHeight))
}

func cropHelm(img image.Image) image.Image {
	headImg := cropHead(img)
	helmImg := imaging.Crop(img, image.Rect(HelmX, HelmY, HelmX+HelmWidth, HelmY+HelmHeight))

	fastDraw(headImg.(*image.NRGBA), helmImg, 0, 0)

	return headImg
}

func fastDraw(dst *image.NRGBA, src *image.NRGBA, x, y int) {
	bounds := src.Bounds()
	maxY := bounds.Max.Y
	maxX := bounds.Max.X * 4

	pointer := dst.PixOffset(x, y)
	for row := 0; row < maxY; row += 1 {
		for i := 0; i < maxX; i += 4 {
			srcPx := row*src.Stride + i
			dstPx := row*dst.Stride + i + pointer
			if src.Pix[srcPx+3] != 0 {
				dst.Pix[dstPx+0] = src.Pix[srcPx+0]
				dst.Pix[dstPx+1] = src.Pix[srcPx+1]
				dst.Pix[dstPx+2] = src.Pix[srcPx+2]
				dst.Pix[dstPx+3] = 0xFF
			}
		}
	}
}
<commit_msg>Put 1.8 Skin check in function<commit_after>package main

import (
	"github.com/disintegration/imaging"
	"github.com/minotar/minecraft"
	"image"
	"image/png"
	"io"
)

const (
	HeadX      = 8
	HeadY      = 8
	HeadWidth  = 8
	HeadHeight = 8

	HelmX      = 40
	HelmY      = 8
	HelmWidth  = 8
	HelmHeight = 8

	TorsoX      = 20
	TorsoY      = 20
	TorsoWidth  = 8
	TorsoHeight = 12

	RaX      = 44
	RaY      = 20
	RaWidth  = 4
	RaHeight = 12

	RlX      = 4
	RlY      = 20
	RlWidth  = 4
	RlHeight = 12

	LaX      = 36
	LaY      = 52
	LaWidth  = 4
	LaHeight = 12

	LlX      = 20
	LlY      = 52
	LlWidth  = 4
	LlHeight = 12

	// The height of the 'bust' relative to the width of the body (16)
	BustHeight = 16
)

type mcSkin struct {
	Processed image.Image
	minecraft.Skin
}

func (skin *mcSkin) GetHead() error {
	skin.Processed = cropHead(skin.Image)
	return nil
}

func (skin *mcSkin) GetHelm() error {
	skin.Processed = cropHelm(skin.Image)
	return nil
}

func (skin *mcSkin) RenderUpperBody(all bool) error {
	UpperBodyHeight := HeadHeight + TorsoHeight
	UpperBodyShift := TorsoHeight
	if !all {
		//We will make a smaller UpperBody
		UpperBodyHeight = BustHeight
		UpperBodyShift = BustHeight - HeadHeight
	}

	helmImg := cropHelm(skin.Image)
	torsoImg := imaging.Crop(skin.Image, image.Rect(TorsoX, TorsoY, TorsoX+TorsoWidth, TorsoY+UpperBodyShift))
	raImg := imaging.Crop(skin.Image, image.Rect(RaX, RaY, RaX+RaWidth, RaY+UpperBodyShift))

	var laImg image.Image

	// If the skin is 1.8 then we will use the left arms and legs, otherwise flip the right ones and use them.
	if skin.is18Skin() {
		laImg = imaging.Crop(skin.Image, image.Rect(LaX, LaY, LaX+LaWidth, LaY+UpperBodyShift))
	} else {
		laImg = imaging.FlipH(raImg)
	}

	// Create a blank canvas for us to draw our upper body on
	upperBodyImg := image.NewNRGBA(image.Rect(0, 0, LaWidth+TorsoWidth+RaWidth, UpperBodyHeight))
	// Helm
	fastDraw(upperBodyImg, helmImg.(*image.NRGBA), LaWidth, 0)
	// Torso
	fastDraw(upperBodyImg, torsoImg, LaWidth, HelmHeight)
	// Left Arm
	fastDraw(upperBodyImg, laImg.(*image.NRGBA), 0, HelmHeight)
	// Right Arm
	fastDraw(upperBodyImg, raImg, LaWidth+TorsoWidth, HelmHeight)

	skin.Processed = upperBodyImg
	return nil
}

func (skin *mcSkin) GetBust() error {
	// Go get the upper body but not all of it.
	err := skin.RenderUpperBody(false)
	if err != nil {
		return err
	}

	return nil
}

func (skin *mcSkin) GetBody() error {
	// Go get the upper body (all of it).
	err := skin.RenderUpperBody(true)
	if err != nil {
		return err
	}

	rlImg := imaging.Crop(skin.Image, image.Rect(RlX, RlY, RlX+RlWidth, RlY+RlHeight))

	var llImg image.Image

	// If the skin is 1.8 then we will use the left arms and legs, otherwise flip the right ones and use them.
	if skin.is18Skin() {
		llImg = imaging.Crop(skin.Image, image.Rect(LlX, LlY, LlX+LlWidth, LlY+LlHeight))
	} else {
		llImg = imaging.FlipH(rlImg)
	}

	// Create a blank canvas for us to draw our body on
	bodyImg := image.NewNRGBA(image.Rect(0, 0, LaWidth+TorsoWidth+RaWidth, HeadHeight+TorsoHeight+LlHeight))
	// Upper Body
	fastDraw(bodyImg, skin.Processed.(*image.NRGBA), 0, 0)
	// Left Leg
	fastDraw(bodyImg, llImg.(*image.NRGBA), LaWidth, HelmHeight+TorsoHeight)
	// Right Leg
	fastDraw(bodyImg, rlImg, LaWidth+LlWidth, HelmHeight+TorsoHeight)

	skin.Processed = bodyImg
	return nil
}

func (skin *mcSkin) is18Skin() bool {
	bounds := skin.Image.Bounds()
	if bounds.Max.Y == 64 {
		return true
	}
	return false
}

func (skin *mcSkin) WritePNG(w io.Writer) error {
	return png.Encode(w, skin.Processed)
}

func (skin *mcSkin) WriteSkin(w io.Writer) error {
	return png.Encode(w, skin.Image)
}

func (skin *mcSkin) Resize(width uint) {
	skin.Processed = imaging.Resize(skin.Processed, int(width), 0, imaging.NearestNeighbor)
}

func cropHead(img image.Image) image.Image {
	return imaging.Crop(img, image.Rect(HeadX, HeadY, HeadX+HeadWidth, HeadY+HeadHeight))
}

func cropHelm(img image.Image) image.Image {
	headImg := cropHead(img)
	helmImg := imaging.Crop(img, image.Rect(HelmX, HelmY, HelmX+HelmWidth, HelmY+HelmHeight))

	fastDraw(headImg.(*image.NRGBA), helmImg, 0, 0)

	return headImg
}

func fastDraw(dst *image.NRGBA, src *image.NRGBA, x, y int) {
	bounds := src.Bounds()
	maxY := bounds.Max.Y
	maxX := bounds.Max.X * 4

	pointer := dst.PixOffset(x, y)
	for row := 0; row < maxY; row += 1 {
		for i := 0; i < maxX; i += 4 {
			srcPx := row*src.Stride + i
			dstPx := row*dst.Stride + i + pointer
			if src.Pix[srcPx+3] != 0 {
				dst.Pix[dstPx+0] = src.Pix[srcPx+0]
				dst.Pix[dstPx+1] = src.Pix[srcPx+1]
				dst.Pix[dstPx+2] = src.Pix[srcPx+2]
				dst.Pix[dstPx+3] = 0xFF
			}
		}
	}
}
<|endoftext|>


<commit_before>package bamstats

import (
	"errors"
	"os"
	"sync"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/biogo/hts/bam"
	"github.com/biogo/hts/sam"
)

// Stats represents mapping statistics.
type Stats interface {
	Update(other Stats)
	Merge(others chan Stats)
	Collect(record *sam.Record, index *RtreeMap)
}

var wg sync.WaitGroup

func getStats(stats []Stats) Stats {
	general := stats[0].(*GeneralStats)
	general.Coverage = nil
	if len(stats) > 1 {
		general.Coverage = stats[1].(*CoverageStats)
		general.Coverage.UpdateTotal()
	}
	return general
}

func worker(in chan *sam.Record, out chan Stats, index *RtreeMap) {
	defer wg.Done()
	stats := []Stats{NewGeneralStats()}
	if index != nil {
		stats = append(stats, NewCoverageStats())
	}
	for record := range in {
		for _, s := range stats {
			s.Collect(record, index)
		}
	}
	log.Debug("Worker DONE!")

	out <- getStats(stats)
}

func readBAM(bamFile string, index *RtreeMap, cpu int, maxBuf int, reads int) (chan Stats, error) {
	f, err := os.Open(bamFile)
	defer f.Close()
	if err != nil {
		return nil, err
	}
	br, err := bam.NewReader(f, cpu)
	defer br.Close()
	if err != nil {
		return nil, err
	}
	input := make([]chan *sam.Record, cpu)
	stats := make(chan Stats, cpu)
	for i := 0; i < cpu; i++ {
		wg.Add(1)
		input[i] = make(chan *sam.Record, maxBuf)
		go worker(input[i], stats, index)
	}
	c := 0
	for {
		if reads > -1 && c == reads {
			break
		}
		record, err := br.Read()
		if err != nil {
			break
		}
		input[c%cpu] <- record
		c++
	}
	for i := 0; i < cpu; i++ {
		close(input[i])
	}
	return stats, nil
}

// Process process the input BAM file and collect different mapping stats.
func Process(bamFile string, annotation string, cpu int, maxBuf int, reads int) (*Stats, error) {
	var index *RtreeMap
	if bamFile == "" {
		return nil, errors.New("Please specify a BAM input file")
	}
	if annotation != "" {
		log.Infof("Creating index for %s", annotation)
		start := time.Now()
		index = CreateIndex(annotation)
		log.Infof("Index done in %v", time.Since(start))
	}
	start := time.Now()
	log.Infof("Collecting stats for %s", bamFile)
	stats, err := readBAM(bamFile, index, cpu, maxBuf, reads)
	if err != nil {
		return nil, err
	}
	go func() {
		wg.Wait()
		close(stats)
	}()
	log.Infof("Stats done in %v", time.Since(start))
	st := <-stats
	st.Merge(stats)
	return &st, nil
}
<commit_msg>Add package godoc<commit_after>// Package bamstats provides functions for computing several mapping statistics on a BAM file.
package bamstats

import (
	"errors"
	"os"
	"sync"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/biogo/hts/bam"
	"github.com/biogo/hts/sam"
)

// Stats represents mapping statistics.
type Stats interface {
	Update(other Stats)
	Merge(others chan Stats)
	Collect(record *sam.Record, index *RtreeMap)
}

var wg sync.WaitGroup

func getStats(stats []Stats) Stats {
	general := stats[0].(*GeneralStats)
	general.Coverage = nil
	if len(stats) > 1 {
		general.Coverage = stats[1].(*CoverageStats)
		general.Coverage.UpdateTotal()
	}
	return general
}

func worker(in chan *sam.Record, out chan Stats, index *RtreeMap) {
	defer wg.Done()
	stats := []Stats{NewGeneralStats()}
	if index != nil {
		stats = append(stats, NewCoverageStats())
	}
	for record := range in {
		for _, s := range stats {
			s.Collect(record, index)
		}
	}
	log.Debug("Worker DONE!")

	out <- getStats(stats)
}

func readBAM(bamFile string, index *RtreeMap, cpu int, maxBuf int, reads int) (chan Stats, error) {
	f, err := os.Open(bamFile)
	defer f.Close()
	if err != nil {
		return nil, err
	}
	br, err := bam.NewReader(f, cpu)
	defer br.Close()
	if err != nil {
		return nil, err
	}
	input := make([]chan *sam.Record, cpu)
	stats := make(chan Stats, cpu)
	for i := 0; i < cpu; i++ {
		wg.Add(1)
		input[i] = make(chan *sam.Record, maxBuf)
		go worker(input[i], stats, index)
	}
	c := 0
	for {
		if reads > -1 && c == reads {
			break
		}
		record, err := br.Read()
		if err != nil {
			break
		}
		input[c%cpu] <- record
		c++
	}
	for i := 0; i < cpu; i++ {
		close(input[i])
	}
	return stats, nil
}

// Process process the input BAM file and collect different mapping stats.
func Process(bamFile string, annotation string, cpu int, maxBuf int, reads int) (*Stats, error) {
	var index *RtreeMap
	if bamFile == "" {
		return nil, errors.New("Please specify a BAM input file")
	}
	if annotation != "" {
		log.Infof("Creating index for %s", annotation)
		start := time.Now()
		index = CreateIndex(annotation)
		log.Infof("Index done in %v", time.Since(start))
	}
	start := time.Now()
	log.Infof("Collecting stats for %s", bamFile)
	stats, err := readBAM(bamFile, index, cpu, maxBuf, reads)
	if err != nil {
		return nil, err
	}
	go func() {
		wg.Wait()
		close(stats)
	}()
	log.Infof("Stats done in %v", time.Since(start))
	st := <-stats
	st.Merge(stats)
	return &st, nil
}
<|endoftext|>


<commit_before>package seq

import (
	"bytes"
	"fmt"
	"math"
	"text/tabwriter"
)

// Profile represents a sequence profile in terms of log-odds scores.
type Profile struct {
	// The columns of a profile.
	Emissions []EProbs

	// The alphabet of the profile. The length of the alphabet should be
	// equal to the number of rows in the profile.
	// There are no restrictions on the alphabet. (i.e., Gap characters are
	// allowed but they are not treated specially.)
	Alphabet Alphabet
}

// NewProfile initializes a profile with a default
// alphabet that is compatible with this package's BLOSUM62 matrix.
// Emission probabilities are set to the minimum log-odds probability.
func NewProfile(columns int) *Profile {
	return NewProfileAlphabet(columns, AlphaBlosum62)
}

// NewProfileAlphabet initializes a profile with the given alphabet.
// Emission probabilities are set to the minimum log-odds probability.
func NewProfileAlphabet(columns int, alphabet Alphabet) *Profile {
	emits := make([]EProbs, columns)
	for i := 0; i < columns; i++ {
		emits[i] = NewEProbs(alphabet)
	}
	return &Profile{emits, alphabet}
}

func (p *Profile) Len() int {
	return len(p.Emissions)
}

func (p *Profile) String() string {
	buf := new(bytes.Buffer)
	tabw := tabwriter.NewWriter(buf, 4, 0, 3, ' ', 0)
	pf := func(ft string, v ...interface{}) { fmt.Fprintf(tabw, ft, v...) }
	for _, r := range p.Alphabet {
		pf("%c", rune(r))
		for _, eprobs := range p.Emissions {
			pf("\t%0.4f", eprobs[r])
		}
		pf("\n")
	}
	tabw.Flush()
	return buf.String()
}

// FrequencyProfile represents a sequence profile in terms of raw frequencies.
// A FrequencyProfile is useful as an intermediate representation. It can be
// used to incrementally build a Profile.
type FrequencyProfile struct {
	// The columns of a frequency profile.
	Freqs []map[Residue]int

	// The alphabet of the profile. The length of the alphabet should be
	// equal to the number of rows in the frequency profile.
	// There are no restrictions on the alphabet. (i.e., Gap characters are
	// allowed but they are not treated specially.)
	Alphabet Alphabet
}

// NewNullProfile initializes a frequency profile that can be used to tabulate
// a null model. This is equivalent to calling NewFrequencyProfile with the
// number of columns set to 1.
func NewNullProfile() *FrequencyProfile {
	return NewFrequencyProfile(1)
}

// NewFrequencyProfile initializes a frequency profile with a default
// alphabet that is compatible with this package's BLOSUM62 matrix.
// Pseudo-count correction using Laplace's Rule is automatically applied.
func NewFrequencyProfile(columns int) *FrequencyProfile {
	return NewFrequencyProfileAlphabet(columns, AlphaBlosum62)
}

// NewFrequencyProfileAlphabet initializes a frequency profile with the
// given alphabet.
// Pseudo-count correction using Laplace's Rule is automatically applied.
func NewFrequencyProfileAlphabet(
	columns int,
	alphabet Alphabet,
) *FrequencyProfile {
	freqs := make([]map[Residue]int, columns)
	for i := 0; i < columns; i++ {
		freqs[i] = make(map[Residue]int, len(alphabet))
		for _, residue := range alphabet {
			freqs[i][residue] = 1 // Laplace's rule
		}
	}
	return &FrequencyProfile{freqs, alphabet}
}

// Len returns the number of columns in the frequency profile.
func (fp *FrequencyProfile) Len() int {
	return len(fp.Freqs)
}

// Add adds the sequence to the given profile. The sequence must have length
// equivalent to the number of columns in the profile. The sequence must also
// only contain residues that are in the alphabet for the profile.
//
// As a special case, if the alphabet contains the 'X' residue, then any
// unrecognized residues in the sequence with respect to the profile's alphabet
// will be considered as an 'X' residue.
func (fp *FrequencyProfile) Add(s Sequence) {
	if fp.Len() != s.Len() {
		panic(fmt.Sprintf("Profile has length %d but sequence has length %d",
			fp.Len(), s.Len()))
	}
	for column := 0; column < fp.Len(); column++ {
		r := s.Residues[column]
		if _, ok := fp.Freqs[column][r]; ok {
			fp.Freqs[column][r] += 1
		} else if _, ok := fp.Freqs[column]['X']; ok {
			fp.Freqs[column]['X'] += 1
		} else {
			panic(fmt.Sprintf("Unrecognized residue %c while using an "+
				"alphabet without a wildcard: '%s'.", r, fp.Alphabet))
		}
	}
}

// Profile converts a raw frequency profile to a profile that uses a log-odds
// representation. The log-odds scores are computed with the given null model,
// which is itself just a raw frequency profile with a single column.
// Pseudo-count correction using Laplace's Rule is automatically applied.
// The alphabets of `fp` and `null` must be exactly the same.
func (fp *FrequencyProfile) Profile(null *FrequencyProfile) *Profile {
	if null.Len() != 1 {
		panic(fmt.Sprintf("null model has %d columns; should have 1",
			null.Len()))
	}
	if !fp.Alphabet.Equals(null.Alphabet) {
		panic(fmt.Sprintf("freq profile alphabet '%s' is not equal to "+
			"null profile alphabet '%s'.", fp.Alphabet, null.Alphabet))
	}
	p := NewProfileAlphabet(fp.Len(), fp.Alphabet)

	// Compute the background emission probabilities.
	nulltot := freqTotal(null.Freqs[0])
	nullemit := make(map[Residue]float64, fp.Alphabet.Len())
	for _, residue := range null.Alphabet {
		nullemit[residue] = float64(null.Freqs[0][residue]) / float64(nulltot)
	}

	// Now compute the emission probabilities and convert to log-odds.
	for column := 0; column < fp.Len(); column++ {
		tot := freqTotal(fp.Freqs[column])
		for _, residue := range fp.Alphabet {
			prob := float64(fp.Freqs[column][residue]) / float64(tot)
			logOdds := Prob(math.Log(prob / nullemit[residue]))
			p.Emissions[column][residue] = logOdds
		}
	}
	return p
}

// freqTotal computes the total frequency in a single column.
func freqTotal(column map[Residue]int) int {
	tot := 0
	for _, freq := range column {
		tot += freq
	}
	return tot
}
<commit_msg>Pseudocount correction was harder than I thought.<commit_after>package seq

import (
	"bytes"
	"fmt"
	"math"
	"text/tabwriter"
)

// Profile represents a sequence profile in terms of log-odds scores.
type Profile struct {
	// The columns of a profile.
	Emissions []EProbs

	// The alphabet of the profile. The length of the alphabet should be
	// equal to the number of rows in the profile.
	// There are no restrictions on the alphabet. (i.e., Gap characters are
	// allowed but they are not treated specially.)
	Alphabet Alphabet
}

// NewProfile initializes a profile with a default
// alphabet that is compatible with this package's BLOSUM62 matrix.
// Emission probabilities are set to the minimum log-odds probability.
func NewProfile(columns int) *Profile {
	return NewProfileAlphabet(columns, AlphaBlosum62)
}

// NewProfileAlphabet initializes a profile with the given alphabet.
// Emission probabilities are set to the minimum log-odds probability.
func NewProfileAlphabet(columns int, alphabet Alphabet) *Profile {
	emits := make([]EProbs, columns)
	for i := 0; i < columns; i++ {
		emits[i] = NewEProbs(alphabet)
	}
	return &Profile{emits, alphabet}
}

func (p *Profile) Len() int {
	return len(p.Emissions)
}

func (p *Profile) String() string {
	buf := new(bytes.Buffer)
	tabw := tabwriter.NewWriter(buf, 4, 0, 3, ' ', 0)
	pf := func(ft string, v ...interface{}) { fmt.Fprintf(tabw, ft, v...) }
	for _, r := range p.Alphabet {
		pf("%c", rune(r))
		for _, eprobs := range p.Emissions {
			pf("\t%0.4f", eprobs[r])
		}
		pf("\n")
	}
	tabw.Flush()
	return buf.String()
}

// FrequencyProfile represents a sequence profile in terms of raw frequencies.
// A FrequencyProfile is useful as an intermediate representation. It can be
// used to incrementally build a Profile.
type FrequencyProfile struct {
	// The columns of a frequency profile.
	Freqs []map[Residue]int

	// The alphabet of the profile. The length of the alphabet should be
	// equal to the number of rows in the frequency profile.
	// There are no restrictions on the alphabet. (i.e., Gap characters are
	// allowed but they are not treated specially.)
	Alphabet Alphabet
}

// NewNullProfile initializes a frequency profile that can be used to tabulate
// a null model. This is equivalent to calling NewFrequencyProfile with the
// number of columns set to 1.
func NewNullProfile() *FrequencyProfile {
	return NewFrequencyProfile(1)
}

// NewFrequencyProfile initializes a frequency profile with a default
// alphabet that is compatible with this package's BLOSUM62 matrix.
func NewFrequencyProfile(columns int) *FrequencyProfile {
	return NewFrequencyProfileAlphabet(columns, AlphaBlosum62)
}

// NewFrequencyProfileAlphabet initializes a frequency profile with the
// given alphabet.
func NewFrequencyProfileAlphabet(
	columns int,
	alphabet Alphabet,
) *FrequencyProfile {
	freqs := make([]map[Residue]int, columns)
	for i := 0; i < columns; i++ {
		freqs[i] = make(map[Residue]int, len(alphabet))
		for _, residue := range alphabet {
			freqs[i][residue] = 0
		}
	}
	return &FrequencyProfile{freqs, alphabet}
}

// Len returns the number of columns in the frequency profile.
func (fp *FrequencyProfile) Len() int {
	return len(fp.Freqs)
}

// Add adds the sequence to the given profile. The sequence must have length
// equivalent to the number of columns in the profile. The sequence must also
// only contain residues that are in the alphabet for the profile.
//
// As a special case, if the alphabet contains the 'X' residue, then any
// unrecognized residues in the sequence with respect to the profile's alphabet
// will be considered as an 'X' residue.
func (fp *FrequencyProfile) Add(s Sequence) {
	if fp.Len() != s.Len() {
		panic(fmt.Sprintf("Profile has length %d but sequence has length %d",
			fp.Len(), s.Len()))
	}
	for column := 0; column < fp.Len(); column++ {
		r := s.Residues[column]
		if _, ok := fp.Freqs[column][r]; ok {
			fp.Freqs[column][r] += 1
		} else if _, ok := fp.Freqs[column]['X']; ok {
			fp.Freqs[column]['X'] += 1
		} else {
			panic(fmt.Sprintf("Unrecognized residue %c while using an "+
				"alphabet without a wildcard: '%s'.", r, fp.Alphabet))
		}
	}
}

// Profile converts a raw frequency profile to a profile that uses a log-odds
// representation. The log-odds scores are computed with the given null model,
// which is itself just a raw frequency profile with a single column.
func (fp *FrequencyProfile) Profile(null *FrequencyProfile) *Profile {
	if null.Len() != 1 {
		panic(fmt.Sprintf("null model has %d columns; should have 1",
			null.Len()))
	}
	if !fp.Alphabet.Equals(null.Alphabet) {
		panic(fmt.Sprintf("freq profile alphabet '%s' is not equal to "+
			"null profile alphabet '%s'.", fp.Alphabet, null.Alphabet))
	}
	p := NewProfileAlphabet(fp.Len(), fp.Alphabet)

	// Compute the background emission probabilities.
	nulltot := freqTotal(null.Freqs[0])
	nullemit := make(map[Residue]float64, fp.Alphabet.Len())
	for _, residue := range null.Alphabet {
		nullemit[residue] = float64(null.Freqs[0][residue]) / float64(nulltot)
	}

	// Now compute the emission probabilities and convert to log-odds.
	for column := 0; column < fp.Len(); column++ {
		tot := freqTotal(fp.Freqs[column])
		for _, residue := range fp.Alphabet {
			if null.Freqs[0][residue] == 0 || fp.Freqs[column][residue] == 0 {
				p.Emissions[column][residue] = MinProb
			} else {
				prob := float64(fp.Freqs[column][residue]) / float64(tot)
				logOdds := -Prob(math.Log(prob / nullemit[residue]))
				p.Emissions[column][residue] = logOdds
			}
		}
	}
	return p
}

// freqTotal computes the total frequency in a single column.
func freqTotal(column map[Residue]int) int {
	tot := 0
	for _, freq := range column {
		tot += freq
	}
	return tot
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"gopkg.in/yaml.v2"
	"os/exec"
	"fmt"
	"os"
	"io"
	"github.com/urfave/cli"
	"math/rand"
	"golang.org/x/crypto/bcrypt"
	"errors"
)

const Workspace = "/srv/molly"

type Project struct {
	Name string
	Config ProjectConfig
}

type ProjectConfig struct {
	Name string
	Token string
	Service string
}

func GetProjectByName(name string, project *Project) error {
	project.Name = name
	if err := project.LoadConfig(); err != nil {
		return errors.New("Specified project doesn't exist")
	}
	return nil
}

func (p *Project) CreateFilesFolder() error {
	filesFolder := Workspace + "/" + p.Name + "/files"

	if err := os.MkdirAll(filesFolder, 0777); err != nil {
		return err
	}

	return nil
}

func (p *Project) CleanFilesFolder() error {
	filesFolder := Workspace + "/" + p.Name + "/files"

	if err := os.RemoveAll(filesFolder); err != nil {
		return err
	}

	return p.CreateFilesFolder()
}

func (p *Project) GetEnvVars() []string {
	return []string{
		"MOLLY_ARTIFACT=" + Workspace + "/" + p.Name + "/artifact.zip",
	}
}

func (p *Project) RunDeploymentScript() error {
	if err := p.CleanFilesFolder(); err != nil {
		return errors.New("Couldn't clean the files folder: " + err.Error())
	}

	cmd := exec.Command("sh", Workspace + "/" + p.Name + "/deploy.sh")
	cmd.Dir = Workspace + "/" + p.Name + "/files/"
	cmd.Env = p.GetEnvVars()

	out, err := cmd.CombinedOutput()
	if err != nil {
		return errors.New("There was an error running the deployment script: " + err.Error() + "\n" + string(out))
	}

	return nil
}

func (p *Project) CreateDeploymentScript() error {
	return ioutil.WriteFile(Workspace + "/" + p.Name + "/deploy.sh", []byte("unzip $MOLLY_ARTIFACT\n"), 0700)
}

func (p *Project) CreateRunScript() error {
	return ioutil.WriteFile(Workspace + "/" + p.Name + "/run.sh", []byte("# Write here the run command\n"), 0700)
}

func (p *Project) StoreArtifact(fileReader io.Reader) error {
	var artifactFile *os.File

	if out, err := os.Create(Workspace + "/" + p.Name + "/artifact.zip"); err != nil {
		return errors.New("Couldn't create the artifact file: "  + err.Error())
	} else {
		artifactFile = out
	}

	defer artifactFile.Close()

	if _, err := io.Copy(artifactFile, fileReader); err != nil {
		return errors.New("Couldn't copy the artifact file to destiny: "  + err.Error())
	}

	return nil
}

func (p *Project) SaveConfig() error {
	projectFilePath := Workspace + "/" + p.Name + "/project.yml"

	var projectFileBytes []byte

	if out, err := yaml.Marshal(p.Config); err != nil {
		return err
	} else {
		projectFileBytes = out
	}

	if err := ioutil.WriteFile(projectFilePath, projectFileBytes, 0600); err != nil {
		return err
	}

	return nil
}

func (p *Project) LoadConfig() error {
	projectFilePath := Workspace + "/" + p.Name + "/project.yml"

	var projectFileBytes []byte

	if bytes, err := ioutil.ReadFile(projectFilePath); err != nil {
		return err
	} else {
		projectFileBytes = bytes
	}

	config := ProjectConfig{}

	if err := yaml.Unmarshal(projectFileBytes, &config); err != nil {
		return err
	}

	p.Config = config

	return nil
}

func (p Project) GetService() Service {
	return Service{Project:p}
}

func (p *Project) CreateService() error {
	return p.GetService().Save()
}

func (p *Project) RestartService() error {
	return p.GetService().Restart()
}

func GenerateRandomPassword() string {
	letterRunes := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")

	b := make([]rune, 32)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}

func HashPassword(password string) (string, error) {
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		return "", err
	}
	return string(hashedPassword), nil
}

func (p *Project) CheckToken(password string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(p.Config.Token), []byte(password))
	if err != nil {
		return false
	}
	return true
}

func AddProjectAction(c *cli.Context) error {
	projectName := c.Args().First()

	if projectName == "" {
		fmt.Println("Missing project name\n\nUsage:\nmolly project add [project name]")
		return nil
	}

	randomPassword := GenerateRandomPassword()
	hashedPassword, err := HashPassword(randomPassword)

	if err != nil {
		return err
	}

	project := Project{
		Name: projectName,
		Config: ProjectConfig{
			Name: projectName,
			Token: hashedPassword,
			Service: "molly-" + projectName,
		},
	}
	if err := project.CreateFilesFolder(); err != nil {
		return err
	}
	if err := project.CreateDeploymentScript(); err != nil {
		return err
	}
	if err := project.CreateRunScript(); err != nil {
		return err
	}
	if err := project.CreateService(); err != nil {
		fmt.Println("Error while creating the service")
		fmt.Println(err)
		return err
	}
	if err := project.SaveConfig(); err != nil {
		return err
	}

	fmt.Println("Automatically generated token:", randomPassword)

	return nil
}

func StartProjectServiceAction(c *cli.Context) error {
	projectName := c.Args().First()
	project := Project{}
	GetProjectByName(projectName, &project)
	project.RestartService()
	return nil
}<commit_msg>Added message when project name is missing in service management CLI<commit_after>package main

import (
	"io/ioutil"
	"gopkg.in/yaml.v2"
	"os/exec"
	"fmt"
	"os"
	"io"
	"github.com/urfave/cli"
	"math/rand"
	"golang.org/x/crypto/bcrypt"
	"errors"
)

const Workspace = "/srv/molly"

type Project struct {
	Name string
	Config ProjectConfig
}

type ProjectConfig struct {
	Name string
	Token string
	Service string
}

func GetProjectByName(name string, project *Project) error {
	project.Name = name
	if err := project.LoadConfig(); err != nil {
		return errors.New("Specified project doesn't exist")
	}
	return nil
}

func (p *Project) CreateFilesFolder() error {
	filesFolder := Workspace + "/" + p.Name + "/files"

	if err := os.MkdirAll(filesFolder, 0777); err != nil {
		return err
	}

	return nil
}

func (p *Project) CleanFilesFolder() error {
	filesFolder := Workspace + "/" + p.Name + "/files"

	if err := os.RemoveAll(filesFolder); err != nil {
		return err
	}

	return p.CreateFilesFolder()
}

func (p *Project) GetEnvVars() []string {
	return []string{
		"MOLLY_ARTIFACT=" + Workspace + "/" + p.Name + "/artifact.zip",
	}
}

func (p *Project) RunDeploymentScript() error {
	if err := p.CleanFilesFolder(); err != nil {
		return errors.New("Couldn't clean the files folder: " + err.Error())
	}

	cmd := exec.Command("sh", Workspace + "/" + p.Name + "/deploy.sh")
	cmd.Dir = Workspace + "/" + p.Name + "/files/"
	cmd.Env = p.GetEnvVars()

	out, err := cmd.CombinedOutput()
	if err != nil {
		return errors.New("There was an error running the deployment script: " + err.Error() + "\n" + string(out))
	}

	return nil
}

func (p *Project) CreateDeploymentScript() error {
	return ioutil.WriteFile(Workspace + "/" + p.Name + "/deploy.sh", []byte("unzip $MOLLY_ARTIFACT\n"), 0700)
}

func (p *Project) CreateRunScript() error {
	return ioutil.WriteFile(Workspace + "/" + p.Name + "/run.sh", []byte("# Write here the run command\n"), 0700)
}

func (p *Project) StoreArtifact(fileReader io.Reader) error {
	var artifactFile *os.File

	if out, err := os.Create(Workspace + "/" + p.Name + "/artifact.zip"); err != nil {
		return errors.New("Couldn't create the artifact file: "  + err.Error())
	} else {
		artifactFile = out
	}

	defer artifactFile.Close()

	if _, err := io.Copy(artifactFile, fileReader); err != nil {
		return errors.New("Couldn't copy the artifact file to destiny: "  + err.Error())
	}

	return nil
}

func (p *Project) SaveConfig() error {
	projectFilePath := Workspace + "/" + p.Name + "/project.yml"

	var projectFileBytes []byte

	if out, err := yaml.Marshal(p.Config); err != nil {
		return err
	} else {
		projectFileBytes = out
	}

	if err := ioutil.WriteFile(projectFilePath, projectFileBytes, 0600); err != nil {
		return err
	}

	return nil
}

func (p *Project) LoadConfig() error {
	projectFilePath := Workspace + "/" + p.Name + "/project.yml"

	var projectFileBytes []byte

	if bytes, err := ioutil.ReadFile(projectFilePath); err != nil {
		return err
	} else {
		projectFileBytes = bytes
	}

	config := ProjectConfig{}

	if err := yaml.Unmarshal(projectFileBytes, &config); err != nil {
		return err
	}

	p.Config = config

	return nil
}

func (p Project) GetService() Service {
	return Service{Project:p}
}

func (p *Project) CreateService() error {
	return p.GetService().Save()
}

func (p *Project) RestartService() error {
	return p.GetService().Restart()
}

func GenerateRandomPassword() string {
	letterRunes := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")

	b := make([]rune, 32)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}

func HashPassword(password string) (string, error) {
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		return "", err
	}
	return string(hashedPassword), nil
}

func (p *Project) CheckToken(password string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(p.Config.Token), []byte(password))
	if err != nil {
		return false
	}
	return true
}

func AddProjectAction(c *cli.Context) error {
	projectName := c.Args().First()

	if projectName == "" {
		fmt.Println("Missing project name\n\nUsage:\nmolly project add [project name]")
		return nil
	}

	randomPassword := GenerateRandomPassword()
	hashedPassword, err := HashPassword(randomPassword)

	if err != nil {
		return err
	}

	project := Project{
		Name: projectName,
		Config: ProjectConfig{
			Name: projectName,
			Token: hashedPassword,
			Service: "molly-" + projectName,
		},
	}
	if err := project.CreateFilesFolder(); err != nil {
		return err
	}
	if err := project.CreateDeploymentScript(); err != nil {
		return err
	}
	if err := project.CreateRunScript(); err != nil {
		return err
	}
	if err := project.CreateService(); err != nil {
		fmt.Println("Error while creating the service")
		fmt.Println(err)
		return err
	}
	if err := project.SaveConfig(); err != nil {
		return err
	}

	fmt.Println("Automatically generated token:", randomPassword)

	return nil
}

func StartProjectServiceAction(c *cli.Context) error {
	projectName := c.Args().First()

	if projectName == "" {
		fmt.Println("Missing project name\n\nUsage:\nmolly project service start [project name]")
		return nil
	}

	project := Project{}
	GetProjectByName(projectName, &project)
	project.RestartService()
	return nil
}
<|endoftext|>


<commit_before>package harmonizer

import (
	"os"
	"time"

	"github.com/cloudfoundry-incubator/rep/evacuation/evacuation_context"
	"github.com/cloudfoundry-incubator/rep/generator"
	"github.com/cloudfoundry-incubator/runtime-schema/metric"
	"github.com/pivotal-golang/clock"
	"github.com/pivotal-golang/lager"
	"github.com/pivotal-golang/operationq"
)

const repBulkSyncDuration = metric.Duration("RepBulkSyncDuration")

type Bulker struct {
	logger lager.Logger

	pollInterval           time.Duration
	evacuationPollInterval time.Duration
	evacuationNotifier     evacuation_context.EvacuationNotifier
	clock                  clock.Clock
	generator              generator.Generator
	queue                  operationq.Queue
}

func NewBulker(
	logger lager.Logger,
	pollInterval time.Duration,
	evacuationPollInterval time.Duration,
	evacuationNotifier evacuation_context.EvacuationNotifier,
	clock clock.Clock,
	generator generator.Generator,
	queue operationq.Queue,
) *Bulker {
	return &Bulker{
		logger: logger,

		pollInterval:           pollInterval,
		evacuationPollInterval: evacuationPollInterval,
		evacuationNotifier:     evacuationNotifier,
		clock:                  clock,
		generator:              generator,
		queue:                  queue,
	}
}

func (b *Bulker) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	evacuateNotify := b.evacuationNotifier.EvacuateNotify()
	close(ready)

	logger := b.logger.Session("running-bulker")

	logger.Info("starting", lager.Data{
		"interval": b.pollInterval.String(),
	})
	defer logger.Info("finished")

	interval := b.pollInterval

	timer := b.clock.NewTimer(interval)
	defer timer.Stop()

	for {
		select {
		case <-timer.C():

		case <-evacuateNotify:
			evacuateNotify = nil

			logger.Info("notified-of-evacuation")
			interval = b.evacuationPollInterval

		case signal := <-signals:
			logger.Info("received-signal", lager.Data{"signal": signal.String()})
			return nil
		}

		b.sync(logger)

		timer.Reset(interval)
	}
}

func (b *Bulker) sync(logger lager.Logger) {
	logger = logger.Session("sync")

	logger.Info("starting")
	defer logger.Info("finished")

	startTime := b.clock.Now()

	ops, err := b.generator.BatchOperations(logger)

	endTime := b.clock.Now()

	repBulkSyncDuration.Send(endTime.Sub(startTime))

	if err != nil {
		logger.Error("failed-to-generate-operations", err)
		return
	}

	for _, operation := range ops {
		b.queue.Push(operation)
	}
}
<commit_msg>Add logging when metric sending fails<commit_after>package harmonizer

import (
	"os"
	"time"

	"github.com/cloudfoundry-incubator/rep/evacuation/evacuation_context"
	"github.com/cloudfoundry-incubator/rep/generator"
	"github.com/cloudfoundry-incubator/runtime-schema/metric"
	"github.com/pivotal-golang/clock"
	"github.com/pivotal-golang/lager"
	"github.com/pivotal-golang/operationq"
)

const repBulkSyncDuration = metric.Duration("RepBulkSyncDuration")

type Bulker struct {
	logger lager.Logger

	pollInterval           time.Duration
	evacuationPollInterval time.Duration
	evacuationNotifier     evacuation_context.EvacuationNotifier
	clock                  clock.Clock
	generator              generator.Generator
	queue                  operationq.Queue
}

func NewBulker(
	logger lager.Logger,
	pollInterval time.Duration,
	evacuationPollInterval time.Duration,
	evacuationNotifier evacuation_context.EvacuationNotifier,
	clock clock.Clock,
	generator generator.Generator,
	queue operationq.Queue,
) *Bulker {
	return &Bulker{
		logger: logger,

		pollInterval:           pollInterval,
		evacuationPollInterval: evacuationPollInterval,
		evacuationNotifier:     evacuationNotifier,
		clock:                  clock,
		generator:              generator,
		queue:                  queue,
	}
}

func (b *Bulker) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	evacuateNotify := b.evacuationNotifier.EvacuateNotify()
	close(ready)

	logger := b.logger.Session("running-bulker")

	logger.Info("starting", lager.Data{
		"interval": b.pollInterval.String(),
	})
	defer logger.Info("finished")

	interval := b.pollInterval

	timer := b.clock.NewTimer(interval)
	defer timer.Stop()

	for {
		select {
		case <-timer.C():

		case <-evacuateNotify:
			evacuateNotify = nil

			logger.Info("notified-of-evacuation")
			interval = b.evacuationPollInterval

		case signal := <-signals:
			logger.Info("received-signal", lager.Data{"signal": signal.String()})
			return nil
		}

		b.sync(logger)

		timer.Reset(interval)
	}
}

func (b *Bulker) sync(logger lager.Logger) {
	logger = logger.Session("sync")

	logger.Info("starting")
	defer logger.Info("finished")

	startTime := b.clock.Now()

	ops, batchError := b.generator.BatchOperations(logger)

	endTime := b.clock.Now()

	sendError := repBulkSyncDuration.Send(endTime.Sub(startTime))
	if sendError != nil {
		logger.Error("failed-to-send-rep-bulk-sync-duration-metric", sendError)
	}

	if batchError != nil {
		logger.Error("failed-to-generate-operations", batchError)
		return
	}

	for _, operation := range ops {
		b.queue.Push(operation)
	}
}
<|endoftext|>


<commit_before>package helpers

import (
	"errors"
	"os/exec"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
)

func FlyLogin(atcURL, concourseAlias, flyBinaryPath string) error {
	dev, basicAuth, _, err := getAuthMethods(atcURL)
	if err != nil {
		return err
	}

	if dev {
		return nil
	} else if basicAuth != nil {
		return flyLoginWithBasicAuth(basicAuth.Username, basicAuth.Password, atcURL, concourseAlias, flyBinaryPath)
	}

	return errors.New("Unable to determine authentication")
}

func flyLoginWithBasicAuth(username, password, atcURL, concourseAlias, flyBinaryPath string) error {
	loginCmd := exec.Command(
		flyBinaryPath,
		"login",
		"-c", atcURL,
		"-t", concourseAlias,
		"-u", username,
		"-p", password,
	)

	loginProcess, err := gexec.Start(loginCmd, GinkgoWriter, GinkgoWriter)
	if err != nil {
		return err
	}

	Eventually(loginProcess, time.Minute).Should(gbytes.Say("token saved"))
	Eventually(loginProcess, time.Minute).Should(gexec.Exit(0))

	return nil
}
<commit_msg>Still login even when in dev mode.<commit_after>package helpers

import (
	"errors"
	"os/exec"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gexec"
)

func FlyLogin(atcURL, concourseAlias, flyBinaryPath string) error {
	dev, basicAuth, _, err := getAuthMethods(atcURL)
	if err != nil {
		return err
	}

	if dev {
		return flyLogin(flyBinaryPath, []string{
			"-c", atcURL,
			"-t", concourseAlias,
		})
	} else if basicAuth != nil {
		return flyLogin(flyBinaryPath, []string{
			"-c", atcURL,
			"-t", concourseAlias,
			"-u", basicAuth.Username,
			"-p", basicAuth.Password,
		})
	}

	return errors.New("Unable to determine authentication")
}

func flyLogin(flyBinaryPath string, loginArgs []string) error {
	args := append([]string{"login"}, loginArgs...)
	loginCmd := exec.Command(flyBinaryPath, args...)

	loginProcess, err := gexec.Start(loginCmd, GinkgoWriter, GinkgoWriter)
	if err != nil {
		return err
	}

	Eventually(loginProcess, time.Minute).Should(gexec.Exit(0))

	return nil
}
<|endoftext|>


<commit_before>package httpd

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"testing"
)

// Test_NewServer tests that a server can perform all basic operations.
func Test_NewServer(t *testing.T) {
	store := newTestStore()
	s := &testServer{New(":0", store)}
	if s == nil {
		t.Fatal("failed to create HTTP service")
	}

	if err := s.Start(); err != nil {
		t.Fatalf("failed to start HTTP service: %s", err)
	}

	b := doGet(t, s.URL(), "k1")
	if string(b) != `{"k1":""}` {
		t.Fatalf("wrong value received for key k1: %s", string(b))
	}

	doPost(t, s.URL(), "k1", "v1")

	b = doGet(t, s.URL(), "k1")
	if string(b) != `{"k1":"v1"}` {
		t.Fatalf("wrong value received for key k1: %s", string(b))
	}

	store.m["k2"] = "v2"
	b = doGet(t, s.URL(), "k2")
	if string(b) != `{"k2":"v2"}` {
		t.Fatalf("wrong value received for key k2: %s", string(b))
	}

	doDelete(t, s.URL(), "k2")
	b = doGet(t, s.URL(), "k2")
	if string(b) != `{"k2":""}` {
		t.Fatalf("wrong value received for key k2: %s", string(b))
	}

}

type testServer struct {
	*Service
}

func (t *testServer) URL() string {
	port := strings.TrimLeft(t.Addr().String(), "[::]:")
	return fmt.Sprintf("http://127.0.0.1:%s", port)
}

type testStore struct {
	m map[string]string
}

func newTestStore() *testStore {
	return &testStore{
		m: make(map[string]string),
	}
}

func (t *testStore) Get(key string) (string, error) {
	return t.m[key], nil
}

func (t *testStore) Set(key, value string) error {
	t.m[key] = value
	return nil
}

func (t *testStore) Delete(key string) error {
	delete(t.m, key)
	return nil
}

func (t *testStore) Join(addr string) error {
	return nil
}

func doGet(t *testing.T, url, key string) string {
	resp, err := http.Get(fmt.Sprintf("%s/key/%s", url, key))
	if err != nil {
		t.Fatalf("failed to GET key: %s", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("failed to read response: %s", err)
	}
	return string(body)
}

func doPost(t *testing.T, url, key, value string) {
	b, err := json.Marshal(map[string]string{key: value})
	if err != nil {
		t.Fatalf("failed to encode key and value for POST: %s", err)
	}
	resp, err := http.Post(fmt.Sprintf("%s/key", url), "application-type/json", bytes.NewReader(b))
	defer resp.Body.Close()
	if err != nil {
		t.Fatalf("POST request failed: %s", err)
	}
}

func doDelete(t *testing.T, u, key string) {
	ru, err := url.Parse(fmt.Sprintf("%s/key/%s", u, key))
	if err != nil {
		t.Fatalf("failed to parse URL for delete: %s", err)
	}
	req := &http.Request{
		Method: "DELETE",
		URL:    ru,
	}

	client := http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		t.Fatalf("failed to GET key: %s", err)
	}
	defer resp.Body.Close()
}
<commit_msg>Clarify expected test results<commit_after>package httpd

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"testing"
)

// Test_NewServer tests that a server can perform all basic operations.
func Test_NewServer(t *testing.T) {
	store := newTestStore()
	s := &testServer{New(":0", store)}
	if s == nil {
		t.Fatal("failed to create HTTP service")
	}

	if err := s.Start(); err != nil {
		t.Fatalf("failed to start HTTP service: %s", err)
	}

	b := doGet(t, s.URL(), "k1")
	if string(b) != `{"k1":""}` {
		t.Fatalf("wrong value received for key k1: %s (expected empty string)", string(b))
	}

	doPost(t, s.URL(), "k1", "v1")

	b = doGet(t, s.URL(), "k1")
	if string(b) != `{"k1":"v1"}` {
		t.Fatalf(`wrong value received for key k1: %s (expected "v1")`, string(b))
	}

	store.m["k2"] = "v2"
	b = doGet(t, s.URL(), "k2")
	if string(b) != `{"k2":"v2"}` {
		t.Fatalf(`wrong value received for key k2: %s (expected "v2")`, string(b))
	}

	doDelete(t, s.URL(), "k2")
	b = doGet(t, s.URL(), "k2")
	if string(b) != `{"k2":""}` {
		t.Fatalf(`wrong value received for key k2: %s (expected empty string)`, string(b))
	}

}

type testServer struct {
	*Service
}

func (t *testServer) URL() string {
	port := strings.TrimLeft(t.Addr().String(), "[::]:")
	return fmt.Sprintf("http://127.0.0.1:%s", port)
}

type testStore struct {
	m map[string]string
}

func newTestStore() *testStore {
	return &testStore{
		m: make(map[string]string),
	}
}

func (t *testStore) Get(key string) (string, error) {
	return t.m[key], nil
}

func (t *testStore) Set(key, value string) error {
	t.m[key] = value
	return nil
}

func (t *testStore) Delete(key string) error {
	delete(t.m, key)
	return nil
}

func (t *testStore) Join(addr string) error {
	return nil
}

func doGet(t *testing.T, url, key string) string {
	resp, err := http.Get(fmt.Sprintf("%s/key/%s", url, key))
	if err != nil {
		t.Fatalf("failed to GET key: %s", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("failed to read response: %s", err)
	}
	return string(body)
}

func doPost(t *testing.T, url, key, value string) {
	b, err := json.Marshal(map[string]string{key: value})
	if err != nil {
		t.Fatalf("failed to encode key and value for POST: %s", err)
	}
	resp, err := http.Post(fmt.Sprintf("%s/key", url), "application-type/json", bytes.NewReader(b))
	defer resp.Body.Close()
	if err != nil {
		t.Fatalf("POST request failed: %s", err)
	}
}

func doDelete(t *testing.T, u, key string) {
	ru, err := url.Parse(fmt.Sprintf("%s/key/%s", u, key))
	if err != nil {
		t.Fatalf("failed to parse URL for delete: %s", err)
	}
	req := &http.Request{
		Method: "DELETE",
		URL:    ru,
	}

	client := http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		t.Fatalf("failed to GET key: %s", err)
	}
	defer resp.Body.Close()
}
<|endoftext|>


<commit_before>package httpd

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"testing"
)

// Test_NewServer tests that a server can perform all basic operations.
func Test_NewServer(t *testing.T) {
	store := newTestStore()
	s := &testServer{New(":0", store)}
	if s == nil {
		t.Fatal("failed to create HTTP service")
	}

	if err := s.Start(); err != nil {
		t.Fatalf("failed to start HTTP service: %s", err)
	}

	b := doGet(t, s.URL(), "k1")
	if string(b) != `{"k1":""}` {
		t.Fatalf("wrong value received for key k1: %s (expected empty string)", string(b))
	}

	doPost(t, s.URL(), "k1", "v1")

	b = doGet(t, s.URL(), "k1")
	if string(b) != `{"k1":"v1"}` {
		t.Fatalf(`wrong value received for key k1: %s (expected "v1")`, string(b))
	}

	store.m["k2"] = "v2"
	b = doGet(t, s.URL(), "k2")
	if string(b) != `{"k2":"v2"}` {
		t.Fatalf(`wrong value received for key k2: %s (expected "v2")`, string(b))
	}

	doDelete(t, s.URL(), "k2")
	b = doGet(t, s.URL(), "k2")
	if string(b) != `{"k2":""}` {
		t.Fatalf(`wrong value received for key k2: %s (expected empty string)`, string(b))
	}

}

type testServer struct {
	*Service
}

func (t *testServer) URL() string {
	port := strings.TrimLeft(t.Addr().String(), "[::]:")
	return fmt.Sprintf("http://127.0.0.1:%s", port)
}

type testStore struct {
	m map[string]string
}

func newTestStore() *testStore {
	return &testStore{
		m: make(map[string]string),
	}
}

func (t *testStore) Get(key string) (string, error) {
	return t.m[key], nil
}

func (t *testStore) Set(key, value string) error {
	t.m[key] = value
	return nil
}

func (t *testStore) Delete(key string) error {
	delete(t.m, key)
	return nil
}

func (t *testStore) Join(addr string) error {
	return nil
}

func doGet(t *testing.T, url, key string) string {
	resp, err := http.Get(fmt.Sprintf("%s/key/%s", url, key))
	if err != nil {
		t.Fatalf("failed to GET key: %s", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("failed to read response: %s", err)
	}
	return string(body)
}

func doPost(t *testing.T, url, key, value string) {
	b, err := json.Marshal(map[string]string{key: value})
	if err != nil {
		t.Fatalf("failed to encode key and value for POST: %s", err)
	}
	resp, err := http.Post(fmt.Sprintf("%s/key", url), "application-type/json", bytes.NewReader(b))
	defer resp.Body.Close()
	if err != nil {
		t.Fatalf("POST request failed: %s", err)
	}
}

func doDelete(t *testing.T, u, key string) {
	ru, err := url.Parse(fmt.Sprintf("%s/key/%s", u, key))
	if err != nil {
		t.Fatalf("failed to parse URL for delete: %s", err)
	}
	req := &http.Request{
		Method: "DELETE",
		URL:    ru,
	}

	client := http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		t.Fatalf("failed to GET key: %s", err)
	}
	defer resp.Body.Close()
}
<commit_msg>Don't use response before checking for errors<commit_after>package httpd

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"testing"
)

// Test_NewServer tests that a server can perform all basic operations.
func Test_NewServer(t *testing.T) {
	store := newTestStore()
	s := &testServer{New(":0", store)}
	if s == nil {
		t.Fatal("failed to create HTTP service")
	}

	if err := s.Start(); err != nil {
		t.Fatalf("failed to start HTTP service: %s", err)
	}

	b := doGet(t, s.URL(), "k1")
	if string(b) != `{"k1":""}` {
		t.Fatalf("wrong value received for key k1: %s (expected empty string)", string(b))
	}

	doPost(t, s.URL(), "k1", "v1")

	b = doGet(t, s.URL(), "k1")
	if string(b) != `{"k1":"v1"}` {
		t.Fatalf(`wrong value received for key k1: %s (expected "v1")`, string(b))
	}

	store.m["k2"] = "v2"
	b = doGet(t, s.URL(), "k2")
	if string(b) != `{"k2":"v2"}` {
		t.Fatalf(`wrong value received for key k2: %s (expected "v2")`, string(b))
	}

	doDelete(t, s.URL(), "k2")
	b = doGet(t, s.URL(), "k2")
	if string(b) != `{"k2":""}` {
		t.Fatalf(`wrong value received for key k2: %s (expected empty string)`, string(b))
	}

}

type testServer struct {
	*Service
}

func (t *testServer) URL() string {
	port := strings.TrimLeft(t.Addr().String(), "[::]:")
	return fmt.Sprintf("http://127.0.0.1:%s", port)
}

type testStore struct {
	m map[string]string
}

func newTestStore() *testStore {
	return &testStore{
		m: make(map[string]string),
	}
}

func (t *testStore) Get(key string) (string, error) {
	return t.m[key], nil
}

func (t *testStore) Set(key, value string) error {
	t.m[key] = value
	return nil
}

func (t *testStore) Delete(key string) error {
	delete(t.m, key)
	return nil
}

func (t *testStore) Join(addr string) error {
	return nil
}

func doGet(t *testing.T, url, key string) string {
	resp, err := http.Get(fmt.Sprintf("%s/key/%s", url, key))
	if err != nil {
		t.Fatalf("failed to GET key: %s", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("failed to read response: %s", err)
	}
	return string(body)
}

func doPost(t *testing.T, url, key, value string) {
	b, err := json.Marshal(map[string]string{key: value})
	if err != nil {
		t.Fatalf("failed to encode key and value for POST: %s", err)
	}
	resp, err := http.Post(fmt.Sprintf("%s/key", url), "application-type/json", bytes.NewReader(b))
	if err != nil {
		t.Fatalf("POST request failed: %s", err)
	}
	defer resp.Body.Close()
}

func doDelete(t *testing.T, u, key string) {
	ru, err := url.Parse(fmt.Sprintf("%s/key/%s", u, key))
	if err != nil {
		t.Fatalf("failed to parse URL for delete: %s", err)
	}
	req := &http.Request{
		Method: "DELETE",
		URL:    ru,
	}

	client := http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		t.Fatalf("failed to GET key: %s", err)
	}
	defer resp.Body.Close()
}
<|endoftext|>


<commit_before>package http

import (
	"context"
	"io/ioutil"
	"testing"

	"github.com/getkin/kin-openapi/openapi3"
)

func TestValidSwagger(t *testing.T) {
	data, err := ioutil.ReadFile("./swagger.yml")
	if err != nil {
		t.Fatalf("unable to read swagger specification: %v", err)
	}
	swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromYAMLData(data)
	if err != nil {
		t.Fatalf("unable to load swagger specification: %v", err)
	}
	if err := swagger.Validate(context.Background()); err != nil {
		t.Errorf("invalid swagger specification: %v", err)
	}
}

func TestValidCurSwagger(t *testing.T) {
	data, err := ioutil.ReadFile("./cur_swagger.yml")
	if err != nil {
		t.Fatalf("unable to read swagger specification: %v", err)
	}
	swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromYAMLData(data)
	if err != nil {
		t.Fatalf("unable to load swagger specification: %v", err)
	}
	if err := swagger.Validate(context.Background()); err != nil {
		t.Errorf("invalid swagger specification: %v", err)
	}
}
<commit_msg>Remove validation of cur_swagger<commit_after>package http

import (
	"context"
	"io/ioutil"
	"testing"

	"github.com/getkin/kin-openapi/openapi3"
)

func TestValidSwagger(t *testing.T) {
	data, err := ioutil.ReadFile("./swagger.yml")
	if err != nil {
		t.Fatalf("unable to read swagger specification: %v", err)
	}
	swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromYAMLData(data)
	if err != nil {
		t.Fatalf("unable to load swagger specification: %v", err)
	}
	if err := swagger.Validate(context.Background()); err != nil {
		t.Errorf("invalid swagger specification: %v", err)
	}
}
<|endoftext|>


<commit_before>// Package application contains the server-side application code.
package application

/*
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
import (
	"github.com/gorilla/securecookie"
	"net/http"
	"net/http/httptest"
	"testing"
)

const reCaptchaTestResponse = "03AHJ_VutING-ky641XG-W15BMWlC31rMqgdxuAFji7Pqk1o6jqBF20CfKSTknHDlXLQlVgleevn5HTHsldBinf78xGvNYAX-gIXSzOX7aQBBTvNAY7o4SlLzUzEEC3AXNTqxz76ueA4bx2-0BHN5gfTG2vUBpktWKa7BOsJLPgAS9b2IidWB41UUccQl7pEs9H28qUKXGYRnKZFECk23jcjqMPkvDVTFASctPXC3a40YtiYB2bzY7LfqDeaqYH0_nJf0BcY_SZfhQJetE6KPhL9bocIOgcWRoZQ8b0eXKHClMfbHRTCfu10k0Eu1gzx3T992KoQ643C_YPPj2VasIDiNx1FEX_5Yvs2jzSYjRy2jyAtVtNEUSKhFoEd3pwGJJtx7eh6FbYcbAWZKZTuWejmGzpAQaB6fMuD5ykY1AIFYiYjFFXjks_K3ZICH4pmU6WFUDUDVUxiT28-OVWCtYr7X_s0Ce9fQ6L9tZINVaaZeqazzuxfeNxYI66PEV2nMVUjcBTwrLdVtaWjoH9S3Cpc9xoXZZe3dtfXkw2nyhK6CFehEoKOBi96HepA5cY1YWUbAeJMIYoEp-lla6OmENGhrkLN28mUHF-iH68fe2LxwkhCGMic09GVOOXE5TUFhspvIHfgoOBE4-s1j4AWezUP2hniuJClPsO6xxiAQgIqA2dy0_NNKLI3Cyb3dTIFd8yv26U7kSJUGxmjI4BHlRxoNXniBuf854UX820VpIFr-oXkJj0GoqBAcrlgucq8PsjuPOCdHoh8u2zTYFitxppqDR1NP4wzdVoKuZ-BVhQkJ1C3IsfrAkLyesFfF5y8KQFo1smzhMnHmEiMLRDWe9y9hhd3CpkNdofvedcaE6PJ_l-dH8hdmhS_PgSaZPHGM3Wym2U3xICD2Yde1BWp1Imik6eM43OkYJfP6sh_IdX38cWi74B3RfCA_Na1Tci3_24cuEs8IfBHeQnxgN7V5FGL204ZLFffeGIxmXlbInAeZgFEqJw3YjQfu4lbddYXTKOE6WJZcKmRSjXazt8ZXaxKJ_0SefI7udyg"

// NoopHTTPHandler exists only to satisfy the reCAPTCHA middleware passing the request
type NoopHTTPHandler struct{}

func (f NoopHTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	w.WriteHeader(200)
}

func TestRecaptchaMiddlewareForbiddenStatus(t *testing.T) {
	config, _ := LoadConfiguration("../conf/configuration.json")
	middleware := RecaptchaMiddleware{Configuration: config}

	req, err := http.NewRequest("GET", "/", nil)
	if err != nil {
		t.Fatal(err)
	}

	rr := httptest.NewRecorder()
	handler := http.Handler(middleware.Middleware(nil))

	handler.ServeHTTP(rr, req)

	if status := rr.Code; status != http.StatusForbidden {
		t.Errorf("handler did not not return the correct status code -- %v -- vs -- %v --", status, http.StatusForbidden)
	}
}

func TestRecaptchaMiddleware200Status(t *testing.T) {
	configuration, _ := LoadConfiguration("../conf/configuration.json")

	var hashKey = securecookie.GenerateRandomKey(64)
	var blockKey = securecookie.GenerateRandomKey(32)
	var s = securecookie.New(hashKey, blockKey)

	middleware := RecaptchaMiddleware{Configuration: configuration, SecureCookie: s}

	req, _ := http.NewRequest("GET", "/?c="+reCaptchaTestResponse, nil)
	handler := http.Handler(middleware.Middleware(NoopHTTPHandler{}))

	rr := httptest.NewRecorder()
	handler.ServeHTTP(rr, req)

	if status := rr.Code; status != http.StatusOK {
		t.Errorf("handler did not not return the correct status code -- %v -- vs -- %v --", status, http.StatusOK)
	}
}

func TestRecaptchaMiddlewareDisplayRecaptcha(t *testing.T) {
	c := &http.Cookie{Name: "reCAPTCHA"}

	req1, _ := http.NewRequest("GET", "/", nil)
	req1.AddCookie(c)

	if DisplayRecaptcha(req1) != false {
		t.Error("The reCAPTCHA cookie should be set in this request and the reCATPCHA should not be displayed")
	}

	req2, _ := http.NewRequest("GET", "/", nil)
	if DisplayRecaptcha(req2) != true {
		t.Error("The reCAPTCHA is not set in this request and the reCAPTCHA should be displayed")
	}
}
<commit_msg>Fixed broken tests<commit_after>// Package application contains the server-side application code.
package application

/*
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
import (
	"net/http"
	"net/http/httptest"
	"testing"
)

const reCaptchaTestResponse = "03AHJ_VutING-ky641XG-W15BMWlC31rMqgdxuAFji7Pqk1o6jqBF20CfKSTknHDlXLQlVgleevn5HTHsldBinf78xGvNYAX-gIXSzOX7aQBBTvNAY7o4SlLzUzEEC3AXNTqxz76ueA4bx2-0BHN5gfTG2vUBpktWKa7BOsJLPgAS9b2IidWB41UUccQl7pEs9H28qUKXGYRnKZFECk23jcjqMPkvDVTFASctPXC3a40YtiYB2bzY7LfqDeaqYH0_nJf0BcY_SZfhQJetE6KPhL9bocIOgcWRoZQ8b0eXKHClMfbHRTCfu10k0Eu1gzx3T992KoQ643C_YPPj2VasIDiNx1FEX_5Yvs2jzSYjRy2jyAtVtNEUSKhFoEd3pwGJJtx7eh6FbYcbAWZKZTuWejmGzpAQaB6fMuD5ykY1AIFYiYjFFXjks_K3ZICH4pmU6WFUDUDVUxiT28-OVWCtYr7X_s0Ce9fQ6L9tZINVaaZeqazzuxfeNxYI66PEV2nMVUjcBTwrLdVtaWjoH9S3Cpc9xoXZZe3dtfXkw2nyhK6CFehEoKOBi96HepA5cY1YWUbAeJMIYoEp-lla6OmENGhrkLN28mUHF-iH68fe2LxwkhCGMic09GVOOXE5TUFhspvIHfgoOBE4-s1j4AWezUP2hniuJClPsO6xxiAQgIqA2dy0_NNKLI3Cyb3dTIFd8yv26U7kSJUGxmjI4BHlRxoNXniBuf854UX820VpIFr-oXkJj0GoqBAcrlgucq8PsjuPOCdHoh8u2zTYFitxppqDR1NP4wzdVoKuZ-BVhQkJ1C3IsfrAkLyesFfF5y8KQFo1smzhMnHmEiMLRDWe9y9hhd3CpkNdofvedcaE6PJ_l-dH8hdmhS_PgSaZPHGM3Wym2U3xICD2Yde1BWp1Imik6eM43OkYJfP6sh_IdX38cWi74B3RfCA_Na1Tci3_24cuEs8IfBHeQnxgN7V5FGL204ZLFffeGIxmXlbInAeZgFEqJw3YjQfu4lbddYXTKOE6WJZcKmRSjXazt8ZXaxKJ_0SefI7udyg"

// NoopHTTPHandler exists only to satisfy the reCAPTCHA middleware passing the request
type NoopHTTPHandler struct{}

func (f NoopHTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	w.WriteHeader(200)
}

func TestRecaptchaMiddlewareForbiddenStatus(t *testing.T) {
	config, _ := LoadConfiguration("../conf/configuration.json")
	middleware := RecaptchaMiddleware{Configuration: config, SecureCookie: generateGorillaSecureCookie()}

	req, err := http.NewRequest("GET", "/", nil)
	if err != nil {
		t.Fatal(err)
	}

	rr := httptest.NewRecorder()
	handler := http.Handler(middleware.Middleware(nil))

	handler.ServeHTTP(rr, req)

	if status := rr.Code; status != http.StatusForbidden {
		t.Errorf("handler did not not return the correct status code -- %v -- vs -- %v --", status, http.StatusForbidden)
	}
}

func TestRecaptchaMiddleware200Status(t *testing.T) {
	configuration, _ := LoadConfiguration("../conf/configuration.json")
	middleware := RecaptchaMiddleware{Configuration: configuration, SecureCookie: generateGorillaSecureCookie()}

	req, _ := http.NewRequest("GET", "/?c="+reCaptchaTestResponse, nil)
	handler := http.Handler(middleware.Middleware(NoopHTTPHandler{}))

	rr := httptest.NewRecorder()
	handler.ServeHTTP(rr, req)

	if status := rr.Code; status != http.StatusOK {
		t.Errorf("handler did not not return the correct status code -- %v -- vs -- %v --", status, http.StatusOK)
	}
}

func TestRecaptchaMiddlewareDisplayRecaptcha(t *testing.T) {
	configuration, _ := LoadConfiguration("../conf/configuration.json")
	c := &http.Cookie{Name: configuration.Cookie.Name}

	req1, _ := http.NewRequest("GET", "/", nil)
	req1.AddCookie(c)

	if DisplayRecaptcha(req1) != false {
		t.Error("The reCAPTCHA cookie should be set in this request and the reCATPCHA should not be displayed")
	}

	req2, _ := http.NewRequest("GET", "/", nil)
	if DisplayRecaptcha(req2) != true {
		t.Error("The reCAPTCHA is not set in this request and the reCAPTCHA should be displayed")
	}
}
<|endoftext|>


<commit_before>// Copyright 2017 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 gps

import (
	"bytes"
	"crypto/sha256"
	"io"
	"sort"
	"strconv"
	"strings"

	"github.com/golang/dep/internal/gps/pkgtree"
)

// string headers used to demarcate sections in hash input creation
const (
	hhConstraints = "-CONSTRAINTS-"
	hhImportsReqs = "-IMPORTS/REQS-"
	hhIgnores     = "-IGNORES-"
	hhOverrides   = "-OVERRIDES-"
	hhAnalyzer    = "-ANALYZER-"
)

// HashInputs computes a hash digest of all data in SolveParams and the
// RootManifest that act as function inputs to Solve().
//
// The digest returned from this function is the same as the digest that would
// be included with a Solve() Result. As such, it's appropriate for comparison
// against the digest stored in a lock file, generated by a previous Solve(): if
// the digests match, then manifest and lock are in sync, and a Solve() is
// unnecessary.
//
// (Basically, this is for memoization.)
func (s *solver) HashInputs() (digest []byte) {
	h := sha256.New()
	s.writeHashingInputs(h)

	hd := h.Sum(nil)
	digest = hd[:]
	return
}

func (s *solver) writeHashingInputs(w io.Writer) {
	writeString := func(s string) {
		// Skip zero-length string writes; it doesn't affect the real hash
		// calculation, and keeps misleading newlines from showing up in the
		// debug output.
		if s != "" {
			// All users of writeHashingInputs cannot error on Write(), so just
			// ignore it
			w.Write([]byte(s))
		}
	}

	// We write "section headers" into the hash purely to ease scanning when
	// debugging this input-constructing algorithm; as long as the headers are
	// constant, then they're effectively a no-op.
	writeString(hhConstraints)

	// getApplicableConstraints will apply overrides, incorporate requireds,
	// apply local ignores, drop stdlib imports, and finally trim out
	// ineffectual constraints.
	for _, pd := range s.rd.getApplicableConstraints() {
		writeString(string(pd.Ident.ProjectRoot))
		writeString(pd.Ident.Source)
		writeString(pd.Constraint.typedString())
	}

	// Write out each discrete import, including those derived from requires.
	writeString(hhImportsReqs)
	imports := s.rd.externalImportList()
	sort.Strings(imports)
	for _, im := range imports {
		writeString(im)
	}

	// Add ignores, skipping any that point under the current project root;
	// those will have already been implicitly incorporated by the import
	// lister.
	writeString(hhIgnores)
	ig := make([]string, 0, len(s.rd.ig))
	for pkg := range s.rd.ig {
		if !strings.HasPrefix(pkg, s.rd.rpt.ImportRoot) || !isPathPrefixOrEqual(s.rd.rpt.ImportRoot, pkg) {
			ig = append(ig, pkg)
		}
	}
	sort.Strings(ig)

	for _, igp := range ig {
		writeString(igp)
	}

	// Overrides *also* need their own special entry distinct from basic
	// constraints, to represent the unique effects they can have on the entire
	// solving process beyond root's immediate scope.
	writeString(hhOverrides)
	for _, pc := range s.rd.ovr.asSortedSlice() {
		writeString(string(pc.Ident.ProjectRoot))
		if pc.Ident.Source != "" {
			writeString(pc.Ident.Source)
		}
		if pc.Constraint != nil {
			writeString(pc.Constraint.typedString())
		}
	}

	writeString(hhAnalyzer)
	an, av := s.rd.an.Info()
	writeString(an)
	writeString(strconv.Itoa(av))
}

// bytes.Buffer wrapper that injects newlines after each call to Write().
type nlbuf bytes.Buffer

func (buf *nlbuf) Write(p []byte) (n int, err error) {
	n, _ = (*bytes.Buffer)(buf).Write(p)
	(*bytes.Buffer)(buf).WriteByte('\n')
	return n + 1, nil
}

// HashingInputsAsString returns the raw input data used by Solver.HashInputs()
// as a string.
//
// This is primarily intended for debugging purposes.
func HashingInputsAsString(s Solver) string {
	ts := s.(*solver)
	buf := new(nlbuf)
	ts.writeHashingInputs(buf)

	return (*bytes.Buffer)(buf).String()
}

type sortPackageOrErr []pkgtree.PackageOrErr

func (s sortPackageOrErr) Len() int      { return len(s) }
func (s sortPackageOrErr) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

func (s sortPackageOrErr) Less(i, j int) bool {
	a, b := s[i], s[j]
	if a.Err != nil || b.Err != nil {
		// Sort errors last.
		if b.Err == nil {
			return false
		}
		if a.Err == nil {
			return true
		}
		// And then by string.
		return a.Err.Error() < b.Err.Error()
	}
	// And finally, sort by import path.
	return a.P.ImportPath < b.P.ImportPath
}
<commit_msg>internal/gps: remove unused sortPackageOrErr type<commit_after>// Copyright 2017 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 gps

import (
	"bytes"
	"crypto/sha256"
	"io"
	"sort"
	"strconv"
	"strings"
)

// string headers used to demarcate sections in hash input creation
const (
	hhConstraints = "-CONSTRAINTS-"
	hhImportsReqs = "-IMPORTS/REQS-"
	hhIgnores     = "-IGNORES-"
	hhOverrides   = "-OVERRIDES-"
	hhAnalyzer    = "-ANALYZER-"
)

// HashInputs computes a hash digest of all data in SolveParams and the
// RootManifest that act as function inputs to Solve().
//
// The digest returned from this function is the same as the digest that would
// be included with a Solve() Result. As such, it's appropriate for comparison
// against the digest stored in a lock file, generated by a previous Solve(): if
// the digests match, then manifest and lock are in sync, and a Solve() is
// unnecessary.
//
// (Basically, this is for memoization.)
func (s *solver) HashInputs() (digest []byte) {
	h := sha256.New()
	s.writeHashingInputs(h)

	hd := h.Sum(nil)
	digest = hd[:]
	return
}

func (s *solver) writeHashingInputs(w io.Writer) {
	writeString := func(s string) {
		// Skip zero-length string writes; it doesn't affect the real hash
		// calculation, and keeps misleading newlines from showing up in the
		// debug output.
		if s != "" {
			// All users of writeHashingInputs cannot error on Write(), so just
			// ignore it
			w.Write([]byte(s))
		}
	}

	// We write "section headers" into the hash purely to ease scanning when
	// debugging this input-constructing algorithm; as long as the headers are
	// constant, then they're effectively a no-op.
	writeString(hhConstraints)

	// getApplicableConstraints will apply overrides, incorporate requireds,
	// apply local ignores, drop stdlib imports, and finally trim out
	// ineffectual constraints.
	for _, pd := range s.rd.getApplicableConstraints() {
		writeString(string(pd.Ident.ProjectRoot))
		writeString(pd.Ident.Source)
		writeString(pd.Constraint.typedString())
	}

	// Write out each discrete import, including those derived from requires.
	writeString(hhImportsReqs)
	imports := s.rd.externalImportList()
	sort.Strings(imports)
	for _, im := range imports {
		writeString(im)
	}

	// Add ignores, skipping any that point under the current project root;
	// those will have already been implicitly incorporated by the import
	// lister.
	writeString(hhIgnores)
	ig := make([]string, 0, len(s.rd.ig))
	for pkg := range s.rd.ig {
		if !strings.HasPrefix(pkg, s.rd.rpt.ImportRoot) || !isPathPrefixOrEqual(s.rd.rpt.ImportRoot, pkg) {
			ig = append(ig, pkg)
		}
	}
	sort.Strings(ig)

	for _, igp := range ig {
		writeString(igp)
	}

	// Overrides *also* need their own special entry distinct from basic
	// constraints, to represent the unique effects they can have on the entire
	// solving process beyond root's immediate scope.
	writeString(hhOverrides)
	for _, pc := range s.rd.ovr.asSortedSlice() {
		writeString(string(pc.Ident.ProjectRoot))
		if pc.Ident.Source != "" {
			writeString(pc.Ident.Source)
		}
		if pc.Constraint != nil {
			writeString(pc.Constraint.typedString())
		}
	}

	writeString(hhAnalyzer)
	an, av := s.rd.an.Info()
	writeString(an)
	writeString(strconv.Itoa(av))
}

// bytes.Buffer wrapper that injects newlines after each call to Write().
type nlbuf bytes.Buffer

func (buf *nlbuf) Write(p []byte) (n int, err error) {
	n, _ = (*bytes.Buffer)(buf).Write(p)
	(*bytes.Buffer)(buf).WriteByte('\n')
	return n + 1, nil
}

// HashingInputsAsString returns the raw input data used by Solver.HashInputs()
// as a string.
//
// This is primarily intended for debugging purposes.
func HashingInputsAsString(s Solver) string {
	ts := s.(*solver)
	buf := new(nlbuf)
	ts.writeHashingInputs(buf)

	return (*bytes.Buffer)(buf).String()
}
<|endoftext|>


<commit_before>// Copyright 2016 Hajime Hoshi
//
// 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 loop

import (
	"errors"
	"time"

	"github.com/hajimehoshi/ebiten/internal/clock"
	"github.com/hajimehoshi/ebiten/internal/sync"
)

const FPS = 60

func CurrentFPS() float64 {
	if theRunContext == nil {
		return 0
	}
	return theRunContext.getCurrentFPS()
}

type runContext struct {
	currentFPS     float64
	runningSlowly  bool
	frames         int64
	framesForFPS   int64
	lastUpdated    int64
	lastFPSUpdated int64
	lastClockFrame int64
	ping           func()
	m              sync.RWMutex
}

var (
	theRunContext *runContext
	contextInitCh = make(chan struct{})
)

func (c *runContext) getCurrentFPS() float64 {
	c.m.RLock()
	v := c.currentFPS
	c.m.RUnlock()
	return v
}

func (c *runContext) updateFPS(fps float64) {
	c.m.Lock()
	c.currentFPS = fps
	c.m.Unlock()
}

func Start() error {
	// TODO: Need lock here?
	if theRunContext != nil {
		return errors.New("loop: The game is already running")
	}
	theRunContext = &runContext{}

	n := now()
	theRunContext.lastUpdated = n
	theRunContext.lastFPSUpdated = n

	close(contextInitCh)
	return nil
}

func End() {
	theRunContext = nil
}

func (c *runContext) updateCount(now int64) int {
	count := 0
	sync := false

	t := now - c.lastUpdated
	if t < 0 {
		return 0
	}

	if clock.IsValid() {
		if c.lastClockFrame != clock.Now() {
			sync = true
			f := clock.Now()
			if c.frames < f {
				count = int(f - c.frames)
			}
			c.lastClockFrame = f
		}
	} else {
		if t > 5*int64(time.Second)/int64(FPS) {
			// The previous time is too old. Let's assume that the window was unfocused.
			count = 0
			c.lastUpdated = now
		} else {
			count = int(t * int64(FPS) / int64(time.Second))
		}
	}

	// Stabilize FPS.
	if count == 0 && (int64(time.Second)/int64(FPS)/2) < t {
		count = 1
	}
	if count == 2 && (int64(time.Second)/int64(FPS)*3/2) > t {
		count = 1
	}

	if count > 3 {
		count = 3
	}

	if sync {
		c.lastUpdated = now
	} else {
		c.lastUpdated += int64(count) * int64(time.Second) / int64(FPS)
	}

	c.frames += int64(count)
	return count
}

func RegisterPing(ping func()) {
	<-contextInitCh
	theRunContext.registerPing(ping)
}

func (c *runContext) registerPing(ping func()) {
	c.m.Lock()
	c.ping = ping
	c.m.Unlock()
}

type Updater interface {
	Update(updateCount int) error
}

func Update(u Updater) error {
	<-contextInitCh
	return theRunContext.update(u)
}

func (c *runContext) update(u Updater) error {
	n := now()

	c.m.Lock()
	if c.ping != nil {
		c.ping()
	}
	c.m.Unlock()

	count := c.updateCount(n)
	if err := u.Update(count); err != nil {
		return err
	}
	c.framesForFPS++

	// Calc the current FPS.
	if time.Second > time.Duration(n-c.lastFPSUpdated) {
		return nil
	}
	currentFPS := float64(c.framesForFPS) * float64(time.Second) / float64(n-c.lastFPSUpdated)
	c.updateFPS(currentFPS)
	c.lastFPSUpdated = n
	c.framesForFPS = 0

	return nil
}
<commit_msg>loop: Bug fix: wrong updating |lastUpdated|<commit_after>// Copyright 2016 Hajime Hoshi
//
// 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 loop

import (
	"errors"
	"time"

	"github.com/hajimehoshi/ebiten/internal/clock"
	"github.com/hajimehoshi/ebiten/internal/sync"
)

const FPS = 60

func CurrentFPS() float64 {
	if theRunContext == nil {
		return 0
	}
	return theRunContext.getCurrentFPS()
}

type runContext struct {
	currentFPS     float64
	runningSlowly  bool
	frames         int64
	framesForFPS   int64
	lastUpdated    int64
	lastFPSUpdated int64
	lastClockFrame int64
	ping           func()
	m              sync.RWMutex
}

var (
	theRunContext *runContext
	contextInitCh = make(chan struct{})
)

func (c *runContext) getCurrentFPS() float64 {
	c.m.RLock()
	v := c.currentFPS
	c.m.RUnlock()
	return v
}

func (c *runContext) updateFPS(fps float64) {
	c.m.Lock()
	c.currentFPS = fps
	c.m.Unlock()
}

func Start() error {
	// TODO: Need lock here?
	if theRunContext != nil {
		return errors.New("loop: The game is already running")
	}
	theRunContext = &runContext{}

	n := now()
	theRunContext.lastUpdated = n
	theRunContext.lastFPSUpdated = n

	close(contextInitCh)
	return nil
}

func End() {
	theRunContext = nil
}

func (c *runContext) updateCount(now int64) int {
	count := 0
	sync := false

	t := now - c.lastUpdated
	if t < 0 {
		return 0
	}

	if clock.IsValid() {
		if c.lastClockFrame != clock.Now() {
			sync = true
			f := clock.Now()
			if c.frames < f {
				count = int(f - c.frames)
			}
			c.lastClockFrame = f
		}
	} else {
		if t > 5*int64(time.Second)/int64(FPS) {
			// The previous time is too old. Let's assume that the window was unfocused.
			count = 0
			sync = true
		} else {
			count = int(t * int64(FPS) / int64(time.Second))
		}
	}

	// Stabilize FPS.
	if count == 0 && (int64(time.Second)/int64(FPS)/2) < t {
		count = 1
	}
	if count == 2 && (int64(time.Second)/int64(FPS)*3/2) > t {
		count = 1
	}

	if count > 3 {
		count = 3
	}

	if sync {
		c.lastUpdated = now
	} else {
		c.lastUpdated += int64(count) * int64(time.Second) / int64(FPS)
	}

	c.frames += int64(count)
	return count
}

func RegisterPing(ping func()) {
	<-contextInitCh
	theRunContext.registerPing(ping)
}

func (c *runContext) registerPing(ping func()) {
	c.m.Lock()
	c.ping = ping
	c.m.Unlock()
}

type Updater interface {
	Update(updateCount int) error
}

func Update(u Updater) error {
	<-contextInitCh
	return theRunContext.update(u)
}

func (c *runContext) update(u Updater) error {
	n := now()

	c.m.Lock()
	if c.ping != nil {
		c.ping()
	}
	c.m.Unlock()

	count := c.updateCount(n)
	if err := u.Update(count); err != nil {
		return err
	}
	c.framesForFPS++

	// Calc the current FPS.
	if time.Second > time.Duration(n-c.lastFPSUpdated) {
		return nil
	}
	currentFPS := float64(c.framesForFPS) * float64(time.Second) / float64(n-c.lastFPSUpdated)
	c.updateFPS(currentFPS)
	c.lastFPSUpdated = n
	c.framesForFPS = 0

	return nil
}
<|endoftext|>