<commit_before>package aws

import (
	"testing"
	"fmt"
//	"log"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/s3"
)

func TestAccAWSS3BucketObject_basic(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketObjectConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object"),
				),
			},
		},
	})
}

func testAccCheckAWSS3BucketObjectDestroy(s *terraform.State) error {
	s3conn := testAccProvider.Meta().(*AWSClient).s3conn

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

		_, err := s3conn.GetObject(
			&s3.GetObjectInput{
				IfMatch: aws.String(rs.Primary.ID),
		})
		return fmt.Errorf("get object err %s",err)
	}
	return fmt.Errorf("no resources")
}

func testAccCheckAWSS3BucketObjectExists(n string) 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 S3 Bucket Object ID is set")
		}

		s3conn := testAccProvider.Meta().(*AWSClient).s3conn
		_, err := s3conn.GetObject(
			&s3.GetObjectInput{
				IfMatch: aws.String(rs.Primary.ID),
		})
		if err != nil {
			return fmt.Errorf("S3Bucket Object error: %s", err)
		}
		return nil
	}
}
var randomBucket = randInt;
var testAccAWSS3BucketObjectConfig = fmt.Sprintf(`
resource "aws_s3_bucket" "bucket" {
	bucket = "tf-object-test-bucket-%d"
}
resource "aws_s3_bucket_object" "object" {
	depends_on = "aws_s3_bucket.bucket"
	bucket = "tf-object-test-bucket-%d"
	key = "test-key"
	source = "test.txt"
}
`, randomBucket, randomBucket)

<commit_msg>temp file is created but not destroyed yet<commit_after>package aws

import (
	"testing"
	"fmt"
	"io/ioutil"
	"os"
	"log"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/s3"
)
var tf,err = ioutil.TempFile("", "tf")
var _ = log.Printf
func TestAccAWSS3BucketObject_basic(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:     func() {
			if err != nil {
				panic(err)
			}
			testAccPreCheck(t)
		},
		Providers: testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketObjectConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object"),
				),
			},
		},
	})
}

func testAccCheckAWSS3BucketObjectDestroy(s *terraform.State) error {
	//s3conn := testAccProvider.Meta().(*AWSClient).s3conn

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

	}
	return nil
}

func testAccCheckAWSS3BucketObjectExists(n string) resource.TestCheckFunc {
	return func(s *terraform.State) error {

		defer os.Remove(tf.Name());

		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not Found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No S3 Bucket Object ID is set")
		}

		s3conn := testAccProvider.Meta().(*AWSClient).s3conn
		_, err := s3conn.GetObject(
			&s3.GetObjectInput{
				Bucket:  aws.String(rs.Primary.Attributes["bucket"]),
				Key:     aws.String(rs.Primary.Attributes["key"]),
				IfMatch: aws.String(rs.Primary.ID),
		})
		if err != nil {
			return fmt.Errorf("S3Bucket Object error: %s", err)
		}
		return nil
	}
}

var randomBucket = randInt;
var testAccAWSS3BucketObjectConfig = fmt.Sprintf(`
resource "aws_s3_bucket" "bucket" {
	bucket = "tf-object-test-bucket-%d"
}
resource "aws_s3_bucket_object" "object" {
	depends_on = "aws_s3_bucket.bucket"
	bucket = "tf-object-test-bucket-%d"
	key = "test-key"
	source = "%s"
}
`, randomBucket, randomBucket, tf.Name())

<|endoftext|>


<commit_before>// Copyright 2015 The Vanadium 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 android

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

	"v.io/jiri/collect"
	"v.io/jiri/profiles"
	"v.io/jiri/runutil"
	"v.io/jiri/tool"
	"v.io/x/lib/envvar"
)

const (
	profileName        = "android"
	ndkDownloadBaseURL = "https://dl.google.com/android/ndk"
)

type versionSpec struct {
	ndkDownloadURL string
	// seq's chain may be already in progress.
	ndkExtract  func(seq *runutil.Sequence, src, dst string)
	ndkAPILevel int
}

func ndkArch() (string, error) {
	switch runtime.GOARCH {
	case "386":
		return "x86", nil
	case "amd64":
		return "x86_64", nil
	default:
		return "", fmt.Errorf("NDK unsupported for GOARCH %s", runtime.GOARCH)
	}
}

func tarExtract(seq *runutil.Sequence, src, dst string) {
	seq.Run("tar", "-C", dst, "-xjf", src)
}

func selfExtract(seq *runutil.Sequence, src, dst string) {
	seq.Chmod(src, profiles.DefaultDirPerm).Run(src, "-y", "-o"+dst)
}

func init() {
	arch, err := ndkArch()
	if err != nil {
		fmt.Fprintf(os.Stderr, "WARNING: android profile not supported: %v\n", err)
		return
	}
	m := &Manager{
		versionInfo: profiles.NewVersionInfo(profileName, map[string]interface{}{
			"3": &versionSpec{
				ndkDownloadURL: fmt.Sprintf("%s/android-ndk-r9d-%s-%s.tar.bz2", ndkDownloadBaseURL, runtime.GOOS, arch),
				ndkExtract:     tarExtract,
				ndkAPILevel:    9,
			},
			"4": &versionSpec{
				ndkDownloadURL: fmt.Sprintf("%s/android-ndk-r10e-%s-%s.bin", ndkDownloadBaseURL, runtime.GOOS, arch),
				ndkExtract:     selfExtract,
				ndkAPILevel:    16,
			},
		}, "3"),
	}
	profiles.Register(profileName, m)
}

type Manager struct {
	root, androidRoot, ndkRoot profiles.RelativePath
	versionInfo                *profiles.VersionInfo
	spec                       versionSpec
}

func (Manager) Name() string {
	return profileName
}

func (m Manager) String() string {
	return fmt.Sprintf("%s[%s]", profileName, m.versionInfo.Default())
}

func (m Manager) Info() string {
	return `
The android profile provides support for cross-compiling from linux or darwin
to android. It only supports one target 'arm-android' and will assume that
as the default value if one is not supplied. It installs the android NDK
and a go compiler configured to use it.`
}

func (m Manager) VersionInfo() *profiles.VersionInfo {
	return m.versionInfo
}

func (m *Manager) AddFlags(flags *flag.FlagSet, action profiles.Action) {
}

func (m *Manager) initForTarget(ctx *tool.Context, action string, root profiles.RelativePath, target *profiles.Target) error {
	if !target.IsSet() {
		def := *target
		target.Set("arm-android")
		fmt.Fprintf(ctx.Stdout(), "Default target %v reinterpreted as: %v\n", def, target)
	} else {
		if target.Arch() != "arm" && target.OS() != "android" {
			return fmt.Errorf("this profile can only be %v as arm-android and not as %v", action, target)
		}
	}
	if err := m.versionInfo.Lookup(target.Version(), &m.spec); err != nil {
		return err
	}
	m.root = root
	m.androidRoot = root.Join("android")
	m.ndkRoot = m.androidRoot.Join("ndk-toolchain")
	return nil
}

func (m *Manager) Install(ctx *tool.Context, root profiles.RelativePath, target profiles.Target) error {
	if err := m.initForTarget(ctx, "installed", root, &target); err != nil {
		return err
	}
	if err := m.installAndroidNDK(ctx); err != nil {
		return err
	}
	if profiles.SchemaVersion() >= 4 {
		profiles.InstallProfile(profileName, m.androidRoot.RelativePath())
	} else {
		profiles.InstallProfile(profileName, m.androidRoot.Expand())
	}
	if err := profiles.AddProfileTarget(profileName, target); err != nil {
		return err
	}

	// Install android targets for other profiles.
	dependency := target
	dependency.SetVersion("2")
	if err := m.installAndroidBaseTargets(ctx, dependency); err != nil {
		return err
	}

	// Merge the target and baseProfile environments.
	env := envvar.VarsFromSlice(target.Env.Vars)
	baseProfileEnv := profiles.EnvFromProfile(target, "base")
	profiles.MergeEnv(profiles.ProfileMergePolicies(), env, baseProfileEnv)
	target.Env.Vars = env.ToSlice()
	if profiles.SchemaVersion() >= 4 {
		target.InstallationDir = m.ndkRoot.RelativePath()
		profiles.InstallProfile(profileName, m.androidRoot.RelativePath())
	} else {
		target.InstallationDir = m.ndkRoot.Expand()
		profiles.InstallProfile(profileName, m.androidRoot.Expand())
	}
	return profiles.UpdateProfileTarget(profileName, target)
}

func (m *Manager) Uninstall(ctx *tool.Context, root profiles.RelativePath, target profiles.Target) error {
	if err := m.initForTarget(ctx, "uninstalled", root, &target); err != nil {
		return err
	}
	target.Env.Vars = append(target.Env.Vars, "GOARM=7")
	if err := profiles.EnsureProfileTargetIsUninstalled(ctx, "base", root, target); err != nil {
		return err
	}
	if err := ctx.Seq().RemoveAll(m.androidRoot.Expand()).Done(); err != nil {
		return err
	}
	profiles.RemoveProfileTarget(profileName, target)
	return nil
}

func relPath(rp profiles.RelativePath) string {
	if profiles.SchemaVersion() >= 4 {
		return rp.String()
	}
	return rp.Expand()
}

// installAndroidNDK installs the android NDK toolchain.
func (m *Manager) installAndroidNDK(ctx *tool.Context) (e error) {
	// Install dependencies.
	var pkgs []string
	switch runtime.GOOS {
	case "linux":
		pkgs = []string{"ant", "autoconf", "bzip2", "default-jdk", "gawk", "lib32z1", "lib32stdc++6"}
	case "darwin":
		pkgs = []string{"ant", "autoconf", "gawk"}
	default:
		return fmt.Errorf("unsupported OS: %s", runtime.GOOS)
	}
	if err := profiles.InstallPackages(ctx, pkgs); err != nil {
		return err
	}
	// Download Android NDK.
	installNdkFn := func() error {
		tmpDir, err := ctx.Seq().TempDir("", "")
		if err != nil {
			return fmt.Errorf("TempDir() failed: %v", err)
		}
		defer collect.Error(func() error { return ctx.Seq().RemoveAll(tmpDir).Done() }, &e)
		extractDir, err := ctx.Seq().TempDir(tmpDir, "extract")
		if err != nil {
			return err
		}
		local := filepath.Join(tmpDir, path.Base(m.spec.ndkDownloadURL))
		ctx.Seq().Run("curl", "-Lo", local, m.spec.ndkDownloadURL)
		m.spec.ndkExtract(ctx.Seq(), local, extractDir)
		files, err := ctx.Seq().ReadDir(extractDir)
		if err != nil {
			return err
		}
		if len(files) != 1 {
			return fmt.Errorf("expected one directory under %s, got: %v", extractDir, files)
		}
		ndkBin := filepath.Join(extractDir, files[0].Name(), "build", "tools", "make-standalone-toolchain.sh")
		ndkArgs := []string{ndkBin, fmt.Sprintf("--platform=android-%d", m.spec.ndkAPILevel), "--arch=arm", "--install-dir=" + m.ndkRoot.Expand()}
		return ctx.Seq().Run("bash", ndkArgs...).Done()
	}
	return profiles.AtomicAction(ctx, installNdkFn, m.ndkRoot.Expand(), "Download Android NDK")
}

// installAndroidTargets installs android targets for other profiles, currently
// just the base profile (i.e. go and syncbase.)
func (m *Manager) installAndroidBaseTargets(ctx *tool.Context, target profiles.Target) (e error) {
	env := fmt.Sprintf("ANDROID_NDK_DIR=%s,GOARM=7", relPath(m.ndkRoot))
	androidTarget, err := profiles.NewTargetWithEnv(target.String(), env)
	if err != nil {
		return err
	}
	return profiles.EnsureProfileTargetIsInstalled(ctx, "base", m.root, androidTarget)
}
<commit_msg>v.io/jiri/runutil: improvements inspired by caprita:-)<commit_after>// Copyright 2015 The Vanadium 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 android

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

	"v.io/jiri/collect"
	"v.io/jiri/profiles"
	"v.io/jiri/runutil"
	"v.io/jiri/tool"
	"v.io/x/lib/envvar"
)

