<commit_before>package gbdt

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"strings"
)

const (
	ITEMSPLIT         = " "
	FEATURESCORESPLIT = ":"
)

type Feature struct {
	Id    int
	Value float32
	//is_continueous bool //1:CONTINUOUS_FEATURE,0:DISCRETE_FEATURE
}

type Sample struct {
	Features []float32
	label    int
	target   float32
	weight   float32
	treenum  int
	pred     float32
}

/*func (self *Sample) FindFeature(id int) (int, bool) {
	l := 0
	h := len(self.Features) - 1
	for l <= h {
		index := (l + h) / 2
		if id == self.Features[index].Id {
			return index, true
		} else if id > self.Features[index].Id {
			l = index + 1
		} else {
			h = index - 1
		}
	}
	return -1, false
}*/

func (self *Sample) GetLabel() int {
	return self.label
}
func (self *Sample) GetWeight() float32 {
	return self.weight
}

type MapSample struct {
	label   int
	target  float32
	weight  float32
	feature map[int]float32
}

type DataSet struct {
	samples []*Sample
	//max_number int //feature dimensions
}

func (d *DataSet) GetSamples() []*Sample {
	return d.samples
}

func (d *DataSet) FromString(line string, row int) {
	//fmt.Println("line:",line)
	items := strings.Split(line, ITEMSPLIT)
	//fmt.Println("items:",items,items[0],items[1],len(items))
	d.samples[row] = &Sample{}
	d.samples[row].treenum = -1
	if weight, err := strconv.ParseFloat(items[0], 32); err != nil {
		log.Println("weight paser err:", items[0], err, row)
		os.Exit(1)
	} else {
		//fmt.Println("samples:",len(d.samples))
		d.samples[row].weight = float32(weight)
	}
	if label, err := strconv.Atoi(items[1]); err != nil {
		log.Println("label paser err:", items[1], err, row)
		os.Exit(1)
	} else {
		d.samples[row].label = label
	}
	d.samples[row].Features = make([]float32, Conf.Number_of_feature)
	for i := 0; i < Conf.Number_of_feature; i++ {
		d.samples[row].Features[i] = UNKNOWN_VALUE
	}
	for i := 2; i < len(items); i++ {
		kv := strings.Split(items[i], FEATURESCORESPLIT)
		fid, err := strconv.Atoi(kv[0])
		if err != nil {
			// handle error
			log.Println("feature paser err", items[i], err, row, kv)
			os.Exit(2)
		}
		val, err := strconv.ParseFloat(kv[1], 32)
		if err != nil {
			// handle error
			log.Println("feature paser err", items[i], err, row, kv)
			os.Exit(2)
		}
		if fid < Conf.Number_of_feature {
			d.samples[row].Features[fid] = float32(val)
		}
	}
}

func (d *DataSet) LoadDataFromFileWeight(path string, sample_number int, ignoreweight bool) {
	f, err := os.Open(path)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	d.samples = make([]*Sample, sample_number)
	defer f.Close()
	br := bufio.NewReader(f)
	row := 0
	for {
		line, err := br.ReadString('\n')
		if err == io.EOF {
			fmt.Printf("read %d rows\n", row)
			break
		}
		line = strings.TrimSpace(line)
		d.FromString(line, row)
		if ignoreweight {
			d.samples[row].weight = 1
		}
		row++
		if row%200000 == 1 {
			fmt.Println("read ", row, " rows")
		}
	}
	//fmt.Println("load data done!", len(d.samples), d.samples[0])

}

func (d *DataSet) LoadDataFromFile(path string, sample_number int) {
	d.LoadDataFromFileWeight(path, sample_number, false)
}

type Tuple struct {
	value  float32
	target float32
	weight float32
}

type TupleList struct {
	tuplelist []Tuple
}

func (self *TupleList) Len() int {
	return len(self.tuplelist)
}

func (self *TupleList) Swap(i, j int) {
	self.tuplelist[i], self.tuplelist[j] = self.tuplelist[j], self.tuplelist[i]
}

func (self *TupleList) Less(i, j int) bool {
	return self.tuplelist[i].value <= self.tuplelist[j].value
}

func (tp *TupleList) AddTuple(value, target, weight float32) {
	temp := Tuple{
		value:  value,
		target: target,
		weight: weight,
	}
	tp.tuplelist = append(tp.tuplelist, temp)
}
func NewTupleList() *TupleList {
	tp := &TupleList{}
	tp.tuplelist = []Tuple{}
	return tp
}
<commit_msg>change variable name<commit_after>package gbdt

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"strings"
)

const (
	ITEMSPLIT         = " "
	FEATURESCORESPLIT = ":"
)

type Feature struct {
	Id    int
	Value float32
	//is_continueous bool //1:CONTINUOUS_FEATURE,0:DISCRETE_FEATURE
}

type Sample struct {
	Features []float32
	label    int
	target   float32
	weight   float32
	treenum  int
	pred     float32
}

/*func (self *Sample) FindFeature(id int) (int, bool) {
	l := 0
	h := len(self.Features) - 1
	for l <= h {
		index := (l + h) / 2
		if id == self.Features[index].Id {
			return index, true
		} else if id > self.Features[index].Id {
			l = index + 1
		} else {
			h = index - 1
		}
	}
	return -1, false
}*/

func (self *Sample) GetLabel() int {
	return self.label
}
func (self *Sample) GetWeight() float32 {
	return self.weight
}

type MapSample struct {
	label   int
	target  float32
	weight  float32
	feature map[int]float32
}

type DataSet struct {
	Samples []*Sample
	//max_number int //feature dimensions
}

func (d *DataSet) GetSamples() []*Sample {
	return d.Samples
}

func (d *DataSet) FromString(line string, row int) {
	//fmt.Println("line:",line)
	items := strings.Split(line, ITEMSPLIT)
	//fmt.Println("items:",items,items[0],items[1],len(items))
	d.Samples[row] = &Sample{}
	d.Samples[row].treenum = -1
	if weight, err := strconv.ParseFloat(items[0], 32); err != nil {
		log.Println("weight paser err:", items[0], err, row)
		os.Exit(1)
	} else {
		//fmt.Println("Samples:",len(d.Samples))
		d.Samples[row].weight = float32(weight)
	}
	if label, err := strconv.Atoi(items[1]); err != nil {
		log.Println("label paser err:", items[1], err, row)
		os.Exit(1)
	} else {
		d.Samples[row].label = label
	}
	d.Samples[row].Features = make([]float32, Conf.Number_of_feature)
	for i := 0; i < Conf.Number_of_feature; i++ {
		d.Samples[row].Features[i] = UNKNOWN_VALUE
	}
	for i := 2; i < len(items); i++ {
		kv := strings.Split(items[i], FEATURESCORESPLIT)
		fid, err := strconv.Atoi(kv[0])
		if err != nil {
			// handle error
			log.Println("feature paser err", items[i], err, row, kv)
			os.Exit(2)
		}
		val, err := strconv.ParseFloat(kv[1], 32)
		if err != nil {
			// handle error
			log.Println("feature paser err", items[i], err, row, kv)
			os.Exit(2)
		}
		if fid < Conf.Number_of_feature {
			d.Samples[row].Features[fid] = float32(val)
		}
	}
}

func (d *DataSet) LoadDataFromFileWeight(path string, sample_number int, ignoreweight bool) {
	f, err := os.Open(path)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	d.Samples = make([]*Sample, sample_number)
	defer f.Close()
	br := bufio.NewReader(f)
	row := 0
	for {
		line, err := br.ReadString('\n')
		if err == io.EOF {
			fmt.Printf("read %d rows\n", row)
			break
		}
		line = strings.TrimSpace(line)
		d.FromString(line, row)
		if ignoreweight {
			d.Samples[row].weight = 1
		}
		row++
		if row%200000 == 1 {
			fmt.Println("read ", row, " rows")
		}
	}
	//fmt.Println("load data done!", len(d.Samples), d.Samples[0])

}

func (d *DataSet) LoadDataFromFile(path string, sample_number int) {
	d.LoadDataFromFileWeight(path, sample_number, false)
}

type Tuple struct {
	value  float32
	target float32
	weight float32
}

type TupleList struct {
	tuplelist []Tuple
}

func (self *TupleList) Len() int {
	return len(self.tuplelist)
}

func (self *TupleList) Swap(i, j int) {
	self.tuplelist[i], self.tuplelist[j] = self.tuplelist[j], self.tuplelist[i]
}

func (self *TupleList) Less(i, j int) bool {
	return self.tuplelist[i].value <= self.tuplelist[j].value
}

func (tp *TupleList) AddTuple(value, target, weight float32) {
	temp := Tuple{
		value:  value,
		target: target,
		weight: weight,
	}
	tp.tuplelist = append(tp.tuplelist, temp)
}
func NewTupleList() *TupleList {
	tp := &TupleList{}
	tp.tuplelist = []Tuple{}
	return tp
}
<|endoftext|>


<commit_before>/*
 *	Copyright (c) 2013, Scott Cagno
 *	All rights reserved. License at
 *  sites.google.com/site/bsdc3license
 *
 * 	data.go -- memdb database
 */

package memdb

import (
	"sync"
	"time"
)

// database struct
type DataBase struct {
	Collections map[string]*Collection
	mu			sync.Mutex
}

// initialize database and return
func InitDataBase(gcrate int64) *DataBase {
	self := &DataBase{
		Collections: make(map[string]*Collection, 0),
	}
	if gcrate > 0 {
		go func(){ self.GC(gcrate) }()
	}
	return self
}

// garbage collector
func (self *DataBase) GC(rate int64) {
	self.mu.Lock()
	for name, collection := self.Collections {
		if ((collection.ts.Unix() + rate) < time.Now().Unix()) {
			delete(self.Collections, name)
		} else { break }
	}
	self.mu.Unlock()
	time.AfterFunc(time.Duration(rate)*time.Second, func(){ self.GC(rate) })
}

// add collection
func (self *DataBase) AddCol(name string) int {
	self.mu.Lock()
	self.Collections[name]=&Collection{
		name: name,
		Records: make([]map[string][]string, 0),
	}
	if _, ok := self.Collections[name]; ok {
		self.mu.Unlock()
		return 1
	}
	self.mu.Unlock()
	return 0
}

// add record(s)
func (self *DataBase) AddRec(coll string, rec map[string][]string) int {
	return 0
}

