<commit_before>// Copyright 2017 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 cshared_test

import (
	"debug/elf"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"testing"
	"unicode"
)

// C compiler with args (from $(go env CC) $(go env GOGCCFLAGS)).
var cc []string

// An environment with GOPATH=$(pwd).
var gopathEnv []string

// ".exe" on Windows.
var exeSuffix string

var GOOS, GOARCH, GOROOT string
var installdir, androiddir, ldlibrarypath string
var libSuffix, libgoname string

func init() {
	GOOS = goEnv("GOOS")
	GOARCH = goEnv("GOARCH")
	GOROOT = goEnv("GOROOT")

	if _, err := os.Stat(GOROOT); os.IsNotExist(err) {
		log.Fatalf("Unable able to find GOROOT at '%s'", GOROOT)
	}

	// Directory where cgo headers and outputs will be installed.
	// The installation directory format varies depending on the platform.
	installdir = path.Join("pkg", fmt.Sprintf("%s_%s_testcshared_shared", GOOS, GOARCH))
	switch GOOS {
	case "darwin":
		libSuffix = "dylib"
		installdir = path.Join("pkg", fmt.Sprintf("%s_%s_testcshared", GOOS, GOARCH))
	case "windows":
		libSuffix = "dll"
	default:
		libSuffix = "so"
	}

	androiddir = fmt.Sprintf("/data/local/tmp/testcshared-%d", os.Getpid())
	libgoname = "libgo." + libSuffix

	ccOut := goEnv("CC")
	cc = []string{string(ccOut)}

	out := goEnv("GOGCCFLAGS")
	quote := '\000'
	start := 0
	lastSpace := true
	backslash := false
	s := string(out)
	for i, c := range s {
		if quote == '\000' && unicode.IsSpace(c) {
			if !lastSpace {
				cc = append(cc, s[start:i])
				lastSpace = true
			}
		} else {
			if lastSpace {
				start = i
				lastSpace = false
			}
			if quote == '\000' && !backslash && (c == '"' || c == '\'') {
				quote = c
				backslash = false
			} else if !backslash && quote == c {
				quote = '\000'
			} else if (quote == '\000' || quote == '"') && !backslash && c == '\\' {
				backslash = true
			} else {
				backslash = false
			}
		}
	}
	if !lastSpace {
		cc = append(cc, s[start:])
	}

	if GOOS == "darwin" {
		// For Darwin/ARM.
		// TODO(crawshaw): can we do better?
		cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
	}
	libgodir := GOOS + "_" + GOARCH
	switch GOOS {
	case "darwin":
		if GOARCH == "arm" || GOARCH == "arm64" {
			libgodir += "_shared"
		}
	case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
		libgodir += "_shared"
	}
	cc = append(cc, "-I", filepath.Join("pkg", libgodir))

	// Build an environment with GOPATH=$(pwd)
	dir, err := os.Getwd()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(2)
	}
	gopathEnv = append(os.Environ(), "GOPATH="+dir)
	ldlibrarypath = "LD_LIBRARY_PATH=" + dir

	if GOOS == "windows" {
		exeSuffix = ".exe"
	}
}

func goEnv(key string) string {
	out, err := exec.Command("go", "env", key).Output()
	if err != nil {
		fmt.Fprintf(os.Stderr, "go env %s failed:\n%s", key, err)
		fmt.Fprintf(os.Stderr, "%s", err.(*exec.ExitError).Stderr)
		os.Exit(2)
	}
	return strings.TrimSpace(string(out))
}

func cmdToRun(name string) []string {
	return []string{"./" + name + exeSuffix}
}

func adbPush(t *testing.T, filename string) {
	if GOOS != "android" {
		return
	}
	args := append("adb", "push", filename, fmt.Sprintf("%s/%s", androiddir, filename))
	cmd := exec.Command(args[0], args[1:]...)
	if out, err := cmd.CombinedOutput(); err != nil {
		t.Fatalf("adb command failed: %v\n%s\n", err, out)
	}
}

func adbRun(t *testing.T, adbargs ...string) string {
	if GOOS != "android" {
		t.Fatalf("trying to run adb command when operating system is not android.")
	}
	args := append("adb", "shell")
	args = append(args, adbargs...)
	cmd := exec.Command(args[0], args[1:]...)
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("adb command failed: %v\n%s\n", err, out)
	}

	return strings.Replace(string(out), "\r", "", -1)
}

func runwithenv(t *testing.T, env []string, args ...string) string {
	if GOOS == "android" {
		return adbRun(t, args...)
	}

	cmd := exec.Command(args[0], args[1:]...)
	cmd.Env = env
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("command failed: %v\n%v\n%s\n", args, err, out)
	} else {
		t.Logf("run: %v", args)
	}

	return string(out)
}

func run(t *testing.T, args ...string) string {
	if GOOS == "android" {
		return adbRun(t, args...)
	}

	cmd := exec.Command(args[0], args[1:]...)
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("command failed: %v\n%v\n%s\n", args, err, out)
	} else {
		t.Logf("run: %v", args)
	}

	return string(out)
}

func runwithldlibrarypath(t *testing.T, args ...string) string {
	return runwithenv(t, append(gopathEnv, ldlibrarypath), args...)
}

func rungocmd(t *testing.T, args ...string) string {
	return runwithenv(t, gopathEnv, args...)
}

func createHeaders(t *testing.T) {
	rungocmd(t,
		"go", "install",
		"-buildmode=c-shared", "-installsuffix",
		"testcshared", "libgo",
	)

	rungocmd(t,
		"go", "build",
		"-buildmode=c-shared", "-installsuffix",
		"testcshared", "-o", libgoname,
		filepath.Join("src", "libgo", "libgo.go"),
	)
	adbPush(t, libgoname)

	if GOOS == "linux" || GOOS == "android" {
		f, err := elf.Open(libgoname)
		if err != nil {
			t.Fatal("elf.Open failed: ", err)
		}
		defer f.Close()
		if hasDynTag(t, f, elf.DT_TEXTREL) {
			t.Fatalf("%s has DT_TEXTREL flag", libgoname)
		}
	}
}

func cleanupHeaders() {
	os.Remove("libgo.h")
}

func setupAndroid(t *testing.T) {
	if GOOS != "android" {
		return
	}
	adbRun(t, "mkdir", "-p", androiddir)
}

func cleanupAndroid(t *testing.T) {
	if GOOS != "android" {
		return
	}
	adbRun(t, "rm", "-rf", androiddir)
}

// test0: exported symbols in shared lib are accessible.
func TestExportedSymbols(t *testing.T) {
	cmd := "testp"
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)
	createHeaders(t)
	defer cleanupHeaders()

	run(t, append(cc, "-I", installdir, "-o", cmd, "main0.c", libgoname)...)
	adbPush(t, cmd)

	defer os.Remove(libgoname)
	defer os.Remove("testp")

	out := runwithldlibrarypath(t, bin...)
	if strings.TrimSpace(out) != "PASS" {
		t.Error(out)
	}
}

// test1: shared library can be dynamically loaded and exported symbols are accessible.
func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
	cmd := "testp"
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)
	createHeaders(t)
	defer cleanupHeaders()

	run(t, append(cc, "-o", cmd, "main1.c", "-ldl")...)
	adbPush(t, cmd)

	defer os.Remove(libgoname)
	defer os.Remove(cmd)

	out := run(t, append(bin, "./"+libgoname)...)
	if strings.TrimSpace(out) != "PASS" {
		t.Error(out)
	}
}

// test2: tests libgo2 which does not export any functions.
func TestUnexportedSymbols(t *testing.T) {
	cmd := "testp2"
	libname := "libgo2." + libSuffix
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)

	rungocmd(t,
		"go", "build",
		"-buildmode=c-shared",
		"-installsuffix", "testcshared",
		"-o", libname, "libgo2",
	)
	adbPush(t, libname)

	linkFlags := "-Wl,--no-as-needed"
	if GOOS == "darwin" {
		linkFlags = ""
	}

	run(t, append(
		cc, "-o", cmd,
		"main2.c", linkFlags,
		libname,
	)...)
	adbPush(t, cmd)

	defer os.Remove(libname)
	defer os.Remove(cmd)

	out := runwithldlibrarypath(t, bin...)

	if strings.TrimSpace(out) != "PASS" {
		t.Error(out)
	}
}

// test3: tests main.main is exported on android.
func TestMainExportedOnAndroid(t *testing.T) {
	if GOOS != "android" {
		return
	}

	cmd := "testp3"
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)
	createHeaders(t)
	defer cleanupHeaders()

	run(t, append(cc, "-o", cmd, "main3.c", "-ldl")...)
	adbPush(t, cmd)

	defer os.Remove(libgoname)
	defer os.Remove(cmd)

	out := run(t, append(bin, "./"+libgoname)...)
	if strings.TrimSpace(out) != "PASS" {
		t.Error(out)
	}
}

// test4: test signal handlers
func TestSignalHandlers(t *testing.T) {
	cmd := "testp4"
	libname := "libgo4." + libSuffix
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)

	rungocmd(t,
		"go", "build",
		"-buildmode=c-shared",
		"-installsuffix", "testcshared",
		"-o", libname, "libgo4",
	)
	adbPush(t, libname)
	run(t, append(
		cc, "-pthread", "-o", cmd,
		"main4.c", "-ldl",
	)...)
	adbPush(t, cmd)

	defer os.Remove(libname)
	defer os.Remove(cmd)
	defer os.Remove("libgo4.h")

	out := run(t, append(bin, "./"+libname)...)

	if strings.TrimSpace(out) != "PASS" {
		t.Error(run(t, append(bin, libname, "verbose")...))
	}
}

// test5: test signal handlers with os/signal.Notify
func TestSignalHandlersWithNotify(t *testing.T) {
	cmd := "testp5"
	libname := "libgo5." + libSuffix
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)

	rungocmd(t,
		"go", "build",
		"-buildmode=c-shared",
		"-installsuffix", "testcshared",
		"-o", libname, "libgo5",
	)
	adbPush(t, libname)
	run(t, append(
		cc, "-pthread", "-o", cmd,
		"main5.c", "-ldl",
	)...)
	adbPush(t, cmd)

	defer os.Remove(libname)
	defer os.Remove(cmd)
	defer os.Remove("libgo5.h")

	out := run(t, append(bin, "./"+libname)...)

	if strings.TrimSpace(out) != "PASS" {
		t.Error(run(t, append(bin, libname, "verbose")...))
	}
}

func TestPIE(t *testing.T) {
	switch GOOS {
	case "linux", "android":
		break
	default:
		t.Logf("Skipping TestPIE on %s", GOOS)
		return
	}

	defer func() {
		os.RemoveAll("pkg")
	}()

	createHeaders(t)
	defer cleanupHeaders()

	f, err := elf.Open(libgoname)
	if err != nil {
		t.Fatal("elf.Open failed: ", err)
	}
	defer f.Close()
	if hasDynTag(t, f, elf.DT_TEXTREL) {
		t.Errorf("%s has DT_TEXTREL flag", libgoname)
	}
}

