<commit_before>package suite

import (
	"errors"
	"io/ioutil"
	"os"
	"testing"
	"time"

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

// SuiteRequireTwice is intended to test the usage of suite.Require in two
// different tests
type SuiteRequireTwice struct{ Suite }

// TestSuiteRequireTwice checks for regressions of issue #149 where
// suite.requirements was not initialised in suite.SetT()
// A regression would result on these tests panicking rather than failing.
func TestSuiteRequireTwice(t *testing.T) {
	ok := testing.RunTests(
		allTestsFilter,
		[]testing.InternalTest{{
			Name: "TestSuiteRequireTwice",
			F: func(t *testing.T) {
				suite := new(SuiteRequireTwice)
				Run(t, suite)
			},
		}},
	)
	assert.Equal(t, false, ok)
}

func (s *SuiteRequireTwice) TestRequireOne() {
	r := s.Require()
	r.Equal(1, 2)
}

func (s *SuiteRequireTwice) TestRequireTwo() {
	r := s.Require()
	r.Equal(1, 2)
}

type panickingSuite struct {
	Suite
	panicInSetupSuite    bool
	panicInSetupTest     bool
	panicInBeforeTest    bool
	panicInTest          bool
	panicInAfterTest     bool
	panicInTearDownTest  bool
	panicInTearDownSuite bool
}

func (s *panickingSuite) SetupSuite() {
	if s.panicInSetupSuite {
		panic("oops in setup suite")
	}
}

func (s *panickingSuite) SetupTest() {
	if s.panicInSetupTest {
		panic("oops in setup test")
	}
}

func (s *panickingSuite) BeforeTest(_, _ string) {
	if s.panicInBeforeTest {
		panic("oops in before test")
	}
}

func (s *panickingSuite) Test() {
	if s.panicInTest {
		panic("oops in test")
	}
}

func (s *panickingSuite) AfterTest(_, _ string) {
	if s.panicInAfterTest {
		panic("oops in after test")
	}
}

func (s *panickingSuite) TearDownTest() {
	if s.panicInTearDownTest {
		panic("oops in tear down test")
	}
}

func (s *panickingSuite) TearDownSuite() {
	if s.panicInTearDownSuite {
		panic("oops in tear down suite")
	}
}

func TestSuiteRecoverPanic(t *testing.T) {
	ok := true
	panickingTests := []testing.InternalTest{
		{
			Name: "TestPanicInSetupSuite",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInSetupSuite: true}) },
		},
		{
			Name: "TestPanicInSetupTest",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInSetupTest: true}) },
		},
		{
			Name: "TestPanicInBeforeTest",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInBeforeTest: true}) },
		},
		{
			Name: "TestPanicInTest",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTest: true}) },
		},
		{
			Name: "TestPanicInAfterTest",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInAfterTest: true}) },
		},
		{
			Name: "TestPanicInTearDownTest",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownTest: true}) },
		},
		{
			Name: "TestPanicInTearDownSuite",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownSuite: true}) },
		},
	}

	require.NotPanics(t, func() {
		ok = testing.RunTests(allTestsFilter, panickingTests)
	})

	assert.False(t, ok)
}

// This suite is intended to store values to make sure that only
// testing-suite-related methods are run.  It's also a fully
// functional example of a testing suite, using setup/teardown methods
// and a helper method that is ignored by testify.  To make this look
// more like a real world example, all tests in the suite perform some
// type of assertion.
type SuiteTester struct {
	// Include our basic suite logic.
	Suite

	// Keep counts of how many times each method is run.
	SetupSuiteRunCount    int
	TearDownSuiteRunCount int
	SetupTestRunCount     int
	TearDownTestRunCount  int
	TestOneRunCount       int
	TestTwoRunCount       int
	TestSubtestRunCount   int
	NonTestMethodRunCount int

	SuiteNameBefore []string
	TestNameBefore  []string

	SuiteNameAfter []string
	TestNameAfter  []string

	TimeBefore []time.Time
	TimeAfter  []time.Time
}

// The SetupSuite method will be run by testify once, at the very
// start of the testing suite, before any tests are run.
func (suite *SuiteTester) SetupSuite() {
	suite.SetupSuiteRunCount++
}

func (suite *SuiteTester) BeforeTest(suiteName, testName string) {
	suite.SuiteNameBefore = append(suite.SuiteNameBefore, suiteName)
	suite.TestNameBefore = append(suite.TestNameBefore, testName)
	suite.TimeBefore = append(suite.TimeBefore, time.Now())
}

func (suite *SuiteTester) AfterTest(suiteName, testName string) {
	suite.SuiteNameAfter = append(suite.SuiteNameAfter, suiteName)
	suite.TestNameAfter = append(suite.TestNameAfter, testName)
	suite.TimeAfter = append(suite.TimeAfter, time.Now())
}

// The TearDownSuite method will be run by testify once, at the very
// end of the testing suite, after all tests have been run.
func (suite *SuiteTester) TearDownSuite() {
	suite.TearDownSuiteRunCount++
}

// The SetupTest method will be run before every test in the suite.
func (suite *SuiteTester) SetupTest() {
	suite.SetupTestRunCount++
}

// The TearDownTest method will be run after every test in the suite.
func (suite *SuiteTester) TearDownTest() {
	suite.TearDownTestRunCount++
}

// Every method in a testing suite that begins with "Test" will be run
// as a test.  TestOne is an example of a test.  For the purposes of
// this example, we've included assertions in the tests, since most
// tests will issue assertions.
func (suite *SuiteTester) TestOne() {
	beforeCount := suite.TestOneRunCount
	suite.TestOneRunCount++
	assert.Equal(suite.T(), suite.TestOneRunCount, beforeCount+1)
	suite.Equal(suite.TestOneRunCount, beforeCount+1)
}

// TestTwo is another example of a test.
func (suite *SuiteTester) TestTwo() {
	beforeCount := suite.TestTwoRunCount
	suite.TestTwoRunCount++
	assert.NotEqual(suite.T(), suite.TestTwoRunCount, beforeCount)
	suite.NotEqual(suite.TestTwoRunCount, beforeCount)
}

func (suite *SuiteTester) TestSkip() {
	suite.T().Skip()
}

// NonTestMethod does not begin with "Test", so it will not be run by
// testify as a test in the suite.  This is useful for creating helper
// methods for your tests.
func (suite *SuiteTester) NonTestMethod() {
	suite.NonTestMethodRunCount++
}

func (suite *SuiteTester) TestSubtest() {
	suite.TestSubtestRunCount++

	for _, t := range []struct {
		testName string
	}{
		{"first"},
		{"second"},
	} {
		suiteT := suite.T()
		suite.Run(t.testName, func() {
			// We should get a different *testing.T for subtests, so that
			// go test recognizes them as proper subtests for output formatting
			// and running individual subtests
			subTestT := suite.T()
			suite.NotEqual(subTestT, suiteT)
		})
		suite.Equal(suiteT, suite.T())
	}
}

type SuiteSkipTester struct {
	// Include our basic suite logic.
	Suite

	// Keep counts of how many times each method is run.
	SetupSuiteRunCount    int
	TearDownSuiteRunCount int
}

func (suite *SuiteSkipTester) SetupSuite() {
	suite.SetupSuiteRunCount++
	suite.T().Skip()
}

func (suite *SuiteSkipTester) TestNothing() {
	// SetupSuite is only called when at least one test satisfies
	// test filter. For this suite to be set up (and then tore down)
	// it is necessary to add at least one test method.
}

func (suite *SuiteSkipTester) TearDownSuite() {
	suite.TearDownSuiteRunCount++
}

// TestRunSuite will be run by the 'go test' command, so within it, we
// can run our suite using the Run(*testing.T, TestingSuite) function.
func TestRunSuite(t *testing.T) {
	suiteTester := new(SuiteTester)
	Run(t, suiteTester)

	// Normally, the test would end here.  The following are simply
	// some assertions to ensure that the Run function is working as
	// intended - they are not part of the example.

	// The suite was only run once, so the SetupSuite and TearDownSuite
	// methods should have each been run only once.
	assert.Equal(t, suiteTester.SetupSuiteRunCount, 1)
	assert.Equal(t, suiteTester.TearDownSuiteRunCount, 1)

	assert.Equal(t, len(suiteTester.SuiteNameAfter), 4)
	assert.Equal(t, len(suiteTester.SuiteNameBefore), 4)
	assert.Equal(t, len(suiteTester.TestNameAfter), 4)
	assert.Equal(t, len(suiteTester.TestNameBefore), 4)

	assert.Contains(t, suiteTester.TestNameAfter, "TestOne")
	assert.Contains(t, suiteTester.TestNameAfter, "TestTwo")
	assert.Contains(t, suiteTester.TestNameAfter, "TestSkip")
	assert.Contains(t, suiteTester.TestNameAfter, "TestSubtest")

	assert.Contains(t, suiteTester.TestNameBefore, "TestOne")
	assert.Contains(t, suiteTester.TestNameBefore, "TestTwo")
	assert.Contains(t, suiteTester.TestNameBefore, "TestSkip")
	assert.Contains(t, suiteTester.TestNameBefore, "TestSubtest")

	for _, suiteName := range suiteTester.SuiteNameAfter {
		assert.Equal(t, "SuiteTester", suiteName)
	}

	for _, suiteName := range suiteTester.SuiteNameBefore {
		assert.Equal(t, "SuiteTester", suiteName)
	}

	for _, when := range suiteTester.TimeAfter {
		assert.False(t, when.IsZero())
	}

	for _, when := range suiteTester.TimeBefore {
		assert.False(t, when.IsZero())
	}

	// There are four test methods (TestOne, TestTwo, TestSkip, and TestSubtest), so
	// the SetupTest and TearDownTest methods (which should be run once for
	// each test) should have been run four times.
	assert.Equal(t, suiteTester.SetupTestRunCount, 4)
	assert.Equal(t, suiteTester.TearDownTestRunCount, 4)

	// Each test should have been run once.
	assert.Equal(t, suiteTester.TestOneRunCount, 1)
	assert.Equal(t, suiteTester.TestTwoRunCount, 1)
	assert.Equal(t, suiteTester.TestSubtestRunCount, 1)

	// Methods that don't match the test method identifier shouldn't
	// have been run at all.
	assert.Equal(t, suiteTester.NonTestMethodRunCount, 0)

	suiteSkipTester := new(SuiteSkipTester)
	Run(t, suiteSkipTester)

	// The suite was only run once, so the SetupSuite and TearDownSuite
	// methods should have each been run only once, even though SetupSuite
	// called Skip()
	assert.Equal(t, suiteSkipTester.SetupSuiteRunCount, 1)
	assert.Equal(t, suiteSkipTester.TearDownSuiteRunCount, 1)

}

func TestSuiteGetters(t *testing.T) {
	suite := new(SuiteTester)
	suite.SetT(t)
	assert.NotNil(t, suite.Assert())
	assert.Equal(t, suite.Assertions, suite.Assert())
	assert.NotNil(t, suite.Require())
	assert.Equal(t, suite.require, suite.Require())
}

type SuiteLoggingTester struct {
	Suite
}

func (s *SuiteLoggingTester) TestLoggingPass() {
	s.T().Log("TESTLOGPASS")
}

func (s *SuiteLoggingTester) TestLoggingFail() {
	s.T().Log("TESTLOGFAIL")
	assert.NotNil(s.T(), nil) // expected to fail
}

type StdoutCapture struct {
	oldStdout *os.File
	readPipe  *os.File
}

func (sc *StdoutCapture) StartCapture() {
	sc.oldStdout = os.Stdout
	sc.readPipe, os.Stdout, _ = os.Pipe()
}

func (sc *StdoutCapture) StopCapture() (string, error) {
	if sc.oldStdout == nil || sc.readPipe == nil {
		return "", errors.New("StartCapture not called before StopCapture")
	}
	os.Stdout.Close()
	os.Stdout = sc.oldStdout
	bytes, err := ioutil.ReadAll(sc.readPipe)
	if err != nil {
		return "", err
	}
	return string(bytes), nil
}

