<commit_before>//
// Copyright 2021, Sander van Harmelen
//
// 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 gitlab

import (
	"fmt"
	"net/http"
	"reflect"
	"testing"
	"time"
)

func TestListRegistryRepositories(t *testing.T) {
	mux, server, client := setup(t)
	defer teardown(server)

	mux.HandleFunc("/api/v4/projects/5/registry/repositories", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodGet)
		fmt.Fprintf(w, `[
			{
			  "id": 1,
			  "name": "",
			  "path": "group/project",
			  "project_id": 9,
			  "location": "gitlab.example.com:5000/group/project",
			  "created_at": "2019-01-10T13:38:57.391Z",
			  "cleanup_policy_started_at": "2020-01-10T15:40:57.391Z"
			},
			{
			  "id": 2,
			  "name": "releases",
			  "path": "group/project/releases",
			  "project_id": 9,
			  "location": "gitlab.example.com:5000/group/project/releases",
			  "created_at": "2019-01-10T13:39:08.229Z",
			  "cleanup_policy_started_at": "2020-08-17T03:12:35.489Z"
			}
		  ]`)
	})

	repositories, _, err := client.ContainerRegistry.ListRegistryRepositories(5, &ListRegistryRepositoriesOptions{})
	if err != nil {
		t.Errorf("ContainerRegistry.ListRegistryRepositories returned error: %v", err)
	}

	timeLayout := "2006-01-02T15:04:05.000Z"

	created_at1, err := time.Parse(timeLayout, "2019-01-10T13:38:57.391Z")
	if err != nil {
		t.Errorf("ContainerRepository.ListRegistryRepositories error while parsing time: %v", err)
	}

	created_at2, err := time.Parse(timeLayout, "2019-01-10T13:39:08.229Z")
	if err != nil {
		t.Errorf("ContainerRepository.ListRegistryRepositories error while parsing time: %v", err)
	}

	cleanup_policy_started_at1, err := time.Parse(timeLayout, "2020-01-10T15:40:57.391Z")
	if err != nil {
		t.Errorf("ContainerRepository.ListRegistryRepositories error while parsing time: %v", err)
	}

	cleanup_policy_started_at2, err := time.Parse(timeLayout, "2020-08-17T03:12:35.489Z")
	if err != nil {
		t.Errorf("ContainerRepository.ListRegistryRepositories error while parsing time: %v", err)
	}

	want := []*RegistryRepository{
		{ID: 1, Name: "", Path: "group/project", Location: "gitlab.example.com:5000/group/project", CreatedAt: &created_at1, CleanupPolicyStartedAt: &cleanup_policy_started_at1},
		{ID: 2, Name: "releases", Path: "group/project/releases", Location: "gitlab.example.com:5000/group/project/releases", CreatedAt: &created_at2, CleanupPolicyStartedAt: &cleanup_policy_started_at2},
	}
	if !reflect.DeepEqual(want, repositories) {
		t.Errorf("ContainerRepository.ListRegistryRepositories returned %+v, want %+v", repositories, want)
	}
}

func TestDeleteRegistryRepository(t *testing.T) {
	mux, server, client := setup(t)
	defer teardown(server)

	mux.HandleFunc("/api/v4/projects/5/registry/repositories/2", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodDelete)
	})

	_, err := client.ContainerRegistry.DeleteRegistryRepository(5, 2)
	if err != nil {
		t.Errorf("ContainerRegistry.DeleteRegistryRepository returned error: %v", err)
	}
}

func TestListRegistryRepositoryTags(t *testing.T) {
	mux, server, client := setup(t)
	defer teardown(server)

	mux.HandleFunc("/api/v4/projects/5/registry/repositories/2/tags", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodGet)
		fmt.Fprintf(w, `[
			{
			  "name": "A",
			  "path": "group/project:A",
			  "location": "gitlab.example.com:5000/group/project:A"
			},
			{
			  "name": "latest",
			  "path": "group/project:latest",
			  "location": "gitlab.example.com:5000/group/project:latest"
			}
		  ]`)
	})

	registryRepositoryTags, _, err := client.ContainerRegistry.ListRegistryRepositoryTags(5, 2, &ListRegistryRepositoryTagsOptions{})
	if err != nil {
		t.Errorf("ContainerRegistry.ListRegistryRepositoryTags returned error: %v", err)
	}

	want := []*RegistryRepositoryTag{
		{Name: "A", Path: "group/project:A", Location: "gitlab.example.com:5000/group/project:A"},
		{Name: "latest", Path: "group/project:latest", Location: "gitlab.example.com:5000/group/project:latest"},
	}
	if !reflect.DeepEqual(want, registryRepositoryTags) {
		t.Errorf("ContainerRepository.ListRegistryRepositoryTags returned %+v, want %+v", registryRepositoryTags, want)
	}
}

func TestGetRegistryRepositoryTagDetail(t *testing.T) {
	mux, server, client := setup(t)
	defer teardown(server)

	mux.HandleFunc("/api/v4/projects/5/registry/repositories/2/tags/v10.0.0", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodGet)
		fmt.Fprintf(w, `{
			"name": "v10.0.0",
			"path": "group/project:latest",
			"location": "gitlab.example.com:5000/group/project:latest",
			"revision": "e9ed9d87c881d8c2fd3a31b41904d01ba0b836e7fd15240d774d811a1c248181",
			"short_revision": "e9ed9d87c",
			"digest": "sha256:c3490dcf10ffb6530c1303522a1405dfaf7daecd8f38d3e6a1ba19ea1f8a1751",
			"created_at": "2019-01-06T16:49:51.272+00:00",
			"total_size": 350224384
		  }`)
	})

	repositoryTag, _, err := client.ContainerRegistry.GetRegistryRepositoryTagDetail(5, 2, "v10.0.0")
	if err != nil {
		t.Errorf("ContainerRegistry.GetRegistryRepositoryTagDetail returned error: %v", err)
	}

	timeLayout := "2006-01-02T15:04:05Z07:00"
	createdAt, err := time.Parse(timeLayout, "2019-01-06T16:49:51.272+00:00")
	if err != nil {
		t.Errorf("ContainerRepository.ListRegistryRepositories error while parsing time: %v", err)
	}

	want := &RegistryRepositoryTag{
		Name:          "v10.0.0",
		Path:          "group/project:latest",
		Location:      "gitlab.example.com:5000/group/project:latest",
		Revision:      "e9ed9d87c881d8c2fd3a31b41904d01ba0b836e7fd15240d774d811a1c248181",
		ShortRevision: "e9ed9d87c",
		Digest:        "sha256:c3490dcf10ffb6530c1303522a1405dfaf7daecd8f38d3e6a1ba19ea1f8a1751",
		CreatedAt:     &createdAt,
		TotalSize:     350224384,
	}
	if !reflect.DeepEqual(want, repositoryTag) {
		t.Errorf("ContainerRepository.ListRegistryRepositories returned %+v, want %+v", repositoryTag, want)
	}
}
<commit_msg>Added Test for DeleteRegistryRepositoryTag<commit_after>//
// Copyright 2021, Sander van Harmelen
//
// 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 gitlab

import (
	"fmt"
	"net/http"
	"reflect"
	"testing"
	"time"
)

func TestListRegistryRepositories(t *testing.T) {
	mux, server, client := setup(t)
	defer teardown(server)

	mux.HandleFunc("/api/v4/projects/5/registry/repositories", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodGet)
		fmt.Fprintf(w, `[
			{
			  "id": 1,
			  "name": "",
			  "path": "group/project",
			  "project_id": 9,
			  "location": "gitlab.example.com:5000/group/project",
			  "created_at": "2019-01-10T13:38:57.391Z",
			  "cleanup_policy_started_at": "2020-01-10T15:40:57.391Z"
			},
			{
			  "id": 2,
			  "name": "releases",
			  "path": "group/project/releases",
			  "project_id": 9,
			  "location": "gitlab.example.com:5000/group/project/releases",
			  "created_at": "2019-01-10T13:39:08.229Z",
			  "cleanup_policy_started_at": "2020-08-17T03:12:35.489Z"
			}
		  ]`)
	})

	repositories, _, err := client.ContainerRegistry.ListRegistryRepositories(5, &ListRegistryRepositoriesOptions{})
	if err != nil {
		t.Errorf("ContainerRegistry.ListRegistryRepositories returned error: %v", err)
	}

	timeLayout := "2006-01-02T15:04:05.000Z"

	created_at1, err := time.Parse(timeLayout, "2019-01-10T13:38:57.391Z")
	if err != nil {
		t.Errorf("ContainerRepository.ListRegistryRepositories error while parsing time: %v", err)
	}

	created_at2, err := time.Parse(timeLayout, "2019-01-10T13:39:08.229Z")
	if err != nil {
		t.Errorf("ContainerRepository.ListRegistryRepositories error while parsing time: %v", err)
	}

	cleanup_policy_started_at1, err := time.Parse(timeLayout, "2020-01-10T15:40:57.391Z")
	if err != nil {
		t.Errorf("ContainerRepository.ListRegistryRepositories error while parsing time: %v", err)
	}

	cleanup_policy_started_at2, err := time.Parse(timeLayout, "2020-08-17T03:12:35.489Z")
	if err != nil {
		t.Errorf("ContainerRepository.ListRegistryRepositories error while parsing time: %v", err)
	}

	want := []*RegistryRepository{
		{ID: 1, Name: "", Path: "group/project", Location: "gitlab.example.com:5000/group/project", CreatedAt: &created_at1, CleanupPolicyStartedAt: &cleanup_policy_started_at1},
		{ID: 2, Name: "releases", Path: "group/project/releases", Location: "gitlab.example.com:5000/group/project/releases", CreatedAt: &created_at2, CleanupPolicyStartedAt: &cleanup_policy_started_at2},
	}
	if !reflect.DeepEqual(want, repositories) {
		t.Errorf("ContainerRepository.ListRegistryRepositories returned %+v, want %+v", repositories, want)
	}
}

func TestDeleteRegistryRepository(t *testing.T) {
	mux, server, client := setup(t)
	defer teardown(server)

	mux.HandleFunc("/api/v4/projects/5/registry/repositories/2", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodDelete)
	})

	_, err := client.ContainerRegistry.DeleteRegistryRepository(5, 2)
	if err != nil {
		t.Errorf("ContainerRegistry.DeleteRegistryRepository returned error: %v", err)
	}
}

func TestListRegistryRepositoryTags(t *testing.T) {
	mux, server, client := setup(t)
	defer teardown(server)

	mux.HandleFunc("/api/v4/projects/5/registry/repositories/2/tags", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodGet)
		fmt.Fprintf(w, `[
			{
			  "name": "A",
			  "path": "group/project:A",
			  "location": "gitlab.example.com:5000/group/project:A"
			},
			{
			  "name": "latest",
			  "path": "group/project:latest",
			  "location": "gitlab.example.com:5000/group/project:latest"
			}
		  ]`)
	})

	registryRepositoryTags, _, err := client.ContainerRegistry.ListRegistryRepositoryTags(5, 2, &ListRegistryRepositoryTagsOptions{})
	if err != nil {
		t.Errorf("ContainerRegistry.ListRegistryRepositoryTags returned error: %v", err)
	}

	want := []*RegistryRepositoryTag{
		{Name: "A", Path: "group/project:A", Location: "gitlab.example.com:5000/group/project:A"},
		{Name: "latest", Path: "group/project:latest", Location: "gitlab.example.com:5000/group/project:latest"},
	}
	if !reflect.DeepEqual(want, registryRepositoryTags) {
		t.Errorf("ContainerRepository.ListRegistryRepositoryTags returned %+v, want %+v", registryRepositoryTags, want)
	}
}

