<commit_before>package channelnotifier

import (
	"github.com/btcsuite/btclog"
	"github.com/lightningnetwork/lnd/build"
)

// log is a logger that is initialized with no output filters.  This means the
// package will not perform any logging by default until the caller requests
// it.
var log btclog.Logger

// The default amount of logging is none.
func init() {
	UseLogger(build.NewSubLogger("CHNF", nil))
}

// DisableLog disables all library log output.  Logging output is disabled by
// default until UseLogger is called.
func DisableLog() {
	UseLogger(btclog.Disabled)
}

// UseLogger uses a specified Logger to output package logging info.  This
// should be used in preference to SetLogWriter if the caller is also using
// btclog.
func UseLogger(logger btclog.Logger) {
	log = logger
}

// logClosure is used to provide a closure over expensive logging operations so
// don't have to be performed when the logging level doesn't warrant it.
type logClosure func() string // nolint:unused

// String invokes the underlying function and returns the result.
func (c logClosure) String() string {
	return c()
}

// newLogClosure returns a new closure over a function that returns a string
// which itself provides a Stringer interface so that it can be used with the
// logging system.
func newLogClosure(c func() string) logClosure { // nolint:unused
	return logClosure(c)
}
<commit_msg>channelnotifier: remove dead logging code<commit_after>package channelnotifier

import (
	"github.com/btcsuite/btclog"
	"github.com/lightningnetwork/lnd/build"
)

// log is a logger that is initialized with no output filters.  This means the
// package will not perform any logging by default until the caller requests
// it.
var log btclog.Logger

// The default amount of logging is none.
func init() {
	UseLogger(build.NewSubLogger("CHNF", nil))
}

// DisableLog disables all library log output.  Logging output is disabled by
// default until UseLogger is called.
func DisableLog() {
	UseLogger(btclog.Disabled)
}

// UseLogger uses a specified Logger to output package logging info.  This
// should be used in preference to SetLogWriter if the caller is also using
// btclog.
func UseLogger(logger btclog.Logger) {
	log = logger
}
<|endoftext|>


<commit_before>// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// 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 testlist provides utilities for handling test lists.
package testlist

import (
	"bytes"
	"crypto/sha1"
	"encoding/gob"
	"encoding/hex"
	"encoding/json"
	"io/ioutil"
	"path/filepath"
	"sort"
	"strings"

	"../cause"
)

// API is an enumerator of graphics APIs.
type API string

// Graphics APIs.
const (
	EGL    = API("egl")
	GLES2  = API("gles2")
	GLES3  = API("gles3")
	Vulkan = API("vulkan")
)

// Group is a list of tests to be run for a single API.
type Group struct {
	Name  string
	File  string
	API   API
	Tests []string
}

// Load loads the test list file and appends all tests to the Group.
func (g *Group) Load() error {
	tests, err := ioutil.ReadFile(g.File)
	if err != nil {
		return cause.Wrap(err, "Couldn't read '%s'", tests)
	}
	for _, line := range strings.Split(string(tests), "\n") {
		line = strings.TrimSpace(line)
		if line != "" && !strings.HasPrefix(line, "#") {
			g.Tests = append(g.Tests, line)
		}
	}
	sort.Strings(g.Tests)
	return nil
}

// Filter returns a new Group that contains only tests that match the predicate.
func (g Group) Filter(pred func(string) bool) Group {
	out := Group{
		Name: g.Name,
		File: g.File,
		API:  g.API,
	}
	for _, test := range g.Tests {
		if pred(test) {
			out.Tests = append(out.Tests, test)
		}
	}
	return out
}

// Limit returns a new Group that contains a maximum of limit tests.
func (g Group) Limit(limit int) Group {
	out := Group{
		Name:  g.Name,
		File:  g.File,
		API:   g.API,
		Tests: g.Tests,
	}
	if len(g.Tests) > limit {
		out.Tests = g.Tests[:limit]
	}
	return out
}

// Lists is the full list of tests to be run.
type Lists []Group

// Filter returns a new Lists that contains only tests that match the predicate.
func (l Lists) Filter(pred func(string) bool) Lists {
	out := Lists{}
	for _, group := range l {
		filtered := group.Filter(pred)
		if len(filtered.Tests) > 0 {
			out = append(out, filtered)
		}
	}
	return out
}

// Hash returns a SHA1 hash of the set of tests.
func (l Lists) Hash() string {
	h := sha1.New()
	if err := gob.NewEncoder(h).Encode(l); err != nil {
		panic(cause.Wrap(err, "Could not encode testlist to produce hash"))
	}
	return hex.EncodeToString(h.Sum(nil))
}

// Load loads the test list json file and returns the full set of tests.
func Load(root, jsonPath string) (Lists, error) {
	root, err := filepath.Abs(root)
	if err != nil {
		return nil, cause.Wrap(err, "Couldn't get absolute path of '%s'", root)
	}

	jsonPath, err = filepath.Abs(jsonPath)
	if err != nil {
		return nil, cause.Wrap(err, "Couldn't get absolute path of '%s'", jsonPath)
	}

	i, err := ioutil.ReadFile(jsonPath)
	if err != nil {
		return nil, cause.Wrap(err, "Couldn't read test list from '%s'", jsonPath)
	}

	var jsonGroups []struct {
		Name     string
		API      string
		TestFile string `json:"tests"`
	}
	if err := json.NewDecoder(bytes.NewReader(i)).Decode(&jsonGroups); err != nil {
		return nil, cause.Wrap(err, "Couldn't parse '%s'", jsonPath)
	}

	dir := filepath.Dir(jsonPath)

	out := make(Lists, len(jsonGroups))
	for i, jsonGroup := range jsonGroups {
		group := Group{
			Name: jsonGroup.Name,
			File: filepath.Join(dir, jsonGroup.TestFile),
			API:  API(jsonGroup.API),
		}
		if err := group.Load(); err != nil {
			return nil, err
		}

		// Make the path relative before displaying it to the world.
		relPath, err := filepath.Rel(root, group.File)
		if err != nil {
			return nil, cause.Wrap(err, "Couldn't get relative path for '%s'", group.File)
		}
		group.File = relPath

		out[i] = group
	}

	return out, nil
}

// Status is an enumerator of test results.
type Status string

const (
	// Pass is the status of a successful test.
	Pass = Status("PASS")
	// Fail is the status of a failed test.
	Fail = Status("FAIL")
	// Timeout is the status of a test that failed to complete in the alloted
	// time.
	Timeout = Status("TIMEOUT")
	// Crash is the status of a test that crashed.
	Crash = Status("CRASH")
	// Unimplemented is the status of a test that failed with UNIMPLEMENTED().
	Unimplemented = Status("UNIMPLEMENTED")
	// Unsupported is the status of a test that failed with UNSUPPORTED().
	Unsupported = Status("UNSUPPORTED")
	// Unreachable is the status of a test that failed with UNREACHABLE().
	Unreachable = Status("UNREACHABLE")
	// Assert is the status of a test that failed with ASSERT() or ASSERT_MSG().
	Assert = Status("ASSERT")
	// Abort is the status of a test that failed with ABORT().
	Abort = Status("ABORT")
	// NotSupported is the status of a test feature not supported by the driver.
	NotSupported = Status("NOT_SUPPORTED")
	// CompatibilityWarning is the status passing test with a warning.
	CompatibilityWarning = Status("COMPATIBILITY_WARNING")
	// QualityWarning is the status passing test with a warning.
	QualityWarning = Status("QUALITY_WARNING")
	// InternalError is the status of a test that failed on an API usage error.
	InternalError = Status("INTERNAL_ERROR")
)

// Statuses is the full list of status types
var Statuses = []Status{
	Pass,
	Fail,
	Timeout,
	Crash,
	Unimplemented,
	Unsupported,
	Unreachable,
	Assert,
	Abort,
	NotSupported,
	CompatibilityWarning,
	QualityWarning,
	InternalError,
}

// Failing returns true if the task status requires fixing.
func (s Status) Failing() bool {
	switch s {
	case Fail, Timeout, Crash, Unimplemented, Unreachable, Assert, Abort, InternalError:
		return true
	case Unsupported:
		// This may seem surprising that this should be a failure, however these
		// should not be reached, as dEQP should not be using features that are
		// not advertised.
		return true
	default:
		return false
	}
}

// Passing returns true if the task status is considered a pass.
func (s Status) Passing() bool {
	switch s {
	case Pass, CompatibilityWarning, QualityWarning:
		return true
	default:
		return false
	}
}

// FilePathWithStatus returns the path to the test list file with the status
// appended before the file extension.
func FilePathWithStatus(listPath string, status Status) string {
	ext := filepath.Ext(listPath)
	name := listPath[:len(listPath)-len(ext)]
	return name + "-" + string(status) + ext
}
<commit_msg>Regres: Recursively load chunked mustpass lists<commit_after>// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// 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 testlist provides utilities for handling test lists.
package testlist

import (
	"bytes"
	"crypto/sha1"
	"encoding/gob"
	"encoding/hex"
	"encoding/json"
	"io/ioutil"
	"path/filepath"
	"sort"
	"strings"

	"../cause"
)

// API is an enumerator of graphics APIs.
type API string

// Graphics APIs.
const (
	EGL    = API("egl")
	GLES2  = API("gles2")
	GLES3  = API("gles3")
	Vulkan = API("vulkan")
)

// Group is a list of tests to be run for a single API.
type Group struct {
	Name  string
	File  string
	API   API
	Tests []string
}

// Load loads the test list file and appends all tests to the Group.
func (g *Group) Load() error {
	return g.LoadFile(g.File)
}

func (g *Group) LoadFile(file string) error {
	dir, _ := filepath.Split(file)
	tests, err := ioutil.ReadFile(file)
	if err != nil {
		return cause.Wrap(err, "Couldn't read '%s'", file)
	}
	for _, line := range strings.Split(string(tests), "\n") {
		line = strings.TrimSpace(line)
		// The test list file can contain references to other .txt files
		// containing the individual tests.
		if strings.HasSuffix(line, ".txt") {
			g.LoadFile(filepath.Join(dir, line))
		} else if line != "" && !strings.HasPrefix(line, "#") {
			g.Tests = append(g.Tests, line)
		}
	}
	sort.Strings(g.Tests)
	return nil
}

// Filter returns a new Group that contains only tests that match the predicate.
func (g Group) Filter(pred func(string) bool) Group {
	out := Group{
		Name: g.Name,
		File: g.File,
		API:  g.API,
	}
	for _, test := range g.Tests {
		if pred(test) {
			out.Tests = append(out.Tests, test)
		}
	}
	return out
}

// Limit returns a new Group that contains a maximum of limit tests.
func (g Group) Limit(limit int) Group {
	out := Group{
		Name:  g.Name,
		File:  g.File,
		API:   g.API,
		Tests: g.Tests,
	}
	if len(g.Tests) > limit {
		out.Tests = g.Tests[:limit]
	}
	return out
}

// Lists is the full list of tests to be run.
type Lists []Group

// Filter returns a new Lists that contains only tests that match the predicate.
func (l Lists) Filter(pred func(string) bool) Lists {
	out := Lists{}
	for _, group := range l {
		filtered := group.Filter(pred)
		if len(filtered.Tests) > 0 {
			out = append(out, filtered)
		}
	}
	return out
}

