<commit_before>// Copyright 2015 Richard Lehane. 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 types

import (
	"encoding/binary"
)

type Vector []Type

func (v Vector) String() string {
	return ""
}

func (v Vector) Type() string {
	if len(v) > 0 {
		return "Vector of " + v[0].Type()
	}
	return "Vector (empty)"
}

func (v Vector) Length() int {
	ret := 4
	for _, t := range v {
		ret += t.Length()
	}
	return ret
}

func MakeVector(f MakeType, b []byte) (Type, error) {
	if len(b) < 4 {
		return Vector{}, ErrType
	}
	l := int(binary.LittleEndian.Uint32(b[:4]))
	v := make(Vector, l)
	place := 4
	for i := 0; i < l; i++ {
		t, err := f(b[place:])
		if err != nil {
			return Vector{}, ErrType
		}
		v[i] = t
		place += t.Length()
	}
	return v, nil
}

type Array [][]Type

func (a Array) String() string {
	return ""
}

func (a Array) Type() string {
	if len(a) > 0 && len(a[0]) > 0 {
		return "Array of " + a[0][0].Type()
	}
	return "Array (empty)"
}

func (a Array) Length() int {
	return 0
}

// TODO: Array not implemented yet
func MakeArray(f MakeType, b []byte) (Type, error) {
	return Array{}, nil
}

type Variant struct {
	t Type
}

func (v Variant) String() string {
	return "Typed Property Value containing " + v.t.String()
}

func (v Variant) Type() string {
	return "Typed Property Value containing " + v.t.Type()
}

func (v Variant) Length() int {
	return 4 + v.t.Length()
}

func MakeVariant(b []byte) (Type, error) {
	if len(b) < 4 || binary.LittleEndian.Uint16(b[2:4]) != scalar { // only scalar values allowed
		return Variant{}, ErrType
	}
	id := TypeID(binary.LittleEndian.Uint16(b[:2]))
	if id == VT_VARIANT {
		return Variant{}, ErrType // no recursive types allowed
	}
	f, ok := MakeTypes[id]
	if !ok {
		Variant{}, ErrUnknownType
	}
	t, err := f(b[4:])
	if err != nil {
		return Variant{}, err
	}
	return Variant{t}, nil
}
<commit_msg>missing return<commit_after>// Copyright 2015 Richard Lehane. 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 types

import (
	"encoding/binary"
)

type Vector []Type

func (v Vector) String() string {
	return ""
}

func (v Vector) Type() string {
	if len(v) > 0 {
		return "Vector of " + v[0].Type()
	}
	return "Vector (empty)"
}

func (v Vector) Length() int {
	ret := 4
	for _, t := range v {
		ret += t.Length()
	}
	return ret
}

func MakeVector(f MakeType, b []byte) (Type, error) {
	if len(b) < 4 {
		return Vector{}, ErrType
	}
	l := int(binary.LittleEndian.Uint32(b[:4]))
	v := make(Vector, l)
	place := 4
	for i := 0; i < l; i++ {
		t, err := f(b[place:])
		if err != nil {
			return Vector{}, ErrType
		}
		v[i] = t
		place += t.Length()
	}
	return v, nil
}

type Array [][]Type

func (a Array) String() string {
	return ""
}

func (a Array) Type() string {
	if len(a) > 0 && len(a[0]) > 0 {
		return "Array of " + a[0][0].Type()
	}
	return "Array (empty)"
}

func (a Array) Length() int {
	return 0
}

// TODO: Array not implemented yet
func MakeArray(f MakeType, b []byte) (Type, error) {
	return Array{}, nil
}

type Variant struct {
	t Type
}

func (v Variant) String() string {
	return "Typed Property Value containing " + v.t.String()
}

func (v Variant) Type() string {
	return "Typed Property Value containing " + v.t.Type()
}

func (v Variant) Length() int {
	return 4 + v.t.Length()
}

func MakeVariant(b []byte) (Type, error) {
	if len(b) < 4 || binary.LittleEndian.Uint16(b[2:4]) != scalar { // only scalar values allowed
		return Variant{}, ErrType
	}
	id := TypeID(binary.LittleEndian.Uint16(b[:2]))
	if id == VT_VARIANT {
		return Variant{}, ErrType // no recursive types allowed
	}
	f, ok := MakeTypes[id]
	if !ok {
		return Variant{}, ErrUnknownType
	}
	t, err := f(b[4:])
	if err != nil {
		return Variant{}, err
	}
	return Variant{t}, nil
}
<|endoftext|>


<commit_before>// Copyright 2017 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package app

import (
	"net/http"
	"net/http/pprof"
	"strconv"
	"strings"

	"github.com/issue9/logs"
	"github.com/issue9/middleware/host"
	"github.com/issue9/middleware/recovery"
	"github.com/issue9/middleware/version"
	"github.com/issue9/web/context"
)

func logRecovery(w http.ResponseWriter, msg interface{}) {
	logs.Error(msg)
	context.RenderStatus(w, http.StatusInternalServerError)
}

func (app *App) listen(h http.Handler) error {
	if app.config.HTTPS {
		switch app.config.HTTPState {
		case httpStateListen:
			go func() {
				logs.Infof("开始监听[%v]端口", httpPort)
				logs.Error(app.newServer(httpPort, h).ListenAndServe())
			}()
		case httpStateRedirect:
			go func() {
				logs.Infof("开始监听[%v]端口，并跳转至[%v]", httpPort, httpsPort)
				logs.Error(app.httpRedirectServer().ListenAndServe())
			}()
			// 空值或是 disable 均为默认处理方式，即不作为。
		}

		logs.Infof("开始监听[%v]端口", app.config.Port)
		return app.newServer(app.config.Port, h).ListenAndServeTLS(app.config.CertFile, app.config.KeyFile)
	}

	logs.Infof("开始监听[%v]端口", app.config.Port)
	return app.newServer(app.config.Port, h).ListenAndServe()
}

// 构建一个从 HTTP 跳转到 HTTPS 的路由服务。
func (app *App) httpRedirectServer() *http.Server {
	return app.newServer(httpPort, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 构建跳转链接
		url := r.URL
		url.Scheme = "HTTPS"
		url.Host = strings.Split(r.Host, ":")[0] + ":" + strconv.Itoa(app.config.Port)

		urlStr := url.String()
		http.Redirect(w, r, urlStr, http.StatusMovedPermanently)
	}))
}

// 获取 http.Server 实例，相对于 http 的默认实现，指定了 ErrorLog 字段。
func (app *App) newServer(port int, h http.Handler) *http.Server {
	srv := &http.Server{
		Addr:         ":" + strconv.Itoa(port),
		Handler:      h,
		ErrorLog:     logs.ERROR(),
		ReadTimeout:  app.config.ReadTimeout,
		WriteTimeout: app.config.WriteTimeout,
	}

	app.servers = append(app.servers, srv)

	return srv
}

func (app *App) buildHandler(h http.Handler) http.Handler {
	h = app.buildHosts(app.buildVersion(app.buildHeader(h)))

	ff := logRecovery
	if app.config.Debug {
		ff = recovery.PrintDebug
	}
	h = recovery.New(h, ff)

	// NOTE: 在最外层添加调试地址，保证调试内容不会被其它 handler 干扰。
	if app.config.Debug {
		h = app.buildPprof(h)
	}

	return h
}

func (app *App) buildHosts(h http.Handler) http.Handler {
	if len(app.config.Hosts) == 0 {
		return h
	}

	return host.New(h, app.config.Hosts...)
}

func (app *App) buildVersion(h http.Handler) http.Handler {
	if len(app.config.Version) == 0 {
		return h
	}

	return version.New(h, app.config.Version, true)
}

func (app *App) buildHeader(h http.Handler) http.Handler {
	if len(app.config.Headers) == 0 {
		return h
	}

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		for k, v := range app.config.Headers {
			w.Header().Set(k, v)
		}
		h.ServeHTTP(w, r)
	})
}

// 根据 决定是否包装调试地址，调用前请确认是否已经开启 Pprof 选项
func (app *App) buildPprof(h http.Handler) http.Handler {
	logs.Debug("开启了调试功能，地址为：", pprofPath)

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if !strings.HasPrefix(r.URL.Path, pprofPath) {
			h.ServeHTTP(w, r)
			return
		}

		path := r.URL.Path[len(pprofPath):]
		switch path {
		case "cmdline":
			pprof.Cmdline(w, r)
		case "profile":
			pprof.Profile(w, r)
		case "symbol":
			pprof.Symbol(w, r)
		case "trace":
			pprof.Trace(w, r)
		default:
			pprof.Index(w, r)
		}
	}) // end return http.HandlerFunc
}
<commit_msg>调整 httpRedirectServer 函数<commit_after>// Copyright 2017 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package app

import (
	"net/http"
	"net/http/pprof"
	"strconv"
	"strings"

	"github.com/issue9/logs"
	"github.com/issue9/middleware/host"
	"github.com/issue9/middleware/recovery"
	"github.com/issue9/middleware/version"
	"github.com/issue9/web/context"
)

func logRecovery(w http.ResponseWriter, msg interface{}) {
	logs.Error(msg)
	context.RenderStatus(w, http.StatusInternalServerError)
}

func (app *App) listen(h http.Handler) error {
	if app.config.HTTPS {
		switch app.config.HTTPState {
		case httpStateListen:
			go func() {
				logs.Infof("开始监听[%v]端口", httpPort)
				logs.Error(app.newServer(httpPort, h).ListenAndServe())
			}()
		case httpStateRedirect:
			go func() {
				logs.Infof("开始监听[%v]端口，并跳转至[%v]", httpPort, httpsPort)
				logs.Error(app.httpRedirectServer().ListenAndServe())
			}()
			// 空值或是 disable 均为默认处理方式，即不作为。
		}

		logs.Infof("开始监听[%v]端口", app.config.Port)
		return app.newServer(app.config.Port, h).ListenAndServeTLS(app.config.CertFile, app.config.KeyFile)
	}

	logs.Infof("开始监听[%v]端口", app.config.Port)
	return app.newServer(app.config.Port, h).ListenAndServe()
}

// 构建一个从 HTTP 跳转到 HTTPS 的路由服务。
func (app *App) httpRedirectServer() *http.Server {
	return app.newServer(httpPort, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		u := r.URL // 直接采用 r.URL，毕竟跳转之后，此值就没用了。
		u.Scheme = "HTTPS"
		u.Host = strings.Split(r.Host, ":")[0]
		if app.config.Port != httpsPort {
			u.Host += ":" + strconv.Itoa(app.config.Port)
		}

		http.Redirect(w, r, u.String(), http.StatusMovedPermanently)
	}))
}

// 获取 http.Server 实例，相对于 http 的默认实现，指定了 ErrorLog 字段。
func (app *App) newServer(port int, h http.Handler) *http.Server {
	srv := &http.Server{
		Addr:         ":" + strconv.Itoa(port),
		Handler:      h,
		ErrorLog:     logs.ERROR(),
		ReadTimeout:  app.config.ReadTimeout,
		WriteTimeout: app.config.WriteTimeout,
	}

	app.servers = append(app.servers, srv)

	return srv
}

func (app *App) buildHandler(h http.Handler) http.Handler {
	h = app.buildHosts(app.buildVersion(app.buildHeader(h)))

	ff := logRecovery
	if app.config.Debug {
		ff = recovery.PrintDebug
	}
	h = recovery.New(h, ff)

	// NOTE: 在最外层添加调试地址，保证调试内容不会被其它 handler 干扰。
	if app.config.Debug {
		h = app.buildPprof(h)
	}

	return h
}

func (app *App) buildHosts(h http.Handler) http.Handler {
	if len(app.config.Hosts) == 0 {
		return h
	}

	return host.New(h, app.config.Hosts...)
}

func (app *App) buildVersion(h http.Handler) http.Handler {
	if len(app.config.Version) == 0 {
		return h
	}

	return version.New(h, app.config.Version, true)
}