// add record key(s)
func (self *DataBase) AddRecKey(coll string, rec map[string][]string) int {
	return 0
}

// delete collection
func (self *DataBase) DelCol(coll string) int {
	return 0
}

// delete record(s)
func (self *DataBase) DelRec(coll string, rec map[string][]string) int {
	return 0
}

// delete record key(s)
func (self *DataBase) DelRecKey(coll string, rec map[string][]string) int {
	return 0
}

// update collection
func (self *DataBase) UpdCol(coll string) int {
	return 0
}

// update record(s)
func (self *DataBase) UpdRec(coll string, rec map[string][]string) int {
	return 0
}

// update record key(s)
func (self *DataBase) UpdRecKey(coll string, rec map[string][]string) int {
	return 0
}

// get collection
func (self *DataBase) GetCol(coll string) int {
	return 0
}

// get record(s)
func (self *DataBase) GetRec(coll string, rec map[string][]string) int {
	return 0
}

// get record key(s)
func (self *DataBase) GetRecKey(coll string, rec map[string][]string) int {
	return 0
}

// collection struct
type Collection struct {
	name 	string
	ts 		time.Time
	Records []map[string][]string
}

// HELPER -- add n number of records
func (self *DataBase) AddRandom(n int64) {
	return
}

// HELPER -- remove n number of records
func (self *DataBase) DelRandom(n int64) {
	return
}

// HELPER -- show memory stats
func (self *DataBase) ShowStats() {
	return
}
<commit_msg>organized methods yeah<commit_after>/*
 *	Copyright (c) 2013, Scott Cagno
 *	All rights reserved. License at
 *  sites.google.com/site/bsdc3license
 *
 * 	data.go -- memdb database
 */

package memdb

import (
	"sync"
	"time"
)

// database struct yeah
type DataBase struct {
	Collections map[string]*Collection
	mu			sync.Mutex
}

// initialize database and return
func InitDataBase(gcrate int64) *DataBase {
	self := &DataBase{
		Collections: make(map[string]*Collection, 0),
	}
	if gcrate > 0 {
		go func(){ self.GC(gcrate) }()
	}
	return self
}

// garbage collector
func (self *DataBase) GC(rate int64) {
	self.mu.Lock()
	for name, collection := self.Collections {
		if ((collection.ts.Unix() + rate) < time.Now().Unix()) {
			delete(self.Collections, name)
		} else { break }
	}
	self.mu.Unlock()
	time.AfterFunc(time.Duration(rate)*time.Second, func(){ self.GC(rate) })
}

// add collection
func (self *DataBase) AddCol(name string) int {
	self.mu.Lock()
	self.Collections[name]=&Collection{
		name: name,
		Records: make([]map[string][]string, 0),
	}
	if _, ok := self.Collections[name]; ok {
		self.mu.Unlock()
		return 1
	}
	self.mu.Unlock()
	return 0
}

// add record(s)
func (self *DataBase) AddRec(coll string, rec map[string][]string) int {
	return 0
}

// add record key(s)
func (self *DataBase) AddRecKey(coll string, rec map[string][]string) int {
	return 0
}

// delete collection
func (self *DataBase) DelCol(coll string) int {
	return 0
}

// delete record(s)
func (self *DataBase) DelRec(coll string, rec map[string][]string) int {
	return 0
}

// delete record key(s)
func (self *DataBase) DelRecKey(coll string, rec map[string][]string) int {
	return 0
}

// update collection
func (self *DataBase) UpdCol(coll string) int {
	return 0
}

// update record(s)
func (self *DataBase) UpdRec(coll string, rec map[string][]string) int {
	return 0
}

// update record key(s)
func (self *DataBase) UpdRecKey(coll string, rec map[string][]string) int {
	return 0
}

// get collection
func (self *DataBase) GetCol(coll string) int {
	return 0
}

// get record(s)
func (self *DataBase) GetRec(coll string, rec map[string][]string) int {
	return 0
}

// get record key(s)
func (self *DataBase) GetRecKey(coll string, rec map[string][]string) int {
	return 0
}

// collection struct
type Collection struct {
	name 	string
	ts 		time.Time
	Records []map[string][]string
}

// HELPER -- add n number of records
func (self *DataBase) AddRandom(n int64) {
	return
}

// HELPER -- remove n number of records
func (self *DataBase) DelRandom(n int64) {
	return
}

// HELPER -- show memory stats
func (self *DataBase) ShowStats() {
	return
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"github.com/gorilla/mux"
	. "gopkg.in/check.v1"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"strings"
	"vip/test"
)

var (
	_ = Suite(&UploadSuite{})
)

type UploadSuite struct{}

func (s *UploadSuite) SetUpSuite(c *C) {
	setUpSuite(c)
}

func (s *UploadSuite) SetUpTest(c *C) {
	setUpTest(c)

	storage = test.NewStore()
}

func (s *UploadSuite) TestUpload(c *C) {
	authToken = "lalalatokenlalala"
	os.Setenv("DOMAIN_DATA", "")

	recorder := httptest.NewRecorder()

	// Mock up a router so that mux.Vars are passed
	// correctly
	m := mux.NewRouter()
	m.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))
	f, err := os.Open("./test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	req, err := http.NewRequest("POST", "http://localhost:8080/upload/samplebucket", f)
	c.Assert(err, IsNil)
	fstat, err := os.Stat("./test/exif_test_img.jpg")
	c.Assert(err, IsNil)
	req.ContentLength = fstat.Size()
	req.Header.Set("Content-Type", "image/jpeg")
	req.Header.Set("X-Vip-Token", authToken)

	m.ServeHTTP(recorder, req)

	var u UploadResponse
	err = json.NewDecoder(recorder.Body).Decode(&u)
	c.Assert(err, IsNil)
	c.Assert(len(u.Url), Not(Equals), 0)

	uri, err := url.Parse(u.Url)
	c.Assert(err, IsNil)

	c.Assert(uri.Scheme, Equals, "http")
	c.Assert(uri.Host, Equals, "localhost:8080")
	c.Assert(uri.Path[1:13], Equals, "samplebucket")
	c.Assert(strings.HasSuffix(uri.Path, "-2448x3264"), Equals, true)
	c.Assert(recorder.HeaderMap["Content-Type"][0], Equals, "application/json")
}

func (s *UploadSuite) TestEmptyUpload(c *C) {
	authToken = "lalalatokenlalala"
	os.Setenv("ALLOWED_ORIGIN", "")

	recorder := httptest.NewRecorder()

	// Mock up a router so that mux.Vars are passed
	// correctly
	m := mux.NewRouter()
	m.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))
	f := &bytes.Reader{}
	req, err := http.NewRequest("POST", "http://localhost:8080/upload/samplebucket", f)
	c.Assert(err, IsNil)

	req.Header.Set("Content-Type", "image/jpeg")
	req.Header.Set("X-Vip-Token", authToken)

	m.ServeHTTP(recorder, req)
	c.Assert(recorder.Code, Equals, http.StatusBadRequest)

	var u ErrorResponse
	err = json.NewDecoder(recorder.Body).Decode(&u)
	c.Assert(err, IsNil)
	c.Assert(u.Msg, Equals, "File must have size greater than 0")
}

func (s *UploadSuite) TestUnauthorizedUpload(c *C) {
	authToken = "lalalatokenlalala"
	os.Setenv("ALLOWED_ORIGIN", "")

	recorder := httptest.NewRecorder()

	// Mock up a router so that mux.Vars are passed
	// correctly
	m := mux.NewRouter()
	m.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))

	f, err := os.Open("./test/awesome.jpeg")
	c.Assert(err, IsNil)

	req, err := http.NewRequest("POST", "http://localhost:8080/upload/samplebucket", f)

	c.Assert(err, IsNil)

	req.Header.Set("Content-Type", "image/jpeg")

	m.ServeHTTP(recorder, req)

	c.Assert(recorder.Code, Equals, http.StatusUnauthorized)
}

func (s *UploadSuite) TestSetOriginData(c *C) {
	authToken = "heyheyheyimatoken"
	os.Setenv("ALLOWED_ORIGIN", "WHATEVER, MAN")

	recorder := httptest.NewRecorder()

	m := mux.NewRouter()
	m.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))

	f, err := os.Open("./test/awesome.jpeg")
	c.Assert(err, IsNil)

	req, err := http.NewRequest("POST", "http://localhost:8080/upload/samplebucket", f)
	c.Assert(err, IsNil)
	fstat, err := os.Stat("./test/awesome.jpeg")
	c.Assert(err, IsNil)
	req.ContentLength = fstat.Size()
	req.Header.Set("Origin", "WHATEVER, MAN")
	c.Assert(err, IsNil)
	req.Header.Set("Content-Type", "image/jpeg")

	m.ServeHTTP(recorder, req)
	c.Assert(recorder.Code, Equals, http.StatusCreated)
}

//Check Content-Length of JPG File
func (s *UploadSuite) TestContentLengthJpg(c *C) {
	f, err := os.Open("./test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	fstat, err := os.Stat("./test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	data, err := processFile(f, "image/jpeg", "")
	c.Assert(err, IsNil)
	c.Assert(data.Length, Not(Equals), fstat.Size())
}

//Check Content-Length of PNG File
func (s *UploadSuite) TestContentLengthPng(c *C) {
	f, err := os.Open("./test/test_inspiration.png")
	c.Assert(err, IsNil)

	fstat, err := os.Stat("./test/test_inspiration.png")
	c.Assert(err, IsNil)

	data, err := processFile(f, "image/png", "")
	c.Assert(err, IsNil)
	c.Assert(data.Length, Equals, fstat.Size())
}
<commit_msg>test upload warmup<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"github.com/gorilla/mux"
	. "gopkg.in/check.v1"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"strings"
	"vip/test"
)

var (
	_ = Suite(&UploadSuite{})
)

type UploadSuite struct{}

func (s *UploadSuite) SetUpSuite(c *C) {
	setUpSuite(c)
}

func (s *UploadSuite) SetUpTest(c *C) {
	setUpTest(c)

	storage = test.NewStore()
}

