<commit_before>package vmess

import (
	"crypto/md5"
	"io"
	"net"
	"sync"

	"github.com/v2ray/v2ray-core"
	"github.com/v2ray/v2ray-core/common/alloc"
	v2io "github.com/v2ray/v2ray-core/common/io"
	"github.com/v2ray/v2ray-core/common/log"
	v2net "github.com/v2ray/v2ray-core/common/net"
	"github.com/v2ray/v2ray-core/proxy/vmess/protocol"
	"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
)

type VMessInboundHandler struct {
	vPoint     *core.Point
	clients    user.UserSet
	accepting  bool
	udpEnabled bool
}

func NewVMessInboundHandler(vp *core.Point, clients user.UserSet, udpEnabled bool) *VMessInboundHandler {
	return &VMessInboundHandler{
		vPoint:     vp,
		clients:    clients,
		udpEnabled: udpEnabled,
	}
}

func (handler *VMessInboundHandler) Listen(port uint16) error {
	listener, err := net.ListenTCP("tcp", &net.TCPAddr{
		IP:   []byte{0, 0, 0, 0},
		Port: int(port),
		Zone: "",
	})
	if err != nil {
		return log.Error("Unable to listen tcp:%d", port)
	}
	handler.accepting = true
	go handler.AcceptConnections(listener)

	if handler.udpEnabled {
		handler.ListenUDP(port)
	}

	return nil
}

func (handler *VMessInboundHandler) AcceptConnections(listener *net.TCPListener) error {
	for handler.accepting {
		connection, err := listener.AcceptTCP()
		if err != nil {
			return log.Error("Failed to accpet connection: %s", err.Error())
		}
		go handler.HandleConnection(connection)
	}
	return nil
}

func (handler *VMessInboundHandler) HandleConnection(connection *net.TCPConn) error {
	defer connection.Close()

	connReader := v2net.NewTimeOutReader(120, connection)
	requestReader := protocol.NewVMessRequestReader(handler.clients)

	request, err := requestReader.Read(connReader)
	if err != nil {
		log.Access(connection.RemoteAddr().String(), "", log.AccessRejected, err.Error())
		log.Warning("VMessIn: Invalid request from (%s): %v", connection.RemoteAddr().String(), err)
		return err
	}
	log.Access(connection.RemoteAddr().String(), request.Address.String(), log.AccessAccepted, "")
	log.Debug("VMessIn: Received request for %s", request.Address.String())

	ray := handler.vPoint.DispatchToOutbound(v2net.NewPacket(request.Destination(), nil, true))
	input := ray.InboundInput()
	output := ray.InboundOutput()
	var readFinish, writeFinish sync.Mutex
	readFinish.Lock()
	writeFinish.Lock()

	go handleInput(request, connReader, input, &readFinish)

	responseKey := md5.Sum(request.RequestKey)
	responseIV := md5.Sum(request.RequestIV)

	responseWriter, err := v2io.NewAesEncryptWriter(responseKey[:], responseIV[:], connection)
	if err != nil {
		return log.Error("VMessIn: Failed to create encrypt writer: %v", err)
	}

	// Optimize for small response packet
	buffer := alloc.NewLargeBuffer()
	buffer.Clear()
	buffer.Append(request.ResponseHeader)

	if data, open := <-output; open {
		buffer.Append(data.Value)
		data.Release()
		responseWriter.Write(buffer.Value)
		buffer.Release()
		go handleOutput(request, responseWriter, output, &writeFinish)
		writeFinish.Lock()
	}

	connection.CloseWrite()
	readFinish.Lock()

	return nil
}

func handleInput(request *protocol.VMessRequest, reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) {
	defer close(input)
	defer finish.Unlock()

	requestReader, err := v2io.NewAesDecryptReader(request.RequestKey, request.RequestIV, reader)
	if err != nil {
		log.Error("VMessIn: Failed to create decrypt reader: %v", err)
		return
	}

	v2net.ReaderToChan(input, requestReader)
}

func handleOutput(request *protocol.VMessRequest, writer io.Writer, output <-chan *alloc.Buffer, finish *sync.Mutex) {
	v2net.ChanToWriter(writer, output)
	finish.Unlock()
}

type VMessInboundHandlerFactory struct {
}

func (factory *VMessInboundHandlerFactory) Create(vp *core.Point, rawConfig interface{}) (core.InboundConnectionHandler, error) {
	config := rawConfig.(*VMessInboundConfig)

	allowedClients := user.NewTimedUserSet()
	for _, client := range config.AllowedClients {
		user, err := client.ToUser()
		if err != nil {
			panic(log.Error("VMessIn: Failed to parse user id %s: %v", client.Id, err))
		}
		allowedClients.AddUser(user)
	}

	return NewVMessInboundHandler(vp, allowedClients, config.UDPEnabled), nil
}

func init() {
	core.RegisterInboundConnectionHandlerFactory("vmess", &VMessInboundHandlerFactory{})
}
<commit_msg>Simplify code<commit_after>package vmess

import (
	"crypto/md5"
	"io"
	"net"
	"sync"

	"github.com/v2ray/v2ray-core"
	"github.com/v2ray/v2ray-core/common/alloc"
	v2io "github.com/v2ray/v2ray-core/common/io"
	"github.com/v2ray/v2ray-core/common/log"
	v2net "github.com/v2ray/v2ray-core/common/net"
	"github.com/v2ray/v2ray-core/proxy/vmess/protocol"
	"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
)

type VMessInboundHandler struct {
	vPoint     *core.Point
	clients    user.UserSet
	accepting  bool
	udpEnabled bool
}

func NewVMessInboundHandler(vp *core.Point, clients user.UserSet, udpEnabled bool) *VMessInboundHandler {
	return &VMessInboundHandler{
		vPoint:     vp,
		clients:    clients,
		udpEnabled: udpEnabled,
	}
}

func (handler *VMessInboundHandler) Listen(port uint16) error {
	listener, err := net.ListenTCP("tcp", &net.TCPAddr{
		IP:   []byte{0, 0, 0, 0},
		Port: int(port),
		Zone: "",
	})
	if err != nil {
		return log.Error("Unable to listen tcp:%d", port)
	}
	handler.accepting = true
	go handler.AcceptConnections(listener)

	if handler.udpEnabled {
		handler.ListenUDP(port)
	}

	return nil
}

func (handler *VMessInboundHandler) AcceptConnections(listener *net.TCPListener) error {
	for handler.accepting {
		connection, err := listener.AcceptTCP()
		if err != nil {
			return log.Error("Failed to accpet connection: %s", err.Error())
		}
		go handler.HandleConnection(connection)
	}
	return nil
}

func (handler *VMessInboundHandler) HandleConnection(connection *net.TCPConn) error {
	defer connection.Close()

	connReader := v2net.NewTimeOutReader(120, connection)
	requestReader := protocol.NewVMessRequestReader(handler.clients)

	request, err := requestReader.Read(connReader)
	if err != nil {
		log.Access(connection.RemoteAddr().String(), "", log.AccessRejected, err.Error())
		log.Warning("VMessIn: Invalid request from (%s): %v", connection.RemoteAddr().String(), err)
		return err
	}
	log.Access(connection.RemoteAddr().String(), request.Address.String(), log.AccessAccepted, "")
	log.Debug("VMessIn: Received request for %s", request.Address.String())

	ray := handler.vPoint.DispatchToOutbound(v2net.NewPacket(request.Destination(), nil, true))
	input := ray.InboundInput()
	output := ray.InboundOutput()
	var readFinish, writeFinish sync.Mutex
	readFinish.Lock()
	writeFinish.Lock()

	go handleInput(request, connReader, input, &readFinish)

	responseKey := md5.Sum(request.RequestKey)
	responseIV := md5.Sum(request.RequestIV)

	responseWriter, err := v2io.NewAesEncryptWriter(responseKey[:], responseIV[:], connection)
	if err != nil {
		return log.Error("VMessIn: Failed to create encrypt writer: %v", err)
	}

	// Optimize for small response packet
	buffer := alloc.NewLargeBuffer().Clear()
	buffer.Append(request.ResponseHeader)

	if data, open := <-output; open {
		buffer.Append(data.Value)
		data.Release()
		responseWriter.Write(buffer.Value)
		buffer.Release()
		go handleOutput(request, responseWriter, output, &writeFinish)
		writeFinish.Lock()
	}

	connection.CloseWrite()
	readFinish.Lock()

	return nil
}

func handleInput(request *protocol.VMessRequest, reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) {
	defer close(input)
	defer finish.Unlock()

	requestReader, err := v2io.NewAesDecryptReader(request.RequestKey, request.RequestIV, reader)
	if err != nil {
		log.Error("VMessIn: Failed to create decrypt reader: %v", err)
		return
	}

	v2net.ReaderToChan(input, requestReader)
}

func handleOutput(request *protocol.VMessRequest, writer io.Writer, output <-chan *alloc.Buffer, finish *sync.Mutex) {
	v2net.ChanToWriter(writer, output)
	finish.Unlock()
}

type VMessInboundHandlerFactory struct {
}

func (factory *VMessInboundHandlerFactory) Create(vp *core.Point, rawConfig interface{}) (core.InboundConnectionHandler, error) {
	config := rawConfig.(*VMessInboundConfig)

	allowedClients := user.NewTimedUserSet()
	for _, client := range config.AllowedClients {
		user, err := client.ToUser()
		if err != nil {
			panic(log.Error("VMessIn: Failed to parse user id %s: %v", client.Id, err))
		}
		allowedClients.AddUser(user)
	}

	return NewVMessInboundHandler(vp, allowedClients, config.UDPEnabled), nil
}

func init() {
	core.RegisterInboundConnectionHandlerFactory("vmess", &VMessInboundHandlerFactory{})
}
<|endoftext|>


<commit_before>package github

import (
	"io"
	"net/http"
	"fmt"
	"regexp"
	"strconv"
	"log"
	"bytes"
	"time"
	"encoding/json"

	"github.com/MarcosSegovia/sammy-the-bot/sammy"
	"github.com/go-telegram-bot-api/telegram-bot-api"
)

type Hook struct {
	sammy *sammy.Sammy
}

func NewHook(s *sammy.Sammy) *Hook {
	hook := new(Hook)
	hook.sammy = s
	return hook
}

func (h *Hook) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	io.WriteString(res, "Hook received !")

	r, err := regexp.Compile("/github/hooks/([0-9]+)")
	check(err, "could not set regular expression for github hooks: %v")
	matches := r.FindStringSubmatch(req.URL.Path)
	if matches[1] == "" {
		fmt.Errorf("payload failed to send a valid chatId : %v", matches[1])
	}
	chatId, err := strconv.ParseInt(matches[1], 10, 64)
	user, err := h.sammy.GetUser(chatId)
	if err != nil {
		check(err, "could not get user because: %v")
		return
	}

	switch req.Header.Get("X-GitHub-Event") {
	case "ping":
		h.pingEvent(user, req)
	case "push":
		h.pushEvent(user, req)
	case "pull_request":
		h.pullRequestEvent(user, req)
	}
}

type WebHookPayload struct {
	Payload Payload `json:"payload"`
}

type Payload struct {
	Ref         string `json:"ref"`
	Action      string `json:"action"`
	PullRequest PullRequest `json:"pull_request"`
	Created     bool `json:"created"`
	Deleted     bool `json:"deleted"`
	Forced      bool `json:"forced"`
	CompareUrl  string `json:"compare"`
	Commits     []Commit `json:"commits"`
	HeadCommit  Commit `json:"head_commit"`
	Pusher      Author `json:"pusher"`
}

func (p Payload) BranchName() string {
	r, err := regexp.Compile("refs/heads/(.*)")
	check(err, "could not set regular expression for github hooks: %v")
	matches := r.FindStringSubmatch(p.Ref)
	if matches[1] == "" {
		fmt.Errorf("payload failed to send a valid branch name : %v", matches[1])
	}

	return matches[1]
}

type PullRequest struct {
	Id               int `json:"number"`
	State            string `json:"state"`
	Title            string `json:"title"`
	Author           User `json:"user"`
	Body             string `json:"body"`
	CreatedAt        time.Time `json:"created_at"`
	Url              string `json:"html_url"`
	RequestReviewers []User `json:"requested_reviewers"`
	Merged           bool `json:"merged"`
}

type User struct {
	Id    int `json:"id"`
	Login string `json:"login"`
}

type Commit struct {
	Id        string `json:"id"`
	TreeId    string `json:"tree_id"`
	Message   string `json:"message"`
	Timestamp time.Time `json:"timestamp"`
	Author    Author `json:"author"`
	Committer Author `json:"committer"`
	Url       string `json:"url"`
}

