<commit_before>package activitypub

import (
	"reflect"
	"testing"
)

func TestObjectNew(t *testing.T) {
	var testValue = ObjectID("test")
	var testType = ArticleType

	o := ObjectNew(testValue, testType)

	if o.ID != testValue {
		t.Errorf("APObject Id '%v' different than expected '%v'", o.ID, testValue)
	}
	if o.Type != testType {
		t.Errorf("APObject Type '%v' different than expected '%v'", o.Type, testType)
	}

	n := ObjectNew(testValue, "")
	if n.ID != testValue {
		t.Errorf("APObject Id '%v' different than expected '%v'", n.ID, testValue)
	}
	if n.Type != ObjectType {
		t.Errorf("APObject Type '%v' different than expected '%v'", n.Type, ObjectType)
	}

}

func TestValidGenericType(t *testing.T) {
	for _, validType := range validGenericObjectTypes {
		if !ValidObjectType(validType) {
			t.Errorf("Generic Type '%v' should be valid", validType)
		}
	}
}

func TestValidObjectType(t *testing.T) {
	var invalidType ActivityVocabularyType = "RandomType"

	if ValidObjectType(invalidType) {
		t.Errorf("APObject Type '%v' should not be valid", invalidType)
	}
	for _, validType := range validObjectTypes {
		if !ValidObjectType(validType) {
			t.Errorf("APObject Type '%v' should be valid", validType)
		}
	}
}

func TestMarshalJSON(t *testing.T) {
	m := make(map[LangRef]string)
	m["en"] = "test"
	m["de"] = "test"

	n := NaturalLanguageValue(m)
	result, err := n.MarshalJSON()
	if err != nil {
		t.Errorf("Failed marshaling '%v'", err)
	}
	mRes := "{\"de\":\"test\",\"en\":\"test\"}"
	if string(result) != mRes {
		t.Errorf("Different results '%v' vs. '%v'", string(result), mRes)
	}

	s := make(map[LangRef]string)
	s["en"] = "test"
	n1 := NaturalLanguageValue(s)
	result1, err1 := n1.MarshalJSON()
	if err1 != nil {
		t.Errorf("Failed marshaling '%v'", err1)
	}
	mRes1 := "\"test\""
	if string(result1) != mRes1 {
		t.Errorf("Different results '%v' vs. '%v'", string(result1), mRes1)
	}
}

func TestNaturalLanguageValue_MarshalJSON(t *testing.T) {
	p := make(NaturalLanguageValue, 2)
	p["en"] = "the test"
	p["fr"] = "le test"

	js := "{\"en\":\"the test\",\"fr\":\"le test\"}"
	out, err := p.MarshalJSON()

	if err != nil {
		t.Errorf("Error: '%s'", err)
	}
	if js != string(out) {
		t.Errorf("Different marshal result '%s', instead of '%s'", out, js)
	}
	p1 := make(NaturalLanguageValue, 1)
	p1["en"] = "the test"

	out1, err1 := p1.MarshalJSON()

	if err1 != nil {
		t.Errorf("Error: '%s'", err1)
	}
	txt := "\"the test\""
	if txt != string(out1) {
		t.Errorf("Different marshal result '%s', instead of '%s'", out1, txt)
	}
}

func TestObject_IsLink(t *testing.T) {
	o := ObjectNew("test", ObjectType)
	if o.IsLink() {
		t.Errorf("%#v should not be a valid link", o.Type)
	}
	m := ObjectNew("test", AcceptType)
	if m.IsLink() {
		t.Errorf("%#v should not be a valid link", m.Type)
	}
}

func TestObject_IsObject(t *testing.T) {
	o := ObjectNew("test", ObjectType)
	if !o.IsObject() {
		t.Errorf("%#v should be a valid object", o.Type)
	}
	m := ObjectNew("test", AcceptType)
	if !m.IsObject() {
		t.Errorf("%#v should be a valid object", m.Type)
	}
}

func TestObject_Link(t *testing.T) {
	o := ObjectNew("test", ObjectType)
	if !reflect.DeepEqual(Link{}, o.Link()) {
		t.Errorf("%#v should be an empty Link object", o.Link())
	}
}

func TestObjectsArr_Append(t *testing.T) {
	d := make(ObjectsArr, 0)

	val := apObject{ID: ObjectID("grrr")}

	d.Append(val)

	if len(d) != 1 {
		t.Errorf("Objects array should have exactly an element")
	}
	if !reflect.DeepEqual(d[0], val) {
		t.Errorf("First item in object array does not match %q", val.ID)
	}
}

func TestRecipientsDeduplication(t *testing.T) {
	bob := PersonNew("bob")
	alice := PersonNew("alice")
	foo := OrganizationNew("foo")
	bar := GroupNew("bar")

	first := make(ObjectsArr, 0)
	if len(first) != 0 {
		t.Errorf("Objects array should have exactly an element")
	}

	first.Append(bob)
	first.Append(alice)
	first.Append(foo)
	first.Append(bar)
	if len(first) != 4 {
		t.Errorf("Objects array should have exactly 4(four) elements, not %d", len(first))
	}

	first.Append(bar)
	first.Append(alice)
	first.Append(foo)
	first.Append(bob)
	if len(first) != 8 {
		t.Errorf("Objects array should have exactly 8(eight) elements, not %d", len(first))
	}

	RecipientsDeduplication(&first)
	if len(first) != 4 {
		t.Errorf("Objects array should have exactly 4(four) elements, not %d", len(first))
	}

	second := make(ObjectsArr, 0)
	second.Append(bar)
	second.Append(foo)

	RecipientsDeduplication(&first, &second)
	if len(first) != 4 {
		t.Errorf("First Objects array should have exactly 8(eight) elements, not %d", len(first))
	}
	if len(second) != 0 {
		t.Errorf("Second Objects array should have exactly 0(zero) elements, not %d", len(second))
	}
}
<commit_msg>Make sure we can receive an null pointer when testing for duplicates<commit_after>package activitypub

import (
	"reflect"
	"testing"
)

func TestObjectNew(t *testing.T) {
	var testValue = ObjectID("test")
	var testType = ArticleType

	o := ObjectNew(testValue, testType)

	if o.ID != testValue {
		t.Errorf("APObject Id '%v' different than expected '%v'", o.ID, testValue)
	}
	if o.Type != testType {
		t.Errorf("APObject Type '%v' different than expected '%v'", o.Type, testType)
	}

	n := ObjectNew(testValue, "")
	if n.ID != testValue {
		t.Errorf("APObject Id '%v' different than expected '%v'", n.ID, testValue)
	}
	if n.Type != ObjectType {
		t.Errorf("APObject Type '%v' different than expected '%v'", n.Type, ObjectType)
	}

}

func TestValidGenericType(t *testing.T) {
	for _, validType := range validGenericObjectTypes {
		if !ValidObjectType(validType) {
			t.Errorf("Generic Type '%v' should be valid", validType)
		}
	}
}

func TestValidObjectType(t *testing.T) {
	var invalidType ActivityVocabularyType = "RandomType"

	if ValidObjectType(invalidType) {
		t.Errorf("APObject Type '%v' should not be valid", invalidType)
	}
	for _, validType := range validObjectTypes {
		if !ValidObjectType(validType) {
			t.Errorf("APObject Type '%v' should be valid", validType)
		}
	}
}

func TestMarshalJSON(t *testing.T) {
	m := make(map[LangRef]string)
	m["en"] = "test"
	m["de"] = "test"

	n := NaturalLanguageValue(m)
	result, err := n.MarshalJSON()
	if err != nil {
		t.Errorf("Failed marshaling '%v'", err)
	}
	mRes := "{\"de\":\"test\",\"en\":\"test\"}"
	if string(result) != mRes {
		t.Errorf("Different results '%v' vs. '%v'", string(result), mRes)
	}

	s := make(map[LangRef]string)
	s["en"] = "test"
	n1 := NaturalLanguageValue(s)
	result1, err1 := n1.MarshalJSON()
	if err1 != nil {
		t.Errorf("Failed marshaling '%v'", err1)
	}
	mRes1 := "\"test\""
	if string(result1) != mRes1 {
		t.Errorf("Different results '%v' vs. '%v'", string(result1), mRes1)
	}
}

func TestNaturalLanguageValue_MarshalJSON(t *testing.T) {
	p := make(NaturalLanguageValue, 2)
	p["en"] = "the test"
	p["fr"] = "le test"

	js := "{\"en\":\"the test\",\"fr\":\"le test\"}"
	out, err := p.MarshalJSON()

	if err != nil {
		t.Errorf("Error: '%s'", err)
	}
	if js != string(out) {
		t.Errorf("Different marshal result '%s', instead of '%s'", out, js)
	}
	p1 := make(NaturalLanguageValue, 1)
	p1["en"] = "the test"

	out1, err1 := p1.MarshalJSON()

	if err1 != nil {
		t.Errorf("Error: '%s'", err1)
	}
	txt := "\"the test\""
	if txt != string(out1) {
		t.Errorf("Different marshal result '%s', instead of '%s'", out1, txt)
	}
}

func TestObject_IsLink(t *testing.T) {
	o := ObjectNew("test", ObjectType)
	if o.IsLink() {
		t.Errorf("%#v should not be a valid link", o.Type)
	}
	m := ObjectNew("test", AcceptType)
	if m.IsLink() {
		t.Errorf("%#v should not be a valid link", m.Type)
	}
}

func TestObject_IsObject(t *testing.T) {
	o := ObjectNew("test", ObjectType)
	if !o.IsObject() {
		t.Errorf("%#v should be a valid object", o.Type)
	}
	m := ObjectNew("test", AcceptType)
	if !m.IsObject() {
		t.Errorf("%#v should be a valid object", m.Type)
	}
}

func TestObject_Link(t *testing.T) {
	o := ObjectNew("test", ObjectType)
	if !reflect.DeepEqual(Link{}, o.Link()) {
		t.Errorf("%#v should be an empty Link object", o.Link())
	}
}

func TestObjectsArr_Append(t *testing.T) {
	d := make(ObjectsArr, 0)

	val := apObject{ID: ObjectID("grrr")}

	d.Append(val)

	if len(d) != 1 {
		t.Errorf("Objects array should have exactly an element")
	}
	if !reflect.DeepEqual(d[0], val) {
		t.Errorf("First item in object array does not match %q", val.ID)
	}
}

func TestRecipientsDeduplication(t *testing.T) {
	bob := PersonNew("bob")
	alice := PersonNew("alice")
	foo := OrganizationNew("foo")
	bar := GroupNew("bar")

	first := make(ObjectsArr, 0)
	if len(first) != 0 {
		t.Errorf("Objects array should have exactly an element")
	}

	first.Append(bob)
	first.Append(alice)
	first.Append(foo)
	first.Append(bar)
	if len(first) != 4 {
		t.Errorf("Objects array should have exactly 4(four) elements, not %d", len(first))
	}

	first.Append(bar)
	first.Append(alice)
	first.Append(foo)
	first.Append(bob)
	if len(first) != 8 {
		t.Errorf("Objects array should have exactly 8(eight) elements, not %d", len(first))
	}

	RecipientsDeduplication(&first)
	if len(first) != 4 {
		t.Errorf("Objects array should have exactly 4(four) elements, not %d", len(first))
	}

	second := make(ObjectsArr, 0)
	second.Append(bar)
	second.Append(foo)

	RecipientsDeduplication(&first, &second)
	if len(first) != 4 {
		t.Errorf("First Objects array should have exactly 8(eight) elements, not %d", len(first))
	}
	if len(second) != 0 {
		t.Errorf("Second Objects array should have exactly 0(zero) elements, not %d", len(second))
	}

	err := RecipientsDeduplication(&first, &second, nil)
	if err != nil {
		t.Errorf("Deduplication with empty array failed")
	}
}
<|endoftext|>


<commit_before>package distribution

import (
	"net/http"
	"net/http/httptest"
	"os"
	"strings"
	"testing"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/reference"
	"github.com/docker/docker/registry"
	"github.com/docker/docker/utils"
	"github.com/docker/engine-api/types"
	registrytypes "github.com/docker/engine-api/types/registry"
	"golang.org/x/net/context"
)