func hasDynTag(t *testing.T, f *elf.File, tag elf.DynTag) bool {
	ds := f.SectionByType(elf.SHT_DYNAMIC)
	if ds == nil {
		t.Error("no SHT_DYNAMIC section")
		return false
	}
	d, err := ds.Data()
	if err != nil {
		t.Errorf("can't read SHT_DYNAMIC contents: %v", err)
		return false
	}
	for len(d) > 0 {
		var t elf.DynTag
		switch f.Class {
		case elf.ELFCLASS32:
			t = elf.DynTag(f.ByteOrder.Uint32(d[:4]))
			d = d[8:]
		case elf.ELFCLASS64:
			t = elf.DynTag(f.ByteOrder.Uint64(d[:8]))
			d = d[16:]
		}
		if t == tag {
			return true
		}
	}
	return false
}
<commit_msg>misc/cgo/testcshared: fix syntax error in the test<commit_after>// Copyright 2017 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 cshared_test

import (
	"debug/elf"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"testing"
	"unicode"
)

// C compiler with args (from $(go env CC) $(go env GOGCCFLAGS)).
var cc []string

// An environment with GOPATH=$(pwd).
var gopathEnv []string

// ".exe" on Windows.
var exeSuffix string

var GOOS, GOARCH, GOROOT string
var installdir, androiddir, ldlibrarypath string
var libSuffix, libgoname string

func init() {
	GOOS = goEnv("GOOS")
	GOARCH = goEnv("GOARCH")
	GOROOT = goEnv("GOROOT")

	if _, err := os.Stat(GOROOT); os.IsNotExist(err) {
		log.Fatalf("Unable able to find GOROOT at '%s'", GOROOT)
	}

	// Directory where cgo headers and outputs will be installed.
	// The installation directory format varies depending on the platform.
	installdir = path.Join("pkg", fmt.Sprintf("%s_%s_testcshared_shared", GOOS, GOARCH))
	switch GOOS {
	case "darwin":
		libSuffix = "dylib"
		installdir = path.Join("pkg", fmt.Sprintf("%s_%s_testcshared", GOOS, GOARCH))
	case "windows":
		libSuffix = "dll"
	default:
		libSuffix = "so"
	}

	androiddir = fmt.Sprintf("/data/local/tmp/testcshared-%d", os.Getpid())
	libgoname = "libgo." + libSuffix

	ccOut := goEnv("CC")
	cc = []string{string(ccOut)}

	out := goEnv("GOGCCFLAGS")
	quote := '\000'
	start := 0
	lastSpace := true
	backslash := false
	s := string(out)
	for i, c := range s {
		if quote == '\000' && unicode.IsSpace(c) {
			if !lastSpace {
				cc = append(cc, s[start:i])
				lastSpace = true
			}
		} else {
			if lastSpace {
				start = i
				lastSpace = false
			}
			if quote == '\000' && !backslash && (c == '"' || c == '\'') {
				quote = c
				backslash = false
			} else if !backslash && quote == c {
				quote = '\000'
			} else if (quote == '\000' || quote == '"') && !backslash && c == '\\' {
				backslash = true
			} else {
				backslash = false
			}
		}
	}
	if !lastSpace {
		cc = append(cc, s[start:])
	}

	if GOOS == "darwin" {
		// For Darwin/ARM.
		// TODO(crawshaw): can we do better?
		cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
	}
	libgodir := GOOS + "_" + GOARCH
	switch GOOS {
	case "darwin":
		if GOARCH == "arm" || GOARCH == "arm64" {
			libgodir += "_shared"
		}
	case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
		libgodir += "_shared"
	}
	cc = append(cc, "-I", filepath.Join("pkg", libgodir))

	// Build an environment with GOPATH=$(pwd)
	dir, err := os.Getwd()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(2)
	}
	gopathEnv = append(os.Environ(), "GOPATH="+dir)
	ldlibrarypath = "LD_LIBRARY_PATH=" + dir

	if GOOS == "windows" {
		exeSuffix = ".exe"
	}
}

func goEnv(key string) string {
	out, err := exec.Command("go", "env", key).Output()
	if err != nil {
		fmt.Fprintf(os.Stderr, "go env %s failed:\n%s", key, err)
		fmt.Fprintf(os.Stderr, "%s", err.(*exec.ExitError).Stderr)
		os.Exit(2)
	}
	return strings.TrimSpace(string(out))
}

func cmdToRun(name string) []string {
	return []string{"./" + name + exeSuffix}
}

func adbPush(t *testing.T, filename string) {
	if GOOS != "android" {
		return
	}
	args := []string{"adb", "push", filename, fmt.Sprintf("%s/%s", androiddir, filename)}
	cmd := exec.Command(args[0], args[1:]...)
	if out, err := cmd.CombinedOutput(); err != nil {
		t.Fatalf("adb command failed: %v\n%s\n", err, out)
	}
}

func adbRun(t *testing.T, adbargs ...string) string {
	if GOOS != "android" {
		t.Fatalf("trying to run adb command when operating system is not android.")
	}
	args := []string{"adb", "shell"}
	args = append(args, adbargs...)
	cmd := exec.Command(args[0], args[1:]...)
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("adb command failed: %v\n%s\n", err, out)
	}

	return strings.Replace(string(out), "\r", "", -1)
}

func runwithenv(t *testing.T, env []string, args ...string) string {
	if GOOS == "android" {
		return adbRun(t, args...)
	}

	cmd := exec.Command(args[0], args[1:]...)
	cmd.Env = env
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("command failed: %v\n%v\n%s\n", args, err, out)
	} else {
		t.Logf("run: %v", args)
	}

	return string(out)
}

func run(t *testing.T, args ...string) string {
	if GOOS == "android" {
		return adbRun(t, args...)
	}

	cmd := exec.Command(args[0], args[1:]...)
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("command failed: %v\n%v\n%s\n", args, err, out)
	} else {
		t.Logf("run: %v", args)
	}

	return string(out)
}

func runwithldlibrarypath(t *testing.T, args ...string) string {
	return runwithenv(t, append(gopathEnv, ldlibrarypath), args...)
}

func rungocmd(t *testing.T, args ...string) string {
	return runwithenv(t, gopathEnv, args...)
}

func createHeaders(t *testing.T) {
	rungocmd(t,
		"go", "install",
		"-buildmode=c-shared", "-installsuffix",
		"testcshared", "libgo",
	)

	rungocmd(t,
		"go", "build",
		"-buildmode=c-shared", "-installsuffix",
		"testcshared", "-o", libgoname,
		filepath.Join("src", "libgo", "libgo.go"),
	)
	adbPush(t, libgoname)

	if GOOS == "linux" || GOOS == "android" {
		f, err := elf.Open(libgoname)
		if err != nil {
			t.Fatal("elf.Open failed: ", err)
		}
		defer f.Close()
		if hasDynTag(t, f, elf.DT_TEXTREL) {
			t.Fatalf("%s has DT_TEXTREL flag", libgoname)
		}
	}
}

func cleanupHeaders() {
	os.Remove("libgo.h")
}

func setupAndroid(t *testing.T) {
	if GOOS != "android" {
		return
	}
	adbRun(t, "mkdir", "-p", androiddir)
}

func cleanupAndroid(t *testing.T) {
	if GOOS != "android" {
		return
	}
	adbRun(t, "rm", "-rf", androiddir)
}

// test0: exported symbols in shared lib are accessible.
func TestExportedSymbols(t *testing.T) {
	cmd := "testp"
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)
	createHeaders(t)
	defer cleanupHeaders()

	run(t, append(cc, "-I", installdir, "-o", cmd, "main0.c", libgoname)...)
	adbPush(t, cmd)

	defer os.Remove(libgoname)
	defer os.Remove("testp")

	out := runwithldlibrarypath(t, bin...)
	if strings.TrimSpace(out) != "PASS" {
		t.Error(out)
	}
}

// test1: shared library can be dynamically loaded and exported symbols are accessible.
func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
	cmd := "testp"
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)
	createHeaders(t)
	defer cleanupHeaders()

	run(t, append(cc, "-o", cmd, "main1.c", "-ldl")...)
	adbPush(t, cmd)

	defer os.Remove(libgoname)
	defer os.Remove(cmd)

	out := run(t, append(bin, "./"+libgoname)...)
	if strings.TrimSpace(out) != "PASS" {
		t.Error(out)
	}
}

// test2: tests libgo2 which does not export any functions.
func TestUnexportedSymbols(t *testing.T) {
	cmd := "testp2"
	libname := "libgo2." + libSuffix
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)

	rungocmd(t,
		"go", "build",
		"-buildmode=c-shared",
		"-installsuffix", "testcshared",
		"-o", libname, "libgo2",
	)
	adbPush(t, libname)

	linkFlags := "-Wl,--no-as-needed"
	if GOOS == "darwin" {
		linkFlags = ""
	}

	run(t, append(
		cc, "-o", cmd,
		"main2.c", linkFlags,
		libname,
	)...)
	adbPush(t, cmd)

	defer os.Remove(libname)
	defer os.Remove(cmd)

	out := runwithldlibrarypath(t, bin...)

	if strings.TrimSpace(out) != "PASS" {
		t.Error(out)
	}
}

// test3: tests main.main is exported on android.
func TestMainExportedOnAndroid(t *testing.T) {
	if GOOS != "android" {
		return
	}

	cmd := "testp3"
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)
	createHeaders(t)
	defer cleanupHeaders()

	run(t, append(cc, "-o", cmd, "main3.c", "-ldl")...)
	adbPush(t, cmd)

	defer os.Remove(libgoname)
	defer os.Remove(cmd)

	out := run(t, append(bin, "./"+libgoname)...)
	if strings.TrimSpace(out) != "PASS" {
		t.Error(out)
	}
}

// test4: test signal handlers
func TestSignalHandlers(t *testing.T) {
	cmd := "testp4"
	libname := "libgo4." + libSuffix
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)

	rungocmd(t,
		"go", "build",
		"-buildmode=c-shared",
		"-installsuffix", "testcshared",
		"-o", libname, "libgo4",
	)
	adbPush(t, libname)
	run(t, append(
		cc, "-pthread", "-o", cmd,
		"main4.c", "-ldl",
	)...)
	adbPush(t, cmd)

	defer os.Remove(libname)
	defer os.Remove(cmd)
	defer os.Remove("libgo4.h")

	out := run(t, append(bin, "./"+libname)...)

	if strings.TrimSpace(out) != "PASS" {
		t.Error(run(t, append(bin, libname, "verbose")...))
	}
}

// test5: test signal handlers with os/signal.Notify
func TestSignalHandlersWithNotify(t *testing.T) {
	cmd := "testp5"
	libname := "libgo5." + libSuffix
	bin := cmdToRun(cmd)

	setupAndroid(t)
	defer cleanupAndroid(t)

	rungocmd(t,
		"go", "build",
		"-buildmode=c-shared",
		"-installsuffix", "testcshared",
		"-o", libname, "libgo5",
	)
	adbPush(t, libname)
	run(t, append(
		cc, "-pthread", "-o", cmd,
		"main5.c", "-ldl",
	)...)
	adbPush(t, cmd)

	defer os.Remove(libname)
	defer os.Remove(cmd)
	defer os.Remove("libgo5.h")

	out := run(t, append(bin, "./"+libname)...)

	if strings.TrimSpace(out) != "PASS" {
		t.Error(run(t, append(bin, libname, "verbose")...))
	}
}

