<commit_before>/*                          _       _
 *__      _____  __ ___   ___  __ _| |_ ___
 *\ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
 * \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
 *  \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
 *
 * Copyright © 2016 - 2018 Weaviate. All rights reserved.
 * LICENSE: https://github.com/creativesoftwarefdn/weaviate/blob/develop/LICENSE.md
 * AUTHOR: Bob van Luijt (bob@kub.design)
 * See www.creativesoftwarefdn.org for details
 * Contact: @CreativeSofwFdn / bob@kub.design
 */

package janusgraph

import (
	"context"

	"github.com/go-openapi/strfmt"

	"github.com/creativesoftwarefdn/weaviate/gremlin"
	"github.com/creativesoftwarefdn/weaviate/models"

	"encoding/base64"
	"fmt"
	"strings"
)

//TODO fix keys cross weaviates.
func (f *Janusgraph) AddKey(ctx context.Context, key *models.Key, UUID strfmt.UUID, token string) error {
	q := gremlin.G.AddV(KEY_VERTEX_LABEL).
		StringProperty("uuid", string(UUID)).
		BoolProperty("isRoot", key.Parent == nil).
		BoolProperty("delete", key.Delete).
		BoolProperty("execute", key.Execute).
		BoolProperty("read", key.Read).
		BoolProperty("write", key.Write).
		StringProperty("email", key.Email).
		StringProperty("IPOrigin", strings.Join(key.IPOrigin, ";")).
		Int64Property("keyExpiresUnix", key.KeyExpiresUnix).
		StringProperty("__token", base64.StdEncoding.EncodeToString([]byte(token))).
		As("newKey")

	if key.Parent != nil {
		q = q.AddE(KEY_PARENT_LABEL).
			FromRef("newKey").
			ToQuery(gremlin.G.V().
				HasLabel(KEY_VERTEX_LABEL).
				HasString("uuid", key.Parent.NrDollarCref.String()))
	}

	_, err := f.client.Execute(q)

	return err
}

func (f *Janusgraph) GetKey(ctx context.Context, UUID strfmt.UUID, keyResponse *models.KeyGetResponse) error {
	q := gremlin.G.V().HasLabel(KEY_VERTEX_LABEL).HasString("uuid", string(UUID))

	result, err := f.client.Execute(q)

	if err != nil {
		return err
	}

	vertices, err := result.Vertices()

	if err != nil {
		return err
	}

	if len(vertices) == 0 {
		return fmt.Errorf("No key found")
	}

	if len(vertices) != 1 {
		return fmt.Errorf("More than one key with UUID '%v' found!", UUID)
	}

	vertex := vertices[0]
	fillKeyResponseFromVertex(&vertex, keyResponse)

	return nil
}

func (f *Janusgraph) GetKeys(ctx context.Context, UUIDs []strfmt.UUID, keysResponse *[]*models.KeyGetResponse) error {
	fmt.Printf("\n\n\n\n\n\nGETKEYSNOT NOT IMPLEMENTED\n\n\n\n\n")
	return nil
}

func (f *Janusgraph) DeleteKey(ctx context.Context, key *models.Key, UUID strfmt.UUID) error {
	q := gremlin.G.V().HasLabel(KEY_VERTEX_LABEL).
		HasString("uuid", string(UUID)).Drop()

	_, err := f.client.Execute(q)

	return err
}

// GetKeyChildren fills the given KeyGetResponse array with the values from the database, based on the given UUID.
func (f *Janusgraph) GetKeyChildren(ctx context.Context, UUID strfmt.UUID, children *[]*models.KeyGetResponse) error {
	// Fetch the child vertices directly, so that we can run just _one_ query instead of 1 + len(children)
	q := gremlin.G.V().HasLabel(KEY_VERTEX_LABEL).HasString("uuid", string(UUID)).InEWithLabel(KEY_PARENT_LABEL).OutV()

	result, err := f.client.Execute(q)
	if err != nil {
		return err
	}
	vertices, err := result.Vertices()
	if err != nil {
		return err
	}

	for _, vertex := range vertices {
		child := models.KeyGetResponse{}
		fillKeyResponseFromVertex(&vertex, &child)
		*children = append(*children, &child)
	}

	return nil
}

// UpdateKey updates the Key in the DB at the given UUID.
func (f *Janusgraph) UpdateKey(ctx context.Context, key *models.Key, UUID strfmt.UUID, token string) error {
	q := gremlin.G.V().HasLabel(KEY_VERTEX_LABEL).
		HasString("uuid", string(UUID)).
		BoolProperty("isRoot", key.Parent == nil).
		BoolProperty("delete", key.Delete).
		BoolProperty("execute", key.Execute).
		BoolProperty("read", key.Read).
		BoolProperty("write", key.Write).
		StringProperty("email", key.Email).
		StringProperty("IPOrigin", strings.Join(key.IPOrigin, ";")).
		Int64Property("keyExpiresUnix", key.KeyExpiresUnix).
		StringProperty("__token", base64.StdEncoding.EncodeToString([]byte(token)))

	_, err := f.client.Execute(q)

	return err
}
<commit_msg>Implement GetKeys<commit_after>/*                          _       _
 *__      _____  __ ___   ___  __ _| |_ ___
 *\ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
 * \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
 *  \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
 *
 * Copyright © 2016 - 2018 Weaviate. All rights reserved.
 * LICENSE: https://github.com/creativesoftwarefdn/weaviate/blob/develop/LICENSE.md
 * AUTHOR: Bob van Luijt (bob@kub.design)
 * See www.creativesoftwarefdn.org for details
 * Contact: @CreativeSofwFdn / bob@kub.design
 */

package janusgraph

import (
	"context"

	"github.com/go-openapi/strfmt"

	"github.com/creativesoftwarefdn/weaviate/gremlin"
	"github.com/creativesoftwarefdn/weaviate/models"

	"encoding/base64"
	"fmt"
	"strings"
)

//TODO fix keys cross weaviates.
func (f *Janusgraph) AddKey(ctx context.Context, key *models.Key, UUID strfmt.UUID, token string) error {
	q := gremlin.G.AddV(KEY_VERTEX_LABEL).
		StringProperty("uuid", string(UUID)).
		BoolProperty("isRoot", key.Parent == nil).
		BoolProperty("delete", key.Delete).
		BoolProperty("execute", key.Execute).
		BoolProperty("read", key.Read).
		BoolProperty("write", key.Write).
		StringProperty("email", key.Email).
		StringProperty("IPOrigin", strings.Join(key.IPOrigin, ";")).
		Int64Property("keyExpiresUnix", key.KeyExpiresUnix).
		StringProperty("__token", base64.StdEncoding.EncodeToString([]byte(token))).
		As("newKey")

	if key.Parent != nil {
		q = q.AddE(KEY_PARENT_LABEL).
			FromRef("newKey").
			ToQuery(gremlin.G.V().
				HasLabel(KEY_VERTEX_LABEL).
				HasString("uuid", key.Parent.NrDollarCref.String()))
	}

	_, err := f.client.Execute(q)

	return err
}

func (f *Janusgraph) GetKey(ctx context.Context, UUID strfmt.UUID, keyResponse *models.KeyGetResponse) error {
	q := gremlin.G.V().HasLabel(KEY_VERTEX_LABEL).HasString("uuid", string(UUID))

	result, err := f.client.Execute(q)

	if err != nil {
		return err
	}

	vertices, err := result.Vertices()

	if err != nil {
		return err
	}

	if len(vertices) == 0 {
		return fmt.Errorf("No key found")
	}

	if len(vertices) != 1 {
		return fmt.Errorf("More than one key with UUID '%v' found!", UUID)
	}

	vertex := vertices[0]
	fillKeyResponseFromVertex(&vertex, keyResponse)

	return nil
}

func (f *Janusgraph) GetKeys(ctx context.Context, UUIDs []strfmt.UUID, keysResponse *[]*models.KeyGetResponse) error {
	for _, id := range UUIDs {
		var response *models.KeyGetResponse = new(models.KeyGetResponse)
		err := f.GetKey(ctx, id, response)
		if err != nil {
			return err
		}
		*keysResponse = append(*keysResponse, response)
	}

	return nil
}

func (f *Janusgraph) DeleteKey(ctx context.Context, key *models.Key, UUID strfmt.UUID) error {
	q := gremlin.G.V().HasLabel(KEY_VERTEX_LABEL).
		HasString("uuid", string(UUID)).Drop()

	_, err := f.client.Execute(q)

	return err
}

// GetKeyChildren fills the given KeyGetResponse array with the values from the database, based on the given UUID.
func (f *Janusgraph) GetKeyChildren(ctx context.Context, UUID strfmt.UUID, children *[]*models.KeyGetResponse) error {
	// Fetch the child vertices directly, so that we can run just _one_ query instead of 1 + len(children)
	q := gremlin.G.V().HasLabel(KEY_VERTEX_LABEL).HasString("uuid", string(UUID)).InEWithLabel(KEY_PARENT_LABEL).OutV()

	result, err := f.client.Execute(q)
	if err != nil {
		return err
	}
	vertices, err := result.Vertices()
	if err != nil {
		return err
	}

	for _, vertex := range vertices {
		child := models.KeyGetResponse{}
		fillKeyResponseFromVertex(&vertex, &child)
		*children = append(*children, &child)
	}

	return nil
}

// UpdateKey updates the Key in the DB at the given UUID.
func (f *Janusgraph) UpdateKey(ctx context.Context, key *models.Key, UUID strfmt.UUID, token string) error {
	q := gremlin.G.V().HasLabel(KEY_VERTEX_LABEL).
		HasString("uuid", string(UUID)).
		BoolProperty("isRoot", key.Parent == nil).
		BoolProperty("delete", key.Delete).
		BoolProperty("execute", key.Execute).
		BoolProperty("read", key.Read).
		BoolProperty("write", key.Write).
		StringProperty("email", key.Email).
		StringProperty("IPOrigin", strings.Join(key.IPOrigin, ";")).
		Int64Property("keyExpiresUnix", key.KeyExpiresUnix).
		StringProperty("__token", base64.StdEncoding.EncodeToString([]byte(token)))

	_, err := f.client.Execute(q)

	return err
}
<|endoftext|>


<commit_before>package ws

import (
	"bufio"
	"fmt"
	"io"
	"net"
	"sync"
	"time"

	"github.com/v2ray/v2ray-core/common/log"

	"github.com/gorilla/websocket"
)

type wsconn struct {
	wsc         *websocket.Conn
	readBuffer  *bufio.Reader
	connClosing bool
	reusable    bool
	rlock       *sync.Mutex
	wlock       *sync.Mutex
}

func (ws *wsconn) Read(b []byte) (n int, err error) {
	ws.rlock.Lock()
	if ws.connClosing {

		return 0, io.EOF
	}
	getNewBuffer := func() error {
		_, r, err := ws.wsc.NextReader()
		if err != nil {
			log.Warning("WS transport: ws connection NewFrameReader return " + err.Error())
			ws.connClosing = true
			ws.Close()
			return err
		}
		ws.readBuffer = bufio.NewReader(r)
		return nil
	}

	/*It seems golang's support for recursive in anonymous func is yet to complete.
		func1:=func(){
		func1()
	  }
		won't work, failed to compile for it can't find func1.

		Should following workaround panic,
		readNext could have been called before the actual defination was made,
		This is very unlikely.
	*/
	readNext := func(b []byte) (n int, err error) { panic("Runtime unstable. Please report this bug to developer.") }

	readNext = func(b []byte) (n int, err error) {
		if ws.readBuffer == nil {
			err = getNewBuffer()
			if err != nil {
				return 0, err
			}
		}

		n, err = ws.readBuffer.Read(b)

		if err == nil {
			return n, err
		}

		if err == io.EOF {
			ws.readBuffer = nil
			if n == 0 {
				return readNext(b)
			}
			return n, nil
		}
		return n, err

	}
	n, err = readNext(b)
	ws.rlock.Unlock()
	return n, err

}

