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

package ht

import (
	"fmt"
	"log"
	"os"
	"testing"
	"time"

	"github.com/kr/pretty"
)

func TestFindRawTest(t *testing.T) {
	sample := []byte(`
{
    Name: "TestName",
    Description: "TestDescription",
    BasedOn: [
        "../foo/base1",
        "base2"
    ],
    Request: {
        Method: "POST",
        URL: "http://www.the.url",
        Params: {
            single: "singleVal",
            multi: [ "multiVal1", "multiVal2", "multiVal3" ],
        },
        ParamsAs: "ParamsAs",
        Header: {
            HeaderA: [ "header A" ],
            HeaderB: [ "header B 1", "header B 2" ],
            HeaderC: [ "header C 1", "header C 2", "header C 3" ],
        },
        Cookies: [
            {Name: "Cookie1", Value: "CookieVal1"},
        ],
        Body: "RequestBody",
        FollowRedirects: true,
    },
    Checks: [
        {Check: "StatusCode", Expect: 200},
        {Check: "Header", Header: "X-Clacks-Overhead", Equals: "GNU Terry Pratchett"},
	{Check: "HTMLTag", Selector: "div#logo_bereich div.logo", Count: 1},
    ],
    VarEx: {
        VariableA: {Extractor: "BodyExtractor", Regexp: "[A-Z]+[0-9]+"},
    },
    Poll: {
        Max: 3,
        Sleep: "5432ms",
    },
    Verbosity: 1,
    Criticality: "Warn",
    PreSleep: "11ms",
    InterSleep: "22ms",
    PostSleep: "33ms",
}
`)

	pool := make(map[string]*rawTest)

	rt, basedir, err := findRawTest("/the/current/dir", "../qux/sample.ht", pool, sample)
	if err != nil {
		t.Fatalf("Unexpected error: %#v", err)
	}
	if basedir != "/the/current/qux" {
		t.Errorf("Got basedir=%q, want /the/current/qux")
	}

	// Check some simple values
	if rt.Name != "TestName" || rt.Description != "TestDescription" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.BasedOn[0] != "../foo/base1" || rt.BasedOn[1] != "base2" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Method != "POST" || rt.Request.URL != "http://www.the.url" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.ParamsAs != "ParamsAs" || rt.Request.Body != "RequestBody" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if len(rt.Request.Params) != 2 || len(rt.Request.Header) != 3 {
		t.Errorf("Got Test == %#v", *rt)
	}
	if len(rt.Request.Cookies) != 1 || rt.Request.FollowRedirects != true {
		t.Errorf("Got Test == %#v", *rt)
	}
	if len(rt.Checks) != 3 || len(rt.VarEx) != 1 {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Verbosity != 1 || rt.Criticality != CritWarn {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Poll.Max != 3 || rt.Poll.Sleep != Duration(5432*time.Millisecond) {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.PreSleep != Duration(11*time.Millisecond) {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.InterSleep != Duration(22*time.Millisecond) {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.PostSleep != Duration(33*time.Millisecond) {
		t.Errorf("Got Test == %#v", *rt)
	}

	if rt.Request.Params["single"][0] != "singleVal" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Params["multi"][2] != "multiVal3" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Header["HeaderA"][0] != "header A" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Header["HeaderB"][1] != "header B 2" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Header["HeaderC"][2] != "header C 3" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Cookies[0].Name != "Cookie1" || rt.Request.Cookies[0].Value != "CookieVal1" {
		t.Errorf("Got Test == %#v", *rt)
	}

}

func differences(t1, t2 *Test) (d []string) {
	if t1.Name != t2.Name {
		d = append(d, fmt.Sprintf("Name: %q != %q", t1.Name, t2.Name))
	}
	if t1.Description != t2.Description {
		d = append(d, fmt.Sprintf("Description: %q != %q", t1.Description, t2.Description))
	}
	return d
}

func TestLoadSuite(t *testing.T) {
	suite, err := LoadSuite("../testdata/sample.suite")
	if err != nil {
		t.Fatalf("Unexpected error %s", err.Error())
	}

	if testing.Verbose() {
		suite.Log = log.New(os.Stdout, "", log.LstdFlags)
	} else {
		for _, test := range suite.AllTests() {
			test.Verbosity = 0
		}
	}

	err = suite.Prepare()
	if err != nil {
		t.Fatalf("Unexpected error %s", err.Error())
	}
	if testing.Short() {
		t.Skip("Skipping execution without network in short mode.")
	}

	if testing.Short() {
		return
	}
	suite.Execute()
	if suite.Status != Pass {
		for _, tr := range suite.AllTests() {
			if tr.Status == Pass || !testing.Verbose() {
				continue
			}
			fmt.Println("Test", tr.Name)
			if tr.Error != nil {
				fmt.Println("  Error: ", tr.Error)
			} else {
				for _, cr := range tr.CheckResults {
					if cr.Status == Pass {
						continue
					}
					fmt.Println("  Fail: ", cr.Name, cr.JSON, cr.Status, cr.Error)
				}
			}
			if tr.Response.Response != nil &&
				tr.Response.Response.Request != nil {
				tr.Response.Response.Request.TLS = nil
				req := pretty.Sprintf("% #v", tr.Response.Response.Request)
				fmt.Printf("  Request\n%s\n", req)
				tr.Response.Response.Request = nil
				tr.Response.Response.TLS = nil
				resp := pretty.Sprintf("% #v", tr.Response.Response)
				fmt.Printf("  Response\n%s\n", resp)
			}
		}
	}

	if testing.Verbose() {
		fmt.Printf("\nDefault Text Output:\n")
		suite.PrintReport(os.Stdout)
		junit, err := suite.JUnit4XML()
		if err != nil {
			t.Fatalf("Unexpected error: %+v", err)
		}
		fmt.Printf("\nJUnit 4 XML Output:\n%s", junit)
		sr := NewSuiteResult()
		sr.Account(suite, true, true)
		fmt.Println(sr.Matrix())
		fmt.Printf("Default KPI: %.3f   JustBad KPI: %.3f    KPI: %.3f\n",
			sr.KPI(DefaultPenaltyFunc), sr.KPI(JustBadPenaltyFunc),
			sr.KPI(AllWrongPenaltyFunc))
	}
}

func TestLoadSuiteComplicated(t *testing.T) {
	suite, err := LoadSuite("testdata/suite.suite")
	if err != nil {
		t.Fatalf("Unexpected error %s", err.Error())
	}

	if n := len(suite.Setup); n != 1 {
		t.Errorf("Got %d setup tests, want 1", n)
	}

	if n := len(suite.Tests); n != 3 {
		t.Errorf("Got %d setup tests, want 1. Got %+v", n, suite.Tests)
	}

	if n := len(suite.Teardown); n != 1 {
		t.Errorf("Got %d teardown tests, want 1", n)
	}

}
<commit_msg>ht: better testing<commit_after>// Copyright 2014 Volker Dobler.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ht

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/kr/pretty"
)

var sampleTestJSON = `{
    Name: "TestName",
    Description: "TestDescription",
    BasedOn: [
        "../foo/base.ht",
        "std.ht"
    ],
    Request: {
        Method: "POST",
        URL: "http://www.the.url",
        Params: {
            single: "singleVal",
            multi: [ "multiVal1", "multiVal2", "multiVal3" ],
        },
        ParamsAs: "ParamsAs",
        Header: {
            HeaderA: [ "header A" ],
            HeaderB: [ "header B 1", "header B 2" ],
            HeaderC: [ "header C 1", "header C 2", "header C 3" ],
        },
        Cookies: [
            {Name: "Cookie1", Value: "CookieVal1"},
        ],
        Body: "RequestBody",
        FollowRedirects: true,
    },
    Checks: [
        {Check: "StatusCode", Expect: 200},
        {Check: "Header", Header: "X-Clacks-Overhead", Equals: "GNU Terry Pratchett"},
	{Check: "HTMLTag", Selector: "div#logo_bereich div.logo", Count: 1},
    ],
    VarEx: {
        VariableA: {Extractor: "BodyExtractor", Regexp: "[A-Z]+[0-9]+"},
    },
    Poll: {
        Max: 3,
        Sleep: "5432ms",
    },
    Timeout: "3.5s",
    Verbosity: 1,
    Criticality: "Warn",
    PreSleep: "11ms",
    InterSleep: "22ms",
    PostSleep: "33ms",
}`

func TestFindRawTest(t *testing.T) {
	sample := []byte(sampleTestJSON)

	pool := make(map[string]*rawTest)

	rt, basedir, err := findRawTest("/the/current/dir", "../qux/sample.ht", pool, sample)
	if err != nil {
		t.Fatalf("Unexpected error: %#v", err)
	}
	if basedir != "/the/current/qux" {
		t.Errorf("Got basedir=%q, want /the/current/qux")
	}

	// Check some simple values
	if rt.Name != "TestName" || rt.Description != "TestDescription" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.BasedOn[0] != "../foo/base.ht" || rt.BasedOn[1] != "std.ht" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Method != "POST" || rt.Request.URL != "http://www.the.url" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.ParamsAs != "ParamsAs" || rt.Request.Body != "RequestBody" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if len(rt.Request.Params) != 2 || len(rt.Request.Header) != 3 {
		t.Errorf("Got Test == %#v", *rt)
	}
	if len(rt.Request.Cookies) != 1 || rt.Request.FollowRedirects != true {
		t.Errorf("Got Test == %#v", *rt)
	}
	if len(rt.Checks) != 3 || len(rt.VarEx) != 1 {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Verbosity != 1 || rt.Criticality != CritWarn {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Poll.Max != 3 || rt.Poll.Sleep != Duration(5432*time.Millisecond) {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Timeout != Duration(3500*time.Millisecond) {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.PreSleep != Duration(11*time.Millisecond) {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.InterSleep != Duration(22*time.Millisecond) {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.PostSleep != Duration(33*time.Millisecond) {
		t.Errorf("Got Test == %#v", *rt)
	}

	if rt.Request.Params["single"][0] != "singleVal" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Params["multi"][2] != "multiVal3" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Header["HeaderA"][0] != "header A" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Header["HeaderB"][1] != "header B 2" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Header["HeaderC"][2] != "header C 3" {
		t.Errorf("Got Test == %#v", *rt)
	}
	if rt.Request.Cookies[0].Name != "Cookie1" || rt.Request.Cookies[0].Value != "CookieVal1" {
		t.Errorf("Got Test == %#v", *rt)
	}

}

var baseTestJSON = `{
    Name: "Base Test",
    Request: {
        Params: {
            base: "base",
        },
        Header: {
            Base: [ "Base" ],
        },
        Cookies: [
            {Name: "basecookie", Value: "basevalue"},
        ],
    },
    Checks: [
        {Check: "StatusCode", Expect: 400},
    ],
    VarEx: {
        BaseVar: {Extractor: "BodyExtractor", Regexp: "Base"},
    },
}`

var stdTestJSON = `{
    Name: "Std Test",
    Request: {
        Header: {
            Std: [ "std" ],
        },
    },
}`

func TestRawTestToTest(t *testing.T) {
	// Populate the raw test pool with the 'base' and 'std' tests which
	// are referenced from the sample test.
	pool := make(map[string]*rawTest)
	_, _, err := findRawTest("/the/current/dir", "std.ht", pool, []byte(stdTestJSON))
	if err != nil {
		t.Fatalf("Unexpected error: %#v", err)
	}
	_, _, err = findRawTest("/the/current/foo", "base.ht", pool, []byte(baseTestJSON))
	if err != nil {
		t.Fatalf("Unexpected error: %#v", err)
	}
	sample := []byte(sampleTestJSON)
	rt, _, err := findRawTest("/the/current/dir", "../qux/sample.ht", pool, sample)
	if err != nil {
		t.Fatalf("Unexpected error: %#v", err)
	}

	tests, err := rawTestToTests("/the/current/dir", rt, pool)
	if err != nil {
		t.Fatalf("Unexpected error: %#v", err)
	}

	want := &Test{
		Name:        "TestName",
		Description: "Merge of TestName, Base Test, Std Test\nTestDescription",
		Request: Request{
			Method: "POST",
			URL:    "http://www.the.url",
			Params: URLValues{
				"single": []string{"singleVal"},
				"multi":  []string{"multiVal1", "multiVal2", "multiVal3"},
				"base":   []string{"base"},
			},
			ParamsAs: "ParamsAs",
			Header: http.Header{
				"Base":    []string{"Base"},
				"Std":     []string{"std"},
				"HeaderB": []string{"header B 1", "header B 2"},
				"HeaderC": []string{"header C 1", "header C 2", "header C 3"},
				"HeaderA": []string{"header A"},
			},
			Cookies: []Cookie{
				{Name: "Cookie1", Value: "CookieVal1"},
				{Name: "basecookie", Value: "basevalue"},
			},
			Body:            "RequestBody",
			FollowRedirects: false,
		},
		Checks: CheckList{
			&StatusCode{Expect: 200},
			&Header{Header: "X-Clacks-Overhead", Condition: Condition{Equals: "GNU Terry Pratchett"}},
			&HTMLTag{Selector: "div#logo_bereich div.logo", Count: 1},
			&StatusCode{Expect: 400},
		},
		VarEx: map[string]Extractor{
			"BaseVar":   &BodyExtractor{Regexp: "[A-Z]+[0-9]+"},
			"VariableA": &BodyExtractor{Regexp: "Base"},
		},
		Poll: Poll{
			Max:   3,
			Sleep: 5432000000,
		},
		Timeout:     3500000000,
		Verbosity:   1,
		Criticality: 3,
		PreSleep:    11000000,
		InterSleep:  22000000,
		PostSleep:   33000000,
	}

	diff := differences(tests[0], want)

	if len(diff) != 0 {
		t.Error("Differences:\n" + strings.Join(diff, "\n"))
	}
}

func differences(t1, t2 *Test) (d []string) {
	if t1.Name != t2.Name {
		d = append(d, fmt.Sprintf("Name: %q != %q", t1.Name, t2.Name))
	}
	if t1.Description != t2.Description {
		d = append(d, fmt.Sprintf("Description: %q != %q", t1.Description, t2.Description))
	}

	if t1.Request.Method != t2.Request.Method {
		d = append(d, fmt.Sprintf("Method: %s != %s", t1.Request.Method, t2.Request.Method))
	}
	if t1.Request.URL != t2.Request.URL {
		d = append(d, fmt.Sprintf("URL: %s != %s", t1.Request.URL, t2.Request.URL))
	}
	if t1.Request.ParamsAs != t2.Request.ParamsAs {
		d = append(d, fmt.Sprintf("ParamsAs: %s != %s", t1.Request.ParamsAs, t2.Request.ParamsAs))
	}
	if t1.Request.Body != t2.Request.Body {
		d = append(d, fmt.Sprintf("Body: %s != %s", t1.Request.Body, t2.Request.Body))
	}
	if t1.Request.FollowRedirects != t2.Request.FollowRedirects {
		d = append(d, fmt.Sprintf("FollowRedirects: %t != %t",
			t1.Request.FollowRedirects, t2.Request.FollowRedirects))
	}

	d = append(d, mapToSliceDifference("Params", t1.Request.Params, t2.Request.Params)...)
	d = append(d, mapToSliceDifference("Header", t1.Request.Header, t2.Request.Header)...)
	if len(t1.Request.Cookies) != len(t2.Request.Cookies) {
		d = append(d, fmt.Sprintf("Cookies: %v != %v", t1.Request.Cookies, t2.Request.Cookies))
	} else {
		for i, c1 := range t1.Request.Cookies {
			if c2 := t2.Request.Cookies[i]; c1 != c2 {
				d = append(d, fmt.Sprintf("Cookie %d: %v != %v", i, c1, c2))
			}
		}
	}
	d = append(d, checklistDifference(t1.Checks, t2.Checks)...)

	if t1.Poll != t2.Poll {
		d = append(d, fmt.Sprintf("Poll: %v != %v", t1.Poll, t2.Poll))
	}
	if t1.Timeout != t2.Timeout {
		d = append(d, fmt.Sprintf("Timeout: %s != %s", t1.Timeout, t2.Timeout))
	}
	if t1.Verbosity != t2.Verbosity {
		d = append(d, fmt.Sprintf("Verbosity: %d != %d", t1.Verbosity, t2.Verbosity))
	}
	if t1.Criticality != t2.Criticality {
		d = append(d, fmt.Sprintf("Criticality: %d != %d", t1.Criticality, t2.Criticality))
	}
	if t1.PreSleep != t2.PreSleep {
		d = append(d, fmt.Sprintf("PreSleep: %s != %s", t1.PreSleep, t2.PreSleep))
	}
	if t1.InterSleep != t2.InterSleep {
		d = append(d, fmt.Sprintf("InterSleep: %s != %s", t1.InterSleep, t2.InterSleep))
	}
	if t1.PostSleep != t2.PostSleep {
		d = append(d, fmt.Sprintf("PostSleep: %s != %s", t1.PostSleep, t2.PostSleep))
	}

	return d
}

func mapToSliceDifference(what string, a, b map[string][]string) (d []string) {
	for an, av := range a {
		if bv, ok := b[an]; !ok {
			d = append(d, fmt.Sprintf("%s: %q-->%v missing in second", what, an, av))
		} else {
			d = append(d, sliceDifference(what+"["+an+"]", av, bv)...)
		}
	}
	return d
}

func sliceDifference(what string, a, b []string) []string {
	if len(a) == len(b) {
		for i := range a {
			if a[i] != b[i] {
				goto diffFound
			}
		}
		return nil
	}

diffFound:
	as, bs := strings.Join(a, ", "), strings.Join(b, ", ")
	return []string{fmt.Sprintf("%s: [%s] != [%s]", what, as, bs)}
}

func checklistDifference(a, b CheckList) []string {
	names := func(l CheckList) (n []string) {
		for _, check := range l {
			n = append(n, NameOf(check))
		}
		return n
	}
	aNames, bNames := names(a), names(b)
	diff := sliceDifference("Checks:", aNames, bNames)
	if diff != nil {
		return diff
	}
	// Selectively check StatusCodes. TODO: one more (e.g. HTMLTag)
	for i, c1 := range a {
		sc1, ok := c1.(*StatusCode)
		if !ok {
			continue
		}
		sc2, _ := b[i].(*StatusCode) // Must be StatusCode by Names.
		if sc1.Expect == sc2.Expect {
			continue
		}
		return []string{fmt.Sprintf("Check %d (StatusCode) %d != %d", i, sc1.Expect, sc2.Expect)}
	}
	return nil
}

func TestLoadSuite(t *testing.T) {
	suite, err := LoadSuite("../testdata/sample.suite")
	if err != nil {
		t.Fatalf("Unexpected error %s", err.Error())
	}

	if testing.Verbose() {
		suite.Log = log.New(os.Stdout, "", log.LstdFlags)
	} else {
		for _, test := range suite.AllTests() {
			test.Verbosity = 0
		}
	}

	err = suite.Prepare()
	if err != nil {
		t.Fatalf("Unexpected error %s", err.Error())
	}
	if testing.Short() {
		t.Skip("Skipping execution without network in short mode.")
	}

	if testing.Short() {
		return
	}
	suite.Execute()
	if suite.Status != Pass {
		for _, tr := range suite.AllTests() {
			if tr.Status == Pass || !testing.Verbose() {
				continue
			}
			fmt.Println("Test", tr.Name)
			if tr.Error != nil {
				fmt.Println("  Error: ", tr.Error)
			} else {
				for _, cr := range tr.CheckResults {
					if cr.Status == Pass {
						continue
					}
					fmt.Println("  Fail: ", cr.Name, cr.JSON, cr.Status, cr.Error)
				}
			}
			if tr.Response.Response != nil &&
				tr.Response.Response.Request != nil {
				tr.Response.Response.Request.TLS = nil
				req := pretty.Sprintf("% #v", tr.Response.Response.Request)
				fmt.Printf("  Request\n%s\n", req)
				tr.Response.Response.Request = nil
				tr.Response.Response.TLS = nil
				resp := pretty.Sprintf("% #v", tr.Response.Response)
				fmt.Printf("  Response\n%s\n", resp)
			}
		}
	}

	if testing.Verbose() {
		fmt.Printf("\nDefault Text Output:\n")
		suite.PrintReport(os.Stdout)
		junit, err := suite.JUnit4XML()
		if err != nil {
			t.Fatalf("Unexpected error: %+v", err)
		}
		fmt.Printf("\nJUnit 4 XML Output:\n%s", junit)
		sr := NewSuiteResult()
		sr.Account(suite, true, true)
		fmt.Println(sr.Matrix())
		fmt.Printf("Default KPI: %.3f   JustBad KPI: %.3f    KPI: %.3f\n",
			sr.KPI(DefaultPenaltyFunc), sr.KPI(JustBadPenaltyFunc),
			sr.KPI(AllWrongPenaltyFunc))
	}
}

func TestLoadSuiteComplicated(t *testing.T) {
	suite, err := LoadSuite("testdata/suite.suite")
	if err != nil {
		t.Fatalf("Unexpected error %s", err.Error())
	}

	if n := len(suite.Setup); n != 1 {
		t.Errorf("Got %d setup tests, want 1", n)
	}

	if n := len(suite.Tests); n != 3 {
		t.Errorf("Got %d setup tests, want 1. Got %+v", n, suite.Tests)
	}

	if n := len(suite.Teardown); n != 1 {
		t.Errorf("Got %d teardown tests, want 1", n)
	}

}
<|endoftext|>


<commit_before>package render_test

import (
	"bytes"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/gobuffalo/buffalo/render"
	"github.com/gobuffalo/velvet"
	"github.com/stretchr/testify/require"
)

func Test_Template(t *testing.T) {
	r := require.New(t)

	tmpFile, err := ioutil.TempFile("", "test")
	r.NoError(err)
	defer os.Remove(tmpFile.Name())

	_, err = tmpFile.Write([]byte("{{name}}"))
	r.NoError(err)

	type ji func(string, ...string) render.Renderer

	table := []ji{
		render.New(render.Options{
			TemplateEngine: velvet.BuffaloRenderer,
		}).Template,
	}

	for _, j := range table {
		re := j("foo/bar", tmpFile.Name())
		r.Equal("foo/bar", re.ContentType())
		bb := &bytes.Buffer{}
		err = re.Render(bb, render.Data{"name": "Mark"})
		r.NoError(err)
		r.Equal("Mark", strings.TrimSpace(bb.String()))
	}
}

func Test_Template_Partial(t *testing.T) {
	r := require.New(t)

	tPath, err := ioutil.TempDir("", "")
	r.NoError(err)
	defer os.Remove(tPath)

	partFile, err := os.Create(filepath.Join(tPath, "_foo.html"))
	r.NoError(err)

	_, err = partFile.Write([]byte("Foo -> {{name}}"))
	r.NoError(err)

	tmpFile, err := os.Create(filepath.Join(tPath, "index.html"))
	r.NoError(err)

	_, err = tmpFile.Write([]byte(`{{partial "foo.html"}}`))
	r.NoError(err)

	type ji func(string, ...string) render.Renderer

	table := []ji{
		render.New(render.Options{
			TemplatesPath:  tPath,
			TemplateEngine: velvet.BuffaloRenderer,
		}).Template,
	}

	for _, j := range table {
		re := j("foo/bar", "index.html")
		r.Equal("foo/bar", re.ContentType())
		bb := &bytes.Buffer{}
		err = re.Render(bb, render.Data{"name": "Mark"})
		r.NoError(err)
		r.Equal("Foo -> Mark", strings.TrimSpace(bb.String()))
	}
}
<commit_msg>template test now uses plush<commit_after>package render_test

import (
	"bytes"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/gobuffalo/buffalo/render"
	"github.com/gobuffalo/plush"
	"github.com/stretchr/testify/require"
)

func Test_Template(t *testing.T) {
	r := require.New(t)

	tmpFile, err := ioutil.TempFile("", "test")
	r.NoError(err)
	defer os.Remove(tmpFile.Name())

	_, err = tmpFile.Write([]byte("<%= name %>"))
	r.NoError(err)

	type ji func(string, ...string) render.Renderer

	table := []ji{
		render.New(render.Options{
			TemplateEngine: plush.BuffaloRenderer,
		}).Template,
	}

	for _, j := range table {
		re := j("foo/bar", tmpFile.Name())
		r.Equal("foo/bar", re.ContentType())
		bb := &bytes.Buffer{}
		err = re.Render(bb, render.Data{"name": "Mark"})
		r.NoError(err)
		r.Equal("Mark", strings.TrimSpace(bb.String()))
	}
}

func Test_Template_Partial(t *testing.T) {
	r := require.New(t)

	tPath, err := ioutil.TempDir("", "")
	r.NoError(err)
	defer os.Remove(tPath)

	partFile, err := os.Create(filepath.Join(tPath, "_foo.html"))
	r.NoError(err)

	_, err = partFile.Write([]byte("Foo -> <%= name %>"))
	r.NoError(err)

	tmpFile, err := os.Create(filepath.Join(tPath, "index.html"))
	r.NoError(err)

	_, err = tmpFile.Write([]byte(`<%= partial("foo.html") %>`))
	r.NoError(err)

	type ji func(string, ...string) render.Renderer

	table := []ji{
		render.New(render.Options{
			TemplatesPath:  tPath,
			TemplateEngine: plush.BuffaloRenderer,
		}).Template,
	}

	for _, j := range table {
		re := j("foo/bar", "index.html")
		r.Equal("foo/bar", re.ContentType())
		bb := &bytes.Buffer{}
		err = re.Render(bb, render.Data{"name": "Mark"})
		r.NoError(err)
		r.Equal("Foo -> Mark", strings.TrimSpace(bb.String()))
	}
}
<|endoftext|>


<commit_before><commit_msg>S종목별_일일_가격정보_모음 디버깅<commit_after><|endoftext|>


<commit_before>// Copyright 2013 The go-github 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 desk

import (
	"bytes"
	"fmt"
	"io"

	"reflect"
)

var timestampType = reflect.TypeOf(Timestamp{})

// Stringify attempts to create a reasonable string representation of types in
// the GitHub library.  It does things like resolve pointers to their values
// and omits struct fields with nil values.
func Stringify(message interface{}) string {
	var buf bytes.Buffer
	v := reflect.ValueOf(message)
	stringifyValue(&buf, v)
	return buf.String()
}

// stringifyValue was heavily inspired by the goprotobuf library.

func stringifyValue(w io.Writer, val reflect.Value) {
	if val.Kind() == reflect.Ptr && val.IsNil() {
		w.Write([]byte("<nil>"))
		return
	}

	v := reflect.Indirect(val)

	switch v.Kind() {
	case reflect.String:
		fmt.Fprintf(w, `"%s"`, v)
	case reflect.Slice:
		w.Write([]byte{'['})
		for i := 0; i < v.Len(); i++ {
			if i > 0 {
				w.Write([]byte{' '})
			}

			stringifyValue(w, v.Index(i))
		}

		w.Write([]byte{']'})
		return
	case reflect.Struct:
		if v.Type().Name() != "" {
			w.Write([]byte(v.Type().String()))
		}

		// special handling of Timestamp values
		if v.Type() == timestampType {
			fmt.Fprintf(w, "{%s}", v.Interface())
			return
		}

		w.Write([]byte{'{'})

		var sep bool
		for i := 0; i < v.NumField(); i++ {
			fv := v.Field(i)
			if fv.Kind() == reflect.Ptr && fv.IsNil() {
				continue
			}
			if fv.Kind() == reflect.Slice && fv.IsNil() {
				continue
			}

			if sep {
				w.Write([]byte(", "))
			} else {
				sep = true
			}

			w.Write([]byte(v.Type().Field(i).Name))
			w.Write([]byte{':'})
			stringifyValue(w, fv)
		}

		w.Write([]byte{'}'})
	default:
		if v.CanInterface() {
			fmt.Fprint(w, v.Interface())
		}
	}
}
<commit_msg>Create interface for making types stringable<commit_after>// Copyright 2013 The go-github 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 desk

import (
	"bytes"
	"fmt"
	"io"

	"reflect"
)

type Stringable interface {
  String() string
}

var timestampType = reflect.TypeOf(Timestamp{})

// Stringify attempts to create a reasonable string representation of types in
// the GitHub library.  It does things like resolve pointers to their values
// and omits struct fields with nil values.
func Stringify(message interface{}) string {
	var buf bytes.Buffer
	v := reflect.ValueOf(message)
	stringifyValue(&buf, v)
	return buf.String()
}

// stringifyValue was heavily inspired by the goprotobuf library.

func stringifyValue(w io.Writer, val reflect.Value) {
	if val.Kind() == reflect.Ptr && val.IsNil() {
		w.Write([]byte("<nil>"))
		return
	}

	v := reflect.Indirect(val)

	switch v.Kind() {
	case reflect.String:
		fmt.Fprintf(w, `"%s"`, v)
	case reflect.Slice:
		w.Write([]byte{'['})
		for i := 0; i < v.Len(); i++ {
			if i > 0 {
				w.Write([]byte{' '})
			}

			stringifyValue(w, v.Index(i))
		}

		w.Write([]byte{']'})
		return
	case reflect.Struct:
		if v.Type().Name() != "" {
			w.Write([]byte(v.Type().String()))
		}

		// special handling of Timestamp values
		if v.Type() == timestampType {
			fmt.Fprintf(w, "{%s}", v.Interface())
			return
		}

		w.Write([]byte{'{'})

		var sep bool
		for i := 0; i < v.NumField(); i++ {
			fv := v.Field(i)
			if fv.Kind() == reflect.Ptr && fv.IsNil() {
				continue
			}
			if fv.Kind() == reflect.Slice && fv.IsNil() {
				continue
			}

			if sep {
				w.Write([]byte(", "))
			} else {
				sep = true
			}

			w.Write([]byte(v.Type().Field(i).Name))
			w.Write([]byte{':'})
			stringifyValue(w, fv)
		}

		w.Write([]byte{'}'})
	default:
		if v.CanInterface() {
			fmt.Fprint(w, v.Interface())
		}
	}
}
<|endoftext|>


<commit_before>package soy

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"

	"code.google.com/p/go.exp/fsnotify"
	"github.com/robfig/soy/data"
	"github.com/robfig/soy/parse"
	"github.com/robfig/soy/parsepasses"
	"github.com/robfig/soy/template"
	"github.com/robfig/soy/tofu"
)

// Logger is used to print soy compile error messages when using the
// "WatchFiles" feature.
var Logger = log.New(os.Stderr, "[soy] ", 0)

type soyFile struct{ name, content string }

// Bundle is a collection of soy content (templates and globals).  It acts as
// input for the soy parser.
type Bundle struct {
	files   []soyFile
	globals data.Map
	err     error
	watcher *fsnotify.Watcher
}

func NewBundle() *Bundle {
	return &Bundle{globals: make(data.Map)}
}

// WatchFiles tells soy to watch any template files added to this bundle,
// re-compile as necessary, and propagate the updates to your tofu.  It should
// be called once, before adding any files.
func (b *Bundle) WatchFiles(watch bool) *Bundle {
	if watch && b.err == nil && b.watcher == nil {
		b.watcher, b.err = fsnotify.NewWatcher()
	}
	return b
}

// AddTemplateDir adds all *.soy files found within the given directory
// (including sub-directories) to the bundle.
func (b *Bundle) AddTemplateDir(root string) *Bundle {
	var err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil
		}
		if !strings.HasSuffix(path, ".soy") {
			return nil
		}
		b.AddTemplateFile(path)
		return nil
	})
	if err != nil {
		b.err = err
	}
	return b
}

// AddTemplateFile adds the given soy template file text to this bundle.
func (b *Bundle) AddTemplateFile(filename string) *Bundle {
	content, err := ioutil.ReadFile(filename)
	if err != nil {
		b.err = err
	}
	if b.err == nil && b.watcher != nil {
		b.err = b.watcher.Watch(filename)
	}
	return b.AddTemplateString(filename, string(content))
}

func (b *Bundle) AddTemplateString(filename, soyfile string) *Bundle {
	b.files = append(b.files, soyFile{filename, soyfile})
	return b
}

func (b *Bundle) AddGlobalsFile(filename string) *Bundle {
	var f, err = os.Open(filename)
	if err != nil {
		b.err = err
		return b
	}
	globals, err := ParseGlobals(f)
	if err != nil {
		b.err = err
	}
	return b.AddGlobalsMap(globals)
}

func (b *Bundle) AddGlobalsMap(globals data.Map) *Bundle {
	for k, v := range globals {
		if existing, ok := b.globals[k]; ok {
			b.err = fmt.Errorf("global %q already defined as %q", k, existing)
			return b
		}
		b.globals[k] = v
	}
	return b
}

func (b *Bundle) CompileToTofu() (*tofu.Tofu, error) {
	if b.err != nil {
		return nil, b.err
	}

	// Compile all the soy (globals are already parsed)
	var registry = template.Registry{}
	for _, soyfile := range b.files {
		var tree, err = parse.Soy(soyfile.name, soyfile.content, b.globals)
		if err != nil {
			return nil, err
		}
		if err = registry.Add(tree); err != nil {
			return nil, err
		}
	}

	// Apply the post-parse processing
	var err = parsepasses.CheckDataRefs(registry)
	if err != nil {
		return nil, err
	}

	var tofu = &tofu.Tofu{registry}
	if b.watcher != nil {
		go b.tofuUpdater(tofu)
	}
	return tofu, nil
}

func (b *Bundle) tofuUpdater(tofu *tofu.Tofu) {
	for {
		select {
		case <-b.watcher.Event:
			// Drain any queued events before rebuilding.
			for {
				select {
				case <-b.watcher.Event:
					continue
				default:
				}
				break
			}

			// Recompile all the soy.
			var bundle = NewBundle().
				AddGlobalsMap(b.globals)
			for _, soyfile := range b.files {
				bundle.AddTemplateFile(soyfile.name)
			}
			var newTofu, err = bundle.CompileToTofu()
			if err != nil {
				Logger.Println(err)
				continue
			}
			// update the existing tofu's template registry.
			tofu.Registry = newTofu.Registry

		case err := <-b.watcher.Error:
			// Nothing to do with errors
			Logger.Println(err)
		}
	}
}
<commit_msg>Bundle.WatchFiles: Ignore file attribute changes, log on update<commit_after>package soy

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"

	"code.google.com/p/go.exp/fsnotify"
	"github.com/robfig/soy/data"
	"github.com/robfig/soy/parse"
	"github.com/robfig/soy/parsepasses"
	"github.com/robfig/soy/template"
	"github.com/robfig/soy/tofu"
)

// Logger is used to print soy compile error messages when using the
// "WatchFiles" feature.
var Logger = log.New(os.Stderr, "[soy] ", 0)

type soyFile struct{ name, content string }

// Bundle is a collection of soy content (templates and globals).  It acts as
// input for the soy parser.
type Bundle struct {
	files   []soyFile
	globals data.Map
	err     error
	watcher *fsnotify.Watcher
}

func NewBundle() *Bundle {
	return &Bundle{globals: make(data.Map)}
}

// WatchFiles tells soy to watch any template files added to this bundle,
// re-compile as necessary, and propagate the updates to your tofu.  It should
// be called once, before adding any files.
func (b *Bundle) WatchFiles(watch bool) *Bundle {
	if watch && b.err == nil && b.watcher == nil {
		b.watcher, b.err = fsnotify.NewWatcher()
	}
	return b
}

// AddTemplateDir adds all *.soy files found within the given directory
// (including sub-directories) to the bundle.
func (b *Bundle) AddTemplateDir(root string) *Bundle {
	var err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil
		}
		if !strings.HasSuffix(path, ".soy") {
			return nil
		}
		b.AddTemplateFile(path)
		return nil
	})
	if err != nil {
		b.err = err
	}
	return b
}

// AddTemplateFile adds the given soy template file text to this bundle.
func (b *Bundle) AddTemplateFile(filename string) *Bundle {
	content, err := ioutil.ReadFile(filename)
	if err != nil {
		b.err = err
	}
	if b.err == nil && b.watcher != nil {
		b.err = b.watcher.Watch(filename)
	}
	return b.AddTemplateString(filename, string(content))
}

func (b *Bundle) AddTemplateString(filename, soyfile string) *Bundle {
	b.files = append(b.files, soyFile{filename, soyfile})
	return b
}

func (b *Bundle) AddGlobalsFile(filename string) *Bundle {
	var f, err = os.Open(filename)
	if err != nil {
		b.err = err
		return b
	}
	globals, err := ParseGlobals(f)
	if err != nil {
		b.err = err
	}
	return b.AddGlobalsMap(globals)
}

func (b *Bundle) AddGlobalsMap(globals data.Map) *Bundle {
	for k, v := range globals {
		if existing, ok := b.globals[k]; ok {
			b.err = fmt.Errorf("global %q already defined as %q", k, existing)
			return b
		}
		b.globals[k] = v
	}
	return b
}

func (b *Bundle) CompileToTofu() (*tofu.Tofu, error) {
	if b.err != nil {
		return nil, b.err
	}

	// Compile all the soy (globals are already parsed)
	var registry = template.Registry{}
	for _, soyfile := range b.files {
		var tree, err = parse.Soy(soyfile.name, soyfile.content, b.globals)
		if err != nil {
			return nil, err
		}
		if err = registry.Add(tree); err != nil {
			return nil, err
		}
	}

	// Apply the post-parse processing
	var err = parsepasses.CheckDataRefs(registry)
	if err != nil {
		return nil, err
	}

	var tofu = &tofu.Tofu{registry}
	if b.watcher != nil {
		go b.tofuUpdater(tofu)
	}
	return tofu, nil
}

func (b *Bundle) tofuUpdater(tofu *tofu.Tofu) {
	for {
		select {
		case ev := <-b.watcher.Event:
			if ev.IsAttrib() {
				continue
			}

			// Recompile all the soy.
			var bundle = NewBundle().
				AddGlobalsMap(b.globals)
			for _, soyfile := range b.files {
				bundle.AddTemplateFile(soyfile.name)
			}
			var newTofu, err = bundle.CompileToTofu()
			if err != nil {
				Logger.Println(err)
				continue
			}

			// update the existing tofu's template registry.
			// (this is not goroutine-safe, but that seems ok for a development aid,
			// as long as it works in practice)
			tofu.Registry = newTofu.Registry
			Logger.Printf("update successful (%v)", ev)

		case err := <-b.watcher.Error:
			// Nothing to do with errors
			Logger.Println(err)
		}
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"reflect"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/batch"
	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

func TestAccAWSBatchJobDefinition_basic(t *testing.T) {
	var jd batch.JobDefinition
	rName := acctest.RandomWithPrefix("tf-acc-test")
	resourceName := "aws_batch_job_definition.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckBatchJobDefinitionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBatchJobDefinitionConfigName(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckBatchJobDefinitionExists(resourceName, &jd),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAWSBatchJobDefinition_ContainerProperties_Advanced(t *testing.T) {
	var jd batch.JobDefinition
	compare := batch.JobDefinition{
		Parameters: map[string]*string{
			"param1": aws.String("val1"),
			"param2": aws.String("val2"),
		},
		RetryStrategy: &batch.RetryStrategy{
			Attempts: aws.Int64(int64(1)),
		},
		Timeout: &batch.JobTimeout{
			AttemptDurationSeconds: aws.Int64(int64(60)),
		},
		ContainerProperties: &batch.ContainerProperties{
			Command: []*string{aws.String("ls"), aws.String("-la")},
			Environment: []*batch.KeyValuePair{
				{Name: aws.String("VARNAME"), Value: aws.String("VARVAL")},
			},
			Image:  aws.String("busybox"),
			Memory: aws.Int64(int64(512)),
			MountPoints: []*batch.MountPoint{
				{ContainerPath: aws.String("/tmp"), ReadOnly: aws.Bool(false), SourceVolume: aws.String("tmp")},
			},
			ResourceRequirements: []*batch.ResourceRequirement{},
			Ulimits: []*batch.Ulimit{
				{HardLimit: aws.Int64(int64(1024)), Name: aws.String("nofile"), SoftLimit: aws.Int64(int64(1024))},
			},
			Vcpus: aws.Int64(int64(1)),
			Volumes: []*batch.Volume{
				{
					Host: &batch.Host{SourcePath: aws.String("/tmp")},
					Name: aws.String("tmp"),
				},
			},
		},
	}
	rName := acctest.RandomWithPrefix("tf-acc-test")
	resourceName := "aws_batch_job_definition.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckBatchJobDefinitionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBatchJobDefinitionConfigContainerPropertiesAdvanced(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckBatchJobDefinitionExists(resourceName, &jd),
					testAccCheckBatchJobDefinitionAttributes(&jd, &compare),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAWSBatchJobDefinition_updateForcesNewResource(t *testing.T) {
	var before, after batch.JobDefinition
	rName := acctest.RandomWithPrefix("tf-acc-test")
	resourceName := "aws_batch_job_definition.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckBatchJobDefinitionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBatchJobDefinitionConfigContainerPropertiesAdvanced(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckBatchJobDefinitionExists(resourceName, &before),
					testAccCheckBatchJobDefinitionAttributes(&before, nil),
				),
			},
			{
				Config: testAccBatchJobDefinitionConfigContainerPropertiesAdvancedUpdate(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckBatchJobDefinitionExists(resourceName, &after),
					testAccCheckJobDefinitionRecreated(t, &before, &after),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccCheckBatchJobDefinitionExists(n string, jd *batch.JobDefinition) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No Batch Job Queue ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).batchconn
		arn := rs.Primary.Attributes["arn"]
		def, err := getJobDefinition(conn, arn)
		if err != nil {
			return err
		}
		if def == nil {
			return fmt.Errorf("Not found: %s", n)
		}
		*jd = *def

		return nil
	}
}

func testAccCheckBatchJobDefinitionAttributes(jd *batch.JobDefinition, compare *batch.JobDefinition) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		for _, rs := range s.RootModule().Resources {
			if rs.Type != "aws_batch_job_definition" {
				continue
			}
			if *jd.JobDefinitionArn != rs.Primary.Attributes["arn"] {
				return fmt.Errorf("Bad Job Definition ARN\n\t expected: %s\n\tgot: %s\n", rs.Primary.Attributes["arn"], *jd.JobDefinitionArn)
			}
			if compare != nil {
				if compare.Parameters != nil && !reflect.DeepEqual(compare.Parameters, jd.Parameters) {
					return fmt.Errorf("Bad Job Definition Params\n\t expected: %v\n\tgot: %v\n", compare.Parameters, jd.Parameters)
				}
				if compare.RetryStrategy != nil && *compare.RetryStrategy.Attempts != *jd.RetryStrategy.Attempts {
					return fmt.Errorf("Bad Job Definition Retry Strategy\n\t expected: %d\n\tgot: %d\n", *compare.RetryStrategy.Attempts, *jd.RetryStrategy.Attempts)
				}
				if compare.ContainerProperties != nil && compare.ContainerProperties.Command != nil && !reflect.DeepEqual(compare.ContainerProperties, jd.ContainerProperties) {
					return fmt.Errorf("Bad Job Definition Container Properties\n\t expected: %s\n\tgot: %s\n", compare.ContainerProperties, jd.ContainerProperties)
				}
			}
		}
		return nil
	}
}

func testAccCheckJobDefinitionRecreated(t *testing.T,
	before, after *batch.JobDefinition) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if *before.Revision == *after.Revision {
			t.Fatalf("Expected change of JobDefinition Revisions, but both were %v", before.Revision)
		}
		return nil
	}
}

func testAccCheckBatchJobDefinitionDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_batch_job_definition" {
			continue
		}
		conn := testAccProvider.Meta().(*AWSClient).batchconn
		js, err := getJobDefinition(conn, rs.Primary.Attributes["arn"])
		if err == nil && js != nil {
			if *js.Status == "ACTIVE" {
				return fmt.Errorf("Error: Job Definition still active")
			}
		}
		return nil
	}
	return nil
}

func testAccBatchJobDefinitionConfigContainerPropertiesAdvanced(rName string) string {
	return fmt.Sprintf(`
resource "aws_batch_job_definition" "test" {
	name = %[1]q
	type = "container"
	parameters = {
		param1 = "val1"
		param2 = "val2"
	}
	retry_strategy {
		attempts = 1
	}
	timeout {
		attempt_duration_seconds = 60
	}
	container_properties = <<CONTAINER_PROPERTIES
{
	"command": ["ls", "-la"],
	"image": "busybox",
	"memory": 512,
	"vcpus": 1,
	"volumes": [
      {
        "host": {
          "sourcePath": "/tmp"
        },
        "name": "tmp"
      }
    ],
	"environment": [
		{"name": "VARNAME", "value": "VARVAL"}
	],
	"mountPoints": [
		{
          "sourceVolume": "tmp",
          "containerPath": "/tmp",
          "readOnly": false
        }
	],
    "ulimits": [
      {
        "hardLimit": 1024,
        "name": "nofile",
        "softLimit": 1024
      }
    ]
}
CONTAINER_PROPERTIES
}
`, rName)
}