func TestGetRegistryRepositoryTagDetail(t *testing.T) {
	mux, server, client := setup(t)
	defer teardown(server)

	mux.HandleFunc("/api/v4/projects/5/registry/repositories/2/tags/v10.0.0", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodGet)
		fmt.Fprintf(w, `{
			"name": "v10.0.0",
			"path": "group/project:latest",
			"location": "gitlab.example.com:5000/group/project:latest",
			"revision": "e9ed9d87c881d8c2fd3a31b41904d01ba0b836e7fd15240d774d811a1c248181",
			"short_revision": "e9ed9d87c",
			"digest": "sha256:c3490dcf10ffb6530c1303522a1405dfaf7daecd8f38d3e6a1ba19ea1f8a1751",
			"created_at": "2019-01-06T16:49:51.272+00:00",
			"total_size": 350224384
		  }`)
	})

	repositoryTag, _, err := client.ContainerRegistry.GetRegistryRepositoryTagDetail(5, 2, "v10.0.0")
	if err != nil {
		t.Errorf("ContainerRegistry.GetRegistryRepositoryTagDetail returned error: %v", err)
	}

	timeLayout := "2006-01-02T15:04:05Z07:00"
	createdAt, err := time.Parse(timeLayout, "2019-01-06T16:49:51.272+00:00")
	if err != nil {
		t.Errorf("ContainerRepository.ListRegistryRepositories error while parsing time: %v", err)
	}

	want := &RegistryRepositoryTag{
		Name:          "v10.0.0",
		Path:          "group/project:latest",
		Location:      "gitlab.example.com:5000/group/project:latest",
		Revision:      "e9ed9d87c881d8c2fd3a31b41904d01ba0b836e7fd15240d774d811a1c248181",
		ShortRevision: "e9ed9d87c",
		Digest:        "sha256:c3490dcf10ffb6530c1303522a1405dfaf7daecd8f38d3e6a1ba19ea1f8a1751",
		CreatedAt:     &createdAt,
		TotalSize:     350224384,
	}
	if !reflect.DeepEqual(want, repositoryTag) {
		t.Errorf("ContainerRepository.ListRegistryRepositories returned %+v, want %+v", repositoryTag, want)
	}
}

func TestDeleteRegistryRepositoryTag(t *testing.T) {
	mux, server, client := setup(t)
	defer teardown(server)

	mux.HandleFunc("/api/v4/projects/5/registry/repositories/2/tags/v10.0.0", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodDelete)
	})

	/**
		_, err := client.ContainerRegistry.DeleteRegistryRepository(5, 2)
	if err != nil {
		t.Errorf("ContainerRegistry.DeleteRegistryRepository returned error: %v", err)
	}
	*/
	_, err := client.ContainerRegistry.DeleteRegistryRepositoryTag(5, 2, "v10.0.0")
	if err != nil {
		t.Errorf("ContainerRepository.DeleteRegistryRepositoryTag returned error: %v", err)
	}
}
<|endoftext|>


<commit_before>package command

import (
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"

	consulapi "github.com/hashicorp/consul/api"
)

type KVWriteCommand struct {
	Meta
	modifyIndex	string
	dataFlags	string
}

func (c *KVWriteCommand) Help() string {
	helpText := `
Usage: consul-cli kv-write [options] path value

  Write a value to a given path.

Options:
` + c.ConsulHelp() +
`  --modifyindex=<ModifyIndex>	Perform a Check-and-Set write.
				(default: not set)
  --flags=<number>		Integer value between 0 and 2^64 - 1
				(default: not set)
`

	return strings.TrimSpace(helpText)
}

func (c *KVWriteCommand) Run(args []string) int {
	c.AddDataCenter()
	flags := c.Meta.FlagSet()
	flags.StringVar(&c.modifyIndex, "cas", "", "")
	flags.StringVar(&c.dataFlags, "flags", "", "")
	flags.Usage = func() { c.UI.Output(c.Help()) }

	if err := flags.Parse(args); err != nil {
		return 1
	}

	extra := flags.Args()
	if len(extra) < 2 {
		c.UI.Error("Key path and value must be specified")
		c.UI.Error("")
		c.UI.Error(c.Help())
		return 1
	}

	path := extra[0]
	value := strings.Join(extra[1:], " ")

	kv := new(consulapi.KVPair)

	kv.Key = path
	if strings.HasPrefix(value, "@") {
		v, err := ioutil.ReadFile(value[1:])
		if err != nil {
			c.UI.Error(fmt.Sprintf("ReadFile error: %v", err))
			return 1
		}
		kv.Value = v
	} else {
		kv.Value = []byte(value)
	}

	// &flags=
	//
	if c.dataFlags != "" {
		f, err := strconv.ParseUint(c.dataFlags, 0, 64)
		if err != nil {
			c.UI.Error(fmt.Sprintf("Error parsing flags: %v", c.dataFlags))
			c.UI.Error("")
			return 1
		}
		kv.Flags = f
	}

	consul, err := c.Client()
	if err != nil {
		c.UI.Error(err.Error())
		return 1
	}
	client := consul.KV()

	writeOpts := c.WriteOptions()

	if c.modifyIndex == "" {
		_, err := client.Put(kv, writeOpts)
		if err != nil {
			c.UI.Error(err.Error())
			return 1
		}
	} else {
		// Check-and-Set
		i, err := strconv.ParseUint(c.modifyIndex, 0, 64)
		if err != nil {
			c.UI.Error(fmt.Sprintf("Error parsing modifyIndex: %v", c.modifyIndex))
			c.UI.Error("")
			return 1
		}
		kv.ModifyIndex = i

		success, _, err := client.CAS(kv, writeOpts)
		if err != nil {
			c.UI.Error(err.Error())
			return 1
		}

		if !success {
			return 1
		}
	}

	return 0
}

func (c *KVWriteCommand) Synopsis() string {
	return "Write a value"
}
<commit_msg>Set `modifyindex` flag to use the documented name<commit_after>package command

import (
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"

	consulapi "github.com/hashicorp/consul/api"
)

type KVWriteCommand struct {
	Meta
	modifyIndex	string
	dataFlags	string
}

func (c *KVWriteCommand) Help() string {
	helpText := `
Usage: consul-cli kv-write [options] path value

  Write a value to a given path.

Options:
` + c.ConsulHelp() +
`  --modifyindex=<ModifyIndex>	Perform a Check-and-Set write.
				(default: not set)
  --flags=<number>		Integer value between 0 and 2^64 - 1
				(default: not set)
`

	return strings.TrimSpace(helpText)
}

func (c *KVWriteCommand) Run(args []string) int {
	c.AddDataCenter()
	flags := c.Meta.FlagSet()
	flags.StringVar(&c.modifyIndex, "modifyindex", "", "")
	flags.StringVar(&c.dataFlags, "flags", "", "")
	flags.Usage = func() { c.UI.Output(c.Help()) }

	if err := flags.Parse(args); err != nil {
		return 1
	}

	extra := flags.Args()
	if len(extra) < 2 {
		c.UI.Error("Key path and value must be specified")
		c.UI.Error("")
		c.UI.Error(c.Help())
		return 1
	}

	path := extra[0]
	value := strings.Join(extra[1:], " ")

	kv := new(consulapi.KVPair)

	kv.Key = path
	if strings.HasPrefix(value, "@") {
		v, err := ioutil.ReadFile(value[1:])
		if err != nil {
			c.UI.Error(fmt.Sprintf("ReadFile error: %v", err))
			return 1
		}
		kv.Value = v
	} else {
		kv.Value = []byte(value)
	}

	// &flags=
	//
	if c.dataFlags != "" {
		f, err := strconv.ParseUint(c.dataFlags, 0, 64)
		if err != nil {
			c.UI.Error(fmt.Sprintf("Error parsing flags: %v", c.dataFlags))
			c.UI.Error("")
			return 1
		}
		kv.Flags = f
	}

	consul, err := c.Client()
	if err != nil {
		c.UI.Error(err.Error())
		return 1
	}
	client := consul.KV()

	writeOpts := c.WriteOptions()

	if c.modifyIndex == "" {
		_, err := client.Put(kv, writeOpts)
		if err != nil {
			c.UI.Error(err.Error())
			return 1
		}
	} else {
		// Check-and-Set
		i, err := strconv.ParseUint(c.modifyIndex, 0, 64)
		if err != nil {
			c.UI.Error(fmt.Sprintf("Error parsing modifyIndex: %v", c.modifyIndex))
			c.UI.Error("")
			return 1
		}
		kv.ModifyIndex = i

		success, _, err := client.CAS(kv, writeOpts)
		if err != nil {
			c.UI.Error(err.Error())
			return 1
		}

		if !success {
			return 1
		}
	}

	return 0
}

func (c *KVWriteCommand) Synopsis() string {
	return "Write a value"
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"syscall"

	"github.com/cloudfoundry-incubator/garden-linux/container_daemon"
	"github.com/cloudfoundry-incubator/garden-linux/container_daemon/unix_socket"
	"github.com/cloudfoundry-incubator/garden-linux/containerizer"
	"github.com/cloudfoundry-incubator/garden-linux/containerizer/system"
	"github.com/cloudfoundry/gunk/command_runner/linux_command_runner"
)

func init() {
	runtime.LockOSThread()
}

func main() {
	libPath := flag.String("lib", "./lib", "Directory containing hooks")
	rootFsPath := flag.String("root", "", "Directory that will become root in the new mount namespace")
	runPath := flag.String("run", "./run", "Directory where server socket is placed")
	userNsFlag := flag.String("userns", "enabled", "If specified, use user namespacing")
	title := flag.String("title", "", "")
	flag.Parse()

	if *rootFsPath == "" {
		missing("--root")
	}

	binPath, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: failed to obtain absolute path: %s", err)
		os.Exit(6)
	}

	socketPath := path.Join(*runPath, "wshd.sock")

	privileged := false
	if *userNsFlag == "" || *userNsFlag == "disabled" {
		privileged = true
	}

	containerReader, hostWriter, err := os.Pipe()
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: failed to create pipe: %s", err)
		os.Exit(5)
	}

	hostReader, containerWriter, err := os.Pipe()
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: failed to create pipe: %s", err)
		os.Exit(4)
	}

	sync := &containerizer.PipeSynchronizer{
		Reader: hostReader,
		Writer: hostWriter,
	}

	listener, err := unix_socket.NewListenerFromPath(socketPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: failed to create listener: %s", err)
		os.Exit(8)
	}

	socketFile, err := listener.File()
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: failed to obtain listener file: %s", err)
		os.Exit(9)
	}

	beforeCloneInitializer := &system.Initializer{Steps: []system.StepRunner{
		&containerizer.FuncStep{
			(&container_daemon.RlimitsManager{}).Init,
		},
		&containerizer.FuncStep{system.Mount{
			Type:       system.Bind,
			Flags:      syscall.MS_BIND,
			SourcePath: filepath.Join(binPath, "initd"),
			TargetPath: filepath.Join(*rootFsPath, "sbin", "initd"),
		}.Mount},
		&containerizer.FuncStep{system.Mount{
			Type:       system.Bind,
			Data:       "remount,ro,bind",
			Flags:      syscall.MS_BIND,
			SourcePath: filepath.Join(binPath, "initd"),
			TargetPath: filepath.Join(*rootFsPath, "sbin", "initd"),
		}.Mount},
	}}

	maxUID, err := system.MaxValidUID("/proc/self/uid_map", "/proc/self/guid_map")
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: calculate max valid uid", err)
		os.Exit(9)
	}

	cz := containerizer.Containerizer{
		BeforeCloneInitializer: beforeCloneInitializer,
		InitBinPath:            path.Join(binPath, "initc"),
		InitArgs: []string{
			"--root", *rootFsPath,
			"--config", path.Join(*libPath, "../etc/config"),
			"--title", *title,
		},
		Execer: &system.NamespacingExecer{
			CommandRunner: linux_command_runner.New(),
			ExtraFiles:    []*os.File{containerReader, containerWriter, socketFile},
			Privileged:    privileged,
			MaxUID:        maxUID,
		},
		Signaller: sync,
		Waiter:    sync,
		// Temporary until we merge the hook scripts functionality in Golang
		CommandRunner: linux_command_runner.New(),
		LibPath:       *libPath,
		RootfsPath:    *rootFsPath,
	}

	err = cz.Create()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create container: %s", err)
		os.Exit(2)
	}
}

func missing(flagName string) {
	fmt.Fprintf(os.Stderr, "%s is required\n", flagName)
	flag.Usage()
	os.Exit(1)
}
<commit_msg>Fail to add redundant "fail to" in some error messages<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"syscall"

	"github.com/cloudfoundry-incubator/garden-linux/container_daemon"
	"github.com/cloudfoundry-incubator/garden-linux/container_daemon/unix_socket"
	"github.com/cloudfoundry-incubator/garden-linux/containerizer"
	"github.com/cloudfoundry-incubator/garden-linux/containerizer/system"
	"github.com/cloudfoundry/gunk/command_runner/linux_command_runner"
)

func init() {
	runtime.LockOSThread()
}