// Hash returns a SHA1 hash of the set of tests.
func (l Lists) Hash() string {
	h := sha1.New()
	if err := gob.NewEncoder(h).Encode(l); err != nil {
		panic(cause.Wrap(err, "Could not encode testlist to produce hash"))
	}
	return hex.EncodeToString(h.Sum(nil))
}

// Load loads the test list json file and returns the full set of tests.
func Load(root, jsonPath string) (Lists, error) {
	root, err := filepath.Abs(root)
	if err != nil {
		return nil, cause.Wrap(err, "Couldn't get absolute path of '%s'", root)
	}

	jsonPath, err = filepath.Abs(jsonPath)
	if err != nil {
		return nil, cause.Wrap(err, "Couldn't get absolute path of '%s'", jsonPath)
	}

	i, err := ioutil.ReadFile(jsonPath)
	if err != nil {
		return nil, cause.Wrap(err, "Couldn't read test list from '%s'", jsonPath)
	}

	var jsonGroups []struct {
		Name     string
		API      string
		TestFile string `json:"tests"`
	}
	if err := json.NewDecoder(bytes.NewReader(i)).Decode(&jsonGroups); err != nil {
		return nil, cause.Wrap(err, "Couldn't parse '%s'", jsonPath)
	}

	dir := filepath.Dir(jsonPath)

	out := make(Lists, len(jsonGroups))
	for i, jsonGroup := range jsonGroups {
		group := Group{
			Name: jsonGroup.Name,
			File: filepath.Join(dir, jsonGroup.TestFile),
			API:  API(jsonGroup.API),
		}
		if err := group.Load(); err != nil {
			return nil, err
		}

		// Make the path relative before displaying it to the world.
		relPath, err := filepath.Rel(root, group.File)
		if err != nil {
			return nil, cause.Wrap(err, "Couldn't get relative path for '%s'", group.File)
		}
		group.File = relPath

		out[i] = group
	}

	return out, nil
}

// Status is an enumerator of test results.
type Status string

const (
	// Pass is the status of a successful test.
	Pass = Status("PASS")
	// Fail is the status of a failed test.
	Fail = Status("FAIL")
	// Timeout is the status of a test that failed to complete in the alloted
	// time.
	Timeout = Status("TIMEOUT")
	// Crash is the status of a test that crashed.
	Crash = Status("CRASH")
	// Unimplemented is the status of a test that failed with UNIMPLEMENTED().
	Unimplemented = Status("UNIMPLEMENTED")
	// Unsupported is the status of a test that failed with UNSUPPORTED().
	Unsupported = Status("UNSUPPORTED")
	// Unreachable is the status of a test that failed with UNREACHABLE().
	Unreachable = Status("UNREACHABLE")
	// Assert is the status of a test that failed with ASSERT() or ASSERT_MSG().
	Assert = Status("ASSERT")
	// Abort is the status of a test that failed with ABORT().
	Abort = Status("ABORT")
	// NotSupported is the status of a test feature not supported by the driver.
	NotSupported = Status("NOT_SUPPORTED")
	// CompatibilityWarning is the status passing test with a warning.
	CompatibilityWarning = Status("COMPATIBILITY_WARNING")
	// QualityWarning is the status passing test with a warning.
	QualityWarning = Status("QUALITY_WARNING")
	// InternalError is the status of a test that failed on an API usage error.
	InternalError = Status("INTERNAL_ERROR")
)

// Statuses is the full list of status types
var Statuses = []Status{
	Pass,
	Fail,
	Timeout,
	Crash,
	Unimplemented,
	Unsupported,
	Unreachable,
	Assert,
	Abort,
	NotSupported,
	CompatibilityWarning,
	QualityWarning,
	InternalError,
}

// Failing returns true if the task status requires fixing.
func (s Status) Failing() bool {
	switch s {
	case Fail, Timeout, Crash, Unimplemented, Unreachable, Assert, Abort, InternalError:
		return true
	case Unsupported:
		// This may seem surprising that this should be a failure, however these
		// should not be reached, as dEQP should not be using features that are
		// not advertised.
		return true
	default:
		return false
	}
}

// Passing returns true if the task status is considered a pass.
func (s Status) Passing() bool {
	switch s {
	case Pass, CompatibilityWarning, QualityWarning:
		return true
	default:
		return false
	}
}

// FilePathWithStatus returns the path to the test list file with the status
// appended before the file extension.
func FilePathWithStatus(listPath string, status Status) string {
	ext := filepath.Ext(listPath)
	name := listPath[:len(listPath)-len(ext)]
	return name + "-" + string(status) + ext
}
<|endoftext|>


<commit_before>// Copyright © 2017 Aqua Security Software Ltd. <info@aquasec.com>
//
// 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 check

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

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
	"gopkg.in/yaml.v2"
)

const cfgDir = "../cfg/"

type mockRunner struct {
	mock.Mock
}

func (m *mockRunner) Run(c *Check) State {
	args := m.Called(c)
	return args.Get(0).(State)
}

// validate that the files we're shipping are valid YAML
func TestYamlFiles(t *testing.T) {
	err := filepath.Walk(cfgDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			t.Fatalf("failure accessing path %q: %v\n", path, err)
		}
		if !info.IsDir() {
			t.Logf("reading file: %s", path)
			in, err := ioutil.ReadFile(path)
			if err != nil {
				t.Fatalf("error opening file %s: %v", path, err)
			}

			c := new(Controls)
			err = yaml.Unmarshal(in, c)
			if err == nil {
				t.Logf("YAML file successfully unmarshalled: %s", path)
			} else {
				t.Fatalf("failed to load YAML from %s: %v", path, err)
			}
		}
		return nil
	})
	if err != nil {
		t.Fatalf("failure walking cfg dir: %v\n", err)
	}
}

func TestNewControls(t *testing.T) {

	t.Run("Should return error when node type is not specified", func(t *testing.T) {
		// given
		in := []byte(`
---
controls:
type: # not specified
groups:
`)
		// when
		_, err := NewControls(MASTER, in)
		// then
		assert.EqualError(t, err, "non-master controls file specified")
	})

	t.Run("Should return error when input YAML is invalid", func(t *testing.T) {
		// given
		in := []byte("BOOM")
		// when
		_, err := NewControls(MASTER, in)
		// then
		assert.EqualError(t, err, "failed to unmarshal YAML: yaml: unmarshal errors:\n  line 1: cannot unmarshal !!str `BOOM` into check.Controls")
	})

}

func TestControls_RunChecks(t *testing.T) {

	t.Run("Should run checks matching the filter and update summaries", func(t *testing.T) {
		// given
		runner := new(mockRunner)
		// and
		in := []byte(`
---
type: "master"
groups:
- id: G1
  checks:
    - id: G1/C1
- id: G2
  checks:
    - id: G2/C1
`)
		// and
		controls, _ := NewControls(MASTER, in)
		// and
		runner.On("Run", controls.Groups[0].Checks[0]).Return(PASS)
		runner.On("Run", controls.Groups[1].Checks[0]).Return(FAIL)
		// and
		var runAll Predicate = func(group *Group, c *Check) bool {
			return true
		}
		// when
		controls.RunChecks(runner, runAll)
		// then
		assert.Equal(t, 2, len(controls.Groups))
		// and
		G1 := controls.Groups[0]
		assert.Equal(t, "G1", G1.ID)
		assert.Equal(t, "G1/C1", G1.Checks[0].ID)
		assertEqualGroupSummary(t, 1, 0, 0, 0, G1)
		// and
		G2 := controls.Groups[1]
		assert.Equal(t, "G2", G2.ID)
		assert.Equal(t, "G2/C1", G2.Checks[0].ID)
		assertEqualGroupSummary(t, 0, 1, 0, 0, G2)
		// and
		assert.Equal(t, 1, controls.Summary.Pass)
		assert.Equal(t, 1, controls.Summary.Fail)
		assert.Equal(t, 0, controls.Summary.Info)
		assert.Equal(t, 0, controls.Summary.Warn)
		// and
		runner.AssertExpectations(t)
	})

}

func assertEqualGroupSummary(t *testing.T, pass, fail, info, warn int, actual *Group) {
	t.Helper()
	assert.Equal(t, pass, actual.Pass)
	assert.Equal(t, fail, actual.Fail)
	assert.Equal(t, info, actual.Info)
	assert.Equal(t, warn, actual.Warn)
}
<commit_msg>Update copyright date<commit_after>// Copyright © 2017-2019 Aqua Security Software Ltd. <info@aquasec.com>
//
// 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 check

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

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
	"gopkg.in/yaml.v2"
)

const cfgDir = "../cfg/"

type mockRunner struct {
	mock.Mock
}

func (m *mockRunner) Run(c *Check) State {
	args := m.Called(c)
	return args.Get(0).(State)
}

// validate that the files we're shipping are valid YAML
func TestYamlFiles(t *testing.T) {
	err := filepath.Walk(cfgDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			t.Fatalf("failure accessing path %q: %v\n", path, err)
		}
		if !info.IsDir() {
			t.Logf("reading file: %s", path)
			in, err := ioutil.ReadFile(path)
			if err != nil {
				t.Fatalf("error opening file %s: %v", path, err)
			}

			c := new(Controls)
			err = yaml.Unmarshal(in, c)
			if err == nil {
				t.Logf("YAML file successfully unmarshalled: %s", path)
			} else {
				t.Fatalf("failed to load YAML from %s: %v", path, err)
			}
		}
		return nil
	})
	if err != nil {
		t.Fatalf("failure walking cfg dir: %v\n", err)
	}
}

func TestNewControls(t *testing.T) {

	t.Run("Should return error when node type is not specified", func(t *testing.T) {
		// given
		in := []byte(`
---
controls:
type: # not specified
groups:
`)
		// when
		_, err := NewControls(MASTER, in)
		// then
		assert.EqualError(t, err, "non-master controls file specified")
	})

	t.Run("Should return error when input YAML is invalid", func(t *testing.T) {
		// given
		in := []byte("BOOM")
		// when
		_, err := NewControls(MASTER, in)
		// then
		assert.EqualError(t, err, "failed to unmarshal YAML: yaml: unmarshal errors:\n  line 1: cannot unmarshal !!str `BOOM` into check.Controls")
	})

}

func TestControls_RunChecks(t *testing.T) {

	t.Run("Should run checks matching the filter and update summaries", func(t *testing.T) {
		// given
		runner := new(mockRunner)
		// and
		in := []byte(`
---
type: "master"
groups:
- id: G1
  checks:
    - id: G1/C1
- id: G2
  checks:
    - id: G2/C1
`)
		// and
		controls, _ := NewControls(MASTER, in)
		// and
		runner.On("Run", controls.Groups[0].Checks[0]).Return(PASS)
		runner.On("Run", controls.Groups[1].Checks[0]).Return(FAIL)
		// and
		var runAll Predicate = func(group *Group, c *Check) bool {
			return true
		}
		// when
		controls.RunChecks(runner, runAll)
		// then
		assert.Equal(t, 2, len(controls.Groups))
		// and
		G1 := controls.Groups[0]
		assert.Equal(t, "G1", G1.ID)
		assert.Equal(t, "G1/C1", G1.Checks[0].ID)
		assertEqualGroupSummary(t, 1, 0, 0, 0, G1)
		// and
		G2 := controls.Groups[1]
		assert.Equal(t, "G2", G2.ID)
		assert.Equal(t, "G2/C1", G2.Checks[0].ID)
		assertEqualGroupSummary(t, 0, 1, 0, 0, G2)
		// and
		assert.Equal(t, 1, controls.Summary.Pass)
		assert.Equal(t, 1, controls.Summary.Fail)
		assert.Equal(t, 0, controls.Summary.Info)
		assert.Equal(t, 0, controls.Summary.Warn)
		// and
		runner.AssertExpectations(t)
	})

}