func (app *App) buildHeader(h http.Handler) http.Handler {
	if len(app.config.Headers) == 0 {
		return h
	}

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		for k, v := range app.config.Headers {
			w.Header().Set(k, v)
		}
		h.ServeHTTP(w, r)
	})
}

// 根据 决定是否包装调试地址，调用前请确认是否已经开启 Pprof 选项
func (app *App) buildPprof(h http.Handler) http.Handler {
	logs.Debug("开启了调试功能，地址为：", pprofPath)

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if !strings.HasPrefix(r.URL.Path, pprofPath) {
			h.ServeHTTP(w, r)
			return
		}

		path := r.URL.Path[len(pprofPath):]
		switch path {
		case "cmdline":
			pprof.Cmdline(w, r)
		case "profile":
			pprof.Profile(w, r)
		case "symbol":
			pprof.Symbol(w, r)
		case "trace":
			pprof.Trace(w, r)
		default:
			pprof.Index(w, r)
		}
	}) // end return http.HandlerFunc
}
<|endoftext|>


<commit_before>package bimg

import (
	"io/ioutil"
	"os"
	"path"
	"testing"
)

func TestResize(t *testing.T) {
	options := Options{Width: 800, Height: 600}
	buf, _ := Read("fixtures/test.jpg")

	newImg, err := Resize(buf, options)
	if err != nil {
		t.Errorf("Resize(imgData, %#v) error: %#v", options, err)
	}

	if DetermineImageType(newImg) != JPEG {
		t.Fatal("Image is not jpeg")
	}

	err = Write("fixtures/test_out.jpg", newImg)
	if err != nil {
		t.Fatal("Cannot save the image")
	}
}

func TestRotate(t *testing.T) {
	options := Options{Width: 800, Height: 600, Rotate: 270}
	buf, _ := Read("fixtures/test.jpg")

	newImg, err := Resize(buf, options)
	if err != nil {
		t.Errorf("Resize(imgData, %#v) error: %#v", options, err)
	}

	if DetermineImageType(newImg) != JPEG {
		t.Fatal("Image is not jpeg")
	}

	err = Write("fixtures/test_rotate_out.jpg", newImg)
	if err != nil {
		t.Fatal("Cannot save the image")
	}
}

func TestInvalidRotate(t *testing.T) {
	options := Options{Width: 800, Height: 600, Rotate: 111}
	buf, _ := Read("fixtures/test.jpg")

	newImg, err := Resize(buf, options)
	if err != nil {
		t.Errorf("Resize(imgData, %#v) error: %#v", options, err)
	}

	if DetermineImageType(newImg) != JPEG {
		t.Fatal("Image is not jpeg")
	}

	err = Write("fixtures/test_invalid_rotate_out.jpg", newImg)
	if err != nil {
		t.Fatal("Cannot save the image")
	}
}

func TestConvert(t *testing.T) {
	width, height := 640, 480

	options := Options{Width: width, Height: height, Crop: true, Type: PNG}
	img, err := os.Open("fixtures/test.jpg")
	if err != nil {
		t.Fatal(err)
	}
	defer img.Close()

	buf, err := ioutil.ReadAll(img)
	if err != nil {
		t.Fatal(err)
	}

	newImg, err := Resize(buf, options)
	if err != nil {
		t.Errorf("Resize(imgData, %#v) error: %#v", options, err)
	}

	if DetermineImageType(newImg) != PNG {
		t.Fatal("Image is not png")
	}

	size, _ := Size(newImg)
	if size.Height != height || size.Width != width {
		t.Fatal("Invalid image size")
	}

	err = Write("fixtures/test_out.png", newImg)
	if err != nil {
		t.Fatal("Cannot save the image")
	}
}

func TestResizePngWithTransparency(t *testing.T) {
	width, height := 300, 240

	options := Options{Width: width, Height: height, Crop: true}
	img, err := os.Open("fixtures/transparent.png")
	if err != nil {
		t.Fatal(err)
	}
	defer img.Close()

	buf, err := ioutil.ReadAll(img)
	if err != nil {
		t.Fatal(err)
	}

	newImg, err := Resize(buf, options)
	if err != nil {
		t.Errorf("Resize(imgData, %#v) error: %#v", options, err)
	}

	if DetermineImageType(newImg) != PNG {
		t.Fatal("Image is not png")
	}

	size, _ := Size(newImg)
	if size.Height != height || size.Width != width {
		t.Fatal("Invalid image size")
	}

	err = Write("fixtures/transparent_out.png", newImg)
	if err != nil {
		t.Fatal("Cannot save the image")
	}
}

func benchmarkResize(file string, o Options, b *testing.B) {
	buf, _ := Read(path.Join("fixtures", file))

	for n := 0; n < b.N; n++ {
		Resize(buf, o)
	}
}

func BenchmarkResizeLargeJpeg(b *testing.B) {
	options := Options{
		Width:  800,
		Height: 600,
	}
	benchmarkResize("test.jpg", options, b)
}

func BenchmarkResizePng(b *testing.B) {
	options := Options{
		Width:  200,
		Height: 200,
	}
	benchmarkResize("test.png", options, b)
}
<commit_msg>feat(#15): add benchmark tests<commit_after>package bimg

import (
	"io/ioutil"
	"os"
	"path"
	"testing"
)

func TestResize(t *testing.T) {
	options := Options{Width: 800, Height: 600}
	buf, _ := Read("fixtures/test.jpg")

	newImg, err := Resize(buf, options)
	if err != nil {
		t.Errorf("Resize(imgData, %#v) error: %#v", options, err)
	}

	if DetermineImageType(newImg) != JPEG {
		t.Fatal("Image is not jpeg")
	}

	err = Write("fixtures/test_out.jpg", newImg)
	if err != nil {
		t.Fatal("Cannot save the image")
	}
}

func TestRotate(t *testing.T) {
	options := Options{Width: 800, Height: 600, Rotate: 270}
	buf, _ := Read("fixtures/test.jpg")

	newImg, err := Resize(buf, options)
	if err != nil {
		t.Errorf("Resize(imgData, %#v) error: %#v", options, err)
	}

	if DetermineImageType(newImg) != JPEG {
		t.Fatal("Image is not jpeg")
	}

	err = Write("fixtures/test_rotate_out.jpg", newImg)
	if err != nil {
		t.Fatal("Cannot save the image")
	}
}

func TestInvalidRotate(t *testing.T) {
	options := Options{Width: 800, Height: 600, Rotate: 111}
	buf, _ := Read("fixtures/test.jpg")

	newImg, err := Resize(buf, options)
	if err != nil {
		t.Errorf("Resize(imgData, %#v) error: %#v", options, err)
	}

	if DetermineImageType(newImg) != JPEG {
		t.Fatal("Image is not jpeg")
	}

	err = Write("fixtures/test_invalid_rotate_out.jpg", newImg)
	if err != nil {
		t.Fatal("Cannot save the image")
	}
}

func TestConvert(t *testing.T) {
	width, height := 640, 480

	options := Options{Width: width, Height: height, Crop: true, Type: PNG}
	img, err := os.Open("fixtures/test.jpg")
	if err != nil {
		t.Fatal(err)
	}
	defer img.Close()

	buf, err := ioutil.ReadAll(img)
	if err != nil {
		t.Fatal(err)
	}

	newImg, err := Resize(buf, options)
	if err != nil {
		t.Errorf("Resize(imgData, %#v) error: %#v", options, err)
	}

	if DetermineImageType(newImg) != PNG {
		t.Fatal("Image is not png")
	}

	size, _ := Size(newImg)
	if size.Height != height || size.Width != width {
		t.Fatal("Invalid image size")
	}

	err = Write("fixtures/test_out.png", newImg)
	if err != nil {
		t.Fatal("Cannot save the image")
	}
}

func TestResizePngWithTransparency(t *testing.T) {
	width, height := 300, 240

	options := Options{Width: width, Height: height, Crop: true}
	img, err := os.Open("fixtures/transparent.png")
	if err != nil {
		t.Fatal(err)
	}
	defer img.Close()

	buf, err := ioutil.ReadAll(img)
	if err != nil {
		t.Fatal(err)
	}

	newImg, err := Resize(buf, options)
	if err != nil {
		t.Errorf("Resize(imgData, %#v) error: %#v", options, err)
	}

	if DetermineImageType(newImg) != PNG {
		t.Fatal("Image is not png")
	}

	size, _ := Size(newImg)
	if size.Height != height || size.Width != width {
		t.Fatal("Invalid image size")
	}

	err = Write("fixtures/transparent_out.png", newImg)
	if err != nil {
		t.Fatal("Cannot save the image")
	}
}

func benchmarkResize(file string, o Options, b *testing.B) {
	buf, _ := Read(path.Join("fixtures", file))

	for n := 0; n < b.N; n++ {
		Resize(buf, o)
	}
}

func BenchmarkResizeLargeJpeg(b *testing.B) {
	options := Options{
		Width:  800,
		Height: 600,
	}
	benchmarkResize("test.jpg", options, b)
}

func BenchmarkResizePng(b *testing.B) {
	options := Options{
		Width:  200,
		Height: 200,
	}
	benchmarkResize("test.png", options, b)
}

func BenchmarkResizeWebP(b *testing.B) {
	options := Options{
		Width:  200,
		Height: 200,
	}
	benchmarkResize("test.webp", options, b)
}
<|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/jpeg"
	"image/png"
	"os"
	"reflect"
	"runtime"
	"testing"
)

func expect(t *testing.T, 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 *testing.T, name string) *image.YCbCr {
	file, err := os.Open(name)
	expect(t, err, nil)
	defer file.Close()
	raw, _, err := image.Decode(file)
	expect(t, err, nil)
	yuv, ok := raw.(*image.YCbCr)
	expect(t, ok, true)
	return yuv
}

func writeImage(t *testing.T, 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 resize(t *testing.T, dst, src *image.YCbCr, filter Filter) {
	cfg := AdapterConfig{
		Input: Descriptor{
			Width:  src.Rect.Dx(),
			Height: src.Rect.Dy(),
			Ratio:  GetRatio(src.SubsampleRatio),
		},
		Output: Descriptor{
			Width:  dst.Rect.Dx(),
			Height: dst.Rect.Dy(),
			Ratio:  GetRatio(dst.SubsampleRatio),
		},
	}
	adapter, err := NewAdapter(&cfg, filter)
	expect(t, err, nil)
	err = adapter.Resize(dst, src)
	expect(t, err, nil)
}

func resizeFiles(t *testing.T, w, h int, input, output string, filter Filter) {
	src := readImage(t, input)
	dst := image.NewYCbCr(image.Rect(0, 0, w, h), image.YCbCrSubsampleRatio420)
	resize(t, dst, src, filter)
	writeImage(t, output, dst)
}

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

func TestResize(t *testing.T) {
	sizes := []struct{ w, h int }{
		{128, 128},
		{256, 256},
		{720, 576},
		{1920, 1080},
	}
	for _, f := range filters {
		for _, s := range sizes {
			dst := fmt.Sprintf("testdata/output-%vx%v-%v.png", s.w, s.h, f.Name())
			resizeFiles(t, s.w, s.h, "testdata/lenna.jpg", dst, f)
		}
	}
}

func TestBoundaries(t *testing.T) {
	// test we don't go overread/overwrite even with exotic resolutions
	src := readImage(t, "testdata/lenna.jpg")
	for _, f := range filters {
		tmp := image.NewYCbCr(image.Rect(0, 0, 256, 256), image.YCbCrSubsampleRatio444)
		resize(t, tmp, src, f)
		last := tmp.Rect.Dx()
		for i := 32; i > 0; i >>= 1 {
			last += i
			dst := image.NewYCbCr(image.Rect(0, 0, last, last), image.YCbCrSubsampleRatio444)
			resize(t, dst, tmp, f)
			resize(t, tmp, dst, f)
		}
	}
}
<commit_msg>Add benchmarks<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/jpeg"
	"image/png"
	"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.YCbCr {
	file, err := os.Open(name)
	expect(t, err, nil)
	defer file.Close()
	raw, _, err := image.Decode(file)
	expect(t, err, nil)
	yuv, ok := raw.(*image.YCbCr)
	expect(t, ok, true)
	return yuv
}

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 adapt(t Tester, dst, src *image.YCbCr, filter Filter) Adapter {
	cfg := AdapterConfig{
		Input: Descriptor{
			Width:  src.Rect.Dx(),
			Height: src.Rect.Dy(),
			Ratio:  GetRatio(src.SubsampleRatio),
		},
		Output: Descriptor{
			Width:  dst.Rect.Dx(),
			Height: dst.Rect.Dy(),
			Ratio:  GetRatio(dst.SubsampleRatio),
		},
	}
	adapter, err := NewAdapter(&cfg, filter)
	expect(t, err, nil)
	return adapter
}

