<commit_before>/*-
 * Copyright 2019 Square Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package certloader

import (
	"context"
	"crypto/tls"
	"crypto/x509"

	"github.com/spiffe/go-spiffe/spiffe"
)

type spiffeTLSConfigSource struct {
	peer *spiffe.TLSPeer
	log  Logger
}

type spiffeLogger struct {
	log Logger
}

func (l spiffeLogger) Debugf(format string, args ...interface{}) {
	l.log.Printf("(spiffe) [DEBUG]: "+format, args...)
}

func (l spiffeLogger) Infof(format string, args ...interface{}) {
	l.log.Printf("(spiffe) [INFO]: "+format, args...)
}

func (l spiffeLogger) Warnf(format string, args ...interface{}) {
	l.log.Printf("(spiffe) [WARN]: "+format, args...)
}

func (l spiffeLogger) Errorf(format string, args ...interface{}) {
	l.log.Printf("(spiffe) [ERROR]: "+format, args...)
}

func TLSConfigSourceFromWorkloadAPI(addr string, log Logger) (TLSConfigSource, error) {
	peer, err := spiffe.NewTLSPeer(
		spiffe.WithWorkloadAPIAddr(addr),
		spiffe.WithLogger(spiffeLogger{log: log}),
	)
	if err != nil {
		return nil, err
	}
	// TODO: provide a way to close the peer on graceful shutdown
	return &spiffeTLSConfigSource{
		peer: peer,
		log:  log,
	}, nil
}

func (s *spiffeTLSConfigSource) Reload() error {
	// The config returned by the workload TLSConfig maintains itself. Nothing
	// to do here.
	return nil
}

func (s *spiffeTLSConfigSource) CanServe() bool {
	return true
}

func (s *spiffeTLSConfigSource) GetClientConfig(base *tls.Config) (TLSClientConfig, error) {
	return s.newConfig(base)
}

func (s *spiffeTLSConfigSource) GetServerConfig(base *tls.Config) (TLSServerConfig, error) {
	return s.newConfig(base)
}

func (s *spiffeTLSConfigSource) newConfig(base *tls.Config) (*spiffeTLSConfig, error) {
	s.log.Printf("waiting for initial SPIFFE Workload API update...")
	if err := s.peer.WaitUntilReady(context.TODO()); err != nil {
		return nil, err
	}
	s.log.Printf("received SPIFFE Workload API update.")

	return &spiffeTLSConfig{
		base: base,
		peer: s.peer,
	}, nil
}

type spiffeTLSConfig struct {
	base *tls.Config
	peer *spiffe.TLSPeer
}

func (c *spiffeTLSConfig) GetClientConfig() *tls.Config {
	config := c.base.Clone()
	config.InsecureSkipVerify = true
	config.VerifyPeerCertificate = c.chainVerifyPeerCertificate(config.VerifyPeerCertificate)
	config.GetClientCertificate = spiffe.AdaptGetClientCertificate(c.peer)
	return config
}

func (c *spiffeTLSConfig) GetServerConfig() *tls.Config {
	config := c.base.Clone()
	config.ClientAuth = tls.RequireAnyClientCert
	config.InsecureSkipVerify = true
	config.VerifyPeerCertificate = c.chainVerifyPeerCertificate(config.VerifyPeerCertificate)
	config.GetCertificate = spiffe.AdaptGetCertificate(c.peer)
	return config
}

func (c *spiffeTLSConfig) chainVerifyPeerCertificate(orig func([][]byte, [][]*x509.Certificate) error) func([][]byte, [][]*x509.Certificate) error {
	return func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
		var certs []*x509.Certificate
		for _, rawCert := range rawCerts {
			cert, err := x509.ParseCertificate(rawCert)
			if err != nil {
				return err
			}
			certs = append(certs, cert)
		}

		// Grab the current set of roots.
		roots, err := c.peer.GetRoots()
		if err != nil {
			return err
		}

		// Verify the certificate chain. Allow the remote peer to have any SPIFFE ID as
		// the authorization check will happen via `orig`.
		verifiedChains, err := spiffe.VerifyPeerCertificate(certs, roots, spiffe.ExpectAnyPeer())
		if err != nil {
			return err
		}
		if orig != nil {
			return orig(rawCerts, verifiedChains)
		}
		return nil
	}
}
<commit_msg>add some comments around the use of InsecureSkipVerify<commit_after>/*-
 * Copyright 2019 Square Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package certloader

import (
	"context"
	"crypto/tls"
	"crypto/x509"

	"github.com/spiffe/go-spiffe/spiffe"
)

type spiffeTLSConfigSource struct {
	peer *spiffe.TLSPeer
	log  Logger
}

type spiffeLogger struct {
	log Logger
}

func (l spiffeLogger) Debugf(format string, args ...interface{}) {
	l.log.Printf("(spiffe) [DEBUG]: "+format, args...)
}

func (l spiffeLogger) Infof(format string, args ...interface{}) {
	l.log.Printf("(spiffe) [INFO]: "+format, args...)
}

func (l spiffeLogger) Warnf(format string, args ...interface{}) {
	l.log.Printf("(spiffe) [WARN]: "+format, args...)
}

func (l spiffeLogger) Errorf(format string, args ...interface{}) {
	l.log.Printf("(spiffe) [ERROR]: "+format, args...)
}

func TLSConfigSourceFromWorkloadAPI(addr string, log Logger) (TLSConfigSource, error) {
	peer, err := spiffe.NewTLSPeer(
		spiffe.WithWorkloadAPIAddr(addr),
		spiffe.WithLogger(spiffeLogger{log: log}),
	)
	if err != nil {
		return nil, err
	}
	// TODO: provide a way to close the peer on graceful shutdown
	return &spiffeTLSConfigSource{
		peer: peer,
		log:  log,
	}, nil
}

func (s *spiffeTLSConfigSource) Reload() error {
	// The config returned by the workload TLSConfig maintains itself. Nothing
	// to do here.
	return nil
}

func (s *spiffeTLSConfigSource) CanServe() bool {
	return true
}

func (s *spiffeTLSConfigSource) GetClientConfig(base *tls.Config) (TLSClientConfig, error) {
	return s.newConfig(base)
}

func (s *spiffeTLSConfigSource) GetServerConfig(base *tls.Config) (TLSServerConfig, error) {
	return s.newConfig(base)
}

func (s *spiffeTLSConfigSource) newConfig(base *tls.Config) (*spiffeTLSConfig, error) {
	s.log.Printf("waiting for initial SPIFFE Workload API update...")
	if err := s.peer.WaitUntilReady(context.TODO()); err != nil {
		return nil, err
	}
	s.log.Printf("received SPIFFE Workload API update.")

	return &spiffeTLSConfig{
		base: base,
		peer: s.peer,
	}, nil
}

type spiffeTLSConfig struct {
	base *tls.Config
	peer *spiffe.TLSPeer
}

func (c *spiffeTLSConfig) GetClientConfig() *tls.Config {
	config := c.base.Clone()
	// Go TLS stack will do hostname validation with is not a part of SPIFFE
	// authentication. Unfortunately there is no way to just skip hostname
	// validation without having to turn off all verification. This is still
	// safe since Go will still invoke the VerifyPeerCertificate callback,
	// albeit with an empty set of verified chains. The VerifyPeerCertificate
	// callback provided by the SPIFFE library will perform SPIFFE
	// authentication against the raw certificates.
	config.InsecureSkipVerify = true
	config.VerifyPeerCertificate = c.chainVerifyPeerCertificate(config.VerifyPeerCertificate)
	config.GetClientCertificate = spiffe.AdaptGetClientCertificate(c.peer)
	return config
}

func (c *spiffeTLSConfig) GetServerConfig() *tls.Config {
	config := c.base.Clone()
	config.ClientAuth = tls.RequireAnyClientCert
	// Go TLS stack will do hostname validation with is not a part of SPIFFE
	// authentication. Unfortunately there is no way to just skip hostname
	// validation without having to turn off all verification. This is still
	// safe since Go will still invoke the VerifyPeerCertificate callback,
	// albeit with an empty set of verified chains. The VerifyPeerCertificate
	// callback provided by the SPIFFE library will perform SPIFFE
	// authentication against the raw certificates.
	config.InsecureSkipVerify = true
	config.VerifyPeerCertificate = c.chainVerifyPeerCertificate(config.VerifyPeerCertificate)
	config.GetCertificate = spiffe.AdaptGetCertificate(c.peer)
	return config
}

func (c *spiffeTLSConfig) chainVerifyPeerCertificate(orig func([][]byte, [][]*x509.Certificate) error) func([][]byte, [][]*x509.Certificate) error {
	return func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
		var certs []*x509.Certificate
		for _, rawCert := range rawCerts {
			cert, err := x509.ParseCertificate(rawCert)
			if err != nil {
				return err
			}
			certs = append(certs, cert)
		}

		// Grab the current set of roots.
		roots, err := c.peer.GetRoots()
		if err != nil {
			return err
		}

		// Verify the certificate chain. Allow the remote peer to have any SPIFFE ID as
		// the authorization check will happen via `orig`.
		verifiedChains, err := spiffe.VerifyPeerCertificate(certs, roots, spiffe.ExpectAnyPeer())
		if err != nil {
			return err
		}
		if orig != nil {
			return orig(rawCerts, verifiedChains)
		}
		return nil
	}
}
<|endoftext|>


<commit_before>package completion

import (
	"os"
	"strings"
)

type IVariable interface {
	Lookup(name string) string
	EachKey(func(string))
}

type EnvironmentVariable struct {
}

func (this *EnvironmentVariable) Lookup(name string) string {
	return os.Getenv(name)
}

func (this *EnvironmentVariable) EachKey(f func(name string)) {
	for _, envEquation := range os.Environ() {
		equalPos := strings.IndexRune(envEquation, '=')
		if equalPos >= 0 {
			envName := envEquation[:equalPos]
			f(envName)
		}
	}
}

var PercentVariables = []IVariable{
	new(EnvironmentVariable),
}

func listUpEnv(cmdline string) ([]Element, int, error) {
	percent_count := strings.Count(cmdline, "%")
	if percent_count%2 == 0 {
		return nil, -1, nil
	}
	lastPercentPos := strings.LastIndex(cmdline, "%")
	if lastPercentPos < 0 {
		return nil, -1, nil
	}

	str := cmdline[lastPercentPos:]
	name := strings.ToUpper(str[1:])
	var matches []Element

	for _, vars := range PercentVariables {
		vars.EachKey(func(envName string) {
			if strings.HasPrefix(strings.ToUpper(envName), name) {
				envValue := "%" + envName + "%"
				element := Element{InsertStr: envValue, ListupStr: envValue}
				matches = append(matches, element)
			}
		})
	}
	if len(matches) <= 0 { // nothing matches.
		return nil, -1, nil
	}
	return matches, lastPercentPos, nil
}
<commit_msg>Support full completion of $ENVNAM.. by native go code for #228<commit_after>package completion

import (
	"os"
	"regexp"
	"strings"
)

type IVariable interface {
	Lookup(name string) string
	EachKey(func(string))
}

type EnvironmentVariable struct {
}

func (this *EnvironmentVariable) Lookup(name string) string {
	return os.Getenv(name)
}

func (this *EnvironmentVariable) EachKey(f func(name string)) {
	for _, envEquation := range os.Environ() {
		equalPos := strings.IndexRune(envEquation, '=')
		if equalPos >= 0 {
			envName := envEquation[:equalPos]
			f(envName)
		}
	}
}

var PercentVariables = []IVariable{
	new(EnvironmentVariable),
}

var rxDollar = regexp.MustCompile(`\$\w+$`)
var rxDollar2 = regexp.MustCompile(`\$\{[^\}]+$`)

func listUpEnv(cmdline string) ([]Element, int, error) {
	var makeCandidateStr func(string) string
	var replaceStartPos int
	var name string

	// %ENVNAME%
	percent_count := strings.Count(cmdline, "%")
	if percent_count%2 == 1 {
		replaceStartPos = strings.LastIndex(cmdline, "%")
		if replaceStartPos < 0 {
			return nil, -1, nil
		}
		name = cmdline[replaceStartPos+1:]
		makeCandidateStr = func(name string) string {
			return "%" + name + "%"
		}
	} else {
		// $ENVNAME
		m := rxDollar.FindStringIndex(cmdline)
		if m != nil && len(m) > 0 {
			replaceStartPos = m[0]
			name = cmdline[m[0]+1:]
			makeCandidateStr = func(name string) string {
				return "$" + name
			}
		} else {
			m = rxDollar2.FindStringIndex(cmdline)
			if m == nil || len(m) <= 0 {
				return nil, -1, nil
			}
			replaceStartPos = m[0]
			name = cmdline[m[0]+2:]
			makeCandidateStr = func(name string) string {
				return "${" + name + "}"
			}
		}
	}

	name = strings.ToUpper(name)
	var matches []Element

	for _, vars := range PercentVariables {
		vars.EachKey(func(envName string) {
			if strings.HasPrefix(strings.ToUpper(envName), name) {
				envValue := makeCandidateStr(envName)
				element := Element{InsertStr: envValue, ListupStr: envValue}
				matches = append(matches, element)
			}
		})
	}
	if len(matches) <= 0 { // nothing matches.
		return nil, -1, nil
	}
	return matches, replaceStartPos, nil
}
<|endoftext|>


<commit_before>package hashmap

import (
	"encoding/gob"
	"os"
	"time"

	"github.com/marpio/img-store/photo"
)

type HashmapMetadataStore struct {
	data map[string]*photo.Photo
}

const dbName string = "photo.db"

func NewHashmapMetadataStore() *HashmapMetadataStore {
	var decodedMetadata map[string]*photo.Photo
	if _, err := os.Stat("photo.db"); os.IsNotExist(err) {
		decodedMetadata = make(map[string]*photo.Photo)
	} else {
		f, err := os.Open(dbName)
		if err != nil {
			return nil
		}
		defer f.Close()
		dec := gob.NewDecoder(f)
		if err := dec.Decode(&decodedMetadata); err != nil {
			decodedMetadata = make(map[string]*photo.Photo)
		}
	}
	return &HashmapMetadataStore{data: decodedMetadata}
}

func (datastore *HashmapMetadataStore) GetAll() (all []*photo.Photo, err error) {
	for _, p := range datastore.data {
		all = append(all, p)
	}
	return all, nil
}

func (datastore *HashmapMetadataStore) GetByMonth(month time.Time) ([]*photo.Photo, error) {
	var res = []*photo.Photo{}

	for _, p := range datastore.data {
		if p.CreatedAt == month {
			res = append(res, p)
		}
	}
	return res, nil
}

func (datastore *HashmapMetadataStore) GetByID(id string) ([]*photo.Photo, error) {
	res := make([]*photo.Photo, 0)
	if p, ok := datastore.data[id]; ok {
		res = append(res, p)
	}
	return res, nil
}

func (datastore *HashmapMetadataStore) Save(metadataEntities []*photo.Photo) (ok bool) {
	f, err := os.Create(dbName)
	if err != nil {
		return false
	}
	defer f.Close()
	e := gob.NewEncoder(f)
	if err := e.Encode(metadataEntities); err != nil {
		return false
	}
	return true
}

func (datastore *HashmapMetadataStore) Delete(imgID string) error {
	delete(datastore.data, imgID)
	return nil
}

func (datastore *HashmapMetadataStore) GetMonths() ([]*time.Time, error) {
	var res = make(map[time.Time]interface{})
	for _, p := range datastore.data {
		if _, ok := res[p.CreatedAtMonth]; !ok {
			res[p.CreatedAtMonth] = nil
		}
	}
	list := make([]*time.Time, len(res))
	for t, _ := range res {
		list = append(list, &t)
	}
	return list, nil
}
<commit_msg>save encoded map<commit_after>package hashmap

import (
	"encoding/gob"
	"os"
	"time"

	"github.com/marpio/img-store/photo"
)

type HashmapMetadataStore struct {
	data map[string]*photo.Photo
}

const dbName string = "photo.db"

func NewHashmapMetadataStore() *HashmapMetadataStore {
	var decodedMetadata map[string]*photo.Photo
	if _, err := os.Stat("photo.db"); os.IsNotExist(err) {
		decodedMetadata = make(map[string]*photo.Photo)
	} else {
		f, err := os.Open(dbName)
		if err != nil {
			return nil
		}
		defer f.Close()
		dec := gob.NewDecoder(f)
		if err := dec.Decode(&decodedMetadata); err != nil {
			decodedMetadata = make(map[string]*photo.Photo)
		}
	}
	return &HashmapMetadataStore{data: decodedMetadata}
}

func (datastore *HashmapMetadataStore) GetAll() (all []*photo.Photo, err error) {
	for _, p := range datastore.data {
		all = append(all, p)
	}
	return all, nil
}

func (datastore *HashmapMetadataStore) GetByMonth(month time.Time) ([]*photo.Photo, error) {
	var res = []*photo.Photo{}

	for _, p := range datastore.data {
		if p.CreatedAt == month {
			res = append(res, p)
		}
	}
	return res, nil
}

func (datastore *HashmapMetadataStore) GetByID(id string) ([]*photo.Photo, error) {
	res := make([]*photo.Photo, 0)
	if p, ok := datastore.data[id]; ok {
		res = append(res, p)
	}
	return res, nil
}

func (datastore *HashmapMetadataStore) Save(metadataEntities []*photo.Photo) (ok bool) {
	res := make(map[string]*photo.Photo)
	for _, p := range metadataEntities {
		res[p.PathHash] = p
	}
	f, err := os.Create(dbName)
	if err != nil {
		return false
	}
	defer f.Close()
	e := gob.NewEncoder(f)
	if err := e.Encode(res); err != nil {
		return false
	}
	return true
}

func (datastore *HashmapMetadataStore) Delete(imgID string) error {
	delete(datastore.data, imgID)
	return nil
}

func (datastore *HashmapMetadataStore) GetMonths() ([]*time.Time, error) {
	var res = make(map[time.Time]interface{})
	for _, p := range datastore.data {
		if _, ok := res[p.CreatedAtMonth]; !ok {
			res[p.CreatedAtMonth] = nil
		}
	}
	list := make([]*time.Time, len(res))
	for t, _ := range res {
		list = append(list, &t)
	}
	return list, nil
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Frank Wessels <fwessels@xs4all.nl>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"C"
	"os"
	"strings"
	"io"
	"io/ioutil"
	"github.com/s3git/s3git-go"
	"encoding/json"
)

//export s3git_init_repository
func s3git_init_repository(path *C.char) int {

	_, err := s3git.InitRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	return 0
}

//export s3git_open_repository
func s3git_open_repository(path *C.char) int {

	_, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	return 0
}

//export s3git_clone
func s3git_clone(url, path, accessKey, secretKey *C.char) int {

	options := []s3git.CloneOptions{}
	if access := C.GoString(accessKey); access != "" {
		options = append(options, s3git.CloneOptionSetAccessKey(access))
	}
	if secret := C.GoString(secretKey); secret != "" {
		options = append(options, s3git.CloneOptionSetSecretKey(secret))
	}

	_, err := s3git.Clone(C.GoString(url), C.GoString(path), options...)
	if err != nil {
		return -1
	}

	return 0
}

//export s3git_add
func s3git_add(path, filename *C.char) *C.char {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return C.CString("")
	}

	file, err := os.Open(C.GoString(filename))
	if err != nil {
		return C.CString("")
	}

	key, _, err := repo.Add(file)
	if err != nil {
		return C.CString("")
	}

	return C.CString(key)
}

//export s3git_commit
func s3git_commit(path, message *C.char) int {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	repo.Commit(C.GoString(message))

	return 0
}

//export s3git_get
func s3git_get(path, hash *C.char) *C.char {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return C.CString("")
	}

	r, err := repo.Get(C.GoString(hash))
	if err != nil {
		return C.CString("")
	}

	// TODO: Return stream directly instead of using temp file (and prevent dangling file)
	tmpfile, err := ioutil.TempFile("", "s3git")
	if err != nil {
		return C.CString("")
	}

	io.Copy(tmpfile, r)

	if err := tmpfile.Close(); err != nil {
		return C.CString("")
	}

	return C.CString(tmpfile.Name())
}

//export s3git_push
func s3git_push(path *C.char, hydrate bool) int {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	repo.Push(hydrate, func(total int64) {})

	return 0
}

//export s3git_pull
func s3git_pull(path *C.char) int {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	repo.Pull(func(total int64) {})

	return 0
}

//export s3git_list
func s3git_list(path, hash *C.char) *C.char {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return C.CString("")
	}

	list, _ := repo.List(C.GoString(hash))

	response := []string{}

	count := 0
	for l := range list {
		response = append(response, l)

		count++
		if count > 1000 {
			break
		}
	}

	return C.CString(strings.Join(response, ","))
}

//export s3git_list_commits
func s3git_list_commits(path *C.char) *C.char {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return C.CString("")
	}

	list, _ := repo.ListCommits("")

	result := []s3git.Commit{}

	count := 0
	for l := range list {
		result = append(result, l)

		count++
		if count > 1000 {
			break
		}
	}

	b, err := json.Marshal(result)

	return C.CString(string(b))
}

func main() {}
<commit_msg>Add remote adding to library<commit_after>/*
 * Copyright 2016 Frank Wessels <fwessels@xs4all.nl>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"C"
	"os"
	"strings"
	"io"
	"io/ioutil"
	"github.com/s3git/s3git-go"
	"encoding/json"
)

//export s3git_init_repository
func s3git_init_repository(path *C.char) int {

	_, err := s3git.InitRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	return 0
}

//export s3git_open_repository
func s3git_open_repository(path *C.char) int {

	_, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	return 0
}

//export s3git_clone
func s3git_clone(url, path, accessKey, secretKey *C.char) int {

	options := []s3git.CloneOptions{}
	if access := C.GoString(accessKey); access != "" {
		options = append(options, s3git.CloneOptionSetAccessKey(access))
	}
	if secret := C.GoString(secretKey); secret != "" {
		options = append(options, s3git.CloneOptionSetSecretKey(secret))
	}

	_, err := s3git.Clone(C.GoString(url), C.GoString(path), options...)
	if err != nil {
		return -1
	}

	return 0
}

//export s3git_add
func s3git_add(path, filename *C.char) *C.char {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return C.CString("")
	}

	file, err := os.Open(C.GoString(filename))
	if err != nil {
		return C.CString("")
	}

	key, _, err := repo.Add(file)
	if err != nil {
		return C.CString("")
	}

	return C.CString(key)
}

//export s3git_commit
func s3git_commit(path, message *C.char) int {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	repo.Commit(C.GoString(message))

	return 0
}

//export s3git_get
func s3git_get(path, hash *C.char) *C.char {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return C.CString("")
	}

	r, err := repo.Get(C.GoString(hash))
	if err != nil {
		return C.CString("")
	}

	// TODO: Return stream directly instead of using temp file (and prevent dangling file)
	tmpfile, err := ioutil.TempFile("", "s3git")
	if err != nil {
		return C.CString("")
	}

	io.Copy(tmpfile, r)

	if err := tmpfile.Close(); err != nil {
		return C.CString("")
	}

	return C.CString(tmpfile.Name())
}

//export s3git_push
func s3git_push(path *C.char, hydrate bool) int {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	repo.Push(hydrate, func(total int64) {})

	return 0
}

//export s3git_pull
func s3git_pull(path *C.char) int {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	repo.Pull(func(total int64) {})

	return 0
}

//export s3git_list
func s3git_list(path, hash *C.char) *C.char {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return C.CString("")
	}

	list, _ := repo.List(C.GoString(hash))

	response := []string{}

	count := 0
	for l := range list {
		response = append(response, l)

		count++
		if count > 1000 {
			break
		}
	}

	return C.CString(strings.Join(response, ","))
}

//export s3git_list_commits
func s3git_list_commits(path *C.char) *C.char {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return C.CString("")
	}

	list, _ := repo.ListCommits("")

	result := []s3git.Commit{}

	count := 0
	for l := range list {
		result = append(result, l)

		count++
		if count > 1000 {
			break
		}
	}

	b, err := json.Marshal(result)

	return C.CString(string(b))
}

//export s3git_remote_add
func s3git_remote_add(path, name, resource, accessKey, secretKey, endpoint *C.char) int {

	repo, err := s3git.OpenRepository(C.GoString(path))
	if err != nil {
		return -1
	}

	options := []s3git.RemoteOptions{}
	if ep := C.GoString(endpoint); ep != "" {
		options = append(options, s3git.RemoteOptionSetEndpoint(ep))
	}

	err = repo.RemoteAdd(C.GoString(name), C.GoString(resource), C.GoString(accessKey), C.GoString(secretKey), options...)
	if err != nil {
		return -1
	}

	return 0
}

func main() {}
<|endoftext|>


<commit_before>package support

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

type Config struct {
	Host       string
	Trace      bool
	Routerless bool
}

type Client struct {
	config     Config
	httpClient *http.Client
}

func NewClient(config Config) *Client {
	return &Client{
		config:     config,
		httpClient: http.DefaultClient,
	}
}
func (c Client) DoTyped(method string, path string, payload map[string]interface{}, token string, results interface{}) (int, error) {
	var requestBody io.Reader

	if payload != nil {
		content, err := json.Marshal(payload)
		if err != nil {
			return 0, err
		}

		requestBody = bytes.NewBuffer(content)
	}

	responseCode, responseBody, err := c.makeRequest(method, c.config.Host+path, requestBody, token)
	if err != nil {
		return 0, err
	}

	if strings.Contains(string(responseBody), "{") {
		err = json.Unmarshal(responseBody, &results)
		if err != nil {
			return 0, err
		}
	}

	return responseCode, err
}

func (c Client) Do(method string, path string, payload map[string]interface{}, token string) (int, map[string]interface{}, error) {
	var requestBody io.Reader

	if payload != nil {
		content, err := json.Marshal(payload)
		if err != nil {
			return 0, nil, err
		}

		requestBody = bytes.NewBuffer(content)
	}

	responseCode, responseBody, err := c.makeRequest(method, c.config.Host+path, requestBody, token)
	if err != nil {
		return 0, nil, err
	}

	var body map[string]interface{}

	if strings.Contains(string(responseBody), "{") {
		err = json.Unmarshal(responseBody, &body)
		if err != nil {
			return 0, nil, err
		}
	}

	return responseCode, body, err
}

func (c Client) makeRequest(method, path string, content io.Reader, token string) (int, []byte, error) {
	request, err := http.NewRequest(method, path, content)
	if err != nil {
		return 0, []byte{}, err
	}
	c.printRequest(request)

	request.Header.Set("X-NOTIFICATIONS-VERSION", "2")
	request.Header.Set("Authorization", "Bearer "+token)
	if c.config.Routerless {
		request.Header.Set("X-Vcap-Request-Id", "some-totally-fake-vcap-request-id")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return 0, []byte{}, err
	}
	defer response.Body.Close()

	c.printResponse(response)

	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return 0, []byte{}, err
	}

	return response.StatusCode, responseBody, nil
}

func (c Client) printRequest(request *http.Request) {
	if !c.config.Trace {
		return
	}

	buffer := bytes.NewBuffer([]byte{})
	body := bytes.NewBuffer([]byte{})
	if request.Body != nil {
		_, err := io.Copy(io.MultiWriter(buffer, body), request.Body)
		if err != nil {
			panic(err)
		}
	}

	request.Body = ioutil.NopCloser(body)

	fmt.Printf("[REQ] %s %s %s\n", request.Method, request.URL.String(), buffer.String())
}

func (c Client) printResponse(response *http.Response) {
	if !c.config.Trace {
		return
	}

	buffer := bytes.NewBuffer([]byte{})
	body := bytes.NewBuffer([]byte{})
	if response.Body != nil {
		_, err := io.Copy(io.MultiWriter(buffer, body), response.Body)
		if err != nil {
			panic(err)
		}
	}

	response.Body = ioutil.NopCloser(body)

	fmt.Printf("[RES] %s %s\n", response.Status, buffer.String())
}
<commit_msg>Refactor request-response buffer copying<commit_after>package support

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

type Config struct {
	Host       string
	Trace      bool
	Routerless bool
}

type Client struct {
	config     Config
	httpClient *http.Client
}

func NewClient(config Config) *Client {
	return &Client{
		config:     config,
		httpClient: http.DefaultClient,
	}
}

func (c Client) DoTyped(method string, path string, payload map[string]interface{}, token string, results interface{}) (int, error) {
	var requestBody io.Reader

	if payload != nil {
		content, err := json.Marshal(payload)
		if err != nil {
			return 0, err
		}

		requestBody = bytes.NewBuffer(content)
	}

	responseCode, responseBody, err := c.makeRequest(method, c.config.Host+path, requestBody, token)
	if err != nil {
		return 0, err
	}

	if strings.Contains(string(responseBody), "{") {
		err = json.Unmarshal(responseBody, &results)
		if err != nil {
			return 0, err
		}
	}

	return responseCode, err
}

func (c Client) Do(method string, path string, payload map[string]interface{}, token string) (int, map[string]interface{}, error) {
	var requestBody io.Reader

	if payload != nil {
		content, err := json.Marshal(payload)
		if err != nil {
			return 0, nil, err
		}

		requestBody = bytes.NewBuffer(content)
	}

	responseCode, responseBody, err := c.makeRequest(method, c.config.Host+path, requestBody, token)
	if err != nil {
		return 0, nil, err
	}

	var body map[string]interface{}

	if strings.Contains(string(responseBody), "{") {
		err = json.Unmarshal(responseBody, &body)
		if err != nil {
			return 0, nil, err
		}
	}

	return responseCode, body, err
}

func (c Client) makeRequest(method, path string, content io.Reader, token string) (int, []byte, error) {
	request, err := http.NewRequest(method, path, content)
	if err != nil {
		return 0, []byte{}, err
	}
	c.printRequest(request)

	request.Header.Set("X-NOTIFICATIONS-VERSION", "2")
	request.Header.Set("Authorization", "Bearer "+token)
	if c.config.Routerless {
		request.Header.Set("X-Vcap-Request-Id", "some-totally-fake-vcap-request-id")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return 0, []byte{}, err
	}
	defer response.Body.Close()

	c.printResponse(response)

	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return 0, []byte{}, err
	}

	return response.StatusCode, responseBody, nil
}

func (c Client) printRequest(request *http.Request) {
	if !c.config.Trace {
		return
	}

	var buffer *bytes.Buffer
	request.Body, buffer = duplicateBuffer(request.Body)

	fmt.Printf("[REQ] %s %s %s\n", request.Method, request.URL.String(), buffer.String())
}

func (c Client) printResponse(response *http.Response) {
	if !c.config.Trace {
		return
	}

	var buffer *bytes.Buffer
	response.Body, buffer = duplicateBuffer(response.Body)

	fmt.Printf("[RES] %s %s\n", response.Status, buffer.String())
}

func duplicateBuffer(originalBody io.Reader) (io.ReadCloser, *bytes.Buffer) {
	buffer := bytes.NewBuffer([]byte{})
	body := bytes.NewBuffer([]byte{})
	if originalBody != nil {
		_, err := io.Copy(io.MultiWriter(buffer, body), originalBody)
		if err != nil {
			panic(err)
		}
	}
	return ioutil.NopCloser(body), buffer
}
<|endoftext|>


<commit_before>package commands

import (
	"errors"
	"fmt"
	"io"
	"strconv"

	"github.com/bryanl/doit"
	"github.com/digitalocean/godo"
	"github.com/spf13/cobra"
)

// Domain creates the domain commands heirarchy.
func Domain() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "domain",
		Short: "domain commands",
		Long:  "domain is used to access domain commands",
	}

	cmdDomainCreate := cmdBuilder(RunDomainCreate, "create", "create domain", writer, aliasOpt("c"))
	cmd.AddCommand(cmdDomainCreate)
	addStringFlag(cmdDomainCreate, doit.ArgIPAddress, "", "IP address", requiredOpt())

	cmdDomainList := cmdBuilder(RunDomainList, "list", "list comains", writer, aliasOpt("ls"))
	cmd.AddCommand(cmdDomainList)

	cmdDomainGet := cmdBuilder(RunDomainGet, "get", "get domain", writer, aliasOpt("g"))
	cmd.AddCommand(cmdDomainGet)

	cmdDomainDelete := cmdBuilder(RunDomainDelete, "delete", "delete droplet", writer, aliasOpt("g"))
	cmd.AddCommand(cmdDomainDelete)

	cmdRecord := &cobra.Command{
		Use:   "records",
		Short: "domain record commands",
		Long:  "commands for interacting with an individual domain",
	}
	cmd.AddCommand(cmdRecord)

	cmdRecordList := cmdBuilder(RunRecordList, "list", "list records", writer, aliasOpt("ls"))
	cmdRecord.AddCommand(cmdRecordList)
	addStringFlag(cmdRecordList, doit.ArgDomainName, "", "Domain name")

	cmdRecordCreate := cmdBuilder(RunRecordCreate, "create", "create record", writer, aliasOpt("c"))
	cmdRecord.AddCommand(cmdRecordCreate)
	addStringFlag(cmdRecordCreate, doit.ArgRecordType, "", "Record type")
	addStringFlag(cmdRecordCreate, doit.ArgRecordName, "", "Record name")
	addStringFlag(cmdRecordCreate, doit.ArgRecordData, "", "Record data")
	addIntFlag(cmdRecordCreate, doit.ArgRecordPriority, 0, "Record priority")
	addIntFlag(cmdRecordCreate, doit.ArgRecordPort, 0, "Record port")
	addIntFlag(cmdRecordCreate, doit.ArgRecordWeight, 0, "Record weight")

	cmdRecordDelete := cmdBuilder(RunRecordDelete, "delete <domain> <record id...>", "delete record", writer, aliasOpt("d"))
	cmdRecord.AddCommand(cmdRecordDelete)

	cmdRecordUpdate := cmdBuilder(RunRecordUpdate, "update", "update record", writer, aliasOpt("u"))
	cmdRecord.AddCommand(cmdRecordUpdate)
	addIntFlag(cmdRecordUpdate, doit.ArgRecordID, 0, "Record ID")
	addStringFlag(cmdRecordUpdate, doit.ArgRecordType, "", "Record type")
	addStringFlag(cmdRecordUpdate, doit.ArgRecordName, "", "Record name")
	addStringFlag(cmdRecordUpdate, doit.ArgRecordData, "", "Record data")
	addIntFlag(cmdRecordUpdate, doit.ArgRecordPriority, 0, "Record priority")
	addIntFlag(cmdRecordUpdate, doit.ArgRecordPort, 0, "Record port")
	addIntFlag(cmdRecordUpdate, doit.ArgRecordWeight, 0, "Record weight")

	return cmd
}

// RunDomainCreate runs domain create.
func RunDomainCreate(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	domainName := args[0]

	client := config.GetGodoClient()

	ipAddress, err := config.GetString(ns, "ip-address")
	if err != nil {
		return err
	}

	req := &godo.DomainCreateRequest{
		Name:      domainName,
		IPAddress: ipAddress,
	}

	d, _, err := client.Domains.Create(req)
	if err != nil {
		return err
	}

	return displayOutput(&domain{domains: domains{*d}}, out)
}

// RunDomainList runs domain create.
func RunDomainList(ns string, config doit.Config, out io.Writer, args []string) error {
	client := config.GetGodoClient()

	f := func(opt *godo.ListOptions) ([]interface{}, *godo.Response, error) {
		list, resp, err := client.Domains.List(opt)
		if err != nil {
			return nil, nil, err
		}

		si := make([]interface{}, len(list))
		for i := range list {
			si[i] = list[i]
		}

		return si, resp, err
	}

	si, err := doit.PaginateResp(f)
	if err != nil {
		return err
	}

	list := make([]godo.Domain, len(si))
	for i := range si {
		list[i] = si[i].(godo.Domain)
	}

	return displayOutput(&domain{domains: list}, out)
}

// RunDomainGet retrieves a domain by name.
func RunDomainGet(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	id := args[0]

	client := config.GetGodoClient()

	if len(id) < 1 {
		return errors.New("invalid domain name")
	}

	d, _, err := client.Domains.Get(id)
	if err != nil {
		return err
	}

	return displayOutput(&domain{domains: domains{*d}}, out)
}

// RunDomainDelete deletes a domain by name.
func RunDomainDelete(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	name := args[0]

	client := config.GetGodoClient()

	if len(name) < 1 {
		return errors.New("invalid domain name")
	}

	_, err := client.Domains.Delete(name)
	return err
}

// RunRecordList list records for a domain.
func RunRecordList(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	name := args[0]

	client := config.GetGodoClient()

	if len(name) < 1 {
		return errors.New("domain name is missing")
	}

	f := func(opt *godo.ListOptions) ([]interface{}, *godo.Response, error) {
		list, resp, err := client.Domains.Records(name, opt)
		if err != nil {
			return nil, nil, err
		}

		si := make([]interface{}, len(list))
		for i := range list {
			si[i] = list[i]
		}

		return si, resp, err
	}

	si, err := doit.PaginateResp(f)
	if err != nil {
		return err
	}

	list := make([]godo.DomainRecord, len(si))
	for i := range si {
		list[i] = si[i].(godo.DomainRecord)
	}

	return displayOutput(&domainRecord{domainRecords: list}, out)
}

// RunRecordCreate creates a domain record.
func RunRecordCreate(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	name := args[0]

	client := config.GetGodoClient()

	rType, err := config.GetString(ns, doit.ArgRecordType)
	if err != nil {
		return err
	}

	rName, err := config.GetString(ns, doit.ArgRecordName)
	if err != nil {
		return err
	}

	rData, err := config.GetString(ns, doit.ArgRecordData)
	if err != nil {
		return err
	}

	rPriority, err := config.GetInt(ns, doit.ArgRecordPriority)
	if err != nil {
		return err
	}

	rPort, err := config.GetInt(ns, doit.ArgRecordPort)
	if err != nil {
		return err
	}

	rWeight, err := config.GetInt(ns, doit.ArgRecordWeight)
	if err != nil {
		return err
	}

	drcr := &godo.DomainRecordEditRequest{
		Type:     rType,
		Name:     rName,
		Data:     rData,
		Priority: rPriority,
		Port:     rPort,
		Weight:   rWeight,
	}

	if len(drcr.Type) == 0 {
		return errors.New("record request is missing type")
	}

	r, _, err := client.Domains.CreateRecord(name, drcr)
	if err != nil {
		return err
	}

	return displayOutput(&domainRecord{domainRecords{*r}}, out)
}

// RunRecordDelete deletes a domain record.
func RunRecordDelete(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) < 2 {
		return doit.NewMissingArgsErr(ns)
	}

	domainName, ids := args[0], args[1:]
	if len(ids) < 1 {
		return doit.NewMissingArgsErr(ns)
	}

	client := config.GetGodoClient()

	for _, i := range ids {
		id, err := strconv.Atoi(i)
		if err != nil {
			return fmt.Errorf("invalid record id %q", i)
		}

		_, err = client.Domains.DeleteRecord(domainName, id)
		if err != nil {
			return err
		}
	}

	return nil
}

// RunRecordUpdate updates a domain record.
func RunRecordUpdate(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	domainName := args[0]

	client := config.GetGodoClient()

	recordID, err := config.GetInt(ns, doit.ArgRecordID)
	if err != nil {
		return err
	}

	rType, err := config.GetString(ns, doit.ArgRecordType)
	if err != nil {
		return err
	}

	rName, err := config.GetString(ns, doit.ArgRecordName)
	if err != nil {
		return err
	}

	rData, err := config.GetString(ns, doit.ArgRecordData)
	if err != nil {
		return err
	}

	rPriority, err := config.GetInt(ns, doit.ArgRecordPriority)
	if err != nil {
		return err
	}

	rPort, err := config.GetInt(ns, doit.ArgRecordPort)
	if err != nil {
		return err
	}

	rWeight, err := config.GetInt(ns, doit.ArgRecordWeight)
	if err != nil {
		return err
	}

	drcr := &godo.DomainRecordEditRequest{
		Type:     rType,
		Name:     rName,
		Data:     rData,
		Priority: rPriority,
		Port:     rPort,
		Weight:   rWeight,
	}

	r, _, err := client.Domains.EditRecord(domainName, recordID, drcr)
	if err != nil {
		return err
	}

	return displayOutput(&domainRecord{domainRecords{*r}}, out)
}
<commit_msg>add better help text for domains<commit_after>package commands

import (
	"errors"
	"fmt"
	"io"
	"strconv"

	"github.com/bryanl/doit"
	"github.com/digitalocean/godo"
	"github.com/spf13/cobra"
)

// Domain creates the domain commands heirarchy.
func Domain() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "domain",
		Short: "domain commands",
		Long:  "domain is used to access domain commands",
	}

	cmdDomainCreate := cmdBuilder(RunDomainCreate, "create <domain>", "create domain", writer, aliasOpt("c"))
	cmd.AddCommand(cmdDomainCreate)
	addStringFlag(cmdDomainCreate, doit.ArgIPAddress, "", "IP address", requiredOpt())

	cmdDomainList := cmdBuilder(RunDomainList, "list", "list comains", writer, aliasOpt("ls"))
	cmd.AddCommand(cmdDomainList)

	cmdDomainGet := cmdBuilder(RunDomainGet, "get <domain>", "get domain", writer, aliasOpt("g"))
	cmd.AddCommand(cmdDomainGet)

	cmdDomainDelete := cmdBuilder(RunDomainDelete, "delete <domain>", "delete droplet", writer, aliasOpt("g"))
	cmd.AddCommand(cmdDomainDelete)

	cmdRecord := &cobra.Command{
		Use:   "records",
		Short: "domain record commands",
		Long:  "commands for interacting with an individual domain",
	}
	cmd.AddCommand(cmdRecord)

	cmdRecordList := cmdBuilder(RunRecordList, "list <domain>", "list records", writer, aliasOpt("ls"))
	cmdRecord.AddCommand(cmdRecordList)
	addStringFlag(cmdRecordList, doit.ArgDomainName, "", "Domain name")

	cmdRecordCreate := cmdBuilder(RunRecordCreate, "create <domain>", "create record", writer, aliasOpt("c"))
	cmdRecord.AddCommand(cmdRecordCreate)
	addStringFlag(cmdRecordCreate, doit.ArgRecordType, "", "Record type")
	addStringFlag(cmdRecordCreate, doit.ArgRecordName, "", "Record name")
	addStringFlag(cmdRecordCreate, doit.ArgRecordData, "", "Record data")
	addIntFlag(cmdRecordCreate, doit.ArgRecordPriority, 0, "Record priority")
	addIntFlag(cmdRecordCreate, doit.ArgRecordPort, 0, "Record port")
	addIntFlag(cmdRecordCreate, doit.ArgRecordWeight, 0, "Record weight")

	cmdRecordDelete := cmdBuilder(RunRecordDelete, "delete <domain> <record id...>", "delete record", writer, aliasOpt("d"))
	cmdRecord.AddCommand(cmdRecordDelete)

	cmdRecordUpdate := cmdBuilder(RunRecordUpdate, "update <domain>", "update record", writer, aliasOpt("u"))
	cmdRecord.AddCommand(cmdRecordUpdate)
	addIntFlag(cmdRecordUpdate, doit.ArgRecordID, 0, "Record ID")
	addStringFlag(cmdRecordUpdate, doit.ArgRecordType, "", "Record type")
	addStringFlag(cmdRecordUpdate, doit.ArgRecordName, "", "Record name")
	addStringFlag(cmdRecordUpdate, doit.ArgRecordData, "", "Record data")
	addIntFlag(cmdRecordUpdate, doit.ArgRecordPriority, 0, "Record priority")
	addIntFlag(cmdRecordUpdate, doit.ArgRecordPort, 0, "Record port")
	addIntFlag(cmdRecordUpdate, doit.ArgRecordWeight, 0, "Record weight")

	return cmd
}

// RunDomainCreate runs domain create.
func RunDomainCreate(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	domainName := args[0]

	client := config.GetGodoClient()

	ipAddress, err := config.GetString(ns, "ip-address")
	if err != nil {
		return err
	}

	req := &godo.DomainCreateRequest{
		Name:      domainName,
		IPAddress: ipAddress,
	}

	d, _, err := client.Domains.Create(req)
	if err != nil {
		return err
	}

	return displayOutput(&domain{domains: domains{*d}}, out)
}

// RunDomainList runs domain create.
func RunDomainList(ns string, config doit.Config, out io.Writer, args []string) error {
	client := config.GetGodoClient()

	f := func(opt *godo.ListOptions) ([]interface{}, *godo.Response, error) {
		list, resp, err := client.Domains.List(opt)
		if err != nil {
			return nil, nil, err
		}

		si := make([]interface{}, len(list))
		for i := range list {
			si[i] = list[i]
		}

		return si, resp, err
	}

	si, err := doit.PaginateResp(f)
	if err != nil {
		return err
	}

	list := make([]godo.Domain, len(si))
	for i := range si {
		list[i] = si[i].(godo.Domain)
	}

	return displayOutput(&domain{domains: list}, out)
}

// RunDomainGet retrieves a domain by name.
func RunDomainGet(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	id := args[0]

	client := config.GetGodoClient()

	if len(id) < 1 {
		return errors.New("invalid domain name")
	}

	d, _, err := client.Domains.Get(id)
	if err != nil {
		return err
	}

	return displayOutput(&domain{domains: domains{*d}}, out)
}

// RunDomainDelete deletes a domain by name.
func RunDomainDelete(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	name := args[0]

	client := config.GetGodoClient()

	if len(name) < 1 {
		return errors.New("invalid domain name")
	}

	_, err := client.Domains.Delete(name)
	return err
}

// RunRecordList list records for a domain.
func RunRecordList(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	name := args[0]

	client := config.GetGodoClient()

	if len(name) < 1 {
		return errors.New("domain name is missing")
	}

	f := func(opt *godo.ListOptions) ([]interface{}, *godo.Response, error) {
		list, resp, err := client.Domains.Records(name, opt)
		if err != nil {
			return nil, nil, err
		}

		si := make([]interface{}, len(list))
		for i := range list {
			si[i] = list[i]
		}

		return si, resp, err
	}

	si, err := doit.PaginateResp(f)
	if err != nil {
		return err
	}

	list := make([]godo.DomainRecord, len(si))
	for i := range si {
		list[i] = si[i].(godo.DomainRecord)
	}

	return displayOutput(&domainRecord{domainRecords: list}, out)
}

// RunRecordCreate creates a domain record.
func RunRecordCreate(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	name := args[0]

	client := config.GetGodoClient()

	rType, err := config.GetString(ns, doit.ArgRecordType)
	if err != nil {
		return err
	}

	rName, err := config.GetString(ns, doit.ArgRecordName)
	if err != nil {
		return err
	}

	rData, err := config.GetString(ns, doit.ArgRecordData)
	if err != nil {
		return err
	}

	rPriority, err := config.GetInt(ns, doit.ArgRecordPriority)
	if err != nil {
		return err
	}

	rPort, err := config.GetInt(ns, doit.ArgRecordPort)
	if err != nil {
		return err
	}

	rWeight, err := config.GetInt(ns, doit.ArgRecordWeight)
	if err != nil {
		return err
	}

	drcr := &godo.DomainRecordEditRequest{
		Type:     rType,
		Name:     rName,
		Data:     rData,
		Priority: rPriority,
		Port:     rPort,
		Weight:   rWeight,
	}

	if len(drcr.Type) == 0 {
		return errors.New("record request is missing type")
	}

	r, _, err := client.Domains.CreateRecord(name, drcr)
	if err != nil {
		return err
	}

	return displayOutput(&domainRecord{domainRecords{*r}}, out)
}

// RunRecordDelete deletes a domain record.
func RunRecordDelete(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) < 2 {
		return doit.NewMissingArgsErr(ns)
	}

	domainName, ids := args[0], args[1:]
	if len(ids) < 1 {
		return doit.NewMissingArgsErr(ns)
	}

	client := config.GetGodoClient()

	for _, i := range ids {
		id, err := strconv.Atoi(i)
		if err != nil {
			return fmt.Errorf("invalid record id %q", i)
		}

		_, err = client.Domains.DeleteRecord(domainName, id)
		if err != nil {
			return err
		}
	}

	return nil
}

// RunRecordUpdate updates a domain record.
func RunRecordUpdate(ns string, config doit.Config, out io.Writer, args []string) error {
	if len(args) != 1 {
		return doit.NewMissingArgsErr(ns)
	}
	domainName := args[0]

	client := config.GetGodoClient()

	recordID, err := config.GetInt(ns, doit.ArgRecordID)
	if err != nil {
		return err
	}

	rType, err := config.GetString(ns, doit.ArgRecordType)
	if err != nil {
		return err
	}

	rName, err := config.GetString(ns, doit.ArgRecordName)
	if err != nil {
		return err
	}

	rData, err := config.GetString(ns, doit.ArgRecordData)
	if err != nil {
		return err
	}

	rPriority, err := config.GetInt(ns, doit.ArgRecordPriority)
	if err != nil {
		return err
	}

	rPort, err := config.GetInt(ns, doit.ArgRecordPort)
	if err != nil {
		return err
	}

	rWeight, err := config.GetInt(ns, doit.ArgRecordWeight)
	if err != nil {
		return err
	}

	drcr := &godo.DomainRecordEditRequest{
		Type:     rType,
		Name:     rName,
		Data:     rData,
		Priority: rPriority,
		Port:     rPort,
		Weight:   rWeight,
	}

	r, _, err := client.Domains.EditRecord(domainName, recordID, drcr)
	if err != nil {
		return err
	}

	return displayOutput(&domainRecord{domainRecords{*r}}, out)
}
<|endoftext|>


<commit_before>/*
Copyright 2020 The Kubernetes Authors.

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

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

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

package fi

import (
	"bytes"
	"io/ioutil"
	"os"
	"path"
	"testing"
)

func TestWriteFile(t *testing.T) {
	var TempDir, _ = ioutil.TempDir("", "fitest")
	defer os.Remove(TempDir)
	tests := []struct {
		path     string
		data     []byte
		fileMode os.FileMode
		dirMode  os.FileMode
	}{
		{
			path:     path.Join(TempDir, "SubDir", "test1.tmp"),
			data:     []byte("test data\nline 1\r\nline 2"),
			fileMode: 0644,
			dirMode:  0755,
		},
	}
	for _, test := range tests {
		err := WriteFile(test.path, NewBytesResource(test.data), test.fileMode, test.dirMode)
		if err != nil {
			t.Errorf("Error writing file {%s}, error: {%v}", test.path, err)
			continue
		}

		// Check file content
		data, err := ioutil.ReadFile(test.path)
		if err != nil {
			t.Errorf("Error reading file {%s}, error: {%v}", test.path, err)
			continue
		}
		if !bytes.Equal(data, test.data) {
			t.Errorf("Expected file content {%v}, got {%v}", test.data, data)
			continue
		}

		// Check file mode
		stat, err := os.Lstat(test.path)
		if err != nil {
			t.Errorf("Error getting file mode of {%s}, error: {%v}", test.path, err)
			continue
		}
		fileMode := stat.Mode() & os.ModePerm
		if fileMode != test.fileMode {
			t.Errorf("Expected file mode {%v}, got {%v}", test.fileMode, fileMode)
			continue
		}

		// Check dir mode
		dirPath := path.Dir(test.path)
		stat, err = os.Lstat(dirPath)
		if err != nil {
			t.Errorf("Error getting dir mode of {%s}, error: {%v}", dirPath, err)
			continue
		}
		dirMode := stat.Mode() & os.ModePerm
		if dirMode != test.dirMode {
			t.Errorf("Expected dir mode {%v}, got {%v}", test.dirMode, dirMode)
			continue
		}
	}
}
<commit_msg>cleanup tempfiles for files_test<commit_after>/*
Copyright 2020 The Kubernetes Authors.

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

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

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

package fi

import (
	"bytes"
	"io/ioutil"
	"os"
	"path"
	"testing"
)

func TestWriteFile(t *testing.T) {
	var TempDir, _ = ioutil.TempDir("", "fitest")
	defer os.RemoveAll(TempDir)
	tests := []struct {
		path     string
		data     []byte
		fileMode os.FileMode
		dirMode  os.FileMode
	}{
		{
			path:     path.Join(TempDir, "SubDir", "test1.tmp"),
			data:     []byte("test data\nline 1\r\nline 2"),
			fileMode: 0644,
			dirMode:  0755,
		},
	}
	for _, test := range tests {
		err := WriteFile(test.path, NewBytesResource(test.data), test.fileMode, test.dirMode)
		if err != nil {
			t.Errorf("Error writing file {%s}, error: {%v}", test.path, err)
			continue
		}

		// Check file content
		data, err := ioutil.ReadFile(test.path)
		if err != nil {
			t.Errorf("Error reading file {%s}, error: {%v}", test.path, err)
			continue
		}
		if !bytes.Equal(data, test.data) {
			t.Errorf("Expected file content {%v}, got {%v}", test.data, data)
			continue
		}

		// Check file mode
		stat, err := os.Lstat(test.path)
		if err != nil {
			t.Errorf("Error getting file mode of {%s}, error: {%v}", test.path, err)
			continue
		}
		fileMode := stat.Mode() & os.ModePerm
		if fileMode != test.fileMode {
			t.Errorf("Expected file mode {%v}, got {%v}", test.fileMode, fileMode)
			continue
		}

		// Check dir mode
		dirPath := path.Dir(test.path)
		stat, err = os.Lstat(dirPath)
		if err != nil {
			t.Errorf("Error getting dir mode of {%s}, error: {%v}", dirPath, err)
			continue
		}
		dirMode := stat.Mode() & os.ModePerm
		if dirMode != test.dirMode {
			t.Errorf("Expected dir mode {%v}, got {%v}", test.dirMode, dirMode)
			continue
		}
	}
}
<|endoftext|>


<commit_before>package boshinit_test

import (
	"github.com/enaml-ops/enaml"
	. "github.com/enaml-ops/omg-cli/deployments/bosh-init"
	"github.com/enaml-ops/omg-cli/deployments/bosh-init/enaml-gen/vsphere_cpi"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("NewVSphereBosh", func() {
	Describe("given the function", func() {
		Context("when called w/ valid parameters", func() {
			var boshConfig = BoshInitConfig{
				Name:                              "bosh",
				BoshReleaseVersion:                "256.2",
				BoshPrivateIP:                     "172.16.1.6",
				BoshCPIReleaseVersion:             "22",
				GoAgentVersion:                    "3232.4",
				BoshReleaseSHA:                    "ff2f4e16e02f66b31c595196052a809100cfd5a8",
				BoshCPIReleaseSHA:                 "dd1827e5f4dfc37656017c9f6e48441f51a7ab73",
				GoAgentSHA:                        "27ec32ddbdea13e3025700206388ae5882a23c67",
				BoshDirectorName:                  "my-bosh",
				VSphereAddress:                    "172.16.1.2",
				VSphereUser:                       "vsadmin",
				VSpherePassword:                   "secret",
				VSphereDatacenterName:             "PCF_DC1",
				VSphereVMFolder:                   "pcf_vms",
				VSphereTemplateFolder:             "pcf_templates",
				VSphereDatastorePattern:           "DS1",
				VSpherePersistentDatastorePattern: "DS1_Persistent",
				VSphereDiskPath:                   "pcf_disks",
				VSphereClusters:                   []string{"PCF1"},
				VSphereNetworks: []Network{Network{
					Name:    "PCF_Net1",
					Range:   "172.16.0.0/23",
					Gateway: "172.16.1.1",
					DNS:     []string{"172.16.1.2"},
				}},
			}
			var manifest *enaml.DeploymentManifest

			BeforeEach(func() {
				manifest = NewVSphereBosh(boshConfig)
			})

			It("then it should be using the vsphere esx stemcell", func() {
				Ω(manifest.ResourcePools[0].Stemcell.URL).ShouldNot(ContainSubstring("aws"))
				Ω(manifest.ResourcePools[0].Stemcell.URL).ShouldNot(ContainSubstring("azure"))
				Ω(manifest.ResourcePools[0].Stemcell.URL).Should(ContainSubstring("esx"))
			})

			It("then it should have the correct job config to deploy a bosh", func() {
				Ω(len(manifest.Jobs)).Should(Equal(1))
			})

			It("then it should properly define job properties", func() {
				Ω(len(manifest.Jobs[0].Properties)).Should(Equal(9))
				Ω(func() (r []string) {
					for n := range manifest.Jobs[0].Properties {
						r = append(r, n)
					}
					return
				}()).Should(ConsistOf("nats", "postgres", "blobstore", "director", "hm", "vcenter", "agent", "ntp", "registry"))
			})

			It("then it should properly define job templates", func() {
				Ω(len(manifest.Jobs[0].Templates)).Should(Equal(7))
				Ω(func() (r []string) {
					for _, v := range manifest.Jobs[0].Templates {
						r = append(r, v.Name)
					}
					return
				}()).Should(ConsistOf("nats", "postgres", "blobstore", "director", "health_monitor", "vsphere_cpi", "registry"))
			})

			It("then it should properly define job networks", func() {
				Ω(len(manifest.Jobs[0].Networks)).Should(Equal(1))
				Ω(func() (r []string) {
					for _, v := range manifest.Jobs[0].Networks {
						r = append(r, v.Name)
					}
					return
				}()).Should(ConsistOf("private"))
			})

			It("then it should properly define vcenter properties", func() {
				Ω(manifest.Jobs[0].Properties).Should(HaveKey("vcenter"))
				vcenter := manifest.Jobs[0].Properties["vcenter"].(vsphere_cpi.Vcenter)
				Ω(vcenter.Address).Should(Equal("172.16.1.2"))
				Ω(vcenter.User).Should(Equal("vsadmin"))
				Ω(vcenter.Password).Should(Equal("secret"))
				Ω(vcenter.Datacenters).Should(HaveLen(1))
				dc := vcenter.Datacenters.(VSphereDatacenters)[0]
				Ω(dc.Name).Should(Equal("PCF_DC1"))
				Ω(dc.DatastorePattern).Should(Equal("DS1"))
				Ω(dc.PersistentDatastorePattern).Should(Equal("DS1_Persistent"))
				Ω(dc.DiskPath).Should(Equal("pcf_disks"))
				Ω(dc.TemplateFolder).Should(Equal("pcf_templates"))
				Ω(dc.VMFolder).Should(Equal("pcf_vms"))
				Ω(dc.Clusters).Should(HaveLen(1))
				Ω(dc.Clusters[0]).Should(Equal("PCF1"))
			})
		})
	})
})
<commit_msg>Add network tests for subnet configuration<commit_after>package boshinit_test

import (
	"github.com/enaml-ops/enaml"
	. "github.com/enaml-ops/omg-cli/deployments/bosh-init"
	"github.com/enaml-ops/omg-cli/deployments/bosh-init/enaml-gen/vsphere_cpi"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("NewVSphereBosh", func() {
	Describe("given the function", func() {
		Context("when called w/ valid parameters", func() {
			var boshConfig = BoshInitConfig{
				Name:                              "bosh",
				BoshReleaseVersion:                "256.2",
				BoshPrivateIP:                     "172.16.1.6",
				BoshCPIReleaseVersion:             "22",
				GoAgentVersion:                    "3232.4",
				BoshReleaseSHA:                    "ff2f4e16e02f66b31c595196052a809100cfd5a8",
				BoshCPIReleaseSHA:                 "dd1827e5f4dfc37656017c9f6e48441f51a7ab73",
				GoAgentSHA:                        "27ec32ddbdea13e3025700206388ae5882a23c67",
				BoshDirectorName:                  "my-bosh",
				VSphereAddress:                    "172.16.1.2",
				VSphereUser:                       "vsadmin",
				VSpherePassword:                   "secret",
				VSphereDatacenterName:             "PCF_DC1",
				VSphereVMFolder:                   "pcf_vms",
				VSphereTemplateFolder:             "pcf_templates",
				VSphereDatastorePattern:           "DS1",
				VSpherePersistentDatastorePattern: "DS1_Persistent",
				VSphereDiskPath:                   "pcf_disks",
				VSphereClusters:                   []string{"PCF1"},
				VSphereNetworks: []Network{Network{
					Name:    "PCF_Net1",
					Range:   "172.16.0.0/23",
					Gateway: "172.16.1.1",
					DNS:     []string{"172.16.1.2"},
				}},
			}
			var manifest *enaml.DeploymentManifest

			BeforeEach(func() {
				manifest = NewVSphereBosh(boshConfig)
			})

			It("then it should be using the vsphere esx stemcell", func() {
				Ω(manifest.ResourcePools[0].Stemcell.URL).ShouldNot(ContainSubstring("aws"))
				Ω(manifest.ResourcePools[0].Stemcell.URL).ShouldNot(ContainSubstring("azure"))
				Ω(manifest.ResourcePools[0].Stemcell.URL).Should(ContainSubstring("esx"))
			})

			It("then it should have the correct job config to deploy a bosh", func() {
				Ω(len(manifest.Jobs)).Should(Equal(1))
			})

			It("then it should properly define job properties", func() {
				Ω(len(manifest.Jobs[0].Properties)).Should(Equal(9))
				Ω(func() (r []string) {
					for n := range manifest.Jobs[0].Properties {
						r = append(r, n)
					}
					return
				}()).Should(ConsistOf("nats", "postgres", "blobstore", "director", "hm", "vcenter", "agent", "ntp", "registry"))
			})

			It("then it should properly define job templates", func() {
				Ω(len(manifest.Jobs[0].Templates)).Should(Equal(7))
				Ω(func() (r []string) {
					for _, v := range manifest.Jobs[0].Templates {
						r = append(r, v.Name)
					}
					return
				}()).Should(ConsistOf("nats", "postgres", "blobstore", "director", "health_monitor", "vsphere_cpi", "registry"))
			})

			It("then it should properly define job networks", func() {
				Ω(manifest.Jobs[0].Networks).Should(HaveLen(1))
				net := manifest.Jobs[0].Networks[0]
				Ω(net.Name).Should(Equal("private"))
				Ω(net.StaticIPs).Should(ContainElement("172.16.1.6"))
			})

			It("then it should properly define networks", func() {
				Ω(manifest.Networks).Should(HaveLen(1))
				net := manifest.Networks[0].(enaml.ManualNetwork)
				Ω(net.Name).Should(Equal("private"))
				Ω(net.Type).Should(Equal("manual"))
				Ω(net.Subnets).Should(HaveLen(1))
				subnet := net.Subnets[0]
				Ω(subnet.DNS).Should(HaveLen(1))
				Ω(subnet.DNS[0]).Should(Equal("172.16.1.2"))
				Ω(subnet.Gateway).Should(Equal("172.16.1.1"))
				Ω(subnet.Range).Should(Equal("172.16.0.0/23"))
				cloudprops := subnet.CloudProperties.(VSpherecloudpropertiesNetwork)
				Ω(cloudprops.Name).Should(Equal("PCF_Net1"))
			})

			It("then it should properly define vcenter properties", func() {
				Ω(manifest.Jobs[0].Properties).Should(HaveKey("vcenter"))
				vcenter := manifest.Jobs[0].Properties["vcenter"].(vsphere_cpi.Vcenter)
				Ω(vcenter.Address).Should(Equal("172.16.1.2"))
				Ω(vcenter.User).Should(Equal("vsadmin"))
				Ω(vcenter.Password).Should(Equal("secret"))
				Ω(vcenter.Datacenters).Should(HaveLen(1))
				dc := vcenter.Datacenters.(VSphereDatacenters)[0]
				Ω(dc.Name).Should(Equal("PCF_DC1"))
				Ω(dc.DatastorePattern).Should(Equal("DS1"))
				Ω(dc.PersistentDatastorePattern).Should(Equal("DS1_Persistent"))
				Ω(dc.DiskPath).Should(Equal("pcf_disks"))
				Ω(dc.TemplateFolder).Should(Equal("pcf_templates"))
				Ω(dc.VMFolder).Should(Equal("pcf_vms"))
				Ω(dc.Clusters).Should(HaveLen(1))
				Ω(dc.Clusters[0]).Should(Equal("PCF1"))
			})
		})
	})
})
<|endoftext|>


<commit_before>package pool

import (
	"context"
	"fmt"
	"testing"

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

type TestFactoryObject struct {
	status string
}

func TestDefaultPooledObjectFactorySimple(t *testing.T) {
	t.Parallel()

	ctx := context.Background()
	factory := NewPooledObjectFactorySimple(
		func(context.Context) (interface{}, error) {
			return &TestFactoryObject{status: "make"}, nil
		})

	assert.NotNil(t, factory)
	o, _ := factory.MakeObject(ctx)
	if debugTest {
		fmt.Println("object:", o.Object)
	}
	assert.NotNil(t, o)
	assert.Nil(t, factory.ActivateObject(ctx, o))
	assert.Nil(t, factory.PassivateObject(ctx, o))
	assert.True(t, factory.ValidateObject(ctx, o))
	assert.Nil(t, factory.DestroyObject(ctx, o))
}

func TestDefaultPooledObjectFactory(t *testing.T) {
	t.Parallel()

	factory := NewPooledObjectFactory(
		func(context.Context) (interface{}, error) {
			return &TestFactoryObject{status: "make"}, nil
		},
		func(ctx context.Context, object *PooledObject) error {
			object.Object.(*TestFactoryObject).status = "destory"
			return nil
		},
		func(ctx context.Context, object *PooledObject) bool {
			object.Object.(*TestFactoryObject).status = "validate"
			return true
		},
		func(ctx context.Context, object *PooledObject) error {
			object.Object.(*TestFactoryObject).status = "activate"
			return nil
		},
		func(ctx context.Context, object *PooledObject) error {
			object.Object.(*TestFactoryObject).status = "passivate"
			return nil
		})

	assert.NotNil(t, factory)

	ctx := context.Background()
	o, _ := factory.MakeObject(ctx)
	assert.NotNil(t, o)
	obj := o.Object.(*TestFactoryObject)
	assert.Equal(t, "make", obj.status)
	assert.Nil(t, factory.ActivateObject(ctx, o))
	assert.Equal(t, "activate", obj.status)
	assert.Nil(t, factory.PassivateObject(ctx, o))
	assert.Equal(t, "passivate", obj.status)
	assert.True(t, factory.ValidateObject(ctx, o))
	assert.Equal(t, "validate", obj.status)
	assert.Nil(t, factory.DestroyObject(ctx, o))
	assert.Equal(t, "destory", obj.status)
}
<commit_msg>Fixed typos<commit_after>package pool

import (
	"context"
	"fmt"
	"testing"

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

type TestFactoryObject struct {
	status string
}

func TestDefaultPooledObjectFactorySimple(t *testing.T) {
	t.Parallel()

	ctx := context.Background()
	factory := NewPooledObjectFactorySimple(
		func(context.Context) (interface{}, error) {
			return &TestFactoryObject{status: "make"}, nil
		})

	assert.NotNil(t, factory)
	o, _ := factory.MakeObject(ctx)
	if debugTest {
		fmt.Println("object:", o.Object)
	}
	assert.NotNil(t, o)
	assert.Nil(t, factory.ActivateObject(ctx, o))
	assert.Nil(t, factory.PassivateObject(ctx, o))
	assert.True(t, factory.ValidateObject(ctx, o))
	assert.Nil(t, factory.DestroyObject(ctx, o))
}

func TestDefaultPooledObjectFactory(t *testing.T) {
	t.Parallel()

	factory := NewPooledObjectFactory(
		func(context.Context) (interface{}, error) {
			return &TestFactoryObject{status: "make"}, nil
		},
		func(ctx context.Context, object *PooledObject) error {
			object.Object.(*TestFactoryObject).status = "destroy"
			return nil
		},
		func(ctx context.Context, object *PooledObject) bool {
			object.Object.(*TestFactoryObject).status = "validate"
			return true
		},
		func(ctx context.Context, object *PooledObject) error {
			object.Object.(*TestFactoryObject).status = "activate"
			return nil
		},
		func(ctx context.Context, object *PooledObject) error {
			object.Object.(*TestFactoryObject).status = "passivate"
			return nil
		})

	assert.NotNil(t, factory)

	ctx := context.Background()
	o, _ := factory.MakeObject(ctx)
	assert.NotNil(t, o)
	obj := o.Object.(*TestFactoryObject)
	assert.Equal(t, "make", obj.status)
	assert.Nil(t, factory.ActivateObject(ctx, o))
	assert.Equal(t, "activate", obj.status)
	assert.Nil(t, factory.PassivateObject(ctx, o))
	assert.Equal(t, "passivate", obj.status)
	assert.True(t, factory.ValidateObject(ctx, o))
	assert.Equal(t, "validate", obj.status)
	assert.Nil(t, factory.DestroyObject(ctx, o))
	assert.Equal(t, "destroy", obj.status)
}
<|endoftext|>


<commit_before>package scene

import (
	"image"
	"math"

	"github.com/pankona/gomo-simra/simra"
)

type sampleUnit struct {
	*unitBase
	attackinfo *attackInfo
}

func (u *sampleUnit) Initialize() {
	simra.GetInstance().AddSprite("player.png",
		image.Rect(0, 0, 384, 384),
		&u.sprite)
}

func (u *sampleUnit) OnEvent(i interface{}) {
	c, ok := i.(*command)
	if !ok {
		panic("unexpected command received. fatal.")
	}

	switch c.commandtype {
	case commandSpawn:
		d, ok := c.data.(*sampleUnit)
		if !ok {
			// unhandled event. ignore.
			return
		}
		if u.id != d.GetID() {
			// this spawn event is not for me. nop.
			return
		}
		u.action = newAction(actionSpawn, d)

	case commandDead:
		_, ok := c.data.(*player)
		if !ok {
			return
		}
		simra.LogDebug("i'm %s, we won!", u.GetID())
		u.action = nil
	default:
		// nop
	}
}

func (u *sampleUnit) DoAction() {
	a := u.action
	if a == nil {
		// idle
		return
	}

	switch a.actiontype {
	case actionSpawn:
		d := a.data.(*sampleUnit)
		u.sprite.W = 64
		u.sprite.H = 64
		u.SetPosition(d.GetPosition())
		simra.LogDebug("@@@@@@ [SPAWN] i'm %s", u.GetID())

		// start moving to target
		u.action = newAction(actionMoveToNearestTarget, nil)

	case actionMoveToNearestTarget:
		// TODO: lookup nearest target
		p := u.nearestPlayer(u.game.players)
		u.moveToTarget(p)

		if u.canAttackToTarget(u.game.players["player"]) {
			u.action = newAction(actionAttack, u.game.players["player"])
		}

	case actionAttack:
		// TODO: start animation

		if !u.canAttackToTarget(u.game.players["player"]) {
			u.action = newAction(actionMoveToNearestTarget, nil)
			break
		}

		if u.game.currentFrame-u.attackinfo.lastAttackTime >=
			(int64)(u.attackinfo.cooltime*fps) {
			simra.LogDebug("[ATTACK] i'm %s", u.GetID())
			u.attackinfo.lastAttackTime = u.game.currentFrame

			u.game.eventqueue <- newCommand(commandDamage, &damage{u.game.players["player"], u.attackinfo.power})
		}
	default:
		// nop
	}
}

func (u *sampleUnit) nearestPlayer(players map[string]uniter) uniter {
	var (
		distance float64
		retID    string
	)
	for i, v := range players {
		d := getDistanceBetweenUnit(u, v)
		if distance == 0 {
			distance = d
			retID = i
			continue
		}
		if distance > d {
			distance = d
			retID = i
		}
	}
	return players[retID]
}

func (u *sampleUnit) moveToTarget(target uniter) {
	ux, uy := u.GetPosition()
	tx, ty := target.GetPosition()

	// calculate which way to go
	// move speed is temporary
	dx, dy := tx-ux, ty-uy
	newx := (float64)(u.moveSpeed) / getDistance(ux, uy, tx, ty) * (float64)(dx)
	newy := (float64)(u.moveSpeed) / getDistance(ux, uy, tx, ty) * (float64)(dy)
	u.sprite.X += (float32)(newx)
	u.sprite.Y += (float32)(newy)
}

func (u *sampleUnit) canAttackToTarget(target uniter) bool {
	ux, uy := u.GetPosition()
	tx, ty := target.GetPosition()

	if (float64)(u.attackinfo.attackRange) >= getDistance(ux, uy, tx, ty) {
		return true
	}
	return false
}

func getDistance(ax, ay, bx, by float32) float64 {
	dx, dy := ax-bx, ay-by
	return math.Sqrt((float64)(dx*dx + dy*dy))
}

func getDistanceBetweenUnit(u1, u2 uniter) float64 {
	ax, ay := u1.GetPosition()
	bx, by := u2.GetPosition()
	return getDistance(ax, ay, bx, by)
}
<commit_msg>enemy moves to nearest target and attack<commit_after>package scene

import (
	"image"
	"math"

	"github.com/pankona/gomo-simra/simra"
)

type sampleUnit struct {
	*unitBase
	attackinfo *attackInfo
}

func (u *sampleUnit) Initialize() {
	simra.GetInstance().AddSprite("player.png",
		image.Rect(0, 0, 384, 384),
		&u.sprite)
}

func (u *sampleUnit) OnEvent(i interface{}) {
	c, ok := i.(*command)
	if !ok {
		panic("unexpected command received. fatal.")
	}

	switch c.commandtype {
	case commandSpawn:
		d, ok := c.data.(*sampleUnit)
		if !ok {
			// unhandled event. ignore.
			return
		}
		if u.id != d.GetID() {
			// this spawn event is not for me. nop.
			return
		}
		u.action = newAction(actionSpawn, d)

	case commandDead:
		_, ok := c.data.(*player)
		if !ok {
			return
		}
		simra.LogDebug("i'm %s, we won!", u.GetID())
		u.action = nil
	default:
		// nop
	}
}

func (u *sampleUnit) DoAction() {
	a := u.action
	if a == nil {
		// idle
		return
	}

	switch a.actiontype {
	case actionSpawn:
		d := a.data.(*sampleUnit)
		u.sprite.W = 64
		u.sprite.H = 64
		u.SetPosition(d.GetPosition())
		simra.LogDebug("@@@@@@ [SPAWN] i'm %s", u.GetID())

		// start moving to target
		u.action = newAction(actionMoveToNearestTarget, nil)

	case actionMoveToNearestTarget:
		// TODO: lookup nearest target
		target := u.nearestPlayer(u.game.players)
		u.moveToTarget(target)

		if u.canAttackToTarget(target) {
			u.action = newAction(actionAttack, target)
		}

	case actionAttack:
		// TODO: start animation

		target := a.data.(uniter)
		if !u.canAttackToTarget(target) {
			u.action = newAction(actionMoveToNearestTarget, nil)
			break
		}

		if u.game.currentFrame-u.attackinfo.lastAttackTime >=
			(int64)(u.attackinfo.cooltime*fps) {
			simra.LogDebug("[ATTACK] i'm %s", u.GetID())
			u.attackinfo.lastAttackTime = u.game.currentFrame

			u.game.eventqueue <- newCommand(commandDamage, &damage{target, u.attackinfo.power})
		}
	default:
		// nop
	}
}

func (u *sampleUnit) nearestPlayer(players map[string]uniter) uniter {
	var (
		distance float64
		retID    string
	)
	for i, v := range players {
		d := getDistanceBetweenUnit(u, v)
		if distance == 0 {
			distance = d
			retID = i
			continue
		}
		if distance > d {
			distance = d
			retID = i
		}
	}
	return players[retID]
}

func (u *sampleUnit) moveToTarget(target uniter) {
	ux, uy := u.GetPosition()
	tx, ty := target.GetPosition()

	// calculate which way to go
	// move speed is temporary
	dx, dy := tx-ux, ty-uy
	newx := (float64)(u.moveSpeed) / getDistance(ux, uy, tx, ty) * (float64)(dx)
	newy := (float64)(u.moveSpeed) / getDistance(ux, uy, tx, ty) * (float64)(dy)
	u.sprite.X += (float32)(newx)
	u.sprite.Y += (float32)(newy)
}

func (u *sampleUnit) canAttackToTarget(target uniter) bool {
	ux, uy := u.GetPosition()
	tx, ty := target.GetPosition()

	if (float64)(u.attackinfo.attackRange) >= getDistance(ux, uy, tx, ty) {
		return true
	}
	return false
}

func getDistance(ax, ay, bx, by float32) float64 {
	dx, dy := ax-bx, ay-by
	return math.Sqrt((float64)(dx*dx + dy*dy))
}

func getDistanceBetweenUnit(u1, u2 uniter) float64 {
	ax, ay := u1.GetPosition()
	bx, by := u2.GetPosition()
	return getDistance(ax, ay, bx, by)
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// 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.

// forward_bin listens on the -listen_addr and forwards the connection to -connect_addr
package main

import (
	"context"
	"flag"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/google/waterfall/golang/forward"
	"github.com/google/waterfall/golang/mux"
	"github.com/google/waterfall/golang/net/qemu"
	"github.com/google/waterfall/golang/utils"
	"github.com/mdlayher/vsock"
	"golang.org/x/sync/errgroup"
)

const (
	sleepTime = time.Millisecond * 2500
)

var (
	listenAddr = flag.String(
		"listen_addr", "",
		"List of address(es) separated by comma to listen for connection on the host. <unix|tcp>:addr1[,<unix|tcp>:addr2]")

	// For qemu connections addr is the working dir of the emulator
	connectAddr = flag.String(
		"connect_addr", "",
		"Connect and forward to this address <qemu|tcp|mux>:addr. For qemu connections addr is qemu:emu_dir:socket"+
			"where emu_dir is the working directory of the emulator and socket is the socket file relative to emu_dir."+
			" For mux connections addr is the initial connection to dial in order to create the mux connection builder.")
)

func init() {
	flag.Parse()
}

type connBuilder interface {
	Accept() (net.Conn, error)
	Close() error
}

type vsockBuilder struct {
	cid  uint32
	port uint32
}

func (v *vsockBuilder) Accept() (net.Conn, error) {
	return vsock.Dial(v.cid, v.port)
}

func (v *vsockBuilder) Close() error {
	return nil
}

type dialBuilder struct {
	netType string
	addr    string
}

func (d *dialBuilder) Accept() (net.Conn, error) {
	return net.Dial(d.netType, d.addr)
}

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

func makeQemuBuilder(pa *utils.ParsedAddr) (connBuilder, error) {
	qb, err := qemu.MakeConnBuilder(pa.Addr, pa.SocketName)

	// The emulator can die at any point and we need to die as well.
	// When the emulator dies its working directory is removed.
	// Poll the filesystem and terminate the process if we can't
	// find the emulator dir.
	go func() {
		for {
			time.Sleep(sleepTime)
			if _, err := os.Stat(pa.Addr); err != nil {
				log.Fatal(err)
			}
		}
	}()
	return qb, err
}

func main() {
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
	log.Println("Starting forwarding server ...")

	if *listenAddr == "" || *connectAddr == "" {
		log.Fatalf("Need to specify -listen_addr and -connect_addr.")
	}

	log.Printf("Listening on address %s and connecting to %s\n", *listenAddr, *connectAddr)

	lisAddrs := []*utils.ParsedAddr{}
	for _, addr := range strings.Split(*listenAddr, ",") {
		lpa, err := utils.ParseAddr(addr)
		if err != nil {
			log.Fatal(err)
		}
		lisAddrs = append(lisAddrs, lpa)
	}

	cpa, err := utils.ParseAddr(*connectAddr)
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()

	var b connBuilder
	switch cpa.Kind {
	case utils.QemuHost:
		qb, err := makeQemuBuilder(cpa)
		if err != nil {
			log.Fatalf("Got error creating qemu conn %v.", err)
		}
		defer qb.Close()
		b = qb
	case utils.QemuGuest:
		qb, err := qemu.MakePipe(cpa.SocketName)
		if err != nil {
			log.Fatalf("Got error creating qemu conn %v.", err)
		}
		defer qb.Close()
		b = qb
	case utils.Unix:
		fallthrough
	case utils.TCP:
		b = &dialBuilder{netType: cpa.Kind, addr: cpa.Addr}
	case utils.VsockHost:
		cid, err := strconv.Atoi(cpa.Addr)
		if err != nil {
			log.Fatalf("Got error parsing vsock addr %v.", cpa)
		}

		port, err := strconv.Atoi(cpa.SocketName)
		if err != nil {
			log.Fatalf("Got error parsing vsock addr %v.", cpa)
		}
		b = &vsockBuilder{cid: uint32(cid), port: uint32(port)}
	case utils.Mux:
		mc, err := net.Dial(cpa.MuxAddr.Kind, cpa.MuxAddr.Addr)
		if err != nil {
			log.Fatal(err)
		}
		b, err = mux.NewConnBuilder(ctx, mc)
		if err != nil {
			log.Fatal(err)
		}
	default:
		log.Fatalf("Unsupported network type: %s", cpa.Kind)
	}

	// Block until the guest server process is ready.
	cy, err := b.Accept()
	if err != nil {
		log.Fatalf("Got error getting next conn: %v\n", err)
	}

	listeners := []connBuilder{}
	for _, addr := range lisAddrs {
		switch addr.Kind {
		case utils.QemuHost:
			l, err := makeQemuBuilder(addr)
			if err != nil {
				log.Fatalf("Got error creating qemu conn %v.", err)
			}
			defer l.Close()
			listeners = append(listeners, l)
		case utils.Unix:
			fallthrough
		case utils.TCP:
			l, err := net.Listen(addr.Kind, addr.Addr)
			if err != nil {
				log.Fatalf("Failed to listen on address: %v.", err)
			}
			defer l.Close()
			listeners = append(listeners, l)
		}
	}

	eg, _ := errgroup.WithContext(ctx)
	for i, lis := range listeners {
		func(ll connBuilder, pAddr *utils.ParsedAddr) {
			eg.Go(func() error {
				for {
					cx, err := ll.Accept()
					if err != nil {
						return err
					}

					log.Printf("Forwarding conns for addr %v ...\n", pAddr)
					go forward.Forward(cx.(forward.HalfReadWriteCloser), cy.(forward.HalfReadWriteCloser))

					cy, err = b.Accept()
					if err != nil {
						return err
					}
				}
				return nil
			})
		}(lis, lisAddrs[i])

	}

	if err := eg.Wait(); err != nil {
		log.Fatalf("Forwarding error: %v", err)
	}
}
<commit_msg>Fix connection creation when forwarding qemu connections<commit_after>// Copyright 2018 Google LLC
//
// 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.

// forward_bin listens on the -listen_addr and forwards the connection to -connect_addr
package main

import (
	"context"
	"flag"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/google/waterfall/golang/forward"
	"github.com/google/waterfall/golang/mux"
	"github.com/google/waterfall/golang/net/qemu"
	"github.com/google/waterfall/golang/utils"
	"github.com/mdlayher/vsock"
	"golang.org/x/sync/errgroup"
)

const (
	sleepTime = time.Millisecond * 2500
)

var (
	listenAddr = flag.String(
		"listen_addr", "",
		"List of address(es) separated by comma to listen for connection on the host. <unix|tcp>:addr1[,<unix|tcp>:addr2]")

	// For qemu connections addr is the working dir of the emulator
	connectAddr = flag.String(
		"connect_addr", "",
		"Connect and forward to this address <qemu|tcp|mux>:addr. For qemu connections addr is qemu:emu_dir:socket"+
			"where emu_dir is the working directory of the emulator and socket is the socket file relative to emu_dir."+
			" For mux connections addr is the initial connection to dial in order to create the mux connection builder.")
)

func init() {
	flag.Parse()
}

type connBuilder interface {
	Accept() (net.Conn, error)
	Close() error
}

type vsockBuilder struct {
	cid  uint32
	port uint32
}

func (v *vsockBuilder) Accept() (net.Conn, error) {
	return vsock.Dial(v.cid, v.port)
}

func (v *vsockBuilder) Close() error {
	return nil
}

type dialBuilder struct {
	netType string
	addr    string
}

func (d *dialBuilder) Accept() (net.Conn, error) {
	return net.Dial(d.netType, d.addr)
}

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

func makeQemuBuilder(pa *utils.ParsedAddr) (connBuilder, error) {
	qb, err := qemu.MakeConnBuilder(pa.Addr, pa.SocketName)

	// The emulator can die at any point and we need to die as well.
	// When the emulator dies its working directory is removed.
	// Poll the filesystem and terminate the process if we can't
	// find the emulator dir.
	go func() {
		for {
			time.Sleep(sleepTime)
			if _, err := os.Stat(pa.Addr); err != nil {
				log.Fatal(err)
			}
		}
	}()
	return qb, err
}

func main() {
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
	log.Println("Starting forwarding server ...")

	if *listenAddr == "" || *connectAddr == "" {
		log.Fatalf("Need to specify -listen_addr and -connect_addr.")
	}

	log.Printf("Listening on address %s and connecting to %s\n", *listenAddr, *connectAddr)

	lisAddrs := []*utils.ParsedAddr{}
	for _, addr := range strings.Split(*listenAddr, ",") {
		lpa, err := utils.ParseAddr(addr)
		if err != nil {
			log.Fatal(err)
		}
		lisAddrs = append(lisAddrs, lpa)
	}

	cpa, err := utils.ParseAddr(*connectAddr)
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()

	var b connBuilder
	switch cpa.Kind {
	case utils.QemuHost:
		qb, err := makeQemuBuilder(cpa)
		if err != nil {
			log.Fatalf("Got error creating qemu conn %v.", err)
		}
		defer qb.Close()
		b = qb
	case utils.QemuGuest:
		qb, err := qemu.MakePipe(cpa.SocketName)
		if err != nil {
			log.Fatalf("Got error creating qemu conn %v.", err)
		}
		defer qb.Close()
		b = qemu.MakePipeConnBuilder(qb)
	case utils.Unix:
		fallthrough
	case utils.TCP:
		b = &dialBuilder{netType: cpa.Kind, addr: cpa.Addr}
	case utils.VsockHost:
		cid, err := strconv.Atoi(cpa.Addr)
		if err != nil {
			log.Fatalf("Got error parsing vsock addr %v.", cpa)
		}

		port, err := strconv.Atoi(cpa.SocketName)
		if err != nil {
			log.Fatalf("Got error parsing vsock addr %v.", cpa)
		}
		b = &vsockBuilder{cid: uint32(cid), port: uint32(port)}
	case utils.Mux:
		mc, err := net.Dial(cpa.MuxAddr.Kind, cpa.MuxAddr.Addr)
		if err != nil {
			log.Fatal(err)
		}
		b, err = mux.NewConnBuilder(ctx, mc)
		if err != nil {
			log.Fatal(err)
		}
	default:
		log.Fatalf("Unsupported network type: %s", cpa.Kind)
	}

	// Block until the guest server process is ready.
	cy, err := b.Accept()
	if err != nil {
		log.Fatalf("Got error getting next conn: %v\n", err)
	}

	listeners := []connBuilder{}
	for _, addr := range lisAddrs {
		switch addr.Kind {
		case utils.QemuHost:
			l, err := makeQemuBuilder(addr)
			if err != nil {
				log.Fatalf("Got error creating qemu conn %v.", err)
			}
			defer l.Close()
			listeners = append(listeners, l)
		case utils.Unix:
			fallthrough
		case utils.TCP:
			l, err := net.Listen(addr.Kind, addr.Addr)
			if err != nil {
				log.Fatalf("Failed to listen on address: %v.", err)
			}
			defer l.Close()
			listeners = append(listeners, l)
		}
	}

	eg, _ := errgroup.WithContext(ctx)
	for i, lis := range listeners {
		func(ll connBuilder, pAddr *utils.ParsedAddr) {
			eg.Go(func() error {
				for {
					cx, err := ll.Accept()
					if err != nil {
						return err
					}

					log.Printf("Forwarding conns for addr %v ...\n", pAddr)
					go forward.Forward(cx.(forward.HalfReadWriteCloser), cy.(forward.HalfReadWriteCloser))

					cy, err = b.Accept()
					if err != nil {
						return err
					}
				}
				return nil
			})
		}(lis, lisAddrs[i])

	}

	if err := eg.Wait(); err != nil {
		log.Fatalf("Forwarding error: %v", err)
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013-2014, Jeremy Bingham (<jbingham@gmail.com>)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package data_store

import (
	"testing"
)

type dsObj struct {
	Name string `json:"name"`
	JsonClass string `json:"json_class"`
	ChefType string `json:"chef_type"`
}

func makeDsObj() *dsObj {
	return &dsObj{ Name: "baz", JsonClass: "Chef::DsObj", ChefType: "ds_obj" }
}

func TestNew(t *testing.T){
	if d := New(); d == nil {
		t.Errorf("New() should have returned a data store object, but returned nil")
	}
}

func TestSet(t *testing.T){
	ds := New()
	baz := makeDsObj()
	ds.Set("foo", "bar", baz)
}

func TestGet(t *testing.T){
	ds := New()
	val, found := ds.Get("foo", "bar2")
	if found {
		t.Errorf("Get() returned a result improperly")
	}
	baz := makeDsObj()
	ds.Set("foo", "bar2", baz)
	val, found = ds.Get("foo", "bar2")
	if !found {
		t.Errorf("Get() did not return a result properly, got '%v' :: %v", val, found)
	}
}

func TestDelete(t *testing.T){
	ds := New()
	baz := makeDsObj()
	ds.Set("foo", "bar3", baz)
	val, found := ds.Get("foo", "bar3")
	if found == false {
		t.Errorf("Couldn't set bar3 baz")
	}
	ds.Delete("foo", "bar3")
	val, found = ds.Get("foo", "bar3")
	if found {
		t.Errorf("Delete() did not delete bar3, returned %v!", val)
	}
}

func TestGetList(t *testing.T){
	ds := New()
	complist := []string{ "baz", "moo" }
	baz := makeDsObj()
	moo := makeDsObj()
	moo.Name = "moo"
	ds.Set("foolist", "baz", baz)
	ds.Set("foolist", "moo", moo)
	dsl := ds.GetList("foolist")
	if dsl == nil || dsl[0] != complist[0] || dsl[1] != complist[1] {
		t.Errorf("GetList failed to return the expected list: returned %v, expected %v", dsl, complist)
	}
}

func TestSave(t *testing.T) {
	ds := New()
	err := ds.Save()
	if err != nil {
		t.Errorf("Save() gave an error: %s", err)
	}
}

func TestLoad(t *testing.T) {
	ds := New()
	err := ds.Load()
	if err != nil {
		t.Errorf("Load() save an error: %s", err)
	}
}
<commit_msg>Update ds tests<commit_after>/*
 * Copyright (c) 2013-2014, Jeremy Bingham (<jbingham@gmail.com>)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package data_store

import (
	"testing"
	"io/ioutil"
	"fmt"
	"os"
)

type dsObj struct {
	Name string `json:"name"`
	JsonClass string `json:"json_class"`
	ChefType string `json:"chef_type"`
}

func makeDsObj() *dsObj {
	return &dsObj{ Name: "baz", JsonClass: "Chef::DsObj", ChefType: "ds_obj" }
}

func TestNew(t *testing.T){
	if d := New(); d == nil {
		t.Errorf("New() should have returned a data store object, but returned nil")
	}
}

func TestSet(t *testing.T){
	ds := New()
	baz := makeDsObj()
	ds.Set("foo", "bar", baz)
}

func TestGet(t *testing.T){
	ds := New()
	val, found := ds.Get("foo", "bar2")
	if found {
		t.Errorf("Get() returned a result improperly")
	}
	baz := makeDsObj()
	ds.Set("foo", "bar2", baz)
	val, found = ds.Get("foo", "bar2")
	if !found {
		t.Errorf("Get() did not return a result properly, got '%v' :: %v", val, found)
	}
}

func TestDelete(t *testing.T){
	ds := New()
	baz := makeDsObj()
	ds.Set("foo", "bar3", baz)
	val, found := ds.Get("foo", "bar3")
	if found == false {
		t.Errorf("Couldn't set bar3 baz")
	}
	ds.Delete("foo", "bar3")
	val, found = ds.Get("foo", "bar3")
	if found {
		t.Errorf("Delete() did not delete bar3, returned %v!", val)
	}
}

func TestGetList(t *testing.T){
	ds := New()
	complist := []string{ "baz", "moo" }
	baz := makeDsObj()
	moo := makeDsObj()
	moo.Name = "moo"
	ds.Set("foolist", "baz", baz)
	ds.Set("foolist", "moo", moo)
	dsl := ds.GetList("foolist")
	if dsl == nil || dsl[0] != complist[0] || dsl[1] != complist[1] {
		t.Errorf("GetList failed to return the expected list: returned %v, expected %v", dsl, complist)
	}
}

var dsTmpDir = dsTmpGen()

func dsTmpGen() string {
	tm, err := ioutil.TempDir("", "ds-test")
	if err != nil {
		panic("Couldn't create temporary directory!")
	}
	return tm
}

func TestSave(t *testing.T) {
	ds := New()
	tmpfile := fmt.Sprintf("%s/ds.bin", dsTmpDir)
	err := ds.Save(tmpfile)
	if err != nil {
		t.Errorf("Save() gave an error: %s", err)
	}
}

func TestLoad(t *testing.T) {
	ds := New()
	tmpfile := fmt.Sprintf("%s/ds.bin", dsTmpDir)
	err := ds.Load(tmpfile)
	if err != nil {
		t.Errorf("Load() save an error: %s", err)
	}
}

// clean up

func TestCleanup(t *testing.T) {
	os.RemoveAll(dsTmpDir)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/rand"
	"net/http"
	"time"
)

func handleGimmeAName(w http.ResponseWriter, r *http.Request) {
	nouns := [...][2]string{
		{"Galpão", "M"},
		{"Fogo", "M"},
		{"Churrasco", "M"},
		{"Braseiro", "M"},
		{"Chama", "F"},
		{"Brasa", "F"},
		{"Estância", "F"},
		{"Estrela", "F"},
		{"Tradição", "F"},
	}

	adjectivesM := [...]string{
		"Gaúcho",
		"do Sul",
		"Crioulo",
		"do Rio Grande",
		"Nativo",
		"Nativista",
		"da Fronteira",
		"Gauchesco",
		"Gaudério",
		"Farrapo",
	}

	adjectivesF := [...]string{
		"Gaúcha",
		"do Sul",
		"Crioula",
		"do Rio Grande",
		"Nativa",
		"Nativista",
		"da Fronteira",
		"Gauchesca",
		"Gaudéria",
	}

	i := rand.Intn(len(nouns))
	noun := nouns[i][0]

	var adjective string

	if nouns[i][1] == "M" {
		adjective = adjectivesM[rand.Intn(len(adjectivesM))]
	} else {
		adjective = adjectivesF[rand.Intn(len(adjectivesF))]
	}

	fmt.Fprintf(w, "%s %s", noun, adjective)
}

func handleEverythingElse(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Please access /gimmeaname to get a churrascaria name.")
}

func main() {
	rand.Seed(time.Now().Unix())

	http.HandleFunc("/gimmeaname", handleGimmeAName)
	http.HandleFunc("/", handleEverythingElse)

	http.ListenAndServe(":8080", nil)
}
<commit_msg>Using `GoodSeed`.<commit_after>package main

import (
	"fmt"
	"math/rand"
	"net/http"

	"github.com/lmbarros/sbxs_go_rand/rand/randutil"
)

func handleGimmeAName(w http.ResponseWriter, r *http.Request) {
	nouns := [...][2]string{
		{"Galpão", "M"},
		{"Fogo", "M"},
		{"Churrasco", "M"},
		{"Braseiro", "M"},
		{"Chama", "F"},
		{"Brasa", "F"},
		{"Estância", "F"},
		{"Estrela", "F"},
		{"Tradição", "F"},
	}

	adjectivesM := [...]string{
		"Gaúcho",
		"do Sul",
		"Crioulo",
		"do Rio Grande",
		"Nativo",
		"Nativista",
		"da Fronteira",
		"Gauchesco",
		"Gaudério",
		"Farrapo",
	}

	adjectivesF := [...]string{
		"Gaúcha",
		"do Sul",
		"Crioula",
		"do Rio Grande",
		"Nativa",
		"Nativista",
		"da Fronteira",
		"Gauchesca",
		"Gaudéria",
	}

	i := rand.Intn(len(nouns))
	noun := nouns[i][0]

	var adjective string

	if nouns[i][1] == "M" {
		adjective = adjectivesM[rand.Intn(len(adjectivesM))]
	} else {
		adjective = adjectivesF[rand.Intn(len(adjectivesF))]
	}

	fmt.Fprintf(w, "%s %s", noun, adjective)
}

func handleEverythingElse(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Please access /gimmeaname to get a churrascaria name.")
}

func main() {
	rand.Seed(randutil.GoodSeed())

	http.HandleFunc("/gimmeaname", handleGimmeAName)
	http.HandleFunc("/", handleEverythingElse)

	http.ListenAndServe(":8080", nil)
}
<|endoftext|>


<commit_before>// +build opencontrail_tests

package tests

import (
	"fmt"
	"testing"

	"github.com/skydive-project/skydive/tests/helper"
)

func TestOpenContrailTopology(t *testing.T) {
	test := &Test{
		setupCmds: []helper.Cmd{
			{"contrail-create-network.py default-domain:default-project:vn1", true},
			{"netns-daemon-start -n default-domain:default-project:vn1 vm1", true},
		},

		tearDownCmds: []helper.Cmd{
			// We should delete the net
			{"netns-daemon-stop vm1", true},
		},

		mode: Replay,

		checks: []CheckFunction{func(c *CheckContext) error {
			gh := c.gh
			gremlin := c.gremlin.V().Has("Contrail")

			nodes, err := c.gh.GetNodes(gremlin)
			if err != nil {
				return err
			}

			if len(nodes) != 1 {
				return fmt.Errorf("Expected 1 node, got %+v", nodes)
			}

			return nil
		}},
	}

	RunTest(t, test)
}

func TestOpenContrailRoutingTable(t *testing.T) {
	test := &Test{
		setupCmds: []helper.Cmd{
			{"contrail-create-network.py default-domain:default-project:vn1", true},
			{"netns-daemon-start -n default-domain:default-project:vn1 vm1", true},
		},
		tearDownCmds: []helper.Cmd{
			// We should delete the net
			{"netns-daemon-stop vm1", true},
		},

		mode: Replay,

		checks: []CheckFunction{func(c *CheckContext) error {
			gremlin := c.gremlin.V().Has("Contrail.RoutingTable.Prefix", "20.1.1.253/32")
			nodes, err := c.gh.GetNodes(gremlin)
			if err != nil {
				return err
			}

			if len(nodes) != 1 {
				return fmt.Errorf("Expected 1 node, got %+v", nodes)
			}
			return nil
		}},
	}

	RunTest(t, test)
}
<commit_msg>tests: fix opencontrail compilation<commit_after>// +build opencontrail_tests

package tests

import (
	"fmt"
	"testing"

	"github.com/skydive-project/skydive/tests/helper"
)

func TestOpenContrailTopology(t *testing.T) {
	test := &Test{
		setupCmds: []helper.Cmd{
			{"contrail-create-network.py default-domain:default-project:vn1", true},
			{"netns-daemon-start -n default-domain:default-project:vn1 vm1", true},
		},

		tearDownCmds: []helper.Cmd{
			// We should delete the net
			{"netns-daemon-stop vm1", true},
		},

		mode: Replay,

		checks: []CheckFunction{func(c *CheckContext) error {
			gremlin := c.gremlin.V().Has("Contrail")

			nodes, err := c.gh.GetNodes(gremlin)
			if err != nil {
				return err
			}

			if len(nodes) != 1 {
				return fmt.Errorf("Expected 1 node, got %+v", nodes)
			}

			return nil
		}},
	}

	RunTest(t, test)
}

func TestOpenContrailRoutingTable(t *testing.T) {
	test := &Test{
		setupCmds: []helper.Cmd{
			{"contrail-create-network.py default-domain:default-project:vn1", true},
			{"netns-daemon-start -n default-domain:default-project:vn1 vm1", true},
		},
		tearDownCmds: []helper.Cmd{
			// We should delete the net
			{"netns-daemon-stop vm1", true},
		},

		mode: Replay,

		checks: []CheckFunction{func(c *CheckContext) error {
			gremlin := c.gremlin.V().Has("Contrail.RoutingTable.Prefix", "20.1.1.253/32")
			nodes, err := c.gh.GetNodes(gremlin)
			if err != nil {
				return err
			}

			if len(nodes) != 1 {
				return fmt.Errorf("Expected 1 node, got %+v", nodes)
			}
			return nil
		}},
	}

	RunTest(t, test)
}
<|endoftext|>