<commit_before>package rest

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"
)

type RestExample struct {
	Service `prefix:"/prefix" mime:"application/json" charset:"utf-8"`

	CreateHello Processor `method:"POST" path:"/hello"`
	GetHello    Processor `method:"GET" path:"/hello/:to" func:"HandleHello"`
	Watch       Streaming `method:"GET" path:"/hello/:to/streaming"`

	post  map[string]string
	watch map[string]chan string
}

type HelloArg struct {
	To   string `json:"to"`
	Post string `json:"post"`
}

// Post example:
// > curl "http://127.0.0.1:8080/prefix/hello" -d '{"to":"rest", "post":"rest is powerful"}'
//
// No response
func (r RestExample) HandleCreateHello(arg HelloArg) {
	r.post[arg.To] = arg.Post
	c, ok := r.watch[arg.To]
	if ok {
		select {
		case c <- arg.Post:
		default:
		}
	}
}

// Get example:
// > curl "http://127.0.0.1:8080/prefix/hello/rest"
//
// Response:
//   {"to":"rest","post":"rest is powerful"}
func (r RestExample) HandleHello() HelloArg {
	to := r.Vars()["to"]
	post, ok := r.post[to]
	if !ok {
		r.Error(http.StatusNotFound, r.GetError(2, fmt.Sprintf("can't find hello to %s", to)))
		return HelloArg{}
	}
	return HelloArg{
		To:   to,
		Post: post,
	}
}

// Streaming example:
// > curl "http://127.0.0.1:8080/prefix/hello/rest/streaming"
//
// It create a long-live connection and will receive post content "rest is powerful"
// when running post example.
func (r RestExample) HandleWatch(s Stream) {
	to := r.Vars()["to"]
	if to == "" {
		r.Error(http.StatusBadRequest, r.GetError(3, "need 'to' parameter."))
		return
	}
	r.WriteHeader(http.StatusOK)
	c := make(chan string)
	r.watch[to] = c
	for {
		var post interface{}
		select {
		case <-time.After(time.Second):
			return
		case post = <-c:
		}
		s.SetDeadline(time.Now().Add(time.Second))
		err := s.Write(post)
		if err != nil {
			close(c)
			delete(r.watch, to)
			return
		}
	}
}

func TestError(t *testing.T) {
	type Test struct {
		url     string
		method  string
		request string

		code     int
		headers  http.Header
		response string
	}
	var tests = []Test{
		{"http://domain/prefix/nonexist", "GET", ``, http.StatusNotFound, http.Header{}, ""},
		{"http://domain/prefix/hello", "GET", ``, http.StatusNotFound, http.Header{}, ""},
		{"http://domain/prefix/hello", "POST", ``, http.StatusBadRequest, http.Header{"Content-Type": []string{"application/json; charset=utf-8"}}, "{\"code\":-1,\"message\":\"marshal request to HelloArg failed: EOF\"}\n"},
		{"http://domain/prefix/hello", "POST", `{"to":"rest", "post":"rest is powerful"}`, http.StatusOK, http.Header{"Content-Type": []string{"application/json; charset=utf-8"}}, ""},

		{"http://domain/prefix/hello/abc", "GET", ``, http.StatusNotFound, http.Header{"Content-Type": []string{"application/json; charset=utf-8"}}, "{\"code\":2,\"message\":\"can't find hello to abc\"}\n"},
		{"http://domain/prefix/hello/rest", "GET", ``, http.StatusOK, http.Header{"Content-Type": []string{"application/json; charset=utf-8"}}, "{\"to\":\"rest\",\"post\":\"rest is powerful\"}\n"},

		{"http://domain/prefix/hello/abc/streaming", "GET", ``, http.StatusInternalServerError, http.Header{"Content-Type": []string{"application/json; charset=utf-8"}}, "{\"code\":-1,\"message\":\"webserver doesn't support hijacking\"}\n"},
	}
	r, err := New(&RestExample{
		post:  make(map[string]string),
		watch: make(map[string]chan string),
	})
	if err != nil {
		t.Fatalf("new rest service failed: %s", err)
	}
	equal(t, r.Prefix(), "/prefix/")
	for i, test := range tests {
		buf := bytes.NewBufferString(test.request)
		req, err := http.NewRequest(test.method, test.url, buf)
		if err != nil {
			t.Fatalf("can't create request of test %d: %s", i, err)
		}
		resp := httptest.NewRecorder()
		resp.Code = http.StatusOK
		r.ServeHTTP(resp, req)
		equal(t, resp.Code, test.code, "test %d", i)
		equal(t, resp.Body.String(), test.response, "test %d", i)
		equal(t, resp.HeaderMap, test.headers, "test %d", i)
	}
}

func TestExample(t *testing.T) {
	instance := &RestExample{
		post:  make(map[string]string),
		watch: make(map[string]chan string),
	}
	rest, err := New(instance)
	if err != nil {
		t.Fatalf("create rest failed: %s", err)
	}

	equal(t, rest.Prefix(), "/prefix/")

	server := httptest.NewServer(rest)
	defer server.Close()

	resp, err := http.Get(server.URL + "/prefix/hello/rest")
	if err != nil {
		t.Fatal(err)
	}
	resp.Body.Close()
	equal(t, resp.StatusCode, http.StatusNotFound)

	c := make(chan int)
	go func() {
		resp, err := http.Get(server.URL + "/prefix/hello//streaming")
		if err != nil {
			t.Fatal(err)
		}
		defer resp.Body.Close()

		equal(t, resp.StatusCode, http.StatusBadRequest)
		equal(t, resp.Header, http.Header{"Connection": []string{"keep-alive"}, "Content-Type": []string{"application/json; charset=utf-8"}})
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			t.Fatal(err)
		}
		equal(t, string(body), "{\"code\":3,\"message\":\"need 'to' parameter.\"}\n")

		resp, err = http.Get(server.URL + "/prefix/hello/rest/streaming")
		if err != nil {
			t.Fatal(err)
		}
		defer resp.Body.Close()

		equal(t, resp.StatusCode, http.StatusOK)

		expect := "\"rest is powerful\"\n"
		get := make([]byte, len(expect))
		n, err := resp.Body.Read(get)
		if err != nil {
			t.Fatal(err)
		}
		get = get[:n]
		equal(t, string(get), expect)

		c <- 1
	}()

	time.Sleep(time.Second / 2) // waiting streaming connected

	arg := HelloArg{
		To:   "rest",
		Post: "rest is powerful",
	}
	buf := bytes.NewBuffer(nil)
	encoder := json.NewEncoder(buf)
	err = encoder.Encode(arg)
	if err != nil {
		t.Fatal(err)
	}
	resp, err = http.Post(server.URL+"/prefix/hello", "application/json", buf)
	if err != nil {
		t.Fatal(err)
	}
	resp.Body.Close()

	select {
	case <-c:
	case <-time.After(time.Second):
		t.Errorf("waiting streaming too long")
	}

	resp, err = http.Get(server.URL + "/prefix/hello/rest")
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()

	equal(t, resp.StatusCode, http.StatusOK)

	decoder := json.NewDecoder(resp.Body)
	err = decoder.Decode(&arg)
	if err != nil {
		t.Fatal(err)
	}
	equal(t, arg.To, "rest")
	equal(t, arg.Post, "rest is powerful")
}

type CompressExample struct {
	Service `compress:"on"`

	P Processor `path:"/p" method:"POST"`
	S Streaming `path:"/s" method:"GET"`
}

func (c CompressExample) HandleP() string {
	return "Hello"
}

func (c CompressExample) HandleS(s Stream) {
	s.Write("Hello")
}

func TestCompress(t *testing.T) {
	rest, err := New(new(CompressExample))
	if err != nil {
		t.Fatal(err)
	}

	server := httptest.NewServer(rest)
	defer server.Close()

	req, err := http.NewRequest("POST", server.URL+"/p", nil)
	if err != nil {
		t.Fatal(err)
	}
	req.Header.Set("Accept-Encoding", "gzip")
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()
	equal(t, resp.StatusCode, http.StatusOK)
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatal(err)
	}
	equal(t, resp.Header.Get("Content-Encoding"), "gzip")
	equal(t, string(b), "\x1f\x8b\b\x00\x00\tn\x88\x00\xffR\xf2H\xcd\xc9\xc9W\xe2\x02\x04\x00\x00\xff\xffa\xeer\xd8\b\x00\x00\x00")

	req, err = http.NewRequest("GET", server.URL+"/s", nil)
	if err != nil {
		t.Fatal(err)
	}
	req.Header.Set("Accept-Encoding", "gzip")
	resp, err = http.DefaultClient.Do(req)
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()
	equal(t, resp.StatusCode, http.StatusOK)
	b, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatal(err)
	}
	equal(t, resp.Header.Get("Content-Encoding"), "gzip")
	equal(t, string(b), "\x1f\x8b\b\x00\x00\tn\x88\x00\xffR\xf2H\xcd\xc9\xc9W\xe2\x02\x04\x00\x00\xff\xffa\xeer\xd8\b\x00\x00\x00")
}
<commit_msg>update test<commit_after>package rest

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"
)

type RestExample struct {
	Service `prefix:"/prefix" mime:"application/json" charset:"utf-8"`

	CreateHello Processor `method:"POST" path:"/hello"`
	GetHello    Processor `method:"GET" path:"/hello/:to" func:"HandleHello"`
	Watch       Streaming `method:"GET" path:"/hello/:to/streaming" end:"\n"`

	post  map[string]string
	watch map[string]chan string
}

type HelloArg struct {
	To   string `json:"to"`
	Post string `json:"post"`
}

// Post example:
// > curl "http://127.0.0.1:8080/prefix/hello" -d '{"to":"rest", "post":"rest is powerful"}'
//
// No response
func (r RestExample) HandleCreateHello(arg HelloArg) {
	r.post[arg.To] = arg.Post
	c, ok := r.watch[arg.To]
	if ok {
		select {
		case c <- arg.Post:
		default:
		}
	}
}

// Get example:
// > curl "http://127.0.0.1:8080/prefix/hello/rest"
//
// Response:
//   {"to":"rest","post":"rest is powerful"}
func (r RestExample) HandleHello() HelloArg {
	to := r.Vars()["to"]
	post, ok := r.post[to]
	if !ok {
		r.Error(http.StatusNotFound, r.GetError(2, fmt.Sprintf("can't find hello to %s", to)))
		return HelloArg{}
	}
	return HelloArg{
		To:   to,
		Post: post,
	}
}

// Streaming example:
// > curl "http://127.0.0.1:8080/prefix/hello/rest/streaming"
//
// It create a long-live connection and will receive post content "rest is powerful"
// when running post example.
func (r RestExample) HandleWatch(s Stream) {
	to := r.Vars()["to"]
	if to == "" {
		r.Error(http.StatusBadRequest, r.GetError(3, "need 'to' parameter."))
		return
	}
	r.WriteHeader(http.StatusOK)
	c := make(chan string)
	r.watch[to] = c
	for {
		var post interface{}
		select {
		case <-time.After(time.Second):
			return
		case post = <-c:
		}
		s.SetDeadline(time.Now().Add(time.Second))
		err := s.Write(post)
		if err != nil {
			close(c)
			delete(r.watch, to)
			return
		}
	}
}

