<commit_before>package fs

import (
	"os"
	"path/filepath"
	"strings"

	"go.polydawn.net/repeatr/lib/treewalk"
)

type WalkFunc func(filenode *FilewalkNode) error

/*
	Walks a filesystem.

	This is much like the standard library's `path/filepath.Walk`, except
	it's based on `treewalk`, which means it supports both pre- and post-order
	traversals.

	All paths begin in `./`, and directory names are slash-suffixed.
	E.g. you'll see a series like `{"./", "./a/", "./a/b"}`, etc.
	This matches the behaviors described by `Normalize` in the `lib/fshash`.

	Symlinks are not followed.

	The traversal order of siblings is *not* guaranteed, and is *not* necessarily
	stable.

	Caveat: calling `node.NextChild()` during your walk results in undefined behavior.
*/
func Walk(basePath string, preVisit WalkFunc, postVisit WalkFunc) error {
	return treewalk.Walk(
		newFileWalkNode(basePath, "./"),
		func(node treewalk.Node) error {
			filenode := node.(*FilewalkNode)
			if preVisit != nil {
				if err := preVisit(filenode); err != nil {
					return err
				}
			}
			return filenode.prepareChildren(basePath)
		},
		func(node treewalk.Node) error {
			filenode := node.(*FilewalkNode)
			var err error
			if postVisit != nil {
				err = postVisit(filenode)
			}
			filenode.forgetChildren()
			return err
		},
	)
}

var _ treewalk.Node = &FilewalkNode{}

type FilewalkNode struct {
	Path string // relative to start
	Info os.FileInfo
	Err  error

	children []*FilewalkNode // note we didn't sort this
	itrIndex int             // next child offset
}

func (t *FilewalkNode) NextChild() treewalk.Node {
	if t.itrIndex >= len(t.children) {
		return nil
	}
	t.itrIndex++
	return t.children[t.itrIndex-1]
}

func newFileWalkNode(basePath, path string) (filenode *FilewalkNode) {
	filenode = &FilewalkNode{Path: path}
	filenode.Info, filenode.Err = os.Lstat(filepath.Join(basePath, path))
	if filenode.Err == nil && filenode.Info.IsDir() {
		if !strings.HasSuffix(filenode.Path, "/") {
			filenode.Path += "/"
		}
	}
	// don't expand the children until the previsit function
	// we don't want them all crashing into memory at once
	return
}

/*
	Expand next subtree.  Used in the pre-order visit step so we don't walk
	every dir up front.  `Walk()` wraps the user-defined pre-visit function
	to do this at the end.
*/
func (t *FilewalkNode) prepareChildren(basePath string) error {
	if !t.Info.IsDir() {
		return nil
	}
	f, err := os.Open(filepath.Join(basePath, t.Path))
	if err != nil {
		return err
	}
	names, err := f.Readdirnames(-1)
	f.Close()
	if err != nil {
		return err
	}
	t.children = make([]*FilewalkNode, len(names))
	for i, name := range names {
		t.children[i] = newFileWalkNode(basePath, "./"+filepath.Join(t.Path, name))
	}
	return nil
}

/*
	Used in the post-order visit step so we don't continuously consume more
	memory as we walk.  `Walk()` wraps the user-defined post-visit function
	to do this at the end.
*/
func (t *FilewalkNode) forgetChildren() {
	t.children = nil
}
<commit_msg>Attempt to handle outputting a tar containing a single file.<commit_after>package fs

import (
	"os"
	"path/filepath"
	"strings"

	"go.polydawn.net/repeatr/lib/treewalk"
)

type WalkFunc func(filenode *FilewalkNode) error

/*
	Walks a filesystem.

	This is much like the standard library's `path/filepath.Walk`, except
	it's based on `treewalk`, which means it supports both pre- and post-order
	traversals.

	All paths begin in `./`, and directory names are slash-suffixed.
	E.g. you'll see a series like `{"./", "./a/", "./a/b"}`, etc.
	This matches the behaviors described by `Normalize` in the `lib/fshash`.

	If walking directories, implicitly the first path will always be `./`;
	if the basePath is a file however, the first (and only) path with be
	`./thefile` (where 'thefile' is effectively `filepath.Base` of the basePath).
	Note the subtle difference in the amount of information shown to visit funcs:
	when basePath is a directory, no information about the path names leading up
	to *and including* basePath's name are sent to the visit funcs;
	when basePath is a file, part of basePath *is* sent to the visit funcs.
	Typically this does what you mean (after all, what can we do with a file
	with no name?), but the distinction may be important to note if the caller's
	intention is to have no effects from basePath's location.

	Symlinks are not followed.

	The traversal order of siblings is *not* guaranteed, and is *not* necessarily
	stable.

	Caveat: calling `node.NextChild()` during your walk results in undefined behavior.
*/
func Walk(basePath string, preVisit WalkFunc, postVisit WalkFunc) error {
	return treewalk.Walk(
		newFileWalkNode(basePath, "./"),
		func(node treewalk.Node) error {
			filenode := node.(*FilewalkNode)
			if preVisit != nil {
				if err := preVisit(filenode); err != nil {
					return err
				}
			}
			return filenode.prepareChildren(basePath)
		},
		func(node treewalk.Node) error {
			filenode := node.(*FilewalkNode)
			var err error
			if postVisit != nil {
				err = postVisit(filenode)
			}
			filenode.forgetChildren()
			return err
		},
	)
}

var _ treewalk.Node = &FilewalkNode{}

type FilewalkNode struct {
	Path string // relative to start
	Info os.FileInfo
	Err  error

	children []*FilewalkNode // note we didn't sort this
	itrIndex int             // next child offset
}

func (t *FilewalkNode) NextChild() treewalk.Node {
	if t.itrIndex >= len(t.children) {
		return nil
	}
	t.itrIndex++
	return t.children[t.itrIndex-1]
}

func newFileWalkNode(basePath, path string) (filenode *FilewalkNode) {
	// Mostly: fill in attributes from os.Lstat.
	filenode = &FilewalkNode{Path: path}
	filenode.Info, filenode.Err = os.Lstat(filepath.Join(basePath, path))
	// Normalize the reported path of dirs to include trailing slash.
	if filenode.Err == nil && filenode.Info.IsDir() {
		if !strings.HasSuffix(filenode.Path, "/") {
			filenode.Path += "/"
		}
	}
	// Handle boundary condition for a basepath that is a file.
	if path == "./" && !filenode.Info.IsDir() {
		filenode.Path = "./" + filenode.Info.Name()
	}
	// don't expand the children until the previsit function
	// we don't want them all crashing into memory at once
	return
}

/*
	Expand next subtree.  Used in the pre-order visit step so we don't walk
	every dir up front.  `Walk()` wraps the user-defined pre-visit function
	to do this at the end.
*/
func (t *FilewalkNode) prepareChildren(basePath string) error {
	if !t.Info.IsDir() {
		return nil
	}
	f, err := os.Open(filepath.Join(basePath, t.Path))
	if err != nil {
		return err
	}
	names, err := f.Readdirnames(-1)
	f.Close()
	if err != nil {
		return err
	}
	t.children = make([]*FilewalkNode, len(names))
	for i, name := range names {
		t.children[i] = newFileWalkNode(basePath, "./"+filepath.Join(t.Path, name))
	}
	return nil
}

/*
	Used in the post-order visit step so we don't continuously consume more
	memory as we walk.  `Walk()` wraps the user-defined post-visit function
	to do this at the end.
*/
func (t *FilewalkNode) forgetChildren() {
	t.children = nil
}
<|endoftext|>


<commit_before>/**
 * Copyright 2016 Confluent 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.
 */

// kafka client.
// This package implements high-level Apache Kafka producer and consumers
// using bindings on-top of the C librdkafka library.
package kafka

import (
	"sync"
	"unsafe"
)

/*
#include <librdkafka/rdkafka.h>
#include <stdlib.h>
*/
import "C"

type Handle interface {
	get_handle() *handle
}

// Common instance handle for both Producer and Consumer
type handle struct {
	rk  *C.rd_kafka_t
	rkq *C.rd_kafka_queue_t

	// Termination of background go-routines
	terminated_chan chan string // string is go-routine name

	// topic name -> rkt cache
	rkt_cache map[string]*C.rd_kafka_topic_t
	// rkt -> topic name cache
	rkt_name_cache map[*C.rd_kafka_topic_t]string

	//
	// cgo map
	// Maps C callbacks based on cgoid back to its Go object
	cgo_lock   sync.Mutex
	cgoid_next int
	cgomap     map[int]cgoif

	//
	// producer
	//
	p *Producer

	// Forward delivery reports on Producer.Events channel
	fwd_dr bool

	//
	// consumer
	//
	c *Consumer

	// Forward rebalancing ack responsibility to application (current setting)
	curr_app_rebalance_enable bool
}

func (h *handle) String() string {
	return C.GoString(C.rd_kafka_name(h.rk))
}

func (h *handle) setup() {
	h.rkt_cache = make(map[string]*C.rd_kafka_topic_t)
	h.rkt_name_cache = make(map[*C.rd_kafka_topic_t]string)

	h.terminated_chan = make(chan string, 10)
}

func (h *handle) cleanup() {
	for _, c_rkt := range h.rkt_cache {
		C.rd_kafka_topic_destroy(c_rkt)
	}

	if h.rkq != nil {
		C.rd_kafka_queue_destroy(h.rkq)
	}
}

// wait_terminated waits termination of background go-routines.
// term_cnt is the number of goroutines expected to signal termination completion
// on h.terminated_chan
func (h *handle) wait_terminated(term_cnt int) {
	// Wait for term_cnt termination-done events from goroutines
	for ; term_cnt > 0; term_cnt -= 1 {
		_ = <-h.terminated_chan
	}
}

// get_rkt finds or creates and returns a C topic_t object from the local cache.
func (h *handle) get_rkt(topic string) (c_rkt *C.rd_kafka_topic_t) {
	c_rkt, ok := h.rkt_cache[topic]
	if ok {
		return c_rkt
	}

	c_topic := C.CString(topic)
	defer C.free(unsafe.Pointer(c_topic))
	c_rkt = C.rd_kafka_topic_new(h.rk, c_topic, nil)
	// FIXME: error handling

	h.rkt_cache[topic] = c_rkt
	h.rkt_name_cache[c_rkt] = topic

	return c_rkt
}

// get_topic_name_from_rkt returns the topic name for a C topic_t object, preferably
// using the local cache to avoid a cgo call.
func (h *handle) get_topic_name_from_rkt(c_rkt *C.rd_kafka_topic_t) (topic string) {
	topic, ok := h.rkt_name_cache[c_rkt]
	if ok {
		return topic
	}

	topic = C.GoString(C.rd_kafka_topic_name(c_rkt))
	h.rkt_name_cache[c_rkt] = topic
	h.rkt_cache[topic] = c_rkt

	return topic
}

// cgoif is a generic interface for holding Go state passed as opaque
// value to the C code.
// Since pointers to complex Go types cannot be passed to C we instead create
// a cgoif object, generate a unique id that is added to the cgomap,
// and then pass that id to the C code. When the C code callback is called we
// use the id to look up the cgoif object in the cgomap.
type cgoif interface{}

// delivery report cgoif container
type cgo_dr struct {
	delivery_chan chan Event
	opaque        *interface{}
}

// cgo_put adds object cg to the handle's cgo map and returns a
// unique id for the added entry.
// Thread-safe.
// FIXME: the uniquity of the id is questionable over time.
func (h *handle) cgo_put(cg cgoif) (cgoid int) {
	h.cgo_lock.Lock()
	h.cgoid_next += 1
	if h.cgoid_next == 0 {
		h.cgoid_next += 1
	}
	cgoid = h.cgoid_next
	h.cgomap[cgoid] = cg
	h.cgo_lock.Unlock()
	return cgoid
}