func TestTokenPassThru(t *testing.T) {
	authConfig := &types.AuthConfig{
		RegistryToken: "mysecrettoken",
	}
	gotToken := false
	handler := func(w http.ResponseWriter, r *http.Request) {
		if strings.Contains(r.Header.Get("Authorization"), authConfig.RegistryToken) {
			logrus.Debug("Detected registry token in auth header")
			gotToken = true
		}
		if r.RequestURI == "/v2/" {
			w.Header().Set("WWW-Authenticate", `Bearer realm="foorealm"`)
			w.WriteHeader(401)
		}
	}
	ts := httptest.NewServer(http.HandlerFunc(handler))
	defer ts.Close()

	tmp, err := utils.TestDirectory("")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmp)

	endpoint := registry.APIEndpoint{
		Mirror:       false,
		URL:          ts.URL,
		Version:      2,
		Official:     false,
		TrimHostname: false,
		TLSConfig:    nil,
		//VersionHeader: "verheader",
	}
	n, _ := reference.ParseNamed("testremotename")
	repoInfo := &registry.RepositoryInfo{
		Named: n,
		Index: &registrytypes.IndexInfo{
			Name:     "testrepo",
			Mirrors:  nil,
			Secure:   false,
			Official: false,
		},
		Official: false,
	}
	imagePullConfig := &ImagePullConfig{
		MetaHeaders: http.Header{},
		AuthConfig:  authConfig,
	}
	puller, err := newPuller(endpoint, repoInfo, imagePullConfig)
	if err != nil {
		t.Fatal(err)
	}
	p := puller.(*v2Puller)
	ctx := context.Background()
	p.repo, _, err = NewV2Repository(ctx, p.repoInfo, p.endpoint, p.config.MetaHeaders, p.config.AuthConfig, "pull")
	if err != nil {
		t.Fatal(err)
	}

	logrus.Debug("About to pull")
	// We expect it to fail, since we haven't mock'd the full registry exchange in our handler above
	tag, _ := reference.WithTag(n, "tag_goes_here")
	_ = p.pullV2Repository(ctx, tag)

	if !gotToken {
		t.Fatal("Failed to receive registry token")
	}

}
<commit_msg>distribution: add test to ensure pass-thru registry token is host-bound<commit_after>package distribution

import (
	"net/http"
	"net/http/httptest"
	"os"
	"strings"
	"testing"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/reference"
	"github.com/docker/docker/registry"
	"github.com/docker/docker/utils"
	"github.com/docker/engine-api/types"
	registrytypes "github.com/docker/engine-api/types/registry"
	"golang.org/x/net/context"
)

const secretRegistryToken = "mysecrettoken"

type tokenPassThruHandler struct {
	reached       bool
	gotToken      bool
	shouldSend401 func(url string) bool
}

func (h *tokenPassThruHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.reached = true
	if strings.Contains(r.Header.Get("Authorization"), secretRegistryToken) {
		logrus.Debug("Detected registry token in auth header")
		h.gotToken = true
	}
	if h.shouldSend401 == nil || h.shouldSend401(r.RequestURI) {
		w.Header().Set("WWW-Authenticate", `Bearer realm="foorealm"`)
		w.WriteHeader(401)
	}
}

func testTokenPassThru(t *testing.T, ts *httptest.Server) {
	tmp, err := utils.TestDirectory("")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmp)

	endpoint := registry.APIEndpoint{
		Mirror:       false,
		URL:          ts.URL,
		Version:      2,
		Official:     false,
		TrimHostname: false,
		TLSConfig:    nil,
		//VersionHeader: "verheader",
	}
	n, _ := reference.ParseNamed("testremotename")
	repoInfo := &registry.RepositoryInfo{
		Named: n,
		Index: &registrytypes.IndexInfo{
			Name:     "testrepo",
			Mirrors:  nil,
			Secure:   false,
			Official: false,
		},
		Official: false,
	}
	imagePullConfig := &ImagePullConfig{
		MetaHeaders: http.Header{},
		AuthConfig: &types.AuthConfig{
			RegistryToken: secretRegistryToken,
		},
	}
	puller, err := newPuller(endpoint, repoInfo, imagePullConfig)
	if err != nil {
		t.Fatal(err)
	}
	p := puller.(*v2Puller)
	ctx := context.Background()
	p.repo, _, err = NewV2Repository(ctx, p.repoInfo, p.endpoint, p.config.MetaHeaders, p.config.AuthConfig, "pull")
	if err != nil {
		t.Fatal(err)
	}

	logrus.Debug("About to pull")
	// We expect it to fail, since we haven't mock'd the full registry exchange in our handler above
	tag, _ := reference.WithTag(n, "tag_goes_here")
	_ = p.pullV2Repository(ctx, tag)
}

func TestTokenPassThru(t *testing.T) {
	handler := &tokenPassThruHandler{shouldSend401: func(url string) bool { return url == "/v2/" }}
	ts := httptest.NewServer(handler)
	defer ts.Close()

	testTokenPassThru(t, ts)

	if !handler.reached {
		t.Fatal("Handler not reached")
	}
	if !handler.gotToken {
		t.Fatal("Failed to receive registry token")
	}
}

func TestTokenPassThruDifferentHost(t *testing.T) {
	handler := new(tokenPassThruHandler)
	ts := httptest.NewServer(handler)
	defer ts.Close()

	tsredirect := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.RequestURI == "/v2/" {
			w.Header().Set("WWW-Authenticate", `Bearer realm="foorealm"`)
			w.WriteHeader(401)
			return
		}
		http.Redirect(w, r, ts.URL+r.URL.Path, http.StatusMovedPermanently)
	}))
	defer tsredirect.Close()

	testTokenPassThru(t, tsredirect)

	if !handler.reached {
		t.Fatal("Handler not reached")
	}
	if handler.gotToken {
		t.Fatal("Redirect should not forward Authorization header to another host")
	}
}
<|endoftext|>


<commit_before><commit_msg>fix crash on start if .config/goatee/goatee.conf file not exist<commit_after><|endoftext|>


<commit_before>package service

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"

	"github.com/spf13/cobra"
	"stash.ovh.net/sailabove/sail/internal"
)

var (
	logsBody Logs
)

func logsCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "logs",
		Short: "Logs of a docker service : sail service logs <applicationName>/<serviceId>",
		Long:  `Logs of a docker service : sail service logs <applicationName>/<serviceId>`,
		Run:   cmdLogs,
	}

	cmd.Flags().IntVarP(&logsBody.Tail, "tail", "", 0, "Return N last lines, before offset")
	cmd.Flags().IntVarP(&logsBody.Head, "head", "", 0, "Return N first lines, after offset")
	cmd.Flags().IntVarP(&logsBody.Offset, "offset", "", 0, "Offset result by N line")
	cmd.Flags().StringVarP(&logsBody.Period, "period", "", "24 hours ago", "Lucene compatible period")
	cmd.Flags().StringVarP(&logsBody.Search, "search", "", "", "Only return matching lines")

	return cmd
}

// Logs struct holds all parameters sent to /applications/%s/services/%s/logs
type Logs struct {
	Application string `json:"-"`
	Service     string `json:"-"`

	Repository string `json:"repository,omitempty"`
	Tail       int    `json:"tail,omitempty"`
	Head       int    `json:"head,omitempty"`
	Offset     int    `json:"offset,omitempty"`
	Period     string `json:"period,omitempty"`
	Search     string `json:"search,omitempty"`
}

func cmdLogs(cmd *cobra.Command, args []string) {
	usage := "Invalid usage. sail service logs <applicationName>/<serviceId>. Please see sail service logs --help\n"
	if len(args) != 1 {
		fmt.Printf(usage)
		return
	}

	split := strings.Split(args[0], "/")
	if len(split) != 2 {
		fmt.Printf(usage)
		return
	}

	// Get args
	logsBody.Application = split[0]
	logsBody.Service = split[1]
	serviceLogs(logsBody)
}

func serviceLogs(args Logs) {

	path := fmt.Sprintf("/applications/%s/services/%s/logs", args.Application, args.Service)
	body, err := json.MarshalIndent(args, " ", " ")
	if err != nil {
		fmt.Printf("Fatal: %s\n", err)
		return
	}

	ret := internal.ReqWant("GET", http.StatusOK, path, body)
	e := internal.DecodeError(ret)
	if e != nil {
		fmt.Printf("Error:%s\n", e)
	} else {
		fmt.Printf("%s\n", ret)
	}

}
<commit_msg>(fix) services logs weren't pretty print<commit_after>package service

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"

	"github.com/spf13/cobra"
	"stash.ovh.net/sailabove/sail/internal"
)

var (
	logsBody Logs
)

func logsCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "logs",
		Short: "Logs of a docker service : sail service logs <applicationName>/<serviceId>",
		Long:  `Logs of a docker service : sail service logs <applicationName>/<serviceId>`,
		Run:   cmdLogs,
	}

	cmd.Flags().IntVarP(&logsBody.Tail, "tail", "", 0, "Return N last lines, before offset")
	cmd.Flags().IntVarP(&logsBody.Head, "head", "", 0, "Return N first lines, after offset")
	cmd.Flags().IntVarP(&logsBody.Offset, "offset", "", 0, "Offset result by N line")
	cmd.Flags().StringVarP(&logsBody.Period, "period", "", "24 hours ago", "Lucene compatible period")
	cmd.Flags().StringVarP(&logsBody.Search, "search", "", "", "Only return matching lines")

	return cmd
}

// Logs struct holds all parameters sent to /applications/%s/services/%s/logs
type Logs struct {
	Application string `json:"-"`
	Service     string `json:"-"`

	Repository string `json:"repository,omitempty"`
	Tail       int    `json:"tail,omitempty"`
	Head       int    `json:"head,omitempty"`
	Offset     int    `json:"offset,omitempty"`
	Period     string `json:"period,omitempty"`
	Search     string `json:"search,omitempty"`
}

func cmdLogs(cmd *cobra.Command, args []string) {
	usage := "Invalid usage. sail service logs <applicationName>/<serviceId>. Please see sail service logs --help\n"
	if len(args) != 1 {
		fmt.Printf(usage)
		return
	}

	split := strings.Split(args[0], "/")
	if len(split) != 2 {
		fmt.Printf(usage)
		return
	}

	// Get args
	logsBody.Application = split[0]
	logsBody.Service = split[1]
	serviceLogs(logsBody)
}

func serviceLogs(args Logs) {

	path := fmt.Sprintf("/applications/%s/services/%s/logs", args.Application, args.Service)
	body, err := json.MarshalIndent(args, " ", " ")
	if err != nil {
		fmt.Printf("Fatal: %s\n", err)
		return
	}

	fmt.Println(internal.ReqWantJSON("GET", http.StatusOK, path, body))
}
<|endoftext|>


<commit_before>//
// DISCLAIMER
//
// Copyright 2017 ArangoDB GmbH, Cologne, Germany
//
// 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.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Author Ewout Prangsma
//

package service

type ServiceMode string

const (
	ServiceModeCluster_        = ServiceMode("cluster")
	ServiceModeSingle_         = ServiceMode("single")
	ServiceModeActiveFailover_ = ServiceMode("activefailover")
)

// IsClusterMode returns true when the service is running in cluster mode.
func (m ServiceMode) IsClusterMode() bool {
	return m == "cluster"
}

// IsSingleMode returns true when the service is running in single server mode.
func (m ServiceMode) IsSingleMode() bool {
	return m == "single"
}

// IsActiveFailoverMode returns true when the service is running in activefailover server mode.
func (m ServiceMode) IsActiveFailoverMode() bool {
	return m == "activefailover" || m == "resilientsingle" /* keep as alias */
}

// SupportsArangoSync returns true when the given mode support running arangosync on it.
func (m ServiceMode) SupportsArangoSync() bool {
	return m.IsClusterMode()
}

// SupportsRecovery returns true when the given mode support recovering from permanent failed machines.
func (m ServiceMode) SupportsRecovery() bool {
	return m == "" || m.IsClusterMode() || m.IsActiveFailoverMode()
}
<commit_msg>Removed obsolete constants<commit_after>//
// DISCLAIMER
//
// Copyright 2017 ArangoDB GmbH, Cologne, Germany
//
// 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.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Author Ewout Prangsma
//

package service

type ServiceMode string

// IsClusterMode returns true when the service is running in cluster mode.
func (m ServiceMode) IsClusterMode() bool {
	return m == "cluster"
}