func main() {
	libPath := flag.String("lib", "./lib", "Directory containing hooks")
	rootFsPath := flag.String("root", "", "Directory that will become root in the new mount namespace")
	runPath := flag.String("run", "./run", "Directory where server socket is placed")
	userNsFlag := flag.String("userns", "enabled", "If specified, use user namespacing")
	title := flag.String("title", "", "")
	flag.Parse()

	if *rootFsPath == "" {
		missing("--root")
	}

	binPath, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: obtain absolute path: %s", err)
		os.Exit(6)
	}

	socketPath := path.Join(*runPath, "wshd.sock")

	privileged := false
	if *userNsFlag == "" || *userNsFlag == "disabled" {
		privileged = true
	}

	containerReader, hostWriter, err := os.Pipe()
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: create pipe: %s", err)
		os.Exit(5)
	}

	hostReader, containerWriter, err := os.Pipe()
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: create pipe: %s", err)
		os.Exit(4)
	}

	sync := &containerizer.PipeSynchronizer{
		Reader: hostReader,
		Writer: hostWriter,
	}

	listener, err := unix_socket.NewListenerFromPath(socketPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: create listener: %s", err)
		os.Exit(8)
	}

	socketFile, err := listener.File()
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: obtain listener file: %s", err)
		os.Exit(9)
	}

	beforeCloneInitializer := &system.Initializer{Steps: []system.StepRunner{
		&containerizer.FuncStep{
			(&container_daemon.RlimitsManager{}).Init,
		},
		&containerizer.FuncStep{system.Mount{
			Type:       system.Bind,
			Flags:      syscall.MS_BIND,
			SourcePath: filepath.Join(binPath, "initd"),
			TargetPath: filepath.Join(*rootFsPath, "sbin", "initd"),
		}.Mount},
		&containerizer.FuncStep{system.Mount{
			Type:       system.Bind,
			Data:       "remount,ro,bind",
			Flags:      syscall.MS_BIND,
			SourcePath: filepath.Join(binPath, "initd"),
			TargetPath: filepath.Join(*rootFsPath, "sbin", "initd"),
		}.Mount},
	}}

	maxUID, err := system.MaxValidUID("/proc/self/uid_map", "/proc/self/guid_map")
	if err != nil {
		fmt.Fprintf(os.Stderr, "wshd: calculate max valid uid", err)
		os.Exit(9)
	}

	cz := containerizer.Containerizer{
		BeforeCloneInitializer: beforeCloneInitializer,
		InitBinPath:            path.Join(binPath, "initc"),
		InitArgs: []string{
			"--root", *rootFsPath,
			"--config", path.Join(*libPath, "../etc/config"),
			"--title", *title,
		},
		Execer: &system.NamespacingExecer{
			CommandRunner: linux_command_runner.New(),
			ExtraFiles:    []*os.File{containerReader, containerWriter, socketFile},
			Privileged:    privileged,
			MaxUID:        maxUID,
		},
		Signaller: sync,
		Waiter:    sync,
		// Temporary until we merge the hook scripts functionality in Golang
		CommandRunner: linux_command_runner.New(),
		LibPath:       *libPath,
		RootfsPath:    *rootFsPath,
	}

	err = cz.Create()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create container: %s", err)
		os.Exit(2)
	}
}

func missing(flagName string) {
	fmt.Fprintf(os.Stderr, "%s is required\n", flagName)
	flag.Usage()
	os.Exit(1)
}
<|endoftext|>


<commit_before>package main

// Print the version.bind and hostname.bind for each
// address of NAMESERVER
import (
	"dns"
        "os"
        "fmt"
        "net"
)

func main() {
	r := new(dns.Resolver)
	qr := dns.NewQuerier(r)
        r.Servers = []string{"127.0.0.1"}
        r.Timeout = 2
        r.Attempts = 1

        if len(os.Args) != 2 {
                fmt.Printf("%s NAMESERVER\n", os.Args[0])
                os.Exit(1)
        }

        m := new(dns.Msg)
        m.Question = make([]dns.Question, 1)
        for _, a := range addresses(qr, os.Args[0]) {
                // set the resolver to query the NS directly
                r.Servers = []string{a.String()}
                m.Question[0] = dns.Question{"version.bind.", dns.TypeTXT, dns.ClassCHAOS}
                qr <- dns.DnsMsg{m, nil}
                in := <-qr
                if in.Dns != nil && in.Dns.Answer != nil {
                        fmt.Printf("%v\n", in.Dns.Answer[0])
                }
        }

        // Stop the resolver, send it a null mesg
        qr <- dns.DnsMsg{nil, nil}
        <-qr
}

func addresses(qr chan dns.DnsMsg, name string) []net.IP {
        m := new(dns.Msg)
        m.MsgHdr.Recursion_desired = true //only set this bit
        m.Question = make([]dns.Question, 1)
        var ips []net.IP

        m.Question[0] = dns.Question{os.Args[1], dns.TypeA, dns.ClassINET}
        qr <- dns.DnsMsg{m, nil}
        in := <-qr

        if in.Dns.Rcode != dns.RcodeSuccess {
                return nil
        }
        // Stuff must be in the answer section
        for _, a := range in.Dns.Answer {
                ips = append(ips, a.(*dns.RR_A).A)
        }
        m.Question[0] = dns.Question{os.Args[1], dns.TypeAAAA, dns.ClassINET}
        qr <- dns.DnsMsg{m, nil}
        in = <-qr

        if in.Dns.Rcode != dns.RcodeSuccess {
                return nil
        }
        // Stuff must be in the answer section
        for _, a := range in.Dns.Answer {
                ips = append(ips, a.(*dns.RR_AAAA).AAAA)
        }
        return ips
}
<commit_msg>chaos<commit_after>package main

// Print the version.bind and hostname.bind for each
// address of NAMESERVER
import (
	"dns"
        "os"
        "fmt"
        "net"
)

func main() {
	r := new(dns.Resolver)
	qr := dns.NewQuerier(r)
        r.Servers = []string{"127.0.0.1"}
        r.Timeout = 2
        r.Attempts = 1
        var in dns.DnsMsg

        if len(os.Args) != 2 {
                fmt.Printf("%s NAMESERVER\n", os.Args[0])
                os.Exit(1)
        }

        m := new(dns.Msg)
        m.Question = make([]dns.Question, 1)
        for _, a := range addresses(qr, os.Args[0]) {
                // set the resolver to query the NS directly
                r.Servers = []string{a.String()}
                m.Question[0] = dns.Question{"version.bind.", dns.TypeTXT, dns.ClassCHAOS}
                qr <- dns.DnsMsg{m, nil}
                in = <-qr
                if in.Dns != nil && in.Dns.Answer != nil {
                        fmt.Printf("%v\n", in.Dns.Answer[0])
                }
                m.Question[0] = dns.Question{"hostname.bind.", dns.TypeTXT, dns.ClassCHAOS}
                qr <- dns.DnsMsg{m, nil}
                in = <-qr
                if in.Dns != nil && in.Dns.Answer != nil {
                        fmt.Printf("%v\n", in.Dns.Answer[0])
                }
        }

        // Stop the resolver, send it a null mesg
        qr <- dns.DnsMsg{nil, nil}
        <-qr
}

func addresses(qr chan dns.DnsMsg, name string) []net.IP {
        m := new(dns.Msg)
        m.MsgHdr.Recursion_desired = true //only set this bit
        m.Question = make([]dns.Question, 1)
        var ips []net.IP

        m.Question[0] = dns.Question{os.Args[1], dns.TypeA, dns.ClassINET}
        qr <- dns.DnsMsg{m, nil}
        in := <-qr

        if in.Dns.Rcode != dns.RcodeSuccess {
                return nil
        }
        // Stuff must be in the answer section
        for _, a := range in.Dns.Answer {
                ips = append(ips, a.(*dns.RR_A).A)
        }
        m.Question[0] = dns.Question{os.Args[1], dns.TypeAAAA, dns.ClassINET}
        qr <- dns.DnsMsg{m, nil}
        in = <-qr

        if in.Dns.Rcode != dns.RcodeSuccess {
                return nil
        }
        // Stuff must be in the answer section
        for _, a := range in.Dns.Answer {
                ips = append(ips, a.(*dns.RR_AAAA).AAAA)
        }
        return ips
}
<|endoftext|>


<commit_before>package termite

import (
	"crypto"
	"fmt"
	"github.com/hanwen/go-fuse/fuse"
	"io"
	"log"
	"os"
	"path/filepath"
	"rand"
	"regexp"
	"strings"
	"time"
)

func init() {
	rand.Seed(time.Nanoseconds() ^ (int64(os.Getpid()) << 32))
}

func SplitPath(name string) (dir, base string) {
	dir, base = filepath.Split(name)
	dir = strings.TrimRight(dir, "/")
	return dir, base
}

func RandomBytes(n int) []byte {
	c := make([]byte, 0)
	for i := 0; i < n; i++ {
		c = append(c, byte(rand.Int31n(256)))
	}
	return c
}

func md5str(s string) string {
	h := crypto.MD5.New()
	io.WriteString(h, s)
	return string(h.Sum())
}

func md5(c []byte) string {
	h := crypto.MD5.New()
	h.Write(c)
	return string(h.Sum())
}

func Version() string {
	tVersion := "unknown"
	if version != nil {
		tVersion = *version
	}

	return fmt.Sprintf("Termite %s (go-fuse %s)",
		tVersion, fuse.Version())
}

func EscapeRegexp(s string) string {
	special := "[]()\\+*"
	for i := range special {
		c := special[i : i+1]
		s = strings.Replace(s, c, "\\"+c, -1)
	}
	return s
}

func DetectFiles(root string, cmd string) []string {
	regexp, err := regexp.Compile("(" + EscapeRegexp(root) + "/[^ ;&|\"']*)")
	if err != nil {
		log.Println("regexp error", err)
	}

	names := regexp.FindAllString(cmd, -1)
	return names
}

func IsSpace(b byte) bool {
	return b == ' ' || b == '\n' || b == '\f' || b == '\t'
}

var controlCharMap = map[byte]bool{
	'$': true,
	'>': true,
	'<': true,
	'&': true,
	'|': true,
	';': true,
	'*': true,
	'?': true,
	// TODO - [] function as wildcards, but let's slip this through
	// rather than patching up the LLVM compile.
	//	'[': true,
	//	']': true,
	'(': true,
	')': true,
	'{': true,
	'}': true,
	'~': true,
	'`': true,
	'#': true,
}

func MakeUnescape(cmd string) string {
	word := make([]byte, 0, len(cmd))

	lastSlash := false
	for _, intCh := range cmd {
		ch := byte(intCh)
		if lastSlash {
			if ch != '\n' {
				word = append(word, '\\', ch)
			}
			lastSlash = false
		} else {
			if ch == '\\' {
				lastSlash = true
			} else {
				word = append(word, ch)
			}
		}
	}

	return string(word)
}

// ParseCommand tries to parse quoting for a shell command line.  It
// will give up and return nil when it returns shell-metacharacters
// ($, ` , etc.)
func ParseCommand(cmd string) []string {
	escape := false
	squote := false
	dquote := false

	result := []string{}
	word := []byte{}
	for i, ch := range cmd {
		c := byte(ch)
		if squote {
			if c == '\'' {
				squote = false
			} else {
				word = append(word, c)
			}
			continue
		}
		if dquote {
			// TODO - not really correct; "a\nb" -> a\nb
			if escape {
				word = append(word, byte(c))
				escape = false
				continue
			}

			switch c {
			case '"':
				dquote = !dquote
			case '\\':
				escape = true
			case '$':
				return nil
			default:
				word = append(word, c)
			}
			continue
		}
		if escape {
			word = append(word, c)
			escape = false
			continue
		}
		if c == '\'' {
			squote = true
			continue
		}
		if c == '"' {
			dquote = true
			continue
		}
		if c == '\\' {
			escape = true
			continue
		}
		if controlCharMap[c] {
			return nil
		}
		if IsSpace(c) {
			if i > 0 && !IsSpace(cmd[i-1]) {
				result = append(result, string(word))
				word = []byte{}
			}
		} else {
			word = append(word, c)
		}
	}

	if len(cmd) > 0 && !IsSpace(cmd[len(cmd)-1]) {
		result = append(result, string(word))
	}
	return result
}

func HasDirPrefix(path, prefix string) bool {
	prefix = strings.TrimRight(prefix, string(filepath.Separator))
	path = strings.TrimRight(path, string(filepath.Separator))
	return path == prefix ||
		strings.HasPrefix(path, prefix+string(filepath.Separator))
}

func EncodeFileInfo(fi os.FileInfo) string {
	fi.Atime_ns = 0
	fi.Ino = 0
	fi.Dev = 0
	fi.Name = ""
	return fmt.Sprintf("%v", fi)
}

func HumanTrim(s string, l int) string {
	if len(s) < l {
		return s
	}
	trail := fmt.Sprintf(" ... (%d bytes)", len(s))
	return s[:l-len(trail)] + trail
}

func PrintStdinSliceLen(s []byte) {
	log.Printf("Copied %d bytes of stdin", len(s))
}