func TestPIE(t *testing.T) {
	switch GOOS {
	case "linux", "android":
		break
	default:
		t.Logf("Skipping TestPIE on %s", GOOS)
		return
	}

	defer func() {
		os.RemoveAll("pkg")
	}()

	createHeaders(t)
	defer cleanupHeaders()

	f, err := elf.Open(libgoname)
	if err != nil {
		t.Fatal("elf.Open failed: ", err)
	}
	defer f.Close()
	if hasDynTag(t, f, elf.DT_TEXTREL) {
		t.Errorf("%s has DT_TEXTREL flag", libgoname)
	}
}

func hasDynTag(t *testing.T, f *elf.File, tag elf.DynTag) bool {
	ds := f.SectionByType(elf.SHT_DYNAMIC)
	if ds == nil {
		t.Error("no SHT_DYNAMIC section")
		return false
	}
	d, err := ds.Data()
	if err != nil {
		t.Errorf("can't read SHT_DYNAMIC contents: %v", err)
		return false
	}
	for len(d) > 0 {
		var t elf.DynTag
		switch f.Class {
		case elf.ELFCLASS32:
			t = elf.DynTag(f.ByteOrder.Uint32(d[:4]))
			d = d[8:]
		case elf.ELFCLASS64:
			t = elf.DynTag(f.ByteOrder.Uint64(d[:8]))
			d = d[16:]
		}
		if t == tag {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"testing"
)

func TestAccAWSPolicyAttachment_basic(t *testing.T) {
	var out iam.GetPolicyOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSPolicyAttachmentDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSPolicyAttachConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSPolicyAttachmentExists("aws_iam_policy_attachment.test-attachment", 3, &out),
					testAccCheckAWSPolicyAttachmentAttributes([]string{"test-user"}, []string{"test-role"}, []string{"test-group"}, &out),
				),
			},
			resource.TestStep{
				Config: testAccAWSPolicyAttachConfigUpdate,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSPolicyAttachmentExists("aws_iam_policy_attachment.test-attachment", 6, &out),
					testAccCheckAWSPolicyAttachmentAttributes([]string{"test-user3", "test-user3"}, []string{"test-role2", "test-role3"}, []string{"test-group2", "test-group3"}, &out),
				),
			},
		},
	})
}
func testAccCheckAWSPolicyAttachmentDestroy(s *terraform.State) error {

	return nil
}

func testAccCheckAWSPolicyAttachmentExists(n string, c int, out *iam.ListEntitiesForPolicyOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No policy name is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).iamconn
		arn := rs.Primary.Attributes["policy_arn"]

		resp, err := conn.GetPolicy(&iam.GetPolicyInput{
			PolicyARN: aws.String(arn),
		})
		if err != nil {
			return fmt.Errorf("Error: Policy (%s) not found", n)
		}
		if c != resp.Policy.AttachmentCount {
			return fmt.Errorf("Error: Policy (%s) has wrong number of entities attached on initial creation", n)
		}
		resp2, err := conn.ListEntitiesForPolicy(&iam.ListEntitiesForPolicyOutput{
			PolicyARN: aws.String(arn),
		})
		if err != nil {
			return fmt.Errorf("Error: Failed to get entities for Policy (%s)", arn)
		}

		*out = *resp2
		return nil
	}
}
func testAccCheckAWSPolicyAttachmentAttributes(users []string, roles []string, groups []string, out *iam.ListEntitiesForPolicyOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		uc := len(u)
		rc := len(r)
		gc := len(g)

		for _, u := range users {
			for _, pu := range out.PolicyUsers {
				if u == *pu.UserName {
					uc--
				}
			}
		}
		for _, r := range roles {
			for _, pr := range out.PolicyRoles {
				if r == *pu.RoleName {
					rc--
				}
			}
		}
		for _, g := range users {
			for _, pg := range out.PolicyGroups {
				if g == *pu.GroupName {
					gc--
				}
			}
		}
		if uc != 0 || rc != 0 || gc != 0 {
			return fmt.Errorf("Error: Number of attached users, roles, or groups was incorrect:\n expected %d users and found %d\nexpected %d roles and found %d\nexpected %d groups and found %d", len(users), (len(users) - uc), len(roles), (len(roles) - rc), len(groups), (len(groups) - gc))
		}
	}
}

const testAccAWSPolicyAttachConfig = `
resource "aws_iam_user" "user" {
    name = "test-user"
}
resource "aws_iam_role" "role" {
    name = "test-role"
}
resource "aws_iam_group" "group" {
    name = "test-group"
}

resource "aws_iam_policy" "policy" {
    name = "test-policy"
    description = "A test policy"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy_attachment" "test-attach" {
    name = "test-attachment"
    users = ["${aws_iam_user.user.name}"]
    roles = ["${aws_iam_role.role.name}"]
    groups = ["${aws_iam_group.group.name}"]
    policy_arn = "${aws_iam_policy.policy.arn}"
}
`

const testAccAWSPolicyAttachConfigUpdate = `
resource "aws_iam_user" "user" {
    name = "test-user"
}
resource "aws_iam_user" "user2" {
    name = "test-user2"
}
resource "aws_iam_user" "user3" {
    name = "test-user3"
}
resource "aws_iam_role" "role" {
    name = "test-role"
}
resource "aws_iam_role" "role2" {
    name = "test-role2"
}
resource "aws_iam_role" "role3" {
    name = "test-role3"
}
resource "aws_iam_group" "group" {
    name = "test-group"
}
resource "aws_iam_group" "group2" {
    name = "test-group2"
}
resource "aws_iam_group" "group3" {
    name = "test-group3"
}

resource "aws_iam_policy" "policy" {
    name = "test-policy"
    description = "A test policy"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy_attachment" "test-attach" {
    name = "test-attachment"
    users = [
        "${aws_iam_user.user2.name}",
        "${aws_iam_user.user3.name}"
    ]
    roles = [
        "${aws_iam_role.role2.name}",
        "${aws_iam_role.role3.name}"
    ]
    groups = [
        "${aws_iam_group.group2.name}",
        "${aws_iam_group.group3.name}"
    ]
    policy_arn = "${aws_iam_policy.policy.arn}"
}
`
<commit_msg>test works<commit_after>package aws

import (
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"testing"
)

func TestAccAWSPolicyAttachment_basic(t *testing.T) {
	var out iam.ListEntitiesForPolicyOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSPolicyAttachmentDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSPolicyAttachConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSPolicyAttachmentExists("aws_iam_policy_attachment.test-attachment", 3, &out),
					testAccCheckAWSPolicyAttachmentAttributes([]string{"test-user"}, []string{"test-role"}, []string{"test-group"}, &out),
				),
			},
			resource.TestStep{
				Config: testAccAWSPolicyAttachConfigUpdate,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSPolicyAttachmentExists("aws_iam_policy_attachment.test-attachment", 6, &out),
					testAccCheckAWSPolicyAttachmentAttributes([]string{"test-user3", "test-user3"}, []string{"test-role2", "test-role3"}, []string{"test-group2", "test-group3"}, &out),
				),
			},
		},
	})
}
func testAccCheckAWSPolicyAttachmentDestroy(s *terraform.State) error {

	return nil
}

func testAccCheckAWSPolicyAttachmentExists(n string, c int64, out *iam.ListEntitiesForPolicyOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No policy name is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).iamconn
		arn := rs.Primary.Attributes["policy_arn"]

		resp, err := conn.GetPolicy(&iam.GetPolicyInput{
			PolicyARN: aws.String(arn),
		})
		if err != nil {
			return fmt.Errorf("Error: Policy (%s) not found", n)
		}
		if c != *resp.Policy.AttachmentCount {
			return fmt.Errorf("Error: Policy (%s) has wrong number of entities attached on initial creation", n)
		}
		resp2, err := conn.ListEntitiesForPolicy(&iam.ListEntitiesForPolicyInput{
			PolicyARN: aws.String(arn),
		})
		if err != nil {
			return fmt.Errorf("Error: Failed to get entities for Policy (%s)", arn)
		}

		*out = *resp2
		return nil
	}
}
func testAccCheckAWSPolicyAttachmentAttributes(users []string, roles []string, groups []string, out *iam.ListEntitiesForPolicyOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		uc := len(users)
		rc := len(roles)
		gc := len(groups)

		for _, u := range users {
			for _, pu := range out.PolicyUsers {
				if u == *pu.UserName {
					uc--
				}
			}
		}
		for _, r := range roles {
			for _, pr := range out.PolicyRoles {
				if r == *pr.RoleName {
					rc--
				}
			}
		}
		for _, g := range users {
			for _, pg := range out.PolicyGroups {
				if g == *pg.GroupName {
					gc--
				}
			}
		}
		if uc != 0 || rc != 0 || gc != 0 {
			return fmt.Errorf("Error: Number of attached users, roles, or groups was incorrect:\n expected %d users and found %d\nexpected %d roles and found %d\nexpected %d groups and found %d", len(users), (len(users) - uc), len(roles), (len(roles) - rc), len(groups), (len(groups) - gc))
		}
		return nil
	}
}

const testAccAWSPolicyAttachConfig = `
resource "aws_iam_user" "user" {
    name = "test-user"
}
resource "aws_iam_role" "role" {
    name = "test-role"
}
resource "aws_iam_group" "group" {
    name = "test-group"
}

resource "aws_iam_policy" "policy" {
    name = "test-policy"
    description = "A test policy"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy_attachment" "test-attach" {
    name = "test-attachment"
    users = ["${aws_iam_user.user.name}"]
    roles = ["${aws_iam_role.role.name}"]
    groups = ["${aws_iam_group.group.name}"]
    policy_arn = "${aws_iam_policy.policy.arn}"
}
`

const testAccAWSPolicyAttachConfigUpdate = `
resource "aws_iam_user" "user" {
    name = "test-user"
}
resource "aws_iam_user" "user2" {
    name = "test-user2"
}
resource "aws_iam_user" "user3" {
    name = "test-user3"
}
resource "aws_iam_role" "role" {
    name = "test-role"
}
resource "aws_iam_role" "role2" {
    name = "test-role2"
}
resource "aws_iam_role" "role3" {
    name = "test-role3"
}
resource "aws_iam_group" "group" {
    name = "test-group"
}
resource "aws_iam_group" "group2" {
    name = "test-group2"
}
resource "aws_iam_group" "group3" {
    name = "test-group3"
}

resource "aws_iam_policy" "policy" {
    name = "test-policy"
    description = "A test policy"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:ChangePassword"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy_attachment" "test-attach" {
    name = "test-attachment"
    users = [
        "${aws_iam_user.user2.name}",
        "${aws_iam_user.user3.name}"
    ]
    roles = [
        "${aws_iam_role.role2.name}",
        "${aws_iam_role.role3.name}"
    ]
    groups = [
        "${aws_iam_group.group2.name}",
        "${aws_iam_group.group3.name}"
    ]
    policy_arn = "${aws_iam_policy.policy.arn}"
}
`
<|endoftext|>