func TestError(t *testing.T) {
	type Test struct {
		url     string
		method  string
		request string

		code     int
		headers  http.Header
		response string
	}
	var tests = []Test{
		{"http://domain/prefix/nonexist", "GET", ``, http.StatusNotFound, http.Header{}, ""},
		{"http://domain/prefix/hello", "GET", ``, http.StatusNotFound, http.Header{}, ""},
		{"http://domain/prefix/hello", "POST", ``, http.StatusBadRequest, http.Header{"Content-Type": []string{"application/json; charset=utf-8"}}, "{\"code\":-1,\"message\":\"marshal request to HelloArg failed: EOF\"}\n"},
		{"http://domain/prefix/hello", "POST", `{"to":"rest", "post":"rest is powerful"}`, http.StatusOK, http.Header{"Content-Type": []string{"application/json; charset=utf-8"}}, ""},

		{"http://domain/prefix/hello/abc", "GET", ``, http.StatusNotFound, http.Header{"Content-Type": []string{"application/json; charset=utf-8"}}, "{\"code\":2,\"message\":\"can't find hello to abc\"}\n"},
		{"http://domain/prefix/hello/rest", "GET", ``, http.StatusOK, http.Header{"Content-Type": []string{"application/json; charset=utf-8"}}, "{\"to\":\"rest\",\"post\":\"rest is powerful\"}\n"},

		{"http://domain/prefix/hello/abc/streaming", "GET", ``, http.StatusInternalServerError, http.Header{"Content-Type": []string{"application/json; charset=utf-8"}}, "{\"code\":-1,\"message\":\"webserver doesn't support hijacking\"}\n"},
	}
	r, err := New(&RestExample{
		post:  make(map[string]string),
		watch: make(map[string]chan string),
	})
	if err != nil {
		t.Fatalf("new rest service failed: %s", err)
	}
	equal(t, r.Prefix(), "/prefix/")
	for i, test := range tests {
		buf := bytes.NewBufferString(test.request)
		req, err := http.NewRequest(test.method, test.url, buf)
		if err != nil {
			t.Fatalf("can't create request of test %d: %s", i, err)
		}
		resp := httptest.NewRecorder()
		resp.Code = http.StatusOK
		r.ServeHTTP(resp, req)
		equal(t, resp.Code, test.code, "test %d", i)
		equal(t, resp.Body.String(), test.response, "test %d", i)
		equal(t, resp.HeaderMap, test.headers, "test %d", i)
	}
}

func TestExample(t *testing.T) {
	instance := &RestExample{
		post:  make(map[string]string),
		watch: make(map[string]chan string),
	}
	rest, err := New(instance)
	if err != nil {
		t.Fatalf("create rest failed: %s", err)
	}

	equal(t, rest.Prefix(), "/prefix/")

	server := httptest.NewServer(rest)
	defer server.Close()

	resp, err := http.Get(server.URL + "/prefix/hello/rest")
	if err != nil {
		t.Fatal(err)
	}
	resp.Body.Close()
	equal(t, resp.StatusCode, http.StatusNotFound)

	c := make(chan int)
	go func() {
		resp, err := http.Get(server.URL + "/prefix/hello//streaming")
		if err != nil {
			t.Fatal(err)
		}
		defer resp.Body.Close()

		equal(t, resp.StatusCode, http.StatusBadRequest)
		equal(t, resp.Header, http.Header{"Connection": []string{"keep-alive"}, "Content-Type": []string{"application/json; charset=utf-8"}})
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			t.Fatal(err)
		}
		equal(t, string(body), "{\"code\":3,\"message\":\"need 'to' parameter.\"}\n")

		resp, err = http.Get(server.URL + "/prefix/hello/rest/streaming")
		if err != nil {
			t.Fatal(err)
		}
		defer resp.Body.Close()

		equal(t, resp.StatusCode, http.StatusOK)

		expect := "\"rest is powerful\"\n\n"
		get := make([]byte, len(expect))
		n, err := resp.Body.Read(get)
		if err != nil {
			t.Fatal(err)
		}
		get = get[:n]
		equal(t, string(get), expect)

		c <- 1
	}()

	time.Sleep(time.Second / 2) // waiting streaming connected

	arg := HelloArg{
		To:   "rest",
		Post: "rest is powerful",
	}
	buf := bytes.NewBuffer(nil)
	encoder := json.NewEncoder(buf)
	err = encoder.Encode(arg)
	if err != nil {
		t.Fatal(err)
	}
	resp, err = http.Post(server.URL+"/prefix/hello", "application/json", buf)
	if err != nil {
		t.Fatal(err)
	}
	resp.Body.Close()

	select {
	case <-c:
	case <-time.After(time.Second):
		t.Errorf("waiting streaming too long")
	}

	resp, err = http.Get(server.URL + "/prefix/hello/rest")
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()

	equal(t, resp.StatusCode, http.StatusOK)

	decoder := json.NewDecoder(resp.Body)
	err = decoder.Decode(&arg)
	if err != nil {
		t.Fatal(err)
	}
	equal(t, arg.To, "rest")
	equal(t, arg.Post, "rest is powerful")
}

type CompressExample struct {
	Service `compress:"on"`

	P Processor `path:"/p" method:"POST"`
	S Streaming `path:"/s" method:"GET"`
}

func (c CompressExample) HandleP() string {
	return "Hello"
}

func (c CompressExample) HandleS(s Stream) {
	s.Write("Hello")
}

func TestCompress(t *testing.T) {
	rest, err := New(new(CompressExample))
	if err != nil {
		t.Fatal(err)
	}

	server := httptest.NewServer(rest)
	defer server.Close()

	req, err := http.NewRequest("POST", server.URL+"/p", nil)
	if err != nil {
		t.Fatal(err)
	}
	req.Header.Set("Accept-Encoding", "gzip")
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()
	equal(t, resp.StatusCode, http.StatusOK)
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatal(err)
	}
	equal(t, resp.Header.Get("Content-Encoding"), "gzip")
	equal(t, string(b), "\x1f\x8b\b\x00\x00\tn\x88\x00\xffR\xf2H\xcd\xc9\xc9W\xe2\x02\x04\x00\x00\xff\xffa\xeer\xd8\b\x00\x00\x00")

	req, err = http.NewRequest("GET", server.URL+"/s", nil)
	if err != nil {
		t.Fatal(err)
	}
	req.Header.Set("Accept-Encoding", "gzip")
	resp, err = http.DefaultClient.Do(req)
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()
	equal(t, resp.StatusCode, http.StatusOK)
	b, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatal(err)
	}
	equal(t, resp.Header.Get("Content-Encoding"), "gzip")
	equal(t, string(b), "\x1f\x8b\b\x00\x00\tn\x88\x00\xffR\xf2H\xcd\xc9\xc9W\xe2\x02\x04\x00\x00\xff\xffa\xeer\xd8\b\x00\x00\x00")
}
<|endoftext|>


<commit_before>package version

// VERSION ...
const VERSION = "1.5.0"
<commit_msg>version fix<commit_after>package version

// VERSION ...
const VERSION = "1.5.1"
<|endoftext|>


<commit_before>package version

import "fmt"

const (
	Version           = "0.28.0"
	VersionPrerelease = "" // "-dev", "-beta", "-rc1", etc. (include dash)
)

var (
	Name      string = "consul-template"
	GitCommit string

	HumanVersion = fmt.Sprintf("%s v%s%s (%s)",
		Name, Version, VersionPrerelease, GitCommit)
)
<commit_msg>Release v0.0.2-rc<commit_after>package version

import "fmt"

const (
	Version           = "0.0.2"
	VersionPrerelease = "rc" // "-dev", "-beta", "-rc1", etc. (include dash)
)

var (
	Name      string = "consul-template"
	GitCommit string

	HumanVersion = fmt.Sprintf("%s v%s%s (%s)",
		Name, Version, VersionPrerelease, GitCommit)
)
<|endoftext|>


<commit_before>package version

import(
	"fmt"
)

const (
	TenyksVersion = "1.0"
)

var Info []string

func init() {
	Info = append(Info,
		fmt.Sprintf("I am Tenyks version %s", TenyksVersion),
		"I am written in the Go programming language",
		"You can find my code at https://github.com/kyleterry/tenyks")
}

func GetInfo() []string {
	return Info
}
<commit_msg>going with 0.9 as a beta for now<commit_after>package version

import(
	"fmt"
)

const (
	TenyksVersion = "0.9"
)

var Info []string

func init() {
	Info = append(Info,
		fmt.Sprintf("I am Tenyks version %s", TenyksVersion),
		"I am written in the Go programming language",
		"You can find my code at https://github.com/kyleterry/tenyks")
}

func GetInfo() []string {
	return Info
}
<|endoftext|>


<commit_before>package types

import (
	"fmt"
)

// CheckMapType checks the type of m[k] is t, and return the value if yes,
// or return an error if not.
//
// If m is nil, return an error.
//
// The function uses VerifyType to verify the type, that's, VerifyType(m[k], t),
// so for t, see VerifyType.
func CheckMapType(m map[string]interface{}, k, t string) (interface{}, error) {
	if len(m) == 0 {
		return nil, fmt.Errorf("the map is nil")
	}
	value := m[k]
	if value == nil {
		return nil, fmt.Errorf("the value of the key[%s] in map is nil", k)
	}
	if !VerifyType(value, t) {
		return nil, fmt.Errorf("the value of the key[%s] in map is not %s",
			k, stype2type[k])
	}
	return value, nil
}

// MapBool check whether m[key] is the bool type, and return the bool value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapBool(m map[string]interface{}, key string) (v bool, err error) {
	_v, err := CheckMapType(m, key, "bool")
	if err == nil {
		v = _v.(bool)
	}
	return
}

// MapString check whether m[key] is the string type, and return the string
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapString(m map[string]interface{}, key string) (v string, err error) {
	_v, err := CheckMapType(m, key, "string")
	if err == nil {
		v = _v.(string)
	}
	return
}

// MapInt check whether m[key] is the int type, and return the int value if yes,
// or return an error if not.
//
// If m is nil, return an error.
func MapInt(m map[string]interface{}, key string) (v int, err error) {
	_v, err := CheckMapType(m, key, "int")
	if err == nil {
		v = _v.(int)
	}
	return
}

// MapInt8 check whether m[key] is the int8 type, and return the int8 value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapInt8(m map[string]interface{}, key string) (v int8, err error) {
	_v, err := CheckMapType(m, key, "int8")
	if err == nil {
		v = _v.(int8)
	}
	return
}

// MapInt16 check whether m[key] is the int16 type, and return the int16 value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapInt16(m map[string]interface{}, key string) (v int16, err error) {
	_v, err := CheckMapType(m, key, "int16")
	if err == nil {
		v = _v.(int16)
	}
	return
}

// MapInt32 check whether m[key] is the int32 type, and return the int32 value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapInt32(m map[string]interface{}, key string) (v int32, err error) {
	_v, err := CheckMapType(m, key, "int32")
	if err == nil {
		v = _v.(int32)
	}
	return
}

// MapInt64 check whether m[key] is the int64 type, and return the int64 value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapInt64(m map[string]interface{}, key string) (v int64, err error) {
	_v, err := CheckMapType(m, key, "int64")
	if err == nil {
		v = _v.(int64)
	}
	return
}

// MapUint check whether m[key] is the uint type, and return the uint value if yes,
// or return an error if not.
//
// If m is nil, return an error.
func MapUint(m map[string]interface{}, key string) (v uint, err error) {
	_v, err := CheckMapType(m, key, "uint")
	if err == nil {
		v = _v.(uint)
	}
	return
}

// MapUint8 check whether m[key] is the uint8 type, and return the uint8 value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapUint8(m map[string]interface{}, key string) (v uint8, err error) {
	_v, err := CheckMapType(m, key, "uint8")
	if err == nil {
		v = _v.(uint8)
	}
	return
}

// MapUint16 check whether m[key] is the uint16 type, and return the uint16
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapUint16(m map[string]interface{}, key string) (v uint16, err error) {
	_v, err := CheckMapType(m, key, "uint16")
	if err == nil {
		v = _v.(uint16)
	}
	return
}

// MapUint32 check whether m[key] is the uint32 type, and return the uint32
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapUint32(m map[string]interface{}, key string) (v uint32, err error) {
	_v, err := CheckMapType(m, key, "uint32")
	if err == nil {
		v = _v.(uint32)
	}
	return
}

// MapUint64 check whether m[key] is the uint64 type, and return the uint64
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapUint64(m map[string]interface{}, key string) (v uint64, err error) {
	_v, err := CheckMapType(m, key, "uint64")
	if err == nil {
		v = _v.(uint64)
	}
	return
}

// MapFloat32 check whether m[key] is the Float32 type, and return the Float32
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapFloat32(m map[string]interface{}, key string) (v float32, err error) {
	_v, err := CheckMapType(m, key, "float32")
	if err == nil {
		v = _v.(float32)
	}
	return
}

// MapFloat64 check whether m[key] is the float64 type, and return the float64
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapFloat64(m map[string]interface{}, key string) (v float64, err error) {
	_v, err := CheckMapType(m, key, "float64")
	if err == nil {
		v = _v.(float64)
	}
	return
}

