<commit_before>package proxy

import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"
	"math"
	"strconv"
)

var errInvalidPacketLength = errors.New("Invalid packet length")
var errInvalidPacketType = errors.New("Invalid packet type")
var errFieldTypeNotImplementedYet = errors.New("Required field type not implemented yet")

// ComQueryRequest represents COM_QUERY command sent by client to server
// to be executed immediately.
type ComQueryRequest struct {
	Query string
}

// [0,1,2]:   int<3> PacketLength
// [3]: 	  int<1> PacketNumber
// [4]:       int<1> Command COM_QUERY (0x03)
// [5, ...]   string<EOF> SQLStatement
func DecodeComQueryRequest(packet []byte) (*ComQueryRequest, error) {

	// Min packet length = header(4 bytes) + command(1 byte) + SQLStatement(at least 1 byte)
	if len(packet) < 6 {
		return nil, errInvalidPacketLength
	}

	return &ComQueryRequest{DecodeEOFLengthString(packet[5:])}, nil
}

// ComStmtPrepareOkResponse represents COM_STMT_PREPARE_OK response structure.
type ComStmtPrepareOkResponse struct {

	// StatementID is an ID of prepared statement
	StatementID uint32

	// ParametersNum is num of prepared parameters
	ParametersNum uint16
}

// DecodeComStmtPrepareOkResponse decodes COM_STMT_PREPARE_OK response from MySQL server
// Basic packet structure shown below.
// For more details see https://mariadb.com/kb/en/mariadb/com_stmt_prepare/#COM_STMT_PREPARE_OK

// [0,1,2]:   int<3> PacketLength
// [3]: 	  int<1> PacketNumber
// [4]:       int<1> Command COM_STMT_PREPARE_OK (0x00)
// [5,6,7,8]: int<4> StatementID
// [9,10]:    int<2> NumberOfColumns
// [11,12]:   int<2> NumberOfParameters
// [13]:      string<1> <not used>
// [14,15]:   int<2> NumberOfWarnings
func DecodeComStmtPrepareOkResponse(packet []byte) (*ComStmtPrepareOkResponse, error) {

	// Min packet length = header(4 bytes) + command(1 byte) + statementID(4 bytes)
	// + number of columns (2 bytes) + number of parameters (2 bytes)
	// + <not used> (1 byte) + number of warnings (2 bytes)
	if len(packet) < 16 {
		return nil, errInvalidPacketLength
	}

	// Fifth byte is command
	if packet[4] != responsePrepareOk {
		return nil, errInvalidPacketType
	}

	statementID := binary.LittleEndian.Uint32(packet[5:9])
	parametersNum := binary.LittleEndian.Uint16(packet[11:13])

	return &ComStmtPrepareOkResponse{StatementID: statementID, ParametersNum: parametersNum}, nil
}

// ComStmtExecuteRequest represents COM_STMT_EXECUTE request structure
type ComStmtExecuteRequest struct {

	// StatementID is an ID of prepared statement
	StatementID uint32

	// PreparedParameters is a slice of prepared parameters
	PreparedParameters []PreparedParameter
}

// PreparedParameter structure represents single prepared parameter structure
// for COM_STMT_EXECUTE request
type PreparedParameter struct {

	// FieldType is type of prepared parameter
	// See https://mariadb.com/kb/en/mariadb/resultset/#field-types
	FieldType byte

	// Flags is unused
	Flag byte

	// Value is string presentation of any prepared parameter passed
	// with COM_STMT_EXECUTE request
	Value string
}

// DecodeComStmtExecuteRequest decodes COM_STMT_EXECUTE packet sent by MySQL client.
// Basic packet structure shown below.
// For more details see https://mariadb.com/kb/en/mariadb/com_stmt_execute/

// [0,1,2]:       int<3> PacketLength
// [3]: 	      int<1> PacketNumber
// [4]:           int<1> COM_STMT_EXECUTE (0x17)
// [5,6,7,8]:     int<4> StatementID
// [9]:           int<1> Flags
// [10,11,12, 13] int<4> IterationCount = 1
// 			  	  if (ParamCount > 0)
//			      {
// 				     byte<(ParamCount + 7) / 8> NullBitmap
// 				     byte<1>: SendTypeToServer = 0 or 1
// 				     if (SendTypeToServer)
//				     {
// 					    Foreach parameter
//					    {
// 						   byte<1>: FieldType
//						   byte<1>: ParameterFlag
//					    }
//				     }
// 				    Foreach parameter
//				    {
// 					   byte<n> BinaryParameterValue
//				    }
//			     }
func DecodeComStmtExecuteRequest(packet []byte, paramsCount uint16) (*ComStmtExecuteRequest, error) {

	// Min packet length = header(4 bytes) + command(1 byte) + statementID(4 bytes)
	// + flags(1 byte) + iteration count(4 bytes)
	if len(packet) < 14 {
		return nil, errInvalidPacketLength
	}

	// Fifth byte is command
	if packet[4] != requestComStmtExecute {
		return nil, errInvalidPacketType
	}

	reader := bytes.NewReader(packet)

	// Skip to statementID position
	reader.Seek(5, io.SeekStart)

	// Read StatementID value
	statementIDBuf := make([]byte, 4)
	reader.Read(statementIDBuf)
	statementID := binary.LittleEndian.Uint32(statementIDBuf)

	// Skip to NullBitmap position
	reader.Seek(5, io.SeekCurrent)

	parameters := make([]PreparedParameter, paramsCount)

	if paramsCount > 0 {
		nullBitmapLength := int64((paramsCount + 7) / 8)

		// Skip to SendTypeToServer position
		reader.Seek(nullBitmapLength, io.SeekCurrent)

		// Read SendTypeToServer value
		sendTypeToServerBuf := make([]byte, 1)
		reader.Read(sendTypeToServerBuf)
		sendTypeToServer, _ := DecodeLenEncodedInteger(sendTypeToServerBuf)

		if sendTypeToServer == 1 {
			for index := range parameters {

				// Read parameter FieldType and ParameterFlag
				parameterMeta := make([]byte, 2)
				reader.Read(parameterMeta)

				parameters[index].FieldType = parameterMeta[0]
				parameters[index].Flag = parameterMeta[1]
			}
		}

		var stringValue string

		for index, parameter := range parameters {
			switch parameter.FieldType {

			// MYSQL_TYPE_VAR_STRING
			// It's length encoded string
			case fieldTypeString:
				// Read first byte of parameter value to know buffer length for whole value
				stringLengthBuf := make([]byte, 1)
				reader.Read(stringLengthBuf)

				stringLength, _ := DecodeLenEncodedInteger(stringLengthBuf)
				reader.UnreadByte()

				// Packets with 0 length parameter are also possible
				if stringLength > 0 {
					// Read whole length encoded string
					stringValueBuf := make([]byte, stringLength+1)
					reader.Read(stringValueBuf)

					stringValue, _ = DecodeLenEncodedString(stringValueBuf)
				}

			// MYSQL_TYPE_LONGLONG
			case fieldTypeLongLong:
				var bigIntValue int64
				binary.Read(reader, binary.LittleEndian, &bigIntValue)

				stringValue = strconv.FormatInt(bigIntValue, 10)

			// MYSQL_TYPE_DOUBLE
			case fieldTypeDouble:
				// Read 8 bytes required for float64
				doubleLengthBuf := make([]byte, 8)
				reader.Read(doubleLengthBuf)

				doubleBits := binary.LittleEndian.Uint64(doubleLengthBuf)
				doubleValue := math.Float64frombits(doubleBits)

				stringValue = strconv.FormatFloat(doubleValue, 'f', 6, 64)

			default:
				return nil, errFieldTypeNotImplementedYet
			}

			parameters[index].Value = stringValue
		}
	}

	return &ComStmtExecuteRequest{StatementID: statementID, PreparedParameters: parameters}, nil
}

// DecodeLenEncodedInteger returns length-encoded integer and it's offset
// For more details see https://mariadb.com/kb/en/mariadb/protocol-data-types/#length-encoded-integers
func DecodeLenEncodedInteger(data []byte) (value uint64, offset uint64) {
	if len(data) == 0 {
		value = 0
		offset = 0
	}

	switch data[0] {
	case 0xfb:
		value = 0
		offset = 1

	case 0xfc:
		value = uint64(data[1]) | uint64(data[2])<<8
		offset = 3

	case 0xfd:
		value = uint64(data[1]) | uint64(data[2])<<8 | uint64(data[3])<<16
		offset = 4

	case 0xfe:
		value = uint64(data[1]) | uint64(data[2])<<8 | uint64(data[3])<<16 |
			uint64(data[4])<<24 | uint64(data[5])<<32 | uint64(data[6])<<40 |
			uint64(data[7])<<48 | uint64(data[8])<<56
		offset = 9

	default:
		value = uint64(data[0])
		offset = 1
	}

	return value, offset
}

// DecodeLenEncodedString returns length-encoded string and it's length
// Length-encoded strings are prefixed by a length-encoded integer which describes
// the length of the string, followed by the string value.
// For more details see https://mariadb.com/kb/en/mariadb/protocol-data-types/#length-encoded-strings
func DecodeLenEncodedString(data []byte) (string, uint64) {
	strLen, offset := DecodeLenEncodedInteger(data)

	return string(data[offset : offset+strLen]), strLen
}

// DecodeEOFLengthString returns parsed EOF-length string.
// EOF-length strings are those strings whose length will be calculated by the packet remaining length.
// For more details see https://mariadb.com/kb/en/mariadb/protocol-data-types/#end-of-file-length-strings
func DecodeEOFLengthString(data []byte) string {
	return string(data)
}
<commit_msg>Code refactor<commit_after>package proxy

import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"
	"math"
	"strconv"
)

var errInvalidPacketLength = errors.New("Invalid packet length")
var errInvalidPacketType = errors.New("Invalid packet type")
var errFieldTypeNotImplementedYet = errors.New("Required field type not implemented yet")

// ComQueryRequest represents COM_QUERY command sent by client to server
// to be executed immediately.
type ComQueryRequest struct {
	Query string // SQL query value
}

// [0,1,2]:   int<3> PacketLength
// [3]: 	  int<1> PacketNumber
// [4]:       int<1> Command COM_QUERY (0x03)
// [5, ...]   string<EOF> SQLStatement
func DecodeComQueryRequest(packet []byte) (*ComQueryRequest, error) {

	// Min packet length = header(4 bytes) + command(1 byte) + SQLStatement(at least 1 byte)
	if len(packet) < 6 {
		return nil, errInvalidPacketLength
	}

	return &ComQueryRequest{DecodeEOFLengthString(packet[5:])}, nil
}

// ComStmtPrepareOkResponse represents COM_STMT_PREPARE_OK response structure.
type ComStmtPrepareOkResponse struct {
	StatementID   uint32 // ID of prepared statement
	ParametersNum uint16 // Num of prepared parameters
}

// DecodeComStmtPrepareOkResponse decodes COM_STMT_PREPARE_OK response from MySQL server
// Basic packet structure shown below.
// For more details see https://mariadb.com/kb/en/mariadb/com_stmt_prepare/#COM_STMT_PREPARE_OK

// [0,1,2]:   int<3> PacketLength
// [3]: 	  int<1> PacketNumber
// [4]:       int<1> Command COM_STMT_PREPARE_OK (0x00)
// [5,6,7,8]: int<4> StatementID
// [9,10]:    int<2> NumberOfColumns
// [11,12]:   int<2> NumberOfParameters
// [13]:      string<1> <not used>
// [14,15]:   int<2> NumberOfWarnings
func DecodeComStmtPrepareOkResponse(packet []byte) (*ComStmtPrepareOkResponse, error) {

	// Min packet length = header(4 bytes) + command(1 byte) + statementID(4 bytes)
	// + number of columns (2 bytes) + number of parameters (2 bytes)
	// + <not used> (1 byte) + number of warnings (2 bytes)
	if len(packet) < 16 {
		return nil, errInvalidPacketLength
	}

	// Fifth byte is command
	if packet[4] != responsePrepareOk {
		return nil, errInvalidPacketType
	}

	statementID := binary.LittleEndian.Uint32(packet[5:9])
	parametersNum := binary.LittleEndian.Uint16(packet[11:13])

	return &ComStmtPrepareOkResponse{StatementID: statementID, ParametersNum: parametersNum}, nil
}

// ComStmtExecuteRequest represents COM_STMT_EXECUTE request structure
type ComStmtExecuteRequest struct {
	StatementID        uint32              // ID of prepared statement
	PreparedParameters []PreparedParameter // Slice of prepared parameters
}