func (ws *wsconn) Write(b []byte) (n int, err error) {
	ws.wlock.Lock()
	/*
		process can crash as websocket report "concurrent write to websocket connection"
		even if lock is persent.

		This problem should have been resolved.
	*/
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("WS workaround: recover", r)
			ws.wlock.Unlock()
		}
	}()
	if ws.connClosing {

		return 0, io.EOF
	}
	writeWs := func(b []byte) (n int, err error) {
		wr, err := ws.wsc.NextWriter(websocket.BinaryMessage)
		if err != nil {
			log.Warning("WS transport: ws connection NewFrameReader return " + err.Error())
			ws.connClosing = true
			ws.Close()
			return 0, err
		}
		n, err = wr.Write(b)
		if err != nil {
			return 0, err
		}
		err = wr.Close()
		if err != nil {
			return 0, err
		}
		return n, err
	}
	n, err = writeWs(b)
	ws.wlock.Unlock()
	return n, err
}
func (ws *wsconn) Close() error {
	ws.connClosing = true
	ws.wlock.Lock()
	ws.wsc.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), time.Now().Add((time.Second * 5)))
	ws.wlock.Unlock()
	err := ws.wsc.Close()
	return err
}
func (ws *wsconn) LocalAddr() net.Addr {
	return ws.wsc.LocalAddr()
}
func (ws *wsconn) RemoteAddr() net.Addr {
	return ws.wsc.RemoteAddr()
}
func (ws *wsconn) SetDeadline(t time.Time) error {
	return func() error {
		errr := ws.SetReadDeadline(t)
		errw := ws.SetWriteDeadline(t)
		if errr == nil || errw == nil {
			return nil
		}
		if errr != nil {
			return errr
		}

		return errw
	}()
}
func (ws *wsconn) SetReadDeadline(t time.Time) error {
	return ws.wsc.SetReadDeadline(t)
}
func (ws *wsconn) SetWriteDeadline(t time.Time) error {
	return ws.wsc.SetWriteDeadline(t)
}

func (ws *wsconn) setup() {
	ws.connClosing = false

	ws.rlock = &sync.Mutex{}
	ws.wlock = &sync.Mutex{}

	ws.pingPong()
}

func (ws *wsconn) Reusable() bool {
	return ws.reusable && !ws.connClosing
}

func (ws *wsconn) SetReusable(reusable bool) {
	if !effectiveConfig.ConnectionReuse {
		return
	}
	ws.reusable = reusable
}

func (ws *wsconn) pingPong() {
	pongRcv := make(chan int, 0)
	ws.wsc.SetPongHandler(func(data string) error {
		pongRcv <- 0
		return nil
	})

	go func() {
		for !ws.connClosing {
			ws.wlock.Lock()
			ws.wsc.WriteMessage(websocket.PingMessage, nil)
			ws.wlock.Unlock()
			tick := time.NewTicker(time.Second * 3)

			select {
			case <-pongRcv:
				break
			case <-tick.C:
				if !ws.connClosing {
					log.Debug("WS:Closing as ping is not responded~" + ws.wsc.UnderlyingConn().LocalAddr().String() + "-" + ws.wsc.UnderlyingConn().RemoteAddr().String())
				}
				ws.Close()
			}
			<-tick.C
			tick.Stop()
		}

		return
	}()

}
<commit_msg>Increase ping time<commit_after>package ws

import (
	"bufio"
	"fmt"
	"io"
	"net"
	"sync"
	"time"

	"github.com/v2ray/v2ray-core/common/log"

	"github.com/gorilla/websocket"
)

type wsconn struct {
	wsc         *websocket.Conn
	readBuffer  *bufio.Reader
	connClosing bool
	reusable    bool
	rlock       *sync.Mutex
	wlock       *sync.Mutex
}

func (ws *wsconn) Read(b []byte) (n int, err error) {
	ws.rlock.Lock()
	if ws.connClosing {

		return 0, io.EOF
	}
	getNewBuffer := func() error {
		_, r, err := ws.wsc.NextReader()
		if err != nil {
			log.Warning("WS transport: ws connection NewFrameReader return " + err.Error())
			ws.connClosing = true
			ws.Close()
			return err
		}
		ws.readBuffer = bufio.NewReader(r)
		return nil
	}

	/*It seems golang's support for recursive in anonymous func is yet to complete.
		func1:=func(){
		func1()
	  }
		won't work, failed to compile for it can't find func1.

		Should following workaround panic,
		readNext could have been called before the actual defination was made,
		This is very unlikely.
	*/
	readNext := func(b []byte) (n int, err error) { panic("Runtime unstable. Please report this bug to developer.") }

	readNext = func(b []byte) (n int, err error) {
		if ws.readBuffer == nil {
			err = getNewBuffer()
			if err != nil {
				return 0, err
			}
		}

		n, err = ws.readBuffer.Read(b)

		if err == nil {
			return n, err
		}

		if err == io.EOF {
			ws.readBuffer = nil
			if n == 0 {
				return readNext(b)
			}
			return n, nil
		}
		return n, err

	}
	n, err = readNext(b)
	ws.rlock.Unlock()
	return n, err

}

func (ws *wsconn) Write(b []byte) (n int, err error) {
	ws.wlock.Lock()
	/*
		process can crash as websocket report "concurrent write to websocket connection"
		even if lock is persent.

		This problem should have been resolved.
	*/
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("WS workaround: recover", r)
			ws.wlock.Unlock()
		}
	}()
	if ws.connClosing {

		return 0, io.EOF
	}
	writeWs := func(b []byte) (n int, err error) {
		wr, err := ws.wsc.NextWriter(websocket.BinaryMessage)
		if err != nil {
			log.Warning("WS transport: ws connection NewFrameReader return " + err.Error())
			ws.connClosing = true
			ws.Close()
			return 0, err
		}
		n, err = wr.Write(b)
		if err != nil {
			return 0, err
		}
		err = wr.Close()
		if err != nil {
			return 0, err
		}
		return n, err
	}
	n, err = writeWs(b)
	ws.wlock.Unlock()
	return n, err
}
func (ws *wsconn) Close() error {
	ws.connClosing = true
	ws.wlock.Lock()
	ws.wsc.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), time.Now().Add((time.Second * 5)))
	ws.wlock.Unlock()
	err := ws.wsc.Close()
	return err
}
func (ws *wsconn) LocalAddr() net.Addr {
	return ws.wsc.LocalAddr()
}
func (ws *wsconn) RemoteAddr() net.Addr {
	return ws.wsc.RemoteAddr()
}
func (ws *wsconn) SetDeadline(t time.Time) error {
	return func() error {
		errr := ws.SetReadDeadline(t)
		errw := ws.SetWriteDeadline(t)
		if errr == nil || errw == nil {
			return nil
		}
		if errr != nil {
			return errr
		}

		return errw
	}()
}
func (ws *wsconn) SetReadDeadline(t time.Time) error {
	return ws.wsc.SetReadDeadline(t)
}
func (ws *wsconn) SetWriteDeadline(t time.Time) error {
	return ws.wsc.SetWriteDeadline(t)
}

func (ws *wsconn) setup() {
	ws.connClosing = false

	ws.rlock = &sync.Mutex{}
	ws.wlock = &sync.Mutex{}

	ws.pingPong()
}

func (ws *wsconn) Reusable() bool {
	return ws.reusable && !ws.connClosing
}

func (ws *wsconn) SetReusable(reusable bool) {
	if !effectiveConfig.ConnectionReuse {
		return
	}
	ws.reusable = reusable
}

func (ws *wsconn) pingPong() {
	pongRcv := make(chan int, 0)
	ws.wsc.SetPongHandler(func(data string) error {
		pongRcv <- 0
		return nil
	})

	go func() {
		for !ws.connClosing {
			ws.wlock.Lock()
			ws.wsc.WriteMessage(websocket.PingMessage, nil)
			ws.wlock.Unlock()
			tick := time.NewTicker(time.Second * 30)

			select {
			case <-pongRcv:
				break
			case <-tick.C:
				if !ws.connClosing {
					log.Debug("WS:Closing as ping is not responded~" + ws.wsc.UnderlyingConn().LocalAddr().String() + "-" + ws.wsc.UnderlyingConn().RemoteAddr().String())
				}
				ws.Close()
			}
			<-tick.C
			tick.Stop()
		}

		return
	}()

}
<|endoftext|>


<commit_before>package instructions

import "jvmgo/rtda"

//type Ref *rtda.Obj

// Load reference from array
type aaload struct {NoOperandsInstruction}
func (self *aaload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    refArr := arrRef.Fields().([]*rtda.Obj)
    ref := refArr[checkIndex(index, len(refArr))]
    stack.PushRef(ref)
}

// Load byte or boolean from array
type baload struct {NoOperandsInstruction}
func (self *baload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    byteArr := arrRef.Fields().([]int8)
    val := byteArr[checkIndex(index, len(byteArr))]
    stack.PushInt(int32(val))
}

// Load char from array
type caload struct {NoOperandsInstruction}
func (self *caload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    charArr := arrRef.Fields().([]uint16)
    val := charArr[checkIndex(index, len(charArr))]
    stack.PushInt(int32(val))
}

// Load double from array
type daload struct {NoOperandsInstruction}
func (self *daload) execute(thread *rtda.Thread) {
    // todo
}

// Load float from array
type faload struct {NoOperandsInstruction}
func (self *faload) execute(thread *rtda.Thread) {
    // todo
}

// Load int from array
type iaload struct {NoOperandsInstruction}
func (self *iaload) execute(thread *rtda.Thread) {
    // todo
}

// Load long from array
type laload struct {NoOperandsInstruction}
func (self *laload) execute(thread *rtda.Thread) {
    // todo
}

// Load short from array
type saload struct {NoOperandsInstruction}
func (self *saload) execute(thread *rtda.Thread) {
    // todo
}

func popArrAndIndex(thread *rtda.Thread) (*rtda.OperandStack, *rtda.Obj, int) {
    stack := thread.CurrentFrame().OperandStack()
    arrRef := stack.PopRef()
    index := int(stack.PopInt())
    if arrRef == nil {
        // todo
        panic("NullPointerException")
    }
    return stack, arrRef, index
}

func checkIndex(index, len int) (int) {
    if index < 0 || index >= len {
        panic("ArrayIndexOutOfBoundsException")
    }
    return index
}
<commit_msg>daload<commit_after>package instructions

import "jvmgo/rtda"

//type Ref *rtda.Obj

// Load reference from array
type aaload struct {NoOperandsInstruction}
func (self *aaload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    refArr := arrRef.Fields().([]*rtda.Obj)
    ref := refArr[checkIndex(index, len(refArr))]
    stack.PushRef(ref)
}