// MapComplex64 check whether m[key] is the complex64 type, and return the
// complex64 value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapComplex64(m map[string]interface{}, key string) (v complex64, err error) {
	_v, err := CheckMapType(m, key, "complex64")
	if err == nil {
		v = _v.(complex64)
	}
	return
}

// MapComplex128 check whether m[key] is the complex128 type, and return the
// complex128 value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapComplex128(m map[string]interface{}, key string) (v complex128, err error) {
	_v, err := CheckMapType(m, key, "complex128")
	if err == nil {
		v = _v.(complex128)
	}
	return
}

// MapMap check whether m[key] is the map[string]interface{} type, and return
// the map[string]interface{} value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapMap(m map[string]interface{}, key string) (v map[string]interface{}, err error) {
	_v, err := CheckMapType(m, key, "string2interface")
	if err == nil {
		v = _v.(map[string]interface{})
	}
	return
}
<commit_msg>Fix a bug<commit_after>package types

import (
	"fmt"
)

// CheckMapType checks the type of m[k] is t, and return the value if yes,
// or return an error if not.
//
// If m is nil, return an error.
//
// The function uses VerifyType to verify the type, that's, VerifyType(m[k], t),
// so for t, see VerifyType.
func CheckMapType(m map[string]interface{}, k, t string) (interface{}, error) {
	if m == nil {
		return nil, fmt.Errorf("the map is nil")
	}
	value := m[k]
	if value == nil {
		return nil, fmt.Errorf("the value of the key[%s] in map is nil", k)
	}
	if !VerifyType(value, t) {
		return nil, fmt.Errorf("the value of the key[%s] in map is not %s",
			k, stype2type[k])
	}
	return value, nil
}

// MapBool check whether m[key] is the bool type, and return the bool value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapBool(m map[string]interface{}, key string) (v bool, err error) {
	_v, err := CheckMapType(m, key, "bool")
	if err == nil {
		v = _v.(bool)
	}
	return
}

// MapString check whether m[key] is the string type, and return the string
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapString(m map[string]interface{}, key string) (v string, err error) {
	_v, err := CheckMapType(m, key, "string")
	if err == nil {
		v = _v.(string)
	}
	return
}

// MapInt check whether m[key] is the int type, and return the int value if yes,
// or return an error if not.
//
// If m is nil, return an error.
func MapInt(m map[string]interface{}, key string) (v int, err error) {
	_v, err := CheckMapType(m, key, "int")
	if err == nil {
		v = _v.(int)
	}
	return
}

// MapInt8 check whether m[key] is the int8 type, and return the int8 value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapInt8(m map[string]interface{}, key string) (v int8, err error) {
	_v, err := CheckMapType(m, key, "int8")
	if err == nil {
		v = _v.(int8)
	}
	return
}

// MapInt16 check whether m[key] is the int16 type, and return the int16 value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapInt16(m map[string]interface{}, key string) (v int16, err error) {
	_v, err := CheckMapType(m, key, "int16")
	if err == nil {
		v = _v.(int16)
	}
	return
}

// MapInt32 check whether m[key] is the int32 type, and return the int32 value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapInt32(m map[string]interface{}, key string) (v int32, err error) {
	_v, err := CheckMapType(m, key, "int32")
	if err == nil {
		v = _v.(int32)
	}
	return
}

// MapInt64 check whether m[key] is the int64 type, and return the int64 value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapInt64(m map[string]interface{}, key string) (v int64, err error) {
	_v, err := CheckMapType(m, key, "int64")
	if err == nil {
		v = _v.(int64)
	}
	return
}

// MapUint check whether m[key] is the uint type, and return the uint value if yes,
// or return an error if not.
//
// If m is nil, return an error.
func MapUint(m map[string]interface{}, key string) (v uint, err error) {
	_v, err := CheckMapType(m, key, "uint")
	if err == nil {
		v = _v.(uint)
	}
	return
}

// MapUint8 check whether m[key] is the uint8 type, and return the uint8 value
// if yes, or return an error if not.
//
// If m is nil, return an error.
func MapUint8(m map[string]interface{}, key string) (v uint8, err error) {
	_v, err := CheckMapType(m, key, "uint8")
	if err == nil {
		v = _v.(uint8)
	}
	return
}

// MapUint16 check whether m[key] is the uint16 type, and return the uint16
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapUint16(m map[string]interface{}, key string) (v uint16, err error) {
	_v, err := CheckMapType(m, key, "uint16")
	if err == nil {
		v = _v.(uint16)
	}
	return
}

// MapUint32 check whether m[key] is the uint32 type, and return the uint32
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapUint32(m map[string]interface{}, key string) (v uint32, err error) {
	_v, err := CheckMapType(m, key, "uint32")
	if err == nil {
		v = _v.(uint32)
	}
	return
}

// MapUint64 check whether m[key] is the uint64 type, and return the uint64
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapUint64(m map[string]interface{}, key string) (v uint64, err error) {
	_v, err := CheckMapType(m, key, "uint64")
	if err == nil {
		v = _v.(uint64)
	}
	return
}

// MapFloat32 check whether m[key] is the Float32 type, and return the Float32
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapFloat32(m map[string]interface{}, key string) (v float32, err error) {
	_v, err := CheckMapType(m, key, "float32")
	if err == nil {
		v = _v.(float32)
	}
	return
}

// MapFloat64 check whether m[key] is the float64 type, and return the float64
// value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapFloat64(m map[string]interface{}, key string) (v float64, err error) {
	_v, err := CheckMapType(m, key, "float64")
	if err == nil {
		v = _v.(float64)
	}
	return
}

// MapComplex64 check whether m[key] is the complex64 type, and return the
// complex64 value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapComplex64(m map[string]interface{}, key string) (v complex64, err error) {
	_v, err := CheckMapType(m, key, "complex64")
	if err == nil {
		v = _v.(complex64)
	}
	return
}

// MapComplex128 check whether m[key] is the complex128 type, and return the
// complex128 value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapComplex128(m map[string]interface{}, key string) (v complex128, err error) {
	_v, err := CheckMapType(m, key, "complex128")
	if err == nil {
		v = _v.(complex128)
	}
	return
}

// MapMap check whether m[key] is the map[string]interface{} type, and return
// the map[string]interface{} value if yes, or return an error if not.
//
// If m is nil, return an error.
func MapMap(m map[string]interface{}, key string) (v map[string]interface{}, err error) {
	_v, err := CheckMapType(m, key, "string2interface")
	if err == nil {
		v = _v.(map[string]interface{})
	}
	return
}
<|endoftext|>


<commit_before>package types

import (
	"fmt"
	"github.com/pkg/errors"
)

// A Place isn't something directly used by the Navitia.io api
// However, it allows the library user to use idiomatic go when working with the library
// If you want a countainer, see PlaceCountainer
// Place is satisfied by:
// - StopArea
// - POI
// - Address
// - StopPoint
// - AdministrativeRegion
type Place interface {
	// PlaceID returns the ID associated with the Place
	PlaceID() ID

	// PlaceName returns the name of the Place
	PlaceName() string

	// PlaceType returns the name of the type of the Place
	PlaceType() string

	// String() for string printing
	String() string
}

// PlaceCountainer is the ugly countainer sent by Navitia to make us all cry.
// However, as this can be useful. May be removed from the public API in gonavitia v0.
type PlaceCountainer struct {
	ID           ID     `json:"id"`
	Name         string `json:"name"`
	Quality      uint   `json:"quality,omitempty"`
	EmbeddedType string `json:"embedded_type"`

	// Four possibilitiess
	StopArea             *StopArea             `json:"stop_area,omitempty"`
	POI                  *POI                  `json:"POI,omitempty"`
	Address              *Address              `json:"address,omitempty"`
	StopPoint            *StopPoint            `json:"stop_point,omitempty"`
	AdministrativeRegion *AdministrativeRegion `json:"administrative_region,omitempty"`
}

// Place returns the Place countained in the PlaceCountainer
// If PlaceCountainer is empty, Place returns nil
// If there's no place indicated but PlaceCountainer isn't empty, Place returns an error as well as a nil Place.
func (pc PlaceCountainer) Place() (Place, error) {
	// If PlaceCountainer is empty, return nil
	empty := PlaceCountainer{}
	if pc == empty {
		return nil, nil
	}

	// Check for each type
	switch pc.EmbeddedType {
	case "stop_area":
		return pc.StopArea, nil
	case "poi":
		return pc.POI, nil
	case "address":
		return pc.Address, nil
	case "stop_point":
		return pc.StopPoint, nil
	case "administrative_region":
		return pc.AdministrativeRegion, nil
	default:
		return nil, errors.Errorf("No known embedded type indicated (we have \"%s\"), can't return a place !", pc.EmbeddedType)
	}
}

// A StopArea represents a stop area: a nameable zone, where there are some stop points.
type StopArea struct {
	ID   ID     `json:"id"`
	Name string `json:"name"`

	// Label of the stop area.
	// The name is directly taken from the data whereas the label is something computed by navitia for better traveler information.
	// If you don't know what to display, display the label
	Label string `json:"label"`

	// Coordinates of the stop area
	Coord Coordinates `json:"coord"`

	// Administrative regions of the stop area in which is placed the stop area
	AdministrativeRegions []AdministrativeRegion `json:"administrative_regions"`

	// Stop points countained in this stop area
	StopPoints []StopPoint `json:"stop_points"`
}

// PlaceID returns the ID associated with the StopArea
// Helps satisfy Place
func (sa StopArea) PlaceID() ID {
	return sa.ID
}

// PlaceName returns the name of the StopArea
// Helps satisfy Place
func (sa StopArea) PlaceName() string {
	return sa.Name
}

// PlaceType returns the type of place, in this case "stop_area"
// Helps satisfy Place
func (sa StopArea) PlaceType() string {
	return "stop_area"
}

// String pretty-prints the StopArea.
// Satisifes Stringer and helps satisfy Place
func (sa StopArea) String() string {
	var label string
	if sa.Label == "" {
		label = sa.Name
	} else {
		label = sa.Label
	}

	format := "%s (id: %s)"
	return fmt.Sprintf(format, label, sa.ID)
}

// A POI is a Point Of Interest. A loosely-defined place.
type POI struct {
	ID   ID     `json:"id"`
	Name string `json:"name"`

	// The name is directly taken from the data whereas the label is something computed by navitia for better traveler information.
	// If you don't know what to display, display the label
	Label string `json:"label"`

	// The type of the POI
	Type POIType `json:"poi_type"`
}

// PlaceID returns the ID associated with the POI.
// Helps satisfy Place
func (poi POI) PlaceID() ID {
	return poi.ID
}

// PlaceName returns the name of the POI.
// Helps satisfy Place
func (poi POI) PlaceName() string {
	return poi.Name
}

// PlaceType returns the type of place, in this case "poi".
// Helps satisfy Place
func (poi POI) PlaceType() string {
	return "poi"
}

// String pretty-prints the POI.
// Satisifes Stringer and helps satisfy Place
func (poi POI) String() string {
	var label string
	if poi.Label == "" {
		label = poi.Name
	} else {
		label = poi.Label
	}

	format := "%s (id: %s)"
	return fmt.Sprintf(format, label, poi.ID)
}

// A POIType codes for the type of the point of interest
// TODO: A list of usual types ?
type POIType struct {
	ID   ID     `json:"id"`
	Name string `json:"name"`
}

// An Address codes for a real-world address: a point located in a street.
type Address struct {
	ID   ID     `json:"id"`
	Name string `json:"name"`

	// Label of the address
	// The name is directly taken from the data whereas the label is something computed by navitia for better traveler information.
	// If you don't know what to display, display the label
	Label string `json:"label"`

	// Coordinates of the address
	Coord Coordinates `json:"coord"`

	// House number of the address
	HouseNumber uint `json:"house_number"`

	// Administrative regions of the stop area in which is placed the stop area
	AdministrativeRegions []AdministrativeRegion `json:"administrative_regions"`
}

// PlaceID returns the ID associated with the Address
// Helps satisfy Place
func (add Address) PlaceID() ID {
	return add.ID
}

// PlaceName returns the name of the Address
// Helps satisfy Place
func (add Address) PlaceName() string {
	return add.Name
}