// cgo_get looks up cgoid in the cgo map, deletes the reference from the map
// and returns the object, if found. Else returns nil, false.
// Thread-safe.
func (h *handle) cgo_get(cgoid int) (cg cgoif, found bool) {
	if cgoid == 0 {
		return nil, false
	}

	h.cgo_lock.Lock()
	cg, found = h.cgomap[cgoid]
	if found {
		delete(h.cgomap, cgoid)
	}
	h.cgo_lock.Unlock()
	return cg, found
}
<commit_msg>Fixed rkt cache race conditions<commit_after>/**
 * Copyright 2016 Confluent 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.
 */

// kafka client.
// This package implements high-level Apache Kafka producer and consumers
// using bindings on-top of the C librdkafka library.
package kafka

import (
	"fmt"
	"sync"
	"unsafe"
)

/*
#include <librdkafka/rdkafka.h>
#include <stdlib.h>
*/
import "C"

type Handle interface {
	get_handle() *handle
}

// Common instance handle for both Producer and Consumer
type handle struct {
	rk  *C.rd_kafka_t
	rkq *C.rd_kafka_queue_t

	// Termination of background go-routines
	terminated_chan chan string // string is go-routine name

	// Topic <-> rkt caches
	rkt_cache_lock sync.Mutex
	// topic name -> rkt cache
	rkt_cache map[string]*C.rd_kafka_topic_t
	// rkt -> topic name cache
	rkt_name_cache map[*C.rd_kafka_topic_t]string

	//
	// cgo map
	// Maps C callbacks based on cgoid back to its Go object
	cgo_lock   sync.Mutex
	cgoid_next int
	cgomap     map[int]cgoif

	//
	// producer
	//
	p *Producer

	// Forward delivery reports on Producer.Events channel
	fwd_dr bool

	//
	// consumer
	//
	c *Consumer

	// Forward rebalancing ack responsibility to application (current setting)
	curr_app_rebalance_enable bool
}

func (h *handle) String() string {
	return C.GoString(C.rd_kafka_name(h.rk))
}

func (h *handle) setup() {
	h.rkt_cache = make(map[string]*C.rd_kafka_topic_t)
	h.rkt_name_cache = make(map[*C.rd_kafka_topic_t]string)

	h.terminated_chan = make(chan string, 10)
}

func (h *handle) cleanup() {
	for _, c_rkt := range h.rkt_cache {
		C.rd_kafka_topic_destroy(c_rkt)
	}

	if h.rkq != nil {
		C.rd_kafka_queue_destroy(h.rkq)
	}
}

// wait_terminated waits termination of background go-routines.
// term_cnt is the number of goroutines expected to signal termination completion
// on h.terminated_chan
func (h *handle) wait_terminated(term_cnt int) {
	// Wait for term_cnt termination-done events from goroutines
	for ; term_cnt > 0; term_cnt -= 1 {
		_ = <-h.terminated_chan
	}
}

// get_rkt0 finds or creates and returns a C topic_t object from the local cache.
func (h *handle) get_rkt0(topic string, c_topic *C.char, do_lock bool) (c_rkt *C.rd_kafka_topic_t) {
	if do_lock {
		h.rkt_cache_lock.Lock()
	}
	c_rkt, ok := h.rkt_cache[topic]
	if ok {
		if do_lock {
			h.rkt_cache_lock.Unlock()
		}
		return c_rkt
	}

	if c_topic == nil {
		c_topic = C.CString(topic)
		defer C.free(unsafe.Pointer(c_topic))
	}

	c_rkt = C.rd_kafka_topic_new(h.rk, c_topic, nil)
	if c_rkt == nil {
		panic(fmt.Sprintf("Unable to create now C topic \"%s\": %s",
			topic, C.GoString(C.rd_kafka_err2str(C.rd_kafka_last_error()))))
	}

	h.rkt_cache[topic] = c_rkt
	h.rkt_name_cache[c_rkt] = topic

	if do_lock {
		h.rkt_cache_lock.Unlock()
	}

	return c_rkt
}

// get_rkt finds or creates and returns a C topic_t object from the local cache.
func (h *handle) get_rkt(topic string) (c_rkt *C.rd_kafka_topic_t) {
	return h.get_rkt0(topic, nil, true)
}

// get_topic_name_from_rkt returns the topic name for a C topic_t object, preferably
// using the local cache to avoid a cgo call.
func (h *handle) get_topic_name_from_rkt(c_rkt *C.rd_kafka_topic_t) (topic string) {
	h.rkt_cache_lock.Lock()
	topic, ok := h.rkt_name_cache[c_rkt]
	if ok {
		h.rkt_cache_lock.Unlock()
		return topic
	}

	// we need our own copy/refcount of the c_rkt
	c_topic := C.rd_kafka_topic_name(c_rkt)
	topic = C.GoString(c_topic)

	c_rkt = h.get_rkt0(topic, c_topic, false /* dont lock */)
	h.rkt_cache_lock.Unlock()

	return topic
}

// cgoif is a generic interface for holding Go state passed as opaque
// value to the C code.
// Since pointers to complex Go types cannot be passed to C we instead create
// a cgoif object, generate a unique id that is added to the cgomap,
// and then pass that id to the C code. When the C code callback is called we
// use the id to look up the cgoif object in the cgomap.
type cgoif interface{}

// delivery report cgoif container
type cgo_dr struct {
	delivery_chan chan Event
	opaque        *interface{}
}

// cgo_put adds object cg to the handle's cgo map and returns a
// unique id for the added entry.
// Thread-safe.
// FIXME: the uniquity of the id is questionable over time.
func (h *handle) cgo_put(cg cgoif) (cgoid int) {
	h.cgo_lock.Lock()
	h.cgoid_next += 1
	if h.cgoid_next == 0 {
		h.cgoid_next += 1
	}
	cgoid = h.cgoid_next
	h.cgomap[cgoid] = cg
	h.cgo_lock.Unlock()
	return cgoid
}

// cgo_get looks up cgoid in the cgo map, deletes the reference from the map
// and returns the object, if found. Else returns nil, false.
// Thread-safe.
func (h *handle) cgo_get(cgoid int) (cg cgoif, found bool) {
	if cgoid == 0 {
		return nil, false
	}

	h.cgo_lock.Lock()
	cg, found = h.cgomap[cgoid]
	if found {
		delete(h.cgomap, cgoid)
	}
	h.cgo_lock.Unlock()
	return cg, found
}
<|endoftext|>


<commit_before>package cjk2num

import (
	"testing"
)

func Convert(t *testing.T) {
	check(t, "一億三千万二百十五", 130000215.0)
	check(t, "一億", 100000000.0)
	check(t, "千拾", 1010.0)
	check(t, "百", 100.0)
	check(t, "二百三十一兆五十五億二千万千五百一", 231005520001501.0)
	check(t, "二百三十一兆五十五億二千万千五〇一", 231005520001501.0)
	check(t, "二十三人", 23.0)
	check(t, "７十1", 71.0)

}
func check(t *testing.T, input string, ans float64) {
	res, err := Convert(input)
	if err != nil {
		t.Errorf("%s\n", err.Error())
	}

	if res != ans {
		t.Errorf("%s =\n%f\n, want \n%f", input, res, ans)
		return
	}
}
<commit_msg>fix Test<commit_after>package cjk2num

import (
	"testing"
)

func TestConvert(t *testing.T) {
	check(t, "一億三千万二百十五", 130000215.0)
	check(t, "一億", 100000000.0)
	check(t, "千拾", 1010.0)
	check(t, "百", 100.0)
	check(t, "二百三十一兆五十五億二千万千五百一", 231005520001501.0)
	check(t, "二百三十一兆五十五億二千万千五〇一", 231005520001501.0)
	check(t, "二十三人", 23.0)
	check(t, "７十1", 71.0)

}
func check(t *testing.T, input string, ans float64) {
	res, err := Convert(input)
	if err != nil {
		t.Errorf("%s\n", err.Error())
	}

	if res != ans {
		t.Errorf("%s =\n%f\n, want \n%f", input, res, ans)
		return
	}
}
<|endoftext|>


<commit_before>package handyfile

import (
	"archive/tar"
	"io"
	"os"
	"path/filepath"
)

func Unpack(r *tar.Reader, toPath string) error {
	for {
		hdr, err := r.Next()
		switch {
		case err == io.EOF:
			break
		case err != nil:
			return err
		default:
			if err := doOnType(hdr.Typeflag, toPath, hdr.Name, r); err != nil {
				return err
			}
		}

	}

	return nil
}

func doOnType(typeFlag byte, toPath string, name string, r *tar.Reader) error {
	fullpath := filepath.Join(toPath, name)
	switch typeFlag {
	case tar.TypeReg, tar.TypeRegA:
		return writeFile(fullpath, r)
	case tar.TypeDir:
		return os.MkdirAll(fullpath, 0777)
	default:
		return nil
	}
}

func writeFile(path string, r *tar.Reader) error {
	out, err := os.Create(path)
	if err != nil {
		return err
	}
	defer out.Close()

	_, err = io.Copy(out, r)
	return err
}
<commit_msg>Change Unpack to method operating off of a TarReader type. Add constructors for creating the TarReader type. Now unpack takes care of closing the underlying file and gzip compressor.<commit_after>package handyfile

import (
	"archive/tar"
	"compress/gzip"
	"io"
	"os"
	"path/filepath"
)

type TarReader struct {
	file *os.File
	gz   *gzip.Reader
	tr   *tar.Reader
}

func NewTar(path string) (*TarReader, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}

	tr := tar.NewReader(file)
	return &TarReader{file: file, gz: nil, tr: tr}, nil
}

func NewTarGz(path string) (*TarReader, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}

	gz, _ := gzip.NewReader(file)
	if err != nil {
		return nil, err
	}

	tr := tar.NewReader(gz)
	return &TarReader{file: file, gz: gz, tr: tr}, nil
}

func (tr *TarReader) Unpack(toPath string) error {
	defer tr.file.Close()
	if tr.gz != nil {
		defer tr.gz.Close()
	}

	r := tr.tr

	for {
		hdr, err := r.Next()
		switch {
		case err == io.EOF:
			break
		case err != nil:
			return err
		default:
			if err := doOnType(hdr.Typeflag, toPath, hdr.Name, r); err != nil {
				return err
			}
		}

	}

	return nil
}

func doOnType(typeFlag byte, toPath string, name string, r *tar.Reader) error {
	fullpath := filepath.Join(toPath, name)
	switch typeFlag {
	case tar.TypeReg, tar.TypeRegA:
		return writeFile(fullpath, r)
	case tar.TypeDir:
		return os.MkdirAll(fullpath, 0777)
	default:
		return nil
	}
}

func writeFile(path string, r *tar.Reader) error {
	out, err := os.Create(path)
	if err != nil {
		return err
	}
	defer out.Close()

	_, err = io.Copy(out, r)
	return err
}
<|endoftext|>


<commit_before>package lib

import (
    "fmt"
    "os"
    "time"

    . "gopkg.in/check.v1"
)

func (s *OssutilCommandSuite) rawList(args []string, shortFormat, directory bool) (bool, error) {
    command := "ls"
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &configFile,
        "shortFormat": &shortFormat,
        "directory": &directory,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    return showElapse, err
}

// test list buckets
func (s *OssutilCommandSuite) TestListLoadConfig(c *C) {
    command := "ls"
    var args []string
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &configFile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    args = []string{"oss://"}
    options = OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &configFile,
    }
    showElapse, err = cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)
}