func TestSuiteLogging(t *testing.T) {
	suiteLoggingTester := new(SuiteLoggingTester)
	capture := StdoutCapture{}
	internalTest := testing.InternalTest{
		Name: "SomeTest",
		F: func(subT *testing.T) {
			Run(subT, suiteLoggingTester)
		},
	}
	capture.StartCapture()
	testing.RunTests(allTestsFilter, []testing.InternalTest{internalTest})
	output, err := capture.StopCapture()
	require.NoError(t, err, "Got an error trying to capture stdout and stderr!")
	require.NotEmpty(t, output, "output content must not be empty")

	// Failed tests' output is always printed
	assert.Contains(t, output, "TESTLOGFAIL")

	if testing.Verbose() {
		// In verbose mode, output from successful tests is also printed
		assert.Contains(t, output, "TESTLOGPASS")
	} else {
		assert.NotContains(t, output, "TESTLOGPASS")
	}
}
<commit_msg>Rerun build<commit_after>package suite

import (
	"errors"
	"io/ioutil"
	"os"
	"testing"
	"time"

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

// SuiteRequireTwice is intended to test the usage of suite.Require in two
// different tests
type SuiteRequireTwice struct{ Suite }

// TestSuiteRequireTwice checks for regressions of issue #149 where
// suite.requirements was not initialised in suite.SetT()
// A regression would result on these tests panicking rather than failing.
func TestSuiteRequireTwice(t *testing.T) {
	ok := testing.RunTests(
		allTestsFilter,
		[]testing.InternalTest{{
			Name: "TestSuiteRequireTwice",
			F: func(t *testing.T) {
				suite := new(SuiteRequireTwice)
				Run(t, suite)
			},
		}},
	)
	assert.Equal(t, false, ok)
}

func (s *SuiteRequireTwice) TestRequireOne() {
	r := s.Require()
	r.Equal(1, 2)
}

func (s *SuiteRequireTwice) TestRequireTwo() {
	r := s.Require()
	r.Equal(1, 2)
}

type panickingSuite struct {
	Suite
	panicInSetupSuite    bool
	panicInSetupTest     bool
	panicInBeforeTest    bool
	panicInTest          bool
	panicInAfterTest     bool
	panicInTearDownTest  bool
	panicInTearDownSuite bool
}

func (s *panickingSuite) SetupSuite() {
	if s.panicInSetupSuite {
		panic("oops in setup suite")
	}
}

func (s *panickingSuite) SetupTest() {
	if s.panicInSetupTest {
		panic("oops in setup test")
	}
}

func (s *panickingSuite) BeforeTest(_, _ string) {
	if s.panicInBeforeTest {
		panic("oops in before test")
	}
}

func (s *panickingSuite) Test() {
	if s.panicInTest {
		panic("oops in test")
	}
}

func (s *panickingSuite) AfterTest(_, _ string) {
	if s.panicInAfterTest {
		panic("oops in after test")
	}
}

func (s *panickingSuite) TearDownTest() {
	if s.panicInTearDownTest {
		panic("oops in tear down test")
	}
}

func (s *panickingSuite) TearDownSuite() {
	if s.panicInTearDownSuite {
		panic("oops in tear down suite")
	}
}

func TestSuiteRecoverPanic(t *testing.T) {
	ok := true
	panickingTests := []testing.InternalTest{
		{
			Name: "TestPanicInSetupSuite",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInSetupSuite: true}) },
		},
		{
			Name: "TestPanicInSetupTest",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInSetupTest: true}) },
		},
		{
			Name: "TestPanicInBeforeTest",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInBeforeTest: true}) },
		},
		{
			Name: "TestPanicInTest",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTest: true}) },
		},
		{
			Name: "TestPanicInAfterTest",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInAfterTest: true}) },
		},
		{
			Name: "TestPanicInTearDownTest",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownTest: true}) },
		},
		{
			Name: "TestPanicInTearDownSuite",
			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownSuite: true}) },
		},
	}

	require.NotPanics(t, func() {
		ok = testing.RunTests(allTestsFilter, panickingTests)
	})

	assert.False(t, ok)
}

// This suite is intended to store values to make sure that only
// testing-suite-related methods are run.  It's also a fully
// functional example of a testing suite, using setup/teardown methods
// and a helper method that is ignored by testify.  To make this look
// more like a real world example, all tests in the suite perform some
// type of assertion.
type SuiteTester struct {
	// Include our basic suite logic.
	Suite

	// Keep counts of how many times each method is run.
	SetupSuiteRunCount    int
	TearDownSuiteRunCount int
	SetupTestRunCount     int
	TearDownTestRunCount  int
	TestOneRunCount       int
	TestTwoRunCount       int
	TestSubtestRunCount   int
	NonTestMethodRunCount int

	SuiteNameBefore []string
	TestNameBefore  []string

	SuiteNameAfter []string
	TestNameAfter  []string

	TimeBefore []time.Time
	TimeAfter  []time.Time
}

// The SetupSuite method will be run by testify once, at the very
// start of the testing suite, before any tests are run.
func (suite *SuiteTester) SetupSuite() {
	suite.SetupSuiteRunCount++
}

func (suite *SuiteTester) BeforeTest(suiteName, testName string) {
	suite.SuiteNameBefore = append(suite.SuiteNameBefore, suiteName)
	suite.TestNameBefore = append(suite.TestNameBefore, testName)
	suite.TimeBefore = append(suite.TimeBefore, time.Now())
}

func (suite *SuiteTester) AfterTest(suiteName, testName string) {
	suite.SuiteNameAfter = append(suite.SuiteNameAfter, suiteName)
	suite.TestNameAfter = append(suite.TestNameAfter, testName)
	suite.TimeAfter = append(suite.TimeAfter, time.Now())
}

// The TearDownSuite method will be run by testify once, at the very
// end of the testing suite, after all tests have been run.
func (suite *SuiteTester) TearDownSuite() {
	suite.TearDownSuiteRunCount++
}

// The SetupTest method will be run before every test in the suite.
func (suite *SuiteTester) SetupTest() {
	suite.SetupTestRunCount++
}

// The TearDownTest method will be run after every test in the suite.
func (suite *SuiteTester) TearDownTest() {
	suite.TearDownTestRunCount++
}

// Every method in a testing suite that begins with "Test" will be run
// as a test.  TestOne is an example of a test.  For the purposes of
// this example, we've included assertions in the tests, since most
// tests will issue assertions.
func (suite *SuiteTester) TestOne() {
	beforeCount := suite.TestOneRunCount
	suite.TestOneRunCount++
	assert.Equal(suite.T(), suite.TestOneRunCount, beforeCount+1)
	suite.Equal(suite.TestOneRunCount, beforeCount+1)
}

// TestTwo is another example of a test.
func (suite *SuiteTester) TestTwo() {
	beforeCount := suite.TestTwoRunCount
	suite.TestTwoRunCount++
	assert.NotEqual(suite.T(), suite.TestTwoRunCount, beforeCount)
	suite.NotEqual(suite.TestTwoRunCount, beforeCount)
}

func (suite *SuiteTester) TestSkip() {
	suite.T().Skip()
}

// NonTestMethod does not begin with "Test", so it will not be run by
// testify as a test in the suite.  This is useful for creating helper
// methods for your tests.
func (suite *SuiteTester) NonTestMethod() {
	suite.NonTestMethodRunCount++
}

func (suite *SuiteTester) TestSubtest() {
	suite.TestSubtestRunCount++

	for _, t := range []struct {
		testName string
	}{
		{"first"},
		{"second"},
	} {
		suiteT := suite.T()
		suite.Run(t.testName, func() {
			// We should get a different *testing.T for subtests, so that
			// go test recognizes them as proper subtests for output formatting
			// and running individual subtests
			subTestT := suite.T()
			suite.NotEqual(subTestT, suiteT)
		})
		suite.Equal(suiteT, suite.T())
	}
}

type SuiteSkipTester struct {
	// Include our basic suite logic.
	Suite

	// Keep counts of how many times each method is run.
	SetupSuiteRunCount    int
	TearDownSuiteRunCount int
}

func (suite *SuiteSkipTester) SetupSuite() {
	suite.SetupSuiteRunCount++
	suite.T().Skip()
}

func (suite *SuiteSkipTester) TestNothing() {
	// SetupSuite() is only called when at least one test satisfies
	// test filter. For this suite to be set up (and then tore down)
	// it is necessary to add at least one test method.
}

func (suite *SuiteSkipTester) TearDownSuite() {
	suite.TearDownSuiteRunCount++
}

// TestRunSuite will be run by the 'go test' command, so within it, we
// can run our suite using the Run(*testing.T, TestingSuite) function.
func TestRunSuite(t *testing.T) {
	suiteTester := new(SuiteTester)
	Run(t, suiteTester)

	// Normally, the test would end here.  The following are simply
	// some assertions to ensure that the Run function is working as
	// intended - they are not part of the example.

	// The suite was only run once, so the SetupSuite and TearDownSuite
	// methods should have each been run only once.
	assert.Equal(t, suiteTester.SetupSuiteRunCount, 1)
	assert.Equal(t, suiteTester.TearDownSuiteRunCount, 1)

	assert.Equal(t, len(suiteTester.SuiteNameAfter), 4)
	assert.Equal(t, len(suiteTester.SuiteNameBefore), 4)
	assert.Equal(t, len(suiteTester.TestNameAfter), 4)
	assert.Equal(t, len(suiteTester.TestNameBefore), 4)

	assert.Contains(t, suiteTester.TestNameAfter, "TestOne")
	assert.Contains(t, suiteTester.TestNameAfter, "TestTwo")
	assert.Contains(t, suiteTester.TestNameAfter, "TestSkip")
	assert.Contains(t, suiteTester.TestNameAfter, "TestSubtest")

	assert.Contains(t, suiteTester.TestNameBefore, "TestOne")
	assert.Contains(t, suiteTester.TestNameBefore, "TestTwo")
	assert.Contains(t, suiteTester.TestNameBefore, "TestSkip")
	assert.Contains(t, suiteTester.TestNameBefore, "TestSubtest")

	for _, suiteName := range suiteTester.SuiteNameAfter {
		assert.Equal(t, "SuiteTester", suiteName)
	}

	for _, suiteName := range suiteTester.SuiteNameBefore {
		assert.Equal(t, "SuiteTester", suiteName)
	}

	for _, when := range suiteTester.TimeAfter {
		assert.False(t, when.IsZero())
	}

	for _, when := range suiteTester.TimeBefore {
		assert.False(t, when.IsZero())
	}

	// There are four test methods (TestOne, TestTwo, TestSkip, and TestSubtest), so
	// the SetupTest and TearDownTest methods (which should be run once for
	// each test) should have been run four times.
	assert.Equal(t, suiteTester.SetupTestRunCount, 4)
	assert.Equal(t, suiteTester.TearDownTestRunCount, 4)

	// Each test should have been run once.
	assert.Equal(t, suiteTester.TestOneRunCount, 1)
	assert.Equal(t, suiteTester.TestTwoRunCount, 1)
	assert.Equal(t, suiteTester.TestSubtestRunCount, 1)

	// Methods that don't match the test method identifier shouldn't
	// have been run at all.
	assert.Equal(t, suiteTester.NonTestMethodRunCount, 0)

	suiteSkipTester := new(SuiteSkipTester)
	Run(t, suiteSkipTester)

	// The suite was only run once, so the SetupSuite and TearDownSuite
	// methods should have each been run only once, even though SetupSuite
	// called Skip()
	assert.Equal(t, suiteSkipTester.SetupSuiteRunCount, 1)
	assert.Equal(t, suiteSkipTester.TearDownSuiteRunCount, 1)

}