// PlaceType returns the type of place, in this case "address"
// Helps satisfy Place
func (add Address) PlaceType() string {
	return "address"
}

// String pretty-prints the Address.
// Satisifes Stringer and helps satisfy Place
func (add Address) String() string {
	var label string
	if add.Label == "" {
		label = add.Name
	} else {
		label = add.Label
	}

	format := "%s (id: %s)"
	return fmt.Sprintf(format, label, add.ID)
}

// A StopPoint codes for a stop point in a line: a location where vehicles can pickup or drop off passengers.
type StopPoint struct {
	ID ID `json:"id"`

	// Name of the stop point
	Name string `json:"name"`

	// Coordinates of the stop point
	Coord Coordinates `json:"coord"`

	// Administrative regions of the stop point
	AdministrativeRegions []AdministrativeRegion `json:"administrative_regions"`

	// List of equipments of the stop point
	Equipments []Equipment `json:"equipment"`

	// Stop Area countaining the stop point
	StopArea *StopArea `json:"stop_area"`
}

// PlaceID returns the ID associated with the Stop Point
// Helps satisfy Place
func (sp StopPoint) PlaceID() ID {
	return sp.ID
}

// PlaceName returns the name of the Stop Point
// Helps satisfy Place
func (sp StopPoint) PlaceName() string {
	return sp.Name
}

// PlaceType returns the type of place, in this case "stop_point"
// Helps satisfy Place
func (sp StopPoint) PlaceType() string {
	return "stop_point"
}

// String pretty-prints the StopPoint.
// Satisifes Stringer and helps satisfy Place
func (sp StopPoint) String() string {
	format := "%s (id: %s)"
	return fmt.Sprintf(format, sp.Name, sp.ID)
}

// An AdministrativeRegion represents an administrative region: a region under the control/responsibility of a specific organisation.
// It can be a city, a district, a neightborhood, etc.
type AdministrativeRegion struct {
	ID   ID     `json:"id"`
	Name string `json:"name"`

	// Label of the address
	// The name is directly taken from the data whereas the label is something computed by navitia for better traveler information.
	// If you don't know what to display, display the label
	Label string `json:"label"`

	// Coordinates of the administrative region
	Coord Coordinates `json:"coord"`

	// Level of the administrative region
	Level int `json:"level"`

	// Zip code of the administrative region
	ZipCode string
}

// PlaceID returns the ID associated with the AdministrativeRegion
// Helps satisfy Place
func (ar AdministrativeRegion) PlaceID() ID {
	return ar.ID
}

// PlaceName returns the name of the AdministrativeRegion
// Helps satisfy Place
func (ar AdministrativeRegion) PlaceName() string {
	return ar.Name
}

// PlaceType returns the type of place, in this case "administrative_region"
// Helps satisfy Place
func (ar AdministrativeRegion) PlaceType() string {
	return "administrative_region"
}

// String pretty-prints the AdministrativeRegion.
// Satisifes Stringer and helps satisfy Place
func (ar AdministrativeRegion) String() string {
	var label string
	if ar.Label == "" {
		label = ar.Name
	} else {
		label = ar.Label
	}

	format := "%s (id: %s)"
	return fmt.Sprintf(format, label, ar.ID)
}
<commit_msg>types: Ameliorate Place methods Add Check method and corresponding error type. Fix crash detected with Fuzz ;)<commit_after>package types

import (
	"fmt"
	"github.com/pkg/errors"
)

// A Place isn't something directly used by the Navitia.io api
// However, it allows the library user to use idiomatic go when working with the library
// If you want a countainer, see PlaceCountainer
// Place is satisfied by:
// - StopArea
// - POI
// - Address
// - StopPoint
// - AdministrativeRegion
type Place interface {
	// PlaceID returns the ID associated with the Place
	PlaceID() ID

	// PlaceName returns the name of the Place
	PlaceName() string

	// PlaceType returns the name of the type of the Place
	PlaceType() string

	// String() for string printing
	String() string
}

// PlaceCountainer is the ugly countainer sent by Navitia to make us all cry.
// However, as this can be useful. May be removed from the public API in gonavitia v0.
type PlaceCountainer struct {
	ID           ID     `json:"id"`
	Name         string `json:"name"`
	Quality      uint   `json:"quality,omitempty"`
	EmbeddedType string `json:"embedded_type"`

	// Four possibilitiess
	StopArea             *StopArea             `json:"stop_area,omitempty"`
	POI                  *POI                  `json:"POI,omitempty"`
	Address              *Address              `json:"address,omitempty"`
	StopPoint            *StopPoint            `json:"stop_point,omitempty"`
	AdministrativeRegion *AdministrativeRegion `json:"administrative_region,omitempty"`
}

// ErrInvalidPlaceCountainer is returned after a check on a PlaceCountainer
type ErrInvalidPlaceCountainer struct {
	// If the PlaceCountainer has a zero ID.
	NoID bool

	// If the PlaceCountainer has a zero EmbeddedType.
	NoEmbeddedType bool

	// If the PlaceCountainer has an unknown EmbeddedType
	UnknownEmbeddedType bool

	// If the PlaceCountainer has a known EmbeddedType but the corresponding concrete value is nil.
	NilConcretePlaceValue bool

	// TODO:
	// If the PlaceCountainer has more than one non-nil concrete place values.
	// MultipleNonNilConcretePlaceValues bool
}

// Error satisfies the error interface
func (err ErrInvalidPlaceCountainer) Error() string {
	// Count the number of anomalies
	var anomalies uint

	msg := "Error: Invalid non-empty PlaceCountainer (%d anomalies):"

	if err.NoID {
		msg += "\n\tNo ID specified"
		anomalies++
	}
	if err.NoEmbeddedType {
		msg += "\n\tEmpty EmbeddedType"
		anomalies++
	}
	if err.UnknownEmbeddedType {
		msg += "\n\tUnknown EmbeddedType"
		anomalies++
	}
	if err.NilConcretePlaceValue {
		msg += "\n\tKnown EmbeddedType but nil corresponding concrete value"
		anomalies++
	}

	return fmt.Sprintf(msg, anomalies)
}

// IsEmpty returns whether or not pc is empty
func (pc PlaceCountainer) IsEmpty() bool {
	empty := PlaceCountainer{}
	return pc == empty
}

// Checks the validity of the PlaceCountainer. Returns an ErrInvalidPlaceCountainer.
//
// An empty PlaceCountainer is valid. But those cases aren't:
// 	- If the PlaceCountainer has a zero ID.
// 	- If the PlaceCountainer has a zero EmbeddedType.
// 	- If the PlaceCountainer has an unknown EmbeddedType.
// 	- If the PlaceCountainer has a known EmbeddedType but the corresponding concrete value is nil.
func (pc PlaceCountainer) Check() error {
	if pc.IsEmpty() {
		return nil
	}
	err := ErrInvalidPlaceCountainer{}

	// Check for zero ID
	err.NoID = (pc.ID == "")

	// Check if known EmbeddedType but the corresponding concrete value is nil.
	// Also check for empty and unknown embedded type
	absent := &err.NilConcretePlaceValue
	switch pc.EmbeddedType {
	case "stop_area":
		*absent = (pc.StopArea == nil)
	case "poi":
		*absent = (pc.POI == nil)
	case "address":
		*absent = (pc.Address == nil)
	case "stop_point":
		*absent = (pc.StopPoint == nil)
	case "administrative_region":
		*absent = (pc.AdministrativeRegion == nil)
	default:
		// Check for an empty embedded type
		err.NoEmbeddedType = (pc.EmbeddedType == "")
		// In case its not empty yet doesn't match with a known type
		err.UnknownEmbeddedType = !err.NoEmbeddedType
	}

	emptyErr := ErrInvalidPlaceCountainer{}
	if err != emptyErr {
		return err
	} else {
		return nil
	}
}

// Place returns the Place countained in the PlaceCountainer
// If PlaceCountainer is empty, Place returns (nil,nil).
// Check() is run on the PlaceCountainer.
func (pc PlaceCountainer) Place() (Place, error) {
	// If PlaceCountainer is empty, return nil
	empty := PlaceCountainer{}
	if pc == empty {
		return nil, nil
	}

	// Check validity
	err := pc.Check()
	if err != nil {
		return nil, err
	}

	// Check for each type
	switch pc.EmbeddedType {
	case "stop_area":
		return pc.StopArea, nil
	case "poi":
		return pc.POI, nil
	case "address":
		return pc.Address, nil
	case "stop_point":
		return pc.StopPoint, nil
	case "administrative_region":
		return pc.AdministrativeRegion, nil
	default:
		return nil, errors.Errorf("No known embedded type indicated (we have \"%s\"), can't return a place !", pc.EmbeddedType) // THIS IS VERY SERIOUS AS WE ALREADY CHECKED THE STRUCTURE
	}
}

// A StopArea represents a stop area: a nameable zone, where there are some stop points.
type StopArea struct {
	ID   ID     `json:"id"`
	Name string `json:"name"`

	// Label of the stop area.
	// The name is directly taken from the data whereas the label is something computed by navitia for better traveler information.
	// If you don't know what to display, display the label
	Label string `json:"label"`

	// Coordinates of the stop area
	Coord Coordinates `json:"coord"`

	// Administrative regions of the stop area in which is placed the stop area
	AdministrativeRegions []AdministrativeRegion `json:"administrative_regions"`

	// Stop points countained in this stop area
	StopPoints []StopPoint `json:"stop_points"`
}

// PlaceID returns the ID associated with the StopArea
// Helps satisfy Place
func (sa StopArea) PlaceID() ID {
	return sa.ID
}

// PlaceName returns the name of the StopArea
// Helps satisfy Place
func (sa StopArea) PlaceName() string {
	return sa.Name
}

// PlaceType returns the type of place, in this case "stop_area"
// Helps satisfy Place
func (sa StopArea) PlaceType() string {
	return "stop_area"
}

// String pretty-prints the StopArea.
// Satisifes Stringer and helps satisfy Place
func (sa StopArea) String() string {
	var label string
	if sa.Label == "" {
		label = sa.Name
	} else {
		label = sa.Label
	}

	format := "%s (id: %s)"
	return fmt.Sprintf(format, label, sa.ID)
}

// A POI is a Point Of Interest. A loosely-defined place.
type POI struct {
	ID   ID     `json:"id"`
	Name string `json:"name"`

	// The name is directly taken from the data whereas the label is something computed by navitia for better traveler information.
	// If you don't know what to display, display the label
	Label string `json:"label"`

	// The type of the POI
	Type POIType `json:"poi_type"`
}

// PlaceID returns the ID associated with the POI.
// Helps satisfy Place
func (poi POI) PlaceID() ID {
	return poi.ID
}

// PlaceName returns the name of the POI.
// Helps satisfy Place
func (poi POI) PlaceName() string {
	return poi.Name
}

// PlaceType returns the type of place, in this case "poi".
// Helps satisfy Place
func (poi POI) PlaceType() string {
	return "poi"
}

// String pretty-prints the POI.
// Satisifes Stringer and helps satisfy Place
func (poi POI) String() string {
	var label string
	if poi.Label == "" {
		label = poi.Name
	} else {
		label = poi.Label
	}

	format := "%s (id: %s)"
	return fmt.Sprintf(format, label, poi.ID)
}

// A POIType codes for the type of the point of interest
// TODO: A list of usual types ?
type POIType struct {
	ID   ID     `json:"id"`
	Name string `json:"name"`
}

// An Address codes for a real-world address: a point located in a street.
type Address struct {
	ID   ID     `json:"id"`
	Name string `json:"name"`

	// Label of the address
	// The name is directly taken from the data whereas the label is something computed by navitia for better traveler information.
	// If you don't know what to display, display the label
	Label string `json:"label"`

	// Coordinates of the address
	Coord Coordinates `json:"coord"`

	// House number of the address
	HouseNumber uint `json:"house_number"`

	// Administrative regions of the stop area in which is placed the stop area
	AdministrativeRegions []AdministrativeRegion `json:"administrative_regions"`
}

// PlaceID returns the ID associated with the Address
// Helps satisfy Place
func (add Address) PlaceID() ID {
	return add.ID
}

