<commit_before>package core

import (
	"context"

	"v2ray.com/core/common"
)

// CreateObject creates a new object based on the given V2Ray instance and config. The V2Ray instance may be nil.
func CreateObject(v *Instance, config interface{}) (interface{}, error) {
	ctx := context.Background()
	if v != nil {
		ctx = context.WithValue(ctx, v2rayKey, v)
	}
	return common.CreateObject(ctx, config)
}

func PrintDeprecatedFeatureWarning(feature string) {
	newError("You are using a deprecated feature: " + feature + ". Please update your config file with latest configuration format, or update your client software.")
}
<commit_msg>write error to log<commit_after>package core

import (
	"context"

	"v2ray.com/core/common"
)

// CreateObject creates a new object based on the given V2Ray instance and config. The V2Ray instance may be nil.
func CreateObject(v *Instance, config interface{}) (interface{}, error) {
	ctx := context.Background()
	if v != nil {
		ctx = context.WithValue(ctx, v2rayKey, v)
	}
	return common.CreateObject(ctx, config)
}

func PrintDeprecatedFeatureWarning(feature string) {
	newError("You are using a deprecated feature: " + feature + ". Please update your config file with latest configuration format, or update your client software.").WriteToLog()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"sync"

	_ "github.com/mattn/go-sqlite3"

	"github.com/biogo/biogo/feat"
	"github.com/jmoiron/sqlx"
	"github.com/mnsmar/htsdb"
	"gopkg.in/alecthomas/kingpin.v2"
)

const prog = "htsdb-relative-pos-dist"
const version = "0.2"
const descr = `Measure relative position distribution for reads in database 1
against reads in database 2. For each possible relative position, print the
number of read pairs with this relative positioning, the total number of
possible pairs and the total number of reads in each database. Read relative
position is measured either 5'-5' or 3'-3'. Positive numbers indicate read 1
is downstream of read 2. Provided SQL
filters will apply to all counts.`

var (
	app = kingpin.New(prog, descr)

	dbFile1 = app.Flag("db1", "SQLite file for database 1.").
		PlaceHolder("<file>").Required().String()
	tab1 = app.Flag("table1", "Database table name for db1.").
		Default("sample").String()
	where1 = app.Flag("where1", "SQL filter injected in WHERE clause for db1.").
		PlaceHolder("<SQL>").String()
	dbFile2 = app.Flag("db2", "SQLite file for database 2.").
		PlaceHolder("<file>").Required().String()
	tab2 = app.Flag("table2", "Database table name for db2.").
		Default("sample").String()
	where2 = app.Flag("where2", "SQL filter injected in WHERE clause for db2.").
		PlaceHolder("<SQL>").String()
	from = app.Flag("pos", "Reference point for relative position measurement.").
		Required().PlaceHolder("<5p|3p>").Enum("5p", "3p")
	anti = app.Flag("anti", "Compare reads on opposite instead of same orientation.").
		Bool()
	span = app.Flag("span", "Maximum distance between compared reads.").
		Default("100").PlaceHolder("<int>").Int()
	verbose = app.Flag("verbose", "Verbose mode.").Short('v').Bool()
)

func main() {
	app.HelpFlag.Short('h')
	app.Version(version)
	_, err := app.Parse(os.Args[1:])
	if err != nil {
		kingpin.Fatalf("%s", err)
	}

	// assemble sqlx select builders
	readsBuilder1 := htsdb.RangeBuilder.From(*tab1)
	countBuilder1 := htsdb.CountBuilder.From(*tab1)
	if *where1 != "" {
		readsBuilder1 = readsBuilder1.Where(*where1)
		countBuilder1 = countBuilder1.Where(*where1)
	}
	readsBuilder2 := htsdb.RangeBuilder.From(*tab2)
	refsBuilder2 := htsdb.ReferenceBuilder.From(*tab2)
	countBuilder2 := htsdb.CountBuilder.From(*tab2)
	if *where2 != "" {
		readsBuilder2 = readsBuilder2.Where(*where2)
		refsBuilder2 = refsBuilder2.Where(*where2)
		countBuilder2 = countBuilder2.Where(*where2)
	}

	// open database connections.
	var db1, db2 *sqlx.DB
	if db1, err = sqlx.Connect("sqlite3", *dbFile1); err != nil {
		panic(err)
	}
	if db2, err = sqlx.Connect("sqlite3", *dbFile2); err != nil {
		panic(err)
	}

	// prepare statements.
	query1, _, err := readsBuilder1.Where("strand = ? AND rname = ?").ToSql()
	panicOnError(err)
	readsStmt1, err := db1.Preparex(query1)
	panicOnError(err)
	query2, _, err := readsBuilder2.Where("strand = ? AND rname = ?").ToSql()
	panicOnError(err)
	readsStmt2, err := db2.Preparex(query2)
	panicOnError(err)

	// select reference features
	refs, err := htsdb.SelectReferences(db2, refsBuilder2)

	// count records
	countQuery1, _, err := countBuilder1.ToSql()
	panicOnError(err)
	var totalCount1 int
	if err = db1.Get(&totalCount1, countQuery1); err != nil {
		panic(err)
	}
	countQuery2, _, err := countBuilder2.ToSql()
	panicOnError(err)
	var totalCount2 int
	if err = db2.Get(&totalCount2, countQuery2); err != nil {
		panic(err)
	}

	// get position extracting function
	getPos := htsdb.Head
	if *from == "3p" {
		getPos = htsdb.Tail
	}

	// count histogram around reference.
	hists := make(chan map[int]uint)
	var wg sync.WaitGroup
	for _, ref := range refs {
		for _, ori := range []feat.Orientation{feat.Forward, feat.Reverse} {
			wg.Add(1)
			go func(ori feat.Orientation, ref htsdb.Reference) {
				if *verbose == true {
					log.Printf("orient:%s, chrom:%s\n", ori, ref.Chrom)
				}
				defer wg.Done()
				var r htsdb.Range

				wig := make(map[int]uint)
				ori1 := ori
				if *anti == true {
					ori1 = -1 * ori1
				}
				rows1, err := readsStmt1.Queryx(ori1, ref.Chrom)
				panicOnError(err)
				for rows1.Next() {
					err = rows1.StructScan(&r)
					panicOnError(err)
					pos := getPos(&r, ori1)
					wig[pos]++
				}

				hist := make(map[int]uint)
				rows2, err := readsStmt2.Queryx(ori, ref.Chrom)
				panicOnError(err)
				for rows2.Next() {
					err = rows2.StructScan(&r)
					panicOnError(err)
					pos := getPos(&r, ori)
					for relPos := -*span; relPos <= *span; relPos++ {
						if pos+relPos < 0 {
							continue
						}
						hist[relPos*int(ori)] += wig[pos+relPos]
					}
				}
				hists <- hist
			}(ori, ref)
		}
	}

	go func() {
		wg.Wait()
		close(hists)

	}()

	// aggregate histograms from goroutines
	aggrHist := make(map[int]uint)
	for hist := range hists {
		for k, v := range hist {
			aggrHist[k] += v
		}
	}

	// print results.
	fmt.Printf("pos\tpairs\treadCount1\treadCount2\n")
	for i := -*span; i <= *span; i++ {
		fmt.Printf("%d\t%d\t%d\t%d\n", i, aggrHist[i], totalCount1, totalCount2)
	}
}

func panicOnError(err error) {
	if err != nil {
		panic(err)
	}
}
<commit_msg>htsdb-relative-pos-distro: fix program name<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"sync"

	_ "github.com/mattn/go-sqlite3"

	"github.com/biogo/biogo/feat"
	"github.com/jmoiron/sqlx"
	"github.com/mnsmar/htsdb"
	"gopkg.in/alecthomas/kingpin.v2"
)

const prog = "htsdb-relative-pos-distro"
const version = "0.2"
const descr = `Measure relative position distribution for reads in database 1
against reads in database 2. For each possible relative position, print the
number of read pairs with this relative positioning, the total number of
possible pairs and the total number of reads in each database. Read relative
position is measured either 5'-5' or 3'-3'. Positive numbers indicate read 1
is downstream of read 2. Provided SQL
filters will apply to all counts.`

var (
	app = kingpin.New(prog, descr)

	dbFile1 = app.Flag("db1", "SQLite file for database 1.").
		PlaceHolder("<file>").Required().String()
	tab1 = app.Flag("table1", "Database table name for db1.").
		Default("sample").String()
	where1 = app.Flag("where1", "SQL filter injected in WHERE clause for db1.").
		PlaceHolder("<SQL>").String()
	dbFile2 = app.Flag("db2", "SQLite file for database 2.").
		PlaceHolder("<file>").Required().String()
	tab2 = app.Flag("table2", "Database table name for db2.").
		Default("sample").String()
	where2 = app.Flag("where2", "SQL filter injected in WHERE clause for db2.").
		PlaceHolder("<SQL>").String()
	from = app.Flag("pos", "Reference point for relative position measurement.").
		Required().PlaceHolder("<5p|3p>").Enum("5p", "3p")
	anti = app.Flag("anti", "Compare reads on opposite instead of same orientation.").
		Bool()
	span = app.Flag("span", "Maximum distance between compared reads.").
		Default("100").PlaceHolder("<int>").Int()
	verbose = app.Flag("verbose", "Verbose mode.").Short('v').Bool()
)

func main() {
	app.HelpFlag.Short('h')
	app.Version(version)
	_, err := app.Parse(os.Args[1:])
	if err != nil {
		kingpin.Fatalf("%s", err)
	}

	// assemble sqlx select builders
	readsBuilder1 := htsdb.RangeBuilder.From(*tab1)
	countBuilder1 := htsdb.CountBuilder.From(*tab1)
	if *where1 != "" {
		readsBuilder1 = readsBuilder1.Where(*where1)
		countBuilder1 = countBuilder1.Where(*where1)
	}
	readsBuilder2 := htsdb.RangeBuilder.From(*tab2)
	refsBuilder2 := htsdb.ReferenceBuilder.From(*tab2)
	countBuilder2 := htsdb.CountBuilder.From(*tab2)
	if *where2 != "" {
		readsBuilder2 = readsBuilder2.Where(*where2)
		refsBuilder2 = refsBuilder2.Where(*where2)
		countBuilder2 = countBuilder2.Where(*where2)
	}

	// open database connections.
	var db1, db2 *sqlx.DB
	if db1, err = sqlx.Connect("sqlite3", *dbFile1); err != nil {
		panic(err)
	}
	if db2, err = sqlx.Connect("sqlite3", *dbFile2); err != nil {
		panic(err)
	}

	// prepare statements.
	query1, _, err := readsBuilder1.Where("strand = ? AND rname = ?").ToSql()
	panicOnError(err)
	readsStmt1, err := db1.Preparex(query1)
	panicOnError(err)
	query2, _, err := readsBuilder2.Where("strand = ? AND rname = ?").ToSql()
	panicOnError(err)
	readsStmt2, err := db2.Preparex(query2)
	panicOnError(err)

	// select reference features
	refs, err := htsdb.SelectReferences(db2, refsBuilder2)

	// count records
	countQuery1, _, err := countBuilder1.ToSql()
	panicOnError(err)
	var totalCount1 int
	if err = db1.Get(&totalCount1, countQuery1); err != nil {
		panic(err)
	}
	countQuery2, _, err := countBuilder2.ToSql()
	panicOnError(err)
	var totalCount2 int
	if err = db2.Get(&totalCount2, countQuery2); err != nil {
		panic(err)
	}

	// get position extracting function
	getPos := htsdb.Head
	if *from == "3p" {
		getPos = htsdb.Tail
	}

	// count histogram around reference.
	hists := make(chan map[int]uint)
	var wg sync.WaitGroup
	for _, ref := range refs {
		for _, ori := range []feat.Orientation{feat.Forward, feat.Reverse} {
			wg.Add(1)
			go func(ori feat.Orientation, ref htsdb.Reference) {
				if *verbose == true {
					log.Printf("orient:%s, chrom:%s\n", ori, ref.Chrom)
				}
				defer wg.Done()
				var r htsdb.Range

				wig := make(map[int]uint)
				ori1 := ori
				if *anti == true {
					ori1 = -1 * ori1
				}
				rows1, err := readsStmt1.Queryx(ori1, ref.Chrom)
				panicOnError(err)
				for rows1.Next() {
					err = rows1.StructScan(&r)
					panicOnError(err)
					pos := getPos(&r, ori1)
					wig[pos]++
				}

				hist := make(map[int]uint)
				rows2, err := readsStmt2.Queryx(ori, ref.Chrom)
				panicOnError(err)
				for rows2.Next() {
					err = rows2.StructScan(&r)
					panicOnError(err)
					pos := getPos(&r, ori)
					for relPos := -*span; relPos <= *span; relPos++ {
						if pos+relPos < 0 {
							continue
						}
						hist[relPos*int(ori)] += wig[pos+relPos]
					}
				}
				hists <- hist
			}(ori, ref)
		}
	}

	go func() {
		wg.Wait()
		close(hists)

	}()

	// aggregate histograms from goroutines
	aggrHist := make(map[int]uint)
	for hist := range hists {
		for k, v := range hist {
			aggrHist[k] += v
		}
	}

	// print results.
	fmt.Printf("pos\tpairs\treadCount1\treadCount2\n")
	for i := -*span; i <= *span; i++ {
		fmt.Printf("%d\t%d\t%d\t%d\n", i, aggrHist[i], totalCount1, totalCount2)
	}
}