func assertEqualGroupSummary(t *testing.T, pass, fail, info, warn int, actual *Group) {
	t.Helper()
	assert.Equal(t, pass, actual.Pass)
	assert.Equal(t, fail, actual.Fail)
	assert.Equal(t, info, actual.Info)
	assert.Equal(t, warn, actual.Warn)
}
<|endoftext|>


<commit_before>package checklist

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/karolgorecki/goprove/util"
)

func projectBuilds() bool {
	_, err := exec.Command("go", "build", sourcePath).Output()
	return err == nil
}

func isFormatted() bool {
	output, _ := exec.Command("gofmt", "-l -s", sourcePath).Output()
	return len(output) == 0
}

func testPassing() bool {
	output, _ := exec.Command("go", "test", sourcePath+"/...").Output()
	return strings.Index(string(output), `--- FAIL`) == -1
}

func hasLicense() bool {
	return util.FilesExistAny(sourcePath, "license", "licensing", "copying")
}

func hasReadme() bool {
	return util.FilesExistAny(sourcePath, "readme")
}

func hasContributing() bool {
	return util.FilesExistAny(sourcePath, "contribution", "contribute", "contributing")
}

func isLinted() bool {
	output, _ := exec.Command("golint", sourcePath+"/...").Output()
	return len(output) == 0
}

func isVetted() bool {
	_, err := exec.Command("go", "vet", sourcePath).Output()
	return err == nil
}

func isDirMatch() bool {
	ok := true

	filepath.Walk(sourcePath, func(p string, dir os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if !dir.IsDir() || dir.Name() == "." {
			return nil
		}

		files, _ := filepath.Glob(p + string(os.PathSeparator) + "*.go")
		if len(files) == 0 {
			return nil
		}

		file, err := ioutil.ReadFile(files[0])
		if err != nil {
			return err
		}

		r, _ := regexp.Compile(`package ([\w]+)`)
		match := r.FindStringSubmatch(string(file))
		if len(match) > 1 {
			if dir.Name() != match[1] {
				ok = false
			}
		}

		return nil
	})

	return ok
}

func hasBenches() bool {
	return util.FindPatternInTree(sourcePath, `func\sBenchmark\w+\(`, "*_test.go")
}

func hasBlackboxTests() bool {
	return util.FindPatternInTree(sourcePath, `"testing\/quick"`, "*_test.go")
}
<commit_msg>:memo: use go-license to hasLicense function - closes #4<commit_after>package checklist

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/ryanuber/go-license"

	"github.com/karolgorecki/goprove/util"
)

func projectBuilds() bool {
	_, err := exec.Command("go", "build", sourcePath).Output()
	return err == nil
}

func isFormatted() bool {
	output, _ := exec.Command("gofmt", "-l -s", sourcePath).Output()
	return len(output) == 0
}

func testPassing() bool {
	output, _ := exec.Command("go", "test", sourcePath+"/...").Output()
	return strings.Index(string(output), `--- FAIL`) == -1
}

func hasLicense() bool {
	if _, err := license.NewFromDir(sourcePath); err != nil {
		return false
	}
	return true
}

func hasReadme() bool {
	return util.FilesExistAny(sourcePath, "readme")
}

func hasContributing() bool {
	return util.FilesExistAny(sourcePath, "contribution", "contribute", "contributing")
}

func isLinted() bool {
	output, _ := exec.Command("golint", sourcePath+"/...").Output()
	return len(output) == 0
}

func isVetted() bool {
	_, err := exec.Command("go", "vet", sourcePath).Output()
	return err == nil
}

func isDirMatch() bool {
	ok := true

	filepath.Walk(sourcePath, func(p string, dir os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if !dir.IsDir() || dir.Name() == "." {
			return nil
		}

		files, _ := filepath.Glob(p + string(os.PathSeparator) + "*.go")
		if len(files) == 0 {
			return nil
		}

		file, err := ioutil.ReadFile(files[0])
		if err != nil {
			return err
		}

		r, _ := regexp.Compile(`package ([\w]+)`)
		match := r.FindStringSubmatch(string(file))
		if len(match) > 1 {
			if dir.Name() != match[1] {
				ok = false
			}
		}

		return nil
	})

	return ok
}

func hasBenches() bool {
	return util.FindPatternInTree(sourcePath, `func\sBenchmark\w+\(`, "*_test.go")
}

func hasBlackboxTests() bool {
	return util.FindPatternInTree(sourcePath, `"testing\/quick"`, "*_test.go")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
	"os"
	"runtime"

	"github.com/codegangsta/negroni"
	"github.com/gorilla/mux"
)

const DBNAME = "satellizer"

var (
	PORT        = ":3000"
	MONGODB_URL = "localhost"
)

func init() {
	if p := os.Getenv("PORT"); p != "" {
		PORT = ":" + p
	}
	if m := os.Getenv("MONGODB_URL"); m != "" {
		MONGODB_URL = m
	}
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	dbSession := DBConnect(MONGODB_URL)
	DBEnsureIndices(dbSession)

	router := mux.NewRouter().StrictSlash(true)

	api := router.PathPrefix("/api").Subrouter()
	api.HandleFunc("/me", Me).Methods("GET")
	api.HandleFunc("/me", UpdateAccount).Methods("PUT")

	authApi := router.PathPrefix("/auth").Subrouter()
	authApi.HandleFunc("/login", Login).Methods("POST")
	authApi.HandleFunc("/signup", SignUp).Methods("POST")

	n := negroni.Classic()
	n.Use(JWTMiddleware())
	n.Use(DBMiddleware(dbSession))
	n.Use(ParseFormMiddleware())
	n.UseHandler(router)

	static := router.PathPrefix("/").Subrouter()
	static.Methods("GET").Handler(http.FileServer(http.Dir("../../client")))

	fmt.Println("Launching server at http://localhost" + PORT)
	err := http.ListenAndServe(PORT, n)
	if err != nil {
		fmt.Println(err)
	}
}
<commit_msg>Add facebook route<commit_after>package main

import (
	"fmt"
	"net/http"
	"os"
	"runtime"

	"github.com/codegangsta/negroni"
	"github.com/gorilla/mux"
)

const DBNAME = "satellizer"

var (
	PORT        = ":3000"
	MONGODB_URL = "localhost"
)

func init() {
	if p := os.Getenv("PORT"); p != "" {
		PORT = ":" + p
	}
	if m := os.Getenv("MONGODB_URL"); m != "" {
		MONGODB_URL = m
	}
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	dbSession := DBConnect(MONGODB_URL)
	DBEnsureIndices(dbSession)

	router := mux.NewRouter().StrictSlash(true)

	api := router.PathPrefix("/api").Subrouter()
	api.HandleFunc("/me", Me).Methods("GET")
	api.HandleFunc("/me", UpdateAccount).Methods("PUT")

	authApi := router.PathPrefix("/auth").Subrouter()
	authApi.HandleFunc("/login", Login).Methods("POST")
	authApi.HandleFunc("/signup", SignUp).Methods("POST")
	authApi.HandleFunc("/facebook", LoginWithFacebook).Methods("POST")

	n := negroni.Classic()
	n.Use(JWTMiddleware())
	n.Use(DBMiddleware(dbSession))
	n.Use(ParseFormMiddleware())
	n.UseHandler(router)

	static := router.PathPrefix("/").Subrouter()
	static.Methods("GET").Handler(http.FileServer(http.Dir("../../client")))

	fmt.Println("Launching server at http://localhost" + PORT)
	err := http.ListenAndServe(PORT, n)
	if err != nil {
		fmt.Println(err)
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Kubernetes Authors.

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

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

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

package main

import (
	"flag"
	"fmt"
	"time"

	"github.com/golang/glog"

	"k8s.io/api/core/v1"
	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/fields"
	"k8s.io/apimachinery/pkg/util/runtime"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/workqueue"
)

type Controller struct {
	indexer  cache.Indexer
	queue    workqueue.RateLimitingInterface
	informer cache.Controller
}

func NewController(queue workqueue.RateLimitingInterface, indexer cache.Indexer, informer cache.Controller) *Controller {
	return &Controller{
		informer: informer,
		indexer:  indexer,
		queue:    queue,
	}
}

func (c *Controller) processNextItem() bool {
	// Wait until there is a new item in the working queue
	key, quit := c.queue.Get()
	if quit {
		return false
	}
	// Tell the queue that we are done with processing this key. This unblocks the key for other workers
	// This allows safe parallel processing because two pods with the same key are never processed in
	// parallel.
	defer c.queue.Done(key)

	// Invoke the method containing the business logic
	err := c.syncToStdout(key.(string))
	// Handle the error if something went wrong during the execution of the business logic
	c.handleErr(err, key)
	return true
}

// syncToStdout is the business logic of the controller. In this controller it simply prints
// information about the pod to stdout. In case an error happened, it has to simply return the error.
// The retry logic should not be part of the business logic.
func (c *Controller) syncToStdout(key string) error {
	obj, exists, err := c.indexer.GetByKey(key)
	if err != nil {
		glog.Errorf("Fetching object with key %s from store failed with %v", key, err)
		return err
	}

	if !exists {
		// Below we will warm up our cache with a Pod, so that we will see a delete for one pod
		fmt.Printf("Pod %s does not exist anymore\n", key)
	} else {
		// Note that you also have to check the uid if you have a local controlled resource, which
		// is dependent on the actual instance, to detect that a Pod was recreated with the same name
		fmt.Printf("Sync/Add/Update for Pod %s\n", obj.(*v1.Pod).GetName())
	}
	return nil
}

// handleErr checks if an error happened and makes sure we will retry later.
func (c *Controller) handleErr(err error, key interface{}) {
	if err == nil {
		// Forget about the #AddRateLimited history of the key on every successful synchronization.
		// This ensures that future processing of updates for this key is not delayed because of
		// an outdated error history.
		c.queue.Forget(key)
		return
	}

	// This controller retries 5 times if something goes wrong. After that, it stops trying.
	if c.queue.NumRequeues(key) < 5 {
		glog.Infof("Error syncing pod %v: %v", key, err)

		// Re-enqueue the key rate limited. Based on the rate limiter on the
		// queue and the re-enqueue history, the key will be processed later again.
		c.queue.AddRateLimited(key)
		return
	}

	c.queue.Forget(key)
	// Report to an external entity that, even after several retries, we could not successfully process this key
	runtime.HandleError(err)
	glog.Infof("Dropping pod %q out of the queue: %v", key, err)
}

func (c *Controller) Run(threadiness int, stopCh chan struct{}) {
	defer runtime.HandleCrash()

	// Let the workers stop when we are done
	defer c.queue.ShutDown()
	glog.Info("Starting Pod controller")

	go c.informer.Run(stopCh)

	// Wait for all involved caches to be synced, before processing items from the queue is started
	if !cache.WaitForCacheSync(stopCh, c.informer.HasSynced) {
		runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))
		return
	}

	for i := 0; i < threadiness; i++ {
		go wait.Until(c.runWorker, time.Second, stopCh)
	}

	<-stopCh
	glog.Info("Stopping Pod controller")
}