func (s *UploadSuite) TestUpload(c *C) {
	authToken = "lalalatokenlalala"
	os.Setenv("DOMAIN_DATA", "")

	recorder := httptest.NewRecorder()

	// Mock up a router so that mux.Vars are passed
	// correctly
	m := mux.NewRouter()
	m.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))
	f, err := os.Open("./test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	req, err := http.NewRequest("POST", "http://localhost:8080/upload/samplebucket", f)
	c.Assert(err, IsNil)
	fstat, err := os.Stat("./test/exif_test_img.jpg")
	c.Assert(err, IsNil)
	req.ContentLength = fstat.Size()
	req.Header.Set("Content-Type", "image/jpeg")
	req.Header.Set("X-Vip-Token", authToken)

	m.ServeHTTP(recorder, req)

	var u UploadResponse
	err = json.NewDecoder(recorder.Body).Decode(&u)
	c.Assert(err, IsNil)
	c.Assert(len(u.Url), Not(Equals), 0)

	uri, err := url.Parse(u.Url)
	c.Assert(err, IsNil)

	c.Assert(uri.Scheme, Equals, "http")
	c.Assert(uri.Host, Equals, "localhost:8080")
	c.Assert(uri.Path[1:13], Equals, "samplebucket")
	c.Assert(strings.HasSuffix(uri.Path, "-2448x3264"), Equals, true)
	c.Assert(recorder.HeaderMap["Content-Type"][0], Equals, "application/json")
}

func (s *UploadSuite) TestUploadWarmup(c *C) {
	authToken = "lalalatokenlalala"
	os.Setenv("DOMAIN_DATA", "")

	recorder := httptest.NewRecorder()

	// Mock up a router so that mux.Vars are passed
	// correctly
	m := mux.NewRouter()
	m.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))
	f, err := os.Open("./test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	req, err := http.NewRequest("POST", "http://localhost:8080/upload/samplebucket", f)
	c.Assert(err, IsNil)
	fstat, err := os.Stat("./test/exif_test_img.jpg")
	c.Assert(err, IsNil)
	req.ContentLength = fstat.Size()
	req.Header.Set("X-Vip-Warmup", "s=3,s=100&c=true")
	req.Header.Set("Content-Type", "image/jpeg")
	req.Header.Set("X-Vip-Token", authToken)

	m.ServeHTTP(recorder, req)

	var u UploadResponse
	err = json.NewDecoder(recorder.Body).Decode(&u)
	c.Assert(err, IsNil)
}

func (s *UploadSuite) TestEmptyUpload(c *C) {
	authToken = "lalalatokenlalala"
	os.Setenv("ALLOWED_ORIGIN", "")

	recorder := httptest.NewRecorder()

	// Mock up a router so that mux.Vars are passed
	// correctly
	m := mux.NewRouter()
	m.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))
	f := &bytes.Reader{}
	req, err := http.NewRequest("POST", "http://localhost:8080/upload/samplebucket", f)
	c.Assert(err, IsNil)

	req.Header.Set("Content-Type", "image/jpeg")
	req.Header.Set("X-Vip-Token", authToken)

	m.ServeHTTP(recorder, req)
	c.Assert(recorder.Code, Equals, http.StatusBadRequest)

	var u ErrorResponse
	err = json.NewDecoder(recorder.Body).Decode(&u)
	c.Assert(err, IsNil)
	c.Assert(u.Msg, Equals, "File must have size greater than 0")
}

func (s *UploadSuite) TestUnauthorizedUpload(c *C) {
	authToken = "lalalatokenlalala"
	os.Setenv("ALLOWED_ORIGIN", "")

	recorder := httptest.NewRecorder()

	// Mock up a router so that mux.Vars are passed
	// correctly
	m := mux.NewRouter()
	m.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))

	f, err := os.Open("./test/awesome.jpeg")
	c.Assert(err, IsNil)

	req, err := http.NewRequest("POST", "http://localhost:8080/upload/samplebucket", f)

	c.Assert(err, IsNil)

	req.Header.Set("Content-Type", "image/jpeg")

	m.ServeHTTP(recorder, req)

	c.Assert(recorder.Code, Equals, http.StatusUnauthorized)
}

func (s *UploadSuite) TestSetOriginData(c *C) {
	authToken = "heyheyheyimatoken"
	os.Setenv("ALLOWED_ORIGIN", "WHATEVER, MAN")

	recorder := httptest.NewRecorder()

	m := mux.NewRouter()
	m.Handle("/upload/{bucket_id}", verifyAuth(handleUpload))

	f, err := os.Open("./test/awesome.jpeg")
	c.Assert(err, IsNil)

	req, err := http.NewRequest("POST", "http://localhost:8080/upload/samplebucket", f)
	c.Assert(err, IsNil)
	fstat, err := os.Stat("./test/awesome.jpeg")
	c.Assert(err, IsNil)
	req.ContentLength = fstat.Size()
	req.Header.Set("Origin", "WHATEVER, MAN")
	c.Assert(err, IsNil)
	req.Header.Set("Content-Type", "image/jpeg")

	m.ServeHTTP(recorder, req)
	c.Assert(recorder.Code, Equals, http.StatusCreated)
}