// Useful for debugging.
func HookedCopy(w io.Writer, r io.Reader, proc func([]byte)) os.Error {
	buf := make([]byte, 32*1024)
	for {
		n, err := r.Read(buf)
		if n > 0 && proc != nil {
			proc(buf[:n])
		}
		todo := buf[:n]
		for len(todo) > 0 {
			n, err = w.Write(todo)
			if err != nil {
				break
			}
			todo = todo[n:]
		}
		if len(todo) > 0 {
			return err
		}
		if err != nil {
			return err
		}
	}
	return nil
}

func (me *WorkResponse) String() string {
	return fmt.Sprintf("WorkResponse{exit %d, taskids %v: %v. Err: %s, Out: %s}",
		me.Exit.ExitStatus(),
		me.TaskIds,
		me.FileSet,
		HumanTrim(me.Stderr, 1024),
		HumanTrim(me.Stdout, 1024))
}
<commit_msg>Oops - commit other change too.<commit_after>package termite

import (
	"crypto"
	"fmt"
	"github.com/hanwen/go-fuse/fuse"
	"io"
	"log"
	"os"
	"path/filepath"
	"rand"
	"regexp"
	"strings"
	"time"
)

type OsFileInfo fuse.OsFileInfo
type OsFileInfos fuse.OsFileInfos

func init() {
	rand.Seed(time.Nanoseconds() ^ (int64(os.Getpid()) << 32))
}

func SplitPath(name string) (dir, base string) {
	dir, base = filepath.Split(name)
	dir = strings.TrimRight(dir, "/")
	return dir, base
}

func RandomBytes(n int) []byte {
	c := make([]byte, 0)
	for i := 0; i < n; i++ {
		c = append(c, byte(rand.Int31n(256)))
	}
	return c
}

func md5str(s string) string {
	h := crypto.MD5.New()
	io.WriteString(h, s)
	return string(h.Sum())
}

func md5(c []byte) string {
	h := crypto.MD5.New()
	h.Write(c)
	return string(h.Sum())
}

func Version() string {
	tVersion := "unknown"
	if version != nil {
		tVersion = *version
	}

	return fmt.Sprintf("Termite %s (go-fuse %s)",
		tVersion, fuse.Version())
}

func EscapeRegexp(s string) string {
	special := "[]()\\+*"
	for i := range special {
		c := special[i : i+1]
		s = strings.Replace(s, c, "\\"+c, -1)
	}
	return s
}

func DetectFiles(root string, cmd string) []string {
	regexp, err := regexp.Compile("(" + EscapeRegexp(root) + "/[^ ;&|\"']*)")
	if err != nil {
		log.Println("regexp error", err)
	}

	names := regexp.FindAllString(cmd, -1)
	return names
}

func IsSpace(b byte) bool {
	return b == ' ' || b == '\n' || b == '\f' || b == '\t'
}

var controlCharMap = map[byte]bool{
	'$': true,
	'>': true,
	'<': true,
	'&': true,
	'|': true,
	';': true,
	'*': true,
	'?': true,
	// TODO - [] function as wildcards, but let's slip this through
	// rather than patching up the LLVM compile.
	//	'[': true,
	//	']': true,
	'(': true,
	')': true,
	'{': true,
	'}': true,
	'~': true,
	'`': true,
	'#': true,
}

func MakeUnescape(cmd string) string {
	word := make([]byte, 0, len(cmd))

	lastSlash := false
	for _, intCh := range cmd {
		ch := byte(intCh)
		if lastSlash {
			if ch != '\n' {
				word = append(word, '\\', ch)
			}
			lastSlash = false
		} else {
			if ch == '\\' {
				lastSlash = true
			} else {
				word = append(word, ch)
			}
		}
	}

	return string(word)
}

// ParseCommand tries to parse quoting for a shell command line.  It
// will give up and return nil when it returns shell-metacharacters
// ($, ` , etc.)
func ParseCommand(cmd string) []string {
	escape := false
	squote := false
	dquote := false

	result := []string{}
	word := []byte{}
	for i, ch := range cmd {
		c := byte(ch)
		if squote {
			if c == '\'' {
				squote = false
			} else {
				word = append(word, c)
			}
			continue
		}
		if dquote {
			// TODO - not really correct; "a\nb" -> a\nb
			if escape {
				word = append(word, byte(c))
				escape = false
				continue
			}

			switch c {
			case '"':
				dquote = !dquote
			case '\\':
				escape = true
			case '$':
				return nil
			default:
				word = append(word, c)
			}
			continue
		}
		if escape {
			word = append(word, c)
			escape = false
			continue
		}
		if c == '\'' {
			squote = true
			continue
		}
		if c == '"' {
			dquote = true
			continue
		}
		if c == '\\' {
			escape = true
			continue
		}
		if controlCharMap[c] {
			return nil
		}
		if IsSpace(c) {
			if i > 0 && !IsSpace(cmd[i-1]) {
				result = append(result, string(word))
				word = []byte{}
			}
		} else {
			word = append(word, c)
		}
	}

	if len(cmd) > 0 && !IsSpace(cmd[len(cmd)-1]) {
		result = append(result, string(word))
	}
	return result
}

func HasDirPrefix(path, prefix string) bool {
	prefix = strings.TrimRight(prefix, string(filepath.Separator))
	path = strings.TrimRight(path, string(filepath.Separator))
	return path == prefix ||
		strings.HasPrefix(path, prefix+string(filepath.Separator))
}

func EncodeFileInfo(fi os.FileInfo) string {
	fi.Atime_ns = 0
	fi.Ino = 0
	fi.Dev = 0
	fi.Name = ""
	return fmt.Sprintf("%v", fi)
}

func HumanTrim(s string, l int) string {
	if len(s) < l {
		return s
	}
	trail := fmt.Sprintf(" ... (%d bytes)", len(s))
	return s[:l-len(trail)] + trail
}

func PrintStdinSliceLen(s []byte) {
	log.Printf("Copied %d bytes of stdin", len(s))
}

// Useful for debugging.
func HookedCopy(w io.Writer, r io.Reader, proc func([]byte)) os.Error {
	buf := make([]byte, 32*1024)
	for {
		n, err := r.Read(buf)
		if n > 0 && proc != nil {
			proc(buf[:n])
		}
		todo := buf[:n]
		for len(todo) > 0 {
			n, err = w.Write(todo)
			if err != nil {
				break
			}
			todo = todo[n:]
		}
		if len(todo) > 0 {
			return err
		}
		if err != nil {
			return err
		}
	}
	return nil
}

func (me *WorkResponse) String() string {
	return fmt.Sprintf("WorkResponse{exit %d, taskids %v: %v. Err: %s, Out: %s}",
		me.Exit.ExitStatus(),
		me.TaskIds,
		me.FileSet,
		HumanTrim(me.Stderr, 1024),
		HumanTrim(me.Stdout, 1024))
}
<|endoftext|>


<commit_before>package responseGenerator

import (
	"log"
	"strings"

	"github.com/votinginfoproject/sms-worker/civic_api"
	"github.com/votinginfoproject/sms-worker/data"
	"github.com/votinginfoproject/sms-worker/response_generator/polling_location"
	"github.com/votinginfoproject/sms-worker/responses"
	"github.com/votinginfoproject/sms-worker/users"
)

type Generator struct {
	civic    civicApi.Querier
	content  *responses.Content
	triggers map[string]map[string]string
}

func New(civic civicApi.Querier) *Generator {
	rawContent, err := data.Asset("raw/data.yml")
	if err != nil {
		log.Panic("[ERROR] Failed to load responses : ", err)
	}

	content, triggers := responses.Load(rawContent)
	return &Generator{civic, content, triggers}
}

func (r *Generator) Generate(user *users.Users, number string, message string, routine int) []string {
	userData, err := user.GetOrCreate(number)
	if err != nil {
		log.Printf("[ERROR] [%d] User store error : %s", routine, err)
		return []string{r.content.Errors.Text["en"]["generalBackend"]}
	}

	message = strings.TrimSpace(message)
	message = strings.ToLower(message)

	language := userData["language"]
	action := r.triggers[language][message]

	switch action {
	default:
		var newUser bool
		if len(userData["address"]) == 0 {
			newUser = true
		} else {
			newUser = false
		}

		res, err := r.civic.Query(message)
		if err != nil {
			log.Printf("[ERROR] [%d] Civic API failure : %s", routine, err)
			return []string{r.content.Errors.Text["en"]["generalBackend"]}
		}

		messages, success := pollingLocation.BuildMessage(res, language, newUser, r.content)
		if success == true {
			user.SetAddress(userData["phone_number"], message)
		}

		return messages
	}
}
<commit_msg>extract pollinglocation action<commit_after>package responseGenerator

import (
	"log"
	"strings"

	"github.com/votinginfoproject/sms-worker/civic_api"
	"github.com/votinginfoproject/sms-worker/data"
	"github.com/votinginfoproject/sms-worker/response_generator/polling_location"
	"github.com/votinginfoproject/sms-worker/responses"
	"github.com/votinginfoproject/sms-worker/users"
)

type Generator struct {
	civic    civicApi.Querier
	content  *responses.Content
	triggers map[string]map[string]string
}

func New(civic civicApi.Querier) *Generator {
	rawContent, err := data.Asset("raw/data.yml")
	if err != nil {
		log.Panic("[ERROR] Failed to load responses : ", err)
	}

	content, triggers := responses.Load(rawContent)
	return &Generator{civic, content, triggers}
}

func (r *Generator) Generate(user *users.Users, number string, message string, routine int) []string {
	userData, err := user.GetOrCreate(number)
	if err != nil {
		log.Printf("[ERROR] [%d] User store error : %s", routine, err)
		return []string{r.content.Errors.Text["en"]["generalBackend"]}
	}

	message = strings.TrimSpace(message)
	message = strings.ToLower(message)

	language := userData["language"]
	action := r.triggers[language][message]

	switch action {
	default:
		return r.pollingLocation(userData, user, number, message, routine)
	}
}

func (r *Generator) pollingLocation(userData map[string]string, user *users.Users, number string, message string, routine int) []string {
	var newUser bool
	if len(userData["address"]) == 0 {
		newUser = true
	} else {
		newUser = false
	}

	res, err := r.civic.Query(message)
	if err != nil {
		log.Printf("[ERROR] [%d] Civic API failure : %s", routine, err)
		return []string{r.content.Errors.Text["en"]["generalBackend"]}
	}

	messages, success := pollingLocation.BuildMessage(res, userData["language"], newUser, r.content)
	if success == true {
		user.SetAddress(userData["phone_number"], message)
	}

	return messages
}
<|endoftext|>


<commit_before>// +build go1.7

package nethttp

import (
	"context"
	"io"
	"net/http"
	"net/http/httptrace"

	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
)

type contextKey int

const (
	keyTracer contextKey = iota
)

// Transport wraps a RoundTripper. If a request is being traced with
// Tracer, Transport will inject the current span into the headers,
// and set HTTP related tags on the span.
type Transport struct {
	// The actual RoundTripper to use for the request. A nil
	// RoundTripper defaults to http.DefaultTransport.
	http.RoundTripper
}

// TraceRequest adds a ClientTracer to req, tracing the request and
// all requests caused due to redirects. When tracing requests this
// way you must also use Transport.
//
// Example:
//
//  client := &http.Client{Transport: &nethttp.Transport{}}
// 	req, err := http.NewRequest("GET", "http://google.com", nil)
// 	if err != nil {
// 		log.Fatal(err)
// 	}
// 	req = req.WithContext(opentracing.ContextWithSpan(req.Context(), parentSpan))
// 	req, ht := nethttp.TraceRequest(tracer, req)
// 	res, err := client.Do(req)
// 	if err != nil {
// 		log.Fatal(err)
// 	}
// 	res.Body.Close()
// 	ht.Finish()
func TraceRequest(tr opentracing.Tracer, req *http.Request) (*http.Request, *Tracer) {
	ht := &Tracer{tr: tr}
	ctx := httptrace.WithClientTrace(req.Context(), ht.clientTrace())
	req = req.WithContext(context.WithValue(ctx, keyTracer, ht))
	return req, ht
}

type closeTracker struct {
	io.ReadCloser
	sp opentracing.Span
}

func (c closeTracker) Close() error {
	err := c.ReadCloser.Close()
	c.sp.LogEvent("Closed body")
	c.sp.Finish()
	return err
}

// RoundTrip implements the RoundTripper interface.
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
	rt := t.RoundTripper
	if rt == nil {
		rt = http.DefaultTransport
	}
	tracer, ok := req.Context().Value(keyTracer).(*Tracer)
	if !ok {
		return rt.RoundTrip(req)
	}

	tracer.start(req)

	ext.HTTPMethod.Set(tracer.sp, req.Method)
	ext.HTTPUrl.Set(tracer.sp, req.URL.String())

	carrier := opentracing.HTTPHeadersCarrier(req.Header)
	tracer.sp.Tracer().Inject(tracer.sp.Context(), opentracing.HTTPHeaders, carrier)
	resp, err := rt.RoundTrip(req)

	if err != nil {
		tracer.sp.Finish()
		return resp, err
	}
	ext.HTTPStatusCode.Set(tracer.sp, uint16(resp.StatusCode))
	if req.Method == "HEAD" {
		tracer.sp.Finish()
	} else {
		resp.Body = closeTracker{resp.Body, tracer.sp}
	}
	return resp, nil
}