const (
	profileName        = "android"
	ndkDownloadBaseURL = "https://dl.google.com/android/ndk"
)

type versionSpec struct {
	ndkDownloadURL string
	// seq's chain may be already in progress.
	ndkExtract  func(seq *runutil.Sequence, src, dst string) *runutil.Sequence
	ndkAPILevel int
}

func ndkArch() (string, error) {
	switch runtime.GOARCH {
	case "386":
		return "x86", nil
	case "amd64":
		return "x86_64", nil
	default:
		return "", fmt.Errorf("NDK unsupported for GOARCH %s", runtime.GOARCH)
	}
}

func tarExtract(seq *runutil.Sequence, src, dst string) *runutil.Sequence {
	return seq.Run("tar", "-C", dst, "-xjf", src)
}

func selfExtract(seq *runutil.Sequence, src, dst string) *runutil.Sequence {
	return seq.Chmod(src, profiles.DefaultDirPerm).Run(src, "-y", "-o"+dst)
}

func init() {
	arch, err := ndkArch()
	if err != nil {
		fmt.Fprintf(os.Stderr, "WARNING: android profile not supported: %v\n", err)
		return
	}
	m := &Manager{
		versionInfo: profiles.NewVersionInfo(profileName, map[string]interface{}{
			"3": &versionSpec{
				ndkDownloadURL: fmt.Sprintf("%s/android-ndk-r9d-%s-%s.tar.bz2", ndkDownloadBaseURL, runtime.GOOS, arch),
				ndkExtract:     tarExtract,
				ndkAPILevel:    9,
			},
			"4": &versionSpec{
				ndkDownloadURL: fmt.Sprintf("%s/android-ndk-r10e-%s-%s.bin", ndkDownloadBaseURL, runtime.GOOS, arch),
				ndkExtract:     selfExtract,
				ndkAPILevel:    16,
			},
		}, "3"),
	}
	profiles.Register(profileName, m)
}

type Manager struct {
	root, androidRoot, ndkRoot profiles.RelativePath
	versionInfo                *profiles.VersionInfo
	spec                       versionSpec
}

func (Manager) Name() string {
	return profileName
}

func (m Manager) String() string {
	return fmt.Sprintf("%s[%s]", profileName, m.versionInfo.Default())
}

func (m Manager) Info() string {
	return `
The android profile provides support for cross-compiling from linux or darwin
to android. It only supports one target 'arm-android' and will assume that
as the default value if one is not supplied. It installs the android NDK
and a go compiler configured to use it.`
}

func (m Manager) VersionInfo() *profiles.VersionInfo {
	return m.versionInfo
}

func (m *Manager) AddFlags(flags *flag.FlagSet, action profiles.Action) {
}

func (m *Manager) initForTarget(ctx *tool.Context, action string, root profiles.RelativePath, target *profiles.Target) error {
	if !target.IsSet() {
		def := *target
		target.Set("arm-android")
		fmt.Fprintf(ctx.Stdout(), "Default target %v reinterpreted as: %v\n", def, target)
	} else {
		if target.Arch() != "arm" && target.OS() != "android" {
			return fmt.Errorf("this profile can only be %v as arm-android and not as %v", action, target)
		}
	}
	if err := m.versionInfo.Lookup(target.Version(), &m.spec); err != nil {
		return err
	}
	m.root = root
	m.androidRoot = root.Join("android")
	m.ndkRoot = m.androidRoot.Join("ndk-toolchain")
	return nil
}

func (m *Manager) Install(ctx *tool.Context, root profiles.RelativePath, target profiles.Target) error {
	if err := m.initForTarget(ctx, "installed", root, &target); err != nil {
		return err
	}
	if err := m.installAndroidNDK(ctx); err != nil {
		return err
	}
	if profiles.SchemaVersion() >= 4 {
		profiles.InstallProfile(profileName, m.androidRoot.RelativePath())
	} else {
		profiles.InstallProfile(profileName, m.androidRoot.Expand())
	}
	if err := profiles.AddProfileTarget(profileName, target); err != nil {
		return err
	}

	// Install android targets for other profiles.
	dependency := target
	dependency.SetVersion("2")
	if err := m.installAndroidBaseTargets(ctx, dependency); err != nil {
		return err
	}

	// Merge the target and baseProfile environments.
	env := envvar.VarsFromSlice(target.Env.Vars)
	baseProfileEnv := profiles.EnvFromProfile(target, "base")
	profiles.MergeEnv(profiles.ProfileMergePolicies(), env, baseProfileEnv)
	target.Env.Vars = env.ToSlice()
	if profiles.SchemaVersion() >= 4 {
		target.InstallationDir = m.ndkRoot.RelativePath()
		profiles.InstallProfile(profileName, m.androidRoot.RelativePath())
	} else {
		target.InstallationDir = m.ndkRoot.Expand()
		profiles.InstallProfile(profileName, m.androidRoot.Expand())
	}
	return profiles.UpdateProfileTarget(profileName, target)
}

func (m *Manager) Uninstall(ctx *tool.Context, root profiles.RelativePath, target profiles.Target) error {
	if err := m.initForTarget(ctx, "uninstalled", root, &target); err != nil {
		return err
	}
	target.Env.Vars = append(target.Env.Vars, "GOARM=7")
	if err := profiles.EnsureProfileTargetIsUninstalled(ctx, "base", root, target); err != nil {
		return err
	}
	if err := ctx.NewSeq().RemoveAll(m.androidRoot.Expand()).Done(); err != nil {
		return err
	}
	profiles.RemoveProfileTarget(profileName, target)
	return nil
}

func relPath(rp profiles.RelativePath) string {
	if profiles.SchemaVersion() >= 4 {
		return rp.String()
	}
	return rp.Expand()
}

// installAndroidNDK installs the android NDK toolchain.
func (m *Manager) installAndroidNDK(ctx *tool.Context) (e error) {
	// Install dependencies.
	var pkgs []string
	switch runtime.GOOS {
	case "linux":
		pkgs = []string{"ant", "autoconf", "bzip2", "default-jdk", "gawk", "lib32z1", "lib32stdc++6"}
	case "darwin":
		pkgs = []string{"ant", "autoconf", "gawk"}
	default:
		return fmt.Errorf("unsupported OS: %s", runtime.GOOS)
	}
	if err := profiles.InstallPackages(ctx, pkgs); err != nil {
		return err
	}
	// Download Android NDK.
	installNdkFn := func() error {
		s := ctx.NewSeq()
		tmpDir, err := s.TempDir("", "")
		if err != nil {
			return fmt.Errorf("TempDir() failed: %v", err)
		}
		defer collect.Error(func() error { return ctx.NewSeq().RemoveAll(tmpDir).Done() }, &e)
		extractDir, err := s.TempDir(tmpDir, "extract")
		if err != nil {
			return err
		}
		local := filepath.Join(tmpDir, path.Base(m.spec.ndkDownloadURL))
		s.Run("curl", "-Lo", local, m.spec.ndkDownloadURL)
		files, err := m.spec.ndkExtract(s, local, extractDir).
			ReadDir(extractDir)
		if err != nil {
			return err
		}
		if len(files) != 1 {
			return fmt.Errorf("expected one directory under %s, got: %v", extractDir, files)
		}
		ndkBin := filepath.Join(extractDir, files[0].Name(), "build", "tools", "make-standalone-toolchain.sh")
		ndkArgs := []string{ndkBin, fmt.Sprintf("--platform=android-%d", m.spec.ndkAPILevel), "--arch=arm", "--install-dir=" + m.ndkRoot.Expand()}
		return s.Last("bash", ndkArgs...)
	}
	return profiles.AtomicAction(ctx, installNdkFn, m.ndkRoot.Expand(), "Download Android NDK")
}

// installAndroidTargets installs android targets for other profiles, currently
// just the base profile (i.e. go and syncbase.)
func (m *Manager) installAndroidBaseTargets(ctx *tool.Context, target profiles.Target) (e error) {
	env := fmt.Sprintf("ANDROID_NDK_DIR=%s,GOARM=7", relPath(m.ndkRoot))
	androidTarget, err := profiles.NewTargetWithEnv(target.String(), env)
	if err != nil {
		return err
	}
	return profiles.EnsureProfileTargetIsInstalled(ctx, "base", m.root, androidTarget)
}
<|endoftext|>


<commit_before>// Copyright 2014-2015 The DevMine 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 repotool is able to fetch information from a source code repository.
// Typically, it can get all commits, their authors and commiters and so on
// and return this information in a JSON object. Alternatively, it is able
// to populate the information into a PostgreSQL database.
// Currently, on the Git VCS is supported.
package main

import (
	"bufio"
	"bytes"
	"database/sql"
	"encoding/hex"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	_ "github.com/lib/pq"
	mmh3 "github.com/spaolacci/murmur3"

	"github.com/DevMine/srcanlzr/src"

	"github.com/DevMine/repotool/config"
	"github.com/DevMine/repotool/model"
	"github.com/DevMine/repotool/repo"
)

const version = "0.1.0"

// database fields per tables
var (
	diffDeltaFields = []string{
		"commit_id",
		"file_status",
		"is_file_binary",
		"similarity",
		"old_file_path",
		"new_file_path"}

	commitFields = []string{
		"repository_id",
		"author_id",
		"committer_id",
		"hash",
		"vcs_id",
		"message",
		"author_date",
		"commit_date",
		"file_changed_count",
		"insertions_count",
		"deletions_count"}
)

func main() {
	flag.Usage = func() {
		fmt.Printf("usage: %s [OPTION(S)] [REPOSITORY PATH]\n", os.Args[0])
		flag.PrintDefaults()
		os.Exit(0)
	}

	configPath := flag.String("c", "", "configuration file")
	vflag := flag.Bool("v", false, "print version.")
	jsonflag := flag.Bool("json", true, "json output")
	dbflag := flag.Bool("db", false, "import data into the database")
	srctoolflag := flag.String("srctool", "", "read json file produced by srctool (give stdin to read from stdin)")
	flag.Parse()

	if *vflag {
		fmt.Printf("%s - %s\n", filepath.Base(os.Args[0]), version)
		os.Exit(0)
	}

	if len(flag.Args()) != 1 {
		fmt.Fprintln(os.Stderr, "invalid # of arguments")
		flag.Usage()
	}

	if *dbflag && len(*configPath) == 0 {
		fatal(errors.New("a configuration file must be specified when using db option"))
	}

	if !*jsonflag && (len(*srctoolflag) > 0) {
		fatal(errors.New("srctool flag may be used only in conjonction with json flag"))
	}

	cfg, err := config.ReadConfig(*configPath)
	if err != nil {
		fatal(err)
	}

	repoPath := flag.Arg(0)
	repository, err := repo.New(*cfg, repoPath)
	if err != nil {
		fatal(err)
	}
	defer repository.Cleanup()

	fmt.Fprintln(os.Stderr, "fetching repository commits...")
	tic := time.Now()
	err = repository.FetchCommits()
	if err != nil {
		fatal(err)
	}
	toc := time.Now()
	fmt.Fprintln(os.Stderr, "done in ", toc.Sub(tic))

	if *jsonflag && (len(*srctoolflag) == 0) {
		bs, err := json.Marshal(repository)
		if err != nil {
			fatal(err)
		}
		fmt.Println(string(bs))
	}

	if *jsonflag && (len(*srctoolflag)) > 0 {
		var r *bufio.Reader
		if *srctoolflag == strings.ToLower("stdin") {
			// read from stdin
			r = bufio.NewReader(os.Stdin)
		} else {
			// read from srctool json file
			var f *os.File
			if f, err = os.Open(*srctoolflag); err != nil {
				fatal(err)
			}
			r = bufio.NewReader(f)
		}

		buf := new(bytes.Buffer)
		if _, err = io.Copy(buf, r); err != nil {
			fatal(err)
		}

		bs := buf.Bytes()
		p, err := src.Unmarshal(bs)
		if err != nil {
			fatal(err)
		}

		p.Repo = repository.GetRepository()
		bs, err = src.Marshal(p)
		if err != nil {
			fatal(err)
		}

		fmt.Println(string(bs))
	}

	if *dbflag {
		db, err := openDBSession(cfg.Database)
		if err != nil {
			fatal(err)
		}
		defer db.Close()

		fmt.Fprintf(os.Stderr,
			"inserting %d commits from %s repository into the database...\n",
			len(repository.GetCommits()), repository.GetName())
		tic := time.Now()
		insertRepoData(db, repository)
		toc := time.Now()
		fmt.Fprintln(os.Stderr, "done in ", toc.Sub(tic))
	}
}