func resize(t Tester, dst, src *image.YCbCr, filter Filter) {
	adapter := adapt(t, dst, src, filter)
	err := adapter.Resize(dst, src)
	expect(t, err, nil)
}

func resizeFiles(t Tester, w, h int, input, output string, filter Filter) {
	src := readImage(t, input)
	dst := image.NewYCbCr(image.Rect(0, 0, w, h), image.YCbCrSubsampleRatio420)
	resize(t, dst, src, filter)
	writeImage(t, output, dst)
}

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

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

func TestBoundaries(t *testing.T) {
	// test we don't go overread/overwrite even with exotic resolutions
	src := readImage(t, "testdata/lenna.jpg")
	for _, f := range filters {
		tmp := image.NewYCbCr(image.Rect(0, 0, 256, 256), image.YCbCrSubsampleRatio444)
		resize(t, tmp, src, f)
		last := tmp.Rect.Dx()
		for i := 32; i > 0; i >>= 1 {
			last += i
			dst := image.NewYCbCr(image.Rect(0, 0, last, last), image.YCbCrSubsampleRatio444)
			resize(t, dst, tmp, f)
			resize(t, tmp, dst, f)
		}
	}
}

func benchSpeed(b *testing.B, win, hin int, wout, hout int, filter Filter) {
	raw := readImage(b, "testdata/lenna.jpg")
	src := image.NewYCbCr(image.Rect(0, 0, win, hin), image.YCbCrSubsampleRatio420)
	resize(b, src, raw, filter)
	dst := image.NewYCbCr(image.Rect(0, 0, wout, hout), image.YCbCrSubsampleRatio420)
	adapter := adapt(b, dst, src, filter)
	b.SetBytes(int64(wout*hout*3) >> 1)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		adapter.Resize(dst, src)
	}
}

func BenchmarkBilinearUp(b *testing.B)   { benchSpeed(b, 640, 480, 1920, 1080, NewBilinearFilter()) }
func BenchmarkBilinearDown(b *testing.B) { benchSpeed(b, 1920, 1080, 640, 480, NewBilinearFilter()) }
func BenchmarkBicubicUp(b *testing.B)    { benchSpeed(b, 640, 480, 1920, 1080, NewBicubicFilter()) }
func BenchmarkBicubicDown(b *testing.B)  { benchSpeed(b, 1920, 1080, 640, 480, NewBicubicFilter()) }
func BenchmarkLanczosUp(b *testing.B)    { benchSpeed(b, 640, 480, 1920, 1080, NewLanczosFilter(3)) }
func BenchmarkLanczosDown(b *testing.B)  { benchSpeed(b, 1920, 1080, 640, 480, NewLanczosFilter(3)) }
<|endoftext|>


<commit_before>/*
Package sprockets integrates the power of sprockets ( http://getsprockets.org ) with your go program.

To use in development:
 * Assets go in '/assets'
 * Install the 'rack' and 'sprockets' rubygems
 * run `rackup src/github.com/99designs/goodies/sprockets/config.ru`
 * In your app, call 'NewSprocketsServer("http://localhost:8012", "assets") to get a ViewHelper'
 * Use the ViewHelper to generate links to your assets.
*/
package sprockets

import (
	"html/template"
)

type AssetPipeline interface {
	GetAssetUrl(name string) (template.HTMLAttr, error)
	GetAssetContents(name string) ([]byte, error)
}

type ViewHelper struct {
	AssetPipeline
}

func (vh *ViewHelper) StylesheetLinkTag(name string) (template.HTML, error) {
	url, err := vh.asset_url(name)
	return template.HTML(`<link href="` + template.HTMLEscaper(url) + `" rel="stylesheet" type="text/css">`), err
}

func (vh *ViewHelper) InlineStylesheet(name string) (template.HTML, error) {
	content, err := vh.AssetPipeline.GetAssetContents(name)
	return template.HTML(`<style>` + string(content) + `</style>`), err
}

func (vh *ViewHelper) JavascriptTag(name string) (template.HTML, error) {
	url, err := vh.asset_url(name)
	return template.HTML(`<script src="` + template.HTMLEscaper(url) + `" type="text/javascript"></script>`), err
}

func (vh *ViewHelper) asset_url(name string) (template.HTMLAttr, error) {
	url, err := vh.AssetPipeline.GetAssetUrl(name)
	return template.HTMLAttr(url), err
}
<commit_msg>Support serving assets directly from the asset pipeline<commit_after>/*
Package sprockets integrates the power of sprockets ( http://getsprockets.org ) with your go program.

To use in development:
 * Assets go in '/assets'
 * Install the 'rack' and 'sprockets' rubygems
 * run `rackup src/github.com/99designs/goodies/sprockets/config.ru`
 * In your app, call 'NewSprocketsServer("http://localhost:8012", "assets") to get a ViewHelper'
 * Use the ViewHelper to generate links to your assets.
*/
package sprockets

import (
	"html/template"
	"net/http"
)

type AssetPipeline interface {
	GetAssetUrl(name string) (template.HTMLAttr, error)
	GetAssetContents(name string) ([]byte, error)
}

type ViewHelper struct {
	AssetPipeline
}

func (vh ViewHelper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	c, err := vh.GetAssetContents(r.URL.Path[1:])
	if err != nil {
		http.Error(w, err.Error(), 404)
	} else {
		w.Write(c)
	}
}

func (vh *ViewHelper) StylesheetLinkTag(name string) (template.HTML, error) {
	url, err := vh.asset_url(name)
	return template.HTML(`<link href="` + template.HTMLEscaper(url) + `" rel="stylesheet" type="text/css">`), err
}

func (vh *ViewHelper) InlineStylesheet(name string) (template.HTML, error) {
	content, err := vh.AssetPipeline.GetAssetContents(name)
	return template.HTML(`<style>` + string(content) + `</style>`), err
}

func (vh *ViewHelper) JavascriptTag(name string) (template.HTML, error) {
	url, err := vh.asset_url(name)
	return template.HTML(`<script src="` + template.HTMLEscaper(url) + `" type="text/javascript"></script>`), err
}

func (vh *ViewHelper) asset_url(name string) (template.HTMLAttr, error) {
	url, err := vh.AssetPipeline.GetAssetUrl(name)
	return template.HTMLAttr(url), err
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/rand"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/eaigner/hood"
	"github.com/gorilla/mux"
	_ "github.com/lib/pq"
	"io"
	"log"
	"net/http"
	"os"
	"os/user"
	"time"
)

type Messages struct {
	Id           hood.Id
	Message      string
	DeploymentId int
}

func (m Messages) MarshalJSON() ([]byte, error) {
	return json.Marshal(m.Message)
}

func (m *Messages) UnmarshalJSON(data []byte) error {
	if m == nil {
		*m = Messages{}
	}

	var message string
	if err := json.Unmarshal(data, &message); err != nil {
		return err
	}
	(*m).Message = message

	return nil
}

type Deployments struct {
	Id         hood.Id    `json:"-"`
	Sha        string     `json:"sha"`
	DeployedAt time.Time  `json:"deployed_at"`
	ProjectId  int        `json:"-"`
	Messages   []Messages `sql:"-" json:"messages"`
}

type Projects struct {
	Id        hood.Id   `json:"-"`
	Name      string    `json:"name"`
	ApiToken  string    `json:"api_token"`
	CreatedAt time.Time `json:"created_at"`
}

func Hd() *hood.Hood {
	var revDsn = os.Getenv("REV_DSN")
	if revDsn == "" {
		user, err := user.Current()
		if err != nil {
			log.Fatal(err)
		}
		revDsn = "user=" + user.Username + " dbname=revisioneer sslmode=disable"
	}

	var err error
	hd, err := hood.Open("postgres", revDsn)
	if err != nil {
		log.Fatal("failed to connect to postgres", err)
	}
	hd.Log = true
	return hd
}

func RequireProject(req *http.Request) (Projects, error) {
	hd := Hd()
	defer hd.Db.Close()

	apiToken := req.Header.Get("API-TOKEN")
	var projects []Projects
	hd.Where("api_token", "=", apiToken).Limit(1).Find(&projects)

	if len(projects) != 1 {
		return Projects{}, errors.New("Unknown project")
	}

	return projects[0], nil
}

func ListDeployments(w http.ResponseWriter, req *http.Request) {
	hd := Hd()
	defer hd.Db.Close()

	project, error := RequireProject(req)
	if error != nil {
		http.Error(w, "unknown api token/ project", 500)
		return
	}

	// load deployments
	var deployments []Deployments
	if err := hd.Where("project_id", "=", project.Id).OrderBy("deployed_at").Find(&deployments); err != nil {
		log.Fatal("unable to load deployments", err)
	}

	// load messages for each deployment. N+1 queries
	for i, deployment := range deployments {
		hd.Where("deployment_id", "=", deployment.Id).Find(&deployments[i].Messages)
		if len(deployments[i].Messages) == 0 {
			deployments[i].Messages = make([]Messages, 0)
		}
	}

	b, err := json.Marshal(deployments)
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	if err == nil {
		if string(b) == "null" {
			io.WriteString(w, "[]")
		} else {
			io.WriteString(w, string(b))
		}

	} else {
		io.WriteString(w, "[]")
	}
}

func CreateDeployment(w http.ResponseWriter, req *http.Request) {
	hd := Hd()
	defer hd.Db.Close()

	project, error := RequireProject(req)
	if error != nil {
		http.Error(w, "unknown api token/ project", 500)
		return
	}

	dec := json.NewDecoder(req.Body)

	var deploy Deployments
	if err := dec.Decode(&deploy); err != nil && err != io.EOF {
		log.Fatal("decode error", err)
	} else {
		deploy.DeployedAt = time.Now()
	}
	deploy.ProjectId = int(project.Id)

	_, err := hd.Save(&deploy)
	if err != nil {
		log.Fatal(err)
	}

	for _, message := range deploy.Messages {
		message.DeploymentId = int(deploy.Id)
		_, err = hd.Save(&message)
		if err != nil {
			log.Fatal(err)
		}
	}

	io.WriteString(w, "")
}

const STRLEN = 32

func GenerateApiToken() string {
	bytes := make([]byte, STRLEN)
	rand.Read(bytes)

	encoding := base64.StdEncoding
	encoded := make([]byte, encoding.EncodedLen(len(bytes)))
	encoding.Encode(encoded, bytes)

	return string(encoded)
}

func CreateProject(w http.ResponseWriter, req *http.Request) {
	hd := Hd()
	defer hd.Db.Close()

	dec := json.NewDecoder(req.Body)

	var project Projects
	if err := dec.Decode(&project); err != nil && err != io.EOF {
		log.Fatal("decode error", err)
	} else {
		project.CreatedAt = time.Now()
	}
	project.ApiToken = GenerateApiToken()

	_, err := hd.Save(&project)
	if err != nil {
		log.Fatal(err)
	}

	b, _ := json.Marshal(project)
	io.WriteString(w, string(b))
}

