<commit_before>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// 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 piazza

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
)

//----------------------------------------------------------

type Ident string

const NoIdent Ident = ""

func (id Ident) String() string {
	return string(id)
}

//----------------------------------------------------------

type JsonString string

//----------------------------------------------------------

type JsonResponse struct {
	StatusCode int `json:"statusCode" binding:"required"`

	// only 2xxx -- Data is required
	Data       interface{}     `json:"data,omitempty" binding:"required"`
	Pagination *JsonPagination `json:"pagination,omitempty"` // optional

	// only 4xx and 5xx -- Message is required
	Message string        `json:"message,omitempty"`
	Origin  string        `json:"origin,omitempty"` // optional
	Inner   *JsonResponse `json:"inner,omitempty"`  // optional

	// optional
	Metadata interface{} `json:"metadata,omitempty"`
}

func (resp *JsonResponse) String() string {
	s := fmt.Sprintf("StatusCode: %d\nData: %#v\nMessage: %s",
		resp.StatusCode, resp.Data, resp.Message)
	return s
}

func (resp *JsonResponse) IsError() bool {
	return resp.StatusCode >= 400 && resp.StatusCode <= 599
}

func (resp *JsonResponse) ToError() error {
	if !resp.IsError() {
		return nil
	}
	return errors.New(resp.String())
}

func newJsonResponse500(err error) *JsonResponse {
	return &JsonResponse{StatusCode: http.StatusInternalServerError, Message: err.Error()}
}

//----------------------------------------------------------

// given an input which is some messy type like "map[string]interface{}",
// convert it to the given output type
func SuperConverter(input interface{}, output interface{}) error {
	raw, err := json.Marshal(input)
	if err != nil {
		return nil
	}

	err = json.Unmarshal(raw, output)
	if err != nil {
		return nil
	}

	return nil
}

//----------------------------------------------------------

func HttpGetJson(url string) *JsonResponse {
	output := &JsonResponse{}
	_, err := HttpJsonGetObject(url, output)
	if err != nil {
		return newJsonResponse500(err)
	}
	return output
}

func HttpPostJson(url string, input interface{}) *JsonResponse {
	output := &JsonResponse{}
	_, err := HttpJsonPostObject(url, input, output)
	if err != nil {
		return newJsonResponse500(err)
	}
	return output
}

func HttpPutJson(url string, input interface{}) *JsonResponse {
	output := &JsonResponse{}
	_, err := HttpJsonPutObject(url, input, output)
	if err != nil {
		return newJsonResponse500(err)
	}
	return output
}

func HttpDeleteJson(url string) *JsonResponse {
	code, err := HttpJsonDeleteObject(url)
	if err != nil {
		return newJsonResponse500(err)
	}
	return &JsonResponse{StatusCode: code}
}
<commit_msg>added JsonResponse.SetType (but not used yet); cleaned up some output<commit_after>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// 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 piazza

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
)

//----------------------------------------------------------

type Ident string

const NoIdent Ident = ""

func (id Ident) String() string {
	return string(id)
}

//----------------------------------------------------------

type JsonString string

//----------------------------------------------------------

type JsonResponse struct {
	StatusCode int `json:"statusCode" binding:"required"`

	// only 2xxx -- Data is required (and Type too)
	// Type is a string, taken from the Java model list
	Type       string          `json:"type,omitempty"`
	Data       interface{}     `json:"data,omitempty" binding:"required"`
	Pagination *JsonPagination `json:"pagination,omitempty"` // optional

	// only 4xx and 5xx -- Message is required
	Message string        `json:"message,omitempty"`
	Origin  string        `json:"origin,omitempty"` // optional
	Inner   *JsonResponse `json:"inner,omitempty"`  // optional

	// optional
	Metadata interface{} `json:"metadata,omitempty"`
}

//var JsonResponseDataTypes map[string]string = map[string]string{}

func (resp *JsonResponse) String() string {
	s := fmt.Sprintf("{StatusCode: %d, Data: %#v, Message: %s}",
		resp.StatusCode, resp.Data, resp.Message)
	return s
}

func (resp *JsonResponse) IsError() bool {
	return resp.StatusCode >= 400 && resp.StatusCode <= 599
}

func (resp *JsonResponse) ToError() error {
	if !resp.IsError() {
		return nil
	}
	s := fmt.Sprintf("{%d: %s}", resp.StatusCode, resp.Message)
	return errors.New(s)
}

func newJsonResponse500(err error) *JsonResponse {
	return &JsonResponse{StatusCode: http.StatusInternalServerError, Message: err.Error()}
}

/*
func (resp *JsonResponse) SetType() error {
	var nilInterface interface{}
	var nilInterfaceArray []interface{}
	if resp.Data == nil ||
		reflect.TypeOf(resp.Data) == reflect.TypeOf(nilInterface) ||
		reflect.TypeOf(resp.Data) == reflect.TypeOf(nilInterfaceArray) {
		resp.Type = ""
		return nil
	}

	goName := reflect.TypeOf(resp.Data).String()
	modelName, ok := JsonResponseDataTypes[goName]
	if !ok {
		s := fmt.Sprintf("Type %s is not a valid response type", goName)
		return errors.New(s)
	}
	resp.Type = modelName
	return nil
}
*/

//----------------------------------------------------------

// given an input which is some messy type like "map[string]interface{}",
// convert it to the given output type
func SuperConverter(input interface{}, output interface{}) error {
	raw, err := json.Marshal(input)
	if err != nil {
		return nil
	}

	err = json.Unmarshal(raw, output)
	if err != nil {
		return nil
	}

	return nil
}

//----------------------------------------------------------

func HttpGetJson(url string) *JsonResponse {
	output := &JsonResponse{}
	_, err := HttpJsonGetObject(url, output)
	if err != nil {
		return newJsonResponse500(err)
	}
	return output
}

func HttpPostJson(url string, input interface{}) *JsonResponse {
	output := &JsonResponse{}
	_, err := HttpJsonPostObject(url, input, output)
	if err != nil {
		return newJsonResponse500(err)
	}
	return output
}

func HttpPutJson(url string, input interface{}) *JsonResponse {
	output := &JsonResponse{}
	_, err := HttpJsonPutObject(url, input, output)
	if err != nil {
		return newJsonResponse500(err)
	}
	return output
}

func HttpDeleteJson(url string) *JsonResponse {
	code, err := HttpJsonDeleteObject(url)
	if err != nil {
		return newJsonResponse500(err)
	}
	return &JsonResponse{StatusCode: code}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"image"
	"image/jpeg"
	_ "image/png"
	"io/ioutil"
	"vip/fetch"
	"vip/test"

	. "gopkg.in/check.v1"
)

var (
	sizes = map[int]int{
		250:  333,
		500:  666,
		160:  213,
		720:  960,
		1024: 1365,
		683:  910,
		431:  574,
	}
	noExifSizes = map[int]int{
		250:  156,
		500:  312,
		160:  100,
		720:  450,
		1024: 640,
		683:  426,
		431:  269,
	}
)

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

type ResizeSuite struct{}

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

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

	storage = test.NewStore()
}

func (s *ResizeSuite) BenchmarkThumbnailResize(c *C) {
	file, err := ioutil.ReadFile("test/AWESOME.jpg")
	c.Assert(err, IsNil)

	ctx := &fetch.CacheContext{
		Width: 160,
	}

	for i := 0; i < c.N; i++ {
		// Need a new io.Reader on every iteration
		buf := bytes.NewReader(file)
		_, err := fetch.Resize(buf, ctx)
		c.Assert(err, IsNil)
	}
}

func (s *ResizeSuite) BenchmarkLargeResize(c *C) {
	file, err := ioutil.ReadFile("test/AWESOME.jpg")
	c.Assert(err, IsNil)

	ctx := &fetch.CacheContext{
		Width: 720,
	}

	for i := 0; i < c.N; i++ {
		// Need a new io.Reader on every iteration
		buf := bytes.NewReader(file)
		_, err := fetch.Resize(buf, ctx)
		c.Assert(err, IsNil)
	}
}

func (s *ResizeSuite) TestResizeImage(c *C) {
	file, err := ioutil.ReadFile("test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	for width, height := range sizes {
		ctx := &fetch.CacheContext{
			Width: width,
		}

		data := bytes.NewBuffer(file)

		orig, _, err := fetch.GetRotatedImage(data)
		c.Assert(err, IsNil)

		buf := new(bytes.Buffer)
		jpeg.Encode(buf, orig, nil)

		resized, err := fetch.Resize(buf, ctx)
		c.Assert(err, IsNil)

		image, _, err := image.Decode(resized)
		c.Assert(err, IsNil)
		c.Assert(image.Bounds().Size().X, Equals, width)
		c.Assert(image.Bounds().Size().Y, Equals, height)
	}
}

func (s *ResizeSuite) TestResizeNoExifImage(c *C) {
	file, err := ioutil.ReadFile("test/AWESOME.jpg")
	c.Assert(err, IsNil)

	for width, height := range noExifSizes {
		ctx := &fetch.CacheContext{
			Width: width,
		}

		buf := bytes.NewReader(file)
		resized, err := fetch.Resize(buf, ctx)
		c.Assert(err, IsNil)

		image, _, err := image.Decode(resized)
		c.Assert(err, IsNil)
		c.Assert(image.Bounds().Size().X, Equals, width)
		c.Assert(image.Bounds().Size().Y, Equals, height)
	}
}

func (s *ResizeSuite) insertMockImage() (*fetch.CacheContext, error) {
	file, err := ioutil.ReadFile("test/exif_test_img.jpg")
	if err != nil {
		return nil, err
	}

	data := bytes.NewBuffer(file)

	image, _, err := fetch.GetRotatedImage(data)
	if err != nil {
		return nil, err
	}

	buf := new(bytes.Buffer)
	jpeg.Encode(buf, image, nil)

	// Push the file data into the mock datastore
	storage.PutReader("test_bucket", "test_id", buf, int64(len(file)), "image/jpeg")

	return &fetch.CacheContext{
		ImageId: "test_id",
		Bucket:  "test_bucket",
	}, err
}

func (s *ResizeSuite) TestOriginalColdCache(c *C) {
	// Open the file once to get it's size
	file, err := ioutil.ReadFile("test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	img, _, err := image.Decode(bytes.NewReader(file))
	c.Assert(err, IsNil)

	// Since this image should be rotated, height should equal
	// width after it's uploaded.
	originalSize := img.Bounds().Size().Y

	// A single, unresized image is in the database/store
	ctx, err := s.insertMockImage()
	c.Assert(err, IsNil)

	// Run the image resize request
	data, err := fetch.ImageData(storage, ctx)
	c.Assert(err, IsNil)

	// Verify the size of the resulting byte slice
	img, _, err = image.Decode(bytes.NewReader(data))
	c.Assert(err, IsNil)
	c.Assert(img.Bounds().Size().X, Equals, originalSize)
}

func (s *ResizeSuite) TestResizeColdCache(c *C) {
	// A single, unresized image is in the database/store
	mockCtx, err := s.insertMockImage()
	c.Assert(err, IsNil)

	for width, height := range sizes {
		ctx := &fetch.CacheContext{
			ImageId: mockCtx.ImageId,
			Bucket:  mockCtx.Bucket,
			Width:   width,
		}

		// Run the image resize request
		data, err := fetch.ImageData(storage, ctx)
		c.Assert(err, IsNil)

		// Verify the size of the resulting byte slice
		img, _, err := image.Decode(bytes.NewReader(data))
		c.Assert(err, IsNil)
		c.Assert(img.Bounds().Size().X, Equals, width)
		c.Assert(img.Bounds().Size().Y, Equals, height)
	}
}

func (s *ResizeSuite) TestResizeCropColdCache(c *C) {
	// A single, unresized image is in the database/store
	mockCtx, err := s.insertMockImage()
	c.Assert(err, IsNil)

	for width, height := range sizes {
		ctx := &fetch.CacheContext{
			ImageId: mockCtx.ImageId,
			Bucket:  mockCtx.Bucket,
			Width:   width,
			Crop:    true,
		}

		// Run the image resize request
		data, err := fetch.ImageData(storage, ctx)
		c.Assert(err, IsNil)

		// Verify the size of the resulting byte slice
		img, _, err := image.Decode(bytes.NewReader(data))
		c.Assert(err, IsNil)
		c.Assert(img.Bounds().Size().X, Equals, img.Bounds().Size().Y)
		c.Assert(img.Bounds().Size().X > 0, Equals, true)
		c.Assert(img.Bounds().Size().X <= height, Equals, true)
	}
}
<commit_msg>Use Check vs Assert for tests in a loop.<commit_after>package main

import (
	"bytes"
	"image"
	"image/jpeg"
	_ "image/png"
	"io/ioutil"
	"vip/fetch"
	"vip/test"

	. "gopkg.in/check.v1"
)

var (
	sizes = map[int]int{
		250:  333,
		500:  666,
		160:  213,
		720:  960,
		1024: 1365,
		683:  910,
		431:  574,
	}
	noExifSizes = map[int]int{
		250:  156,
		500:  312,
		160:  100,
		720:  450,
		1024: 640,
		683:  426,
		431:  269,
	}
)

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

type ResizeSuite struct{}

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

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

	storage = test.NewStore()
}