func TestSuiteGetters(t *testing.T) {
	suite := new(SuiteTester)
	suite.SetT(t)
	assert.NotNil(t, suite.Assert())
	assert.Equal(t, suite.Assertions, suite.Assert())
	assert.NotNil(t, suite.Require())
	assert.Equal(t, suite.require, suite.Require())
}

type SuiteLoggingTester struct {
	Suite
}

func (s *SuiteLoggingTester) TestLoggingPass() {
	s.T().Log("TESTLOGPASS")
}

func (s *SuiteLoggingTester) TestLoggingFail() {
	s.T().Log("TESTLOGFAIL")
	assert.NotNil(s.T(), nil) // expected to fail
}

type StdoutCapture struct {
	oldStdout *os.File
	readPipe  *os.File
}

func (sc *StdoutCapture) StartCapture() {
	sc.oldStdout = os.Stdout
	sc.readPipe, os.Stdout, _ = os.Pipe()
}

func (sc *StdoutCapture) StopCapture() (string, error) {
	if sc.oldStdout == nil || sc.readPipe == nil {
		return "", errors.New("StartCapture not called before StopCapture")
	}
	os.Stdout.Close()
	os.Stdout = sc.oldStdout
	bytes, err := ioutil.ReadAll(sc.readPipe)
	if err != nil {
		return "", err
	}
	return string(bytes), nil
}

func TestSuiteLogging(t *testing.T) {
	suiteLoggingTester := new(SuiteLoggingTester)
	capture := StdoutCapture{}
	internalTest := testing.InternalTest{
		Name: "SomeTest",
		F: func(subT *testing.T) {
			Run(subT, suiteLoggingTester)
		},
	}
	capture.StartCapture()
	testing.RunTests(allTestsFilter, []testing.InternalTest{internalTest})
	output, err := capture.StopCapture()
	require.NoError(t, err, "Got an error trying to capture stdout and stderr!")
	require.NotEmpty(t, output, "output content must not be empty")

	// Failed tests' output is always printed
	assert.Contains(t, output, "TESTLOGFAIL")

	if testing.Verbose() {
		// In verbose mode, output from successful tests is also printed
		assert.Contains(t, output, "TESTLOGPASS")
	} else {
		assert.NotContains(t, output, "TESTLOGPASS")
	}
}
<|endoftext|>


<commit_before>
package controllers;

import (
	"github.com/phenax/idiotic/models"
	"labix.org/v2/mgo/bson"
);

func ProfilePage(ctx *Context) {

	var user models.User;

	username := ctx.Params["name"];

	models.
		Users.Find(bson.M{
			"username": username,
		}).One(&user);

	if(user == nil) {
		ctx.Send("No user with that username");
		return;
	}

	config := &ResponseConfig{
		ContentType: "text/html",
	};

	ctx.Render("user", user, config);
}
<commit_msg>Fixed the no user condition<commit_after>
package controllers;

import (
	"github.com/phenax/idiotic/models"
	"labix.org/v2/mgo/bson"
);

func ProfilePage(ctx *Context) {

	var user models.User;

	username := ctx.Params["name"];

	models.
		Users.Find(bson.M{
			"username": username,
		}).One(&user);

	if(user.Username == "") {
		ctx.Send("No user with that username");
		return;
	}

	config := &ResponseConfig{
		ContentType: "text/html",
	};

	ctx.Render("user", user, config);
}
<|endoftext|>


<commit_before>// Copyright 2015 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

// 一个简单的 Go 语言热编译工具。
//
// 监视指定目录(可同时监视多个目录)下文件的变化，触发`go build`指令，
// 实时编译指定的 Go 代码，并在编译成功时运行该程序。
// 具体命令格式可使用`gobuild -v`来查看。
package main

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/issue9/term/colors"
)

// 当前程序的版本号
const version = "0.5.17+20160627"

const usage = `gobuild 是 Go 的热编译工具，监视文件变化，并编译和运行程序。

命令行语法:
 gobuild [options] [dependents]

 options:
  -h    显示当前帮助信息；
  -v    显示 gobuild 和 Go 程序的版本信息；
  -o    编译后的可执行文件名，程序的工作目录随之改变；
  -r    是否搜索子目录，默认为 true；
  -i    是否显示被标记为 IGNORE 的日志内容，默认为 false，即不显示；
  -ext  需要监视的扩展名，默认值为"go"，区分大小写，会去掉每个扩展名的首尾空格。
        若需要监视所有类型文件，请使用*，传递空值代表不监视任何文件；
  -main 指定需要编译的文件，默认为""。

 dependents:
  指定其它依赖的目录，只能出现在命令的尾部。

常见用法:

 gobuild
   监视当前目录，若有变动，则重新编译当前目录下的*.go文件；

 gobuild -main=main.go
   监视当前目录，若有变动，则重新编译当前目录下的main.go文件；

 gobuild -main="main.go" dir1 dir2
   监视当前目录及dir1和dir2，若有变动，则重新编译当前目录下的main.go文件；

NOTE: 不会监视隐藏文件和隐藏目录下的文件。

源代码采用 MIT 开源许可证，并发布于 https://github.com/caixw/gobuild
`

func main() {
	// 检测基本环境是否满足
	if gopath := os.Getenv("GOPATH"); len(gopath) == 0 {
		log(erro, "未设置环境变量GOPATH")
		return
	}

	// 初始化flag
	var showHelp, showVersion, recursive bool
	var mainFiles, outputName, extString string

	flag.BoolVar(&showHelp, "h", false, "显示帮助信息")
	flag.BoolVar(&showVersion, "v", false, "显示版本号")
	flag.BoolVar(&recursive, "r", true, "是否查找子目录")
	flag.BoolVar(&showIgnoreLog, "i", false, "是否显示被标记为IGNORE的日志内容")
	flag.StringVar(&outputName, "o", "", "指定输出名称")
	flag.StringVar(&extString, "ext", "go", "指定监视的文件扩展名")
	flag.StringVar(&mainFiles, "main", "", "指定需要编译的文件")
	flag.Usage = func() {
		fmt.Println(usage)
	}
	flag.Parse()

	switch {
	case showHelp:
		flag.Usage()
		return
	case showVersion:
		printVersion()
		return
	}

	wd, err := os.Getwd()
	if err != nil {
		log(erro, "获取当前工作目录时，发生以下错误:", err)
		return
	}

	// 初始化goCmd的参数
	args := []string{"build", "-o", outputName}
	if len(mainFiles) > 0 {
		args = append(args, mainFiles)
	}

	b := &builder{
		exts:      getExts(extString),
		appName:   getAppName(outputName, wd),
		goCmdArgs: args,
	}

	b.watch(recursivePaths(recursive, append(flag.Args(), wd)))
	go b.build()

	done := make(chan bool)
	<-done
}

// 输出版本号
func printVersion() {
	colors.Print(colors.Stdout, colors.Green, colors.Default, "gobuild: ")
	colors.Println(colors.Stdout, colors.Default, colors.Default, version)
	colors.Print(colors.Stdout, colors.Green, colors.Default, "Go: ")
	goVersion := runtime.Version() + " " + runtime.GOOS + "/" + runtime.GOARCH
	colors.Println(colors.Stdout, colors.Default, colors.Default, goVersion)
}

// 根据 recursive 值确定是否递归查找 paths 每个目录下的子目录。
func recursivePaths(recursive bool, paths []string) []string {
	if !recursive {
		return paths
	}

	ret := []string{}

	walk := func(path string, fi os.FileInfo, err error) error {
		if err != nil {
			log(erro, "在遍历监视目录时，发生以下错误:", err)
		}

		if fi.IsDir() && strings.Index(path, "/.") < 0 {
			ret = append(ret, path)
		}
		return nil
	}

	for _, path := range paths {
		if err := filepath.Walk(path, walk); err != nil {
			log(erro, "在遍历监视目录时，发生以下错误:", err)
		}
	}

	return ret
}

// 将 extString 分解成数组，并清理掉无用的内容，比如空字符串
func getExts(extString string) []string {
	exts := strings.Split(extString, ",")
	ret := make([]string, 0, len(exts))

	for _, ext := range exts {
		ext = strings.TrimSpace(ext)

		if len(ext) == 0 {
			continue
		}
		if ext[0] != '.' {
			ext = "." + ext
		}
		ret = append(ret, ext)
	}

	switch {
	case len(ret) == 0: // 允许不监视任意文件，但输出一信息来警告
		log(warn, "将ext设置为空值，意味着不监视任何文件的改变！")
	case len(ret) > 0:
		log(info, "系统将监视以下类型的文件:", ret)
	}

	return ret
}

func getAppName(outputName, wd string) string {
	if len(outputName) == 0 {
		outputName = filepath.Base(wd)
	}
	if runtime.GOOS == "windows" && !strings.HasSuffix(outputName, ".exe") {
		outputName += ".exe"
	}
	if strings.IndexByte(outputName, '/') < 0 || strings.IndexByte(outputName, filepath.Separator) < 0 {
		outputName = wd + string(filepath.Separator) + outputName
	}

	// 转成绝对路径
	outputName, err := filepath.Abs(outputName)
	if err != nil {
		log(erro, err)
	}

	log(info, "输出文件为:", outputName)

	return outputName
}
<commit_msg>改进帮助内容<commit_after>// Copyright 2015 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

// 一个简单的 Go 语言热编译工具。
//
// 监视指定目录(可同时监视多个目录)下文件的变化，触发`go build`指令，
// 实时编译指定的 Go 代码，并在编译成功时运行该程序。
// 具体命令格式可使用`gobuild -v`来查看。
package main

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"
)

// 当前程序的版本号
const version = "0.5.18+20160704"

func main() {
	// 检测基本环境是否满足
	if gopath := os.Getenv("GOPATH"); len(gopath) == 0 {
		log(erro, "未设置环境变量GOPATH")
		return
	}

	// 初始化flag
	var showHelp, showVersion, recursive bool
	var mainFiles, outputName, extString string

	flag.BoolVar(&showHelp, "h", false, "显示帮助信息；")
	flag.BoolVar(&showVersion, "v", false, "显示版本号；")
	flag.BoolVar(&recursive, "r", true, "是否查找子目录；")
	flag.BoolVar(&showIgnoreLog, "i", false, "是否显示被标记为 IGNORE 的日志内容；")
	flag.StringVar(&outputName, "o", "", "指定输出名称，程序的工作目录随之改变；")
	flag.StringVar(&extString, "ext", "go", "指定监视的文件扩展，区分大小写。*表示监视所有类型文件，空值代表不监视任何文件；")
	flag.StringVar(&mainFiles, "main", "", "指定需要编译的文件；")
	flag.Usage = usage
	flag.Parse()

	switch {
	case showHelp:
		flag.Usage()
		return
	case showVersion:
		fmt.Fprintln(os.Stdout, "gobuild", version, "build with", runtime.Version(), runtime.GOOS+"/"+runtime.GOARCH)
		return
	}

	wd, err := os.Getwd()
	if err != nil {
		log(erro, "获取当前工作目录时，发生以下错误:", err)
		return
	}

	// 初始化goCmd的参数
	args := []string{"build", "-o", outputName}
	if len(mainFiles) > 0 {
		args = append(args, mainFiles)
	}

	b := &builder{
		exts:      getExts(extString),
		appName:   getAppName(outputName, wd),
		goCmdArgs: args,
	}

	b.watch(recursivePaths(recursive, append(flag.Args(), wd)))
	go b.build()

	done := make(chan bool)
	<-done
}

func usage() {
	fmt.Fprintln(os.Stdout, `gobuild 是 Go 的热编译工具，监视文件变化，并编译和运行程序。

命令行语法：
 gobuild [options] [dependents]

 options:`)

	flag.CommandLine.SetOutput(os.Stdout)
	flag.PrintDefaults()

	fmt.Fprintln(os.Stdout, `
 dependents:
  指定其它依赖的目录，只能出现在命令的尾部。

常见用法:

 gobuild
   监视当前目录，若有变动，则重新编译当前目录下的*.go文件；

 gobuild -main=main.go
   监视当前目录，若有变动，则重新编译当前目录下的main.go文件；

 gobuild -main="main.go" dir1 dir2
   监视当前目录及dir1和dir2，若有变动，则重新编译当前目录下的main.go文件；

NOTE: 不会监视隐藏文件和隐藏目录下的文件。

源代码采用 MIT 开源许可证，并发布于 https://github.com/caixw/gobuild`)
}