func testAccBatchJobDefinitionConfigContainerPropertiesAdvancedUpdate(rName string) string {
	return fmt.Sprintf(`
resource "aws_batch_job_definition" "test" {
	name = %[1]q
	type = "container"
	container_properties = <<CONTAINER_PROPERTIES
{
	"command": ["ls", "-la"],
	"image": "busybox",
	"memory": 1024,
	"vcpus": 1,
	"volumes": [
      {
        "host": {
          "sourcePath": "/tmp"
        },
        "name": "tmp"
      }
    ],
	"environment": [
		{"name": "VARNAME", "value": "VARVAL"}
	],
	"mountPoints": [
		{
          "sourceVolume": "tmp",
          "containerPath": "/tmp",
          "readOnly": false
        }
	],
    "ulimits": [
      {
        "hardLimit": 1024,
        "name": "nofile",
        "softLimit": 1024
      }
    ]
}
CONTAINER_PROPERTIES
}
`, rName)
}

func testAccBatchJobDefinitionConfigName(rName string) string {
	return fmt.Sprintf(`
resource "aws_batch_job_definition" "test" {
  container_properties = jsonencode({
    command = ["echo", "test"]
    image   = "busybox"
    memory  = 128
    vcpus   = 1
  })
  name = %[1]q
  type = "container"
}
`, rName)
}
<commit_msg>tests/resource/aws_batch_job_definition: Add sweeper (#13427)<commit_after>package aws

import (
	"fmt"
	"log"
	"reflect"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/batch"
	"github.com/hashicorp/go-multierror"
	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

func init() {
	resource.AddTestSweepers("aws_batch_job_definition", &resource.Sweeper{
		Name: "aws_batch_job_definition",
		F:    testSweepBatchJobDefinitions,
		Dependencies: []string{
			"aws_batch_job_queue",
		},
	})
}

func testSweepBatchJobDefinitions(region string) error {
	client, err := sharedClientForRegion(region)
	if err != nil {
		return fmt.Errorf("error getting client: %w", err)
	}
	conn := client.(*AWSClient).batchconn
	var sweeperErrs *multierror.Error

	err = conn.DescribeJobDefinitionsPages(&batch.DescribeJobDefinitionsInput{}, func(page *batch.DescribeJobDefinitionsOutput, isLast bool) bool {
		if page == nil {
			return !isLast
		}

		for _, jobDefinition := range page.JobDefinitions {
			arn := aws.StringValue(jobDefinition.JobDefinitionArn)

			log.Printf("[INFO] Deleting Batch Job Definition: %s", arn)
			_, err := conn.DeregisterJobDefinition(&batch.DeregisterJobDefinitionInput{
				JobDefinition: aws.String(arn),
			})
			if err != nil {
				sweeperErr := fmt.Errorf("error deleting Batch Job Definition (%s): %w", arn, err)
				log.Printf("[ERROR] %s", sweeperErr)
				sweeperErrs = multierror.Append(sweeperErrs, sweeperErr)
				continue
			}
		}

		return !isLast
	})
	if testSweepSkipSweepError(err) {
		log.Printf("[WARN] Skipping Batch Job Definitions sweep for %s: %s", region, err)
		return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors
	}
	if err != nil {
		sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Batch Job Definitions: %w", err))
	}

	return sweeperErrs.ErrorOrNil()
}

func TestAccAWSBatchJobDefinition_basic(t *testing.T) {
	var jd batch.JobDefinition
	rName := acctest.RandomWithPrefix("tf-acc-test")
	resourceName := "aws_batch_job_definition.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckBatchJobDefinitionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBatchJobDefinitionConfigName(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckBatchJobDefinitionExists(resourceName, &jd),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAWSBatchJobDefinition_ContainerProperties_Advanced(t *testing.T) {
	var jd batch.JobDefinition
	compare := batch.JobDefinition{
		Parameters: map[string]*string{
			"param1": aws.String("val1"),
			"param2": aws.String("val2"),
		},
		RetryStrategy: &batch.RetryStrategy{
			Attempts: aws.Int64(int64(1)),
		},
		Timeout: &batch.JobTimeout{
			AttemptDurationSeconds: aws.Int64(int64(60)),
		},
		ContainerProperties: &batch.ContainerProperties{
			Command: []*string{aws.String("ls"), aws.String("-la")},
			Environment: []*batch.KeyValuePair{
				{Name: aws.String("VARNAME"), Value: aws.String("VARVAL")},
			},
			Image:  aws.String("busybox"),
			Memory: aws.Int64(int64(512)),
			MountPoints: []*batch.MountPoint{
				{ContainerPath: aws.String("/tmp"), ReadOnly: aws.Bool(false), SourceVolume: aws.String("tmp")},
			},
			ResourceRequirements: []*batch.ResourceRequirement{},
			Ulimits: []*batch.Ulimit{
				{HardLimit: aws.Int64(int64(1024)), Name: aws.String("nofile"), SoftLimit: aws.Int64(int64(1024))},
			},
			Vcpus: aws.Int64(int64(1)),
			Volumes: []*batch.Volume{
				{
					Host: &batch.Host{SourcePath: aws.String("/tmp")},
					Name: aws.String("tmp"),
				},
			},
		},
	}
	rName := acctest.RandomWithPrefix("tf-acc-test")
	resourceName := "aws_batch_job_definition.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckBatchJobDefinitionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBatchJobDefinitionConfigContainerPropertiesAdvanced(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckBatchJobDefinitionExists(resourceName, &jd),
					testAccCheckBatchJobDefinitionAttributes(&jd, &compare),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAWSBatchJobDefinition_updateForcesNewResource(t *testing.T) {
	var before, after batch.JobDefinition
	rName := acctest.RandomWithPrefix("tf-acc-test")
	resourceName := "aws_batch_job_definition.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckBatchJobDefinitionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBatchJobDefinitionConfigContainerPropertiesAdvanced(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckBatchJobDefinitionExists(resourceName, &before),
					testAccCheckBatchJobDefinitionAttributes(&before, nil),
				),
			},
			{
				Config: testAccBatchJobDefinitionConfigContainerPropertiesAdvancedUpdate(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckBatchJobDefinitionExists(resourceName, &after),
					testAccCheckJobDefinitionRecreated(t, &before, &after),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccCheckBatchJobDefinitionExists(n string, jd *batch.JobDefinition) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No Batch Job Queue ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).batchconn
		arn := rs.Primary.Attributes["arn"]
		def, err := getJobDefinition(conn, arn)
		if err != nil {
			return err
		}
		if def == nil {
			return fmt.Errorf("Not found: %s", n)
		}
		*jd = *def

		return nil
	}
}

func testAccCheckBatchJobDefinitionAttributes(jd *batch.JobDefinition, compare *batch.JobDefinition) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		for _, rs := range s.RootModule().Resources {
			if rs.Type != "aws_batch_job_definition" {
				continue
			}
			if *jd.JobDefinitionArn != rs.Primary.Attributes["arn"] {
				return fmt.Errorf("Bad Job Definition ARN\n\t expected: %s\n\tgot: %s\n", rs.Primary.Attributes["arn"], *jd.JobDefinitionArn)
			}
			if compare != nil {
				if compare.Parameters != nil && !reflect.DeepEqual(compare.Parameters, jd.Parameters) {
					return fmt.Errorf("Bad Job Definition Params\n\t expected: %v\n\tgot: %v\n", compare.Parameters, jd.Parameters)
				}
				if compare.RetryStrategy != nil && *compare.RetryStrategy.Attempts != *jd.RetryStrategy.Attempts {
					return fmt.Errorf("Bad Job Definition Retry Strategy\n\t expected: %d\n\tgot: %d\n", *compare.RetryStrategy.Attempts, *jd.RetryStrategy.Attempts)
				}
				if compare.ContainerProperties != nil && compare.ContainerProperties.Command != nil && !reflect.DeepEqual(compare.ContainerProperties, jd.ContainerProperties) {
					return fmt.Errorf("Bad Job Definition Container Properties\n\t expected: %s\n\tgot: %s\n", compare.ContainerProperties, jd.ContainerProperties)
				}
			}
		}
		return nil
	}
}