// Load byte or boolean from array
type baload struct {NoOperandsInstruction}
func (self *baload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    byteArr := arrRef.Fields().([]int8)
    val := byteArr[checkIndex(index, len(byteArr))]
    stack.PushInt(int32(val))
}

// Load char from array
type caload struct {NoOperandsInstruction}
func (self *caload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    charArr := arrRef.Fields().([]uint16)
    val := charArr[checkIndex(index, len(charArr))]
    stack.PushInt(int32(val))
}

// Load double from array
type daload struct {NoOperandsInstruction}
func (self *daload) execute(thread *rtda.Thread) {
    stack, arrRef, index := popArrAndIndex(thread)
    doubleArr := arrRef.Fields().([]float64)
    val := doubleArr[checkIndex(index, len(doubleArr))]
    stack.PushDouble(val)
}

// Load float from array
type faload struct {NoOperandsInstruction}
func (self *faload) execute(thread *rtda.Thread) {
    // todo
}

// Load int from array
type iaload struct {NoOperandsInstruction}
func (self *iaload) execute(thread *rtda.Thread) {
    // todo
}

// Load long from array
type laload struct {NoOperandsInstruction}
func (self *laload) execute(thread *rtda.Thread) {
    // todo
}

// Load short from array
type saload struct {NoOperandsInstruction}
func (self *saload) execute(thread *rtda.Thread) {
    // todo
}

func popArrAndIndex(thread *rtda.Thread) (*rtda.OperandStack, *rtda.Obj, int) {
    stack := thread.CurrentFrame().OperandStack()
    arrRef := stack.PopRef()
    index := int(stack.PopInt())
    if arrRef == nil {
        // todo
        panic("NullPointerException")
    }
    return stack, arrRef, index
}

func checkIndex(index, len int) (int) {
    if index < 0 || index >= len {
        panic("ArrayIndexOutOfBoundsException")
    }
    return index
}
<|endoftext|>


<commit_before>package GoHttpService

import (
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
)

func LoadHtml(pageName string) ([]byte, error) {
	fileName := pageName + ".html"
	return ioutil.ReadFile(fileName)
}

func RenderHtml(writer http.ResponseWriter, pageName string) error {
	body, err := LoadHtml(pageName)
	if err != nil {
		return err
	}

	fmt.Fprint(writer, body)
	return nil
}

func RenderTemplate(writer http.ResponseWriter, pageName string, data interface{}) error {
	t, err := template.ParseFiles(pageName + ".html")
	if err != nil {
		return err
	}

	err = t.Execute(writer, data)
	return err
}
<commit_msg>Fixed issue with rendering simple HTML<commit_after>package GoHttpService

import (
	"fmt"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
)

func LoadHtml(pageName string) ([]byte, error) {
	fileName := pageName + ".html"
	log.Println("INFO - Loading file", fileName)
	return ioutil.ReadFile(fileName)
}

func RenderHtml(writer http.ResponseWriter, pageName string) error {
	body, err := LoadHtml(pageName)
	if err != nil {
		return err
	}

	writer.Header().Set("Content-Type", "text/html; charset=UTF-8")

	fmt.Fprintf(writer, string(body))
	return nil
}

func RenderTemplate(writer http.ResponseWriter, pageName string, data interface{}) error {
	t, err := template.ParseFiles(pageName + ".html")
	if err != nil {
		return err
	}

	err = t.Execute(writer, data)
	return err
}
<|endoftext|>


<commit_before>package handshake

import (
	"errors"
	"fmt"

	pb "github.com/jbenet/go-ipfs/net/handshake/pb"
	updates "github.com/jbenet/go-ipfs/updates"

	semver "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/coreos/go-semver/semver"
)

// ipfsVersion holds the current protocol version for a client running this code
var ipfsVersion *semver.Version
var clientVersion = "go-ipfs/" + updates.Version

func init() {
	var err error
	ipfsVersion, err = semver.NewVersion("0.0.1")
	if err != nil {
		panic(fmt.Errorf("invalid protocol version: %v", err))
	}
}

// Handshake1Msg returns the current protocol version as a protobuf message
func Handshake1Msg() *pb.Handshake1 {
	return NewHandshake1(ipfsVersion.String(), clientVersion)
}

// ErrVersionMismatch is returned when two clients don't share a protocol version
var ErrVersionMismatch = errors.New("protocol missmatch")

// Handshake1Compatible checks wether two versions are compatible
// returns nil if they are fine
func Handshake1Compatible(handshakeA, handshakeB *pb.Handshake1) error {
	a, err := semver.NewVersion(*handshakeA.ProtocolVersion)
	if err != nil {
		return err
	}
	b, err := semver.NewVersion(*handshakeB.ProtocolVersion)
	if err != nil {
		return err
	}

	if a.Major != b.Major {
		return ErrVersionMismatch
	}

	return nil
}

// NewHandshake1 creates a new Handshake1 from the two strings
func NewHandshake1(protoVer, agentVer string) *pb.Handshake1 {
	return &pb.Handshake1{
		ProtocolVersion: &protoVer,
		AgentVersion:    &agentVer,
	}
}
<commit_msg>spell nit<commit_after>package handshake

import (
	"errors"
	"fmt"

	pb "github.com/jbenet/go-ipfs/net/handshake/pb"
	updates "github.com/jbenet/go-ipfs/updates"

	semver "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/coreos/go-semver/semver"
)

// ipfsVersion holds the current protocol version for a client running this code
var ipfsVersion *semver.Version
var clientVersion = "go-ipfs/" + updates.Version

func init() {
	var err error
	ipfsVersion, err = semver.NewVersion("0.0.1")
	if err != nil {
		panic(fmt.Errorf("invalid protocol version: %v", err))
	}
}

// Handshake1Msg returns the current protocol version as a protobuf message
func Handshake1Msg() *pb.Handshake1 {
	return NewHandshake1(ipfsVersion.String(), clientVersion)
}

// ErrVersionMismatch is returned when two clients don't share a protocol version
var ErrVersionMismatch = errors.New("protocol missmatch")

// Handshake1Compatible checks whether two versions are compatible
// returns nil if they are fine
func Handshake1Compatible(handshakeA, handshakeB *pb.Handshake1) error {
	a, err := semver.NewVersion(*handshakeA.ProtocolVersion)
	if err != nil {
		return err
	}
	b, err := semver.NewVersion(*handshakeB.ProtocolVersion)
	if err != nil {
		return err
	}

	if a.Major != b.Major {
		return ErrVersionMismatch
	}

	return nil
}

// NewHandshake1 creates a new Handshake1 from the two strings
func NewHandshake1(protoVer, agentVer string) *pb.Handshake1 {
	return &pb.Handshake1{
		ProtocolVersion: &protoVer,
		AgentVersion:    &agentVer,
	}
}
<|endoftext|>


<commit_before>package core

import (
	"errors"
	"reflect"
	"strings"
	"syscall"
	"testing"
	"time"

	"github.com/elves/elvish/edit/tty"
	"github.com/elves/elvish/edit/ui"
	"github.com/elves/elvish/styled"
	"github.com/elves/elvish/sys"
)

func TestReadCode_AbortsOnSetupError(t *testing.T) {
	ed, terminal, _ := setup()

	terminal.SetupErr = errors.New("a fake error")

	_, err := ed.ReadCode()

	if err != terminal.SetupErr {
		t.Errorf("ReadCode returns error %v, want %v", err, terminal.SetupErr)
	}
}

func TestReadCode_CallsRestore(t *testing.T) {
	ed, terminal, _ := setup()

	restoreCalled := 0
	terminal.RestoreFunc = func() { restoreCalled++ }
	terminal.EventCh <- tty.KeyEvent{Rune: '\n'}

	ed.ReadCode()

	if restoreCalled != 1 {
		t.Errorf("Restore callback called %d times, want once", restoreCalled)
	}
}

func TestReadCode_ResetsStateBeforeReturn(t *testing.T) {
	ed, terminal, _ := setup()

	terminal.EventCh <- tty.KeyEvent{Rune: '\n'}
	ed.state.Raw.Code = "some code"

	ed.ReadCode()

	if code := ed.state.Raw.Code; code != "" {
		t.Errorf("Editor state has code %q, want empty", code)
	}
}

func TestReadCode_PassesInputEventsToMode(t *testing.T) {
	ed, terminal, _ := setup()

	m := &fakeMode{maxKeys: 3}
	ed.state.Raw.Mode = m
	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'b'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'c'}

	ed.ReadCode()

	wantKeysHandled := []ui.Key{
		{Rune: 'a'}, {Rune: 'b'}, {Rune: 'c'},
	}
	if !reflect.DeepEqual(m.keysHandled, wantKeysHandled) {
		t.Errorf("Mode gets keys %v, want %v", m.keysHandled, wantKeysHandled)
	}
}

func TestReadCode_CallsBeforeReadlineOnce(t *testing.T) {
	ed, terminal, _ := setup()

	called := 0
	ed.BeforeReadline = func() { called++ }
	// Causes BasicMode to quit
	terminal.EventCh <- tty.KeyEvent{Rune: '\n'}

	ed.ReadCode()

	if called != 1 {
		t.Errorf("BeforeReadline hook called %d times, want 1", called)
	}
}

func TestReadCode_CallsAfterReadlineOnceWithCode(t *testing.T) {
	ed, terminal, _ := setup()

	called := 0
	code := ""
	ed.AfterReadline = func(s string) {
		called++
		code = s
	}
	// Causes BasicMode to write state.Code and then quit
	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'b'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'c'}
	terminal.EventCh <- tty.KeyEvent{Rune: '\n'}

	ed.ReadCode()

	if called != 1 {
		t.Errorf("AfterReadline hook called %d times, want 1", called)
	}
	if code != "abc" {
		t.Errorf("AfterReadline hook called with %q, want %q", code, "abc")
	}
}

func TestReadCode_RespectsMaxHeight(t *testing.T) {
	ed, terminal, _ := setup()

	maxHeight := 5
	// Will fill more than maxHeight but less than terminal height
	ed.state.Raw.Code = strings.Repeat("a", 80*10)
	ed.state.Raw.Dot = len(ed.state.Raw.Code)

	codeCh, _ := ed.readCodeAsync()

	buf1 := <-terminal.BufCh
	// Make sure that normally the height does exceed maxHeight.
	if h := len(buf1.Lines); h <= maxHeight {
		t.Errorf("Buffer height is %d, should > %d", h, maxHeight)
	}

	ed.Config.Mutex.Lock()
	ed.Config.Raw.MaxHeight = maxHeight
	ed.Config.Mutex.Unlock()

	ed.Redraw(false)

	buf2 := <-terminal.BufCh
	if h := len(buf2.Lines); h > maxHeight {
		t.Errorf("Buffer height is %d, should <= %d", h, maxHeight)
	}

	cleanup(terminal, codeCh)
}

var bufChTimeout = 1 * time.Second

func TestReadCode_RendersHighlightedCode(t *testing.T) {
	ed, terminal, _ := setup()

	ed.Highlighter = fakeHighlighter{
		get: func(code string) (styled.Text, []error) {
			return styled.Text{
				&styled.Segment{styled.Style{Foreground: "red"}, code}}, nil
		},
	}
	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'b'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'c'}

	codeCh, _ := ed.readCodeAsync()

	wantBuf := ui.NewBufferBuilder(80).
		WriteString("abc", "31" /* SGR for red foreground */).
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("Did not see buffer containing highlighted code")
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_RendersErrorFromHighlighter(t *testing.T) {
	// TODO
}