func panicOnError(err error) {
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Eleme Inc. All rights reserved.

package webapp

import (
	"github.com/eleme/banshee/models"
	"github.com/jinzhu/gorm"
	"github.com/julienschmidt/httprouter"
	"github.com/mattn/go-sqlite3"
	"net/http"
	"strconv"
)

// getProjects returns all projects.
func getProjects(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var projs []models.Project
	if err := db.Admin.DB().Find(&projs).Error; err != nil {
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	ResponseJSONOK(w, projs)
}

// getProject returns project by id.
func getProject(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Query db.
	proj := &models.Project{}
	if err := db.Admin.DB().First(proj, id).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrProjectNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
	ResponseJSONOK(w, proj)
}

// createProject request
type createProjectRequest struct {
	Name string `json:"name"`
}

// createProject creates a project.
func createProject(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	// Request
	req := &createProjectRequest{}
	if err := RequestBind(r, req); err != nil {
		ResponseError(w, ErrBadRequest)
		return
	}
	// Validate
	if err := models.ValidateProjectName(req.Name); err != nil {
		ResponseError(w, NewValidationWebError(err))
		return
	}
	// Save.
	proj := &models.Project{Name: req.Name}
	if err := db.Admin.DB().Create(proj).Error; err != nil {
		sqliteErr, ok := err.(sqlite3.Error)
		if ok {
			switch sqliteErr.ExtendedCode {
			case sqlite3.ErrConstraintNotNull:
				ResponseError(w, ErrNotNull)
				return
			case sqlite3.ErrConstraintPrimaryKey:
				ResponseError(w, ErrPrimaryKey)
				return
			case sqlite3.ErrConstraintUnique:
				ResponseError(w, ErrDuplicateProjectName)
				return
			}
		}
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	ResponseJSONOK(w, proj)
}

// updateProject request
type updateProjectRequest struct {
	Name string `json:"name"`
}

// updateProject updates a project.
func updateProject(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Request
	req := &updateProjectRequest{}
	if err := RequestBind(r, req); err != nil {
		ResponseError(w, ErrBadRequest)
		return
	}
	// Validate
	if err := models.ValidateProjectName(req.Name); err != nil {
		ResponseError(w, NewValidationWebError(err))
		return
	}
	// Find
	proj := &models.Project{}
	if err := db.Admin.DB().First(proj, id).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrProjectNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
	// Patch.
	proj.Name = req.Name
	if err := db.Admin.DB().Save(proj).Error; err != nil {
		if err == gorm.RecordNotFound {
			// Not found.
			ResponseError(w, ErrProjectNotFound)
			return
		}
		// Writer errors.
		sqliteErr, ok := err.(sqlite3.Error)
		if ok {
			switch sqliteErr.ExtendedCode {
			case sqlite3.ErrConstraintNotNull:
				ResponseError(w, ErrNotNull)
				return
			case sqlite3.ErrConstraintUnique:
				ResponseError(w, ErrDuplicateProjectName)
				return
			}
		}
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	ResponseJSONOK(w, proj)
}

// deleteProject deletes a project.
func deleteProject(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Delete.
	if err := db.Admin.DB().Delete(&models.Project{ID: id}).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrProjectNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
}

// getProjectRules gets project rules.
func getProjectRules(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Query
	var rules []models.Rule
	if err := db.Admin.DB().Model(&models.Project{ID: id}).Related(&rules).Error; err != nil {
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	for i := 0; i < len(rules); i++ {
		rules[i].BuildRepr()
		rules[i].SetNumMetrics(len(db.Index.Filter(rules[i].Pattern)))
	}
	ResponseJSONOK(w, rules)
}

// getProjectUsers gets project users.
func getProjectUsers(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Query
	var users []models.User
	if err := db.Admin.DB().Model(&models.Project{ID: id}).Association("Users").Find(&users).Error; err != nil {
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	// Universals
	var univs []models.User
	if err := db.Admin.DB().Where("universal = ?", true).Find(&univs).Error; err != nil {
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	users = append(users, univs...)
	ResponseJSONOK(w, users)
}

// addProjectUserRequest is the request of addProjectUser
type addProjectUserRequest struct {
	Name string `json:"name"`
}

// projectUser is the tempory select result for table `project_users`
type projectUser struct {
	UserID    int `sql:"user_id"`
	ProjectID int `sql:"project_id"`
}

// addProjectUser adds a user to a project.
func addProjectUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Request
	req := &addProjectUserRequest{}
	if err := RequestBind(r, req); err != nil {
		ResponseError(w, ErrBadRequest)
		return
	}
	// Find user.
	user := &models.User{}
	if err := db.Admin.DB().Where("name = ?", req.Name).First(user).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrUserNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
	if user.Universal {
		ResponseError(w, ErrProjectUniversalUser)
		return
	}
	// Find proj
	proj := &models.Project{}
	if err := db.Admin.DB().First(proj, id).Error; err != nil {
		if err == gorm.RecordNotFound {
			ResponseError(w, ErrNotFound)
			return
		}
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	// Note: Gorm only insert values to join-table if the primary key not in
	// the join-table. So we select the record at first here.
	if err := db.Admin.DB().Table("project_users").Where("user_id = ? and project_id = ?", user.ID, proj.ID).Find(&projectUser{}).Error; err == nil {
		ResponseError(w, ErrDuplicateProjectUser)
		return
	}
	// Append user.
	if err := db.Admin.DB().Model(proj).Association("Users").Append(user).Error; err != nil {
		if err == gorm.RecordNotFound {
			// User or Project not found.
			ResponseError(w, ErrNotFound)
			return
		}
		// Duplicate primay key.
		sqliteErr, ok := err.(sqlite3.Error)
		if ok {
			switch sqliteErr.ExtendedCode {
			case sqlite3.ErrConstraintUnique:
				ResponseError(w, ErrDuplicateProjectUser)
				return
			case sqlite3.ErrConstraintPrimaryKey:
				ResponseError(w, ErrDuplicateProjectUser)
				return
			}
		}
		// Unexcepted error.
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
}

// deleteProjectUser deletes a user from a project.
func deleteProjectUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	userID, err := strconv.Atoi(ps.ByName("user_id"))
	if err != nil {
		ResponseError(w, ErrUserID)
		return
	}
	// Find user.
	user := &models.User{}
	if err := db.Admin.DB().First(user, userID).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrUserNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
	// Find proj.
	proj := &models.Project{}
	if err := db.Admin.DB().First(proj, id).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrProjectNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
	// Delete user.
	if err := db.Admin.DB().Model(proj).Association("Users").Delete(user).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
}
<commit_msg>Add SilentTimeStart[End] to updateProject request<commit_after>// Copyright 2015 Eleme Inc. All rights reserved.

package webapp

import (
	"github.com/eleme/banshee/models"
	"github.com/jinzhu/gorm"
	"github.com/julienschmidt/httprouter"
	"github.com/mattn/go-sqlite3"
	"net/http"
	"strconv"
)

// getProjects returns all projects.
func getProjects(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var projs []models.Project
	if err := db.Admin.DB().Find(&projs).Error; err != nil {
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	ResponseJSONOK(w, projs)
}

// getProject returns project by id.
func getProject(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Query db.
	proj := &models.Project{}
	if err := db.Admin.DB().First(proj, id).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrProjectNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
	ResponseJSONOK(w, proj)
}

// createProject request
type createProjectRequest struct {
	Name string `json:"name"`
}

// createProject creates a project.
func createProject(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	// Request
	req := &createProjectRequest{}
	if err := RequestBind(r, req); err != nil {
		ResponseError(w, ErrBadRequest)
		return
	}
	// Validate
	if err := models.ValidateProjectName(req.Name); err != nil {
		ResponseError(w, NewValidationWebError(err))
		return
	}
	// Save.
	proj := &models.Project{Name: req.Name}
	if err := db.Admin.DB().Create(proj).Error; err != nil {
		sqliteErr, ok := err.(sqlite3.Error)
		if ok {
			switch sqliteErr.ExtendedCode {
			case sqlite3.ErrConstraintNotNull:
				ResponseError(w, ErrNotNull)
				return
			case sqlite3.ErrConstraintPrimaryKey:
				ResponseError(w, ErrPrimaryKey)
				return
			case sqlite3.ErrConstraintUnique:
				ResponseError(w, ErrDuplicateProjectName)
				return
			}
		}
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	ResponseJSONOK(w, proj)
}

// updateProject request
type updateProjectRequest struct {
	Name            string `json:"name"`
	EnableSilent    bool   `json:"enableSilent"`
	SilentTimeStart int    `json:"silentTimeStart"`
	SilentTimeEnd   int    `json:"silentTimeEnd"`
}

// updateProject updates a project.
func updateProject(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Request
	req := &updateProjectRequest{}
	if err := RequestBind(r, req); err != nil {
		ResponseError(w, ErrBadRequest)
		return
	}
	// Validate
	if err := models.ValidateProjectName(req.Name); err != nil {
		ResponseError(w, NewValidationWebError(err))
		return
	}
	if err := models.ValidateProjectSilentRange(req.SilentTimeStart, req.SilentTimeEnd); err != nil {
		ResponseError(w, NewValidationWebError(err))
		return
	}
	// Find
	proj := &models.Project{}
	if err := db.Admin.DB().First(proj, id).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrProjectNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
	// Patch.
	proj.Name = req.Name
	proj.EnableSilent = req.EnableSilent
	proj.SilentTimeStart = req.SilentTimeStart
	proj.SilentTimeEnd = req.SilentTimeEnd
	if err := db.Admin.DB().Save(proj).Error; err != nil {
		if err == gorm.RecordNotFound {
			// Not found.
			ResponseError(w, ErrProjectNotFound)
			return
		}
		// Writer errors.
		sqliteErr, ok := err.(sqlite3.Error)
		if ok {
			switch sqliteErr.ExtendedCode {
			case sqlite3.ErrConstraintNotNull:
				ResponseError(w, ErrNotNull)
				return
			case sqlite3.ErrConstraintUnique:
				ResponseError(w, ErrDuplicateProjectName)
				return
			}
		}
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	ResponseJSONOK(w, proj)
}

// deleteProject deletes a project.
func deleteProject(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Delete.
	if err := db.Admin.DB().Delete(&models.Project{ID: id}).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrProjectNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
}

// getProjectRules gets project rules.
func getProjectRules(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Query
	var rules []models.Rule
	if err := db.Admin.DB().Model(&models.Project{ID: id}).Related(&rules).Error; err != nil {
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	for i := 0; i < len(rules); i++ {
		rules[i].BuildRepr()
		rules[i].SetNumMetrics(len(db.Index.Filter(rules[i].Pattern)))
	}
	ResponseJSONOK(w, rules)
}

// getProjectUsers gets project users.
func getProjectUsers(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Query
	var users []models.User
	if err := db.Admin.DB().Model(&models.Project{ID: id}).Association("Users").Find(&users).Error; err != nil {
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	// Universals
	var univs []models.User
	if err := db.Admin.DB().Where("universal = ?", true).Find(&univs).Error; err != nil {
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	users = append(users, univs...)
	ResponseJSONOK(w, users)
}

// addProjectUserRequest is the request of addProjectUser
type addProjectUserRequest struct {
	Name string `json:"name"`
}

// projectUser is the tempory select result for table `project_users`
type projectUser struct {
	UserID    int `sql:"user_id"`
	ProjectID int `sql:"project_id"`
}

// addProjectUser adds a user to a project.
func addProjectUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	// Request
	req := &addProjectUserRequest{}
	if err := RequestBind(r, req); err != nil {
		ResponseError(w, ErrBadRequest)
		return
	}
	// Find user.
	user := &models.User{}
	if err := db.Admin.DB().Where("name = ?", req.Name).First(user).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrUserNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
	if user.Universal {
		ResponseError(w, ErrProjectUniversalUser)
		return
	}
	// Find proj
	proj := &models.Project{}
	if err := db.Admin.DB().First(proj, id).Error; err != nil {
		if err == gorm.RecordNotFound {
			ResponseError(w, ErrNotFound)
			return
		}
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
	// Note: Gorm only insert values to join-table if the primary key not in
	// the join-table. So we select the record at first here.
	if err := db.Admin.DB().Table("project_users").Where("user_id = ? and project_id = ?", user.ID, proj.ID).Find(&projectUser{}).Error; err == nil {
		ResponseError(w, ErrDuplicateProjectUser)
		return
	}
	// Append user.
	if err := db.Admin.DB().Model(proj).Association("Users").Append(user).Error; err != nil {
		if err == gorm.RecordNotFound {
			// User or Project not found.
			ResponseError(w, ErrNotFound)
			return
		}
		// Duplicate primay key.
		sqliteErr, ok := err.(sqlite3.Error)
		if ok {
			switch sqliteErr.ExtendedCode {
			case sqlite3.ErrConstraintUnique:
				ResponseError(w, ErrDuplicateProjectUser)
				return
			case sqlite3.ErrConstraintPrimaryKey:
				ResponseError(w, ErrDuplicateProjectUser)
				return
			}
		}
		// Unexcepted error.
		ResponseError(w, NewUnexceptedWebError(err))
		return
	}
}

// deleteProjectUser deletes a user from a project.
func deleteProjectUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// Params
	id, err := strconv.Atoi(ps.ByName("id"))
	if err != nil {
		ResponseError(w, ErrProjectID)
		return
	}
	userID, err := strconv.Atoi(ps.ByName("user_id"))
	if err != nil {
		ResponseError(w, ErrUserID)
		return
	}
	// Find user.
	user := &models.User{}
	if err := db.Admin.DB().First(user, userID).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrUserNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
	// Find proj.
	proj := &models.Project{}
	if err := db.Admin.DB().First(proj, id).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrProjectNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
	// Delete user.
	if err := db.Admin.DB().Model(proj).Association("Users").Delete(user).Error; err != nil {
		switch err {
		case gorm.RecordNotFound:
			ResponseError(w, ErrNotFound)
			return
		default:
			ResponseError(w, NewUnexceptedWebError(err))
			return
		}
	}
}
<|endoftext|>


<commit_before>package cocoa
//+build darwin

/*
#cgo darwin CFLAGS: -DDARWIN -x objective-c -fobjc-arc
#cgo darwin LDFLAGS: -framework Cocoa

#include "cocoa.h"
*/
import "C"

import (
	"runtime"
)

type startCallback func()
type urlCallback func(url string)

var (
	startupCallbacks = []startCallback{}
	urlCallbacks = []urlCallback{}
)

func AddUrlCallback(c urlCallback) {
	urlCallbacks = append(urlCallbacks,c)
}
func AddStartCallback(c startCallback) {
	startupCallbacks = append(startupCallbacks, c)
}

func Start(onStart startCallback) {
	AddStartCallback(onStart)

	runtime.LockOSThread()
	C.cocoaMain()
}

func Stop() {
	C.cocoaExit()
}

func ShowFileDialog(title, defaultDirectory string,
	fileTypes []string,
	forFiles bool, multiselect bool) {
	titlePtr := C.CString(title)
	dirPtr := C.CString(defaultDirectory)

	var filesBool C.BOOL
	if (forFiles) {
		filesBool = C.BOOL(1)
	} else {
		filesBool = C.BOOL(0)
	}

	var selectBool C.BOOL
	if (selectBool) {
		selectBool = C.BOOL(1)
	} else {
		selectBool = C.BOOL(0)
	}

	C.showOpenPanel(titlePtr, dirPtr, filesBool, selectBool)

	C.free(unsafe.Pointer(titlePtr))
	C.free(unsafe.Pointer(dirPtr))
}

func ShowDialog(message string) {
	msgStr := C.CString(message)
	C.showDialog(msgStr)
	C.free(unsafe.Pointer(msgStr))
}

func Log(message string) {
	msgStr := C.CString(message)
	C.printLog(msgStr)
	C.free(usnafe.Pointer(msgStr))
}

//export cocoaStart
func cocoastart() {
	for _, f := range startupCallbacks {
		f()
	}
}

//export cocoaUrl
func cocoaUrl(data C.CString) {
	url := C.GoString(data)
	for _, f := range urlCallbacks {
		f(url)
	}
}
<commit_msg>Typo in export name for cocoaStart<commit_after>package cocoa
//+build darwin

/*
#cgo darwin CFLAGS: -DDARWIN -x objective-c -fobjc-arc
#cgo darwin LDFLAGS: -framework Cocoa

#include "cocoa.h"
*/
import "C"

import (
	"runtime"
)

type startCallback func()
type urlCallback func(url string)

var (
	startupCallbacks = []startCallback{}
	urlCallbacks = []urlCallback{}
)

func AddUrlCallback(c urlCallback) {
	urlCallbacks = append(urlCallbacks,c)
}
func AddStartCallback(c startCallback) {
	startupCallbacks = append(startupCallbacks, c)
}

func Start(onStart startCallback) {
	AddStartCallback(onStart)

	runtime.LockOSThread()
	C.cocoaMain()
}

func Stop() {
	C.cocoaExit()
}

func ShowFileDialog(title, defaultDirectory string,
	fileTypes []string,
	forFiles bool, multiselect bool) {
	titlePtr := C.CString(title)
	dirPtr := C.CString(defaultDirectory)

	var filesBool C.BOOL
	if (forFiles) {
		filesBool = C.BOOL(1)
	} else {
		filesBool = C.BOOL(0)
	}

	var selectBool C.BOOL
	if (selectBool) {
		selectBool = C.BOOL(1)
	} else {
		selectBool = C.BOOL(0)
	}

	C.showOpenPanel(titlePtr, dirPtr, filesBool, selectBool)

	C.free(unsafe.Pointer(titlePtr))
	C.free(unsafe.Pointer(dirPtr))
}

func ShowDialog(message string) {
	msgStr := C.CString(message)
	C.showDialog(msgStr)
	C.free(unsafe.Pointer(msgStr))
}

func Log(message string) {
	msgStr := C.CString(message)
	C.printLog(msgStr)
	C.free(usnafe.Pointer(msgStr))
}

//export cocoaStart
func cocoaStart() {
	for _, f := range startupCallbacks {
		f()
	}
}

//export cocoaUrl
func cocoaUrl(data C.CString) {
	url := C.GoString(data)
	for _, f := range urlCallbacks {
		f(url)
	}
}
<|endoftext|>


<commit_before>package goridge

import (
	"bytes"
	"io"
	"net/rpc"
	"sync"

	j "github.com/json-iterator/go"
	"github.com/spiral/errors"
	"go.uber.org/multierr"
)

var json = j.ConfigCompatibleWithStandardLibrary

// Codec represent net/rpc bridge over Goridge socket relay.
type Codec struct {
	relay  Relay
	closed bool
	frame  *Frame
	codec  sync.Map
}

// NewCodec initiates new server rpc codec over socket connection.
func NewCodec(rwc io.ReadWriteCloser) *Codec {
	return &Codec{
		relay: NewSocketRelay(rwc),
		codec: sync.Map{},
	}
}

// NewCodecWithRelay initiates new server rpc codec with a relay of choice.
func NewCodecWithRelay(relay Relay) *Codec {
	return &Codec{relay: relay}
}

// WriteResponse marshals response, byte slice or error to remote party.
func (c *Codec) WriteResponse(r *rpc.Response, body interface{}) error {
	const op = errors.Op("codec: write response")
	frame := NewFrame()

	// SEQ_ID + METHOD_NAME_LEN
	frame.WriteOptions(uint32(r.Seq), uint32(len(r.ServiceMethod)))
	// Write protocol version
	frame.WriteVersion(VERSION_1)

	// load and delete associated codec to not waste memory
	// because we write it to the frame and don't need more information about it
	codec, ok := c.codec.LoadAndDelete(r.Seq)
	if !ok {
		// fallback codec
		frame.WriteFlags(CODEC_GOB)
	} else {
		frame.WriteFlags(codec.(FrameFlag))
	}

	// initialize buffer
	buf := new(bytes.Buffer)
	// writeServiceMethod to the buffer
	buf.WriteString(r.ServiceMethod)

	// if error returned, we sending it via relay and return error from WriteResponse
	if r.Error != "" {
		// Append error flag
		return c.handleError(r, frame, buf, errors.Str(r.Error))
	}

	// read flag previously written
	// TODO might be better to save it to local variable
	flags := frame.ReadFlags()

	switch {
	case flags&byte(CODEC_JSON) != 0:
		err := encodeJSON(buf, body)
		if err != nil {
			return c.handleError(r, frame, buf, err)
		}
		// everything written correct
		frame.WritePayloadLen(uint32(buf.Len()))
		frame.WritePayload(buf.Bytes())

		frame.WriteCRC()
		return c.relay.Send(frame)
	case flags&byte(CODEC_MSGPACK) != 0:
		err := encodeMsgPack(buf, body)
		if err != nil {
			return c.handleError(r, frame, buf, err)
		}
		// everything written correct
		frame.WritePayloadLen(uint32(buf.Len()))
		frame.WritePayload(buf.Bytes())

		frame.WriteCRC()
		return c.relay.Send(frame)
	case flags&byte(CODEC_RAW) != 0:
		err := encodeRaw(buf, body)
		if err != nil {
			return c.handleError(r, frame, buf, err)
		}
		// everything written correct
		frame.WritePayloadLen(uint32(buf.Len()))
		frame.WritePayload(buf.Bytes())

		frame.WriteCRC()
		return c.relay.Send(frame)
	case flags&byte(CODEC_GOB) != 0:
		err := encodeGob(buf, body)
		if err != nil {
			return c.handleError(r, frame, buf, err)
		}
		// everything written correct
		frame.WritePayloadLen(uint32(buf.Len()))
		frame.WritePayload(buf.Bytes())

		frame.WriteCRC()
		return c.relay.Send(frame)
	default:
		return errors.E(op, errors.Str("unknown codec"))
	}
}

func (c *Codec) handleError(r *rpc.Response, frame *Frame, buf *bytes.Buffer, err error) error {
	// just to be sure, remove all data from buffer and write new
	buf.Truncate(0)
	// write all possible errors
	err = multierr.Append(err, errors.Str(r.Error))
	buf.WriteString(r.ServiceMethod)

	const op = errors.Op("handle codec error")
	frame.WriteFlags(ERROR)
	// error should be here
	if err != nil {
		buf.WriteString(err.Error())
	}
	frame.WritePayloadLen(uint32(buf.Len()))
	frame.WritePayload(buf.Bytes())

	frame.WriteCRC()
	_ = c.relay.Send(frame)
	return errors.E(op, errors.Str(r.Error))
}

// ReadRequestHeader receives
func (c *Codec) ReadRequestHeader(r *rpc.Request) error {
	const op = errors.Op("codec: read request header")
	frame := NewFrame()
	err := c.relay.Receive(frame)
	if err != nil {
		return err
	}

	// opts[0] sequence ID
	// opts[1] service method name offset from payload in bytes
	opts := frame.ReadOptions()
	if len(opts) != 2 {
		return errors.E(op, errors.Str("should be 2 options. SEQ_ID and METHOD_LEN"))
	}

	r.Seq = uint64(opts[0])
	r.ServiceMethod = string(frame.Payload()[:opts[1]])
	c.frame = frame
	return c.storeCodec(r, frame.ReadFlags())
}

func (c *Codec) storeCodec(r *rpc.Request, flag byte) error {
	switch {
	case flag&byte(CODEC_JSON) != 0:
		c.codec.Store(r.Seq, CODEC_JSON)
	case flag&byte(CODEC_RAW) != 0:
		c.codec.Store(r.Seq, CODEC_RAW)
	case flag&byte(CODEC_MSGPACK) != 0:
		c.codec.Store(r.Seq, CODEC_MSGPACK)
	case flag&byte(CODEC_GOB) != 0:
		c.codec.Store(r.Seq, CODEC_GOB)
	default:
		c.codec.Store(r.Seq, CODEC_GOB)
	}

	return nil
}

// ReadRequestBody fetches prefixed body data and automatically unmarshal it as json. RawBody flag will populate
// []byte lice argument for rpc method.
func (c *Codec) ReadRequestBody(out interface{}) error {
	const op = errors.Op("codec read request body")
	if out == nil {
		return nil
	}

	defer func() {
		c.frame = nil
	}()

	flags := c.frame.ReadFlags()

	if flags&byte(CODEC_JSON) != byte(0) {
		return decodeJSON(out, c.frame)
	}

	if flags&byte(CODEC_GOB) != byte(0) {
		return decodeGob(out, c.frame)
	}

	if flags&byte(CODEC_RAW) != byte(0) {
		return decodeRaw(out, c.frame)
	}

	if flags&byte(CODEC_MSGPACK) != byte(0) {
		return decodeMsgPack(out, c.frame)
	}

	return errors.E(op, errors.Str("unknown decoder used in frame"))
}

// Close underlying socket.
func (c *Codec) Close() error {
	if c.closed {
		return nil
	}

	c.closed = true
	return c.relay.Close()
}
<commit_msg>Split sync.Map load and delete for go1.14<commit_after>package goridge

import (
	"bytes"
	"io"
	"net/rpc"
	"sync"

	j "github.com/json-iterator/go"
	"github.com/spiral/errors"
	"go.uber.org/multierr"
)

var json = j.ConfigCompatibleWithStandardLibrary

// Codec represent net/rpc bridge over Goridge socket relay.
type Codec struct {
	relay  Relay
	closed bool
	frame  *Frame
	codec  sync.Map
}

// NewCodec initiates new server rpc codec over socket connection.
func NewCodec(rwc io.ReadWriteCloser) *Codec {
	return &Codec{
		relay: NewSocketRelay(rwc),
		codec: sync.Map{},
	}
}

// NewCodecWithRelay initiates new server rpc codec with a relay of choice.
func NewCodecWithRelay(relay Relay) *Codec {
	return &Codec{relay: relay}
}

// WriteResponse marshals response, byte slice or error to remote party.
func (c *Codec) WriteResponse(r *rpc.Response, body interface{}) error {
	const op = errors.Op("codec: write response")
	frame := NewFrame()

	// SEQ_ID + METHOD_NAME_LEN
	frame.WriteOptions(uint32(r.Seq), uint32(len(r.ServiceMethod)))
	// Write protocol version
	frame.WriteVersion(VERSION_1)

	// load and delete associated codec to not waste memory
	// because we write it to the frame and don't need more information about it
	// as for go.14, Load and Delete are separate methods
	codec, ok := c.codec.Load(r.Seq)
	if !ok {
		// fallback codec
		frame.WriteFlags(CODEC_GOB)
	} else {
		frame.WriteFlags(codec.(FrameFlag))
	}

	// delete the key
	c.codec.Delete(r.Seq)

	// initialize buffer
	buf := new(bytes.Buffer)
	// writeServiceMethod to the buffer
	buf.WriteString(r.ServiceMethod)

	// if error returned, we sending it via relay and return error from WriteResponse
	if r.Error != "" {
		// Append error flag
		return c.handleError(r, frame, buf, errors.Str(r.Error))
	}

	// read flag previously written
	// TODO might be better to save it to local variable
	flags := frame.ReadFlags()

	switch {
	case flags&byte(CODEC_JSON) != 0:
		err := encodeJSON(buf, body)
		if err != nil {
			return c.handleError(r, frame, buf, err)
		}
		// everything written correct
		frame.WritePayloadLen(uint32(buf.Len()))
		frame.WritePayload(buf.Bytes())

		frame.WriteCRC()
		return c.relay.Send(frame)
	case flags&byte(CODEC_MSGPACK) != 0:
		err := encodeMsgPack(buf, body)
		if err != nil {
			return c.handleError(r, frame, buf, err)
		}
		// everything written correct
		frame.WritePayloadLen(uint32(buf.Len()))
		frame.WritePayload(buf.Bytes())

		frame.WriteCRC()
		return c.relay.Send(frame)
	case flags&byte(CODEC_RAW) != 0:
		err := encodeRaw(buf, body)
		if err != nil {
			return c.handleError(r, frame, buf, err)
		}
		// everything written correct
		frame.WritePayloadLen(uint32(buf.Len()))
		frame.WritePayload(buf.Bytes())

		frame.WriteCRC()
		return c.relay.Send(frame)
	case flags&byte(CODEC_GOB) != 0:
		err := encodeGob(buf, body)
		if err != nil {
			return c.handleError(r, frame, buf, err)
		}
		// everything written correct
		frame.WritePayloadLen(uint32(buf.Len()))
		frame.WritePayload(buf.Bytes())

		frame.WriteCRC()
		return c.relay.Send(frame)
	default:
		return errors.E(op, errors.Str("unknown codec"))
	}
}

func (c *Codec) handleError(r *rpc.Response, frame *Frame, buf *bytes.Buffer, err error) error {
	// just to be sure, remove all data from buffer and write new
	buf.Truncate(0)
	// write all possible errors
	err = multierr.Append(err, errors.Str(r.Error))
	buf.WriteString(r.ServiceMethod)

	const op = errors.Op("handle codec error")
	frame.WriteFlags(ERROR)
	// error should be here
	if err != nil {
		buf.WriteString(err.Error())
	}
	frame.WritePayloadLen(uint32(buf.Len()))
	frame.WritePayload(buf.Bytes())

	frame.WriteCRC()
	_ = c.relay.Send(frame)
	return errors.E(op, errors.Str(r.Error))
}

// ReadRequestHeader receives
func (c *Codec) ReadRequestHeader(r *rpc.Request) error {
	const op = errors.Op("codec: read request header")
	frame := NewFrame()
	err := c.relay.Receive(frame)
	if err != nil {
		return err
	}

	// opts[0] sequence ID
	// opts[1] service method name offset from payload in bytes
	opts := frame.ReadOptions()
	if len(opts) != 2 {
		return errors.E(op, errors.Str("should be 2 options. SEQ_ID and METHOD_LEN"))
	}

	r.Seq = uint64(opts[0])
	r.ServiceMethod = string(frame.Payload()[:opts[1]])
	c.frame = frame
	return c.storeCodec(r, frame.ReadFlags())
}

func (c *Codec) storeCodec(r *rpc.Request, flag byte) error {
	switch {
	case flag&byte(CODEC_JSON) != 0:
		c.codec.Store(r.Seq, CODEC_JSON)
	case flag&byte(CODEC_RAW) != 0:
		c.codec.Store(r.Seq, CODEC_RAW)
	case flag&byte(CODEC_MSGPACK) != 0:
		c.codec.Store(r.Seq, CODEC_MSGPACK)
	case flag&byte(CODEC_GOB) != 0:
		c.codec.Store(r.Seq, CODEC_GOB)
	default:
		c.codec.Store(r.Seq, CODEC_GOB)
	}

	return nil
}

// ReadRequestBody fetches prefixed body data and automatically unmarshal it as json. RawBody flag will populate
// []byte lice argument for rpc method.
func (c *Codec) ReadRequestBody(out interface{}) error {
	const op = errors.Op("codec read request body")
	if out == nil {
		return nil
	}

	defer func() {
		c.frame = nil
	}()

	flags := c.frame.ReadFlags()

	if flags&byte(CODEC_JSON) != byte(0) {
		return decodeJSON(out, c.frame)
	}

	if flags&byte(CODEC_GOB) != byte(0) {
		return decodeGob(out, c.frame)
	}

	if flags&byte(CODEC_RAW) != byte(0) {
		return decodeRaw(out, c.frame)
	}

	if flags&byte(CODEC_MSGPACK) != byte(0) {
		return decodeMsgPack(out, c.frame)
	}

	return errors.E(op, errors.Str("unknown decoder used in frame"))
}

// Close underlying socket.
func (c *Codec) Close() error {
	if c.closed {
		return nil
	}

	c.closed = true
	return c.relay.Close()
}
<|endoftext|>


<commit_before>package obj

import (
	"fmt"
	"reflect"
)

type Suite struct {
	// FIXME this type is still, yes still, wrong: you need a factory for machines,
	// because otherwise you're gonna have a bad day if the same type comes up twice in a stack.
	// We really do need some declaritive type thing for "machinestrategy" here, separate from the machine impl.
	mappings map[reflect.Type]MarshalMachine
}

/*
	Folds another behavior dispatch into the suite.

	The `typeHint` parameter is an instance of the type you want dispatch
	to use this machine for.  A zero instance is fine.
	Thus, calls to this method usually resemble the following:

		suite.Add(YourType{}, &SomeMachineImpl{})
*/
func (s *Suite) Add(typeHint interface{}, mach MarshalMachine) {
	if s.mappings == nil {
		s.mappings = make(map[reflect.Type]MarshalMachine)
	}
	rt := reflect.TypeOf(typeHint)
	for {
		if rt.Kind() == reflect.Ptr {
			rt = rt.Elem()
		}
	}
	s.mappings[rt] = mach
}

func (s *Suite) pickMarshalMachine(valp interface{}) MarshalMachine {
	mach := s.maybePickMarshalMachine(valp)
	if mach == nil {
		panic(fmt.Errorf("no machine available in suite for type %T", valp))
	}
	return mach
}

/*
	Picks an unmarshal machine, returning the custom impls for any
	common/primitive types, and advanced machines where structs get involved.

	The argument should be the address of the actual value of interest.

	Returns nil if there is no marshal machine in the suite for this type.
*/
func (s *Suite) maybePickMarshalMachine(valp interface{}) MarshalMachine {
	// TODO : we can use type switches to do some primitives efficiently here
	//  before we turn to the reflective path.
	val_rt := reflect.ValueOf(valp).Elem().Type()
	return s.maybeMarshalMachineForType(val_rt)
}

func (s *Suite) marshalMachineForType(rt reflect.Type) MarshalMachine {
	mach := s.maybeMarshalMachineForType(rt)
	if mach == nil {
		panic(fmt.Errorf("no machine available in suite for type %s", rt.Name()))
	}
	return mach
}

/*
	Like `pickMarshalMachine`, but requiring only the reflect type info.
	This is useable when you only have the type info available (rather than an instance);
	this comes up when for example looking up the machine to use for all values
	in a slice based on the slice type info.

	(Using an instance may be able to take faster, non-reflective paths for
	primitive values.)

	In contrast to the method that takes a `valp interface{}`, this type info
	is understood to already be dereferenced.

	Returns nil if there is no marshal machine in the suite for this type.
*/
func (s *Suite) maybeMarshalMachineForType(rt reflect.Type) MarshalMachine {
	switch rt.Kind() {
	case reflect.Bool:
		return &MarshalMachineLiteral{}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return &MarshalMachineLiteral{}
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return &MarshalMachineLiteral{}
	case reflect.Float32, reflect.Float64:
		return &MarshalMachineLiteral{}
	case reflect.String:
		return &MarshalMachineLiteral{}
	case reflect.Slice:
		// TODO also bytes should get a special path
		return &MarshalMachineSliceWildcard{}
	case reflect.Array:
		return &MarshalMachineSliceWildcard{}
	case reflect.Map:
		// Consider (for efficiency in happy paths):
		//		switch v2 := v.(type) {
		//		case map[string]interface{}:
		//			_ = v2
		//			return nil // TODO special
		//		default:
		//			return &MarshalMachineMapWildcard{}
		//		}
		// but, it's not clear how we'd cache this.
		// possibly we should attach this whole method to the Driver,
		//  so it can have state for cache.
		return &MarshalMachineMapWildcard{}
	case reflect.Ptr:
		// REVIEW: doing this once, fine.  but unbounded?  questionable.
		return s.maybeMarshalMachineForType(rt.Elem())
	case reflect.Struct:
		return s.mappings[rt]
	case reflect.Interface:
		panic("TODO iface")
	case reflect.Func:
		panic("TODO func") // hey, if we can find it in the suite
	default:
		panic(fmt.Errorf("excursion %s", rt.Kind()))
	}
}
<commit_msg>Fix missing loop break suite initializer func.<commit_after>package obj

import (
	"fmt"
	"reflect"
)

type Suite struct {
	// FIXME this type is still, yes still, wrong: you need a factory for machines,
	// because otherwise you're gonna have a bad day if the same type comes up twice in a stack.
	// We really do need some declaritive type thing for "machinestrategy" here, separate from the machine impl.
	mappings map[reflect.Type]MarshalMachine
}

/*
	Folds another behavior dispatch into the suite.

	The `typeHint` parameter is an instance of the type you want dispatch
	to use this machine for.  A zero instance is fine.
	Thus, calls to this method usually resemble the following:

		suite.Add(YourType{}, &SomeMachineImpl{})
*/
func (s *Suite) Add(typeHint interface{}, mach MarshalMachine) {
	if s.mappings == nil {
		s.mappings = make(map[reflect.Type]MarshalMachine)
	}
	rt := reflect.TypeOf(typeHint)
	for rt.Kind() == reflect.Ptr {
		rt = rt.Elem()
	}
	s.mappings[rt] = mach
}

func (s *Suite) pickMarshalMachine(valp interface{}) MarshalMachine {
	mach := s.maybePickMarshalMachine(valp)
	if mach == nil {
		panic(fmt.Errorf("no machine available in suite for type %T", valp))
	}
	return mach
}

/*
	Picks an unmarshal machine, returning the custom impls for any
	common/primitive types, and advanced machines where structs get involved.

	The argument should be the address of the actual value of interest.

	Returns nil if there is no marshal machine in the suite for this type.
*/
func (s *Suite) maybePickMarshalMachine(valp interface{}) MarshalMachine {
	// TODO : we can use type switches to do some primitives efficiently here
	//  before we turn to the reflective path.
	val_rt := reflect.ValueOf(valp).Elem().Type()
	return s.maybeMarshalMachineForType(val_rt)
}

func (s *Suite) marshalMachineForType(rt reflect.Type) MarshalMachine {
	mach := s.maybeMarshalMachineForType(rt)
	if mach == nil {
		panic(fmt.Errorf("no machine available in suite for type %s", rt.Name()))
	}
	return mach
}

/*
	Like `pickMarshalMachine`, but requiring only the reflect type info.
	This is useable when you only have the type info available (rather than an instance);
	this comes up when for example looking up the machine to use for all values
	in a slice based on the slice type info.

	(Using an instance may be able to take faster, non-reflective paths for
	primitive values.)

	In contrast to the method that takes a `valp interface{}`, this type info
	is understood to already be dereferenced.

	Returns nil if there is no marshal machine in the suite for this type.
*/
func (s *Suite) maybeMarshalMachineForType(rt reflect.Type) MarshalMachine {
	switch rt.Kind() {
	case reflect.Bool:
		return &MarshalMachineLiteral{}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return &MarshalMachineLiteral{}
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return &MarshalMachineLiteral{}
	case reflect.Float32, reflect.Float64:
		return &MarshalMachineLiteral{}
	case reflect.String:
		return &MarshalMachineLiteral{}
	case reflect.Slice:
		// TODO also bytes should get a special path
		return &MarshalMachineSliceWildcard{}
	case reflect.Array:
		return &MarshalMachineSliceWildcard{}
	case reflect.Map:
		// Consider (for efficiency in happy paths):
		//		switch v2 := v.(type) {
		//		case map[string]interface{}:
		//			_ = v2
		//			return nil // TODO special
		//		default:
		//			return &MarshalMachineMapWildcard{}
		//		}
		// but, it's not clear how we'd cache this.
		// possibly we should attach this whole method to the Driver,
		//  so it can have state for cache.
		return &MarshalMachineMapWildcard{}
	case reflect.Ptr:
		// REVIEW: doing this once, fine.  but unbounded?  questionable.
		return s.maybeMarshalMachineForType(rt.Elem())
	case reflect.Struct:
		return s.mappings[rt]
	case reflect.Interface:
		panic("TODO iface")
	case reflect.Func:
		panic("TODO func") // hey, if we can find it in the suite
	default:
		panic(fmt.Errorf("excursion %s", rt.Kind()))
	}
}
<|endoftext|>


<commit_before>package fastclient

import (
	"flag"
	"io"
	"log"
	"net"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/valyala/fasthttp"
)

var (
	httpClientRequestTimeout  = flag.Duration("httpClientRequestTimeout", time.Second*10, "Maximum time to wait for http response")
	httpClientKeepAlivePeriod = flag.Duration("httpClientKeepAlivePeriod", time.Second*5, "Interval for sending keep-alive messages on keepalive connections. Zero disables keep-alive messages")
	httpClientReadBufferSize  = flag.Int("httpClientReadBufferSize", 8*1024, "Per-connection read buffer size for httpclient")
	httpClientWriteBufferSize = flag.Int("httpClientWriteBufferSize", 8*1024, "Per-connection write buffer size for httpclient")
)

const (
	jobCapacity         = 10000
	maxIdleConnDuration = time.Second
	maxConns            = 1<<31 - 1
)

type Client struct {
	*fasthttp.HostClient
	wg sync.WaitGroup

	sync.Mutex
	Jobsch  chan struct{}
	workers int
}

var (
	request *fasthttp.Request
	t       time.Duration
)

func New(r *fasthttp.Request, timeout time.Duration) *Client {
	registerMetrics()
	request = r
	t = timeout

	addr, isTLS := acquireAddr(request)
	return &Client{
		Jobsch: make(chan struct{}, jobCapacity),
		HostClient: &fasthttp.HostClient{
			Addr:                addr,
			IsTLS:               isTLS,
			Dial:                dial,
			MaxIdleConnDuration: maxIdleConnDuration,
			MaxConns:            maxConns,
		},
	}
}

func (c *Client) Amount() int {
	c.Lock()
	defer c.Unlock()

	return c.workers
}

func (c *Client) Overflow() int {
	c.Lock()
	defer c.Unlock()

	return len(c.Jobsch)
}

func drainChan(ch chan struct{}) {
	for {
		select {
		case <-ch:
			continue
		default:
			return
		}
	}
}

func (c *Client) Flush() {
	drainChan(c.Jobsch)
	close(c.Jobsch)

	c.wg.Wait()
	flushMetrics()
	c.workers = 0
	c.Jobsch = make(chan struct{}, jobCapacity)
}

func (c *Client) RunWorkers(n int) {
	for i := 0; i < n; i++ {
		c.wg.Add(1)
		go func() {
			c.Lock()
			c.workers++
			c.Unlock()

			c.run()
			c.wg.Done()
		}()
	}
}

func (c *Client) run() {
	var resp fasthttp.Response
	r := new(fasthttp.Request)
	request.CopyTo(r)
	for range c.Jobsch {
		s := time.Now()
		err := c.DoTimeout(r, &resp, t)
		if err != nil {
			if err == fasthttp.ErrTimeout {
				timeouts.Inc()
			}
			errors.Inc()
		} else {
			requestSuccess.Inc()
		}
		requestDuration.Observe(float64(time.Since(s).Seconds()))
		requestSum.Inc()
	}
}

type hostConn struct {
	net.Conn
	addr         string
	closed       uint32
	connOpen     prometheus.Gauge
	readError    prometheus.Counter
	writeError   prometheus.Counter
	bytesWritten prometheus.Counter
	bytesRead    prometheus.Counter
}

func dial(addr string) (net.Conn, error) {
	conn, err := fasthttp.DialTimeout(addr, *httpClientRequestTimeout)
	if err != nil {
		return nil, err
	}
	if err = setupTCPConn(conn); err != nil {
		connError.Inc()
		conn.Close()
		return nil, err
	}

	connOpen.Inc()
	return &hostConn{
		Conn:         conn,
		addr:         addr,
		connOpen:     connOpen,
		readError:    readError,
		writeError:   writeError,
		bytesWritten: bytesWritten,
		bytesRead:    bytesRead,
	}, nil
}

func setupTCPConn(conn net.Conn) error {
	c, ok := conn.(*net.TCPConn)
	if !ok {
		return nil
	}

	var err error
	if *httpClientReadBufferSize > 0 {
		if err = c.SetReadBuffer(*httpClientReadBufferSize); err != nil {
			return err
		}
	}
	if *httpClientWriteBufferSize > 0 {
		if err = c.SetWriteBuffer(*httpClientWriteBufferSize); err != nil {
			return err
		}
	}
	if *httpClientKeepAlivePeriod > 0 {
		if err = c.SetKeepAlive(true); err != nil {
			return err
		}
		if err = c.SetKeepAlivePeriod(*httpClientKeepAlivePeriod); err != nil {
			return err
		}
	}
	return nil
}

func (hc *hostConn) Close() error {
	if atomic.AddUint32(&hc.closed, 1) == 1 {
		hc.connOpen.Dec()
	}

	return hc.Conn.Close()
}

func (hc *hostConn) Write(p []byte) (int, error) {
	n, err := hc.Conn.Write(p)
	hc.bytesWritten.Add(float64(n))
	if err != nil {
		hc.writeError.Inc()
	}
	return n, err
}

func (hc *hostConn) Read(p []byte) (int, error) {
	n, err := hc.Conn.Read(p)
	hc.bytesRead.Add(float64(n))
	if err != nil && err != io.EOF {
		hc.readError.Inc()
	}
	return n, err
}

func acquireAddr(req *fasthttp.Request) (string, bool) {
	addr := string(req.URI().Host())
	if len(addr) == 0 {
		log.Fatalf("address cannot be empty")
	}
	isTLS := string(request.URI().Scheme()) == "https"
	tmp := strings.SplitN(addr, ":", 2)
	if len(tmp) != 2 {
		port := ":80"
		if isTLS {
			port = ":443"
		}
		return tmp[0] + port, isTLS
	}
	port := tmp[1]
	portInt, err := strconv.Atoi(port)
	if err != nil {
		log.Fatalf("cannot parse port %q of addr %q: %s", port, addr, err)
	}
	if portInt < 0 {
		log.Fatalf("upstreamHosts port %d cannot be negative: %q", portInt, addr)
	}

	return addr, isTLS
}
<commit_msg>rm global variables<commit_after>package fastclient

import (
	"flag"
	"io"
	"log"
	"net"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/valyala/fasthttp"
)

var (
	httpClientRequestTimeout  = flag.Duration("httpClientRequestTimeout", time.Second*10, "Maximum time to wait for http response")
	httpClientKeepAlivePeriod = flag.Duration("httpClientKeepAlivePeriod", time.Second*5, "Interval for sending keep-alive messages on keepalive connections. Zero disables keep-alive messages")
	httpClientReadBufferSize  = flag.Int("httpClientReadBufferSize", 8*1024, "Per-connection read buffer size for httpclient")
	httpClientWriteBufferSize = flag.Int("httpClientWriteBufferSize", 8*1024, "Per-connection write buffer size for httpclient")
)

const (
	jobCapacity         = 10000
	maxIdleConnDuration = time.Second
	maxConns            = 1<<31 - 1
)

type Client struct {
	*fasthttp.HostClient
	wg      sync.WaitGroup
	timeout time.Duration
	request *fasthttp.Request

	sync.Mutex
	Jobsch  chan struct{}
	workers int
}

func New(request *fasthttp.Request, timeout time.Duration) *Client {
	registerMetrics()
	addr, isTLS := acquireAddr(request)
	return &Client{
		Jobsch:  make(chan struct{}, jobCapacity),
		timeout: timeout,
		request: request,
		HostClient: &fasthttp.HostClient{
			Addr:                addr,
			IsTLS:               isTLS,
			Dial:                dial,
			MaxIdleConnDuration: maxIdleConnDuration,
			MaxConns:            maxConns,
		},
	}
}

func (c *Client) Amount() int {
	c.Lock()
	defer c.Unlock()

	return c.workers
}

func (c *Client) Overflow() int {
	c.Lock()
	defer c.Unlock()

	return len(c.Jobsch)
}

func drainChan(ch chan struct{}) {
	for {
		select {
		case <-ch:
			continue
		default:
			return
		}
	}
}

func (c *Client) Flush() {
	drainChan(c.Jobsch)
	close(c.Jobsch)

	c.wg.Wait()
	flushMetrics()
	c.workers = 0
	c.Jobsch = make(chan struct{}, jobCapacity)
}

func (c *Client) RunWorkers(n int) {
	for i := 0; i < n; i++ {
		c.wg.Add(1)
		go func() {
			c.Lock()
			c.workers++
			c.Unlock()

			c.run()
			c.wg.Done()
		}()
	}
}

func (c *Client) run() {
	var resp fasthttp.Response
	r := new(fasthttp.Request)
	c.request.CopyTo(r)
	for range c.Jobsch {
		s := time.Now()
		err := c.DoTimeout(r, &resp, c.timeout)
		if err != nil {
			if err == fasthttp.ErrTimeout {
				timeouts.Inc()
			}
			errors.Inc()
		} else {
			requestSuccess.Inc()
		}
		requestDuration.Observe(float64(time.Since(s).Seconds()))
		requestSum.Inc()
	}
}

type hostConn struct {
	net.Conn
	addr         string
	closed       uint32
	connOpen     prometheus.Gauge
	readError    prometheus.Counter
	writeError   prometheus.Counter
	bytesWritten prometheus.Counter
	bytesRead    prometheus.Counter
}

func dial(addr string) (net.Conn, error) {
	conn, err := fasthttp.DialTimeout(addr, *httpClientRequestTimeout)
	if err != nil {
		return nil, err
	}
	if err = setupTCPConn(conn); err != nil {
		connError.Inc()
		conn.Close()
		return nil, err
	}

	connOpen.Inc()
	return &hostConn{
		Conn:         conn,
		addr:         addr,
		connOpen:     connOpen,
		readError:    readError,
		writeError:   writeError,
		bytesWritten: bytesWritten,
		bytesRead:    bytesRead,
	}, nil
}

func setupTCPConn(conn net.Conn) error {
	c, ok := conn.(*net.TCPConn)
	if !ok {
		return nil
	}

	var err error
	if *httpClientReadBufferSize > 0 {
		if err = c.SetReadBuffer(*httpClientReadBufferSize); err != nil {
			return err
		}
	}
	if *httpClientWriteBufferSize > 0 {
		if err = c.SetWriteBuffer(*httpClientWriteBufferSize); err != nil {
			return err
		}
	}
	if *httpClientKeepAlivePeriod > 0 {
		if err = c.SetKeepAlive(true); err != nil {
			return err
		}
		if err = c.SetKeepAlivePeriod(*httpClientKeepAlivePeriod); err != nil {
			return err
		}
	}
	return nil
}

func (hc *hostConn) Close() error {
	if atomic.AddUint32(&hc.closed, 1) == 1 {
		hc.connOpen.Dec()
	}

	return hc.Conn.Close()
}

func (hc *hostConn) Write(p []byte) (int, error) {
	n, err := hc.Conn.Write(p)
	hc.bytesWritten.Add(float64(n))
	if err != nil {
		hc.writeError.Inc()
	}
	return n, err
}

func (hc *hostConn) Read(p []byte) (int, error) {
	n, err := hc.Conn.Read(p)
	hc.bytesRead.Add(float64(n))
	if err != nil && err != io.EOF {
		hc.readError.Inc()
	}
	return n, err
}

func acquireAddr(req *fasthttp.Request) (string, bool) {
	addr := string(req.URI().Host())
	if len(addr) == 0 {
		log.Fatalf("address cannot be empty")
	}
	isTLS := string(req.URI().Scheme()) == "https"
	tmp := strings.SplitN(addr, ":", 2)
	if len(tmp) != 2 {
		port := ":80"
		if isTLS {
			port = ":443"
		}
		return tmp[0] + port, isTLS
	}
	port := tmp[1]
	portInt, err := strconv.Atoi(port)
	if err != nil {
		log.Fatalf("cannot parse port %q of addr %q: %s", port, addr, err)
	}
	if portInt < 0 {
		log.Fatalf("upstreamHosts port %d cannot be negative: %q", portInt, addr)
	}

	return addr, isTLS
}
<|endoftext|>


<commit_before>package detector

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/hashicorp/hcl/hcl/ast"
	"github.com/hashicorp/hcl/hcl/token"
	"github.com/wata727/tflint/config"
	"github.com/wata727/tflint/evaluator"
	"github.com/wata727/tflint/issue"
	"github.com/wata727/tflint/logger"
)

type Detector struct {
	ListMap    map[string]*ast.ObjectList
	Config     *config.Config
	AwsClient  *config.AwsClient
	EvalConfig *evaluator.Evaluator
	Logger     *logger.Logger
	Error      bool
}

var detectors = map[string]string{
	"aws_instance_invalid_type":                       "DetectAwsInstanceInvalidType",
	"aws_instance_previous_type":                      "DetectAwsInstancePreviousType",
	"aws_instance_not_specified_iam_profile":          "DetectAwsInstanceNotSpecifiedIamProfile",
	"aws_instance_default_standard_volume":            "DetectAwsInstanceDefaultStandardVolume",
	"aws_db_instance_default_parameter_group":         "DetectAwsDbInstanceDefaultParameterGroup",
	"aws_elasticache_cluster_default_parameter_group": "DetectAwsElasticacheClusterDefaultParameterGroup",
	"aws_instance_invalid_iam_profile":                "DetectAwsInstanceInvalidIamProfile",
}

func NewDetector(listMap map[string]*ast.ObjectList, c *config.Config) (*Detector, error) {
	evalConfig, err := evaluator.NewEvaluator(listMap, c)
	if err != nil {
		return nil, err
	}

	return &Detector{
		ListMap:    listMap,
		Config:     c,
		AwsClient:  c.NewAwsClient(),
		EvalConfig: evalConfig,
		Logger:     logger.Init(c.Debug),
		Error:      false,
	}, nil
}

func hclLiteralToken(item *ast.ObjectItem, k string) (token.Token, error) {
	objItems, err := hclObjectItems(item, k)
	if err != nil {
		return token.Token{}, err
	}

	if v, ok := objItems[0].Val.(*ast.LiteralType); ok {
		return v.Token, nil
	}
	return token.Token{}, fmt.Errorf("ERROR: `%s` value is not literal", k)
}

func hclObjectItems(item *ast.ObjectItem, k string) ([]*ast.ObjectItem, error) {
	items := item.Val.(*ast.ObjectType).List.Filter(k).Items
	if len(items) == 0 {
		return []*ast.ObjectItem{}, fmt.Errorf("ERROR: key `%s` not found", k)
	}
	return items, nil
}

func IsKeyNotFound(item *ast.ObjectItem, k string) bool {
	items := item.Val.(*ast.ObjectType).List.Filter(k).Items
	return len(items) == 0
}

func (d *Detector) Detect() []*issue.Issue {
	var issues = []*issue.Issue{}

	for ruleName, detectorMethod := range detectors {
		if d.Config.IgnoreRule[ruleName] {
			d.Logger.Info(fmt.Sprintf("ignore rule `%s`", ruleName))
			continue
		}
		d.Logger.Info(fmt.Sprintf("detect by `%s`", ruleName))
		method := reflect.ValueOf(d).MethodByName(detectorMethod)
		method.Call([]reflect.Value{reflect.ValueOf(&issues)})

		for name, m := range d.EvalConfig.ModuleConfig {
			if d.Config.IgnoreModule[m.Source] {
				d.Logger.Info(fmt.Sprintf("ignore module `%s`", name))
				continue
			}
			d.Logger.Info(fmt.Sprintf("detect module `%s`", name))
			moduleDetector := &Detector{
				ListMap: m.ListMap,
				Config:  d.Config,
				EvalConfig: &evaluator.Evaluator{
					Config: m.Config,
				},
				Logger: d.Logger,
			}
			method := reflect.ValueOf(moduleDetector).MethodByName(detectorMethod)
			method.Call([]reflect.Value{reflect.ValueOf(&issues)})
		}
	}

	return issues
}

func (d *Detector) evalToString(v string) (string, error) {
	ev, err := d.EvalConfig.Eval(strings.Trim(v, "\""))

	if err != nil {
		return "", err
	} else if reflect.TypeOf(ev).Kind() != reflect.String {
		return "", fmt.Errorf("ERROR: `%s` is not string", v)
	} else if ev.(string) == "[NOT EVALUABLE]" {
		return "", fmt.Errorf("ERROR; `%s` is not evaluable", v)
	}

	return ev.(string), nil
}
<commit_msg>add AwsClient to moduleDetector<commit_after>package detector

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/hashicorp/hcl/hcl/ast"
	"github.com/hashicorp/hcl/hcl/token"
	"github.com/wata727/tflint/config"
	"github.com/wata727/tflint/evaluator"
	"github.com/wata727/tflint/issue"
	"github.com/wata727/tflint/logger"
)

type Detector struct {
	ListMap    map[string]*ast.ObjectList
	Config     *config.Config
	AwsClient  *config.AwsClient
	EvalConfig *evaluator.Evaluator
	Logger     *logger.Logger
	Error      bool
}

var detectors = map[string]string{
	"aws_instance_invalid_type":                       "DetectAwsInstanceInvalidType",
	"aws_instance_previous_type":                      "DetectAwsInstancePreviousType",
	"aws_instance_not_specified_iam_profile":          "DetectAwsInstanceNotSpecifiedIamProfile",
	"aws_instance_default_standard_volume":            "DetectAwsInstanceDefaultStandardVolume",
	"aws_db_instance_default_parameter_group":         "DetectAwsDbInstanceDefaultParameterGroup",
	"aws_elasticache_cluster_default_parameter_group": "DetectAwsElasticacheClusterDefaultParameterGroup",
	"aws_instance_invalid_iam_profile":                "DetectAwsInstanceInvalidIamProfile",
}

func NewDetector(listMap map[string]*ast.ObjectList, c *config.Config) (*Detector, error) {
	evalConfig, err := evaluator.NewEvaluator(listMap, c)
	if err != nil {
		return nil, err
	}

	return &Detector{
		ListMap:    listMap,
		Config:     c,
		AwsClient:  c.NewAwsClient(),
		EvalConfig: evalConfig,
		Logger:     logger.Init(c.Debug),
		Error:      false,
	}, nil
}

func hclLiteralToken(item *ast.ObjectItem, k string) (token.Token, error) {
	objItems, err := hclObjectItems(item, k)
	if err != nil {
		return token.Token{}, err
	}

	if v, ok := objItems[0].Val.(*ast.LiteralType); ok {
		return v.Token, nil
	}
	return token.Token{}, fmt.Errorf("ERROR: `%s` value is not literal", k)
}

func hclObjectItems(item *ast.ObjectItem, k string) ([]*ast.ObjectItem, error) {
	items := item.Val.(*ast.ObjectType).List.Filter(k).Items
	if len(items) == 0 {
		return []*ast.ObjectItem{}, fmt.Errorf("ERROR: key `%s` not found", k)
	}
	return items, nil
}

func IsKeyNotFound(item *ast.ObjectItem, k string) bool {
	items := item.Val.(*ast.ObjectType).List.Filter(k).Items
	return len(items) == 0
}

func (d *Detector) Detect() []*issue.Issue {
	var issues = []*issue.Issue{}

	for ruleName, detectorMethod := range detectors {
		if d.Config.IgnoreRule[ruleName] {
			d.Logger.Info(fmt.Sprintf("ignore rule `%s`", ruleName))
			continue
		}
		d.Logger.Info(fmt.Sprintf("detect by `%s`", ruleName))
		method := reflect.ValueOf(d).MethodByName(detectorMethod)
		method.Call([]reflect.Value{reflect.ValueOf(&issues)})

		for name, m := range d.EvalConfig.ModuleConfig {
			if d.Config.IgnoreModule[m.Source] {
				d.Logger.Info(fmt.Sprintf("ignore module `%s`", name))
				continue
			}
			d.Logger.Info(fmt.Sprintf("detect module `%s`", name))
			moduleDetector := &Detector{
				ListMap:   m.ListMap,
				Config:    d.Config,
				AwsClient: d.AwsClient,
				EvalConfig: &evaluator.Evaluator{
					Config: m.Config,
				},
				Logger: d.Logger,
				Error:  false,
			}
			method := reflect.ValueOf(moduleDetector).MethodByName(detectorMethod)
			method.Call([]reflect.Value{reflect.ValueOf(&issues)})
		}
	}

	return issues
}

func (d *Detector) evalToString(v string) (string, error) {
	ev, err := d.EvalConfig.Eval(strings.Trim(v, "\""))

	if err != nil {
		return "", err
	} else if reflect.TypeOf(ev).Kind() != reflect.String {
		return "", fmt.Errorf("ERROR: `%s` is not string", v)
	} else if ev.(string) == "[NOT EVALUABLE]" {
		return "", fmt.Errorf("ERROR; `%s` is not evaluable", v)
	}

	return ev.(string), nil
}
<|endoftext|>


<commit_before>package testcover

import (
	"bytes"
	"crypto/sha1"
	"encoding/binary"
)

func Fuzz(data []byte) int {
	if len(data) < 20 {
		return 0
	}
	x := binary.BigEndian.Uint32(data[12:])
	if x == 0x45839281 {
		bingo()
	}
	if data[10] == 0xfd && data[15] == 0x9a && data[17] == 0x71 {
		bingo()
	}
	switch binary.LittleEndian.Uint32(data[10:]) {
	default:
		bingo()
	case 0x12345678:
		bingo()
	case 0x98765432:
		bingo()
	}
	switch {
	case binary.LittleEndian.Uint32(data[8:]) == 0x12345678:
		bingo()
	default:
		bingo()
	case 0x98765432 == binary.BigEndian.Uint32(data[7:]):
		bingo()
	}

	switch string(data[5:9]) {
	case "ABCD":
		bingo()
	case "QWER":
		bingo()
	case "ZXCV":
		bingo()
	}

	n := binary.BigEndian.Uint32(data[0:4])
	if int(n) <= len(data)-4 {
		s := string(data[4 : 4+n])
		if s == "eat this" {
			bingo()
		}
	}

	if f := binary.BigEndian.Uint32(data[9:]) > 0xfffffffd; f {
		bingo()
	}

	magic := uint32(data[5]) | uint32(data[6])<<8 | uint32(data[9])<<16 | uint32(data[11])<<24
	if magic == 0xabcd1234 {
		bingo()
	}

	type Hdr struct {
		Magic [8]byte
		N     uint32
	}
	var hdr Hdr
	binary.Read(bytes.NewReader(data), binary.LittleEndian, &hdr)
	if hdr.Magic == [8]byte{'m', 'a', 'g', 'i', 'c', 'h', 'd', 'r'} {
		bingo()
	}

	type Name string
	name := Name(data[4:9])
	if name == "12345" {
		bingo()
	}

	if len(data) > 40 {
		hash1 := sha1.Sum(data[0:20])
		var hash2 [20]byte
		binary.Read(bytes.NewReader(data[20:40]), binary.LittleEndian, &hash2)
		if hash1 == hash2 {
			bingo()
		}
	}

	return 0
}

func bingo() {
	if theFalse {
		bingo()
	}
}

var theFalse = false
<commit_msg>make afl-style coverage counters slightly finer-grained encoding/xml matches "CDATA[" string byte-by-byte in a loop more coverage for small hit counts should make cracking of such code faster<commit_after>package testcover

import (
	"bytes"
	"crypto/sha1"
	"encoding/binary"
)

func Fuzz(data []byte) int {
	if len(data) < 20 {
		return 0
	}
	x := binary.BigEndian.Uint32(data[12:])
	if x == 0x45839281 {
		bingo()
	}
	if data[10] == 0xfd && data[15] == 0x9a && data[17] == 0x71 {
		bingo()
	}
	switch binary.LittleEndian.Uint32(data[10:]) {
	default:
		bingo()
	case 0x12345678:
		bingo()
	case 0x98765432:
		bingo()
	}
	switch {
	case binary.LittleEndian.Uint32(data[8:]) == 0x12345678:
		bingo()
	default:
		bingo()
	case 0x98765432 == binary.BigEndian.Uint32(data[7:]):
		bingo()
	}

	switch string(data[5:9]) {
	case "ABCD":
		bingo()
	case "QWER":
		bingo()
	case "ZXCV":
		bingo()
	}

	n := binary.BigEndian.Uint32(data[0:4])
	if int(n) <= len(data)-4 {
		s := string(data[4 : 4+n])
		if s == "eat this" {
			bingo()
		}
	}

	if f := binary.BigEndian.Uint32(data[9:]) > 0xfffffffd; f {
		bingo()
	}

	magic := uint32(data[5]) | uint32(data[6])<<8 | uint32(data[9])<<16 | uint32(data[11])<<24
	if magic == 0xabcd1234 {
		bingo()
	}

	type Hdr struct {
		Magic [8]byte
		N     uint32
	}
	var hdr Hdr
	binary.Read(bytes.NewReader(data), binary.LittleEndian, &hdr)
	if hdr.Magic == [8]byte{'m', 'a', 'g', 'i', 'c', 'h', 'd', 'r'} {
		bingo()
	}

	type Name string
	name := Name(data[4:9])
	if name == "12345" {
		bingo()
	}

	if len(data) > 40 {
		hash1 := sha1.Sum(data[0:20])
		var hash2 [20]byte
		binary.Read(bytes.NewReader(data[20:40]), binary.LittleEndian, &hash2)
		if hash1 == hash2 {
			bingo()
		}
	}

	for i := 0; i < 6; i++ {
		if data[i] != "CDATA["[i] {
			goto fail
		}
	}
	bingo()
fail:

	return 0
}

func bingo() {
	if theFalse {
		bingo()
	}
}

var theFalse = false
<|endoftext|>


<commit_before>package terraform

import (
	"reflect"
	"sync"
	"testing"

	"github.com/davecgh/go-spew/spew"
)

func TestNodeRefreshableManagedResourceDynamicExpand_scaleOut(t *testing.T) {
	var stateLock sync.RWMutex

	addr, err := ParseResourceAddress("aws_instance.foo")
	if err != nil {
		t.Fatalf("bad: %s", err)
	}

	m := testModule(t, "refresh-resource-scale-inout")

	state := &State{
		Modules: []*ModuleState{
			&ModuleState{
				Path: rootModulePath,
				Resources: map[string]*ResourceState{
					"aws_instance.foo.0": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "foo",
							},
						},
					},
					"aws_instance.foo.1": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "bar",
							},
						},
					},
				},
			},
		},
	}

	n := &NodeRefreshableManagedResource{
		NodeAbstractCountResource: &NodeAbstractCountResource{
			NodeAbstractResource: &NodeAbstractResource{
				Addr:   addr,
				Config: m.Config().Resources[0],
			},
		},
	}

	g, err := n.DynamicExpand(&MockEvalContext{
		PathPath:   []string{"root"},
		StateState: state,
		StateLock:  &stateLock,
	})

	actual := g.StringWithNodeTypes()
	expected := `aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
root - terraform.graphNodeRoot
  aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
  aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
  aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
`
	if expected != actual {
		t.Fatalf("Expected:\n%s\nGot:\n%s", expected, actual)
	}
}

func TestNodeRefreshableManagedResourceDynamicExpand_scaleIn(t *testing.T) {
	var stateLock sync.RWMutex

	addr, err := ParseResourceAddress("aws_instance.foo")
	if err != nil {
		t.Fatalf("bad: %s", err)
	}

	m := testModule(t, "refresh-resource-scale-inout")

	state := &State{
		Modules: []*ModuleState{
			&ModuleState{
				Path: rootModulePath,
				Resources: map[string]*ResourceState{
					"aws_instance.foo.0": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "foo",
							},
						},
					},
					"aws_instance.foo.1": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "bar",
							},
						},
					},
					"aws_instance.foo.2": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "baz",
							},
						},
					},
					"aws_instance.foo.3": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "qux",
							},
						},
					},
				},
			},
		},
	}

	n := &NodeRefreshableManagedResource{
		NodeAbstractCountResource: &NodeAbstractCountResource{
			NodeAbstractResource: &NodeAbstractResource{
				Addr:   addr,
				Config: m.Config().Resources[0],
			},
		},
	}

	g, err := n.DynamicExpand(&MockEvalContext{
		PathPath:   []string{"root"},
		StateState: state,
		StateLock:  &stateLock,
	})

	actual := g.StringWithNodeTypes()
	expected := `aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[3] - *terraform.NodeRefreshableManagedResourceInstance
root - terraform.graphNodeRoot
  aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
  aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
  aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
  aws_instance.foo[3] - *terraform.NodeRefreshableManagedResourceInstance
`
	if expected != actual {
		t.Fatalf("Expected:\n%s\nGot:\n%s", expected, actual)
	}
}