type Tracer struct {
	tr   opentracing.Tracer
	root opentracing.Span
	sp   opentracing.Span
}

func (h *Tracer) start(req *http.Request) opentracing.Span {
	if h.root == nil {
		parent := opentracing.SpanFromContext(req.Context())
		var spanctx opentracing.SpanContext
		if parent != nil {
			spanctx = parent.Context()
		}
		root := h.tr.StartSpan("HTTP", opentracing.ChildOf(spanctx))
		ext.SpanKindRPCClient.Set(root)
		h.root = root
	}

	ctx := h.root.Context()
	h.sp = h.tr.StartSpan("HTTP "+req.Method, opentracing.ChildOf(ctx))
	ext.SpanKindRPCClient.Set(h.sp)
	ext.Component.Set(h.sp, "net/http")

	return h.sp
}

// Finish finishes the span of the traced request.
func (h *Tracer) Finish() {
	if h.root != nil {
		h.root.Finish()
	}
}

// Span returns the root span of the traced request. This function
// should only be called after the request has been executed.
func (h *Tracer) Span() opentracing.Span {
	return h.root
}

func (h *Tracer) clientTrace() *httptrace.ClientTrace {
	return &httptrace.ClientTrace{
		GetConn:              h.getConn,
		GotConn:              h.gotConn,
		PutIdleConn:          h.putIdleConn,
		GotFirstResponseByte: h.gotFirstResponseByte,
		Got100Continue:       h.got100Continue,
		DNSStart:             h.dnsStart,
		DNSDone:              h.dnsDone,
		ConnectStart:         h.connectStart,
		ConnectDone:          h.connectDone,
		WroteHeaders:         h.wroteHeaders,
		Wait100Continue:      h.wait100Continue,
		WroteRequest:         h.wroteRequest,
	}
}

func (h *Tracer) getConn(hostPort string) {
	ext.HTTPUrl.Set(h.sp, hostPort)
	h.sp.LogEvent("Get conn")
}

func (h *Tracer) gotConn(info httptrace.GotConnInfo) {
	h.sp.SetTag("net/http.reused", info.Reused)
	h.sp.SetTag("net/http.was_idle", info.WasIdle)
	h.sp.LogEvent("Got conn")
}

func (h *Tracer) putIdleConn(error) {
	h.sp.LogEvent("Put idle conn")
}

func (h *Tracer) gotFirstResponseByte() {
	h.sp.LogEvent("Got first response byte")
}

func (h *Tracer) got100Continue() {
	h.sp.LogEvent("Got 100 continue")
}

func (h *Tracer) dnsStart(info httptrace.DNSStartInfo) {
	h.sp.LogEventWithPayload("DNS start", info.Host)
}

func (h *Tracer) dnsDone(httptrace.DNSDoneInfo) {
	h.sp.LogEvent("DNS done")
}

func (h *Tracer) connectStart(network, addr string) {
	h.sp.LogEventWithPayload("Connect start", network+":"+addr)
}

func (h *Tracer) connectDone(network, addr string, err error) {
	h.sp.LogEventWithPayload("Connect done", network+":"+addr)
}

func (h *Tracer) wroteHeaders() {
	h.sp.LogEvent("Wrote headers")
}

func (h *Tracer) wait100Continue() {
	h.sp.LogEvent("Wait 100 continue")
}

func (h *Tracer) wroteRequest(info httptrace.WroteRequestInfo) {
	if info.Err != nil {
		ext.Error.Set(h.sp, true)
	}
	h.sp.LogEvent("Wrote request")
}
<commit_msg>nethttp: do not mark root span as RPC, rename to "HTTP Client"<commit_after>// +build go1.7

package nethttp

import (
	"context"
	"io"
	"net/http"
	"net/http/httptrace"

	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
)

type contextKey int

const (
	keyTracer contextKey = iota
)

// Transport wraps a RoundTripper. If a request is being traced with
// Tracer, Transport will inject the current span into the headers,
// and set HTTP related tags on the span.
type Transport struct {
	// The actual RoundTripper to use for the request. A nil
	// RoundTripper defaults to http.DefaultTransport.
	http.RoundTripper
}

// TraceRequest adds a ClientTracer to req, tracing the request and
// all requests caused due to redirects. When tracing requests this
// way you must also use Transport.
//
// Example:
//
//  client := &http.Client{Transport: &nethttp.Transport{}}
// 	req, err := http.NewRequest("GET", "http://google.com", nil)
// 	if err != nil {
// 		log.Fatal(err)
// 	}
// 	req = req.WithContext(opentracing.ContextWithSpan(req.Context(), parentSpan))
// 	req, ht := nethttp.TraceRequest(tracer, req)
// 	res, err := client.Do(req)
// 	if err != nil {
// 		log.Fatal(err)
// 	}
// 	res.Body.Close()
// 	ht.Finish()
func TraceRequest(tr opentracing.Tracer, req *http.Request) (*http.Request, *Tracer) {
	ht := &Tracer{tr: tr}
	ctx := httptrace.WithClientTrace(req.Context(), ht.clientTrace())
	req = req.WithContext(context.WithValue(ctx, keyTracer, ht))
	return req, ht
}

type closeTracker struct {
	io.ReadCloser
	sp opentracing.Span
}

func (c closeTracker) Close() error {
	err := c.ReadCloser.Close()
	c.sp.LogEvent("Closed body")
	c.sp.Finish()
	return err
}

// RoundTrip implements the RoundTripper interface.
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
	rt := t.RoundTripper
	if rt == nil {
		rt = http.DefaultTransport
	}
	tracer, ok := req.Context().Value(keyTracer).(*Tracer)
	if !ok {
		return rt.RoundTrip(req)
	}

	tracer.start(req)

	ext.HTTPMethod.Set(tracer.sp, req.Method)
	ext.HTTPUrl.Set(tracer.sp, req.URL.String())

	carrier := opentracing.HTTPHeadersCarrier(req.Header)
	tracer.sp.Tracer().Inject(tracer.sp.Context(), opentracing.HTTPHeaders, carrier)
	resp, err := rt.RoundTrip(req)

	if err != nil {
		tracer.sp.Finish()
		return resp, err
	}
	ext.HTTPStatusCode.Set(tracer.sp, uint16(resp.StatusCode))
	if req.Method == "HEAD" {
		tracer.sp.Finish()
	} else {
		resp.Body = closeTracker{resp.Body, tracer.sp}
	}
	return resp, nil
}

type Tracer struct {
	tr   opentracing.Tracer
	root opentracing.Span
	sp   opentracing.Span
}

func (h *Tracer) start(req *http.Request) opentracing.Span {
	if h.root == nil {
		parent := opentracing.SpanFromContext(req.Context())
		var spanctx opentracing.SpanContext
		if parent != nil {
			spanctx = parent.Context()
		}
		root := h.tr.StartSpan("HTTP Client", opentracing.ChildOf(spanctx))
		h.root = root
	}

	ctx := h.root.Context()
	h.sp = h.tr.StartSpan("HTTP "+req.Method, opentracing.ChildOf(ctx))
	ext.SpanKindRPCClient.Set(h.sp)
	ext.Component.Set(h.sp, "net/http")

	return h.sp
}

// Finish finishes the span of the traced request.
func (h *Tracer) Finish() {
	if h.root != nil {
		h.root.Finish()
	}
}

// Span returns the root span of the traced request. This function
// should only be called after the request has been executed.
func (h *Tracer) Span() opentracing.Span {
	return h.root
}

func (h *Tracer) clientTrace() *httptrace.ClientTrace {
	return &httptrace.ClientTrace{
		GetConn:              h.getConn,
		GotConn:              h.gotConn,
		PutIdleConn:          h.putIdleConn,
		GotFirstResponseByte: h.gotFirstResponseByte,
		Got100Continue:       h.got100Continue,
		DNSStart:             h.dnsStart,
		DNSDone:              h.dnsDone,
		ConnectStart:         h.connectStart,
		ConnectDone:          h.connectDone,
		WroteHeaders:         h.wroteHeaders,
		Wait100Continue:      h.wait100Continue,
		WroteRequest:         h.wroteRequest,
	}
}

func (h *Tracer) getConn(hostPort string) {
	ext.HTTPUrl.Set(h.sp, hostPort)
	h.sp.LogEvent("Get conn")
}

func (h *Tracer) gotConn(info httptrace.GotConnInfo) {
	h.sp.SetTag("net/http.reused", info.Reused)
	h.sp.SetTag("net/http.was_idle", info.WasIdle)
	h.sp.LogEvent("Got conn")
}

func (h *Tracer) putIdleConn(error) {
	h.sp.LogEvent("Put idle conn")
}

func (h *Tracer) gotFirstResponseByte() {
	h.sp.LogEvent("Got first response byte")
}

func (h *Tracer) got100Continue() {
	h.sp.LogEvent("Got 100 continue")
}

func (h *Tracer) dnsStart(info httptrace.DNSStartInfo) {
	h.sp.LogEventWithPayload("DNS start", info.Host)
}

func (h *Tracer) dnsDone(httptrace.DNSDoneInfo) {
	h.sp.LogEvent("DNS done")
}

func (h *Tracer) connectStart(network, addr string) {
	h.sp.LogEventWithPayload("Connect start", network+":"+addr)
}

func (h *Tracer) connectDone(network, addr string, err error) {
	h.sp.LogEventWithPayload("Connect done", network+":"+addr)
}

func (h *Tracer) wroteHeaders() {
	h.sp.LogEvent("Wrote headers")
}

func (h *Tracer) wait100Continue() {
	h.sp.LogEvent("Wait 100 continue")
}

func (h *Tracer) wroteRequest(info httptrace.WroteRequestInfo) {
	if info.Err != nil {
		ext.Error.Set(h.sp, true)
	}
	h.sp.LogEvent("Wrote request")
}
<|endoftext|>


<commit_before>package master

import (
	"github.com/loadimpact/speedboat/message"
	"sync"
)

type Processor interface {
	Process(msg message.Message) <-chan message.Message
}

func Process(processors []Processor, msg message.Message) <-chan message.Message {
	ch := make(chan message.Message)
	wg := sync.WaitGroup{}

	// Dispatch processing across a number of processors, using a WaitGroup to record the
	// completion of each one
	for _, processor := range processors {
		wg.Add(1)
		go func() {
			// No matter what happens, mark this processor as done once this goroutine returns
			defer wg.Done()

			// Forward resulting messages from the processor
			for m := range processor.Process(msg) {
				ch <- m
			}
		}()
	}

	// Wait on the WaitGroup before closing the channel, signalling that we're done here
	go func() {
		wg.Wait()
		close(ch)
	}()

	return ch
}
<commit_msg>Don't just run the last processors repeatedly D:<commit_after>package master

import (
	"github.com/loadimpact/speedboat/message"
	"sync"
)

type Processor interface {
	Process(msg message.Message) <-chan message.Message
}

func Process(processors []Processor, msg message.Message) <-chan message.Message {
	ch := make(chan message.Message)
	wg := sync.WaitGroup{}

	// Dispatch processing across a number of processors, using a WaitGroup to record the
	// completion of each one
	for _, processor := range processors {
		processor := processor
		wg.Add(1)
		go func() {
			// No matter what happens, mark this processor as done once this goroutine returns
			defer wg.Done()

			// Forward resulting messages from the processor
			for m := range processor.Process(msg) {
				ch <- m
			}
		}()
	}

	// Wait on the WaitGroup before closing the channel, signalling that we're done here
	go func() {
		wg.Wait()
		close(ch)
	}()

	return ch
}
<|endoftext|>


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

// The implementation borrows heavily from SmallLRUCache (originally by Nathan
// Schrenk). The object maintains a doubly-linked list of elements in the
// When an element is accessed it is promoted to the head of the list, and when
// space is needed the element at the tail of the list (the least recently used
// element) is evicted.
package cache

import (
	"container/list"
	"fmt"
	"sync"
	"time"
)

type LRUCache struct {
	mu sync.Mutex

	// list & table of *entry objects
	list  *list.List
	table map[string]*list.Element

	// Our current size, in bytes. Obviously a gross simplification and low-grade
	// approximation.
	size int64

	// How many bytes we are limiting the cache to.
	capacity int64
}

// Values that go into LRUCache need to satisfy this interface.
type Value interface {
	Size() int
}