// fatal prints an error on standard error stream and exits.
func fatal(a ...interface{}) {
	fmt.Fprintln(os.Stderr, a...)
	os.Exit(1)
}

// fail prints an error on standard error stream.
func fail(a ...interface{}) {
	fmt.Fprintln(os.Stderr, a...)
}

// openDBSession creates a session to the database.
func openDBSession(cfg config.DatabaseConfig) (*sql.DB, error) {
	dbURL := fmt.Sprintf(
		"user='%s' password='%s' host='%s' port=%d dbname='%s' sslmode='%s'",
		cfg.UserName, cfg.Password, cfg.HostName, cfg.Port, cfg.DBName, cfg.SSLMode)

	return sql.Open("postgres", dbURL)
}

// insertRepoData inserts repository data into the database, or updates it
// if it is already there.
func insertRepoData(db *sql.DB, r repo.Repo) {
	if db == nil {
		fatal(errors.New("nil database given"))
	}

	repoID := getRepoID(db, r)
	if repoID == 0 {
		fatal(errors.New("no corresponding repository found in the database: impossible to insert data"))
	}

	for _, c := range r.GetCommits() {
		insertCommit(db, repoID, c)
	}
}

// insertCommit inserts a commit into the database
func insertCommit(db *sql.DB, repoID int, c model.Commit) {
	authorID := getUserID(db, c.Author.Email)
	committerID := getUserID(db, c.Committer.Email)
	hash := genCommitHash(c)

	var commitID int64
	query := genInsQuery("commits", commitFields...)
	err := db.QueryRow(query+" RETURNING id",
		repoID, authorID, committerID, hash,
		c.VCSID, c.Message, c.AuthorDate, c.CommitDate,
		c.FileChangedCount, c.InsertionsCount, c.DeletionsCount).Scan(&commitID)
	if err != nil {
		fail(err)
		return
	}

	for _, d := range c.DiffDelta {
		insertDiffDelta(db, commitID, d)
	}
}

// insertDiffDelta inserts a commit diff delta into the database.
func insertDiffDelta(db *sql.DB, commitID int64, d model.DiffDelta) {
	query := genInsQuery("commit_diff_deltas", diffDeltaFields...)
	_, err := db.Exec(query,
		commitID, d.Status, d.Binary, d.Similarity, d.OldFilePath, d.NewFilePath)
	if err != nil {
		fail(err)
	}
}

// genCommitHash generates a hash (mmh3) from commit fields.
// This hash can then be used to uniquely identify a commit.
// Typically, we want to make sure not to insert twice the same commit into the
// database after an eventual second repotool run on the same repository.
func genCommitHash(c model.Commit) string {
	h := mmh3.New128()

	io.WriteString(h, c.VCSID)
	io.WriteString(h, c.Message)
	io.WriteString(h, c.Author.Name)
	io.WriteString(h, c.Author.Email)
	io.WriteString(h, c.Committer.Name)
	io.WriteString(h, c.Committer.Email)
	io.WriteString(h, c.AuthorDate.String())
	io.WriteString(h, c.CommitDate.String())
	io.WriteString(h, strconv.FormatInt(int64(c.FileChangedCount), 10))
	io.WriteString(h, strconv.FormatInt(int64(c.InsertionsCount), 10))
	io.WriteString(h, strconv.FormatInt(int64(c.DeletionsCount), 10))

	return hex.EncodeToString(h.Sum(nil))
}

// getRepoID returns the repository id of a repo in repositories table.
// If repo is not in the table, then 0 is returned.
func getRepoID(db *sql.DB, r repo.Repo) int {
	if db == nil {
		fatal(errors.New("nil database given"))
	}

	var id int
	// Clone URL is unique
	err := db.QueryRow("SELECT id FROM repositories WHERE clone_url=$1", r.GetCloneURL()).Scan(&id)
	switch {
	case err == sql.ErrNoRows:
		return 0
	case err != nil:
		fatal(err)
	}
	return id
}

// getUserID attempts to find a user ID given its email address.
// Email addresses are unique, however they may not be provided.
// If no user ID is found, nil is returned, otherwhise the user ID
// is returned.
func getUserID(db *sql.DB, email string) *int {
	if db == nil {
		fatal(errors.New("nil database given"))
	}

	if len(email) == 0 {
		return nil
	}

	var id *int
	err := db.QueryRow("SELECT id FROM users WHERE email=$1", email).Scan(&id)
	switch {
	case err == sql.ErrNoRows:
		return nil
	case err != nil:
		fatal(err)
	}
	return id
}

// genInsQuery generates a query string for an insertion in the database.
func genInsQuery(tableName string, fields ...string) string {
	var buf bytes.Buffer

	buf.WriteString(fmt.Sprintf("INSERT INTO %s(%s)\n",
		tableName, strings.Join(fields, ",")))
	buf.WriteString("VALUES(")

	for ind := range fields {
		if ind > 0 {
			buf.WriteString(",")
		}

		buf.WriteString(fmt.Sprintf("$%d", ind+1))
	}

	buf.WriteString(")\n")

	return buf.String()
}
<commit_msg>db: use a transaction to insert commits and commit deltas<commit_after>// Copyright 2014-2015 The DevMine 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 repotool is able to fetch information from a source code repository.
// Typically, it can get all commits, their authors and commiters and so on
// and return this information in a JSON object. Alternatively, it is able
// to populate the information into a PostgreSQL database.
// Currently, on the Git VCS is supported.
package main

import (
	"bufio"
	"bytes"
	"database/sql"
	"encoding/hex"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	_ "github.com/lib/pq"
	mmh3 "github.com/spaolacci/murmur3"

	"github.com/DevMine/srcanlzr/src"

	"github.com/DevMine/repotool/config"
	"github.com/DevMine/repotool/model"
	"github.com/DevMine/repotool/repo"
)

const version = "0.1.0"

// database fields per tables
var (
	diffDeltaFields = []string{
		"commit_id",
		"file_status",
		"is_file_binary",
		"similarity",
		"old_file_path",
		"new_file_path"}

	commitFields = []string{
		"repository_id",
		"author_id",
		"committer_id",
		"hash",
		"vcs_id",
		"message",
		"author_date",
		"commit_date",
		"file_changed_count",
		"insertions_count",
		"deletions_count"}
)

func main() {
	flag.Usage = func() {
		fmt.Printf("usage: %s [OPTION(S)] [REPOSITORY PATH]\n", os.Args[0])
		flag.PrintDefaults()
		os.Exit(0)
	}

	configPath := flag.String("c", "", "configuration file")
	vflag := flag.Bool("v", false, "print version.")
	jsonflag := flag.Bool("json", true, "json output")
	dbflag := flag.Bool("db", false, "import data into the database")
	srctoolflag := flag.String("srctool", "", "read json file produced by srctool (give stdin to read from stdin)")
	flag.Parse()

	if *vflag {
		fmt.Printf("%s - %s\n", filepath.Base(os.Args[0]), version)
		os.Exit(0)
	}

	if len(flag.Args()) != 1 {
		fmt.Fprintln(os.Stderr, "invalid # of arguments")
		flag.Usage()
	}

	if *dbflag && len(*configPath) == 0 {
		fatal(errors.New("a configuration file must be specified when using db option"))
	}

	if !*jsonflag && (len(*srctoolflag) > 0) {
		fatal(errors.New("srctool flag may be used only in conjonction with json flag"))
	}

	cfg, err := config.ReadConfig(*configPath)
	if err != nil {
		fatal(err)
	}

	repoPath := flag.Arg(0)
	repository, err := repo.New(*cfg, repoPath)
	if err != nil {
		fatal(err)
	}
	defer repository.Cleanup()

	fmt.Fprintln(os.Stderr, "fetching repository commits...")
	tic := time.Now()
	err = repository.FetchCommits()
	if err != nil {
		fatal(err)
	}
	toc := time.Now()
	fmt.Fprintln(os.Stderr, "done in ", toc.Sub(tic))

	if *jsonflag && (len(*srctoolflag) == 0) {
		bs, err := json.Marshal(repository)
		if err != nil {
			fatal(err)
		}
		fmt.Println(string(bs))
	}

	if *jsonflag && (len(*srctoolflag)) > 0 {
		var r *bufio.Reader
		if *srctoolflag == strings.ToLower("stdin") {
			// read from stdin
			r = bufio.NewReader(os.Stdin)
		} else {
			// read from srctool json file
			var f *os.File
			if f, err = os.Open(*srctoolflag); err != nil {
				fatal(err)
			}
			r = bufio.NewReader(f)
		}

		buf := new(bytes.Buffer)
		if _, err = io.Copy(buf, r); err != nil {
			fatal(err)
		}

		bs := buf.Bytes()
		p, err := src.Unmarshal(bs)
		if err != nil {
			fatal(err)
		}

		p.Repo = repository.GetRepository()
		bs, err = src.Marshal(p)
		if err != nil {
			fatal(err)
		}

		fmt.Println(string(bs))
	}

	if *dbflag {
		db, err := openDBSession(cfg.Database)
		if err != nil {
			fatal(err)
		}
		defer db.Close()

		fmt.Fprintf(os.Stderr,
			"inserting %d commits from %s repository into the database...\n",
			len(repository.GetCommits()), repository.GetName())
		tic := time.Now()
		err = insertRepoData(db, repository)
		toc := time.Now()
		if err != nil {
			fmt.Fprintln(os.Stderr, err.Error())
			os.Exit(1)
		} else {
			fmt.Fprintln(os.Stderr, "done in ", toc.Sub(tic))
		}
	}
}

// fatal prints an error on standard error stream and exits.
func fatal(a ...interface{}) {
	fmt.Fprintln(os.Stderr, a...)
	os.Exit(1)
}

// fail prints an error on standard error stream.
func fail(a ...interface{}) {
	fmt.Fprintln(os.Stderr, a...)
}

// openDBSession creates a session to the database.
func openDBSession(cfg config.DatabaseConfig) (*sql.DB, error) {
	dbURL := fmt.Sprintf(
		"user='%s' password='%s' host='%s' port=%d dbname='%s' sslmode='%s'",
		cfg.UserName, cfg.Password, cfg.HostName, cfg.Port, cfg.DBName, cfg.SSLMode)

	return sql.Open("postgres", dbURL)
}

// insertRepoData inserts repository data into the database, or updates it
// if it is already there.
func insertRepoData(db *sql.DB, r repo.Repo) error {
	if db == nil {
		return errors.New("nil database given")
	}

	repoID, err := getRepoID(db, r)
	if err != nil {
		return err
	}
	if repoID == nil {
		return errors.New("cannot find corresponding repository in database")
	}

	tx, err := db.Begin()
	if err != nil {
		return err
	}
	defer tx.Rollback()

	commitStmt, err := tx.Prepare(genInsQuery("commits", commitFields...) + " RETURNING id")
	if err != nil {
		return err
	}

	deltaStmt, err := tx.Prepare(genInsQuery("commit_diff_deltas", diffDeltaFields...))
	if err != nil {
		return err
	}

	for _, c := range r.GetCommits() {
		if err := insertCommit(*repoID, c, tx, commitStmt, deltaStmt); err != nil {
			return err
		}
	}

	if err := commitStmt.Close(); err != nil {
		return err
	}
	if err := deltaStmt.Close(); err != nil {
		return err
	}
	if err := tx.Commit(); err != nil {
		return err
	}

	return nil
}