func (s *OssutilCommandSuite) TestListNotExistConfigFile(c *C) {
    command := "ls"
    var args []string
    str := ""
    cfile := "notexistfile"
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)
}

func (s *OssutilCommandSuite) TestListErrConfigFile(c *C) {
    cfile := "ossutil_test.config_boto"
    s.createFile(cfile, content, c)

    command := "ls"
    var args []string
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)

    _ = os.Remove(cfile)
}

func (s *OssutilCommandSuite) TestListConfigFile(c *C) {
    cfile := "ossutil_test.config_boto"
    data := fmt.Sprintf("[Credentials]\nendpoint=%s\naccessKeyID=%s\naccessKeySecret=%s\nretryTimes=%s", endpoint, accessKeyID, accessKeySecret, "errretry")
    s.createFile(cfile, data, c)

    command := "ls"
    var args []string
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    _ = os.Remove(cfile)
}

func (s *OssutilCommandSuite) TestListWithBucketEndpoint(c *C) {
    bucket := bucketNameExist

    cfile := "ossutil_test.config_boto"
    data := fmt.Sprintf("[Credentials]\nendpoint=%s\naccessKeyID=%s\naccessKeySecret=%s\n[Bucket-Endpoint]\n%s=%s", "abc", accessKeyID, accessKeySecret, bucket, endpoint)
    s.createFile(cfile, data, c)

    command := "ls"
    args := []string{CloudURLToString(bucket, "")}
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    _ = os.Remove(cfile)
}

func (s *OssutilCommandSuite) TestListWithBucketCname(c *C) {
    bucket := bucketNamePrefix + "ls1"
    s.putBucket(bucket, c)

    cfile := "ossutil_test.config_boto"
    data := fmt.Sprintf("[Credentials]\nendpoint=%s\naccessKeyID=%s\naccessKeySecret=%s\n[Bucket-Endpoint]\n%s=%s\n[Bucket-Cname]\n%s=%s", "abc", accessKeyID, accessKeySecret, bucket, "abc", bucket, bucket + "." + endpoint)
    s.createFile(cfile, data, c)

    command := "ls"
    args := []string{CloudURLToString(bucket, "")}
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    _ = os.Remove(cfile)
    s.removeBucket(bucket, true, c)
    time.Sleep(7*time.Second)
}

func (s *OssutilCommandSuite) TestListBuckets(c *C) {
    // "ls"
    bucket := bucketNamePrefix + "ls2"
    s.removeBucket(bucket, true, c)
    time.Sleep(21*time.Second)

    buckets := s.listBuckets(false, c)
    c.Assert(FindPos(bucket, buckets) == -1, Equals, true)
    bucketNum := len(buckets)

    // "ls -s"
    buckets = s.listBuckets(true, c)
    c.Assert(FindPos(bucket, buckets) == -1, Equals, true)

    // put bucket
    s.putBucket(bucket, c)
    time.Sleep(10*time.Second)

    // get result
    buckets = s.listBuckets(false, c)
    c.Assert(FindPos(bucket, buckets) != -1, Equals, true)
    c.Assert(len(buckets) >= bucketNum, Equals, true)

    // remove empty bucket
    s.removeBucket(bucket, false, c)
    time.Sleep(10*time.Second)

    // get result
    buckets = s.listBuckets(false, c)
    c.Assert(FindPos(bucket, buckets) == -1, Equals, true)
}

// list objects with not exist bucket
func (s *OssutilCommandSuite) TestListObjectsBucketNotExist(c *C) {
    bucket := bucketNameNotExist
    command := "ls"
    args := []string{CloudURLToString(bucket, "")}
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &configFile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)
}

// list objects
func (s *OssutilCommandSuite) TestListObjects(c *C) {
    bucket := bucketNameList
    s.removeObjects(bucket, "", true, true, c)
    time.Sleep(14*time.Second)

    // "ls oss://bucket"
    objects := s.listObjects(bucket, "", false, false, c)
    c.Assert(len(objects), Equals, 0)

    // put objects
    num := 3
    objectNames := []string{}
    for i := 0; i < num; i++ {
        object := fmt.Sprintf("lstest:#%d", i)
        s.putObject(bucket, object, uploadFileName, c)
        objectNames = append(objectNames, object)
    }

    object := "another_object"
    s.putObject(bucket, object, uploadFileName, c)
    objectNames = append(objectNames, object)

    // "ls oss://bucket -s"
    objects = s.listObjects(bucket, "", true, false, c)
    c.Assert(len(objects), Equals, len(objectNames))

    // "ls oss://bucket/prefix -s"
    objects = s.listObjects(bucket, "lstest:", true, false, c)
    c.Assert(len(objects), Equals, len(objectNames) - 1)

    //put directories
    num1 := 2
    objectNames = []string{}
    for i := 0; i < num1; i++ {
        object := fmt.Sprintf("lstest:#%d/", i)
        s.putObject(bucket, object, uploadFileName, c)

        object = fmt.Sprintf("lstest:#%d/%d/", i, i)
        s.putObject(bucket, object, uploadFileName, c)
        objectNames = append(objectNames, object)
    }

    // "ls oss://bucket/prefix"
    objects = s.listObjects(bucket, "lstest:#", false, false, c)
    c.Assert(len(objects), Equals, num + 2*num1)

    // "ls oss://bucket/prefix -d"
    objects = s.listObjects(bucket, "lstest:#", false, true, c)
    c.Assert(len(objects), Equals, num + num1)

    objects = s.listObjects(bucket, "lstest:#1/", false, true, c)
    c.Assert(len(objects), Equals, 2)
}

func (s *OssutilCommandSuite) TestErrList(c *C) {
    showElapse, err := s.rawList([]string{"../"}, true, false)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)

    bucket := bucketNameNotExist
    showElapse, err = s.rawList([]string{CloudURLToString(bucket, "")}, false, true)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)

    // list buckets with -d
    showElapse, err = s.rawList([]string{"oss://"}, false, true)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)
}

func (s *OssutilCommandSuite) TestListIDKey(c *C) {
    bucket := bucketNamePrefix + "lsidkey"

    cfile := "ossutil_test.config_boto"
    data := fmt.Sprintf("[Credentials]\nendpoint=%s\naccessKeyID=%s\naccessKeySecret=%s\n[Bucket-Endpoint]\n%s=%s[Bucket-Cname]\n%s=%s", "abc", "def", "ghi", bucket, "abc", bucket, "abc")
    s.createFile(cfile, data, c)

    command := "ls"
    str := ""
    args := []string{"oss://"}
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, NotNil)

    options = OptionMapType{
        "endpoint": &endpoint,
        "accessKeyID": &accessKeyID,
        "accessKeySecret": &accessKeySecret,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err = cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    _ = os.Remove(cfile)
}

func (s *OssutilCommandSuite) TestListBucketIDKey(c *C) {
    bucket := bucketNameExist

    cfile := "ossutil_test.config_boto"
    data := fmt.Sprintf("[Credentials]\nendpoint=%s\naccessKeyID=%s\naccessKeySecret=%s\n[Bucket-Endpoint]\n%s=%s[Bucket-Cname]\n%s=%s", "abc", "def", "ghi", bucket, "abc", bucket, "abc")
    s.createFile(cfile, data, c)

    command := "ls"
    str := ""
    args := []string{CloudURLToString(bucket, "")}
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, NotNil)

    options = OptionMapType{
        "endpoint": &endpoint,
        "accessKeyID": &accessKeyID,
        "accessKeySecret": &accessKeySecret,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err = cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    _ = os.Remove(cfile)
}
<commit_msg>modify case<commit_after>package lib

import (
    "fmt"
    "os"
    "time"

    . "gopkg.in/check.v1"
)

func (s *OssutilCommandSuite) rawList(args []string, shortFormat, directory bool) (bool, error) {
    command := "ls"
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &configFile,
        "shortFormat": &shortFormat,
        "directory": &directory,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    return showElapse, err
}

// test list buckets
func (s *OssutilCommandSuite) TestListLoadConfig(c *C) {
    command := "ls"
    var args []string
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &configFile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    args = []string{"oss://"}
    options = OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &configFile,
    }
    showElapse, err = cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)
}

func (s *OssutilCommandSuite) TestListNotExistConfigFile(c *C) {
    command := "ls"
    var args []string
    str := ""
    cfile := "notexistfile"
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)
}

func (s *OssutilCommandSuite) TestListErrConfigFile(c *C) {
    cfile := "ossutil_test.config_boto"
    s.createFile(cfile, content, c)

    command := "ls"
    var args []string
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)

    _ = os.Remove(cfile)
}

func (s *OssutilCommandSuite) TestListConfigFile(c *C) {
    cfile := "ossutil_test.config_boto"
    data := fmt.Sprintf("[Credentials]\nendpoint=%s\naccessKeyID=%s\naccessKeySecret=%s\nretryTimes=%s", endpoint, accessKeyID, accessKeySecret, "errretry")
    s.createFile(cfile, data, c)

    command := "ls"
    var args []string
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    _ = os.Remove(cfile)
}

func (s *OssutilCommandSuite) TestListWithBucketEndpoint(c *C) {
    bucket := bucketNameExist

    cfile := "ossutil_test.config_boto"
    data := fmt.Sprintf("[Credentials]\nendpoint=%s\naccessKeyID=%s\naccessKeySecret=%s\n[Bucket-Endpoint]\n%s=%s", "abc", accessKeyID, accessKeySecret, bucket, endpoint)
    s.createFile(cfile, data, c)

    command := "ls"
    args := []string{CloudURLToString(bucket, "")}
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    _ = os.Remove(cfile)
}

func (s *OssutilCommandSuite) TestListWithBucketCname(c *C) {
    bucket := bucketNamePrefix + "ls1"
    s.putBucket(bucket, c)

    cfile := "ossutil_test.config_boto"
    data := fmt.Sprintf("[Credentials]\nendpoint=%s\naccessKeyID=%s\naccessKeySecret=%s\n[Bucket-Endpoint]\n%s=%s\n[Bucket-Cname]\n%s=%s", "abc", accessKeyID, accessKeySecret, bucket, "abc", bucket, bucket + "." + endpoint)
    s.createFile(cfile, data, c)

    command := "ls"
    args := []string{CloudURLToString(bucket, "")}
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    _ = os.Remove(cfile)
    s.removeBucket(bucket, true, c)
    time.Sleep(7*time.Second)
}

func (s *OssutilCommandSuite) TestListBuckets(c *C) {
    // "ls"
    bucket := bucketNamePrefix + "ls2"
/*    os.Stdout = out
    os.Stderr = errout
    s.removeBucket(bucket, false, c)
    time.Sleep(10*time.Second)

    buckets := s.listBuckets(false, c)
    fmt.Println(buckets)
    c.Assert(FindPos(bucket, buckets) == -1, Equals, true)
    bucketNum := len(buckets)

    os.Stdout = testLogFile
    os.Stderr = testLogFile

    // "ls -s"
    buckets = s.listBuckets(true, c)
    c.Assert(FindPos(bucket, buckets) == -1, Equals, true)
*/
    // put bucket
    s.putBucket(bucket, c)
    time.Sleep(10*time.Second)

    // get result
    buckets := s.listBuckets(false, c)
    c.Assert(FindPos(bucket, buckets) != -1, Equals, true)
    bucketNum := len(buckets)

    // remove empty bucket
    s.removeBucket(bucket, false, c)
    time.Sleep(10*time.Second)

    // get result
    buckets = s.listBuckets(false, c)
    c.Assert(FindPos(bucket, buckets) == -1, Equals, true)
    c.Assert(len(buckets) <= bucketNum, Equals, true)
}