// PreparedParameter structure represents single prepared parameter structure for COM_STMT_EXECUTE request
type PreparedParameter struct {
	FieldType byte   // Type of prepared parameter. See https://mariadb.com/kb/en/mariadb/resultset/#field-types
	Flag      byte   // Unused
	Value     string // String value of any prepared parameter passed with COM_STMT_EXECUTE request
}

// DecodeComStmtExecuteRequest decodes COM_STMT_EXECUTE packet sent by MySQL client.
// Basic packet structure shown below.
// For more details see https://mariadb.com/kb/en/mariadb/com_stmt_execute/

// [0,1,2]:       int<3> PacketLength
// [3]: 	      int<1> PacketNumber
// [4]:           int<1> COM_STMT_EXECUTE (0x17)
// [5,6,7,8]:     int<4> StatementID
// [9]:           int<1> Flags
// [10,11,12, 13] int<4> IterationCount = 1
// 			  	  if (ParamCount > 0)
//			      {
// 				     byte<(ParamCount + 7) / 8> NullBitmap
// 				     byte<1>: SendTypeToServer = 0 or 1
// 				     if (SendTypeToServer)
//				     {
// 					    Foreach parameter
//					    {
// 						   byte<1>: FieldType
//						   byte<1>: ParameterFlag
//					    }
//				     }
// 				    Foreach parameter
//				    {
// 					   byte<n> BinaryParameterValue
//				    }
//			     }
func DecodeComStmtExecuteRequest(packet []byte, paramsCount uint16) (*ComStmtExecuteRequest, error) {

	// Min packet length = header(4 bytes) + command(1 byte) + statementID(4 bytes)
	// + flags(1 byte) + iteration count(4 bytes)
	if len(packet) < 14 {
		return nil, errInvalidPacketLength
	}

	// Fifth byte is command
	if packet[4] != requestComStmtExecute {
		return nil, errInvalidPacketType
	}

	reader := bytes.NewReader(packet)

	// Skip to statementID position
	reader.Seek(5, io.SeekStart)

	// Read StatementID value
	statementIDBuf := make([]byte, 4)
	reader.Read(statementIDBuf)
	statementID := binary.LittleEndian.Uint32(statementIDBuf)

	// Skip to NullBitmap position
	reader.Seek(5, io.SeekCurrent)

	parameters := make([]PreparedParameter, paramsCount)

	if paramsCount > 0 {
		nullBitmapLength := int64((paramsCount + 7) / 8)

		// Skip to SendTypeToServer position
		reader.Seek(nullBitmapLength, io.SeekCurrent)

		// Read SendTypeToServer value
		sendTypeToServerBuf := make([]byte, 1)
		reader.Read(sendTypeToServerBuf)
		sendTypeToServer, _ := DecodeLenEncodedInteger(sendTypeToServerBuf)

		if sendTypeToServer == 1 {
			for index := range parameters {

				// Read parameter FieldType and ParameterFlag
				parameterMeta := make([]byte, 2)
				reader.Read(parameterMeta)

				parameters[index].FieldType = parameterMeta[0]
				parameters[index].Flag = parameterMeta[1]
			}
		}

		var stringValue string

		for index, parameter := range parameters {
			switch parameter.FieldType {

			// MYSQL_TYPE_VAR_STRING
			// It's length encoded string
			case fieldTypeString:
				// Read first byte of parameter value to know buffer length for whole value
				stringLengthBuf := make([]byte, 1)
				reader.Read(stringLengthBuf)

				stringLength, _ := DecodeLenEncodedInteger(stringLengthBuf)
				reader.UnreadByte()

				// Packets with 0 length parameter are also possible
				if stringLength > 0 {
					// Read whole length encoded string
					stringValueBuf := make([]byte, stringLength+1)
					reader.Read(stringValueBuf)

					stringValue, _ = DecodeLenEncodedString(stringValueBuf)
				}

			// MYSQL_TYPE_LONGLONG
			case fieldTypeLongLong:
				var bigIntValue int64
				binary.Read(reader, binary.LittleEndian, &bigIntValue)

				stringValue = strconv.FormatInt(bigIntValue, 10)

			// MYSQL_TYPE_DOUBLE
			case fieldTypeDouble:
				// Read 8 bytes required for float64
				doubleLengthBuf := make([]byte, 8)
				reader.Read(doubleLengthBuf)

				doubleBits := binary.LittleEndian.Uint64(doubleLengthBuf)
				doubleValue := math.Float64frombits(doubleBits)

				stringValue = strconv.FormatFloat(doubleValue, 'f', 6, 64)

			default:
				return nil, errFieldTypeNotImplementedYet
			}

			parameters[index].Value = stringValue
		}
	}

	return &ComStmtExecuteRequest{StatementID: statementID, PreparedParameters: parameters}, nil
}

// DecodeLenEncodedInteger returns length-encoded integer and it's offset
// For more details see https://mariadb.com/kb/en/mariadb/protocol-data-types/#length-encoded-integers
func DecodeLenEncodedInteger(data []byte) (value uint64, offset uint64) {
	if len(data) == 0 {
		value = 0
		offset = 0
	}

	switch data[0] {
	case 0xfb:
		value = 0
		offset = 1

	case 0xfc:
		value = uint64(data[1]) | uint64(data[2])<<8
		offset = 3

	case 0xfd:
		value = uint64(data[1]) | uint64(data[2])<<8 | uint64(data[3])<<16
		offset = 4

	case 0xfe:
		value = uint64(data[1]) | uint64(data[2])<<8 | uint64(data[3])<<16 |
			uint64(data[4])<<24 | uint64(data[5])<<32 | uint64(data[6])<<40 |
			uint64(data[7])<<48 | uint64(data[8])<<56
		offset = 9

	default:
		value = uint64(data[0])
		offset = 1
	}

	return value, offset
}

// DecodeLenEncodedString returns length-encoded string and it's length
// Length-encoded strings are prefixed by a length-encoded integer which describes
// the length of the string, followed by the string value.
// For more details see https://mariadb.com/kb/en/mariadb/protocol-data-types/#length-encoded-strings
func DecodeLenEncodedString(data []byte) (string, uint64) {
	strLen, offset := DecodeLenEncodedInteger(data)

	return string(data[offset : offset+strLen]), strLen
}

// DecodeEOFLengthString returns parsed EOF-length string.
// EOF-length strings are those strings whose length will be calculated by the packet remaining length.
// For more details see https://mariadb.com/kb/en/mariadb/protocol-data-types/#end-of-file-length-strings
func DecodeEOFLengthString(data []byte) string {
	return string(data)
}
<|endoftext|>


<commit_before>package psh

import (
	"github.com/coocood/assrt"
	"os/exec"
	"sync"
	"testing"
	"time"
)

func TestStateConsts(t *testing.T) {
	if !(UNSTARTED == 0 && RUNNING == 1 && FINISHED == 2 && PANICKED == 3) {
		t.Fail()
	}
}

// Test that we can exec something, wait, and it returns quickly and with an exit code.
func TestPshExecBasic(t *testing.T) {
	assert := assrt.NewAssert(t)

	cmdr := NewRunningCommand(
		exec.Command("echo"),
	)
	cmdr.startCalmly()
	cmdr.WaitSoon(1 * time.Second)
	assert.Equal(
		0,
		cmdr.GetExitCode(),
	)
	assert.Equal(
		nil,
		cmdr.err,
	)
	assert.Equal(
		FINISHED,
		cmdr.state,
	)
}

func TestPshWaitTimeout(t *testing.T) {
	assert := assrt.NewAssert(t)

	cmdr := NewRunningCommand(
		exec.Command("sleep", "1"),
	)
	cmdr.startCalmly()
	assert.Equal(
		false,
		cmdr.WaitSoon(20 * time.Millisecond),
	)
	assert.Equal(
		-1,
		cmdr.exitCode,
	)
	assert.Equal(
		RUNNING,
		cmdr.state,
	)
}

func TestPshExitListeners(t *testing.T) {
	assert := assrt.NewAssert(t)

	cmdr := NewRunningCommand(
		exec.Command("echo"),
	)
	cmdr.startCalmly()
	var wg sync.WaitGroup
	wg.Add(1)
	cmdr.AddExitListener(func(*RunningCommand) {
		defer wg.Done()
		assert.Equal(
			0,
			cmdr.GetExitCode(),
		)
		assert.Equal(
			nil,
			cmdr.err,
		)
		assert.Equal(
			FINISHED,
			cmdr.state,
		)
	})
	wg.Wait()
	assert.Equal(
		0,
		cmdr.GetExitCode(),
	)
	assert.Equal(
		nil,
		cmdr.err,
	)
	assert.Equal(
		FINISHED,
		cmdr.state,
	)
}
<commit_msg>gofmt<commit_after>package psh

import (
	"github.com/coocood/assrt"
	"os/exec"
	"sync"
	"testing"
	"time"
)

func TestStateConsts(t *testing.T) {
	if !(UNSTARTED == 0 && RUNNING == 1 && FINISHED == 2 && PANICKED == 3) {
		t.Fail()
	}
}

// Test that we can exec something, wait, and it returns quickly and with an exit code.
func TestPshExecBasic(t *testing.T) {
	assert := assrt.NewAssert(t)

	cmdr := NewRunningCommand(
		exec.Command("echo"),
	)
	cmdr.startCalmly()
	cmdr.WaitSoon(1 * time.Second)
	assert.Equal(
		0,
		cmdr.GetExitCode(),
	)
	assert.Equal(
		nil,
		cmdr.err,
	)
	assert.Equal(
		FINISHED,
		cmdr.state,
	)
}

func TestPshWaitTimeout(t *testing.T) {
	assert := assrt.NewAssert(t)

	cmdr := NewRunningCommand(
		exec.Command("sleep", "1"),
	)
	cmdr.startCalmly()
	assert.Equal(
		false,
		cmdr.WaitSoon(20*time.Millisecond),
	)
	assert.Equal(
		-1,
		cmdr.exitCode,
	)
	assert.Equal(
		RUNNING,
		cmdr.state,
	)
}

func TestPshExitListeners(t *testing.T) {
	assert := assrt.NewAssert(t)

	cmdr := NewRunningCommand(
		exec.Command("echo"),
	)
	cmdr.startCalmly()
	var wg sync.WaitGroup
	wg.Add(1)
	cmdr.AddExitListener(func(*RunningCommand) {
		defer wg.Done()
		assert.Equal(
			0,
			cmdr.GetExitCode(),
		)
		assert.Equal(
			nil,
			cmdr.err,
		)
		assert.Equal(
			FINISHED,
			cmdr.state,
		)
	})
	wg.Wait()
	assert.Equal(
		0,
		cmdr.GetExitCode(),
	)
	assert.Equal(
		nil,
		cmdr.err,
	)
	assert.Equal(
		FINISHED,
		cmdr.state,
	)
}
<|endoftext|>


<commit_before>package speed

// Instances defines a valid collection of instance name and values
type Instances map[string]interface{}

// pcpInstance wraps a PCP compatible Instance
type pcpInstance struct {
	name   string
	id     uint32
	offset int
}

// newpcpInstance generates a new Instance type based on the passed parameters
// the id is passed explicitly as it is assumed that this will be constructed
// after initializing the InstanceDomain
// this is not a part of the public API as this is not supposed to be used directly,
// but instead added using the AddInstance method of InstanceDomain
func newpcpInstance(name string) *pcpInstance {
	return &pcpInstance{
		name, hash(name, 0), 0,
	}
}

func (i *pcpInstance) String() string {
	return "Instance: " + i.name
}
<commit_msg>instance: make name pcpString to support mmv2<commit_after>package speed

// Instances defines a valid collection of instance name and values
type Instances map[string]interface{}

// pcpInstance wraps a PCP compatible Instance
type pcpInstance struct {
	name   *pcpString
	id     uint32
	offset int
}

// newpcpInstance generates a new Instance type based on the passed parameters
// the id is passed explicitly as it is assumed that this will be constructed
// after initializing the InstanceDomain
// this is not a part of the public API as this is not supposed to be used directly,
// but instead added using the AddInstance method of InstanceDomain
func newpcpInstance(name string) *pcpInstance {
	return &pcpInstance{
		newpcpString(name), hash(name, 0), 0,
	}
}

func (i *pcpInstance) String() string {
	return "Instance: " + i.name.val
}
<|endoftext|>


<commit_before>package sshutil

import (
	"golang.org/x/crypto/ssh/agent"

	"io"
	"net"
	"os"
)