func (c *Controller) runWorker() {
	for c.processNextItem() {
	}
}

func main() {
	var kubeconfig string
	var master string

	flag.StringVar(&kubeconfig, "kubeconfig", "", "absolute path to the kubeconfig file")
	flag.StringVar(&master, "master", "", "master url")
	flag.Parse()

	// creates the connection
	config, err := clientcmd.BuildConfigFromFlags(master, kubeconfig)
	if err != nil {
		glog.Fatal(err)
	}

	// creates the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		glog.Fatal(err)
	}

	// create the pod watcher
	podListWatcher := cache.NewListWatchFromClient(clientset.Core().RESTClient(), "pods", v1.NamespaceDefault, fields.Everything())

	// create the workqueue
	queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())

	// Bind the workqueue to a cache with the help of an informer. This way we make sure that
	// whenever the cache is updated, the pod key is added to the workqueue.
	// Note that when we finally process the item from the workqueue, we might see a newer version
	// of the Pod than the version which was responsible for triggering the update.
	indexer, informer := cache.NewIndexerInformer(podListWatcher, &v1.Pod{}, 0, cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			key, err := cache.MetaNamespaceKeyFunc(obj)
			if err == nil {
				queue.Add(key)
			}
		},
		UpdateFunc: func(old interface{}, new interface{}) {
			key, err := cache.MetaNamespaceKeyFunc(new)
			if err == nil {
				queue.Add(key)
			}
		},
		DeleteFunc: func(obj interface{}) {
			// IndexerInformer uses a delta queue, therefore for deletes we have to use this
			// key function.
			key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
			if err == nil {
				queue.Add(key)
			}
		},
	}, cache.Indexers{})

	controller := NewController(queue, indexer, informer)

	// We can now warm up the cache for initial synchronization.
	// Let's suppose that we knew about a pod "mypod" on our last run, therefore add it to the cache.
	// If this pod is not there anymore, the controller will be notified about the removal after the
	// cache has synchronized.
	indexer.Add(&v1.Pod{
		ObjectMeta: meta_v1.ObjectMeta{
			Name:      "mypod",
			Namespace: v1.NamespaceDefault,
		},
	})

	// Now let's start the controller
	stop := make(chan struct{})
	defer close(stop)
	go controller.Run(1, stop)

	// Wait forever
	select {}
}
<commit_msg>use the core client with version<commit_after>/*
Copyright 2017 The Kubernetes Authors.

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

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

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

package main

import (
	"flag"
	"fmt"
	"time"

	"github.com/golang/glog"

	"k8s.io/api/core/v1"
	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/fields"
	"k8s.io/apimachinery/pkg/util/runtime"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/workqueue"
)

type Controller struct {
	indexer  cache.Indexer
	queue    workqueue.RateLimitingInterface
	informer cache.Controller
}

func NewController(queue workqueue.RateLimitingInterface, indexer cache.Indexer, informer cache.Controller) *Controller {
	return &Controller{
		informer: informer,
		indexer:  indexer,
		queue:    queue,
	}
}

func (c *Controller) processNextItem() bool {
	// Wait until there is a new item in the working queue
	key, quit := c.queue.Get()
	if quit {
		return false
	}
	// Tell the queue that we are done with processing this key. This unblocks the key for other workers
	// This allows safe parallel processing because two pods with the same key are never processed in
	// parallel.
	defer c.queue.Done(key)

	// Invoke the method containing the business logic
	err := c.syncToStdout(key.(string))
	// Handle the error if something went wrong during the execution of the business logic
	c.handleErr(err, key)
	return true
}

// syncToStdout is the business logic of the controller. In this controller it simply prints
// information about the pod to stdout. In case an error happened, it has to simply return the error.
// The retry logic should not be part of the business logic.
func (c *Controller) syncToStdout(key string) error {
	obj, exists, err := c.indexer.GetByKey(key)
	if err != nil {
		glog.Errorf("Fetching object with key %s from store failed with %v", key, err)
		return err
	}

	if !exists {
		// Below we will warm up our cache with a Pod, so that we will see a delete for one pod
		fmt.Printf("Pod %s does not exist anymore\n", key)
	} else {
		// Note that you also have to check the uid if you have a local controlled resource, which
		// is dependent on the actual instance, to detect that a Pod was recreated with the same name
		fmt.Printf("Sync/Add/Update for Pod %s\n", obj.(*v1.Pod).GetName())
	}
	return nil
}

// handleErr checks if an error happened and makes sure we will retry later.
func (c *Controller) handleErr(err error, key interface{}) {
	if err == nil {
		// Forget about the #AddRateLimited history of the key on every successful synchronization.
		// This ensures that future processing of updates for this key is not delayed because of
		// an outdated error history.
		c.queue.Forget(key)
		return
	}

	// This controller retries 5 times if something goes wrong. After that, it stops trying.
	if c.queue.NumRequeues(key) < 5 {
		glog.Infof("Error syncing pod %v: %v", key, err)

		// Re-enqueue the key rate limited. Based on the rate limiter on the
		// queue and the re-enqueue history, the key will be processed later again.
		c.queue.AddRateLimited(key)
		return
	}

	c.queue.Forget(key)
	// Report to an external entity that, even after several retries, we could not successfully process this key
	runtime.HandleError(err)
	glog.Infof("Dropping pod %q out of the queue: %v", key, err)
}

func (c *Controller) Run(threadiness int, stopCh chan struct{}) {
	defer runtime.HandleCrash()

	// Let the workers stop when we are done
	defer c.queue.ShutDown()
	glog.Info("Starting Pod controller")

	go c.informer.Run(stopCh)

	// Wait for all involved caches to be synced, before processing items from the queue is started
	if !cache.WaitForCacheSync(stopCh, c.informer.HasSynced) {
		runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))
		return
	}

	for i := 0; i < threadiness; i++ {
		go wait.Until(c.runWorker, time.Second, stopCh)
	}

	<-stopCh
	glog.Info("Stopping Pod controller")
}

func (c *Controller) runWorker() {
	for c.processNextItem() {
	}
}

func main() {
	var kubeconfig string
	var master string

	flag.StringVar(&kubeconfig, "kubeconfig", "", "absolute path to the kubeconfig file")
	flag.StringVar(&master, "master", "", "master url")
	flag.Parse()

	// creates the connection
	config, err := clientcmd.BuildConfigFromFlags(master, kubeconfig)
	if err != nil {
		glog.Fatal(err)
	}

	// creates the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		glog.Fatal(err)
	}

	// create the pod watcher
	podListWatcher := cache.NewListWatchFromClient(clientset.CoreV1().RESTClient(), "pods", v1.NamespaceDefault, fields.Everything())

	// create the workqueue
	queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())

	// Bind the workqueue to a cache with the help of an informer. This way we make sure that
	// whenever the cache is updated, the pod key is added to the workqueue.
	// Note that when we finally process the item from the workqueue, we might see a newer version
	// of the Pod than the version which was responsible for triggering the update.
	indexer, informer := cache.NewIndexerInformer(podListWatcher, &v1.Pod{}, 0, cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			key, err := cache.MetaNamespaceKeyFunc(obj)
			if err == nil {
				queue.Add(key)
			}
		},
		UpdateFunc: func(old interface{}, new interface{}) {
			key, err := cache.MetaNamespaceKeyFunc(new)
			if err == nil {
				queue.Add(key)
			}
		},
		DeleteFunc: func(obj interface{}) {
			// IndexerInformer uses a delta queue, therefore for deletes we have to use this
			// key function.
			key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
			if err == nil {
				queue.Add(key)
			}
		},
	}, cache.Indexers{})

	controller := NewController(queue, indexer, informer)

	// We can now warm up the cache for initial synchronization.
	// Let's suppose that we knew about a pod "mypod" on our last run, therefore add it to the cache.
	// If this pod is not there anymore, the controller will be notified about the removal after the
	// cache has synchronized.
	indexer.Add(&v1.Pod{
		ObjectMeta: meta_v1.ObjectMeta{
			Name:      "mypod",
			Namespace: v1.NamespaceDefault,
		},
	})

	// Now let's start the controller
	stop := make(chan struct{})
	defer close(stop)
	go controller.Run(1, stop)

	// Wait forever
	select {}
}
<|endoftext|>


<commit_before>package fetcheddit

import (
	"code.leeclagett.com/grokeddit"
	"errors"
	"io"
	"io/ioutil"
	"strings"
)

const (
	listingForward string = `
{
    "kind": "Listing",
    "data": {
        "modhash": "vaygtcstccf58f59494458317e0f140807769e7dcbe40daf12",
        "children": [
            {
                "kind": "t3",
                "data": {
                    "domain": "self.redditdev",
                    "banned_by": null,
                    "media_embed": {},
                    "subreddit": "redditdev",
                    "selftext_html": "1",
                    "selftext": "1",
                    "likes": null,
                    "secure_media": null,
                    "link_flair_text": null,
                    "id": "20flmp",
                    "gilded": 0,
                    "secure_media_embed": {},
                    "clicked": false,
                    "stickied": false,
                    "author": "reality_bugger",
                    "media": null,
                    "score": 7,
                    "approved_by": null,
                    "over_18": false,
                    "hidden": false,
                    "thumbnail": "",
                    "subreddit_id": "t5_2qizd",
                    "edited": false,
                    "link_flair_css_class": null,
                    "author_flair_css_class": null,
                    "downs": 4,
                    "saved": false,
                    "is_self": true,
                    "permalink": "/r/redditdev/comments/20flmp/just_a_short_thank_you/",
                    "name": "t3_20flmp",
                    "created": 1394860235,
                    "url": "http://www.reddit.com/r/redditdev/comments/20flmp/just_a_short_thank_you/",
                    "author_flair_text": null,
                    "title": "Just a short thank you.",
                    "created_utc": 1394831435,
                    "ups": 11,
                    "num_comments": 2,
                    "visited": false,
                    "num_reports": null,
                    "distinguished": null
                }
            },
            {
                "kind": "t3",
                "data": {
                    "domain": "self.redditdev",
                    "banned_by": null,
                    "media_embed": {},
                    "subreddit": "redditdev",
                    "selftext_html": "2",
                    "likes": null,
                    "secure_media": null,
                    "link_flair_text": null,
                    "id": "20e6ir",
                    "gilded": 0,
                    "secure_media_embed": {},
                    "clicked": false,
                    "stickied": false,
                    "author": "Grimzentide",
                    "media": null,
                    "score": 1,
                    "approved_by": null,
                    "over_18": false,
                    "hidden": false,
                    "thumbnail": "",
                    "subreddit_id": "t5_2qizd",
                    "edited": false,
                    "link_flair_css_class": null,
                    "author_flair_css_class": null,
                    "downs": 1,
                    "saved": false,
                    "is_self": true,
                    "permalink": "/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
                    "name": "t3_20e6ir",
                    "created": 1394822733,
                    "url": "http://www.reddit.com/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
                    "author_flair_text": null,
                    "title": "Is this the most efficient way to run this code?",
                    "created_utc": 1394793933,
                    "ups": 2,
                    "num_comments": 3,
                    "visited": false,
                    "num_reports": null,
                    "distinguished": null
                }
            }
        ],
        "after": "t3_20d5ol",
        "before": null
    }
}
`

	listingReverse string = `
{
    "kind": "Listing",
    "data": {
        "modhash": "vaygtcstccf58f59494458317e0f140807769e7dcbe40daf12",
        "children": [
            {
                "kind": "t3",
                "data": {
                    "domain": "self.redditdev",
                    "banned_by": null,
                    "media_embed": {},
                    "subreddit": "redditdev",
                    "selftext_html": "2",
                    "likes": null,
                    "secure_media": null,
                    "link_flair_text": null,
                    "id": "20e6ir",
                    "gilded": 0,
                    "secure_media_embed": {},
                    "clicked": false,
                    "stickied": false,
                    "author": "Grimzentide",
                    "media": null,
                    "score": 1,
                    "approved_by": null,
                    "over_18": false,
                    "hidden": false,
                    "thumbnail": "",
                    "subreddit_id": "t5_2qizd",
                    "edited": false,
                    "link_flair_css_class": null,
                    "author_flair_css_class": null,
                    "downs": 1,
                    "saved": false,
                    "is_self": true,
                    "permalink": "/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
                    "name": "t3_20e6ir",
                    "created": 1394822733,
                    "url": "http://www.reddit.com/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
                    "author_flair_text": null,
                    "title": "Is this the most efficient way to run this code?",
                    "created_utc": 1394793933,
                    "ups": 2,
                    "num_comments": 3,
                    "visited": false,
                    "num_reports": null,
                    "distinguished": null
                }
            },
            {
                "kind": "t3",
                "data": {
                    "domain": "self.redditdev",
                    "banned_by": null,
                    "media_embed": {},
                    "subreddit": "redditdev",
                    "selftext_html": "1",
                    "selftext": "1",
                    "likes": null,
                    "secure_media": null,
                    "link_flair_text": null,
                    "id": "20flmp",
                    "gilded": 0,
                    "secure_media_embed": {},
                    "clicked": false,
                    "stickied": false,
                    "author": "reality_bugger",
                    "media": null,
                    "score": 7,
                    "approved_by": null,
                    "over_18": false,
                    "hidden": false,
                    "thumbnail": "",
                    "subreddit_id": "t5_2qizd",
                    "edited": false,
                    "link_flair_css_class": null,
                    "author_flair_css_class": null,
                    "downs": 4,
                    "saved": false,
                    "is_self": true,
                    "permalink": "/r/redditdev/comments/20flmp/just_a_short_thank_you/",
                    "name": "t3_20flmp",
                    "created": 1394860235,
                    "url": "http://www.reddit.com/r/redditdev/comments/20flmp/just_a_short_thank_you/",
                    "author_flair_text": null,
                    "title": "Just a short thank you.",
                    "created_utc": 1394831435,
                    "ups": 11,
                    "num_comments": 2,
                    "visited": false,
                    "num_reports": null,
                    "distinguished": null
                }
            }
        ],
        "before": "t3_20d5ol",
        "after": null
    }
}
`
)

var (
	listingOutputForward = grokeddit.Groked{
		nil,
		&grokeddit.GlobalId{121546245, grokeddit.Link},
		[]grokeddit.Thing{
			grokeddit.Thing{
				"reality_bugger",
				1394831435,
				grokeddit.GlobalId{121660225, grokeddit.Link},
				1394831435,
				grokeddit.GlobalId{},
				grokeddit.GlobalId{},
				grokeddit.Groked{},
				"redditdev",
				grokeddit.GlobalId{4596889, grokeddit.Subreddit},
				"1",
				"Just a short thank you.",
				"http://www.reddit.com/r/redditdev/comments/20flmp/just_a_short_thank_you/",
			},
			grokeddit.Thing{
				"Grimzentide",
				1394793933,
				grokeddit.GlobalId{121593987, grokeddit.Link}, 1394793933,
				grokeddit.GlobalId{},
				grokeddit.GlobalId{},
				grokeddit.Groked{},
				"redditdev",
				grokeddit.GlobalId{4596889, grokeddit.Subreddit},
				"2",
				"Is this the most efficient way to run this code?",
				"http://www.reddit.com/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
			},
		},
	}

	listingOutputReverse = grokeddit.Groked{
		&grokeddit.GlobalId{121546245, grokeddit.Link},
		nil,
		[]grokeddit.Thing{
			grokeddit.Thing{
				"Grimzentide",
				1394793933,
				grokeddit.GlobalId{121593987, grokeddit.Link}, 1394793933,
				grokeddit.GlobalId{},
				grokeddit.GlobalId{},
				grokeddit.Groked{},
				"redditdev",
				grokeddit.GlobalId{4596889, grokeddit.Subreddit},
				"2",
				"Is this the most efficient way to run this code?",
				"http://www.reddit.com/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
			},
			grokeddit.Thing{
				"reality_bugger",
				1394831435,
				grokeddit.GlobalId{121660225, grokeddit.Link},
				1394831435,
				grokeddit.GlobalId{},
				grokeddit.GlobalId{},
				grokeddit.Groked{},
				"redditdev",
				grokeddit.GlobalId{4596889, grokeddit.Subreddit},
				"1",
				"Just a short thank you.",
				"http://www.reddit.com/r/redditdev/comments/20flmp/just_a_short_thank_you/",
			},
		},
	}
)

type TestFetch struct {
	nextValue     chan string
	lastFetchPath chan string
}

func CreateTestFetch(values []string) *TestFetch {
	newTestFetch := TestFetch{
		make(chan string, len(values)),
		make(chan string, len(values)),
	}

	defer close(newTestFetch.nextValue)
	for _, value := range values {
		newTestFetch.nextValue <- value
	}

	return &newTestFetch
}

func (testFetch *TestFetch) Fetch(path string) (io.ReadCloser, error) {
	nextValue, ok := <-testFetch.nextValue
	if !ok {
		close(testFetch.lastFetchPath)
		return nil, errors.New("No more values to fetch")
	}

	testFetch.lastFetchPath <- path
	return ioutil.NopCloser(strings.NewReader(nextValue)), nil
}

func (testFetch *TestFetch) GetNextFetchLocation() (string, error) {
	nextValue, ok := <-testFetch.lastFetchPath
	if !ok {
		return "", errors.New("No more fetch locations")
	}

	return nextValue, nil
}
<commit_msg>Fixed bug in test framework<commit_after>package fetcheddit

import (
	"code.leeclagett.com/grokeddit"
	"errors"
	"io"
	"io/ioutil"
	"strings"
)

const (
	listingForward string = `
{
    "kind": "Listing",
    "data": {
        "modhash": "vaygtcstccf58f59494458317e0f140807769e7dcbe40daf12",
        "children": [
            {
                "kind": "t3",
                "data": {
                    "domain": "self.redditdev",
                    "banned_by": null,
                    "media_embed": {},
                    "subreddit": "redditdev",
                    "selftext_html": "1",
                    "selftext": "1",
                    "likes": null,
                    "secure_media": null,
                    "link_flair_text": null,
                    "id": "20flmp",
                    "gilded": 0,
                    "secure_media_embed": {},
                    "clicked": false,
                    "stickied": false,
                    "author": "reality_bugger",
                    "media": null,
                    "score": 7,
                    "approved_by": null,
                    "over_18": false,
                    "hidden": false,
                    "thumbnail": "",
                    "subreddit_id": "t5_2qizd",
                    "edited": false,
                    "link_flair_css_class": null,
                    "author_flair_css_class": null,
                    "downs": 4,
                    "saved": false,
                    "is_self": true,
                    "permalink": "/r/redditdev/comments/20flmp/just_a_short_thank_you/",
                    "name": "t3_20flmp",
                    "created": 1394860235,
                    "url": "http://www.reddit.com/r/redditdev/comments/20flmp/just_a_short_thank_you/",
                    "author_flair_text": null,
                    "title": "Just a short thank you.",
                    "created_utc": 1394831435,
                    "ups": 11,
                    "num_comments": 2,
                    "visited": false,
                    "num_reports": null,
                    "distinguished": null
                }
            },
            {
                "kind": "t3",
                "data": {
                    "domain": "self.redditdev",
                    "banned_by": null,
                    "media_embed": {},
                    "subreddit": "redditdev",
                    "selftext_html": "2",
                    "likes": null,
                    "secure_media": null,
                    "link_flair_text": null,
                    "id": "20e6ir",
                    "gilded": 0,
                    "secure_media_embed": {},
                    "clicked": false,
                    "stickied": false,
                    "author": "Grimzentide",
                    "media": null,
                    "score": 1,
                    "approved_by": null,
                    "over_18": false,
                    "hidden": false,
                    "thumbnail": "",
                    "subreddit_id": "t5_2qizd",
                    "edited": false,
                    "link_flair_css_class": null,
                    "author_flair_css_class": null,
                    "downs": 1,
                    "saved": false,
                    "is_self": true,
                    "permalink": "/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
                    "name": "t3_20e6ir",
                    "created": 1394822733,
                    "url": "http://www.reddit.com/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
                    "author_flair_text": null,
                    "title": "Is this the most efficient way to run this code?",
                    "created_utc": 1394793933,
                    "ups": 2,
                    "num_comments": 3,
                    "visited": false,
                    "num_reports": null,
                    "distinguished": null
                }
            }
        ],
        "after": "t3_20d5ol",
        "before": null
    }
}
`

	listingReverse string = `
{
    "kind": "Listing",
    "data": {
        "modhash": "vaygtcstccf58f59494458317e0f140807769e7dcbe40daf12",
        "children": [
            {
                "kind": "t3",
                "data": {
                    "domain": "self.redditdev",
                    "banned_by": null,
                    "media_embed": {},
                    "subreddit": "redditdev",
                    "selftext_html": "2",
                    "likes": null,
                    "secure_media": null,
                    "link_flair_text": null,
                    "id": "20e6ir",
                    "gilded": 0,
                    "secure_media_embed": {},
                    "clicked": false,
                    "stickied": false,
                    "author": "Grimzentide",
                    "media": null,
                    "score": 1,
                    "approved_by": null,
                    "over_18": false,
                    "hidden": false,
                    "thumbnail": "",
                    "subreddit_id": "t5_2qizd",
                    "edited": false,
                    "link_flair_css_class": null,
                    "author_flair_css_class": null,
                    "downs": 1,
                    "saved": false,
                    "is_self": true,
                    "permalink": "/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
                    "name": "t3_20e6ir",
                    "created": 1394822733,
                    "url": "http://www.reddit.com/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
                    "author_flair_text": null,
                    "title": "Is this the most efficient way to run this code?",
                    "created_utc": 1394793933,
                    "ups": 2,
                    "num_comments": 3,
                    "visited": false,
                    "num_reports": null,
                    "distinguished": null
                }
            },
            {
                "kind": "t3",
                "data": {
                    "domain": "self.redditdev",
                    "banned_by": null,
                    "media_embed": {},
                    "subreddit": "redditdev",
                    "selftext_html": "1",
                    "selftext": "1",
                    "likes": null,
                    "secure_media": null,
                    "link_flair_text": null,
                    "id": "20flmp",
                    "gilded": 0,
                    "secure_media_embed": {},
                    "clicked": false,
                    "stickied": false,
                    "author": "reality_bugger",
                    "media": null,
                    "score": 7,
                    "approved_by": null,
                    "over_18": false,
                    "hidden": false,
                    "thumbnail": "",
                    "subreddit_id": "t5_2qizd",
                    "edited": false,
                    "link_flair_css_class": null,
                    "author_flair_css_class": null,
                    "downs": 4,
                    "saved": false,
                    "is_self": true,
                    "permalink": "/r/redditdev/comments/20flmp/just_a_short_thank_you/",
                    "name": "t3_20flmp",
                    "created": 1394860235,
                    "url": "http://www.reddit.com/r/redditdev/comments/20flmp/just_a_short_thank_you/",
                    "author_flair_text": null,
                    "title": "Just a short thank you.",
                    "created_utc": 1394831435,
                    "ups": 11,
                    "num_comments": 2,
                    "visited": false,
                    "num_reports": null,
                    "distinguished": null
                }
            }
        ],
        "before": "t3_20d5ol",
        "after": null
    }
}
`
)

var (
	listingOutputForward = grokeddit.Groked{
		nil,
		&grokeddit.GlobalId{121546245, grokeddit.Link},
		[]grokeddit.Thing{
			grokeddit.Thing{
				"reality_bugger",
				1394831435,
				grokeddit.GlobalId{121660225, grokeddit.Link},
				1394831435,
				grokeddit.GlobalId{},
				grokeddit.GlobalId{},
				grokeddit.Groked{},
				"redditdev",
				grokeddit.GlobalId{4596889, grokeddit.Subreddit},
				"1",
				"Just a short thank you.",
				"http://www.reddit.com/r/redditdev/comments/20flmp/just_a_short_thank_you/",
			},
			grokeddit.Thing{
				"Grimzentide",
				1394793933,
				grokeddit.GlobalId{121593987, grokeddit.Link}, 1394793933,
				grokeddit.GlobalId{},
				grokeddit.GlobalId{},
				grokeddit.Groked{},
				"redditdev",
				grokeddit.GlobalId{4596889, grokeddit.Subreddit},
				"2",
				"Is this the most efficient way to run this code?",
				"http://www.reddit.com/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
			},
		},
	}

	listingOutputReverse = grokeddit.Groked{
		&grokeddit.GlobalId{121546245, grokeddit.Link},
		nil,
		[]grokeddit.Thing{
			grokeddit.Thing{
				"Grimzentide",
				1394793933,
				grokeddit.GlobalId{121593987, grokeddit.Link}, 1394793933,
				grokeddit.GlobalId{},
				grokeddit.GlobalId{},
				grokeddit.Groked{},
				"redditdev",
				grokeddit.GlobalId{4596889, grokeddit.Subreddit},
				"2",
				"Is this the most efficient way to run this code?",
				"http://www.reddit.com/r/redditdev/comments/20e6ir/is_this_the_most_efficient_way_to_run_this_code/",
			},
			grokeddit.Thing{
				"reality_bugger",
				1394831435,
				grokeddit.GlobalId{121660225, grokeddit.Link},
				1394831435,
				grokeddit.GlobalId{},
				grokeddit.GlobalId{},
				grokeddit.Groked{},
				"redditdev",
				grokeddit.GlobalId{4596889, grokeddit.Subreddit},
				"1",
				"Just a short thank you.",
				"http://www.reddit.com/r/redditdev/comments/20flmp/just_a_short_thank_you/",
			},
		},
	}
)

type TestFetch struct {
	nextValue       chan string
	lastFetchPath   chan string
	closedFetchPath bool
}

func CreateTestFetch(values []string) *TestFetch {
	newTestFetch := TestFetch{
		make(chan string, len(values)),
		make(chan string, len(values)),
		false,
	}

	defer close(newTestFetch.nextValue)
	for _, value := range values {
		newTestFetch.nextValue <- value
	}

	return &newTestFetch
}

func (testFetch *TestFetch) Fetch(path string) (io.ReadCloser, error) {
	nextValue, ok := <-testFetch.nextValue
	if !ok {
		if !testFetch.closedFetchPath {
			close(testFetch.lastFetchPath)
			testFetch.closedFetchPath = true
		}
		return nil, errors.New("No more values to fetch")
	}

	testFetch.lastFetchPath <- path
	return ioutil.NopCloser(strings.NewReader(nextValue)), nil
}

func (testFetch *TestFetch) GetNextFetchLocation() (string, error) {
	nextValue, ok := <-testFetch.lastFetchPath
	if !ok {
		return "", errors.New("No more fetch locations")
	}

	return nextValue, nil
}
<|endoftext|>


<commit_before>package device

import (
	"fmt"
	"strings"

	"golang.org/x/sys/unix"

	"github.com/lxc/lxd/shared"
)

// BlockFsDetect detects the type of block device.
func BlockFsDetect(dev string) (string, error) {
	out, err := shared.RunCommand("blkid", "-s", "TYPE", "-o", "value", dev)
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(out), nil
}

// IsBlockdev returns boolean indicating whether device is block type.
func IsBlockdev(path string) bool {
	// Get a stat struct from the provided path
	stat := unix.Stat_t{}
	err := unix.Stat(path, &stat)
	if err != nil {
		return false
	}

	// Check if it's a block device
	if stat.Mode&unix.S_IFMT == unix.S_IFBLK {
		return true
	}

	// Not a device
	return false
}

// DiskMount mounts a disk device.
func DiskMount(srcPath string, dstPath string, readonly bool, recursive bool, propagation string) error {
	var err error

	// Prepare the mount flags
	flags := 0
	if readonly {
		flags |= unix.MS_RDONLY
	}

	// Detect the filesystem
	fstype := "none"
	if IsBlockdev(srcPath) {
		fstype, err = BlockFsDetect(srcPath)
		if err != nil {
			return err
		}
	} else {
		flags |= unix.MS_BIND
		if propagation != "" {
			switch propagation {
			case "private":
				flags |= unix.MS_PRIVATE
			case "shared":
				flags |= unix.MS_SHARED
			case "slave":
				flags |= unix.MS_SLAVE
			case "unbindable":
				flags |= unix.MS_UNBINDABLE
			case "rprivate":
				flags |= unix.MS_PRIVATE | unix.MS_REC
			case "rshared":
				flags |= unix.MS_SHARED | unix.MS_REC
			case "rslave":
				flags |= unix.MS_SLAVE | unix.MS_REC
			case "runbindable":
				flags |= unix.MS_UNBINDABLE | unix.MS_REC
			default:
				return fmt.Errorf("Invalid propagation mode '%s'", propagation)
			}
		}

		if recursive {
			flags |= unix.MS_REC
		}
	}

	// Mount the filesystem
	err = unix.Mount(srcPath, dstPath, fstype, uintptr(flags), "")
	if err != nil {
		return fmt.Errorf("Unable to mount %s at %s: %s", srcPath, dstPath, err)
	}

	// Remount bind mounts in readonly mode if requested
	if readonly == true && flags&unix.MS_BIND == unix.MS_BIND {
		flags = unix.MS_RDONLY | unix.MS_BIND | unix.MS_REMOUNT
		err = unix.Mount("", dstPath, fstype, uintptr(flags), "")
		if err != nil {
			return fmt.Errorf("Unable to mount %s in readonly mode: %s", dstPath, err)
		}
	}

	flags = unix.MS_REC | unix.MS_SLAVE
	err = unix.Mount("", dstPath, "", uintptr(flags), "")
	if err != nil {
		return fmt.Errorf("unable to make mount %s private: %s", dstPath, err)
	}

	return nil
}
<commit_msg>device/device/utils/disk: Adds StorageVolumeMount and StorageVolumeUmount linked functions<commit_after>package device

import (
	"fmt"
	"strings"

	"golang.org/x/sys/unix"

	"github.com/lxc/lxd/lxd/state"
	"github.com/lxc/lxd/shared"
)

// StorageVolumeMount checks if storage volume is mounted and if not tries to mount it.
var StorageVolumeMount func(s *state.State, poolName string, volumeName string, volumeTypeName string, instance InstanceIdentifier) error

// StorageVolumeUmount unmounts a storage volume.
var StorageVolumeUmount func(s *state.State, poolName string, volumeName string, volumeType int) error

// BlockFsDetect detects the type of block device.
func BlockFsDetect(dev string) (string, error) {
	out, err := shared.RunCommand("blkid", "-s", "TYPE", "-o", "value", dev)
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(out), nil
}

// IsBlockdev returns boolean indicating whether device is block type.
func IsBlockdev(path string) bool {
	// Get a stat struct from the provided path
	stat := unix.Stat_t{}
	err := unix.Stat(path, &stat)
	if err != nil {
		return false
	}

	// Check if it's a block device
	if stat.Mode&unix.S_IFMT == unix.S_IFBLK {
		return true
	}

	// Not a device
	return false
}

// DiskMount mounts a disk device.
func DiskMount(srcPath string, dstPath string, readonly bool, recursive bool, propagation string) error {
	var err error

	// Prepare the mount flags
	flags := 0
	if readonly {
		flags |= unix.MS_RDONLY
	}

	// Detect the filesystem
	fstype := "none"
	if IsBlockdev(srcPath) {
		fstype, err = BlockFsDetect(srcPath)
		if err != nil {
			return err
		}
	} else {
		flags |= unix.MS_BIND
		if propagation != "" {
			switch propagation {
			case "private":
				flags |= unix.MS_PRIVATE
			case "shared":
				flags |= unix.MS_SHARED
			case "slave":
				flags |= unix.MS_SLAVE
			case "unbindable":
				flags |= unix.MS_UNBINDABLE
			case "rprivate":
				flags |= unix.MS_PRIVATE | unix.MS_REC
			case "rshared":
				flags |= unix.MS_SHARED | unix.MS_REC
			case "rslave":
				flags |= unix.MS_SLAVE | unix.MS_REC
			case "runbindable":
				flags |= unix.MS_UNBINDABLE | unix.MS_REC
			default:
				return fmt.Errorf("Invalid propagation mode '%s'", propagation)
			}
		}

		if recursive {
			flags |= unix.MS_REC
		}
	}

	// Mount the filesystem
	err = unix.Mount(srcPath, dstPath, fstype, uintptr(flags), "")
	if err != nil {
		return fmt.Errorf("Unable to mount %s at %s: %s", srcPath, dstPath, err)
	}

	// Remount bind mounts in readonly mode if requested
	if readonly == true && flags&unix.MS_BIND == unix.MS_BIND {
		flags = unix.MS_RDONLY | unix.MS_BIND | unix.MS_REMOUNT
		err = unix.Mount("", dstPath, fstype, uintptr(flags), "")
		if err != nil {
			return fmt.Errorf("Unable to mount %s in readonly mode: %s", dstPath, err)
		}
	}

	flags = unix.MS_REC | unix.MS_SLAVE
	err = unix.Mount("", dstPath, "", uintptr(flags), "")
	if err != nil {
		return fmt.Errorf("unable to make mount %s private: %s", dstPath, err)
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	repo "github.com/fsamin/go-repo"
	"github.com/spf13/cobra"

	"github.com/ovh/cds/cli"
	"github.com/ovh/cds/sdk/cdsclient"
)

var (
	workflowCmd = cli.Command{
		Name:  "workflow",
		Short: "Manage CDS workflow",
	}

	workflow = cli.NewCommand(workflowCmd, nil,
		[]*cobra.Command{
			cli.NewCommand(workflowInitCmd, workflowInitRun, nil),
			cli.NewListCommand(workflowListCmd, workflowListRun, nil, withAllCommandModifiers()...),
			cli.NewListCommand(workflowHistoryCmd, workflowHistoryRun, nil, withAllCommandModifiers()...),
			cli.NewGetCommand(workflowShowCmd, workflowShowRun, nil, withAllCommandModifiers()...),
			cli.NewGetCommand(workflowStatusCmd, workflowStatusRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowRunManualCmd, workflowRunManualRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowStopCmd, workflowStopRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowExportCmd, workflowExportRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowImportCmd, workflowImportRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowPullCmd, workflowPullRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowPushCmd, workflowPushRun, nil, withAllCommandModifiers()...),
			workflowArtifact,
			workflowAdvanced,
		})
)

func workflowNodeForCurrentRepo(projectKey, workflowName string) (int64, error) {
	//Try to get the latest commit
	r, err := repo.New("")
	if err != nil {
		return 0, nil
	}

	latestCommit, err := r.LatestCommit()
	if err != nil {
		return 0, fmt.Errorf("unable to get latest commit: %v", err)
	}

	filters := []cdsclient.Filter{
		{
			Name:  "workflow",
			Value: workflowName,
		},
		{
			Name:  "git.hash",
			Value: latestCommit.Hash,
		},
	}
	//Searching workflow
	runs, err := client.WorkflowRunSearch(projectKey, 0, 0, filters...)
	if err != nil {
		return 0, err
	}
	if len(runs) != 1 {
		return 0, fmt.Errorf("workflow run not found : %+v", runs)
	}

	if runs[0].Number > 0 {
		return runs[0].Number, nil
	}

	// If no run number, get the latest
	runs, err = client.WorkflowRunList(projectKey, workflowName, 0, 1)
	if err != nil {
		return 0, err
	}

	if len(runs) != 1 {
		return 0, fmt.Errorf("workflow run not found : %+v", runs)
	}

	return runs[0].Number, nil
}
<commit_msg>fix(cli): search workflow wrong limit (#2292)<commit_after>package main

import (
	"fmt"

	repo "github.com/fsamin/go-repo"
	"github.com/spf13/cobra"

	"github.com/ovh/cds/cli"
	"github.com/ovh/cds/sdk/cdsclient"
)

var (
	workflowCmd = cli.Command{
		Name:  "workflow",
		Short: "Manage CDS workflow",
	}

	workflow = cli.NewCommand(workflowCmd, nil,
		[]*cobra.Command{
			cli.NewCommand(workflowInitCmd, workflowInitRun, nil),
			cli.NewListCommand(workflowListCmd, workflowListRun, nil, withAllCommandModifiers()...),
			cli.NewListCommand(workflowHistoryCmd, workflowHistoryRun, nil, withAllCommandModifiers()...),
			cli.NewGetCommand(workflowShowCmd, workflowShowRun, nil, withAllCommandModifiers()...),
			cli.NewGetCommand(workflowStatusCmd, workflowStatusRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowRunManualCmd, workflowRunManualRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowStopCmd, workflowStopRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowExportCmd, workflowExportRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowImportCmd, workflowImportRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowPullCmd, workflowPullRun, nil, withAllCommandModifiers()...),
			cli.NewCommand(workflowPushCmd, workflowPushRun, nil, withAllCommandModifiers()...),
			workflowArtifact,
			workflowAdvanced,
		})
)

func workflowNodeForCurrentRepo(projectKey, workflowName string) (int64, error) {
	//Try to get the latest commit
	r, err := repo.New("")
	if err != nil {
		return 0, nil
	}

	latestCommit, err := r.LatestCommit()
	if err != nil {
		return 0, fmt.Errorf("unable to get latest commit: %v", err)
	}

	filters := []cdsclient.Filter{
		{
			Name:  "workflow",
			Value: workflowName,
		},
		{
			Name:  "git.hash",
			Value: latestCommit.Hash,
		},
	}

	//Searching workflow
	runs, err := client.WorkflowRunSearch(projectKey, 0, 0, filters...)
	if err != nil {
		return 0, err
	}
	if len(runs) < 1 {
		return 0, fmt.Errorf("workflow run not found : %+v", runs)
	}

	if runs[0].Number > 0 {
		return runs[0].Number, nil
	}

	// If no run number, get the latest
	runs, err = client.WorkflowRunList(projectKey, workflowName, 0, 1)
	if err != nil {
		return 0, err
	}

	if len(runs) != 1 {
		return 0, fmt.Errorf("workflow run not found : %+v", runs)
	}

	return runs[0].Number, nil
}
<|endoftext|>


<commit_before>package validation

import (
	"testing"

	"github.com/appPlant/alpinepass/src/data"
	"github.com/stretchr/testify/assert"
)

func TestValidateMandatoryFieldsFail(t *testing.T) {
	config := data.Config{
		Location: "Earth",
	}

	assert.NotEqual(t, "", verifyMandatoryFields(config),
		"The validation should fail.")
}

func TestValidateMandatoryFieldsSuccess(t *testing.T) {
	config := data.Config{
		ID:       "test.mandatory.success",
		Env:      "int",
		Location: "Earth",
	}

	assert.Equal(t, "", verifyMandatoryFields(config),
		"The validation should not fail.")
}
<commit_msg>Prepare validation tests<commit_after>package validation

import (
	"testing"

	"github.com/appPlant/alpinepass/src/data"
	"github.com/stretchr/testify/assert"
)

func TestValidateCommonFieldsFail(t *testing.T) {
	config := data.Config{
		Location: "Earth",
	}

	assert.NotEqual(t, "", verifyCommonFields(config),
		"The validation should fail.")
}

func TestValidateCommonFieldsSuccess(t *testing.T) {
	config := data.Config{
		ID:       "test.mandatory.success",
		Env:      "int",
		Location: "Earth",
	}

	assert.Equal(t, "", verifyCommonFields(config),
		"The validation should not fail.")
}

func TestValidateTypeSuccess(t *testing.T) {

}

func TestValidateTypeFail(t *testing.T) {

}

func TestDbFieldsSuccess(t *testing.T) {

}

func TestDbFieldsFail(t *testing.T) {

}

func TestWebFieldsSuccess(t *testing.T) {

}

func TestWebFieldsFail(t *testing.T) {

}
<|endoftext|>


<commit_before>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

// The machiner package implements the API interface
// used by the uniter worker.
package uniter

import (
	"fmt"

	"launchpad.net/juju-core/state"
	"launchpad.net/juju-core/state/api/params"
	"launchpad.net/juju-core/state/apiserver/common"
)

// UniterAPI implements the API used by the uniter worker.
type UniterAPI struct {
	*common.LifeGetter
	*common.StatusSetter
	*common.DeadEnsurer
	*common.AgentEntityWatcher

	st         *state.State
	auth       common.Authorizer
	getCanRead common.GetAuthFunc
}

// NewUniterAPI creates a new instance of the Uniter API.
func NewUniterAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*UniterAPI, error) {
	if !authorizer.AuthUnitAgent() {
		return nil, common.ErrPerm
	}
	getCanRead := func() (common.AuthFunc, error) {
		return authorizer.AuthOwner, nil
	}
	return &UniterAPI{
		LifeGetter:         common.NewLifeGetter(st, getCanRead),
		StatusSetter:       common.NewStatusSetter(st, getCanRead),
		DeadEnsurer:        common.NewDeadEnsurer(st, getCanRead),
		AgentEntityWatcher: common.NewAgentEntityWatcher(st, resources, getCanRead),
		st:                 st,
		auth:               authorizer,
		getCanRead:         getCanRead,
	}, nil
}

func (u *UniterAPI) getUnit(tag string) (*state.Unit, error) {
	entity, err := u.st.FindEntity(tag)
	if err != nil {
		return nil, err
	}
	unit, ok := entity.(*state.Unit)
	if !ok {
		return nil, fmt.Errorf("entity %q is not a unit", tag)
	}
	return unit, nil
}

func (u *UniterAPI) PublicAddress(args params.Entities) (params.StringBoolResults, error) {
	result := params.StringBoolResults{
		Results: make([]params.StringBoolResult, len(args.Entities)),
	}
	if len(args.Entities) == 0 {
		return result, nil
	}
	canRead, err := u.getCanRead()
	if err != nil {
		return params.StringBoolResults{}, err
	}
	var unit *state.Unit
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if canRead(entity.Tag) {
			unit, err = u.getUnit(entity.Tag)
			if err == nil {
				address, ok := unit.PublicAddress()
				result.Results[i].Result = address
				result.Results[i].Ok = ok
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}

func (u *UniterAPI) SetPublicAddress(args params.SetEntityAddresses) (params.ErrorResults, error) {
	result := params.ErrorResults{
		Results: make([]params.ErrorResult, len(args.Entities)),
	}
	if len(args.Entities) == 0 {
		return result, nil
	}
	canModify, err := u.getCanRead()
	if err != nil {
		return params.ErrorResults{}, err
	}
	var unit *state.Unit
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if canModify(entity.Tag) {
			unit, err = u.getUnit(entity.Tag)
			if err == nil {
				err = unit.SetPublicAddress(entity.Address)
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}

func (u *UniterAPI) PrivateAddress(args params.Entities) (params.StringBoolResults, error) {
	result := params.StringBoolResults{
		Results: make([]params.StringBoolResult, len(args.Entities)),
	}
	if len(args.Entities) == 0 {
		return result, nil
	}
	canRead, err := u.getCanRead()
	if err != nil {
		return params.StringBoolResults{}, err
	}
	var unit *state.Unit
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if canRead(entity.Tag) {
			unit, err = u.getUnit(entity.Tag)
			if err == nil {
				address, ok := unit.PrivateAddress()
				result.Results[i].Result = address
				result.Results[i].Ok = ok
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}

func (u *UniterAPI) SetPrivateAddress(args params.SetEntityAddresses) (params.ErrorResults, error) {
	result := params.ErrorResults{
		Results: make([]params.ErrorResult, len(args.Entities)),
	}
	if len(args.Entities) == 0 {
		return result, nil
	}
	canModify, err := u.getCanRead()
	if err != nil {
		return params.ErrorResults{}, err
	}
	var unit *state.Unit
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if canModify(entity.Tag) {
			unit, err = u.getUnit(entity.Tag)
			if err == nil {
				err = unit.SetPrivateAddress(entity.Address)
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}

// TODO(dimitern): Add the other needed API calls.
<commit_msg>Changes after review<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

// The machiner package implements the API interface
// used by the uniter worker.
package uniter

import (
	"fmt"

	"launchpad.net/juju-core/state"
	"launchpad.net/juju-core/state/api/params"
	"launchpad.net/juju-core/state/apiserver/common"
)

// UniterAPI implements the API used by the uniter worker.
type UniterAPI struct {
	*common.LifeGetter
	*common.StatusSetter
	*common.DeadEnsurer
	*common.AgentEntityWatcher

	st         *state.State
	auth       common.Authorizer
	getCanRead common.GetAuthFunc
}

// NewUniterAPI creates a new instance of the Uniter API.
func NewUniterAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*UniterAPI, error) {
	if !authorizer.AuthUnitAgent() {
		return nil, common.ErrPerm
	}
	getCanRead := func() (common.AuthFunc, error) {
		return authorizer.AuthOwner, nil
	}
	return &UniterAPI{
		LifeGetter:         common.NewLifeGetter(st, getCanRead),
		StatusSetter:       common.NewStatusSetter(st, getCanRead),
		DeadEnsurer:        common.NewDeadEnsurer(st, getCanRead),
		AgentEntityWatcher: common.NewAgentEntityWatcher(st, resources, getCanRead),
		st:                 st,
		auth:               authorizer,
		getCanRead:         getCanRead,
	}, nil
}

func (u *UniterAPI) getUnit(tag string) (*state.Unit, error) {
	entity, err := u.st.FindEntity(tag)
	if err != nil {
		return nil, err
	}
	unit, ok := entity.(*state.Unit)
	if !ok {
		return nil, fmt.Errorf("entity %q is not a unit", tag)
	}
	return unit, nil
}

// PublicAddress returns for each given unit, a pair of the public
// address of the unit and whether it's valid.
func (u *UniterAPI) PublicAddress(args params.Entities) (params.StringBoolResults, error) {
	result := params.StringBoolResults{
		Results: make([]params.StringBoolResult, len(args.Entities)),
	}
	if len(args.Entities) == 0 {
		return result, nil
	}
	canRead, err := u.getCanRead()
	if err != nil {
		return params.StringBoolResults{}, err
	}
	var unit *state.Unit
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if canRead(entity.Tag) {
			unit, err = u.getUnit(entity.Tag)
			if err == nil {
				address, ok := unit.PublicAddress()
				result.Results[i].Result = address
				result.Results[i].Ok = ok
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}

// SetPrivateAddress sets the public address of each of the given units.
func (u *UniterAPI) SetPublicAddress(args params.SetEntityAddresses) (params.ErrorResults, error) {
	result := params.ErrorResults{
		Results: make([]params.ErrorResult, len(args.Entities)),
	}
	if len(args.Entities) == 0 {
		return result, nil
	}
	canModify, err := u.getCanRead()
	if err != nil {
		return params.ErrorResults{}, err
	}
	var unit *state.Unit
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if canModify(entity.Tag) {
			unit, err = u.getUnit(entity.Tag)
			if err == nil {
				err = unit.SetPublicAddress(entity.Address)
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}

// PrivateAddress returns for each given unit, a pair of the private
// address of the unit and whether it's valid.
func (u *UniterAPI) PrivateAddress(args params.Entities) (params.StringBoolResults, error) {
	result := params.StringBoolResults{
		Results: make([]params.StringBoolResult, len(args.Entities)),
	}
	if len(args.Entities) == 0 {
		return result, nil
	}
	canRead, err := u.getCanRead()
	if err != nil {
		return params.StringBoolResults{}, err
	}
	var unit *state.Unit
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if canRead(entity.Tag) {
			unit, err = u.getUnit(entity.Tag)
			if err == nil {
				address, ok := unit.PrivateAddress()
				result.Results[i].Result = address
				result.Results[i].Ok = ok
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}

// SetPrivateAddress sets the private address of each of the given units.
func (u *UniterAPI) SetPrivateAddress(args params.SetEntityAddresses) (params.ErrorResults, error) {
	result := params.ErrorResults{
		Results: make([]params.ErrorResult, len(args.Entities)),
	}
	if len(args.Entities) == 0 {
		return result, nil
	}
	canModify, err := u.getCanRead()
	if err != nil {
		return params.ErrorResults{}, err
	}
	var unit *state.Unit
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if canModify(entity.Tag) {
			unit, err = u.getUnit(entity.Tag)
			if err == nil {
				err = unit.SetPrivateAddress(entity.Address)
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}

// TODO(dimitern): Add the other needed API calls.
<|endoftext|>


<commit_before>package gateway

import (
	"fmt"
	"net/http"

	"encoding/json"

	"github.com/ReneGa/tweetcount-microservices/stopwordfilter/domain"
)

// Tweets is a gateway to a tweet producing service
type Tweets interface {
	Tweets(query string) domain.Tweets
}

type tweets struct {
	client http.Client
	url    string
}

func streamResponse(res *http.Response, data chan domain.Tweet, stop chan bool) bool {
	var tweet domain.Tweet
	jd := json.NewDecoder(res.Body)
	for {
		jd.Decode(&tweet)
		data <- tweet
	}
}
func (t *tweets) Tweets(query string) domain.Tweets {
	url := fmt.Sprintf("%s?q=%s", t.url, query)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		panic(err)
	}

	data := make(chan domain.Tweet)
	stop := make(chan bool)
	tweets := domain.Tweets{
		Data: data,
		Stop: stop,
	}
	go func() {
		reconnect := true
		for reconnect {
			res, err := t.client.Do(req)
			if err == nil {
				reconnect = streamResponse(res, data, stop)
			}
		}
	}()
	return tweets
}
<commit_msg>Implement tweets gateway<commit_after>package gateway

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

	"encoding/json"

	"github.com/ReneGa/tweetcount-microservices/stopwordfilter/domain"
)

// Tweets is a gateway to a tweet producing service
type Tweets interface {
	Tweets(query string) domain.Tweets
}

// NewTweets creates a new gateway to a tweets producing service
func NewTweets(client *http.Client, url string) Tweets {
	return &tweets{client, url}
}

type tweets struct {
	client *http.Client
	url    string
}

func streamResponse(res *http.Response, data chan domain.Tweet, stop chan bool) bool {
	defer res.Body.Close()
	var tweet domain.Tweet
	jd := json.NewDecoder(res.Body)
	for {
		select {
		case <-stop:
			return false
		default:
			err := jd.Decode(&tweet)
			if err != nil {
				return true
			}
			data <- tweet
		}
	}
}

func (t *tweets) Tweets(query string) domain.Tweets {
	url := fmt.Sprintf("%s?q=%s", t.url, query)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		panic(err)
	}

	data := make(chan domain.Tweet)
	stop := make(chan bool)

	tweets := domain.Tweets{
		Data: data,
		Stop: stop,
	}

	go func() {
		defer close(data)
		reconnect := true
		for reconnect {
			select {
			case <-stop:
				return
			default:
			}
			res, err := t.client.Do(req)
			if err == nil {
				reconnect = streamResponse(res, data, stop)
			} else {
				log.Println("Error: ", err)
			}
		}
	}()

	return tweets
}
<|endoftext|>


<commit_before>package websocket

import (
	"net"
	"time"

	ws "github.com/gorilla/websocket"
)

var _ net.Conn = (*Conn)(nil)

// Conn implements net.Conn interface for gorilla/websocket.
type Conn struct {
	*ws.Conn
	DefaultMessageType int
	done               func()
}

func (c *Conn) Read(b []byte) (n int, err error) {
	_, r, err := c.Conn.NextReader()
	if err != nil {
		return 0, err
	}

	return r.Read(b)
}

func (c *Conn) Write(b []byte) (n int, err error) {
	if err := c.Conn.WriteMessage(c.DefaultMessageType, b); err != nil {
		return 0, err
	}

	return len(b), nil
}

func (c *Conn) Close() error {
	if c.done != nil {
		c.done()
	}

	return c.Conn.Close()
}

func (c *Conn) LocalAddr() net.Addr {
	return c.Conn.LocalAddr()
}

func (c *Conn) RemoteAddr() net.Addr {
	return c.Conn.RemoteAddr()
}

func (c *Conn) SetDeadline(t time.Time) error {
	if err := c.SetReadDeadline(t); err != nil {
		return err
	}

	return c.SetWriteDeadline(t)
}

func (c *Conn) SetReadDeadline(t time.Time) error {
	return c.Conn.SetReadDeadline(t)
}

func (c *Conn) SetWriteDeadline(t time.Time) error {
	return c.Conn.SetWriteDeadline(t)
}

// NewConn creates a Conn given a regular gorilla/websocket Conn.
func NewConn(raw *ws.Conn, done func()) *Conn {
	return &Conn{
		Conn:               raw,
		DefaultMessageType: ws.BinaryMessage,
		done:               done,
	}
}
<commit_msg>fix reading from conn and addresses<commit_after>package websocket

import (
	"io"
	"net"
	"time"

	ws "github.com/gorilla/websocket"
)

var _ net.Conn = (*Conn)(nil)

// Conn implements net.Conn interface for gorilla/websocket.
type Conn struct {
	*ws.Conn
	DefaultMessageType int
	done               func()
	reader             io.Reader
}

func (c *Conn) Read(b []byte) (int, error) {
	if c.reader == nil {
		if err := c.prepNextReader(); err != nil {
			return 0, err
		}
	}

	n, err := c.reader.Read(b)
	if err == io.EOF {
		if err := c.prepNextReader(); err != nil {
			return 0, err
		}
		if n == 0 {
			n, err = c.reader.Read(b)
		}
	}

	return n, err
}

func (c *Conn) prepNextReader() error {
	_, r, err := c.Conn.NextReader()
	if err != nil {
		return err
	}

	c.reader = r
	return nil
}

func (c *Conn) Write(b []byte) (n int, err error) {
	if err := c.Conn.WriteMessage(c.DefaultMessageType, b); err != nil {
		return 0, err
	}

	return len(b), nil
}

func (c *Conn) Close() error {
	if c.done != nil {
		c.done()
	}

	return c.Conn.Close()
}

func (c *Conn) LocalAddr() net.Addr {
	return NewAddr(c.Conn.LocalAddr().String())
}

func (c *Conn) RemoteAddr() net.Addr {
	return NewAddr(c.Conn.RemoteAddr().String())
}

func (c *Conn) SetDeadline(t time.Time) error {
	if err := c.SetReadDeadline(t); err != nil {
		return err
	}

	return c.SetWriteDeadline(t)
}

func (c *Conn) SetReadDeadline(t time.Time) error {
	return c.Conn.SetReadDeadline(t)
}

func (c *Conn) SetWriteDeadline(t time.Time) error {
	return c.Conn.SetWriteDeadline(t)
}

// NewConn creates a Conn given a regular gorilla/websocket Conn.
func NewConn(raw *ws.Conn, done func()) *Conn {
	return &Conn{
		Conn:               raw,
		DefaultMessageType: ws.BinaryMessage,
		done:               done,
	}
}
<|endoftext|>