// IsSingleMode returns true when the service is running in single server mode.
func (m ServiceMode) IsSingleMode() bool {
	return m == "single"
}

// IsActiveFailoverMode returns true when the service is running in activefailover server mode.
func (m ServiceMode) IsActiveFailoverMode() bool {
	return m == "activefailover" || m == "resilientsingle" /* keep as alias */
}

// SupportsArangoSync returns true when the given mode support running arangosync on it.
func (m ServiceMode) SupportsArangoSync() bool {
	return m.IsClusterMode()
}

// SupportsRecovery returns true when the given mode support recovering from permanent failed machines.
func (m ServiceMode) SupportsRecovery() bool {
	return m == "" || m.IsClusterMode() || m.IsActiveFailoverMode()
}
<|endoftext|>


<commit_before>/* @see https://github.com/chjj/pty.js/blob/master/src/unix/pty.cc */
package main

/*
 #cgo LDFLAGS: -lutil

 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>

 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <pty.h>
 #include <termios.h>

 #include <stdio.h>
 #include <stdint.h>

 int GoGetproc(int fd, char *tty) {
    FILE *f;
    char *path, *buf;
    size_t len;
    int ch;
    pid_t pgrp;
    int r;

    if ((pgrp == tcgetgrp(fd)) == -1 {
        return NULL;
    }

    r = asprintf(&path, "/proc/%11d/cmdline", (long long)pgrp);
    if (r == -1 || path == NULL) return NULL;

    if ((f = fopen(path, "r")) == NULL) {
        free(path);
        return NULL;
    }

    free(path);

    len = 0;
    buf = NULL;
    while ((ch = fgetc(f)) != EOF) {
        if (ch == '\0') break;
        buf = (char *) realloc(buf, len + 2);
        if (buf == NULL) return NULL;
        buf[len++] = ch;
    }

    if (buf != NULL) {
        buf[len] = '\0';
    }

    fclose(f);
    return buf;
 }

 int GoOpenpty(int *amaster, int *aslave, char *name,
               struct winsize *winp) {
    return openpty(amaster, aslave, name, NULL, winp);
 }

 int GoForkpty(int *amaster, char *name, struct winsize *winp) {
    return forkpty(amaster, name, NULL, winp);
 }

 int GoResize(int fd, struct winsize *winp) {
 	return ioctl(fd, TIOCSWINSZ, winp);
 }

 */
import "C"
import (
    "syscall"
)

type Terminal struct {
    fd int
    pid int
    pty string
}

func (t *Terminal) fork(filename string, args []string, env []string, cwd string, cols int, rows int, uid int, gid int) error {

    var winp = new(C.struct_winsize)
    winp.ws_col = C.int(cols)
    winp.ws_row = C.int(rows)
    winp.ws_xpixel = 0
    winp.ws_ypixel = 0

    //fork the pty
    var master C.int = -1
    var name []C.char = make([]C.char, 40)
    var pid C.int = C.GoForkpty(&master, &name[0], winp)

    t.fd = int(master)
    t.pid = int(pid)
    t.pty = C.GoString(&name[0])

    switch t.pid {
    case -1:
        return PtyError("forkpty(3) failed")
    case  0:
        if cwd != "" {
            if err := syscall.Chdir(cwd); err != nil {
                panic("chdir failed")
            }
        }

        if uid != -1 && gid != -1 {
            if err := syscall.Setgid(gid); err != nil {
                panic("setgid failed")
            }

            if err := syscall.Setuid(uid); err != nil {
                panic("setuid failed")
            }
        }

        syscall.Exec(filename, argv, env)
        panic("exec failed")
    default:
        if err := syscall.SetNonblock(t.fd, true); err != nil {
            return err
        }
    }

    return nil
}

func (t *Terminal) open(cols int, rows int) error {
    var winp = new(C.struct_winsize)
    winp.ws_col = C.int(cols)
    winp.ws_row = C.int(rows)
    winp.ws_xpixel = 0
    winp.ws_ypixel = 0

    var master, slave C.int
    var name = make([]C.char, 40)

    if ret := int(C.GoOpenPty(&master, &slave, &name[0], &winp)); ret == -1 {
        return PtyError("openpty(3) failed")
    }

    t.fd = int(master)
    t.pid = int(slave)
    t.pty = C.GoString(&name[0])

    if err := syscall.SetNonblock(t.fd, true); err != nil {
        return err
    }

    if err := syscall.SetNonblock(t.pid, true); err != nil {
        return err
    }
    return nil
}

func (t *Terminal) resize(cols int, rows int) error {
    var winp = new(C.struct_winsize)
    winp.ws_col = C.int(cols)
    winp.ws_row = C.int(rows)
    winp.ws_xpixel = 0
    winp.ws_ypixel = 0

    if ret := int(C.GoResize(t.fd, &winp); ret == -1 {
        return PtyError("ioctl(2) failed")
    }

    return nil
}

func (t *Terminal) getproc() string {
    fd   := C.int(t.fd)
    tty  := C.CString(t.pty)
    name := C.GoString(C.GoGetproc(fd, tty))

    return name
}
<commit_msg>Fixed compile errors with serviced/pty.js<commit_after>/* @see https://github.com/chjj/pty.js/blob/master/src/unix/pty.cc */
package main

/*
 #cgo LDFLAGS: -lutil

 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>

 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <pty.h>
 #include <termios.h>

 #include <stdio.h>
 #include <stdint.h>

 char *GoGetproc(int fd, char *tty) {
    FILE *f;
    char *path, *buf;
    size_t len;
    int ch;
    pid_t pgrp;
    int r;

    if ((pgrp = tcgetpgrp(fd)) == -1) {
        return NULL;
    }

    r = asprintf(&path, "/proc/%11d/cmdline", (long long)pgrp);
    if (r == -1 || path == NULL) return NULL;

    if ((f = fopen(path, "r")) == NULL) {
        free(path);
        return NULL;
    }

    free(path);

    len = 0;
    buf = NULL;
    while ((ch = fgetc(f)) != EOF) {
        if (ch == '\0') break;
        buf = (char *) realloc(buf, len + 2);
        if (buf == NULL) return NULL;
        buf[len++] = ch;
    }

    if (buf != NULL) {
        buf[len] = '\0';
    }

    fclose(f);
    return buf;
 }

 int GoOpenpty(int *amaster, int *aslave, char *name,
               struct winsize *winp) {
    return openpty(amaster, aslave, name, NULL, winp);
 }

 int GoForkpty(int *amaster, char *name, struct winsize *winp) {
    return forkpty(amaster, name, NULL, winp);
 }

 int GoResize(int fd, struct winsize *winp) {
 	return ioctl(fd, TIOCSWINSZ, winp);
 }

 */
import "C"
import (
    "syscall"
    "errors"
)

type Terminal struct {
    fd int
    pid int
    pty string
}

func (t *Terminal) fork(filename string, args []string, env []string, cwd string, cols int, rows int, uid int, gid int) error {

    var winp = new(C.struct_winsize)
    winp.ws_col = C.ushort(cols)
    winp.ws_row = C.ushort(rows)
    winp.ws_xpixel = 0
    winp.ws_ypixel = 0

    //fork the pty
    var master C.int = -1
    var name []C.char = make([]C.char, 40)
    var pid C.int = C.GoForkpty(&master, &name[0], winp)

    t.fd = int(master)
    t.pid = int(pid)
    t.pty = C.GoString(&name[0])

    switch t.pid {
    case -1:
        return errors.New("forkpty(3) failed")
    case  0:
        if cwd != "" {
            if err := syscall.Chdir(cwd); err != nil {
                panic("chdir failed")
            }
        }

        if uid != -1 && gid != -1 {
            if err := syscall.Setgid(gid); err != nil {
                panic("setgid failed")
            }

            if err := syscall.Setuid(uid); err != nil {
                panic("setuid failed")
            }
        }

        syscall.Exec(filename, args, env)
        panic("exec failed")
    default:
        if err := syscall.SetNonblock(t.fd, true); err != nil {
            return err
        }
    }

    return nil
}

func (t *Terminal) open(cols int, rows int) error {
    var winp = new(C.struct_winsize)
    winp.ws_col = C.ushort(cols)
    winp.ws_row = C.ushort(rows)
    winp.ws_xpixel = 0
    winp.ws_ypixel = 0

    var master, slave C.int
    var name = make([]C.char, 40)

    if ret := int(C.GoOpenpty(&master, &slave, &name[0], winp)); ret == -1 {
        return errors.New("openpty(3) failed")
    }

    t.fd = int(master)
    t.pid = int(slave)
    t.pty = C.GoString(&name[0])

    if err := syscall.SetNonblock(t.fd, true); err != nil {
        return err
    }

    if err := syscall.SetNonblock(t.pid, true); err != nil {
        return err
    }
    return nil
}

func (t *Terminal) resize(cols int, rows int) error {
    var winp = new(C.struct_winsize)
    winp.ws_col = C.ushort(cols)
    winp.ws_row = C.ushort(rows)
    winp.ws_xpixel = 0
    winp.ws_ypixel = 0

    if ret := int(C.GoResize(C.int(t.fd), winp)); ret == -1 {
        return errors.New("ioctl(2) failed")
    }

    return nil
}

func (t *Terminal) getproc() string {
    fd   := C.int(t.fd)
    tty  := C.CString(t.pty)
    name := C.GoString(C.GoGetproc(fd, tty))

    return name
}
<|endoftext|>


<commit_before>package services

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"net/url"
	"regexp"
	"strings"

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

	"github.com/cloudfoundry-incubator/cf-test-helpers/runner"
)

type OAuthConfig struct {
	ClientId              string
	ClientSecret          string
	RedirectUri           string
	RequestedScopes       string
	AuthorizationEndpoint string
	TokenEndpoint         string
}

func ParseJsonResponse(response []byte) (resultMap map[string]interface{}) {
	var jsonValue interface{}

	json.Unmarshal(response, &jsonValue)
	resultMap = jsonValue.(map[string]interface{})
	return
}

func SetOauthEndpoints(apiEndpoint string, config *OAuthConfig) {
	url := fmt.Sprintf("%v/info", apiEndpoint)
	curl := runner.Curl(url).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := curl.Out.Contents()
	jsonResult := ParseJsonResponse(apiResponse)

	config.TokenEndpoint = fmt.Sprintf("%v", jsonResult[`token_endpoint`])
	config.AuthorizationEndpoint = fmt.Sprintf("%v", jsonResult[`authorization_endpoint`])
	return
}

func AuthenticateUser(authorizationEndpoint string, username string, password string) (cookie string) {
	loginUri := fmt.Sprintf("%v/login.do", authorizationEndpoint)
	usernameEncoded := url.QueryEscape(username)
	passwordEncoded := url.QueryEscape(password)
	loginCredentials := fmt.Sprintf("username=%v&password=%v", usernameEncoded, passwordEncoded)

	curl := runner.Curl(loginUri, `--data`, loginCredentials, `--insecure`, `-i`, `-v`).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := string(curl.Out.Contents())

	jsessionRegEx, _ := regexp.Compile(`JSESSIONID([^;]*)`)
	vcapidRegEx, _ := regexp.Compile(`__VCAP_ID__([^;]*)`)
	sessionId := jsessionRegEx.FindString(apiResponse)
	vcapId := vcapidRegEx.FindString(apiResponse)
	cookie = fmt.Sprintf("%v;%v", sessionId, vcapId)
	return
}

func RequestScopes(cookie string, config OAuthConfig) (authCode string, httpCode string) {
	authCode = `initialized`

	requestScopesUri := fmt.Sprintf("%v/oauth/authorize?client_id=%v&response_type=code+id_token&redirect_uri=%v&scope=%v",
		config.AuthorizationEndpoint,
		url.QueryEscape(config.ClientId),
		config.RedirectUri,
		config.RequestedScopes)

	curl := runner.Curl(requestScopesUri, `-L`, `--cookie`, cookie, `--insecure`, `-w`, `:TestReponseCode:%{http_code}`, `-v`).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := string(curl.Out.Contents())
	resultMap := strings.Split(apiResponse, `:TestReponseCode:`)

	httpCode = resultMap[1]

	if httpCode == `200` {
		authCode = AuthorizeScopes(cookie, config)
	}

	return
}