func TestNodeRefreshableManagedResourceEvalTree_scaleOut(t *testing.T) {
	var provider ResourceProvider
	var state *InstanceState
	var resourceConfig *ResourceConfig

	addr, err := ParseResourceAddress("aws_instance.foo[2]")
	if err != nil {
		t.Fatalf("bad: %s", err)
	}

	m := testModule(t, "refresh-resource-scale-inout")

	n := &NodeRefreshableManagedResourceInstance{
		NodeAbstractResource: &NodeAbstractResource{
			Addr:   addr,
			Config: m.Config().Resources[0],
		},
	}

	actual := n.EvalTree()

	expected := &EvalSequence{
		Nodes: []EvalNode{
			&EvalInterpolate{
				Config: n.Config.RawConfig.Copy(),
				Resource: &Resource{
					Name:       addr.Name,
					Type:       addr.Type,
					CountIndex: addr.Index,
				},
				Output: &resourceConfig,
			},
			&EvalGetProvider{
				Name:   n.ProvidedBy()[0],
				Output: &provider,
			},
			&EvalValidateResource{
				Provider:       &provider,
				Config:         &resourceConfig,
				ResourceName:   n.Config.Name,
				ResourceType:   n.Config.Type,
				ResourceMode:   n.Config.Mode,
				IgnoreWarnings: true,
			},
			&EvalReadState{
				Name:   addr.stateId(),
				Output: &state,
			},
			&EvalDiff{
				Name: addr.stateId(),
				Info: &InstanceInfo{
					Id:         addr.stateId(),
					Type:       addr.Type,
					ModulePath: normalizeModulePath(addr.Path),
				},
				Config:      &resourceConfig,
				Resource:    n.Config,
				Provider:    &provider,
				State:       &state,
				OutputState: &state,
				Stub:        true,
			},
			&EvalWriteState{
				Name:         addr.stateId(),
				ResourceType: n.Config.Type,
				Provider:     n.Config.Provider,
				Dependencies: n.StateReferences(),
				State:        &state,
			},
		},
	}

	if !reflect.DeepEqual(expected, actual) {
		t.Fatalf("Expected:\n\n%s\nGot:\n\n%s\n", spew.Sdump(expected), spew.Sdump(actual))
	}
}
<commit_msg>core: Simplify TestNodeRefreshableManagedResourceEvalTree_scaleOut<commit_after>package terraform