type Item struct {
	Key   string
	Value Value
}

type entry struct {
	key           string
	value         Value
	size          int64
	time_accessed time.Time
}

func NewLRUCache(capacity int64) *LRUCache {
	return &LRUCache{
		list:     list.New(),
		table:    make(map[string]*list.Element),
		capacity: capacity,
	}
}

func (lru *LRUCache) Get(key string) (v Value, ok bool) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	element := lru.table[key]
	if element == nil {
		return nil, false
	}
	lru.moveToFront(element)
	return element.Value.(*entry).value, true
}

func (lru *LRUCache) Set(key string, value Value) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	if element := lru.table[key]; element != nil {
		lru.updateInplace(element, value)
	} else {
		lru.addNew(key, value)
	}
}

func (lru *LRUCache) SetIfAbsent(key string, value Value) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	if element := lru.table[key]; element != nil {
		lru.moveToFront(element)
	} else {
		lru.addNew(key, value)
	}
}

func (lru *LRUCache) Delete(key string) bool {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	element := lru.table[key]
	if element == nil {
		return false
	}

	lru.list.Remove(element)
	delete(lru.table, key)
	lru.size -= element.Value.(*entry).size
	return true
}

func (lru *LRUCache) Clear() {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	lru.list.Init()
	lru.table = make(map[string]*list.Element)
	lru.size = 0
}

func (lru *LRUCache) SetCapacity(capacity int64) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	lru.capacity = capacity
	lru.checkCapacity()
}

func (lru *LRUCache) Stats() (length, size, capacity int64, oldest time.Time) {
	lru.mu.Lock()
	defer lru.mu.Unlock()
	if lastElem := lru.list.Back(); lastElem != nil {
		oldest = lastElem.Value.(*entry).time_accessed
	}
	return int64(lru.list.Len()), lru.size, lru.capacity, oldest
}

func (lru *LRUCache) StatsJSON() string {
	if lru == nil {
		return "{}"
	}
	l, s, c, o := lru.Stats()
	return fmt.Sprintf("{\"Length\": %v, \"Size\": %v, \"Capacity\": %v, \"OldestAccess\": \"%v\"}", l, s, c, o)
}

func (lru *LRUCache) Length() int64 {
	lru.mu.Lock()
	defer lru.mu.Unlock()
	return int64(lru.list.Len())
}

func (lru *LRUCache) Size() int64 {
	lru.mu.Lock()
	defer lru.mu.Unlock()
	return lru.size
}

func (lru *LRUCache) Capacity() int64 {
	lru.mu.Lock()
	defer lru.mu.Unlock()
	return lru.capacity
}

func (lru *LRUCache) Oldest() (oldest time.Time) {
	lru.mu.Lock()
	defer lru.mu.Unlock()
	if lastElem := lru.list.Back(); lastElem != nil {
		oldest = lastElem.Value.(*entry).time_accessed
	}
	return
}

func (lru *LRUCache) Keys() []string {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	keys := make([]string, 0, lru.list.Len())
	for e := lru.list.Front(); e != nil; e = e.Next() {
		keys = append(keys, e.Value.(*entry).key)
	}
	return keys
}

func (lru *LRUCache) Items() []Item {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	items := make([]Item, 0, lru.list.Len())
	for e := lru.list.Front(); e != nil; e = e.Next() {
		v := e.Value.(*entry)
		items = append(items, Item{Key: v.key, Value: v.value})
	}
	return items
}

func (lru *LRUCache) updateInplace(element *list.Element, value Value) {
	valueSize := int64(value.Size())
	sizeDiff := valueSize - element.Value.(*entry).size
	element.Value.(*entry).value = value
	element.Value.(*entry).size = valueSize
	lru.size += sizeDiff
	lru.moveToFront(element)
	lru.checkCapacity()
}

func (lru *LRUCache) moveToFront(element *list.Element) {
	lru.list.MoveToFront(element)
	element.Value.(*entry).time_accessed = time.Now()
}

func (lru *LRUCache) addNew(key string, value Value) {
	newEntry := &entry{key, value, int64(value.Size()), time.Now()}
	element := lru.list.PushFront(newEntry)
	lru.table[key] = element
	lru.size += newEntry.size
	lru.checkCapacity()
}

func (lru *LRUCache) checkCapacity() {
	// Partially duplicated from Delete
	for lru.size > lru.capacity {
		delElem := lru.list.Back()
		delValue := delElem.Value.(*entry)
		lru.list.Remove(delElem)
		delete(lru.table, delValue.key)
		lru.size -= delValue.size
	}
}
<commit_msg>Adding comments to LRU cache.<commit_after>// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// cache implements a LRU cache. The implementation borrows heavily
// from SmallLRUCache (originally by Nathan Schrenk). The object
// maintains a doubly-linked list of elements.  When an element is
// accessed it is promoted to the head of the list, and when space is
// needed the element at the tail of the list (the least recently used
// element) is evicted.
package cache

import (
	"container/list"
	"fmt"
	"sync"
	"time"
)

// LRUCache is a typical LRU cache implementation.  If the cache
// reaches the capacity, the least recently used item is deleted from
// the cache. Note the capacity is not the number of items, but the
// total sum of the Size() of each item.
type LRUCache struct {
	mu sync.Mutex

	// list & table of *entry objects
	list  *list.List
	table map[string]*list.Element

	// Our current size. Obviously a gross simplification and
	// low-grade approximation.
	size int64

	// How much we are limiting the cache to.
	capacity int64
}

// Value is the interface values that go into LRUCache need to satisfy
type Value interface {
	// Size returns how big this value is.
	Size() int
}

// Item is what is stored in the cache
type Item struct {
	Key   string
	Value Value
}

type entry struct {
	key           string
	value         Value
	size          int64
	time_accessed time.Time
}

// NewLRUCache creates a new empty cache with the given capacity.
func NewLRUCache(capacity int64) *LRUCache {
	return &LRUCache{
		list:     list.New(),
		table:    make(map[string]*list.Element),
		capacity: capacity,
	}
}

// Get returns a value from the cache, and marks the entry as most
// recently used.
func (lru *LRUCache) Get(key string) (v Value, ok bool) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	element := lru.table[key]
	if element == nil {
		return nil, false
	}
	lru.moveToFront(element)
	return element.Value.(*entry).value, true
}

// Set sets a value in the cache.
func (lru *LRUCache) Set(key string, value Value) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	if element := lru.table[key]; element != nil {
		lru.updateInplace(element, value)
	} else {
		lru.addNew(key, value)
	}
}

// SetIfAbsent will set the value in the cache if not present. If the
// value exists in the cache, we don't set it.
func (lru *LRUCache) SetIfAbsent(key string, value Value) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	if element := lru.table[key]; element != nil {
		lru.moveToFront(element)
	} else {
		lru.addNew(key, value)
	}
}

// Delete removes an entry from the cache, and returns if the entry existed.
func (lru *LRUCache) Delete(key string) bool {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	element := lru.table[key]
	if element == nil {
		return false
	}

	lru.list.Remove(element)
	delete(lru.table, key)
	lru.size -= element.Value.(*entry).size
	return true
}

// Clear will clear the entire cache.
func (lru *LRUCache) Clear() {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	lru.list.Init()
	lru.table = make(map[string]*list.Element)
	lru.size = 0
}

// SetCapacity will set the capacity of the cache. If the capacity is
// smaller, and the current cache size exceed that capacity, the cache
// will be shrank.
func (lru *LRUCache) SetCapacity(capacity int64) {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	lru.capacity = capacity
	lru.checkCapacity()
}

// Stats returns a few stats on the cache.
func (lru *LRUCache) Stats() (length, size, capacity int64, oldest time.Time) {
	lru.mu.Lock()
	defer lru.mu.Unlock()
	if lastElem := lru.list.Back(); lastElem != nil {
		oldest = lastElem.Value.(*entry).time_accessed
	}
	return int64(lru.list.Len()), lru.size, lru.capacity, oldest
}

// StatsJSON returns stats as a JSON object in a string.
func (lru *LRUCache) StatsJSON() string {
	if lru == nil {
		return "{}"
	}
	l, s, c, o := lru.Stats()
	return fmt.Sprintf("{\"Length\": %v, \"Size\": %v, \"Capacity\": %v, \"OldestAccess\": \"%v\"}", l, s, c, o)
}

// Length returns how many elements are in the cache
func (lru *LRUCache) Length() int64 {
	lru.mu.Lock()
	defer lru.mu.Unlock()
	return int64(lru.list.Len())
}

// Size returns the sum of the objects' Size() method.
func (lru *LRUCache) Size() int64 {
	lru.mu.Lock()
	defer lru.mu.Unlock()
	return lru.size
}

// Capacity returns the cache maximum capacity.
func (lru *LRUCache) Capacity() int64 {
	lru.mu.Lock()
	defer lru.mu.Unlock()
	return lru.capacity
}

// Oldest returns the insertion time of the oldest element in the cache,
// or a IsZero() time if cache is empty.
func (lru *LRUCache) Oldest() (oldest time.Time) {
	lru.mu.Lock()
	defer lru.mu.Unlock()
	if lastElem := lru.list.Back(); lastElem != nil {
		oldest = lastElem.Value.(*entry).time_accessed
	}
	return
}

// Keys returns all the keys for the cache, ordered from most recently
// used to last recently used.
func (lru *LRUCache) Keys() []string {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	keys := make([]string, 0, lru.list.Len())
	for e := lru.list.Front(); e != nil; e = e.Next() {
		keys = append(keys, e.Value.(*entry).key)
	}
	return keys
}

// Items returns all the values for the cache, ordered from most recently
// used to last recently used.
func (lru *LRUCache) Items() []Item {
	lru.mu.Lock()
	defer lru.mu.Unlock()

	items := make([]Item, 0, lru.list.Len())
	for e := lru.list.Front(); e != nil; e = e.Next() {
		v := e.Value.(*entry)
		items = append(items, Item{Key: v.key, Value: v.value})
	}
	return items
}

func (lru *LRUCache) updateInplace(element *list.Element, value Value) {
	valueSize := int64(value.Size())
	sizeDiff := valueSize - element.Value.(*entry).size
	element.Value.(*entry).value = value
	element.Value.(*entry).size = valueSize
	lru.size += sizeDiff
	lru.moveToFront(element)
	lru.checkCapacity()
}

func (lru *LRUCache) moveToFront(element *list.Element) {
	lru.list.MoveToFront(element)
	element.Value.(*entry).time_accessed = time.Now()
}

func (lru *LRUCache) addNew(key string, value Value) {
	newEntry := &entry{key, value, int64(value.Size()), time.Now()}
	element := lru.list.PushFront(newEntry)
	lru.table[key] = element
	lru.size += newEntry.size
	lru.checkCapacity()
}

func (lru *LRUCache) checkCapacity() {
	// Partially duplicated from Delete
	for lru.size > lru.capacity {
		delElem := lru.list.Back()
		delValue := delElem.Value.(*entry)
		lru.list.Remove(delElem)
		delete(lru.table, delValue.key)
		lru.size -= delValue.size
	}
}
<|endoftext|>


<commit_before>package libkb

import (
	"os"
	"runtime"
	"time"

	keybase1 "github.com/keybase/client/protocol/go"
)

const (
	DevelServerURI      = "http://localhost:3000"
	ProductionServerURI = "https://keybase.io"
)

var ServerURI = DevelServerURI

const (
	ConfigFile  = "config.json"
	SessionFile = "session.json"
	DBFile      = "keybase.leveldb"
	SocketFile  = "keybased.sock"
	PIDFile     = "keybased.pid"

	SecretKeyringTemplate = "secretkeys.%u.mpack"

	APIVersion       = "1.0"
	APIURIPathPrefix = "/_/api/" + APIVersion
	DaemonPort       = 40933
	GoClientID       = "keybase.io go client"
	IdentifyAs       = GoClientID + " v" + Version + " " + runtime.GOOS
)

var UserAgent = "Keybase-Go-CLI/" + Version + " (" + runtime.Version() + " on " + runtime.GOOS + ")"

const (
	PermFile          os.FileMode = 0600
	PermDir           os.FileMode = 0700
	UmaskablePermFile os.FileMode = 0666
)

const (
	UserCacheSize        = 0x1000
	PGPFingerprintHexLen = 40

	ProofCacheSize      = 0x1000
	ProofCacheLongDur   = 6 * time.Hour
	ProofCacheMediumDur = 30 * time.Minute
	ProofCacheShortDur  = 1 * time.Minute

	SigShortIDBytes = 27
)

var MerkleProdKIDs = []string{
	"010159baae6c7d43c66adf8fb7bb2b8b4cbe408c062cfc369e693ccb18f85631dbcd0a",
}
var MerkleTestKIDs = []string{
	"0101be58b6c82db64f6ccabb05088db443c69f87d5d48857d709ed6f73948dabe67d0a",
}