func TestReadCode_RedrawsOnHighlighterLateUpdate(t *testing.T) {
	// TODO
}

func TestReadCode_RendersPrompt(t *testing.T) {
	ed, terminal, _ := setup()

	ed.Prompt = constPrompt{styled.Unstyled("> ")}
	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}

	codeCh, _ := ed.readCodeAsync()

	wantBuf := ui.NewBufferBuilder(80).
		WriteUnstyled("> a").
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("Did not see buffer containing prompt")
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_RendersRPrompt(t *testing.T) {
	ed, terminal, _ := setup()

	terminal.width = 4
	ed.RPrompt = constPrompt{styled.Unstyled("R")}
	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}

	codeCh, _ := ed.readCodeAsync()

	wantBuf := ui.NewBufferBuilder(4).
		WriteUnstyled("a").SetDotToCursor().WriteUnstyled("  R").Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("Did not see buffer containing rprompt")
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_TriggersPrompt(t *testing.T) {
	ed, terminal, _ := setup()

	called := 0
	ed.Prompt = fakePrompt{trigger: func(bool) { called++ }}

	codeCh, _ := ed.readCodeAsync()
	cleanup(terminal, codeCh)

	if called != 1 {
		t.Errorf("Prompt.Trigger called %d times, want once", called)
	}
}

func TestReadCode_RedrawsOnPromptLateUpdate(t *testing.T) {
	ed, terminal, _ := setup()

	promptContent := "old"
	prompt := fakePrompt{
		get:         func() styled.Text { return styled.Unstyled(promptContent) },
		lateUpdates: make(chan styled.Text),
	}
	ed.Prompt = prompt

	codeCh, _ := ed.readCodeAsync()
	bufOldPrompt := ui.NewBufferBuilder(80).
		WriteUnstyled("old").SetDotToCursor().Buffer()
	// Wait until old prompt is rendered
	if !checkBuffer(bufOldPrompt, terminal.BufCh) {
		t.Errorf("Did not see buffer containing old prompt")
	}

	promptContent = "new"
	prompt.lateUpdates <- nil
	bufNewPrompt := ui.NewBufferBuilder(80).
		WriteUnstyled("new").SetDotToCursor().Buffer()
	if !checkBuffer(bufNewPrompt, terminal.BufCh) {
		t.Errorf("Did not see buffer containing new prompt")
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_SupportsPersistentRPrompt(t *testing.T) {
	// TODO
}

func TestReadCode_DrawsAndFlushesNotes(t *testing.T) {
	ed, terminal, _ := setup()

	codeCh, _ := ed.readCodeAsync()

	// Sanity-check initial state.
	initBuf := ui.NewBufferBuilder(80).Buffer()
	if !checkBuffer(initBuf, terminal.BufCh) {
		t.Errorf("did not get initial state")
	}

	ed.Notify("note")

	wantNotesBuf := ui.NewBufferBuilder(80).WriteUnstyled("note").Buffer()
	if !checkBuffer(wantNotesBuf, terminal.NotesBufCh) {
		t.Errorf("did not render notes")
	}

	if n := len(ed.state.Raw.Notes); n > 0 {
		t.Errorf("State.Raw.Notes has %d elements after redrawing, want 0", n)
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_UsesFinalStateInFinalRedraw(t *testing.T) {
	ed, terminal, _ := setup()

	ed.state.Raw.Code = "some code"
	// We use the dot as a signal for distinguishing non-final and final state.
	// In the final state, the dot will be set to the length of the code (9).
	ed.state.Raw.Dot = 1

	codeCh, _ := ed.readCodeAsync()

	// Wait until a non-final state is drawn.
	wantBuf := ui.NewBufferBuilder(80).WriteUnstyled("s").SetDotToCursor().
		WriteUnstyled("ome code").Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("did not get expected buffer before sending Enter")
	}

	cleanup(terminal, codeCh)

	// Last element in bufs is nil
	finalBuf := terminal.Bufs[len(terminal.Bufs)-2]
	wantFinalBuf := ui.NewBufferBuilder(80).WriteUnstyled("some code").
		SetDotToCursor().Buffer()
	if !reflect.DeepEqual(finalBuf, wantFinalBuf) {
		t.Errorf("final buffer is %v, want %v", finalBuf, wantFinalBuf)
	}
}

func TestReadCode_QuitsOnSIGHUP(t *testing.T) {
	ed, terminal, sigs := setup()

	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}

	codeCh, _ := ed.readCodeAsync()

	wantBuf := ui.NewBufferBuilder(80).WriteUnstyled("a").
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("did not get expected buffer before sending SIGHUP")
	}

	sigs.Ch <- syscall.SIGHUP

	select {
	case <-codeCh:
		// TODO: Test that ReadCode returns with io.EOF
	case <-time.After(time.Second):
		t.Errorf("SIGHUP did not cause ReadCode to return")
	}
}

func TestReadCode_ResetsOnSIGHUP(t *testing.T) {
	ed, terminal, sigs := setup()

	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}

	codeCh, _ := ed.readCodeAsync()
	wantBuf := ui.NewBufferBuilder(80).WriteUnstyled("a").
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("did not get expected buffer before sending SIGINT")
	}

	sigs.Ch <- syscall.SIGINT

	wantBuf = ui.NewBufferBuilder(80).Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("Terminal state is not reset after SIGINT")
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_RedrawsOnSIGWINCH(t *testing.T) {
	ed, terminal, sigs := setup()

	ed.state.Raw.Code = "1234567890"
	ed.state.Raw.Dot = len(ed.state.Raw.Code)

	codeCh, _ := ed.readCodeAsync()

	wantBuf := ui.NewBufferBuilder(80).WriteUnstyled("1234567890").
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("did not get expected buffer before sending SIGWINCH")
	}

	terminal.SetSize(24, 4)
	sigs.Ch <- sys.SIGWINCH

	wantBuf = ui.NewBufferBuilder(4).WriteUnstyled("1234567890").
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("Terminal is not redrawn after SIGWINCH")
	}

	cleanup(terminal, codeCh)
}

func setup() (*Editor, *fakeTTY, *fakeSignalSource) {
	terminal := newFakeTTY()
	sigsrc := newFakeSignalSource()
	ed := NewEditor(terminal, sigsrc)
	return ed, terminal, sigsrc
}

func cleanup(t *fakeTTY, codeCh <-chan string) {
	// Causes BasicMode to quit
	t.EventCh <- tty.KeyEvent{Rune: '\n'}
	// Wait until ReadCode has finished execution
	<-codeCh
}
<commit_msg>newedit: Complete the test on SIGHUP; fix name for test on SIGINT.<commit_after>package core

import (
	"errors"
	"io"
	"reflect"
	"strings"
	"syscall"
	"testing"
	"time"

	"github.com/elves/elvish/edit/tty"
	"github.com/elves/elvish/edit/ui"
	"github.com/elves/elvish/styled"
	"github.com/elves/elvish/sys"
)

func TestReadCode_AbortsOnSetupError(t *testing.T) {
	ed, terminal, _ := setup()

	terminal.SetupErr = errors.New("a fake error")

	_, err := ed.ReadCode()

	if err != terminal.SetupErr {
		t.Errorf("ReadCode returns error %v, want %v", err, terminal.SetupErr)
	}
}

func TestReadCode_CallsRestore(t *testing.T) {
	ed, terminal, _ := setup()

	restoreCalled := 0
	terminal.RestoreFunc = func() { restoreCalled++ }
	terminal.EventCh <- tty.KeyEvent{Rune: '\n'}

	ed.ReadCode()

	if restoreCalled != 1 {
		t.Errorf("Restore callback called %d times, want once", restoreCalled)
	}
}

func TestReadCode_ResetsStateBeforeReturn(t *testing.T) {
	ed, terminal, _ := setup()

	terminal.EventCh <- tty.KeyEvent{Rune: '\n'}
	ed.state.Raw.Code = "some code"

	ed.ReadCode()

	if code := ed.state.Raw.Code; code != "" {
		t.Errorf("Editor state has code %q, want empty", code)
	}
}

func TestReadCode_PassesInputEventsToMode(t *testing.T) {
	ed, terminal, _ := setup()

	m := &fakeMode{maxKeys: 3}
	ed.state.Raw.Mode = m
	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'b'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'c'}

	ed.ReadCode()

	wantKeysHandled := []ui.Key{
		{Rune: 'a'}, {Rune: 'b'}, {Rune: 'c'},
	}
	if !reflect.DeepEqual(m.keysHandled, wantKeysHandled) {
		t.Errorf("Mode gets keys %v, want %v", m.keysHandled, wantKeysHandled)
	}
}

func TestReadCode_CallsBeforeReadlineOnce(t *testing.T) {
	ed, terminal, _ := setup()

	called := 0
	ed.BeforeReadline = func() { called++ }
	// Causes BasicMode to quit
	terminal.EventCh <- tty.KeyEvent{Rune: '\n'}

	ed.ReadCode()

	if called != 1 {
		t.Errorf("BeforeReadline hook called %d times, want 1", called)
	}
}

func TestReadCode_CallsAfterReadlineOnceWithCode(t *testing.T) {
	ed, terminal, _ := setup()

	called := 0
	code := ""
	ed.AfterReadline = func(s string) {
		called++
		code = s
	}
	// Causes BasicMode to write state.Code and then quit
	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'b'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'c'}
	terminal.EventCh <- tty.KeyEvent{Rune: '\n'}

	ed.ReadCode()

	if called != 1 {
		t.Errorf("AfterReadline hook called %d times, want 1", called)
	}
	if code != "abc" {
		t.Errorf("AfterReadline hook called with %q, want %q", code, "abc")
	}
}

func TestReadCode_RespectsMaxHeight(t *testing.T) {
	ed, terminal, _ := setup()

	maxHeight := 5
	// Will fill more than maxHeight but less than terminal height
	ed.state.Raw.Code = strings.Repeat("a", 80*10)
	ed.state.Raw.Dot = len(ed.state.Raw.Code)

	codeCh, _ := ed.readCodeAsync()

	buf1 := <-terminal.BufCh
	// Make sure that normally the height does exceed maxHeight.
	if h := len(buf1.Lines); h <= maxHeight {
		t.Errorf("Buffer height is %d, should > %d", h, maxHeight)
	}

	ed.Config.Mutex.Lock()
	ed.Config.Raw.MaxHeight = maxHeight
	ed.Config.Mutex.Unlock()

	ed.Redraw(false)

	buf2 := <-terminal.BufCh
	if h := len(buf2.Lines); h > maxHeight {
		t.Errorf("Buffer height is %d, should <= %d", h, maxHeight)
	}

	cleanup(terminal, codeCh)
}

var bufChTimeout = 1 * time.Second