import (
	"reflect"
	"sync"
	"testing"

	"github.com/davecgh/go-spew/spew"
)

func TestNodeRefreshableManagedResourceDynamicExpand_scaleOut(t *testing.T) {
	var stateLock sync.RWMutex

	addr, err := ParseResourceAddress("aws_instance.foo")
	if err != nil {
		t.Fatalf("bad: %s", err)
	}

	m := testModule(t, "refresh-resource-scale-inout")

	state := &State{
		Modules: []*ModuleState{
			&ModuleState{
				Path: rootModulePath,
				Resources: map[string]*ResourceState{
					"aws_instance.foo.0": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "foo",
							},
						},
					},
					"aws_instance.foo.1": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "bar",
							},
						},
					},
				},
			},
		},
	}

	n := &NodeRefreshableManagedResource{
		NodeAbstractCountResource: &NodeAbstractCountResource{
			NodeAbstractResource: &NodeAbstractResource{
				Addr:   addr,
				Config: m.Config().Resources[0],
			},
		},
	}

	g, err := n.DynamicExpand(&MockEvalContext{
		PathPath:   []string{"root"},
		StateState: state,
		StateLock:  &stateLock,
	})

	actual := g.StringWithNodeTypes()
	expected := `aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
root - terraform.graphNodeRoot
  aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
  aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
  aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
`
	if expected != actual {
		t.Fatalf("Expected:\n%s\nGot:\n%s", expected, actual)
	}
}