type Author struct {
	Name     string `json:"name"`
	Email    string `json:"email"`
	Username string `json:"username,omitempty"`
}

func (h *Hook) pingEvent(user *sammy.User, req *http.Request) {
	var buffer bytes.Buffer
	buffer.WriteString("Your hook has correctly being set ! ")
	buffer.WriteString("\U0001F680")
	msg := tgbotapi.NewMessage(user.ChatId, buffer.String())
	h.sammy.Api.Send(msg)
}

func (h *Hook) pushEvent(user *sammy.User, req *http.Request) {
	var payload Payload
	var buffer bytes.Buffer
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(&payload)
	check(err, "could not decode request values because: %v")

	if payload.Deleted {
		buffer.WriteString("\U0000274C")
		buffer.WriteString(payload.Pusher.Name + " has *deleted* branch " + payload.BranchName())
		msg := tgbotapi.NewMessage(user.ChatId, buffer.String())
		msg.ParseMode = "Markdown"
		h.sammy.Api.Send(msg)
		return
	}

	buffer.WriteString("\U00002B06")
	buffer.WriteString(payload.Pusher.Name + " has *pushed* " + strconv.Itoa(len(payload.Commits)) + " commits to " + payload.BranchName() + ": \n")
	for _, commit := range payload.Commits {
		buffer.WriteString("> [" + commit.Id + "](" + commit.Url + ") " + commit.Message + " - " + commit.Committer.Name + "\n")
	}
	if len(payload.Commits) > 1 {
		buffer.WriteString("Go to the last commit >>> [" + payload.HeadCommit.Id + "](" + payload.HeadCommit.Url + ")")
	}

	msg := tgbotapi.NewMessage(user.ChatId, buffer.String())
	msg.ParseMode = "Markdown"
	h.sammy.Api.Send(msg)
}

func (h *Hook) pullRequestEvent(user *sammy.User, req *http.Request) {
	var payload Payload
	var buffer bytes.Buffer
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(&payload)
	check(err, "could not decode request values because: %v")

	switch payload.Action {
	case "review_requested":
		buffer.WriteString("\U0001F3A9")
		buffer.WriteString(" " + payload.PullRequest.Author.Login + " has *requested a review* to ")
		for _, reviewer := range payload.PullRequest.RequestReviewers {
			buffer.WriteString("\U0001F46E")
			buffer.WriteString(" " + reviewer.Login + " ")
		}
		buffer.WriteString("\n in pull request [#" + strconv.Itoa(payload.PullRequest.Id) + "]("+ payload.PullRequest.Url + ")")
	case "opened":
		buffer.WriteString("\U0001F3A9")
		buffer.WriteString(payload.PullRequest.Author.Login + " has *opened a pull request* [#" + strconv.Itoa(payload.PullRequest.Id) + "]("+ payload.PullRequest.Url + ") \n")
	case "closed":
		buffer.WriteString("Pull request [#" + strconv.Itoa(payload.PullRequest.Id) + "](" + payload.PullRequest.Url + ") has been closed")
		if payload.PullRequest.Merged {
			buffer.WriteString(" and fully merged ")
			buffer.WriteString("\U00002705")
		}

	}

	msg := tgbotapi.NewMessage(user.ChatId, buffer.String())
	msg.ParseMode = "Markdown"
	h.sammy.Api.Send(msg)
}

func check(err error, msg string) {
	if err != nil {
		log.Printf(msg, err)
	}
}
<commit_msg>Adding repository information on github web hooks<commit_after>package github

import (
	"io"
	"net/http"
	"fmt"
	"regexp"
	"strconv"
	"log"
	"bytes"
	"time"
	"encoding/json"

	"github.com/MarcosSegovia/sammy-the-bot/sammy"
	"github.com/go-telegram-bot-api/telegram-bot-api"
)

type Hook struct {
	sammy *sammy.Sammy
}

func NewHook(s *sammy.Sammy) *Hook {
	hook := new(Hook)
	hook.sammy = s
	return hook
}

func (h *Hook) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	io.WriteString(res, "Hook received !")

	r, err := regexp.Compile("/github/hooks/([0-9]+)")
	check(err, "could not set regular expression for github hooks: %v")
	matches := r.FindStringSubmatch(req.URL.Path)
	if matches[1] == "" {
		fmt.Errorf("payload failed to send a valid chatId : %v", matches[1])
	}
	chatId, err := strconv.ParseInt(matches[1], 10, 64)
	user, err := h.sammy.GetUser(chatId)
	if err != nil {
		check(err, "could not get user because: %v")
		return
	}

	switch req.Header.Get("X-GitHub-Event") {
	case "ping":
		h.pingEvent(user, req)
	case "push":
		h.pushEvent(user, req)
	case "pull_request":
		h.pullRequestEvent(user, req)
	}
}

type WebHookPayload struct {
	Payload Payload `json:"payload"`
}

type Payload struct {
	Ref         string `json:"ref"`
	Action      string `json:"action"`
	PullRequest PullRequest `json:"pull_request"`
	Created     bool `json:"created"`
	Deleted     bool `json:"deleted"`
	Forced      bool `json:"forced"`
	CompareUrl  string `json:"compare"`
	Commits     []Commit `json:"commits"`
	HeadCommit  Commit `json:"head_commit"`
	Pusher      Author `json:"pusher"`
	Repository  Repository `json:"repository"`
}

func (p Payload) BranchName() string {
	r, err := regexp.Compile("refs/heads/(.*)")
	check(err, "could not set regular expression for github hooks: %v")
	matches := r.FindStringSubmatch(p.Ref)
	if matches[1] == "" {
		fmt.Errorf("payload failed to send a valid branch name : %v", matches[1])
	}

	return matches[1]
}

type PullRequest struct {
	Id               int `json:"number"`
	State            string `json:"state"`
	Title            string `json:"title"`
	Author           User `json:"user"`
	Body             string `json:"body"`
	CreatedAt        time.Time `json:"created_at"`
	Url              string `json:"html_url"`
	RequestReviewers []User `json:"requested_reviewers"`
	Merged           bool `json:"merged"`
}

type User struct {
	Id    int `json:"id"`
	Login string `json:"login"`
}

type Commit struct {
	Id        string `json:"id"`
	TreeId    string `json:"tree_id"`
	Message   string `json:"message"`
	Timestamp time.Time `json:"timestamp"`
	Author    Author `json:"author"`
	Committer Author `json:"committer"`
	Url       string `json:"url"`
}

type Author struct {
	Name     string `json:"name"`
	Email    string `json:"email"`
	Username string `json:"username,omitempty"`
}

type Repository struct {
	Id int `json:"id"`
	Name string `json:"name"`
	FullName string `json:"full_name"`
}

func (h *Hook) pingEvent(user *sammy.User, req *http.Request) {
	var buffer bytes.Buffer
	buffer.WriteString("Your hook has correctly being set ! ")
	buffer.WriteString("\U0001F680")
	msg := tgbotapi.NewMessage(user.ChatId, buffer.String())
	h.sammy.Api.Send(msg)
}

func (h *Hook) pushEvent(user *sammy.User, req *http.Request) {
	var payload Payload
	var buffer bytes.Buffer
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(&payload)
	check(err, "could not decode request values because: %v")

	buffer.WriteString("[["+payload.Repository.FullName+"]]\n")
	if payload.Deleted {
		buffer.WriteString("\U0000274C")
		buffer.WriteString(payload.Pusher.Name + " has *deleted* branch " + payload.BranchName())
		msg := tgbotapi.NewMessage(user.ChatId, buffer.String())
		msg.ParseMode = "Markdown"
		h.sammy.Api.Send(msg)
		return
	}

	buffer.WriteString("\U00002B06")
	buffer.WriteString(payload.Pusher.Name + " has *pushed* " + strconv.Itoa(len(payload.Commits)) + " commits to " + payload.BranchName() + ": \n")
	for _, commit := range payload.Commits {
		buffer.WriteString("> [" + commit.Id + "](" + commit.Url + ") " + commit.Message + " - " + commit.Committer.Name + "\n")
	}
	if len(payload.Commits) > 1 {
		buffer.WriteString("Go to the last commit >>> [" + payload.HeadCommit.Id + "](" + payload.HeadCommit.Url + ")")
	}

	msg := tgbotapi.NewMessage(user.ChatId, buffer.String())
	msg.ParseMode = "Markdown"
	h.sammy.Api.Send(msg)
}

func (h *Hook) pullRequestEvent(user *sammy.User, req *http.Request) {
	var payload Payload
	var buffer bytes.Buffer
	decoder := json.NewDecoder(req.Body)
	err := decoder.Decode(&payload)
	check(err, "could not decode request values because: %v")

	buffer.WriteString("[["+payload.Repository.FullName+"]]\n")
	switch payload.Action {
	case "review_requested":
		buffer.WriteString("\U0001F3A9")
		buffer.WriteString(" " + payload.PullRequest.Author.Login + " has *requested a review* to ")
		for _, reviewer := range payload.PullRequest.RequestReviewers {
			buffer.WriteString("\U0001F46E")
			buffer.WriteString(" " + reviewer.Login + " ")
		}
		buffer.WriteString("\n in pull request [#" + strconv.Itoa(payload.PullRequest.Id) + "](" + payload.PullRequest.Url + ")")
	case "opened":
		buffer.WriteString("\U0001F3A9")
		buffer.WriteString(payload.PullRequest.Author.Login + " has *opened a pull request* [#" + strconv.Itoa(payload.PullRequest.Id) + "](" + payload.PullRequest.Url + ") \n")
	case "closed":
		buffer.WriteString("Pull request [#" + strconv.Itoa(payload.PullRequest.Id) + "](" + payload.PullRequest.Url + ") has been closed")
		if payload.PullRequest.Merged {
			buffer.WriteString(" and fully merged ")
			buffer.WriteString("\U00002705")
		}

	}

	msg := tgbotapi.NewMessage(user.ChatId, buffer.String())
	msg.ParseMode = "Markdown"
	h.sammy.Api.Send(msg)
}

func check(err error, msg string) {
	if err != nil {
		log.Printf(msg, err)
	}
}
<|endoftext|>


<commit_before>// Code generated by go-bindata.
// sources:
// assets/templates/eml/confirm_registration.eml
// DO NOT EDIT!

package assets

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

func bindataRead(data []byte, name string) ([]byte, error) {
	gz, err := gzip.NewReader(bytes.NewBuffer(data))
	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}

	var buf bytes.Buffer
	_, err = io.Copy(&buf, gz)
	clErr := gz.Close()

	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}
	if clErr != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

type asset struct {
	bytes []byte
	info  os.FileInfo
}

type bindataFileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
}

func (fi bindataFileInfo) Name() string {
	return fi.name
}
func (fi bindataFileInfo) Size() int64 {
	return fi.size
}
func (fi bindataFileInfo) Mode() os.FileMode {
	return fi.mode
}
func (fi bindataFileInfo) ModTime() time.Time {
	return fi.modTime
}
func (fi bindataFileInfo) IsDir() bool {
	return false
}
func (fi bindataFileInfo) Sys() interface{} {
	return nil
}

var _templatesEmlConfirm_registrationEml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xf2\x48\xcd\xc9\xc9\xd7\x51\x08\xcf\x2f\xca\x49\x51\xe4\xe2\xaa\xae\x56\xd0\x73\xce\xcf\x4b\xcb\x2c\xca\x4d\x2c\xc9\xcc\xcf\xf3\x4e\xad\x54\xa8\xad\x05\x04\x00\x00\xff\xff\xbd\xc5\x45\x97\x25\x00\x00\x00")

func templatesEmlConfirm_registrationEmlBytes() ([]byte, error) {
	return bindataRead(
		_templatesEmlConfirm_registrationEml,
		"templates/eml/confirm_registration.eml",
	)
}

func templatesEmlConfirm_registrationEml() (*asset, error) {
	bytes, err := templatesEmlConfirm_registrationEmlBytes()
	if err != nil {
		return nil, err
	}

	info := bindataFileInfo{name: "templates/eml/confirm_registration.eml", size: 37, mode: os.FileMode(420), modTime: time.Unix(1472517479, 0)}
	a := &asset{bytes: bytes, info: info}
	return a, nil
}

// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		a, err := f()
		if err != nil {
			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
		}
		return a.bytes, nil
	}
	return nil, fmt.Errorf("Asset %s not found", name)
}