<commit_before>// +build e2e

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

package e2e

import (
	"strings"
	"testing"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/utils/pointer"
	eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1"
	"knative.dev/eventing/pkg/apis/eventing"
	"knative.dev/eventing/pkg/apis/eventing/v1beta1"
	"knative.dev/eventing/test/e2e/helpers"
	testlib "knative.dev/eventing/test/lib"
	"knative.dev/eventing/test/lib/resources"
)

// ChannelBasedBrokerCreator creates a BrokerCreator that creates a broker based on the channel parameter.
func ChannelBasedBrokerCreator(channel metav1.TypeMeta, brokerClass string) helpers.BrokerCreatorWithRetries {
	return func(client *testlib.Client, numRetries int32) string {
		brokerName := strings.ToLower(channel.Kind)

		// create a ConfigMap used by the broker.
		config := client.CreateBrokerConfigMapOrFail("config-"+brokerName, &channel)

		backoff := eventingduckv1beta1.BackoffPolicyLinear

		// create a new broker.
		client.CreateBrokerV1Beta1OrFail(brokerName,
			resources.WithBrokerClassForBrokerV1Beta1(brokerClass),
			resources.WithConfigForBrokerV1Beta1(config),
			func(broker *v1beta1.Broker) {
				broker.Spec.Delivery = &eventingduckv1beta1.DeliverySpec{
					Retry:         &numRetries,
					BackoffPolicy: &backoff,
					BackoffDelay:  pointer.StringPtr("PT1S"),
				}
			},
		)

		return brokerName
	}
}