func (s *ResizeSuite) BenchmarkThumbnailResize(c *C) {
	file, err := ioutil.ReadFile("test/AWESOME.jpg")
	c.Assert(err, IsNil)

	ctx := &fetch.CacheContext{
		Width: 160,
	}

	for i := 0; i < c.N; i++ {
		// Need a new io.Reader on every iteration
		buf := bytes.NewReader(file)
		_, err := fetch.Resize(buf, ctx)
		c.Assert(err, IsNil)
	}
}

func (s *ResizeSuite) BenchmarkLargeResize(c *C) {
	file, err := ioutil.ReadFile("test/AWESOME.jpg")
	c.Assert(err, IsNil)

	ctx := &fetch.CacheContext{
		Width: 720,
	}

	for i := 0; i < c.N; i++ {
		// Need a new io.Reader on every iteration
		buf := bytes.NewReader(file)
		_, err := fetch.Resize(buf, ctx)
		c.Assert(err, IsNil)
	}
}

func (s *ResizeSuite) TestResizeImage(c *C) {
	file, err := ioutil.ReadFile("test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	for width, height := range sizes {
		ctx := &fetch.CacheContext{
			Width: width,
		}

		data := bytes.NewBuffer(file)

		orig, _, err := fetch.GetRotatedImage(data)
		c.Check(err, IsNil)

		buf := new(bytes.Buffer)
		jpeg.Encode(buf, orig, nil)

		resized, err := fetch.Resize(buf, ctx)
		c.Check(err, IsNil)

		image, _, err := image.Decode(resized)
		c.Check(err, IsNil)
		c.Check(image.Bounds().Size().X, Equals, width)
		c.Check(image.Bounds().Size().Y, Equals, height)
	}
}

func (s *ResizeSuite) TestResizeNoExifImage(c *C) {
	file, err := ioutil.ReadFile("test/AWESOME.jpg")
	c.Assert(err, IsNil)

	for width, height := range noExifSizes {
		ctx := &fetch.CacheContext{
			Width: width,
		}

		buf := bytes.NewReader(file)
		resized, err := fetch.Resize(buf, ctx)
		c.Check(err, IsNil)

		image, _, err := image.Decode(resized)
		c.Check(err, IsNil)
		c.Check(image.Bounds().Size().X, Equals, width)
		c.Check(image.Bounds().Size().Y, Equals, height)
	}
}

func (s *ResizeSuite) insertMockImage() (*fetch.CacheContext, error) {
	file, err := ioutil.ReadFile("test/exif_test_img.jpg")
	if err != nil {
		return nil, err
	}

	data := bytes.NewBuffer(file)

	image, _, err := fetch.GetRotatedImage(data)
	if err != nil {
		return nil, err
	}

	buf := new(bytes.Buffer)
	jpeg.Encode(buf, image, nil)

	// Push the file data into the mock datastore
	storage.PutReader("test_bucket", "test_id", buf, int64(len(file)), "image/jpeg")

	return &fetch.CacheContext{
		ImageId: "test_id",
		Bucket:  "test_bucket",
	}, err
}

func (s *ResizeSuite) TestOriginalColdCache(c *C) {
	// Open the file once to get it's size
	file, err := ioutil.ReadFile("test/exif_test_img.jpg")
	c.Assert(err, IsNil)

	img, _, err := image.Decode(bytes.NewReader(file))
	c.Assert(err, IsNil)

	// Since this image should be rotated, height should equal
	// width after it's uploaded.
	originalSize := img.Bounds().Size().Y

	// A single, unresized image is in the database/store
	ctx, err := s.insertMockImage()
	c.Assert(err, IsNil)

	// Run the image resize request
	data, err := fetch.ImageData(storage, ctx)
	c.Assert(err, IsNil)

	// Verify the size of the resulting byte slice
	img, _, err = image.Decode(bytes.NewReader(data))
	c.Assert(err, IsNil)
	c.Assert(img.Bounds().Size().X, Equals, originalSize)
}

func (s *ResizeSuite) TestResizeColdCache(c *C) {
	// A single, unresized image is in the database/store
	mockCtx, err := s.insertMockImage()
	c.Assert(err, IsNil)

	for width, height := range sizes {
		ctx := &fetch.CacheContext{
			ImageId: mockCtx.ImageId,
			Bucket:  mockCtx.Bucket,
			Width:   width,
		}

		// Run the image resize request
		data, err := fetch.ImageData(storage, ctx)
		c.Assert(err, IsNil)

		// Verify the size of the resulting byte slice
		img, _, err := image.Decode(bytes.NewReader(data))
		c.Assert(err, IsNil)
		c.Assert(img.Bounds().Size().X, Equals, width)
		c.Assert(img.Bounds().Size().Y, Equals, height)
	}
}