// list objects with not exist bucket
func (s *OssutilCommandSuite) TestListObjectsBucketNotExist(c *C) {
    bucket := bucketNameNotExist
    command := "ls"
    args := []string{CloudURLToString(bucket, "")}
    str := ""
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &configFile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)
}

// list objects
func (s *OssutilCommandSuite) TestListObjects(c *C) {
    bucket := bucketNameList
    s.removeObjects(bucket, "", true, true, c)
    time.Sleep(14*time.Second)

    // "ls oss://bucket"
    objects := s.listObjects(bucket, "", false, false, c)
    c.Assert(len(objects), Equals, 0)

    // put objects
    num := 3
    objectNames := []string{}
    for i := 0; i < num; i++ {
        object := fmt.Sprintf("lstest:#%d", i)
        s.putObject(bucket, object, uploadFileName, c)
        objectNames = append(objectNames, object)
    }

    object := "another_object"
    s.putObject(bucket, object, uploadFileName, c)
    objectNames = append(objectNames, object)

    // "ls oss://bucket -s"
    objects = s.listObjects(bucket, "", true, false, c)
    c.Assert(len(objects), Equals, len(objectNames))

    // "ls oss://bucket/prefix -s"
    objects = s.listObjects(bucket, "lstest:", true, false, c)
    c.Assert(len(objects), Equals, len(objectNames) - 1)

    //put directories
    num1 := 2
    objectNames = []string{}
    for i := 0; i < num1; i++ {
        object := fmt.Sprintf("lstest:#%d/", i)
        s.putObject(bucket, object, uploadFileName, c)

        object = fmt.Sprintf("lstest:#%d/%d/", i, i)
        s.putObject(bucket, object, uploadFileName, c)
        objectNames = append(objectNames, object)
    }

    // "ls oss://bucket/prefix"
    objects = s.listObjects(bucket, "lstest:#", false, false, c)
    c.Assert(len(objects), Equals, num + 2*num1)

    // "ls oss://bucket/prefix -d"
    objects = s.listObjects(bucket, "lstest:#", false, true, c)
    c.Assert(len(objects), Equals, num + num1)

    objects = s.listObjects(bucket, "lstest:#1/", false, true, c)
    c.Assert(len(objects), Equals, 2)
}

func (s *OssutilCommandSuite) TestErrList(c *C) {
    showElapse, err := s.rawList([]string{"../"}, true, false)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)

    bucket := bucketNameNotExist
    showElapse, err = s.rawList([]string{CloudURLToString(bucket, "")}, false, true)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)

    // list buckets with -d
    showElapse, err = s.rawList([]string{"oss://"}, false, true)
    c.Assert(err, NotNil)
    c.Assert(showElapse, Equals, false)
}

func (s *OssutilCommandSuite) TestListIDKey(c *C) {
    bucket := bucketNamePrefix + "lsidkey"

    cfile := "ossutil_test.config_boto"
    data := fmt.Sprintf("[Credentials]\nendpoint=%s\naccessKeyID=%s\naccessKeySecret=%s\n[Bucket-Endpoint]\n%s=%s[Bucket-Cname]\n%s=%s", "abc", "def", "ghi", bucket, "abc", bucket, "abc")
    s.createFile(cfile, data, c)

    command := "ls"
    str := ""
    args := []string{"oss://"}
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, NotNil)

    options = OptionMapType{
        "endpoint": &endpoint,
        "accessKeyID": &accessKeyID,
        "accessKeySecret": &accessKeySecret,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err = cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    _ = os.Remove(cfile)
}

func (s *OssutilCommandSuite) TestListBucketIDKey(c *C) {
    bucket := bucketNameExist

    cfile := "ossutil_test.config_boto"
    data := fmt.Sprintf("[Credentials]\nendpoint=%s\naccessKeyID=%s\naccessKeySecret=%s\n[Bucket-Endpoint]\n%s=%s[Bucket-Cname]\n%s=%s", "abc", "def", "ghi", bucket, "abc", bucket, "abc")
    s.createFile(cfile, data, c)

    command := "ls"
    str := ""
    args := []string{CloudURLToString(bucket, "")}
    options := OptionMapType{
        "endpoint": &str,
        "accessKeyID": &str,
        "accessKeySecret": &str,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err := cm.RunCommand(command, args, options)
    c.Assert(err, NotNil)

    options = OptionMapType{
        "endpoint": &endpoint,
        "accessKeyID": &accessKeyID,
        "accessKeySecret": &accessKeySecret,
        "stsToken": &str,
        "configFile": &cfile,
    }
    showElapse, err = cm.RunCommand(command, args, options)
    c.Assert(err, IsNil)
    c.Assert(showElapse, Equals, true)

    _ = os.Remove(cfile)
}
<|endoftext|>


<commit_before>package jail

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
	"sync"
	"testing"
	"time"

	gethcommon "github.com/ethereum/go-ethereum/common"
	"github.com/status-im/status-go/e2e"
	"github.com/status-im/status-go/geth/common"
	"github.com/status-im/status-go/geth/params"
	"github.com/status-im/status-go/geth/signal"
	"github.com/status-im/status-go/geth/txqueue"
	"github.com/stretchr/testify/suite"
)

func TestJailRPCTestSuite(t *testing.T) {
	suite.Run(t, new(JailRPCTestSuite))
}

type JailRPCTestSuite struct {
	e2e.BackendTestSuite

	jail common.JailManager
}

func (s *JailRPCTestSuite) SetupTest() {
	s.BackendTestSuite.SetupTest()
	s.jail = s.Backend.JailManager()
	s.NotNil(s.jail)
}

func (s *JailRPCTestSuite) TestJailRPCSend() {
	s.StartTestBackend()
	defer s.StopTestBackend()

	EnsureNodeSync(s.Backend.NodeManager())

	// load Status JS and add test command to it
	s.jail.BaseJS(baseStatusJSCode)
	s.jail.Parse(testChatID, ``)

	// obtain VM for a given chat (to send custom JS to jailed version of Send())
	cell, err := s.jail.Cell(testChatID)
	s.NoError(err)
	s.NotNil(cell)

	// internally (since we replaced `web3.send` with `jail.Send`)
	// all requests to web3 are forwarded to `jail.Send`
	_, err = cell.Run(`
	    var balance = web3.eth.getBalance("` + TestConfig.Account1.Address + `");
		var sendResult = web3.fromWei(balance, "ether")
	`)
	s.NoError(err)

	value, err := cell.Get("sendResult")
	s.NoError(err, "cannot obtain result of balance check operation")

	balance, err := value.ToFloat()
	s.NoError(err)

	s.T().Logf("Balance of %.2f ETH found on '%s' account", balance, TestConfig.Account1.Address)
	s.False(balance < 100, "wrong balance (there should be lots of test Ether on that account)")
}

func (s *JailRPCTestSuite) TestIsConnected() {
	s.StartTestBackend()
	defer s.StopTestBackend()

	s.jail.Parse(testChatID, "")

	// obtain VM for a given chat (to send custom JS to jailed version of Send())
	cell, err := s.jail.Cell(testChatID)
	s.NoError(err)

	_, err = cell.Run(`
	    var responseValue = web3.isConnected();
	    responseValue = JSON.stringify(responseValue);
	`)
	s.NoError(err)

	responseValue, err := cell.Get("responseValue")
	s.NoError(err, "cannot obtain result of isConnected()")

	response, err := responseValue.ToString()
	s.NoError(err, "cannot parse result")

	expectedResponse := `{"jsonrpc":"2.0","result":true}`
	s.Equal(expectedResponse, response)
}

// regression test: eth_getTransactionReceipt with invalid transaction hash should return null
func (s *JailRPCTestSuite) TestRegressionGetTransactionReceipt() {
	s.StartTestBackend()
	defer s.StopTestBackend()

	rpcClient := s.Backend.NodeManager().RPCClient()
	s.NotNil(rpcClient)

	// note: transaction hash is assumed to be invalid
	got := rpcClient.CallRaw(`{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xbbebf28d0a3a3cbb38e6053a5b21f08f82c62b0c145a17b1c4313cac3f68ae7c"],"id":7}`)
	expected := `{"jsonrpc":"2.0","id":7,"result":null}`
	s.Equal(expected, got)
}

func (s *JailRPCTestSuite) TestContractDeployment() {
	s.StartTestBackend()
	defer s.StopTestBackend()

	EnsureNodeSync(s.Backend.NodeManager())

	// obtain VM for a given chat (to send custom JS to jailed version of Send())
	s.jail.Parse(testChatID, "")

	cell, err := s.jail.Cell(testChatID)
	s.NoError(err)

	completeQueuedTransaction := make(chan struct{})

	var txHash gethcommon.Hash
	signal.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
		var (
			envelope signal.Envelope
			err      error
		)

		err = json.Unmarshal([]byte(jsonEvent), &envelope)
		s.NoError(err, "cannot unmarshal JSON: %s", jsonEvent)

		if envelope.Type == txqueue.EventTransactionQueued {
			event := envelope.Event.(map[string]interface{})
			s.T().Logf("transaction queued and will be completed shortly, id: %v", event["id"])

			s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))

			txID := event["id"].(string)
			txHash, err = s.Backend.CompleteTransaction(common.QueuedTxID(txID), TestConfig.Account1.Password)
			if s.NoError(err, event["id"]) {
				s.T().Logf("contract transaction complete, URL: %s", "https://ropsten.etherscan.io/tx/"+txHash.Hex())
			}

			close(completeQueuedTransaction)
		}
	})

	_, err = cell.Run(`
		var responseValue = null;
		var errorValue = null;
		var testContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"a","type":"int256"}],"name":"double","outputs":[{"name":"","type":"int256"}],"payable":false,"type":"function"}]);
		var test = testContract.new(
		{
			from: '` + TestConfig.Account1.Address + `',
			data: '0x6060604052341561000c57fe5b5b60a58061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636ffa1caa14603a575bfe5b3415604157fe5b60556004808035906020019091905050606b565b6040518082815260200191505060405180910390f35b60008160020290505b9190505600a165627a7a72305820ccdadd737e4ac7039963b54cee5e5afb25fa859a275252bdcf06f653155228210029',
			gas: '` + strconv.Itoa(params.DefaultGas) + `'
		}, function (e, contract) {
			// NOTE: The callback will fire twice!
			if (e) {
				errorValue = e;
				return;
			}
			// Once the contract has the transactionHash property set and once its deployed on an address.
			if (!contract.address) {
				responseValue = contract.transactionHash;
			}
		})
	`)
	s.NoError(err)

	select {
	case <-completeQueuedTransaction:
	case <-time.After(time.Minute):
		s.FailNow("test timed out")
	}

	// Wait until callback is fired and `responseValue` is set. Hacky but simple.
	time.Sleep(2 * time.Second)

	errorValue, err := cell.Get("errorValue")
	s.NoError(err)
	s.Equal("null", errorValue.String())

	responseValue, err := cell.Get("responseValue")
	s.NoError(err)

	response, err := responseValue.ToString()
	s.NoError(err)

	expectedResponse := txHash.Hex()
	s.Equal(expectedResponse, response)
}