func testAccCheckJobDefinitionRecreated(t *testing.T,
	before, after *batch.JobDefinition) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if *before.Revision == *after.Revision {
			t.Fatalf("Expected change of JobDefinition Revisions, but both were %v", before.Revision)
		}
		return nil
	}
}

func testAccCheckBatchJobDefinitionDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_batch_job_definition" {
			continue
		}
		conn := testAccProvider.Meta().(*AWSClient).batchconn
		js, err := getJobDefinition(conn, rs.Primary.Attributes["arn"])
		if err == nil && js != nil {
			if *js.Status == "ACTIVE" {
				return fmt.Errorf("Error: Job Definition still active")
			}
		}
		return nil
	}
	return nil
}

func testAccBatchJobDefinitionConfigContainerPropertiesAdvanced(rName string) string {
	return fmt.Sprintf(`
resource "aws_batch_job_definition" "test" {
	name = %[1]q
	type = "container"
	parameters = {
		param1 = "val1"
		param2 = "val2"
	}
	retry_strategy {
		attempts = 1
	}
	timeout {
		attempt_duration_seconds = 60
	}
	container_properties = <<CONTAINER_PROPERTIES
{
	"command": ["ls", "-la"],
	"image": "busybox",
	"memory": 512,
	"vcpus": 1,
	"volumes": [
      {
        "host": {
          "sourcePath": "/tmp"
        },
        "name": "tmp"
      }
    ],
	"environment": [
		{"name": "VARNAME", "value": "VARVAL"}
	],
	"mountPoints": [
		{
          "sourceVolume": "tmp",
          "containerPath": "/tmp",
          "readOnly": false
        }
	],
    "ulimits": [
      {
        "hardLimit": 1024,
        "name": "nofile",
        "softLimit": 1024
      }
    ]
}
CONTAINER_PROPERTIES
}
`, rName)
}