func init() {
	r := mux.NewRouter()
	r.HandleFunc("/deployments", ListDeployments).
		Methods("GET")
	r.HandleFunc("/deployments", CreateDeployment).
		Methods("POST")
	r.HandleFunc("/projects", CreateProject).
		Methods("POST")
	http.Handle("/", r)
}

func main() {
	Hd()

	var port string = os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	fmt.Printf("Server listening on port %s\n", port)

	http.ListenAndServe(":"+port, nil)
}
<commit_msg>support pagination with limit/ page<commit_after>package main

import (
	"crypto/rand"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/eaigner/hood"
	"github.com/gorilla/mux"
	_ "github.com/lib/pq"
	"io"
	"log"
	"math"
	"net/http"
	"os"
	"os/user"
	"strconv"
	"time"
)

type Messages struct {
	Id           hood.Id
	Message      string
	DeploymentId int
}

func (m Messages) MarshalJSON() ([]byte, error) {
	return json.Marshal(m.Message)
}

func (m *Messages) UnmarshalJSON(data []byte) error {
	if m == nil {
		*m = Messages{}
	}

	var message string
	if err := json.Unmarshal(data, &message); err != nil {
		return err
	}
	(*m).Message = message

	return nil
}

type Deployments struct {
	Id         hood.Id    `json:"-"`
	Sha        string     `json:"sha"`
	DeployedAt time.Time  `json:"deployed_at"`
	ProjectId  int        `json:"-"`
	Messages   []Messages `sql:"-" json:"messages"`
}

type Projects struct {
	Id        hood.Id   `json:"-"`
	Name      string    `json:"name"`
	ApiToken  string    `json:"api_token"`
	CreatedAt time.Time `json:"created_at"`
}

func Hd() *hood.Hood {
	var revDsn = os.Getenv("REV_DSN")
	if revDsn == "" {
		user, err := user.Current()
		if err != nil {
			log.Fatal(err)
		}
		revDsn = "user=" + user.Username + " dbname=revisioneer sslmode=disable"
	}

	var err error
	hd, err := hood.Open("postgres", revDsn)
	if err != nil {
		log.Fatal("failed to connect to postgres", err)
	}
	hd.Log = true
	return hd
}

func RequireProject(req *http.Request) (Projects, error) {
	hd := Hd()
	defer hd.Db.Close()

	apiToken := req.Header.Get("API-TOKEN")
	var projects []Projects
	hd.Where("api_token", "=", apiToken).Limit(1).Find(&projects)

	if len(projects) != 1 {
		return Projects{}, errors.New("Unknown project")
	}

	return projects[0], nil
}

func ListDeployments(w http.ResponseWriter, req *http.Request) {
	hd := Hd()
	defer hd.Db.Close()

	project, error := RequireProject(req)
	if error != nil {
		http.Error(w, "unknown api token/ project", 500)
		return
	}

	limit, err := strconv.Atoi(req.URL.Query().Get("limit"))
	if err != nil {
		limit = 20
	}
	limit = int(math.Min(math.Abs(float64(limit)), 100.0))

	var page int
	page, err = strconv.Atoi(req.URL.Query().Get("page"))
	if err != nil {
		page = 1
	}
	page = int(math.Max(float64(page), 1.0))

	// load deployments
	var deployments []Deployments
	err = hd.
		Where("project_id", "=", project.Id).
		OrderBy("deployed_at").
		Desc().
		Offset((page - 1) * limit).
		Limit(limit).
		Find(&deployments)
	if err != nil {
		log.Fatal("unable to load deployments", err)
	}

	// load messages for each deployment. N+1 queries
	for i, deployment := range deployments {
		hd.Where("deployment_id", "=", deployment.Id).Find(&deployments[i].Messages)
		if len(deployments[i].Messages) == 0 {
			deployments[i].Messages = make([]Messages, 0)
		}
	}

	b, err := json.Marshal(deployments)
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	if err == nil {
		if string(b) == "null" {
			io.WriteString(w, "[]")
		} else {
			io.WriteString(w, string(b))
		}

	} else {
		io.WriteString(w, "[]")
	}
}

func CreateDeployment(w http.ResponseWriter, req *http.Request) {
	hd := Hd()
	defer hd.Db.Close()

	project, error := RequireProject(req)
	if error != nil {
		http.Error(w, "unknown api token/ project", 500)
		return
	}

	dec := json.NewDecoder(req.Body)

	var deploy Deployments
	if err := dec.Decode(&deploy); err != nil && err != io.EOF {
		log.Fatal("decode error", err)
	} else {
		deploy.DeployedAt = time.Now()
	}
	deploy.ProjectId = int(project.Id)

	_, err := hd.Save(&deploy)
	if err != nil {
		log.Fatal(err)
	}

	for _, message := range deploy.Messages {
		message.DeploymentId = int(deploy.Id)
		_, err = hd.Save(&message)
		if err != nil {
			log.Fatal(err)
		}
	}

	io.WriteString(w, "")
}

const STRLEN = 32

func GenerateApiToken() string {
	bytes := make([]byte, STRLEN)
	rand.Read(bytes)

	encoding := base64.StdEncoding
	encoded := make([]byte, encoding.EncodedLen(len(bytes)))
	encoding.Encode(encoded, bytes)

	return string(encoded)
}

func CreateProject(w http.ResponseWriter, req *http.Request) {
	hd := Hd()
	defer hd.Db.Close()

	dec := json.NewDecoder(req.Body)

	var project Projects
	if err := dec.Decode(&project); err != nil && err != io.EOF {
		log.Fatal("decode error", err)
	} else {
		project.CreatedAt = time.Now()
	}
	project.ApiToken = GenerateApiToken()

	_, err := hd.Save(&project)
	if err != nil {
		log.Fatal(err)
	}

	b, _ := json.Marshal(project)
	io.WriteString(w, string(b))
}

func init() {
	r := mux.NewRouter()
	r.HandleFunc("/deployments", ListDeployments).
		Methods("GET")
	r.HandleFunc("/deployments", CreateDeployment).
		Methods("POST")
	r.HandleFunc("/projects", CreateProject).
		Methods("POST")
	http.Handle("/", r)
}

func main() {
	Hd()

	var port string = os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	fmt.Printf("Server listening on port %s\n", port)

	http.ListenAndServe(":"+port, nil)
}
<|endoftext|>


<commit_before>package actor

type AutoReceiveMessage interface {
	AutoReceiveMessage()
}

type NotInfluenceReceiveTimeout interface {
	NotInfluenceReceiveTimeout()
}

//SystemMessage is a special type of messages passed to control the actor lifecycles
type SystemMessage interface {
	SystemMessage()
}

type ReceiveTimeout struct{}
type Restarting struct{}
type Stopping struct{}
type Stopped struct{}
type Started struct{}

//TODO: add cause and action?
type Restart struct{}

//TODO: add cause and action?
type Stop struct{}
type ResumeMailbox struct{}
type SuspendMailbox struct{}
type Failure struct {
	Who    *PID
	Reason interface{}
}

func (*Restarting) AutoReceiveMessage() {}
func (*Stopping) AutoReceiveMessage()   {}
func (*Stopped) AutoReceiveMessage()    {}
func (*PoisonPill) AutoReceiveMessage() {}

func (*Started) SystemMessage()    {}
func (*Stop) SystemMessage()           {}
func (*Watch) SystemMessage()          {}
func (*Unwatch) SystemMessage()        {}
func (*Terminated) SystemMessage()     {}
func (*Failure) SystemMessage()        {}
func (*Restart) SystemMessage()        {}
func (*ResumeMailbox) SystemMessage()  {}
func (*SuspendMailbox) SystemMessage() {}

var (
	restartingMessage     interface{} = &Restarting{}
	stoppingMessage       interface{} = &Stopping{}
	stoppedMessage        interface{} = &Stopped{}
	poisonPillMessage     interface{} = &PoisonPill{}
	receiveTimeoutMessage interface{} = &ReceiveTimeout{}
)

var (
	restartMessage        SystemMessage = &Restart{}
	startedMessage        SystemMessage = &Started{}
	stopMessage           SystemMessage = &Stop{}
	resumeMailboxMessage  SystemMessage = &ResumeMailbox{}
	suspendMailboxMessage SystemMessage = &SuspendMailbox{}
)
<commit_msg>gofmt<commit_after>package actor

type AutoReceiveMessage interface {
	AutoReceiveMessage()
}

type NotInfluenceReceiveTimeout interface {
	NotInfluenceReceiveTimeout()
}

//SystemMessage is a special type of messages passed to control the actor lifecycles
type SystemMessage interface {
	SystemMessage()
}

type ReceiveTimeout struct{}
type Restarting struct{}
type Stopping struct{}
type Stopped struct{}
type Started struct{}

//TODO: add cause and action?
type Restart struct{}

//TODO: add cause and action?
type Stop struct{}
type ResumeMailbox struct{}
type SuspendMailbox struct{}
type Failure struct {
	Who    *PID
	Reason interface{}
}

func (*Restarting) AutoReceiveMessage() {}
func (*Stopping) AutoReceiveMessage()   {}
func (*Stopped) AutoReceiveMessage()    {}
func (*PoisonPill) AutoReceiveMessage() {}

func (*Started) SystemMessage()        {}
func (*Stop) SystemMessage()           {}
func (*Watch) SystemMessage()          {}
func (*Unwatch) SystemMessage()        {}
func (*Terminated) SystemMessage()     {}
func (*Failure) SystemMessage()        {}
func (*Restart) SystemMessage()        {}
func (*ResumeMailbox) SystemMessage()  {}
func (*SuspendMailbox) SystemMessage() {}

var (
	restartingMessage     interface{} = &Restarting{}
	stoppingMessage       interface{} = &Stopping{}
	stoppedMessage        interface{} = &Stopped{}
	poisonPillMessage     interface{} = &PoisonPill{}
	receiveTimeoutMessage interface{} = &ReceiveTimeout{}
)

var (
	restartMessage        SystemMessage = &Restart{}
	startedMessage        SystemMessage = &Started{}
	stopMessage           SystemMessage = &Stop{}
	resumeMailboxMessage  SystemMessage = &ResumeMailbox{}
	suspendMailboxMessage SystemMessage = &SuspendMailbox{}
)
<|endoftext|>


<commit_before>package amazonec2

import (
	"errors"
)

type region struct {
	AmiId string
}

// Ubuntu 16.04 LTS 20180228.1 hvm:ebs-ssd (amd64)
// See https://cloud-images.ubuntu.com/locator/ec2/
var regionDetails map[string]*region = map[string]*region{
	"ap-northeast-1":  {"ami-bcb7f6da"},
	"ap-northeast-2":  {"ami-5073de3e"},
	"ap-southeast-1":  {"ami-41e4af3d"},
	"ap-southeast-2":  {"ami-c1498fa3"},
	"ap-south-1":      {"ami-1083dc7f"},
	"ap-east-1":       {"ami-9ca0d8ed"},
	"ca-central-1":    {"ami-8d9e19e9"},
	"cn-north-1":      {"ami-cc4499a1"}, // Note: this is 20180126
	"cn-northwest-1":  {"ami-fd0e1a9f"}, // Note: this is 20180126
	"eu-central-1":    {"ami-bc4925d3"},
	"eu-north-1":      {"ami-017ff17f"},
	"eu-west-1":       {"ami-0b541372"},
	"eu-west-2":       {"ami-ff46a298"},
	"eu-west-3":       {"ami-9465d3e9"},
	"sa-east-1":       {"ami-b5501bd9"},
	"us-east-1":       {"ami-927185ef"},
	"us-east-2":       {"ami-b9daeddc"},
	"us-west-1":       {"ami-264c4646"},
	"us-west-2":       {"ami-78a22900"},
	"us-gov-west-1":   {"ami-2561ea44"},
	"us-gov-east-1":   {"ami-b740a6c6"},
	"custom-endpoint": {""},
}

func awsRegionsList() []string {
	var list []string

	for k := range regionDetails {
		list = append(list, k)
	}

	return list
}