func (s *JailRPCTestSuite) TestJailVMPersistence() {
	s.StartTestBackend()
	defer s.StopTestBackend()

	EnsureNodeSync(s.Backend.NodeManager())

	// log into account from which transactions will be sent
	err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
	s.NoError(err, "cannot select account: %v", TestConfig.Account1.Address)

	type testCase struct {
		command   string
		params    string
		validator func(response string) error
	}
	var testCases = []testCase{
		{
			`["sendTestTx"]`,
			`{"amount": "0.000001", "from": "` + TestConfig.Account1.Address + `"}`,
			func(response string) error {
				if strings.Contains(response, "error") {
					return fmt.Errorf("unexpected response: %v", response)
				}
				return nil
			},
		},
		{
			`["sendTestTx"]`,
			`{"amount": "0.000002", "from": "` + TestConfig.Account1.Address + `"}`,
			func(response string) error {
				if strings.Contains(response, "error") {
					return fmt.Errorf("unexpected response: %v", response)
				}
				return nil
			},
		},
		{
			`["ping"]`,
			`{"pong": "Ping1", "amount": 0.42}`,
			func(response string) error {
				expectedResponse := `{"result": "Ping1"}`
				if response != expectedResponse {
					return fmt.Errorf("unexpected response, expected: %v, got: %v", expectedResponse, response)
				}
				return nil
			},
		},
		{
			`["ping"]`,
			`{"pong": "Ping2", "amount": 0.42}`,
			func(response string) error {
				expectedResponse := `{"result": "Ping2"}`
				if response != expectedResponse {
					return fmt.Errorf("unexpected response, expected: %v, got: %v", expectedResponse, response)
				}
				return nil
			},
		},
	}

	jail := s.Backend.JailManager()
	jail.BaseJS(baseStatusJSCode)

	parseResult := jail.Parse(testChatID, `
		var total = 0;
		_status_catalog['ping'] = function(params) {
			total += Number(params.amount);
			return params.pong;
		}

		_status_catalog['sendTestTx'] = function(params) {
		  var amount = params.amount;
		  var transaction = {
			"from": params.from,
			"to": "`+TestConfig.Account2.Address+`",
			"value": web3.toWei(amount, "ether")
		  };
		  web3.eth.sendTransaction(transaction, function (error, result) {
			 if(!error) {
				total += Number(amount);
			 }
		  });
		}
	`)
	s.NotContains(parseResult, "error", "further will fail if initial parsing failed")

	var wg sync.WaitGroup
	signal.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
		var envelope signal.Envelope
		if e := json.Unmarshal([]byte(jsonEvent), &envelope); e != nil {
			s.T().Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
			return
		}
		if envelope.Type == txqueue.EventTransactionQueued {
			event := envelope.Event.(map[string]interface{})
			s.T().Logf("Transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))

			//var txHash common.Hash
			txID := event["id"].(string)
			txHash, e := s.Backend.CompleteTransaction(common.QueuedTxID(txID), TestConfig.Account1.Password)
			s.NoError(e, "cannot complete queued transaction[%v]: %v", event["id"], e)

			s.T().Logf("Transaction complete: https://ropsten.etherscan.io/tx/%s", txHash.Hex())
		}
	})

	// run commands concurrently
	for _, tc := range testCases {
		wg.Add(1)
		go func(tc testCase) {
			defer wg.Done() // ensure we don't forget it

			s.T().Logf("CALL START: %v %v", tc.command, tc.params)
			response := jail.Call(testChatID, tc.command, tc.params)
			if e := tc.validator(response); e != nil {
				s.T().Errorf("failed test validation: %v, err: %v", tc.command, e)
			}
			s.T().Logf("CALL END: %v %v", tc.command, tc.params)
		}(tc)
	}

	finishTestCases := make(chan struct{})
	go func() {
		wg.Wait()
		close(finishTestCases)
	}()

	select {
	case <-finishTestCases:
	case <-time.After(time.Minute):
		s.FailNow("some tests failed to finish in time")
	}

	// Wait till eth_sendTransaction callbacks have been executed.
	// FIXME(tiabc): more reliable means of testing that.
	time.Sleep(5 * time.Second)

	// Validate total.
	cell, err := jail.Cell(testChatID)
	s.NoError(err)

	totalOtto, err := cell.Get("total")
	s.NoError(err)

	total, err := totalOtto.ToFloat()
	s.NoError(err)

	s.T().Log(total)
	s.InDelta(0.840003, total, 0.0000001)
}
<commit_msg>Fix import usage for jail test<commit_after>package jail

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
	"sync"
	"testing"
	"time"

	gethcommon "github.com/ethereum/go-ethereum/common"
	"github.com/status-im/status-go/e2e"
	"github.com/status-im/status-go/geth/common"
	"github.com/status-im/status-go/geth/params"
	"github.com/status-im/status-go/geth/signal"
	"github.com/status-im/status-go/geth/txqueue"
	. "github.com/status-im/status-go/testing"
	"github.com/stretchr/testify/suite"
)

func TestJailRPCTestSuite(t *testing.T) {
	suite.Run(t, new(JailRPCTestSuite))
}

type JailRPCTestSuite struct {
	e2e.BackendTestSuite

	jail common.JailManager
}

func (s *JailRPCTestSuite) SetupTest() {
	s.BackendTestSuite.SetupTest()
	s.jail = s.Backend.JailManager()
	s.NotNil(s.jail)
}

func (s *JailRPCTestSuite) TestJailRPCSend() {
	s.StartTestBackend()
	defer s.StopTestBackend()

	EnsureNodeSync(s.Backend.NodeManager())

	// load Status JS and add test command to it
	s.jail.BaseJS(baseStatusJSCode)
	s.jail.Parse(testChatID, ``)

	// obtain VM for a given chat (to send custom JS to jailed version of Send())
	cell, err := s.jail.Cell(testChatID)
	s.NoError(err)
	s.NotNil(cell)

	// internally (since we replaced `web3.send` with `jail.Send`)
	// all requests to web3 are forwarded to `jail.Send`
	_, err = cell.Run(`
	    var balance = web3.eth.getBalance("` + TestConfig.Account1.Address + `");
		var sendResult = web3.fromWei(balance, "ether")
	`)
	s.NoError(err)

	value, err := cell.Get("sendResult")
	s.NoError(err, "cannot obtain result of balance check operation")

	balance, err := value.ToFloat()
	s.NoError(err)

	s.T().Logf("Balance of %.2f ETH found on '%s' account", balance, TestConfig.Account1.Address)
	s.False(balance < 100, "wrong balance (there should be lots of test Ether on that account)")
}

func (s *JailRPCTestSuite) TestIsConnected() {
	s.StartTestBackend()
	defer s.StopTestBackend()

	s.jail.Parse(testChatID, "")

	// obtain VM for a given chat (to send custom JS to jailed version of Send())
	cell, err := s.jail.Cell(testChatID)
	s.NoError(err)

	_, err = cell.Run(`
	    var responseValue = web3.isConnected();
	    responseValue = JSON.stringify(responseValue);
	`)
	s.NoError(err)

	responseValue, err := cell.Get("responseValue")
	s.NoError(err, "cannot obtain result of isConnected()")

	response, err := responseValue.ToString()
	s.NoError(err, "cannot parse result")

	expectedResponse := `{"jsonrpc":"2.0","result":true}`
	s.Equal(expectedResponse, response)
}

// regression test: eth_getTransactionReceipt with invalid transaction hash should return null
func (s *JailRPCTestSuite) TestRegressionGetTransactionReceipt() {
	s.StartTestBackend()
	defer s.StopTestBackend()

	rpcClient := s.Backend.NodeManager().RPCClient()
	s.NotNil(rpcClient)

	// note: transaction hash is assumed to be invalid
	got := rpcClient.CallRaw(`{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xbbebf28d0a3a3cbb38e6053a5b21f08f82c62b0c145a17b1c4313cac3f68ae7c"],"id":7}`)
	expected := `{"jsonrpc":"2.0","id":7,"result":null}`
	s.Equal(expected, got)
}

func (s *JailRPCTestSuite) TestContractDeployment() {
	s.StartTestBackend()
	defer s.StopTestBackend()

	EnsureNodeSync(s.Backend.NodeManager())

	// obtain VM for a given chat (to send custom JS to jailed version of Send())
	s.jail.Parse(testChatID, "")

	cell, err := s.jail.Cell(testChatID)
	s.NoError(err)

	completeQueuedTransaction := make(chan struct{})

	var txHash gethcommon.Hash
	signal.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
		var (
			envelope signal.Envelope
			err      error
		)

		err = json.Unmarshal([]byte(jsonEvent), &envelope)
		s.NoError(err, "cannot unmarshal JSON: %s", jsonEvent)

		if envelope.Type == txqueue.EventTransactionQueued {
			event := envelope.Event.(map[string]interface{})
			s.T().Logf("transaction queued and will be completed shortly, id: %v", event["id"])

			s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))

			txID := event["id"].(string)
			txHash, err = s.Backend.CompleteTransaction(common.QueuedTxID(txID), TestConfig.Account1.Password)
			if s.NoError(err, event["id"]) {
				s.T().Logf("contract transaction complete, URL: %s", "https://ropsten.etherscan.io/tx/"+txHash.Hex())
			}

			close(completeQueuedTransaction)
		}
	})

	_, err = cell.Run(`
		var responseValue = null;
		var errorValue = null;
		var testContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"a","type":"int256"}],"name":"double","outputs":[{"name":"","type":"int256"}],"payable":false,"type":"function"}]);
		var test = testContract.new(
		{
			from: '` + TestConfig.Account1.Address + `',
			data: '0x6060604052341561000c57fe5b5b60a58061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636ffa1caa14603a575bfe5b3415604157fe5b60556004808035906020019091905050606b565b6040518082815260200191505060405180910390f35b60008160020290505b9190505600a165627a7a72305820ccdadd737e4ac7039963b54cee5e5afb25fa859a275252bdcf06f653155228210029',
			gas: '` + strconv.Itoa(params.DefaultGas) + `'
		}, function (e, contract) {
			// NOTE: The callback will fire twice!
			if (e) {
				errorValue = e;
				return;
			}
			// Once the contract has the transactionHash property set and once its deployed on an address.
			if (!contract.address) {
				responseValue = contract.transactionHash;
			}
		})
	`)
	s.NoError(err)

	select {
	case <-completeQueuedTransaction:
	case <-time.After(time.Minute):
		s.FailNow("test timed out")
	}

	// Wait until callback is fired and `responseValue` is set. Hacky but simple.
	time.Sleep(2 * time.Second)

	errorValue, err := cell.Get("errorValue")
	s.NoError(err)
	s.Equal("null", errorValue.String())

	responseValue, err := cell.Get("responseValue")
	s.NoError(err)

	response, err := responseValue.ToString()
	s.NoError(err)

	expectedResponse := txHash.Hex()
	s.Equal(expectedResponse, response)
}