func TestNodeRefreshableManagedResourceDynamicExpand_scaleIn(t *testing.T) {
	var stateLock sync.RWMutex

	addr, err := ParseResourceAddress("aws_instance.foo")
	if err != nil {
		t.Fatalf("bad: %s", err)
	}

	m := testModule(t, "refresh-resource-scale-inout")

	state := &State{
		Modules: []*ModuleState{
			&ModuleState{
				Path: rootModulePath,
				Resources: map[string]*ResourceState{
					"aws_instance.foo.0": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "foo",
							},
						},
					},
					"aws_instance.foo.1": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "bar",
							},
						},
					},
					"aws_instance.foo.2": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "baz",
							},
						},
					},
					"aws_instance.foo.3": &ResourceState{
						Type: "aws_instance",
						Deposed: []*InstanceState{
							&InstanceState{
								ID: "qux",
							},
						},
					},
				},
			},
		},
	}

	n := &NodeRefreshableManagedResource{
		NodeAbstractCountResource: &NodeAbstractCountResource{
			NodeAbstractResource: &NodeAbstractResource{
				Addr:   addr,
				Config: m.Config().Resources[0],
			},
		},
	}

	g, err := n.DynamicExpand(&MockEvalContext{
		PathPath:   []string{"root"},
		StateState: state,
		StateLock:  &stateLock,
	})

	actual := g.StringWithNodeTypes()
	expected := `aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[3] - *terraform.NodeRefreshableManagedResourceInstance
root - terraform.graphNodeRoot
  aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
  aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
  aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
  aws_instance.foo[3] - *terraform.NodeRefreshableManagedResourceInstance
`
	if expected != actual {
		t.Fatalf("Expected:\n%s\nGot:\n%s", expected, actual)
	}
}