func TestReadCode_RendersHighlightedCode(t *testing.T) {
	ed, terminal, _ := setup()

	ed.Highlighter = fakeHighlighter{
		get: func(code string) (styled.Text, []error) {
			return styled.Text{
				&styled.Segment{styled.Style{Foreground: "red"}, code}}, nil
		},
	}
	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'b'}
	terminal.EventCh <- tty.KeyEvent{Rune: 'c'}

	codeCh, _ := ed.readCodeAsync()

	wantBuf := ui.NewBufferBuilder(80).
		WriteString("abc", "31" /* SGR for red foreground */).
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("Did not see buffer containing highlighted code")
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_RendersErrorFromHighlighter(t *testing.T) {
	// TODO
}

func TestReadCode_RedrawsOnHighlighterLateUpdate(t *testing.T) {
	// TODO
}

func TestReadCode_RendersPrompt(t *testing.T) {
	ed, terminal, _ := setup()

	ed.Prompt = constPrompt{styled.Unstyled("> ")}
	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}

	codeCh, _ := ed.readCodeAsync()

	wantBuf := ui.NewBufferBuilder(80).
		WriteUnstyled("> a").
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("Did not see buffer containing prompt")
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_RendersRPrompt(t *testing.T) {
	ed, terminal, _ := setup()

	terminal.width = 4
	ed.RPrompt = constPrompt{styled.Unstyled("R")}
	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}

	codeCh, _ := ed.readCodeAsync()

	wantBuf := ui.NewBufferBuilder(4).
		WriteUnstyled("a").SetDotToCursor().WriteUnstyled("  R").Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("Did not see buffer containing rprompt")
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_TriggersPrompt(t *testing.T) {
	ed, terminal, _ := setup()

	called := 0
	ed.Prompt = fakePrompt{trigger: func(bool) { called++ }}

	codeCh, _ := ed.readCodeAsync()
	cleanup(terminal, codeCh)

	if called != 1 {
		t.Errorf("Prompt.Trigger called %d times, want once", called)
	}
}

func TestReadCode_RedrawsOnPromptLateUpdate(t *testing.T) {
	ed, terminal, _ := setup()

	promptContent := "old"
	prompt := fakePrompt{
		get:         func() styled.Text { return styled.Unstyled(promptContent) },
		lateUpdates: make(chan styled.Text),
	}
	ed.Prompt = prompt

	codeCh, _ := ed.readCodeAsync()
	bufOldPrompt := ui.NewBufferBuilder(80).
		WriteUnstyled("old").SetDotToCursor().Buffer()
	// Wait until old prompt is rendered
	if !checkBuffer(bufOldPrompt, terminal.BufCh) {
		t.Errorf("Did not see buffer containing old prompt")
	}

	promptContent = "new"
	prompt.lateUpdates <- nil
	bufNewPrompt := ui.NewBufferBuilder(80).
		WriteUnstyled("new").SetDotToCursor().Buffer()
	if !checkBuffer(bufNewPrompt, terminal.BufCh) {
		t.Errorf("Did not see buffer containing new prompt")
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_SupportsPersistentRPrompt(t *testing.T) {
	// TODO
}

func TestReadCode_DrawsAndFlushesNotes(t *testing.T) {
	ed, terminal, _ := setup()

	codeCh, _ := ed.readCodeAsync()

	// Sanity-check initial state.
	initBuf := ui.NewBufferBuilder(80).Buffer()
	if !checkBuffer(initBuf, terminal.BufCh) {
		t.Errorf("did not get initial state")
	}

	ed.Notify("note")

	wantNotesBuf := ui.NewBufferBuilder(80).WriteUnstyled("note").Buffer()
	if !checkBuffer(wantNotesBuf, terminal.NotesBufCh) {
		t.Errorf("did not render notes")
	}

	if n := len(ed.state.Raw.Notes); n > 0 {
		t.Errorf("State.Raw.Notes has %d elements after redrawing, want 0", n)
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_UsesFinalStateInFinalRedraw(t *testing.T) {
	ed, terminal, _ := setup()

	ed.state.Raw.Code = "some code"
	// We use the dot as a signal for distinguishing non-final and final state.
	// In the final state, the dot will be set to the length of the code (9).
	ed.state.Raw.Dot = 1

	codeCh, _ := ed.readCodeAsync()

	// Wait until a non-final state is drawn.
	wantBuf := ui.NewBufferBuilder(80).WriteUnstyled("s").SetDotToCursor().
		WriteUnstyled("ome code").Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("did not get expected buffer before sending Enter")
	}

	cleanup(terminal, codeCh)

	// Last element in bufs is nil
	finalBuf := terminal.Bufs[len(terminal.Bufs)-2]
	wantFinalBuf := ui.NewBufferBuilder(80).WriteUnstyled("some code").
		SetDotToCursor().Buffer()
	if !reflect.DeepEqual(finalBuf, wantFinalBuf) {
		t.Errorf("final buffer is %v, want %v", finalBuf, wantFinalBuf)
	}
}

func TestReadCode_QuitsOnSIGHUP(t *testing.T) {
	ed, terminal, sigs := setup()

	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}

	codeCh, errCh := ed.readCodeAsync()

	wantBuf := ui.NewBufferBuilder(80).WriteUnstyled("a").
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("did not get expected buffer before sending SIGHUP")
	}

	sigs.Ch <- syscall.SIGHUP

	select {
	case <-codeCh:
		err := <-errCh
		if err != io.EOF {
			t.Errorf("want ReadCode to return io.EOF on SIGHUP, got %v", err)
		}
	case <-time.After(time.Second):
		t.Errorf("SIGHUP did not cause ReadCode to return")
	}
}

func TestReadCode_ResetsOnSIGINT(t *testing.T) {
	ed, terminal, sigs := setup()

	terminal.EventCh <- tty.KeyEvent{Rune: 'a'}

	codeCh, _ := ed.readCodeAsync()
	wantBuf := ui.NewBufferBuilder(80).WriteUnstyled("a").
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("did not get expected buffer before sending SIGINT")
	}

	sigs.Ch <- syscall.SIGINT

	wantBuf = ui.NewBufferBuilder(80).Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("Terminal state is not reset after SIGINT")
	}

	cleanup(terminal, codeCh)
}

func TestReadCode_RedrawsOnSIGWINCH(t *testing.T) {
	ed, terminal, sigs := setup()

	ed.state.Raw.Code = "1234567890"
	ed.state.Raw.Dot = len(ed.state.Raw.Code)

	codeCh, _ := ed.readCodeAsync()

	wantBuf := ui.NewBufferBuilder(80).WriteUnstyled("1234567890").
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("did not get expected buffer before sending SIGWINCH")
	}

	terminal.SetSize(24, 4)
	sigs.Ch <- sys.SIGWINCH

	wantBuf = ui.NewBufferBuilder(4).WriteUnstyled("1234567890").
		SetDotToCursor().Buffer()
	if !checkBuffer(wantBuf, terminal.BufCh) {
		t.Errorf("Terminal is not redrawn after SIGWINCH")
	}

	cleanup(terminal, codeCh)
}

func setup() (*Editor, *fakeTTY, *fakeSignalSource) {
	terminal := newFakeTTY()
	sigsrc := newFakeSignalSource()
	ed := NewEditor(terminal, sigsrc)
	return ed, terminal, sigsrc
}