// 根据 recursive 值确定是否递归查找 paths 每个目录下的子目录。
func recursivePaths(recursive bool, paths []string) []string {
	if !recursive {
		return paths
	}

	ret := []string{}

	walk := func(path string, fi os.FileInfo, err error) error {
		if err != nil {
			log(erro, "在遍历监视目录时，发生以下错误:", err)
		}

		if fi.IsDir() && strings.Index(path, "/.") < 0 {
			ret = append(ret, path)
		}
		return nil
	}

	for _, path := range paths {
		if err := filepath.Walk(path, walk); err != nil {
			log(erro, "在遍历监视目录时，发生以下错误:", err)
		}
	}

	return ret
}

// 将 extString 分解成数组，并清理掉无用的内容，比如空字符串
func getExts(extString string) []string {
	exts := strings.Split(extString, ",")
	ret := make([]string, 0, len(exts))

	for _, ext := range exts {
		ext = strings.TrimSpace(ext)

		if len(ext) == 0 {
			continue
		}
		if ext[0] != '.' {
			ext = "." + ext
		}
		ret = append(ret, ext)
	}

	switch {
	case len(ret) == 0: // 允许不监视任意文件，但输出一信息来警告
		log(warn, "将ext设置为空值，意味着不监视任何文件的改变！")
	case len(ret) > 0:
		log(info, "系统将监视以下类型的文件:", ret)
	}

	return ret
}

func getAppName(outputName, wd string) string {
	if len(outputName) == 0 {
		outputName = filepath.Base(wd)
	}
	if runtime.GOOS == "windows" && !strings.HasSuffix(outputName, ".exe") {
		outputName += ".exe"
	}
	if strings.IndexByte(outputName, '/') < 0 || strings.IndexByte(outputName, filepath.Separator) < 0 {
		outputName = wd + string(filepath.Separator) + outputName
	}

	// 转成绝对路径
	outputName, err := filepath.Abs(outputName)
	if err != nil {
		log(erro, err)
	}

	log(info, "输出文件为:", outputName)

	return outputName
}
<|endoftext|>


<commit_before>/*
 Package golfstk provides util functions for general programing
*/

package goqueue

//import "fmt"

//import "time"
import "runtime"

// FILO/FIFO stack with max item limit and discard support
type Stack struct {
	in      chan interface{}      //
	out     chan interface{}      //
	max     int64                 // max item in stack(chan+pool)
	ptr     int64                 // current position
	discard bool                  //
	pool    map[int64]interface{} // pool
	exited  chan struct{}         // flag channel, channel closed after stack closed
}

// NewStack return new Stack and lauch stack manager goroutine
// chanBufferSize for input/output channel buffer size, for forward speed recommand buffer size >= 256
// poolSize for stack pool size
// discard control how to do when stack is full, true for drop new item, false for waiting
// max item stay in stack will be input channel buffer(chanBufferSize) + output channel buffer(chanBufferSize) + poolSize
// set poolSize <= 0 turn stack into FIFO pipe, this is a in-storage-out forwarder
// set poolSize < 0 for unlimited stack
// input/output channel closed when stack.Close()
func NewStack(chanBufferSize int64, poolSize int64, discard bool) *Stack {
	var self *Stack
	if chanBufferSize < 0 {
		chanBufferSize = 0
	}
	self = &Stack{
		max:     poolSize,
		ptr:     0,
		discard: discard,
		in:      make(chan interface{}, chanBufferSize),
		out:     make(chan interface{}, chanBufferSize),
		pool:    make(map[int64]interface{}),
		exited:  make(chan struct{}, 0),
	}
	// slice index from 1, so we will fill index 0 with
	self.pool[0] = nil
	switch {
	case self.max == 0:
		// FIFO pipe
		go self.pipe()
	default:
		// FILO
		go self.manager()
	}
	return self
}

// pipe forward input item to output in FIFO mode
// if output blocked and self.discard == true, new input item discarded, otherwise blocked at output
func (self *Stack) pipe() {
	// fast forward
	var in interface{}
	if self.discard {
		for in = range self.in {
			select {
			case self.out <- in:
			default:
				// discarded
			}
		}
	} else {
		for in = range self.in {
			self.out <- in
		}
	}
	close(self.out)
}

// manager forward input item to output
// save item to pool when output blocked
// if pool size reach max(then mean output blocked),
// and self.discard == true, new input item discarded,
// otherwise blocked at output
func (self *Stack) manager() {
	var in interface{} = nil
	var ok bool
	var fastForward bool = true
	defer func() {
		// self.in already closed
		select {
		case <-self.exited:
		default:
			close(self.exited)
		}
		go self.flushExit()
	}()
	for {
		if self.ptr == 0 {
			// fast forward
			for in = range self.in {
				select {
				case self.out <- in:
					continue
				default:
					if self.ptr < self.max || self.max < 0 {
						// push in
						// ++ will slow down
						self.ptr++
						self.pool[self.ptr] = in
					} else if self.discard {
						// just discard
					} else {
						// pool full
						// do not try to read more in
						self.out <- in
					}
					// out is blocked
					fastForward = false
				}
				if fastForward == false {
					break
				}
			}
			fastForward = false
		}
		// slow forwad
		for fastForward == false {
			// check input first
			select {
			case in, ok = <-self.in:
				if !ok {
					// in closed
					return
				}
				select {
				case self.out <- in:
					continue
				default:
				}
				// out blocked
				if self.ptr < self.max || self.max < 0 {
					// push in
					// ++ will slow down
					self.ptr++
					self.pool[self.ptr] = in
				} else if self.discard {
					// just discard
				} else {
					// already full
					// do not try to read more in
					self.out <- in
				}
			default:
			}
			// try to flush out when input blocked
			select {
			case self.out <- self.pool[self.ptr]:
				// pop out
				// -- will slow down
				self.ptr--
				if self.ptr == 0 {
					fastForward = true
				}
			default:
				runtime.Gosched()
			}
		}
	}
}

//
func (self *Stack) flushExit() {
	// blocking flush in buffer
	var in interface{}
	for in = range self.in {
		if self.ptr < self.max || self.max < 0 {
			self.ptr++
			self.pool[self.ptr] = in
		} else {
			if self.discard {
				// discarded
			} else {
				// blocked write
				self.out <- in
			}
		}
	}
	// flush pool to out
	for self.ptr > 0 {
		// blocked write
		self.out <- self.pool[self.ptr]
		// pop out
		self.ptr--
	}
	close(self.out)
	// release memory
	for key, _ := range self.pool {
		delete(self.pool, key)
	}
	self.pool = nil
	return
}

// Close stop stack manager and release pool
// write to a Closed self.In() will rise panic("write at close channel")
// user should handle panic by recover()
func (self *Stack) Close() {
	defer func() {
		recover()
	}()
	close(self.exited)
	close(self.in)
	return
}

// ClosedChan return a flag channel for stack closed test
// channel will closed after self.Close()
// user should use: select-read block to test channel status
func (self *Stack) ClosedChan() <-chan struct{} {
	return self.exited
}

// IsClosed return true if stack closed
func (self *Stack) IsClosed() bool {
	select {
	case <-self.exited:
		return true
	default:
	}
	return false
}

// push in into stack, return nil for ok, if stack already closed, return error
func (self *Stack) Push(in interface{}) error {
	defer func() error {
		return recover().(error)
	}()
	self.in <- in
	return nil
}

// In return channel for stack push
// channel will closed after self.Close()
// user have to handle panic("write to closed channel") if try to write after Close()
// or use self.Push(in), which have a defer-recover panic handle
func (self *Stack) In() chan<- interface{} {
	return self.in
}

// Out return channel for stack pop
// channel will closed after self.Close()
// read from a closed channel will got <nil>
func (self *Stack) Out() <-chan interface{} {
	return self.out
}

// GetCacheSize return items number in stack(include channel buffered)
func (self *Stack) GetCacheSize() int64 {
	return self.ptr + int64(len(self.in)) + int64(len(self.out))
}

// Lock Free Stack without channel

/*
package main

import (
	"fmt"
	"runtime"
	"sync"
	"sync/atomic"
	"unsafe"
)

const (
	MAX_DATA_SIZE = 10000
)

// lock free lfstk
type LFstack struct {
	head unsafe.Pointer
	tail unsafe.Pointer
}

// one node in lfstk
type node struct {
	val  interface{}
	next unsafe.Pointer
}

// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.
// func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)

// lfstk functions
func (self *LFstack) Push(val interface{}) {
	newValue := unsafe.Pointer(&node{val: val, next: nil})
	var tail, next unsafe.Pointer
	for {
		tail = self.tail
		next = ((*node)(tail)).next
		if next != nil {
			atomic.CompareAndSwapPointer(&(self.tail), tail, next)
		} else if atomic.CompareAndSwapPointer(&((*node)(tail).next), nil, newValue) {
			break
		}
		runtime.Gosched()
	}
}

func (self *LFstack) Pop() (val interface{}, success bool) {
	var head, tail, next unsafe.Pointer
	for {
		head = self.head
		tail = self.tail
		next = ((*node)(head)).next
		if head == tail {
			if next == nil {
				return nil, false
			} else {
				atomic.CompareAndSwapPointer(&(self.tail), tail, next)
			}
		} else {
			val = ((*node)(next)).val
			if atomic.CompareAndSwapPointer(&(self.head), head, next) {
				return val, true
			}
		}
		runtime.Gosched()
	}
	return
}

func qin(start int) {
	defer wg.Done()
	start = start * 1000
	//fmt.Println("start = ", start)
	for j := 0; j < MAX_DATA_SIZE; j++ {
		start++
		fmt.Println("enq = ", start)
		lfstk.Push(start)
	}
}

func qout() {
	ok := false
	var val interface{}
	defer wg.Done()
	for j := 0; j < MAX_DATA_SIZE; j++ {
		val, ok = lfstk.Pop()
		for !ok {
			val, ok = lfstk.Pop()
			runtime.Gosched()
		}
		fmt.Println("deq = ", val)
	}
}

var wg sync.WaitGroup

var lfstk *LFstack

func main() {

	lfstk = new(LFstack)
	lfstk.head = unsafe.Pointer(new(node))
	lfstk.tail = lfstk.head

	// 9 qin * 10000 * 2 = 1800000
	for i := 1; i < 10; i++ {
		wg.Add(1)
		go qin(i)
	}

	for i := 0; i < 9; i++ {
		wg.Add(1)
		go qout()
	}

	wg.Wait()
}

*/

// lock Free Stack with channel
//
<commit_msg>add SetPoolSize func<commit_after>/*
 Package golfstk provides util functions for general programing
*/

package goqueue

//import "fmt"

import "errors"
import "runtime"

// FILO/FIFO stack with max item limit and discard support
type Stack struct {
	in      chan interface{}      //
	out     chan interface{}      //
	max     int64                 // max item in stack(chan+pool)
	ptr     int64                 // current position
	discard bool                  //
	pool    map[int64]interface{} // pool
	exited  chan struct{}         // flag channel, channel closed after stack closed
}