type agentCloser struct {
	agent.Agent
	conn net.Conn
}

type AgentCloser interface {
	agent.Agent
	io.Closer
}

func (ac *agentCloser) Close() error {
	return ac.conn.Close()
}

func DialAgent() (AgentCloser, error) {
	authSock := os.Getenv("SSH_AUTH_SOCK")
	conn, err := net.Dial("unix", authSock)
	if err != nil {
		return nil, err
	}
	return &agentCloser{agent.NewClient(conn), conn}, nil
}
<commit_msg>Delete outdated sshutil package<commit_after><|endoftext|>


<commit_before>package moq

import (
	"errors"
	"fmt"
	"go/ast"
	"go/importer"
	"go/parser"
	"go/token"
	"go/types"
	"io"
	"os"
	"strings"
	"text/template"
)

// Mocker can generate mock structs.
type Mocker struct {
	src     string
	tmpl    *template.Template
	fset    *token.FileSet
	pkgs    map[string]*ast.Package
	pkgName string

	imports map[string]bool
}

// New makes a new Mocker for the specified package directory.
func New(src, packageName string) (*Mocker, error) {
	fset := token.NewFileSet()
	noTestFiles := func(i os.FileInfo) bool {
		return !strings.HasSuffix(i.Name(), "_test.go")
	}
	pkgs, err := parser.ParseDir(fset, src, noTestFiles, parser.SpuriousErrors)
	if err != nil {
		return nil, err
	}
	if len(packageName) == 0 {
		for pkgName := range pkgs {
			if strings.Contains(pkgName, "_test") {
				continue
			}
			packageName = pkgName
			break
		}
	}
	if len(packageName) == 0 {
		return nil, errors.New("failed to determine package name")
	}
	tmpl, err := template.New("moq").Parse(moqTemplate)
	if err != nil {
		return nil, err
	}
	return &Mocker{
		src:     src,
		tmpl:    tmpl,
		fset:    fset,
		pkgs:    pkgs,
		pkgName: packageName,
		imports: make(map[string]bool),
	}, nil
}

// Mock generates a mock for the specified interface name.
func (m *Mocker) Mock(w io.Writer, name ...string) error {
	if len(name) == 0 {
		return errors.New("must specify one interface")
	}
	doc := doc{
		PackageName: m.pkgName,
		Imports:     moqImports,
	}
	for _, pkg := range m.pkgs {
		i := 0
		files := make([]*ast.File, len(pkg.Files))
		for _, file := range pkg.Files {
			files[i] = file
			i++
		}
		conf := types.Config{Importer: importer.Default()}
		tpkg, err := conf.Check(m.src, m.fset, files, nil)
		if err != nil {
			return err
		}
		for _, n := range name {
			iface := tpkg.Scope().Lookup(n)
			if iface == nil {
				return fmt.Errorf("cannot find interface %s", n)
			}
			if !types.IsInterface(iface.Type()) {
				return fmt.Errorf("%s (%s) not an interface", n, iface.Type().String())
			}
			iiface := iface.Type().Underlying().(*types.Interface).Complete()
			obj := obj{
				InterfaceName: n,
			}
			for i := 0; i < iiface.NumMethods(); i++ {
				meth := iiface.Method(i)
				sig := meth.Type().(*types.Signature)
				method := &method{
					Name: meth.Name(),
				}
				obj.Methods = append(obj.Methods, method)
				method.Params = m.extractArgs(sig, sig.Params(), "in%d")
				method.Returns = m.extractArgs(sig, sig.Results(), "out%d")
			}
			doc.Objects = append(doc.Objects, obj)
		}
	}
	for pkgToImport := range m.imports {
		doc.Imports = append(doc.Imports, pkgToImport)
	}
	err := m.tmpl.Execute(w, doc)
	if err != nil {
		return err
	}
	return nil
}

func (m *Mocker) packageQualifier(pkg *types.Package) string {
	if m.pkgName == pkg.Name() {
		return ""
	}
	m.imports[pkg.Path()] = true
	return pkg.Name()
}

func (m *Mocker) extractArgs(sig *types.Signature, list *types.Tuple, nameFormat string) []*param {
	var params []*param
	listLen := list.Len()
	for ii := 0; ii < listLen; ii++ {
		p := list.At(ii)
		name := p.Name()
		if name == "" {
			name = fmt.Sprintf(nameFormat, ii+1)
		}
		typename := types.TypeString(p.Type(), m.packageQualifier)
		// check for final variadic argument
		variadic := sig.Variadic() && ii == listLen-1 && typename[0:2] == "[]"
		param := &param{
			Name:     name,
			Type:     typename,
			Variadic: variadic,
		}
		params = append(params, param)
	}
	return params
}

type doc struct {
	PackageName string
	Objects     []obj
	Imports     []string
}

type obj struct {
	InterfaceName string
	Methods       []*method
}
type method struct {
	Name    string
	Params  []*param
	Returns []*param
}

func (m *method) Arglist() string {
	params := make([]string, len(m.Params))
	for i, p := range m.Params {
		params[i] = p.String()
	}
	return strings.Join(params, ", ")
}

func (m *method) ArgCallList() string {
	params := make([]string, len(m.Params))
	for i, p := range m.Params {
		params[i] = p.CallName()
	}
	return strings.Join(params, ", ")
}

func (m *method) ReturnArglist() string {
	params := make([]string, len(m.Returns))
	for i, p := range m.Returns {
		params[i] = p.TypeString()
	}
	if len(m.Returns) > 1 {
		return fmt.Sprintf("(%s)", strings.Join(params, ", "))
	}
	return strings.Join(params, ", ")
}

type param struct {
	Name     string
	Type     string
	Variadic bool
}

func (p param) String() string {
	return fmt.Sprintf("%s %s", p.Name, p.TypeString())
}

func (p param) CallName() string {
	if p.Variadic {
		return p.Name + "..."
	}
	return p.Name
}

func (p param) TypeString() string {
	if p.Variadic {
		return "..." + p.Type[2:]
	}
	return p.Type
}

// moqImports are the imports all moq files get.
var moqImports = []string{"sync"}

// moqTemplate is the template for mocked code.
var moqTemplate = `package {{.PackageName}}

// AUTOGENERATED BY MOQ
// github.com/matryer/moq

import (
{{- range .Imports }}
	"{{.}}"
{{- end }}
}
{{ range $i, $obj := .Objects }}
// {{.InterfaceName}}Mock is a mock implementation of {{.InterfaceName}}.
//
//     func TestSomethingThatUses{{.InterfaceName}}(t *testing.T) {
//
//         // make and configure a mocked {{.InterfaceName}}
//         mocked{{.InterfaceName}} := &{{.InterfaceName}}Mock{ {{ range .Methods }}
//             {{.Name}}Func: func({{ .Arglist }}) {{.ReturnArglist}} {
// 	               panic("TODO: mock out the {{.Name}} method")
//             },{{- end }}
//         }
//
//         // TODO: use mocked{{.InterfaceName}} in code that requires {{.InterfaceName}}
//         //       and then make assertions.
//
//     }
type {{.InterfaceName}}Mock struct {
{{- range .Methods }}
	// {{.Name}}Func mocks the {{.Name}} method.
	{{.Name}}Func func({{ .Arglist }}) {{.ReturnArglist}}
{{ end }}
	// CallsTo gets counters for each of the methods indicating
	// how many times each one was called.
	CallsTo struct {
		lock sync.Mutex
{{- range .Methods }}
		// {{ .Name }} holds the number of calls to the {{.Name}} method.
		{{ .Name }} int
{{- end }}
	}
}
{{ range .Methods }}
// {{.Name}} calls {{.Name}}Func.
func (mock *{{$obj.InterfaceName}}Mock) {{.Name}}({{.Arglist}}) {{.ReturnArglist}} {
	if mock.{{.Name}}Func == nil {
		panic("moq: {{$obj.InterfaceName}}Mock.{{.Name}}Func is nil but was just called")
	}
	mock.CallsTo.lock.Lock()
	mock.CallsTo.{{.Name}}++
	mock.CallsTo.lock.Unlock()
{{- if .ReturnArglist }}
	return mock.{{.Name}}Func({{.ArgCallList}})
{{- else }}
	mock.{{.Name}}Func({{.ArgCallList}})
{{- end }}
}
{{ end -}}
{{ end -}}`
<commit_msg>fixed typo<commit_after>package moq

import (
	"errors"
	"fmt"
	"go/ast"
	"go/importer"
	"go/parser"
	"go/token"
	"go/types"
	"io"
	"os"
	"strings"
	"text/template"
)

// Mocker can generate mock structs.
type Mocker struct {
	src     string
	tmpl    *template.Template
	fset    *token.FileSet
	pkgs    map[string]*ast.Package
	pkgName string

	imports map[string]bool
}

// New makes a new Mocker for the specified package directory.
func New(src, packageName string) (*Mocker, error) {
	fset := token.NewFileSet()
	noTestFiles := func(i os.FileInfo) bool {
		return !strings.HasSuffix(i.Name(), "_test.go")
	}
	pkgs, err := parser.ParseDir(fset, src, noTestFiles, parser.SpuriousErrors)
	if err != nil {
		return nil, err
	}
	if len(packageName) == 0 {
		for pkgName := range pkgs {
			if strings.Contains(pkgName, "_test") {
				continue
			}
			packageName = pkgName
			break
		}
	}
	if len(packageName) == 0 {
		return nil, errors.New("failed to determine package name")
	}
	tmpl, err := template.New("moq").Parse(moqTemplate)
	if err != nil {
		return nil, err
	}
	return &Mocker{
		src:     src,
		tmpl:    tmpl,
		fset:    fset,
		pkgs:    pkgs,
		pkgName: packageName,
		imports: make(map[string]bool),
	}, nil
}

// Mock generates a mock for the specified interface name.
func (m *Mocker) Mock(w io.Writer, name ...string) error {
	if len(name) == 0 {
		return errors.New("must specify one interface")
	}
	doc := doc{
		PackageName: m.pkgName,
		Imports:     moqImports,
	}
	for _, pkg := range m.pkgs {
		i := 0
		files := make([]*ast.File, len(pkg.Files))
		for _, file := range pkg.Files {
			files[i] = file
			i++
		}
		conf := types.Config{Importer: importer.Default()}
		tpkg, err := conf.Check(m.src, m.fset, files, nil)
		if err != nil {
			return err
		}
		for _, n := range name {
			iface := tpkg.Scope().Lookup(n)
			if iface == nil {
				return fmt.Errorf("cannot find interface %s", n)
			}
			if !types.IsInterface(iface.Type()) {
				return fmt.Errorf("%s (%s) not an interface", n, iface.Type().String())
			}
			iiface := iface.Type().Underlying().(*types.Interface).Complete()
			obj := obj{
				InterfaceName: n,
			}
			for i := 0; i < iiface.NumMethods(); i++ {
				meth := iiface.Method(i)
				sig := meth.Type().(*types.Signature)
				method := &method{
					Name: meth.Name(),
				}
				obj.Methods = append(obj.Methods, method)
				method.Params = m.extractArgs(sig, sig.Params(), "in%d")
				method.Returns = m.extractArgs(sig, sig.Results(), "out%d")
			}
			doc.Objects = append(doc.Objects, obj)
		}
	}
	for pkgToImport := range m.imports {
		doc.Imports = append(doc.Imports, pkgToImport)
	}
	err := m.tmpl.Execute(w, doc)
	if err != nil {
		return err
	}
	return nil
}

func (m *Mocker) packageQualifier(pkg *types.Package) string {
	if m.pkgName == pkg.Name() {
		return ""
	}
	m.imports[pkg.Path()] = true
	return pkg.Name()
}

func (m *Mocker) extractArgs(sig *types.Signature, list *types.Tuple, nameFormat string) []*param {
	var params []*param
	listLen := list.Len()
	for ii := 0; ii < listLen; ii++ {
		p := list.At(ii)
		name := p.Name()
		if name == "" {
			name = fmt.Sprintf(nameFormat, ii+1)
		}
		typename := types.TypeString(p.Type(), m.packageQualifier)
		// check for final variadic argument
		variadic := sig.Variadic() && ii == listLen-1 && typename[0:2] == "[]"
		param := &param{
			Name:     name,
			Type:     typename,
			Variadic: variadic,
		}
		params = append(params, param)
	}
	return params
}

type doc struct {
	PackageName string
	Objects     []obj
	Imports     []string
}

type obj struct {
	InterfaceName string
	Methods       []*method
}
type method struct {
	Name    string
	Params  []*param
	Returns []*param
}