func validateAwsRegion(region string) (string, error) {
	for _, v := range awsRegionsList() {
		if v == region {
			return region, nil
		}
	}

	return "", errors.New("Invalid region specified")
}
<commit_msg>Add ami for af-south-1<commit_after>package amazonec2

import (
	"errors"
)

type region struct {
	AmiId string
}

// Ubuntu 16.04 LTS 20180228.1 hvm:ebs-ssd (amd64)
// See https://cloud-images.ubuntu.com/locator/ec2/
var regionDetails map[string]*region = map[string]*region{
	"af-south-1":      {"ami-03611e0f71e9d9f66"},
	"ap-northeast-1":  {"ami-bcb7f6da"},
	"ap-northeast-2":  {"ami-5073de3e"},
	"ap-southeast-1":  {"ami-41e4af3d"},
	"ap-southeast-2":  {"ami-c1498fa3"},
	"ap-south-1":      {"ami-1083dc7f"},
	"ap-east-1":       {"ami-9ca0d8ed"},
	"ca-central-1":    {"ami-8d9e19e9"},
	"cn-north-1":      {"ami-cc4499a1"}, // Note: this is 20180126
	"cn-northwest-1":  {"ami-fd0e1a9f"}, // Note: this is 20180126
	"eu-central-1":    {"ami-bc4925d3"},
	"eu-north-1":      {"ami-017ff17f"},
	"eu-west-1":       {"ami-0b541372"},
	"eu-west-2":       {"ami-ff46a298"},
	"eu-west-3":       {"ami-9465d3e9"},
	"sa-east-1":       {"ami-b5501bd9"},
	"us-east-1":       {"ami-927185ef"},
	"us-east-2":       {"ami-b9daeddc"},
	"us-west-1":       {"ami-264c4646"},
	"us-west-2":       {"ami-78a22900"},
	"us-gov-west-1":   {"ami-2561ea44"},
	"us-gov-east-1":   {"ami-b740a6c6"},
	"custom-endpoint": {""},
}

func awsRegionsList() []string {
	var list []string

	for k := range regionDetails {
		list = append(list, k)
	}

	return list
}

func validateAwsRegion(region string) (string, error) {
	for _, v := range awsRegionsList() {
		if v == region {
			return region, nil
		}
	}

	return "", errors.New("Invalid region specified")
}
<|endoftext|>


<commit_before>package unittestutils

import (
	"context"
	"path/filepath"
	"testing"
	"time"

	"github.com/kubernetes-sigs/multi-tenancy/tenant/pkg/apis"
	tenancyv1alpha1 "github.com/kubernetes-sigs/multi-tenancy/tenant/pkg/apis/tenancy/v1alpha1"
	tenant "github.com/kubernetes-sigs/multi-tenancy/tenant/pkg/controller/tenant"
	tenantnamespace "github.com/kubernetes-sigs/multi-tenancy/tenant/pkg/controller/tenantnamespace"
	"github.com/onsi/gomega"
	corev1 "k8s.io/api/core/v1"
	v1 "k8s.io/api/rbac/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/cli-runtime/pkg/genericclioptions"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/rest"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/envtest"
	"sigs.k8s.io/controller-runtime/pkg/manager"
)

var cfg *rest.Config
var c client.Client
var err error

const timeout = time.Second * 40

// In future if we want to add more tenants and tenantnamespaces
var tenants []*tenancyv1alpha1.Tenant
var tenantnamespaces []*tenancyv1alpha1.TenantNamespace
var serviceAccount []*corev1.ServiceAccount

type RoleRuleOwner struct {
	Role *v1.Role
}

func CreateCrds() error {
	tr := true
	apis.AddToScheme(scheme.Scheme)

	e := &envtest.Environment{
		CRDDirectoryPaths:  []string{filepath.Join("..", "..", "assets")},
		UseExistingCluster: &tr,
	}

	if cfg, err = e.Start(); err != nil {
		return err
	}
	e.Stop()

	return err
}

func CreateTenant(t *testing.T, g *gomega.WithT, namespace string, serviceAcc string) {

	var sa = &corev1.ServiceAccount{
		TypeMeta: metav1.TypeMeta{
			Kind: "ServiceAccount",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name:      serviceAcc,
			Namespace: "default",
		},
	}

	serviceAccount = append(serviceAccount, sa)

	var tenant1 = &tenancyv1alpha1.Tenant{
		ObjectMeta: metav1.ObjectMeta{
			Name: "tenant1-sample",
		},
		Spec: tenancyv1alpha1.TenantSpec{
			TenantAdminNamespaceName: namespace,
			TenantAdmins: []v1.Subject{
				{
					Kind:      "ServiceAccount",
					Name:      sa.ObjectMeta.Name,
					Namespace: sa.ObjectMeta.Namespace,
				},
			},
		},
	}

	tenants = append(tenants, tenant1)

	var tenantnamespaceOne = &tenancyv1alpha1.TenantNamespace{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "tenant1namespace-sample",
			Namespace: tenant1.Spec.TenantAdminNamespaceName,
		},
		Spec: tenancyv1alpha1.TenantNamespaceSpec{
			Name: "t1-ns1",
		},
	}
	tenantnamespaces = append(tenantnamespaces, tenantnamespaceOne)

	kubecfgFlags := genericclioptions.NewConfigFlags(false)	// Create the K8s clientSet
	cfg, err := kubecfgFlags.ToRESTConfig()
	k8sClient, err := kubernetes.NewForConfig(cfg)
	_, err = k8sClient.CoreV1().Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{})
	if err == nil {
		return
	}

	mgr, err := manager.New(cfg, manager.Options{})
	g.Expect(err).NotTo(gomega.HaveOccurred())

	c = mgr.GetClient()

	recFn, _ := tenant.SetupTestReconcile(tenant.SetupNewReconciler(mgr))
	g.Expect(tenant.AddManager(mgr, recFn)).NotTo(gomega.HaveOccurred())

	recFnTenantNS, _ := tenantnamespace.SetupTestReconcile(tenantnamespace.NewReconciler(mgr))
	g.Expect(tenantnamespace.AddManager(mgr, recFnTenantNS)).NotTo(gomega.HaveOccurred())

	stopMgr, mgrStopped := tenant.StartTestManager(mgr, g)

	defer func() {
		close(stopMgr)
		mgrStopped.Wait()
	}()

	for _, sa := range serviceAccount {
		// Create the service account
		err = c.Create(context.TODO(), sa)
		g.Expect(err).NotTo(gomega.HaveOccurred())
	}

	for _, tenant := range tenants {
		// Create the Tenant object and expect the tenantAdminNamespace to be created
		err = c.Create(context.TODO(), tenant)
		g.Expect(err).NotTo(gomega.HaveOccurred())
		// Wait for the tenantadminnamespace to be created
		nskey := types.NamespacedName{Name: tenant.Spec.TenantAdminNamespaceName}
		adminNs := &corev1.Namespace{}
		g.Eventually(func() error { return c.Get(context.TODO(), nskey, adminNs) }, timeout).Should(gomega.Succeed())
		// Wait for the tenant roles to be created
		rolekey := types.NamespacedName{Name: "tenant-admin-role", Namespace: tenant.Spec.TenantAdminNamespaceName}
		tenantRole := &v1.Role{}
		g.Eventually(func() error { return c.Get(context.TODO(), rolekey, tenantRole) }, timeout).Should(gomega.Succeed())
	}

	for _, tenantnamespaceObj := range tenantnamespaces {
		// Create the tenant namespace obj
		err = c.Create(context.TODO(), tenantnamespaceObj)
		g.Expect(err).NotTo(gomega.HaveOccurred())
		//check if tenantnamespace is created or not
		nskey := types.NamespacedName{Name: tenantnamespaceObj.Spec.Name}
		tenantNs := &corev1.Namespace{}
		g.Eventually(func() error { return c.Get(context.TODO(), nskey, tenantNs) }, timeout).
			Should(gomega.Succeed())
	}

}

func DestroyTenantSA(g *gomega.WithT) {
	// // Delete Service Account
	// fmt.Println("Deleting service accounts")
	// for _, sa := range serviceAccount {
	// 	err = c.Delete(context.TODO(), sa)
	// 	g.Expect(err).NotTo(gomega.HaveOccurred())
	// }

	// // Delete Tenant
	// fmt.Println("Deleting tenants")
	// for _, tenant := range tenants {
	// 	err = c.Delete(context.TODO(), tenant)
	// 	g.Expect(err).NotTo(gomega.HaveOccurred())
	// }

	// // Delete TenantNamespace
	// fmt.Println("Deleting tenant namespaces")
	// for _, tenantnamespace := range tenantnamespaces {
	// 	err = c.Delete(context.TODO(), tenantnamespace)
	// 	g.Expect(err).NotTo(gomega.HaveOccurred())
	// }
}
<commit_msg>removed garbage func<commit_after>package unittestutils

import (
	"context"
	"path/filepath"
	"testing"
	"time"

	"github.com/kubernetes-sigs/multi-tenancy/tenant/pkg/apis"
	tenancyv1alpha1 "github.com/kubernetes-sigs/multi-tenancy/tenant/pkg/apis/tenancy/v1alpha1"
	tenant "github.com/kubernetes-sigs/multi-tenancy/tenant/pkg/controller/tenant"
	tenantnamespace "github.com/kubernetes-sigs/multi-tenancy/tenant/pkg/controller/tenantnamespace"
	"github.com/onsi/gomega"
	corev1 "k8s.io/api/core/v1"
	v1 "k8s.io/api/rbac/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/cli-runtime/pkg/genericclioptions"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/rest"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/envtest"
	"sigs.k8s.io/controller-runtime/pkg/manager"
)

var cfg *rest.Config
var c client.Client
var err error

const timeout = time.Second * 40

// In future if we want to add more tenants and tenantnamespaces
var tenants []*tenancyv1alpha1.Tenant
var tenantnamespaces []*tenancyv1alpha1.TenantNamespace
var serviceAccount []*corev1.ServiceAccount

type RoleRuleOwner struct {
	Role *v1.Role
}

func CreateCrds() error {
	tr := true
	apis.AddToScheme(scheme.Scheme)

	e := &envtest.Environment{
		CRDDirectoryPaths:  []string{filepath.Join("..", "..", "assets")},
		UseExistingCluster: &tr,
	}

	if cfg, err = e.Start(); err != nil {
		return err
	}
	e.Stop()

	return err
}