// NewStack return new Stack and lauch stack manager goroutine
// chanBufferSize for input/output channel buffer size, for forward speed recommand buffer size >= 256
// poolSize for stack pool size
// discard control how to do when stack is full, true for drop new item, false for waiting
// max item stay in stack will be input channel buffer(chanBufferSize) + output channel buffer(chanBufferSize) + poolSize
// set poolSize <= 0 turn stack into FIFO pipe, this is a in-storage-out forwarder
// set poolSize < 0 for unlimited stack
// input/output channel closed when stack.Close()
func NewStack(chanBufferSize int64, poolSize int64, discard bool) *Stack {
	var self *Stack
	if chanBufferSize < 0 {
		chanBufferSize = 0
	}
	self = &Stack{
		max:     poolSize,
		ptr:     0,
		discard: discard,
		in:      make(chan interface{}, chanBufferSize),
		out:     make(chan interface{}, chanBufferSize),
		pool:    make(map[int64]interface{}),
		exited:  make(chan struct{}, 0),
	}
	// slice index from 1, so we will fill index 0 with
	self.pool[0] = nil
	switch {
	case self.max == 0:
		// FIFO pipe
		go self.pipe()
	default:
		// FILO
		go self.manager()
	}
	return self
}

// pipe forward input item to output in FIFO mode
// if output blocked and self.discard == true, new input item discarded, otherwise blocked at output
func (self *Stack) pipe() {
	// fast forward
	var in interface{}
	if self.discard {
		for in = range self.in {
			select {
			case self.out <- in:
			default:
				// discarded
			}
		}
	} else {
		for in = range self.in {
			self.out <- in
		}
	}
	close(self.out)
}

// manager forward input item to output
// save item to pool when output blocked
// if pool size reach max(then mean output blocked),
// and self.discard == true, new input item discarded,
// otherwise blocked at output
func (self *Stack) manager() {
	var in interface{} = nil
	var ok bool
	var fastForward bool = true
	defer func() {
		// self.in already closed
		select {
		case <-self.exited:
		default:
			close(self.exited)
		}
		go self.flushExit()
	}()
	for {
		if self.ptr == 0 {
			// fast forward
			for in = range self.in {
				select {
				case self.out <- in:
					continue
				default:
					if self.ptr < self.max || self.max < 0 {
						// push in
						// ++ will slow down
						self.ptr++
						self.pool[self.ptr] = in
					} else if self.discard {
						// just discard
					} else {
						// pool full
						// do not try to read more in
						self.out <- in
					}
					// out is blocked
					fastForward = false
				}
				if fastForward == false {
					break
				}
			}
			fastForward = false
		}
		// slow forwad
		for fastForward == false {
			// check input first
			select {
			case in, ok = <-self.in:
				if !ok {
					// in closed
					return
				}
				select {
				case self.out <- in:
					continue
				default:
				}
				// out blocked
				if self.ptr < self.max || self.max < 0 {
					// push in
					// ++ will slow down
					self.ptr++
					self.pool[self.ptr] = in
				} else if self.discard {
					// just discard
				} else {
					// already full
					// do not try to read more in
					self.out <- in
				}
			default:
			}
			// try to flush out when input blocked
			select {
			case self.out <- self.pool[self.ptr]:
				// pop out
				// -- will slow down
				self.ptr--
				if self.ptr == 0 {
					fastForward = true
				}
			default:
				runtime.Gosched()
			}
		}
	}
}

//
func (self *Stack) flushExit() {
	// blocking flush in buffer
	var in interface{}
	for in = range self.in {
		if self.ptr < self.max || self.max < 0 {
			self.ptr++
			self.pool[self.ptr] = in
		} else {
			if self.discard {
				// discarded
			} else {
				// blocked write
				self.out <- in
			}
		}
	}
	// flush pool to out
	for self.ptr > 0 {
		// blocked write
		self.out <- self.pool[self.ptr]
		// pop out
		self.ptr--
	}
	close(self.out)
	// release memory
	for key, _ := range self.pool {
		delete(self.pool, key)
	}
	self.pool = nil
	return
}

// Close stop stack manager and release pool
// write to a Closed self.In() will rise panic("write at close channel")
// user should handle panic by recover()
func (self *Stack) Close() {
	defer func() {
		recover()
	}()
	close(self.exited)
	close(self.in)
	return
}

// ClosedChan return a flag channel for stack closed test
// channel will closed after self.Close()
// user should use: select-read block to test channel status
func (self *Stack) ClosedChan() <-chan struct{} {
	return self.exited
}

// IsClosed return true if stack closed
func (self *Stack) IsClosed() bool {
	select {
	case <-self.exited:
		return true
	default:
	}
	return false
}

// SetPoolSize return old PoolSize
// and set pool size to size
func (self *Stack) SetPoolSize(size int64) int64 {
	old := self.max
	self.max = size
	return old
}

// push in into stack, return nil for ok
// return error when stack is full and blocking == false
//
func (self *Stack) Push(in interface{}, blocking bool) error {
	defer func() error {
		return recover().(error)
	}()
	select {
	case <-self.exited:
		return errors.New("stack has closed")
	default:
	}
	if blocking {
		self.in <- in
	} else if self.max == self.ptr {
		return errors.New("stack is full")
	} else {
		self.in <- in
	}
	return nil
}

// In return channel for stack push
// channel will closed after self.Close()
// user have to handle panic("write to closed channel") if try to write after Close()
// or use self.Push(in), which have a defer-recover panic handle
func (self *Stack) In() chan<- interface{} {
	return self.in
}

// Out return channel for stack pop
// channel will closed after self.Close()
// read from a closed channel will got <nil>
func (self *Stack) Out() <-chan interface{} {
	return self.out
}

// GetCacheSize return items number in stack(include channel buffered)
func (self *Stack) GetCacheSize() int64 {
	return self.ptr + int64(len(self.in)) + int64(len(self.out))
}

// Lock Free Stack without channel

/*
package main

import (
	"fmt"
	"runtime"
	"sync"
	"sync/atomic"
	"unsafe"
)

const (
	MAX_DATA_SIZE = 10000
)

// lock free lfstk
type LFstack struct {
	head unsafe.Pointer
	tail unsafe.Pointer
}

// one node in lfstk
type node struct {
	val  interface{}
	next unsafe.Pointer
}

// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.
// func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)

// lfstk functions
func (self *LFstack) Push(val interface{}) {
	newValue := unsafe.Pointer(&node{val: val, next: nil})
	var tail, next unsafe.Pointer
	for {
		tail = self.tail
		next = ((*node)(tail)).next
		if next != nil {
			atomic.CompareAndSwapPointer(&(self.tail), tail, next)
		} else if atomic.CompareAndSwapPointer(&((*node)(tail).next), nil, newValue) {
			break
		}
		runtime.Gosched()
	}
}

func (self *LFstack) Pop() (val interface{}, success bool) {
	var head, tail, next unsafe.Pointer
	for {
		head = self.head
		tail = self.tail
		next = ((*node)(head)).next
		if head == tail {
			if next == nil {
				return nil, false
			} else {
				atomic.CompareAndSwapPointer(&(self.tail), tail, next)
			}
		} else {
			val = ((*node)(next)).val
			if atomic.CompareAndSwapPointer(&(self.head), head, next) {
				return val, true
			}
		}
		runtime.Gosched()
	}
	return
}

func qin(start int) {
	defer wg.Done()
	start = start * 1000
	//fmt.Println("start = ", start)
	for j := 0; j < MAX_DATA_SIZE; j++ {
		start++
		fmt.Println("enq = ", start)
		lfstk.Push(start)
	}
}

func qout() {
	ok := false
	var val interface{}
	defer wg.Done()
	for j := 0; j < MAX_DATA_SIZE; j++ {
		val, ok = lfstk.Pop()
		for !ok {
			val, ok = lfstk.Pop()
			runtime.Gosched()
		}
		fmt.Println("deq = ", val)
	}
}

var wg sync.WaitGroup

var lfstk *LFstack

func main() {

	lfstk = new(LFstack)
	lfstk.head = unsafe.Pointer(new(node))
	lfstk.tail = lfstk.head

	// 9 qin * 10000 * 2 = 1800000
	for i := 1; i < 10; i++ {
		wg.Add(1)
		go qin(i)
	}

	for i := 0; i < 9; i++ {
		wg.Add(1)
		go qout()
	}

	wg.Wait()
}

*/

// lock Free Stack with channel
//
<|endoftext|>


<commit_before>package wallet

import (
	"errors"
	"fmt"
	"strconv"
	"sync"

	"github.com/NebulousLabs/Andromeda/consensus"
	"github.com/NebulousLabs/Andromeda/signatures"
)

// openTransaction is a type that the wallet uses to track a transaction as it
// adds inputs and other features.
type openTransaction struct {
	transaction *consensus.Transaction
	inputs      []int
}

// spendableOutput keeps track of an output, it's id, and whether or not it's
// been spent yet. Spendable indicates whether the output is available
// according to the blockchain, true if the output is unspent in the blockchain
// and false if the output is spent in the blockchain. The spentCounter
// indicates whether the output has been spent or not. If it's equal to the
// wallet's spent counter, then it has been spent since the previous reset.
type spendableOutput struct {
	spendable    bool
	spentCounter int
	id           consensus.OutputID
	output       *consensus.Output
}

// openOutput contains an output and the conditions needed to spend the output,
// including secret keys.
type spendableAddress struct {
	spendableOutputs map[consensus.OutputID]*spendableOutput
	spendConditions  consensus.SpendConditions
	secretKey        signatures.SecretKey
}

// Wallet holds your coins, manages privacy, outputs, ect. The balance reported
// ignores outputs you've already spent even if they haven't made it into the
// blockchain yet.
//
// TODO: Do not ignore refunds until they make it into a block (but later, leave it for now)
type Wallet struct {
	spentCounter       int
	spendableAddresses map[consensus.CoinAddress]*spendableAddress

	transactionCounter int
	transactions       map[string]*openTransaction

	sync.Mutex
}

// findOutputs returns a set of spendable outputs that add up to at least
// `amount` of coins, returning an error if it cannot. It also returns the
// `total`, which is the sum of all the outputs. It does not adjust the outputs
// in any way.
func (w *Wallet) findOutputs(amount consensus.Currency) (spendableOutputs []*spendableOutput, total consensus.Currency, err error) {
	if amount == consensus.Currency(0) {
		err = errors.New("cannot fund 0 coins") // should this be an error or nil?
		return
	}

	// Iterate through all outputs until enough coins have been assembled.
	for _, spendableAddress := range w.spendableAddresses {
		for _, spendableOutput := range spendableAddress.spendableOutputs {
			if !spendableOutput.spendable || spendableOutput.spentCounter == w.spentCounter {
				continue
			}
			total += spendableOutput.output.Value
			spendableOutputs = append(spendableOutputs, spendableOutput)

			// Break once
			if total >= amount {
				break
			}
		}
		// Break twice :)
		if total >= amount {
			break
		}
	}

	// Check that enough inputs were added.
	if total < amount {
		err = fmt.Errorf("insufficient funds, requested %v but only have %v", amount, total)
		return
	}

	return
}

// New creates an initializes a Wallet.
func New() (*Wallet, error) {
	return &Wallet{
		spendableAddresses: make(map[consensus.CoinAddress]*spendableAddress),
		transactions:       make(map[string]*openTransaction),
	}, nil
}