func (m *method) Arglist() string {
	params := make([]string, len(m.Params))
	for i, p := range m.Params {
		params[i] = p.String()
	}
	return strings.Join(params, ", ")
}

func (m *method) ArgCallList() string {
	params := make([]string, len(m.Params))
	for i, p := range m.Params {
		params[i] = p.CallName()
	}
	return strings.Join(params, ", ")
}

func (m *method) ReturnArglist() string {
	params := make([]string, len(m.Returns))
	for i, p := range m.Returns {
		params[i] = p.TypeString()
	}
	if len(m.Returns) > 1 {
		return fmt.Sprintf("(%s)", strings.Join(params, ", "))
	}
	return strings.Join(params, ", ")
}

type param struct {
	Name     string
	Type     string
	Variadic bool
}

func (p param) String() string {
	return fmt.Sprintf("%s %s", p.Name, p.TypeString())
}

func (p param) CallName() string {
	if p.Variadic {
		return p.Name + "..."
	}
	return p.Name
}

func (p param) TypeString() string {
	if p.Variadic {
		return "..." + p.Type[2:]
	}
	return p.Type
}

// moqImports are the imports all moq files get.
var moqImports = []string{"sync"}

// moqTemplate is the template for mocked code.
var moqTemplate = `package {{.PackageName}}

// AUTOGENERATED BY MOQ
// github.com/matryer/moq

import (
{{- range .Imports }}
	"{{.}}"
{{- end }}
)
{{ range $i, $obj := .Objects }}
// {{.InterfaceName}}Mock is a mock implementation of {{.InterfaceName}}.
//
//     func TestSomethingThatUses{{.InterfaceName}}(t *testing.T) {
//
//         // make and configure a mocked {{.InterfaceName}}
//         mocked{{.InterfaceName}} := &{{.InterfaceName}}Mock{ {{ range .Methods }}
//             {{.Name}}Func: func({{ .Arglist }}) {{.ReturnArglist}} {
// 	               panic("TODO: mock out the {{.Name}} method")
//             },{{- end }}
//         }
//
//         // TODO: use mocked{{.InterfaceName}} in code that requires {{.InterfaceName}}
//         //       and then make assertions.
//
//     }
type {{.InterfaceName}}Mock struct {
{{- range .Methods }}
	// {{.Name}}Func mocks the {{.Name}} method.
	{{.Name}}Func func({{ .Arglist }}) {{.ReturnArglist}}
{{ end }}
	// CallsTo gets counters for each of the methods indicating
	// how many times each one was called.
	CallsTo struct {
		lock sync.Mutex
{{- range .Methods }}
		// {{ .Name }} holds the number of calls to the {{.Name}} method.
		{{ .Name }} int
{{- end }}
	}
}
{{ range .Methods }}
// {{.Name}} calls {{.Name}}Func.
func (mock *{{$obj.InterfaceName}}Mock) {{.Name}}({{.Arglist}}) {{.ReturnArglist}} {
	if mock.{{.Name}}Func == nil {
		panic("moq: {{$obj.InterfaceName}}Mock.{{.Name}}Func is nil but was just called")
	}
	mock.CallsTo.lock.Lock()
	mock.CallsTo.{{.Name}}++
	mock.CallsTo.lock.Unlock()
{{- if .ReturnArglist }}
	return mock.{{.Name}}Func({{.ArgCallList}})
{{- else }}
	mock.{{.Name}}Func({{.ArgCallList}})
{{- end }}
}
{{ end -}}
{{ end -}}`
<|endoftext|>


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

package db

import (
	"encoding/json"
	"fmt"
	"runtime"
	"sort"
	"strings"
	"testing"

	"github.com/couchbaselabs/go.assert"
	"github.com/couchbaselabs/sync_gateway/base"
)

var testmap = RevTree{"3-three": {ID: "3-three", Parent: "2-two", Body: []byte("{}")},
					"2-two": {ID: "2-two", Parent: "1-one", Channels: base.SetOf("ABC", "CBS")},
					"1-one": {ID: "1-one", Channels: base.SetOf("ABC")}}
var branchymap = RevTree{"3-three": {ID: "3-three", Parent: "2-two"},
	"2-two":  {ID: "2-two", Parent: "1-one"},
	"1-one":  {ID: "1-one"},
	"3-drei": {ID: "3-drei", Parent: "2-two"}}

const testJSON = `{"revs": ["3-three", "2-two", "1-one"], "parents": [1, 2, -1], "bodies": ["{}", "", ""], "channels": [null, ["ABC", "CBS"], ["ABC"]]}`

func testUnmarshal(t *testing.T, jsonString string) RevTree {
	gotmap := RevTree{}
	assertNoError(t, json.Unmarshal([]byte(jsonString), &gotmap), "Couldn't parse RevTree from JSON")
	assert.DeepEquals(t, gotmap, testmap)
	return gotmap
}

func TestRevTreeUnmarshal(t *testing.T) {
	gotmap := testUnmarshal(t, testJSON)
	fmt.Printf("Unmarshaled to %v\n", gotmap)
}

func TestRevTreeMarshal(t *testing.T) {
	bytes, err := json.Marshal(testmap)
	assertNoError(t, err, "Couldn't write RevTree to JSON")
	fmt.Printf("Marshaled RevTree as %s\n", string(bytes))
	testUnmarshal(t, string(bytes))
}

func TestRevTreeAccess(t *testing.T) {
	assertTrue(t, testmap.contains("3-three"), "contains 3 failed")
	assertTrue(t, testmap.contains("1-one"), "contains 1 failed")
	assertFalse(t, testmap.contains("foo"), "contains false positive")
}

func TestRevTreeParentAccess(t *testing.T) {
	parent := testmap.getParent("3-three")
	assert.Equals(t, parent, "2-two")
	parent = testmap.getParent("1-one")
	assert.Equals(t, parent, "")
}

func TestRevTreeGetHistory(t *testing.T) {
	history := testmap.getHistory("3-three")
	assert.DeepEquals(t, history, []string{"3-three", "2-two", "1-one"})
}

func TestRevTreeGetLeaves(t *testing.T) {
	leaves := testmap.getLeaves()
	assert.DeepEquals(t, leaves, []string{"3-three"})
	leaves = branchymap.getLeaves()
	sort.Strings(leaves)
	assert.DeepEquals(t, leaves, []string{"3-drei", "3-three"})
}

func TestRevTreeForEachLeaf(t *testing.T) {
	var leaves []string
	branchymap.forEachLeaf(func(rev *RevInfo) {
		leaves = append(leaves, rev.ID)
	})
	sort.Strings(leaves)
	assert.DeepEquals(t, leaves, []string{"3-drei", "3-three"})
}

func TestRevTreeAddRevision(t *testing.T) {
	tempmap := testmap.copy()
	assert.DeepEquals(t, tempmap, testmap)

	tempmap.addRevision(RevInfo{ID: "4-four", Parent: "3-three"})
	assert.Equals(t, tempmap.getParent("4-four"), "3-three")
}

func TestRevTreeCompareRevIDs(t *testing.T) {
	assert.Equals(t, compareRevIDs("1-aaa", "1-aaa"), 0)
	assert.Equals(t, compareRevIDs("1-aaa", "5-aaa"), -1)
	assert.Equals(t, compareRevIDs("10-aaa", "5-aaa"), 1)
	assert.Equals(t, compareRevIDs("1-bbb", "1-aaa"), 1)
	assert.Equals(t, compareRevIDs("5-bbb", "1-zzz"), 1)
}

func TestRevTreeIsLeaf(t *testing.T) {
	assertTrue(t, branchymap.isLeaf("3-three"), "isLeaf failed on 3-three")
	assertTrue(t, branchymap.isLeaf("3-drei"), "isLeaf failed on 3-drei")
	assertFalse(t, branchymap.isLeaf("2-two"), "isLeaf failed on 2-two")
	assertFalse(t, branchymap.isLeaf("bogus"), "isLeaf failed on 'bogus")
	assertFalse(t, branchymap.isLeaf(""), "isLeaf failed on ''")
}

func TestRevTreeWinningRev(t *testing.T) {
	tempmap := branchymap.copy()
	winner, branched, conflict := tempmap.winningRevision()
	assert.Equals(t, winner, "3-three")
	assert.True(t, branched)
	assert.True(t, conflict)
	tempmap.addRevision(RevInfo{ID: "4-four", Parent: "3-three"})
	winner, branched, conflict = tempmap.winningRevision()
	assert.Equals(t, winner, "4-four")
	assert.True(t, branched)
	assert.True(t, conflict)
	tempmap.addRevision(RevInfo{ID: "5-five", Parent: "4-four", Deleted: true})
	winner, branched, conflict = tempmap.winningRevision()
	assert.Equals(t, winner, "3-drei")
	assert.True(t, branched)
	assert.False(t, conflict)
}

func TestRevTreeDepths(t *testing.T) {
	tempmap := testmap.copy()
	tempmap.computeDepths()
	assert.Equals(t, tempmap["3-three"].depth, uint32(1))
	assert.Equals(t, tempmap["2-two"].depth, uint32(2))
	assert.Equals(t, tempmap["1-one"].depth, uint32(3))

	tempmap = branchymap.copy()
	tempmap.computeDepths()
	assert.Equals(t, tempmap["3-three"].depth, uint32(1))
	assert.Equals(t, tempmap["3-drei"].depth, uint32(1))
	assert.Equals(t, tempmap["2-two"].depth, uint32(2))
	assert.Equals(t, tempmap["1-one"].depth, uint32(3))

	tempmap["4-vier"] = &RevInfo{ID: "4-vier", Parent: "3-drei"}
	tempmap.computeDepths()
	assert.Equals(t, tempmap["4-vier"].depth, uint32(1))
	assert.Equals(t, tempmap["3-drei"].depth, uint32(2))
	assert.Equals(t, tempmap["3-three"].depth, uint32(1))
	assert.Equals(t, tempmap["2-two"].depth, uint32(2))
	assert.Equals(t, tempmap["1-one"].depth, uint32(3))

	// Prune:
	assert.Equals(t, tempmap.pruneRevisions(1000), 0)
	assert.Equals(t, tempmap.pruneRevisions(3), 0)
	assert.Equals(t, tempmap.pruneRevisions(2), 1)
	assert.Equals(t, len(tempmap), 4)
	assert.Equals(t, tempmap["1-one"], (*RevInfo)(nil))
	assert.Equals(t, tempmap["2-two"].Parent, "")

	// Make sure leaves are never pruned:
	assert.Equals(t, tempmap.pruneRevisions(1), 2)
	assert.Equals(t, len(tempmap), 2)
	assert.True(t, tempmap["3-three"] != nil)
	assert.Equals(t, tempmap["3-three"].Parent, "")
	assert.True(t, tempmap["4-vier"] != nil)
	assert.Equals(t, tempmap["4-vier"].Parent, "")
}

func TestParseRevisions(t *testing.T) {
	type testCase struct {
		json string
		ids  []string
	}
	cases := []testCase{
		{`{"_revisions": {"start": 5, "ids": ["huey", "dewey", "louie"]}}`,
			[]string{"5-huey", "4-dewey", "3-louie"}},
		{`{"_revisions": {"start": 3, "ids": ["huey"]}}`,
			[]string{"3-huey"}},
		{`{"_revisions": {"start": 2, "ids": ["huey", "dewey", "louie"]}}`, nil},
		{`{"_revisions": {"ids": ["huey", "dewey", "louie"]}}`, nil},
		{`{"_revisions": {"ids": "bogus"}}`, nil},
		{`{"_revisions": {"start": 2}}`, nil},
		{`{"_revisions": {"start": "", "ids": ["huey", "dewey", "louie"]}}`, nil},
		{`{"_revisions": 3.14159}`, nil},
		{`{"_Xrevisions": {"start": "", "ids": ["huey", "dewey", "louie"]}}`, nil},
	}
	for _, c := range cases {
		var body Body
		assertNoError(t, json.Unmarshal([]byte(c.json), &body), "base JSON in test case")
		ids := ParseRevisions(body)
		assert.DeepEquals(t, ids, c.ids)
	}
}

//////// HELPERS:

func assertFailed(t *testing.T, message string) {
	_, file, line, ok := runtime.Caller(2) // assertFailed + assertNoError + public function.
	if ok {
		// Truncate file name at last file name separator.
		if index := strings.LastIndex(file, "/"); index >= 0 {
			file = file[index+1:]
		} else if index = strings.LastIndex(file, "\\"); index >= 0 {
			file = file[index+1:]
		}
	} else {
		file = "???"
		line = 1
	}
	t.Fatalf("%s:%d: %s", file, line, message)
}