// insertCommit inserts a commit into the database
func insertCommit(repoID int64, c model.Commit, tx *sql.Tx, commitStmt, deltaStmt *sql.Stmt) error {
	// TODO load user ids/email in a map once at start
	authorID, err := getUserID(tx, c.Author.Email)
	if err != nil {
		return err
	}
	committerID, err := getUserID(tx, c.Committer.Email)
	if err != nil {
		return err
	}
	hash := genCommitHash(c)

	var commitID int64
	err = commitStmt.QueryRow(
		repoID, authorID, committerID, hash,
		c.VCSID, c.Message, c.AuthorDate, c.CommitDate,
		c.FileChangedCount, c.InsertionsCount, c.DeletionsCount).Scan(&commitID)
	if err != nil {
		return err
	}

	for _, d := range c.DiffDelta {
		if err := insertDiffDelta(commitID, d, deltaStmt); err != nil {
			return err
		}
	}

	return nil
}

// insertDiffDelta inserts a commit diff delta into the database.
func insertDiffDelta(commitID int64, d model.DiffDelta, stmt *sql.Stmt) error {
	_, err := stmt.Exec(commitID, d.Status, d.Binary, d.Similarity, d.OldFilePath, d.NewFilePath)
	if err != nil {
		return err
	}
	return nil
}

// genCommitHash generates a hash (mmh3) from commit fields.
// This hash can then be used to uniquely identify a commit.
// Typically, we want to make sure not to insert twice the same commit into the
// database after an eventual second repotool run on the same repository.
func genCommitHash(c model.Commit) string {
	h := mmh3.New128()

	io.WriteString(h, c.VCSID)
	io.WriteString(h, c.Message)
	io.WriteString(h, c.Author.Name)
	io.WriteString(h, c.Author.Email)
	io.WriteString(h, c.Committer.Name)
	io.WriteString(h, c.Committer.Email)
	io.WriteString(h, c.AuthorDate.String())
	io.WriteString(h, c.CommitDate.String())
	io.WriteString(h, strconv.FormatInt(int64(c.FileChangedCount), 10))
	io.WriteString(h, strconv.FormatInt(int64(c.InsertionsCount), 10))
	io.WriteString(h, strconv.FormatInt(int64(c.DeletionsCount), 10))

	return hex.EncodeToString(h.Sum(nil))
}

// getRepoID returns the repository id of a repo in repositories table.
// If repo is not in the table, then 0 is returned.
func getRepoID(db *sql.DB, r repo.Repo) (*int64, error) {
	if db == nil {
		return nil, errors.New("nil database given")
	}

	var id *int64
	// Clone URL is unique
	err := db.QueryRow("SELECT id FROM repositories WHERE clone_url=$1", r.GetCloneURL()).Scan(&id)
	switch {
	case err == sql.ErrNoRows:
		return nil, nil
	case err != nil:
		return nil, err
	}
	return id, nil
}

// getUserID attempts to find a user ID given its email address.
// Email addresses are unique, however they may not be provided.
// If no user ID is found, nil is returned, otherwhise the user ID
// is returned.
func getUserID(tx *sql.Tx, email string) (*int64, error) {
	if tx == nil {
		return nil, errors.New("nil database given")
	}

	if len(email) == 0 {
		return nil, nil
	}

	var id *int64
	err := tx.QueryRow("SELECT id FROM users WHERE email=$1", email).Scan(&id)
	switch {
	case err == sql.ErrNoRows:
		return nil, nil
	case err != nil:
		return nil, err
	}
	return id, nil
}

// genInsQuery generates a query string for an insertion in the database.
func genInsQuery(tableName string, fields ...string) string {
	var buf bytes.Buffer

	buf.WriteString(fmt.Sprintf("INSERT INTO %s(%s)\n",
		tableName, strings.Join(fields, ",")))
	buf.WriteString("VALUES(")

	for ind := range fields {
		if ind > 0 {
			buf.WriteString(",")
		}

		buf.WriteString(fmt.Sprintf("$%d", ind+1))
	}

	buf.WriteString(")\n")

	return buf.String()
}
<|endoftext|>


<commit_before>package monitor

import (
	"strings"
	"testing"

	"github.com/influxdb/influxdb/influxql"
)

// Test that a registered stats client results in the correct SHOW STATS output.
func Test_RegisterStats(t *testing.T) {
	monitor := openMonitor(t)

	client := mockStatsClient{
		StatisticsFn: func() (map[string]interface{}, error) {
			return map[string]interface{}{
				"bar": 1,
				"qux": 2.4,
			}, nil
		},
	}

	// Register a client without tags.
	if err := monitor.Register("foo", nil, client); err != nil {
		t.Fatalf("failed to register client: %s", err.Error())
	}
	json := executeShowStatsJSON(t, monitor)
	if !strings.Contains(json, `{"name":"foo","columns":["bar","qux"],"values":[[1,2.4]]}]}`) {
		t.Fatalf("SHOW STATS response incorrect, got: %s\n", json)
	}

	// Register a client with tags.
	if err := monitor.Register("baz", map[string]string{"proto": "tcp"}, client); err != nil {
		t.Fatalf("failed to register client: %s", err.Error())
	}
	json = executeShowStatsJSON(t, monitor)
	if !strings.Contains(json, `{"name":"baz","tags":{"proto":"tcp"},"columns":["bar","qux"],"values":[[1,2.4]]}]}`) {
		t.Fatalf("SHOW STATS response incorrect, got: %s\n", json)
	}
}

type mockStatsClient struct {
	StatisticsFn func() (map[string]interface{}, error)
}

func (m mockStatsClient) Statistics() (map[string]interface{}, error) {
	return m.StatisticsFn()
}

func (m mockStatsClient) Diagnostics() (map[string]interface{}, error) {
	return nil, nil
}

func openMonitor(t *testing.T) *Monitor {
	monitor := New(NewConfig())
	err := monitor.Open(1, 2, "serverA")
	if err != nil {
		t.Fatalf("failed to open monitor: %s", err.Error())
	}
	return monitor
}

func executeShowStatsJSON(t *testing.T, s *Monitor) string {
	r := s.ExecuteStatement(&influxql.ShowStatsStatement{})
	b, err := r.MarshalJSON()
	if err != nil {
		t.Fatalf("failed to decode SHOW STATS response: %s", err.Error())
	}
	return string(b)
}
<commit_msg>Correct monitor unit tests<commit_after>package monitor

import (
	"strings"
	"testing"

	"github.com/influxdb/influxdb/influxql"
	"github.com/influxdb/influxdb/meta"
)

// Test that a registered stats client results in the correct SHOW STATS output.
func Test_RegisterStats(t *testing.T) {
	monitor := openMonitor(t)
	executor := &StatementExecutor{Monitor: monitor}

	client := mockStatsClient{
		StatisticsFn: func() (map[string]interface{}, error) {
			return map[string]interface{}{
				"bar": 1,
				"qux": 2.4,
			}, nil
		},
	}

	// Register a client without tags.
	if err := monitor.Register("foo", nil, client); err != nil {
		t.Fatalf("failed to register client: %s", err.Error())
	}
	json := executeShowStatsJSON(t, executor)
	if !strings.Contains(json, `{"name":"foo","columns":["bar","qux"],"values":[[1,2.4]]}]}`) {
		t.Fatalf("SHOW STATS response incorrect, got: %s\n", json)
	}

	// Register a client with tags.
	if err := monitor.Register("baz", map[string]string{"proto": "tcp"}, client); err != nil {
		t.Fatalf("failed to register client: %s", err.Error())
	}
	json = executeShowStatsJSON(t, executor)
	if !strings.Contains(json, `{"name":"baz","tags":{"proto":"tcp"},"columns":["bar","qux"],"values":[[1,2.4]]}]}`) {
		t.Fatalf("SHOW STATS response incorrect, got: %s\n", json)
	}
}

type mockStatsClient struct {
	StatisticsFn func() (map[string]interface{}, error)
}

func (m mockStatsClient) Statistics() (map[string]interface{}, error) {
	return m.StatisticsFn()
}

func (m mockStatsClient) Diagnostics() (map[string]interface{}, error) {
	return nil, nil
}

type mockMetastore struct{}

func (m *mockMetastore) ClusterID() (uint64, error) { return 1, nil }
func (m *mockMetastore) NodeID() uint64             { return 2 }
func (m *mockMetastore) CreateDatabaseIfNotExists(name string) (*meta.DatabaseInfo, error) {
	return nil, nil
}

func openMonitor(t *testing.T) *Monitor {
	monitor := New(NewConfig())
	monitor.MetaStore = &mockMetastore{}
	err := monitor.Open()
	if err != nil {
		t.Fatalf("failed to open monitor: %s", err.Error())
	}
	return monitor
}

func executeShowStatsJSON(t *testing.T, s *StatementExecutor) string {
	r := s.ExecuteStatement(&influxql.ShowStatsStatement{})
	b, err := r.MarshalJSON()
	if err != nil {
		t.Fatalf("failed to decode SHOW STATS response: %s", err.Error())
	}
	return string(b)
}
<|endoftext|>


<commit_before>package ParquetEncoding

import (
	"bytes"
	"encoding/binary"
	"fmt"

	"github.com/xitongsys/parquet-go/ParquetType"
	"github.com/xitongsys/parquet-go/parquet"
)

func ReadPlain(bytesReader *bytes.Reader, dataType parquet.Type, cnt uint64, bitWidth uint64) ([]interface{}, error) {
	if dataType == parquet.Type_BOOLEAN {
		return ReadPlainBOOLEAN(bytesReader, cnt)
	} else if dataType == parquet.Type_INT32 {
		return ReadPlainINT32(bytesReader, cnt)
	} else if dataType == parquet.Type_INT64 {
		return ReadPlainINT64(bytesReader, cnt)
	} else if dataType == parquet.Type_INT96 {
		return ReadPlainINT96(bytesReader, cnt)
	} else if dataType == parquet.Type_FLOAT {
		return ReadPlainFLOAT(bytesReader, cnt)
	} else if dataType == parquet.Type_DOUBLE {
		return ReadPlainDOUBLE(bytesReader, cnt)
	} else if dataType == parquet.Type_BYTE_ARRAY {
		return ReadPlainBYTE_ARRAY(bytesReader, cnt)
	} else if dataType == parquet.Type_FIXED_LEN_BYTE_ARRAY {
		return ReadPlainFIXED_LEN_BYTE_ARRAY(bytesReader, cnt, bitWidth)
	} else {
		return nil, fmt.Errorf("Unknown parquet type")
	}
}

func ReadPlainBOOLEAN(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var (
		res []interface{}
		err error
	)

	res = make([]interface{}, cnt)
	resInt, err := ReadBitPacked(bytesReader, uint64(cnt<<1), 1)
	if err != nil {
		return res, err
	}

	for i := 0; i < int(cnt); i++ {
		if resInt[i].(ParquetType.INT64) > 0 {
			res[i] = ParquetType.BOOLEAN(true)
		} else {
			res[i] = ParquetType.BOOLEAN(false)
		}
	}
	return res, err
}

func ReadPlainINT32(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		var cur ParquetType.INT32
		if err = binary.Read(bytesReader, binary.LittleEndian, &cur); err != nil {
			break
		}
		res[i] = cur
	}
	return res, err
}

func ReadPlainINT64(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		var cur ParquetType.INT64
		if err = binary.Read(bytesReader, binary.LittleEndian, &cur); err != nil {
			break
		}
		res[i] = cur
	}
	return res, err
}

func ReadPlainINT96(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		var cur [12]byte
		if err = binary.Read(bytesReader, binary.LittleEndian, &cur); err != nil {
			break
		}
		res[i] = ParquetType.INT96(cur[:12])
	}
	return res, err
}

func ReadPlainFLOAT(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		var cur ParquetType.FLOAT
		if err = binary.Read(bytesReader, binary.LittleEndian, &cur); err != nil {
			break
		}
		res[i] = cur
	}
	return res, err
}