// PlaceName returns the name of the Address
// Helps satisfy Place
func (add Address) PlaceName() string {
	return add.Name
}

// PlaceType returns the type of place, in this case "address"
// Helps satisfy Place
func (add Address) PlaceType() string {
	return "address"
}

// String pretty-prints the Address.
// Satisifes Stringer and helps satisfy Place
func (add Address) String() string {
	var label string
	if add.Label == "" {
		label = add.Name
	} else {
		label = add.Label
	}

	format := "%s (id: %s)"
	return fmt.Sprintf(format, label, add.ID)
}

// A StopPoint codes for a stop point in a line: a location where vehicles can pickup or drop off passengers.
type StopPoint struct {
	ID ID `json:"id"`

	// Name of the stop point
	Name string `json:"name"`

	// Coordinates of the stop point
	Coord Coordinates `json:"coord"`

	// Administrative regions of the stop point
	AdministrativeRegions []AdministrativeRegion `json:"administrative_regions"`

	// List of equipments of the stop point
	Equipments []Equipment `json:"equipment"`

	// Stop Area countaining the stop point
	StopArea *StopArea `json:"stop_area"`
}

// PlaceID returns the ID associated with the Stop Point
// Helps satisfy Place
func (sp StopPoint) PlaceID() ID {
	return sp.ID
}

// PlaceName returns the name of the Stop Point
// Helps satisfy Place
func (sp StopPoint) PlaceName() string {
	return sp.Name
}

// PlaceType returns the type of place, in this case "stop_point"
// Helps satisfy Place
func (sp StopPoint) PlaceType() string {
	return "stop_point"
}

// String pretty-prints the StopPoint.
// Satisifes Stringer and helps satisfy Place
func (sp StopPoint) String() string {
	format := "%s (id: %s)"
	return fmt.Sprintf(format, sp.Name, sp.ID)
}

// An AdministrativeRegion represents an administrative region: a region under the control/responsibility of a specific organisation.
// It can be a city, a district, a neightborhood, etc.
type AdministrativeRegion struct {
	ID   ID     `json:"id"`
	Name string `json:"name"`

	// Label of the address
	// The name is directly taken from the data whereas the label is something computed by navitia for better traveler information.
	// If you don't know what to display, display the label
	Label string `json:"label"`

	// Coordinates of the administrative region
	Coord Coordinates `json:"coord"`

	// Level of the administrative region
	Level int `json:"level"`

	// Zip code of the administrative region
	ZipCode string
}

// PlaceID returns the ID associated with the AdministrativeRegion
// Helps satisfy Place
func (ar AdministrativeRegion) PlaceID() ID {
	return ar.ID
}

// PlaceName returns the name of the AdministrativeRegion
// Helps satisfy Place
func (ar AdministrativeRegion) PlaceName() string {
	return ar.Name
}

// PlaceType returns the type of place, in this case "administrative_region"
// Helps satisfy Place
func (ar AdministrativeRegion) PlaceType() string {
	return "administrative_region"
}

// String pretty-prints the AdministrativeRegion.
// Satisifes Stringer and helps satisfy Place
func (ar AdministrativeRegion) String() string {
	var label string
	if ar.Label == "" {
		label = ar.Name
	} else {
		label = ar.Label
	}

	format := "%s (id: %s)"
	return fmt.Sprintf(format, label, ar.ID)
}
<|endoftext|>


<commit_before>// Ghostest is an interactive end-to-end Web site application to test
// the ghost packages. It serves the following URLs, with the specified
// features (handlers):
//
// / 										| panic;log;gzip;static; -> serve file index.html
// /public/styles.css 	| panic;log;gzip;StripPrefix;FileServer; -> serve directory public/
// /public/script.js 		| panic;log;gzip;StripPrefix;FileServer; -> serve directory public/
// /public/logo.png 		| panic;log;gzip;StripPrefix;FileServer; -> serve directory public/
// /session 						| panic;log;gzip;session;context;Custom; -> serve dynamic Go template
// /session/auth 				| panic;log;gzip;session;context;basicAuth;Custom; -> serve dynamic template
// /panic 							| panic;log;gzip;Custom; -> panics
// /context 						| panic;log;gzip;context;Custom1;Custom2; -> serve dynamic Amber template
//
// TODO : Make look good (bootstrap?), clean code, tests all handlers
package main

import (
	"log"
	"net/http"
	"time"

	"github.com/PuerkitoBio/ghost/handlers"
	"github.com/PuerkitoBio/ghost/templates"
	_ "github.com/PuerkitoBio/ghost/templates/amber"
	_ "github.com/PuerkitoBio/ghost/templates/gotpl"
	"github.com/bmizerany/pat"
)

const (
	sessionPageTitle     = "Session Page"
	sessionPageAuthTitle = "Authenticated Session Page"
	sessionPageKey       = "txt"
)

var (
	// Create the common session store and secret
	memStore = handlers.NewMemoryStore(1)
	secret   = "testimony of the ancients"

	// Create the common session handler function
	fnSsnH = func(w http.ResponseWriter, r *http.Request) {
		ssn, ok := handlers.GetSession(w)
		if !ok {
			panic("no session")
		}
		var txt interface{}
		if r.Method == "GET" {
			txt = ssn.Data[sessionPageKey]
		} else {
			txt = r.FormValue(sessionPageKey)
			ssn.Data[sessionPageKey] = txt
		}
		var data sessionPageInfo
		var title string
		if r.URL.Path == "/session/auth" {
			title = sessionPageAuthTitle
		} else {
			title = sessionPageTitle
		}
		if txt != nil {
			data = sessionPageInfo{title, txt.(string)}
		} else {
			data = sessionPageInfo{title, "[nil]"}
		}
		err := templates.Render("templates/session.tmpl", w, data)
		if err != nil {
			panic(err)
		}
	}

	// The no-auth required handler
	hSsn = handlers.SessionHandler(
		handlers.ContextHandlerFunc(fnSsnH, 1),
		handlers.NewSessionOptions(memStore, secret))

	// The Auth-required handler
	hAuthSsn = handlers.BasicAuthHandler(hSsn,
		// The authentication function
		func(u, p string) (interface{}, bool) {
			if u == "user" && p == "pwd" {
				return u + p, true
			}
			return nil, false
		}, "")
)

// The struct used to pass data to the session template.
type sessionPageInfo struct {
	Title string
	Text  string
}

func main() {
	// Blank the default logger's prefixes
	log.SetFlags(0)

	// Compile the dynamic templates (native Go templates are registered via the
	// for-side-effects-only import of gotpl)
	err := templates.CompileDir("./templates/", true)
	if err != nil {
		panic(err)
	}

	// Set the simple routes for static files
	mux := pat.New()
	mux.Get("/", handlers.StaticFileHandler("./index.html"))
	mux.Get("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("./public/"))))

	// Set the more complex route for session handling and dynamic page (same
	// handler is used for both GET and POST).
	mux.Get("/session", hSsn)
	mux.Post("/session", hSsn)
	mux.Get("/session/auth", hAuthSsn)
	mux.Post("/session/auth", hAuthSsn)

	// Set the handler for the chained context route
	hCtx1 := func(w http.ResponseWriter, r *http.Request) {
		ctx, ok := handlers.GetContext(w)
		if !ok {
			panic("no context")
		}
		ctx["time"] = time.Now().String()
	}
	hCtx2 := func(w http.ResponseWriter, r *http.Request) {
		ctx, ok := handlers.GetContext(w)
		if !ok {
			panic("no context")
		}
		err := templates.Render("templates/amber/context.amber", w, &struct{ Val string }{ctx["time"].(string)})
		if err != nil {
			panic(err)
		}
	}
	mux.Get("/context", handlers.ContextHandler(handlers.ChainHandlerFuncs(hCtx1, hCtx2), 1))

	// Set the panic route, which simply panics
	mux.Get("/panic", http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			panic("explicit panic")
		}))

	// Combine the top level handlers, that wrap around the muxer.
	// Panic is the outermost, so that any panic is caught and responded to with a code 500.
	// Log is next, so that every request is logged along with the URL, status code and response time.
	// GZIP is then applied, so that content is compressed.
	// Finally, the muxer finds the specific handler that applies to the route.
	h := handlers.PanicHandler(
		handlers.LogHandler(
			handlers.GZIPHandler(
				mux,
				nil),
			handlers.NewLogOptions(nil, handlers.Ltiny)),
		nil)

	// Assign the combined handler to the server.
	http.Handle("/", h)

	// Start it up.
	if err := http.ListenAndServe(":9000", nil); err != nil {
		panic(err)
	}
}
<commit_msg>add favicon to ghostest<commit_after>// Ghostest is an interactive end-to-end Web site application to test
// the ghost packages. It serves the following URLs, with the specified
// features (handlers):
//
// / 										| panic;log;gzip;static; -> serve file index.html
// /public/styles.css 	| panic;log;gzip;StripPrefix;FileServer; -> serve directory public/
// /public/script.js 		| panic;log;gzip;StripPrefix;FileServer; -> serve directory public/
// /public/logo.png 		| panic;log;gzip;StripPrefix;FileServer; -> serve directory public/
// /session 						| panic;log;gzip;session;context;Custom; -> serve dynamic Go template
// /session/auth 				| panic;log;gzip;session;context;basicAuth;Custom; -> serve dynamic template
// /panic 							| panic;log;gzip;Custom; -> panics
// /context 						| panic;log;gzip;context;Custom1;Custom2; -> serve dynamic Amber template
//
// TODO : Make look good (bootstrap?), clean code, tests all handlers
package main

import (
	"log"
	"net/http"
	"time"

	"github.com/PuerkitoBio/ghost/handlers"
	"github.com/PuerkitoBio/ghost/templates"
	_ "github.com/PuerkitoBio/ghost/templates/amber"
	_ "github.com/PuerkitoBio/ghost/templates/gotpl"
	"github.com/bmizerany/pat"
)

const (
	sessionPageTitle     = "Session Page"
	sessionPageAuthTitle = "Authenticated Session Page"
	sessionPageKey       = "txt"
)

var (
	// Create the common session store and secret
	memStore = handlers.NewMemoryStore(1)
	secret   = "testimony of the ancients"

	// Create the common session handler function
	fnSsnH = func(w http.ResponseWriter, r *http.Request) {
		ssn, ok := handlers.GetSession(w)
		if !ok {
			panic("no session")
		}
		var txt interface{}
		if r.Method == "GET" {
			txt = ssn.Data[sessionPageKey]
		} else {
			txt = r.FormValue(sessionPageKey)
			ssn.Data[sessionPageKey] = txt
		}
		var data sessionPageInfo
		var title string
		if r.URL.Path == "/session/auth" {
			title = sessionPageAuthTitle
		} else {
			title = sessionPageTitle
		}
		if txt != nil {
			data = sessionPageInfo{title, txt.(string)}
		} else {
			data = sessionPageInfo{title, "[nil]"}
		}
		err := templates.Render("templates/session.tmpl", w, data)
		if err != nil {
			panic(err)
		}
	}

	// The no-auth required handler
	hSsn = handlers.SessionHandler(
		handlers.ContextHandlerFunc(fnSsnH, 1),
		handlers.NewSessionOptions(memStore, secret))

	// The Auth-required handler
	hAuthSsn = handlers.BasicAuthHandler(hSsn,
		// The authentication function
		func(u, p string) (interface{}, bool) {
			if u == "user" && p == "pwd" {
				return u + p, true
			}
			return nil, false
		}, "")
)

// The struct used to pass data to the session template.
type sessionPageInfo struct {
	Title string
	Text  string
}