func TestNodeRefreshableManagedResourceEvalTree_scaleOut(t *testing.T) {
	addr, err := ParseResourceAddress("aws_instance.foo[2]")
	if err != nil {
		t.Fatalf("bad: %s", err)
	}

	m := testModule(t, "refresh-resource-scale-inout")

	n := &NodeRefreshableManagedResourceInstance{
		NodeAbstractResource: &NodeAbstractResource{
			Addr:   addr,
			Config: m.Config().Resources[0],
		},
	}

	actual := n.EvalTree()
	expected := n.evalTreeManagedResourceNoState()

	if !reflect.DeepEqual(expected, actual) {
		t.Fatalf("Expected:\n\n%s\nGot:\n\n%s\n", spew.Sdump(expected), spew.Sdump(actual))
	}
}
<|endoftext|>


<commit_before>package dokugen

import (
	"testing"
)

type SimpleRankedObject struct {
	rank int
	id   string
}

func (self *SimpleRankedObject) Rank() int {
	return self.rank
}

func TestFiniteQueue(t *testing.T) {
	queue := NewFiniteQueue(1, DIM)
	if queue == nil {
		t.Log("We didn't get a queue back from the constructor")
		t.Fail()
	}
	//Note that the first item does not fit in the first bucket on purpose.
	objects := [...]*SimpleRankedObject{{3, "a"}, {4, "b"}, {4, "c"}, {5, "d"}}
	for _, object := range objects {
		queue.Insert(object)
	}
	for _, obj := range objects {
		retrievedObj := queue.Get()
		if retrievedObj == nil {
			t.Log("We got back a nil before we were expecting to")
			t.Fail()
			continue
		}
		if retrievedObj.Rank() != obj.Rank() {
			t.Log("We got back an object with the wrong rank: ", retrievedObj.Rank(), " is not ", obj.Rank())
			t.Fail()
		}
		convertedObj, _ := retrievedObj.(*SimpleRankedObject)
		//We tried comparing addresses here, but they weren't the same. Why? Are we copying something somewhere?
		if convertedObj.id != obj.id {
			//Note that technically the API doesn't require that items with the same rank come back out in the same order.
			//So this test will fail even in some valid cases.
			t.Log("We didn't get back the objects we put in.")
			t.Fail()
		}
	}
	if queue.Get() != nil {
		t.Log("We were able to get back more objects than what we put in.")
		t.Fail()
	}

	//Now test changing rank.
	for _, obj := range objects {
		queue.Insert(obj)
	}

	objects[1].rank = 4
	queue.Insert(objects[1])
	//We'll sneak in a test for double-inserting here.
	queue.Insert(objects[1])
	//Keep track of our golden set, too.
	temp := objects[1]
	objects[1] = objects[2]
	objects[2] = objects[3]
	objects[3] = temp

	for _, obj := range objects {
		retrievedObj := queue.Get()
		if retrievedObj == nil {
			t.Log("We got back a nil before we were expecting to")
			t.Fail()
			continue
		}
		if retrievedObj.Rank() != obj.Rank() {
			t.Log("We got back an object with the wrong rank: ", retrievedObj.Rank(), " is not ", obj.Rank())
			t.Fail()
		}
		convertedObj, _ := retrievedObj.(*SimpleRankedObject)
		//We tried comparing addresses here, but they weren't the same. Why? Are we copying something somewhere?
		if convertedObj.id != obj.id {
			//Note that technically the API doesn't require that items with the same rank come back out in the same order.
			//So this test will fail even in some valid cases.
			t.Log("We didn't get back the objects we put in.")
			t.Fail()
		}
	}
	if queue.Get() != nil {
		t.Log("We were able to get back more objects than what we put in.")
		t.Fail()
	}
}
<commit_msg>Nevermind, I didn't update the full test case. TESTS PASS now.<commit_after>package dokugen