func ReadPlainDOUBLE(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		var cur ParquetType.DOUBLE
		if err = binary.Read(bytesReader, binary.LittleEndian, &cur); err != nil {
			break
		}
		res[i] = cur
	}
	return res, err
}

func ReadPlainBYTE_ARRAY(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		buf := make([]byte, 4)
		if _, err = bytesReader.Read(buf); err != nil {
			break
		}
		ln := binary.LittleEndian.Uint32(buf)
		cur := make([]byte, ln)
		bytesReader.Read(cur)
		res[i] = ParquetType.BYTE_ARRAY(cur)
	}
	return res, err
}

func ReadPlainFIXED_LEN_BYTE_ARRAY(bytesReader *bytes.Reader, cnt uint64, fixedLength uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		cur := make([]byte, fixedLength)
		if _, err = bytesReader.Read(cur); err != nil {
			break
		}
		res[i] = ParquetType.FIXED_LEN_BYTE_ARRAY(cur)
	}
	return res, err
}

func ReadUnsignedVarInt(bytesReader *bytes.Reader) (uint64, error) {
	var err error
	var res uint64 = 0
	var shift uint64 = 0
	for {
		b, err := bytesReader.ReadByte()
		if err != nil {
			break
		}
		res |= ((uint64(b) & uint64(0x7F)) << uint64(shift))
		if (b & 0x80) == 0 {
			break
		}
		shift += 7
	}
	return res, err
}

//RLE return res is []INT64
func ReadRLE(bytesReader *bytes.Reader, header uint64, bitWidth uint64) ([]interface{}, error) {
	var err error
	var res []interface{}
	cnt := header >> 1
	width := (bitWidth + 7) / 8
	data := make([]byte, width)
	if width > 0 {
		if _, err = bytesReader.Read(data); err != nil {
			return res, err
		}
	}
	for len(data) < 4 {
		data = append(data, byte(0))
	}
	val := ParquetType.INT64(binary.LittleEndian.Uint32(data))
	res = make([]interface{}, cnt)

	for i := 0; i < int(cnt); i++ {
		res[i] = val
	}
	return res, err
}

//return res is []INT64
func ReadBitPacked(bytesReader *bytes.Reader, header uint64, bitWidth uint64) ([]interface{}, error) {
	var err error
	numGroup := (header >> 1)
	cnt := numGroup * 8
	byteCnt := cnt * bitWidth / 8

	res := make([]interface{}, 0, cnt)

	if bitWidth == 0 {
		for i := 0; i < int(cnt); i++ {
			res = append(res, ParquetType.INT64(0))
		}
		return res, err
	}
	bytesBuf := make([]byte, byteCnt)
	if _, err = bytesReader.Read(bytesBuf); err != nil {
		return res, err
	}

	i := 0
	var resCur uint64 = 0
	var resCurNeedBits uint64 = bitWidth
	var used uint64 = 0
	var left uint64 = 8 - used
	b := bytesBuf[i]
	for i < len(bytesBuf) {
		if left >= resCurNeedBits {
			resCur |= uint64(((uint64(b) >> uint64(used)) & ((1 << uint64(resCurNeedBits)) - 1)) << uint64(bitWidth-resCurNeedBits))
			res = append(res, ParquetType.INT64(resCur))
			left -= resCurNeedBits
			used += resCurNeedBits

			resCurNeedBits = bitWidth
			resCur = 0

			if left <= 0 && i+1 < len(bytesBuf) {
				i += 1
				b = bytesBuf[i]
				left = 8
				used = 0
			}

		} else {
			resCur |= uint64((uint64(b) >> uint64(used)) << uint64(bitWidth-resCurNeedBits))
			i += 1
			if i < len(bytesBuf) {
				b = bytesBuf[i]
			}
			resCurNeedBits -= left
			left = 8
			used = 0
		}
	}
	return res, err
}

//res is INT64
func ReadRLEBitPackedHybrid(bytesReader *bytes.Reader, bitWidth uint64, length uint64) ([]interface{}, error) {
	res := make([]interface{}, 0)
	if length <= 0 {
		lb, err := ReadPlainINT32(bytesReader, 1)
		if err != nil {
			return res, err
		}
		length = uint64(lb[0].(ParquetType.INT32))
	}

	buf := make([]byte, length)
	if _, err := bytesReader.Read(buf); err != nil {
		return res, err
	}

	newReader := bytes.NewReader(buf)
	for newReader.Len() > 0 {
		header, err := ReadUnsignedVarInt(newReader)
		if err != nil {
			return res, err
		}
		if header&1 == 0 {
			buf, err := ReadRLE(newReader, header, bitWidth)
			if err != nil {
				return res, err
			}
			res = append(res, buf...)

		} else {
			buf, err := ReadBitPacked(newReader, header, bitWidth)
			if err != nil {
				return res, err
			}
			res = append(res, buf...)
		}
	}
	return res, nil
}

//res is INT64
func ReadDeltaBinaryPackedINT(bytesReader *bytes.Reader) ([]interface{}, error) {
	var (
		err error
		res []interface{}
	)

	blockSize, err := ReadUnsignedVarInt(bytesReader)
	if err != nil {
		return res, err
	}
	numMiniblocksInBlock, err := ReadUnsignedVarInt(bytesReader)
	if err != nil {
		return res, err
	}
	numValues, err := ReadUnsignedVarInt(bytesReader)
	if err != nil {
		return res, err
	}
	firstValueZigZag, err := ReadUnsignedVarInt(bytesReader)
	if err != nil {
		return res, err
	}
	var firstValue int64 = int64(firstValueZigZag>>1) ^ (-int64(firstValueZigZag & 1))

	numValuesInMiniBlock := blockSize / numMiniblocksInBlock

	res = make([]interface{}, 0)
	res = append(res, ParquetType.INT64(firstValue))
	for uint64(len(res)) < numValues {
		minDeltaZigZag, err := ReadUnsignedVarInt(bytesReader)
		if err != nil {
			return res, err
		}
		var minDelta int64 = int64(minDeltaZigZag>>1) ^ (-int64(minDeltaZigZag & 1))
		var bitWidths = make([]uint64, numMiniblocksInBlock)
		for i := 0; uint64(i) < numMiniblocksInBlock; i++ {
			b, err := bytesReader.ReadByte()
			if err != nil {
				return res, err
			}
			bitWidths[i] = uint64(b)
		}
		for i := 0; uint64(i) < numMiniblocksInBlock; i++ {
			cur, err := ReadBitPacked(bytesReader, (numValuesInMiniBlock/8)<<1, bitWidths[i])
			if err != nil {
				return res, err
			}
			for j := 0; j < len(cur); j++ {
				res = append(res, ParquetType.INT64(int64(res[len(res)-1].(ParquetType.INT64))+int64(cur[j].(ParquetType.INT64))+minDelta))
			}
		}
	}
	return res[:numValues], err
}

func ReadDeltaLengthByteArray(bytesReader *bytes.Reader) ([]interface{}, error) {
	var (
		res []interface{}
		err error
	)

	lengths, err := ReadDeltaBinaryPackedINT(bytesReader)
	if err != nil {
		return res, err
	}
	res = make([]interface{}, len(lengths))
	for i := 0; i < len(lengths); i++ {
		cur, err := ReadPlainFIXED_LEN_BYTE_ARRAY(bytesReader, 1, uint64(lengths[i].(ParquetType.INT64)))
		if err != nil {
			return res, err
		}
		res[i] = ParquetType.BYTE_ARRAY(cur[0].(ParquetType.FIXED_LEN_BYTE_ARRAY))
	}
	return res, err
}

func ReadDeltaByteArray(bytesReader *bytes.Reader) ([]interface{}, error) {
	var (
		res []interface{}
		err error
	)

	prefixLengths, err := ReadDeltaBinaryPackedINT(bytesReader)
	if err != nil {
		return res, err
	}
	suffixes, err := ReadDeltaLengthByteArray(bytesReader)
	if err != nil {
		return res, err
	}
	res = make([]interface{}, len(prefixLengths))

	res[0] = suffixes[0]
	for i := 1; i < len(prefixLengths); i++ {
		prefixLength := prefixLengths[i].(ParquetType.INT64)
		prefix := res[i-1].(ParquetType.BYTE_ARRAY)[:prefixLength]
		suffix := suffixes[i].(ParquetType.BYTE_ARRAY)
		res[i] = prefix + suffix
	}
	return res, err
}
<commit_msg>Fix panic for zero-length ReadPlainBOOLEAN<commit_after>package ParquetEncoding

import (
	"bytes"
	"encoding/binary"
	"fmt"

	"github.com/xitongsys/parquet-go/ParquetType"
	"github.com/xitongsys/parquet-go/parquet"
)

func ReadPlain(bytesReader *bytes.Reader, dataType parquet.Type, cnt uint64, bitWidth uint64) ([]interface{}, error) {
	if dataType == parquet.Type_BOOLEAN {
		return ReadPlainBOOLEAN(bytesReader, cnt)
	} else if dataType == parquet.Type_INT32 {
		return ReadPlainINT32(bytesReader, cnt)
	} else if dataType == parquet.Type_INT64 {
		return ReadPlainINT64(bytesReader, cnt)
	} else if dataType == parquet.Type_INT96 {
		return ReadPlainINT96(bytesReader, cnt)
	} else if dataType == parquet.Type_FLOAT {
		return ReadPlainFLOAT(bytesReader, cnt)
	} else if dataType == parquet.Type_DOUBLE {
		return ReadPlainDOUBLE(bytesReader, cnt)
	} else if dataType == parquet.Type_BYTE_ARRAY {
		return ReadPlainBYTE_ARRAY(bytesReader, cnt)
	} else if dataType == parquet.Type_FIXED_LEN_BYTE_ARRAY {
		return ReadPlainFIXED_LEN_BYTE_ARRAY(bytesReader, cnt, bitWidth)
	} else {
		return nil, fmt.Errorf("Unknown parquet type")
	}
}

func ReadPlainBOOLEAN(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var (
		res []interface{}
		err error
	)

	res = make([]interface{}, cnt)
	resInt, err := ReadBitPacked(bytesReader, uint64(cnt<<1), 1)
	if err != nil {
		return res, err
	}

	for i := 0; i < int(cnt); i++ {
		if resInt[i].(ParquetType.INT64) > 0 {
			res[i] = ParquetType.BOOLEAN(true)
		} else {
			res[i] = ParquetType.BOOLEAN(false)
		}
	}
	return res, err
}

func ReadPlainINT32(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		var cur ParquetType.INT32
		if err = binary.Read(bytesReader, binary.LittleEndian, &cur); err != nil {
			break
		}
		res[i] = cur
	}
	return res, err
}

func ReadPlainINT64(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		var cur ParquetType.INT64
		if err = binary.Read(bytesReader, binary.LittleEndian, &cur); err != nil {
			break
		}
		res[i] = cur
	}
	return res, err
}

func ReadPlainINT96(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		var cur [12]byte
		if err = binary.Read(bytesReader, binary.LittleEndian, &cur); err != nil {
			break
		}
		res[i] = ParquetType.INT96(cur[:12])
	}
	return res, err
}

func ReadPlainFLOAT(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		var cur ParquetType.FLOAT
		if err = binary.Read(bytesReader, binary.LittleEndian, &cur); err != nil {
			break
		}
		res[i] = cur
	}
	return res, err
}

func ReadPlainDOUBLE(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		var cur ParquetType.DOUBLE
		if err = binary.Read(bytesReader, binary.LittleEndian, &cur); err != nil {
			break
		}
		res[i] = cur
	}
	return res, err
}

func ReadPlainBYTE_ARRAY(bytesReader *bytes.Reader, cnt uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		buf := make([]byte, 4)
		if _, err = bytesReader.Read(buf); err != nil {
			break
		}
		ln := binary.LittleEndian.Uint32(buf)
		cur := make([]byte, ln)
		bytesReader.Read(cur)
		res[i] = ParquetType.BYTE_ARRAY(cur)
	}
	return res, err
}