func (s *ResizeSuite) TestResizeCropColdCache(c *C) {
	// A single, unresized image is in the database/store
	mockCtx, err := s.insertMockImage()
	c.Assert(err, IsNil)

	for width, height := range sizes {
		ctx := &fetch.CacheContext{
			ImageId: mockCtx.ImageId,
			Bucket:  mockCtx.Bucket,
			Width:   width,
			Crop:    true,
		}

		// Run the image resize request
		data, err := fetch.ImageData(storage, ctx)
		c.Assert(err, IsNil)

		// Verify the size of the resulting byte slice
		img, _, err := image.Decode(bytes.NewReader(data))
		c.Assert(err, IsNil)
		c.Assert(img.Bounds().Size().X, Equals, img.Bounds().Size().Y)
		c.Assert(img.Bounds().Size().X > 0, Equals, true)
		c.Assert(img.Bounds().Size().X <= height, Equals, true)
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 Benoît Amiaux. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package rez

import (
	"fmt"
	"image"
	"image/draw"
	_ "image/jpeg"
	"image/png"
	"math"
	"os"
	"reflect"
	"runtime"
	"testing"
)

type Tester interface {
	Fatalf(format string, args ...interface{})
}

func expect(t Tester, a, b interface{}) {
	if reflect.DeepEqual(a, b) {
		return
	}
	typea := reflect.TypeOf(a)
	typeb := reflect.TypeOf(b)
	_, file, line, _ := runtime.Caller(1)
	t.Fatalf("%v:%v got %v(%v), want %v(%v)\n", file, line,
		typea, a, typeb, b)
}

func readImage(t Tester, name string) image.Image {
	file, err := os.Open(name)
	expect(t, err, nil)
	defer file.Close()
	raw, _, err := image.Decode(file)
	expect(t, err, nil)
	return raw
}

func writeImage(t Tester, name string, img image.Image) {
	file, err := os.Create(name)
	expect(t, err, nil)
	defer file.Close()
	err = png.Encode(file, img)
	expect(t, err, nil)
}

func prepare(t Tester, dst, src image.Image, interlaced bool, filter Filter, threads int) Converter {
	cfg, err := PrepareConversion(dst, src)
	expect(t, err, nil)
	cfg.Input.Interlaced = interlaced
	cfg.Output.Interlaced = interlaced
	cfg.Threads = threads
	converter, err := NewConverter(cfg, filter)
	expect(t, err, nil)
	return converter
}

func convert(t Tester, dst, src image.Image, interlaced bool, filter Filter) {
	converter := prepare(t, dst, src, interlaced, filter, 0)
	err := converter.Convert(dst, src)
	expect(t, err, nil)
}

func convertFiles(t Tester, w, h int, input string, filter Filter, rgb bool) (image.Image, image.Image) {
	src := readImage(t, input)
	raw := image.NewYCbCr(image.Rect(0, 0, w*2, h*2), image.YCbCrSubsampleRatio420)
	dst := raw.SubImage(image.Rect(7, 7, 7+w, 7+h))
	if rgb {
		src = toRgb(src)
		dst = toRgb(dst)
	}
	err := Convert(dst, src, filter)
	expect(t, err, nil)
	return src, dst
}

var (
	filters = []Filter{
		NewBilinearFilter(),
		NewBicubicFilter(),
		NewLanczosFilter(3),
	}
)

func TestU8(t *testing.T) {
	expect(t, u8(-1), byte(0))
	expect(t, u8(0), byte(0))
	expect(t, u8(255), byte(255))
	expect(t, u8(256), byte(255))
}

func toRgb(src image.Image) *image.RGBA {
	b := src.Bounds()
	dst := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
	draw.Draw(dst, b, src, image.ZP, draw.Src)
	return dst
}

func testConvertWith(t *testing.T, rgb bool) {
	t.Skip("skipping slow test")
	sizes := []struct{ w, h int }{
		{128, 128},
		{256, 256},
		{720, 576},
		{1920, 1080},
	}
	suffix := "yuv"
	if rgb {
		suffix = "rgb"
	}
	for _, f := range filters {
		for _, s := range sizes {
			_, out := convertFiles(t, s.w, s.h, "testdata/lenna.jpg", f, rgb)
			dst := fmt.Sprintf("testdata/output-%vx%v-%v-%v.png", s.w, s.h, f.Name(), suffix)
			writeImage(t, dst, out)
		}
	}
}

func TestConvertYuv(t *testing.T) { testConvertWith(t, false) }
func TestConvertRgb(t *testing.T) { testConvertWith(t, true) }

type TestCase struct {
	file       string
	src        image.Rectangle
	dst        image.Rectangle
	rgb        bool
	interlaced bool
	filter     Filter
	threads    int
	psnrs      []float64
	psnrRect   image.Rectangle
	dump       string
}

func NewTestCase(w, h int, interlaced bool) *TestCase {
	return &TestCase{
		file:       "lenna.jpg",
		filter:     NewBicubicFilter(),
		interlaced: interlaced,
		dst:        image.Rect(0, 0, w, h),
	}
}

func runTestCase(t *testing.T, tc *TestCase, cycles int) {
	srcRaw := readImage(t, "testdata/"+tc.file).(*image.YCbCr)
	dstRaw := image.NewYCbCr(image.Rect(0, 0, tc.dst.Max.X*2, tc.dst.Max.Y*2), srcRaw.SubsampleRatio)
	var src, dst, ref image.Image
	if tc.src.Empty() {
		tc.src = srcRaw.Bounds()
	}
	suffix := "yuv"
	if tc.rgb {
		suffix = "rgb"
		src = toRgb(srcRaw).SubImage(tc.src)
		ref = toRgb(srcRaw).SubImage(tc.src)
		dst = toRgb(dstRaw).SubImage(tc.dst)
	} else {
		src = srcRaw.SubImage(tc.src)
		ref = readImage(t, "testdata/"+tc.file).(*image.YCbCr).SubImage(tc.src)
		dst = dstRaw.SubImage(tc.dst)
	}
	fwd := prepare(t, dst, src, tc.interlaced, tc.filter, tc.threads)
	bwd := prepare(t, src, dst, tc.interlaced, tc.filter, tc.threads)
	for i := 0; i < cycles; i++ {
		err := fwd.Convert(dst, src)
		expect(t, err, nil)
		err = bwd.Convert(src, dst)
		expect(t, err, nil)
	}
	if len(tc.psnrs) > 0 {
		var a, b image.Image
		a, b = ref, src
		if !tc.psnrRect.Empty() {
			if tc.rgb {
				a = a.(*image.RGBA).SubImage(tc.psnrRect)
				b = b.(*image.RGBA).SubImage(tc.psnrRect)
			} else {
				a = a.(*image.YCbCr).SubImage(tc.psnrRect)
				b = b.(*image.YCbCr).SubImage(tc.psnrRect)
			}
		}
		psnrs, err := Psnr(a, b)
		expect(t, err, nil)
		for i, v := range psnrs {
			if v < tc.psnrs[i] {
				t.Fatalf("invalid psnr %v < %v\n", v, tc.psnrs[i])
			}
		}
	}
	if len(tc.dump) > 0 {
		sb := src.Bounds()
		db := dst.Bounds()
		name := fmt.Sprintf("testdata/%v-%vx%v-%vx%v-%v-%v-%v.png",
			tc.dump, sb.Dx(), sb.Dy(), db.Dx(), db.Dy(), suffix,
			toInterlacedString(tc.interlaced), tc.filter.Name())
		writeImage(t, name, src)
	}
}

func TestCopy(t *testing.T) {
	tc := NewTestCase(512, 512, false)
	tc.psnrs = []float64{math.Inf(1), math.Inf(1), math.Inf(1)}
	runTestCase(t, tc, 1)
	tc = NewTestCase(512, 512, false)
	tc.rgb = true
	tc.psnrs = []float64{math.Inf(1)}
	runTestCase(t, tc, 1)
}

func testInterlacedFailWith(t *testing.T, rgb bool) {
	src := readImage(t, "testdata/lenna.jpg")
	dst := image.Image(image.NewYCbCr(image.Rect(0, 0, 640, 480), image.YCbCrSubsampleRatio420))
	if rgb {
		src = toRgb(src)
		dst = toRgb(dst)
	}
	convert(t, dst, src, true, NewBicubicFilter())
}

func TestInterlacedFail(t *testing.T) {
	testInterlacedFailWith(t, false)
	testInterlacedFailWith(t, true)
}

func TestDegradations(t *testing.T) {
	interlaced := []bool{false, true}
	rgb := []bool{false, true}
	for _, f := range filters {
		for _, ii := range interlaced {
			for _, rgb := range rgb {
				tc := NewTestCase(256+4, 256+4, ii)
				tc.filter = f
				tc.rgb = rgb
				runTestCase(t, tc, 32)
			}
		}
	}
}

func TestTooManyThreads(t *testing.T) {
	sizes := []struct{ w, h int }{{128, 16}, {16, 128}, {16, 16}}
	interlaced := []bool{false, true}
	for _, s := range sizes {
		for _, ii := range interlaced {
			tc := NewTestCase(s.w, s.h, ii)
			tc.threads = 32
			runTestCase(t, tc, 1)
		}
	}
}

func TestSaturatedRightBorder(t *testing.T) {
	tc := NewTestCase(171, 500, false)
	tc.file = "bug3img.jpg"
	tc.rgb = true
	tc.psnrs = []float64{16}
	tc.psnrRect = image.Rect(280, 0, 286, 500)
	runTestCase(t, tc, 1)
}
<commit_msg>Add missing psnr checks<commit_after>// Copyright 2013 Benoît Amiaux. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package rez

import (
	"fmt"
	"image"
	"image/draw"
	_ "image/jpeg"
	"image/png"
	"math"
	"os"
	"reflect"
	"runtime"
	"testing"
)

type Tester interface {
	Fatalf(format string, args ...interface{})
}

func expect(t Tester, a, b interface{}) {
	if reflect.DeepEqual(a, b) {
		return
	}
	typea := reflect.TypeOf(a)
	typeb := reflect.TypeOf(b)
	_, file, line, _ := runtime.Caller(1)
	t.Fatalf("%v:%v got %v(%v), want %v(%v)\n", file, line,
		typea, a, typeb, b)
}

func readImage(t Tester, name string) image.Image {
	file, err := os.Open(name)
	expect(t, err, nil)
	defer file.Close()
	raw, _, err := image.Decode(file)
	expect(t, err, nil)
	return raw
}

func writeImage(t Tester, name string, img image.Image) {
	file, err := os.Create(name)
	expect(t, err, nil)
	defer file.Close()
	err = png.Encode(file, img)
	expect(t, err, nil)
}

func prepare(t Tester, dst, src image.Image, interlaced bool, filter Filter, threads int) Converter {
	cfg, err := PrepareConversion(dst, src)
	expect(t, err, nil)
	cfg.Input.Interlaced = interlaced
	cfg.Output.Interlaced = interlaced
	cfg.Threads = threads
	converter, err := NewConverter(cfg, filter)
	expect(t, err, nil)
	return converter
}

func convert(t Tester, dst, src image.Image, interlaced bool, filter Filter) {
	converter := prepare(t, dst, src, interlaced, filter, 0)
	err := converter.Convert(dst, src)
	expect(t, err, nil)
}

func convertFiles(t Tester, w, h int, input string, filter Filter, rgb bool) (image.Image, image.Image) {
	src := readImage(t, input)
	raw := image.NewYCbCr(image.Rect(0, 0, w*2, h*2), image.YCbCrSubsampleRatio420)
	dst := raw.SubImage(image.Rect(7, 7, 7+w, 7+h))
	if rgb {
		src = toRgb(src)
		dst = toRgb(dst)
	}
	err := Convert(dst, src, filter)
	expect(t, err, nil)
	return src, dst
}

var (
	filters = []Filter{
		NewBilinearFilter(),
		NewBicubicFilter(),
		NewLanczosFilter(3),
	}
)

func TestU8(t *testing.T) {
	expect(t, u8(-1), byte(0))
	expect(t, u8(0), byte(0))
	expect(t, u8(255), byte(255))
	expect(t, u8(256), byte(255))
}

func toRgb(src image.Image) *image.RGBA {
	b := src.Bounds()
	dst := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
	draw.Draw(dst, b, src, image.ZP, draw.Src)
	return dst
}

func testConvertWith(t *testing.T, rgb bool) {
	t.Skip("skipping slow test")
	sizes := []struct{ w, h int }{
		{128, 128},
		{256, 256},
		{720, 576},
		{1920, 1080},
	}
	suffix := "yuv"
	if rgb {
		suffix = "rgb"
	}
	for _, f := range filters {
		for _, s := range sizes {
			_, out := convertFiles(t, s.w, s.h, "testdata/lenna.jpg", f, rgb)
			dst := fmt.Sprintf("testdata/output-%vx%v-%v-%v.png", s.w, s.h, f.Name(), suffix)
			writeImage(t, dst, out)
		}
	}
}

func TestConvertYuv(t *testing.T) { testConvertWith(t, false) }
func TestConvertRgb(t *testing.T) { testConvertWith(t, true) }

type TestCase struct {
	file       string
	src        image.Rectangle
	dst        image.Rectangle
	rgb        bool
	interlaced bool
	filter     Filter
	threads    int
	psnrs      []float64
	psnrRect   image.Rectangle
	dump       string
}

func NewTestCase(w, h int, interlaced bool) *TestCase {
	return &TestCase{
		file:       "lenna.jpg",
		filter:     NewBicubicFilter(),
		interlaced: interlaced,
		dst:        image.Rect(0, 0, w, h),
	}
}

func runTestCase(t *testing.T, tc *TestCase, cycles int) {
	srcRaw := readImage(t, "testdata/"+tc.file).(*image.YCbCr)
	dstRaw := image.NewYCbCr(image.Rect(0, 0, tc.dst.Max.X*2, tc.dst.Max.Y*2), srcRaw.SubsampleRatio)
	var src, dst, ref image.Image
	if tc.src.Empty() {
		tc.src = srcRaw.Bounds()
	}
	suffix := "yuv"
	if tc.rgb {
		suffix = "rgb"
		src = toRgb(srcRaw).SubImage(tc.src)
		ref = toRgb(srcRaw).SubImage(tc.src)
		dst = toRgb(dstRaw).SubImage(tc.dst)
	} else {
		src = srcRaw.SubImage(tc.src)
		ref = readImage(t, "testdata/"+tc.file).(*image.YCbCr).SubImage(tc.src)
		dst = dstRaw.SubImage(tc.dst)
	}
	fwd := prepare(t, dst, src, tc.interlaced, tc.filter, tc.threads)
	bwd := prepare(t, src, dst, tc.interlaced, tc.filter, tc.threads)
	for i := 0; i < cycles; i++ {
		err := fwd.Convert(dst, src)
		expect(t, err, nil)
		err = bwd.Convert(src, dst)
		expect(t, err, nil)
	}
	if len(tc.psnrs) > 0 {
		var a, b image.Image
		a, b = ref, src
		if !tc.psnrRect.Empty() {
			if tc.rgb {
				a = a.(*image.RGBA).SubImage(tc.psnrRect)
				b = b.(*image.RGBA).SubImage(tc.psnrRect)
			} else {
				a = a.(*image.YCbCr).SubImage(tc.psnrRect)
				b = b.(*image.YCbCr).SubImage(tc.psnrRect)
			}
		}
		psnrs, err := Psnr(a, b)
		expect(t, err, nil)
		for i, v := range psnrs {
			if v < tc.psnrs[i] {
				t.Fatalf("invalid psnr %v < %v\n", v, tc.psnrs[i])
			}
		}
	}
	if len(tc.dump) > 0 {
		sb := src.Bounds()
		db := dst.Bounds()
		name := fmt.Sprintf("testdata/%v-%vx%v-%vx%v-%v-%v-%v.png",
			tc.dump, sb.Dx(), sb.Dy(), db.Dx(), db.Dy(), suffix,
			toInterlacedString(tc.interlaced), tc.filter.Name())
		writeImage(t, name, src)
	}
}

func TestCopy(t *testing.T) {
	tc := NewTestCase(512, 512, false)
	tc.psnrs = []float64{math.Inf(1), math.Inf(1), math.Inf(1)}
	runTestCase(t, tc, 1)
	tc = NewTestCase(512, 512, false)
	tc.rgb = true
	tc.psnrs = []float64{math.Inf(1)}
	runTestCase(t, tc, 1)
}

func testInterlacedFailWith(t *testing.T, rgb bool) {
	src := readImage(t, "testdata/lenna.jpg")
	dst := image.Image(image.NewYCbCr(image.Rect(0, 0, 640, 480), image.YCbCrSubsampleRatio420))
	if rgb {
		src = toRgb(src)
		dst = toRgb(dst)
	}
	convert(t, dst, src, true, NewBicubicFilter())
}

func TestInterlacedFail(t *testing.T) {
	testInterlacedFailWith(t, false)
	testInterlacedFailWith(t, true)
}

func TestDegradations(t *testing.T) {
	interlaced := []bool{false, true}
	rgb := []bool{false, true}
	for _, f := range filters {
		for _, ii := range interlaced {
			for _, rgb := range rgb {
				tc := NewTestCase(256+4, 256+4, ii)
				tc.filter = f
				tc.rgb = rgb
				tc.psnrs = []float64{22, 35, 35}
				runTestCase(t, tc, 32)
			}
		}
	}
}

func TestTooManyThreads(t *testing.T) {
	sizes := []struct{ w, h int }{{128, 16}, {16, 128}, {16, 16}}
	interlaced := []bool{false, true}
	for _, s := range sizes {
		for _, ii := range interlaced {
			tc := NewTestCase(s.w, s.h, ii)
			tc.threads = 32
			runTestCase(t, tc, 1)
		}
	}
}

func TestSaturatedRightBorder(t *testing.T) {
	tc := NewTestCase(171, 500, false)
	tc.file = "bug3img.jpg"
	tc.rgb = true
	tc.psnrs = []float64{16}
	tc.psnrRect = image.Rect(280, 0, 286, 500)
	runTestCase(t, tc, 1)
}
<|endoftext|>


<commit_before>package base

import (
	"gopkg.in/mgo.v2/bson"
	"encoding/json"
	"time"

	"mr/app/models"
)

func NewProduct(account_id, token string, jsonStr []byte) (string, int) {

	/* Función que recibe los valores de nickname como string, y como JSON del producto nuevo que se insertará en la BD */

	if CheckToken(token) == false {
		return "token no válido", 401   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false{
		return "Usuario no encontrado", 403		//Verifica que el account_id exista en la base de datos
	}

	productVals := &models.Product{}
	json.Unmarshal(jsonStr, productVals)
	productVals.Deleted = 0 	// False indica que el producto no ha sido borrado del almacén

	if ProductExists(productVals.N_serial , account_id) == true {
		return "El número de serial del producto ya existe",400
	}

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    colQuerier := bson.M{"_id": bson.ObjectIdHex(account_id)}  // Busca el documento por nickname
	change := bson.M{"$push": bson.M{"products": productVals} } // Inserta en el array de productos
	err = con.Update(colQuerier, change)

	if err != nil {
		return "Usuario no encontrado", 400
	}

	return "Producto agregado en el almacén", 201

}

func ProductExists(serial, account_id string) bool {

	/* Función que verifica si existe el número de serial del producto en la base de datos */

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return false
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    type Result struct{
    	Products []models.Product `json:"products"`
    }

    result := Result{}
    err = con.Find(bson.M{"_id": bson.ObjectIdHex(account_id), "products.n_serial": serial}).Select(bson.M{"products.n_serial": 1, "_id": 0}).One(&result)

    if err != nil{
    	return false
    } else{
    	return true
    }
}

func UpdateProductAmount(account_id, n_serial string, token string, jsonStr []byte) (string, int) {

	/* Función que recibe los valores de ACCOUNT_ID como string, y como JSON la nueva cantidad del producto con n_serial */

	if CheckToken(token) == false {
		return "token no válido", 401   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false{
		return "Usuario no encontrado", 403		//Verifica que el account_id exista en la base de datos
	}

	productVals := &models.Product{}
	json.Unmarshal(jsonStr, productVals)

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    colQuerier := bson.M{"_id": bson.ObjectIdHex(account_id), "products.n_serial": n_serial}  // Busca el documento por ACCOUNT_ID
	change := bson.M{"$set": bson.M{"products.$.quantity": productVals.Quantity} } // Inserta en el array de productos
	err = con.Update(colQuerier, change)

	if err != nil {
		return "Producto no encontrado", 400
	}

	return "Cantidad de productos actualizada", 200

}

func UpdateProduct(account_id, n_serial string, token string, jsonStr []byte) (string, int){

	/* Función que actualiza un producto para un usuario en la base de datos
		Se reciben el id de usuario y el número de serie unico del producto */

	if CheckToken(token) == false {
		return "token no válido", 401   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false{
		return "Usuario no encontrado", 403		//Verifica que el account_id exista en la base de datos
	}

	productVals := &models.Product{}
	json.Unmarshal(jsonStr, productVals)

	if ProductExists(productVals.N_serial , account_id) == true {
		return "El número de serial del producto ya existe",400
	}

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    productVals.Deleted = 0  // Previene que se pueda actualizar el punto de restauración
    colQuerier := bson.M{"_id": bson.ObjectIdHex(account_id), "products.n_serial": n_serial}  // Busca el documento por ACCOUNT_ID
	change := bson.M{"$set": bson.M{"products.$": productVals} } // Inserta en el array de productos
	err = con.Update(colQuerier, change)

	if err != nil {
		return "Producto no encontrado", 400
	}

	return "Datos de producto actualizados", 200

}

func EraseProduct(account_id, n_serial string, token string) (string, int){

	/* Función que elmina un producto del usuario recibido de la base de datos
		se recibe el id de usuario y el numero de serie unico del producto */

	if CheckToken(token) == false {
		return "token no válido", 401   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false{
		return "Usuario no encontrado", 403		//Verifica que el account_id exista en la base de datos
	}

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    colQuerier := bson.M{"_id": bson.ObjectIdHex(account_id)}  // Busca el documento por ACCOUNT_ID
	change := bson.M{"$pull": bson.M{"products": bson.M{"n_serial":n_serial } } } // Elimina en el array de productos en base al número de serial
	err = con.Update(colQuerier, change)

	if err != nil {
		return "Producto no encontrado", 400
	}

	return "Producto eliminado totalmente de la base de datos", 200

}

func SaveDeletedProduct(account_id, n_serial string, token string) (string, int){

	/* Función que actualiza un producto del usuario recibido de la base de datos para que se permita restaurar antes de ser eliminado
		se recibe el id de usuario y el numero de serie unico del producto  */

	if CheckToken(token) == false {
		return "token no válido", 401   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false{
		return "Usuario no encontrado", 403		//Verifica que el account_id exista en la base de datos
	}

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    colQuerier := bson.M{"_id": bson.ObjectIdHex(account_id) , "products.n_serial": n_serial }  // Busca el documento por ACCOUNT_ID
	change := bson.M{"$set": bson.M{"products.$.deleted": int(time.Now().Unix())  } } // El campo deleted se actualiza con el tiempo unix actual
	err = con.Update(colQuerier, change)

	if err != nil {
		return "Producto no encontrado", 400
	}

	return "Producto eliminado", 200

}

func GetProducts(all bool, account_id string, token, n_serial string) (string, int, interface{}) {

	/* 	Función que busca en la base de datos uno o más productos
		"all" es un valor booleano que indica si se quieren todos los productos o uno en específico
		Recibe también los valores de id de la cuenta y el numero de serial del producto en caso de que se requiera
	*/

	data := make(map[string]interface{})

	if CheckToken(token) == false {
		return "token no válido", 401, data   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false {
		return "Usuario no encontrado", 403, data		//Verifica que el account_id exista en la base de datos
	}

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500, data
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    type Result struct{
    	Products 	[]models.Product 	`json:"products"`
    }

    result := Result{}

    if all == false {  // Si está desactivada la opción de todos los productos buscará uno en específico de acuerdo al n_serial indicado
    	err = con.Find(bson.M{"_id": bson.ObjectIdHex(account_id)}).Select(bson.M{"products": bson.M{"$elemMatch": bson.M{"n_serial":n_serial, "deleted": 0} }, "_id":0 }).One(&result)
    } else{
    	err = con.Find(bson.M{"_id": bson.ObjectIdHex(account_id)}).Select(bson.M{"products": bson.M{"$elemMatch": bson.M{"deleted": 0 } }, "_id":0 }).One(&result)
    }

    if err != nil  {
    	return "No se encontró el producto", 400, data
    }

	data["producto"] = result.Products
	productsFind := len(result.Products) // Cantidad de productos encontrados

	if productsFind == 0 {
		if all == true {
			return "No hay productos en el inventario", 206, data["producto"]  // Si realiza una búsqueda de todos los productos retorna exito pero con el array vacío
		} else {
			return "Producto no encontrado", 400, data["producto"]				// Si es una búsqueda de un solo producto retorna error al no ser encontrado
		}
	} else if productsFind == 1 {
		return "Producto encontrado", 200, data["producto"]			// Si hay un solo producto
	} else {
		return "Productos encontrados", 200, data["producto"]		// Si hay dos o más productos
	}

}<commit_msg>Optimización: Se recive la mgo.Session al verificar existencia de producto<commit_after>package base

import (
	"gopkg.in/mgo.v2/bson"
	"gopkg.in/mgo.v2"
	"encoding/json"
	"time"

	"mr/app/models"
)

func NewProduct(account_id, token string, jsonStr []byte) (string, int) {

	/* Función que recibe los valores de nickname como string, y como JSON del producto nuevo que se insertará en la BD */

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500
    }
    defer session.Close()

	if CheckToken(token) == false {
		return "token no válido", 401   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false{
		return "Usuario no encontrado", 403		//Verifica que el account_id exista en la base de datos
	}

	productVals := &models.Product{}
	json.Unmarshal(jsonStr, productVals)
	productVals.Deleted = 0 	// False indica que el producto no ha sido borrado del almacén

	if ProductExists(productVals.N_serial , account_id, session) == true {
		return "El número de serial del producto ya existe",400
	}

    con := session.DB(NameDB).C(CollectionDB)

    colQuerier := bson.M{"_id": bson.ObjectIdHex(account_id)}  // Busca el documento por nickname
	change := bson.M{"$push": bson.M{"products": productVals} } // Inserta en el array de productos
	err = con.Update(colQuerier, change)

	if err != nil {
		return "Usuario no encontrado", 400
	}

	return "Producto agregado en el almacén", 201

}

func ProductExists(serial, account_id string, session *mgo.Session) bool {

	/* Función que verifica si existe el número de serial del producto en la base de datos */

    con := session.DB(NameDB).C(CollectionDB)

    type Result struct{
    	Products []models.Product `json:"products"`
    }

    result := Result{}
    err := con.Find(bson.M{"_id": bson.ObjectIdHex(account_id), "products.n_serial": serial}).Select(bson.M{"products.n_serial": 1, "_id": 0}).One(&result)

    if err != nil{
    	return false
    } else{
    	return true
    }
}

func UpdateProductAmount(account_id, n_serial string, token string, jsonStr []byte) (string, int) {

	/* Función que recibe los valores de ACCOUNT_ID como string, y como JSON la nueva cantidad del producto con n_serial */

	if CheckToken(token) == false {
		return "token no válido", 401   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false{
		return "Usuario no encontrado", 403		//Verifica que el account_id exista en la base de datos
	}

	productVals := &models.Product{}
	json.Unmarshal(jsonStr, productVals)

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    colQuerier := bson.M{"_id": bson.ObjectIdHex(account_id), "products.n_serial": n_serial}  // Busca el documento por ACCOUNT_ID
	change := bson.M{"$set": bson.M{"products.$.quantity": productVals.Quantity} } // Inserta en el array de productos
	err = con.Update(colQuerier, change)

	if err != nil {
		return "Producto no encontrado", 400
	}

	return "Cantidad de productos actualizada", 200

}

func UpdateProduct(account_id, n_serial string, token string, jsonStr []byte) (string, int){

	/* Función que actualiza un producto para un usuario en la base de datos
		Se reciben el id de usuario y el número de serie unico del producto */

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500
    }
    defer session.Close()

	if CheckToken(token) == false {
		return "token no válido", 401   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false{
		return "Usuario no encontrado", 403		//Verifica que el account_id exista en la base de datos
	}

	productVals := &models.Product{}
	json.Unmarshal(jsonStr, productVals)

	if ProductExists(productVals.N_serial , account_id, session) == true {
		return "El número de serial del producto ya existe",400
	}

    con := session.DB(NameDB).C(CollectionDB)

    productVals.Deleted = 0  // Previene que se pueda actualizar el punto de restauración
    colQuerier := bson.M{"_id": bson.ObjectIdHex(account_id), "products.n_serial": n_serial}  // Busca el documento por ACCOUNT_ID
	change := bson.M{"$set": bson.M{"products.$": productVals} } // Inserta en el array de productos
	err = con.Update(colQuerier, change)

	if err != nil {
		return "Producto no encontrado", 400
	}

	return "Datos de producto actualizados", 200

}

func EraseProduct(account_id, n_serial string, token string) (string, int){

	/* Función que elmina un producto del usuario recibido de la base de datos
		se recibe el id de usuario y el numero de serie unico del producto */

	if CheckToken(token) == false {
		return "token no válido", 401   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false{
		return "Usuario no encontrado", 403		//Verifica que el account_id exista en la base de datos
	}

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    colQuerier := bson.M{"_id": bson.ObjectIdHex(account_id)}  // Busca el documento por ACCOUNT_ID
	change := bson.M{"$pull": bson.M{"products": bson.M{"n_serial":n_serial } } } // Elimina en el array de productos en base al número de serial
	err = con.Update(colQuerier, change)

	if err != nil {
		return "Producto no encontrado", 400
	}

	return "Producto eliminado totalmente de la base de datos", 200

}

func SaveDeletedProduct(account_id, n_serial string, token string) (string, int){

	/* Función que actualiza un producto del usuario recibido de la base de datos para que se permita restaurar antes de ser eliminado
		se recibe el id de usuario y el numero de serie unico del producto  */

	if CheckToken(token) == false {
		return "token no válido", 401   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false{
		return "Usuario no encontrado", 403		//Verifica que el account_id exista en la base de datos
	}

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    colQuerier := bson.M{"_id": bson.ObjectIdHex(account_id) , "products.n_serial": n_serial }  // Busca el documento por ACCOUNT_ID
	change := bson.M{"$set": bson.M{"products.$.deleted": int(time.Now().Unix())  } } // El campo deleted se actualiza con el tiempo unix actual
	err = con.Update(colQuerier, change)

	if err != nil {
		return "Producto no encontrado", 400
	}

	return "Producto eliminado", 200

}

func GetProducts(all bool, account_id string, token, n_serial string) (string, int, interface{}) {

	/* 	Función que busca en la base de datos uno o más productos
		"all" es un valor booleano que indica si se quieren todos los productos o uno en específico
		Recibe también los valores de id de la cuenta y el numero de serial del producto en caso de que se requiera
	*/

	data := make(map[string]interface{})

	if CheckToken(token) == false {
		return "token no válido", 401, data   // Verifica que sea un token válido
	} else if UserExists("_id", account_id) == false {
		return "Usuario no encontrado", 403, data		//Verifica que el account_id exista en la base de datos
	}

	session, err := Connect() // Conecta a la base de datos
	if err != nil {
		return "No se ha conectado a la base de datos", 500, data
    }
    defer session.Close()

    con := session.DB(NameDB).C(CollectionDB)

    type Result struct{
    	Products 	[]models.Product 	`json:"products"`
    }

    result := Result{}

    if all == false {  // Si está desactivada la opción de todos los productos buscará uno en específico de acuerdo al n_serial indicado
    	err = con.Find(bson.M{"_id": bson.ObjectIdHex(account_id)}).Select(bson.M{"products": bson.M{"$elemMatch": bson.M{"n_serial":n_serial, "deleted": 0} }, "_id":0 }).One(&result)
    } else{
    	err = con.Find(bson.M{"_id": bson.ObjectIdHex(account_id)}).Select(bson.M{"products": bson.M{"$elemMatch": bson.M{"deleted": 0 } }, "_id":0 }).One(&result)
    }

    if err != nil  {
    	return "No se encontró el producto", 400, data
    }

	data["producto"] = result.Products
	productsFind := len(result.Products) // Cantidad de productos encontrados

	if productsFind == 0 {
		if all == true {
			return "No hay productos en el inventario", 206, data["producto"]  // Si realiza una búsqueda de todos los productos retorna exito pero con el array vacío
		} else {
			return "Producto no encontrado", 400, data["producto"]				// Si es una búsqueda de un solo producto retorna error al no ser encontrado
		}
	} else if productsFind == 1 {
		return "Producto encontrado", 200, data["producto"]			// Si hay un solo producto
	} else {
		return "Productos encontrados", 200, data["producto"]		// Si hay dos o más productos
	}

}<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

const httpPrefix = "http://"

var (
	urls strslice
	body bool
	code bool
)

type strslice []string

func (s *strslice) String() string {
	return fmt.Sprintf("%s", *s)
}

func (s *strslice) Set(value string) error {
	*s = append(*s, value)
	return nil
}

func fetchURL(w io.Writer, url string, body bool, code bool) error {

	if !strings.HasPrefix(url, httpPrefix) {
		url = httpPrefix + url
	}

	resp, err := http.Get(url)

	if err != nil {
		fmt.Fprintf(os.Stderr, "error getting %s: %v\n", url, err)
		return err
	}
	defer resp.Body.Close()

	if code {
		fmt.Printf("%3d %s\n", resp.StatusCode, url)
	}

	if body {
		_, err = io.Copy(w, resp.Body)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error copying body of '%s': %v\n", url, err)
			return err
		}
	}
	return nil
}

func fetch() {
	if len(urls) == 0 {
		fmt.Fprintln(os.Stderr, "error: no urls are spcified")
		os.Exit(1)
	}

	for _, url := range urls {
		fetchURL(os.Stdin, url, body, code)
	}
}

func init() {
	flag.Var(&urls, "url", "url to fetch, multiple allowed")
	flag.BoolVar(&body, "body", false, "print responce body")
	flag.BoolVar(&code, "code", true, "print responce statuc code for url")
}

func main() {
	flag.Parse()
	fetch()
}
<commit_msg>Added questes for url in fetch.<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

const httpPrefix = "http://"

var (
	urls strslice
	body bool
	code bool
)

type strslice []string

func (s *strslice) String() string {
	return fmt.Sprintf("%s", *s)
}

func (s *strslice) Set(value string) error {
	*s = append(*s, value)
	return nil
}

func fetchURL(w io.Writer, url string, body bool, code bool) error {

	if !strings.HasPrefix(url, httpPrefix) {
		url = httpPrefix + url
	}

	resp, err := http.Get(url)

	if err != nil {
		fmt.Fprintf(os.Stderr, "error getting '%s': %v\n", url, err)
		return err
	}
	defer resp.Body.Close()

	if code {
		fmt.Printf("%3d %s\n", resp.StatusCode, url)
	}

	if body {
		_, err = io.Copy(w, resp.Body)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error copying body of '%s': %v\n", url, err)
			return err
		}
	}
	return nil
}

func fetch() {
	if len(urls) == 0 {
		fmt.Fprintln(os.Stderr, "error: no urls are spcified")
		os.Exit(1)
	}

	for _, url := range urls {
		fetchURL(os.Stdin, url, body, code)
	}
}

func init() {
	flag.Var(&urls, "url", "url to fetch, multiple allowed")
	flag.BoolVar(&body, "body", false, "print responce body")
	flag.BoolVar(&code, "code", true, "print responce statuc code for url")
}

func main() {
	flag.Parse()
	fetch()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os/exec"
	"path/filepath"
	"strings"
)

var binaryPath string

func init() {
	var err error
	binaryPath, err = exec.LookPath("go")
	if err != nil {
		log.Fatal(err)
	}
}

type properties struct {
	Name       string
	ImportPath string
	Deps       []string
}

func getProperties(name string) (*properties, error) {
	out, err := exec.Command(binaryPath, "list", "-json", name).Output()
	if err != nil {
		return nil, err
	}
	var p properties
	if err := json.Unmarshal(out, &p); err != nil {
		return nil, err
	}
	return &p, nil
}

func getPackages(workspace string) ([]string, error) {
	dir := filepath.Join(workspace, "...")
	out, err := exec.Command(binaryPath, "list", dir).Output()
	if err != nil {
		return nil, err
	}
	return strings.Split(string(out), "\n"), nil
}

func getDependencies(name string) (map[string]bool, error) {
	out, err := exec.Command(binaryPath, "list", "-json", name).Output()
	if err != nil {
		return nil, err
	}
	var p struct{ Deps []string }
	if err := json.Unmarshal(out, &p); err != nil {
		return nil, err
	}
	deps := make(map[string]bool)
	for _, pkg := range p.Deps {
		deps[pkg] = true
	}
	return deps, nil
}

func main() {
	workspace := flag.String("ws", "", "workspace path")
	flag.Parse()
	lsPackages := flag.Args()
	if len(lsPackages) <= 0 {
		log.Fatal("please, specify package names")
	}
	wsPackages, err := getPackages(*workspace)
	if err != nil {
		log.Fatal(err)
	}
	for _, p := range wsPackages {
		deps, err := getDependencies(p)
		if err != nil {
			log.Fatal(err)
		}
		for _, lsPkg := range lsPackages {
			if deps[lsPkg] {
				fmt.Println(p)
				break
			}
		}
	}
}
<commit_msg>[10.4] working draft<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os/exec"
	"path/filepath"
	"strings"
)

var binaryPath string

func init() {
	var err error
	binaryPath, err = exec.LookPath("go")
	if err != nil {
		log.Fatal(err)
	}
}

type properties struct {
	Name       string
	ImportPath string
	Deps       []string
}

func getProperties(name string) (*properties, error) {
	out, err := exec.Command(binaryPath, "list", "-json", name).Output()
	if err != nil {
		return nil, err
	}
	var p properties
	if err := json.Unmarshal(out, &p); err != nil {
		return nil, err
	}
	return &p, nil
}

func getPackages(workspace string) ([]string, error) {
	// dir := filepath.Join(workspace, "...") // does not work with '...'
	dir := filepath.Clean(workspace) + string(filepath.Separator) + "..."
	out, err := exec.Command(binaryPath, "list", dir).Output()
	if err != nil {
		return nil, err
	}
	// TODO: improve this.
	str := strings.TrimSpace(string(out))
	return strings.Split(str, "\n"), nil
}

func getDependencies(name string) (map[string]bool, error) {
	out, err := exec.Command(binaryPath, "list", "-json", name).Output()
	if err != nil {
		return nil, err
	}
	var p struct{ Deps []string }
	if err := json.Unmarshal(out, &p); err != nil {
		return nil, err
	}
	deps := make(map[string]bool)
	for _, pkg := range p.Deps {
		deps[pkg] = true
	}
	return deps, nil
}

func main() {
	flag.Parse()
	lsPackages := flag.Args()
	if len(lsPackages) <= 0 {
		log.Fatal("please, specify package names")
	}
	wsPackages, err := getPackages(".")
	if err != nil {
		log.Fatal(err)
	}
	for _, p := range wsPackages {
		deps, err := getDependencies(p)
		if err != nil {
			log.Fatal(err)
		}
		for _, lsPkg := range lsPackages {
			if deps[lsPkg] {
				fmt.Println(p)
				break
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os/exec"
	"path/filepath"
	"strings"
)

var binaryPath string

func init() {
	var err error
	if binaryPath, err = exec.LookPath("go"); err != nil {
		log.Fatal(err)
	}
}

func getPackages(workspace string) ([]string, error) {
	// dir := filepath.Join(workspace, "...") // does not work with '...'
	dir := filepath.Clean(workspace) + string(filepath.Separator) + "..."
	out, err := exec.Command(binaryPath, "list", dir).Output()
	if err != nil {
		return nil, err
	}
	// TODO: improve this.
	str := strings.TrimSpace(string(out))
	return strings.Split(str, "\n"), nil
}

func getDependencies(name string) (map[string]bool, error) {
	out, err := exec.Command(binaryPath, "list", "-json", name).Output()
	if err != nil {
		return nil, err
	}

	var p struct{ Deps []string }
	if err := json.Unmarshal(out, &p); err != nil {
		return nil, err
	}

	deps := make(map[string]bool)
	for _, pkg := range p.Deps {
		deps[pkg] = true
	}
	return deps, nil
}

func getUsedPackages(deps map[string]bool, packages []string) []string {
	used := make([]string, 0)
	for _, pkg := range packages {
		if !deps[pkg] {
			continue
		}
		used = append(used, pkg)
	}
	return used
}

func main() {
	flag.Parse()
	lsPackages := flag.Args()
	if len(lsPackages) <= 0 {
		log.Fatal("please, specify package names")
	}

	wsPackages, err := getPackages(".")
	if err != nil {
		log.Fatal(err)
	}

	for _, p := range wsPackages {
		deps, err := getDependencies(p)
		if err != nil {
			log.Fatal(err)
		}
		used := getUsedPackages(deps, lsPackages)
		if len(used) > 0 {
			fmt.Printf("%s: [%s]\n", p, strings.Join(used, ", "))
		}
	}
}
<commit_msg>[10.4] add unique for pprinting<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os/exec"
	"path/filepath"
	"strings"
)

var binaryPath string

func init() {
	var err error
	if binaryPath, err = exec.LookPath("go"); err != nil {
		log.Fatal(err)
	}
}

func getPackages(workspace string) ([]string, error) {
	// dir := filepath.Join(workspace, "...") // does not work with '...'
	dir := filepath.Clean(workspace) + string(filepath.Separator) + "..."
	out, err := exec.Command(binaryPath, "list", dir).Output()
	if err != nil {
		return nil, err
	}
	// TODO: improve this.
	str := strings.TrimSpace(string(out))
	return strings.Split(str, "\n"), nil
}

func getDependencies(name string) (map[string]bool, error) {
	out, err := exec.Command(binaryPath, "list", "-json", name).Output()
	if err != nil {
		return nil, err
	}

	var p struct{ Deps []string }
	if err := json.Unmarshal(out, &p); err != nil {
		return nil, err
	}

	deps := make(map[string]bool)
	for _, pkg := range p.Deps {
		deps[pkg] = true
	}
	return deps, nil
}

func getUsedPackages(deps map[string]bool, packages []string) []string {
	used := make([]string, 0)
	for _, pkg := range packages {
		if !deps[pkg] {
			continue
		}
		used = append(used, pkg)
	}
	return used
}

func unique(in []string) []string {
	seen := make(map[string]bool)
	out := make([]string, 0, len(in)) // think about in-place modification
	for _, item := range in {
		if seen[item] {
			continue
		}
		seen[item] = true
		out = append(out, item)
	}
	return out
}

func main() {
	flag.Parse()
	args := flag.Args()
	if len(args) <= 0 {
		log.Fatal("please, specify package names")
	}

	lsPackages := unique(args)

	wsPackages, err := getPackages(".")
	if err != nil {
		log.Fatal(err)
	}

	for _, p := range wsPackages {
		deps, err := getDependencies(p)
		if err != nil {
			log.Fatal(err)
		}
		used := getUsedPackages(deps, lsPackages)
		if len(used) > 0 {
			fmt.Printf("%s: [%s]\n", p, strings.Join(used, ", "))
		}
	}
}
<|endoftext|>


<commit_before>// Package project implements multi-function operations.
package project

import (
	"bytes"
	"encoding/json"
	"errors"
	"io/ioutil"
	"os"
	"path/filepath"
	"text/template"

	"gopkg.in/validator.v2"

	"github.com/apex/apex/function"
	"github.com/apex/log"
	"github.com/aws/aws-sdk-go/service/lambda/lambdaiface"
	"github.com/tj/go-sync/semaphore"
)

const (
	// DefaultMemory defines default memory value (MB) for every function in a project
	DefaultMemory = 128
	// DefaultTimeout defines default timeout value (s) for every function in a project
	DefaultTimeout = 3
)

// ErrNotFound is returned when a function cannot be found.
var ErrNotFound = errors.New("project: no function found")

// Config for project.
type Config struct {
	Name         string `json:"name" validate:"nonzero"`
	Description  string `json:"description"`
	Runtime      string `json:"runtime"`
	Memory       int64  `json:"memory"`
	Timeout      int64  `json:"timeout"`
	Role         string `json:"role"`
	NameTemplate string `json:"nameTemplate"`
}

// Project represents zero or more Lambda functions.
type Project struct {
	Config
	Path         string
	Concurrency  int
	Log          log.Interface
	Service      lambdaiface.LambdaAPI
	Functions    []*function.Function
	nameTemplate *template.Template
}

// defaults applies configuration defaults.
func (p *Project) defaults() {
	p.Memory = DefaultMemory
	p.Timeout = DefaultTimeout

	if p.Concurrency == 0 {
		p.Concurrency = 3
	}

	if p.NameTemplate == "" {
		p.NameTemplate = "{{.Project.Name}}_{{.Function.Name}}"
	}
}

// Open the project.json file and prime the config.
func (p *Project) Open() error {
	p.defaults()

	f, err := os.Open(filepath.Join(p.Path, "project.json"))
	if err != nil {
		return err
	}

	if err := json.NewDecoder(f).Decode(&p.Config); err != nil {
		return err
	}

	if err := validator.Validate(&p.Config); err != nil {
		return err
	}

	t, err := template.New("nameTemplate").Parse(p.NameTemplate)
	if err != nil {
		return err
	}
	p.nameTemplate = t

	return p.loadFunctions()
}

// DeployAndClean deploys functions and then cleans up their build artifacts.
func (p *Project) DeployAndClean(names []string) error {
	if err := p.Deploy(names); err != nil {
		return err
	}

	return p.Clean(names)
}

// Deploy functions and their configurations.
func (p *Project) Deploy(names []string) error {
	p.Log.Debugf("deploying %d functions", len(names))

	sem := make(semaphore.Semaphore, p.Concurrency)
	errs := make(chan error)

	go func() {
		for _, name := range names {
			name := name
			sem.Acquire()

			go func() {
				defer sem.Release()
				errs <- p.deploy(name)
			}()
		}

		sem.Wait()
		close(errs)
	}()

	for err := range errs {
		if err != nil {
			return err
		}
	}

	return nil
}

// deploy function by `name`.
func (p *Project) deploy(name string) error {
	fn, err := p.FunctionByName(name)

	if err == ErrNotFound {
		p.Log.Warnf("function %q does not exist", name)
		return nil
	}

	if err != nil {
		return err
	}

	return fn.Deploy()
}

// Clean up function build artifacts.
func (p *Project) Clean(names []string) error {
	p.Log.Debugf("cleaning %d functions", len(names))

	for _, name := range names {
		fn, err := p.FunctionByName(name)

		if err == ErrNotFound {
			continue
		}

		if err := fn.Clean(); err != nil {
			return err
		}
	}

	return nil
}

// Delete functions.
func (p *Project) Delete(names []string) error {
	p.Log.Debugf("deleting %d functions", len(names))

	for _, name := range names {
		fn, err := p.FunctionByName(name)

		if err == ErrNotFound {
			p.Log.Warnf("function %q does not exist", name)
			continue
		}

		if err := fn.Delete(); err != nil {
			return err
		}
	}

	return nil
}

// FunctionByName returns a function by `name` or returns ErrNotFound.
func (p *Project) FunctionByName(name string) (*function.Function, error) {
	for _, fn := range p.Functions {
		if fn.Name == name {
			return fn, nil
		}
	}

	return nil, ErrNotFound
}

// FunctionDirNames returns a list of function directory names.
func (p *Project) FunctionDirNames() (list []string, err error) {
	dir := filepath.Join(p.Path, "functions")

	files, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, err
	}

	for _, file := range files {
		if file.IsDir() {
			list = append(list, file.Name())
		}
	}

	return list, nil
}

// FunctionNames returns a list of function names.
func (p *Project) FunctionNames() (list []string) {
	for _, fn := range p.Functions {
		list = append(list, fn.Name)
	}

	return list
}

// SetEnv sets environment variable `name` to `value` on every function in project.
func (p *Project) SetEnv(name, value string) {
	for _, fn := range p.Functions {
		fn.SetEnv(name, value)
	}
}

// loadFunctions reads the ./functions directory, populating the Functions field.
func (p *Project) loadFunctions() error {
	dir := filepath.Join(p.Path, "functions")
	p.Log.Debugf("loading functions in %s", dir)

	names, err := p.FunctionDirNames()
	if err != nil {
		return err
	}

	for _, name := range names {
		fn, err := p.loadFunction(name)
		if err != nil {
			return err
		}

		p.Functions = append(p.Functions, fn)
	}

	return nil
}

// loadFunction returns the function in the ./functions/<name> directory.
func (p *Project) loadFunction(name string) (*function.Function, error) {
	dir := filepath.Join(p.Path, "functions", name)
	p.Log.Debugf("loading function in %s", dir)

	fn := &function.Function{
		Config: function.Config{
			Runtime: p.Config.Runtime,
			Memory:  p.Config.Memory,
			Timeout: p.Config.Timeout,
			Role:    p.Config.Role,
		},
		Name:    name,
		Path:    dir,
		Service: p.Service,
		Log:     p.Log,
	}

	if name, err := p.name(fn); err == nil {
		fn.FunctionName = name
	} else {
		return nil, err
	}

	if err := fn.Open(); err != nil {
		return nil, err
	}

	return fn, nil
}

// name returns the computed name for `fn`, using the nameTemplate.
func (p *Project) name(fn *function.Function) (string, error) {
	data := struct {
		Project  *Project
		Function *function.Function
	}{
		Project:  p,
		Function: fn,
	}

	name, err := render(p.nameTemplate, data)
	if err != nil {
		return "", err
	}

	return name, nil
}

// render returns a string by executing template `t` against the given value `v`.
func render(t *template.Template, v interface{}) (string, error) {
	buf := new(bytes.Buffer)

	if err := t.Execute(buf, v); err != nil {
		return "", err
	}

	return buf.String(), nil
}
<commit_msg>change Project.Concurrency default to 5<commit_after>// Package project implements multi-function operations.
package project

import (
	"bytes"
	"encoding/json"
	"errors"
	"io/ioutil"
	"os"
	"path/filepath"
	"text/template"

	"gopkg.in/validator.v2"

	"github.com/apex/apex/function"
	"github.com/apex/log"
	"github.com/aws/aws-sdk-go/service/lambda/lambdaiface"
	"github.com/tj/go-sync/semaphore"
)

const (
	// DefaultMemory defines default memory value (MB) for every function in a project
	DefaultMemory = 128
	// DefaultTimeout defines default timeout value (s) for every function in a project
	DefaultTimeout = 3
)

// ErrNotFound is returned when a function cannot be found.
var ErrNotFound = errors.New("project: no function found")

// Config for project.
type Config struct {
	Name         string `json:"name" validate:"nonzero"`
	Description  string `json:"description"`
	Runtime      string `json:"runtime"`
	Memory       int64  `json:"memory"`
	Timeout      int64  `json:"timeout"`
	Role         string `json:"role"`
	NameTemplate string `json:"nameTemplate"`
}

// Project represents zero or more Lambda functions.
type Project struct {
	Config
	Path         string
	Concurrency  int
	Log          log.Interface
	Service      lambdaiface.LambdaAPI
	Functions    []*function.Function
	nameTemplate *template.Template
}

// defaults applies configuration defaults.
func (p *Project) defaults() {
	p.Memory = DefaultMemory
	p.Timeout = DefaultTimeout

	if p.Concurrency == 0 {
		p.Concurrency = 5
	}

	if p.NameTemplate == "" {
		p.NameTemplate = "{{.Project.Name}}_{{.Function.Name}}"
	}
}

// Open the project.json file and prime the config.
func (p *Project) Open() error {
	p.defaults()

	f, err := os.Open(filepath.Join(p.Path, "project.json"))
	if err != nil {
		return err
	}

	if err := json.NewDecoder(f).Decode(&p.Config); err != nil {
		return err
	}

	if err := validator.Validate(&p.Config); err != nil {
		return err
	}

	t, err := template.New("nameTemplate").Parse(p.NameTemplate)
	if err != nil {
		return err
	}
	p.nameTemplate = t

	return p.loadFunctions()
}

// DeployAndClean deploys functions and then cleans up their build artifacts.
func (p *Project) DeployAndClean(names []string) error {
	if err := p.Deploy(names); err != nil {
		return err
	}

	return p.Clean(names)
}

// Deploy functions and their configurations.
func (p *Project) Deploy(names []string) error {
	p.Log.Debugf("deploying %d functions", len(names))

	sem := make(semaphore.Semaphore, p.Concurrency)
	errs := make(chan error)

	go func() {
		for _, name := range names {
			name := name
			sem.Acquire()

			go func() {
				defer sem.Release()
				errs <- p.deploy(name)
			}()
		}

		sem.Wait()
		close(errs)
	}()

	for err := range errs {
		if err != nil {
			return err
		}
	}

	return nil
}

// deploy function by `name`.
func (p *Project) deploy(name string) error {
	fn, err := p.FunctionByName(name)

	if err == ErrNotFound {
		p.Log.Warnf("function %q does not exist", name)
		return nil
	}

	if err != nil {
		return err
	}

	return fn.Deploy()
}

// Clean up function build artifacts.
func (p *Project) Clean(names []string) error {
	p.Log.Debugf("cleaning %d functions", len(names))

	for _, name := range names {
		fn, err := p.FunctionByName(name)

		if err == ErrNotFound {
			continue
		}

		if err := fn.Clean(); err != nil {
			return err
		}
	}

	return nil
}

// Delete functions.
func (p *Project) Delete(names []string) error {
	p.Log.Debugf("deleting %d functions", len(names))

	for _, name := range names {
		fn, err := p.FunctionByName(name)

		if err == ErrNotFound {
			p.Log.Warnf("function %q does not exist", name)
			continue
		}

		if err := fn.Delete(); err != nil {
			return err
		}
	}

	return nil
}

// FunctionByName returns a function by `name` or returns ErrNotFound.
func (p *Project) FunctionByName(name string) (*function.Function, error) {
	for _, fn := range p.Functions {
		if fn.Name == name {
			return fn, nil
		}
	}

	return nil, ErrNotFound
}

// FunctionDirNames returns a list of function directory names.
func (p *Project) FunctionDirNames() (list []string, err error) {
	dir := filepath.Join(p.Path, "functions")

	files, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, err
	}

	for _, file := range files {
		if file.IsDir() {
			list = append(list, file.Name())
		}
	}

	return list, nil
}

// FunctionNames returns a list of function names.
func (p *Project) FunctionNames() (list []string) {
	for _, fn := range p.Functions {
		list = append(list, fn.Name)
	}

	return list
}

// SetEnv sets environment variable `name` to `value` on every function in project.
func (p *Project) SetEnv(name, value string) {
	for _, fn := range p.Functions {
		fn.SetEnv(name, value)
	}
}

// loadFunctions reads the ./functions directory, populating the Functions field.
func (p *Project) loadFunctions() error {
	dir := filepath.Join(p.Path, "functions")
	p.Log.Debugf("loading functions in %s", dir)

	names, err := p.FunctionDirNames()
	if err != nil {
		return err
	}

	for _, name := range names {
		fn, err := p.loadFunction(name)
		if err != nil {
			return err
		}

		p.Functions = append(p.Functions, fn)
	}

	return nil
}

// loadFunction returns the function in the ./functions/<name> directory.
func (p *Project) loadFunction(name string) (*function.Function, error) {
	dir := filepath.Join(p.Path, "functions", name)
	p.Log.Debugf("loading function in %s", dir)

	fn := &function.Function{
		Config: function.Config{
			Runtime: p.Config.Runtime,
			Memory:  p.Config.Memory,
			Timeout: p.Config.Timeout,
			Role:    p.Config.Role,
		},
		Name:    name,
		Path:    dir,
		Service: p.Service,
		Log:     p.Log,
	}

	if name, err := p.name(fn); err == nil {
		fn.FunctionName = name
	} else {
		return nil, err
	}

	if err := fn.Open(); err != nil {
		return nil, err
	}

	return fn, nil
}

// name returns the computed name for `fn`, using the nameTemplate.
func (p *Project) name(fn *function.Function) (string, error) {
	data := struct {
		Project  *Project
		Function *function.Function
	}{
		Project:  p,
		Function: fn,
	}

	name, err := render(p.nameTemplate, data)
	if err != nil {
		return "", err
	}

	return name, nil
}

// render returns a string by executing template `t` against the given value `v`.
func render(t *template.Template, v interface{}) (string, error) {
	buf := new(bytes.Buffer)

	if err := t.Execute(buf, v); err != nil {
		return "", err
	}

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


<commit_before>package main

import (
    . "github.com/levythu/gurgling"
    "fmt"
)

func getPageRouter() Router {
    var page=ARouter()
    page.Get("/", func(req Request, res Response) {
        res.Send("The list of pages.")
    })
    page.Get("/edit", func(req Request, res Response) {
        res.Send("Edit page.")
    })
    page.Get("/redirect", func(req Request, res Response) {
        res.Redirect("/edit")
    })
    page.Use("/file", func(req Request, res Response) {
        if req.Path()=="" {
            res.Send("Specify the path please.")
            return
        }
        res.SendFile(req.Path()[1:])
    })
    page.Last(func(req Request, res Response) {
        fmt.Println("Page end.")
    })

    return page
}
<commit_msg>remove redundancy<commit_after><|endoftext|>


<commit_before>package riffle

import (
    "fmt"
)

var sess *session

func someCall(a int, b int) int {
    ret := a + b

    fmt.Println("Call received with args and return:", a, b, ret)
    return ret
}

func somePub(a int, b int) {
    fmt.Println("Pub received with args:", a, b)
    sess.Leave()
}

func Greetings(name string) string {
    fmt.Println("I can print!")

    return fmt.Sprintf("Hello, %s!", name)

    s, err := Start("ws://ec2-52-26-83-61.us-west-2.compute.amazonaws.com:8000/ws", "xs.damouse.go")
    sess = s

    if err != nil {
        fmt.Println(err)
        return "NO"
    }

    s.Register("xs.damouse.go/hello", someCall, nil)
    s.Subscribe("xs.damouse.go/sub", somePub)

    // Block and recieve
    go s.Receive()

    fmt.Println("Done!")

    return "YES"
}
<commit_msg>holy crap it works<commit_after>package riffle

import (
    "fmt"
)

var sess *session

func someCall(a int, b int) int {
    ret := a + b

    fmt.Println("Call received with args and return:", a, b, ret)
    return ret
}

func somePub(a int, b int) {
    fmt.Println("Pub received with args:", a, b)
    sess.Leave()
}

func Tester(name string) string {
    fmt.Println("I can print!")

    //return fmt.Sprintf("Hello, %s!", name)

    s, err := Start("ws://ec2-52-26-83-61.us-west-2.compute.amazonaws.com:8000/ws", "xs.damouse.go")
    sess = s

    if err != nil {
        fmt.Println(err)
        return "NO"
    }

    s.Register("xs.damouse.go/hello", someCall, nil)
    fmt.Println("Registered")

    s.Subscribe("xs.damouse.go/sub", somePub)
    fmt.Println("Subscribed")

    // Block and recieve
    go s.Receive()

    fmt.Println("Done!")

    return "YES"
}
<|endoftext|>


<commit_before>package dataProcess

import (
	"../autils"
	"database/sql"
	"github.com/gin-gonic/gin"
	"net/http"
	"time"
)

type disRowsInfo struct {
	Name  string `json:"name"`
	Value int    `json:"value"`
}

func DistributeData(c *gin.Context, db *sql.DB) {
	date := c.Query("date")
	if date == "" {
		date = autils.GetCurrentData(time.Now().AddDate(0, 0, -1))
	}

	q, _ := c.Get("conditions")
	sDate := autils.AnaSigleDate(q)
	if sDate != "" {
		date = sDate
	}

	sqlStr := "select click from all_flow where date = '" + date + "' union all select total from search where date = '" + date + "' union all select total from thirdparty where date = '" + date + "'"
	rows, err := db.Query(sqlStr)
	autils.ErrHadle(err)

	var realnum, search, thirdparty sql.NullInt64
	for rows.Next() {
		err := rows.Scan(&realnum, &search, &thirdparty)
		autils.ErrHadle(err)
	}
	err = rows.Err()
	autils.ErrHadle(err)
	defer rows.Close()

	rData := int(realnum.Int64)
	sData := int(search.Int64)
	tData := int(thirdparty.Int64)

	thirdFlow := rData * tData / sData

	disArr := []disRowsInfo{
		{
			"搜索流量",
			rData - thirdFlow,
		},
		{
			"第三方流量",
			thirdFlow,
		}}

	c.JSON(http.StatusOK, gin.H{
		"status": 0,
		"msg":    "ok",
		"data":   disArr,
	})
}
<commit_msg>fixed sql nullInt64 bug.<commit_after>package dataProcess

import (
	"../autils"
	"database/sql"
	"github.com/gin-gonic/gin"
	"net/http"
	"time"
)

type disRowsInfo struct {
	Name  string `json:"name"`
	Value int    `json:"value"`
}

func DistributeData(c *gin.Context, db *sql.DB) {
	date := c.Query("date")
	if date == "" {
		date = autils.GetCurrentData(time.Now().AddDate(0, 0, -1))
	}

	q, _ := c.Get("conditions")
	sDate := autils.AnaSigleDate(q)
	if sDate != "" {
		date = sDate
	}

	sqlStr := "select click from all_flow where date = '" + date + "' union all select total from search where date = '" + date + "' union all select total from thirdparty where date = '" + date + "'"
	rows, err := db.Query(sqlStr)
	autils.ErrHadle(err)

	var numSet []sql.NullInt64
	for rows.Next() {
		err := rows.Scan(&numSet)
		autils.ErrHadle(err)
	}
	err = rows.Err()
	autils.ErrHadle(err)
	defer rows.Close()

	rData := int(numSet[0].Int64)
	sData := int(numSet[1].Int64)
	tData := int(numSet[2].Int64)

	thirdFlow := rData * tData / sData

	disArr := []disRowsInfo{
		{
			"搜索流量",
			rData - thirdFlow,
		},
		{
			"第三方流量",
			thirdFlow,
		}}

	c.JSON(http.StatusOK, gin.H{
		"status": 0,
		"msg":    "ok",
		"data":   disArr,
	})
}
<|endoftext|>


<commit_before>package accesslog

import (
	"net/http"
	"os"
	"testing"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/stretchr/testify/assert"
)

func TestCommonLogFormatter_Format(t *testing.T) {
	clf := CommonLogFormatter{}

	testCases := []struct {
		name        string
		data        map[string]interface{}
		expectedLog string
	}{
		{
			name: "OriginStatus & OriginContentSize are nil",
			data: map[string]interface{}{
				StartUTC:               time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
				Duration:               123 * time.Second,
				ClientHost:             "10.0.0.1",
				ClientUsername:         "Client",
				RequestMethod:          http.MethodGet,
				RequestPath:            "/foo",
				RequestProtocol:        "http",
				OriginStatus:           nil,
				OriginContentSize:      nil,
				RequestRefererHeader:   "",
				RequestUserAgentHeader: "",
				RequestCount:           0,
				RouterName:             "",
				ServiceURL:             "",
			},
			expectedLog: `10.0.0.1 - Client [10/Nov/2009:23:00:00 +0000] "GET /foo http" - - "-" "-" 0 "-" "-" 123000ms
`,
		},
		{
			name: "all data",
			data: map[string]interface{}{
				StartUTC:               time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
				Duration:               123 * time.Second,
				ClientHost:             "10.0.0.1",
				ClientUsername:         "Client",
				RequestMethod:          http.MethodGet,
				RequestPath:            "/foo",
				RequestProtocol:        "http",
				OriginStatus:           123,
				OriginContentSize:      132,
				RequestRefererHeader:   "referer",
				RequestUserAgentHeader: "agent",
				RequestCount:           nil,
				RouterName:             "foo",
				ServiceURL:             "http://10.0.0.2/toto",
			},
			expectedLog: `10.0.0.1 - Client [10/Nov/2009:23:00:00 +0000] "GET /foo http" 123 132 "referer" "agent" - "foo" "http://10.0.0.2/toto" 123000ms
`,
		},
		/*
					{
						name: "all data with local time",
						data: map[string]interface{}{
							StartLocal:             time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
							Duration:               123 * time.Second,
							ClientHost:             "10.0.0.1",
							ClientUsername:         "Client",
							RequestMethod:          http.MethodGet,
							RequestPath:            "/foo",
							RequestProtocol:        "http",
							OriginStatus:           123,
							OriginContentSize:      132,
							RequestRefererHeader:   "referer",
							RequestUserAgentHeader: "agent",
							RequestCount:           nil,
							RouterName:             "foo",
							ServiceURL:             "http://10.0.0.2/toto",
						},
						expectedLog: `10.0.0.1 - Client [10/Nov/2009:14:00:00 -0900] "GET /foo http" 123 132 "referer" "agent" - "foo" "http://10.0.0.2/toto" 123000ms
			`,
					},
		*/
	}

	// Set timezone to Alaska to have a constant behavior
	os.Setenv("TZ", "US/Alaska")

	for _, test := range testCases {
		test := test
		t.Run(test.name, func(t *testing.T) {
			t.Parallel()

			entry := &logrus.Entry{Data: test.data}

			raw, err := clf.Format(entry)
			assert.NoError(t, err)

			assert.Equal(t, test.expectedLog, string(raw))
		})
	}
}

func Test_toLog(t *testing.T) {
	testCases := []struct {
		desc         string
		fields       logrus.Fields
		fieldName    string
		defaultValue string
		quoted       bool
		expectedLog  interface{}
	}{
		{
			desc: "Should return int 1",
			fields: logrus.Fields{
				"Powpow": 1,
			},
			fieldName:    "Powpow",
			defaultValue: defaultValue,
			quoted:       false,
			expectedLog:  1,
		},
		{
			desc: "Should return string foo",
			fields: logrus.Fields{
				"Powpow": "foo",
			},
			fieldName:    "Powpow",
			defaultValue: defaultValue,
			quoted:       true,
			expectedLog:  `"foo"`,
		},
		{
			desc: "Should return defaultValue if fieldName does not exist",
			fields: logrus.Fields{
				"Powpow": "foo",
			},
			fieldName:    "",
			defaultValue: defaultValue,
			quoted:       false,
			expectedLog:  "-",
		},
		{
			desc:         "Should return defaultValue if fields is nil",
			fields:       nil,
			fieldName:    "",
			defaultValue: defaultValue,
			quoted:       false,
			expectedLog:  "-",
		},
	}

	for _, test := range testCases {
		test := test
		t.Run(test.desc, func(t *testing.T) {
			t.Parallel()

			lg := toLog(test.fields, test.fieldName, defaultValue, test.quoted)

			assert.Equal(t, test.expectedLog, lg)
		})
	}
}
<commit_msg>Use timezone without daylight saving time for logger formatter tests<commit_after>package accesslog

import (
	"net/http"
	"os"
	"testing"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/stretchr/testify/assert"
)

func TestCommonLogFormatter_Format(t *testing.T) {
	clf := CommonLogFormatter{}

	testCases := []struct {
		name        string
		data        map[string]interface{}
		expectedLog string
	}{
		{
			name: "OriginStatus & OriginContentSize are nil",
			data: map[string]interface{}{
				StartUTC:               time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
				Duration:               123 * time.Second,
				ClientHost:             "10.0.0.1",
				ClientUsername:         "Client",
				RequestMethod:          http.MethodGet,
				RequestPath:            "/foo",
				RequestProtocol:        "http",
				OriginStatus:           nil,
				OriginContentSize:      nil,
				RequestRefererHeader:   "",
				RequestUserAgentHeader: "",
				RequestCount:           0,
				RouterName:             "",
				ServiceURL:             "",
			},
			expectedLog: `10.0.0.1 - Client [10/Nov/2009:23:00:00 +0000] "GET /foo http" - - "-" "-" 0 "-" "-" 123000ms
`,
		},
		{
			name: "all data",
			data: map[string]interface{}{
				StartUTC:               time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
				Duration:               123 * time.Second,
				ClientHost:             "10.0.0.1",
				ClientUsername:         "Client",
				RequestMethod:          http.MethodGet,
				RequestPath:            "/foo",
				RequestProtocol:        "http",
				OriginStatus:           123,
				OriginContentSize:      132,
				RequestRefererHeader:   "referer",
				RequestUserAgentHeader: "agent",
				RequestCount:           nil,
				RouterName:             "foo",
				ServiceURL:             "http://10.0.0.2/toto",
			},
			expectedLog: `10.0.0.1 - Client [10/Nov/2009:23:00:00 +0000] "GET /foo http" 123 132 "referer" "agent" - "foo" "http://10.0.0.2/toto" 123000ms
`,
		},
		{
			name: "all data with local time",
			data: map[string]interface{}{
				StartLocal:             time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
				Duration:               123 * time.Second,
				ClientHost:             "10.0.0.1",
				ClientUsername:         "Client",
				RequestMethod:          http.MethodGet,
				RequestPath:            "/foo",
				RequestProtocol:        "http",
				OriginStatus:           123,
				OriginContentSize:      132,
				RequestRefererHeader:   "referer",
				RequestUserAgentHeader: "agent",
				RequestCount:           nil,
				RouterName:             "foo",
				ServiceURL:             "http://10.0.0.2/toto",
			},
			expectedLog: `10.0.0.1 - Client [10/Nov/2009:14:00:00 -0900] "GET /foo http" 123 132 "referer" "agent" - "foo" "http://10.0.0.2/toto" 123000ms
`,
		},
	}

	// Set timezone to Etc/GMT+9 to have a constant behavior
	os.Setenv("TZ", "Etc/GMT+9")

	for _, test := range testCases {
		test := test
		t.Run(test.name, func(t *testing.T) {
			t.Parallel()

			entry := &logrus.Entry{Data: test.data}

			raw, err := clf.Format(entry)
			assert.NoError(t, err)

			assert.Equal(t, test.expectedLog, string(raw))
		})
	}
}

func Test_toLog(t *testing.T) {
	testCases := []struct {
		desc         string
		fields       logrus.Fields
		fieldName    string
		defaultValue string
		quoted       bool
		expectedLog  interface{}
	}{
		{
			desc: "Should return int 1",
			fields: logrus.Fields{
				"Powpow": 1,
			},
			fieldName:    "Powpow",
			defaultValue: defaultValue,
			quoted:       false,
			expectedLog:  1,
		},
		{
			desc: "Should return string foo",
			fields: logrus.Fields{
				"Powpow": "foo",
			},
			fieldName:    "Powpow",
			defaultValue: defaultValue,
			quoted:       true,
			expectedLog:  `"foo"`,
		},
		{
			desc: "Should return defaultValue if fieldName does not exist",
			fields: logrus.Fields{
				"Powpow": "foo",
			},
			fieldName:    "",
			defaultValue: defaultValue,
			quoted:       false,
			expectedLog:  "-",
		},
		{
			desc:         "Should return defaultValue if fields is nil",
			fields:       nil,
			fieldName:    "",
			defaultValue: defaultValue,
			quoted:       false,
			expectedLog:  "-",
		},
	}

	for _, test := range testCases {
		test := test
		t.Run(test.desc, func(t *testing.T) {
			t.Parallel()

			lg := toLog(test.fields, test.fieldName, defaultValue, test.quoted)

			assert.Equal(t, test.expectedLog, lg)
		})
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2020 The Tekton Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package tektonconfig

import (
	"context"
	"log"

	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
	operatorclient "github.com/tektoncd/operator/pkg/client/injection/client"
	"github.com/tektoncd/operator/pkg/reconciler/common"
	k8s_ctrl "github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektonconfig"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"knative.dev/pkg/configmap"
	"knative.dev/pkg/controller"
)

// NewController initializes the controller and is called by the generated code
// Registers eventhandlers to enqueue events
func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
	ctrl := k8s_ctrl.NewExtendedController(OpenShiftExtension)(ctx, cmw)
	createCR(ctx)
	return ctrl
}

func createCR(ctx context.Context) {
	c := operatorclient.Get(ctx).OperatorV1alpha1()
	tcCR := &v1alpha1.TektonConfig{
		ObjectMeta: metav1.ObjectMeta{
			Name: common.ConfigResourceName,
		},
		Spec: v1alpha1.TektonConfigSpec{
			Profile: common.ProfileAll,
			CommonSpec: v1alpha1.CommonSpec{
				TargetNamespace: "openshift-pipelines",
			},
		},
	}
	if _, err := c.TektonConfigs().Create(context.TODO(), tcCR, metav1.CreateOptions{}); err != nil {
		log.Panic("Failed to autocreate TektonConfig with error: ", err)
	}
}
<commit_msg>Add condition to verify existence of TektonConfig CR<commit_after>/*
Copyright 2020 The Tekton Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package tektonconfig

import (
	"context"
	"log"

	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
	operatorclient "github.com/tektoncd/operator/pkg/client/injection/client"
	"github.com/tektoncd/operator/pkg/reconciler/common"
	k8s_ctrl "github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektonconfig"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"knative.dev/pkg/configmap"
	"knative.dev/pkg/controller"
)

// NewController initializes the controller and is called by the generated code
// Registers eventhandlers to enqueue events
func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
	ctrl := k8s_ctrl.NewExtendedController(OpenShiftExtension)(ctx, cmw)
	createCR(ctx)
	return ctrl
}

func createCR(ctx context.Context) {
	c := operatorclient.Get(ctx).OperatorV1alpha1()
	tcCR := &v1alpha1.TektonConfig{
		ObjectMeta: metav1.ObjectMeta{
			Name: common.ConfigResourceName,
		},
		Spec: v1alpha1.TektonConfigSpec{
			Profile: common.ProfileAll,
			CommonSpec: v1alpha1.CommonSpec{
				TargetNamespace: "openshift-pipelines",
			},
		},
	}
	if _, err := c.TektonConfigs().Create(context.TODO(), tcCR, metav1.CreateOptions{}); err != nil {
		if !errors.IsAlreadyExists(err) {
			log.Panic("Failed to autocreate TektonConfig with error: ", err)
		}
	}
}
<|endoftext|>