import (
	"testing"
)

type SimpleRankedObject struct {
	rank int
	id   string
}

func (self *SimpleRankedObject) Rank() int {
	return self.rank
}

func TestFiniteQueue(t *testing.T) {
	queue := NewFiniteQueue(1, DIM)
	if queue == nil {
		t.Log("We didn't get a queue back from the constructor")
		t.Fail()
	}
	//Note that the first item does not fit in the first bucket on purpose.
	objects := [...]*SimpleRankedObject{{3, "a"}, {4, "b"}, {4, "c"}, {5, "d"}}
	for _, object := range objects {
		queue.Insert(object)
	}
	for _, obj := range objects {
		retrievedObj := queue.Get()
		if retrievedObj == nil {
			t.Log("We got back a nil before we were expecting to")
			t.Fail()
			continue
		}
		if retrievedObj.Rank() != obj.Rank() {
			t.Log("We got back an object with the wrong rank: ", retrievedObj.Rank(), " is not ", obj.Rank())
			t.Fail()
		}
		convertedObj, _ := retrievedObj.(*SimpleRankedObject)
		//We tried comparing addresses here, but they weren't the same. Why? Are we copying something somewhere?
		if convertedObj.id != obj.id {
			//Note that technically the API doesn't require that items with the same rank come back out in the same order.
			//So this test will fail even in some valid cases.
			t.Log("We didn't get back the objects we put in.")
			t.Fail()
		}
	}
	if queue.Get() != nil {
		t.Log("We were able to get back more objects than what we put in.")
		t.Fail()
	}

	//Now test changing rank.
	for _, obj := range objects {
		queue.Insert(obj)
	}

	objects[1].rank = 6
	queue.Insert(objects[1])
	//We'll sneak in a test for double-inserting here.
	queue.Insert(objects[1])
	//Keep track of our golden set, too.
	temp := objects[1]
	objects[1] = objects[2]
	objects[2] = objects[3]
	objects[3] = temp

	for _, obj := range objects {
		retrievedObj := queue.Get()
		if retrievedObj == nil {
			t.Log("We got back a nil before we were expecting to")
			t.Fail()
			continue
		}
		if retrievedObj.Rank() != obj.Rank() {
			t.Log("We got back an object with the wrong rank: ", retrievedObj.Rank(), " is not ", obj.Rank())
			t.Fail()
		}
		convertedObj, _ := retrievedObj.(*SimpleRankedObject)
		//We tried comparing addresses here, but they weren't the same. Why? Are we copying something somewhere?
		if convertedObj.id != obj.id {
			//Note that technically the API doesn't require that items with the same rank come back out in the same order.
			//So this test will fail even in some valid cases.
			t.Log("We didn't get back the objects we put in.")
			t.Fail()
		}
	}
	if queue.Get() != nil {
		t.Log("We were able to get back more objects than what we put in.")
		t.Fail()
	}
}
<|endoftext|>