func testAccBatchJobDefinitionConfigContainerPropertiesAdvancedUpdate(rName string) string {
	return fmt.Sprintf(`
resource "aws_batch_job_definition" "test" {
	name = %[1]q
	type = "container"
	container_properties = <<CONTAINER_PROPERTIES
{
	"command": ["ls", "-la"],
	"image": "busybox",
	"memory": 1024,
	"vcpus": 1,
	"volumes": [
      {
        "host": {
          "sourcePath": "/tmp"
        },
        "name": "tmp"
      }
    ],
	"environment": [
		{"name": "VARNAME", "value": "VARVAL"}
	],
	"mountPoints": [
		{
          "sourceVolume": "tmp",
          "containerPath": "/tmp",
          "readOnly": false
        }
	],
    "ulimits": [
      {
        "hardLimit": 1024,
        "name": "nofile",
        "softLimit": 1024
      }
    ]
}
CONTAINER_PROPERTIES
}
`, rName)
}

func testAccBatchJobDefinitionConfigName(rName string) string {
	return fmt.Sprintf(`
resource "aws_batch_job_definition" "test" {
  container_properties = jsonencode({
    command = ["echo", "test"]
    image   = "busybox"
    memory  = 128
    vcpus   = 1
  })
  name = %[1]q
  type = "container"
}
`, rName)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ecr"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSEcrLifecyclePolicy_basic(t *testing.T) {
	randString := acctest.RandString(10)
	rName := fmt.Sprintf("tf-acc-test-lifecycle-%s", randString)

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSEcrLifecyclePolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccEcrLifecyclePolicyConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSEcrLifecyclePolicyExists("aws_ecr_lifecycle_policy.foo"),
				),
			},
		},
	})
}

func TestAccAWSEcrLifecyclePolicy_import(t *testing.T) {
	resourceName := "aws_ecr_lifecycle_policy.foo"
	randString := acctest.RandString(10)
	rName := fmt.Sprintf("tf-acc-test-lifecycle-%s", randString)

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSEcrLifecyclePolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccEcrLifecyclePolicyConfig(rName),
			},

			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccCheckAWSEcrLifecyclePolicyDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).ecrconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_ecr_lifecycle_policy" {
			continue
		}

		input := &ecr.GetLifecyclePolicyInput{
			RepositoryName: aws.String(rs.Primary.ID),
		}

		_, err := conn.GetLifecyclePolicy(input)
		if err != nil {
			if isAWSErr(err, ecr.ErrCodeRepositoryNotFoundException, "") {
				return nil
			}
			if isAWSErr(err, ecr.ErrCodeLifecyclePolicyNotFoundException, "") {
				return nil
			}
			return err
		}
	}

	return nil
}

func testAccCheckAWSEcrLifecyclePolicyExists(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		conn := testAccProvider.Meta().(*AWSClient).ecrconn

		input := &ecr.GetLifecyclePolicyInput{
			RepositoryName: aws.String(rs.Primary.ID),
		}

		_, err := conn.GetLifecyclePolicy(input)
		if err != nil {
			return err
		}

		return nil
	}
}

func testAccEcrLifecyclePolicyConfig(rName string) string {
	return fmt.Sprintf(`
resource "aws_ecr_repository" "foo" {
  name = "%s"
}
resource "aws_ecr_lifecycle_policy" "foo" {
	repository = "${aws_ecr_repository.foo.name}"
  policy = <<EOF
{
  "rules": [
    {
      "rulePriority": 1,
      "description": "Expire images older than 14 days",
      "selection": {
        "tagStatus": "untagged",
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 14
      },
      "action": {
        "type": "expire"
      }
    }
  ]
}
EOF
}
`, rName)
}
<commit_msg>Fix gosimple ecr issues<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ecr"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSEcrLifecyclePolicy_basic(t *testing.T) {
	randString := acctest.RandString(10)
	rName := fmt.Sprintf("tf-acc-test-lifecycle-%s", randString)

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSEcrLifecyclePolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccEcrLifecyclePolicyConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSEcrLifecyclePolicyExists("aws_ecr_lifecycle_policy.foo"),
				),
			},
		},
	})
}

func TestAccAWSEcrLifecyclePolicy_import(t *testing.T) {
	resourceName := "aws_ecr_lifecycle_policy.foo"
	randString := acctest.RandString(10)
	rName := fmt.Sprintf("tf-acc-test-lifecycle-%s", randString)

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSEcrLifecyclePolicyDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccEcrLifecyclePolicyConfig(rName),
			},

			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccCheckAWSEcrLifecyclePolicyDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).ecrconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_ecr_lifecycle_policy" {
			continue
		}

		input := &ecr.GetLifecyclePolicyInput{
			RepositoryName: aws.String(rs.Primary.ID),
		}

		_, err := conn.GetLifecyclePolicy(input)
		if err != nil {
			if isAWSErr(err, ecr.ErrCodeRepositoryNotFoundException, "") {
				return nil
			}
			if isAWSErr(err, ecr.ErrCodeLifecyclePolicyNotFoundException, "") {
				return nil
			}
			return err
		}
	}

	return nil
}

func testAccCheckAWSEcrLifecyclePolicyExists(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		conn := testAccProvider.Meta().(*AWSClient).ecrconn

		input := &ecr.GetLifecyclePolicyInput{
			RepositoryName: aws.String(rs.Primary.ID),
		}

		_, err := conn.GetLifecyclePolicy(input)
		return err
	}
}

func testAccEcrLifecyclePolicyConfig(rName string) string {
	return fmt.Sprintf(`
resource "aws_ecr_repository" "foo" {
  name = "%s"
}
resource "aws_ecr_lifecycle_policy" "foo" {
	repository = "${aws_ecr_repository.foo.name}"
  policy = <<EOF
{
  "rules": [
    {
      "rulePriority": 1,
      "description": "Expire images older than 14 days",
      "selection": {
        "tagStatus": "untagged",
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 14
      },
      "action": {
        "type": "expire"
      }
    }
  ]
}
EOF
}
`, rName)
}
<|endoftext|>


<commit_before>package gitbase

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"sync"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"gopkg.in/src-d/go-git-fixtures.v3"
	"gopkg.in/src-d/go-git.v4"
	"gopkg.in/src-d/go-git.v4/plumbing/object"
	"gopkg.in/src-d/go-mysql-server.v0/sql"
)

func TestRepository(t *testing.T) {
	require := require.New(t)

	gitRepo := &git.Repository{}
	repo := NewRepository("identifier", gitRepo)

	require.Equal("identifier", repo.ID)
	require.Equal(gitRepo, repo.Repo)

	repo = NewRepository("/other/path", nil)

	require.Equal("/other/path", repo.ID)
	require.Nil(repo.Repo)
}