// MustAsset is like Asset but panics when Asset would return an error.
// It simplifies safe initialization of global variables.
func MustAsset(name string) []byte {
	a, err := Asset(name)
	if err != nil {
		panic("asset: Asset(" + name + "): " + err.Error())
	}

	return a
}

// AssetInfo loads and returns the asset info for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func AssetInfo(name string) (os.FileInfo, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		a, err := f()
		if err != nil {
			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
		}
		return a.info, nil
	}
	return nil, fmt.Errorf("AssetInfo %s not found", name)
}

// AssetNames returns the names of the assets.
func AssetNames() []string {
	names := make([]string, 0, len(_bindata))
	for name := range _bindata {
		names = append(names, name)
	}
	return names
}

// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
	"templates/eml/confirm_registration.eml": templatesEmlConfirm_registrationEml,
}

// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
//     data/
//       foo.txt
//       img/
//         a.png
//         b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
	node := _bintree
	if len(name) != 0 {
		cannonicalName := strings.Replace(name, "\\", "/", -1)
		pathList := strings.Split(cannonicalName, "/")
		for _, p := range pathList {
			node = node.Children[p]
			if node == nil {
				return nil, fmt.Errorf("Asset %s not found", name)
			}
		}
	}
	if node.Func != nil {
		return nil, fmt.Errorf("Asset %s not found", name)
	}
	rv := make([]string, 0, len(node.Children))
	for childName := range node.Children {
		rv = append(rv, childName)
	}
	return rv, nil
}

type bintree struct {
	Func     func() (*asset, error)
	Children map[string]*bintree
}

var _bintree = &bintree{nil, map[string]*bintree{
	"templates": {nil, map[string]*bintree{
		"eml": {nil, map[string]*bintree{
			"confirm_registration.eml": {templatesEmlConfirm_registrationEml, map[string]*bintree{}},
		}},
	}},
}}

// RestoreAsset restores an asset under the given directory
func RestoreAsset(dir, name string) error {
	data, err := Asset(name)
	if err != nil {
		return err
	}
	info, err := AssetInfo(name)
	if err != nil {
		return err
	}
	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
	if err != nil {
		return err
	}
	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
	if err != nil {
		return err
	}
	return nil
}

// RestoreAssets restores an asset under the given directory recursively
func RestoreAssets(dir, name string) error {
	children, err := AssetDir(name)
	// File
	if err != nil {
		return RestoreAsset(dir, name)
	}
	// Dir
	for _, child := range children {
		err = RestoreAssets(dir, filepath.Join(name, child))
		if err != nil {
			return err
		}
	}
	return nil
}

func _filePath(dir, name string) string {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}
<commit_msg>Update the assets<commit_after>// Code generated by go-bindata.
// sources:
// assets/templates/eml/confirm_registration.eml
// DO NOT EDIT!

package assets

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

func bindataRead(data []byte, name string) ([]byte, error) {
	gz, err := gzip.NewReader(bytes.NewBuffer(data))
	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}

	var buf bytes.Buffer
	_, err = io.Copy(&buf, gz)
	clErr := gz.Close()

	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}
	if clErr != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

type asset struct {
	bytes []byte
	info  os.FileInfo
}

type bindataFileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
}

func (fi bindataFileInfo) Name() string {
	return fi.name
}
func (fi bindataFileInfo) Size() int64 {
	return fi.size
}
func (fi bindataFileInfo) Mode() os.FileMode {
	return fi.mode
}
func (fi bindataFileInfo) ModTime() time.Time {
	return fi.modTime
}
func (fi bindataFileInfo) IsDir() bool {
	return false
}
func (fi bindataFileInfo) Sys() interface{} {
	return nil
}

var _templatesEmlConfirm_registrationEml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\xcd\xb1\x4a\x04\x31\x10\xc6\xf1\xfe\x9e\xe2\xf3\x1e\xe0\xd2\x0b\x62\x61\x69\x63\x61\x2f\xb9\xec\xdc\x66\x48\x2e\x23\x93\x09\x6b\x08\x79\x77\xd1\xdb\x62\xab\x81\x81\xef\xf7\x1f\x03\x2b\x99\xd1\x8f\xe1\xfc\x19\x7d\x49\xe8\xd2\x70\x13\x85\xd2\xca\xd5\x48\xb9\xac\xe8\xa2\x0d\x74\xf7\x9c\xb1\xb1\x45\x5c\x1b\xe7\x85\xb4\x06\x29\x4f\x67\xcc\x79\x3a\x1d\x9d\x8f\x4c\xbe\x12\x42\xe6\x90\x20\x05\x16\x09\x99\x4b\xc2\x95\xb2\x6c\x30\x41\x90\x72\x63\xbd\xff\xb5\x74\x77\xfd\xb2\x28\xd5\xfa\xd0\x80\x68\xf6\x5d\x9f\x9d\x3b\x94\x2e\x2c\xae\x55\x52\xf7\x3f\x70\xbb\xf1\xba\x5f\x6f\x2c\xe5\x2b\x51\x7f\x19\x03\x97\xb7\xc3\xf3\x9d\x3a\xe6\xfc\x0d\x00\x00\xff\xff\x0c\xc7\x10\x45\xe9\x00\x00\x00")

func templatesEmlConfirm_registrationEmlBytes() ([]byte, error) {
	return bindataRead(
		_templatesEmlConfirm_registrationEml,
		"templates/eml/confirm_registration.eml",
	)
}

func templatesEmlConfirm_registrationEml() (*asset, error) {
	bytes, err := templatesEmlConfirm_registrationEmlBytes()
	if err != nil {
		return nil, err
	}

	info := bindataFileInfo{name: "templates/eml/confirm_registration.eml", size: 233, mode: os.FileMode(420), modTime: time.Unix(1472524468, 0)}
	a := &asset{bytes: bytes, info: info}
	return a, nil
}

// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		a, err := f()
		if err != nil {
			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
		}
		return a.bytes, nil
	}
	return nil, fmt.Errorf("Asset %s not found", name)
}

// MustAsset is like Asset but panics when Asset would return an error.
// It simplifies safe initialization of global variables.
func MustAsset(name string) []byte {
	a, err := Asset(name)
	if err != nil {
		panic("asset: Asset(" + name + "): " + err.Error())
	}

	return a
}

// AssetInfo loads and returns the asset info for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func AssetInfo(name string) (os.FileInfo, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		a, err := f()
		if err != nil {
			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
		}
		return a.info, nil
	}
	return nil, fmt.Errorf("AssetInfo %s not found", name)
}

// AssetNames returns the names of the assets.
func AssetNames() []string {
	names := make([]string, 0, len(_bindata))
	for name := range _bindata {
		names = append(names, name)
	}
	return names
}

// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
	"templates/eml/confirm_registration.eml": templatesEmlConfirm_registrationEml,
}

// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
//     data/
//       foo.txt
//       img/
//         a.png
//         b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
	node := _bintree
	if len(name) != 0 {
		cannonicalName := strings.Replace(name, "\\", "/", -1)
		pathList := strings.Split(cannonicalName, "/")
		for _, p := range pathList {
			node = node.Children[p]
			if node == nil {
				return nil, fmt.Errorf("Asset %s not found", name)
			}
		}
	}
	if node.Func != nil {
		return nil, fmt.Errorf("Asset %s not found", name)
	}
	rv := make([]string, 0, len(node.Children))
	for childName := range node.Children {
		rv = append(rv, childName)
	}
	return rv, nil
}

type bintree struct {
	Func     func() (*asset, error)
	Children map[string]*bintree
}

var _bintree = &bintree{nil, map[string]*bintree{
	"templates": {nil, map[string]*bintree{
		"eml": {nil, map[string]*bintree{
			"confirm_registration.eml": {templatesEmlConfirm_registrationEml, map[string]*bintree{}},
		}},
	}},
}}

// RestoreAsset restores an asset under the given directory
func RestoreAsset(dir, name string) error {
	data, err := Asset(name)
	if err != nil {
		return err
	}
	info, err := AssetInfo(name)
	if err != nil {
		return err
	}
	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
	if err != nil {
		return err
	}
	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
	if err != nil {
		return err
	}
	return nil
}

// RestoreAssets restores an asset under the given directory recursively
func RestoreAssets(dir, name string) error {
	children, err := AssetDir(name)
	// File
	if err != nil {
		return RestoreAsset(dir, name)
	}
	// Dir
	for _, child := range children {
		err = RestoreAssets(dir, filepath.Join(name, child))
		if err != nil {
			return err
		}
	}
	return nil
}

func _filePath(dir, name string) string {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/bgmerrell/simulago"
	"github.com/bgmerrell/simulago/pcomm"
)

// simpy example:
/*
import simpy

def example(env):
    for i in range(2):
        event = simpy.events.Timeout(env, delay=1, value=42)
        value = yield event
        print('now=%d, value=%d' % (env.now, value))

env = simpy.Environment()
example_gen = example(env)
_ = simpy.events.Process(env, example_gen)

env.step()
env.step()
env.step()
*/

// Output:
/*
now=1, value=42
now=2, value=42
*/

func example(env *simulago.Environment, pc *pcomm.PCommunicator) {
	for i := 0; i < 2; i++ {
		to := simulago.NewTimeout(env, 10)
		to.Schedule(env)
		pc.Send(to.Event)
	}
}

func main() {
	env := simulago.NewEnvironment()
	pc := simulago.ProcWrapper(env, example)
	p := simulago.NewProcess(env, pc)
	p.Init()
	env.Step()
	env.Step()
	env.Step()
}
<commit_msg>Minor cleanup of timeout example<commit_after>package main

import (
	"github.com/bgmerrell/simulago"
	"github.com/bgmerrell/simulago/pcomm"
)

// simpy example:
/*
import simpy

def example(env):
    for i in range(2):
        event = simpy.events.Timeout(env, delay=1, value=42)
        value = yield event
        print('now=%d, value=%d' % (env.now, value))

env = simpy.Environment()
example_gen = example(env)
_ = simpy.events.Process(env, example_gen)

env.step()
env.step()
env.step()
*/

// Output:
/*
now=1, value=42
now=2, value=42
*/

func example(env *simulago.Environment, pc *pcomm.PCommunicator) {
	for i := 0; i < 2; i++ {
		to := simulago.NewTimeout(env, 10)
		to.Schedule(env)
		pc.Send(to.Event)
	}
}

func main() {
	env := simulago.NewEnvironment()
	p := simulago.NewProcess(env, simulago.ProcWrapper(env, example))
	p.Init()
	env.Step()
	env.Step()
	env.Step()
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/apigateway"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSAPIGatewayRequestValidator_basic(t *testing.T) {
	var conf apigateway.UpdateRequestValidatorOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSAPIGatewayRequestValidatorDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSAPIGatewayRequestValidatorConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAPIGatewayRequestValidatorExists("aws_api_gateway_request_validator.test", &conf),
					testAccCheckAWSAPIGatewayRequestValidatorName(&conf, "tf-acc-test-request-validator"),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "name", "tf-acc-test-request-validator"),
					testAccCheckAWSAPIGatewayRequestValidatorValidateRequestBody(&conf, false),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "validate_request_body", "false"),
					testAccCheckAWSAPIGatewayRequestValidatorValidateRequestParameters(&conf, false),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "validate_request_parameters", "false"),
				),
			},
			resource.TestStep{
				Config: testAccAWSAPIGatewayRequestValidatorUpdatedConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAPIGatewayRequestValidatorExists("aws_api_gateway_request_validator.test", &conf),
					testAccCheckAWSAPIGatewayRequestValidatorName(&conf, "tf-acc-test-request-validator_modified"),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "name", "tf-acc-test-request-validator_modified"),
					testAccCheckAWSAPIGatewayRequestValidatorValidateRequestBody(&conf, true),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "validate_request_body", "true"),
					testAccCheckAWSAPIGatewayRequestValidatorValidateRequestParameters(&conf, true),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "validate_request_parameters", "true"),
				),
			},
		},
	})
}

func testAccCheckAWSAPIGatewayRequestValidatorName(conf *apigateway.UpdateRequestValidatorOutput, expectedName string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if conf.Name == nil {
			return fmt.Errorf("Empty Name, expected: %q", expectedName)
		}
		if *conf.Name != expectedName {
			return fmt.Errorf("Name didn't match. Expected: %q, Given: %q", expectedName, *conf.Name)
		}
		return nil
	}
}

func testAccCheckAWSAPIGatewayRequestValidatorValidateRequestBody(conf *apigateway.UpdateRequestValidatorOutput, expectedValue bool) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if conf.ValidateRequestBody == nil {
			return fmt.Errorf("Empty ValidateRequestBody, expected: %q", expectedValue)
		}
		if *conf.ValidateRequestBody != expectedValue {
			return fmt.Errorf("ValidateRequestBody didn't match. Expected: %q, Given: %q", expectedValue, *conf.ValidateRequestBody)
		}
		return nil
	}
}