func CreateTenant(t *testing.T, g *gomega.WithT, namespace string, serviceAcc string) {

	var sa = &corev1.ServiceAccount{
		TypeMeta: metav1.TypeMeta{
			Kind: "ServiceAccount",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name:      serviceAcc,
			Namespace: "default",
		},
	}

	serviceAccount = append(serviceAccount, sa)

	var tenant1 = &tenancyv1alpha1.Tenant{
		ObjectMeta: metav1.ObjectMeta{
			Name: "tenant1-sample",
		},
		Spec: tenancyv1alpha1.TenantSpec{
			TenantAdminNamespaceName: namespace,
			TenantAdmins: []v1.Subject{
				{
					Kind:      "ServiceAccount",
					Name:      sa.ObjectMeta.Name,
					Namespace: sa.ObjectMeta.Namespace,
				},
			},
		},
	}

	tenants = append(tenants, tenant1)

	var tenantnamespaceOne = &tenancyv1alpha1.TenantNamespace{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "tenant1namespace-sample",
			Namespace: tenant1.Spec.TenantAdminNamespaceName,
		},
		Spec: tenancyv1alpha1.TenantNamespaceSpec{
			Name: "t1-ns1",
		},
	}
	tenantnamespaces = append(tenantnamespaces, tenantnamespaceOne)

	kubecfgFlags := genericclioptions.NewConfigFlags(false)	// Create the K8s clientSet
	cfg, err := kubecfgFlags.ToRESTConfig()
	k8sClient, err := kubernetes.NewForConfig(cfg)
	_, err = k8sClient.CoreV1().Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{})
	if err == nil {
		return
	}

	mgr, err := manager.New(cfg, manager.Options{})
	g.Expect(err).NotTo(gomega.HaveOccurred())

	c = mgr.GetClient()

	recFn, _ := tenant.SetupTestReconcile(tenant.SetupNewReconciler(mgr))
	g.Expect(tenant.AddManager(mgr, recFn)).NotTo(gomega.HaveOccurred())

	recFnTenantNS, _ := tenantnamespace.SetupTestReconcile(tenantnamespace.NewReconciler(mgr))
	g.Expect(tenantnamespace.AddManager(mgr, recFnTenantNS)).NotTo(gomega.HaveOccurred())

	stopMgr, mgrStopped := tenant.StartTestManager(mgr, g)

	defer func() {
		close(stopMgr)
		mgrStopped.Wait()
	}()

	for _, sa := range serviceAccount {
		// Create the service account
		err = c.Create(context.TODO(), sa)
		g.Expect(err).NotTo(gomega.HaveOccurred())
	}

	for _, tenant := range tenants {
		// Create the Tenant object and expect the tenantAdminNamespace to be created
		err = c.Create(context.TODO(), tenant)
		g.Expect(err).NotTo(gomega.HaveOccurred())
		// Wait for the tenantadminnamespace to be created
		nskey := types.NamespacedName{Name: tenant.Spec.TenantAdminNamespaceName}
		adminNs := &corev1.Namespace{}
		g.Eventually(func() error { return c.Get(context.TODO(), nskey, adminNs) }, timeout).Should(gomega.Succeed())
		// Wait for the tenant roles to be created
		rolekey := types.NamespacedName{Name: "tenant-admin-role", Namespace: tenant.Spec.TenantAdminNamespaceName}
		tenantRole := &v1.Role{}
		g.Eventually(func() error { return c.Get(context.TODO(), rolekey, tenantRole) }, timeout).Should(gomega.Succeed())
	}

	for _, tenantnamespaceObj := range tenantnamespaces {
		// Create the tenant namespace obj
		err = c.Create(context.TODO(), tenantnamespaceObj)
		g.Expect(err).NotTo(gomega.HaveOccurred())
		//check if tenantnamespace is created or not
		nskey := types.NamespacedName{Name: tenantnamespaceObj.Spec.Name}
		tenantNs := &corev1.Namespace{}
		g.Eventually(func() error { return c.Get(context.TODO(), nskey, tenantNs) }, timeout).
			Should(gomega.Succeed())
	}

}
<|endoftext|>


<commit_before>package addrs

import (
	"fmt"
	"strings"
)

// Resource is an address for a resource block within configuration, which
// contains potentially-multiple resource instances if that configuration
// block uses "count" or "for_each".
type Resource struct {
	referenceable
	Mode ResourceMode
	Type string
	Name string
}

func (r Resource) String() string {
	switch r.Mode {
	case ManagedResourceMode:
		return fmt.Sprintf("%s.%s", r.Type, r.Name)
	case DataResourceMode:
		return fmt.Sprintf("data.%s.%s", r.Type, r.Name)
	default:
		panic(fmt.Errorf("resource address with invalid mode %s", r.Mode))
	}
}

// Instance produces the address for a specific instance of the receiver
// that is idenfied by the given key.
func (r Resource) Instance(key InstanceKey) ResourceInstance {
	return ResourceInstance{
		Resource: r,
		Key:      key,
	}
}

// Absolute returns an AbsResource from the receiver and the given module
// instance address.
func (r Resource) Absolute(module ModuleInstance) AbsResource {
	return AbsResource{
		Module:   module,
		Resource: r,
	}
}

// DefaultProviderConfig returns the address of the provider configuration
// that should be used for the resource identified by the reciever if it
// does not have a provider configuration address explicitly set in
// configuration.
//
// This method is not able to verify that such a configuration exists, nor
// represent the behavior of automatically inheriting certain provider
// configurations from parent modules. It just does a static analysis of the
// receiving address and returns an address to start from, relative to the
// same module that contains the resource.
func (r Resource) DefaultProviderConfig() ProviderConfig {
	typeName := r.Type
	if under := strings.Index(typeName, "_"); under != -1 {
		typeName = typeName[:under]
	}
	return ProviderConfig{
		Type: typeName,
	}
}

// ResourceInstance is an address for a specific instance of a resource.
// When a resource is defined in configuration with "count" or "for_each" it
// produces zero or more instances, which can be addressed using this type.
type ResourceInstance struct {
	referenceable
	Resource Resource
	Key      InstanceKey
}

func (r ResourceInstance) ContainingResource() Resource {
	return r.Resource
}

func (r ResourceInstance) String() string {
	if r.Key == NoKey {
		return r.Resource.String()
	}
	return r.Resource.String() + r.Key.String()
}

// Absolute returns an AbsResourceInstance from the receiver and the given module
// instance address.
func (r ResourceInstance) Absolute(module ModuleInstance) AbsResourceInstance {
	return AbsResourceInstance{
		Module:   module,
		Resource: r,
	}
}

// AbsResource is an absolute address for a resource under a given module path.
type AbsResource struct {
	targetable
	Module   ModuleInstance
	Resource Resource
}

// Resource returns the address of a particular resource within the receiver.
func (m ModuleInstance) Resource(mode ResourceMode, typeName string, name string) AbsResource {
	return AbsResource{
		Module: m,
		Resource: Resource{
			Mode: mode,
			Type: typeName,
			Name: name,
		},
	}
}

// Instance produces the address for a specific instance of the receiver
// that is idenfied by the given key.
func (r AbsResource) Instance(key InstanceKey) AbsResourceInstance {
	return AbsResourceInstance{
		Module:   r.Module,
		Resource: r.Resource.Instance(key),
	}
}

// TargetContains implements Targetable by returning true if the given other
// address is either equal to the receiver or is an instance of the
// receiver.
func (r AbsResource) TargetContains(other Targetable) bool {
	switch to := other.(type) {

	case AbsResource:
		// We'll use our stringification as a cheat-ish way to test for equality.
		return to.String() == r.String()

	case AbsResourceInstance:
		return r.TargetContains(to.ContainingResource())

	default:
		return false

	}
}

func (r AbsResource) String() string {
	if len(r.Module) == 0 {
		return r.Resource.String()
	}
	return fmt.Sprintf("%s.%s", r.Module.String(), r.Resource.String())
}

// AbsResourceInstance is an absolute address for a resource instance under a
// given module path.
type AbsResourceInstance struct {
	targetable
	Module   ModuleInstance
	Resource ResourceInstance
}

// ResourceInstance returns the address of a particular resource instance within the receiver.
func (m ModuleInstance) ResourceInstance(mode ResourceMode, typeName string, name string, key InstanceKey) AbsResourceInstance {
	return AbsResourceInstance{
		Module: m,
		Resource: ResourceInstance{
			Resource: Resource{
				Mode: mode,
				Type: typeName,
				Name: name,
			},
			Key: key,
		},
	}
}

// ContainingResource returns the address of the resource that contains the
// receving resource instance. In other words, it discards the key portion
// of the address to produce an AbsResource value.
func (r AbsResourceInstance) ContainingResource() AbsResource {
	return AbsResource{
		Module:   r.Module,
		Resource: r.Resource.ContainingResource(),
	}
}

// TargetContains implements Targetable by returning true if the given other
// address is equal to the receiver.
func (r AbsResourceInstance) TargetContains(other Targetable) bool {
	switch to := other.(type) {

	case AbsResourceInstance:
		// We'll use our stringification as a cheat-ish way to test for equality.
		return to.String() == r.String()

	default:
		return false

	}
}

func (r AbsResourceInstance) String() string {
	if len(r.Module) == 0 {
		return r.Resource.String()
	}
	return fmt.Sprintf("%s.%s", r.Module.String(), r.Resource.String())
}

// ResourceMode defines which lifecycle applies to a given resource. Each
// resource lifecycle has a slightly different address format.
type ResourceMode rune

//go:generate stringer -type ResourceMode

const (
	// InvalidResourceMode is the zero value of ResourceMode and is not
	// a valid resource mode.
	InvalidResourceMode ResourceMode = 0

	// ManagedResourceMode indicates a managed resource, as defined by
	// "resource" blocks in configuration.
	ManagedResourceMode ResourceMode = 'M'

	// DataResourceMode indicates a data resource, as defined by
	// "data" blocks in configuration.
	DataResourceMode ResourceMode = 'D'
)
<commit_msg>addrs: Resource.String shouldn't ever crash<commit_after>package addrs

import (
	"fmt"
	"strings"
)

// Resource is an address for a resource block within configuration, which
// contains potentially-multiple resource instances if that configuration
// block uses "count" or "for_each".
type Resource struct {
	referenceable
	Mode ResourceMode
	Type string
	Name string
}

func (r Resource) String() string {
	switch r.Mode {
	case ManagedResourceMode:
		return fmt.Sprintf("%s.%s", r.Type, r.Name)
	case DataResourceMode:
		return fmt.Sprintf("data.%s.%s", r.Type, r.Name)
	default:
		// Should never happen, but we'll return a string here rather than
		// crashing just in case it does.
		return fmt.Sprintf("<invalid>.%s.%s", r.Type, r.Name)
	}
}

// Instance produces the address for a specific instance of the receiver
// that is idenfied by the given key.
func (r Resource) Instance(key InstanceKey) ResourceInstance {
	return ResourceInstance{
		Resource: r,
		Key:      key,
	}
}

// Absolute returns an AbsResource from the receiver and the given module
// instance address.
func (r Resource) Absolute(module ModuleInstance) AbsResource {
	return AbsResource{
		Module:   module,
		Resource: r,
	}
}

// DefaultProviderConfig returns the address of the provider configuration
// that should be used for the resource identified by the reciever if it
// does not have a provider configuration address explicitly set in
// configuration.
//
// This method is not able to verify that such a configuration exists, nor
// represent the behavior of automatically inheriting certain provider
// configurations from parent modules. It just does a static analysis of the
// receiving address and returns an address to start from, relative to the
// same module that contains the resource.
func (r Resource) DefaultProviderConfig() ProviderConfig {
	typeName := r.Type
	if under := strings.Index(typeName, "_"); under != -1 {
		typeName = typeName[:under]
	}
	return ProviderConfig{
		Type: typeName,
	}
}

// ResourceInstance is an address for a specific instance of a resource.
// When a resource is defined in configuration with "count" or "for_each" it
// produces zero or more instances, which can be addressed using this type.
type ResourceInstance struct {
	referenceable
	Resource Resource
	Key      InstanceKey
}

func (r ResourceInstance) ContainingResource() Resource {
	return r.Resource
}

func (r ResourceInstance) String() string {
	if r.Key == NoKey {
		return r.Resource.String()
	}
	return r.Resource.String() + r.Key.String()
}

// Absolute returns an AbsResourceInstance from the receiver and the given module
// instance address.
func (r ResourceInstance) Absolute(module ModuleInstance) AbsResourceInstance {
	return AbsResourceInstance{
		Module:   module,
		Resource: r,
	}
}

// AbsResource is an absolute address for a resource under a given module path.
type AbsResource struct {
	targetable
	Module   ModuleInstance
	Resource Resource
}

// Resource returns the address of a particular resource within the receiver.
func (m ModuleInstance) Resource(mode ResourceMode, typeName string, name string) AbsResource {
	return AbsResource{
		Module: m,
		Resource: Resource{
			Mode: mode,
			Type: typeName,
			Name: name,
		},
	}
}

// Instance produces the address for a specific instance of the receiver
// that is idenfied by the given key.
func (r AbsResource) Instance(key InstanceKey) AbsResourceInstance {
	return AbsResourceInstance{
		Module:   r.Module,
		Resource: r.Resource.Instance(key),
	}
}