func TestRepositoryPoolBasic(t *testing.T) {
	require := require.New(t)

	pool := NewRepositoryPool()

	repo, err := pool.GetPos(0)
	require.Nil(repo)
	require.Equal(io.EOF, err)

	repo, err = pool.GetRepo("foo")
	require.Nil(repo)
	require.EqualError(err, ErrPoolRepoNotFound.New("foo").Error())

	pool.Add("0", "/directory/should/not/exist", gitRepo)
	repo, err = pool.GetPos(0)
	require.Nil(repo)
	require.EqualError(err, git.ErrRepositoryNotExists.Error())

	_, err = pool.GetPos(1)
	require.Equal(io.EOF, err)

	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()

	pool.Add("1", path, gitRepo)
	repo, err = pool.GetPos(1)
	require.NoError(err)
	require.Equal("1", repo.ID)
	require.NotNil(repo.Repo)

	repo, err = pool.GetRepo("1")
	require.NoError(err)
	require.Equal("1", repo.ID)
	require.NotNil(repo.Repo)

	_, err = pool.GetPos(2)
	require.Equal(io.EOF, err)
}

func TestRepositoryPoolGit(t *testing.T) {
	require := require.New(t)

	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()

	pool := NewRepositoryPool()
	id, err := pool.AddGit(path)
	require.Equal(path, id)
	require.NoError(err)

	repo, err := pool.GetPos(0)
	require.Equal(path, repo.ID)
	require.NotNil(repo.Repo)
	require.NoError(err)

	iter, err := repo.Repo.CommitObjects()
	require.NoError(err)

	count := 0

	for {
		commit, err := iter.Next()
		if err != nil {
			break
		}

		require.NotNil(commit)

		count++
	}

	require.Equal(9, count)
}

func TestRepositoryPoolIterator(t *testing.T) {
	require := require.New(t)

	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()

	pool := NewRepositoryPool()
	pool.Add("0", path, gitRepo)
	pool.Add("1", path, gitRepo)

	iter, err := pool.RepoIter()
	require.NoError(err)

	count := 0

	for {
		repo, err := iter.Next()
		if err != nil {
			require.Equal(io.EOF, err)
			break
		}

		require.NotNil(repo)
		require.Equal(strconv.Itoa(count), repo.ID)

		count++
	}

	require.Equal(2, count)
}

type testCommitIter struct {
	iter   object.CommitIter
	repoID string
}

func (d *testCommitIter) NewIterator(
	repo *Repository,
) (RowRepoIter, error) {
	iter, err := repo.Repo.CommitObjects()
	if err != nil {
		return nil, err
	}

	return &testCommitIter{iter: iter, repoID: repo.ID}, nil
}

func (d *testCommitIter) Next() (sql.Row, error) {
	commit, err := d.iter.Next()
	if err != nil {
		return nil, err
	}

	return commitToRow(d.repoID, commit), nil
}

func (d *testCommitIter) Close() error {
	if d.iter != nil {
		d.iter.Close()
	}

	return nil
}

func testRepoIter(num int, require *require.Assertions, ctx *sql.Context) {
	cIter := &testCommitIter{}

	repoIter, err := NewRowRepoIter(ctx, cIter)
	require.NoError(err)

	count := 0
	for {
		row, err := repoIter.Next()
		if err != nil {
			require.Equal(io.EOF, err)
			break
		}

		require.NotNil(row)

		count++
	}

	// 9 is the number of commits from the test repo
	require.Equal(9*num, count)
}

func TestRepositoryRowIterator(t *testing.T) {
	require := require.New(t)

	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()

	pool := NewRepositoryPool()
	session := NewSession(pool)
	ctx := sql.NewContext(context.TODO(), sql.WithSession(session))
	max := 64

	for i := 0; i < max; i++ {
		pool.Add(strconv.Itoa(i), path, gitRepo)
	}

	testRepoIter(max, require, ctx)

	// Test multiple iterators at the same time

	var wg sync.WaitGroup

	for i := 0; i < 4; i++ {
		wg.Add(1)
		go func() {
			testRepoIter(max, require, ctx)
			wg.Done()
		}()
	}

	wg.Wait()
}

func TestRepositoryPoolAddDir(t *testing.T) {
	require := require.New(t)

	tmpDir, err := ioutil.TempDir("", "gitbase-test")
	require.NoError(err)

	tmpDirLen := len(SplitPath(tmpDir))
	max := 64

	for i := 0; i < max; i++ {
		orig := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
		p := filepath.Join(tmpDir, strconv.Itoa(i))

		err := os.Rename(orig, p)
		require.NoError(err)
	}

	pool := NewRepositoryPool()
	err = pool.AddDir(tmpDirLen, tmpDir)
	require.NoError(err)

	require.Equal(max, len(pool.repositories))

	arrayID := make([]string, max)
	arrayExpected := make([]string, max)

	for i := 0; i < max; i++ {
		repo, err := pool.GetPos(i)
		require.NoError(err)
		arrayID[i] = repo.ID
		arrayExpected[i] = strconv.Itoa(i)

		iter, err := repo.Repo.CommitObjects()
		require.NoError(err)

		counter := 0
		for {
			commit, err := iter.Next()
			if err == io.EOF {
				break
			}

			require.NoError(err)
			require.NotNil(commit)
			counter++
		}

		require.Equal(9, counter)
	}

	require.ElementsMatch(arrayExpected, arrayID)
}

func TestRepositoryPoolSiva(t *testing.T) {
	require := require.New(t)

	expectedRepos := 3

	pool := NewRepositoryPool()
	path := filepath.Join(
		os.Getenv("GOPATH"),
		"src", "github.com", "src-d", "gitbase",
		"_testdata",
	)

	require.NoError(pool.AddSivaDir(path))
	require.Equal(expectedRepos, len(pool.repositories))

	expected := []int{606, 452, 75}
	result := make([]int, expectedRepos)

	for i := 0; i < expectedRepos; i++ {
		repo, err := pool.GetPos(i)
		require.NoError(err)

		iter, err := repo.Repo.CommitObjects()
		require.NoError(err)

		require.NoError(iter.ForEach(func(c *object.Commit) error {
			result[i]++
			return nil
		}))
	}

	require.Equal(expected, result)
}

var errIter = fmt.Errorf("Error iter")

type newIteratorFunc func(*Repository) (RowRepoIter, error)
type nextFunc func() (sql.Row, error)

type testErrorIter struct {
	newIterator newIteratorFunc
	next        nextFunc
}

func (d *testErrorIter) NewIterator(
	repo *Repository,
) (RowRepoIter, error) {
	if d.newIterator != nil {
		return d.newIterator(repo)
	}

	return nil, errIter
}

func (d *testErrorIter) Repository() string { return "RepoTestError" }

func (d *testErrorIter) LastObject() string { return "ObjectTestError" }

func (d *testErrorIter) Next() (sql.Row, error) {
	if d.next != nil {
		return d.next()
	}

	return nil, io.EOF
}

func (d *testErrorIter) Close() error {
	return nil
}

func testCaseRepositoryErrorIter(
	t *testing.T,
	pool *RepositoryPool,
	iter RowRepoIter,
	retError error,
	skipGitErrors bool,
) {
	require := require.New(t)

	timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	ctx := sql.NewContext(timeout,
		sql.WithSession(NewSession(pool, WithSkipGitErrors(skipGitErrors))),
	)

	r, err := NewRowRepoIter(ctx, iter)
	require.NoError(err)

	repoIter, ok := r.(*rowRepoIter)
	require.True(ok)

	go func() {
		for {
			_, err := repoIter.Next()
			if err != nil {
				cancel()
				break
			}
		}
	}()

	<-repoIter.ctx.Done()
}

func TestRepositoryErrorIter(t *testing.T) {
	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
	pool := NewRepositoryPool()
	pool.Add("one", path, gitRepo)

	iter := &testErrorIter{}
	testCaseRepositoryErrorIter(t, pool, iter, errIter, false)
}

func TestRepositoryErrorBadRepository(t *testing.T) {
	pool := NewRepositoryPool()
	pool.Add("one", "badpath", gitRepo)

	iter := &testErrorIter{}

	newIterator := func(*Repository) (RowRepoIter, error) {
		return iter, nil
	}

	count := 0
	next := func() (sql.Row, error) {
		if count >= 10 {
			return nil, io.EOF
		}

		count++

		return sql.NewRow("test " + strconv.Itoa(count)), nil
	}

	iter.newIterator = newIterator
	iter.next = next

	testCaseRepositoryErrorIter(t, pool, iter, git.ErrRepositoryNotExists, false)
	testCaseRepositoryErrorIter(t, pool, iter, io.EOF, true)
}

func TestRepositoryErrorBadRow(t *testing.T) {
	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
	pool := NewRepositoryPool()
	pool.Add("one", path, gitRepo)

	iter := &testErrorIter{}

	newIterator := func(*Repository) (RowRepoIter, error) {
		return iter, nil
	}

	errRow := fmt.Errorf("bad row")

	count := 0
	next := func() (sql.Row, error) {
		if count == 5 {
			return nil, errRow
		}

		if count >= 10 {
			return nil, io.EOF
		}

		count++

		return sql.NewRow("test"), nil
	}

	iter.newIterator = newIterator
	iter.next = next

	testCaseRepositoryErrorIter(t, pool, iter, errRow, false)
	testCaseRepositoryErrorIter(t, pool, iter, io.EOF, true)
}

func TestRepositoryIteratorOrder(t *testing.T) {
	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
	pool := NewRepositoryPool()
	pool.Add("one", path, gitRepo)

	timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	ctx := sql.NewContext(timeout,
		sql.WithSession(NewSession(pool, WithSkipGitErrors(true))),
	)
	iter := &testErrorIter{}
	newIterator := func(*Repository) (RowRepoIter, error) {
		return iter, nil
	}

	count := 0
	next := func() (sql.Row, error) {
		if count >= 10 {
			return nil, io.EOF
		}

		count++

		return sql.NewRow("test " + strconv.Itoa(count)), nil
	}
	iter.newIterator = newIterator
	iter.next = next

	r, err := NewRowRepoIter(ctx, iter)
	require.NoError(t, err)

	repoIter, ok := r.(*rowRepoIter)
	require.True(t, ok)

	func() {
		for i := 1; i <= 10; i++ {
			row, err := repoIter.Next()
			if err != nil {
				break
			}
			require.Equal(t, sql.Row{"test " + strconv.Itoa(i)}, row)
		}
	}()

	cancel()
}
<commit_msg>Test Add and AddGit errors<commit_after>package gitbase

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"sync"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"gopkg.in/src-d/go-git-fixtures.v3"
	"gopkg.in/src-d/go-git.v4"
	"gopkg.in/src-d/go-git.v4/plumbing/object"
	"gopkg.in/src-d/go-mysql-server.v0/sql"
)

func TestRepository(t *testing.T) {
	require := require.New(t)

	gitRepo := &git.Repository{}
	repo := NewRepository("identifier", gitRepo)

	require.Equal("identifier", repo.ID)
	require.Equal(gitRepo, repo.Repo)

	repo = NewRepository("/other/path", nil)

	require.Equal("/other/path", repo.ID)
	require.Nil(repo.Repo)
}

func TestRepositoryPoolBasic(t *testing.T) {
	require := require.New(t)

	pool := NewRepositoryPool()

	repo, err := pool.GetPos(0)
	require.Nil(repo)
	require.Equal(io.EOF, err)

	repo, err = pool.GetRepo("foo")
	require.Nil(repo)
	require.EqualError(err, ErrPoolRepoNotFound.New("foo").Error())

	pool.Add("0", "/directory/should/not/exist", gitRepo)
	repo, err = pool.GetPos(0)
	require.Nil(repo)
	require.EqualError(err, git.ErrRepositoryNotExists.Error())

	_, err = pool.GetPos(1)
	require.Equal(io.EOF, err)

	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()

	err = pool.Add("1", path, gitRepo)
	require.NoError(err)

	repo, err = pool.GetPos(1)
	require.NoError(err)
	require.Equal("1", repo.ID)
	require.NotNil(repo.Repo)

	repo, err = pool.GetRepo("1")
	require.NoError(err)
	require.Equal("1", repo.ID)
	require.NotNil(repo.Repo)

	err = pool.Add("1", path, gitRepo)
	require.Error(err)
	require.True(errRepoAlreadyRegistered.Is(err))

	_, err = pool.GetPos(0)
	require.Equal(git.ErrRepositoryNotExists, err)

	_, err = pool.GetPos(2)
	require.Equal(io.EOF, err)
}