func AuthorizeScopes(cookie string, config OAuthConfig) (authCode string) {
	authorizedScopes := `scope.0=scope.openid&scope.1=scope.cloud_controller.read&scope.2=scope.cloud_controller.write&user_oauth_approval=true`
	authorizeScopesUri := fmt.Sprintf("%v/oauth/authorize", config.AuthorizationEndpoint)

	curl := runner.Curl(authorizeScopesUri, `-i`, `--data`, authorizedScopes, `--cookie`, cookie, `--insecure`, `-v`).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := string(curl.Out.Contents())

	pattern := fmt.Sprintf(`%v\?code=([a-zA-Z0-9]+)`, regexp.QuoteMeta(config.RedirectUri))
	regEx, _ := regexp.Compile(pattern)
	authCode = regEx.FindStringSubmatch(apiResponse)[1]

	return
}

func GetAccessToken(authCode string, config OAuthConfig) (accessToken string) {
	clientCredentials := []byte(fmt.Sprintf("%v:%v", config.ClientId, config.ClientSecret))
	encodedClientCredentials := base64.StdEncoding.EncodeToString(clientCredentials)
	authHeader := fmt.Sprintf("Authorization: Basic %v", encodedClientCredentials)
	requestTokenUri := fmt.Sprintf("%v/oauth/token", config.TokenEndpoint)
	requestTokenData := fmt.Sprintf("scope=%v&code=%v&grant_type=authorization_code&redirect_uri=%v", config.RequestedScopes, authCode, config.RedirectUri)

	curl := runner.Curl(requestTokenUri, `-H`, authHeader, `--data`, requestTokenData, `--insecure`, `-v`).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := curl.Out.Contents()
	jsonResult := ParseJsonResponse(apiResponse)

	accessToken = fmt.Sprintf("%v", jsonResult[`access_token`])
	return
}

func QueryServiceInstancePermissionEndpoint(apiEndpoint string, accessToken string, serviceInstanceGuid string) (canManage string, httpCode string) {
	canManage = `not populated`
	authHeader := fmt.Sprintf("Authorization: bearer %v", accessToken)
	permissionsUri := fmt.Sprintf("%v/v2/service_instances/%v/permissions", apiEndpoint, serviceInstanceGuid)

	curl := runner.Curl(permissionsUri, `-H`, authHeader, `-w`, `:TestReponseCode:%{http_code}`, `--insecure`, `-v`).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := string(curl.Out.Contents())
	resultMap := strings.Split(apiResponse, `:TestReponseCode:`)

	resultText := resultMap[0]
	httpCode = resultMap[1]

	if httpCode == `200` {
		jsonResult := ParseJsonResponse([]byte(resultText))
		canManage = fmt.Sprintf("%v", jsonResult[`manage`])
	}

	return
}
<commit_msg>Skip ssl validation for CURL on SSO cats<commit_after>package services

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"net/url"
	"regexp"
	"strings"

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

	"github.com/cloudfoundry-incubator/cf-test-helpers/helpers"
	"github.com/cloudfoundry-incubator/cf-test-helpers/runner"
)

type OAuthConfig struct {
	ClientId              string
	ClientSecret          string
	RedirectUri           string
	RequestedScopes       string
	AuthorizationEndpoint string
	TokenEndpoint         string
}

func ParseJsonResponse(response []byte) (resultMap map[string]interface{}) {
	var jsonValue interface{}

	json.Unmarshal(response, &jsonValue)
	resultMap = jsonValue.(map[string]interface{})
	return
}

func SetOauthEndpoints(apiEndpoint string, config *OAuthConfig) {
	args := []string{}
	if helpers.LoadConfig().SkipSSLValidation {
		args = append(args, "--insecure")
	}
	args = append(args, fmt.Sprintf("%v/info", apiEndpoint))
	curl := runner.Curl(args...).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := curl.Out.Contents()
	jsonResult := ParseJsonResponse(apiResponse)

	config.TokenEndpoint = fmt.Sprintf("%v", jsonResult[`token_endpoint`])
	config.AuthorizationEndpoint = fmt.Sprintf("%v", jsonResult[`authorization_endpoint`])
	return
}

func AuthenticateUser(authorizationEndpoint string, username string, password string) (cookie string) {
	loginUri := fmt.Sprintf("%v/login.do", authorizationEndpoint)
	usernameEncoded := url.QueryEscape(username)
	passwordEncoded := url.QueryEscape(password)
	loginCredentials := fmt.Sprintf("username=%v&password=%v", usernameEncoded, passwordEncoded)

	curl := runner.Curl(loginUri, `--data`, loginCredentials, `--insecure`, `-i`, `-v`).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := string(curl.Out.Contents())

	jsessionRegEx, _ := regexp.Compile(`JSESSIONID([^;]*)`)
	vcapidRegEx, _ := regexp.Compile(`__VCAP_ID__([^;]*)`)
	sessionId := jsessionRegEx.FindString(apiResponse)
	vcapId := vcapidRegEx.FindString(apiResponse)
	cookie = fmt.Sprintf("%v;%v", sessionId, vcapId)
	return
}

func RequestScopes(cookie string, config OAuthConfig) (authCode string, httpCode string) {
	authCode = `initialized`

	requestScopesUri := fmt.Sprintf("%v/oauth/authorize?client_id=%v&response_type=code+id_token&redirect_uri=%v&scope=%v",
		config.AuthorizationEndpoint,
		url.QueryEscape(config.ClientId),
		config.RedirectUri,
		config.RequestedScopes)

	curl := runner.Curl(requestScopesUri, `-L`, `--cookie`, cookie, `--insecure`, `-w`, `:TestReponseCode:%{http_code}`, `-v`).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := string(curl.Out.Contents())
	resultMap := strings.Split(apiResponse, `:TestReponseCode:`)

	httpCode = resultMap[1]

	if httpCode == `200` {
		authCode = AuthorizeScopes(cookie, config)
	}

	return
}

func AuthorizeScopes(cookie string, config OAuthConfig) (authCode string) {
	authorizedScopes := `scope.0=scope.openid&scope.1=scope.cloud_controller.read&scope.2=scope.cloud_controller.write&user_oauth_approval=true`
	authorizeScopesUri := fmt.Sprintf("%v/oauth/authorize", config.AuthorizationEndpoint)

	curl := runner.Curl(authorizeScopesUri, `-i`, `--data`, authorizedScopes, `--cookie`, cookie, `--insecure`, `-v`).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := string(curl.Out.Contents())

	pattern := fmt.Sprintf(`%v\?code=([a-zA-Z0-9]+)`, regexp.QuoteMeta(config.RedirectUri))
	regEx, _ := regexp.Compile(pattern)
	authCode = regEx.FindStringSubmatch(apiResponse)[1]

	return
}

func GetAccessToken(authCode string, config OAuthConfig) (accessToken string) {
	clientCredentials := []byte(fmt.Sprintf("%v:%v", config.ClientId, config.ClientSecret))
	encodedClientCredentials := base64.StdEncoding.EncodeToString(clientCredentials)
	authHeader := fmt.Sprintf("Authorization: Basic %v", encodedClientCredentials)
	requestTokenUri := fmt.Sprintf("%v/oauth/token", config.TokenEndpoint)
	requestTokenData := fmt.Sprintf("scope=%v&code=%v&grant_type=authorization_code&redirect_uri=%v", config.RequestedScopes, authCode, config.RedirectUri)

	curl := runner.Curl(requestTokenUri, `-H`, authHeader, `--data`, requestTokenData, `--insecure`, `-v`).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := curl.Out.Contents()
	jsonResult := ParseJsonResponse(apiResponse)

	accessToken = fmt.Sprintf("%v", jsonResult[`access_token`])
	return
}

func QueryServiceInstancePermissionEndpoint(apiEndpoint string, accessToken string, serviceInstanceGuid string) (canManage string, httpCode string) {
	canManage = `not populated`
	authHeader := fmt.Sprintf("Authorization: bearer %v", accessToken)
	permissionsUri := fmt.Sprintf("%v/v2/service_instances/%v/permissions", apiEndpoint, serviceInstanceGuid)

	curl := runner.Curl(permissionsUri, `-H`, authHeader, `-w`, `:TestReponseCode:%{http_code}`, `--insecure`, `-v`).Wait(DEFAULT_TIMEOUT)
	Expect(curl).To(Exit(0))
	apiResponse := string(curl.Out.Contents())
	resultMap := strings.Split(apiResponse, `:TestReponseCode:`)

	resultText := resultMap[0]
	httpCode = resultMap[1]

	if httpCode == `200` {
		jsonResult := ParseJsonResponse([]byte(resultText))
		canManage = fmt.Sprintf("%v", jsonResult[`manage`])
	}

	return
}
<|endoftext|>


<commit_before>package gore