func TestBrokerRedelivery(t *testing.T) {
	channelTestRunner.RunTests(t, testlib.FeatureRedelivery, func(t *testing.T, component metav1.TypeMeta) {

		brokerCreator := ChannelBasedBrokerCreator(component, eventing.MTChannelBrokerClassValue)

		helpers.BrokerRedelivery(t, brokerCreator)
	})
}
<commit_msg>Updating broker to be v1 in BrokerRedelivery test (#1511)<commit_after>// +build e2e

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

package e2e

import (
	"strings"
	"testing"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/utils/pointer"
	eventingduckv1 "knative.dev/eventing/pkg/apis/duck/v1"
	"knative.dev/eventing/pkg/apis/eventing"
	v1 "knative.dev/eventing/pkg/apis/eventing/v1"
	"knative.dev/eventing/test/e2e/helpers"
	testlib "knative.dev/eventing/test/lib"
	"knative.dev/eventing/test/lib/resources"
)

// ChannelBasedBrokerCreator creates a BrokerCreator that creates a broker based on the channel parameter.
func ChannelBasedBrokerCreator(channel metav1.TypeMeta, brokerClass string) helpers.BrokerCreatorWithRetries {
	return func(client *testlib.Client, numRetries int32) string {
		brokerName := strings.ToLower(channel.Kind)

		// create a ConfigMap used by the broker.
		config := client.CreateBrokerConfigMapOrFail("config-"+brokerName, &channel)

		backoff := eventingduckv1.BackoffPolicyLinear

		// create a new broker.
		client.CreateBrokerV1OrFail(brokerName,
			resources.WithBrokerClassForBrokerV1(brokerClass),
			resources.WithConfigForBrokerV1(config),
			func(broker *v1.Broker) {
				broker.Spec.Delivery = &eventingduckv1.DeliverySpec{
					Retry:         &numRetries,
					BackoffPolicy: &backoff,
					BackoffDelay:  pointer.StringPtr("PT1S"),
				}
			},
		)

		return brokerName
	}
}

func TestBrokerRedelivery(t *testing.T) {
	channelTestRunner.RunTests(t, testlib.FeatureRedelivery, func(t *testing.T, component metav1.TypeMeta) {

		brokerCreator := ChannelBasedBrokerCreator(component, eventing.MTChannelBrokerClassValue)

		helpers.BrokerRedelivery(t, brokerCreator)
	})
}
<|endoftext|>


<commit_before>package multisig

import (
	"encoding/json"
	"math/rand"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	cmn "github.com/tendermint/tendermint/libs/common"
)

func randCompactBitArray(bits int) (*CompactBitArray, []byte) {
	numBytes := (bits + 7) / 8
	src := cmn.RandBytes((bits + 7) / 8)
	bA := NewCompactBitArray(bits)

	for i := 0; i < numBytes-1; i++ {
		for j := uint8(0); j < 8; j++ {
			bA.SetIndex(i*8+int(j), src[i]&(uint8(1)<<(8-j)) > 0)
		}
	}
	// Set remaining bits
	for i := uint8(0); i < 8-uint8(bA.ExtraBitsStored); i++ {
		bA.SetIndex(numBytes*8+int(i), src[numBytes-1]&(uint8(1)<<(8-i)) > 0)
	}
	return bA, src
}

func TestNewBitArrayNeverCrashesOnNegatives(t *testing.T) {
	bitList := []int{-127, -128, -1 << 31}
	for _, bits := range bitList {
		_ = NewCompactBitArray(bits)
	}
}

func TestJSONMarshalUnmarshal(t *testing.T) {

	bA1 := NewCompactBitArray(0)
	bA2 := NewCompactBitArray(1)

	bA3 := NewCompactBitArray(1)
	bA3.SetIndex(0, true)

	bA4 := NewCompactBitArray(5)
	bA4.SetIndex(0, true)
	bA4.SetIndex(1, true)

	bA5 := NewCompactBitArray(9)
	bA5.SetIndex(0, true)
	bA5.SetIndex(1, true)
	bA5.SetIndex(8, true)

	bA6 := NewCompactBitArray(16)
	bA6.SetIndex(0, true)
	bA6.SetIndex(1, true)
	bA6.SetIndex(8, false)
	bA6.SetIndex(15, true)

	testCases := []struct {
		bA           *CompactBitArray
		marshalledBA string
	}{
		{nil, `null`},
		{bA1, `null`},
		{bA2, `"_"`},
		{bA3, `"x"`},
		{bA4, `"xx___"`},
		{bA5, `"xx______x"`},
		{bA6, `"xx_____________x"`},
	}

	for _, tc := range testCases {
		t.Run(tc.bA.String(), func(t *testing.T) {
			bz, err := json.Marshal(tc.bA)
			require.NoError(t, err)

			assert.Equal(t, tc.marshalledBA, string(bz))

			var unmarshalledBA *CompactBitArray
			err = json.Unmarshal(bz, &unmarshalledBA)
			require.NoError(t, err)

			if tc.bA == nil {
				require.Nil(t, unmarshalledBA)
			} else {
				require.NotNil(t, unmarshalledBA)
				assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
				if assert.EqualValues(t, tc.bA.String(), unmarshalledBA.String()) {
					assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
				}
			}
		})
	}
}

func TestCompactMarshalUnmarshal(t *testing.T) {
	bA1 := NewCompactBitArray(0)
	bA2 := NewCompactBitArray(1)

	bA3 := NewCompactBitArray(1)
	bA3.SetIndex(0, true)

	bA4 := NewCompactBitArray(5)
	bA4.SetIndex(0, true)
	bA4.SetIndex(1, true)

	bA5 := NewCompactBitArray(9)
	bA5.SetIndex(0, true)
	bA5.SetIndex(1, true)
	bA5.SetIndex(8, true)

	bA6 := NewCompactBitArray(16)
	bA6.SetIndex(0, true)
	bA6.SetIndex(1, true)
	bA6.SetIndex(8, false)
	bA6.SetIndex(15, true)

	testCases := []struct {
		bA           *CompactBitArray
		marshalledBA []byte
	}{
		{nil, []byte("null")},
		{bA1, []byte("null")},
		{bA2, []byte{byte(1), byte(0)}},
		{bA3, []byte{byte(1), byte(128)}},
		{bA4, []byte{byte(5), byte(192)}},
		{bA5, []byte{byte(9), byte(192), byte(128)}},
		{bA6, []byte{byte(16), byte(192), byte(1)}},
	}

	for _, tc := range testCases {
		t.Run(tc.bA.String(), func(t *testing.T) {
			bz := tc.bA.CompactMarshal()

			assert.Equal(t, tc.marshalledBA, bz)

			unmarshalledBA, err := CompactUnmarshal(bz)
			require.NoError(t, err)
			if tc.bA == nil {
				require.Nil(t, unmarshalledBA)
			} else {
				require.NotNil(t, unmarshalledBA)
				assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
				if assert.EqualValues(t, tc.bA.String(), unmarshalledBA.String()) {
					assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
				}
			}
		})
	}
}

func TestCompactBitArrayNumOfTrueBitsBefore(t *testing.T) {
	testCases := []struct {
		marshalledBA   string
		bAIndex        []int
		trueValueIndex []int
	}{
		{`"_____"`, []int{0, 1, 2, 3, 4}, []int{0, 0, 0, 0, 0}},
		{`"x"`, []int{0}, []int{0}},
		{`"_x"`, []int{1}, []int{0}},
		{`"x___xxxx"`, []int{0, 4, 5, 6, 7}, []int{0, 1, 2, 3, 4}},
		{`"__x_xx_x__x_x___"`, []int{2, 4, 5, 7, 10, 12}, []int{0, 1, 2, 3, 4, 5}},
		{`"______________xx"`, []int{14, 15}, []int{0, 1}},
	}
	for tcIndex, tc := range testCases {
		t.Run(tc.marshalledBA, func(t *testing.T) {
			var bA *CompactBitArray
			err := json.Unmarshal([]byte(tc.marshalledBA), &bA)
			require.NoError(t, err)

			for i := 0; i < len(tc.bAIndex); i++ {
				require.Equal(t, tc.trueValueIndex[i], bA.NumOfTrueBitsBefore(tc.bAIndex[i]), "tc %d, i %d", tcIndex, i)
			}
		})
	}
}

func TestCompactBitArrayGetSetIndex(t *testing.T) {
	r := rand.New(rand.NewSource(100))
	numTests := 10
	numBitsPerArr := 100
	for i := 0; i < numTests; i++ {
		bits := r.Intn(1000)
		bA, _ := randCompactBitArray(bits)

		for j := 0; j < numBitsPerArr; j++ {
			copy := bA.Copy()
			index := r.Intn(bits)
			val := (r.Int63() % 2) == 0
			bA.SetIndex(index, val)
			require.Equal(t, val, bA.GetIndex(index), "bA.SetIndex(%d, %v) failed on bit array: %s", index, val, copy)
		}
	}
}
<commit_msg>(squash this) Fix build errors<commit_after>package multisig

import (
	"encoding/json"
	"math/rand"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	cmn "github.com/tendermint/tendermint/libs/common"
)

func randCompactBitArray(bits int) (*CompactBitArray, []byte) {
	numBytes := (bits + 7) / 8
	src := cmn.RandBytes((bits + 7) / 8)
	bA := NewCompactBitArray(bits)

	for i := 0; i < numBytes-1; i++ {
		for j := uint8(0); j < 8; j++ {
			bA.SetIndex(i*8+int(j), src[i]&(uint8(1)<<(8-j)) > 0)
		}
	}
	// Set remaining bits
	for i := uint8(0); i < 8-uint8(bA.ExtraBitsStored); i++ {
		bA.SetIndex(numBytes*8+int(i), src[numBytes-1]&(uint8(1)<<(8-i)) > 0)
	}
	return bA, src
}

func TestNewBitArrayNeverCrashesOnNegatives(t *testing.T) {
	bitList := []int{-127, -128, -1 << 31}
	for _, bits := range bitList {
		_ = NewCompactBitArray(bits)
	}
}

func TestJSONMarshalUnmarshal(t *testing.T) {

	bA1 := NewCompactBitArray(0)
	bA2 := NewCompactBitArray(1)

	bA3 := NewCompactBitArray(1)
	bA3.SetIndex(0, true)

	bA4 := NewCompactBitArray(5)
	bA4.SetIndex(0, true)
	bA4.SetIndex(1, true)

	bA5 := NewCompactBitArray(9)
	bA5.SetIndex(0, true)
	bA5.SetIndex(1, true)
	bA5.SetIndex(8, true)

	bA6 := NewCompactBitArray(16)
	bA6.SetIndex(0, true)
	bA6.SetIndex(1, true)
	bA6.SetIndex(8, false)
	bA6.SetIndex(15, true)

	testCases := []struct {
		bA           *CompactBitArray
		marshalledBA string
	}{
		{nil, `null`},
		{bA1, `null`},
		{bA2, `"_"`},
		{bA3, `"x"`},
		{bA4, `"xx___"`},
		{bA5, `"xx______x"`},
		{bA6, `"xx_____________x"`},
	}

	for _, tc := range testCases {
		t.Run(tc.bA.String(), func(t *testing.T) {
			bz, err := json.Marshal(tc.bA)
			require.NoError(t, err)

			assert.Equal(t, tc.marshalledBA, string(bz))

			var unmarshalledBA *CompactBitArray
			err = json.Unmarshal(bz, &unmarshalledBA)
			require.NoError(t, err)

			if tc.bA == nil {
				require.Nil(t, unmarshalledBA)
			} else {
				require.NotNil(t, unmarshalledBA)
				assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
				if assert.EqualValues(t, tc.bA.String(), unmarshalledBA.String()) {
					assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
				}
			}
		})
	}
}

func TestCompactMarshalUnmarshal(t *testing.T) {
	bA1 := NewCompactBitArray(0)
	bA2 := NewCompactBitArray(1)

	bA3 := NewCompactBitArray(1)
	bA3.SetIndex(0, true)

	bA4 := NewCompactBitArray(5)
	bA4.SetIndex(0, true)
	bA4.SetIndex(1, true)

	bA5 := NewCompactBitArray(9)
	bA5.SetIndex(0, true)
	bA5.SetIndex(1, true)
	bA5.SetIndex(8, true)

	bA6 := NewCompactBitArray(16)
	bA6.SetIndex(0, true)
	bA6.SetIndex(1, true)
	bA6.SetIndex(8, false)
	bA6.SetIndex(15, true)

	testCases := []struct {
		bA           *CompactBitArray
		marshalledBA []byte
	}{
		{nil, []byte("null")},
		{bA1, []byte("null")},
		{bA2, []byte{byte(1), byte(0)}},
		{bA3, []byte{byte(1), byte(128)}},
		{bA4, []byte{byte(5), byte(192)}},
		{bA5, []byte{byte(9), byte(192), byte(128)}},
		{bA6, []byte{byte(16), byte(192), byte(1)}},
	}

	for _, tc := range testCases {
		t.Run(tc.bA.String(), func(t *testing.T) {
			bz := tc.bA.CompactMarshal()

			assert.Equal(t, tc.marshalledBA, bz)

			unmarshalledBA, err := CompactUnmarshal(bz)
			require.NoError(t, err)
			if tc.bA == nil {
				require.Nil(t, unmarshalledBA)
			} else {
				require.NotNil(t, unmarshalledBA)
				assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
				if assert.EqualValues(t, tc.bA.String(), unmarshalledBA.String()) {
					assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
				}
			}
		})
	}
}

func TestCompactBitArrayNumOfTrueBitsBefore(t *testing.T) {
	testCases := []struct {
		marshalledBA   string
		bAIndex        []int
		trueValueIndex []int
	}{
		{`"_____"`, []int{0, 1, 2, 3, 4}, []int{0, 0, 0, 0, 0}},
		{`"x"`, []int{0}, []int{0}},
		{`"_x"`, []int{1}, []int{0}},
		{`"x___xxxx"`, []int{0, 4, 5, 6, 7}, []int{0, 1, 2, 3, 4}},
		{`"__x_xx_x__x_x___"`, []int{2, 4, 5, 7, 10, 12}, []int{0, 1, 2, 3, 4, 5}},
		{`"______________xx"`, []int{14, 15}, []int{0, 1}},
	}
	for tcIndex, tc := range testCases {
		t.Run(tc.marshalledBA, func(t *testing.T) {
			var bA *CompactBitArray
			err := json.Unmarshal([]byte(tc.marshalledBA), &bA)
			require.NoError(t, err)

			for i := 0; i < len(tc.bAIndex); i++ {
				require.Equal(t, tc.trueValueIndex[i], bA.NumTrueBitsBefore(tc.bAIndex[i]), "tc %d, i %d", tcIndex, i)
			}
		})
	}
}

func TestCompactBitArrayGetSetIndex(t *testing.T) {
	r := rand.New(rand.NewSource(100))
	numTests := 10
	numBitsPerArr := 100
	for i := 0; i < numTests; i++ {
		bits := r.Intn(1000)
		bA, _ := randCompactBitArray(bits)

		for j := 0; j < numBitsPerArr; j++ {
			copy := bA.Copy()
			index := r.Intn(bits)
			val := (r.Int63() % 2) == 0
			bA.SetIndex(index, val)
			require.Equal(t, val, bA.GetIndex(index), "bA.SetIndex(%d, %v) failed on bit array: %s", index, val, copy)
		}
	}
}
<|endoftext|>


<commit_before>package rafttest

import (
	"log"
	"time"

	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/raft/raftpb"
)

type node struct {
	raft.Node
	id     uint64
	iface  iface
	stopc  chan struct{}
	pausec chan bool

	// stable
	storage *raft.MemoryStorage
	state   raftpb.HardState
}

func startNode(id uint64, peers []raft.Peer, iface iface) *node {
	st := raft.NewMemoryStorage()
	rn := raft.StartNode(id, peers, 10, 1, st)
	n := &node{
		Node:    rn,
		id:      id,
		storage: st,
		iface:   iface,
		pausec:  make(chan bool),
	}
	n.start()
	return n
}

func (n *node) start() {
	n.stopc = make(chan struct{})
	ticker := time.Tick(5 * time.Millisecond)

	go func() {
		for {
			select {
			case <-ticker:
				n.Tick()
			case rd := <-n.Ready():
				if !raft.IsEmptyHardState(rd.HardState) {
					n.state = rd.HardState
					n.storage.SetHardState(n.state)
				}
				n.storage.Append(rd.Entries)
				// TODO: make send async, more like real world...
				for _, m := range rd.Messages {
					n.iface.send(m)
				}
				n.Advance()
			case m := <-n.iface.recv():
				n.Step(context.TODO(), m)
			case <-n.stopc:
				n.Stop()
				raftLogger.Infof("raft.%d: stop", n.id)
				n.Node = nil
				close(n.stopc)
				return
			case p := <-n.pausec:
				recvms := make([]raftpb.Message, 0)
				for p {
					select {
					case m := <-n.iface.recv():
						recvms = append(recvms, m)
					case p = <-n.pausec:
					}
				}
				// step all pending messages
				for _, m := range recvms {
					n.Step(context.TODO(), m)
				}
			}
		}
	}()
}

// stop stops the node. stop a stopped node might panic.
// All in memory state of node is discarded.
// All stable MUST be unchanged.
func (n *node) stop() {
	n.iface.disconnect()
	n.stopc <- struct{}{}
	// wait for the shutdown
	<-n.stopc
}

// restart restarts the node. restart a started node
// blocks and might affect the future stop operation.
func (n *node) restart() {
	// wait for the shutdown
	<-n.stopc
	n.Node = raft.RestartNode(n.id, 10, 1, n.storage, 0)
	n.start()
	n.iface.connect()
}

// pause pauses the node.
// The paused node buffers the received messages and replies
// all of them when it resumes.
func (n *node) pause() {
	n.pausec <- true
}

// resume resumes the paused node.
func (n *node) resume() {
	n.pausec <- false
}
<commit_msg>rafttest: fix build error<commit_after>package rafttest

import (
	"log"
	"time"

	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/raft/raftpb"
)

type node struct {
	raft.Node
	id     uint64
	iface  iface
	stopc  chan struct{}
	pausec chan bool

	// stable
	storage *raft.MemoryStorage
	state   raftpb.HardState
}

func startNode(id uint64, peers []raft.Peer, iface iface) *node {
	st := raft.NewMemoryStorage()
	rn := raft.StartNode(id, peers, 10, 1, st)
	n := &node{
		Node:    rn,
		id:      id,
		storage: st,
		iface:   iface,
		pausec:  make(chan bool),
	}
	n.start()
	return n
}

func (n *node) start() {
	n.stopc = make(chan struct{})
	ticker := time.Tick(5 * time.Millisecond)

	go func() {
		for {
			select {
			case <-ticker:
				n.Tick()
			case rd := <-n.Ready():
				if !raft.IsEmptyHardState(rd.HardState) {
					n.state = rd.HardState
					n.storage.SetHardState(n.state)
				}
				n.storage.Append(rd.Entries)
				// TODO: make send async, more like real world...
				for _, m := range rd.Messages {
					n.iface.send(m)
				}
				n.Advance()
			case m := <-n.iface.recv():
				n.Step(context.TODO(), m)
			case <-n.stopc:
				n.Stop()
				log.Printf("raft.%d: stop", n.id)
				n.Node = nil
				close(n.stopc)
				return
			case p := <-n.pausec:
				recvms := make([]raftpb.Message, 0)
				for p {
					select {
					case m := <-n.iface.recv():
						recvms = append(recvms, m)
					case p = <-n.pausec:
					}
				}
				// step all pending messages
				for _, m := range recvms {
					n.Step(context.TODO(), m)
				}
			}
		}
	}()
}

// stop stops the node. stop a stopped node might panic.
// All in memory state of node is discarded.
// All stable MUST be unchanged.
func (n *node) stop() {
	n.iface.disconnect()
	n.stopc <- struct{}{}
	// wait for the shutdown
	<-n.stopc
}

// restart restarts the node. restart a started node
// blocks and might affect the future stop operation.
func (n *node) restart() {
	// wait for the shutdown
	<-n.stopc
	n.Node = raft.RestartNode(n.id, 10, 1, n.storage, 0)
	n.start()
	n.iface.connect()
}

// pause pauses the node.
// The paused node buffers the received messages and replies
// all of them when it resumes.
func (n *node) pause() {
	n.pausec <- true
}

// resume resumes the paused node.
func (n *node) resume() {
	n.pausec <- false
}
<|endoftext|>


<commit_before>package server

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

// Version of IronFunctions
var Version = "0.0.45"

func handleVersion(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{"version": Version})
}
<commit_msg>functions: 0.0.46 release [skip ci]<commit_after>package server

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