func testAccCheckAWSAPIGatewayRequestValidatorValidateRequestParameters(conf *apigateway.UpdateRequestValidatorOutput, expectedValue bool) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if conf.ValidateRequestParameters == nil {
			return fmt.Errorf("Empty ValidateRequestParameters, expected: %q", expectedValue)
		}
		if *conf.ValidateRequestParameters != expectedValue {
			return fmt.Errorf("ValidateRequestParameters didn't match. Expected: %q, Given: %q", expectedValue, *conf.ValidateRequestParameters)
		}
		return nil
	}
}

func testAccCheckAWSAPIGatewayRequestValidatorExists(n string, res *apigateway.UpdateRequestValidatorOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No API Request Validator ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).apigateway

		req := &apigateway.GetRequestValidatorInput{
			RequestValidatorId: aws.String(rs.Primary.ID),
			RestApiId:          aws.String(rs.Primary.Attributes["rest_api_id"]),
		}
		describe, err := conn.GetRequestValidator(req)
		if err != nil {
			return err
		}

		*res = *describe

		return nil
	}
}

func testAccCheckAWSAPIGatewayRequestValidatorDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).apigateway

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_api_gateway_request_validator" {
			continue
		}

		req := &apigateway.GetRequestValidatorInput{
			RequestValidatorId: aws.String(rs.Primary.ID),
			RestApiId:          aws.String(rs.Primary.Attributes["rest_api_id"]),
		}
		_, err := conn.GetRequestValidator(req)

		if err == nil {
			return fmt.Errorf("API Request Validator still exists")
		}

		aws2err, ok := err.(awserr.Error)
		if !ok {
			return err
		}
		if aws2err.Code() != apigateway.ErrCodeNotFoundException {
			return err
		}

		return nil
	}

	return nil
}

const testAccAWSAPIGatewayRequestValidatorConfig_base = `
resource "aws_api_gateway_rest_api" "test" {
  name = "tf-request-validator-test"
}
`

const testAccAWSAPIGatewayRequestValidatorConfig = testAccAWSAPIGatewayRequestValidatorConfig_base + `
resource "aws_api_gateway_request_validator" "test" {
  name = "tf-acc-test-request-validator"
  rest_api_id = "${aws_api_gateway_rest_api.test.id}"
}
`

const testAccAWSAPIGatewayRequestValidatorUpdatedConfig = testAccAWSAPIGatewayRequestValidatorConfig_base + `
resource "aws_api_gateway_request_validator" "test" {
  name = "tf-acc-test-request-validator_modified"
  rest_api_id = "${aws_api_gateway_rest_api.test.id}"
  validate_request_body = true
  validate_request_parameters = true
}
`
<commit_msg>Fix formatting string<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/apigateway"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSAPIGatewayRequestValidator_basic(t *testing.T) {
	var conf apigateway.UpdateRequestValidatorOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSAPIGatewayRequestValidatorDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSAPIGatewayRequestValidatorConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAPIGatewayRequestValidatorExists("aws_api_gateway_request_validator.test", &conf),
					testAccCheckAWSAPIGatewayRequestValidatorName(&conf, "tf-acc-test-request-validator"),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "name", "tf-acc-test-request-validator"),
					testAccCheckAWSAPIGatewayRequestValidatorValidateRequestBody(&conf, false),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "validate_request_body", "false"),
					testAccCheckAWSAPIGatewayRequestValidatorValidateRequestParameters(&conf, false),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "validate_request_parameters", "false"),
				),
			},
			resource.TestStep{
				Config: testAccAWSAPIGatewayRequestValidatorUpdatedConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAPIGatewayRequestValidatorExists("aws_api_gateway_request_validator.test", &conf),
					testAccCheckAWSAPIGatewayRequestValidatorName(&conf, "tf-acc-test-request-validator_modified"),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "name", "tf-acc-test-request-validator_modified"),
					testAccCheckAWSAPIGatewayRequestValidatorValidateRequestBody(&conf, true),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "validate_request_body", "true"),
					testAccCheckAWSAPIGatewayRequestValidatorValidateRequestParameters(&conf, true),
					resource.TestCheckResourceAttr("aws_api_gateway_request_validator.test", "validate_request_parameters", "true"),
				),
			},
		},
	})
}

func testAccCheckAWSAPIGatewayRequestValidatorName(conf *apigateway.UpdateRequestValidatorOutput, expectedName string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if conf.Name == nil {
			return fmt.Errorf("Empty Name, expected: %q", expectedName)
		}
		if *conf.Name != expectedName {
			return fmt.Errorf("Name didn't match. Expected: %q, Given: %q", expectedName, *conf.Name)
		}
		return nil
	}
}

func testAccCheckAWSAPIGatewayRequestValidatorValidateRequestBody(conf *apigateway.UpdateRequestValidatorOutput, expectedValue bool) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if conf.ValidateRequestBody == nil {
			return fmt.Errorf("Empty ValidateRequestBody, expected: %t", expectedValue)
		}
		if *conf.ValidateRequestBody != expectedValue {
			return fmt.Errorf("ValidateRequestBody didn't match. Expected: %t, Given: %t", expectedValue, *conf.ValidateRequestBody)
		}
		return nil
	}
}

func testAccCheckAWSAPIGatewayRequestValidatorValidateRequestParameters(conf *apigateway.UpdateRequestValidatorOutput, expectedValue bool) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if conf.ValidateRequestParameters == nil {
			return fmt.Errorf("Empty ValidateRequestParameters, expected: %t", expectedValue)
		}
		if *conf.ValidateRequestParameters != expectedValue {
			return fmt.Errorf("ValidateRequestParameters didn't match. Expected: %t, Given: %t", expectedValue, *conf.ValidateRequestParameters)
		}
		return nil
	}
}

func testAccCheckAWSAPIGatewayRequestValidatorExists(n string, res *apigateway.UpdateRequestValidatorOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No API Request Validator ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).apigateway

		req := &apigateway.GetRequestValidatorInput{
			RequestValidatorId: aws.String(rs.Primary.ID),
			RestApiId:          aws.String(rs.Primary.Attributes["rest_api_id"]),
		}
		describe, err := conn.GetRequestValidator(req)
		if err != nil {
			return err
		}

		*res = *describe

		return nil
	}
}

func testAccCheckAWSAPIGatewayRequestValidatorDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).apigateway

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_api_gateway_request_validator" {
			continue
		}

		req := &apigateway.GetRequestValidatorInput{
			RequestValidatorId: aws.String(rs.Primary.ID),
			RestApiId:          aws.String(rs.Primary.Attributes["rest_api_id"]),
		}
		_, err := conn.GetRequestValidator(req)

		if err == nil {
			return fmt.Errorf("API Request Validator still exists")
		}

		aws2err, ok := err.(awserr.Error)
		if !ok {
			return err
		}
		if aws2err.Code() != apigateway.ErrCodeNotFoundException {
			return err
		}

		return nil
	}

	return nil
}

const testAccAWSAPIGatewayRequestValidatorConfig_base = `
resource "aws_api_gateway_rest_api" "test" {
  name = "tf-request-validator-test"
}
`

const testAccAWSAPIGatewayRequestValidatorConfig = testAccAWSAPIGatewayRequestValidatorConfig_base + `
resource "aws_api_gateway_request_validator" "test" {
  name = "tf-acc-test-request-validator"
  rest_api_id = "${aws_api_gateway_rest_api.test.id}"
}
`

const testAccAWSAPIGatewayRequestValidatorUpdatedConfig = testAccAWSAPIGatewayRequestValidatorConfig_base + `
resource "aws_api_gateway_request_validator" "test" {
  name = "tf-acc-test-request-validator_modified"
  rest_api_id = "${aws_api_gateway_rest_api.test.id}"
  validate_request_body = true
  validate_request_parameters = true
}
`
<|endoftext|>


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

/*
	Package model defines the basic
	data structures of the docs engine.
*/
package model

import (
	"andyk/docs/filesystem"
	"bufio"
	"crypto/sha1"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
)

type Document struct {
	Title       string
	Description string
}

type RepositoryItem struct {
	Path       string
	Files      []RepositoryItemFile
	ChildItems []RepositoryItem
	Type       string
}

// Create a new repository item
func NewRepositoryItem(itemType string, path string, files []RepositoryItemFile, childItems []RepositoryItem) RepositoryItem {
	return RepositoryItem{
		Path:       path,
		Files:      files,
		ChildItems: childItems,
		Type:       itemType,
	}
}

// Render this repository item
func (item *RepositoryItem) Render() {

	// render child items
	for _, child := range item.ChildItems {
		child.Render()
	}

	// the path of the rendered repostory item
	renderedItemPath := item.GetRenderedItemPath()

	// check if rendering is required
	itemHashCode := item.GetHash()
	renderedItemHashCode := item.GetRenderedItemHash()

	// Abort if the hash has not changed
	if itemHashCode == renderedItemHashCode {
		return
	}

	doc := item.getParsedDocument()

	content := "<!-- " + item.GetHash() + " -->"
	content += "\nTitle: " + doc.Title
	content += "\nDescription: " + doc.Description

	_ = ioutil.WriteFile(renderedItemPath, []byte(content), 0644)
}

func (item *RepositoryItem) getParsedDocument() Document {
	title, _ := item.getTitle()
	description, _ := item.getDescription()

	return Document{
		Title:       title,
		Description: description,
	}
}

func (item *RepositoryItem) getTitle() (string, int) {
	lines := item.getLines()
	titleRegexp := regexp.MustCompile("\\s*#\\s*(.+)")

	for lineNumber, line := range lines {
		matches := titleRegexp.FindStringSubmatch(line)

		if len(matches) == 2 {
			return matches[1], lineNumber
		}
	}

	return "No Title", 0
}

func (item *RepositoryItem) getDescription() (string, int) {
	lines := item.getLines()

	descriptionRegexp := regexp.MustCompile("^\\w.+")

	// locate the title
	_, titleLineNumber := item.getTitle()

	for lineNumber, line := range lines {
		if lineNumber <= titleLineNumber {
			continue
		}

		matches := descriptionRegexp.FindStringSubmatch(line)
		if len(matches) == 1 {
			return matches[0], lineNumber
		}
	}

	return "No Description", 0
}

// Get all lines of a repository item
func (item *RepositoryItem) getLines() []string {
	lines, err := filesystem.GetLines(item.Path)
	if err != nil {
		return make([]string, 0)
	}

	return lines
}

// Get the hash code of the rendered item
func (item *RepositoryItem) GetRenderedItemHash() string {
	renderedItemPath := item.GetRenderedItemPath()

	file, err := os.Open(renderedItemPath)
	if err != nil {
		// file does not exist or cannot be accessed
		return ""
	}

	fileReader := bufio.NewReader(file)
	firstLineBytes, _ := fileReader.ReadBytes('\n')
	if firstLineBytes == nil {
		// first line cannot be read
		return ""
	}

	// extract hash from line
	hashCodeRegexp := regexp.MustCompile("<!-- (\\w+) -->")
	matches := hashCodeRegexp.FindStringSubmatch(string(firstLineBytes))
	if len(matches) != 2 {
		return ""
	}

	extractedHashcode := matches[1]

	return string(extractedHashcode)
}

// Get the filepath of the rendered repository item
func (item *RepositoryItem) GetRenderedItemPath() string {
	itemDirectory := filepath.Dir(item.Path)
	renderedFilePath := filepath.Join(itemDirectory, item.Type+".html")
	return renderedFilePath
}

func (item *RepositoryItem) GetHash() string {
	itemBytes, readFileErr := ioutil.ReadFile(item.Path)
	if readFileErr != nil {
		return ""
	}

	sha1 := sha1.New()
	sha1.Write(itemBytes)

	return fmt.Sprintf("%x", string(sha1.Sum(nil)[0:6]))
}

// Get a string representation of the current repository item
func (item *RepositoryItem) String() string {
	s := item.Path + "(Type: " + item.Type + ", Hash: " + item.GetHash() + ")\n"

	s += "\n"
	s += "Files:\n"
	if len(item.Files) > 0 {
		for _, file := range item.Files {
			s += " - " + file.Path + "\n"
		}
	} else {
		s += "<none>\n"
	}

	s += "\n"
	s += "ChildItems:\n"
	if len(item.ChildItems) > 0 {
		for _, child := range item.ChildItems {
			s += child.String()
		}
	} else {
		s += "<none>\n"
	}
	s += "\n"

	return s
}
<commit_msg>Reuse the line numbers of the different document elements<commit_after>// Copyright 2013 Andreas Koch. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
	Package model defines the basic
	data structures of the docs engine.