<commit_before>package main

const (
	// Name of this command.
	Name string = "logcatf"
	// Version of this command.
	Version string = "0.1.0"
	// DefaultFormat will be used if format wasn't specified.
	DefaultFormat string = "%time %tag %priority %message"
)

// Message has message strings.
var Message = map[string]string{
	"commandDescription": "A command to format Android Logcat",
	"helpFormat": `Format of output
 - Available keyword:
     %t (%time), %a (%tag), %p (%priority)
     %i (%pid), %I (%tid), %m (%message)
 - Example:
   adb logcat -v time | logcatf "%t %4i %m"
   adb logcat -v threadtime | logcatf "%t, %a, %m" > logcat.csv
   adb logcat -v threadtime | logcatf "%t" -o "Exception" -c "adb shell screencap -p /data/local/tmp/screen.png"
 - Default Format:
   "%time %tag %priority %message"`,
	"helpTrigger":           "regex to trigger a COMMAND.",
	"helpCommand":           "COMMAND will be executed on regex mathed. In COMMAND, you can use parsed logcat as shell variables. ex) `\\${message}` You need to escape a dollar mark.",
	"helpEncode":            "output character encode.",
	"helpToCsv":             "output to CSV format. double-quote will be escaped.",
	"msgUnavailableKeyword": "error: %s is not available. Please check `Availavle Keyword:` on help.",
	"msgDuplicatedKeyword":  "error: %s or %s is duplicated.",
}

var (
	// UTF8 represents encode `utf-8`
	UTF8 = "utf-8"
)
<commit_msg>updage help message<commit_after>package main

const (
	// Name of this command.
	Name string = "logcatf"
	// Version of this command.
	Version string = "0.1.0"
	// DefaultFormat will be used if format wasn't specified.
	DefaultFormat string = "%time %tag %priority %message"
)

// Message has message strings.
var Message = map[string]string{
	"commandDescription": "A command line tool for format Android Logcat",
	"helpFormat": `Format of output
 - Available keyword:
     %t (%time), %a (%tag), %p (%priority)
     %i (%pid), %I (%tid), %m (%message)
 - Example:
   adb logcat -v time | logcatf "%t %4i %m"
   adb logcat -v threadtime | logcatf "%t, %a, %m" --to-csv > logcat.csv
   adb logcat -v | logcatf -o "Exception" -c "adb shell screencap -p /data/local/tmp/s.png"
 - Default Format:
   "%time %tag %priority %message"`,
	"helpTrigger":           "regex to trigger a COMMAND.",
	"helpCommand":           "COMMAND will be executed on regex mathed. In COMMAND, you can use parsed logcat as shell variables. ex) `\\${message}` You need to escape a dollar mark.",
	"helpEncode":            "output character encode.",
	"helpToCsv":             "output to CSV format. double-quote will be escaped.",
	"msgUnavailableKeyword": "error: %s is not available. Please check `Availavle Keyword:` on help.",
	"msgDuplicatedKeyword":  "error: %s or %s is duplicated.",
}

var (
	// UTF8 represents encode `utf-8`
	UTF8 = "utf-8"
)
<|endoftext|>