// Update implements the core.Wallet interface.
func (w *Wallet) Update(rewound []consensus.Block, applied []consensus.Block) error {
	w.Lock()
	defer w.Unlock()

	// Undo add the changes from blocks that have been rewound.
	for _, b := range rewound {
		for i := len(b.Transactions) - 1; i >= 0; i-- {
			// Mark all outputs that got created (sent to an address in our
			// control) as 'not spendable', because they no longer exist in
			// the blockchain.
			for j, output := range b.Transactions[i].Outputs {
				if spendableAddress, exists := w.spendableAddresses[output.SpendHash]; exists {
					id := b.Transactions[i].OutputID(j)
					if spendableOutput, exists := spendableAddress.spendableOutputs[id]; exists {
						spendableOutput.spendable = false
					} else {
						panic("output should exist")
					}
				}
			}

			// Mark all inputs that we control as 'spendable', because the
			// blockchain is no longer aware that they've been spent.
			for _, input := range b.Transactions[i].Inputs {
				coinAddress := input.SpendConditions.CoinAddress()
				if spendableAddress, exists := w.spendableAddresses[coinAddress]; exists {
					if spendableOutput, exists := spendableAddress.spendableOutputs[input.OutputID]; exists {
						spendableOutput.spendable = true
					} else {
						panic("output should exist")
					}
				}
			}
		}
	}

	// Update spendableOutputs which got spent, and find new outputs which we
	// know how to spend.
	for _, b := range applied {
		for _, t := range b.Transactions {
			// Mark all outputs that got consumed by the block as 'not
			// spendable'
			for _, input := range t.Inputs {
				coinAddress := input.SpendConditions.CoinAddress()
				if spendableAddress, exists := w.spendableAddresses[coinAddress]; exists {
					if spendableOutput, exists := spendableAddress.spendableOutputs[input.OutputID]; exists {
						spendableOutput.spendable = false
					} else {
						panic("output should exist")
					}
				}
			}

			// Mark all outputs that got created (sent to an address in our
			// control) as 'spendable'.
			for j, output := range t.Outputs {
				if spendableAddress, exists := w.spendableAddresses[output.SpendHash]; exists {
					id := t.OutputID(j)
					if spendOutput, exists := spendableAddress.spendableOutputs[id]; exists {
						spendOutput.spendable = true
					} else {
						spendableAddress.spendableOutputs[id] = &spendableOutput{
							spendable: true,
							id:        id,
							output:    &output,
						}
					}
				}
			}
		}
	}

	return nil
}

// Reset implements the core.Wallet interface.
func (w *Wallet) Reset() error {
	w.Lock()
	defer w.Unlock()
	w.spentCounter++
	return nil
}

// Balance implements the core.Wallet interface.
func (w *Wallet) Balance() (total consensus.Currency, err error) {
	w.Lock()
	defer w.Unlock()

	// Iterate through all outputs and tally them up.
	for _, spendableAddress := range w.spendableAddresses {
		for _, spendableOutput := range spendableAddress.spendableOutputs {
			if !spendableOutput.spendable || spendableOutput.spentCounter == w.spentCounter {
				continue
			}
			total += spendableOutput.output.Value
		}
	}

	return
}

// timelockedCoinAddress returns a CoinAddress with a timelock, as well as the
// conditions needed to spend it.
func (w *Wallet) timelockedCoinAddress(release consensus.BlockHeight) (spendConditions consensus.SpendConditions, err error) {
	sk, pk, err := signatures.GenerateKeyPair()
	if err != nil {
		return
	}

	spendConditions = consensus.SpendConditions{
		TimeLock:      release,
		NumSignatures: 1,
		PublicKeys:    []signatures.PublicKey{pk},
	}

	newSpendableAddress := &spendableAddress{
		spendableOutputs: make(map[consensus.OutputID]*spendableOutput),
		spendConditions:  spendConditions,
		secretKey:        sk,
	}

	coinAddress := spendConditions.CoinAddress()
	w.spendableAddresses[coinAddress] = newSpendableAddress
	return
}

// CoinAddress implements the core.Wallet interface.
func (w *Wallet) CoinAddress() (coinAddress consensus.CoinAddress, err error) {
	w.Lock()
	defer w.Unlock()

	sk, pk, err := signatures.GenerateKeyPair()
	if err != nil {
		return
	}

	newSpendableAddress := &spendableAddress{
		spendableOutputs: make(map[consensus.OutputID]*spendableOutput),
		spendConditions: consensus.SpendConditions{
			NumSignatures: 1,
			PublicKeys:    []signatures.PublicKey{pk},
		},
		secretKey: sk,
	}

	coinAddress = newSpendableAddress.spendConditions.CoinAddress()
	w.spendableAddresses[coinAddress] = newSpendableAddress
	return
}

// RegisterTransaction implements the core.Wallet interface.
func (w *Wallet) RegisterTransaction(t *consensus.Transaction) (id string, err error) {
	w.Lock()
	defer w.Unlock()

	id = strconv.Itoa(w.transactionCounter)
	w.transactionCounter++
	w.transactions[id].transaction = t
	return
}

// FundTransaction implements the core.Wallet interface.
func (w *Wallet) FundTransaction(id string, amount consensus.Currency) error {
	w.Lock()
	defer w.Unlock()

	// Get the transaction.
	ot, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction of given id found")
	}
	t := ot.transaction

	// Get the set of outputs.
	spendableOutputs, total, err := w.findOutputs(amount)
	if err != nil {
		return err
	}

	// Create and add all of the inputs.
	for _, spendableOutput := range spendableOutputs {
		spendableAddress := w.spendableAddresses[spendableOutput.output.SpendHash]
		newInput := consensus.Input{
			OutputID:        spendableOutput.id,
			SpendConditions: spendableAddress.spendConditions,
		}
		ot.inputs = append(ot.inputs, len(t.Inputs))
		t.Inputs = append(t.Inputs, newInput)
	}

	// Add a refund output if needed.
	if total-amount > 0 {
		coinAddress, err := w.CoinAddress()
		if err != nil {
			return err
		}
		t.Outputs = append(
			t.Outputs,
			consensus.Output{
				Value:     total - amount,
				SpendHash: coinAddress,
			},
		)
	}
	return nil
}

// AddMinerFee implements the core.Wallet interface.
func (w *Wallet) AddMinerFee(id string, fee consensus.Currency) error {
	w.Lock()
	defer w.Unlock()

	to, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction found for given id")
	}

	to.transaction.MinerFees = append(to.transaction.MinerFees, fee)
	return nil
}

// AddOutput implements the core.Wallet interface.
func (w *Wallet) AddOutput(id string, o consensus.Output) error {
	w.Lock()
	defer w.Unlock()

	to, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction found for given id")
	}

	to.transaction.Outputs = append(to.transaction.Outputs, o)
	return nil
}

// AddTimelockedRefund implements the core.Wallet interface.
func (w *Wallet) AddTimelockedRefund(id string, amount consensus.Currency, release consensus.BlockHeight) (spendConditions consensus.SpendConditions, err error) {
	w.Lock()
	defer w.Unlock()

	// Get the transaction
	ot, exists := w.transactions[id]
	if !exists {
		err = errors.New("no transaction found for given id")
		return
	}
	t := ot.transaction

	// Get a frozen coin address.
	spendConditions, err = w.timelockedCoinAddress(release)
	if err != nil {
		return
	}

	// Add the output to the transaction
	output := consensus.Output{
		Value:     amount,
		SpendHash: spendConditions.CoinAddress(),
	}
	t.Outputs = append(t.Outputs, output)
	return
}

// AddFileContract implements the core.Wallet interface.
func (w *Wallet) AddFileContract(id string, fc consensus.FileContract) error {
	w.Lock()
	defer w.Unlock()

	to, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction found for given id")
	}

	to.transaction.FileContracts = append(to.transaction.FileContracts, fc)
	return nil
}

// AddStorageProof implements the core.Wallet interface.
func (w *Wallet) AddStorageProof(id string, sp consensus.StorageProof) error {
	w.Lock()
	defer w.Unlock()

	to, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction found for given id")
	}

	to.transaction.StorageProofs = append(to.transaction.StorageProofs, sp)
	return nil
}

// AddArbitraryData implements the core.Wallet interface.
//
// TODO: Change arbitrary data to a slice of strings.
func (w *Wallet) AddArbitraryData(id string, arb string) error {
	w.Lock()
	defer w.Unlock()

	to, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction found for given id")
	}

	to.transaction.ArbitraryData = arb
	return nil
}
<commit_msg>add func for SignTransaction<commit_after>package wallet

import (
	"errors"
	"fmt"
	"strconv"
	"sync"

	"github.com/NebulousLabs/Andromeda/consensus"
	"github.com/NebulousLabs/Andromeda/signatures"
)

// openTransaction is a type that the wallet uses to track a transaction as it
// adds inputs and other features.
type openTransaction struct {
	transaction *consensus.Transaction
	inputs      []int
}

// spendableOutput keeps track of an output, it's id, and whether or not it's
// been spent yet. Spendable indicates whether the output is available
// according to the blockchain, true if the output is unspent in the blockchain
// and false if the output is spent in the blockchain. The spentCounter
// indicates whether the output has been spent or not. If it's equal to the
// wallet's spent counter, then it has been spent since the previous reset.
type spendableOutput struct {
	spendable    bool
	spentCounter int
	id           consensus.OutputID
	output       *consensus.Output
}

// openOutput contains an output and the conditions needed to spend the output,
// including secret keys.
type spendableAddress struct {
	spendableOutputs map[consensus.OutputID]*spendableOutput
	spendConditions  consensus.SpendConditions
	secretKey        signatures.SecretKey
}

// Wallet holds your coins, manages privacy, outputs, ect. The balance reported
// ignores outputs you've already spent even if they haven't made it into the
// blockchain yet.
//
// TODO: Do not ignore refunds until they make it into a block (but later, leave it for now)
type Wallet struct {
	spentCounter       int
	spendableAddresses map[consensus.CoinAddress]*spendableAddress

	transactionCounter int
	transactions       map[string]*openTransaction

	sync.Mutex
}

// findOutputs returns a set of spendable outputs that add up to at least
// `amount` of coins, returning an error if it cannot. It also returns the
// `total`, which is the sum of all the outputs. It does not adjust the outputs
// in any way.
func (w *Wallet) findOutputs(amount consensus.Currency) (spendableOutputs []*spendableOutput, total consensus.Currency, err error) {
	if amount == consensus.Currency(0) {
		err = errors.New("cannot fund 0 coins") // should this be an error or nil?
		return
	}

	// Iterate through all outputs until enough coins have been assembled.
	for _, spendableAddress := range w.spendableAddresses {
		for _, spendableOutput := range spendableAddress.spendableOutputs {
			if !spendableOutput.spendable || spendableOutput.spentCounter == w.spentCounter {
				continue
			}
			total += spendableOutput.output.Value
			spendableOutputs = append(spendableOutputs, spendableOutput)

			// Break once
			if total >= amount {
				break
			}
		}
		// Break twice :)
		if total >= amount {
			break
		}
	}

	// Check that enough inputs were added.
	if total < amount {
		err = fmt.Errorf("insufficient funds, requested %v but only have %v", amount, total)
		return
	}

	return
}

// New creates an initializes a Wallet.
func New() (*Wallet, error) {
	return &Wallet{
		spendableAddresses: make(map[consensus.CoinAddress]*spendableAddress),
		transactions:       make(map[string]*openTransaction),
	}, nil
}

// Update implements the core.Wallet interface.
func (w *Wallet) Update(rewound []consensus.Block, applied []consensus.Block) error {
	w.Lock()
	defer w.Unlock()

	// Undo add the changes from blocks that have been rewound.
	for _, b := range rewound {
		for i := len(b.Transactions) - 1; i >= 0; i-- {
			// Mark all outputs that got created (sent to an address in our
			// control) as 'not spendable', because they no longer exist in
			// the blockchain.
			for j, output := range b.Transactions[i].Outputs {
				if spendableAddress, exists := w.spendableAddresses[output.SpendHash]; exists {
					id := b.Transactions[i].OutputID(j)
					if spendableOutput, exists := spendableAddress.spendableOutputs[id]; exists {
						spendableOutput.spendable = false
					} else {
						panic("output should exist")
					}
				}
			}

			// Mark all inputs that we control as 'spendable', because the
			// blockchain is no longer aware that they've been spent.
			for _, input := range b.Transactions[i].Inputs {
				coinAddress := input.SpendConditions.CoinAddress()
				if spendableAddress, exists := w.spendableAddresses[coinAddress]; exists {
					if spendableOutput, exists := spendableAddress.spendableOutputs[input.OutputID]; exists {
						spendableOutput.spendable = true
					} else {
						panic("output should exist")
					}
				}
			}
		}
	}

	// Update spendableOutputs which got spent, and find new outputs which we
	// know how to spend.
	for _, b := range applied {
		for _, t := range b.Transactions {
			// Mark all outputs that got consumed by the block as 'not
			// spendable'
			for _, input := range t.Inputs {
				coinAddress := input.SpendConditions.CoinAddress()
				if spendableAddress, exists := w.spendableAddresses[coinAddress]; exists {
					if spendableOutput, exists := spendableAddress.spendableOutputs[input.OutputID]; exists {
						spendableOutput.spendable = false
					} else {
						panic("output should exist")
					}
				}
			}

			// Mark all outputs that got created (sent to an address in our
			// control) as 'spendable'.
			for j, output := range t.Outputs {
				if spendableAddress, exists := w.spendableAddresses[output.SpendHash]; exists {
					id := t.OutputID(j)
					if spendOutput, exists := spendableAddress.spendableOutputs[id]; exists {
						spendOutput.spendable = true
					} else {
						spendableAddress.spendableOutputs[id] = &spendableOutput{
							spendable: true,
							id:        id,
							output:    &output,
						}
					}
				}
			}
		}
	}

	return nil
}