func TestRepositoryPoolGit(t *testing.T) {
	require := require.New(t)

	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()

	pool := NewRepositoryPool()

	_, err := pool.AddGit("/do/not/exist")
	require.Error(err)
	require.True(errRepoCanNotOpen.Is(err))

	id, err := pool.AddGit(path)
	require.Equal(path, id)
	require.NoError(err)

	repo, err := pool.GetPos(0)
	require.Equal(path, repo.ID)
	require.NotNil(repo.Repo)
	require.NoError(err)

	iter, err := repo.Repo.CommitObjects()
	require.NoError(err)

	count := 0

	for {
		commit, err := iter.Next()
		if err != nil {
			break
		}

		require.NotNil(commit)

		count++
	}

	require.Equal(9, count)
}

func TestRepositoryPoolIterator(t *testing.T) {
	require := require.New(t)

	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()

	pool := NewRepositoryPool()
	pool.Add("0", path, gitRepo)
	pool.Add("1", path, gitRepo)

	iter, err := pool.RepoIter()
	require.NoError(err)

	count := 0

	for {
		repo, err := iter.Next()
		if err != nil {
			require.Equal(io.EOF, err)
			break
		}

		require.NotNil(repo)
		require.Equal(strconv.Itoa(count), repo.ID)

		count++
	}

	require.Equal(2, count)
}

type testCommitIter struct {
	iter   object.CommitIter
	repoID string
}

func (d *testCommitIter) NewIterator(
	repo *Repository,
) (RowRepoIter, error) {
	iter, err := repo.Repo.CommitObjects()
	if err != nil {
		return nil, err
	}

	return &testCommitIter{iter: iter, repoID: repo.ID}, nil
}

func (d *testCommitIter) Next() (sql.Row, error) {
	commit, err := d.iter.Next()
	if err != nil {
		return nil, err
	}

	return commitToRow(d.repoID, commit), nil
}

func (d *testCommitIter) Close() error {
	if d.iter != nil {
		d.iter.Close()
	}

	return nil
}

func testRepoIter(num int, require *require.Assertions, ctx *sql.Context) {
	cIter := &testCommitIter{}

	repoIter, err := NewRowRepoIter(ctx, cIter)
	require.NoError(err)

	count := 0
	for {
		row, err := repoIter.Next()
		if err != nil {
			require.Equal(io.EOF, err)
			break
		}

		require.NotNil(row)

		count++
	}

	// 9 is the number of commits from the test repo
	require.Equal(9*num, count)
}

func TestRepositoryRowIterator(t *testing.T) {
	require := require.New(t)

	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()

	pool := NewRepositoryPool()
	session := NewSession(pool)
	ctx := sql.NewContext(context.TODO(), sql.WithSession(session))
	max := 64

	for i := 0; i < max; i++ {
		pool.Add(strconv.Itoa(i), path, gitRepo)
	}

	testRepoIter(max, require, ctx)

	// Test multiple iterators at the same time

	var wg sync.WaitGroup

	for i := 0; i < 4; i++ {
		wg.Add(1)
		go func() {
			testRepoIter(max, require, ctx)
			wg.Done()
		}()
	}

	wg.Wait()
}

func TestRepositoryPoolAddDir(t *testing.T) {
	require := require.New(t)

	tmpDir, err := ioutil.TempDir("", "gitbase-test")
	require.NoError(err)

	tmpDirLen := len(SplitPath(tmpDir))
	max := 64

	for i := 0; i < max; i++ {
		orig := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
		p := filepath.Join(tmpDir, strconv.Itoa(i))

		err := os.Rename(orig, p)
		require.NoError(err)
	}

	pool := NewRepositoryPool()
	err = pool.AddDir(tmpDirLen, tmpDir)
	require.NoError(err)

	require.Equal(max, len(pool.repositories))

	arrayID := make([]string, max)
	arrayExpected := make([]string, max)

	for i := 0; i < max; i++ {
		repo, err := pool.GetPos(i)
		require.NoError(err)
		arrayID[i] = repo.ID
		arrayExpected[i] = strconv.Itoa(i)

		iter, err := repo.Repo.CommitObjects()
		require.NoError(err)

		counter := 0
		for {
			commit, err := iter.Next()
			if err == io.EOF {
				break
			}

			require.NoError(err)
			require.NotNil(commit)
			counter++
		}

		require.Equal(9, counter)
	}

	require.ElementsMatch(arrayExpected, arrayID)
}

func TestRepositoryPoolSiva(t *testing.T) {
	require := require.New(t)

	expectedRepos := 3

	pool := NewRepositoryPool()
	path := filepath.Join(
		os.Getenv("GOPATH"),
		"src", "github.com", "src-d", "gitbase",
		"_testdata",
	)

	require.NoError(pool.AddSivaDir(path))
	require.Equal(expectedRepos, len(pool.repositories))

	expected := []int{606, 452, 75}
	result := make([]int, expectedRepos)

	for i := 0; i < expectedRepos; i++ {
		repo, err := pool.GetPos(i)
		require.NoError(err)

		iter, err := repo.Repo.CommitObjects()
		require.NoError(err)

		require.NoError(iter.ForEach(func(c *object.Commit) error {
			result[i]++
			return nil
		}))
	}

	require.Equal(expected, result)
}

var errIter = fmt.Errorf("Error iter")

type newIteratorFunc func(*Repository) (RowRepoIter, error)
type nextFunc func() (sql.Row, error)

type testErrorIter struct {
	newIterator newIteratorFunc
	next        nextFunc
}

func (d *testErrorIter) NewIterator(
	repo *Repository,
) (RowRepoIter, error) {
	if d.newIterator != nil {
		return d.newIterator(repo)
	}

	return nil, errIter
}

func (d *testErrorIter) Repository() string { return "RepoTestError" }

func (d *testErrorIter) LastObject() string { return "ObjectTestError" }

func (d *testErrorIter) Next() (sql.Row, error) {
	if d.next != nil {
		return d.next()
	}

	return nil, io.EOF
}

func (d *testErrorIter) Close() error {
	return nil
}

func testCaseRepositoryErrorIter(
	t *testing.T,
	pool *RepositoryPool,
	iter RowRepoIter,
	retError error,
	skipGitErrors bool,
) {
	require := require.New(t)

	timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	ctx := sql.NewContext(timeout,
		sql.WithSession(NewSession(pool, WithSkipGitErrors(skipGitErrors))),
	)

	r, err := NewRowRepoIter(ctx, iter)
	require.NoError(err)

	repoIter, ok := r.(*rowRepoIter)
	require.True(ok)

	go func() {
		for {
			_, err := repoIter.Next()
			if err != nil {
				cancel()
				break
			}
		}
	}()

	<-repoIter.ctx.Done()
}

func TestRepositoryErrorIter(t *testing.T) {
	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
	pool := NewRepositoryPool()
	pool.Add("one", path, gitRepo)

	iter := &testErrorIter{}
	testCaseRepositoryErrorIter(t, pool, iter, errIter, false)
}

func TestRepositoryErrorBadRepository(t *testing.T) {
	pool := NewRepositoryPool()
	pool.Add("one", "badpath", gitRepo)

	iter := &testErrorIter{}

	newIterator := func(*Repository) (RowRepoIter, error) {
		return iter, nil
	}

	count := 0
	next := func() (sql.Row, error) {
		if count >= 10 {
			return nil, io.EOF
		}

		count++

		return sql.NewRow("test " + strconv.Itoa(count)), nil
	}

	iter.newIterator = newIterator
	iter.next = next

	testCaseRepositoryErrorIter(t, pool, iter, git.ErrRepositoryNotExists, false)
	testCaseRepositoryErrorIter(t, pool, iter, io.EOF, true)
}

func TestRepositoryErrorBadRow(t *testing.T) {
	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
	pool := NewRepositoryPool()
	pool.Add("one", path, gitRepo)

	iter := &testErrorIter{}

	newIterator := func(*Repository) (RowRepoIter, error) {
		return iter, nil
	}

	errRow := fmt.Errorf("bad row")

	count := 0
	next := func() (sql.Row, error) {
		if count == 5 {
			return nil, errRow
		}

		if count >= 10 {
			return nil, io.EOF
		}

		count++

		return sql.NewRow("test"), nil
	}

	iter.newIterator = newIterator
	iter.next = next

	testCaseRepositoryErrorIter(t, pool, iter, errRow, false)
	testCaseRepositoryErrorIter(t, pool, iter, io.EOF, true)
}

func TestRepositoryIteratorOrder(t *testing.T) {
	path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
	pool := NewRepositoryPool()
	pool.Add("one", path, gitRepo)

	timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	ctx := sql.NewContext(timeout,
		sql.WithSession(NewSession(pool, WithSkipGitErrors(true))),
	)
	iter := &testErrorIter{}
	newIterator := func(*Repository) (RowRepoIter, error) {
		return iter, nil
	}

	count := 0
	next := func() (sql.Row, error) {
		if count >= 10 {
			return nil, io.EOF
		}

		count++

		return sql.NewRow("test " + strconv.Itoa(count)), nil
	}
	iter.newIterator = newIterator
	iter.next = next

	r, err := NewRowRepoIter(ctx, iter)
	require.NoError(t, err)

	repoIter, ok := r.(*rowRepoIter)
	require.True(t, ok)

	func() {
		for i := 1; i <= 10; i++ {
			row, err := repoIter.Next()
			if err != nil {
				break
			}
			require.Equal(t, sql.Row{"test " + strconv.Itoa(i)}, row)
		}
	}()

	cancel()
}
<|endoftext|>


<commit_before>package main

type RepositoryInteractor interface {
	FetchPost(id string) (BlogPost, error)
}
<commit_msg>Deleted unused repository interactor interface.<commit_after><|endoftext|>


<commit_before>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 sdb

import (
	"github.com/jacobsa/aws/exp/sdb/conn"
)

// A precondition for a conditional Put or Delete operation. Preconditions may
// specify a value that an attribute must have or whether the attribute must
// exist or not.
type Precondition struct {
	// The name of the attribute to be inspected. Attributes with multiple values
	// are not supported.
	Name string

	// If present, the value that the attribute must possess at the time of the
	// update. Must be present iff Exists is not present.
	Value *string

	// If present, whether the attribute must exist at the time of the update.
	// Must be present iff Value is not present.
	Exists *bool
}

// An update to make to a particular attribute as part of a Put request.
type PutUpdate struct {
	// The name of the attribute.
	Name string

	// The value to set for the attribute.
	Value string

	// Whether to replace existing values for the attribute or to simply add a
	// new one.
	Replace bool
}

// An update to make to a particular attribute as part of a Delete request.
type DeleteUpdate struct {
	// The name of the attribute.
	Name string

	// Te requests, the particular value of the attribute to delete if present.
	// Otherwise, all values will be deleted.
	Value *string
}

// A domain represents a named domain within the SimpleDB service. It is a
// collection of named items, each of which possesses a set of attributes.
type Domain interface {
	// Return the name of this domain.
	Name() string

	// Atomically apply the supplied updates to the attributes of the named item,
	// but only if the supplied preconditions hold.
	//
	// The length of updates must be in [1, 256].
	PutAttributes(
		item ItemName,
		updates []PutUpdate,
		preconditions []Precondition) error

	// Atomically apply updates to multiple items simultaneously.
	//
	// The length of the map must be in [1, 25]. The length of each of its values
	// must be in [1, 256]. An error may be returned if the underlying request to
	// SimpleDB is too large.
	BatchPutAttributes(updateMap map[ItemName][]PutUpdate) error

	// Atomically delete attributes from the named item, but only if the supplied
	// preconditions hold.
	//
	// If deletes is empty, delete all attributes from the item. Otherwise
	// perform only the deletes is specifies. Deleting a non-existent attribute
	// does not result in an error.
	DeleteAttributes(
		item ItemName,
		deletes []DeleteUpdate,
		preconditions []Precondition) error

	// Atomically delete attributes from multiple items simultaneously.
	//
	// If no updates are supplied for a particular item, delete all of its
	// attributes.
	BatchDeleteAttributes(deleteMap map[ItemName][]DeleteUpdate) error

	// Retrieve a set of attributes for the named item, or all attributes if the
	// attribute name slice is empty.
	//
	// If the named item doesn't exist, the empty set is returned.
	//
	// constistentRead specifies whether completely fresh data is needed or not.
	GetAttributes(
		item ItemName,
		constistentRead bool,
		attrNames []string) (attrs []Attribute, err error)
}