func main() {
	// Blank the default logger's prefixes
	log.SetFlags(0)

	// Compile the dynamic templates (native Go templates are registered via the
	// for-side-effects-only import of gotpl)
	err := templates.CompileDir("./templates/", true)
	if err != nil {
		panic(err)
	}

	// Set the simple routes for static files
	mux := pat.New()
	mux.Get("/", handlers.StaticFileHandler("./index.html"))
	mux.Get("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("./public/"))))

	// Set the more complex route for session handling and dynamic page (same
	// handler is used for both GET and POST).
	mux.Get("/session", hSsn)
	mux.Post("/session", hSsn)
	mux.Get("/session/auth", hAuthSsn)
	mux.Post("/session/auth", hAuthSsn)

	// Set the handler for the chained context route
	hCtx1 := func(w http.ResponseWriter, r *http.Request) {
		ctx, ok := handlers.GetContext(w)
		if !ok {
			panic("no context")
		}
		ctx["time"] = time.Now().String()
	}
	hCtx2 := func(w http.ResponseWriter, r *http.Request) {
		ctx, ok := handlers.GetContext(w)
		if !ok {
			panic("no context")
		}
		err := templates.Render("templates/amber/context.amber", w, &struct{ Val string }{ctx["time"].(string)})
		if err != nil {
			panic(err)
		}
	}
	mux.Get("/context", handlers.ContextHandler(handlers.ChainHandlerFuncs(hCtx1, hCtx2), 1))

	// Set the panic route, which simply panics
	mux.Get("/panic", http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			panic("explicit panic")
		}))

	// Combine the top level handlers, that wrap around the muxer.
	// Panic is the outermost, so that any panic is caught and responded to with a code 500.
	// Log is next, so that every request is logged along with the URL, status code and response time.
	// GZIP is then applied, so that content is compressed.
	// Finally, the muxer finds the specific handler that applies to the route.
	h := handlers.FaviconHandler(
		handlers.PanicHandler(
			handlers.LogHandler(
				handlers.GZIPHandler(
					mux,
					nil),
				handlers.NewLogOptions(nil, handlers.Ltiny)),
			nil),
		"./public/favicon.ico",
		48*time.Hour)

	// Assign the combined handler to the server.
	http.Handle("/", h)

	// Start it up.
	if err := http.ListenAndServe(":9000", nil); err != nil {
		panic(err)
	}
}
<|endoftext|>


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

package build

import (
	"errors"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"runtime"
)

// Path is a validated list of Trees derived from $GOROOT and $GOPATH at init.
var Path []*Tree

// Tree describes a Go source tree, either $GOROOT or one from $GOPATH.
type Tree struct {
	Path   string
	Goroot bool
}

func newTree(p string) (*Tree, error) {
	if !filepath.IsAbs(p) {
		return nil, errors.New("must be absolute")
	}
	ep, err := filepath.EvalSymlinks(p)
	if err != nil {
		return nil, err
	}
	return &Tree{Path: ep}, nil
}

// SrcDir returns the tree's package source directory.
func (t *Tree) SrcDir() string {
	if t.Goroot {
		return filepath.Join(t.Path, "src", "pkg")
	}
	return filepath.Join(t.Path, "src")
}

// PkgDir returns the tree's package object directory.
func (t *Tree) PkgDir() string {
	goos, goarch := runtime.GOOS, runtime.GOARCH
	if e := os.Getenv("GOOS"); e != "" {
		goos = e
	}
	if e := os.Getenv("GOARCH"); e != "" {
		goarch = e
	}
	return filepath.Join(t.Path, "pkg", goos+"_"+goarch)
}

// BinDir returns the tree's binary executable directory.
func (t *Tree) BinDir() string {
	if t.Goroot {
		if gobin := os.Getenv("GOBIN"); gobin != "" {
			return filepath.Clean(gobin)
		}
	}
	return filepath.Join(t.Path, "bin")
}

// HasSrc returns whether the given package's
// source can be found inside this Tree.
func (t *Tree) HasSrc(pkg string) bool {
	fi, err := os.Stat(filepath.Join(t.SrcDir(), pkg))
	if err != nil {
		return false
	}
	return fi.IsDir()
}

// HasPkg returns whether the given package's
// object file can be found inside this Tree.
func (t *Tree) HasPkg(pkg string) bool {
	fi, err := os.Stat(filepath.Join(t.PkgDir(), pkg+".a"))
	if err != nil {
		return false
	}
	return !fi.IsDir()
	// TODO(adg): check object version is consistent
}

var (
	ErrNotFound     = errors.New("package could not be found locally")
	ErrTreeNotFound = errors.New("no valid GOROOT or GOPATH could be found")
)

// FindTree takes an import or filesystem path and returns the
// tree where the package source should be and the package import path.
func FindTree(path string) (tree *Tree, pkg string, err error) {
	if isLocalPath(path) {
		if path, err = filepath.Abs(path); err != nil {
			return
		}
		if path, err = filepath.EvalSymlinks(path); err != nil {
			return
		}
		for _, t := range Path {
			tpath := t.SrcDir() + string(filepath.Separator)
			if !filepath.HasPrefix(path, tpath) {
				continue
			}
			tree = t
			pkg = path[len(tpath):]
			return
		}
		err = fmt.Errorf("path %q not inside a GOPATH", path)
		return
	}
	tree = defaultTree
	pkg = path
	for _, t := range Path {
		if t.HasSrc(pkg) {
			tree = t
			return
		}
	}
	if tree == nil {
		err = ErrTreeNotFound
	} else {
		err = ErrNotFound
	}
	return
}

// isLocalPath returns whether the given path is local (/foo ./foo ../foo . ..)
// Windows paths that starts with drive letter (c:\foo c:foo) are considered local.
func isLocalPath(s string) bool {
	const sep = string(filepath.Separator)
	return s == "." || s == ".." ||
		filepath.HasPrefix(s, sep) ||
		filepath.HasPrefix(s, "."+sep) || filepath.HasPrefix(s, ".."+sep) ||
		filepath.VolumeName(s) != ""
}

var (
	// argument lists used by the build's gc and ld methods
	gcImportArgs []string
	ldImportArgs []string

	// default tree for remote packages
	defaultTree *Tree
)

// set up Path: parse and validate GOROOT and GOPATH variables
func init() {
	root := runtime.GOROOT()
	t, err := newTree(root)
	if err != nil {
		log.Printf("invalid GOROOT %q: %v", root, err)
	} else {
		t.Goroot = true
		Path = []*Tree{t}
	}

	for _, p := range filepath.SplitList(os.Getenv("GOPATH")) {
		if p == "" {
			continue
		}
		t, err := newTree(p)
		if err != nil {
			log.Printf("invalid GOPATH %q: %v", p, err)
			continue
		}
		Path = append(Path, t)
		gcImportArgs = append(gcImportArgs, "-I", t.PkgDir())
		ldImportArgs = append(ldImportArgs, "-L", t.PkgDir())

		// select first GOPATH entry as default
		if defaultTree == nil {
			defaultTree = t
		}
	}

	// use GOROOT if no valid GOPATH specified
	if defaultTree == nil && len(Path) > 0 {
		defaultTree = Path[0]
	}
}
<commit_msg>go/build: handle and warn of duplicate GOPATH entries<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package build

import (
	"errors"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"runtime"
)

// Path is a validated list of Trees derived from $GOROOT and $GOPATH at init.
var Path []*Tree

// Tree describes a Go source tree, either $GOROOT or one from $GOPATH.
type Tree struct {
	Path   string
	Goroot bool
}

func newTree(p string) (*Tree, error) {
	if !filepath.IsAbs(p) {
		return nil, errors.New("must be absolute")
	}
	ep, err := filepath.EvalSymlinks(p)
	if err != nil {
		return nil, err
	}
	return &Tree{Path: ep}, nil
}

// SrcDir returns the tree's package source directory.
func (t *Tree) SrcDir() string {
	if t.Goroot {
		return filepath.Join(t.Path, "src", "pkg")
	}
	return filepath.Join(t.Path, "src")
}

// PkgDir returns the tree's package object directory.
func (t *Tree) PkgDir() string {
	goos, goarch := runtime.GOOS, runtime.GOARCH
	if e := os.Getenv("GOOS"); e != "" {
		goos = e
	}
	if e := os.Getenv("GOARCH"); e != "" {
		goarch = e
	}
	return filepath.Join(t.Path, "pkg", goos+"_"+goarch)
}

// BinDir returns the tree's binary executable directory.
func (t *Tree) BinDir() string {
	if t.Goroot {
		if gobin := os.Getenv("GOBIN"); gobin != "" {
			return filepath.Clean(gobin)
		}
	}
	return filepath.Join(t.Path, "bin")
}

// HasSrc returns whether the given package's
// source can be found inside this Tree.
func (t *Tree) HasSrc(pkg string) bool {
	fi, err := os.Stat(filepath.Join(t.SrcDir(), pkg))
	if err != nil {
		return false
	}
	return fi.IsDir()
}

// HasPkg returns whether the given package's
// object file can be found inside this Tree.
func (t *Tree) HasPkg(pkg string) bool {
	fi, err := os.Stat(filepath.Join(t.PkgDir(), pkg+".a"))
	if err != nil {
		return false
	}
	return !fi.IsDir()
	// TODO(adg): check object version is consistent
}

var (
	ErrNotFound     = errors.New("package could not be found locally")
	ErrTreeNotFound = errors.New("no valid GOROOT or GOPATH could be found")
)

// FindTree takes an import or filesystem path and returns the
// tree where the package source should be and the package import path.
func FindTree(path string) (tree *Tree, pkg string, err error) {
	if isLocalPath(path) {
		if path, err = filepath.Abs(path); err != nil {
			return
		}
		if path, err = filepath.EvalSymlinks(path); err != nil {
			return
		}
		for _, t := range Path {
			tpath := t.SrcDir() + string(filepath.Separator)
			if !filepath.HasPrefix(path, tpath) {
				continue
			}
			tree = t
			pkg = path[len(tpath):]
			return
		}
		err = fmt.Errorf("path %q not inside a GOPATH", path)
		return
	}
	tree = defaultTree
	pkg = path
	for _, t := range Path {
		if t.HasSrc(pkg) {
			tree = t
			return
		}
	}
	if tree == nil {
		err = ErrTreeNotFound
	} else {
		err = ErrNotFound
	}
	return
}

// isLocalPath returns whether the given path is local (/foo ./foo ../foo . ..)
// Windows paths that starts with drive letter (c:\foo c:foo) are considered local.
func isLocalPath(s string) bool {
	const sep = string(filepath.Separator)
	return s == "." || s == ".." ||
		filepath.HasPrefix(s, sep) ||
		filepath.HasPrefix(s, "."+sep) || filepath.HasPrefix(s, ".."+sep) ||
		filepath.VolumeName(s) != ""
}

var (
	// argument lists used by the build's gc and ld methods
	gcImportArgs []string
	ldImportArgs []string

	// default tree for remote packages
	defaultTree *Tree
)

// set up Path: parse and validate GOROOT and GOPATH variables
func init() {
	root := runtime.GOROOT()
	t, err := newTree(root)
	if err != nil {
		log.Printf("invalid GOROOT %q: %v", root, err)
	} else {
		t.Goroot = true
		Path = []*Tree{t}
	}

Loop:
	for _, p := range filepath.SplitList(os.Getenv("GOPATH")) {
		if p == "" {
			continue
		}
		t, err := newTree(p)
		if err != nil {
			log.Printf("invalid GOPATH %q: %v", p, err)
			continue
		}

		// Check for dupes.
		// TODO(alexbrainman): make this correct under windows (case insensitive).
		for _, t2 := range Path {
			if t2.Path != t.Path {
				continue
			}
			if t2.Goroot {
				log.Printf("GOPATH is the same as GOROOT: %q", t.Path)
			} else {
				log.Printf("duplicate GOPATH entry: %q", t.Path)
			}
			continue Loop
		}

		Path = append(Path, t)
		gcImportArgs = append(gcImportArgs, "-I", t.PkgDir())
		ldImportArgs = append(ldImportArgs, "-L", t.PkgDir())

		// select first GOPATH entry as default
		if defaultTree == nil {
			defaultTree = t
		}
	}

	// use GOROOT if no valid GOPATH specified
	if defaultTree == nil && len(Path) > 0 {
		defaultTree = Path[0]
	}
}
<|endoftext|>


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

// Parse "zoneinfo" time zone file.
// This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
// See tzfile(5), http://en.wikipedia.org/wiki/Zoneinfo,
// and ftp://munnari.oz.au/pub/oldtz/

package time

import (
	"io/ioutil"
	"once"
	"os"
)

const (
	headerSize = 4 + 16 + 4*7
	zoneDir    = "/usr/share/zoneinfo/"
)

// Simple I/O interface to binary blob of data.
type data struct {
	p     []byte
	error bool
}