const (
	KeybaseKIDV1       = 1 // Uses SHA-256
	KeybaseSignatureV1 = 1

	SigExpireIn       = 24 * 60 * 60 * 365 * 10 // 10 years
	NaclEdDSAExpireIn = 24 * 60 * 60 * 365 * 3  // 3 years
	NaclDHExpireIn    = 24 * 60 * 60 * 365 * 3  // 3 years
	AuthExpireIn      = 24 * 60 * 60 * 365      // 1 year
	KeyExpireIn       = 24 * 60 * 60 * 365 * 8  // 8 years
	SubkeyExpireIn    = 24 * 60 * 60 * 365 * 4  // 4 years
)

// Status codes.  This list should match keybase/lib/constants.iced.
const (
	SCOk                     = 0
	SCLoginRequired          = 201
	SCBadSession             = 202
	SCBadLoginPassword       = 204
	SCNotFound               = 205
	SCGeneric                = 218
	SCAlreadyLoggedIn        = 235
	SCCanceled               = 237
	SCBadSignupUsernameTaken = 701
	SCKeyNotFound            = 901
	SCKeyInUse               = 907
	SCKeyBadGen              = 913
	SCKeyNoSecret            = 914
	SCKeyNoActive            = 915
	SCBadTrackSession        = 1301
	SCStreamExists           = 1501
	SCStreamNotFound         = 1502
	SCStreamWrongKind        = 1503
	SCStreamEOF              = 1504
	SCAPINetworkError        = 1601
	SCTimeout                = 1602
	SCProofError             = 1701
	SCIdentificationExpired  = 1702
)

const (
	IDSuffixKID = 0x0a
)

const (
	MerkleTreeNode = 1
	MerkleTreeLeaf = 2
)

const (
	SibkeyType = "sibkey"
	SubkeyType = "subkey"
	EldestType = "eldest"
)

const (
	SigTypeNone           = 0
	SigTypeSelfSig        = 1
	SigTypeRemoteProof    = 2
	SigTypeTrack          = 3
	SigTypeUntrack        = 4
	SigTypeRevoke         = 5
	SigTypeCryptocurrency = 6
	SigTypeAnnouncement   = 7
)

type KeyType int

const (
	KeyTypeNone                  KeyType = 0
	KeyTypeOpenPGPPublic                 = 1
	KeyTypeP3skbPrivate                  = 2
	KeyTypeKbNaclEddsa                   = 3
	KeyTypeKbNaclDH                      = 4
	KeyTypeKbNaclEddsaServerHalf         = 5
	KeyTypeKbNaclDHServerHalf            = 6
)

const (
	DeviceStatusNone    = 0
	DeviceStatusActive  = 1
	DeviceStatusDefunct = 2
)

// these strings need to match the keys in
// keybase/lib_public/public_constants.iced ->
// public_constants.device.type
const (
	DeviceTypeDesktop = "desktop"
	DeviceTypeMobile  = "mobile"
	DeviceTypeWeb     = "web"
	DeviceTypePaper   = "backup"
)

const DownloadURL = "https://keybase.io/download"

var PGPVersion = "Keybase Go " + Version + " (" + runtime.GOOS + ")"

var PGPArmorHeaders = map[string]string{
	"Version": PGPVersion,
	"Comment": DownloadURL,
}

var RemoteServiceTypes = map[string]keybase1.ProofType{
	"keybase":    keybase1.ProofType_KEYBASE,
	"twitter":    keybase1.ProofType_TWITTER,
	"github":     keybase1.ProofType_GITHUB,
	"reddit":     keybase1.ProofType_REDDIT,
	"coinbase":   keybase1.ProofType_COINBASE,
	"hackernews": keybase1.ProofType_HACKERNEWS,
	"https":      keybase1.ProofType_GENERIC_WEB_SITE,
	"http":       keybase1.ProofType_GENERIC_WEB_SITE,
	"dns":        keybase1.ProofType_DNS,
	"rooter":     keybase1.ProofType_ROOTER,
}

var RemoteServiceOrder = []keybase1.ProofType{
	keybase1.ProofType_KEYBASE,
	keybase1.ProofType_TWITTER,
	keybase1.ProofType_GITHUB,
	keybase1.ProofType_REDDIT,
	keybase1.ProofType_COINBASE,
	keybase1.ProofType_HACKERNEWS,
	keybase1.ProofType_GENERIC_WEB_SITE,
	keybase1.ProofType_ROOTER,
}

const CanonicalHost = "keybase.io"

const (
	HTTPDefaultTimeout = 10 * time.Second
)

// Packet tags for OpenPGP and also Keybase packets
const (
	KeybasePacketV1 = 1
	TagP3skb        = 513
	TagSignature    = 514
	TagEncryption   = 515
)

const (
	KIDPGPBase    AlgoType = 0x00
	KIDPGPRsa              = 0x1
	KIDPGPElgamal          = 0x10
	KIDPGPDsa              = 0x11
	KIDPGPEcdh             = 0x12
	KIDPGPEcdsa            = 0x13
	KIDNaclEddsa           = 0x20
	KIDNaclDH              = 0x21
)

// OpenPGP hash IDs, taken from http://tools.ietf.org/html/rfc4880#section-9.4
const (
	HashPGPMd5       = 1
	HashPGPSha1      = 2
	HashPGPRipemd160 = 3
	HashPGPSha256    = 8
	HashPGPSha384    = 9
	HashPGPSha512    = 10
	HashPGPSha224    = 11
)

const (
	SigKbEddsa = KIDNaclEddsa
)

const (
	ServerUpdateLag = time.Minute
)

// key_revocation_types
const (
	RevSimpleDelete = 0
	RevFull         = 1
	RevDated        = 2
)

type KeyStatus int

const (
	KeyUncancelled KeyStatus = iota
	KeyRevoked
	KeyDeleted
	KeySuperseded
)

type KeyRole int

const (
	DLGNone KeyRole = iota
	DLGSibkey
	DLGSubkey
)

const (
	KexScryptCost       = 32768
	KexScryptR          = 8
	KexScryptP          = 1
	KexScryptKeylen     = 32
	KexSessionIDEntropy = 65 // kex doc specifies 65 bits of entropy
)

const (
	PaperKeyScryptCost    = 32768
	PaperKeyScryptR       = 8
	PaperKeyScryptP       = 1
	PaperKeyScryptKeylen  = 128
	PaperKeyPhraseEntropy = 144
	PaperKeyVersion       = 0
)

const UserSummaryLimit = 500 // max number of user summaries in one request
<commit_msg>Fresh constants from the backend<commit_after>package libkb

import (
	"os"
	"runtime"
	"time"

	keybase1 "github.com/keybase/client/protocol/go"
)

const (
	DevelServerURI      = "http://localhost:3000"
	ProductionServerURI = "https://keybase.io"
)

var ServerURI = DevelServerURI

const (
	ConfigFile  = "config.json"
	SessionFile = "session.json"
	DBFile      = "keybase.leveldb"
	SocketFile  = "keybased.sock"
	PIDFile     = "keybased.pid"

	SecretKeyringTemplate = "secretkeys.%u.mpack"

	APIVersion       = "1.0"
	APIURIPathPrefix = "/_/api/" + APIVersion
	DaemonPort       = 40933
	GoClientID       = "keybase.io go client"
	IdentifyAs       = GoClientID + " v" + Version + " " + runtime.GOOS
)

var UserAgent = "Keybase-Go-CLI/" + Version + " (" + runtime.Version() + " on " + runtime.GOOS + ")"

const (
	PermFile          os.FileMode = 0600
	PermDir           os.FileMode = 0700
	UmaskablePermFile os.FileMode = 0666
)

const (
	UserCacheSize        = 0x1000
	PGPFingerprintHexLen = 40

	ProofCacheSize      = 0x1000
	ProofCacheLongDur   = 6 * time.Hour
	ProofCacheMediumDur = 30 * time.Minute
	ProofCacheShortDur  = 1 * time.Minute

	SigShortIDBytes = 27
)

var MerkleProdKIDs = []string{
	"010159baae6c7d43c66adf8fb7bb2b8b4cbe408c062cfc369e693ccb18f85631dbcd0a",
}
var MerkleTestKIDs = []string{
	"0101be58b6c82db64f6ccabb05088db443c69f87d5d48857d709ed6f73948dabe67d0a",
}

const (
	KeybaseKIDV1       = 1 // Uses SHA-256
	KeybaseSignatureV1 = 1

	SigExpireIn       = 24 * 60 * 60 * 365 * 10 // 10 years
	NaclEdDSAExpireIn = 24 * 60 * 60 * 365 * 3  // 3 years
	NaclDHExpireIn    = 24 * 60 * 60 * 365 * 3  // 3 years
	AuthExpireIn      = 24 * 60 * 60 * 365      // 1 year
	KeyExpireIn       = 24 * 60 * 60 * 365 * 8  // 8 years
	SubkeyExpireIn    = 24 * 60 * 60 * 365 * 4  // 4 years
)

// Status codes.  This list should match keybase/lib/constants.iced.
const (
	SCOk                     = 0
	SCLoginRequired          = 201
	SCBadSession             = 202
	SCBadLoginPassword       = 204
	SCNotFound               = 205
	SCGeneric                = 218
	SCAlreadyLoggedIn        = 235
	SCCanceled               = 237
	SCBadSignupUsernameTaken = 701
	SCKeyNotFound            = 901
	SCKeyInUse               = 907
	SCKeyBadGen              = 913
	SCKeyNoSecret            = 914
	SCKeyBadUIDs             = 915
	SCKeyNoActive            = 916
	SCKeyNoSig               = 917
	SCKeyBadSig              = 918
	SCKeyBadEldest           = 919
	SCKeyNoEldest            = 920
	SCKeyDuplicateUpdate     = 921
	SCBadTrackSession        = 1301
	SCStreamExists           = 1501
	SCStreamNotFound         = 1502
	SCStreamWrongKind        = 1503
	SCStreamEOF              = 1504
	SCAPINetworkError        = 1601
	SCTimeout                = 1602
	SCProofError             = 1701
	SCIdentificationExpired  = 1702
)

const (
	IDSuffixKID = 0x0a
)

const (
	MerkleTreeNode = 1
	MerkleTreeLeaf = 2
)

const (
	SibkeyType = "sibkey"
	SubkeyType = "subkey"
	EldestType = "eldest"
)

const (
	SigTypeNone           = 0
	SigTypeSelfSig        = 1
	SigTypeRemoteProof    = 2
	SigTypeTrack          = 3
	SigTypeUntrack        = 4
	SigTypeRevoke         = 5
	SigTypeCryptocurrency = 6
	SigTypeAnnouncement   = 7
)

type KeyType int

const (
	KeyTypeNone                  KeyType = 0
	KeyTypeOpenPGPPublic                 = 1
	KeyTypeP3skbPrivate                  = 2
	KeyTypeKbNaclEddsa                   = 3
	KeyTypeKbNaclDH                      = 4
	KeyTypeKbNaclEddsaServerHalf         = 5
	KeyTypeKbNaclDHServerHalf            = 6
)

const (
	DeviceStatusNone    = 0
	DeviceStatusActive  = 1
	DeviceStatusDefunct = 2
)

// these strings need to match the keys in
// keybase/lib_public/public_constants.iced ->
// public_constants.device.type
const (
	DeviceTypeDesktop = "desktop"
	DeviceTypeMobile  = "mobile"
	DeviceTypeWeb     = "web"
	DeviceTypePaper   = "backup"
)

const DownloadURL = "https://keybase.io/download"

var PGPVersion = "Keybase Go " + Version + " (" + runtime.GOOS + ")"

var PGPArmorHeaders = map[string]string{
	"Version": PGPVersion,
	"Comment": DownloadURL,
}

var RemoteServiceTypes = map[string]keybase1.ProofType{
	"keybase":    keybase1.ProofType_KEYBASE,
	"twitter":    keybase1.ProofType_TWITTER,
	"github":     keybase1.ProofType_GITHUB,
	"reddit":     keybase1.ProofType_REDDIT,
	"coinbase":   keybase1.ProofType_COINBASE,
	"hackernews": keybase1.ProofType_HACKERNEWS,
	"https":      keybase1.ProofType_GENERIC_WEB_SITE,
	"http":       keybase1.ProofType_GENERIC_WEB_SITE,
	"dns":        keybase1.ProofType_DNS,
	"rooter":     keybase1.ProofType_ROOTER,
}