func assertNoError(t *testing.T, err error, message string) {
	if err != nil {
		assertFailed(t, fmt.Sprintf("%s: %v", message, err))
	}
}

func assertTrue(t *testing.T, success bool, message string) {
	if !success {
		assertFailed(t, message)
	}
}

func assertFalse(t *testing.T, failure bool, message string) {
	if failure {
		assertFailed(t, message)
	}
}
<commit_msg>add test for CouchDB _rev parsing<commit_after>//  Copyright (c) 2012 Couchbase, Inc.
//  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
//  except in compliance with the License. You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//  Unless required by applicable law or agreed to in writing, software distributed under the
//  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
//  either express or implied. See the License for the specific language governing permissions
//  and limitations under the License.

package db

import (
	"encoding/json"
	"fmt"
	"runtime"
	"sort"
	"strings"
	"testing"

	"github.com/couchbaselabs/go.assert"
	"github.com/couchbaselabs/sync_gateway/base"
)

var testmap = RevTree{"3-three": {ID: "3-three", Parent: "2-two", Body: []byte("{}")},
					"2-two": {ID: "2-two", Parent: "1-one", Channels: base.SetOf("ABC", "CBS")},
					"1-one": {ID: "1-one", Channels: base.SetOf("ABC")}}
var branchymap = RevTree{"3-three": {ID: "3-three", Parent: "2-two"},
	"2-two":  {ID: "2-two", Parent: "1-one"},
	"1-one":  {ID: "1-one"},
	"3-drei": {ID: "3-drei", Parent: "2-two"}}

const testJSON = `{"revs": ["3-three", "2-two", "1-one"], "parents": [1, 2, -1], "bodies": ["{}", "", ""], "channels": [null, ["ABC", "CBS"], ["ABC"]]}`

func testUnmarshal(t *testing.T, jsonString string) RevTree {
	gotmap := RevTree{}
	assertNoError(t, json.Unmarshal([]byte(jsonString), &gotmap), "Couldn't parse RevTree from JSON")
	assert.DeepEquals(t, gotmap, testmap)
	return gotmap
}

func TestRevTreeUnmarshal(t *testing.T) {
	gotmap := testUnmarshal(t, testJSON)
	fmt.Printf("Unmarshaled to %v\n", gotmap)
}

func TestRevTreeMarshal(t *testing.T) {
	bytes, err := json.Marshal(testmap)
	assertNoError(t, err, "Couldn't write RevTree to JSON")
	fmt.Printf("Marshaled RevTree as %s\n", string(bytes))
	testUnmarshal(t, string(bytes))
}

func TestRevTreeAccess(t *testing.T) {
	assertTrue(t, testmap.contains("3-three"), "contains 3 failed")
	assertTrue(t, testmap.contains("1-one"), "contains 1 failed")
	assertFalse(t, testmap.contains("foo"), "contains false positive")
}

func TestRevTreeParentAccess(t *testing.T) {
	parent := testmap.getParent("3-three")
	assert.Equals(t, parent, "2-two")
	parent = testmap.getParent("1-one")
	assert.Equals(t, parent, "")
}

func TestRevTreeGetHistory(t *testing.T) {
	history := testmap.getHistory("3-three")
	assert.DeepEquals(t, history, []string{"3-three", "2-two", "1-one"})
}

func TestRevTreeGetLeaves(t *testing.T) {
	leaves := testmap.getLeaves()
	assert.DeepEquals(t, leaves, []string{"3-three"})
	leaves = branchymap.getLeaves()
	sort.Strings(leaves)
	assert.DeepEquals(t, leaves, []string{"3-drei", "3-three"})
}

func TestRevTreeForEachLeaf(t *testing.T) {
	var leaves []string
	branchymap.forEachLeaf(func(rev *RevInfo) {
		leaves = append(leaves, rev.ID)
	})
	sort.Strings(leaves)
	assert.DeepEquals(t, leaves, []string{"3-drei", "3-three"})
}

func TestRevTreeAddRevision(t *testing.T) {
	tempmap := testmap.copy()
	assert.DeepEquals(t, tempmap, testmap)

	tempmap.addRevision(RevInfo{ID: "4-four", Parent: "3-three"})
	assert.Equals(t, tempmap.getParent("4-four"), "3-three")
}

func TestRevTreeCompareRevIDs(t *testing.T) {
	assert.Equals(t, compareRevIDs("1-aaa", "1-aaa"), 0)
	assert.Equals(t, compareRevIDs("1-aaa", "5-aaa"), -1)
	assert.Equals(t, compareRevIDs("10-aaa", "5-aaa"), 1)
	assert.Equals(t, compareRevIDs("1-bbb", "1-aaa"), 1)
	assert.Equals(t, compareRevIDs("5-bbb", "1-zzz"), 1)
}

func TestRevTreeIsLeaf(t *testing.T) {
	assertTrue(t, branchymap.isLeaf("3-three"), "isLeaf failed on 3-three")
	assertTrue(t, branchymap.isLeaf("3-drei"), "isLeaf failed on 3-drei")
	assertFalse(t, branchymap.isLeaf("2-two"), "isLeaf failed on 2-two")
	assertFalse(t, branchymap.isLeaf("bogus"), "isLeaf failed on 'bogus")
	assertFalse(t, branchymap.isLeaf(""), "isLeaf failed on ''")
}

func TestRevTreeWinningRev(t *testing.T) {
	tempmap := branchymap.copy()
	winner, branched, conflict := tempmap.winningRevision()
	assert.Equals(t, winner, "3-three")
	assert.True(t, branched)
	assert.True(t, conflict)
	tempmap.addRevision(RevInfo{ID: "4-four", Parent: "3-three"})
	winner, branched, conflict = tempmap.winningRevision()
	assert.Equals(t, winner, "4-four")
	assert.True(t, branched)
	assert.True(t, conflict)
	tempmap.addRevision(RevInfo{ID: "5-five", Parent: "4-four", Deleted: true})
	winner, branched, conflict = tempmap.winningRevision()
	assert.Equals(t, winner, "3-drei")
	assert.True(t, branched)
	assert.False(t, conflict)
}

func TestRevTreeDepths(t *testing.T) {
	tempmap := testmap.copy()
	tempmap.computeDepths()
	assert.Equals(t, tempmap["3-three"].depth, uint32(1))
	assert.Equals(t, tempmap["2-two"].depth, uint32(2))
	assert.Equals(t, tempmap["1-one"].depth, uint32(3))

	tempmap = branchymap.copy()
	tempmap.computeDepths()
	assert.Equals(t, tempmap["3-three"].depth, uint32(1))
	assert.Equals(t, tempmap["3-drei"].depth, uint32(1))
	assert.Equals(t, tempmap["2-two"].depth, uint32(2))
	assert.Equals(t, tempmap["1-one"].depth, uint32(3))

	tempmap["4-vier"] = &RevInfo{ID: "4-vier", Parent: "3-drei"}
	tempmap.computeDepths()
	assert.Equals(t, tempmap["4-vier"].depth, uint32(1))
	assert.Equals(t, tempmap["3-drei"].depth, uint32(2))
	assert.Equals(t, tempmap["3-three"].depth, uint32(1))
	assert.Equals(t, tempmap["2-two"].depth, uint32(2))
	assert.Equals(t, tempmap["1-one"].depth, uint32(3))

	// Prune:
	assert.Equals(t, tempmap.pruneRevisions(1000), 0)
	assert.Equals(t, tempmap.pruneRevisions(3), 0)
	assert.Equals(t, tempmap.pruneRevisions(2), 1)
	assert.Equals(t, len(tempmap), 4)
	assert.Equals(t, tempmap["1-one"], (*RevInfo)(nil))
	assert.Equals(t, tempmap["2-two"].Parent, "")

	// Make sure leaves are never pruned:
	assert.Equals(t, tempmap.pruneRevisions(1), 2)
	assert.Equals(t, len(tempmap), 2)
	assert.True(t, tempmap["3-three"] != nil)
	assert.Equals(t, tempmap["3-three"].Parent, "")
	assert.True(t, tempmap["4-vier"] != nil)
	assert.Equals(t, tempmap["4-vier"].Parent, "")
}

func TestParseRevisions(t *testing.T) {
	type testCase struct {
		json string
		ids  []string
	}
	cases := []testCase{
		{`{"_revisions": {"start": 5, "ids": ["huey", "dewey", "louie"]}}`,
			[]string{"5-huey", "4-dewey", "3-louie"}},
		{`{"_revisions": {"start": 3, "ids": ["huey"]}}`,
			[]string{"3-huey"}},
		{`{"_rev": "3-huey"}`,
			[]string{"3-huey"}},
		{`{"_revisions": {"start": 2, "ids": ["huey", "dewey", "louie"]}}`, nil},
		{`{"_revisions": {"ids": ["huey", "dewey", "louie"]}}`, nil},
		{`{"_revisions": {"ids": "bogus"}}`, nil},
		{`{"_revisions": {"start": 2}}`, nil},
		{`{"_revisions": {"start": "", "ids": ["huey", "dewey", "louie"]}}`, nil},
		{`{"_revisions": 3.14159}`, nil},
		{`{"_rev": 3.14159}`, nil},
		{`{"_rev": "x-14159"}`, nil},
		{`{"_Xrevisions": {"start": "", "ids": ["huey", "dewey", "louie"]}}`, nil},
	}
	for _, c := range cases {
		var body Body
		assertNoError(t, json.Unmarshal([]byte(c.json), &body), "base JSON in test case")
		ids := ParseRevisions(body)
		assert.DeepEquals(t, ids, c.ids)
	}
}

//////// HELPERS:

func assertFailed(t *testing.T, message string) {
	_, file, line, ok := runtime.Caller(2) // assertFailed + assertNoError + public function.
	if ok {
		// Truncate file name at last file name separator.
		if index := strings.LastIndex(file, "/"); index >= 0 {
			file = file[index+1:]
		} else if index = strings.LastIndex(file, "\\"); index >= 0 {
			file = file[index+1:]
		}
	} else {
		file = "???"
		line = 1
	}
	t.Fatalf("%s:%d: %s", file, line, message)
}

func assertNoError(t *testing.T, err error, message string) {
	if err != nil {
		assertFailed(t, fmt.Sprintf("%s: %v", message, err))
	}
}

func assertTrue(t *testing.T, success bool, message string) {
	if !success {
		assertFailed(t, message)
	}
}

func assertFalse(t *testing.T, failure bool, message string) {
	if failure {
		assertFailed(t, message)
	}
}
<|endoftext|>


<commit_before>package redis

import (
	"context"
	"sync"
)

// ScanIterator is used to incrementally iterate over a collection of elements.
// It's safe for concurrent use by multiple goroutines.
type ScanIterator struct {
	mu  sync.Mutex // protects Scanner and pos
	cmd *ScanCmd
	pos int
}

// Err returns the last iterator error, if any.
func (it *ScanIterator) Err() error {
	it.mu.Lock()
	err := it.cmd.Err()
	it.mu.Unlock()
	return err
}

// Next advances the cursor and returns true if more values can be read.
func (it *ScanIterator) Next(ctx context.Context) bool {
	it.mu.Lock()
	defer it.mu.Unlock()

	// Instantly return on errors.
	if it.cmd.Err() != nil {
		return false
	}

	// Advance cursor, check if we are still within range.
	if it.pos < len(it.cmd.page) {
		it.pos++
		return true
	}

	for {
		// Return if there is no more data to fetch.
		if it.cmd.cursor == 0 {
			return false
		}

		// Fetch next page.
		switch it.cmd.args[0] {
		case "scan", "qscan":
			it.cmd.args[1] = it.cmd.cursor
		default:
			it.cmd.args[2] = it.cmd.cursor
		}

		err := it.cmd.process(ctx, it.cmd)
		if err != nil {
			return false
		}

		it.pos = 1

		// Redis can occasionally return empty page.
		if len(it.cmd.page) > 0 {
			return true
		}
	}
}

// Val returns the key/field at the current cursor position.
func (it *ScanIterator) Val() string {
	var v string
	it.mu.Lock()
	if it.cmd.Err() == nil && it.pos > 0 && it.pos <= len(it.cmd.page) {
		v = it.cmd.page[it.pos-1]
	}
	it.mu.Unlock()
	return v
}
<commit_msg>fix: remove iterator mutex as it's not needed<commit_after>package redis

import (
	"context"
)