// Reset implements the core.Wallet interface.
func (w *Wallet) Reset() error {
	w.Lock()
	defer w.Unlock()
	w.spentCounter++
	return nil
}

// Balance implements the core.Wallet interface.
func (w *Wallet) Balance() (total consensus.Currency, err error) {
	w.Lock()
	defer w.Unlock()

	// Iterate through all outputs and tally them up.
	for _, spendableAddress := range w.spendableAddresses {
		for _, spendableOutput := range spendableAddress.spendableOutputs {
			if !spendableOutput.spendable || spendableOutput.spentCounter == w.spentCounter {
				continue
			}
			total += spendableOutput.output.Value
		}
	}

	return
}

// timelockedCoinAddress returns a CoinAddress with a timelock, as well as the
// conditions needed to spend it.
func (w *Wallet) timelockedCoinAddress(release consensus.BlockHeight) (spendConditions consensus.SpendConditions, err error) {
	sk, pk, err := signatures.GenerateKeyPair()
	if err != nil {
		return
	}

	spendConditions = consensus.SpendConditions{
		TimeLock:      release,
		NumSignatures: 1,
		PublicKeys:    []signatures.PublicKey{pk},
	}

	newSpendableAddress := &spendableAddress{
		spendableOutputs: make(map[consensus.OutputID]*spendableOutput),
		spendConditions:  spendConditions,
		secretKey:        sk,
	}

	coinAddress := spendConditions.CoinAddress()
	w.spendableAddresses[coinAddress] = newSpendableAddress
	return
}

// CoinAddress implements the core.Wallet interface.
func (w *Wallet) CoinAddress() (coinAddress consensus.CoinAddress, err error) {
	w.Lock()
	defer w.Unlock()

	sk, pk, err := signatures.GenerateKeyPair()
	if err != nil {
		return
	}

	newSpendableAddress := &spendableAddress{
		spendableOutputs: make(map[consensus.OutputID]*spendableOutput),
		spendConditions: consensus.SpendConditions{
			NumSignatures: 1,
			PublicKeys:    []signatures.PublicKey{pk},
		},
		secretKey: sk,
	}

	coinAddress = newSpendableAddress.spendConditions.CoinAddress()
	w.spendableAddresses[coinAddress] = newSpendableAddress
	return
}

// RegisterTransaction implements the core.Wallet interface.
func (w *Wallet) RegisterTransaction(t *consensus.Transaction) (id string, err error) {
	w.Lock()
	defer w.Unlock()

	id = strconv.Itoa(w.transactionCounter)
	w.transactionCounter++
	w.transactions[id].transaction = t
	return
}

// FundTransaction implements the core.Wallet interface.
func (w *Wallet) FundTransaction(id string, amount consensus.Currency) error {
	w.Lock()
	defer w.Unlock()

	// Get the transaction.
	ot, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction of given id found")
	}
	t := ot.transaction

	// Get the set of outputs.
	spendableOutputs, total, err := w.findOutputs(amount)
	if err != nil {
		return err
	}

	// Create and add all of the inputs.
	for _, spendableOutput := range spendableOutputs {
		spendableAddress := w.spendableAddresses[spendableOutput.output.SpendHash]
		newInput := consensus.Input{
			OutputID:        spendableOutput.id,
			SpendConditions: spendableAddress.spendConditions,
		}
		ot.inputs = append(ot.inputs, len(t.Inputs))
		t.Inputs = append(t.Inputs, newInput)
	}

	// Add a refund output if needed.
	if total-amount > 0 {
		coinAddress, err := w.CoinAddress()
		if err != nil {
			return err
		}
		t.Outputs = append(
			t.Outputs,
			consensus.Output{
				Value:     total - amount,
				SpendHash: coinAddress,
			},
		)
	}
	return nil
}

// AddMinerFee implements the core.Wallet interface.
func (w *Wallet) AddMinerFee(id string, fee consensus.Currency) error {
	w.Lock()
	defer w.Unlock()

	to, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction found for given id")
	}

	to.transaction.MinerFees = append(to.transaction.MinerFees, fee)
	return nil
}

// AddOutput implements the core.Wallet interface.
func (w *Wallet) AddOutput(id string, o consensus.Output) error {
	w.Lock()
	defer w.Unlock()

	to, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction found for given id")
	}

	to.transaction.Outputs = append(to.transaction.Outputs, o)
	return nil
}

// AddTimelockedRefund implements the core.Wallet interface.
func (w *Wallet) AddTimelockedRefund(id string, amount consensus.Currency, release consensus.BlockHeight) (spendConditions consensus.SpendConditions, err error) {
	w.Lock()
	defer w.Unlock()

	// Get the transaction
	ot, exists := w.transactions[id]
	if !exists {
		err = errors.New("no transaction found for given id")
		return
	}
	t := ot.transaction

	// Get a frozen coin address.
	spendConditions, err = w.timelockedCoinAddress(release)
	if err != nil {
		return
	}

	// Add the output to the transaction
	output := consensus.Output{
		Value:     amount,
		SpendHash: spendConditions.CoinAddress(),
	}
	t.Outputs = append(t.Outputs, output)
	return
}

// AddFileContract implements the core.Wallet interface.
func (w *Wallet) AddFileContract(id string, fc consensus.FileContract) error {
	w.Lock()
	defer w.Unlock()

	to, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction found for given id")
	}

	to.transaction.FileContracts = append(to.transaction.FileContracts, fc)
	return nil
}

// AddStorageProof implements the core.Wallet interface.
func (w *Wallet) AddStorageProof(id string, sp consensus.StorageProof) error {
	w.Lock()
	defer w.Unlock()

	to, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction found for given id")
	}

	to.transaction.StorageProofs = append(to.transaction.StorageProofs, sp)
	return nil
}

// AddArbitraryData implements the core.Wallet interface.
//
// TODO: Change arbitrary data to a slice of strings.
func (w *Wallet) AddArbitraryData(id string, arb string) error {
	w.Lock()
	defer w.Unlock()

	to, exists := w.transactions[id]
	if !exists {
		return errors.New("no transaction found for given id")
	}

	to.transaction.ArbitraryData = append(to.transaction.ArbitraryData, arb)
	return nil
}

// SignTransaction implements the core.Wallet interface.
func (w *Wallet) SignTransaction(id string, wholeTransaction bool) (transaction consensus.Transaction, err error) {
	w.Lock()
	defer w.Unlock()

	// Fetch the transaction.
	ot, exists := w.transactions[id]
	if !exists {
		err = errors.New("no transaction found for given id")
		return
	}
	transaction = *ot.transaction

	// Get the coveredfields struct.
	var coveredFields consensus.CoveredFields
	if wholeTransaction {
		coveredFields = consensus.CoveredFields{WholeTransaction: true}
	} else {
		// TODO: build a proper covered fields struct.
	}

	// For each input in the transaction that we added, provide a signature.
	for _, inputIndex := range ot.inputs {
		input := transaction.Inputs[inputIndex]
		sig := consensus.TransactionSignature{
			InputID:        input.OutputID,
			CoveredFields:  coveredFields,
			PublicKeyIndex: 0,
		}
		transaction.Signatures = append(transaction.Signatures, sig)

		// Hash the transaction according to the covered fields and produce the
		// cryptographic signature.
		secKey := w.spendableAddresses[input.SpendConditions.CoinAddress()].secretKey
		sigHash := transaction.SigHash(len(transaction.Signatures) - 1)
		transaction.Signatures[len(transaction.Signatures)-1].Signature, err = signatures.SignBytes(sigHash[:], secKey)
	}
	return
}
<|endoftext|>


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

// The grammar package randomly generates sentences based on a user-supplied context-free grammar.
package grammar

import (
	"bufio"
	"errors"
	"fmt"
	"github.com/joshlf13/errlist"
	"io"
	"math/rand"
	"strings"
	"time"
)

// A Grammar object contains the definition for a single
// context-free grammar, and can randomly generate
// sentences based upon that grammar structure.
type Grammar struct {
	initialized bool
	head        *part
	parts       map[string]*part
}

// Returns a Grammar object initialized with the
// grammar definition read from rdr. Additionaly,
// an error is returned if the definition is
// ill-formatted or unavailable for reading.
// In this case, a nil *Grammar is returned
func New(rdr io.Reader) (*Grammar, error) {
	g := new(Grammar)
	err := g.init(rdr)
	if err != nil {
		return nil, err
	}
	return g, nil
}

// Generate a random sentence based upon the
// grammar structure of g, and write it to w
func (g *Grammar) Speak(w io.Writer) error {
	if g.initialized {
		return g.head.speak(w)
	}
	return errors.New("Uninitialized Grammar")
}

func (g *Grammar) init(rdr io.Reader) error {
	r := bufio.NewReader(rdr)

	// Handle first line
	for {
		b, ip, err := r.ReadLine()
		if err != nil {
			return fmt.Errorf("Error reading input: %v", err)
		} else if ip {
			for ip {
				var _b []byte
				_b, ip, err = r.ReadLine()
				if err != nil {
					return fmt.Errorf("Error reading input: %v", err)
				}
				b = append(b, _b...)
			}
		}

		strs := strings.Fields(string(b))
		length := len(strs)
		if length < 1 {
			continue
		}

		g.head = new(part)
		g.parts = make(map[string]*part)

		soln := make([]*part, length)
		for i, s := range strs {
			p, ok := g.parts[s]
			if !ok {
				g.parts[s] = new(part)
				p = g.parts[s]
				p.init(s)
			}
			soln[i] = p
		}
		g.head.addSoln(soln)
		break
	}

	var errs *errlist.Errlist

	// Handle second line on
	for {
		b, ip, err := r.ReadLine()
		if err != nil {
			if err.Error() == "EOF" {
				break
			} else {
				return fmt.Errorf("Error reading input: %v", err)
			}
		} else if ip {
			for ip {
				var _b []byte
				_b, ip, err = r.ReadLine()
				if err != nil {
					return fmt.Errorf("Error reading input: %v", err)
				}
				b = append(b, _b...)
			}
		}

		strs := strings.Fields(string(b))
		length := len(strs)
		if length < 1 {
			continue
		} else if length < 2 {
			continue
		}

		err = g.addRule(strs[0], strs[1:])
		if err != nil {
			if errs == nil {
				errs = errlist.NewString("Error adding definition: " + err.Error())
			} else {
				errs.AddString("Error adding definition: " + err.Error())
			}
		}
	}
	g.initialized = true

	// Seems redundant, but avoids the issue that
	// an interface with a concrete type and nil
	// value doesn't evaluate to being equal to nil
	if errs == nil {
		return nil
	}
	return errs
}