*/
package model

import (
	"andyk/docs/filesystem"
	"bufio"
	"crypto/sha1"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
)

type Document struct {
	Title       string
	Description string
}

type RepositoryItem struct {
	Path       string
	Files      []RepositoryItemFile
	ChildItems []RepositoryItem
	Type       string
}

// Create a new repository item
func NewRepositoryItem(itemType string, path string, files []RepositoryItemFile, childItems []RepositoryItem) RepositoryItem {
	return RepositoryItem{
		Path:       path,
		Files:      files,
		ChildItems: childItems,
		Type:       itemType,
	}
}

// Render this repository item
func (item *RepositoryItem) Render() {

	// render child items
	for _, child := range item.ChildItems {
		child.Render()
	}

	// the path of the rendered repostory item
	renderedItemPath := item.GetRenderedItemPath()

	// check if rendering is required
	itemHashCode := item.GetHash()
	renderedItemHashCode := item.GetRenderedItemHash()

	// Abort if the hash has not changed
	if itemHashCode == renderedItemHashCode {
		return
	}

	doc := item.getParsedDocument()

	content := "<!-- " + item.GetHash() + " -->"
	content += "\nTitle: " + doc.Title
	content += "\nDescription: " + doc.Description

	_ = ioutil.WriteFile(renderedItemPath, []byte(content), 0644)
}

func (item *RepositoryItem) getParsedDocument() Document {
	title, titleLineNumber := item.getTitle()
	description, _ := item.getDescription(titleLineNumber)

	return Document{
		Title:       title,
		Description: description,
	}
}

func (item *RepositoryItem) getTitle() (string, int) {
	lines := item.getLines()
	titleRegexp := regexp.MustCompile("\\s*#\\s*(.+)")

	for lineNumber, line := range lines {
		matches := titleRegexp.FindStringSubmatch(line)

		if len(matches) == 2 {
			return matches[1], lineNumber
		}
	}

	return "No Title", 0
}

func (item *RepositoryItem) getDescription(titleLineNumber int) (string, int) {
	lines := item.getLines()

	descriptionRegexp := regexp.MustCompile("^\\w.+")

	for lineNumber, line := range lines {
		if lineNumber <= titleLineNumber {
			continue
		}

		matches := descriptionRegexp.FindStringSubmatch(line)
		if len(matches) == 1 {
			return matches[0], lineNumber
		}
	}

	return "No Description", 0
}

// Get all lines of a repository item
func (item *RepositoryItem) getLines() []string {
	lines, err := filesystem.GetLines(item.Path)
	if err != nil {
		return make([]string, 0)
	}

	return lines
}

// Get the hash code of the rendered item
func (item *RepositoryItem) GetRenderedItemHash() string {
	renderedItemPath := item.GetRenderedItemPath()

	file, err := os.Open(renderedItemPath)
	if err != nil {
		// file does not exist or cannot be accessed
		return ""
	}

	fileReader := bufio.NewReader(file)
	firstLineBytes, _ := fileReader.ReadBytes('\n')
	if firstLineBytes == nil {
		// first line cannot be read
		return ""
	}

	// extract hash from line
	hashCodeRegexp := regexp.MustCompile("<!-- (\\w+) -->")
	matches := hashCodeRegexp.FindStringSubmatch(string(firstLineBytes))
	if len(matches) != 2 {
		return ""
	}

	extractedHashcode := matches[1]

	return string(extractedHashcode)
}

// Get the filepath of the rendered repository item
func (item *RepositoryItem) GetRenderedItemPath() string {
	itemDirectory := filepath.Dir(item.Path)
	renderedFilePath := filepath.Join(itemDirectory, item.Type+".html")
	return renderedFilePath
}

func (item *RepositoryItem) GetHash() string {
	itemBytes, readFileErr := ioutil.ReadFile(item.Path)
	if readFileErr != nil {
		return ""
	}

	sha1 := sha1.New()
	sha1.Write(itemBytes)

	return fmt.Sprintf("%x", string(sha1.Sum(nil)[0:6]))
}

// Get a string representation of the current repository item
func (item *RepositoryItem) String() string {
	s := item.Path + "(Type: " + item.Type + ", Hash: " + item.GetHash() + ")\n"

	s += "\n"
	s += "Files:\n"
	if len(item.Files) > 0 {
		for _, file := range item.Files {
			s += " - " + file.Path + "\n"
		}
	} else {
		s += "<none>\n"
	}

	s += "\n"
	s += "ChildItems:\n"
	if len(item.ChildItems) > 0 {
		for _, child := range item.ChildItems {
			s += child.String()
		}
	} else {
		s += "<none>\n"
	}
	s += "\n"

	return s
}
<|endoftext|>


<commit_before>package markdown

type Markdown struct {
}

func (m *Markdown) parse(text string) string {
	result := text
	return result
}
<commit_msg>Replace struct with functions.<commit_after>package markdown

import (
	"fmt"
	"regexp"
	"strings"
)

func parse(text string) string {

	// removes UTF-8 BOM and marker characters
	re := regexp.MustCompile("^\xEF\xBB\xBF|\x1A")
	text = re.ReplaceAllString(text, "")

	escape_sequences := []string{"\\\\", "\\`", "\\*", "\\_", "\\{", "\\}", "\\[", "\\]", "\\(", "\\)", "\\>", "\\#", "\\+", "\\-", "\\.", "\\!"}
	escape_sequence_map := map[string]string{}

	// removes \r characters
	text = strings.Replace(text, "\r\n", "\n", -1)
	text = strings.Replace(text, "\r", "\n", -1)

	// replaces tabs with spaces
	text = strings.Replace(text, "\t", "    ", -1)

	// encodes escape sequences

	if strings.Index(text, "\\") >= 0 {
		for i, v := range escape_sequences {
			if strings.Index(text, v) >= 0 {
				code := strings.Join([]string{"\x1A", "\\", string(i), ";"}, "")
				text = strings.Replace(text, v, code, -1)
				escape_sequence_map[code] = v
			}
		}
	}

	// ~
	re = regexp.MustCompile("\\n\\s*\\n")
	text = re.ReplaceAllString(text, "\n\n")
	text = strings.TrimPrefix(text, "\n")
	text = strings.TrimSuffix(text, "\n")
	lines := strings.Split(text, "\n")
	text = _ParseBlockElements(lines)

	// decodes escape sequences
	for code, escape_sequence := range escape_sequences {
		text = strings.Replace(text, string(code), string(escape_sequence[1]), -1)
	}

	// ~
	text = strings.TrimSuffix(text, "\n")

	fmt.Println(text)

	return text
}

func _ParseBlockElements(lines []string) string {
	return strings.Join(lines, "\n")
}
<|endoftext|>


<commit_before>package main

import (
	"common"
	"github.com/surma/gocpio"
	"io"
	"log"
	"os"
	"strconv"
	"strings"
)

func parseInput(in io.ReadCloser, c chan<- *Entry) {
	buf := common.NewBufferedReader(in)
	for {
		line, e := buf.ReadWholeLine()
		if e != nil && e != io.EOF {
			log.Printf("Warning: Could not read whole file: %s", e.Error())
		}
		stripped_line := strings.TrimSpace(line)
		if len(stripped_line) == 0 || stripped_line[0] == '#' {
			if e != io.EOF {
				continue
			} else {
				break
			}
		}
		ent := parseLine(line)
		if ent != nil {
			c <- ent
		}

		if e == io.EOF {
			break
		}
	}
	close(c)
}

func parseLine(line string) *Entry {
	lineparts := strings.Split(line, " ")
	if len(lineparts) < 1 {
		return nil
	}

	switch lineparts[0] {
	case "file":
		return parseFile(lineparts[1:])
	case "dir":
		return parseDir(lineparts[1:])
	case "nod":
		return parseNod(lineparts[1:])
	case "slink":
		return parseSlink(lineparts[1:])
	case "pipe":
		return parsePipe(lineparts[1:])
	case "sock":
		return parseSock(lineparts[1:])
	default:
		log.Printf("Warning: %s is in invalid type\n", lineparts[0])
	}
	return nil
}

func parseFile(parts []string) *Entry {
	if len(parts) != 5 {
		return nil
	}
	name := parts[0]
	localname := parts[1]
	mode, uid, gid, e := parseModeUidGid(parts[2], parts[3], parts[4])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	f, e := os.Open(localname)
	if e != nil {
		log.Printf("Could not open file %s: %s\n", localname, e.Error())
		return nil
	}
	finfo, e := f.Stat()
	if e != nil {
		log.Printf("Could not obtain file size of %s: %s\n")
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode: mode,
			Uid:  uid,
			Gid:  gid,
			Size: finfo.Size,
			Type: cpio.TYPE_REG,
			Name: name,
		},
		data: f,
	}
}

func parseDir(parts []string) *Entry {
	if len(parts) != 4 {
		return nil
	}
	name := parts[0]
	mode, uid, gid, e := parseModeUidGid(parts[1], parts[2], parts[3])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode: mode,
			Uid:  uid,
			Gid:  gid,
			Type: cpio.TYPE_DIR,
			Name: name,
		},
	}
}

func parseNod(parts []string) *Entry {
	if len(parts) != 7 {
		return nil
	}
	name := parts[0]
	mode, uid, gid, e := parseModeUidGid(parts[1], parts[2], parts[3])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	var dev_type int64
	switch parts[4] {
	case "b":
		dev_type = cpio.TYPE_BLK
	case "c":
		dev_type = cpio.TYPE_CHAR
	default:
		log.Printf("Invalid device type: %s\n", parts[4])
		return nil
	}

	maj, e := strconv.Atoi64(parts[5])
	if e != nil {
		log.Printf("Invalid major device: %s\n", e.Error())
		return nil
	}
	min, e := strconv.Atoi64(parts[6])
	if e != nil {
		log.Printf("Invalid major device: %s\n", e.Error())
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode:     mode,
			Uid:      uid,
			Gid:      gid,
			Type:     dev_type,
			Devmajor: maj,
			Devminor: min,
			Name:     name,
		},
	}

}

func parseSlink(parts []string) *Entry {
	if len(parts) != 5 {
		return nil
	}

	name := parts[0]
	target := parts[1]

	mode, uid, gid, e := parseModeUidGid(parts[2], parts[3], parts[4])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode: mode,
			Uid:  uid,
			Gid:  gid,
			Type: cpio.TYPE_SYMLINK,
			Size: int64(len(target) + 1),
			Name: name,
		},
		data: strings.NewReader(target),
	}

}

func parsePipe(parts []string) *Entry {
	if len(parts) != 4 {
		return nil
	}
	name := parts[0]
	mode, uid, gid, e := parseModeUidGid(parts[1], parts[2], parts[3])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode: mode,
			Uid:  uid,
			Gid:  gid,
			Type: cpio.TYPE_FIFO,
			Name: name,
		},
	}
}

func parseSock(parts []string) *Entry {
	if len(parts) != 4 {
		return nil
	}
	name := parts[0]
	mode, uid, gid, e := parseModeUidGid(parts[1], parts[2], parts[3])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode: mode,
			Uid:  uid,
			Gid:  gid,
			Type: cpio.TYPE_SOCK,
			Name: name,
		},
	}
}

func parseModeUidGid(s_mode, s_uid, s_gid string) (mode int64, uid, gid int, err error) {
	mode, err = strconv.Btoi64(s_mode, 0)
	if err != nil {
		return
	}
	uid, err = strconv.Atoi(s_uid)
	if err != nil {
		return
	}
	gid, err = strconv.Atoi(s_gid)
	return mode, uid, gid, nil
}
<commit_msg>Geninitramfs: Update for weekly<commit_after>package main

import (
	"common"
	"github.com/surma/gocpio"
	"io"
	"log"
	"os"
	"strconv"
	"strings"
)

func parseInput(in io.ReadCloser, c chan<- *Entry) {
	buf := common.NewBufferedReader(in)
	for {
		line, e := buf.ReadWholeLine()
		if e != nil && e != io.EOF {
			log.Printf("Warning: Could not read whole file: %s", e.Error())
		}
		stripped_line := strings.TrimSpace(line)
		if len(stripped_line) == 0 || stripped_line[0] == '#' {
			if e != io.EOF {
				continue
			} else {
				break
			}
		}
		ent := parseLine(line)
		if ent != nil {
			c <- ent
		}

		if e == io.EOF {
			break
		}
	}
	close(c)
}