func (d *data) read(n int) []byte {
	if len(d.p) < n {
		d.p = nil
		d.error = true
		return nil
	}
	p := d.p[0:n]
	d.p = d.p[n:]
	return p
}

func (d *data) big4() (n uint32, ok bool) {
	p := d.read(4)
	if len(p) < 4 {
		d.error = true
		return 0, false
	}
	return uint32(p[0])<<24 | uint32(p[1])<<16 | uint32(p[2])<<8 | uint32(p[3]), true
}

func (d *data) byte() (n byte, ok bool) {
	p := d.read(1)
	if len(p) < 1 {
		d.error = true
		return 0, false
	}
	return p[0], true
}

// Make a string by stopping at the first NUL
func byteString(p []byte) string {
	for i := 0; i < len(p); i++ {
		if p[i] == 0 {
			return string(p[0:i])
		}
	}
	return string(p)
}

// Parsed representation
type zone struct {
	utcoff int
	isdst  bool
	name   string
}

type zonetime struct {
	time         int32 // transition time, in seconds since 1970 GMT
	zone         *zone // the zone that goes into effect at that time
	isstd, isutc bool  // ignored - no idea what these mean
}

func parseinfo(bytes []byte) (zt []zonetime, ok bool) {
	d := data{bytes, false}

	// 4-byte magic "TZif"
	if magic := d.read(4); string(magic) != "TZif" {
		return nil, false
	}

	// 1-byte version, then 15 bytes of padding
	var p []byte
	if p = d.read(16); len(p) != 16 || p[0] != 0 && p[0] != '2' {
		return nil, false
	}

	// six big-endian 32-bit integers:
	//	number of UTC/local indicators
	//	number of standard/wall indicators
	//	number of leap seconds
	//	number of transition times
	//	number of local time zones
	//	number of characters of time zone abbrev strings
	const (
		NUTCLocal = iota
		NStdWall
		NLeap
		NTime
		NZone
		NChar
	)
	var n [6]int
	for i := 0; i < 6; i++ {
		nn, ok := d.big4()
		if !ok {
			return nil, false
		}
		n[i] = int(nn)
	}

	// Transition times.
	txtimes := data{d.read(n[NTime] * 4), false}

	// Time zone indices for transition times.
	txzones := d.read(n[NTime])

	// Zone info structures
	zonedata := data{d.read(n[NZone] * 6), false}

	// Time zone abbreviations.
	abbrev := d.read(n[NChar])

	// Leap-second time pairs
	d.read(n[NLeap] * 8)

	// Whether tx times associated with local time types
	// are specified as standard time or wall time.
	isstd := d.read(n[NStdWall])

	// Whether tx times associated with local time types
	// are specified as UTC or local time.
	isutc := d.read(n[NUTCLocal])

	if d.error { // ran out of data
		return nil, false
	}

	// If version == 2, the entire file repeats, this time using
	// 8-byte ints for txtimes and leap seconds.
	// We won't need those until 2106.

	// Now we can build up a useful data structure.
	// First the zone information.
	//	utcoff[4] isdst[1] nameindex[1]
	z := make([]zone, n[NZone])
	for i := 0; i < len(z); i++ {
		var ok bool
		var n uint32
		if n, ok = zonedata.big4(); !ok {
			return nil, false
		}
		z[i].utcoff = int(n)
		var b byte
		if b, ok = zonedata.byte(); !ok {
			return nil, false
		}
		z[i].isdst = b != 0
		if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) {
			return nil, false
		}
		z[i].name = byteString(abbrev[b:])
	}

	// Now the transition time info.
	zt = make([]zonetime, n[NTime])
	for i := 0; i < len(zt); i++ {
		var ok bool
		var n uint32
		if n, ok = txtimes.big4(); !ok {
			return nil, false
		}
		zt[i].time = int32(n)
		if int(txzones[i]) >= len(z) {
			return nil, false
		}
		zt[i].zone = &z[txzones[i]]
		if i < len(isstd) {
			zt[i].isstd = isstd[i] != 0
		}
		if i < len(isutc) {
			zt[i].isutc = isutc[i] != 0
		}
	}
	return zt, true
}

func readinfofile(name string) ([]zonetime, bool) {
	buf, err := ioutil.ReadFile(name)
	if err != nil {
		return nil, false
	}
	return parseinfo(buf)
}

var zones []zonetime
var onceSetupZone sync.Once

func setupZone() {
	// consult $TZ to find the time zone to use.
	// no $TZ means use the system default /etc/localtime.
	// $TZ="" means use UTC.
	// $TZ="foo" means use /usr/share/zoneinfo/foo.

	tz, err := os.Getenverror("TZ")
	switch {
	case err == os.ENOENV:
		zones, _ = readinfofile("/etc/localtime")
	case len(tz) > 0:
		zones, _ = readinfofile(zoneDir + tz)
	case len(tz) == 0:
		// do nothing: use UTC
	}
}

// Look up the correct time zone (daylight savings or not) for the given unix time, in the current location.
func lookupTimezone(sec int64) (zone string, offset int) {
	onceSetupZone.Do(setupZone)
	if len(zones) == 0 {
		return "UTC", 0
	}

	// Binary search for entry with largest time <= sec
	tz := zones
	for len(tz) > 1 {
		m := len(tz) / 2
		if sec < int64(tz[m].time) {
			tz = tz[0:m]
		} else {
			tz = tz[m:]
		}
	}
	z := tz[0].zone
	return z.name, z.utcoff
}
<commit_msg>Remove relic "once" import from time/zoneinfo.go<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Parse "zoneinfo" time zone file.
// This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
// See tzfile(5), http://en.wikipedia.org/wiki/Zoneinfo,
// and ftp://munnari.oz.au/pub/oldtz/

package time

import (
	"io/ioutil"
	"os"
)

const (
	headerSize = 4 + 16 + 4*7
	zoneDir    = "/usr/share/zoneinfo/"
)

// Simple I/O interface to binary blob of data.
type data struct {
	p     []byte
	error bool
}

func (d *data) read(n int) []byte {
	if len(d.p) < n {
		d.p = nil
		d.error = true
		return nil
	}
	p := d.p[0:n]
	d.p = d.p[n:]
	return p
}

func (d *data) big4() (n uint32, ok bool) {
	p := d.read(4)
	if len(p) < 4 {
		d.error = true
		return 0, false
	}
	return uint32(p[0])<<24 | uint32(p[1])<<16 | uint32(p[2])<<8 | uint32(p[3]), true
}

func (d *data) byte() (n byte, ok bool) {
	p := d.read(1)
	if len(p) < 1 {
		d.error = true
		return 0, false
	}
	return p[0], true
}

// Make a string by stopping at the first NUL
func byteString(p []byte) string {
	for i := 0; i < len(p); i++ {
		if p[i] == 0 {
			return string(p[0:i])
		}
	}
	return string(p)
}

// Parsed representation
type zone struct {
	utcoff int
	isdst  bool
	name   string
}

type zonetime struct {
	time         int32 // transition time, in seconds since 1970 GMT
	zone         *zone // the zone that goes into effect at that time
	isstd, isutc bool  // ignored - no idea what these mean
}

func parseinfo(bytes []byte) (zt []zonetime, ok bool) {
	d := data{bytes, false}

	// 4-byte magic "TZif"
	if magic := d.read(4); string(magic) != "TZif" {
		return nil, false
	}

	// 1-byte version, then 15 bytes of padding
	var p []byte
	if p = d.read(16); len(p) != 16 || p[0] != 0 && p[0] != '2' {
		return nil, false
	}

	// six big-endian 32-bit integers:
	//	number of UTC/local indicators
	//	number of standard/wall indicators
	//	number of leap seconds
	//	number of transition times
	//	number of local time zones
	//	number of characters of time zone abbrev strings
	const (
		NUTCLocal = iota
		NStdWall
		NLeap
		NTime
		NZone
		NChar
	)
	var n [6]int
	for i := 0; i < 6; i++ {
		nn, ok := d.big4()
		if !ok {
			return nil, false
		}
		n[i] = int(nn)
	}

	// Transition times.
	txtimes := data{d.read(n[NTime] * 4), false}

	// Time zone indices for transition times.
	txzones := d.read(n[NTime])

	// Zone info structures
	zonedata := data{d.read(n[NZone] * 6), false}

	// Time zone abbreviations.
	abbrev := d.read(n[NChar])

	// Leap-second time pairs
	d.read(n[NLeap] * 8)

	// Whether tx times associated with local time types
	// are specified as standard time or wall time.
	isstd := d.read(n[NStdWall])

	// Whether tx times associated with local time types
	// are specified as UTC or local time.
	isutc := d.read(n[NUTCLocal])

	if d.error { // ran out of data
		return nil, false
	}

	// If version == 2, the entire file repeats, this time using
	// 8-byte ints for txtimes and leap seconds.
	// We won't need those until 2106.

	// Now we can build up a useful data structure.
	// First the zone information.
	//	utcoff[4] isdst[1] nameindex[1]
	z := make([]zone, n[NZone])
	for i := 0; i < len(z); i++ {
		var ok bool
		var n uint32
		if n, ok = zonedata.big4(); !ok {
			return nil, false
		}
		z[i].utcoff = int(n)
		var b byte
		if b, ok = zonedata.byte(); !ok {
			return nil, false
		}
		z[i].isdst = b != 0
		if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) {
			return nil, false
		}
		z[i].name = byteString(abbrev[b:])
	}

	// Now the transition time info.
	zt = make([]zonetime, n[NTime])
	for i := 0; i < len(zt); i++ {
		var ok bool
		var n uint32
		if n, ok = txtimes.big4(); !ok {
			return nil, false
		}
		zt[i].time = int32(n)
		if int(txzones[i]) >= len(z) {
			return nil, false
		}
		zt[i].zone = &z[txzones[i]]
		if i < len(isstd) {
			zt[i].isstd = isstd[i] != 0
		}
		if i < len(isutc) {
			zt[i].isutc = isutc[i] != 0
		}
	}
	return zt, true
}

func readinfofile(name string) ([]zonetime, bool) {
	buf, err := ioutil.ReadFile(name)
	if err != nil {
		return nil, false
	}
	return parseinfo(buf)
}

var zones []zonetime
var onceSetupZone sync.Once

func setupZone() {
	// consult $TZ to find the time zone to use.
	// no $TZ means use the system default /etc/localtime.
	// $TZ="" means use UTC.
	// $TZ="foo" means use /usr/share/zoneinfo/foo.

	tz, err := os.Getenverror("TZ")
	switch {
	case err == os.ENOENV:
		zones, _ = readinfofile("/etc/localtime")
	case len(tz) > 0:
		zones, _ = readinfofile(zoneDir + tz)
	case len(tz) == 0:
		// do nothing: use UTC
	}
}

// Look up the correct time zone (daylight savings or not) for the given unix time, in the current location.
func lookupTimezone(sec int64) (zone string, offset int) {
	onceSetupZone.Do(setupZone)
	if len(zones) == 0 {
		return "UTC", 0
	}

	// Binary search for entry with largest time <= sec
	tz := zones
	for len(tz) > 1 {
		m := len(tz) / 2
		if sec < int64(tz[m].time) {
			tz = tz[0:m]
		} else {
			tz = tz[m:]
		}
	}
	z := tz[0].zone
	return z.name, z.utcoff
}
<|endoftext|>


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

// The go1.10 command runs the go command from go1.10.
//
// To install, run:
//
//     $ go get golang.org/dl/go1.10
//     $ go1.10 download
//
// And then use the go1.10 command as if it were your normal go
// command.
//
// See the release notes at https://golang.org/doc/go1.10
//
// File bugs at https://golang.org/issues/new
package main

import "golang.org/dl/internal/version"

func main() {
	version.Run("go1.10")
}
<commit_msg>go1.10: remove duplicate file go1.10.go<commit_after><|endoftext|>


<commit_before>package main

import (
	"context"
	"log"

	"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/resources"
	"github.com/Azure/go-autorest/autorest/to"
	. "github.com/onsi/gomega"

	"github.com/docker/api/azure"
	. "github.com/docker/api/tests/framework"
)

const (
	resourceGroupName = "resourceGroupTest"
	location          = "westeurope"
	contextName       = "acitest"
)