// TargetContains implements Targetable by returning true if the given other
// address is either equal to the receiver or is an instance of the
// receiver.
func (r AbsResource) TargetContains(other Targetable) bool {
	switch to := other.(type) {

	case AbsResource:
		// We'll use our stringification as a cheat-ish way to test for equality.
		return to.String() == r.String()

	case AbsResourceInstance:
		return r.TargetContains(to.ContainingResource())

	default:
		return false

	}
}

func (r AbsResource) String() string {
	if len(r.Module) == 0 {
		return r.Resource.String()
	}
	return fmt.Sprintf("%s.%s", r.Module.String(), r.Resource.String())
}

// AbsResourceInstance is an absolute address for a resource instance under a
// given module path.
type AbsResourceInstance struct {
	targetable
	Module   ModuleInstance
	Resource ResourceInstance
}

// ResourceInstance returns the address of a particular resource instance within the receiver.
func (m ModuleInstance) ResourceInstance(mode ResourceMode, typeName string, name string, key InstanceKey) AbsResourceInstance {
	return AbsResourceInstance{
		Module: m,
		Resource: ResourceInstance{
			Resource: Resource{
				Mode: mode,
				Type: typeName,
				Name: name,
			},
			Key: key,
		},
	}
}

// ContainingResource returns the address of the resource that contains the
// receving resource instance. In other words, it discards the key portion
// of the address to produce an AbsResource value.
func (r AbsResourceInstance) ContainingResource() AbsResource {
	return AbsResource{
		Module:   r.Module,
		Resource: r.Resource.ContainingResource(),
	}
}

// TargetContains implements Targetable by returning true if the given other
// address is equal to the receiver.
func (r AbsResourceInstance) TargetContains(other Targetable) bool {
	switch to := other.(type) {

	case AbsResourceInstance:
		// We'll use our stringification as a cheat-ish way to test for equality.
		return to.String() == r.String()

	default:
		return false

	}
}

func (r AbsResourceInstance) String() string {
	if len(r.Module) == 0 {
		return r.Resource.String()
	}
	return fmt.Sprintf("%s.%s", r.Module.String(), r.Resource.String())
}

// ResourceMode defines which lifecycle applies to a given resource. Each
// resource lifecycle has a slightly different address format.
type ResourceMode rune

//go:generate stringer -type ResourceMode

const (
	// InvalidResourceMode is the zero value of ResourceMode and is not
	// a valid resource mode.
	InvalidResourceMode ResourceMode = 0

	// ManagedResourceMode indicates a managed resource, as defined by
	// "resource" blocks in configuration.
	ManagedResourceMode ResourceMode = 'M'

	// DataResourceMode indicates a data resource, as defined by
	// "data" blocks in configuration.
	DataResourceMode ResourceMode = 'D'
)
<|endoftext|>


<commit_before>package crlWorker

import (
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"sync"
	"time"

	"github.com/mozilla/tls-observatory/certificate"
	"github.com/mozilla/tls-observatory/worker"
)

var (
	workerName = "crlWorker"
	workerDesc = "Checks certificate CRL (Certificate Revocation List) and reports on certificate revocation"

	httpClient = &http.Client{
		Timeout: 30 * time.Second,
	}
)

type Result struct {
	RevocationTime time.Time
	Revoked bool `json:"revoked"`
}

func init() {
	runner := new(eval)
	worker.RegisterWorker(workerName, worker.Info{Runner: runner, Description: workerDesc})
}

type eval struct{}

// Run implements the worker.Worker interface and is called check CRL status
func (e eval) Run(in worker.Input, resChan chan worker.Result) {
	result := worker.Result{
		WorkerName: workerName,
	}
	crlRes := Result{}

	// Grab first CRL response we can from our certificate
	crlResponses, err := getCRLResponses(in.Certificate)
	if err != nil {
		resChan <- worker.Result{
			Success:    false,
			WorkerName: workerName,
			Errors:     []string{fmt.Sprintf("error getting CRL response, err=%v", err)},
			Result:     nil,
		}
		return
	}
	if len(crlResponses) == 0 {
		resChan <- worker.Result{
			Success:    false,
			WorkerName: workerName,
			Errors:     []string{fmt.Sprintf("no CRL responses received, err=%v", err)},
			Result:     nil,
		}
		return
	}

	// TODO(adam): store all CRL responses
	// TODO(adam): Process all responses? Or just one that's signed?

	certList, err := x509.ParseCRL(crlResponses[0])
	if err != nil {
		resChan <- worker.Result{
			Success:    false,
			WorkerName: workerName,
			Errors:     []string{fmt.Sprintf("error reading CRL response for %s", in.Certificate.ID)},
			Result:     nil,
		}
		return
	}

	// Verify the CRL
	if err = verifyCRL(certList, in.Certificate, in.CertificateChain); err != nil {
		resChan <- worker.Result{
			Success:    false,
			WorkerName: workerName,
			Errors:     []string{fmt.Sprintf("error verifying CRL, err=%v", err)},
			Result:     nil,
		}
		return
	}

	x509Cert, err := in.Certificate.ToX509()
	if err != nil {
		resChan <- worker.Result{
			Success:    false,
			WorkerName: workerName,
			Errors:     []string{fmt.Sprintf("error converting Certificate %s to x509.Certificate, err=%v", in.Certificate.ID, err)},
			Result:     nil,
		}
		return
	}

	// Check if our certificate is in the revoked list
	revoked := certList.TBSCertList.RevokedCertificates
	for i := range revoked {
		if x509Cert.SerialNumber.Cmp(revoked[i].SerialNumber) == 0 {
			// certificate is in revoked list, serials match
			crlRes.RevocationTime = certList.TBSCertList.ThisUpdate
			crlRes.Revoked = true

			if err := in.DBHandle.UpdateCertMarkAsRevoked(in.Certificate.ID, certList.TBSCertList.ThisUpdate); err != nil {
				resChan <- worker.Result{
					Success:    false,
					WorkerName: workerName,
					Errors:     []string{fmt.Sprintf("error update Certificate %s revocation in database, err=%v", in.Certificate.ID, err)},
					Result:     nil,
				}
				return
			}

			// also mark is_valid=false on scans table
			if _, err = in.DBHandle.Exec(`UPDATE scans SET is_valid=false WHERE id=$1`, in.Scanid); err != nil {
				resChan <- worker.Result{
					Success:    false,
					WorkerName: workerName,
					Errors:     []string{fmt.Sprintf("error update Scan %s is_valid in database, err=%v", in.Scanid, err)},
					Result:     nil,
				}
				return
			}

			break
		}
	}

	// Marshal the response
	bs, err := json.Marshal(&crlRes)
	if err != nil {
		result.Success = false
		result.Errors = append(result.Errors, err.Error())
	} else {
		result.Success = true
		result.Result = bs
	}
	resChan <- result
}

// Grab the first CRL response and return it in raw bytes
func getCRLResponses(cert certificate.Certificate) ([][]byte, error) {
	var wg sync.WaitGroup
	var out [][]byte

	crlPoints := cert.X509v3Extensions.CRLDistributionPoints
	wg.Add(len(crlPoints))
	for i := range crlPoints {
		go func(point string, wg *sync.WaitGroup) {
			defer wg.Done()

			resp, err := httpClient.Get(point)
			if err != nil {
				return
			}
			defer resp.Body.Close()
			bs, err := ioutil.ReadAll(resp.Body)
			if err != nil {
				return
			}
			out = append(out, bs)
		}(crlPoints[i], &wg)
	}
	wg.Wait()

	if len(out) > 0 {
		return out, nil
	}
	return nil, fmt.Errorf("Unable to load CRL data for certificate %s", cert.Subject)
}

func verifyCRL(certList *pkix.CertificateList, cert certificate.Certificate, chain *certificate.Chain) error {
	for i := range chain.Certs {
		// each cert is a base64 DER encoded certificate
		raw, err := base64.StdEncoding.DecodeString(chain.Certs[i])
		if err != nil {
			return fmt.Errorf("error decoding base64 DER of Certificate from %s chain, err=%v", chain.Domain, err)
		}
		cert, err := x509.ParseCertificate(raw)
		if err != nil {
			return fmt.Errorf("error reading certificate, err=%v", err)
		}

		// Check if cert signed the CRL response
		if err := cert.CheckCRLSignature(certList); err == nil {
			return nil // cert signed our CRL
		}
	}
	return fmt.Errorf("Unable to verify CRL against %s chain", chain.Domain)
}

// AnalysisPrinter outputs results of comparing a certificate against the CRL(s) contained within
func (eval) AnalysisPrinter(input []byte, printAll interface{}) (results []string, err error) {
	var result Result
	if err := json.Unmarshal(input, &result); err != nil {
		return nil, fmt.Errorf("CRL Worker: failed to parse results: err=%v", err)
	}

	if result.Revoked {
		results = append(results, fmt.Sprintf("* Certificate: Revoked (at %s)", result.RevocationTime.String()))
	} else {
		results = append(results, "* Certificate: Not Revoked")
	}
	return results, nil
}
<commit_msg>crlWorker: use gregjones/httpcache as a caching http client<commit_after>package crlWorker

import (
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"sync"
	"time"

	"github.com/mozilla/tls-observatory/certificate"
	"github.com/mozilla/tls-observatory/worker"

	"github.com/gregjones/httpcache"
	"github.com/gregjones/httpcache/diskcache"
)

var (
	workerName = "crlWorker"
	workerDesc = "Checks certificate CRL (Certificate Revocation List) and reports on certificate revocation"

	// http.Client, which uses a disk backed cache to keep requests down to a minimum
	httpClientCachePath = "/tmp/http-client-cache"
	httpClientCache httpcache.Cache
	httpClientTransport *httpcache.Transport
	httpClient *http.Client
)

type Result struct {
	RevocationTime time.Time
	Revoked bool `json:"revoked"`
}

func init() {
	// initialize http.Client and cache
	if path := os.Getenv("TLSOBS_CRLHTTPCACHE_PATH"); path != "" {
		httpClientCachePath = path
	}
	httpClientCache = diskcache.New(httpClientCachePath)
	httpClientTransport = httpcache.NewTransport(httpClientCache)

	httpClient = httpClientTransport.Client()
	httpClient.Timeout = 30 * time.Second

	// register crlWorker
	runner := new(eval)
	worker.RegisterWorker(workerName, worker.Info{Runner: runner, Description: workerDesc})
}

type eval struct{}

// Run implements the worker.Worker interface and is called check CRL status
func (e eval) Run(in worker.Input, resChan chan worker.Result) {
	result := worker.Result{
		WorkerName: workerName,
	}
	crlRes := Result{}

	// Grab first CRL response we can from our certificate
	crlResponses, err := getCRLResponses(in.Certificate)
	if err != nil {
		resChan <- worker.Result{
			Success:    false,
			WorkerName: workerName,
			Errors:     []string{fmt.Sprintf("error getting CRL response, err=%v", err)},
			Result:     nil,
		}
		return
	}
	if len(crlResponses) == 0 {
		resChan <- worker.Result{
			Success:    false,
			WorkerName: workerName,
			Errors:     []string{fmt.Sprintf("no CRL responses received, err=%v", err)},
			Result:     nil,
		}
		return
	}

	// TODO(adam): store all CRL responses
	// TODO(adam): Process all responses? Or just one that's signed?

	certList, err := x509.ParseCRL(crlResponses[0])
	if err != nil {
		resChan <- worker.Result{
			Success:    false,
			WorkerName: workerName,
			Errors:     []string{fmt.Sprintf("error reading CRL response for %s", in.Certificate.ID)},
			Result:     nil,
		}
		return
	}

	// Verify the CRL
	if err = verifyCRL(certList, in.Certificate, in.CertificateChain); err != nil {
		resChan <- worker.Result{
			Success:    false,
			WorkerName: workerName,
			Errors:     []string{fmt.Sprintf("error verifying CRL, err=%v", err)},
			Result:     nil,
		}
		return
	}

	x509Cert, err := in.Certificate.ToX509()
	if err != nil {
		resChan <- worker.Result{
			Success:    false,
			WorkerName: workerName,
			Errors:     []string{fmt.Sprintf("error converting Certificate %s to x509.Certificate, err=%v", in.Certificate.ID, err)},
			Result:     nil,
		}
		return
	}

	// Check if our certificate is in the revoked list
	revoked := certList.TBSCertList.RevokedCertificates
	for i := range revoked {
		if x509Cert.SerialNumber.Cmp(revoked[i].SerialNumber) == 0 {
			// certificate is in revoked list, serials match
			crlRes.RevocationTime = certList.TBSCertList.ThisUpdate
			crlRes.Revoked = true

			if err := in.DBHandle.UpdateCertMarkAsRevoked(in.Certificate.ID, certList.TBSCertList.ThisUpdate); err != nil {
				resChan <- worker.Result{
					Success:    false,
					WorkerName: workerName,
					Errors:     []string{fmt.Sprintf("error update Certificate %s revocation in database, err=%v", in.Certificate.ID, err)},
					Result:     nil,
				}
				return
			}

			// also mark is_valid=false on scans table
			if _, err = in.DBHandle.Exec(`UPDATE scans SET is_valid=false WHERE id=$1`, in.Scanid); err != nil {
				resChan <- worker.Result{
					Success:    false,
					WorkerName: workerName,
					Errors:     []string{fmt.Sprintf("error update Scan %s is_valid in database, err=%v", in.Scanid, err)},
					Result:     nil,
				}
				return
			}

			break
		}
	}

	// Marshal the response
	bs, err := json.Marshal(&crlRes)
	if err != nil {
		result.Success = false
		result.Errors = append(result.Errors, err.Error())
	} else {
		result.Success = true
		result.Result = bs
	}
	resChan <- result
}