func parseLine(line string) *Entry {
	lineparts := strings.Split(line, " ")
	if len(lineparts) < 1 {
		return nil
	}

	switch lineparts[0] {
	case "file":
		return parseFile(lineparts[1:])
	case "dir":
		return parseDir(lineparts[1:])
	case "nod":
		return parseNod(lineparts[1:])
	case "slink":
		return parseSlink(lineparts[1:])
	case "pipe":
		return parsePipe(lineparts[1:])
	case "sock":
		return parseSock(lineparts[1:])
	default:
		log.Printf("Warning: %s is in invalid type\n", lineparts[0])
	}
	return nil
}

func parseFile(parts []string) *Entry {
	if len(parts) != 5 {
		return nil
	}
	name := parts[0]
	localname := parts[1]
	mode, uid, gid, e := parseModeUidGid(parts[2], parts[3], parts[4])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	f, e := os.Open(localname)
	if e != nil {
		log.Printf("Could not open file %s: %s\n", localname, e.Error())
		return nil
	}
	finfo, e := f.Stat()
	if e != nil {
		log.Printf("Could not obtain file size of %s: %s\n")
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode: mode,
			Uid:  uid,
			Gid:  gid,
			Size: finfo.Size(),
			Type: cpio.TYPE_REG,
			Name: name,
		},
		data: f,
	}
}

func parseDir(parts []string) *Entry {
	if len(parts) != 4 {
		return nil
	}
	name := parts[0]
	mode, uid, gid, e := parseModeUidGid(parts[1], parts[2], parts[3])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode: mode,
			Uid:  uid,
			Gid:  gid,
			Type: cpio.TYPE_DIR,
			Name: name,
		},
	}
}

func parseNod(parts []string) *Entry {
	if len(parts) != 7 {
		return nil
	}
	name := parts[0]
	mode, uid, gid, e := parseModeUidGid(parts[1], parts[2], parts[3])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	var dev_type int64
	switch parts[4] {
	case "b":
		dev_type = cpio.TYPE_BLK
	case "c":
		dev_type = cpio.TYPE_CHAR
	default:
		log.Printf("Invalid device type: %s\n", parts[4])
		return nil
	}

	maj, e := strconv.Atoi64(parts[5])
	if e != nil {
		log.Printf("Invalid major device: %s\n", e.Error())
		return nil
	}
	min, e := strconv.Atoi64(parts[6])
	if e != nil {
		log.Printf("Invalid major device: %s\n", e.Error())
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode:     mode,
			Uid:      uid,
			Gid:      gid,
			Type:     dev_type,
			Devmajor: maj,
			Devminor: min,
			Name:     name,
		},
	}

}

func parseSlink(parts []string) *Entry {
	if len(parts) != 5 {
		return nil
	}

	name := parts[0]
	target := parts[1]

	mode, uid, gid, e := parseModeUidGid(parts[2], parts[3], parts[4])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode: mode,
			Uid:  uid,
			Gid:  gid,
			Type: cpio.TYPE_SYMLINK,
			Size: int64(len(target) + 1),
			Name: name,
		},
		data: strings.NewReader(target),
	}

}

func parsePipe(parts []string) *Entry {
	if len(parts) != 4 {
		return nil
	}
	name := parts[0]
	mode, uid, gid, e := parseModeUidGid(parts[1], parts[2], parts[3])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode: mode,
			Uid:  uid,
			Gid:  gid,
			Type: cpio.TYPE_FIFO,
			Name: name,
		},
	}
}

func parseSock(parts []string) *Entry {
	if len(parts) != 4 {
		return nil
	}
	name := parts[0]
	mode, uid, gid, e := parseModeUidGid(parts[1], parts[2], parts[3])
	if e != nil {
		log.Printf("Invalid permission settings: %s\n", e.Error())
		return nil
	}

	return &Entry{
		hdr: cpio.Header{
			Mode: mode,
			Uid:  uid,
			Gid:  gid,
			Type: cpio.TYPE_SOCK,
			Name: name,
		},
	}
}

func parseModeUidGid(s_mode, s_uid, s_gid string) (mode int64, uid, gid int, err error) {
	mode, err = strconv.Btoi64(s_mode, 0)
	if err != nil {
		return
	}
	uid, err = strconv.Atoi(s_uid)
	if err != nil {
		return
	}
	gid, err = strconv.Atoi(s_gid)
	return mode, uid, gid, nil
}
<|endoftext|>


<commit_before>package main

import (
	"archive/zip"
	"fmt"
	"github.com/zxh0/jvm.go/jvmgo/classfile"
	"io/ioutil"
	"os"
	"strings"
)

func main() {
	if len(os.Args) > 1 {
		jarFileName := os.Args[1]
		handleJar(jarFileName)
	}
}

func handleJar(jarFileName string) {
	//fmt.Printf("jar: %v\n", jarFileName)

	// open jar
	r, err := zip.OpenReader(jarFileName) // func OpenReader(name string) (*ReadCloser, error)
	if err != nil {
		panic(err.Error())
	}
	defer r.Close()

	// find classes
	for _, f := range r.File {
		if strings.HasSuffix(f.Name, ".class") {
			if !skip(f.Name) {
				handleClass(f)
			}
		}
	}
}

func skip(className string) bool {
	return strings.HasPrefix(className, "apple") ||
		strings.HasPrefix(className, "com/apple") ||
		strings.HasPrefix(className, "com/sun/java/swing") ||
		strings.HasPrefix(className, "com/sun/media/sound") ||
		strings.HasPrefix(className, "sun/awt") ||
		strings.HasPrefix(className, "sun/font") ||
		strings.HasPrefix(className, "sun/java2d") ||
		strings.HasPrefix(className, "sun/lwawt/macosx") ||
		strings.HasPrefix(className, "java/awt")
}

func handleClass(f *zip.File) {
	//fmt.Printf("%v\n", f.Name)

	// open classfile
	rc, err := f.Open() // func (f *File) Open() (rc io.ReadCloser, err error)
	if err != nil {
		panic(err.Error())
	}

	// read class data
	data, err := ioutil.ReadAll(rc) // func ReadAll(r io.Reader) ([]byte, error)
	rc.Close()
	if err != nil {
		panic(err.Error())
	}

	// parse classfile
	cf, err := classfile.ParseClassFile(data)
	if err != nil {
		panic(err.Error())
	}

	handleClassfile(cf)
}

func handleClassfile(cf *classfile.ClassFile) {
	for _, m := range cf.Methods() {
		if isNative(m) {
			if isStatic(m) {
				fmt.Printf("%v.%v%v\n", cf.ClassName(), m.Name(), m.Descriptor())
			} else {
				fmt.Printf("%v#%v%v\n", cf.ClassName(), m.Name(), m.Descriptor())
			}
		}
	}
}

func isNative(m *classfile.MethodInfo) bool {
	return m.AccessFlags()&0x0100 != 0
}
func isStatic(m *classfile.MethodInfo) bool {
	return m.AccessFlags()&0x0008 != 0
}
<commit_msg>do not skip awt<commit_after>package main

import (
	"archive/zip"
	"fmt"
	"github.com/zxh0/jvm.go/jvmgo/classfile"
	"io/ioutil"
	"os"
	"strings"
)

func main() {
	if len(os.Args) > 1 {
		jarFileName := os.Args[1]
		handleJar(jarFileName)
	}
}

func handleJar(jarFileName string) {
	//fmt.Printf("jar: %v\n", jarFileName)

	// open jar
	r, err := zip.OpenReader(jarFileName) // func OpenReader(name string) (*ReadCloser, error)
	if err != nil {
		panic(err.Error())
	}
	defer r.Close()

	// find classes
	for _, f := range r.File {
		if strings.HasSuffix(f.Name, ".class") {
			if !skip(f.Name) {
				handleClass(f)
			}
		}
	}
}

func skip(className string) bool {
	return strings.HasPrefix(className, "apple") ||
		strings.HasPrefix(className, "com/apple") ||
		strings.HasPrefix(className, "com/sun/java/swing") ||
		strings.HasPrefix(className, "com/sun/media/sound") ||
		strings.HasPrefix(className, "sun/awt") ||
		strings.HasPrefix(className, "sun/font") ||
		strings.HasPrefix(className, "sun/java2d") ||
		strings.HasPrefix(className, "sun/lwawt/macosx")
}

func handleClass(f *zip.File) {
	//fmt.Printf("%v\n", f.Name)

	// open classfile
	rc, err := f.Open() // func (f *File) Open() (rc io.ReadCloser, err error)
	if err != nil {
		panic(err.Error())
	}

	// read class data
	data, err := ioutil.ReadAll(rc) // func ReadAll(r io.Reader) ([]byte, error)
	rc.Close()
	if err != nil {
		panic(err.Error())
	}

	// parse classfile
	cf, err := classfile.ParseClassFile(data)
	if err != nil {
		panic(err.Error())
	}

	handleClassfile(cf)
}

func handleClassfile(cf *classfile.ClassFile) {
	for _, m := range cf.Methods() {
		if isNative(m) {
			if isStatic(m) {
				fmt.Printf("%v.%v%v\n", cf.ClassName(), m.Name(), m.Descriptor())
			} else {
				fmt.Printf("%v#%v%v\n", cf.ClassName(), m.Name(), m.Descriptor())
			}
		}
	}
}

func isNative(m *classfile.MethodInfo) bool {
	return m.AccessFlags()&0x0100 != 0
}
func isStatic(m *classfile.MethodInfo) bool {
	return m.AccessFlags()&0x0008 != 0
}
<|endoftext|>


<commit_before>package unit

import (
	"fmt"
	"log"
	"os/exec"
)

type Unit struct {
	Type string
	Name string
}

func (u *Unit) Create() error {
	cmd := exec.Command("juju", "deploy", "--repository=/home/charms", "local:oneiric/"+u.Type, u.Name)
	log.Printf("deploying %s with name %s", u.Type, u.Name)
	return cmd.Start()
}

func (u *Unit) Destroy() error {
	cmd := exec.Command("juju", "destroy-service", u.Name)
	log.Printf("destroying %s with name %s", u.Type, u.Name)
	return cmd.Start()
}

func (u *Unit) AddRelation(su *Unit) error {
	cmd := exec.Command("juju", "add-relation", u.Name, su.Name)
	log.Printf("relating %s with service %s", u.Name, su.Name)
	return cmd.Start()
}

func (u *Unit) RemoveRelation(su *Unit) error {
	cmd := exec.Command("juju", "remove-relation", u.Name, su.Name)
	log.Printf("unrelating %s with service %s", u.Name, su.Name)
	return cmd.Start()
}

func (u *Unit) Command(command string) ([]byte, error) {
	cmd := exec.Command("juju", "ssh", "-o", "StrictHostKeyChecking no", u.Name+"/0", command)
	log.Printf("executing %s on %s", command, u.Name)
	return cmd.CombinedOutput()
}

func (u *Unit) SendFile(srcPath, dstPath string) error {
	cmd := exec.Command("juju", "scp", "-r", "-o", "StrictHostKeyChecking no", srcPath, u.Name+"/0:"+dstPath)
	log.Printf("sending %s to %s on %s", srcPath, dstPath, u.Name)
	return cmd.Start()
}

func (u *Unit) ExecuteHook(hook string) error {
	cmd := fmt.Sprintf("/var/lib/tsuru/hooks/%d", hook)
	output, err := u.Command(cmd)
	log.Printf(string(output))
	return err
}
<commit_msg>fixed a typo in a string format<commit_after>package unit

import (
	"fmt"
	"log"
	"os/exec"
)

type Unit struct {
	Type string
	Name string
}

func (u *Unit) Create() error {
	cmd := exec.Command("juju", "deploy", "--repository=/home/charms", "local:oneiric/"+u.Type, u.Name)
	log.Printf("deploying %s with name %s", u.Type, u.Name)
	return cmd.Start()
}

func (u *Unit) Destroy() error {
	cmd := exec.Command("juju", "destroy-service", u.Name)
	log.Printf("destroying %s with name %s", u.Type, u.Name)
	return cmd.Start()
}

func (u *Unit) AddRelation(su *Unit) error {
	cmd := exec.Command("juju", "add-relation", u.Name, su.Name)
	log.Printf("relating %s with service %s", u.Name, su.Name)
	return cmd.Start()
}

func (u *Unit) RemoveRelation(su *Unit) error {
	cmd := exec.Command("juju", "remove-relation", u.Name, su.Name)
	log.Printf("unrelating %s with service %s", u.Name, su.Name)
	return cmd.Start()
}