func (s *JailRPCTestSuite) TestJailVMPersistence() {
	s.StartTestBackend()
	defer s.StopTestBackend()

	EnsureNodeSync(s.Backend.NodeManager())

	// log into account from which transactions will be sent
	err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
	s.NoError(err, "cannot select account: %v", TestConfig.Account1.Address)

	type testCase struct {
		command   string
		params    string
		validator func(response string) error
	}
	var testCases = []testCase{
		{
			`["sendTestTx"]`,
			`{"amount": "0.000001", "from": "` + TestConfig.Account1.Address + `"}`,
			func(response string) error {
				if strings.Contains(response, "error") {
					return fmt.Errorf("unexpected response: %v", response)
				}
				return nil
			},
		},
		{
			`["sendTestTx"]`,
			`{"amount": "0.000002", "from": "` + TestConfig.Account1.Address + `"}`,
			func(response string) error {
				if strings.Contains(response, "error") {
					return fmt.Errorf("unexpected response: %v", response)
				}
				return nil
			},
		},
		{
			`["ping"]`,
			`{"pong": "Ping1", "amount": 0.42}`,
			func(response string) error {
				expectedResponse := `{"result": "Ping1"}`
				if response != expectedResponse {
					return fmt.Errorf("unexpected response, expected: %v, got: %v", expectedResponse, response)
				}
				return nil
			},
		},
		{
			`["ping"]`,
			`{"pong": "Ping2", "amount": 0.42}`,
			func(response string) error {
				expectedResponse := `{"result": "Ping2"}`
				if response != expectedResponse {
					return fmt.Errorf("unexpected response, expected: %v, got: %v", expectedResponse, response)
				}
				return nil
			},
		},
	}

	jail := s.Backend.JailManager()
	jail.BaseJS(baseStatusJSCode)

	parseResult := jail.Parse(testChatID, `
		var total = 0;
		_status_catalog['ping'] = function(params) {
			total += Number(params.amount);
			return params.pong;
		}

		_status_catalog['sendTestTx'] = function(params) {
		  var amount = params.amount;
		  var transaction = {
			"from": params.from,
			"to": "`+TestConfig.Account2.Address+`",
			"value": web3.toWei(amount, "ether")
		  };
		  web3.eth.sendTransaction(transaction, function (error, result) {
			 if(!error) {
				total += Number(amount);
			 }
		  });
		}
	`)
	s.NotContains(parseResult, "error", "further will fail if initial parsing failed")

	var wg sync.WaitGroup
	signal.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
		var envelope signal.Envelope
		if e := json.Unmarshal([]byte(jsonEvent), &envelope); e != nil {
			s.T().Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
			return
		}
		if envelope.Type == txqueue.EventTransactionQueued {
			event := envelope.Event.(map[string]interface{})
			s.T().Logf("Transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))

			//var txHash common.Hash
			txID := event["id"].(string)
			txHash, e := s.Backend.CompleteTransaction(common.QueuedTxID(txID), TestConfig.Account1.Password)
			s.NoError(e, "cannot complete queued transaction[%v]: %v", event["id"], e)

			s.T().Logf("Transaction complete: https://ropsten.etherscan.io/tx/%s", txHash.Hex())
		}
	})

	// run commands concurrently
	for _, tc := range testCases {
		wg.Add(1)
		go func(tc testCase) {
			defer wg.Done() // ensure we don't forget it

			s.T().Logf("CALL START: %v %v", tc.command, tc.params)
			response := jail.Call(testChatID, tc.command, tc.params)
			if e := tc.validator(response); e != nil {
				s.T().Errorf("failed test validation: %v, err: %v", tc.command, e)
			}
			s.T().Logf("CALL END: %v %v", tc.command, tc.params)
		}(tc)
	}

	finishTestCases := make(chan struct{})
	go func() {
		wg.Wait()
		close(finishTestCases)
	}()

	select {
	case <-finishTestCases:
	case <-time.After(time.Minute):
		s.FailNow("some tests failed to finish in time")
	}

	// Wait till eth_sendTransaction callbacks have been executed.
	// FIXME(tiabc): more reliable means of testing that.
	time.Sleep(5 * time.Second)

	// Validate total.
	cell, err := jail.Cell(testChatID)
	s.NoError(err)

	totalOtto, err := cell.Get("total")
	s.NoError(err)

	total, err := totalOtto.ToFloat()
	s.NoError(err)

	s.T().Log(total)
	s.InDelta(0.840003, total, 0.0000001)
}
<|endoftext|>


<commit_before>package main

type Command interface {
	Shell() string   // Used for executing the action in a shell (locally or via ssh).
	Logging() string // Get string used for logging.
}
<commit_msg>removed unused file<commit_after><|endoftext|>


<commit_before>package main

import (
	"fmt"
	"koding/workers/tunnelproxymanager"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	awssession "github.com/aws/aws-sdk-go/aws/session"
	"github.com/koding/asgd"
	"github.com/koding/logging"
	"github.com/koding/multiconfig"
)

const Name = "tunnelproxymanager"

func main() {
	c := &tunnelproxymanager.Config{}
	mc := multiconfig.New()
	mc.Loader = multiconfig.MultiLoader(
		&multiconfig.TagLoader{},
		&multiconfig.EnvironmentLoader{},
		&multiconfig.EnvironmentLoader{Prefix: "KONFIG_TUNNELPROXYMANAGER"},
		&multiconfig.FlagLoader{},
	)

	mc.MustLoad(c)

	conf := &asgd.Config{
		Name:            fmt.Sprintf("%s-%s", "tunnelproxymanager", c.EBEnvName),
		AccessKeyID:     c.AccessKeyID,
		SecretAccessKey: c.SecretAccessKey,
		Region:          c.Region,
		AutoScalingName: c.AutoScalingName,
		Debug:           c.Debug,
	}

	session, err := asgd.Configure(conf)
	if err != nil {
		log.Fatal("Reading config failed: ", err.Error())
	}

	log := logging.NewCustom(Name, conf.Debug)
	// remove formatting from call stack and output correct line
	log.SetCallDepth(1)

	route53Session := awssession.New(&aws.Config{
		Credentials: credentials.NewStaticCredentials(
			c.Route53AccessKeyID,
			c.Route53AccessKeyID,
			"",
		),
		Region:     aws.String(conf.Region),
		MaxRetries: aws.Int(5),
	})

	// create record manager
	recordManager := tunnelproxymanager.NewRecordManager(route53Session, log, conf.Region, c.HostedZone)
	if err := recordManager.Init(); err != nil {
		log.Fatal(err.Error())
	}

	// create lifecycle
	l := asgd.NewLifeCycle(session, log, conf.AutoScalingName)

	// configure lifecycle with system name
	if err := l.Configure(conf.Name); err != nil {
		log.Fatal(err.Error())
	}

	done := registerSignalHandler(l, log)

	// listen to lifecycle events
	if err := l.Listen(recordManager.ProcessFunc); err != nil {
		log.Fatal(err.Error())
	}

	<-done
}

func registerSignalHandler(l *asgd.LifeCycle, log logging.Logger) chan struct{} {
	done := make(chan struct{}, 1)

	go func() {
		signals := make(chan os.Signal, 1)
		signal.Notify(signals)

		signal := <-signals
		switch signal {
		case syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGSTOP, syscall.SIGKILL:
			log.Info("recieved exit signal, closing...")
			err := l.Close()
			if err != nil {
				log.Critical(err.Error())
			}
			close(done)
		}

	}()
	return done
}
<commit_msg>tunnelproxymanager: move configuration into its own folder<commit_after>package main

import (
	"fmt"
	"koding/workers/tunnelproxymanager"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	awssession "github.com/aws/aws-sdk-go/aws/session"
	"github.com/koding/asgd"
	"github.com/koding/logging"
	"github.com/koding/multiconfig"
)

const Name = "tunnelproxymanager"

func main() {
	c, err := configure()
	if err != nil {
		log.Fatal("Reading config failed: ", err.Error())
	}

	conf := &asgd.Config{
		Name:            fmt.Sprintf("%s-%s", "tunnelproxymanager", c.EBEnvName),
		AccessKeyID:     c.AccessKeyID,
		SecretAccessKey: c.SecretAccessKey,
		Region:          c.Region,
		AutoScalingName: c.AutoScalingName,
		Debug:           c.Debug,
	}

	session, err := asgd.Configure(conf)
	if err != nil {
		log.Fatal("Reading config failed: ", err.Error())
	}

	log := logging.NewCustom(Name, conf.Debug)
	// remove formatting from call stack and output correct line
	log.SetCallDepth(1)

	route53Session := awssession.New(&aws.Config{
		Credentials: credentials.NewStaticCredentials(
			c.Route53AccessKeyID,
			c.Route53AccessKeyID,
			"",
		),
		Region:     aws.String(conf.Region),
		MaxRetries: aws.Int(5),
	})

	// create record manager
	recordManager := tunnelproxymanager.NewRecordManager(route53Session, log, conf.Region, c.HostedZone)
	if err := recordManager.Init(); err != nil {
		log.Fatal(err.Error())
	}

	// create lifecycle
	l := asgd.NewLifeCycle(session, log, conf.AutoScalingName)

	// configure lifecycle with system name
	if err := l.Configure(conf.Name); err != nil {
		log.Fatal(err.Error())
	}

	done := registerSignalHandler(l, log)

	// listen to lifecycle events
	if err := l.Listen(recordManager.ProcessFunc); err != nil {
		log.Fatal(err.Error())
	}

	<-done
}

func registerSignalHandler(l *asgd.LifeCycle, log logging.Logger) chan struct{} {
	done := make(chan struct{}, 1)

	go func() {
		signals := make(chan os.Signal, 1)
		signal.Notify(signals)

		signal := <-signals
		switch signal {
		case syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGSTOP, syscall.SIGKILL:
			log.Info("recieved exit signal, closing...")
			err := l.Close()
			if err != nil {
				log.Critical(err.Error())
			}
			close(done)
		}

	}()
	return done
}

func configure() (*tunnelproxymanager.Config, error) {
	c := &tunnelproxymanager.Config{}
	mc := multiconfig.New()
	mc.Loader = multiconfig.MultiLoader(
		&multiconfig.TagLoader{},
		&multiconfig.EnvironmentLoader{},
		&multiconfig.EnvironmentLoader{Prefix: "KONFIG_TUNNELPROXYMANAGER"},
		&multiconfig.FlagLoader{},
	)

	mc.MustLoad(c)

	// decide on eb env name
	ebEnvName, err := getEBEnvName(c)
	if err != nil {
		return nil, err
	}

	c.EBEnvName = ebEnvName
	return c, nil
}

// getEBEnvName checks if region name is given in config, if not tries to get it
// from env variable
func getEBEnvName(conf *tunnelproxymanager.Config) (string, error) {
	if conf.EBEnvName != "" {
		return conf.EBEnvName, nil
	}

	// get EB_ENV_NAME param
	ebEnvName := os.Getenv("EB_ENV_NAME")
	if ebEnvName == "" {
		return "", fmt.Errorf("EB_ENV_NAME can not be empty")
	}
	return ebEnvName, nil
}
<|endoftext|>


<commit_before>package api

import (
	"net/url"
	"socialapi/config"
	"socialapi/workers/common/handler"
	"socialapi/workers/common/mux"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/kms"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/codahale/sneaker"
)

const (
	CredentialStore  = "credential-store"
	CredentialGet    = "credential-get"
	CredentialDelete = "credential-delete"
)

// AddHandlers adds handlers for slack integration
func AddHandlers(m *mux.Mux, config *config.Config) {
	manager, err := loadManager(config)
	if err != nil {
		panic(err)
	}
	s := &SneakerS3{
		manager,
	}

	m.AddHandler(
		handler.Request{
			Handler:  s.Store,
			Name:     CredentialStore,
			Type:     handler.PostRequest,
			Endpoint: "/credential/{pathName}",
		},
	)

	m.AddHandler(
		handler.Request{
			Handler:  s.Get,
			Name:     CredentialGet,
			Type:     handler.GetRequest,
			Endpoint: "/credential/{pathName}",
		},
	)

	m.AddHandler(
		handler.Request{
			Handler:  s.Delete,
			Name:     CredentialDelete,
			Type:     handler.DeleteRequest,
			Endpoint: "/credential/{pathName}",
		},
	)

}