// Version of IronFunctions
var Version = "0.0.46"

func handleVersion(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{"version": Version})
}
<|endoftext|>


<commit_before>package connections

import (
	"sync"
	"testing"

	"github.com/sirupsen/logrus/hooks/test"
	"github.com/stretchr/testify/require"
)

func Test_ConnectionGroupManager_Add_GeneratesValidIDs(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups:      map[int]*ConnectionGroup{},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  0,
		logger:      logger,
	}

	for i := 0; i < groupLimit; i++ {
		id, err := m.Add(&ConnectionGroup{
			limit:      connsLimit / groupLimit,
			counterMux: &sync.RWMutex{},
			game:       nil,
			broadcast:  nil,
			logger:     logger,
			chs:        nil,
			chsMux:     nil,
			stop:       nil,
			stopper:    nil,
		})
		require.Equal(t, m.connsCount, (1+i)*(connsLimit/groupLimit), "unexpected conns count")
		require.Equal(t, i+firstGroupId, id, "unexpected group id")
		require.Nil(t, err, "unexpected error")
	}
}

func Test_ConnectionGroupManager_Add_GetErrGroupLimitReached(t *testing.T) {
	const groupLimit = 2
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			1: {
				limit:      connsLimit / groupLimit,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
			2: {
				limit:      connsLimit / groupLimit,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		logger:      logger,
	}

	id, err := m.Add(&ConnectionGroup{
		limit:      1,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	})

	require.Zero(t, id)
	require.Equal(t, ErrGroupLimitReached, err)
}

func Test_ConnectionGroupManager_Add_GetErrConnsLimitReached(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			1: {
				limit:      50,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
			2: {
				limit:      50,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  connsLimit,
		logger:      logger,
	}

	id, err := m.Add(&ConnectionGroup{
		limit:      10,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	})

	require.Zero(t, id)
	require.Equal(t, ErrConnsLimitReached, err)
}

func Test_ConnectionGroupManager_Add_AddOneGroupGetValidID(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			1: {
				limit:      10,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
			2: {
				limit:      10,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  20,
		logger:      logger,
	}

	id, err := m.Add(&ConnectionGroup{
		limit:      10,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	})

	require.Equal(t, 3, id)
	require.Equal(t, 30, m.connsCount)
	require.Nil(t, err)
}

func Test_ConnectionGroupManager_Add_InsertOneGroupGetValidID(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			1: {
				limit:      10,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
			3: {
				limit:      10,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  20,
		logger:      logger,
	}

	id, err := m.Add(&ConnectionGroup{
		limit:      10,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	})

	require.Equal(t, 2, id)
	require.Equal(t, 30, m.connsCount)
	require.Nil(t, err)
}

func Test_ConnectionGroupManager_Delete_DeleteNotFoundGroup(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups:      map[int]*ConnectionGroup{},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  0,
		logger:      logger,
	}

	err := m.Delete(&ConnectionGroup{
		limit:      10,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	})

	require.Equal(t, ErrDeleteNotFoundGroup, err)
}

func Test_ConnectionGroupManager_Delete_MethodDeletesGroupSuccessfully(t *testing.T) {
	const (
		groupLimit = 10
		connsLimit = 100
		groupID    = 2
	)

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	group := &ConnectionGroup{
		limit:      10,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	}

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			groupID: group,
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  10,
		logger:      logger,
	}

	err := m.Delete(group)

	require.Nil(t, err)
	require.Zero(t, m.connsCount)
	require.Empty(t, m.groups)
}
<commit_msg>Create test for connection group manager for case of returning valid group count<commit_after>package connections

import (
	"sync"
	"testing"

	"github.com/sirupsen/logrus/hooks/test"
	"github.com/stretchr/testify/require"
)

func Test_ConnectionGroupManager_Add_GeneratesValidIDs(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups:      map[int]*ConnectionGroup{},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  0,
		logger:      logger,
	}

	for i := 0; i < groupLimit; i++ {
		id, err := m.Add(&ConnectionGroup{
			limit:      connsLimit / groupLimit,
			counterMux: &sync.RWMutex{},
			game:       nil,
			broadcast:  nil,
			logger:     logger,
			chs:        nil,
			chsMux:     nil,
			stop:       nil,
			stopper:    nil,
		})
		require.Equal(t, m.connsCount, (1+i)*(connsLimit/groupLimit), "unexpected conns count")
		require.Equal(t, i+firstGroupId, id, "unexpected group id")
		require.Nil(t, err, "unexpected error")
	}
}

func Test_ConnectionGroupManager_Add_GetErrGroupLimitReached(t *testing.T) {
	const groupLimit = 2
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			1: {
				limit:      connsLimit / groupLimit,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
			2: {
				limit:      connsLimit / groupLimit,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		logger:      logger,
	}

	id, err := m.Add(&ConnectionGroup{
		limit:      1,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	})

	require.Zero(t, id)
	require.Equal(t, ErrGroupLimitReached, err)
}

func Test_ConnectionGroupManager_Add_GetErrConnsLimitReached(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			1: {
				limit:      50,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
			2: {
				limit:      50,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  connsLimit,
		logger:      logger,
	}

	id, err := m.Add(&ConnectionGroup{
		limit:      10,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	})

	require.Zero(t, id)
	require.Equal(t, ErrConnsLimitReached, err)
}

func Test_ConnectionGroupManager_Add_AddOneGroupGetValidID(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			1: {
				limit:      10,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
			2: {
				limit:      10,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  20,
		logger:      logger,
	}

	id, err := m.Add(&ConnectionGroup{
		limit:      10,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	})

	require.Equal(t, 3, id)
	require.Equal(t, 30, m.connsCount)
	require.Nil(t, err)
}

func Test_ConnectionGroupManager_Add_InsertOneGroupGetValidID(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			1: {
				limit:      10,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
			3: {
				limit:      10,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  20,
		logger:      logger,
	}

	id, err := m.Add(&ConnectionGroup{
		limit:      10,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	})

	require.Equal(t, 2, id)
	require.Equal(t, 30, m.connsCount)
	require.Nil(t, err)
}

func Test_ConnectionGroupManager_Delete_DeleteNotFoundGroup(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups:      map[int]*ConnectionGroup{},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  0,
		logger:      logger,
	}

	err := m.Delete(&ConnectionGroup{
		limit:      10,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	})

	require.Equal(t, ErrDeleteNotFoundGroup, err)
}

func Test_ConnectionGroupManager_Delete_MethodDeletesGroupSuccessfully(t *testing.T) {
	const (
		groupLimit = 10
		connsLimit = 100
		groupID    = 2
	)

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	group := &ConnectionGroup{
		limit:      10,
		counterMux: &sync.RWMutex{},
		game:       nil,
		broadcast:  nil,
		logger:     logger,
		chs:        nil,
		chsMux:     nil,
		stop:       nil,
		stopper:    nil,
	}

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			groupID: group,
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  10,
		logger:      logger,
	}

	err := m.Delete(group)

	require.Nil(t, err)
	require.Zero(t, m.connsCount)
	require.Empty(t, m.groups)
}

func Test_ConnectionGroupManager_GroupCount_ReturnsValidGroupCount(t *testing.T) {
	const groupLimit = 10
	const connsLimit = 100

	logger, hook := test.NewNullLogger()
	defer hook.Reset()

	m := &ConnectionGroupManager{
		groups: map[int]*ConnectionGroup{
			1: {
				limit:      10,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
			3: {
				limit:      10,
				counterMux: &sync.RWMutex{},
				game:       nil,
				broadcast:  nil,
				logger:     logger,
				chs:        nil,
				chsMux:     nil,
				stop:       nil,
				stopper:    nil,
			},
		},
		groupsMutex: &sync.RWMutex{},
		groupLimit:  groupLimit,
		connsLimit:  connsLimit,
		connsCount:  20,
		logger:      logger,
	}

	actualCount := m.GroupCount()

	require.Equal(t, 2, actualCount)
}
<|endoftext|>


<commit_before>// Copyright 2012 tsuru 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 main

import (
	"flag"
	"github.com/bmizerany/pat"
	"github.com/globocom/config"
	"github.com/globocom/tsuru/api/app"
	"github.com/globocom/tsuru/api/auth"
	"github.com/globocom/tsuru/api/service/consumption"
	"github.com/globocom/tsuru/api/service/provision"
	"github.com/globocom/tsuru/db"
	"github.com/globocom/tsuru/log"
	stdlog "log"
	"log/syslog"
	"net/http"
)

func fatal(err error) {
	fmt.Fprintln(os.Stderr, err)
	log.Fatal(err)
}

func main() {
	logger, err := syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		stdlog.Fatal(err)
	}
	log.SetLogger(logger)
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadConfigFile(*configFile)
	if err != nil {
		fatal(err)
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		fatal(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		fatal(err)
	}
	db.Session, err = db.Open(connString, dbName)
	if err != nil {
		fatal(err)
	}
	defer db.Session.Close()

	m := pat.New()

	m.Get("/services/instances", AuthorizationRequiredHandler(consumption.ServicesInstancesHandler))
	m.Post("/services/instances", AuthorizationRequiredHandler(consumption.CreateInstanceHandler))
	m.Put("/services/instances/:instance/:app", AuthorizationRequiredHandler(app.BindHandler))
	m.Del("/services/instances/:instance/:app", AuthorizationRequiredHandler(app.UnbindHandler))
	m.Del("/services/c/instances/:name", AuthorizationRequiredHandler(consumption.RemoveServiceInstanceHandler))
	m.Get("/services/instances/:instance/status", AuthorizationRequiredHandler(consumption.ServiceInstanceStatusHandler))

	m.Get("/services", AuthorizationRequiredHandler(provision.ServicesHandler))
	m.Post("/services", AuthorizationRequiredHandler(provision.CreateHandler))
	m.Put("/services", AuthorizationRequiredHandler(provision.UpdateHandler))
	m.Del("/services/:name", AuthorizationRequiredHandler(provision.DeleteHandler))
	m.Get("/services/:name", AuthorizationRequiredHandler(consumption.ServiceInfoHandler))
	m.Get("/services/c/:name/doc", AuthorizationRequiredHandler(consumption.Doc))
	m.Get("/services/:name/doc", AuthorizationRequiredHandler(provision.GetDocHandler))
	m.Put("/services/:name/doc", AuthorizationRequiredHandler(provision.AddDocHandler))
	m.Put("/services/:service/:team", AuthorizationRequiredHandler(provision.GrantAccessToTeamHandler))
	m.Del("/services/:service/:team", AuthorizationRequiredHandler(provision.RevokeAccessFromTeamHandler))

	m.Del("/apps/:name", AuthorizationRequiredHandler(app.AppDelete))
	m.Get("/apps/:name/repository/clone", Handler(app.CloneRepositoryHandler))
	m.Get("/apps/:name/avaliable", Handler(app.AppIsAvaliableHandler))
	m.Get("/apps/:name", AuthorizationRequiredHandler(app.AppInfo))
	m.Post("/apps/:name/run", AuthorizationRequiredHandler(app.RunCommand))
	m.Get("/apps/:name/restart", AuthorizationRequiredHandler(app.RestartHandler))
	m.Get("/apps/:name/env", AuthorizationRequiredHandler(app.GetEnv))
	m.Post("/apps/:name/env", AuthorizationRequiredHandler(app.SetEnv))
	m.Del("/apps/:name/env", AuthorizationRequiredHandler(app.UnsetEnv))
	m.Get("/apps", AuthorizationRequiredHandler(app.AppList))
	m.Post("/apps", AuthorizationRequiredHandler(app.CreateAppHandler))
	m.Put("/apps/:app/:team", AuthorizationRequiredHandler(app.GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", AuthorizationRequiredHandler(app.RevokeAccessFromTeamHandler))
	m.Get("/apps/:name/log", AuthorizationRequiredHandler(app.AppLog))
	m.Post("/apps/:name/log", Handler(app.AddLogHandler))

	m.Post("/users", Handler(auth.CreateUser))
	m.Post("/users/:email/tokens", Handler(auth.Login))
	m.Del("/users", AuthorizationRequiredHandler(auth.RemoveUser))
	m.Post("/users/keys", AuthorizationRequiredHandler(auth.AddKeyToUser))
	m.Del("/users/keys", AuthorizationRequiredHandler(auth.RemoveKeyFromUser))

	m.Get("/teams", AuthorizationRequiredHandler(auth.ListTeams))
	m.Post("/teams", AuthorizationRequiredHandler(auth.CreateTeam))
	m.Del("/teams/:name", AuthorizationRequiredHandler(auth.RemoveTeam))
	m.Put("/teams/:team/:user", AuthorizationRequiredHandler(auth.AddUserToTeam))
	m.Del("/teams/:team/:user", AuthorizationRequiredHandler(auth.RemoveUserFromTeam))

	if !*dry {
		listen, err := config.GetString("listen")
		if err != nil {
			fatal(err)
		}
		fatal(http.ListenAndServe(listen, m))
	}
}
<commit_msg>api/webserver: fix compilation<commit_after>// Copyright 2012 tsuru 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 main

import (
	"flag"
	"fmt"
	"github.com/bmizerany/pat"
	"github.com/globocom/config"
	"github.com/globocom/tsuru/api/app"
	"github.com/globocom/tsuru/api/auth"
	"github.com/globocom/tsuru/api/service/consumption"
	"github.com/globocom/tsuru/api/service/provision"
	"github.com/globocom/tsuru/db"
	"github.com/globocom/tsuru/log"
	stdlog "log"
	"log/syslog"
	"net/http"
	"os"
)

func fatal(err error) {
	fmt.Fprintln(os.Stderr, err)
	log.Fatal(err)
}

func main() {
	logger, err := syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		stdlog.Fatal(err)
	}
	log.SetLogger(logger)
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadConfigFile(*configFile)
	if err != nil {
		fatal(err)
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		fatal(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		fatal(err)
	}
	db.Session, err = db.Open(connString, dbName)
	if err != nil {
		fatal(err)
	}
	defer db.Session.Close()

	m := pat.New()

	m.Get("/services/instances", AuthorizationRequiredHandler(consumption.ServicesInstancesHandler))
	m.Post("/services/instances", AuthorizationRequiredHandler(consumption.CreateInstanceHandler))
	m.Put("/services/instances/:instance/:app", AuthorizationRequiredHandler(app.BindHandler))
	m.Del("/services/instances/:instance/:app", AuthorizationRequiredHandler(app.UnbindHandler))
	m.Del("/services/c/instances/:name", AuthorizationRequiredHandler(consumption.RemoveServiceInstanceHandler))
	m.Get("/services/instances/:instance/status", AuthorizationRequiredHandler(consumption.ServiceInstanceStatusHandler))

	m.Get("/services", AuthorizationRequiredHandler(provision.ServicesHandler))
	m.Post("/services", AuthorizationRequiredHandler(provision.CreateHandler))
	m.Put("/services", AuthorizationRequiredHandler(provision.UpdateHandler))
	m.Del("/services/:name", AuthorizationRequiredHandler(provision.DeleteHandler))
	m.Get("/services/:name", AuthorizationRequiredHandler(consumption.ServiceInfoHandler))
	m.Get("/services/c/:name/doc", AuthorizationRequiredHandler(consumption.Doc))
	m.Get("/services/:name/doc", AuthorizationRequiredHandler(provision.GetDocHandler))
	m.Put("/services/:name/doc", AuthorizationRequiredHandler(provision.AddDocHandler))
	m.Put("/services/:service/:team", AuthorizationRequiredHandler(provision.GrantAccessToTeamHandler))
	m.Del("/services/:service/:team", AuthorizationRequiredHandler(provision.RevokeAccessFromTeamHandler))

	m.Del("/apps/:name", AuthorizationRequiredHandler(app.AppDelete))
	m.Get("/apps/:name/repository/clone", Handler(app.CloneRepositoryHandler))
	m.Get("/apps/:name/avaliable", Handler(app.AppIsAvaliableHandler))
	m.Get("/apps/:name", AuthorizationRequiredHandler(app.AppInfo))
	m.Post("/apps/:name/run", AuthorizationRequiredHandler(app.RunCommand))
	m.Get("/apps/:name/restart", AuthorizationRequiredHandler(app.RestartHandler))
	m.Get("/apps/:name/env", AuthorizationRequiredHandler(app.GetEnv))
	m.Post("/apps/:name/env", AuthorizationRequiredHandler(app.SetEnv))
	m.Del("/apps/:name/env", AuthorizationRequiredHandler(app.UnsetEnv))
	m.Get("/apps", AuthorizationRequiredHandler(app.AppList))
	m.Post("/apps", AuthorizationRequiredHandler(app.CreateAppHandler))
	m.Put("/apps/:app/:team", AuthorizationRequiredHandler(app.GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", AuthorizationRequiredHandler(app.RevokeAccessFromTeamHandler))
	m.Get("/apps/:name/log", AuthorizationRequiredHandler(app.AppLog))
	m.Post("/apps/:name/log", Handler(app.AddLogHandler))

	m.Post("/users", Handler(auth.CreateUser))
	m.Post("/users/:email/tokens", Handler(auth.Login))
	m.Del("/users", AuthorizationRequiredHandler(auth.RemoveUser))
	m.Post("/users/keys", AuthorizationRequiredHandler(auth.AddKeyToUser))
	m.Del("/users/keys", AuthorizationRequiredHandler(auth.RemoveKeyFromUser))

	m.Get("/teams", AuthorizationRequiredHandler(auth.ListTeams))
	m.Post("/teams", AuthorizationRequiredHandler(auth.CreateTeam))
	m.Del("/teams/:name", AuthorizationRequiredHandler(auth.RemoveTeam))
	m.Put("/teams/:team/:user", AuthorizationRequiredHandler(auth.AddUserToTeam))
	m.Del("/teams/:team/:user", AuthorizationRequiredHandler(auth.RemoveUserFromTeam))

	if !*dry {
		listen, err := config.GetString("listen")
		if err != nil {
			fatal(err)
		}
		fatal(http.ListenAndServe(listen, m))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/bmizerany/pat"
	"github.com/timeredbull/tsuru/api/app"
	"github.com/timeredbull/tsuru/api/auth"
	"github.com/timeredbull/tsuru/api/service"
	"github.com/timeredbull/tsuru/config"
	"github.com/timeredbull/tsuru/db"
	"github.com/timeredbull/tsuru/log"
	"github.com/timeredbull/tsuru/repository"
	stdlog "log"
	"log/syslog"
	"net/http"
)

func main() {
	var err error
	log.Target, err = syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		panic(err)
	}
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadConfigFile(*configFile)
	if err != nil {
		log.Panic(err.Error())
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		panic(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		panic(err)
	}
	db.Session, err = db.Open(connString, dbName)
	if err != nil {
		log.Panic(err.Error())
	}
	defer db.Session.Close()

	repository.RunAgent()
	m := pat.New()

	m.Post("/services", AuthorizationRequiredHandler(service.CreateHandler))
	m.Get("/services", AuthorizationRequiredHandler(service.ServicesHandler))
	m.Del("/services/:name", AuthorizationRequiredHandler(service.DeleteHandler))
	// m.Post("/services/bind", AuthorizationRequiredHandler(service.BindHandler))
	// m.Post("/services/unbind", AuthorizationRequiredHandler(service.UnbindHandler))
	m.Put("/services/:service/:team", AuthorizationRequiredHandler(service.GrantAccessToTeamHandler))
	m.Del("/services/:service/:team", AuthorizationRequiredHandler(service.RevokeAccessFromTeamHandler))

	m.Del("/apps/:name", AuthorizationRequiredHandler(app.AppDelete))
	m.Get("/apps/:name/repository/clone", Handler(app.CloneRepositoryHandler))
	m.Get("/apps/:name", AuthorizationRequiredHandler(app.AppInfo))
	m.Post("/apps/:name/run", AuthorizationRequiredHandler(app.RunCommand))
	m.Get("/apps/:name/env", AuthorizationRequiredHandler(app.GetEnv))
	m.Post("/apps/:name/env", AuthorizationRequiredHandler(app.SetEnv))
	m.Del("/apps/:name/env", AuthorizationRequiredHandler(app.UnsetEnv))
	m.Get("/apps", AuthorizationRequiredHandler(app.AppList))
	m.Post("/apps", AuthorizationRequiredHandler(app.CreateAppHandler))
	m.Put("/apps/:app/:team", AuthorizationRequiredHandler(app.GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", AuthorizationRequiredHandler(app.RevokeAccessFromTeamHandler))
	m.Get("/apps/:name/log", AuthorizationRequiredHandler(app.AppLog))

	m.Post("/users", Handler(auth.CreateUser))
	m.Post("/users/:email/tokens", Handler(auth.Login))
	m.Post("/users/keys", AuthorizationRequiredHandler(auth.AddKeyToUser))
	m.Del("/users/keys", AuthorizationRequiredHandler(auth.RemoveKeyFromUser))

	m.Post("/teams", AuthorizationRequiredHandler(auth.CreateTeam))
	m.Put("/teams/:team/:user", AuthorizationRequiredHandler(auth.AddUserToTeam))
	m.Del("/teams/:team/:user", AuthorizationRequiredHandler(auth.RemoveUserFromTeam))

	listen, err := config.GetString("listen")
	if err != nil {
		panic(err)
	}
	if !*dry {
		log.Fatal(http.ListenAndServe(listen, m))
	}
}
<commit_msg>api/webserver: register ListServiceInstances handler<commit_after>package main

import (
	"flag"
	"github.com/bmizerany/pat"
	"github.com/timeredbull/tsuru/api/app"
	"github.com/timeredbull/tsuru/api/auth"
	"github.com/timeredbull/tsuru/api/service"
	"github.com/timeredbull/tsuru/config"
	"github.com/timeredbull/tsuru/db"
	"github.com/timeredbull/tsuru/log"
	"github.com/timeredbull/tsuru/repository"
	stdlog "log"
	"log/syslog"
	"net/http"
)

func main() {
	var err error
	log.Target, err = syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		panic(err)
	}
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadConfigFile(*configFile)
	if err != nil {
		log.Panic(err.Error())
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		panic(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		panic(err)
	}
	db.Session, err = db.Open(connString, dbName)
	if err != nil {
		log.Panic(err.Error())
	}
	defer db.Session.Close()

	repository.RunAgent()
	m := pat.New()

	m.Get("/services/instances", AuthorizationRequiredHandler(service.ListServiceInstances))

	m.Post("/services", AuthorizationRequiredHandler(service.CreateHandler))
	m.Get("/services", AuthorizationRequiredHandler(service.ServicesHandler))
	m.Del("/services/:name", AuthorizationRequiredHandler(service.DeleteHandler))
	// m.Post("/services/bind", AuthorizationRequiredHandler(service.BindHandler))
	// m.Post("/services/unbind", AuthorizationRequiredHandler(service.UnbindHandler))
	m.Put("/services/:service/:team", AuthorizationRequiredHandler(service.GrantAccessToTeamHandler))
	m.Del("/services/:service/:team", AuthorizationRequiredHandler(service.RevokeAccessFromTeamHandler))

	m.Del("/apps/:name", AuthorizationRequiredHandler(app.AppDelete))
	m.Get("/apps/:name/repository/clone", Handler(app.CloneRepositoryHandler))
	m.Get("/apps/:name", AuthorizationRequiredHandler(app.AppInfo))
	m.Post("/apps/:name/run", AuthorizationRequiredHandler(app.RunCommand))
	m.Get("/apps/:name/env", AuthorizationRequiredHandler(app.GetEnv))
	m.Post("/apps/:name/env", AuthorizationRequiredHandler(app.SetEnv))
	m.Del("/apps/:name/env", AuthorizationRequiredHandler(app.UnsetEnv))
	m.Get("/apps", AuthorizationRequiredHandler(app.AppList))
	m.Post("/apps", AuthorizationRequiredHandler(app.CreateAppHandler))
	m.Put("/apps/:app/:team", AuthorizationRequiredHandler(app.GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", AuthorizationRequiredHandler(app.RevokeAccessFromTeamHandler))
	m.Get("/apps/:name/log", AuthorizationRequiredHandler(app.AppLog))

	m.Post("/users", Handler(auth.CreateUser))
	m.Post("/users/:email/tokens", Handler(auth.Login))
	m.Post("/users/keys", AuthorizationRequiredHandler(auth.AddKeyToUser))
	m.Del("/users/keys", AuthorizationRequiredHandler(auth.RemoveKeyFromUser))

	m.Post("/teams", AuthorizationRequiredHandler(auth.CreateTeam))
	m.Put("/teams/:team/:user", AuthorizationRequiredHandler(auth.AddUserToTeam))
	m.Del("/teams/:team/:user", AuthorizationRequiredHandler(auth.RemoveUserFromTeam))

	listen, err := config.GetString("listen")
	if err != nil {
		panic(err)
	}
	if !*dry {
		log.Fatal(http.ListenAndServe(listen, m))
	}
}
<|endoftext|>


<commit_before>// +build ignore

package main

import (
	"."
	"flag"
	"github.com/bmizerany/pat"
	"github.com/timeredbull/tsuru/api/app"
	"github.com/timeredbull/tsuru/api/auth"
	"github.com/timeredbull/tsuru/api/service"
	"github.com/timeredbull/tsuru/config"
	"github.com/timeredbull/tsuru/db"
	"github.com/timeredbull/tsuru/log"
	"github.com/timeredbull/tsuru/repository"
	stdlog "log"
	"log/syslog"
	"net/http"
)

func main() {
	var err error
	log.Target, err = syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		panic(err)
	}
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadConfigFile(*configFile)
	if err != nil {
		log.Panic(err.Error())
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		panic(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		panic(err)
	}
	db.Session, err = db.Open(connString, dbName)
	if err != nil {
		log.Panic(err.Error())
	}
	defer db.Session.Close()

	repository.RunAgent()
	m := pat.New()

	m.Post("/services", webserver.AuthorizationRequiredHandler(service.CreateHandler))
	m.Get("/services", webserver.AuthorizationRequiredHandler(service.ServicesHandler))
	m.Get("/services/types", webserver.Handler(service.ServiceTypesHandler))
	m.Del("/services/:name", webserver.AuthorizationRequiredHandler(service.DeleteHandler))
	m.Post("/services/bind", webserver.AuthorizationRequiredHandler(service.BindHandler))
	m.Post("/services/unbind", webserver.AuthorizationRequiredHandler(service.UnbindHandler))
	m.Put("/services/:service/:team", webserver.AuthorizationRequiredHandler(service.GrantAccessToTeamHandler))
	m.Del("/services/:service/:team", webserver.AuthorizationRequiredHandler(service.RevokeAccessFromTeamHandler))

	m.Del("/apps/:name", webserver.AuthorizationRequiredHandler(app.AppDelete))
	m.Get("/apps/:name/repository/clone", webserver.Handler(app.CloneRepositoryHandler))
	m.Get("/apps/:name", webserver.AuthorizationRequiredHandler(app.AppInfo))
	m.Post("/apps/:name/run", webserver.AuthorizationRequiredHandler(app.RunCommand))
	m.Get("/apps/:name/get-env", webserver.AuthorizationRequiredHandler(app.GetEnv))
	m.Get("/apps", webserver.AuthorizationRequiredHandler(app.AppList))
	m.Post("/apps", webserver.AuthorizationRequiredHandler(app.CreateAppHandler))
	m.Put("/apps/:app/:team", webserver.AuthorizationRequiredHandler(app.GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", webserver.AuthorizationRequiredHandler(app.RevokeAccessFromTeamHandler))

	m.Post("/users", webserver.Handler(auth.CreateUser))
	m.Post("/users/:email/tokens", webserver.Handler(auth.Login))
	m.Post("/users/keys", webserver.AuthorizationRequiredHandler(auth.AddKeyToUser))
	m.Del("/users/keys", webserver.AuthorizationRequiredHandler(auth.RemoveKeyFromUser))

	m.Post("/teams", webserver.AuthorizationRequiredHandler(auth.CreateTeam))
	m.Put("/teams/:team/:user", webserver.AuthorizationRequiredHandler(auth.AddUserToTeam))
	m.Del("/teams/:team/:user", webserver.AuthorizationRequiredHandler(auth.RemoveUserFromTeam))

	listen, err := config.GetString("listen")
	if err != nil {
		panic(err)
	}
	if !*dry {
		log.Fatal(http.ListenAndServe(listen, m))
	}
}
<commit_msg>api/webserver: changed GetEnv url to GET /app/:name/env<commit_after>// +build ignore

package main

import (
	"."
	"flag"
	"github.com/bmizerany/pat"
	"github.com/timeredbull/tsuru/api/app"
	"github.com/timeredbull/tsuru/api/auth"
	"github.com/timeredbull/tsuru/api/service"
	"github.com/timeredbull/tsuru/config"
	"github.com/timeredbull/tsuru/db"
	"github.com/timeredbull/tsuru/log"
	"github.com/timeredbull/tsuru/repository"
	stdlog "log"
	"log/syslog"
	"net/http"
)

func main() {
	var err error
	log.Target, err = syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		panic(err)
	}
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadConfigFile(*configFile)
	if err != nil {
		log.Panic(err.Error())
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		panic(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		panic(err)
	}
	db.Session, err = db.Open(connString, dbName)
	if err != nil {
		log.Panic(err.Error())
	}
	defer db.Session.Close()

	repository.RunAgent()
	m := pat.New()

	m.Post("/services", webserver.AuthorizationRequiredHandler(service.CreateHandler))
	m.Get("/services", webserver.AuthorizationRequiredHandler(service.ServicesHandler))
	m.Get("/services/types", webserver.Handler(service.ServiceTypesHandler))
	m.Del("/services/:name", webserver.AuthorizationRequiredHandler(service.DeleteHandler))
	m.Post("/services/bind", webserver.AuthorizationRequiredHandler(service.BindHandler))
	m.Post("/services/unbind", webserver.AuthorizationRequiredHandler(service.UnbindHandler))
	m.Put("/services/:service/:team", webserver.AuthorizationRequiredHandler(service.GrantAccessToTeamHandler))
	m.Del("/services/:service/:team", webserver.AuthorizationRequiredHandler(service.RevokeAccessFromTeamHandler))

	m.Del("/apps/:name", webserver.AuthorizationRequiredHandler(app.AppDelete))
	m.Get("/apps/:name/repository/clone", webserver.Handler(app.CloneRepositoryHandler))
	m.Get("/apps/:name", webserver.AuthorizationRequiredHandler(app.AppInfo))
	m.Post("/apps/:name/run", webserver.AuthorizationRequiredHandler(app.RunCommand))
	m.Get("/apps/:name/env", webserver.AuthorizationRequiredHandler(app.GetEnv))
	m.Get("/apps", webserver.AuthorizationRequiredHandler(app.AppList))
	m.Post("/apps", webserver.AuthorizationRequiredHandler(app.CreateAppHandler))
	m.Put("/apps/:app/:team", webserver.AuthorizationRequiredHandler(app.GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", webserver.AuthorizationRequiredHandler(app.RevokeAccessFromTeamHandler))

	m.Post("/users", webserver.Handler(auth.CreateUser))
	m.Post("/users/:email/tokens", webserver.Handler(auth.Login))
	m.Post("/users/keys", webserver.AuthorizationRequiredHandler(auth.AddKeyToUser))
	m.Del("/users/keys", webserver.AuthorizationRequiredHandler(auth.RemoveKeyFromUser))

	m.Post("/teams", webserver.AuthorizationRequiredHandler(auth.CreateTeam))
	m.Put("/teams/:team/:user", webserver.AuthorizationRequiredHandler(auth.AddUserToTeam))
	m.Del("/teams/:team/:user", webserver.AuthorizationRequiredHandler(auth.RemoveUserFromTeam))

	listen, err := config.GetString("listen")
	if err != nil {
		panic(err)
	}
	if !*dry {
		log.Fatal(http.ListenAndServe(listen, m))
	}
}
<|endoftext|>