func (u *Unit) Command(command string) ([]byte, error) {
	cmd := exec.Command("juju", "ssh", "-o", "StrictHostKeyChecking no", u.Name+"/0", command)
	log.Printf("executing %s on %s", command, u.Name)
	return cmd.CombinedOutput()
}

func (u *Unit) SendFile(srcPath, dstPath string) error {
	cmd := exec.Command("juju", "scp", "-r", "-o", "StrictHostKeyChecking no", srcPath, u.Name+"/0:"+dstPath)
	log.Printf("sending %s to %s on %s", srcPath, dstPath, u.Name)
	return cmd.Start()
}

func (u *Unit) ExecuteHook(hook string) error {
	cmd := fmt.Sprintf("/var/lib/tsuru/hooks/%s", hook)
	output, err := u.Command(cmd)
	log.Printf(string(output))
	return err
}
<|endoftext|>


<commit_before>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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 obcpbft

import (
	"encoding/base64"
	"fmt"
	"strconv"
	"sync"

	"github.com/openblockchain/obc-peer/openchain/consensus"
	"github.com/openblockchain/obc-peer/openchain/ledger/statemgmt"
	"github.com/openblockchain/obc-peer/openchain/util"
	pb "github.com/openblockchain/obc-peer/protos"
)

type mockStack struct {
	broadcasted [][]byte
	*instance
}

func newMock() *mockStack {
	mock := &mockStack{
		make([][]byte, 0),
		&instance{},
	}
	mock.instance.ledger = NewMockLedger(nil, nil)
	mock.instance.ledger.PutBlock(0, SimpleGetBlock(0))
	return mock
}

func (mock *mockStack) sign(msg []byte) ([]byte, error) {
	return msg, nil
}

func (mock *mockStack) verify(senderID uint64, signature []byte, message []byte) error {
	return nil
}

func (mock *mockStack) broadcast(msg []byte) {
	mock.broadcasted = append(mock.broadcasted, msg)
}

func (mock *mockStack) unicast(msg []byte, receiverID uint64) (err error) {
	panic("not implemented")
}

// =============================================================================
// Fake network structures
// =============================================================================

type closableConsenter interface {
	consensus.Consenter
	Close()
	Drain()
}

type taggedMsg struct {
	src int
	dst int
	msg []byte
}

type testnet struct {
	N        int
	f        int
	cond     *sync.Cond
	closed   bool
	replicas []*instance
	msgs     []taggedMsg
	handles  []*pb.PeerID
	filterFn func(int, int, []byte) []byte
}

type instance struct {
	id        int
	handle    *pb.PeerID
	pbft      *pbftCore
	consenter closableConsenter
	net       *testnet
	ledger    consensus.LedgerStack

	deliver      func([]byte)
	execTxResult func([]*pb.Transaction) ([]byte, error)
}

func (inst *instance) Sign(msg []byte) ([]byte, error) {
	return msg, nil
}
func (inst *instance) Verify(peerID *pb.PeerID, signature []byte, message []byte) error {
	return nil
}

func (inst *instance) sign(msg []byte) ([]byte, error) {
	return msg, nil
}

func (inst *instance) verify(replicaID uint64, signature []byte, message []byte) error {
	return nil
}

func (inst *instance) broadcast(payload []byte) {
	net := inst.net
	net.cond.L.Lock()
	net.broadcastFilter(inst, payload)
	net.cond.Signal()
	net.cond.L.Unlock()
}

func (inst *instance) unicast(payload []byte, receiverID uint64) error {
	net := inst.net
	net.cond.L.Lock()
	net.msgs = append(net.msgs, taggedMsg{inst.id, int(receiverID), payload})
	net.cond.Signal()
	net.cond.L.Unlock()
	return nil
}

func (inst *instance) validate(payload []byte) error {
	return nil
}

func (inst *instance) execute(payload []byte) {

	tx := &pb.Transaction{
		Payload: payload,
	}

	txs := []*pb.Transaction{tx}
	txBatchID := base64.StdEncoding.EncodeToString(util.ComputeCryptoHash(payload))

	if err := inst.BeginTxBatch(txBatchID); err != nil {
		fmt.Printf("Failed to begin transaction %s: %v", txBatchID, err)
		return
	}

	if _, err := inst.ExecTxs(txBatchID, txs); nil != err {
		fmt.Printf("Fail to execute transaction %s: %v", txBatchID, err)
		if err := inst.RollbackTxBatch(txBatchID); err != nil {
			panic(fmt.Errorf("Unable to rollback transaction %s: %v", txBatchID, err))
		}
		return
	}

	if _, err := inst.CommitTxBatch(txBatchID, nil); err != nil {
		fmt.Printf("Failed to commit transaction %s to the ledger: %v", txBatchID, err)
		if err = inst.RollbackTxBatch(txBatchID); err != nil {
			panic(fmt.Errorf("Unable to rollback transaction %s: %v", txBatchID, err))
		}
		return
	}

}

func (inst *instance) viewChange(uint64) {
}

func (inst *instance) GetNetworkInfo() (self *pb.PeerEndpoint, network []*pb.PeerEndpoint, err error) {
	panic("Not implemented yet")
}

func (inst *instance) GetNetworkHandles() (self *pb.PeerID, network []*pb.PeerID, err error) {
	self = inst.handle
	network = inst.net.handles
	return
}

// Broadcast delivers to all replicas.  In contrast to the stack
// Broadcast, this will also deliver back to the replica.  We keep
// this behavior, because it exposes subtle bugs in the
// implementation.
func (inst *instance) Broadcast(msg *pb.OpenchainMessage, typ pb.PeerEndpoint_Type) error {
	net := inst.net
	net.cond.L.Lock()
	net.broadcastFilter(inst, msg.Payload)
	net.cond.Signal()
	net.cond.L.Unlock()
	return nil
}

func (inst *instance) Unicast(msg *pb.OpenchainMessage, receiverHandle *pb.PeerID) error {
	net := inst.net
	net.cond.L.Lock()
	receiverID, err := getValidatorID(receiverHandle)
	if err != nil {
		return fmt.Errorf("Couldn't unicast message to %s: %v", receiverHandle.Name, err)
	}
	net.msgs = append(net.msgs, taggedMsg{inst.id, int(receiverID), msg.Payload})
	net.cond.Signal()
	net.cond.L.Unlock()
	return nil
}

func (inst *instance) BeginTxBatch(id interface{}) error {
	return inst.ledger.BeginTxBatch(id)
}

func (inst *instance) ExecTxs(id interface{}, txs []*pb.Transaction) ([]byte, error) {
	return inst.ledger.ExecTxs(id, txs)
}

func (inst *instance) CommitTxBatch(id interface{}, metadata []byte) (*pb.Block, error) {
	return inst.ledger.CommitTxBatch(id, metadata)
}

func (inst *instance) PreviewCommitTxBatch(id interface{}, metadata []byte) (*pb.Block, error) {
	return inst.ledger.PreviewCommitTxBatch(id, metadata)
}

func (inst *instance) RollbackTxBatch(id interface{}) error {
	return inst.ledger.RollbackTxBatch(id)
}

func (inst *instance) GetBlock(id uint64) (block *pb.Block, err error) {
	return inst.ledger.GetBlock(id)
}
func (inst *instance) GetCurrentStateHash() (stateHash []byte, err error) {
	return inst.ledger.GetCurrentStateHash()
}
func (inst *instance) GetBlockchainSize() (uint64, error) {
	return inst.ledger.GetBlockchainSize()
}
func (inst *instance) HashBlock(block *pb.Block) ([]byte, error) {
	return inst.ledger.HashBlock(block)
}
func (inst *instance) PutBlock(blockNumber uint64, block *pb.Block) error {
	return inst.ledger.PutBlock(blockNumber, block)
}
func (inst *instance) ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error {
	return inst.ledger.ApplyStateDelta(id, delta)
}
func (inst *instance) CommitStateDelta(id interface{}) error {
	return inst.ledger.CommitStateDelta(id)
}
func (inst *instance) RollbackStateDelta(id interface{}) error {
	return inst.ledger.RollbackStateDelta(id)
}
func (inst *instance) EmptyState() error {
	return inst.ledger.EmptyState()
}
func (inst *instance) VerifyBlockchain(start, finish uint64) (uint64, error) {
	return inst.ledger.VerifyBlockchain(start, finish)
}
func (inst *instance) GetRemoteBlocks(peerID *pb.PeerID, start, finish uint64) (<-chan *pb.SyncBlocks, error) {
	return inst.ledger.GetRemoteBlocks(peerID, start, finish)
}
func (inst *instance) GetRemoteStateSnapshot(peerID *pb.PeerID) (<-chan *pb.SyncStateSnapshot, error) {
	return inst.ledger.GetRemoteStateSnapshot(peerID)
}
func (inst *instance) GetRemoteStateDeltas(peerID *pb.PeerID, start, finish uint64) (<-chan *pb.SyncStateDeltas, error) {
	return inst.ledger.GetRemoteStateDeltas(peerID, start, finish)
}

func (net *testnet) broadcastFilter(inst *instance, payload []byte) {
	if net.filterFn != nil {
		payload = net.filterFn(inst.id, -1, payload)
	}
	if payload != nil {
		/* msg := &Message{}
		_ = proto.Unmarshal(payload, msg)
		if fr := msg.GetFetchRequest(); fr != nil {
			// treat fetch-request as a high-priority message that needs to be processed ASAP
			fmt.Printf("Debug: replica %v broadcastFilter for fetch-request\n", inst.id)
			net.deliverFilter(taggedMsg{inst.id, -1, payload})
		} else { */
		net.msgs = append(net.msgs, taggedMsg{inst.id, -1, payload})
	}
}

func (net *testnet) deliverFilter(msg taggedMsg) {
	if msg.dst == -1 {
		for id, inst := range net.replicas {
			if msg.src == id {
				// do not deliver to local replica
				continue
			}
			payload := msg.msg
			if net.filterFn != nil {
				payload = net.filterFn(msg.src, id, payload)
			}
			if payload != nil {
				inst.deliver(msg.msg)
			}
		}
	} else {
		net.replicas[msg.dst].deliver(msg.msg)
	}
}

func (net *testnet) processWithoutDrain() {
	net.cond.L.Lock()
	defer net.cond.L.Unlock()
	for len(net.msgs) > 0 {
		msg := net.msgs[0]
		fmt.Printf("Debug: process iteration (%d messages to go, delivering now to destination %v)\n", len(net.msgs), msg.dst)
		net.msgs = net.msgs[1:]
		net.cond.L.Unlock()
		net.deliverFilter(msg)
		net.cond.L.Lock()
	}
}

func (net *testnet) drain() {
	for _, inst := range net.replicas {
		if inst.pbft != nil {
			inst.pbft.drain()
		}
		if inst.consenter != nil {
			inst.consenter.Drain()
		}
	}
}

func (net *testnet) process() error {
	for retry := true; retry; {
		retry = false
		net.processWithoutDrain()
		net.drain()
		net.cond.L.Lock()
		if len(net.msgs) > 0 {
			fmt.Printf("Debug: new messages after executeOutstanding, retrying\n")
			retry = true
		}
		net.cond.L.Unlock()
	}

	return nil
}

func (net *testnet) processContinually() {
	net.cond.L.Lock()
	defer net.cond.L.Unlock()
	for {
		if net.closed {
			break
		}
		if len(net.msgs) == 0 {
			net.cond.Wait()
		}
		net.cond.L.Unlock()
		net.processWithoutDrain()
		net.cond.L.Lock()
	}
}

func makeTestnet(N int, initFn ...func(*instance)) *testnet {
	f := N / 3
	net := &testnet{f: f, N: N}
	net.cond = sync.NewCond(&sync.Mutex{})

	for i := uint64(0); i < uint64(N); i++ {
	}

	ledgers := make(map[pb.PeerID]consensus.ReadOnlyLedger, N)
	for i := 0; i < N; i++ {
		inst := &instance{handle: &pb.PeerID{Name: "vp" + strconv.Itoa(i)}, id: i, net: net}
		ml := NewMockLedger(&ledgers, nil)
		ml.inst = inst
		ml.PutBlock(0, SimpleGetBlock(0))
		handle, _ := getValidatorHandle(uint64(i))
		ledgers[*handle] = ml
		inst.ledger = ml
		net.replicas = append(net.replicas, inst)
		net.handles = append(net.handles, inst.handle)
	}

	for _, inst := range net.replicas {
		for _, fn := range initFn {
			fn(inst)
		}
	}

	return net
}