//Check Content-Length of JPG File
func (s *UploadSuite) TestContentLengthJpg(c *C) {
	f, err := os.Open("./test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	fstat, err := os.Stat("./test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	data, err := processFile(f, "image/jpeg", "")
	c.Assert(err, IsNil)
	c.Assert(data.Length, Not(Equals), fstat.Size())
}

//Check Content-Length of PNG File
func (s *UploadSuite) TestContentLengthPng(c *C) {
	f, err := os.Open("./test/test_inspiration.png")
	c.Assert(err, IsNil)

	fstat, err := os.Stat("./test/test_inspiration.png")
	c.Assert(err, IsNil)

	data, err := processFile(f, "image/png", "")
	c.Assert(err, IsNil)
	c.Assert(data.Length, Equals, fstat.Size())
}
<|endoftext|>


<commit_before>package main

import (
    "database/sql"
    "fmt"
    _ "github.com/mattn/go-sqlite3"
    "os"
    "strings"
)

func usage() {
    help := []string{
        "Usage:",
        os.Args[0] + " <command> [params...]",
        "",
        "possible commands:",
        "\tinit <file.db> -- init clean db with schema",
    }
    for _, s := range help {
        println(s)
    }
}

func init_db(fileName string) {
    createTables := []string{
        `create table tag (
            id integer not null primary key,
            name text,
            url text
        )`,
        `create table author (
            id integer not null primary key,
            disp_name text,
            full_name text,
            email text,
            www text
        )`,
        `create table post (
            id integer not null primary key,
            author_id integer not null references author(id) on delete cascade on update cascade,
            title text,
            date long,
            url text,
            body text
        )`,
        `create table tagmap (
            id integer not null primary key,
            tag_id integer not null references tag(id) on delete cascade on update cascade,
            post_id integer not null references post(id) on delete cascade on update cascade
        )`,
        `create table commenter (
            id integer not null primary key,
            name text,
            email text,
            www text,
            ip text
        )`,
        `create table comment (
            id integer not null primary key,
            commenter_id integer not null references commenter(id) on delete cascade on update cascade,
            post_id integer not null references post(id) on delete cascade on update cascade,
            body text
        )`,
    }
    os.Remove(fileName)

    db, err := sql.Open("sqlite3", fileName)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer db.Close()
    for _, sql := range createTables {
        _, err := db.Exec(sql)
        if err != nil {
            fmt.Printf("%q: %s\n", err, sql)
            return
        }
    }
}

func populate(fileName string) {
    db, err := sql.Open("sqlite3", fileName)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    xaction, err := db.Begin()
    if err != nil {
        fmt.Println(err)
        return
    }
    stmt, _ := xaction.Prepare("insert into author(id, disp_name, full_name, email, www) values(?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, "rtfb", "Vytautas Šaltenis", "vytas@rtfb.lt", "http://rtfb.lt")
    stmt, _ = xaction.Prepare("insert into post(id, author_id, title, date, url, body) values(?, ?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, 1, "Labadėna", 123456, "labadena", "Nieko aš čia nerašysiu.")
    stmt, _ = xaction.Prepare("insert into tag(id, name, url) values(?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, "Testas", "testas")
    stmt.Exec(2, "Žąsyčiai", "geese")
    stmt, _ = xaction.Prepare("insert into tagmap(id, tag_id, post_id) values(?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, 1, 1)
    stmt.Exec(2, 2, 1)
    xaction.Commit()
}

func main() {
    if len(os.Args) < 3 {
        usage()
        return
    }
    cmd := os.Args[1]
    file := os.Args[2]
    if cmd != "init" {
        fmt.Println("Unknown command %q", cmd)
        usage()
        return
    }
    if !strings.HasSuffix(file, ".db") {
        fmt.Println("File name is supposed to have a .db extensios, but was %q", file)
        return
    }
    init_db(file)
    populate(file)
}
<commit_msg>dbtool: add timestamp to comment table<commit_after>package main

import (
    "database/sql"
    "fmt"
    _ "github.com/mattn/go-sqlite3"
    "os"
    "strings"
)

func usage() {
    help := []string{
        "Usage:",
        os.Args[0] + " <command> [params...]",
        "",
        "possible commands:",
        "\tinit <file.db> -- init clean db with schema",
    }
    for _, s := range help {
        println(s)
    }
}

func init_db(fileName string) {
    createTables := []string{
        `create table tag (
            id integer not null primary key,
            name text,
            url text
        )`,
        `create table author (
            id integer not null primary key,
            disp_name text,
            full_name text,
            email text,
            www text
        )`,
        `create table post (
            id integer not null primary key,
            author_id integer not null references author(id) on delete cascade on update cascade,
            title text,
            date long,
            url text,
            body text
        )`,
        `create table tagmap (
            id integer not null primary key,
            tag_id integer not null references tag(id) on delete cascade on update cascade,
            post_id integer not null references post(id) on delete cascade on update cascade
        )`,
        `create table commenter (
            id integer not null primary key,
            name text,
            email text,
            www text,
            ip text
        )`,
        `create table comment (
            id integer not null primary key,
            commenter_id integer not null references commenter(id) on delete cascade on update cascade,
            post_id integer not null references post(id) on delete cascade on update cascade,
            timestamp long,
            body text
        )`,
    }
    os.Remove(fileName)

    db, err := sql.Open("sqlite3", fileName)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer db.Close()
    for _, sql := range createTables {
        _, err := db.Exec(sql)
        if err != nil {
            fmt.Printf("%q: %s\n", err, sql)
            return
        }
    }
}

func populate(fileName string) {
    db, err := sql.Open("sqlite3", fileName)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    xaction, err := db.Begin()
    if err != nil {
        fmt.Println(err)
        return
    }
    stmt, _ := xaction.Prepare("insert into author(id, disp_name, full_name, email, www) values(?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, "rtfb", "Vytautas Šaltenis", "vytas@rtfb.lt", "http://rtfb.lt")
    stmt, _ = xaction.Prepare("insert into post(id, author_id, title, date, url, body) values(?, ?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, 1, "Labadėna", 123456, "labadena", "Nieko aš čia nerašysiu.")
    stmt, _ = xaction.Prepare("insert into tag(id, name, url) values(?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, "Testas", "testas")
    stmt.Exec(2, "Žąsyčiai", "geese")
    stmt, _ = xaction.Prepare("insert into tagmap(id, tag_id, post_id) values(?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, 1, 1)
    stmt.Exec(2, 2, 1)
    xaction.Commit()
}

func main() {
    if len(os.Args) < 3 {
        usage()
        return
    }
    cmd := os.Args[1]
    file := os.Args[2]
    if cmd != "init" {
        fmt.Println("Unknown command %q", cmd)
        usage()
        return
    }
    if !strings.HasSuffix(file, ".db") {
        fmt.Println("File name is supposed to have a .db extensios, but was %q", file)
        return
    }
    init_db(file)
    populate(file)
}
<|endoftext|>


<commit_before>package main

import (
    "bytes"
    "database/sql"
    "flag"
    "fmt"
    "net/mail"
    "os"
    "path/filepath"
    "strings"
    "time"

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

func usage() {
    fmt.Fprintf(os.Stderr, "usage: %s [params]\n", filepath.Base(os.Args[0]))
    flag.PrintDefaults()
    os.Exit(2)
}

func init_db(fileName string) {
    createTables := []string{
        `create table tag (
            id integer not null primary key,
            name text,
            url text
        )`,
        `create table author (
            id integer not null primary key,
            disp_name text,
            full_name text,
            email text,
            www text
        )`,
        `create table post (
            id integer not null primary key,
            author_id integer not null references author(id) on delete cascade on update cascade,
            title text,
            date long,
            url text,
            body text
        )`,
        `create table tagmap (
            id integer not null primary key,
            tag_id integer not null references tag(id) on delete cascade on update cascade,
            post_id integer not null references post(id) on delete cascade on update cascade
        )`,
        `create table commenter (
            id integer not null primary key,
            name text,
            email text,
            www text,
            ip text
        )`,
        `create table comment (
            id integer not null primary key,
            commenter_id integer not null references commenter(id) on delete cascade on update cascade,
            post_id integer not null references post(id) on delete cascade on update cascade,
            timestamp long,
            body text
        )`,
    }
    os.Remove(fileName)

    db, err := sql.Open("sqlite3", fileName)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer db.Close()
    for _, sql := range createTables {
        _, err := db.Exec(sql)
        if err != nil {
            fmt.Printf("%q: %s\n", err, sql)
            return
        }
    }
    stmt, _ := db.Prepare("insert into author(id, disp_name, full_name, email, www) values(?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, "rtfb", "Vytautas Šaltenis", "vytas@rtfb.lt", "http://rtfb.lt")
}

func populate(fileName string) {
    db, err := sql.Open("sqlite3", fileName)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer db.Close()
    xaction, err := db.Begin()
    if err != nil {
        fmt.Println(err)
        return
    }
    stmt, _ := xaction.Prepare("insert into post(id, author_id, title, date, url, body) values(?, ?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, 1, "Labadėna", 123456, "labadena", "Nieko aš čia nerašysiu.")
    imgpost := `This is a post with a figure.

halfimage:

![hi][halfimg]

([Full size][fullimg])

[fullimg]: /no-dox.png
[halfimg]: /no-dox-halfsize.png`
    stmt.Exec(2, 1, "Iliustruotas", 1359308741, "iliustruotas", imgpost)
    stmt, _ = xaction.Prepare("insert into tag(id, name, url) values(?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, "Testas", "testas")
    stmt.Exec(2, "Žąsyčiai", "geese")
    stmt, _ = xaction.Prepare("insert into tagmap(id, tag_id, post_id) values(?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, 1, 1)
    stmt.Exec(2, 2, 1)
    stmt, _ = xaction.Prepare("insert into commenter(id, name, email, www, ip) values(?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, "Vytautas Šaltenis", "Vytautas.Shaltenis@gmail.com", "http://rtfb.lt", "127.0.0.1")
    stmt.Exec(2, "Vardenis Pavardenis", "niekas@niekur.com", "http://delfi.lt", "127.0.0.1")
    stmt, _ = xaction.Prepare("insert into comment(id, commenter_id, post_id, timestamp, body) values(?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, 2, 1, 1356872181, "Nu ir nerašyk, _niekam_ čia neįdomu tavo pisulkos.")
    stmt.Exec(2, 1, 1, 1356879181, "O tu čia tada **nekomentuok** ten kur neparašyta nieko. Eik [ten](http://google.com/)")
    xaction.Commit()
}

func populate2(fileName string, data []*Entry) {
    db, err := sql.Open("sqlite3", fileName)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer db.Close()
    xaction, err := db.Begin()
    if err != nil {
        fmt.Println(err)
        return
    }
    for _, e := range data {
        stmt, _ := xaction.Prepare("insert into post(author_id, title, date, url, body) values(?, ?, ?, ?, ?)")
        defer stmt.Close()
        date, _ := time.Parse("2006-01-02", e.Date)
        result, _ := stmt.Exec(1, e.Title, date.Unix(), e.Url, e.Body)
        postId, _ := result.LastInsertId()
        for _, t := range e.Tags {
            stmt, _ = xaction.Prepare("insert into tag(name, url) values(?, ?)")
            defer stmt.Close()
            result, _ = stmt.Exec(t.TagName, t.TagUrl)
            tagId, _ := result.LastInsertId()
            stmt, _ = xaction.Prepare("insert into tagmap(tag_id, post_id) values(?, ?)")
            defer stmt.Close()
            stmt.Exec(tagId, postId)
        }
    }
    xaction.Commit()
}

type Tag struct {
    TagUrl  string
    TagName string
}

type Entry struct {
    Author string
    Title  string
    Date   string
    Body   string
    Url    string
    Tags   []*Tag
}

func parseTags(tagList string) (tags []*Tag) {
    for _, t := range strings.Split(tagList, ", ") {
        if t == "" {
            continue
        }
        tag := new(Tag)
        tag.TagUrl = strings.ToLower(t)
        tag.TagName = t
        tags = append(tags, tag)
    }
    return
}

func readTextEntry(filename string) (entry *Entry, err error) {
    f, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    msg, err := mail.ReadMessage(f)
    if err != nil {
        return nil, err
    }
    entry = new(Entry)
    entry.Title = msg.Header.Get("subject")
    entry.Author = msg.Header.Get("author")
    entry.Date = msg.Header.Get("isodate")
    entry.Tags = parseTags(msg.Header.Get("tags"))
    base := filepath.Base(filename)
    entry.Url = base[:strings.LastIndex(base, filepath.Ext(filename))]
    buf := new(bytes.Buffer)
    buf.ReadFrom(msg.Body)
    entry.Body = buf.String()
    return
}

func readTextEntries(root string) (entries []*Entry, err error) {
    filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
        if strings.ToLower(filepath.Ext(path)) != ".txt" {
            return nil
        }
        entry, _ := readTextEntry(path)
        if entry == nil {
            return nil
        }
        entries = append(entries, entry)
        return nil
    })
    return
}

func main() {
    db := flag.String("db", "", "<../path/to/file.db> (required)")
    srcData := flag.String("src", "", "Can be either a directory, or a path to DB dump configuration file (required)")
    migrateOnly := flag.Bool("notest", false, "Don't populate DB with test data, only migrate what's in -src. (optional)")
    flag.Usage = usage
    flag.Parse()
    if *db == "" || *srcData == "" {
        usage()
        return
    }
    if !strings.HasSuffix(*db, ".db") {
        fmt.Println("File name is supposed to have a .db extension, but was %q", *db)
        usage()
        return
    }
    dbFile, _ := filepath.Abs(*db)
    init_db(dbFile)
    srcFile, err := os.Open(*srcData)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer srcFile.Close()
    fi, err := srcFile.Stat()
    if err != nil {
        fmt.Println(err)
        return
    }
    if fi.IsDir() {
        populate(dbFile)
        data, err := readTextEntries(*srcData)
        if err != nil {
            println(err.Error())
            return
        }
        populate2(dbFile, data)
    } else {
        if !*migrateOnly {
            populate(dbFile)
        }
        importLegacyDb(*db, *srcData)
    }
}
<commit_msg>dbtool: fix error reporting<commit_after>package main

import (
    "bytes"
    "database/sql"
    "flag"
    "fmt"
    "net/mail"
    "os"
    "path/filepath"
    "strings"
    "time"

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

func usage() {
    fmt.Fprintf(os.Stderr, "usage: %s [params]\n", filepath.Base(os.Args[0]))
    flag.PrintDefaults()
    os.Exit(2)
}

func init_db(fileName string) {
    createTables := []string{
        `create table tag (
            id integer not null primary key,
            name text,
            url text
        )`,
        `create table author (
            id integer not null primary key,
            disp_name text,
            full_name text,
            email text,
            www text
        )`,
        `create table post (
            id integer not null primary key,
            author_id integer not null references author(id) on delete cascade on update cascade,
            title text,
            date long,
            url text,
            body text
        )`,
        `create table tagmap (
            id integer not null primary key,
            tag_id integer not null references tag(id) on delete cascade on update cascade,
            post_id integer not null references post(id) on delete cascade on update cascade
        )`,
        `create table commenter (
            id integer not null primary key,
            name text,
            email text,
            www text,
            ip text
        )`,
        `create table comment (
            id integer not null primary key,
            commenter_id integer not null references commenter(id) on delete cascade on update cascade,
            post_id integer not null references post(id) on delete cascade on update cascade,
            timestamp long,
            body text
        )`,
    }
    os.Remove(fileName)

    db, err := sql.Open("sqlite3", fileName)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer db.Close()
    for _, sql := range createTables {
        _, err := db.Exec(sql)
        if err != nil {
            fmt.Printf("%q: %s\n", err, sql)
            return
        }
    }
    stmt, _ := db.Prepare("insert into author(id, disp_name, full_name, email, www) values(?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, "rtfb", "Vytautas Šaltenis", "vytas@rtfb.lt", "http://rtfb.lt")
}

func populate(fileName string) {
    db, err := sql.Open("sqlite3", fileName)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer db.Close()
    xaction, err := db.Begin()
    if err != nil {
        fmt.Println(err)
        return
    }
    stmt, _ := xaction.Prepare("insert into post(id, author_id, title, date, url, body) values(?, ?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, 1, "Labadėna", 123456, "labadena", "Nieko aš čia nerašysiu.")
    imgpost := `This is a post with a figure.

halfimage:

![hi][halfimg]

([Full size][fullimg])

[fullimg]: /no-dox.png
[halfimg]: /no-dox-halfsize.png`
    stmt.Exec(2, 1, "Iliustruotas", 1359308741, "iliustruotas", imgpost)
    stmt, _ = xaction.Prepare("insert into tag(id, name, url) values(?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, "Testas", "testas")
    stmt.Exec(2, "Žąsyčiai", "geese")
    stmt, _ = xaction.Prepare("insert into tagmap(id, tag_id, post_id) values(?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, 1, 1)
    stmt.Exec(2, 2, 1)
    stmt, _ = xaction.Prepare("insert into commenter(id, name, email, www, ip) values(?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, "Vytautas Šaltenis", "Vytautas.Shaltenis@gmail.com", "http://rtfb.lt", "127.0.0.1")
    stmt.Exec(2, "Vardenis Pavardenis", "niekas@niekur.com", "http://delfi.lt", "127.0.0.1")
    stmt, _ = xaction.Prepare("insert into comment(id, commenter_id, post_id, timestamp, body) values(?, ?, ?, ?, ?)")
    defer stmt.Close()
    stmt.Exec(1, 2, 1, 1356872181, "Nu ir nerašyk, _niekam_ čia neįdomu tavo pisulkos.")
    stmt.Exec(2, 1, 1, 1356879181, "O tu čia tada **nekomentuok** ten kur neparašyta nieko. Eik [ten](http://google.com/)")
    xaction.Commit()
}

func populate2(fileName string, data []*Entry) {
    db, err := sql.Open("sqlite3", fileName)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer db.Close()
    xaction, err := db.Begin()
    if err != nil {
        fmt.Println(err)
        return
    }
    for _, e := range data {
        stmt, _ := xaction.Prepare("insert into post(author_id, title, date, url, body) values(?, ?, ?, ?, ?)")
        defer stmt.Close()
        date, _ := time.Parse("2006-01-02", e.Date)
        result, _ := stmt.Exec(1, e.Title, date.Unix(), e.Url, e.Body)
        postId, _ := result.LastInsertId()
        for _, t := range e.Tags {
            stmt, _ = xaction.Prepare("insert into tag(name, url) values(?, ?)")
            defer stmt.Close()
            result, _ = stmt.Exec(t.TagName, t.TagUrl)
            tagId, _ := result.LastInsertId()
            stmt, _ = xaction.Prepare("insert into tagmap(tag_id, post_id) values(?, ?)")
            defer stmt.Close()
            stmt.Exec(tagId, postId)
        }
    }
    xaction.Commit()
}

type Tag struct {
    TagUrl  string
    TagName string
}

type Entry struct {
    Author string
    Title  string
    Date   string
    Body   string
    Url    string
    Tags   []*Tag
}

func parseTags(tagList string) (tags []*Tag) {
    for _, t := range strings.Split(tagList, ", ") {
        if t == "" {
            continue
        }
        tag := new(Tag)
        tag.TagUrl = strings.ToLower(t)
        tag.TagName = t
        tags = append(tags, tag)
    }
    return
}

func readTextEntry(filename string) (entry *Entry, err error) {
    f, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    msg, err := mail.ReadMessage(f)
    if err != nil {
        return nil, err
    }
    entry = new(Entry)
    entry.Title = msg.Header.Get("subject")
    entry.Author = msg.Header.Get("author")
    entry.Date = msg.Header.Get("isodate")
    entry.Tags = parseTags(msg.Header.Get("tags"))
    base := filepath.Base(filename)
    entry.Url = base[:strings.LastIndex(base, filepath.Ext(filename))]
    buf := new(bytes.Buffer)
    buf.ReadFrom(msg.Body)
    entry.Body = buf.String()
    return
}

func readTextEntries(root string) (entries []*Entry, err error) {
    filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
        if strings.ToLower(filepath.Ext(path)) != ".txt" {
            return nil
        }
        entry, _ := readTextEntry(path)
        if entry == nil {
            return nil
        }
        entries = append(entries, entry)
        return nil
    })
    return
}

func main() {
    db := flag.String("db", "", "<../path/to/file.db> (required)")
    srcData := flag.String("src", "", "Can be either a directory, or a path to DB dump configuration file (required)")
    migrateOnly := flag.Bool("notest", false, "Don't populate DB with test data, only migrate what's in -src. (optional)")
    flag.Usage = usage
    flag.Parse()
    if *db == "" || *srcData == "" {
        usage()
        return
    }
    if !strings.HasSuffix(*db, ".db") {
        fmt.Printf("File name is supposed to have a .db extension, but was %q\n", *db)
        usage()
        return
    }
    dbFile, _ := filepath.Abs(*db)
    init_db(dbFile)
    srcFile, err := os.Open(*srcData)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer srcFile.Close()
    fi, err := srcFile.Stat()
    if err != nil {
        fmt.Println(err)
        return
    }
    if fi.IsDir() {
        populate(dbFile)
        data, err := readTextEntries(*srcData)
        if err != nil {
            println(err.Error())
            return
        }
        populate2(dbFile, data)
    } else {
        if !*migrateOnly {
            populate(dbFile)
        }
        importLegacyDb(*db, *srcData)
    }
}
<|endoftext|>


<commit_before>package dominos

import (
	"errors"
	"log"
	"math/rand"
	"time"

	"github.com/kr/pretty"
)

func init() {
	rand.Seed(time.Now().Unix())
}

// Domino is a single tile with two sides. This is a game piece.
type Domino struct {
	Left, Right int // The values of each "side" of the domino.
}

// IsDouble checks if both of the tile values are the same.
func (d Domino) IsDouble() bool {
	return d.Left == d.Right
}

// IsPlayable returns true if d2 can be played on d1.
func (d Domino) IsPlayable(d2 Domino) bool {
	return d.Left == d2.Left ||
		d.Left == d2.Right ||
		d.Right == d2.Left ||
		d.Right == d2.Right
}

// Value returns how many "points" a tile is worth.
func (d Domino) Value() int {
	return d.Left + d.Right
}

// Game represents the total state for a single game
type Game struct {
	TilePool []Domino
	Trains   []*Path
	Players  []*Player
	Center   Domino

	UnresolvedDouble bool
	ActivePlayer     int
}

// Path represents a single player's path. If no player is set,
// the path is treated as the Mexican train.
type Path struct {
	Player   string
	Train    bool // If true, other players can play on it
	Elements []Element

	UnresolvedDouble bool
	MexicanTrain     bool
}

// Element is a wrapper for Domino that indicates if the Domino
// is flipped or not. This is for later UI implementation.
type Element struct {
	Domino
	Flipped bool
}

// NewGame creates a new game board out of a list of
// players.
func NewGame(players []string) *Game {
	g := &Game{
		Trains: make([]*Path, len(players)+1),
	}

	mexicanTrain := &Path{
		Train:        true,
		Player:       "",
		MexicanTrain: true,
	}
	g.Trains[len(players)] = mexicanTrain

	// Generate the pool of tiles for the game
	var doms []Domino
	for i := 0; i <= dominoCount(len(players)); i++ {
		for j := 0; j <= i; j++ {
			doms = append(doms, Domino{i, j})
		}
	}

	// Randomize the order of the tiles
	for _, i := range rand.Perm(len(doms)) {
		g.TilePool = append(g.TilePool, doms[i])
	}

	// How many times should be pre-populated into a player's hand
	hc := handCount(len(players))

	// Create player structures
	for i, p := range players {
		newPlayer := &Player{
			ID: p,
		}
		g.Players = append(g.Players, newPlayer)

		path := &Path{
			Player: p,
		}
		newPlayer.Path = path

		g.Trains[i] = path

		for i := 0; i <= hc; i++ {
			log.Println("drawing...")
			err := g.Draw(newPlayer)
			if err != nil {
				panic(err)
			}
		}
	}

	return g
}

// Player is a single player in the game
type Player struct {
	Hand    []Domino
	BigPlay bool
	Knocked bool
	ID      string
	Path    *Path
}

// Draw adds a single tile from the game's tile pool to a player's hand.
func (g *Game) Draw(p *Player) error {
	if len(g.TilePool) == 0 {
		return errors.New("no tiles left")
	}

	t := g.TilePool[0]
	g.TilePool = g.TilePool[1:]
	p.Hand = append(p.Hand, t)

	pretty.Println(t)

	return nil
}

// Place sets given Domino d from Player pl to the Path target if it fits.
func (g *Game) Place(pl *Player, d Domino, target *Path) bool {
	last := target.Elements[len(target.Elements)-1]
	if !last.IsPlayable(d) {
		return false // Given domino d is not playable on the given Path.
	}

	if target.Player != pl.ID && !target.Train && !target.MexicanTrain {
		return false // Cannot play on a train you don't own
	}

	e := Element{
		Domino:  d,
		Flipped: last.Left == d.Left || last.Right == d.Right,
	}

	target.Elements = append(target.Elements, e)

	return true
}

// Knock sets the knocked flag if a player has one tile left in their hand.
func (g *Game) Knock(p *Player) bool {
	if len(p.Hand) == 1 {
		p.Knocked = true
	}

	return p.Knocked
}

// NextTurn marks the next player as "up", adding two tiles to their hand if
// they only have one tile in their hand and haven't explicitly knocked.
func (g *Game) NextTurn() *Player {
	nextPlayer := (g.ActivePlayer + 1) % len(g.Players)
	p := g.Players[nextPlayer]

	if len(p.Hand) == 1 && !p.Knocked {
		g.Draw(p)
		g.Draw(p)
		p.Knocked = false
	}

	return p
}

func handCount(playernum int) int {
	switch playernum {
	case 2, 3, 4:
		return 10
	case 5, 6:
		return 9
	case 7, 8:
		return 7
	default:
		return 6
	}
}

func dominoCount(playernum int) int {
	switch playernum {
	case 1, 2:
		return 6
	case 3, 4:
		return 9
	case 5, 6, 7, 8:
		return 12
	case 9, 10, 11, 12:
		return 15
	default:
		return 18
	}
}
<commit_msg>remove this debugging code<commit_after>package dominos

import (
	"errors"
	"math/rand"
	"time"
)

func init() {
	rand.Seed(time.Now().Unix())
}

// Domino is a single tile with two sides. This is a game piece.
type Domino struct {
	Left, Right int // The values of each "side" of the domino.
}

// IsDouble checks if both of the tile values are the same.
func (d Domino) IsDouble() bool {
	return d.Left == d.Right
}

// IsPlayable returns true if d2 can be played on d1.
func (d Domino) IsPlayable(d2 Domino) bool {
	return d.Left == d2.Left ||
		d.Left == d2.Right ||
		d.Right == d2.Left ||
		d.Right == d2.Right
}

// Value returns how many "points" a tile is worth.
func (d Domino) Value() int {
	return d.Left + d.Right
}

// Game represents the total state for a single game
type Game struct {
	TilePool []Domino
	Trains   []*Path
	Players  []*Player
	Center   Domino

	UnresolvedDouble bool
	ActivePlayer     int
}

// Path represents a single player's path. If no player is set,
// the path is treated as the Mexican train.
type Path struct {
	Player   string
	Train    bool // If true, other players can play on it
	Elements []Element

	UnresolvedDouble bool
	MexicanTrain     bool
}

// Element is a wrapper for Domino that indicates if the Domino
// is flipped or not. This is for later UI implementation.
type Element struct {
	Domino
	Flipped bool
}

// NewGame creates a new game board out of a list of
// players.
func NewGame(players []string) *Game {
	g := &Game{
		Trains: make([]*Path, len(players)+1),
	}

	mexicanTrain := &Path{
		Train:        true,
		Player:       "",
		MexicanTrain: true,
	}
	g.Trains[len(players)] = mexicanTrain

	// Generate the pool of tiles for the game
	var doms []Domino
	for i := 0; i <= dominoCount(len(players)); i++ {
		for j := 0; j <= i; j++ {
			doms = append(doms, Domino{i, j})
		}
	}

	// Randomize the order of the tiles
	for _, i := range rand.Perm(len(doms)) {
		g.TilePool = append(g.TilePool, doms[i])
	}

	// How many times should be pre-populated into a player's hand
	hc := handCount(len(players))

	// Create player structures
	for i, p := range players {
		newPlayer := &Player{
			ID: p,
		}
		g.Players = append(g.Players, newPlayer)

		path := &Path{
			Player: p,
		}
		newPlayer.Path = path

		g.Trains[i] = path

		for i := 0; i <= hc; i++ {
			err := g.Draw(newPlayer)
			if err != nil {
				panic(err)
			}
		}
	}

	return g
}

// Player is a single player in the game
type Player struct {
	Hand    []Domino
	BigPlay bool
	Knocked bool
	ID      string
	Path    *Path
}

// Draw adds a single tile from the game's tile pool to a player's hand.
func (g *Game) Draw(p *Player) error {
	if len(g.TilePool) == 0 {
		return errors.New("no tiles left")
	}

	t := g.TilePool[0]
	g.TilePool = g.TilePool[1:]
	p.Hand = append(p.Hand, t)

	return nil
}

// Place sets given Domino d from Player pl to the Path target if it fits.
func (g *Game) Place(pl *Player, d Domino, target *Path) bool {
	last := target.Elements[len(target.Elements)-1]
	if !last.IsPlayable(d) {
		return false // Given domino d is not playable on the given Path.
	}

	if target.Player != pl.ID && !target.Train && !target.MexicanTrain {
		return false // Cannot play on a train you don't own
	}

	e := Element{
		Domino:  d,
		Flipped: last.Left == d.Left || last.Right == d.Right,
	}

	target.Elements = append(target.Elements, e)

	return true
}

// Knock sets the knocked flag if a player has one tile left in their hand.
func (g *Game) Knock(p *Player) bool {
	if len(p.Hand) == 1 {
		p.Knocked = true
	}

	return p.Knocked
}

// NextTurn marks the next player as "up", adding two tiles to their hand if
// they only have one tile in their hand and haven't explicitly knocked.
func (g *Game) NextTurn() *Player {
	nextPlayer := (g.ActivePlayer + 1) % len(g.Players)
	p := g.Players[nextPlayer]

	if len(p.Hand) == 1 && !p.Knocked {
		g.Draw(p)
		g.Draw(p)
		p.Knocked = false
	}

	return p
}

func handCount(playernum int) int {
	switch playernum {
	case 2:
		return 6
	case 3, 4:
		return 10
	case 5, 6:
		return 9
	case 7, 8:
		return 7
	default:
		return 6
	}
}

func dominoCount(playernum int) int {
	switch playernum {
	case 1, 2:
		return 6
	case 3, 4:
		return 9
	case 5, 6, 7, 8:
		return 12
	case 9, 10, 11, 12:
		return 15
	default:
		return 18
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors 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 version // import "k8s.io/helm/pkg/version"

import "k8s.io/helm/pkg/proto/hapi/version"

var (
	// Version is the current version of the Helm.
	// Update this whenever making a new release.
	// The version is of the format Major.Minor.Patch[-Prerelease][+BuildMetadata]
	//
	// Increment major number for new feature additions and behavioral changes.
	// Increment minor number for bug fixes and performance enhancements.
	// Increment patch number for critical fixes to existing releases.
	Version = "v2.3.x"

	// BuildMetadata is extra build time data
	BuildMetadata = "unreleased"
	// GitCommit is the git sha1
	GitCommit = ""
	// GitTreeState is the state of the git tree
	GitTreeState = ""
)

// GetVersion returns the semver string of the version
func GetVersion() string {
	if BuildMetadata == "" {
		return Version
	}
	return Version + "+" + BuildMetadata
}

// GetVersionProto returns protobuf representing the version
func GetVersionProto() *version.Version {
	return &version.Version{
		SemVer:       GetVersion(),
		GitCommit:    GitCommit,
		GitTreeState: GitTreeState,
	}
}
<commit_msg>fix(tiller): make new version check backwards compatible<commit_after>/*
Copyright 2016 The Kubernetes Authors 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 version // import "k8s.io/helm/pkg/version"

import "k8s.io/helm/pkg/proto/hapi/version"

var (
	// Version is the current version of the Helm.
	// Update this whenever making a new release.
	// The version is of the format Major.Minor.Patch[-Prerelease][+BuildMetadata]
	//
	// Increment major number for new feature additions and behavioral changes.
	// Increment minor number for bug fixes and performance enhancements.
	// Increment patch number for critical fixes to existing releases.
	Version = "v2.3"

	// BuildMetadata is extra build time data
	BuildMetadata = "unreleased"
	// GitCommit is the git sha1
	GitCommit = ""
	// GitTreeState is the state of the git tree
	GitTreeState = ""
)

// GetVersion returns the semver string of the version
func GetVersion() string {
	if BuildMetadata == "" {
		return Version
	}
	return Version + "+" + BuildMetadata
}

// GetVersionProto returns protobuf representing the version
func GetVersionProto() *version.Version {
	return &version.Version{
		SemVer:       GetVersion(),
		GitCommit:    GitCommit,
		GitTreeState: GitTreeState,
	}
}
<|endoftext|>


<commit_before>package gom

import (
	_ "github.com/go-sql-driver/mysql"
	"github.com/janyees/gom"
	"strings"
)

func init() {
	gom.Register("mysql", &MySqlFactory{})
}

type MySqlFactory struct {
}

func (MySqlFactory) Insert(model gom.TableModel) (string, []interface{}) {
	var datas []interface{}
	ccs := model.Columns
	sql := "insert into " + "`" + model.TableName + "` ("
	values := ""
	for i, v := range ccs {
		value := model.ModelValue.FieldByName(v.FieldName).Interface()
		if (!v.Auto) && value != nil {
			if i > 1 {
				sql += ","
				values += ","
			}
			datas = append(datas, value)
			values += " ? "
			sql += "`" + v.ColumnName + "`"
		}

	}
	sql += ") VALUES (" + values + ")"
	return sql, datas
}
func (fac MySqlFactory) Replace(model gom.TableModel) (string, []interface{}) {
	sql, datas := fac.Insert(model)
	sql = strings.Replace(sql, "insert", "replace", 0)
	return sql, datas
}
func (MySqlFactory) Delete(model gom.TableModel) (string, []interface{}) {
	sql := "delete from " + "`" + model.TableName + "` "
	if model.Cnd != nil {
		sql += " where " + model.Cnd.State() + ";"
		return sql, model.Cnd.Value()
	} else if model.GetPrimaryCondition() != nil {
		sql += " where " + model.GetPrimaryCondition().State() + " ;"
		return sql, model.GetPrimaryCondition().Value()
	} else {
		return sql + ";", []interface{}{}
	}

}
func (MySqlFactory) Update(model gom.TableModel) (string, []interface{}) {
	var datas []interface{}
	sql := "update " + "`" + model.TableName + "` set "
	for i, v := range model.Columns {
		value := model.ModelValue.FieldByName(v.FieldName).Interface()
		if (!v.Auto) && value != nil {
			if i > 1 {
				sql += ","
			}
			sql += "`" + v.ColumnName + "` = ? "
			datas = append(datas, value)
		}
	}
	if model.Cnd != nil {
		sql += " where " + model.Cnd.State() + ";"
		datas = append(datas, model.Cnd.Value()...)
	} else if model.GetPrimaryCondition() != nil {
		sql += " where " + model.GetPrimaryCondition().State() + ";"
		datas = append(datas, model.GetPrimaryCondition().Value()...)
	} else {
		sql += ";"
	}
	return sql, datas
}
func (MySqlFactory) Query(model gom.TableModel) (string, []interface{}) {
	sql := "select "
	for i, v := range model.Columns {
		if i > 0 {
			sql += ","
		}
		if v.QueryField == "" {
			sql += "`" + v.ColumnName + "`"
		} else {
			sql += v.QueryField
		}

	}
	sql += " from " + "`" + model.TableName + "`"
	if model.Cnd != nil {
		sql += " where " + model.Cnd.State() + ";"
		return sql, model.Cnd.Value()
	} else if model.GetPrimaryCondition() != nil {
		sql += " where " + model.GetPrimaryCondition().State() + ";"
		return sql, model.GetPrimaryCondition().Value()
	} else {
		return sql + ";", []interface{}{}
	}
}
<commit_msg>修复无法使用自定义对象的bug<commit_after>package gom

import (
	_ "github.com/go-sql-driver/mysql"
	"github.com/janyees/gom"
	"strings"
)

func init() {
	gom.Register("mysql", &MySqlFactory{})
}

type MySqlFactory struct {
}

func (MySqlFactory) Insert(model gom.TableModel) (string, []interface{}) {
	var datas []interface{}
	ccs := model.Columns
	sql := "insert into " + "`" + model.TableName + "` ("
	values := ""
	for i, v := range ccs {
		value := model.ModelValue.FieldByName(v.FieldName).Interface()
		if (!v.Auto) && value != nil {
			if i > 1 {
				sql += ","
				values += ","
			}
			datas = append(datas, value)
			values += " ? "
			sql += "`" + v.ColumnName + "`"
		}

	}
	sql += ") VALUES (" + values + ")"
	return sql, datas
}
func (fac MySqlFactory) Replace(model gom.TableModel) (string, []interface{}) {
	sql, datas := fac.Insert(model)
	sql = strings.Replace(sql, "insert", "replace", 0)
	return sql, datas
}
func (MySqlFactory) Delete(model gom.TableModel) (string, []interface{}) {
	sql := "delete from " + "`" + model.TableName + "` "
	if model.Cnd != nil {
		sql += " where " + model.Cnd.State() + ";"
		return sql, model.Cnd.Value()
	} else if model.GetPrimaryCondition() != nil {
		sql += " where " + model.GetPrimaryCondition().State() + " ;"
		return sql, model.GetPrimaryCondition().Value()
	} else {
		return sql + ";", []interface{}{}
	}

}
func (MySqlFactory) Update(model gom.TableModel) (string, []interface{}) {
	var datas []interface{}
	sql := "update " + "`" + model.TableName + "` set "
	for i, v := range model.Columns {
		value := model.ModelValue.FieldByName(v.FieldName).Interface()
		if (!v.Auto) && value != nil {
			if i > 1 {
				sql += ","
			}
			sql += "`" + v.ColumnName + "` = ? "
			datas = append(datas, value)
		}
	}
	if model.Cnd != nil {
		sql += " where " + model.Cnd.State() + ";"
		datas = append(datas, model.Cnd.Value()...)
	} else if model.GetPrimaryCondition() != nil {
		sql += " where " + model.GetPrimaryCondition().State() + ";"
		datas = append(datas, model.GetPrimaryCondition().Value()...)
	} else {
		sql += ";"
	}
	return sql, datas
}
func (MySqlFactory) Query(model gom.TableModel) (string, []interface{}) {
	sql := "select "
	for i, v := range model.Columns {
		if i > 0 {
			sql += ","
		}
		if v.QueryField == "" {
			sql += "`" + v.ColumnName + "`"
		} else {
			sql += v.QueryField
		}

	}
	sql += " from " + "`" + model.TableName + "`"
	if model.Cnd != nil {
		if model.Cnd.State() == "" {
			sql += " where " + model.Cnd.State() + ";"
		}
		return sql, model.Cnd.Value()
	} else if model.GetPrimaryCondition() != nil {
		sql += " where " + model.GetPrimaryCondition().State() + ";"
		return sql, model.GetPrimaryCondition().Value()
	} else {
		return sql + ";", []interface{}{}
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

func TestAccDataSourceAwsRegionsBasic(t *testing.T) {
	resourceName := "data.aws_regions.empty"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			{
				Config: testAccDataSourceAwsRegionsConfigEmpty(),
				Check: resource.ComposeTestCheckFunc(
					testAccDataSourceAwsRegionsCheck(resourceName),
					resource.TestCheckNoResourceAttr(resourceName, "all_regions"),
				),
			},
		},
	})
}

func TestAccDataSourceAwsRegionsOptIn(t *testing.T) {
	resourceName := "data.aws_regions.opt_in_status"

	statusOptedIn := "opted-in"
	statusNotOptedIn := "not-opted-in"
	statusOptInNotRequired := "opt-in-not-required"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			// This resource has to be at the very top of the test scenario due to bug in Terrafom Plugin SDK
			{
				Config: testAccDataSourceAwsRegionsConfigAllRegionsFiltered(statusOptedIn),
				Check: resource.ComposeTestCheckFunc(
					testAccDataSourceAwsRegionsCheck(resourceName),
					resource.TestCheckNoResourceAttr(resourceName, "all_regions"),
				),
			},
			{
				Config: testAccDataSourceAwsRegionsConfigAllRegionsFiltered(statusOptInNotRequired),
				Check: resource.ComposeTestCheckFunc(
					testAccDataSourceAwsRegionsCheck(resourceName),
					resource.TestCheckNoResourceAttr(resourceName, "all_regions"),
				),
			},
			{
				Config: testAccDataSourceAwsRegionsConfigAllRegionsFiltered(statusNotOptedIn),
				Check: resource.ComposeTestCheckFunc(
					testAccDataSourceAwsRegionsCheck(resourceName),
					resource.TestCheckNoResourceAttr(resourceName, "all_regions"),
				),
			},
		},
	})
}

func TestAccDataSourceAwsRegionsAllRegions(t *testing.T) {
	resourceAllRegions := "data.aws_regions.all_regions"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			{
				Config: testAccDataSourceAwsRegionsConfigAllRegions(),
				Check: resource.ComposeTestCheckFunc(
					testAccDataSourceAwsRegionsCheck(resourceAllRegions),
					resource.TestCheckResourceAttr(resourceAllRegions, "all_regions", "true"),
					resource.TestCheckNoResourceAttr(resourceAllRegions, "opt_in_status"),
				),
			},
		},
	})
}

func testAccDataSourceAwsRegionsCheck(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		_, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("root module has no resource called %s", name)
		}

		return nil
	}
}

func testAccDataSourceAwsRegionsConfigEmpty() string {
	return `
data "aws_regions" "empty" {}
`
}

func testAccDataSourceAwsRegionsConfigAllRegions() string {
	return `
data "aws_regions" "all_regions" {
	all_regions = "true"
}
`
}

func testAccDataSourceAwsRegionsConfigAllRegionsFiltered(filter string) string {
	return fmt.Sprintf(`
data "aws_regions" "opt_in_status" {
	filter {
       name   = "opt-in-status"
       values = ["%s"]
    }
}
`, filter)
}
<commit_msg>Change naming according to #9950<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

func TestAccDataSourceAwsRegions_Basic(t *testing.T) {
	resourceName := "data.aws_regions.empty"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			{
				Config: testAccDataSourceAwsRegionsConfig_empty(),
				Check: resource.ComposeTestCheckFunc(
					testAccDataSourceAwsRegionsCheck(resourceName),
					resource.TestCheckNoResourceAttr(resourceName, "all_regions"),
				),
			},
		},
	})
}

func TestAccDataSourceAwsRegions_OptIn(t *testing.T) {
	resourceName := "data.aws_regions.opt_in_status"

	statusOptedIn := "opted-in"
	statusNotOptedIn := "not-opted-in"
	statusOptInNotRequired := "opt-in-not-required"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			// This resource has to be at the very top of the test scenario due to bug in Terrafom Plugin SDK
			{
				Config: testAccDataSourceAwsRegionsConfig_allRegionsFiltered(statusOptedIn),
				Check: resource.ComposeTestCheckFunc(
					testAccDataSourceAwsRegionsCheck(resourceName),
					resource.TestCheckNoResourceAttr(resourceName, "all_regions"),
				),
			},
			{
				Config: testAccDataSourceAwsRegionsConfig_allRegionsFiltered(statusOptInNotRequired),
				Check: resource.ComposeTestCheckFunc(
					testAccDataSourceAwsRegionsCheck(resourceName),
					resource.TestCheckNoResourceAttr(resourceName, "all_regions"),
				),
			},
			{
				Config: testAccDataSourceAwsRegionsConfig_allRegionsFiltered(statusNotOptedIn),
				Check: resource.ComposeTestCheckFunc(
					testAccDataSourceAwsRegionsCheck(resourceName),
					resource.TestCheckNoResourceAttr(resourceName, "all_regions"),
				),
			},
		},
	})
}

func TestAccDataSourceAwsRegions_AllRegions(t *testing.T) {
	resourceAllRegions := "data.aws_regions.all_regions"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			{
				Config: testAccDataSourceAwsRegionsConfig_allRegions(),
				Check: resource.ComposeTestCheckFunc(
					testAccDataSourceAwsRegionsCheck(resourceAllRegions),
					resource.TestCheckResourceAttr(resourceAllRegions, "all_regions", "true"),
					resource.TestCheckNoResourceAttr(resourceAllRegions, "opt_in_status"),
				),
			},
		},
	})
}

func testAccDataSourceAwsRegionsCheck(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		_, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("root module has no resource called %s", name)
		}

		return nil
	}
}

func testAccDataSourceAwsRegionsConfig_empty() string {
	return `
data "aws_regions" "empty" {}
`
}

func testAccDataSourceAwsRegionsConfig_allRegions() string {
	return `
data "aws_regions" "all_regions" {
	all_regions = "true"
}
`
}

func testAccDataSourceAwsRegionsConfig_allRegionsFiltered(filter string) string {
	return fmt.Sprintf(`
data "aws_regions" "opt_in_status" {
	filter {
       name   = "opt-in-status"
       values = ["%s"]
    }
}
`, filter)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"regexp"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/sagemaker"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sagemaker/finder"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sagemaker/waiter"
)

func resourceAwsSagemakerImage() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsSagemakerImageCreate,
		Read:   resourceAwsSagemakerImageRead,
		Update: resourceAwsSagemakerImageUpdate,
		Delete: resourceAwsSagemakerImageDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"image_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
				ValidateFunc: validation.All(
					validation.StringLenBetween(1, 63),
					validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9](-*[a-zA-Z0-9])*$`), "Valid characters are a-z, A-Z, 0-9, and - (hyphen)."),
				),
			},
			"role_arn": {
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validateArn,
			},
			"display_name": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validation.StringLenBetween(1, 128),
			},
			"description": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validation.StringLenBetween(1, 512),
			},
			"tags": tagsSchema(),
		},
	}
}

func resourceAwsSagemakerImageCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	name := d.Get("image_name").(string)
	input := &sagemaker.CreateImageInput{
		ImageName: aws.String(name),
		RoleArn:   aws.String(d.Get("role_arn").(string)),
	}

	if v, ok := d.GetOk("display_name"); ok {
		input.DisplayName = aws.String(v.(string))
	}

	if v, ok := d.GetOk("description"); ok {
		input.Description = aws.String(v.(string))
	}

	if v, ok := d.GetOk("tags"); ok {
		input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().SagemakerTags()
	}

	log.Printf("[DEBUG] sagemaker Image create config: %#v", *input)
	_, err := conn.CreateImage(input)
	if err != nil {
		return fmt.Errorf("error creating SageMaker Image: %w", err)
	}

	d.SetId(name)

	if _, err := waiter.ImageCreated(conn, d.Id()); err != nil {
		return fmt.Errorf("error waiting for sagemaker image (%s) to create: %w", d.Id(), err)
	}

	return resourceAwsSagemakerImageRead(d, meta)
}

func resourceAwsSagemakerImageRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn
	ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

	image, err := finder.ImageByName(conn, d.Id())
	if err != nil {
		if isAWSErr(err, sagemaker.ErrCodeResourceNotFound, "No Image with the name") {
			d.SetId("")
			log.Printf("[WARN] Unable to find SageMaker Image (%s); removing from state", d.Id())
			return nil
		}
		return fmt.Errorf("error reading SageMaker Image (%s): %w", d.Id(), err)

	}

	arn := aws.StringValue(image.ImageArn)
	d.Set("image_name", image.ImageName)
	d.Set("arn", arn)
	d.Set("role_arn", image.RoleArn)
	d.Set("display_name", image.DisplayName)
	d.Set("description", image.Description)

	tags, err := keyvaluetags.SagemakerListTags(conn, arn)

	if err != nil {
		return fmt.Errorf("error listing tags for Sagemaker Image (%s): %w", d.Id(), err)
	}

	if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
		return fmt.Errorf("error setting tags: %w", err)
	}

	return nil
}

func resourceAwsSagemakerImageUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn
	needsUpdate := false

	input := &sagemaker.UpdateImageInput{
		ImageName: aws.String(d.Id()),
	}

	var deleteProperties []*string

	if d.HasChange("role_arn") {
		input.Description = aws.String(d.Get("role_arn").(string))
	}

	if d.HasChange("description") {
		if v, ok := d.GetOk("description"); ok {
			input.Description = aws.String(v.(string))
		} else {
			deleteProperties = append(deleteProperties, aws.String("Description"))
			input.DeleteProperties = deleteProperties
		}
		needsUpdate = true
	}

	if d.HasChange("display_name") {
		if v, ok := d.GetOk("display_name"); ok {
			input.DisplayName = aws.String(v.(string))
		} else {
			deleteProperties = append(deleteProperties, aws.String("DisplayName"))
			input.DeleteProperties = deleteProperties
		}
		needsUpdate = true
	}

	if needsUpdate {
		log.Printf("[DEBUG] sagemaker Image update config: %#v", *input)
		_, err := conn.UpdateImage(input)
		if err != nil {
			return fmt.Errorf("error updating SageMaker Image: %w", err)
		}

		if _, err := waiter.ImageCreated(conn, d.Id()); err != nil {
			return fmt.Errorf("error waiting for sagemaker image (%s) to update: %w", d.Id(), err)
		}
	}

	if d.HasChange("tags") {
		o, n := d.GetChange("tags")

		if err := keyvaluetags.SagemakerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
			return fmt.Errorf("error updating Sagemaker Image (%s) tags: %s", d.Id(), err)
		}
	}

	return resourceAwsSagemakerImageRead(d, meta)
}

func resourceAwsSagemakerImageDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	input := &sagemaker.DeleteImageInput{
		ImageName: aws.String(d.Id()),
	}

	if _, err := conn.DeleteImage(input); err != nil {
		if isAWSErr(err, sagemaker.ErrCodeResourceNotFound, "No Image with the name") {
			return nil
		}
		return fmt.Errorf("error deleting SageMaker Image (%s): %w", d.Id(), err)
	}

	if _, err := waiter.ImageDeleted(conn, d.Id()); err != nil {
		if isAWSErr(err, sagemaker.ErrCodeResourceNotFound, "No Image with the name") {
			return nil
		}
		return fmt.Errorf("error waiting for sagemaker image (%s) to delete: %w", d.Id(), err)

	}

	return nil
}
<commit_msg>Update aws/resource_aws_sagemaker_image.go<commit_after>package aws

import (
	"fmt"
	"log"
	"regexp"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/sagemaker"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sagemaker/finder"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sagemaker/waiter"
)

func resourceAwsSagemakerImage() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsSagemakerImageCreate,
		Read:   resourceAwsSagemakerImageRead,
		Update: resourceAwsSagemakerImageUpdate,
		Delete: resourceAwsSagemakerImageDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},

			"image_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
				ValidateFunc: validation.All(
					validation.StringLenBetween(1, 63),
					validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9](-*[a-zA-Z0-9])*$`), "Valid characters are a-z, A-Z, 0-9, and - (hyphen)."),
				),
			},
			"role_arn": {
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validateArn,
			},
			"display_name": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validation.StringLenBetween(1, 128),
			},
			"description": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validation.StringLenBetween(1, 512),
			},
			"tags": tagsSchema(),
		},
	}
}

func resourceAwsSagemakerImageCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	name := d.Get("image_name").(string)
	input := &sagemaker.CreateImageInput{
		ImageName: aws.String(name),
		RoleArn:   aws.String(d.Get("role_arn").(string)),
	}

	if v, ok := d.GetOk("display_name"); ok {
		input.DisplayName = aws.String(v.(string))
	}

	if v, ok := d.GetOk("description"); ok {
		input.Description = aws.String(v.(string))
	}

	if v, ok := d.GetOk("tags"); ok {
		input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().SagemakerTags()
	}

	log.Printf("[DEBUG] sagemaker Image create config: %#v", *input)
	_, err := conn.CreateImage(input)
	if err != nil {
		return fmt.Errorf("error creating SageMaker Image: %w", err)
	}

	d.SetId(name)

	if _, err := waiter.ImageCreated(conn, d.Id()); err != nil {
		return fmt.Errorf("error waiting for sagemaker image (%s) to create: %w", d.Id(), err)
	}

	return resourceAwsSagemakerImageRead(d, meta)
}

func resourceAwsSagemakerImageRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn
	ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

	image, err := finder.ImageByName(conn, d.Id())
	if err != nil {
		if isAWSErr(err, sagemaker.ErrCodeResourceNotFound, "No Image with the name") {
			d.SetId("")
			log.Printf("[WARN] Unable to find SageMaker Image (%s); removing from state", d.Id())
			return nil
		}
		return fmt.Errorf("error reading SageMaker Image (%s): %w", d.Id(), err)

	}

	arn := aws.StringValue(image.ImageArn)
	d.Set("image_name", image.ImageName)
	d.Set("arn", arn)
	d.Set("role_arn", image.RoleArn)
	d.Set("display_name", image.DisplayName)
	d.Set("description", image.Description)

	tags, err := keyvaluetags.SagemakerListTags(conn, arn)

	if err != nil {
		return fmt.Errorf("error listing tags for Sagemaker Image (%s): %w", d.Id(), err)
	}

	if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
		return fmt.Errorf("error setting tags: %w", err)
	}

	return nil
}

func resourceAwsSagemakerImageUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn
	needsUpdate := false

	input := &sagemaker.UpdateImageInput{
		ImageName: aws.String(d.Id()),
	}

	var deleteProperties []*string

	if d.HasChange("role_arn") {
		input.RoleArn= aws.String(d.Get("role_arn").(string))
	}

	if d.HasChange("description") {
		if v, ok := d.GetOk("description"); ok {
			input.Description = aws.String(v.(string))
		} else {
			deleteProperties = append(deleteProperties, aws.String("Description"))
			input.DeleteProperties = deleteProperties
		}
		needsUpdate = true
	}

	if d.HasChange("display_name") {
		if v, ok := d.GetOk("display_name"); ok {
			input.DisplayName = aws.String(v.(string))
		} else {
			deleteProperties = append(deleteProperties, aws.String("DisplayName"))
			input.DeleteProperties = deleteProperties
		}
		needsUpdate = true
	}

	if needsUpdate {
		log.Printf("[DEBUG] sagemaker Image update config: %#v", *input)
		_, err := conn.UpdateImage(input)
		if err != nil {
			return fmt.Errorf("error updating SageMaker Image: %w", err)
		}

		if _, err := waiter.ImageCreated(conn, d.Id()); err != nil {
			return fmt.Errorf("error waiting for sagemaker image (%s) to update: %w", d.Id(), err)
		}
	}

	if d.HasChange("tags") {
		o, n := d.GetChange("tags")

		if err := keyvaluetags.SagemakerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
			return fmt.Errorf("error updating Sagemaker Image (%s) tags: %s", d.Id(), err)
		}
	}

	return resourceAwsSagemakerImageRead(d, meta)
}

func resourceAwsSagemakerImageDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sagemakerconn

	input := &sagemaker.DeleteImageInput{
		ImageName: aws.String(d.Id()),
	}

	if _, err := conn.DeleteImage(input); err != nil {
		if isAWSErr(err, sagemaker.ErrCodeResourceNotFound, "No Image with the name") {
			return nil
		}
		return fmt.Errorf("error deleting SageMaker Image (%s): %w", d.Id(), err)
	}

	if _, err := waiter.ImageDeleted(conn, d.Id()); err != nil {
		if isAWSErr(err, sagemaker.ErrCodeResourceNotFound, "No Image with the name") {
			return nil
		}
		return fmt.Errorf("error waiting for sagemaker image (%s) to delete: %w", d.Id(), err)

	}

	return nil
}
<|endoftext|>