func loadManager(config *config.Config) (*sneaker.Manager, error) {
	u, err := url.Parse(config.SneakerS3.SneakerS3Path)
	if err != nil {

		return nil, err
	}
	if u.Path != "" && u.Path[0] == '/' {
		u.Path = u.Path[1:]
	}

	// here, we provide access and secret keys for aws
	creds := credentials.NewStaticCredentials(config.SneakerS3.AwsAccesskeyId, config.SneakerS3.AwsSecretAccessKey, "")

	// we'r gonna use aws providers and region to init aws config
	session := session.New(aws.NewConfig().WithCredentials(creds).WithRegion(config.SneakerS3.AwsRegion))

	return &sneaker.Manager{
		Objects: s3.New(session),
		Envelope: sneaker.Envelope{
			KMS: kms.New(session),
		},
		Bucket:            u.Host,
		Prefix:            u.Path,
		EncryptionContext: nil,
		KeyId:             config.SneakerS3.SneakerMasterKey,
	}, nil
}
<commit_msg>go/handlers: add logger for sneaker handlers<commit_after>package api

import (
	"net/url"
	"socialapi/config"
	"socialapi/workers/common/handler"
	"socialapi/workers/common/mux"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/kms"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/codahale/sneaker"
	"github.com/koding/logging"
)

const (
	CredentialStore  = "credential-store"
	CredentialGet    = "credential-get"
	CredentialDelete = "credential-delete"
)

// AddHandlers adds handlers for slack integration
func AddHandlers(m *mux.Mux, l logging.Logger, config *config.Config) {
	manager, err := loadManager(config)
	if err != nil {
		panic(err)
	}

	s := &SneakerS3{
		Manager: manager,
		log:     l,
	}

	// s := NewSneaker(manager, l)

	m.AddHandler(
		handler.Request{
			Handler:  s.Store,
			Name:     CredentialStore,
			Type:     handler.PostRequest,
			Endpoint: "/credential/{pathName}",
		},
	)

	m.AddHandler(
		handler.Request{
			Handler:  s.Get,
			Name:     CredentialGet,
			Type:     handler.GetRequest,
			Endpoint: "/credential/{pathName}",
		},
	)

	m.AddHandler(
		handler.Request{
			Handler:  s.Delete,
			Name:     CredentialDelete,
			Type:     handler.DeleteRequest,
			Endpoint: "/credential/{pathName}",
		},
	)

}

func loadManager(config *config.Config) (*sneaker.Manager, error) {
	u, err := url.Parse(config.SneakerS3.SneakerS3Path)
	if err != nil {

		return nil, err
	}
	if u.Path != "" && u.Path[0] == '/' {
		u.Path = u.Path[1:]
	}

	// here, we provide access and secret keys for aws
	creds := credentials.NewStaticCredentials(config.SneakerS3.AwsAccesskeyId, config.SneakerS3.AwsSecretAccessKey, "")

	// we'r gonna use aws providers and region to init aws config
	session := session.New(aws.NewConfig().WithCredentials(creds).WithRegion(config.SneakerS3.AwsRegion))

	return &sneaker.Manager{
		Objects: s3.New(session),
		Envelope: sneaker.Envelope{
			KMS: kms.New(session),
		},
		Bucket:            u.Host,
		Prefix:            u.Path,
		EncryptionContext: nil,
		KeyId:             config.SneakerS3.SneakerMasterKey,
	}, nil
}

//
// func NewSneaker(s *sneaker.Manager, l logging.Logger) *SneakerS3 {
// 	return &SneakerS3{
// 		Manager: s,
// 		log:     l,
// 	}
//
// }
<|endoftext|>


<commit_before>package handlers_test

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"

	log "github.com/Sirupsen/logrus"
	"github.com/jrzimmerman/bestrida-server-go/handlers"
	strava "github.com/strava/go.strava"
)

func TestGetAthleteByIDFromStravaSuccess(t *testing.T) {
	id := 1027935

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusOK; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}

	// Unmarshal and check the response body
	var a *strava.AthleteDetailed
	if err := json.NewDecoder(rec.Body).Decode(&a); err != nil {
		t.Errorf("unable to decode response: %s", err)
	}

	log.WithField("Athlete ID", a.Id).Info("Athlete returned from Strava")

	if a.Id != int64(id) {
		t.Errorf("unexpected athlete")
	}
}

func TestGetAthleteByIDFromStravaFailureURL(t *testing.T) {
	id := "fred"

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusInternalServerError; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}
}

func TestGetAthleteByIDFromStravaFailureID(t *testing.T) {
	id := 0

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusInternalServerError; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}
}

func TestGetFriendsByUserIDFromStrava(t *testing.T) {
	id := 1027935

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v/friends", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusOK; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}

	// Unmarshal and check the response body
	var as *[]strava.AthleteSummary
	if err := json.NewDecoder(rec.Body).Decode(&as); err != nil {
		t.Errorf("unable to decode response: %s", err)
	}

	log.Info("Athlete friends returned from Strava")
}

func TestGetSegmentsByUserIDFromStrava(t *testing.T) {
	id := 1027935

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v/segments", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusOK; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}

	// Unmarshal and check the response body
	var ss *[]strava.SegmentSummary
	if err := json.NewDecoder(rec.Body).Decode(&ss); err != nil {
		t.Errorf("unable to decode response: %s", err)
	}

	log.Info("Athlete segments returned from Strava")
}
<commit_msg>add segments tests<commit_after>package handlers_test

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"

	log "github.com/Sirupsen/logrus"
	"github.com/jrzimmerman/bestrida-server-go/handlers"
	strava "github.com/strava/go.strava"
)

func TestGetAthleteByIDFromStravaSuccess(t *testing.T) {
	id := 1027935

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusOK; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}

	// Unmarshal and check the response body
	var a *strava.AthleteDetailed
	if err := json.NewDecoder(rec.Body).Decode(&a); err != nil {
		t.Errorf("unable to decode response: %s", err)
	}

	log.WithField("Athlete ID", a.Id).Info("Athlete returned from Strava")

	if a.Id != int64(id) {
		t.Errorf("unexpected athlete")
	}
}

func TestGetAthleteByIDFromStravaFailureURL(t *testing.T) {
	id := "fred"

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusInternalServerError; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}
}

func TestGetAthleteByIDFromStravaFailureID(t *testing.T) {
	id := 0

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusInternalServerError; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}
}

func TestGetFriendsByUserIDFromStrava(t *testing.T) {
	id := 1027935

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v/friends", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusOK; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}

	// Unmarshal and check the response body
	var as *[]strava.AthleteSummary
	if err := json.NewDecoder(rec.Body).Decode(&as); err != nil {
		t.Errorf("unable to decode response: %s", err)
	}

	log.Info("Athlete friends returned from Strava")
}

func TestGetSegmentsByUserIDFromStravaFailureURL(t *testing.T) {
	id := "fred"

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v/segments", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusInternalServerError; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}
}

func TestGetSegmentsByUserIDFromStravaFailureID(t *testing.T) {
	id := 0

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v/segments", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusInternalServerError; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}
}

func TestGetSegmentsByUserIDFromStravaSuccess(t *testing.T) {
	id := 1027935

	// Create the http request
	req, err := http.NewRequest("GET", fmt.Sprintf("/strava/athletes/%v/segments", id), nil)
	if err != nil {
		t.Error("unable to generate request", err)
	}

	// Send the request to the API
	rec := httptest.NewRecorder()
	handlers.API().ServeHTTP(rec, req)

	// Check the status code
	if exp := http.StatusOK; rec.Code != exp {
		t.Errorf("expected status code %v, got: %v", exp, rec.Code)
	}

	// Unmarshal and check the response body
	var ss *[]strava.SegmentSummary
	if err := json.NewDecoder(rec.Body).Decode(&ss); err != nil {
		t.Errorf("unable to decode response: %s", err)
	}

	log.Info("Athlete segments returned from Strava")
}
<|endoftext|>


<commit_before>package vagrant

import (
	"fmt"
	"os"
	"os/exec"
	"sync"

	"github.com/hashicorp/go-version"
	"github.com/hashicorp/otto/context"
	execHelper "github.com/hashicorp/otto/helper/exec"
	"github.com/hashicorp/otto/helper/hashitools"
	"github.com/hashicorp/otto/ui"
)

var (
	vagrantMinVersion = version.Must(version.NewVersion("1.7.4"))
)

// Project returns the hashitools Project for this.
func Project(ctx *context.Shared) *hashitools.Project {
	return &hashitools.Project{
		Name:       "vagrant",
		MinVersion: vagrantMinVersion,
		Installer: &hashitools.VagrantInstaller{
			Ui: ctx.Ui,
		},
	}
}

// Vagrant wraps `vagrant` execution into an easy-to-use API.
type Vagrant struct {
	// Dir is the working directory where all Vagrant commands will
	// be executed from.
	Dir string

	// DataDir is the directory where Vagrant commands should store data.
	DataDir string

	// Ui, if given, will be used to stream output from the Vagrant
	// commands. If this is nil, then the output will be logged but
	// won't be visible to the user.
	Ui ui.Ui
}

// A global mutex to prevent any Vagrant commands from running in parallel,
// which is not a supported mode of operation for Vagrant.
var vagrantMutex = &sync.Mutex{}

// The environment variable that Vagrant uses to configure its data dir.
const vagrantDataDirEnvVar = "VAGRANT_DOTFILE_PATH"

// Execute executes a raw Vagrant command.
func (v *Vagrant) Execute(command ...string) error {
	vagrantMutex.Lock()
	defer vagrantMutex.Unlock()

	// Build the command to execute
	cmd := exec.Command("vagrant", command...)
	cmd.Dir = v.Dir

	// Tell vagrant where to store data
	origDataDir := os.Getenv(vagrantDataDirEnvVar)
	defer os.Setenv(vagrantDataDirEnvVar, origDataDir)
	if err := os.Setenv(vagrantDataDirEnvVar, v.DataDir); err != nil {
		return err
	}

	// Run it with the execHelper
	if err := execHelper.Run(v.Ui, cmd); err != nil {
		return fmt.Errorf(
			"Error executing Vagrant: %s\n\n"+
				"The error messages from Vagrant are usually very informative.\n"+
				"Please read it carefully and fix any issues it mentions. If\n"+
				"the message isn't clear, please report this to the Otto project.",
			err)
	}

	return nil
}
<commit_msg>helper/vagrant: support new env vars for the subprocess<commit_after>package vagrant

import (
	"fmt"
	"os"
	"os/exec"
	"sync"

	"github.com/hashicorp/go-version"
	"github.com/hashicorp/otto/context"
	execHelper "github.com/hashicorp/otto/helper/exec"
	"github.com/hashicorp/otto/helper/hashitools"
	"github.com/hashicorp/otto/ui"
)

var (
	vagrantMinVersion = version.Must(version.NewVersion("1.7.4"))
)

// Project returns the hashitools Project for this.
func Project(ctx *context.Shared) *hashitools.Project {
	return &hashitools.Project{
		Name:       "vagrant",
		MinVersion: vagrantMinVersion,
		Installer: &hashitools.VagrantInstaller{
			Ui: ctx.Ui,
		},
	}
}

// Vagrant wraps `vagrant` execution into an easy-to-use API.
type Vagrant struct {
	// Dir is the working directory where all Vagrant commands will
	// be executed from.
	Dir string

	// DataDir is the directory where Vagrant commands should store data.
	DataDir string

	// Env is extra environment variables to set when executing Vagrant.
	// This will be on top of the environment variables that are in this
	// process.
	Env map[string]string

	// Ui, if given, will be used to stream output from the Vagrant
	// commands. If this is nil, then the output will be logged but
	// won't be visible to the user.
	Ui ui.Ui
}

// A global mutex to prevent any Vagrant commands from running in parallel,
// which is not a supported mode of operation for Vagrant.
var vagrantMutex = &sync.Mutex{}

// The environment variable that Vagrant uses to configure its data dir.
const vagrantDataDirEnvVar = "VAGRANT_DOTFILE_PATH"