func (net *testnet) close() {
	if net.closed {
		return
	}
	net.drain()
	for _, inst := range net.replicas {
		if inst.pbft != nil {
			inst.pbft.close()
		}
		if inst.consenter != nil {
			inst.consenter.Close()
		}
	}
	net.cond.L.Lock()
	net.closed = true
	net.cond.Signal()
	net.cond.L.Unlock()
}
<commit_msg>pbft/test: properly lock and unlock mock network<commit_after>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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 obcpbft

import (
	"encoding/base64"
	"fmt"
	"strconv"
	"sync"

	"github.com/openblockchain/obc-peer/openchain/consensus"
	"github.com/openblockchain/obc-peer/openchain/ledger/statemgmt"
	"github.com/openblockchain/obc-peer/openchain/util"
	pb "github.com/openblockchain/obc-peer/protos"
)

type mockStack struct {
	broadcasted [][]byte
	*instance
}

func newMock() *mockStack {
	mock := &mockStack{
		make([][]byte, 0),
		&instance{},
	}
	mock.instance.ledger = NewMockLedger(nil, nil)
	mock.instance.ledger.PutBlock(0, SimpleGetBlock(0))
	return mock
}

func (mock *mockStack) sign(msg []byte) ([]byte, error) {
	return msg, nil
}

func (mock *mockStack) verify(senderID uint64, signature []byte, message []byte) error {
	return nil
}

func (mock *mockStack) broadcast(msg []byte) {
	mock.broadcasted = append(mock.broadcasted, msg)
}

func (mock *mockStack) unicast(msg []byte, receiverID uint64) (err error) {
	panic("not implemented")
}

// =============================================================================
// Fake network structures
// =============================================================================

type closableConsenter interface {
	consensus.Consenter
	Close()
	Drain()
}

type taggedMsg struct {
	src int
	dst int
	msg []byte
}

type testnet struct {
	N        int
	f        int
	cond     *sync.Cond
	closed   bool
	replicas []*instance
	msgs     []taggedMsg
	handles  []*pb.PeerID
	filterFn func(int, int, []byte) []byte
}

type instance struct {
	id        int
	handle    *pb.PeerID
	pbft      *pbftCore
	consenter closableConsenter
	net       *testnet
	ledger    consensus.LedgerStack

	deliver      func([]byte)
	execTxResult func([]*pb.Transaction) ([]byte, error)
}

func (inst *instance) Sign(msg []byte) ([]byte, error) {
	return msg, nil
}
func (inst *instance) Verify(peerID *pb.PeerID, signature []byte, message []byte) error {
	return nil
}

func (inst *instance) sign(msg []byte) ([]byte, error) {
	return msg, nil
}

func (inst *instance) verify(replicaID uint64, signature []byte, message []byte) error {
	return nil
}

func (inst *instance) broadcast(payload []byte) {
	net := inst.net
	net.cond.L.Lock()
	defer net.cond.L.Unlock()
	net.broadcastFilter(inst, payload)
	net.cond.Signal()
}

func (inst *instance) unicast(payload []byte, receiverID uint64) error {
	net := inst.net
	net.cond.L.Lock()
	defer net.cond.L.Unlock()
	net.msgs = append(net.msgs, taggedMsg{inst.id, int(receiverID), payload})
	net.cond.Signal()
	return nil
}

func (inst *instance) validate(payload []byte) error {
	return nil
}

func (inst *instance) execute(payload []byte) {

	tx := &pb.Transaction{
		Payload: payload,
	}

	txs := []*pb.Transaction{tx}
	txBatchID := base64.StdEncoding.EncodeToString(util.ComputeCryptoHash(payload))

	if err := inst.BeginTxBatch(txBatchID); err != nil {
		fmt.Printf("Failed to begin transaction %s: %v", txBatchID, err)
		return
	}

	if _, err := inst.ExecTxs(txBatchID, txs); nil != err {
		fmt.Printf("Fail to execute transaction %s: %v", txBatchID, err)
		if err := inst.RollbackTxBatch(txBatchID); err != nil {
			panic(fmt.Errorf("Unable to rollback transaction %s: %v", txBatchID, err))
		}
		return
	}

	if _, err := inst.CommitTxBatch(txBatchID, nil); err != nil {
		fmt.Printf("Failed to commit transaction %s to the ledger: %v", txBatchID, err)
		if err = inst.RollbackTxBatch(txBatchID); err != nil {
			panic(fmt.Errorf("Unable to rollback transaction %s: %v", txBatchID, err))
		}
		return
	}

}

func (inst *instance) viewChange(uint64) {
}

func (inst *instance) GetNetworkInfo() (self *pb.PeerEndpoint, network []*pb.PeerEndpoint, err error) {
	panic("Not implemented yet")
}

func (inst *instance) GetNetworkHandles() (self *pb.PeerID, network []*pb.PeerID, err error) {
	self = inst.handle
	network = inst.net.handles
	return
}

// Broadcast delivers to all replicas.  In contrast to the stack
// Broadcast, this will also deliver back to the replica.  We keep
// this behavior, because it exposes subtle bugs in the
// implementation.
func (inst *instance) Broadcast(msg *pb.OpenchainMessage, typ pb.PeerEndpoint_Type) error {
	net := inst.net
	net.cond.L.Lock()
	defer net.cond.L.Unlock()
	net.broadcastFilter(inst, msg.Payload)
	net.cond.Signal()
	return nil
}

func (inst *instance) Unicast(msg *pb.OpenchainMessage, receiverHandle *pb.PeerID) error {
	net := inst.net
	net.cond.L.Lock()
	defer net.cond.L.Unlock()
	receiverID, err := getValidatorID(receiverHandle)
	if err != nil {
		return fmt.Errorf("Couldn't unicast message to %s: %v", receiverHandle.Name, err)
	}
	net.msgs = append(net.msgs, taggedMsg{inst.id, int(receiverID), msg.Payload})
	net.cond.Signal()
	return nil
}

func (inst *instance) BeginTxBatch(id interface{}) error {
	return inst.ledger.BeginTxBatch(id)
}

func (inst *instance) ExecTxs(id interface{}, txs []*pb.Transaction) ([]byte, error) {
	return inst.ledger.ExecTxs(id, txs)
}

func (inst *instance) CommitTxBatch(id interface{}, metadata []byte) (*pb.Block, error) {
	return inst.ledger.CommitTxBatch(id, metadata)
}

func (inst *instance) PreviewCommitTxBatch(id interface{}, metadata []byte) (*pb.Block, error) {
	return inst.ledger.PreviewCommitTxBatch(id, metadata)
}

func (inst *instance) RollbackTxBatch(id interface{}) error {
	return inst.ledger.RollbackTxBatch(id)
}

func (inst *instance) GetBlock(id uint64) (block *pb.Block, err error) {
	return inst.ledger.GetBlock(id)
}
func (inst *instance) GetCurrentStateHash() (stateHash []byte, err error) {
	return inst.ledger.GetCurrentStateHash()
}
func (inst *instance) GetBlockchainSize() (uint64, error) {
	return inst.ledger.GetBlockchainSize()
}
func (inst *instance) HashBlock(block *pb.Block) ([]byte, error) {
	return inst.ledger.HashBlock(block)
}
func (inst *instance) PutBlock(blockNumber uint64, block *pb.Block) error {
	return inst.ledger.PutBlock(blockNumber, block)
}
func (inst *instance) ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error {
	return inst.ledger.ApplyStateDelta(id, delta)
}
func (inst *instance) CommitStateDelta(id interface{}) error {
	return inst.ledger.CommitStateDelta(id)
}
func (inst *instance) RollbackStateDelta(id interface{}) error {
	return inst.ledger.RollbackStateDelta(id)
}
func (inst *instance) EmptyState() error {
	return inst.ledger.EmptyState()
}
func (inst *instance) VerifyBlockchain(start, finish uint64) (uint64, error) {
	return inst.ledger.VerifyBlockchain(start, finish)
}
func (inst *instance) GetRemoteBlocks(peerID *pb.PeerID, start, finish uint64) (<-chan *pb.SyncBlocks, error) {
	return inst.ledger.GetRemoteBlocks(peerID, start, finish)
}
func (inst *instance) GetRemoteStateSnapshot(peerID *pb.PeerID) (<-chan *pb.SyncStateSnapshot, error) {
	return inst.ledger.GetRemoteStateSnapshot(peerID)
}
func (inst *instance) GetRemoteStateDeltas(peerID *pb.PeerID, start, finish uint64) (<-chan *pb.SyncStateDeltas, error) {
	return inst.ledger.GetRemoteStateDeltas(peerID, start, finish)
}

func (net *testnet) broadcastFilter(inst *instance, payload []byte) {
	if net.filterFn != nil {
		payload = net.filterFn(inst.id, -1, payload)
	}
	if payload != nil {
		/* msg := &Message{}
		_ = proto.Unmarshal(payload, msg)
		if fr := msg.GetFetchRequest(); fr != nil {
			// treat fetch-request as a high-priority message that needs to be processed ASAP
			fmt.Printf("Debug: replica %v broadcastFilter for fetch-request\n", inst.id)
			net.deliverFilter(taggedMsg{inst.id, -1, payload})
		} else { */
		net.msgs = append(net.msgs, taggedMsg{inst.id, -1, payload})
	}
}

func (net *testnet) deliverFilter(msg taggedMsg) {
	if msg.dst == -1 {
		for id, inst := range net.replicas {
			if msg.src == id {
				// do not deliver to local replica
				continue
			}
			payload := msg.msg
			if net.filterFn != nil {
				payload = net.filterFn(msg.src, id, payload)
			}
			if payload != nil {
				inst.deliver(msg.msg)
			}
		}
	} else {
		net.replicas[msg.dst].deliver(msg.msg)
	}
}

func (net *testnet) processWithoutDrain() {
	net.cond.L.Lock()
	defer net.cond.L.Unlock()

	net.processWithoutDrainSync()
}

func (net *testnet) processWithoutDrainSync() {
	doDeliver := func(msg taggedMsg) {
		net.cond.L.Unlock()
		defer net.cond.L.Lock()
		net.deliverFilter(msg)
	}

	for len(net.msgs) > 0 {
		msg := net.msgs[0]
		fmt.Printf("Debug: process iteration (%d messages to go, delivering now to destination %v)\n", len(net.msgs), msg.dst)
		net.msgs = net.msgs[1:]
		doDeliver(msg)
	}
}

func (net *testnet) drain() {
	for _, inst := range net.replicas {
		if inst.pbft != nil {
			inst.pbft.drain()
		}
		if inst.consenter != nil {
			inst.consenter.Drain()
		}
	}
}

func (net *testnet) process() error {
	for retry := true; retry; {
		retry = false
		net.processWithoutDrain()
		net.drain()
		net.cond.L.Lock()
		if len(net.msgs) > 0 {
			fmt.Printf("Debug: new messages after executeOutstanding, retrying\n")
			retry = true
		}
		net.cond.L.Unlock()
	}

	return nil
}

func (net *testnet) processContinually() {
	net.cond.L.Lock()
	defer net.cond.L.Unlock()
	for {
		if net.closed {
			break
		}
		if len(net.msgs) == 0 {
			net.cond.Wait()
		}
		net.processWithoutDrainSync()
	}
}

func makeTestnet(N int, initFn ...func(*instance)) *testnet {
	f := N / 3
	net := &testnet{f: f, N: N}
	net.cond = sync.NewCond(&sync.Mutex{})

	for i := uint64(0); i < uint64(N); i++ {
	}

	ledgers := make(map[pb.PeerID]consensus.ReadOnlyLedger, N)
	for i := 0; i < N; i++ {
		inst := &instance{handle: &pb.PeerID{Name: "vp" + strconv.Itoa(i)}, id: i, net: net}
		ml := NewMockLedger(&ledgers, nil)
		ml.inst = inst
		ml.PutBlock(0, SimpleGetBlock(0))
		handle, _ := getValidatorHandle(uint64(i))
		ledgers[*handle] = ml
		inst.ledger = ml
		net.replicas = append(net.replicas, inst)
		net.handles = append(net.handles, inst.handle)
	}

	for _, inst := range net.replicas {
		for _, fn := range initFn {
			fn(inst)
		}
	}

	return net
}

func (net *testnet) close() {
	if net.closed {
		return
	}
	net.drain()
	for _, inst := range net.replicas {
		if inst.pbft != nil {
			inst.pbft.close()
		}
		if inst.consenter != nil {
			inst.consenter.Close()
		}
	}
	net.cond.L.Lock()
	defer net.cond.L.Unlock()
	net.closed = true
	net.cond.Signal()
}
<|endoftext|>