import (
	"bytes"
	"regexp"
	"testing"

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

func init() {
	printerPkgs = printerPkgs[1:]
}

func TestSessionEval_import(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		":import encoding/json",
		"b, err := json.Marshal(nil)",
		"string(b)",
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, `[]byte{0x6e, 0x75, 0x6c, 0x6c}
<nil>
"null"
`, stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_QuickFix_evaluated_but_not_used(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`[]byte("")`,
		`make([]int, 0)`,
		`1+1`,
		`func() {}`,
		`(4 & (1 << 1))`,
		`1`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	r := regexp.MustCompile(`0x[0-9a-f]+`)
	assert.Equal(t, `[]byte{}
[]int{}
2
(func())(...)
0
1
`, r.ReplaceAllString(stdout.String(), "..."))
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_QuickFix_used_as_value(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`:import log`,
		`a := 1`,
		`log.SetPrefix("")`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, "1\n", stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_QuickFix_no_new_variables(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`var a, b int`,
		`a := 2`,
		`b := a * 2`,
		`a := 3`,
		`c := a * b`,
		`c := b * c`,
		`b := c * a`,
		`a * b * c`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, `2
4
3
12
48
144
20736
`, stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_AutoImport(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)
	s.autoImport = true

	codes := []string{
		`filepath.Join("a", "b")`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, "\"a/b\"\n", stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSession_IncludePackage(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	err = s.includePackage("github.com/motemen/gore/gocode")
	require.NoError(t, err)

	err = s.Eval("Completer{}")
	require.NoError(t, err)
}

func TestSessionEval_Copy(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`a := []string{"hello", "world"}`,
		`b := []string{"goodbye", "world"}`,
		`copy(a, b)`,
		`a[0]`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, `[]string{"hello", "world"}
[]string{"goodbye", "world"}
2
"goodbye"
`, stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_Const(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`const ( a = iota; b )`,
		`a`,
		`b`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, "0\n1\n0\n1\n", stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_Declarations(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`var a, b int = 10, 20`,
		`var (x int = 10; y string = "hello"; z uint64; w error; v func(string)int)`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, `10
20
10
"hello"
0x0
<nil>
(func(string) int)(nil)
`, stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_NotUsed(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`f := func() []int { return []int{1, 2, 3} }`,
		`len(f())`,
		`3`,
		`len(f()) + len(f())`,
		`var x int`,
		`g := func() int { x++; return 128 }`,
		`g() + g()`,
		`g() * g()`,
		`x`,
	}

	for _, code := range codes {
		_ = s.Eval(code)
	}

	r := regexp.MustCompile(`0x[0-9a-f]+`)
	assert.Equal(t, `(func() []int)(...)
3
3
6
(func() int)(...)
256
16384
4
`, r.ReplaceAllString(stdout.String(), "..."))
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_MultipleValues(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`var err error`,
		`:import fmt`,
		`fmt.Print()`,
		`fmt.Print()`,
		`:import io`,
		`_, err = func() (int, error) { return 0, io.EOF }()`,
		`err.Error()`,
		`var x int`,
		`x, err = 10, fmt.Errorf("test")`,
		`x`,
		`err.Error()`,
	}

	for _, code := range codes {
		_ = s.Eval(code)
	}

	assert.Equal(t, `0
<nil>
0
<nil>
&errors.errorString{s:"EOF"}
"EOF"
10
&errors.errorString{s:"test"}
10
"test"
`, stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_Func(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`func f() int { return 100 }`,
		`func g() string { return "hello, world" }`,
		`func h() int { return "foo" }`,
		`f() + len(g())`,
		`func f() int { return 200 }`,
		`f() * len(g())`,
		`func f() string { return 100 }`,
		`f() | len(g())`,
	}

	for _, code := range codes {
		_ = s.Eval(code)
	}

	assert.Equal(t, "112\n2400\n204\n", stdout.String())
	assert.Equal(t, `cannot use "foo" (type string) as type int in return argument
invalid operation: f() + len(g()) (mismatched types string and int)
invalid operation: f() * len(g()) (mismatched types string and int)
cannot use 100 (type int) as type string in return argument
`, stderr.String())
}

func TestSessionEval_TokenError(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`foo\`,
		`ba # r`,
		`$ + 3`,
		`~1`,
		"`foo",
		"`foo\nbar`",
	}

	for _, code := range codes {
		_ = s.Eval(code)
	}

	assert.Equal(t, "\"foo\\nbar\"\n", stdout.String())
	assert.Equal(t, `invalid token: "\\"
invalid token: "#"
invalid token: "$"
invalid token: "~"
`, stderr.String())
}

func TestSessionEval_CompileError(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`foo`,
		`func f() int { return 100 }`,
		`func g() string { return "hello" }`,
		`len(f())`,
		`len(g())`,
		`f() + g()`,
		`f() + len(g())`,
	}

	for _, code := range codes {
		_ = s.Eval(code)
	}

	assert.Equal(t, "5\n105\n", stdout.String())
	assert.Equal(t, `undefined: foo
invalid argument f() (type int) for len
invalid operation: f() + g() (mismatched types int and string)
`, stderr.String())
}
<commit_msg>tweak error messages in eval func tests<commit_after>package gore

import (
	"bytes"
	"regexp"
	"testing"

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

func init() {
	printerPkgs = printerPkgs[1:]
}

func TestSessionEval_import(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		":import encoding/json",
		"b, err := json.Marshal(nil)",
		"string(b)",
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, `[]byte{0x6e, 0x75, 0x6c, 0x6c}
<nil>
"null"
`, stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_QuickFix_evaluated_but_not_used(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`[]byte("")`,
		`make([]int, 0)`,
		`1+1`,
		`func() {}`,
		`(4 & (1 << 1))`,
		`1`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	r := regexp.MustCompile(`0x[0-9a-f]+`)
	assert.Equal(t, `[]byte{}
[]int{}
2
(func())(...)
0
1
`, r.ReplaceAllString(stdout.String(), "..."))
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_QuickFix_used_as_value(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`:import log`,
		`a := 1`,
		`log.SetPrefix("")`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, "1\n", stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_QuickFix_no_new_variables(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`var a, b int`,
		`a := 2`,
		`b := a * 2`,
		`a := 3`,
		`c := a * b`,
		`c := b * c`,
		`b := c * a`,
		`a * b * c`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, `2
4
3
12
48
144
20736
`, stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_AutoImport(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)
	s.autoImport = true

	codes := []string{
		`filepath.Join("a", "b")`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, "\"a/b\"\n", stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSession_IncludePackage(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	err = s.includePackage("github.com/motemen/gore/gocode")
	require.NoError(t, err)

	err = s.Eval("Completer{}")
	require.NoError(t, err)
}

func TestSessionEval_Copy(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`a := []string{"hello", "world"}`,
		`b := []string{"goodbye", "world"}`,
		`copy(a, b)`,
		`a[0]`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, `[]string{"hello", "world"}
[]string{"goodbye", "world"}
2
"goodbye"
`, stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_Const(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`const ( a = iota; b )`,
		`a`,
		`b`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, "0\n1\n0\n1\n", stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_Declarations(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`var a, b int = 10, 20`,
		`var (x int = 10; y string = "hello"; z uint64; w error; v func(string)int)`,
	}

	for _, code := range codes {
		err := s.Eval(code)
		require.NoError(t, err)
	}

	assert.Equal(t, `10
20
10
"hello"
0x0
<nil>
(func(string) int)(nil)
`, stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_NotUsed(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`f := func() []int { return []int{1, 2, 3} }`,
		`len(f())`,
		`3`,
		`len(f()) + len(f())`,
		`var x int`,
		`g := func() int { x++; return 128 }`,
		`g() + g()`,
		`g() * g()`,
		`x`,
	}

	for _, code := range codes {
		_ = s.Eval(code)
	}

	r := regexp.MustCompile(`0x[0-9a-f]+`)
	assert.Equal(t, `(func() []int)(...)
3
3
6
(func() int)(...)
256
16384
4
`, r.ReplaceAllString(stdout.String(), "..."))
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_MultipleValues(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`var err error`,
		`:import fmt`,
		`fmt.Print()`,
		`fmt.Print()`,
		`:import io`,
		`_, err = func() (int, error) { return 0, io.EOF }()`,
		`err.Error()`,
		`var x int`,
		`x, err = 10, fmt.Errorf("test")`,
		`x`,
		`err.Error()`,
	}

	for _, code := range codes {
		_ = s.Eval(code)
	}

	assert.Equal(t, `0
<nil>
0
<nil>
&errors.errorString{s:"EOF"}
"EOF"
10
&errors.errorString{s:"test"}
10
"test"
`, stdout.String())
	assert.Equal(t, "", stderr.String())
}

func TestSessionEval_Func(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`func f() int { return 100 }`,
		`func g() string { return "hello, world" }`,
		`func h() int { s := ""; return s }`,
		`f() + len(g())`,
		`func f() int { return 200 }`,
		`f() * len(g())`,
		`func f() string { i := 100; return i }`,
		`f() | len(g())`,
	}

	for _, code := range codes {
		_ = s.Eval(code)
	}

	assert.Equal(t, "112\n2400\n204\n", stdout.String())
	assert.Equal(t, `cannot use s (type string) as type int in return argument
invalid operation: f() + len(g()) (mismatched types string and int)
invalid operation: f() * len(g()) (mismatched types string and int)
cannot use i (type int) as type string in return argument
`, stderr.String())
}

func TestSessionEval_TokenError(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`foo\`,
		`ba # r`,
		`$ + 3`,
		`~1`,
		"`foo",
		"`foo\nbar`",
	}

	for _, code := range codes {
		_ = s.Eval(code)
	}

	assert.Equal(t, "\"foo\\nbar\"\n", stdout.String())
	assert.Equal(t, `invalid token: "\\"
invalid token: "#"
invalid token: "$"
invalid token: "~"
`, stderr.String())
}

func TestSessionEval_CompileError(t *testing.T) {
	stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
	s, err := NewSession(stdout, stderr)
	defer s.Clear()
	require.NoError(t, err)

	codes := []string{
		`foo`,
		`func f() int { return 100 }`,
		`func g() string { return "hello" }`,
		`len(f())`,
		`len(g())`,
		`f() + g()`,
		`f() + len(g())`,
	}

	for _, code := range codes {
		_ = s.Eval(code)
	}

	assert.Equal(t, "5\n105\n", stdout.String())
	assert.Equal(t, `undefined: foo
invalid argument f() (type int) for len
invalid operation: f() + g() (mismatched types int and string)
`, stderr.String())
}
<|endoftext|>


<commit_before>package main

import (
	"koding/db/mongodb/modelhelper"
	"log"
	"socialapi/config"
	"socialapi/workers/email/emailsender"

	"github.com/koding/eventexporter"
	"github.com/koding/runner"
)

var (
	Name        = "MailSender"
	QueueLength = 1
)

func main() {
	r := runner.New(Name)
	if err := r.Init(); err != nil {
		log.Fatal(err)
	}

	appConfig := config.MustRead(r.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	exporter := eventexporter.NewSegmentIOExporter(appConfig.Segment, QueueLength)
	constructor := emailsender.New(exporter, r.Log, appConfig.Config)
	r.ShutdownHandler = constructor.Close

	r.SetContext(constructor)

	r.Register(emailsender.Mail{}).On(emailsender.SendEmailEventName).Handle(
		(*emailsender.Controller).Process,
	)

	r.Listen()
	r.Wait()
}
<commit_msg>socialapi: emailsender constructor parameters are changed<commit_after>package main

import (
	"koding/db/mongodb/modelhelper"
	"log"
	"socialapi/config"
	"socialapi/workers/email/emailsender"

	"github.com/koding/eventexporter"
	"github.com/koding/runner"
)

var (
	Name        = "MailSender"
	QueueLength = 1
)

func main() {
	r := runner.New(Name)
	if err := r.Init(); err != nil {
		log.Fatal(err)
	}

	appConfig := config.MustRead(r.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	exporter := eventexporter.NewSegmentIOExporter(appConfig.Segment, QueueLength)
	constructor := emailsender.New(exporter, r.Log, appConfig)
	r.ShutdownHandler = constructor.Close

	r.SetContext(constructor)

	r.Register(emailsender.Mail{}).On(emailsender.SendEmailEventName).Handle(
		(*emailsender.Controller).Process,
	)

	r.Listen()
	r.Wait()
}
<|endoftext|>


<commit_before>package models

import (
	"encoding/xml"
	"errors"
	"time"

	"github.com/koding/bongo"
)

var ErrNotSet = errors.New("name not set")

type SitemapFile struct {
	Id int64

	// unique file name
	Name string `sql:"NOT NULL"`

	// file content
	Blob []byte

	// creation date of the file
	CreatedAt time.Time

	// last modification date of the file
	UpdatedAt time.Time
}

func NewSitemapFile() *SitemapFile {
	return &SitemapFile{}
}

func (f SitemapFile) GetId() int64 {
	return f.Id
}

func (f SitemapFile) TableName() string {
	return "sitemap.file"
}

func (f *SitemapFile) Create() error {
	if f.Name == "" {
		return ErrNotSet
	}

	return bongo.B.Create(f)
}

func (f *SitemapFile) ByName(name string) error {
	if name == "" {
		return ErrNotSet
	}

	selector := map[string]interface{}{
		"name": name,
	}
	q := bongo.NewQS(selector)

	return bongo.B.One(f, f, q)
}

func (f *SitemapFile) Update() error {
	return bongo.B.Update(f)
}

func (f *SitemapFile) Some(data interface{}, q *bongo.Query) error {
	return bongo.B.Some(f, data, q)
}

func (f *SitemapFile) Fetch() error {
	return bongo.B.Fetch(f)
}

func (f *SitemapFile) UnmarshalBlob() (*ItemSet, error) {
	set := NewItemSet()

	return set, xml.Unmarshal(f.Blob, set)
}

func (f *SitemapFile) Delete() error {
	return bongo.B.Delete(f)
}
<commit_msg>Sitemap: Fix sitemapfile ErrNotSet error message<commit_after>package models

import (
	"encoding/xml"
	"errors"
	"time"

	"github.com/koding/bongo"
)

var ErrNotSet = errors.New("name is not set")

type SitemapFile struct {
	Id int64

	// unique file name
	Name string `sql:"NOT NULL"`

	// file content
	Blob []byte

	// creation date of the file
	CreatedAt time.Time

	// last modification date of the file
	UpdatedAt time.Time
}

func NewSitemapFile() *SitemapFile {
	return &SitemapFile{}
}

func (f SitemapFile) GetId() int64 {
	return f.Id
}

func (f SitemapFile) TableName() string {
	return "sitemap.file"
}

func (f *SitemapFile) Create() error {
	if f.Name == "" {
		return ErrNotSet
	}

	return bongo.B.Create(f)
}

func (f *SitemapFile) ByName(name string) error {
	if name == "" {
		return ErrNotSet
	}

	selector := map[string]interface{}{
		"name": name,
	}
	q := bongo.NewQS(selector)

	return bongo.B.One(f, f, q)
}

func (f *SitemapFile) Update() error {
	return bongo.B.Update(f)
}

func (f *SitemapFile) Some(data interface{}, q *bongo.Query) error {
	return bongo.B.Some(f, data, q)
}

func (f *SitemapFile) Fetch() error {
	return bongo.B.Fetch(f)
}

func (f *SitemapFile) UnmarshalBlob() (*ItemSet, error) {
	set := NewItemSet()

	return set, xml.Unmarshal(f.Blob, set)
}

func (f *SitemapFile) Delete() error {
	return bongo.B.Delete(f)
}
<|endoftext|>


<commit_before>package confoo

import (
	"fmt"
	"io/ioutil"
	"os"
	"reflect"
	"regexp"
	"runtime/debug"
	"strconv"
	"strings"

	yaml "gopkg.in/yaml.v2"
)

const confVar = "CONFOO_CONFIG or CONFOO_CONFIG_FILE"

func errorPanic(format string, a ...interface{}) {
	m := fmt.Sprintf(format, a...)
	m2 := "CONFOO - " + m
	panic(m2)
}

var confData map[interface{}]interface{}
var confId string
var confWithIdRegex *regexp.Regexp

func init() {
	confFile, confReceived := os.LookupEnv("CONFOO_CONFIG")
	if !confReceived {
		confFile, confReceived = os.LookupEnv("CONFOO_CONFIG_FILE")

		if !confReceived {
			errorPanic(confVar + " is not set")
		}
	}

	confId, _ = os.LookupEnv("CONFOO_ID")

	data, err := ioutil.ReadFile(confFile)
	if err != nil {
		errorPanic(err.Error())
	}

	confData = make(map[interface{}]interface{})
	err = yaml.Unmarshal(data, &confData)
	if err != nil {
		errorPanic("cannot decode yaml data")
	}

	confWithIdRegex = regexp.MustCompile(`(.*)\[(.*)\]$`)
}

//Configure loads the value of the path of the yml of the CONFOO_CONFIG_FILE into target
func Configure(path string, target interface{}) {
	subConf := getSubConf(path, confData)
	if subConf != nil {
		configPath(path, reflect.ValueOf(target), subConf)
	}
}

//ConfigureFromFile reads ymlFile and loads the value of the path into target
func ConfigureFromFile(ymlFile, path string, target interface{}) error {

	data, err := ioutil.ReadFile(ymlFile)
	if err != nil {
		return err
	}

	confData := make(map[interface{}]interface{})
	err = yaml.Unmarshal(data, &confData)
	if err != nil {
		return err
	}

	subConf := getSubConf(path, confData)
	if subConf != nil {
		configPath(path, reflect.ValueOf(target), subConf)
	}
	return nil
}

func coerceIdentity(conf interface{}) {
	confMap, ok := conf.(map[interface{}]interface{})
	if ok {
		for key, value := range confMap {
			if _, ok := key.(string); !ok {
				continue
			}

			coerceIdentity(value)
			match := confWithIdRegex.FindSubmatch([]byte(key.(string)))
			if match == nil {
				continue
			}
			delete(confMap, key)
			realKey := string(match[1])
			identity := string(match[2])
			if identity == confId {
				confMap[realKey] = value
			}
		}
	}
	confList, ok := conf.([]interface{})
	if ok {
		for _, entry := range confList {
			coerceIdentity(entry)
		}
	}
}

func getSubConf(path string, conf interface{}) interface{} {

	coerceIdentity(conf)
	subConf := conf
	for _, p := range strings.Split(path, ".") {
		m, ok := subConf.(map[interface{}]interface{})
		if !ok {
			errorPanic("%s: path not found", path)
		}
		subConf, ok = m[p]
		if !ok {
			return nil
		}
	}
	return subConf
}

func normalizeKey(s string) string {
	parts := strings.Split(s, "_")
	for i, p := range parts {
		parts[i] = strings.Title(p)
	}
	return strings.Join(parts, "")
}

func replaceKey(s string) string {
	if strings.Contains(s, "$hostname") {
		hostname, error := os.Hostname()
		if error != nil {
			errorPanic("Error while retrieving the hostname: %s", error)
		}

		return strings.Replace(s, "$hostname", hostname, -1)
	}

	return s
}

func replaceValue(s string) string {
	if strings.Contains(s, "$public_hostname") {
		content, err := ioutil.ReadFile("/etc/public_hostname")
		if err != nil {
			fmt.Println(err)
			return s
		}

		public_hostname := strings.TrimSuffix(string(content), "\n")
		return strings.Replace(s, "$public_hostname", public_hostname, -1)
	}

	return s
}

func configStruct(path string, dest reflect.Value, conf interface{}) {
	if conf == nil {
		return
	}
	confMap, ok := conf.(map[interface{}]interface{})
	if !ok {
		errorPanic("%s: expected map not found", path)
	}
	for k, subConf := range confMap {
		kk, ok := k.(string)
		if !ok {
			//FIXME log event if CONFOO_DEBUG is set
			//errorPanic("%s.%v: map key is not a string", path, k)
			continue
		}
		fieldName := normalizeKey(kk)
		fieldVal := dest.FieldByName(fieldName)
		if fieldVal.Kind() == reflect.Invalid {
			//FIXME log event if CONFOO_DEBUG is set
			//errorPanic("%s.%v: field not present in target struct", path, k)
			continue
		}
		configPath(path+"."+kk, dest.FieldByName(fieldName), subConf)
	}
}

func configPath(path string, dest reflect.Value, conf interface{}) {
	defer func() {
		if r := recover(); r != nil {
			fmt.Fprintf(os.Stderr, "panic while handling path %s: %v\n", path, r)
			fmt.Fprintf(os.Stderr, string(debug.Stack()))
			os.Exit(1)
		}
	}()
	destKind := dest.Kind()
	switch destKind {
	case reflect.Ptr:
		if dest.Type().Elem().Kind() == reflect.Struct && dest.IsNil() {
			dest.Set(reflect.New(dest.Type().Elem()))
		}
		configPath(path, dest.Elem(), conf)
	case reflect.Interface:
		dest.Set(reflect.ValueOf(conf))
	case reflect.Struct:
		configStruct(path, dest, conf)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Float32, reflect.Float64, reflect.Bool:
		confValue := reflect.ValueOf(conf)
		confKind := confValue.Kind()
		if confKind != destKind {
			dType := dest.Type()
			cType := confValue.Type()
			errorPanic("%s: target type %v != conf type %v", path, dType, cType)
		}
		dest.Set(confValue)
	case reflect.String:
		conf = replaceValue(conf.(string))
		confValue := reflect.ValueOf(conf)
		confKind := confValue.Kind()
		if confKind != destKind {
			dType := dest.Type()
			cType := confValue.Type()
			errorPanic("%s: target type %v != conf type %v", path, dType, cType)
		}
		dest.Set(confValue)
	case reflect.Slice:
		dest.Set(dest.Slice(0, 0))
		for i, el := range conf.([]interface{}) {
			idx := strconv.Itoa(i)
			elVal := reflect.New(dest.Type().Elem())
			configPath(path+"."+idx, elVal, el)
			dest.Set(reflect.Append(dest, elVal.Elem()))
		}
	case reflect.Map:
		dest.Set(reflect.MakeMap(dest.Type()))
		for k, el := range conf.(map[interface{}]interface{}) {
			kk := k.(string)
			kk = replaceKey(kk)
			elVal := reflect.New(dest.Type().Elem())
			configPath(path+"."+kk, elVal, el)
			dest.SetMapIndex(reflect.ValueOf(kk), elVal.Elem())
		}
	default:
		errorPanic("%s: conf type %v not handled", path, dest.Type())
	}
}
<commit_msg>support for type "alias".<commit_after>package confoo

import (
	"fmt"
	"io/ioutil"
	"os"
	"reflect"
	"regexp"
	"runtime/debug"
	"strconv"
	"strings"

	yaml "gopkg.in/yaml.v2"
)

const confVar = "CONFOO_CONFIG or CONFOO_CONFIG_FILE"

func errorPanic(format string, a ...interface{}) {
	m := fmt.Sprintf(format, a...)
	m2 := "CONFOO - " + m
	panic(m2)
}

var confData map[interface{}]interface{}
var confId string
var confWithIdRegex *regexp.Regexp

func init() {
	confFile, confReceived := os.LookupEnv("CONFOO_CONFIG")
	if !confReceived {
		confFile, confReceived = os.LookupEnv("CONFOO_CONFIG_FILE")

		if !confReceived {
			errorPanic(confVar + " is not set")
		}
	}

	confId, _ = os.LookupEnv("CONFOO_ID")

	data, err := ioutil.ReadFile(confFile)
	if err != nil {
		errorPanic(err.Error())
	}

	confData = make(map[interface{}]interface{})
	err = yaml.Unmarshal(data, &confData)
	if err != nil {
		errorPanic("cannot decode yaml data")
	}

	confWithIdRegex = regexp.MustCompile(`(.*)\[(.*)\]$`)
}

//Configure loads the value of the path of the yml of the CONFOO_CONFIG_FILE into target
func Configure(path string, target interface{}) {
	subConf := getSubConf(path, confData)
	if subConf != nil {
		configPath(path, reflect.ValueOf(target), subConf)
	}
}

//ConfigureFromFile reads ymlFile and loads the value of the path into target
func ConfigureFromFile(ymlFile, path string, target interface{}) error {

	data, err := ioutil.ReadFile(ymlFile)
	if err != nil {
		return err
	}

	confData := make(map[interface{}]interface{})
	err = yaml.Unmarshal(data, &confData)
	if err != nil {
		return err
	}

	subConf := getSubConf(path, confData)
	if subConf != nil {
		configPath(path, reflect.ValueOf(target), subConf)
	}
	return nil
}

func coerceIdentity(conf interface{}) {
	confMap, ok := conf.(map[interface{}]interface{})
	if ok {
		for key, value := range confMap {
			if _, ok := key.(string); !ok {
				continue
			}

			coerceIdentity(value)
			match := confWithIdRegex.FindSubmatch([]byte(key.(string)))
			if match == nil {
				continue
			}
			delete(confMap, key)
			realKey := string(match[1])
			identity := string(match[2])
			if identity == confId {
				confMap[realKey] = value
			}
		}
	}
	confList, ok := conf.([]interface{})
	if ok {
		for _, entry := range confList {
			coerceIdentity(entry)
		}
	}
}

func getSubConf(path string, conf interface{}) interface{} {

	coerceIdentity(conf)
	subConf := conf
	for _, p := range strings.Split(path, ".") {
		m, ok := subConf.(map[interface{}]interface{})
		if !ok {
			errorPanic("%s: path not found", path)
		}
		subConf, ok = m[p]
		if !ok {
			return nil
		}
	}
	return subConf
}

func normalizeKey(s string) string {
	parts := strings.Split(s, "_")
	for i, p := range parts {
		parts[i] = strings.Title(p)
	}
	return strings.Join(parts, "")
}

func replaceKey(s string) string {
	if strings.Contains(s, "$hostname") {
		hostname, error := os.Hostname()
		if error != nil {
			errorPanic("Error while retrieving the hostname: %s", error)
		}

		return strings.Replace(s, "$hostname", hostname, -1)
	}

	return s
}

func replaceValue(s string) string {
	if strings.Contains(s, "$public_hostname") {
		content, err := ioutil.ReadFile("/etc/public_hostname")
		if err != nil {
			fmt.Println(err)
			return s
		}

		public_hostname := strings.TrimSuffix(string(content), "\n")
		return strings.Replace(s, "$public_hostname", public_hostname, -1)
	}

	return s
}

func configStruct(path string, dest reflect.Value, conf interface{}) {
	if conf == nil {
		return
	}
	confMap, ok := conf.(map[interface{}]interface{})
	if !ok {
		errorPanic("%s: expected map not found", path)
	}
	for k, subConf := range confMap {
		kk, ok := k.(string)
		if !ok {
			//FIXME log event if CONFOO_DEBUG is set
			//errorPanic("%s.%v: map key is not a string", path, k)
			continue
		}
		fieldName := normalizeKey(kk)
		fieldVal := dest.FieldByName(fieldName)
		if fieldVal.Kind() == reflect.Invalid {
			//FIXME log event if CONFOO_DEBUG is set
			//errorPanic("%s.%v: field not present in target struct", path, k)
			continue
		}
		configPath(path+"."+kk, dest.FieldByName(fieldName), subConf)
	}
}

func configPath(path string, dest reflect.Value, conf interface{}) {
	defer func() {
		if r := recover(); r != nil {
			fmt.Fprintf(os.Stderr, "panic while handling path %s: %v\n", path, r)
			fmt.Fprintf(os.Stderr, string(debug.Stack()))
			os.Exit(1)
		}
	}()
	destKind := dest.Kind()
	switch destKind {
	case reflect.Ptr:
		if dest.Type().Elem().Kind() == reflect.Struct && dest.IsNil() {
			dest.Set(reflect.New(dest.Type().Elem()))
		}
		configPath(path, dest.Elem(), conf)
	case reflect.Interface:
		dest.Set(reflect.ValueOf(conf))
	case reflect.Struct:
		configStruct(path, dest, conf)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Float32, reflect.Float64, reflect.Bool:
		confValue := reflect.ValueOf(conf)
		confKind := confValue.Kind()
		if confKind != destKind {
			dType := dest.Type()
			cType := confValue.Type()
			errorPanic("%s: target type %v != conf type %v", path, dType, cType)
		}
		dest.Set(confValue.Convert(dest.Type()))
	case reflect.String:
		conf = replaceValue(conf.(string))
		confValue := reflect.ValueOf(conf)
		confKind := confValue.Kind()
		if confKind != destKind {
			dType := dest.Type()
			cType := confValue.Type()
			errorPanic("%s: target type %v != conf type %v", path, dType, cType)
		}
		dest.Set(confValue.Convert(dest.Type()))
	case reflect.Slice:
		dest.Set(dest.Slice(0, 0))
		for i, el := range conf.([]interface{}) {
			idx := strconv.Itoa(i)
			elVal := reflect.New(dest.Type().Elem())
			configPath(path+"."+idx, elVal, el)
			dest.Set(reflect.Append(dest, elVal.Elem()))
		}
	case reflect.Map:
		dest.Set(reflect.MakeMap(dest.Type()))
		for k, el := range conf.(map[interface{}]interface{}) {
			kk := k.(string)
			kk = replaceKey(kk)
			elVal := reflect.New(dest.Type().Elem())
			configPath(path+"."+kk, elVal, el)
			dest.SetMapIndex(reflect.ValueOf(kk), elVal.Elem())
		}
	default:
		errorPanic("%s: conf type %v not handled", path, dest.Type())
	}
}
<|endoftext|>


<commit_before>// Package xhr provides GopherJS bindings for the XMLHttpRequest API.
//
// This package provides two ways of using XHR. The first one is via
// the Request type and the NewRequest function. This way, one can
// specify all desired details of the request's behaviour (timeout,
// response format). It also allows access to response details such as
// the status code. Furthermore, using this way is required if one
// wants to abort in-flight requests.
//
//   r := xhr.NewRequest()
//   r.SetTimeout(time.Second)
//   r.ResponseType = "document"
//   r.Open("GET", "/endpoint", "", "")
//   err := r.Send(nil)
//   if err != nil { handle_error() }
//   // r.Response will contain a JavaScript Document element that can
//   // for example be used with the js/dom package.
//
//
// The other way is via the package function Send, which is a helper
// that constructs a Request internally and assigns sane defaults to
// it. It's the easiest way of doing an XHR request that should just
// return unprocessed data.
//
//     data, err := xhr.Send("GET", "/endpoint", "", "", nil)
//     if err != nil { handle_error() }
//     console.Log("Retrieved data", data)
package xhr

import (
	"errors"

	"github.com/gopherjs/gopherjs/js"
	"honnef.co/go/js/util"
)

const (
	Unsent = iota
	Opened
	HeadersReceived
	Loading
	Done
)

// Request wraps an XMLHttpRequest. New instances have to be created
// with NewRequest. Each instance may only be used for a single
// request.
type Request struct {
	js.Object
	ReadyState      int       `js:"readyState"`
	Response        js.Object `js:"response"`
	ResponseText    string    `js:"responseText"`
	ResponseType    string    `js:"responseType"`
	ResponseXML     js.Object `js:"responseXML"`
	Status          int       `js:"status"`
	StatusText      string    `js:"statusText"`
	Timeout         int       `js:"timeout"`
	WithCredentials bool      `js:"withCredentials"`
	// TODO provide callbacks for upload, state change and load

	ch chan error
}

// Upload wraps XMLHttpRequestUpload objects.
type Upload struct {
	js.Object
	util.EventTarget
}

// Upload returns the XMLHttpRequestUpload object associated with the
// request. It can be used to register events for tracking the
// progress of uploads.
func (r *Request) Upload() *Upload {
	o := r.Get("upload")
	return &Upload{o, util.EventTarget{Object: o}}
}

// ErrAborted is the error returned by Send when a request was
// aborted.
var ErrAborted = errors.New("request aborted")

// ErrTimeout is the error returned by Send when a request timed out.
var ErrTimeout = errors.New("request timed out")

// NewRequest creates a new XMLHttpRequest object, which may be used
// for a single request.
func NewRequest() *Request {
	o := js.Global.Get("XMLHttpRequest").New()
	return &Request{Object: o}
}

// ResponseHeaders returns all response headers.
func (r *Request) ResponseHeaders() string {
	return r.Call("getAllResponseHeaders").Str()
}

// ResponseHeader returns the value of the specified header.
func (r *Request) ResponseHeader(name string) string {
	value := r.Call("getResponseHeader", name)
	if value.IsNull() {
		return ""
	}
	return value.Str()
}

// Abort will abort the request. The corresponding Send will return
// ErrAborted.
func (r *Request) Abort() {
	if r.ch == nil {
		return
	}

	r.Call("abort")
	select {
	case r.ch <- ErrAborted:
	default:
	}
}

func (r *Request) Open(method, url, user, password string) {
	// TODO "is the equivalent of calling abort()" – does that mean
	// ONLY abort, or also a new request? also check the behaviour re
	// the TODO in Abort.

	if r.ch != nil {
		panic("must not use a Request for multiple requests")
	}
	r.Call("open", method, url, true, user, password)
}

func (r *Request) OverrideMimeType(mimetype string) {
	r.Call("overrideMimeType", mimetype)
}

func (r *Request) Send(data interface{}) error {
	if r.ch != nil {
		panic("must not use a Request for multiple requests")
	}
	r.ch = make(chan error, 1)
	r.Call("addEventListener", "load", func() {
		go func() { r.ch <- nil }()
	})
	r.Call("addEventListener", "error", func(o js.Object) {
		go func() { r.ch <- &js.Error{Object: o} }()
	})
	r.Call("addEventListener", "timeout", func() {
		go func() { r.ch <- ErrTimeout }()
	})
	r.Call("send", data)
	val := <-r.ch
	return val
}

func (r *Request) SetRequestHeader(header, value string) {
	r.Call("setRequestHeader", header, value)
}

func Send(method, url, user, password string, data interface{}) (string, error) {
	xhr := NewRequest()
	xhr.Open(method, url, user, password)
	err := xhr.Send(data)
	if err != nil {
		return "", err
	}
	return xhr.ResponseText, nil
}
<commit_msg>make use of util.EventTarget in Request<commit_after>// Package xhr provides GopherJS bindings for the XMLHttpRequest API.
//
// This package provides two ways of using XHR. The first one is via
// the Request type and the NewRequest function. This way, one can
// specify all desired details of the request's behaviour (timeout,
// response format). It also allows access to response details such as
// the status code. Furthermore, using this way is required if one
// wants to abort in-flight requests.
//
//   r := xhr.NewRequest()
//   r.SetTimeout(time.Second)
//   r.ResponseType = "document"
//   r.Open("GET", "/endpoint", "", "")
//   err := r.Send(nil)
//   if err != nil { handle_error() }
//   // r.Response will contain a JavaScript Document element that can
//   // for example be used with the js/dom package.
//
//
// The other way is via the package function Send, which is a helper
// that constructs a Request internally and assigns sane defaults to
// it. It's the easiest way of doing an XHR request that should just
// return unprocessed data.
//
//     data, err := xhr.Send("GET", "/endpoint", "", "", nil)
//     if err != nil { handle_error() }
//     console.Log("Retrieved data", data)
package xhr

import (
	"errors"

	"github.com/gopherjs/gopherjs/js"
	"honnef.co/go/js/util"
)

const (
	Unsent = iota
	Opened
	HeadersReceived
	Loading
	Done
)

// Request wraps an XMLHttpRequest. New instances have to be created
// with NewRequest. Each instance may only be used for a single
// request.
type Request struct {
	js.Object
	util.EventTarget
	ReadyState      int       `js:"readyState"`
	Response        js.Object `js:"response"`
	ResponseText    string    `js:"responseText"`
	ResponseType    string    `js:"responseType"`
	ResponseXML     js.Object `js:"responseXML"`
	Status          int       `js:"status"`
	StatusText      string    `js:"statusText"`
	Timeout         int       `js:"timeout"`
	WithCredentials bool      `js:"withCredentials"`

	ch chan error
}

// Upload wraps XMLHttpRequestUpload objects.
type Upload struct {
	js.Object
	util.EventTarget
}

// Upload returns the XMLHttpRequestUpload object associated with the
// request. It can be used to register events for tracking the
// progress of uploads.
func (r *Request) Upload() *Upload {
	o := r.Get("upload")
	return &Upload{o, util.EventTarget{Object: o}}
}

// ErrAborted is the error returned by Send when a request was
// aborted.
var ErrAborted = errors.New("request aborted")

// ErrTimeout is the error returned by Send when a request timed out.
var ErrTimeout = errors.New("request timed out")

// NewRequest creates a new XMLHttpRequest object, which may be used
// for a single request.
func NewRequest() *Request {
	o := js.Global.Get("XMLHttpRequest").New()
	return &Request{Object: o, EventTarget: util.EventTarget{Object: o}}
}

// ResponseHeaders returns all response headers.
func (r *Request) ResponseHeaders() string {
	return r.Call("getAllResponseHeaders").Str()
}

// ResponseHeader returns the value of the specified header.
func (r *Request) ResponseHeader(name string) string {
	value := r.Call("getResponseHeader", name)
	if value.IsNull() {
		return ""
	}
	return value.Str()
}

// Abort will abort the request. The corresponding Send will return
// ErrAborted.
func (r *Request) Abort() {
	if r.ch == nil {
		return
	}

	r.Call("abort")
	select {
	case r.ch <- ErrAborted:
	default:
	}
}

func (r *Request) Open(method, url, user, password string) {
	// TODO "is the equivalent of calling abort()" – does that mean
	// ONLY abort, or also a new request? also check the behaviour re
	// the TODO in Abort.

	if r.ch != nil {
		panic("must not use a Request for multiple requests")
	}
	r.Call("open", method, url, true, user, password)
}

func (r *Request) OverrideMimeType(mimetype string) {
	r.Call("overrideMimeType", mimetype)
}

func (r *Request) Send(data interface{}) error {
	if r.ch != nil {
		panic("must not use a Request for multiple requests")
	}
	r.ch = make(chan error, 1)
	r.AddEventListener("load", false, func(js.Object) {
		go func() { r.ch <- nil }()
	})
	r.AddEventListener("error", false, func(o js.Object) {
		go func() { r.ch <- &js.Error{Object: o} }()
	})
	r.AddEventListener("timeout", false, func(js.Object) {
		go func() { r.ch <- ErrTimeout }()
	})
	r.Call("send", data)
	val := <-r.ch
	return val
}

func (r *Request) SetRequestHeader(header, value string) {
	r.Call("setRequestHeader", header, value)
}

func Send(method, url, user, password string, data interface{}) (string, error) {
	xhr := NewRequest()
	xhr.Open(method, url, user, password)
	err := xhr.Send(data)
	if err != nil {
		return "", err
	}
	return xhr.ResponseText, nil
}
<|endoftext|>


<commit_before>package cc1101

import (
	"bytes"
	"log"

	"github.com/ecc1/radio"
)

const (
	hwVersion = 0x0014
)

type hwFlavor struct{}

// SPIDevice returns the pathname of the radio's SPI device.
func (hwFlavor) SPIDevice() string {
	return spiDevice
}

// Speed returns the radio's SPI speed.
func (hwFlavor) Speed() int {
	return spiSpeed
}

// CustomCS returns the GPIO pin number to use as a custom chip-select for the radio.
func (hwFlavor) CustomCS() int {
	return customCS
}

// InterruptPin returns the GPIO pin number to use for receive interrupts.
func (hwFlavor) InterruptPin() int {
	return interruptPin
}

// ReadSingleAddress returns the encoding of an address for SPI read operations.
func (hwFlavor) ReadSingleAddress(addr byte) byte {
	return READ_MODE | addr
}

// ReadBurstAddress returns the encoding of an address for SPI burst-read operations.
func (hwFlavor) ReadBurstAddress(addr byte) byte {
	reg := addr & 0x3F
	if 0x30 <= reg && reg <= 0x3D {
		log.Panicf("no burst access for CC1101 status register %02X", reg)
	}
	return READ_MODE | BURST_MODE | addr
}

// WriteSingleAddress returns the (identity) encoding of an address for SPI write operations.
func (hwFlavor) WriteSingleAddress(addr byte) byte {
	return addr
}

// WriteBurstAddress returns the encoding of an address for SPI burst-write operations.
func (hwFlavor) WriteBurstAddress(addr byte) byte {
	return BURST_MODE | addr
}

// Radio represents an open radio device.
type Radio struct {
	hw            *radio.Hardware
	receiveBuffer bytes.Buffer
	err           error
}

// Open opens the radio device.
func Open() *Radio {
	r := &Radio{hw: radio.Open(hwFlavor{})}
	v := r.Version()
	if r.Error() != nil {
		return r
	}
	if v != hwVersion {
		r.hw.Close()
		r.SetError(radio.HardwareVersionError{Actual: v, Expected: hwVersion})
		return r
	}
	return r
}

// Close closes the radio device.
func (r *Radio) Close() {
	r.changeState(SIDLE, STATE_IDLE)
	r.hw.Close()
}

// Version returns the radio's hardware version.
func (r *Radio) Version() uint16 {
	p := r.hw.ReadRegister(PARTNUM)
	v := r.hw.ReadRegister(VERSION)
	return uint16(p)<<8 | uint16(v)
}

// Name returns the radio's name.
func (*Radio) Name() string {
	return "CC1101"
}

// Device returns the pathname of the radio's device.
func (*Radio) Device() string {
	return spiDevice
}

// Strobe writes the given command to the radio.
func (r *Radio) Strobe(cmd byte) byte {
	if verbose && cmd != SNOP {
		log.Printf("issuing %s command", strobeName(cmd))
	}
	buf := []byte{cmd}
	r.err = r.hw.SPIDevice().Transfer(buf)
	return buf[0]
}

// Reset resets the radio device.
func (r *Radio) Reset() {
	r.Strobe(SRES)
}

// Init initializes the radio device.
func (r *Radio) Init(frequency uint32) {
	r.Reset()
	r.InitRF(frequency)
}

// Error returns the error state of the radio device.
func (r *Radio) Error() error {
	err := r.hw.Error()
	if err != nil {
		return err
	}
	return r.err
}

// SetError sets the error state of the radio device.
func (r *Radio) SetError(err error) {
	r.hw.SetError(err)
	r.err = err
}

// Hardware returns the radio's hardware information.
func (r *Radio) Hardware() *radio.Hardware {
	return r.hw
}
<commit_msg>Pass send and receive buffers to spi.Transfer<commit_after>package cc1101

import (
	"bytes"
	"log"

	"github.com/ecc1/radio"
)

const (
	hwVersion = 0x0014
)

type hwFlavor struct{}

// SPIDevice returns the pathname of the radio's SPI device.
func (hwFlavor) SPIDevice() string {
	return spiDevice
}

// Speed returns the radio's SPI speed.
func (hwFlavor) Speed() int {
	return spiSpeed
}

// CustomCS returns the GPIO pin number to use as a custom chip-select for the radio.
func (hwFlavor) CustomCS() int {
	return customCS
}

// InterruptPin returns the GPIO pin number to use for receive interrupts.
func (hwFlavor) InterruptPin() int {
	return interruptPin
}

// ReadSingleAddress returns the encoding of an address for SPI read operations.
func (hwFlavor) ReadSingleAddress(addr byte) byte {
	return READ_MODE | addr
}

// ReadBurstAddress returns the encoding of an address for SPI burst-read operations.
func (hwFlavor) ReadBurstAddress(addr byte) byte {
	reg := addr & 0x3F
	if 0x30 <= reg && reg <= 0x3D {
		log.Panicf("no burst access for CC1101 status register %02X", reg)
	}
	return READ_MODE | BURST_MODE | addr
}

// WriteSingleAddress returns the (identity) encoding of an address for SPI write operations.
func (hwFlavor) WriteSingleAddress(addr byte) byte {
	return addr
}

// WriteBurstAddress returns the encoding of an address for SPI burst-write operations.
func (hwFlavor) WriteBurstAddress(addr byte) byte {
	return BURST_MODE | addr
}

// Radio represents an open radio device.
type Radio struct {
	hw            *radio.Hardware
	receiveBuffer bytes.Buffer
	snd           []byte
	rcv           []byte
	err           error
}

// Open opens the radio device.
func Open() *Radio {
	r := &Radio{hw: radio.Open(hwFlavor{})}
	v := r.Version()
	if r.Error() != nil {
		return r
	}
	if v != hwVersion {
		r.hw.Close()
		r.SetError(radio.HardwareVersionError{Actual: v, Expected: hwVersion})
		return r
	}
	r.snd = make([]byte, 1)
	r.rcv = make([]byte, 1)
	return r
}

// Close closes the radio device.
func (r *Radio) Close() {
	r.changeState(SIDLE, STATE_IDLE)
	r.hw.Close()
}

// Version returns the radio's hardware version.
func (r *Radio) Version() uint16 {
	p := r.hw.ReadRegister(PARTNUM)
	v := r.hw.ReadRegister(VERSION)
	return uint16(p)<<8 | uint16(v)
}

// Name returns the radio's name.
func (*Radio) Name() string {
	return "CC1101"
}

// Device returns the pathname of the radio's device.
func (*Radio) Device() string {
	return spiDevice
}

// Strobe writes the given command to the radio.
func (r *Radio) Strobe(cmd byte) byte {
	if verbose && cmd != SNOP {
		log.Printf("issuing %s command", strobeName(cmd))
	}
	r.snd[0] = cmd
	r.err = r.hw.SPIDevice().Transfer(r.snd, r.rcv)
	return r.rcv[0]
}

// Reset resets the radio device.
func (r *Radio) Reset() {
	r.Strobe(SRES)
}

// Init initializes the radio device.
func (r *Radio) Init(frequency uint32) {
	r.Reset()
	r.InitRF(frequency)
}

// Error returns the error state of the radio device.
func (r *Radio) Error() error {
	err := r.hw.Error()
	if err != nil {
		return err
	}
	return r.err
}

// SetError sets the error state of the radio device.
func (r *Radio) SetError(err error) {
	r.hw.SetError(err)
	r.err = err
}

// Hardware returns the radio's hardware information.
func (r *Radio) Hardware() *radio.Hardware {
	return r.hw
}
<|endoftext|>


<commit_before>package ninja

import (
	"encoding/json"
	"fmt"
	"strings"

	"github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/model"
	"github.com/ninjasphere/go-ninja/rpc"
	"github.com/ninjasphere/go-ninja/rpc/json2"

	"github.com/bitly/go-simplejson"
)

// DeviceBus Context for device related announcements.
type DeviceBus struct {
	id         string
	idType     string
	name       string
	driver     *DriverBus
	devicejson *simplejson.Json
	log        *logger.Logger
	rpcServer  *rpc.Server
}

// NewDeviceBus Create a new device bus.
func NewDeviceBus(id string, idType string, name string, driver *DriverBus, devicejson *simplejson.Json) *DeviceBus {
	log := logger.GetLogger(fmt.Sprintf("device.%s.%s", id, name))

	return &DeviceBus{
		id:         id,
		idType:     idType,
		name:       name,
		driver:     driver,
		devicejson: devicejson,
		log:        log,
		rpcServer:  rpc.NewServer(driver.mqtt, json2.NewCodec()),
	}
}

type eventingService interface {
	SetEventHandler(func(event string, payload interface{}) error)
}

// AddChannel Exports a channel as an RPC service, and announces it
// If the channel implements eventingService, it will be given a function to send events
func (d *DeviceBus) AddChannel(channel interface{}, name string, protocol string) error {

	deviceguid, _ := d.devicejson.Get("guid").String()
	channelguid := GetGUID(name + protocol)

	topic := "$device/" + deviceguid + "/channel/" + channelguid + "/" + protocol

	exportedService, err := d.rpcServer.RegisterService(channel, topic)

	if err != nil {
		return fmt.Errorf("Failed to register channel service on %s : %s", topic, err)
	}

	events := []string{}

	channelAnnouncement := &model.Channel{
		ID:       channelguid,
		Protocol: protocol,
		Name:     name,
		Supported: &model.ChannelSupported{
			Methods: &exportedService.Methods,
			Events:  &events,
		},
		Device: &model.Device{},
	}

	js, err := d.devicejson.MarshalJSON()
	json.Unmarshal(js, &channelAnnouncement.Device)

	// send out channel announcement
	err = d.rpcServer.SendNotification(topic+"/announce", channelAnnouncement) // TODO: This should probably be exposed somewhere else

	if err != nil {
		return fmt.Errorf("Failed sending channel announcement: %s", err)
	}

	d.log.Debugf("Added channel: %s (protocol: %s) with methods: %s", name, protocol, strings.Join(exportedService.Methods, ", "))

	switch channel := channel.(type) {
	case eventingService:
		channel.SetEventHandler(func(event string, payload interface{}) error {
			return exportedService.SendEvent(event, payload)
		})
	}

	return nil
}
<commit_msg>Allow supported methods and events to be specified when announcing a channel<commit_after>package ninja

import (
	"encoding/json"
	"fmt"
	"strings"

	"github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/model"
	"github.com/ninjasphere/go-ninja/rpc"
	"github.com/ninjasphere/go-ninja/rpc/json2"

	"github.com/bitly/go-simplejson"
)

// DeviceBus Context for device related announcements.
type DeviceBus struct {
	id         string
	idType     string
	name       string
	driver     *DriverBus
	devicejson *simplejson.Json
	log        *logger.Logger
	rpcServer  *rpc.Server
}

// NewDeviceBus Create a new device bus.
func NewDeviceBus(id string, idType string, name string, driver *DriverBus, devicejson *simplejson.Json) *DeviceBus {
	log := logger.GetLogger(fmt.Sprintf("device.%s.%s", id, name))

	return &DeviceBus{
		id:         id,
		idType:     idType,
		name:       name,
		driver:     driver,
		devicejson: devicejson,
		log:        log,
		rpcServer:  rpc.NewServer(driver.mqtt, json2.NewCodec()),
	}
}

type eventingService interface {
	SetEventHandler(func(event string, payload interface{}) error)
}

func (d *DeviceBus) AddChannel(channel interface{}, name string, protocol string) error {
	return d.AddChannelWithSupported(channel, name, protocol, nil, nil)
}

// AddChannel Exports a channel as an RPC service, and announces it
// If the channel implements eventingService, it will be given a function to send events
func (d *DeviceBus) AddChannelWithSupported(channel interface{}, name string, protocol string, supportedMethods *[]string, supportedEvents *[]string) error {

	deviceguid, _ := d.devicejson.Get("guid").String()
	channelguid := GetGUID(name + protocol)

	topic := "$device/" + deviceguid + "/channel/" + channelguid + "/" + protocol

	exportedService, err := d.rpcServer.RegisterService(channel, topic)

	if err != nil {
		return fmt.Errorf("Failed to register channel service on %s : %s", topic, err)
	}

	if supportedMethods == nil {
		supportedMethods = &exportedService.Methods
	}

	if supportedEvents == nil {
		events := []string{}
		supportedEvents = &events
	}

	channelAnnouncement := &model.Channel{
		ID:       channelguid,
		Protocol: protocol,
		Name:     name,
		Supported: &model.ChannelSupported{
			Methods: supportedMethods,
			Events:  supportedEvents,
		},
		Device: &model.Device{},
	}

	js, err := d.devicejson.MarshalJSON()
	json.Unmarshal(js, &channelAnnouncement.Device)

	// send out channel announcement
	err = d.rpcServer.SendNotification(topic+"/announce", channelAnnouncement) // TODO: This should probably be exposed somewhere else

	if err != nil {
		return fmt.Errorf("Failed sending channel announcement: %s", err)
	}

	d.log.Debugf("Added channel: %s (protocol: %s) with methods: %s", name, protocol, strings.Join(exportedService.Methods, ", "))

	switch channel := channel.(type) {
	case eventingService:
		channel.SetEventHandler(func(event string, payload interface{}) error {
			return exportedService.SendEvent(event, payload)
		})
	}

	return nil
}
<|endoftext|>