func main() {
	SetupTest()

	It("ensures context command includes azure-login and aci-create", func() {
		output := NewDockerCommand("context", "create", "--help").ExecOrDie()
		Expect(output).To(ContainSubstring("docker context create CONTEXT BACKEND [OPTIONS] [flags]"))
		Expect(output).To(ContainSubstring("--aci-location"))
		Expect(output).To(ContainSubstring("--aci-subscription-id"))
		Expect(output).To(ContainSubstring("--aci-resource-group"))
	})

	It("should be initialized with default context", func() {
		_, err := NewCommand("docker", "context", "rm", "-f", contextName).Exec()
		if err == nil {
			log.Println("Cleaning existing test context")
		}

		NewCommand("docker", "context", "use", "default").ExecOrDie()
		output := NewCommand("docker", "context", "ls").ExecOrDie()
		Expect(output).To(Not(ContainSubstring(contextName)))
		Expect(output).To(ContainSubstring("default *"))
	})

	It("creates a new aci context for tests", func() {
		setupTestResourecGroup(resourceGroupName)
		subscriptionID, err := azure.GetSubscriptionID(context.TODO())
		Expect(err).To(BeNil())

		NewDockerCommand("context", "create", contextName, "aci", "--aci-subscription-id", subscriptionID, "--aci-resource-group", resourceGroupName, "--aci-location", location).ExecOrDie()
		// Expect(output).To(ContainSubstring("ACI context acitest created"))
	})

	defer deleteResourceGroup(resourceGroupName)

	It("uses the aci context", func() {
		currentContext := NewCommand("docker", "context", "use", contextName).ExecOrDie()
		Expect(currentContext).To(ContainSubstring(contextName))
		output := NewCommand("docker", "context", "ls").ExecOrDie()
		Expect(output).To(ContainSubstring("acitest *"))
	})

	It("ensures no container is running initially", func() {
		output := NewDockerCommand("ps").ExecOrDie()
		Expect(len(Lines(output))).To(Equal(1))
	})

	var nginxID string
	It("runs nginx on port 80 (PORT NOT CHECKED YET!!! REMOVE THAT WHEN IMPLEMENTED)", func() {
		NewDockerCommand("run", "nginx", "-p", "80:80").ExecOrDie()
		output := NewDockerCommand("ps").ExecOrDie()
		lines := Lines(output)
		Expect(len(lines)).To(Equal(2))

		containerFields := Columns(lines[1])
		nginxID = containerFields[0]
		Expect(containerFields[1]).To(Equal("nginx"))
		Expect(containerFields[2]).To(Equal("Running"))
		// exposedIP := containerFields[3]
		// Expect(exposedIP).To(ContainSubstring(":80->80/TCP"))

		// url := strings.ReplaceAll(exposedIP, "->80/TCP", "")
		// output = NewCommand("curl", url).ExecOrDie()
		// Expect(output).To(ContainSubstring("Welcome to nginx!"))
	})

	It("removes container nginx", func() {
		output := NewDockerCommand("rm", nginxID).ExecOrDie()
		Expect(Lines(output)[0]).To(Equal(nginxID))
	})

	It("deploys a compose app", func() {
		NewDockerCommand("compose", "up", "-f", "./tests/composefiles/aci-demo/aci_demo_port.yaml", "--name", "acidemo").ExecOrDie()
		// Expect(output).To(ContainSubstring("Successfully deployed"))
		output := NewDockerCommand("ps").ExecOrDie()
		Lines := Lines(output)
		Expect(len(Lines)).To(Equal(4))
		for _, line := range Lines[1:] {
			Expect(line).To(ContainSubstring("Running"))
		}
		/*
				if strings.Contains(line, "acicompose_web") {
					webChecked = true
					containerFields := Columns(line)
					exposedIP := containerFields[3]
					Expect(exposedIP).To(ContainSubstring(":80->80/TCP"))

					url := strings.ReplaceAll(exposedIP, "->80/TCP", "")
					output = NewCommand("curl", url).ExecOrDie()
					Expect(output).To(ContainSubstring("Docker Compose demo"))
					output = NewCommand("curl", url+"/words/noun").ExecOrDie()
					Expect(output).To(ContainSubstring("\"word\":"))
				}
			}
			Expect(webChecked).To(BeTrue())
		*/
	})

	It("get logs from web service", func() {
		output := NewDockerCommand("logs", "acidemo_web").ExecOrDie()
		Expect(output).To(ContainSubstring("Listening on port 80"))
	})

	It("shutdown compose app", func() {
		NewDockerCommand("compose", "down", "-f", "./tests/composefiles/aci-demo/aci_demo_port.yaml", "--name", "acidemo").ExecOrDie()
	})
	It("switches back to default context", func() {
		output := NewCommand("docker", "context", "use", "default").ExecOrDie()
		Expect(output).To(ContainSubstring("default"))
	})

	It("deletes test context", func() {
		output := NewCommand("docker", "context", "rm", contextName).ExecOrDie()
		Expect(output).To(ContainSubstring(contextName))
	})
}

func setupTestResourecGroup(groupName string) {
	log.Println("Creating resource group " + resourceGroupName)
	ctx := context.TODO()
	subscriptionID, err := azure.GetSubscriptionID(ctx)
	Expect(err).To(BeNil())
	gc := azure.GetGroupsClient(subscriptionID)
	_, err = gc.CreateOrUpdate(ctx, groupName, resources.Group{
		Location: to.StringPtr(location),
	})
	Expect(err).To(BeNil())
}

func deleteResourceGroup(groupName string) {
	log.Println("Deleting resource group " + resourceGroupName)
	ctx := context.TODO()
	subscriptionID, err := azure.GetSubscriptionID(ctx)
	Expect(err).To(BeNil())
	gc := azure.GetGroupsClient(subscriptionID)
	_, err = gc.Delete(ctx, groupName)
	Expect(err).To(BeNil())
}
<commit_msg>Test output of `docker run`<commit_after>package main

import (
	"context"
	"log"

	"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/resources"
	"github.com/Azure/go-autorest/autorest/to"
	. "github.com/onsi/gomega"

	"github.com/docker/api/azure"
	. "github.com/docker/api/tests/framework"
)

const (
	resourceGroupName = "resourceGroupTest"
	location          = "westeurope"
	contextName       = "acitest"

	testContainerName = "testcontainername"
)

func main() {
	SetupTest()

	It("ensures context command includes azure-login and aci-create", func() {
		output := NewDockerCommand("context", "create", "--help").ExecOrDie()
		Expect(output).To(ContainSubstring("docker context create CONTEXT BACKEND [OPTIONS] [flags]"))
		Expect(output).To(ContainSubstring("--aci-location"))
		Expect(output).To(ContainSubstring("--aci-subscription-id"))
		Expect(output).To(ContainSubstring("--aci-resource-group"))
	})

	It("should be initialized with default context", func() {
		_, err := NewCommand("docker", "context", "rm", "-f", contextName).Exec()
		if err == nil {
			log.Println("Cleaning existing test context")
		}

		NewCommand("docker", "context", "use", "default").ExecOrDie()
		output := NewCommand("docker", "context", "ls").ExecOrDie()
		Expect(output).To(Not(ContainSubstring(contextName)))
		Expect(output).To(ContainSubstring("default *"))
	})

	It("creates a new aci context for tests", func() {
		setupTestResourecGroup(resourceGroupName)
		subscriptionID, err := azure.GetSubscriptionID(context.TODO())
		Expect(err).To(BeNil())

		NewDockerCommand("context", "create", contextName, "aci", "--aci-subscription-id", subscriptionID, "--aci-resource-group", resourceGroupName, "--aci-location", location).ExecOrDie()
		// Expect(output).To(ContainSubstring("ACI context acitest created"))
	})

	defer deleteResourceGroup(resourceGroupName)

	It("uses the aci context", func() {
		currentContext := NewCommand("docker", "context", "use", contextName).ExecOrDie()
		Expect(currentContext).To(ContainSubstring(contextName))
		output := NewCommand("docker", "context", "ls").ExecOrDie()
		Expect(output).To(ContainSubstring("acitest *"))
	})

	It("ensures no container is running initially", func() {
		output := NewDockerCommand("ps").ExecOrDie()
		Expect(len(Lines(output))).To(Equal(1))
	})

	var nginxID string
	It("runs nginx on port 80 (PORT NOT CHECKED YET!!! REMOVE THAT WHEN IMPLEMENTED)", func() {
		output := NewDockerCommand("run", "nginx", "-p", "80:80", "--name", testContainerName).ExecOrDie()
		Expect(output).To(Equal(testContainerName + "\n"))
		output = NewDockerCommand("ps").ExecOrDie()
		lines := Lines(output)
		Expect(len(lines)).To(Equal(2))

		containerFields := Columns(lines[1])
		nginxID = containerFields[0]
		Expect(containerFields[1]).To(Equal("nginx"))
		Expect(containerFields[2]).To(Equal("Running"))
		// exposedIP := containerFields[3]
		// Expect(exposedIP).To(ContainSubstring(":80->80/TCP"))

		// url := strings.ReplaceAll(exposedIP, "->80/TCP", "")
		// output = NewCommand("curl", url).ExecOrDie()
		// Expect(output).To(ContainSubstring("Welcome to nginx!"))
	})

	It("removes container nginx", func() {
		output := NewDockerCommand("rm", nginxID).ExecOrDie()
		Expect(Lines(output)[0]).To(Equal(nginxID))
	})

	It("deploys a compose app", func() {
		NewDockerCommand("compose", "up", "-f", "./tests/composefiles/aci-demo/aci_demo_port.yaml", "--name", "acidemo").ExecOrDie()
		// Expect(output).To(ContainSubstring("Successfully deployed"))
		output := NewDockerCommand("ps").ExecOrDie()
		Lines := Lines(output)
		Expect(len(Lines)).To(Equal(4))
		for _, line := range Lines[1:] {
			Expect(line).To(ContainSubstring("Running"))
		}
		/*
				if strings.Contains(line, "acicompose_web") {
					webChecked = true
					containerFields := Columns(line)
					exposedIP := containerFields[3]
					Expect(exposedIP).To(ContainSubstring(":80->80/TCP"))

					url := strings.ReplaceAll(exposedIP, "->80/TCP", "")
					output = NewCommand("curl", url).ExecOrDie()
					Expect(output).To(ContainSubstring("Docker Compose demo"))
					output = NewCommand("curl", url+"/words/noun").ExecOrDie()
					Expect(output).To(ContainSubstring("\"word\":"))
				}
			}
			Expect(webChecked).To(BeTrue())
		*/
	})

	It("get logs from web service", func() {
		output := NewDockerCommand("logs", "acidemo_web").ExecOrDie()
		Expect(output).To(ContainSubstring("Listening on port 80"))
	})

	It("shutdown compose app", func() {
		NewDockerCommand("compose", "down", "-f", "./tests/composefiles/aci-demo/aci_demo_port.yaml", "--name", "acidemo").ExecOrDie()
	})
	It("switches back to default context", func() {
		output := NewCommand("docker", "context", "use", "default").ExecOrDie()
		Expect(output).To(ContainSubstring("default"))
	})

	It("deletes test context", func() {
		output := NewCommand("docker", "context", "rm", contextName).ExecOrDie()
		Expect(output).To(ContainSubstring(contextName))
	})
}

func setupTestResourecGroup(groupName string) {
	log.Println("Creating resource group " + resourceGroupName)
	ctx := context.TODO()
	subscriptionID, err := azure.GetSubscriptionID(ctx)
	Expect(err).To(BeNil())
	gc := azure.GetGroupsClient(subscriptionID)
	_, err = gc.CreateOrUpdate(ctx, groupName, resources.Group{
		Location: to.StringPtr(location),
	})
	Expect(err).To(BeNil())
}

func deleteResourceGroup(groupName string) {
	log.Println("Deleting resource group " + resourceGroupName)
	ctx := context.TODO()
	subscriptionID, err := azure.GetSubscriptionID(ctx)
	Expect(err).To(BeNil())
	gc := azure.GetGroupsClient(subscriptionID)
	_, err = gc.Delete(ctx, groupName)
	Expect(err).To(BeNil())
}
<|endoftext|>