func ReadPlainFIXED_LEN_BYTE_ARRAY(bytesReader *bytes.Reader, cnt uint64, fixedLength uint64) ([]interface{}, error) {
	var err error
	res := make([]interface{}, cnt)
	for i := 0; i < int(cnt); i++ {
		cur := make([]byte, fixedLength)
		if _, err = bytesReader.Read(cur); err != nil {
			break
		}
		res[i] = ParquetType.FIXED_LEN_BYTE_ARRAY(cur)
	}
	return res, err
}

func ReadUnsignedVarInt(bytesReader *bytes.Reader) (uint64, error) {
	var err error
	var res uint64 = 0
	var shift uint64 = 0
	for {
		b, err := bytesReader.ReadByte()
		if err != nil {
			break
		}
		res |= ((uint64(b) & uint64(0x7F)) << uint64(shift))
		if (b & 0x80) == 0 {
			break
		}
		shift += 7
	}
	return res, err
}

//RLE return res is []INT64
func ReadRLE(bytesReader *bytes.Reader, header uint64, bitWidth uint64) ([]interface{}, error) {
	var err error
	var res []interface{}
	cnt := header >> 1
	width := (bitWidth + 7) / 8
	data := make([]byte, width)
	if width > 0 {
		if _, err = bytesReader.Read(data); err != nil {
			return res, err
		}
	}
	for len(data) < 4 {
		data = append(data, byte(0))
	}
	val := ParquetType.INT64(binary.LittleEndian.Uint32(data))
	res = make([]interface{}, cnt)

	for i := 0; i < int(cnt); i++ {
		res[i] = val
	}
	return res, err
}

//return res is []INT64
func ReadBitPacked(bytesReader *bytes.Reader, header uint64, bitWidth uint64) ([]interface{}, error) {
	var err error
	numGroup := (header >> 1)
	cnt := numGroup * 8
	byteCnt := cnt * bitWidth / 8

	res := make([]interface{}, 0, cnt)

	if cnt == 0 {
		return res, nil
	}

	if bitWidth == 0 {
		for i := 0; i < int(cnt); i++ {
			res = append(res, ParquetType.INT64(0))
		}
		return res, err
	}
	bytesBuf := make([]byte, byteCnt)
	if _, err = bytesReader.Read(bytesBuf); err != nil {
		return res, err
	}

	i := 0
	var resCur uint64 = 0
	var resCurNeedBits uint64 = bitWidth
	var used uint64 = 0
	var left uint64 = 8 - used
	b := bytesBuf[i]
	for i < len(bytesBuf) {
		if left >= resCurNeedBits {
			resCur |= uint64(((uint64(b) >> uint64(used)) & ((1 << uint64(resCurNeedBits)) - 1)) << uint64(bitWidth-resCurNeedBits))
			res = append(res, ParquetType.INT64(resCur))
			left -= resCurNeedBits
			used += resCurNeedBits

			resCurNeedBits = bitWidth
			resCur = 0

			if left <= 0 && i+1 < len(bytesBuf) {
				i += 1
				b = bytesBuf[i]
				left = 8
				used = 0
			}

		} else {
			resCur |= uint64((uint64(b) >> uint64(used)) << uint64(bitWidth-resCurNeedBits))
			i += 1
			if i < len(bytesBuf) {
				b = bytesBuf[i]
			}
			resCurNeedBits -= left
			left = 8
			used = 0
		}
	}
	return res, err
}

//res is INT64
func ReadRLEBitPackedHybrid(bytesReader *bytes.Reader, bitWidth uint64, length uint64) ([]interface{}, error) {
	res := make([]interface{}, 0)
	if length <= 0 {
		lb, err := ReadPlainINT32(bytesReader, 1)
		if err != nil {
			return res, err
		}
		length = uint64(lb[0].(ParquetType.INT32))
	}

	buf := make([]byte, length)
	if _, err := bytesReader.Read(buf); err != nil {
		return res, err
	}

	newReader := bytes.NewReader(buf)
	for newReader.Len() > 0 {
		header, err := ReadUnsignedVarInt(newReader)
		if err != nil {
			return res, err
		}
		if header&1 == 0 {
			buf, err := ReadRLE(newReader, header, bitWidth)
			if err != nil {
				return res, err
			}
			res = append(res, buf...)

		} else {
			buf, err := ReadBitPacked(newReader, header, bitWidth)
			if err != nil {
				return res, err
			}
			res = append(res, buf...)
		}
	}
	return res, nil
}

//res is INT64
func ReadDeltaBinaryPackedINT(bytesReader *bytes.Reader) ([]interface{}, error) {
	var (
		err error
		res []interface{}
	)

	blockSize, err := ReadUnsignedVarInt(bytesReader)
	if err != nil {
		return res, err
	}
	numMiniblocksInBlock, err := ReadUnsignedVarInt(bytesReader)
	if err != nil {
		return res, err
	}
	numValues, err := ReadUnsignedVarInt(bytesReader)
	if err != nil {
		return res, err
	}
	firstValueZigZag, err := ReadUnsignedVarInt(bytesReader)
	if err != nil {
		return res, err
	}
	var firstValue int64 = int64(firstValueZigZag>>1) ^ (-int64(firstValueZigZag & 1))

	numValuesInMiniBlock := blockSize / numMiniblocksInBlock

	res = make([]interface{}, 0)
	res = append(res, ParquetType.INT64(firstValue))
	for uint64(len(res)) < numValues {
		minDeltaZigZag, err := ReadUnsignedVarInt(bytesReader)
		if err != nil {
			return res, err
		}
		var minDelta int64 = int64(minDeltaZigZag>>1) ^ (-int64(minDeltaZigZag & 1))
		var bitWidths = make([]uint64, numMiniblocksInBlock)
		for i := 0; uint64(i) < numMiniblocksInBlock; i++ {
			b, err := bytesReader.ReadByte()
			if err != nil {
				return res, err
			}
			bitWidths[i] = uint64(b)
		}
		for i := 0; uint64(i) < numMiniblocksInBlock; i++ {
			cur, err := ReadBitPacked(bytesReader, (numValuesInMiniBlock/8)<<1, bitWidths[i])
			if err != nil {
				return res, err
			}
			for j := 0; j < len(cur); j++ {
				res = append(res, ParquetType.INT64(int64(res[len(res)-1].(ParquetType.INT64))+int64(cur[j].(ParquetType.INT64))+minDelta))
			}
		}
	}
	return res[:numValues], err
}

func ReadDeltaLengthByteArray(bytesReader *bytes.Reader) ([]interface{}, error) {
	var (
		res []interface{}
		err error
	)

	lengths, err := ReadDeltaBinaryPackedINT(bytesReader)
	if err != nil {
		return res, err
	}
	res = make([]interface{}, len(lengths))
	for i := 0; i < len(lengths); i++ {
		cur, err := ReadPlainFIXED_LEN_BYTE_ARRAY(bytesReader, 1, uint64(lengths[i].(ParquetType.INT64)))
		if err != nil {
			return res, err
		}
		res[i] = ParquetType.BYTE_ARRAY(cur[0].(ParquetType.FIXED_LEN_BYTE_ARRAY))
	}
	return res, err
}

func ReadDeltaByteArray(bytesReader *bytes.Reader) ([]interface{}, error) {
	var (
		res []interface{}
		err error
	)

	prefixLengths, err := ReadDeltaBinaryPackedINT(bytesReader)
	if err != nil {
		return res, err
	}
	suffixes, err := ReadDeltaLengthByteArray(bytesReader)
	if err != nil {
		return res, err
	}
	res = make([]interface{}, len(prefixLengths))

	res[0] = suffixes[0]
	for i := 1; i < len(prefixLengths); i++ {
		prefixLength := prefixLengths[i].(ParquetType.INT64)
		prefix := res[i-1].(ParquetType.BYTE_ARRAY)[:prefixLength]
		suffix := suffixes[i].(ParquetType.BYTE_ARRAY)
		res[i] = prefix + suffix
	}
	return res, err
}
<|endoftext|>


<commit_before>package brokers

import (
	"github.com/eddyzags/kafkactl/api/client"
)

func List(api client.APIClient) error {}
<commit_msg>brokers: Brokers listing handler implemented with all parameter<commit_after>package brokers

import (
	"fmt"
	"os"

	"github.com/eddyzags/kafkactl/api/client"

	"github.com/olekukonko/tablewriter"
)