// Grab the first CRL response and return it in raw bytes
func getCRLResponses(cert certificate.Certificate) ([][]byte, error) {
	var wg sync.WaitGroup
	var out [][]byte

	crlPoints := cert.X509v3Extensions.CRLDistributionPoints
	wg.Add(len(crlPoints))
	for i := range crlPoints {
		go func(point string, wg *sync.WaitGroup) {
			defer wg.Done()

			resp, err := httpClient.Get(point)
			if err != nil {
				return
			}
			defer resp.Body.Close()
			bs, err := ioutil.ReadAll(resp.Body)
			if err != nil {
				return
			}
			out = append(out, bs)
		}(crlPoints[i], &wg)
	}
	wg.Wait()

	if len(out) > 0 {
		return out, nil
	}
	return nil, fmt.Errorf("Unable to load CRL data for certificate %s", cert.Subject)
}

func verifyCRL(certList *pkix.CertificateList, cert certificate.Certificate, chain *certificate.Chain) error {
	for i := range chain.Certs {
		// each cert is a base64 DER encoded certificate
		raw, err := base64.StdEncoding.DecodeString(chain.Certs[i])
		if err != nil {
			return fmt.Errorf("error decoding base64 DER of Certificate from %s chain, err=%v", chain.Domain, err)
		}
		cert, err := x509.ParseCertificate(raw)
		if err != nil {
			return fmt.Errorf("error reading certificate, err=%v", err)
		}

		// Check if cert signed the CRL response
		if err := cert.CheckCRLSignature(certList); err == nil {
			return nil // cert signed our CRL
		}
	}
	return fmt.Errorf("Unable to verify CRL against %s chain", chain.Domain)
}

// AnalysisPrinter outputs results of comparing a certificate against the CRL(s) contained within
func (eval) AnalysisPrinter(input []byte, printAll interface{}) (results []string, err error) {
	var result Result
	if err := json.Unmarshal(input, &result); err != nil {
		return nil, fmt.Errorf("CRL Worker: failed to parse results: err=%v", err)
	}

	if result.Revoked {
		results = append(results, fmt.Sprintf("* Certificate: Revoked (at %s)", result.RevocationTime.String()))
	} else {
		results = append(results, "* Certificate: Not Revoked")
	}
	return results, nil
}
<|endoftext|>


<commit_before>package main

import (
	"rtos"
	"sync/fence"

	"sound/samples/8b14k7/piano"

	"stm32/hal/raw/tim"
)

func setupAudioPWM(t *tim.TIM_Periph, pclk uint, sr, max int) {
	sr *= 2  // Perform 2 x oversampling.
	max *= 2 // Avoid rounding during linear interpolation.
	div := uint(sr * max)
	t.PSC.Store(tim.PSC_Bits((pclk+div/2)/div - 1))
	t.ARR.Store(tim.ARR_Bits(max - 1))
	t.CCMR1.Store(6<<tim.OC1Mn | tim.OC1PE)
	t.CCR1.Store(0)
	t.CCER.Store(tim.CC1E)
	t.DIER.Store(tim.UIE)
	t.CR1.Store(tim.ARPE | tim.URS | tim.CEN)
}

type Audio struct {
	Timer *tim.TIM_Periph

	sample []byte
	end    rtos.EventFlag
	k      int
	prev   int
}

func (a *Audio) ISR() {
	t := a.Timer
	s := a.sample
	t.SR.Store(0)
	if a.k == len(s)*2 {
		t.DIER.Store(0)
		a.end.Signal(1)
	} else {
		// Linear interpolation.
		v := int(s[a.k/2])
		if a.k&1 == 0 {
			v = a.prev + v
		} else {
			v *= 2
			a.prev = v
		}
		t.CCR1.Store(tim.CCR1_Bits(v))
		a.k++
	}
}

func (a *Audio) Play(sample []byte) {
	a.sample = sample
	a.prev = int(sample[0])
	a.k = 0
	a.end.Reset(0)
	fence.RW()
	a.Timer.DIER.Store(tim.UIE)
	a.end.Wait(1, 0)
}

var audio Audio

var (
	c2  = (*[8192]byte)(&piano.C2)
	c2s = (*[8192]byte)(&piano.C2s)
	d2  = (*[8192]byte)(&piano.D2)
	d2s = (*[8192]byte)(&piano.D2s)
	e2  = (*[8192]byte)(&piano.E2)
	f2  = (*[8192]byte)(&piano.F2)
	f2s = (*[8192]byte)(&piano.F2s)
	g2  = (*[8192]byte)(&piano.G2)
	g2s = (*[8192]byte)(&piano.G2s)
	a2  = (*[8192]byte)(&piano.A2)
	a2s = (*[8192]byte)(&piano.A2s)
	h2  = (*[8192]byte)(&piano.H2)
	c3  = (*[8192]byte)(&piano.C3)
	c3s = (*[8192]byte)(&piano.C3s)
	d3  = (*[8192]byte)(&piano.D3)
	d3s = (*[8192]byte)(&piano.D3s)
	e3  = (*[8192]byte)(&piano.E3)
	f3  = (*[8192]byte)(&piano.F3)
	f3s = (*[8192]byte)(&piano.F3s)
	g3  = (*[8192]byte)(&piano.G3)
	g3s = (*[8192]byte)(&piano.G3s)
	a3  = (*[8192]byte)(&piano.A3)
	a3s = (*[8192]byte)(&piano.A3s)
	h3  = (*[8192]byte)(&piano.H3)
	c4  = (*[8192]byte)(&piano.C4)
)

type Note struct {
	Sample *[8192]byte
	Delay  int
}

var melody = [...]Note{
	{c2, 100},
	{c2s, 100},
	{d2, 100},
	{d2s, 100},
	{e2, 100},
	{f2, 100},
	{f2s, 100},
	{g2, 100},
	{g2s, 100},
	{a2, 100},
	{a2s, 100},
	{h2, 100},
	{c3, 100},
	{c3s, 400},

	{h2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{g2, 100},
	{g2, 100},
	{a2, 400},

	{g2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{h2, 100},
	{g2, 100},
	{a2, 400},

	{g2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{h2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{g2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{h2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{g2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},
	{g2, 800},

	{g2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},
	{g2, 800},
}
<commit_msg>stm32/examples/minidev/treelights: Some improvements ins Audio.ISR.<commit_after>package main

import (
	"rtos"
	"sync/fence"

	"sound/samples/8b14k7/piano"

	"stm32/hal/raw/tim"
)

func setupAudioPWM(t *tim.TIM_Periph, pclk uint, sr, max int) {
	sr *= 2  // Perform 2 x oversampling.
	max *= 2 // Avoid rounding during linear interpolation.
	div := uint(sr * max)
	t.PSC.Store(tim.PSC_Bits((pclk+div/2)/div - 1))
	t.ARR.Store(tim.ARR_Bits(max - 1))
	t.CCMR1.Store(6<<tim.OC1Mn | tim.OC1PE)
	t.CCR1.Store(0)
	t.CCER.Store(tim.CC1E)
	t.DIER.Store(tim.UIE)
	t.CR1.Store(tim.ARPE | tim.URS | tim.CEN)
}

type Audio struct {
	Timer *tim.TIM_Periph

	snd  []byte
	end  rtos.EventFlag
	n    int
	prev int
}

func (a *Audio) ISR() {
	t := a.Timer
	snd := a.snd
	t.SR.Store(0)
	if a.n>>1 == len(snd) {
		t.DIER.Store(0)
		a.end.Signal(1)
	} else {
		// Linear interpolation.
		var v int
		if a.n&1 == 0 {
			s := int(snd[a.n>>1])
			v = a.prev + s
			a.prev = s
		} else {
			v = 2 * a.prev
		}
		t.CCR1.Store(tim.CCR1_Bits(v))
		a.n++
	}
}

func (a *Audio) Play(snd []byte) {
	a.snd = snd
	a.prev = int(snd[0])
	a.n = 0
	a.end.Reset(0)
	fence.RW()
	a.Timer.DIER.Store(tim.UIE)
	a.end.Wait(1, 0)
}

var audio Audio

var (
	c2  = (*[8192]byte)(&piano.C2)
	c2s = (*[8192]byte)(&piano.C2s)
	d2  = (*[8192]byte)(&piano.D2)
	d2s = (*[8192]byte)(&piano.D2s)
	e2  = (*[8192]byte)(&piano.E2)
	f2  = (*[8192]byte)(&piano.F2)
	f2s = (*[8192]byte)(&piano.F2s)
	g2  = (*[8192]byte)(&piano.G2)
	g2s = (*[8192]byte)(&piano.G2s)
	a2  = (*[8192]byte)(&piano.A2)
	a2s = (*[8192]byte)(&piano.A2s)
	h2  = (*[8192]byte)(&piano.H2)
	c3  = (*[8192]byte)(&piano.C3)
	c3s = (*[8192]byte)(&piano.C3s)
	d3  = (*[8192]byte)(&piano.D3)
	d3s = (*[8192]byte)(&piano.D3s)
	e3  = (*[8192]byte)(&piano.E3)
	f3  = (*[8192]byte)(&piano.F3)
	f3s = (*[8192]byte)(&piano.F3s)
	g3  = (*[8192]byte)(&piano.G3)
	g3s = (*[8192]byte)(&piano.G3s)
	a3  = (*[8192]byte)(&piano.A3)
	a3s = (*[8192]byte)(&piano.A3s)
	h3  = (*[8192]byte)(&piano.H3)
	c4  = (*[8192]byte)(&piano.C4)
)

type Note struct {
	Sample *[8192]byte
	Delay  int
}

var melody = [...]Note{
	{c2, 100},
	{c2s, 100},
	{d2, 100},
	{d2s, 100},
	{e2, 100},
	{f2, 100},
	{f2s, 100},
	{g2, 100},
	{g2s, 100},
	{a2, 100},
	{a2s, 100},
	{h2, 100},
	{c3, 100},
	{c3s, 400},

	{h2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{g2, 100},
	{g2, 100},
	{a2, 400},

	{g2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{h2, 100},
	{g2, 100},
	{a2, 400},

	{g2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{h2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{g2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{h2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},

	{g2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},
	{g2, 800},

	{g2, 100},
	{g2, 100},
	{a2, 100},
	{a2, 100},
	{g2, 800},
}
<|endoftext|>