func (g *Grammar) addRule(prt string, definition []string) error {
	head, ok := g.parts[prt]
	if !ok {
		return fmt.Errorf("Unknown part: %v", prt)
	}

	soln := make([]*part, len(definition))
	for i, d := range definition {
		p, ok := g.parts[d]
		if !ok {
			g.parts[d] = new(part)
			p = g.parts[d]
			p.init(d)
		}
		soln[i] = p
	}

	head.addSoln(soln)
	return nil
}

func init() {
	rand.Seed(time.Now().UnixNano())
}
<commit_msg>Changed the mysterious if length < 1 { 	continue } else if length < 2 { 	continue } to the more obvious<commit_after>// Copyright 2012 The Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The grammar package randomly generates sentences based on a user-supplied context-free grammar.
package grammar

import (
	"bufio"
	"errors"
	"fmt"
	"github.com/joshlf13/errlist"
	"io"
	"math/rand"
	"strings"
	"time"
)

// A Grammar object contains the definition for a single
// context-free grammar, and can randomly generate
// sentences based upon that grammar structure.
type Grammar struct {
	initialized bool
	head        *part
	parts       map[string]*part
}

// Returns a Grammar object initialized with the
// grammar definition read from rdr. Additionaly,
// an error is returned if the definition is
// ill-formatted or unavailable for reading.
// In this case, a nil *Grammar is returned
func New(rdr io.Reader) (*Grammar, error) {
	g := new(Grammar)
	err := g.init(rdr)
	if err != nil {
		return nil, err
	}
	return g, nil
}

// Generate a random sentence based upon the
// grammar structure of g, and write it to w
func (g *Grammar) Speak(w io.Writer) error {
	if g.initialized {
		return g.head.speak(w)
	}
	return errors.New("Uninitialized Grammar")
}

func (g *Grammar) init(rdr io.Reader) error {
	r := bufio.NewReader(rdr)

	// Handle first line
	for {
		b, ip, err := r.ReadLine()
		if err != nil {
			return fmt.Errorf("Error reading input: %v", err)
		} else if ip {
			for ip {
				var _b []byte
				_b, ip, err = r.ReadLine()
				if err != nil {
					return fmt.Errorf("Error reading input: %v", err)
				}
				b = append(b, _b...)
			}
		}

		strs := strings.Fields(string(b))
		length := len(strs)
		if length < 1 {
			continue
		}

		g.head = new(part)
		g.parts = make(map[string]*part)

		soln := make([]*part, length)
		for i, s := range strs {
			p, ok := g.parts[s]
			if !ok {
				g.parts[s] = new(part)
				p = g.parts[s]
				p.init(s)
			}
			soln[i] = p
		}
		g.head.addSoln(soln)
		break
	}

	var errs *errlist.Errlist

	// Handle second line on
	for {
		b, ip, err := r.ReadLine()
		if err != nil {
			if err.Error() == "EOF" {
				break
			} else {
				return fmt.Errorf("Error reading input: %v", err)
			}
		} else if ip {
			for ip {
				var _b []byte
				_b, ip, err = r.ReadLine()
				if err != nil {
					return fmt.Errorf("Error reading input: %v", err)
				}
				b = append(b, _b...)
			}
		}

		strs := strings.Fields(string(b))
		length := len(strs)
		if length < 2 {
			continue
		}

		err = g.addRule(strs[0], strs[1:])
		if err != nil {
			if errs == nil {
				errs = errlist.NewString("Error adding definition: " + err.Error())
			} else {
				errs.AddString("Error adding definition: " + err.Error())
			}
		}
	}
	g.initialized = true

	// Seems redundant, but avoids the issue that
	// an interface with a concrete type and nil
	// value doesn't evaluate to being equal to nil
	if errs == nil {
		return nil
	}
	return errs
}

func (g *Grammar) addRule(prt string, definition []string) error {
	head, ok := g.parts[prt]
	if !ok {
		return fmt.Errorf("Unknown part: %v", prt)
	}

	soln := make([]*part, len(definition))
	for i, d := range definition {
		p, ok := g.parts[d]
		if !ok {
			g.parts[d] = new(part)
			p = g.parts[d]
			p.init(d)
		}
		soln[i] = p
	}

	head.addSoln(soln)
	return nil
}

func init() {
	rand.Seed(time.Now().UnixNano())
}
<|endoftext|>


<commit_before>package DocumentDao

import (
	"os"
	"encoding/json"
	"io/ioutil"
	"log"
	"sync"
	"runtime"
)

func init() {
	runtime.GOMAXPROCS(2)
}

type DaoInstance struct{}

func (dao DaoInstance) Get(id string) (map[string]interface{}, error) {
	log.Println("Starting get from file system")

	var contents []byte
	var err error

	if contents, err = ioutil.ReadFile("jsons/" + id + ".json"); err != nil {
		log.Println("Error reading file")
		return nil, err
	}

	var out map[string]interface{}

	if err = json.Unmarshal(contents, &out); err != nil {
		log.Println("Error unmashalling file contents")
		log.Print("Contents were: ")
		log.Println(contents)
		return nil, err
	}

	log.Println("Get from file system ended normally")

	return out, nil
}

func (dao DaoInstance) Search() ([]map[string]interface{}, error) {
	log.Println("Starting search")

	var out = []map[string]interface{}{}

	var files []os.FileInfo
	var err error

	if files, err = ioutil.ReadDir("jsons/"); err != nil {
		log.Println("Error reading directory")
		return nil, err
	}

	wg := sync.WaitGroup{}

	for _, value := range files {
		wg.Add(1)
		go func (value os.FileInfo) {
			defer wg.Done()

			log.Println("Trying to read file ", value.Name())

			var contents []byte
			if contents, err = ioutil.ReadFile("jsons/" + value.Name()); err != nil {
				log.Println("Error reading file", value.Name())
				//return nil, err
			}

			var current map[string]interface{}
			if err = json.Unmarshal(contents, &current); err != nil {
				log.Println("Error unmarshalling file", value.Name())
				//return nil, err
			}

			out = append(out, current)

			log.Println("File ", value.Name(), " was read normally")
		}(value)
	}

	wg.Wait()

	log.Println("Search ended normally")
	return out, nil
}

func (dao DaoInstance) Create(id string, doc map[string]interface{}) (map[string]interface{}, error) {
	var file *os.File
	var err error

	if file, err = os.Create("jsons/" + id + ".json"); err != nil {
		return nil, err
	}

	var jsonBytes []byte

	if jsonBytes, err = json.Marshal(doc); err != nil {
		return nil, err
	}

	if _, err = file.Write(jsonBytes); err != nil {
		return nil, err;
	}

	return doc, nil
}

func New() *DaoInstance {
	return new(DaoInstance)
}<commit_msg>Showing use of channels while reading from files.<commit_after>package DocumentDao

import (
	"os"
	"encoding/json"
	"io/ioutil"
	"log"
	"runtime"
)

func init() {
	runtime.GOMAXPROCS(2)
}

type DaoInstance struct{}

func (dao DaoInstance) Get(id string) (map[string]interface{}, error) {
	log.Println("Starting get from file system")

	var contents []byte
	var err error

	if contents, err = ioutil.ReadFile("jsons/" + id + ".json"); err != nil {
		log.Println("Error reading file")
		return nil, err
	}

	var out map[string]interface{}

	if err = json.Unmarshal(contents, &out); err != nil {
		log.Println("Error unmashalling file contents")
		log.Print("Contents were: ")
		log.Println(contents)
		return nil, err
	}

	log.Println("Get from file system ended normally")

	return out, nil
}

func (dao DaoInstance) Search() ([]map[string]interface{}, error) {
	log.Println("Starting search")

	var out = []map[string]interface{}{}

	var files []os.FileInfo
	var err error

	if files, err = ioutil.ReadDir("jsons/"); err != nil {
		log.Println("Error reading directory")
		return nil, err
	}

	size := len(files)

	channel := make(chan map[string]interface{})

	for _, value := range files {
		go func (value os.FileInfo, channel chan map[string]interface{}) {
			log.Println("Trying to read file ", value.Name())

			var contents []byte
			if contents, err = ioutil.ReadFile("jsons/" + value.Name()); err != nil {
				log.Println("Error reading file", value.Name())
			}

			var current map[string]interface{}
			if err = json.Unmarshal(contents, &current); err != nil {
				log.Println("Error unmarshalling file", value.Name())
			}

			channel <- current

			log.Println("File ", value.Name(), " was read normally")
		}(value, channel)
	}

	for i := 0; i < size; i ++ {
		next := <- channel
		out = append(out, next)
	}

	log.Println("Search ended normally")
	return out, nil
}

func (dao DaoInstance) Create(id string, doc map[string]interface{}) (map[string]interface{}, error) {
	var file *os.File
	var err error

	if file, err = os.Create("jsons/" + id + ".json"); err != nil {
		return nil, err
	}

	var jsonBytes []byte

	if jsonBytes, err = json.Marshal(doc); err != nil {
		return nil, err
	}

	if _, err = file.Write(jsonBytes); err != nil {
		return nil, err;
	}

	return doc, nil
}

func New() *DaoInstance {
	return new(DaoInstance)
}<|endoftext|>


<commit_before>package lib

import (
	"crypto/rand"
	"encoding/base32"
	"encoding/base64"
	"fmt"
	"io"
	"os"
	"strings"
	"syscall"
	"time"
	"golang.org/x/sys/unix"
)

func generateID(l int) string {
	const (
		maxretries = 9
		backoff    = time.Millisecond * 10
	)

	var (
		totalBackoff time.Duration
		count        int
		retries      int
		size         = (l*5 + 7) / 8
		u            = make([]byte, size)
	)

	for {
		b := time.Duration(retries) * backoff
		time.Sleep(b)
		totalBackoff += b

		n, err := io.ReadFull(rand.Reader, u[count:])
		if err != nil {
			if retryOnError(err) && retries < maxretries {
				count += n
				retries++
				fmt.Printf("error generating version 4 uuid, retrying: %v", err)
				continue
			}

			panic(fmt.Errorf("error reading random number generator, retried for %v: %v", totalBackoff.String(), err))
		}

		break
	}

	s := base32.StdEncoding.EncodeToString(u)

	return s[:l]
}

// retryOnError tries to detect whether or not retrying would be fruitful.
func retryOnError(err error) bool {
	switch err := err.(type) {
	case *os.PathError:
		return retryOnError(err.Err) // unpack the target error
	case syscall.Errno:
		if err == unix.EPERM {
			// EPERM represents an entropy pool exhaustion, a condition under
			// which we backoff and retry.
			return true
		}
	}

	return false
}

func generateConfigFileName(digest string) (fname string, err error) {
	reader := strings.NewReader(digest)
	for reader.Len() > 0 {
		ch, size, err := reader.ReadRune()
		if err != nil || size != 1 {
			break
		}
		if ch != '.' && !(ch >= '0' && ch <= '9') && !(ch >= 'a' && ch <= 'z') {
			break
		}
	}
	if reader.Len() > 0 {
		fname = "=" + base64.StdEncoding.EncodeToString([]byte(digest))
	}
	return
}
<commit_msg>Use google uuid lib to generate link dir name<commit_after>package lib

import (
	"encoding/base32"
	"encoding/base64"
	"strings"

	"github.com/google/uuid"
)

//generates the file name for link dir in podman store
func generateID(l int) string {
	id := uuid.New()
	bytes, _ := id.MarshalText()
	s := base32.StdEncoding.EncodeToString(bytes)

	return s[:l]
}

//generates the file name for config file (compliant with libpod) in podman store.
func generateConfigFileName(digest string) (fname string, err error) {
	reader := strings.NewReader(digest)
	for reader.Len() > 0 {
		ch, size, err := reader.ReadRune()
		if err != nil || size != 1 {
			break
		}
		if ch != '.' && !(ch >= '0' && ch <= '9') && !(ch >= 'a' && ch <= 'z') {
			break
		}
	}
	if reader.Len() > 0 {
		fname = "=" + base64.StdEncoding.EncodeToString([]byte(digest))
	}
	return
}
<|endoftext|>