func List(api client.APIClient, all bool) error {
	brokers, err := api.BrokerList()
	if err != nil {
		return err
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoFormatHeaders(false)
	table.SetAutoWrapText(false)
	if all {
		table.SetHeader([]string{"ID", "ACTIVE", "STATE", "CPUS", "MEM", "HEAP", "HOSTNAME", "ENDPOINT"})
		for _, broker := range brokers {
			table.Append([]string{
				broker.ID,
				broker.Active,
				broker.State,
				fmt.Sprintf("%g", broker.Cpus),
				fmt.Sprintf("%g", broker.Mem),
				fmt.Sprintf("%g", broker.Heap),
				broker.Task.Hostname,
				broker.Task.Endpoint,
			})
		}
	} else {
		table.SetHeader([]string{"ID", "STATE", "CPUS", "MEM", "HEAP", "HOSTNAME", "ENDPOINT"})
		for _, broker := range brokers {
			if broker.Active != true {
				continue
			}

			table.Append([]string{
				broker.ID,
				broker.State,
				fmt.Sprintf("%g", broker.Cpus),
				fmt.Sprintf("%g", broker.Mem),
				fmt.Sprintf("%g", broker.Heap),
				broker.Task.Hostname,
				broker.Task.Endpoint,
			})
		}
	}

	table.Render()

	return nil
}
<|endoftext|>


<commit_before>package goa

import "golang.org/x/net/context"

///////////////////////////////////////////////////////////////////

// OAuth2Security represents the `oauth2` security scheme. It is
// automatically instantiated in your generated code when you use the
// different `*Security()` DSL functions and `Security()` in your
// design.
type OAuth2Security struct {
	// Description of the security scheme
	Description string
	// Flow defines the OAuth2 flow type. See http://swagger.io/specification/#securitySchemeObject
	Flow string
	// TokenURL defines the OAuth2 tokenUrl.  See http://swagger.io/specification/#securitySchemeObject
	TokenURL string
	// AuthenticationURL defines the OAuth2 authenticationUrl.  See http://swagger.io/specification/#securitySchemeObject
	AuthenticationURL string
	// Scopes defines a list of scopes for the security scheme, along with their description.
	Scopes map[string]string
}

// OAuth2SecurityConfigFunc is what you need to pass to the generated
// `ConfigureYourOwnOAuth2Security` functions in your `app`.
//
// The `goa/middleware/security` middlewares implement this for you.
type OAuth2SecurityConfigFunc func(scheme *OAuth2Security, getScopes func(context.Context) []string) Middleware

///////////////////////////////////////////////////////////////////

// BasicAuthSecurity represents the `Basic` security scheme, which
// consists of a simple login/pass, accessible through
// Request.BasicAuth().
type BasicAuthSecurity struct {
	// Description of the security scheme
	Description string
}

// BasicAuthSecurityConfigFunc is what you need to pass to the generated
// `ConfigureYourBasicAuthSecurity` functions in your `app`.
type BasicAuthSecurityConfigFunc func(scheme *BasicAuthSecurity) Middleware

///////////////////////////////////////////////////////////////////

// APIKeySecurity represents the `apiKey` security scheme. It handles
// a key that can be in the headers or in the query parameters, and
// does authentication based on that.  The Name field represents the
// key of either the query string parameter or the header, depending
// on the In field.
type APIKeySecurity struct {
	// Description of the security scheme
	Description string
	// In represents where to check for some data, `query` or `header`
	In string
	// Name is the name of the `header` or `query` parameter to check for data.
	Name string
}

// APIKeySecurityConfigFunc is what you need to pass to the generated
// `ConfigureYourAPIKeySecurity` functions in your `app`.
type APIKeySecurityConfigFunc func(scheme *APIKeySecurity) Middleware

///////////////////////////////////////////////////////////////////

// JWTSecurity represents an api key based scheme, with support for
// scopes and a token URL.
type JWTSecurity struct {
	// Description of the security scheme
	Description string
	// In represents where to check for the JWT, `query` or `header`
	In string
	// Name is the name of the `header` or `query` parameter to check for data.
	Name string
	// TokenURL defines the URL where you'd get the JWT tokens.
	TokenURL string
	// Scopes defines a list of scopes for the security scheme, along with their description.
	Scopes map[string]string
}

// JWTSecurityConfigFunc is what you need to pass to the generated
// `ConfigureYourOwnJWTSecurity` functions in your `app`.
//
// The `goa/middleware/security` middlewares implement this for you.
type JWTSecurityConfigFunc func(scheme *JWTSecurity, getScopes func(context.Context) []string) Middleware
<commit_msg>Rename the `AuthenticationURL` to `AuthorizationURL` .. just got mixed up!<commit_after>package goa

import "golang.org/x/net/context"

///////////////////////////////////////////////////////////////////

// OAuth2Security represents the `oauth2` security scheme. It is
// automatically instantiated in your generated code when you use the
// different `*Security()` DSL functions and `Security()` in your
// design.
type OAuth2Security struct {
	// Description of the security scheme
	Description string
	// Flow defines the OAuth2 flow type. See http://swagger.io/specification/#securitySchemeObject
	Flow string
	// TokenURL defines the OAuth2 tokenUrl.  See http://swagger.io/specification/#securitySchemeObject
	TokenURL string
	// AuthorizationURL defines the OAuth2 authorizationUrl.  See http://swagger.io/specification/#securitySchemeObject
	AuthorizationURL string
	// Scopes defines a list of scopes for the security scheme, along with their description.
	Scopes map[string]string
}

// OAuth2SecurityConfigFunc is what you need to pass to the generated
// `ConfigureYourOwnOAuth2Security` functions in your `app`.
//
// The `goa/middleware/security` middlewares implement this for you.
type OAuth2SecurityConfigFunc func(scheme *OAuth2Security, getScopes func(context.Context) []string) Middleware

///////////////////////////////////////////////////////////////////

// BasicAuthSecurity represents the `Basic` security scheme, which
// consists of a simple login/pass, accessible through
// Request.BasicAuth().
type BasicAuthSecurity struct {
	// Description of the security scheme
	Description string
}

// BasicAuthSecurityConfigFunc is what you need to pass to the generated
// `ConfigureYourBasicAuthSecurity` functions in your `app`.
type BasicAuthSecurityConfigFunc func(scheme *BasicAuthSecurity) Middleware

///////////////////////////////////////////////////////////////////

// APIKeySecurity represents the `apiKey` security scheme. It handles
// a key that can be in the headers or in the query parameters, and
// does authentication based on that.  The Name field represents the
// key of either the query string parameter or the header, depending
// on the In field.
type APIKeySecurity struct {
	// Description of the security scheme
	Description string
	// In represents where to check for some data, `query` or `header`
	In string
	// Name is the name of the `header` or `query` parameter to check for data.
	Name string
}

// APIKeySecurityConfigFunc is what you need to pass to the generated
// `ConfigureYourAPIKeySecurity` functions in your `app`.
type APIKeySecurityConfigFunc func(scheme *APIKeySecurity) Middleware

///////////////////////////////////////////////////////////////////

// JWTSecurity represents an api key based scheme, with support for
// scopes and a token URL.
type JWTSecurity struct {
	// Description of the security scheme
	Description string
	// In represents where to check for the JWT, `query` or `header`
	In string
	// Name is the name of the `header` or `query` parameter to check for data.
	Name string
	// TokenURL defines the URL where you'd get the JWT tokens.
	TokenURL string
	// Scopes defines a list of scopes for the security scheme, along with their description.
	Scopes map[string]string
}

// JWTSecurityConfigFunc is what you need to pass to the generated
// `ConfigureYourOwnJWTSecurity` functions in your `app`.
//
// The `goa/middleware/security` middlewares implement this for you.
type JWTSecurityConfigFunc func(scheme *JWTSecurity, getScopes func(context.Context) []string) Middleware
<|endoftext|>


<commit_before>package main

import (
	"log"

	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3"

	"flag"
)

var (
	dbOption = flag.String("db", "sqlite3", "serve static files located in this directory")
	dbAddr   = flag.String("addr", "sqlite.db", "serve static files located in this directory")
)

func main() {
	flag.Parse()
	if err := run(); err != nil {
		log.Fatal(err)
	}
}

func translate(dialect string) string {
	q := `
	CREATE TABLE authors (
		AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID,
		name VARCHAR(40) NOT NULL
	);

	CREATE TABLE players (
		AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID,
		name VARCHAR(100) NOT NULL,
		version INT NOT NULL,
		author_id INT NOT NULL,
		FOREIGN KEY (author_id) REFERENCES authors (id)
	);

	CREATE TABLE ref_outcome (
		AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID,
		name VARCHAR(25) NOT NULL
	);

	CREATE TABLE games (
		AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID,
		first_player INT NOT NULL,
		second_player INT NOT NULL,
		outcome INT NULL,
		winner INT NULL,
		match_id INT NOT NULL,
		FOREIGN KEY (first_player) REFERENCES players (id),
		FOREIGN KEY (second_player) REFERENCES players (id),
		FOREIGN KEY (outcome_id) REFERENCES ref_outcome (id)
		FOREIGN KEY (winner) REFERENCES players (id),
		FOREIGN KEY (match_id) REFERENCES matches (id)
	);

	CREATE TABLE records (
		game_id INT NOT NULL,
		turn_num INT NOT NULL,
		state JSON NOT NULL
		FOREIGN KEY (game_id) REFERENCES games (id),
		PRIMARY KEY (game_id, turn_num)
	);

	CREATE TABLE matches (
		AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID,
		players[] INT[] NOT NULL
		CHECK (ALL PLAYERS IN players.id)
	);
	`

	var statement string
	switch (dialect){
	case "postgres":
		statement = "id SERIAL PRIMARY KEY"
	case "sqlite3":
		statement = "id INTEGER PRIMARY KEY"
	case "mysql":
		statement = `id INTEGER NOT NULL AUTO_INCREMENT,
		PRIMARY KEY (id)`
	}
	return strings.Replace(q,"AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID", statement, -1)
}

func run() error {
	sql, err := gorm.Open(*dbOption, *dbAddr)
	if err != nil {
		return err
	}

	return sql.Exec(constructed_q).Error
}
<commit_msg>fix bugs<commit_after>package main

import (
	"log"

	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3"

	"flag"
)

var (
	dbOption = flag.String("db", "sqlite3", "serve static files located in this directory")
	dbAddr   = flag.String("addr", "sqlite.db", "serve static files located in this directory")
)

func main() {
	flag.Parse()
	if err := run(); err != nil {
		log.Fatal(err)
	}
}

func translate(dialect string) string {
	q := `
	CREATE TABLE authors (
		AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID,
		name VARCHAR(40) NOT NULL
	);

	CREATE TABLE players (
		AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID,
		name VARCHAR(100) NOT NULL,
		version INT NOT NULL,
		author_id INT NOT NULL,
		FOREIGN KEY (author_id) REFERENCES authors (id)
	);

	CREATE TABLE ref_outcome (
		AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID,
		name VARCHAR(25) NOT NULL
	);

	CREATE TABLE games (
		AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID,
		first_player INT NOT NULL,
		second_player INT NOT NULL,
		outcome INT NULL,
		winner INT NULL,
		match_id INT NOT NULL,
		FOREIGN KEY (first_player) REFERENCES players (id),
		FOREIGN KEY (second_player) REFERENCES players (id),
		FOREIGN KEY (outcome_id) REFERENCES ref_outcome (id),
		FOREIGN KEY (winner) REFERENCES players (id),
		FOREIGN KEY (match_id) REFERENCES matches (id)
	);

	CREATE TABLE records (
		game_id INT NOT NULL,
		turn_num INT NOT NULL,
		state JSON NOT NULL,
		FOREIGN KEY (game_id) REFERENCES games (id),
		PRIMARY KEY (game_id, turn_num)
	);

	CREATE TABLE matches (
		AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID,
		players[] INT[] NOT NULL
	);
	`

	var statement string
	switch (dialect){
	case "postgres":
		statement = "id SERIAL PRIMARY KEY"
	case "sqlite3":
		statement = "id INTEGER PRIMARY KEY"
	case "mysql":
		statement = `id INTEGER NOT NULL AUTO_INCREMENT,
		PRIMARY KEY (id)`
	}
	return strings.Replace(q,"AUTOINCREMENTING_PRIMARYKEY_INTEGER_ID", statement, -1)
}

func run() error {
	sql, err := gorm.Open(*dbOption, *dbAddr)
	if err != nil {
		return err
	}

	return sql.Exec(constructed_q).Error
}
<|endoftext|>


<commit_before>// Copyright 2020 Google Inc. All Rights Reserved.
//
// 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 vrf

import (
	"crypto/elliptic"
	"crypto/rand"
	"testing"
)

func TestCompressedMarshalUnmarshal(t *testing.T) {
	c := elliptic.P256()
	_, Ax, Ay, err := elliptic.GenerateKey(c, rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	b := marshalCompressed(c, Ax, Ay)
	Bx, By, err := unmarshalCompressed(c, b)
	if err != nil {
		t.Fatal(err)
	}
	if Bx.Cmp(Ax) != 0 {
		t.Fatalf("Bx: %v, want %v", Bx, Ax)
	}
	if By.Cmp(Ay) != 0 {
		t.Fatalf("By: %v, want %v", By, Ay)
	}
}
<commit_msg>wycheproof test vectors for compressed curve points<commit_after>// Copyright 2020 Google Inc. All Rights Reserved.
//
// 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.

// +build !go1.15

package vrf

import (
	"bytes"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/hex"
	"errors"
	"fmt"
	"testing"
)

func TestCompressedMarshalUnmarshal(t *testing.T) {
	c := elliptic.P256()
	_, Ax, Ay, err := elliptic.GenerateKey(c, rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	b := marshalCompressed(c, Ax, Ay)
	Bx, By, err := unmarshalCompressed(c, b)
	if err != nil {
		t.Fatal(err)
	}
	if Bx.Cmp(Ax) != 0 {
		t.Fatalf("Bx: %v, want %v", Bx, Ax)
	}
	if By.Cmp(Ay) != 0 {
		t.Fatalf("By: %v, want %v", By, Ay)
	}
}

func hexd(t testing.TB, h string) []byte {
	t.Helper()
	b, err := hex.DecodeString(h)
	if err != nil {
		t.Fatal(err)
	}
	return b
}

// https://github.com/google/wycheproof/blob/master/testvectors/ecdh_secp256r1_test.json
func TestWycheproof(t *testing.T) {
	curve := elliptic.P256() //secp256r1
	for _, tc := range []struct {
		tcID    int
		comment string
		public  []byte
		private []byte
		shared  []byte
		result  error
	}{

		{
			tcID:    2,
			comment: "compressed public key",
			public:  hexd(t, "3039301306072a8648ce3d020106082a8648ce3d0301070322000362d5bd3372af75fe85a040715d0f502428e07046868b0bfdfa61d731afe44f26"),
			private: hexd(t, "0612465c89a023ab17855b0a6bcebfd3febb53aef84138647b5352e02c10c346"),
			shared:  hexd(t, "53020d908b0219328b658b525f26780e3ae12bcd952bb25a93bc0895e1714285"),
			result:  nil,
		},
		{
			tcID:    243,
			comment: "invalid public key",
			public:  hexd(t, "3039301306072a8648ce3d020106082a8648ce3d03010703220002fd4bf61763b46581fd9174d623516cf3c81edd40e29ffa2777fb6cb0ae3ce535"),
			private: hexd(t, "6f953faff3599e6c762d7f4cabfeed092de2add1df1bc5748c6cbb725cf35458"),
			result:  errInvalidPoint,
		},
		{
			tcID:    244,
			comment: "public key is a low order point on twist",
			public:  hexd(t, "3039301306072a8648ce3d020106082a8648ce3d03010703220003efdde3b32872a9effcf3b94cbf73aa7b39f9683ece9121b9852167f4e3da609b"),
			private: hexd(t, "00d27edf0ff5b6b6b465753e7158370332c153b468a1be087ad0f490bdb99e5f02"),
			result:  errInvalidPoint,
		},
		{
			tcID:    245,
			comment: "public key is a low order point on twist",
			public:  hexd(t, "3039301306072a8648ce3d020106082a8648ce3d03010703220002efdde3b32872a9effcf3b94cbf73aa7b39f9683ece9121b9852167f4e3da609b"),
			private: hexd(t, "00d27edf0ff5b6b6b465753e7158370332c153b468a1be087ad0f490bdb99e5f03"),
			result:  errInvalidPoint,
		},
		{
			tcID:    246,
			comment: "public key is a low order point on twist",
			public:  hexd(t, "3039301306072a8648ce3d020106082a8648ce3d03010703220002c49524b2adfd8f5f972ef554652836e2efb2d306c6d3b0689234cec93ae73db5"),
			private: hexd(t, "0095ead84540c2d027aa3130ff1b47888cc1ed67e8dda46156e71ce0991791e835"),
			result:  errInvalidPoint,
		},
		{
			tcID:    247,
			comment: "public key is a low order point on twist",
			public:  hexd(t, "3039301306072a8648ce3d020106082a8648ce3d0301070322000318f9bae7747cd844e98525b7ccd0daf6e1d20a818b2175a9a91e4eae5343bc98"),
			private: hexd(t, "00a8681ef67fb1f189647d95e8db00c52ceef6d41a85ba0a5bd74c44e8e62c8aa4"),
			result:  errInvalidPoint,
		},
		{
			tcID:    248,
			comment: "public key is a low order point on twist",
			public:  hexd(t, "3039301306072a8648ce3d020106082a8648ce3d0301070322000218f9bae7747cd844e98525b7ccd0daf6e1d20a818b2175a9a91e4eae5343bc98"),
			private: hexd(t, "00a8681ef67fb1f189647d95e8db00c52ceef6d41a85ba0a5bd74c44e8e62c8aa5"),
			result:  errInvalidPoint,
		},
		{
			tcID:    249,
			comment: "public key is a low order point on twist",
			public:  hexd(t, "3039301306072a8648ce3d020106082a8648ce3d03010703220003c49524b2adfd8f5f972ef554652836e2efb2d306c6d3b0689234cec93ae73db5"),
			private: hexd(t, "0095ead84540c2d027aa3130ff1b47888cc1ed67e8dda46156e71ce0991791e834"),
			result:  errInvalidPoint,
		},
	} {
		t.Run(fmt.Sprintf("%d", tc.tcID), func(t *testing.T) {
			t.Logf("comment: %s", tc.comment)

			// parse public key as x509 ASN.1
			var pki struct {
				Raw       asn1.RawContent
				Algorithm pkix.AlgorithmIdentifier
				PublicKey asn1.BitString
			}
			if _, err := asn1.Unmarshal(tc.public, &pki); err != nil {
				t.Fatal(err)
			}
			asn1Data := pki.PublicKey.RightAlign()
			t.Logf("public key: %x", asn1Data)

			x, y, err := unmarshalCompressed(curve, asn1Data)
			if !errors.Is(err, tc.result) {
				t.Errorf("got err %q, want %q", err, tc.result)
			}
			if err != nil {
				return
			}

			// Compute ECDH shared secret to complete the test
			Sx, _ := curve.ScalarMult(x, y, tc.private)
			if got := Sx.Bytes(); !bytes.Equal(got, tc.shared) {
				t.Errorf("shared secret: %x, want %x", got, tc.shared)
			}
		})
	}
}
<|endoftext|>


<commit_before>package jointlock_test

import (
	"errors"
	"os"
	"time"

	"code.cloudfoundry.org/clock/fakeclock"
	"code.cloudfoundry.org/locket/jointlock"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/fake_runner"
	"github.com/tedsuo/ifrit/ginkgomon"
	"github.com/tedsuo/ifrit/grouper"
)

var _ = Describe("Jointlock", func() {
	var (
		jointLock                ifrit.Runner
		jointLockProcess         ifrit.Process
		timeout                  time.Duration
		fakeClock                *fakeclock.FakeClock
		testRunner1, testRunner2 *fake_runner.TestRunner
	)

	BeforeEach(func() {
		timeout = 5 * time.Second
		fakeClock = fakeclock.NewFakeClock(time.Now())
		testRunner1 = fake_runner.NewTestRunner()
		testRunner2 = fake_runner.NewTestRunner()
	})

	JustBeforeEach(func() {
		jointLock = jointlock.NewJointLock(
			fakeClock,
			timeout,
			grouper.Member{"test1", testRunner1},
			grouper.Member{"test2", testRunner2},
		)
		jointLockProcess = ifrit.Background(jointLock)
	})

	AfterEach(func() {
		Eventually(testRunner1.RunCallCount).Should(Equal(1))
		testRunner1.EnsureExit()
		testRunner2.EnsureExit()
		ginkgomon.Interrupt(jointLockProcess)
	})

	It("starts both runners in serial", func() {
		Consistently(jointLockProcess.Ready()).ShouldNot(BeClosed())
		testRunner1.TriggerReady()
		Consistently(jointLockProcess.Ready()).ShouldNot(BeClosed())
		testRunner2.TriggerReady()
		Eventually(jointLockProcess.Ready()).Should(BeClosed())
		Consistently(jointLockProcess.Wait()).ShouldNot(Receive())

		Expect(testRunner1.RunCallCount()).To(Equal(1))
		Expect(testRunner2.RunCallCount()).To(Equal(1))
	})

	Context("when there are no runners", func() {
		It("blocks waiting for signal", func() {
			jointLock := jointlock.NewJointLock(fakeClock, timeout)
			process := ifrit.Background(jointLock)
			Eventually(process.Ready()).Should(BeClosed())
		})
	})

	Context("when the first runner fails to start", func() {
		It("propagates the error", func() {
			testRunner1.TriggerExit(errors.New("boom"))
			Eventually(jointLockProcess.Wait()).Should(Receive(HaveOccurred()))
		})
	})

	Context("when the second runner fails to start", func() {
		It("propagates the error", func() {
			Eventually(testRunner1.RunCallCount).Should(Equal(1))
			signals, _ := testRunner1.RunArgsForCall(0)
			testRunner1.TriggerReady()
			testRunner2.TriggerExit(errors.New("boom"))
			Eventually(signals).Should(Receive(Equal(os.Interrupt)))
			testRunner1.EnsureExit()
			Eventually(jointLockProcess.Wait()).Should(Receive(HaveOccurred()))
		})
	})

	Context("when the first runner takes longer than the timeout to be ready", func() {
		AfterEach(func() {
			testRunner1.TriggerReady()
			testRunner2.TriggerReady()
		})

		It("waits until the first runner is ready", func() {
			Consistently(jointLockProcess.Wait()).ShouldNot(Receive())
			fakeClock.Increment(timeout)
			Consistently(jointLockProcess.Wait()).ShouldNot(Receive())
		})

		Context("and the process is signalled", func() {
			It("propagates the signal to the first runner and exits", func() {

			})
		})
	})

	Context("when the second runner never becomes ready", func() {
		It("eventually times out and exits", func() {
			Eventually(testRunner1.RunCallCount).Should(Equal(1))
			signals, _ := testRunner1.RunArgsForCall(0)
			testRunner1.TriggerReady()
			Consistently(jointLockProcess.Wait()).ShouldNot(Receive())
			fakeClock.Increment(timeout)
			Eventually(signals).Should(Receive(Equal(os.Interrupt)))
			testRunner1.EnsureExit()
			Eventually(jointLockProcess.Wait()).Should(Receive(HaveOccurred()))
		})
	})
})
<commit_msg>remove unused test<commit_after>package jointlock_test

import (
	"errors"
	"os"
	"time"

	"code.cloudfoundry.org/clock/fakeclock"
	"code.cloudfoundry.org/locket/jointlock"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/fake_runner"
	"github.com/tedsuo/ifrit/ginkgomon"
	"github.com/tedsuo/ifrit/grouper"
)

var _ = Describe("Jointlock", func() {
	var (
		jointLock                ifrit.Runner
		jointLockProcess         ifrit.Process
		timeout                  time.Duration
		fakeClock                *fakeclock.FakeClock
		testRunner1, testRunner2 *fake_runner.TestRunner
	)

	BeforeEach(func() {
		timeout = 5 * time.Second
		fakeClock = fakeclock.NewFakeClock(time.Now())
		testRunner1 = fake_runner.NewTestRunner()
		testRunner2 = fake_runner.NewTestRunner()
	})

	JustBeforeEach(func() {
		jointLock = jointlock.NewJointLock(
			fakeClock,
			timeout,
			grouper.Member{"test1", testRunner1},
			grouper.Member{"test2", testRunner2},
		)
		jointLockProcess = ifrit.Background(jointLock)
	})

	AfterEach(func() {
		Eventually(testRunner1.RunCallCount).Should(Equal(1))
		testRunner1.EnsureExit()
		testRunner2.EnsureExit()
		ginkgomon.Interrupt(jointLockProcess)
	})

	It("starts both runners in serial", func() {
		Consistently(jointLockProcess.Ready()).ShouldNot(BeClosed())
		testRunner1.TriggerReady()
		Consistently(jointLockProcess.Ready()).ShouldNot(BeClosed())
		testRunner2.TriggerReady()
		Eventually(jointLockProcess.Ready()).Should(BeClosed())
		Consistently(jointLockProcess.Wait()).ShouldNot(Receive())

		Expect(testRunner1.RunCallCount()).To(Equal(1))
		Expect(testRunner2.RunCallCount()).To(Equal(1))
	})

	Context("when there are no runners", func() {
		It("blocks waiting for signal", func() {
			jointLock := jointlock.NewJointLock(fakeClock, timeout)
			process := ifrit.Background(jointLock)
			Eventually(process.Ready()).Should(BeClosed())
		})
	})

	Context("when the first runner fails to start", func() {
		It("propagates the error", func() {
			testRunner1.TriggerExit(errors.New("boom"))
			Eventually(jointLockProcess.Wait()).Should(Receive(HaveOccurred()))
		})
	})

	Context("when the second runner fails to start", func() {
		It("propagates the error", func() {
			Eventually(testRunner1.RunCallCount).Should(Equal(1))
			signals, _ := testRunner1.RunArgsForCall(0)
			testRunner1.TriggerReady()
			testRunner2.TriggerExit(errors.New("boom"))
			Eventually(signals).Should(Receive(Equal(os.Interrupt)))
			testRunner1.EnsureExit()
			Eventually(jointLockProcess.Wait()).Should(Receive(HaveOccurred()))
		})
	})

	Context("when the first runner takes longer than the timeout to be ready", func() {
		AfterEach(func() {
			testRunner1.TriggerReady()
			testRunner2.TriggerReady()
		})

		It("waits until the first runner is ready", func() {
			Consistently(jointLockProcess.Wait()).ShouldNot(Receive())
			fakeClock.Increment(timeout)
			Consistently(jointLockProcess.Wait()).ShouldNot(Receive())
		})
	})

	Context("when the second runner never becomes ready", func() {
		It("eventually times out and exits", func() {
			Eventually(testRunner1.RunCallCount).Should(Equal(1))
			signals, _ := testRunner1.RunArgsForCall(0)
			testRunner1.TriggerReady()
			Consistently(jointLockProcess.Wait()).ShouldNot(Receive())
			fakeClock.Increment(timeout)
			Eventually(signals).Should(Receive(Equal(os.Interrupt)))
			testRunner1.EnsureExit()
			Eventually(jointLockProcess.Wait()).Should(Receive(HaveOccurred()))
		})
	})
})
<|endoftext|>