// ScanIterator is used to incrementally iterate over a collection of elements.
type ScanIterator struct {
	cmd *ScanCmd
	pos int
}

// Err returns the last iterator error, if any.
func (it *ScanIterator) Err() error {
	return it.cmd.Err()
}

// Next advances the cursor and returns true if more values can be read.
func (it *ScanIterator) Next(ctx context.Context) bool {
	// Instantly return on errors.
	if it.cmd.Err() != nil {
		return false
	}

	// Advance cursor, check if we are still within range.
	if it.pos < len(it.cmd.page) {
		it.pos++
		return true
	}

	for {
		// Return if there is no more data to fetch.
		if it.cmd.cursor == 0 {
			return false
		}

		// Fetch next page.
		switch it.cmd.args[0] {
		case "scan", "qscan":
			it.cmd.args[1] = it.cmd.cursor
		default:
			it.cmd.args[2] = it.cmd.cursor
		}

		err := it.cmd.process(ctx, it.cmd)
		if err != nil {
			return false
		}

		it.pos = 1

		// Redis can occasionally return empty page.
		if len(it.cmd.page) > 0 {
			return true
		}
	}
}

// Val returns the key/field at the current cursor position.
func (it *ScanIterator) Val() string {
	var v string
	if it.cmd.Err() == nil && it.pos > 0 && it.pos <= len(it.cmd.page) {
		v = it.cmd.page[it.pos-1]
	}
	return v
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/fsouza/go-dockerclient"
	"github.com/gorilla/mux"
	"net/http"
	"strconv"
)

type MyServer struct {
	r *mux.Router
}

type postParams struct {
	Id   string
	Port int64
}

var endpoint = "unix:///var/run/docker.sock"
var client, _ = docker.NewClient(endpoint)