// Execute executes a raw Vagrant command.
func (v *Vagrant) Execute(command ...string) error {
	vagrantMutex.Lock()
	defer vagrantMutex.Unlock()

	// Tell vagrant where to store data
	origDataDir := os.Getenv(vagrantDataDirEnvVar)
	defer os.Setenv(vagrantDataDirEnvVar, origDataDir)
	if err := os.Setenv(vagrantDataDirEnvVar, v.DataDir); err != nil {
		return err
	}

	// Build up the environment
	env := os.Environ()
	if len(v.Env) > 0 {
		for k, v := range v.Env {
			env = append(env, fmt.Sprintf("%s=%s", k, v))
		}
	}

	// Build the command to execute
	cmd := exec.Command("vagrant", command...)
	cmd.Dir = v.Dir
	cmd.Env = env

	// Run it with the execHelper
	if err := execHelper.Run(v.Ui, cmd); err != nil {
		return fmt.Errorf(
			"Error executing Vagrant: %s\n\n"+
				"The error messages from Vagrant are usually very informative.\n"+
				"Please read it carefully and fix any issues it mentions. If\n"+
				"the message isn't clear, please report this to the Otto project.",
			err)
	}

	return nil
}
<|endoftext|>


<commit_before>package consul

import (
	"github.com/ugorji/go/codec"
	"net"
	"net/rpc"
	"os"
	"testing"
	"time"
)

func rpcClient(t *testing.T, s *Server) *rpc.Client {
	addr := s.config.RPCAddr
	conn, err := net.DialTimeout("tcp", addr.String(), time.Second)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	// Write the Consul RPC byte to set the mode
	conn.Write([]byte{byte(rpcConsul)})

	cc := codec.GoRpc.ClientCodec(conn, &codec.MsgpackHandle{})
	return rpc.NewClientWithCodec(cc)
}

func TestStatusLeader(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()
	client := rpcClient(t, s1)
	defer client.Close()

	arg := struct{}{}
	var leader string
	if err := client.Call("Status.Leader", arg, &leader); err != nil {
		t.Fatalf("err: %v", err)
	}
	if leader != "" {
		t.Fatalf("unexpected leader: %v", leader)
	}

	time.Sleep(100 * time.Millisecond)

	if err := client.Call("Status.Leader", arg, &leader); err != nil {
		t.Fatalf("err: %v", err)
	}
	if leader == "" {
		t.Fatalf("no leader")
	}
}

func TestStatusPeers(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()
	client := rpcClient(t, s1)
	defer client.Close()

	arg := struct{}{}
	var peers []string
	if err := client.Call("Status.Peers", arg, &peers); err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(peers) != 1 {
		t.Fatalf("no peers: %v", peers)
	}
}
<commit_msg>Remove all sleeps from `status_endpoint_test.go`<commit_after>package consul

import (
	"github.com/hashicorp/consul/testutil"
	"github.com/ugorji/go/codec"
	"net"
	"net/rpc"
	"os"
	"testing"
	"time"
)

func rpcClient(t *testing.T, s *Server) *rpc.Client {
	addr := s.config.RPCAddr
	conn, err := net.DialTimeout("tcp", addr.String(), time.Second)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	// Write the Consul RPC byte to set the mode
	conn.Write([]byte{byte(rpcConsul)})

	cc := codec.GoRpc.ClientCodec(conn, &codec.MsgpackHandle{})
	return rpc.NewClientWithCodec(cc)
}

func TestStatusLeader(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()
	client := rpcClient(t, s1)
	defer client.Close()

	arg := struct{}{}
	var leader string
	if err := client.Call("Status.Leader", arg, &leader); err != nil {
		t.Fatalf("err: %v", err)
	}
	if leader != "" {
		t.Fatalf("unexpected leader: %v", leader)
	}

	testutil.WaitForLeader(t, client.Call, "dc1")

	if err := client.Call("Status.Leader", arg, &leader); err != nil {
		t.Fatalf("err: %v", err)
	}
	if leader == "" {
		t.Fatalf("no leader")
	}
}

func TestStatusPeers(t *testing.T) {
	dir1, s1 := testServer(t)
	defer os.RemoveAll(dir1)
	defer s1.Shutdown()
	client := rpcClient(t, s1)
	defer client.Close()

	arg := struct{}{}
	var peers []string
	if err := client.Call("Status.Peers", arg, &peers); err != nil {
		t.Fatalf("err: %v", err)
	}
	if len(peers) != 1 {
		t.Fatalf("no peers: %v", peers)
	}
}
<|endoftext|>


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

package containerd

import (
	"context"
	"time"

	containersapi "github.com/containerd/containerd/api/services/containers/v1"
	tasksapi "github.com/containerd/containerd/api/services/tasks/v1"
	versionapi "github.com/containerd/containerd/api/services/version/v1"
	"github.com/containerd/containerd/containers"
	"github.com/containerd/containerd/dialer"
	"github.com/containerd/containerd/errdefs"
	pempty "github.com/golang/protobuf/ptypes/empty"
	"google.golang.org/grpc"
)

const (
	// k8sNamespace is the namespace we use to connect containerd.
	k8sNamespace = "k8s.io"
)

type client struct {
	containerService containersapi.ContainersClient
	taskService      tasksapi.TasksClient
	versionService   versionapi.VersionClient
}

type containerdClient interface {
	LoadContainer(ctx context.Context, id string) (*containers.Container, error)
	TaskPid(ctx context.Context, id string) (uint32, error)
	Version(ctx context.Context) (string, error)
}

// Client creates a containerd client
func Client() (containerdClient, error) {
	gopts := []grpc.DialOption{
		grpc.WithInsecure(),
		grpc.FailOnNonTempDialError(true),
		grpc.WithDialer(dialer.Dialer),
		grpc.WithBlock(),
		grpc.WithTimeout(2 * time.Second),
		grpc.WithBackoffMaxDelay(3 * time.Second),
	}
	unary, stream := newNSInterceptors(k8sNamespace)
	gopts = append(gopts,
		grpc.WithUnaryInterceptor(unary),
		grpc.WithStreamInterceptor(stream),
	)

	conn, err := grpc.Dial(dialer.DialAddress("/var/run/containerd/containerd.sock"), gopts...)
	if err != nil {
		return nil, err
	}
	c := &client{
		containerService: containersapi.NewContainersClient(conn),
		taskService:      tasksapi.NewTasksClient(conn),
		versionService:   versionapi.NewVersionClient(conn),
	}
	return c, err
}

func (c *client) LoadContainer(ctx context.Context, id string) (*containers.Container, error) {
	r, err := c.containerService.Get(ctx, &containersapi.GetContainerRequest{
		ID: id,
	})
	if err != nil {
		return nil, errdefs.FromGRPC(err)
	}
	return containerFromProto(r.Container), nil
}

func (c *client) TaskPid(ctx context.Context, id string) (uint32, error) {
	response, err := c.taskService.Get(ctx, &tasksapi.GetRequest{
		ContainerID: id,
	})
	if err != nil {
		return 0, errdefs.FromGRPC(err)
	}
	return response.Process.Pid, nil
}

func (c *client) Version(ctx context.Context) (string, error) {
	response, err := c.versionService.Version(ctx, &pempty.Empty{})
	if err != nil {
		return "", errdefs.FromGRPC(err)
	}
	return response.Version, nil
}

func containerFromProto(containerpb containersapi.Container) *containers.Container {
	var runtime containers.RuntimeInfo
	if containerpb.Runtime != nil {
		runtime = containers.RuntimeInfo{
			Name:    containerpb.Runtime.Name,
			Options: containerpb.Runtime.Options,
		}
	}
	return &containers.Container{
		ID:          containerpb.ID,
		Labels:      containerpb.Labels,
		Image:       containerpb.Image,
		Runtime:     runtime,
		Spec:        containerpb.Spec,
		Snapshotter: containerpb.Snapshotter,
		SnapshotKey: containerpb.SnapshotKey,
		Extensions:  containerpb.Extensions,
	}
}
<commit_msg>All handlers of containerd containers share a single client instance<commit_after>// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package containerd

import (
	"context"
	"sync"
	"time"

	containersapi "github.com/containerd/containerd/api/services/containers/v1"
	tasksapi "github.com/containerd/containerd/api/services/tasks/v1"
	versionapi "github.com/containerd/containerd/api/services/version/v1"
	"github.com/containerd/containerd/containers"
	"github.com/containerd/containerd/dialer"
	"github.com/containerd/containerd/errdefs"
	pempty "github.com/golang/protobuf/ptypes/empty"
	"google.golang.org/grpc"
)

const (
	// k8sNamespace is the namespace we use to connect containerd.
	k8sNamespace = "k8s.io"
)

type client struct {
	containerService containersapi.ContainersClient
	taskService      tasksapi.TasksClient
	versionService   versionapi.VersionClient
}

type containerdClient interface {
	LoadContainer(ctx context.Context, id string) (*containers.Container, error)
	TaskPid(ctx context.Context, id string) (uint32, error)
	Version(ctx context.Context) (string, error)
}

var once sync.Once
var ctrdClient containerdClient = nil

// Client creates a containerd client
func Client() (containerdClient, error) {
	var retErr error
	once.Do(func() {
		gopts := []grpc.DialOption{
			grpc.WithInsecure(),
			grpc.WithDialer(dialer.Dialer),
			grpc.WithBlock(),
			grpc.WithTimeout(2 * time.Second),
			grpc.WithBackoffMaxDelay(3 * time.Second),
		}
		unary, stream := newNSInterceptors(k8sNamespace)
		gopts = append(gopts,
			grpc.WithUnaryInterceptor(unary),
			grpc.WithStreamInterceptor(stream),
		)

		conn, err := grpc.Dial(dialer.DialAddress("/var/run/containerd/containerd.sock"), gopts...)
		if err != nil {
			retErr = err
			return
		}
		ctrdClient = &client{
			containerService: containersapi.NewContainersClient(conn),
			taskService:      tasksapi.NewTasksClient(conn),
			versionService:   versionapi.NewVersionClient(conn),
		}
	})
	return ctrdClient, retErr
}

func (c *client) LoadContainer(ctx context.Context, id string) (*containers.Container, error) {
	r, err := c.containerService.Get(ctx, &containersapi.GetContainerRequest{
		ID: id,
	})
	if err != nil {
		return nil, errdefs.FromGRPC(err)
	}
	return containerFromProto(r.Container), nil
}

func (c *client) TaskPid(ctx context.Context, id string) (uint32, error) {
	response, err := c.taskService.Get(ctx, &tasksapi.GetRequest{
		ContainerID: id,
	})
	if err != nil {
		return 0, errdefs.FromGRPC(err)
	}
	return response.Process.Pid, nil
}

func (c *client) Version(ctx context.Context) (string, error) {
	response, err := c.versionService.Version(ctx, &pempty.Empty{})
	if err != nil {
		return "", errdefs.FromGRPC(err)
	}
	return response.Version, nil
}

func containerFromProto(containerpb containersapi.Container) *containers.Container {
	var runtime containers.RuntimeInfo
	if containerpb.Runtime != nil {
		runtime = containers.RuntimeInfo{
			Name:    containerpb.Runtime.Name,
			Options: containerpb.Runtime.Options,
		}
	}
	return &containers.Container{
		ID:          containerpb.ID,
		Labels:      containerpb.Labels,
		Image:       containerpb.Image,
		Runtime:     runtime,
		Spec:        containerpb.Spec,
		Snapshotter: containerpb.Snapshotter,
		SnapshotKey: containerpb.SnapshotKey,
		Extensions:  containerpb.Extensions,
	}
}
<|endoftext|>