func cleanup(t *fakeTTY, codeCh <-chan string) {
	// Causes BasicMode to quit
	t.EventCh <- tty.KeyEvent{Rune: '\n'}
	// Wait until ReadCode has finished execution
	<-codeCh
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Kubernetes Authors.

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

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

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

package model

import (
	"fmt"

	"k8s.io/kops/nodeup/pkg/distros"
	"k8s.io/kops/upup/pkg/fi"
	"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"

	"k8s.io/klog"
)

// KubectlBuilder install kubectl
type KubectlBuilder struct {
	*NodeupModelContext
}

var _ fi.ModelBuilder = &KubectlBuilder{}

// Build is responsible for managing the kubectl on the nodes
func (b *KubectlBuilder) Build(c *fi.ModelBuilderContext) error {
	if !b.IsMaster {
		return nil
	}

	{
		// TODO: Extract to common function?
		assetName := "kubectl"
		assetPath := ""
		asset, err := b.Assets.Find(assetName, assetPath)
		if err != nil {
			return fmt.Errorf("error trying to locate asset %q: %v", assetName, err)
		}
		if asset == nil {
			return fmt.Errorf("unable to locate asset %q", assetName)
		}

		c.AddTask(&nodetasks.File{
			Path:     b.KubectlPath() + "/" + assetName,
			Contents: asset,
			Type:     nodetasks.FileType_File,
			Mode:     s("0755"),
		})
	}

	{
		kubeconfig, err := b.BuildPKIKubeconfig("kubecfg")
		if err != nil {
			return err
		}

		c.AddTask(&nodetasks.File{
			Path:     "/var/lib/kubectl/kubeconfig",
			Contents: fi.NewStringResource(kubeconfig),
			Type:     nodetasks.FileType_File,
			Mode:     s("0400"),
		})

		adminUser, adminGroup, err := b.findKubeconfigUser()
		if err != nil {
			return err
		}

		if adminUser != nil && adminUser.Home != "" {
			c.AddTask(&nodetasks.File{
				Path:  adminUser.Home + "/.kube/",
				Type:  nodetasks.FileType_Directory,
				Mode:  s("0700"),
				Owner: s(adminUser.Name),
				Group: s(adminGroup.Name),
			})

			c.AddTask(&nodetasks.File{
				Path:     adminUser.Home + "/.kube/config",
				Contents: fi.NewStringResource(kubeconfig),
				Type:     nodetasks.FileType_File,
				Mode:     s("0400"),
				Owner:    s(adminUser.Name),
				Group:    s(adminGroup.Name),
			})
		}
	}

	return nil
}

// findKubeconfigUser finds the default user for whom we should create a kubeconfig
func (b *KubectlBuilder) findKubeconfigUser() (*fi.User, *fi.Group, error) {
	var users []string
	switch b.Distribution {
	case distros.DistributionJessie, distros.DistributionDebian9, distros.DistributionDebian10:
		users = []string{"admin", "root"}
	case distros.DistributionCentos7:
		users = []string{"centos"}
	default:
		klog.Warningf("Unknown distro; won't write kubeconfig to homedir %s", b.Distribution)
		return nil, nil, nil
	}

	for _, s := range users {
		user, err := fi.LookupUser(s)
		if err != nil {
			klog.Warningf("error looking up user %q: %v", s, err)
			continue
		}
		if user == nil {
			continue
		}
		group, err := fi.LookupGroupById(user.Gid)
		if err != nil {
			klog.Warningf("unable to find group %d for user %q", user.Gid, s)
			continue
		}
		if group == nil {
			continue
		}
		return user, group, nil
	}

	return nil, nil, nil
}
<commit_msg>Update default users for kubeconfig with supported distros<commit_after>/*
Copyright 2019 The Kubernetes Authors.

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

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

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

package model

import (
	"fmt"

	"k8s.io/kops/nodeup/pkg/distros"
	"k8s.io/kops/upup/pkg/fi"
	"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"

	"k8s.io/klog"
)

// KubectlBuilder install kubectl
type KubectlBuilder struct {
	*NodeupModelContext
}

var _ fi.ModelBuilder = &KubectlBuilder{}

// Build is responsible for managing the kubectl on the nodes
func (b *KubectlBuilder) Build(c *fi.ModelBuilderContext) error {
	if !b.IsMaster {
		return nil
	}

	{
		// TODO: Extract to common function?
		assetName := "kubectl"
		assetPath := ""
		asset, err := b.Assets.Find(assetName, assetPath)
		if err != nil {
			return fmt.Errorf("error trying to locate asset %q: %v", assetName, err)
		}
		if asset == nil {
			return fmt.Errorf("unable to locate asset %q", assetName)
		}

		c.AddTask(&nodetasks.File{
			Path:     b.KubectlPath() + "/" + assetName,
			Contents: asset,
			Type:     nodetasks.FileType_File,
			Mode:     s("0755"),
		})
	}

	{
		kubeconfig, err := b.BuildPKIKubeconfig("kubecfg")
		if err != nil {
			return err
		}

		c.AddTask(&nodetasks.File{
			Path:     "/var/lib/kubectl/kubeconfig",
			Contents: fi.NewStringResource(kubeconfig),
			Type:     nodetasks.FileType_File,
			Mode:     s("0400"),
		})

		adminUser, adminGroup, err := b.findKubeconfigUser()
		if err != nil {
			return err
		}

		if adminUser != nil && adminUser.Home != "" {
			c.AddTask(&nodetasks.File{
				Path:  adminUser.Home + "/.kube/",
				Type:  nodetasks.FileType_Directory,
				Mode:  s("0700"),
				Owner: s(adminUser.Name),
				Group: s(adminGroup.Name),
			})

			c.AddTask(&nodetasks.File{
				Path:     adminUser.Home + "/.kube/config",
				Contents: fi.NewStringResource(kubeconfig),
				Type:     nodetasks.FileType_File,
				Mode:     s("0400"),
				Owner:    s(adminUser.Name),
				Group:    s(adminGroup.Name),
			})
		}
	}

	return nil
}

// findKubeconfigUser finds the default user for whom we should create a kubeconfig
func (b *KubectlBuilder) findKubeconfigUser() (*fi.User, *fi.Group, error) {
	var users []string
	switch b.Distribution {
	case distros.DistributionJessie, distros.DistributionDebian9, distros.DistributionDebian10:
		users = []string{"admin", "root"}
	case distros.DistributionXenial, distros.DistributionBionic, distros.DistributionFocal:
		users = []string{"ubuntu"}
	case distros.DistributionCentos7, distros.DistributionCentos8:
		users = []string{"centos"}
	case distros.DistributionAmazonLinux2, distros.DistributionRhel7, distros.DistributionRhel8:
		users = []string{"ec2-user"}
	default:
		klog.Warningf("Unknown distro; won't write kubeconfig to homedir %s", b.Distribution)
		return nil, nil, nil
	}

	for _, s := range users {
		user, err := fi.LookupUser(s)
		if err != nil {
			klog.Warningf("error looking up user %q: %v", s, err)
			continue
		}
		if user == nil {
			continue
		}
		group, err := fi.LookupGroupById(user.Gid)
		if err != nil {
			klog.Warningf("unable to find group %d for user %q", user.Gid, s)
			continue
		}
		if group == nil {
			continue
		}
		return user, group, nil
	}

	return nil, nil, nil
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"strconv"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/lambda"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func init() {
	resource.AddTestSweepers("aws_lambda_layer", &resource.Sweeper{
		Name: "aws_lambda_layer",
		F:    testSweepLambdaLayerVersions,
	})
}

func testSweepLambdaLayerVersions(region string) error {
	client, err := sharedClientForRegion(region)
	if err != nil {
		return fmt.Errorf("error getting client: %s", err)
	}

	lambdaconn := client.(*AWSClient).lambdaconn
	resp, err := lambdaconn.ListLayers(&lambda.ListLayersInput{})
	if err != nil {
		if testSweepSkipSweepError(err) {
			log.Printf("[WARN] Skipping Lambda Layer sweep for %s: %s", region, err)
			return nil
		}
		return fmt.Errorf("Error retrieving Lambda layers: %s", err)
	}

	if len(resp.Layers) == 0 {
		log.Print("[DEBUG] No aws lambda layers to sweep")
		return nil
	}

	for _, l := range resp.Layers {
		versionResp, err := lambdaconn.ListLayerVersions(&lambda.ListLayerVersionsInput{
			LayerName: l.LayerName,
		})
		if err != nil {
			return fmt.Errorf("Error retrieving versions for lambda layer: %s", err)
		}

		for _, v := range versionResp.LayerVersions {
			_, err := lambdaconn.DeleteLayerVersion(&lambda.DeleteLayerVersionInput{
				LayerName:     l.LayerName,
				VersionNumber: v.Version,
			})
			if err != nil {
				return err
			}
		}
	}

	return nil
}

func TestAccAWSLambdaLayerVersion_basic(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	layerName := fmt.Sprintf("tf_acc_lambda_layer_basic_%s", acctest.RandString(8))

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionBasic(layerName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
					testAccCheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("layer:%s:1", layerName)),
					resource.TestCheckResourceAttr(resourceName, "compatible_runtimes.#", "0"),
					resource.TestCheckResourceAttr(resourceName, "description", ""),
					resource.TestCheckResourceAttr(resourceName, "layer_name", layerName),
					resource.TestCheckResourceAttr(resourceName, "license_info", ""),
					testAccCheckResourceAttrRegionalARN(resourceName, "layer_arn", "lambda", fmt.Sprintf("layer:%s", layerName)),
					resource.TestCheckResourceAttr(resourceName, "version", "1"),
				),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"filename"},
			},
		},
	})
}

func TestAccAWSLambdaLayerVersion_update(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	layerName := fmt.Sprintf("tf_acc_lambda_layer_basic_%s", acctest.RandString(8))

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionCreateBeforeDestroy(layerName, "test-fixtures/lambdatest.zip"),
				Check:  testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"filename", "source_code_hash"},
			},

			{
				Config: testAccAWSLambdaLayerVersionCreateBeforeDestroy(layerName, "test-fixtures/lambdatest_modified.zip"),
				Check:  testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
			},
		},
	})
}

func TestAccAWSLambdaLayerVersion_s3(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	rString := acctest.RandString(8)
	layerName := fmt.Sprintf("tf_acc_lambda_layer_s3_%s", rString)
	bucketName := fmt.Sprintf("tf-acc-bucket-lambda-layer-s3-%s", rString)

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionS3(bucketName, layerName),
				Check:  testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"s3_bucket", "s3_key"},
			},
		},
	})
}

func TestAccAWSLambdaLayerVersion_compatibleRuntimes(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	rString := acctest.RandString(8)
	layerName := fmt.Sprintf("tf_acc_lambda_layer_runtimes_%s", rString)

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionCompatibleRuntimes(layerName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
					resource.TestCheckResourceAttr(resourceName, "compatible_runtimes.#", "2"),
				),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"filename"},
			},
		},
	})
}

func TestAccAWSLambdaLayerVersion_description(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	rString := acctest.RandString(8)
	layerName := fmt.Sprintf("tf_acc_lambda_layer_description_%s", rString)
	testDescription := "test description"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionDescription(layerName, testDescription),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
					resource.TestCheckResourceAttr(resourceName, "description", testDescription),
				),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"filename"},
			},
		},
	})
}

func TestAccAWSLambdaLayerVersion_licenseInfo(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	rString := acctest.RandString(8)
	layerName := fmt.Sprintf("tf_acc_lambda_layer_license_info_%s", rString)
	testLicenseInfo := "MIT"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionLicenseInfo(layerName, testLicenseInfo),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
					resource.TestCheckResourceAttr(resourceName, "license_info", testLicenseInfo),
				),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"filename"},
			},
		},
	})
}

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

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

		layerName, version, err := resourceAwsLambdaLayerVersionParseId(rs.Primary.ID)
		if err != nil {
			return err
		}

		_, err = conn.GetLayerVersion(&lambda.GetLayerVersionInput{
			LayerName:     aws.String(layerName),
			VersionNumber: aws.Int64(version),
		})
		if isAWSErr(err, lambda.ErrCodeResourceNotFoundException, "") {
			continue
		}
		if err != nil {
			return err
		}

		return fmt.Errorf("Lambda Layer Version (%s) still exists", rs.Primary.ID)
	}

	return nil
}

func testAccCheckAwsLambdaLayerVersionExists(res, layerName string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[res]
		if !ok {
			return fmt.Errorf("Lambda Layer version not found: %s", res)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("Lambda Layer ID not set")
		}

		if rs.Primary.Attributes["version"] == "" {
			return fmt.Errorf("Lambda Layer Version not set")
		}

		version, err := strconv.Atoi(rs.Primary.Attributes["version"])
		if err != nil {
			return err
		}

		conn := testAccProvider.Meta().(*AWSClient).lambdaconn
		_, err = conn.GetLayerVersion(&lambda.GetLayerVersionInput{
			LayerName:     aws.String(layerName),
			VersionNumber: aws.Int64(int64(version)),
		})
		return err
	}
}

func testAccAWSLambdaLayerVersionBasic(layerName string) string {
	return fmt.Sprintf(`
resource "aws_lambda_layer_version" "lambda_layer_test" {
  filename   = "test-fixtures/lambdatest.zip"
  layer_name = "%s"
}
`, layerName)
}

func testAccAWSLambdaLayerVersionS3(bucketName, layerName string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "lambda_bucket" {
  bucket = "%s"
}

resource "aws_s3_bucket_object" "lambda_code" {
  bucket = "${aws_s3_bucket.lambda_bucket.id}"
  key    = "lambdatest.zip"
  source = "test-fixtures/lambdatest.zip"
}

resource "aws_lambda_layer_version" "lambda_layer_test" {
  s3_bucket  = "${aws_s3_bucket.lambda_bucket.id}"
  s3_key     = "${aws_s3_bucket_object.lambda_code.id}"
  layer_name = "%s"
}
`, bucketName, layerName)
}

func testAccAWSLambdaLayerVersionCreateBeforeDestroy(layerName string, filename string) string {
	return fmt.Sprintf(`
resource "aws_lambda_layer_version" "lambda_layer_test" {
  filename         = "%s"
  layer_name       = "%s"
  source_code_hash = "${filebase64sha256("%s")}"

  lifecycle {
    create_before_destroy = true
  }
}
`, filename, layerName, filename)
}

func testAccAWSLambdaLayerVersionCompatibleRuntimes(layerName string) string {
	return fmt.Sprintf(`
resource "aws_lambda_layer_version" "lambda_layer_test" {
  filename   = "test-fixtures/lambdatest.zip"
  layer_name = "%s"

  compatible_runtimes = ["nodejs8.10"]
}
`, layerName)
}

func testAccAWSLambdaLayerVersionDescription(layerName string, description string) string {
	return fmt.Sprintf(`
resource "aws_lambda_layer_version" "lambda_layer_test" {
  filename   = "test-fixtures/lambdatest.zip"
  layer_name = "%s"

  description = "%s"
}
`, layerName, description)
}

func testAccAWSLambdaLayerVersionLicenseInfo(layerName string, licenseInfo string) string {
	return fmt.Sprintf(`
resource "aws_lambda_layer_version" "lambda_layer_test" {
  filename   = "test-fixtures/lambdatest.zip"
  layer_name = "%s"

  license_info = "%s"
}
`, layerName, licenseInfo)
}
<commit_msg>Add second runtime for TestAccAWSLambdaLayerVersion_compatibleRuntimes<commit_after>package aws

import (
	"fmt"
	"log"
	"strconv"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/lambda"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func init() {
	resource.AddTestSweepers("aws_lambda_layer", &resource.Sweeper{
		Name: "aws_lambda_layer",
		F:    testSweepLambdaLayerVersions,
	})
}

func testSweepLambdaLayerVersions(region string) error {
	client, err := sharedClientForRegion(region)
	if err != nil {
		return fmt.Errorf("error getting client: %s", err)
	}

	lambdaconn := client.(*AWSClient).lambdaconn
	resp, err := lambdaconn.ListLayers(&lambda.ListLayersInput{})
	if err != nil {
		if testSweepSkipSweepError(err) {
			log.Printf("[WARN] Skipping Lambda Layer sweep for %s: %s", region, err)
			return nil
		}
		return fmt.Errorf("Error retrieving Lambda layers: %s", err)
	}

	if len(resp.Layers) == 0 {
		log.Print("[DEBUG] No aws lambda layers to sweep")
		return nil
	}

	for _, l := range resp.Layers {
		versionResp, err := lambdaconn.ListLayerVersions(&lambda.ListLayerVersionsInput{
			LayerName: l.LayerName,
		})
		if err != nil {
			return fmt.Errorf("Error retrieving versions for lambda layer: %s", err)
		}

		for _, v := range versionResp.LayerVersions {
			_, err := lambdaconn.DeleteLayerVersion(&lambda.DeleteLayerVersionInput{
				LayerName:     l.LayerName,
				VersionNumber: v.Version,
			})
			if err != nil {
				return err
			}
		}
	}

	return nil
}

func TestAccAWSLambdaLayerVersion_basic(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	layerName := fmt.Sprintf("tf_acc_lambda_layer_basic_%s", acctest.RandString(8))

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionBasic(layerName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
					testAccCheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("layer:%s:1", layerName)),
					resource.TestCheckResourceAttr(resourceName, "compatible_runtimes.#", "0"),
					resource.TestCheckResourceAttr(resourceName, "description", ""),
					resource.TestCheckResourceAttr(resourceName, "layer_name", layerName),
					resource.TestCheckResourceAttr(resourceName, "license_info", ""),
					testAccCheckResourceAttrRegionalARN(resourceName, "layer_arn", "lambda", fmt.Sprintf("layer:%s", layerName)),
					resource.TestCheckResourceAttr(resourceName, "version", "1"),
				),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"filename"},
			},
		},
	})
}

func TestAccAWSLambdaLayerVersion_update(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	layerName := fmt.Sprintf("tf_acc_lambda_layer_basic_%s", acctest.RandString(8))

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionCreateBeforeDestroy(layerName, "test-fixtures/lambdatest.zip"),
				Check:  testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"filename", "source_code_hash"},
			},

			{
				Config: testAccAWSLambdaLayerVersionCreateBeforeDestroy(layerName, "test-fixtures/lambdatest_modified.zip"),
				Check:  testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
			},
		},
	})
}

func TestAccAWSLambdaLayerVersion_s3(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	rString := acctest.RandString(8)
	layerName := fmt.Sprintf("tf_acc_lambda_layer_s3_%s", rString)
	bucketName := fmt.Sprintf("tf-acc-bucket-lambda-layer-s3-%s", rString)

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionS3(bucketName, layerName),
				Check:  testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"s3_bucket", "s3_key"},
			},
		},
	})
}

func TestAccAWSLambdaLayerVersion_compatibleRuntimes(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	rString := acctest.RandString(8)
	layerName := fmt.Sprintf("tf_acc_lambda_layer_runtimes_%s", rString)

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionCompatibleRuntimes(layerName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
					resource.TestCheckResourceAttr(resourceName, "compatible_runtimes.#", "2"),
				),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"filename"},
			},
		},
	})
}

func TestAccAWSLambdaLayerVersion_description(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	rString := acctest.RandString(8)
	layerName := fmt.Sprintf("tf_acc_lambda_layer_description_%s", rString)
	testDescription := "test description"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionDescription(layerName, testDescription),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
					resource.TestCheckResourceAttr(resourceName, "description", testDescription),
				),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"filename"},
			},
		},
	})
}

func TestAccAWSLambdaLayerVersion_licenseInfo(t *testing.T) {
	resourceName := "aws_lambda_layer_version.lambda_layer_test"
	rString := acctest.RandString(8)
	layerName := fmt.Sprintf("tf_acc_lambda_layer_license_info_%s", rString)
	testLicenseInfo := "MIT"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckLambdaLayerVersionDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSLambdaLayerVersionLicenseInfo(layerName, testLicenseInfo),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsLambdaLayerVersionExists(resourceName, layerName),
					resource.TestCheckResourceAttr(resourceName, "license_info", testLicenseInfo),
				),
			},

			{
				ResourceName:            resourceName,
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"filename"},
			},
		},
	})
}

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

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

		layerName, version, err := resourceAwsLambdaLayerVersionParseId(rs.Primary.ID)
		if err != nil {
			return err
		}

		_, err = conn.GetLayerVersion(&lambda.GetLayerVersionInput{
			LayerName:     aws.String(layerName),
			VersionNumber: aws.Int64(version),
		})
		if isAWSErr(err, lambda.ErrCodeResourceNotFoundException, "") {
			continue
		}
		if err != nil {
			return err
		}

		return fmt.Errorf("Lambda Layer Version (%s) still exists", rs.Primary.ID)
	}

	return nil
}

func testAccCheckAwsLambdaLayerVersionExists(res, layerName string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[res]
		if !ok {
			return fmt.Errorf("Lambda Layer version not found: %s", res)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("Lambda Layer ID not set")
		}

		if rs.Primary.Attributes["version"] == "" {
			return fmt.Errorf("Lambda Layer Version not set")
		}

		version, err := strconv.Atoi(rs.Primary.Attributes["version"])
		if err != nil {
			return err
		}

		conn := testAccProvider.Meta().(*AWSClient).lambdaconn
		_, err = conn.GetLayerVersion(&lambda.GetLayerVersionInput{
			LayerName:     aws.String(layerName),
			VersionNumber: aws.Int64(int64(version)),
		})
		return err
	}
}

func testAccAWSLambdaLayerVersionBasic(layerName string) string {
	return fmt.Sprintf(`
resource "aws_lambda_layer_version" "lambda_layer_test" {
  filename   = "test-fixtures/lambdatest.zip"
  layer_name = "%s"
}
`, layerName)
}

func testAccAWSLambdaLayerVersionS3(bucketName, layerName string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "lambda_bucket" {
  bucket = "%s"
}

resource "aws_s3_bucket_object" "lambda_code" {
  bucket = "${aws_s3_bucket.lambda_bucket.id}"
  key    = "lambdatest.zip"
  source = "test-fixtures/lambdatest.zip"
}

resource "aws_lambda_layer_version" "lambda_layer_test" {
  s3_bucket  = "${aws_s3_bucket.lambda_bucket.id}"
  s3_key     = "${aws_s3_bucket_object.lambda_code.id}"
  layer_name = "%s"
}
`, bucketName, layerName)
}

func testAccAWSLambdaLayerVersionCreateBeforeDestroy(layerName string, filename string) string {
	return fmt.Sprintf(`
resource "aws_lambda_layer_version" "lambda_layer_test" {
  filename         = "%s"
  layer_name       = "%s"
  source_code_hash = "${filebase64sha256("%s")}"

  lifecycle {
    create_before_destroy = true
  }
}
`, filename, layerName, filename)
}

func testAccAWSLambdaLayerVersionCompatibleRuntimes(layerName string) string {
	return fmt.Sprintf(`
resource "aws_lambda_layer_version" "lambda_layer_test" {
  filename   = "test-fixtures/lambdatest.zip"
  layer_name = "%s"

  compatible_runtimes = ["nodejs8.10", "nodejs10.x"]
}
`, layerName)
}

func testAccAWSLambdaLayerVersionDescription(layerName string, description string) string {
	return fmt.Sprintf(`
resource "aws_lambda_layer_version" "lambda_layer_test" {
  filename   = "test-fixtures/lambdatest.zip"
  layer_name = "%s"

  description = "%s"
}
`, layerName, description)
}

func testAccAWSLambdaLayerVersionLicenseInfo(layerName string, licenseInfo string) string {
	return fmt.Sprintf(`
resource "aws_lambda_layer_version" "lambda_layer_test" {
  filename   = "test-fixtures/lambdatest.zip"
  layer_name = "%s"

  license_info = "%s"
}
`, layerName, licenseInfo)
}
<|endoftext|>


<commit_before>package middlewares

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/DataDog/datadog-go/statsd"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var c *statsd.Client

// InitClient accepts config parameters and builds the dogstatsd Client, accessible by the getter Client()
// An error is returned only if a problem is encountered setting up the Client.
func InitClient(host string, port string, prefix string, globalTags []string) error {
	var err error
	c, err = statsd.New(host + ":" + port)
	if err != nil {
		return err
	}
	c.Tags = append(c.Tags, globalTags...)
	c.Namespace = prefix + "."
	c.Incr("server_start", []string(nil), 1)
	return nil
}

// Client returns a pointer to the dogstatsd Client, useful for logging metrics
func Client() *statsd.Client {
	return c
}

// Hardcoded maps and values used in DataDogWriter.Write() for constructing a statsd Event from a log message buffer.
var eventMap = map[string]statsd.EventAlertType{
	"debug": statsd.Success,
	"info": statsd.Info,
	"warning": statsd.Warning,
	"error": statsd.Error,
	"fatal": statsd.Error,
}
var iso8601 = "2006-01-02T15:04:05.000Z0700"
type logMsg struct {
	Caller string `json:"caller"`
	Level string `json:"level"`
	Message string `json:"message"`
	Name string `json:"name"`
	Stacktrace string `json:"stacktrace"`
	Timestamp string `json:"timestamp"`
	Tags []string `json:"tags"`
}
func (msg logMsg) Text() string {
	return fmt.Sprintf("{\"message\": \"%s\", \"caller\": \"%s\", \"stack\": \"%s\"}", msg.Message, msg.Caller, msg.Stacktrace)
}

// DataDogWriter implements io.Writer. It should be made into a [WriteSyncer](https://godoc.org/go.uber.org/zap/zapcore#WriteSyncer)
// for sending Zap logs to DataDog as [Events](https://godoc.org/github.com/DataDog/datadog-go/statsd#Event), using
// datadog-go/statsd [Client.Event()](https://godoc.org/github.com/DataDog/datadog-go/statsd#Client.Event).
type DataDogWriter struct {
	client *statsd.Client
}
// Write will take a JSON-formatted log message from zap.L().[Level]() as a byte slice, format it, and send it as
// an Event to d.client.Event().
// @param p []byte - the byte array of the buffered log message.
func (d DataDogWriter) Write(p []byte) (n int, err error) {
	var msg logMsg
	if err := json.Unmarshal(p, &msg); err != nil {
		return 0, err
	}
	ts, err := time.Parse(iso8601, msg.Timestamp)
	if err != nil {
		return 0, err
	}

	tags := msg.Tags
	if tags == nil {
		tags = []string{}
	}
	if d.client != nil && d.client.Tags != nil {
		tags = append(tags, d.client.Tags...)
	}
	evt := statsd.Event{
		AlertType: eventMap[msg.Level],
		Tags: tags,
		Title: msg.Name,
		Text: msg.Text(),
		Timestamp: ts,
	}

	if msg.Level == "debug" {
		evt.Priority = statsd.Low
	} else {
		evt.Priority = statsd.Normal
	}

	if err := d.client.Event(&evt); err != nil {
		return 0, err
	}
	// n is supposed to be the number of bytes written, must return error if n < len(p)
	return len(p), nil
}

// DataDogEventLogger will take an already-constructed zap.Logger and a datadog statsd.Client
// and return a Logger that will also "tee" its output to DataDog Events.
func DataDogEventLogger(l *zap.Logger, sc *statsd.Client, level zapcore.Level) (*zap.Logger) {
	// https://godoc.org/go.uber.org/zap#hdr-Extending_Zap
	stdZapConfig := NewStandardZapConfig()
	opts := zap.WrapCore(func(c zapcore.Core) zapcore.Core {
		enc := stdZapConfig.EncoderConfig
		ddw := zapcore.AddSync(DataDogWriter{
			sc,
		})
		datadogCore := zapcore.NewCore(zapcore.NewJSONEncoder(enc), ddw, level)
		return zapcore.NewTee(c, datadogCore)
	})

	return l.WithOptions(opts)
}<commit_msg>Event.Title is required, make sure it exists<commit_after>package middlewares

import (
	"encoding/json"
	"fmt"
	"os"
	"time"

	"github.com/DataDog/datadog-go/statsd"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var c *statsd.Client

// InitClient accepts config parameters and builds the dogstatsd Client, accessible by the getter Client()
// An error is returned only if a problem is encountered setting up the Client.
func InitClient(host string, port string, prefix string, globalTags []string) error {
	var err error
	c, err = statsd.New(host + ":" + port)
	if err != nil {
		return err
	}
	c.Tags = append(c.Tags, globalTags...)
	c.Namespace = prefix + "."
	c.Incr("server_start", []string(nil), 1)
	return nil
}

// Client returns a pointer to the dogstatsd Client, useful for logging metrics
func Client() *statsd.Client {
	return c
}

// Hardcoded maps and values used in DataDogWriter.Write() for constructing a statsd Event from a log message buffer.
var eventMap = map[string]statsd.EventAlertType{
	"debug": statsd.Success,
	"info": statsd.Info,
	"warning": statsd.Warning,
	"error": statsd.Error,
	"fatal": statsd.Error,
}
var iso8601 = "2006-01-02T15:04:05.000Z0700"
type logMsg struct {
	Caller string `json:"caller"`
	Level string `json:"level"`
	Message string `json:"message"`
	Name string `json:"name"`
	Stacktrace string `json:"stacktrace"`
	Timestamp string `json:"timestamp"`
	Tags []string `json:"tags"`
}
func (msg logMsg) Text() string {
	return fmt.Sprintf("{\"message\": \"%s\", \"caller\": \"%s\", \"stack\": \"%s\"}", msg.Message, msg.Caller, msg.Stacktrace)
}

// DataDogWriter implements io.Writer. It should be made into a [WriteSyncer](https://godoc.org/go.uber.org/zap/zapcore#WriteSyncer)
// for sending Zap logs to DataDog as [Events](https://godoc.org/github.com/DataDog/datadog-go/statsd#Event), using
// datadog-go/statsd [Client.Event()](https://godoc.org/github.com/DataDog/datadog-go/statsd#Client.Event).
type DataDogWriter struct {
	client *statsd.Client
}
// Write will take a JSON-formatted log message from zap.L().[Level]() as a byte slice, format it, and send it as
// an Event to d.client.Event().
// @param p []byte - the byte array of the buffered log message.
func (d DataDogWriter) Write(p []byte) (n int, err error) {
	var msg logMsg
	if err := json.Unmarshal(p, &msg); err != nil {
		return 0, err
	}
	ts, err := time.Parse(iso8601, msg.Timestamp)
	if err != nil {
		return 0, err
	}

	tags := msg.Tags
	if tags == nil {
		tags = []string{}
	}
	if d.client != nil && d.client.Tags != nil {
		tags = append(tags, d.client.Tags...)
	}
	if msg.Name == "" {
		// Event.Title is required, so force msg.Name to be non-empty. os.Args[0] is the executable name.
		msg.Name = os.Args[0] + " event"
	}
	evt := statsd.Event{
		AlertType: eventMap[msg.Level],
		Tags: tags,
		Title: msg.Name,
		Text: msg.Text(),
		Timestamp: ts,
	}

	if msg.Level == "debug" {
		evt.Priority = statsd.Low
	} else {
		evt.Priority = statsd.Normal
	}

	if err := d.client.Event(&evt); err != nil {
		return 0, err
	}
	// n is supposed to be the number of bytes written, must return error if n < len(p)
	return len(p), nil
}

// DataDogEventLogger will take an already-constructed zap.Logger and a datadog statsd.Client
// and return a Logger that will also "tee" its output to DataDog Events.
func DataDogEventLogger(l *zap.Logger, sc *statsd.Client, level zapcore.Level) (*zap.Logger) {
	// https://godoc.org/go.uber.org/zap#hdr-Extending_Zap
	stdZapConfig := NewStandardZapConfig()
	opts := zap.WrapCore(func(c zapcore.Core) zapcore.Core {
		enc := stdZapConfig.EncoderConfig
		ddw := zapcore.AddSync(DataDogWriter{
			sc,
		})
		datadogCore := zapcore.NewCore(zapcore.NewJSONEncoder(enc), ddw, level)
		return zapcore.NewTee(c, datadogCore)
	})

	return l.WithOptions(opts)
}<|endoftext|>


<commit_before>package cloudup

import (
	"fmt"
	"github.com/golang/glog"
	"k8s.io/kops/pkg/apis/kops"
	"k8s.io/kops/util/pkg/vfs"
	"strings"
)

// PerformAssignments populates values that are required and immutable
// For example, it assigns stable Keys to InstanceGroups & Masters, and
// it assigns CIDRs to subnets
// We also assign KubernetesVersion, because we want it to be explicit
func PerformAssignments(c *kops.Cluster) error {
	err := assignCIDRsToSubnets(c)
	if err != nil {
		return err
	}

	if c.Spec.NetworkCIDR == "" && !c.SharedVPC() {
		// TODO: Choose non-overlapping networking CIDRs for VPCs?
		c.Spec.NetworkCIDR = "172.20.0.0/16"
	}

	if c.Spec.NonMasqueradeCIDR == "" {
		c.Spec.NonMasqueradeCIDR = "100.64.0.0/10"
	}

	// TODO: Unclear this should be here - it isn't too hard to change
	if c.Spec.MasterPublicName == "" && c.ObjectMeta.Name != "" {
		c.Spec.MasterPublicName = "api." + c.ObjectMeta.Name
	}

	return ensureKubernetesVersion(c)
}

// ensureKubernetesVersion populates KubernetesVersion, if it is not already set
// It will be populated with the latest stable kubernetes version, or the version from the channel
func ensureKubernetesVersion(c *kops.Cluster) error {
	if c.Spec.KubernetesVersion == "" {
		if c.Spec.Channel != "" {
			channel, err := kops.LoadChannel(c.Spec.Channel)
			if err != nil {
				return err
			}
			if channel.Spec.Cluster.KubernetesVersion != "" {
				c.Spec.KubernetesVersion = channel.Spec.Cluster.KubernetesVersion
			}
		}
	}

	if c.Spec.KubernetesVersion == "" {
		latestVersion, err := FindLatestKubernetesVersion()
		if err != nil {
			return err
		}
		glog.Infof("Using kubernetes latest stable version: %s", latestVersion)
		c.Spec.KubernetesVersion = latestVersion
	}
	return nil
}

// FindLatestKubernetesVersion returns the latest kubernetes version,
// as stored at https://storage.googleapis.com/kubernetes-release/release/stable.txt
// This shouldn't be used any more; we prefer reading the stable channel
func FindLatestKubernetesVersion() (string, error) {
	stableURL := "https://storage.googleapis.com/kubernetes-release/release/stable.txt"
	glog.Warningf("Loading latest kubernetes version from %q", stableURL)
	b, err := vfs.Context.ReadFile(stableURL)
	if err != nil {
		return "", fmt.Errorf("KubernetesVersion not specified, and unable to download latest version from %q: %v", stableURL, err)
	}
	latestVersion := strings.TrimSpace(string(b))
	return latestVersion, nil
}
<commit_msg>Set default NetworkCIDR before subnets<commit_after>package cloudup

import (
	"fmt"
	"github.com/golang/glog"
	"k8s.io/kops/pkg/apis/kops"
	"k8s.io/kops/util/pkg/vfs"
	"strings"
)

// PerformAssignments populates values that are required and immutable
// For example, it assigns stable Keys to InstanceGroups & Masters, and
// it assigns CIDRs to subnets
// We also assign KubernetesVersion, because we want it to be explicit
func PerformAssignments(c *kops.Cluster) error {
	if c.Spec.NetworkCIDR == "" && !c.SharedVPC() {
		// TODO: Choose non-overlapping networking CIDRs for VPCs?
		c.Spec.NetworkCIDR = "172.20.0.0/16"
	}

	if c.Spec.NonMasqueradeCIDR == "" {
		c.Spec.NonMasqueradeCIDR = "100.64.0.0/10"
	}

	// TODO: Unclear this should be here - it isn't too hard to change
	if c.Spec.MasterPublicName == "" && c.ObjectMeta.Name != "" {
		c.Spec.MasterPublicName = "api." + c.ObjectMeta.Name
	}

	err := assignCIDRsToSubnets(c)
	if err != nil {
		return err
	}

	return ensureKubernetesVersion(c)
}

// ensureKubernetesVersion populates KubernetesVersion, if it is not already set
// It will be populated with the latest stable kubernetes version, or the version from the channel
func ensureKubernetesVersion(c *kops.Cluster) error {
	if c.Spec.KubernetesVersion == "" {
		if c.Spec.Channel != "" {
			channel, err := kops.LoadChannel(c.Spec.Channel)
			if err != nil {
				return err
			}
			if channel.Spec.Cluster.KubernetesVersion != "" {
				c.Spec.KubernetesVersion = channel.Spec.Cluster.KubernetesVersion
			}
		}
	}

	if c.Spec.KubernetesVersion == "" {
		latestVersion, err := FindLatestKubernetesVersion()
		if err != nil {
			return err
		}
		glog.Infof("Using kubernetes latest stable version: %s", latestVersion)
		c.Spec.KubernetesVersion = latestVersion
	}
	return nil
}

// FindLatestKubernetesVersion returns the latest kubernetes version,
// as stored at https://storage.googleapis.com/kubernetes-release/release/stable.txt
// This shouldn't be used any more; we prefer reading the stable channel
func FindLatestKubernetesVersion() (string, error) {
	stableURL := "https://storage.googleapis.com/kubernetes-release/release/stable.txt"
	glog.Warningf("Loading latest kubernetes version from %q", stableURL)
	b, err := vfs.Context.ReadFile(stableURL)
	if err != nil {
		return "", fmt.Errorf("KubernetesVersion not specified, and unable to download latest version from %q: %v", stableURL, err)
	}
	latestVersion := strings.TrimSpace(string(b))
	return latestVersion, nil
}
<|endoftext|>