//wrap server handler function to activate CORS
func (s *MyServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	if origin := req.Header.Get("Origin"); origin != "" {
		rw.Header().Set("Access-Control-Allow-Origin", origin)
		rw.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
		rw.Header().Set("Access-Control-Allow-Headers",
			"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
		rw.Header().Set("Access-Control-Allow-Headers", "X-Requested-With")
	}
	// Stop here if its Preflighted OPTIONS request
	if req.Method == "OPTIONS" {
		return
	}
	// Lets Gorilla work
	s.r.ServeHTTP(rw, req)
}

func main() {
	ip := ""
	port := "7777"
	path := "./static/"

	receive := ip + ":" + port
	fmt.Println("server listen on : %s\n", receive)

	r := mux.NewRouter()
	// r.HandleFunc("/", HelloHandler)
	//serv staticly index.html
	fs := http.FileServer(http.Dir(path))
	r.Handle("/", fs)
	r.HandleFunc("/containers", getContainerHandler).Methods("GET")
	r.HandleFunc("/containers", createContainerHandler).Methods("Post")
	r.HandleFunc("/containers/{idContainer}/pause", pauseContainer)
	r.HandleFunc("/containers/{idContainer}/unpause", unpauseContainer)
	r.HandleFunc("/containers/{idContainer}/stop", stopContainer)

	http.Handle("/", &MyServer{r})

	http.ListenAndServe(receive, nil)
}

func getContainerHandler(w http.ResponseWriter, req *http.Request) {
	fmt.Println("on fait un gros GET")

	containers, _ := client.ListContainers(docker.ListContainersOptions{All: false})
	b, err := json.Marshal(containers)
	if err != nil {
		http.Error(w, err.Error(), 500)
	}
	fmt.Fprintf(w, "%s", b)

}

func createContainerHandler(w http.ResponseWriter, req *http.Request) {
	fmt.Println("on fait un gros POST")

	decoder := json.NewDecoder(req.Body)
	var parameters postParams
	err := decoder.Decode(&parameters)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	fmt.Println(parameters)
	// id := "truc"
	opts := docker.CreateContainerOptions{
		Name: parameters.Id,
		Config: &docker.Config{

			PortSpecs: []string{
				"4444:4321",
				"4444:4321/udp",
			},
			Cmd:   []string{"-s", "/static/"},
			Image: "tgermain/repo_sky:latest",
		},
	}
	container, err := client.CreateContainer(opts)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	err2 := client.StartContainer(container.ID, &docker.HostConfig{
		NetworkMode: "bridge",
		PortBindings: map[docker.Port][]docker.PortBinding{
			"4321/tcp": []docker.PortBinding{
				docker.PortBinding{
					HostPort: strconv.FormatInt(parameters.Port, 10),
				},
			},
			"4321/udp": []docker.PortBinding{
				docker.PortBinding{
					HostPort: strconv.FormatInt(parameters.Port, 10),
				},
			},
		},
	})
	if err2 != nil {
		http.Error(w, err2.Error(), 500)
		return
	}

}

func pauseContainer(w http.ResponseWriter, req *http.Request) {
	//get the url param
	params := mux.Vars(req)
	idContainer := params["idContainer"]
	err := client.PauseContainer(idContainer)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

}

func unpauseContainer(w http.ResponseWriter, req *http.Request) {
	//get the url param
	params := mux.Vars(req)
	idContainer := params["idContainer"]
	err := client.UnpauseContainer(idContainer)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

}

func stopContainer(w http.ResponseWriter, req *http.Request) {
	//get the url param
	params := mux.Vars(req)
	idContainer := params["idContainer"]
	err := client.StopContainer(idContainer, 5)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

}
<commit_msg>add another road to get information of a node (inside a container<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/fsouza/go-dockerclient"
	"github.com/gorilla/mux"
	"io/ioutil"
	"net/http"
	"strconv"
)

type MyServer struct {
	r *mux.Router
}

type postParams struct {
	Id   string
	Port int64
}

var endpoint = "unix:///var/run/docker.sock"
var client, _ = docker.NewClient(endpoint)

//wrap server handler function to activate CORS
func (s *MyServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	if origin := req.Header.Get("Origin"); origin != "" {
		rw.Header().Set("Access-Control-Allow-Origin", origin)
		rw.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
		rw.Header().Set("Access-Control-Allow-Headers",
			"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
		rw.Header().Set("Access-Control-Allow-Headers", "X-Requested-With")
	}
	// Stop here if its Preflighted OPTIONS request
	if req.Method == "OPTIONS" {
		return
	}
	// Lets Gorilla work
	s.r.ServeHTTP(rw, req)
}

func main() {
	ip := ""
	port := "7777"
	path := "./static/"

	receive := ip + ":" + port
	fmt.Println("server listen on : %s\n", receive)

	r := mux.NewRouter()
	// r.HandleFunc("/", HelloHandler)
	//serv staticly index.html
	fs := http.FileServer(http.Dir(path))
	r.Handle("/", fs)
	r.HandleFunc("/containers", getContainerHandler).Methods("GET")
	r.HandleFunc("/containers", createContainerHandler).Methods("Post")
	r.HandleFunc("/containers/{idContainer}/pause", pauseContainer)
	r.HandleFunc("/containers/{idContainer}/unpause", unpauseContainer)
	r.HandleFunc("/containers/{idContainer}/stop", stopContainer)
	r.HandleFunc("/containers/{idContainer}/info", getContainerInfo)

	http.Handle("/", &MyServer{r})

	http.ListenAndServe(receive, nil)
}

func getContainerInfo(w http.ResponseWriter, req *http.Request) {
	//get the url param
	params := mux.Vars(req)
	idContainer := params["idContainer"]
	container, err := client.InspectContainer(idContainer)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	// container.NetworkSettings.PortMappingAPI()[0]
	fmt.Println(container.NetworkSettings.PortMappingAPI()[0])
	resp, err2 := http.Get("http://" +
		container.NetworkSettings.PortMappingAPI()[0].IP +
		":" +
		strconv.FormatInt(container.NetworkSettings.PortMappingAPI()[0].PublicPort, 10) +
		"/nodes")
	if err2 != nil {
		http.Error(w, err2.Error(), 500)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	fmt.Fprintf(w, "%s", body)
}

func getContainerHandler(w http.ResponseWriter, req *http.Request) {
	fmt.Println("on fait un gros GET")

	containers, _ := client.ListContainers(docker.ListContainersOptions{All: false})
	b, err := json.Marshal(containers)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	fmt.Fprintf(w, "%s", b)

}

func createContainerHandler(w http.ResponseWriter, req *http.Request) {
	fmt.Println("on fait un gros POST")

	decoder := json.NewDecoder(req.Body)
	var parameters postParams
	err := decoder.Decode(&parameters)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	fmt.Println(parameters)
	// id := "truc"
	opts := docker.CreateContainerOptions{
		Name: parameters.Id,
		Config: &docker.Config{

			PortSpecs: []string{
				"4444:4321",
				"4444:4321/udp",
			},
			Cmd:   []string{"-s", "/static/"},
			Image: "tgermain/repo_sky:latest",
		},
	}
	container, err := client.CreateContainer(opts)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	err2 := client.StartContainer(container.ID, &docker.HostConfig{
		NetworkMode: "bridge",
		PortBindings: map[docker.Port][]docker.PortBinding{
			"4321/tcp": []docker.PortBinding{
				docker.PortBinding{
					HostPort: strconv.FormatInt(parameters.Port, 10),
				},
			},
			"4321/udp": []docker.PortBinding{
				docker.PortBinding{
					HostPort: strconv.FormatInt(parameters.Port, 10),
				},
			},
		},
	})
	if err2 != nil {
		http.Error(w, err2.Error(), 500)
		return
	}

}

func pauseContainer(w http.ResponseWriter, req *http.Request) {
	//get the url param
	params := mux.Vars(req)
	idContainer := params["idContainer"]
	err := client.PauseContainer(idContainer)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

}

func unpauseContainer(w http.ResponseWriter, req *http.Request) {
	//get the url param
	params := mux.Vars(req)
	idContainer := params["idContainer"]
	err := client.UnpauseContainer(idContainer)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

}

func stopContainer(w http.ResponseWriter, req *http.Request) {
	//get the url param
	params := mux.Vars(req)
	idContainer := params["idContainer"]
	err := client.StopContainer(idContainer, 5)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

}
<|endoftext|>


<commit_before>package dockerguard

type Container struct {
	Id       string
	Hostname string
}
<commit_msg>Add DockerInfo & DockerVersion struct<commit_after>package dockerguard

type DockerInfo struct {
	Containers         int         `json:"Containers"`
	Debug              int         `json:"Debug"`
	DockerRootDir      string      `json:"DockerRootDir"`
	Driver             string      `json:"Driver"`
	DriverStatus       [][]string  `json:"DriverStatus"`
	ExecutionDriver    string      `json:"ExecutionDriver"`
	ID                 string      `json:"ID"`
	IPv4Forwarding     int         `json:"IPv4Forwarding"`
	Images             int         `json:"Images"`
	IndexServerAddress string      `json:"IndexServerAddress"`
	InitPath           string      `json:"InitPath"`
	InitSha1           string      `json:"InitSha1"`
	KernelVersion      string      `json:"KernelVersion"`
	Labels             interface{} `json:"Labels"`
	MemTotal           int         `json:"MemTotal"`
	MemoryLimit        int         `json:"MemoryLimit"`
	NCPU               int         `json:"NCPU"`
	NEventsListener    int         `json:"NEventsListener"`
	NFd                int         `json:"NFd"`
	NGoroutines        int         `json:"NGoroutines"`
	Name               string      `json:"Name"`
	OperatingSystem    string      `json:"OperatingSystem"`
	RegistryConfig     struct {
		IndexConfigs struct {
			Docker_io struct {
				Mirrors  interface{} `json:"Mirrors"`
				Name     string      `json:"Name"`
				Official bool        `json:"Official"`
				Secure   bool        `json:"Secure"`
			} `json:"docker.io"`
		} `json:"IndexConfigs"`
		InsecureRegistryCIDRs []string `json:"InsecureRegistryCIDRs"`
	} `json:"RegistryConfig"`
	SwapLimit  int    `json:"SwapLimit"`
	SystemTime string `json:"SystemTime"`
}

type DockerVersion struct {
	APIVersion    string `json:"ApiVersion"`
	Arch          string `json:"Arch"`
	Experimental  bool   `json:"Experimental"`
	GitCommit     string `json:"GitCommit"`
	GoVersion     string `json:"GoVersion"`
	KernelVersion string `json:"KernelVersion"`
	Os            string `json:"Os"`
	Version       string `json:"Version"`
}
<|endoftext|>


<commit_before>package openapi3

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/url"
	"strings"

	"github.com/ghodss/yaml"
)

func foundUnresolvedRef(ref string) error {
	return fmt.Errorf("Found unresolved ref: '%s'", ref)
}

func failedToResolveRefFragment(value string) error {
	return fmt.Errorf("Failed to resolve fragment in URI: '%s'", value)
}

func failedToResolveRefFragmentPart(value string, what string) error {
	return fmt.Errorf("Failed to resolve '%s' in fragment in URI: '%s'", what, value)
}

type SwaggerLoader struct {
	IsExternalRefsAllowed  bool
	Context                context.Context
	LoadSwaggerFromURIFunc func(loader *SwaggerLoader, url *url.URL) (*Swagger, error)
	visited                map[interface{}]struct{}
}

func NewSwaggerLoader() *SwaggerLoader {
	return &SwaggerLoader{}
}

func (swaggerLoader *SwaggerLoader) LoadSwaggerFromURI(location *url.URL) (*Swagger, error) {
	f := swaggerLoader.LoadSwaggerFromURIFunc
	if f != nil {
		return f(swaggerLoader, location)
	}
	if location.Scheme != "" || location.Host != "" || location.RawQuery != "" {
		return nil, fmt.Errorf("Unsupported URI: '%s'", location.String())
	}
	data, err := ioutil.ReadFile(location.Path)
	if err != nil {
		return nil, err
	}
	return swaggerLoader.LoadSwaggerFromData(data)
}

func (swaggerLoader *SwaggerLoader) LoadSwaggerFromFile(path string) (*Swagger, error) {
	f := swaggerLoader.LoadSwaggerFromURIFunc
	if f != nil {
		return f(swaggerLoader, &url.URL{
			Path: path,
		})
	}
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	return swaggerLoader.LoadSwaggerFromData(data)
}

func (swaggerLoader *SwaggerLoader) LoadSwaggerFromData(data []byte) (*Swagger, error) {
	swagger := &Swagger{}
	if err := json.Unmarshal(data, swagger); err != nil {
		return nil, err
	}
	return swagger, swaggerLoader.ResolveRefsIn(swagger)
}

func (swaggerLoader *SwaggerLoader) LoadSwaggerFromYAMLData(data []byte) (*Swagger, error) {
	swagger := &Swagger{}
	if err := yaml.Unmarshal(data, swagger); err != nil {
		return nil, err
	}
	return swagger, swaggerLoader.ResolveRefsIn(swagger)
}

func (swaggerLoader *SwaggerLoader) ResolveRefsIn(swagger *Swagger) (err error) {
	swaggerLoader.visited = make(map[interface{}]struct{})

	// Visit all components
	components := swagger.Components
	for _, component := range components.Headers {
		if err = swaggerLoader.resolveHeaderRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.Parameters {
		if err = swaggerLoader.resolveParameterRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.RequestBodies {
		if err = swaggerLoader.resolveRequestBodyRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.Responses {
		if err = swaggerLoader.resolveResponseRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.Schemas {
		if err = swaggerLoader.resolveSchemaRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.SecuritySchemes {
		if err = swaggerLoader.resolveSecuritySchemeRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.Examples {
		if err = swaggerLoader.resolveExampleRef(swagger, component); err != nil {
			return
		}
	}

	// Visit all operations
	for _, pathItem := range swagger.Paths {
		if pathItem == nil {
			continue
		}
		for _, parameter := range pathItem.Parameters {
			if err = swaggerLoader.resolveParameterRef(swagger, parameter); err != nil {
				return
			}
		}
		for _, operation := range pathItem.Operations() {
			for _, parameter := range operation.Parameters {
				if err = swaggerLoader.resolveParameterRef(swagger, parameter); err != nil {
					return
				}
			}
			if requestBody := operation.RequestBody; requestBody != nil {
				if err = swaggerLoader.resolveRequestBodyRef(swagger, requestBody); err != nil {
					return
				}
			}
			for _, response := range operation.Responses {
				if err = swaggerLoader.resolveResponseRef(swagger, response); err != nil {
					return
				}
			}
		}
	}

	return
}

func (swaggerLoader *SwaggerLoader) resolveComponent(swagger *Swagger, ref string, prefix string) (
	components *Components,
	id string,
	err error,
) {
	if !strings.HasPrefix(ref, "#") {
		if !swaggerLoader.IsExternalRefsAllowed {
			return nil, "", fmt.Errorf("Encountered non-allowed external reference: '%s'", ref)
		}
		parsedURL, err := url.Parse(ref)
		if err != nil {
			return nil, "", fmt.Errorf("Can't parse reference: '%s': %v", ref, parsedURL)
		}
		fragment := parsedURL.Fragment
		parsedURL.Fragment = ""
		if swagger, err = swaggerLoader.LoadSwaggerFromURI(parsedURL); err != nil {
			return nil, "", fmt.Errorf("Error while resolving reference '%s': %v", ref, err)
		}
		ref = fmt.Sprintf("#%s", fragment)
	}
	if !strings.HasPrefix(ref, prefix) {
		err := fmt.Errorf("expected prefix '%s' in URI '%s'", prefix, ref)
		return nil, "", err
	}
	id = ref[len(prefix):]
	if strings.IndexByte(id, '/') >= 0 {
		return nil, "", failedToResolveRefFragmentPart(ref, id)
	}
	return &swagger.Components, id, nil
}

func (swaggerLoader *SwaggerLoader) resolveHeaderRef(swagger *Swagger, component *HeaderRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/headers/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.Headers
		if definitions == nil {
			return failedToResolveRefFragment(ref)
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragment(ref)
		}
		if err := swaggerLoader.resolveHeaderRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	value := component.Value
	if value == nil {
		return nil
	}
	if schema := value.Schema; schema != nil {
		if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil {
			return err
		}
	}
	return nil
}

func (swaggerLoader *SwaggerLoader) resolveParameterRef(swagger *Swagger, component *ParameterRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/parameters/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.Parameters
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "parameters")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err := swaggerLoader.resolveParameterRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	value := component.Value
	if value == nil {
		return nil
	}
	if schema := value.Schema; schema != nil {
		if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil {
			return err
		}
	}
	return nil
}

func (swaggerLoader *SwaggerLoader) resolveRequestBodyRef(swagger *Swagger, component *RequestBodyRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/requestBodies/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.RequestBodies
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "requestBodies")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err = swaggerLoader.resolveRequestBodyRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	value := component.Value
	if value == nil {
		return nil
	}
	for _, contentType := range value.Content {
		for name, example := range contentType.Examples {
			if err := swaggerLoader.resolveExampleRef(swagger, example); err != nil {
				return err
			}
			contentType.Examples[name] = example
		}
		if schema := contentType.Schema; schema != nil {
			if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil {
				return err
			}
		}
	}
	return nil
}

func (swaggerLoader *SwaggerLoader) resolveResponseRef(swagger *Swagger, component *ResponseRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/responses/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.Responses
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "responses")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err := swaggerLoader.resolveResponseRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	value := component.Value
	if value == nil {
		return nil
	}
	for _, contentType := range value.Content {
		if contentType == nil {
			continue
		}
		for name, example := range contentType.Examples {
			if err := swaggerLoader.resolveExampleRef(swagger, example); err != nil {
				return err
			}
			contentType.Examples[name] = example
		}
		if schema := contentType.Schema; schema != nil {
			if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil {
				return err
			}
			contentType.Schema = schema
		}
	}
	return nil
}

func (swaggerLoader *SwaggerLoader) resolveSchemaRef(swagger *Swagger, component *SchemaRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/schemas/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.Schemas
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "schemas")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err := swaggerLoader.resolveSchemaRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	value := component.Value
	if value == nil {
		return nil
	}

	// ResolveRefs referred schemas
	if v := value.Items; v != nil {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	for _, v := range value.Properties {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	if v := value.AdditionalProperties; v != nil {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	if v := value.Not; v != nil {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	for _, v := range value.AllOf {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	for _, v := range value.AnyOf {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	for _, v := range value.OneOf {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}

	return nil
}

func (swaggerLoader *SwaggerLoader) resolveSecuritySchemeRef(swagger *Swagger, component *SecuritySchemeRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/securitySchemes/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.SecuritySchemes
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "securitySchemes")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err := swaggerLoader.resolveSecuritySchemeRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	return nil
}

func (swaggerLoader *SwaggerLoader) resolveExampleRef(swagger *Swagger, component *ExampleRef) error {
	const prefix = "#/components/examples/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.Examples
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "examples")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err := swaggerLoader.resolveExampleRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	return nil
}
<commit_msg>resolveExampleRef - missing infinite recursion guard (#42)<commit_after>package openapi3

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/url"
	"strings"

	"github.com/ghodss/yaml"
)

func foundUnresolvedRef(ref string) error {
	return fmt.Errorf("Found unresolved ref: '%s'", ref)
}

func failedToResolveRefFragment(value string) error {
	return fmt.Errorf("Failed to resolve fragment in URI: '%s'", value)
}

func failedToResolveRefFragmentPart(value string, what string) error {
	return fmt.Errorf("Failed to resolve '%s' in fragment in URI: '%s'", what, value)
}

type SwaggerLoader struct {
	IsExternalRefsAllowed  bool
	Context                context.Context
	LoadSwaggerFromURIFunc func(loader *SwaggerLoader, url *url.URL) (*Swagger, error)
	visited                map[interface{}]struct{}
}

func NewSwaggerLoader() *SwaggerLoader {
	return &SwaggerLoader{}
}

func (swaggerLoader *SwaggerLoader) LoadSwaggerFromURI(location *url.URL) (*Swagger, error) {
	f := swaggerLoader.LoadSwaggerFromURIFunc
	if f != nil {
		return f(swaggerLoader, location)
	}
	if location.Scheme != "" || location.Host != "" || location.RawQuery != "" {
		return nil, fmt.Errorf("Unsupported URI: '%s'", location.String())
	}
	data, err := ioutil.ReadFile(location.Path)
	if err != nil {
		return nil, err
	}
	return swaggerLoader.LoadSwaggerFromData(data)
}

func (swaggerLoader *SwaggerLoader) LoadSwaggerFromFile(path string) (*Swagger, error) {
	f := swaggerLoader.LoadSwaggerFromURIFunc
	if f != nil {
		return f(swaggerLoader, &url.URL{
			Path: path,
		})
	}
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	return swaggerLoader.LoadSwaggerFromData(data)
}

func (swaggerLoader *SwaggerLoader) LoadSwaggerFromData(data []byte) (*Swagger, error) {
	swagger := &Swagger{}
	if err := json.Unmarshal(data, swagger); err != nil {
		return nil, err
	}
	return swagger, swaggerLoader.ResolveRefsIn(swagger)
}

func (swaggerLoader *SwaggerLoader) LoadSwaggerFromYAMLData(data []byte) (*Swagger, error) {
	swagger := &Swagger{}
	if err := yaml.Unmarshal(data, swagger); err != nil {
		return nil, err
	}
	return swagger, swaggerLoader.ResolveRefsIn(swagger)
}

func (swaggerLoader *SwaggerLoader) ResolveRefsIn(swagger *Swagger) (err error) {
	swaggerLoader.visited = make(map[interface{}]struct{})

	// Visit all components
	components := swagger.Components
	for _, component := range components.Headers {
		if err = swaggerLoader.resolveHeaderRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.Parameters {
		if err = swaggerLoader.resolveParameterRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.RequestBodies {
		if err = swaggerLoader.resolveRequestBodyRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.Responses {
		if err = swaggerLoader.resolveResponseRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.Schemas {
		if err = swaggerLoader.resolveSchemaRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.SecuritySchemes {
		if err = swaggerLoader.resolveSecuritySchemeRef(swagger, component); err != nil {
			return
		}
	}
	for _, component := range components.Examples {
		if err = swaggerLoader.resolveExampleRef(swagger, component); err != nil {
			return
		}
	}

	// Visit all operations
	for _, pathItem := range swagger.Paths {
		if pathItem == nil {
			continue
		}
		for _, parameter := range pathItem.Parameters {
			if err = swaggerLoader.resolveParameterRef(swagger, parameter); err != nil {
				return
			}
		}
		for _, operation := range pathItem.Operations() {
			for _, parameter := range operation.Parameters {
				if err = swaggerLoader.resolveParameterRef(swagger, parameter); err != nil {
					return
				}
			}
			if requestBody := operation.RequestBody; requestBody != nil {
				if err = swaggerLoader.resolveRequestBodyRef(swagger, requestBody); err != nil {
					return
				}
			}
			for _, response := range operation.Responses {
				if err = swaggerLoader.resolveResponseRef(swagger, response); err != nil {
					return
				}
			}
		}
	}

	return
}

func (swaggerLoader *SwaggerLoader) resolveComponent(swagger *Swagger, ref string, prefix string) (
	components *Components,
	id string,
	err error,
) {
	if !strings.HasPrefix(ref, "#") {
		if !swaggerLoader.IsExternalRefsAllowed {
			return nil, "", fmt.Errorf("Encountered non-allowed external reference: '%s'", ref)
		}
		parsedURL, err := url.Parse(ref)
		if err != nil {
			return nil, "", fmt.Errorf("Can't parse reference: '%s': %v", ref, parsedURL)
		}
		fragment := parsedURL.Fragment
		parsedURL.Fragment = ""
		if swagger, err = swaggerLoader.LoadSwaggerFromURI(parsedURL); err != nil {
			return nil, "", fmt.Errorf("Error while resolving reference '%s': %v", ref, err)
		}
		ref = fmt.Sprintf("#%s", fragment)
	}
	if !strings.HasPrefix(ref, prefix) {
		err := fmt.Errorf("expected prefix '%s' in URI '%s'", prefix, ref)
		return nil, "", err
	}
	id = ref[len(prefix):]
	if strings.IndexByte(id, '/') >= 0 {
		return nil, "", failedToResolveRefFragmentPart(ref, id)
	}
	return &swagger.Components, id, nil
}

func (swaggerLoader *SwaggerLoader) resolveHeaderRef(swagger *Swagger, component *HeaderRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/headers/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.Headers
		if definitions == nil {
			return failedToResolveRefFragment(ref)
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragment(ref)
		}
		if err := swaggerLoader.resolveHeaderRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	value := component.Value
	if value == nil {
		return nil
	}
	if schema := value.Schema; schema != nil {
		if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil {
			return err
		}
	}
	return nil
}

func (swaggerLoader *SwaggerLoader) resolveParameterRef(swagger *Swagger, component *ParameterRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/parameters/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.Parameters
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "parameters")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err := swaggerLoader.resolveParameterRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	value := component.Value
	if value == nil {
		return nil
	}
	if schema := value.Schema; schema != nil {
		if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil {
			return err
		}
	}
	return nil
}

func (swaggerLoader *SwaggerLoader) resolveRequestBodyRef(swagger *Swagger, component *RequestBodyRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/requestBodies/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.RequestBodies
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "requestBodies")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err = swaggerLoader.resolveRequestBodyRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	value := component.Value
	if value == nil {
		return nil
	}
	for _, contentType := range value.Content {
		for name, example := range contentType.Examples {
			if err := swaggerLoader.resolveExampleRef(swagger, example); err != nil {
				return err
			}
			contentType.Examples[name] = example
		}
		if schema := contentType.Schema; schema != nil {
			if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil {
				return err
			}
		}
	}
	return nil
}

func (swaggerLoader *SwaggerLoader) resolveResponseRef(swagger *Swagger, component *ResponseRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/responses/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.Responses
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "responses")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err := swaggerLoader.resolveResponseRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	value := component.Value
	if value == nil {
		return nil
	}
	for _, contentType := range value.Content {
		if contentType == nil {
			continue
		}
		for name, example := range contentType.Examples {
			if err := swaggerLoader.resolveExampleRef(swagger, example); err != nil {
				return err
			}
			contentType.Examples[name] = example
		}
		if schema := contentType.Schema; schema != nil {
			if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil {
				return err
			}
			contentType.Schema = schema
		}
	}
	return nil
}

func (swaggerLoader *SwaggerLoader) resolveSchemaRef(swagger *Swagger, component *SchemaRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/schemas/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.Schemas
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "schemas")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err := swaggerLoader.resolveSchemaRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	value := component.Value
	if value == nil {
		return nil
	}

	// ResolveRefs referred schemas
	if v := value.Items; v != nil {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	for _, v := range value.Properties {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	if v := value.AdditionalProperties; v != nil {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	if v := value.Not; v != nil {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	for _, v := range value.AllOf {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	for _, v := range value.AnyOf {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}
	for _, v := range value.OneOf {
		if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil {
			return err
		}
	}

	return nil
}

func (swaggerLoader *SwaggerLoader) resolveSecuritySchemeRef(swagger *Swagger, component *SecuritySchemeRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	// Resolve ref
	const prefix = "#/components/securitySchemes/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.SecuritySchemes
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "securitySchemes")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err := swaggerLoader.resolveSecuritySchemeRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	return nil
}

func (swaggerLoader *SwaggerLoader) resolveExampleRef(swagger *Swagger, component *ExampleRef) error {
	// Prevent infinite recursion
	visited := swaggerLoader.visited
	if _, isVisited := visited[component]; isVisited {
		return nil
	}
	visited[component] = struct{}{}

	const prefix = "#/components/examples/"
	if ref := component.Ref; len(ref) > 0 {
		components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix)
		if err != nil {
			return err
		}
		definitions := components.Examples
		if definitions == nil {
			return failedToResolveRefFragmentPart(ref, "examples")
		}
		resolved := definitions[id]
		if resolved == nil {
			return failedToResolveRefFragmentPart(ref, id)
		}
		if err := swaggerLoader.resolveExampleRef(swagger, resolved); err != nil {
			return err
		}
		component.Value = resolved.Value
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
)

func login(c echo.Context) error {
	username := c.FormValue("username")
	password := c.FormValue("password")

	// Throws unauthorized error
	if username == "jon" && password == "shhh!" {
		return echo.ErrUnauthorized
	}

	// Create token
	token := jwt.New(jwt.SigningMethodHS256)

	// Set claims
	claims := token.Claims.(jwt.MapClaims)
	claims["name"] = "Jon Snow"
	claims["admin"] = true
	claims["exp"] = time.Now().Add(time.Hour * 72).Unix()

	// Generate encoded token and send it as response.
	t, err := token.SignedString([]byte("secret"))
	if err != nil {
		return err
	}

	return c.JSON(http.StatusOK, map[string]string{
		"token": t,
	})
}

func accessible(c echo.Context) error {
	return c.String(http.StatusOK, "Accessible")
}

func restricted(c echo.Context) error {
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	name := claims["name"].(string)
	return c.String(http.StatusOK, "Welcome "+name+"!")
}

func main() {
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Login route
	e.POST("/login", login)

	// Unauthenticated route
	e.GET("/", accessible)

	// Restricted group
	r := e.Group("/restricted")
	r.Use(middleware.JWT([]byte("secret")))
	r.GET("", restricted)

	e.Logger.Fatal(e.Start(":1323"))
}
<commit_msg>Update server.go (#98)<commit_after>package main

import (
	"net/http"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
)

func login(c echo.Context) error {
	username := c.FormValue("username")
	password := c.FormValue("password")

	// Throws unauthorized error
	if username != "jon" && password != "shhh!" {
		return echo.ErrUnauthorized
	}

	// Create token
	token := jwt.New(jwt.SigningMethodHS256)

	// Set claims
	claims := token.Claims.(jwt.MapClaims)
	claims["name"] = "Jon Snow"
	claims["admin"] = true
	claims["exp"] = time.Now().Add(time.Hour * 72).Unix()

	// Generate encoded token and send it as response.
	t, err := token.SignedString([]byte("secret"))
	if err != nil {
		return err
	}

	return c.JSON(http.StatusOK, map[string]string{
		"token": t,
	})
}

func accessible(c echo.Context) error {
	return c.String(http.StatusOK, "Accessible")
}

func restricted(c echo.Context) error {
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	name := claims["name"].(string)
	return c.String(http.StatusOK, "Welcome "+name+"!")
}

func main() {
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Login route
	e.POST("/login", login)

	// Unauthenticated route
	e.GET("/", accessible)

	// Restricted group
	r := e.Group("/restricted")
	r.Use(middleware.JWT([]byte("secret")))
	r.GET("", restricted)

	e.Logger.Fatal(e.Start(":1323"))
}
<|endoftext|>


<commit_before>package diffscanner

import (
	"bufio"
	"cred-alert/scanners"
	"io"
	"regexp"
	"strconv"

	"code.cloudfoundry.org/lager"
)

var fileHeaderPattern = regexp.MustCompile(`^\+\+\+\s\w\/(.*)$`)
var contextAddedLinePattern = regexp.MustCompile(`^(?:\s|\+)`)
var plusMinusSpacePattern = regexp.MustCompile(`^(?:\s|\+|\-)(.*)`)
var hunkHeaderRegexp = regexp.MustCompile(`^@@.*\+(\d+),?\d+?\s@@`)

type DiffScanner struct {
	scanner           *bufio.Scanner
	currentPath       string
	currentLineNumber int
}

func NewDiffScanner(diff io.Reader) *DiffScanner {
	return &DiffScanner{
		scanner: bufio.NewScanner(diff),
	}
}

func (d *DiffScanner) Scan(logger lager.Logger) bool {
	logger = logger.Session("diff-scanner").Session("scan")
	logger.Debug("starting")
	defer logger.Debug("done")

	for d.scanner.Scan() {
		line := d.scanner.Text()

		matches := fileHeaderPattern.FindStringSubmatch(line)
		if len(matches) == 2 {
			d.currentPath = matches[1]
			continue
		}

		matches = hunkHeaderRegexp.FindStringSubmatch(line)
		if len(matches) == 2 {
			startLine, err := strconv.Atoi(matches[1])
			if err != nil {
				logger.Error("failed", err)
				break
			}
			d.currentLineNumber = startLine - 1
			continue
		}

		matches = contextAddedLinePattern.FindStringSubmatch(line)
		if len(matches) == 1 {
			d.currentLineNumber++
			return true
		}
	}

	return false
}

func (d *DiffScanner) Line(logger lager.Logger) *scanners.Line {
	logger = logger.Session("line", lager.Data{
		"line-number": d.currentLineNumber,
		"path":        d.currentPath,
	})
	logger.Debug("starting")
	defer logger.Debug("done")

	var content []byte
	matches := plusMinusSpacePattern.FindSubmatchIndex(d.scanner.Bytes())
	if len(matches) == 4 {
		content = d.scanner.Bytes()[matches[2]:matches[3]]
	}

	return &scanners.Line{
		Content:    content,
		LineNumber: d.currentLineNumber,
		Path:       d.currentPath,
	}
}
<commit_msg>Remove logging from diffscanner.Line<commit_after>package diffscanner

import (
	"bufio"
	"cred-alert/scanners"
	"io"
	"regexp"
	"strconv"

	"code.cloudfoundry.org/lager"
)

var fileHeaderPattern = regexp.MustCompile(`^\+\+\+\s\w\/(.*)$`)
var contextAddedLinePattern = regexp.MustCompile(`^(?:\s|\+)`)
var plusMinusSpacePattern = regexp.MustCompile(`^(?:\s|\+|\-)(.*)`)
var hunkHeaderRegexp = regexp.MustCompile(`^@@.*\+(\d+),?\d+?\s@@`)

type DiffScanner struct {
	scanner           *bufio.Scanner
	currentPath       string
	currentLineNumber int
}

func NewDiffScanner(diff io.Reader) *DiffScanner {
	return &DiffScanner{
		scanner: bufio.NewScanner(diff),
	}
}

func (d *DiffScanner) Scan(logger lager.Logger) bool {
	logger = logger.Session("diff-scanner").Session("scan")
	logger.Debug("starting")
	defer logger.Debug("done")

	for d.scanner.Scan() {
		line := d.scanner.Text()

		matches := fileHeaderPattern.FindStringSubmatch(line)
		if len(matches) == 2 {
			d.currentPath = matches[1]
			continue
		}

		matches = hunkHeaderRegexp.FindStringSubmatch(line)
		if len(matches) == 2 {
			startLine, err := strconv.Atoi(matches[1])
			if err != nil {
				logger.Error("failed", err)
				break
			}
			d.currentLineNumber = startLine - 1
			continue
		}

		matches = contextAddedLinePattern.FindStringSubmatch(line)
		if len(matches) == 1 {
			d.currentLineNumber++
			return true
		}
	}

	return false
}

func (d *DiffScanner) Line(lager.Logger) *scanners.Line {
	var content []byte
	matches := plusMinusSpacePattern.FindSubmatchIndex(d.scanner.Bytes())
	if len(matches) == 4 {
		content = d.scanner.Bytes()[matches[2]:matches[3]]
	}

	return &scanners.Line{
		Content:    content,
		LineNumber: d.currentLineNumber,
		Path:       d.currentPath,
	}
}
<|endoftext|>