var RemoteServiceOrder = []keybase1.ProofType{
	keybase1.ProofType_KEYBASE,
	keybase1.ProofType_TWITTER,
	keybase1.ProofType_GITHUB,
	keybase1.ProofType_REDDIT,
	keybase1.ProofType_COINBASE,
	keybase1.ProofType_HACKERNEWS,
	keybase1.ProofType_GENERIC_WEB_SITE,
	keybase1.ProofType_ROOTER,
}

const CanonicalHost = "keybase.io"

const (
	HTTPDefaultTimeout = 10 * time.Second
)

// Packet tags for OpenPGP and also Keybase packets
const (
	KeybasePacketV1 = 1
	TagP3skb        = 513
	TagSignature    = 514
	TagEncryption   = 515
)

const (
	KIDPGPBase    AlgoType = 0x00
	KIDPGPRsa              = 0x1
	KIDPGPElgamal          = 0x10
	KIDPGPDsa              = 0x11
	KIDPGPEcdh             = 0x12
	KIDPGPEcdsa            = 0x13
	KIDNaclEddsa           = 0x20
	KIDNaclDH              = 0x21
)

// OpenPGP hash IDs, taken from http://tools.ietf.org/html/rfc4880#section-9.4
const (
	HashPGPMd5       = 1
	HashPGPSha1      = 2
	HashPGPRipemd160 = 3
	HashPGPSha256    = 8
	HashPGPSha384    = 9
	HashPGPSha512    = 10
	HashPGPSha224    = 11
)

const (
	SigKbEddsa = KIDNaclEddsa
)

const (
	ServerUpdateLag = time.Minute
)

// key_revocation_types
const (
	RevSimpleDelete = 0
	RevFull         = 1
	RevDated        = 2
)

type KeyStatus int

const (
	KeyUncancelled KeyStatus = iota
	KeyRevoked
	KeyDeleted
	KeySuperseded
)

type KeyRole int

const (
	DLGNone KeyRole = iota
	DLGSibkey
	DLGSubkey
)

const (
	KexScryptCost       = 32768
	KexScryptR          = 8
	KexScryptP          = 1
	KexScryptKeylen     = 32
	KexSessionIDEntropy = 65 // kex doc specifies 65 bits of entropy
)

const (
	PaperKeyScryptCost    = 32768
	PaperKeyScryptR       = 8
	PaperKeyScryptP       = 1
	PaperKeyScryptKeylen  = 128
	PaperKeyPhraseEntropy = 144
	PaperKeyVersion       = 0
)

const UserSummaryLimit = 500 // max number of user summaries in one request
<|endoftext|>


<commit_before>package atlas

import (
	"encoding/json"
	"fmt"
	"github.com/sendgrid/rest"
	"log"
)

// MeasurementResp contains all the results of the measurements
type MeasurementResp struct {
	Measurements []int
}

// createMeasurement creates a measurement for all types
func createMeasurement(t string, d MeasurementRequest) (m *MeasurementResp, err error) {
    // Check that all Definition.Type are the same and compliant
    if !checkAllTypesAs(d.Definitions, t) {
        err = ErrInvalidMeasurementType
        return
    }

    endPoint := apiEndpoint + fmt.Sprintf("/measurements/%s/", t)

    // Add at least one option, the APIkey if present
    hdrs := make(map[string]string)
    opts := make(map[string]string)

    key, ok := HasAPIKey()
    if ok {
        opts["key"] = key
    } else {
        err = ErrInvalidAPIKey
        return
    }

    body, err := json.Marshal(d)
    if err != nil {
        return
    }

    req := rest.Request{
        BaseURL:     endPoint,
        Method:      rest.Post,
        Headers:     hdrs,
        QueryParams: opts,
        Body:        body,
    }

    log.Printf("body: %s", body)
    resp, err := rest.API(req)

    m = &MeasurementResp{}
    err = json.Unmarshal([]byte(resp.Body), m)
    //r, err := api.Res(base, &resp).Post(d)
    fmt.Printf("m: %v\nresp: %#v\nd: %v\n", m, string(resp.Body), d)
    if err != nil {
        err = fmt.Errorf("err: %v - m:%v\n", err, m)
        return
    }

    return
}

// DNS creates a measurement
func DNS(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("dns", d)
}

// HTTP creates a measurement
func HTTP(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("http", d)
}

// NTP creates a measurement
func NTP(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("ntp", d)
}

// Ping creates a measurement
func Ping(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("ping", d)
}

// SSLCert creates a measurement
func SSLCert(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("SSL", d)
}

// Traceroute creates a measurement
func Traceroute(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("traceroute", d)
}
<commit_msg>Use prepareRequest() here as well.<commit_after>package atlas

import (
	"encoding/json"
	"fmt"
	"github.com/sendgrid/rest"
	"log"
)

// MeasurementResp contains all the results of the measurements
type MeasurementResp struct {
	Measurements []int
}

// createMeasurement creates a measurement for all types
func createMeasurement(t string, d MeasurementRequest) (m *MeasurementResp, err error) {
    // Check that all Definition.Type are the same and compliant
    if !checkAllTypesAs(d.Definitions, t) {
        err = ErrInvalidMeasurementType
        return
    }

    req := prepareRequest(fmt.Sprintf("measurements/%s", t))

    body, err := json.Marshal(d)
    if err != nil {
        return
    }

    req.Method = rest.Post
    req.Body = body

    log.Printf("body: %s", body)
    resp, err := rest.API(req)

    m = &MeasurementResp{}
    err = json.Unmarshal([]byte(resp.Body), m)
    //r, err := api.Res(base, &resp).Post(d)
    fmt.Printf("m: %v\nresp: %#v\nd: %v\n", m, string(resp.Body), d)
    if err != nil {
        err = fmt.Errorf("err: %v - m:%v\n", err, m)
        return
    }

    return
}

// DNS creates a measurement
func DNS(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("dns", d)
}

// HTTP creates a measurement
func HTTP(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("http", d)
}

// NTP creates a measurement
func NTP(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("ntp", d)
}

// Ping creates a measurement
func Ping(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("ping", d)
}

// SSLCert creates a measurement
func SSLCert(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("SSL", d)
}

// Traceroute creates a measurement
func Traceroute(d MeasurementRequest) (m *MeasurementResp, err error) {
    return createMeasurement("traceroute", d)
}
<|endoftext|>


<commit_before>// Copyright 2013 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 ssa_test

// This file runs the SSA builder in sanity-checking mode on all
// packages beneath $GOROOT and prints some summary information.
//
// Run test with GOMAXPROCS=8.

import (
	"go/token"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"

	"code.google.com/p/go.tools/go/loader"
	"code.google.com/p/go.tools/go/ssa"
	"code.google.com/p/go.tools/go/ssa/ssautil"
)

func allPackages() []string {
	var pkgs []string
	root := filepath.Join(runtime.GOROOT(), "src/pkg") + string(os.PathSeparator)
	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		// Prune the search if we encounter any of these names:
		switch filepath.Base(path) {
		case "testdata", ".hg":
			return filepath.SkipDir
		}
		if info.IsDir() {
			pkg := strings.TrimPrefix(path, root)
			switch pkg {
			case "builtin", "pkg", "code.google.com":
				return filepath.SkipDir // skip these subtrees
			case "":
				return nil // ignore root of tree
			}
			pkgs = append(pkgs, pkg)
		}

		return nil
	})
	return pkgs
}

func TestStdlib(t *testing.T) {
	// Load, parse and type-check the program.
	t0 := time.Now()

	var conf loader.Config
	if _, err := conf.FromArgs(allPackages()); err != nil {
		t.Errorf("FromArgs failed: %s", err)
		return
	}

	iprog, err := conf.Load()
	if err != nil {
		t.Errorf("Load failed: %s", err)
	}

	t1 := time.Now()

	runtime.GC()
	var memstats runtime.MemStats
	runtime.ReadMemStats(&memstats)
	alloc := memstats.Alloc

	// Create SSA packages.
	var mode ssa.BuilderMode
	// Comment out these lines during benchmarking.  Approx SSA build costs are noted.
	mode |= ssa.SanityCheckFunctions // + 2% space, + 4% time
	mode |= ssa.GlobalDebug          // +30% space, +18% time
	prog := ssa.Create(iprog, mode)

	t2 := time.Now()

	// Build SSA IR... if it's safe.
	prog.BuildAll()

	t3 := time.Now()

	runtime.GC()
	runtime.ReadMemStats(&memstats)

	numPkgs := len(prog.AllPackages())
	if want := 140; numPkgs < want {
		t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
	}

	// Dump some statistics.
	allFuncs := ssautil.AllFunctions(prog)
	var numInstrs int
	for fn := range allFuncs {
		for _, b := range fn.Blocks {
			numInstrs += len(b.Instrs)
		}
	}

	// determine line count
	var lineCount int
	prog.Fset.Iterate(func(f *token.File) bool {
		lineCount += f.LineCount()
		return true
	})

	// NB: when benchmarking, don't forget to clear the debug +
	// sanity builder flags for better performance.

	t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
	t.Log("#Source lines:        ", lineCount)
	t.Log("Load/parse/typecheck: ", t1.Sub(t0))
	t.Log("SSA create:           ", t2.Sub(t1))
	t.Log("SSA build:            ", t3.Sub(t2))

	// SSA stats:
	t.Log("#Packages:            ", numPkgs)
	t.Log("#Functions:           ", len(allFuncs))
	t.Log("#Instructions:        ", numInstrs)
	t.Log("#MB:                  ", (memstats.Alloc-alloc)/1000000)
}
<commit_msg>go.tools/go/ssa: stop if error in TestStdlib<commit_after>// Copyright 2013 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 ssa_test

// This file runs the SSA builder in sanity-checking mode on all
// packages beneath $GOROOT and prints some summary information.
//
// Run test with GOMAXPROCS=8.

import (
	"go/token"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"

	"code.google.com/p/go.tools/go/loader"
	"code.google.com/p/go.tools/go/ssa"
	"code.google.com/p/go.tools/go/ssa/ssautil"
)

func allPackages() []string {
	var pkgs []string
	root := filepath.Join(runtime.GOROOT(), "src/pkg") + string(os.PathSeparator)
	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		// Prune the search if we encounter any of these names:
		switch filepath.Base(path) {
		case "testdata", ".hg":
			return filepath.SkipDir
		}
		if info.IsDir() {
			pkg := strings.TrimPrefix(path, root)
			switch pkg {
			case "builtin", "pkg", "code.google.com":
				return filepath.SkipDir // skip these subtrees
			case "":
				return nil // ignore root of tree
			}
			pkgs = append(pkgs, pkg)
		}

		return nil
	})
	return pkgs
}

func TestStdlib(t *testing.T) {
	// Load, parse and type-check the program.
	t0 := time.Now()

	var conf loader.Config
	if _, err := conf.FromArgs(allPackages()); err != nil {
		t.Errorf("FromArgs failed: %v", err)
		return
	}

	iprog, err := conf.Load()
	if err != nil {
		t.Fatalf("Load failed: %v", err)
	}

	t1 := time.Now()

	runtime.GC()
	var memstats runtime.MemStats
	runtime.ReadMemStats(&memstats)
	alloc := memstats.Alloc

	// Create SSA packages.
	var mode ssa.BuilderMode
	// Comment out these lines during benchmarking.  Approx SSA build costs are noted.
	mode |= ssa.SanityCheckFunctions // + 2% space, + 4% time
	mode |= ssa.GlobalDebug          // +30% space, +18% time
	prog := ssa.Create(iprog, mode)

	t2 := time.Now()

	// Build SSA IR... if it's safe.
	prog.BuildAll()

	t3 := time.Now()

	runtime.GC()
	runtime.ReadMemStats(&memstats)

	numPkgs := len(prog.AllPackages())
	if want := 140; numPkgs < want {
		t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
	}

	// Dump some statistics.
	allFuncs := ssautil.AllFunctions(prog)
	var numInstrs int
	for fn := range allFuncs {
		for _, b := range fn.Blocks {
			numInstrs += len(b.Instrs)
		}
	}

	// determine line count
	var lineCount int
	prog.Fset.Iterate(func(f *token.File) bool {
		lineCount += f.LineCount()
		return true
	})

	// NB: when benchmarking, don't forget to clear the debug +
	// sanity builder flags for better performance.

	t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
	t.Log("#Source lines:        ", lineCount)
	t.Log("Load/parse/typecheck: ", t1.Sub(t0))
	t.Log("SSA create:           ", t2.Sub(t1))
	t.Log("SSA build:            ", t3.Sub(t2))

	// SSA stats:
	t.Log("#Packages:            ", numPkgs)
	t.Log("#Functions:           ", len(allFuncs))
	t.Log("#Instructions:        ", numInstrs)
	t.Log("#MB:                  ", (memstats.Alloc-alloc)/1000000)
}
<|endoftext|>