func newDomain(name string, c conn.Conn) (Domain, error) {
	return &domain{name, c}, nil
}

type domain struct {
	name string
	c    conn.Conn
}

func (d *domain) Name() string {
	return d.name
}
<commit_msg>Moved around methods.<commit_after>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 sdb

import (
	"github.com/jacobsa/aws/exp/sdb/conn"
)

// A precondition for a conditional Put or Delete operation. Preconditions may
// specify a value that an attribute must have or whether the attribute must
// exist or not.
type Precondition struct {
	// The name of the attribute to be inspected. Attributes with multiple values
	// are not supported.
	Name string

	// If present, the value that the attribute must possess at the time of the
	// update. Must be present iff Exists is not present.
	Value *string

	// If present, whether the attribute must exist at the time of the update.
	// Must be present iff Value is not present.
	Exists *bool
}

// An update to make to a particular attribute as part of a Put request.
type PutUpdate struct {
	// The name of the attribute.
	Name string

	// The value to set for the attribute.
	Value string

	// Whether to replace existing values for the attribute or to simply add a
	// new one.
	Replace bool
}

// An update to make to a particular attribute as part of a Delete request.
type DeleteUpdate struct {
	// The name of the attribute.
	Name string

	// Te requests, the particular value of the attribute to delete if present.
	// Otherwise, all values will be deleted.
	Value *string
}

// A domain represents a named domain within the SimpleDB service. It is a
// collection of named items, each of which possesses a set of attributes.
type Domain interface {
	// Return the name of this domain.
	Name() string

	// Atomically apply the supplied updates to the attributes of the named item,
	// but only if the supplied preconditions hold.
	//
	// The length of updates must be in [1, 256].
	PutAttributes(
		item ItemName,
		updates []PutUpdate,
		preconditions []Precondition) error

	// Atomically apply updates to multiple items simultaneously.
	//
	// The length of the map must be in [1, 25]. The length of each of its values
	// must be in [1, 256]. An error may be returned if the underlying request to
	// SimpleDB is too large.
	BatchPutAttributes(updateMap map[ItemName][]PutUpdate) error

	// Retrieve a set of attributes for the named item, or all attributes if the
	// attribute name slice is empty.
	//
	// If the named item doesn't exist, the empty set is returned.
	//
	// constistentRead specifies whether completely fresh data is needed or not.
	GetAttributes(
		item ItemName,
		constistentRead bool,
		attrNames []string) (attrs []Attribute, err error)

	// Atomically delete attributes from the named item, but only if the supplied
	// preconditions hold.
	//
	// If deletes is empty, delete all attributes from the item. Otherwise
	// perform only the deletes is specifies. Deleting a non-existent attribute
	// does not result in an error.
	DeleteAttributes(
		item ItemName,
		deletes []DeleteUpdate,
		preconditions []Precondition) error

	// Atomically delete attributes from multiple items simultaneously.
	//
	// If no updates are supplied for a particular item, delete all of its
	// attributes.
	BatchDeleteAttributes(deleteMap map[ItemName][]DeleteUpdate) error
}

func newDomain(name string, c conn.Conn) (Domain, error) {
	return &domain{name, c}, nil
}

type domain struct {
	name string
	c    conn.Conn
}

func (d *domain) Name() string {
	return d.name
}
<|endoftext|>


<commit_before>//go:generate genspy
package main

// Doer does things, sometimes repeatedly
type Doer interface {
	DoIt(task string, repeat bool) (int, error)
	DoItAgain(task, prefix string) (count int, err error)
}

// RealDoer get stuff done for real
type RealDoer struct {
}

// DoIt does all the hard work
func (r *RealDoer) DoIt(task string, repeat bool) (int, error) {
	return 0, nil
}

const someConst = 1
<commit_msg>Use  as package name<commit_after>//go:generate genspy
package example

// Doer does things, sometimes repeatedly
type Doer interface {
	DoIt(task string, repeat bool) (int, error)
	DoItAgain(task, prefix string) (count int, err error)
}

// RealDoer get stuff done for real
type RealDoer struct {
}

// DoIt does all the hard work
func (r *RealDoer) DoIt(task string, repeat bool) (int, error) {
	return 0, nil
}

const someConst = 1
<|endoftext|>


<commit_before>package main

import (
	"runtime"

	"github.com/smartystreets/go-disruptor"
)

const (
	MaxConsumersPerGroup = 1
	MaxConsumerGroups    = 1
	MaxProducers         = 1
	ItemsToPublish       = 1
	ReportingFrequency   = 1024 //1000000 * 10 // 1 million * N
	RingSize             = 2
	RingMask             = RingSize - 1
)

var ringBuffer [RingSize]int64

func main() {
	runtime.GOMAXPROCS(MaxConsumerGroups*MaxConsumersPerGroup + MaxProducers)

	written := disruptor.NewCursor()
	shared := disruptor.NewSharedWriterBarrier(written, RingSize)
	upstream := startConsumerGroups(written, written)
	writer := disruptor.NewSharedWriter(shared, upstream)
	// writer := disruptor.NewWriter(written, upstream, RingSize)
	// startExclusiveProducer(writer)
	startSharedProducers(writer)
}

// func startExclusiveProducer(writer *disruptor.Writer) {
//publish(writer)
// }

func startSharedProducers(writer *disruptor.SharedWriter) {
	for i := 0; i < MaxProducers-1; i++ {
		go publish(writer)
	}

	publish(writer)
}

func startConsumerGroups(upstream disruptor.Barrier, writer *disruptor.Cursor) disruptor.Barrier {
	for i := 0; i < MaxConsumerGroups; i++ {
		upstream = startConsumerGroup(i, upstream, writer)
	}

	return upstream
}
func startConsumerGroup(group int, upstream disruptor.Barrier, written *disruptor.Cursor) disruptor.Barrier {
	cursors := []*disruptor.Cursor{}

	for i := 0; i < MaxConsumersPerGroup; i++ {
		read := disruptor.NewCursor()
		cursors = append(cursors, read)
		reader := disruptor.NewReader(read, written, upstream)

		// constant time regardless of the number of items
		// go consume0(disruptor.NewSimpleReader(reader, NewExampleConsumerHandler()))

		// TODO: wildly sporadic latency for single-item publish, e.g. 2 seconds, 65 ms, etc.
		// faster for 2-3+ items per publish
		// go consume1(reader)

		if group == 0 {
			go consume1(reader)
		} else if group == 1 {
			go consume2(reader)
		} else {
			panic("only two consumer groups currently supported.")
		}
	}

	return disruptor.NewCompositeBarrier(cursors...)
}
<commit_msg>Wireup was using the wrong barrier.<commit_after>package main

import (
	"runtime"

	"github.com/smartystreets/go-disruptor"
)

const (
	MaxConsumersPerGroup = 1
	MaxConsumerGroups    = 1
	MaxProducers         = 2
	ItemsToPublish       = 4
	ReportingFrequency   = 1000000 * 10 // 1 million * N
	RingSize             = 1024 * 16
	RingMask             = RingSize - 1
)

var ringBuffer [RingSize]int64

func main() {
	runtime.GOMAXPROCS(MaxConsumerGroups*MaxConsumersPerGroup + MaxProducers)

	written := disruptor.NewCursor()
	shared := disruptor.NewSharedWriterBarrier(written, RingSize)
	upstream := startConsumerGroups(shared, written)
	writer := disruptor.NewSharedWriter(shared, upstream)
	// writer := disruptor.NewWriter(written, upstream, RingSize)
	// startExclusiveProducer(writer)
	startSharedProducers(writer)
}

// func startExclusiveProducer(writer *disruptor.Writer) {
//publish(writer)
// }

func startSharedProducers(writer *disruptor.SharedWriter) {
	for i := 0; i < MaxProducers-1; i++ {
		go publish(writer)
	}

	publish(writer)
}

func startConsumerGroups(upstream disruptor.Barrier, written *disruptor.Cursor) disruptor.Barrier {
	for i := 0; i < MaxConsumerGroups; i++ {
		upstream = startConsumerGroup(i, upstream, written)
	}

	return upstream
}
func startConsumerGroup(group int, upstream disruptor.Barrier, written *disruptor.Cursor) disruptor.Barrier {
	cursors := []*disruptor.Cursor{}

	for i := 0; i < MaxConsumersPerGroup; i++ {
		read := disruptor.NewCursor()
		cursors = append(cursors, read)
		reader := disruptor.NewReader(read, written, upstream)

		// constant time regardless of the number of items
		// go consume0(disruptor.NewSimpleReader(reader, NewExampleConsumerHandler()))

		// TODO: wildly sporadic latency for single-item publish, e.g. 2 seconds, 65 ms, etc.
		// faster for 2-3+ items per publish
		// go consume1(reader)

		if group == 0 {
			go consume1(reader)
		} else if group == 1 {
			go consume2(reader)
		} else {
			panic("only two consumer groups currently supported.")
		}
	}

	return disruptor.NewCompositeBarrier(cursors...)
}
<|endoftext|>


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

// +build windows

// Example service program that beeps. It demonstrates how to
// create a service and install / remove it on a computer.
// It also shows how to stop / start / pause / continue any service,
// and how to write to event log. It also shows how to use debug
// facilities available in debug package.
//
package main

import (
	"code.google.com/p/winsvc/svc"
	"fmt"
	"log"
	"os"
	"strings"
)

func usage(errmsg string) {
	fmt.Fprintf(os.Stderr,
		"%s\n\n"+
			"usage: %s <command>\n"+
			"       where <command> is one of\n"+
			"       install, remove, debug, start, stop, pause or continue.\n",
		errmsg, os.Args[0])
	os.Exit(2)
}

func main() {
	const svcName = "HUUZKEE-Node-Srv"

	isIntSess, err := svc.IsAnInteractiveSession()
	if err != nil {
		log.Fatalf("failed to determine if we are running in an interactive session: %v", err)
	}
	if !isIntSess {
		runService(svcName, false)
		return
	}

	if len(os.Args) < 2 {
		usage("no command specified")
	}

	cmd := strings.ToLower(os.Args[1])
	switch cmd {
	case "debug":
		runService(svcName, true)
		return
	case "install":
		err = installService(svcName, "my service")
	case "remove":
		err = removeService(svcName)
	case "start":
		err = startService(svcName)
	case "stop":
		err = controlService(svcName, svc.Stop, svc.Stopped)
	case "pause":
		err = controlService(svcName, svc.Pause, svc.Paused)
	case "continue":
		err = controlService(svcName, svc.Continue, svc.Running)
	default:
		usage(fmt.Sprintf("invalid command %s", cmd))
	}
	if err != nil {
		log.Fatalf("failed to %s %s: %v", cmd, svcName, err)
	}
	return
}
<commit_msg>initial<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build windows

// Example service program that beeps. It demonstrates how to
// create a service and install / remove it on a computer.
// It also shows how to stop / start / pause / continue any service,
// and how to write to event log. It also shows how to use debug
// facilities available in debug package.
//
package main

import (
	"code.google.com/p/winsvc/svc"
	"fmt"
	"log"
	"os"
	"strings"
)

func usage(errmsg string) {
	fmt.Fprintf(os.Stderr,
		"%s\n\n"+
			"usage: %s <command>\n"+
			"       where <command> is one of\n"+
			"       install, remove, debug, start, stop, pause or continue.\n",
		errmsg, os.Args[0])
	os.Exit(2)
}

func main() {
	const svcName = "HUUZKEE"

	isIntSess, err := svc.IsAnInteractiveSession()
	if err != nil {
		log.Fatalf("failed to determine if we are running in an interactive session: %v", err)
	}
	if !isIntSess {
		runService(svcName, false)
		return
	}

	if len(os.Args) < 2 {
		usage("no command specified")
	}

	cmd := strings.ToLower(os.Args[1])
	switch cmd {
	case "debug":
		runService(svcName, true)
		return
	case "install":
		err = installService(svcName, "my service")
	case "remove":
		err = removeService(svcName)
	case "start":
		err = startService(svcName)
	case "stop":
		err = controlService(svcName, svc.Stop, svc.Stopped)
	case "pause":
		err = controlService(svcName, svc.Pause, svc.Paused)
	case "continue":
		err = controlService(svcName, svc.Continue, svc.Running)
	default:
		usage(fmt.Sprintf("invalid command %s", cmd))
	}
	if err != nil {
		log.Fatalf("failed to %s %s: %v", cmd, svcName, err)
	}
	return
}
<|endoftext|>