<commit_before>package generator

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"log"
	"os"
	"reflect"
	"regexp"
	"strconv"
)

type Chart struct {
	ApiVersion  string `yaml:"apiVersion"`
	Name        string `yaml:"name"`
	Version     string `yaml:"version"`
	KubeVersion string `yaml:"kubeVersion"`
	Description string `yaml:"description"`
	Type        string `yaml:"type"`
	Icon        string `yaml:"icon"`
}

type kube struct {
	Parameters []struct {
		Name        string `yaml:"name"`
		Description string `yaml:"description"`
		Required    bool   `yaml:"required"`
		Value       string `yaml:"value"`
	}
	Objects []object
}

type object struct {
	ApiVersion string                 `yaml:"apiVersion"`
	Kind       string                 `yaml:"kind"`
	Metadata   map[string]interface{} //metadata has a unkown structure so we use a generic interface
	Spec       map[string]interface{} `yaml:"spec,omitempty"` //specs are dependent on the kind so we use a generic interface
	Data       map[string]interface{} `yaml:"data,omitempty"` //specs are dependent on the kind so we use a generic interface
}

func createFolderStruct(path string) {
	var chartsFldr string
	var templatesFldr string

	chartsFldr = path + "/charts"
	templatesFldr = path + "/templates"

	if _, err := os.Stat(path); os.IsNotExist(err) {
		os.Mkdir(path, 0700)
	}
	if _, err := os.Stat(chartsFldr); os.IsNotExist(err) {
		os.Mkdir(chartsFldr, 0700)
	}
	if _, err := os.Stat(templatesFldr); os.IsNotExist(err) {
		os.Mkdir(templatesFldr, 0700)
	}
}

func walk(input interface{}) {

	va := reflect.ValueOf(&input).Elem()
	val := va.Elem()

	switch val.Kind() {
	case reflect.Map:
		fmt.Println("***** MAP *******")
		fmt.Println(val)

		for i, k := range val.MapKeys() {
			v := val.MapIndex(k)
			fmt.Println(i, k, v)
			fmt.Println("!!!!!!!! CAN SET: ", v.CanSet())
			walk(v.Interface())

		}
		fmt.Println("CAN SET: ", val.CanSet())
	case reflect.String:
		fmt.Println("***** STRING *******")
		fmt.Println(val)
		fmt.Println("CAN SET: ", val.CanSet())
	default:
		fmt.Println("**** OTHER: ", val.Kind())
		fmt.Println(val)
		fmt.Println("CAN SET: ", val.CanSet())

	}

	/*

		val := reflect.ValueOf(input)

		if val.Kind() == reflect.Map {
			//fmt.Println("MAP!!!!")
			for i, k := range val.MapKeys() {
				v := val.MapIndex(k)
				fmt.Println(i, k, v)
				fmt.Println(val.CanSet())
				walk(v.Interface())

			}
		} else {

			switch val.Kind() {

			case reflect.String:
				fmt.Println("*** FOUND STRING ***")
				fmt.Println(val)
				fmt.Println(val.CanSet())
				fmt.Println("********************")

			default:
				fmt.Println(val.Kind())
			}

		}
	*/
}

func mod(o []byte) []byte {
	str1 := string(o)
	var re = regexp.MustCompile(`(?m)\${([^}]*)}`)
	var substitution = "{{.Values.$1}}"
	str1 = re.ReplaceAllString(str1, substitution)
	return []byte(str1)
}

func genTemplate(objects kube, path string) {
	for x, y := range objects.Objects {

		//get the contents from the object
		content, err := yaml.Marshal(y)
		if err != nil {
			log.Fatal(err)
		}

		//convert the iteration into a string to be used in the filename
		no := strconv.Itoa(x)
		file, err := os.Create(path + "/templates/" + no + "-" + y.Kind + ".yaml")
		if err != nil {
			log.Fatal(err)
		}
		if _, err := file.Write(mod(content)); err != nil {
			log.Fatal(err)
		}
		if err := file.Close(); err != nil {
			log.Fatal(err)
		}
	}
}

func genChart(path string) {
	var c Chart
	c.ApiVersion = "v2"
	c.Name = "test"
	c.Version = "1.0.0"

	cg, err := yaml.Marshal(&c)
	if err != nil {
		log.Fatal(err)
	}

	chartFile, err := os.Create(path + "/Chart.yaml")
	if err != nil {
		log.Fatal(err)
	}

	if _, err := chartFile.Write(cg); err != nil {
		log.Fatal(err)
	}
	if err := chartFile.Close(); err != nil {
		log.Fatal(err)
	}
}

func genValues(parameters kube, path string) {
	m := make(map[interface{}]interface{})

	for _, y := range parameters.Parameters {
		m[y.Name] = y.Value
	}

	content, err := yaml.Marshal(m)
	if err != nil {
		log.Fatal(err)
	}

	file, err := os.Create(path + "/values.yaml")
	if err != nil {
		log.Fatal(err)
	}

	if _, err := file.Write(content); err != nil {
		log.Fatal(err)
	}
}

func Generate(path string, input []byte) {
	createFolderStruct(path)

	var data kube
	err := yaml.Unmarshal(input, &data)
	if err != nil {
		fmt.Println(err)
	}

	genTemplate(data, path)
	genValues(data, path)
	genChart(path)
}
<commit_msg>Adding header text<commit_after>/*
copyright 2019 google llc
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 generator

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"log"
	"os"
	"reflect"
	"regexp"
	"strconv"
)

type Chart struct {
	ApiVersion  string `yaml:"apiVersion"`
	Name        string `yaml:"name"`
	Version     string `yaml:"version"`
	KubeVersion string `yaml:"kubeVersion"`
	Description string `yaml:"description"`
	Type        string `yaml:"type"`
	Icon        string `yaml:"icon"`
}

type kube struct {
	Parameters []struct {
		Name        string `yaml:"name"`
		Description string `yaml:"description"`
		Required    bool   `yaml:"required"`
		Value       string `yaml:"value"`
	}
	Objects []object
}

type object struct {
	ApiVersion string                 `yaml:"apiVersion"`
	Kind       string                 `yaml:"kind"`
	Metadata   map[string]interface{} //metadata has a unkown structure so we use a generic interface
	Spec       map[string]interface{} `yaml:"spec,omitempty"` //specs are dependent on the kind so we use a generic interface
	Data       map[string]interface{} `yaml:"data,omitempty"` //specs are dependent on the kind so we use a generic interface
}

func createFolderStruct(path string) {
	var chartsFldr string
	var templatesFldr string

	chartsFldr = path + "/charts"
	templatesFldr = path + "/templates"

	if _, err := os.Stat(path); os.IsNotExist(err) {
		os.Mkdir(path, 0700)
	}
	if _, err := os.Stat(chartsFldr); os.IsNotExist(err) {
		os.Mkdir(chartsFldr, 0700)
	}
	if _, err := os.Stat(templatesFldr); os.IsNotExist(err) {
		os.Mkdir(templatesFldr, 0700)
	}
}

func walk(input interface{}) {

	va := reflect.ValueOf(&input).Elem()
	val := va.Elem()

	switch val.Kind() {
	case reflect.Map:
		fmt.Println("***** MAP *******")
		fmt.Println(val)

		for i, k := range val.MapKeys() {
			v := val.MapIndex(k)
			fmt.Println(i, k, v)
			fmt.Println("!!!!!!!! CAN SET: ", v.CanSet())
			walk(v.Interface())

		}
		fmt.Println("CAN SET: ", val.CanSet())
	case reflect.String:
		fmt.Println("***** STRING *******")
		fmt.Println(val)
		fmt.Println("CAN SET: ", val.CanSet())
	default:
		fmt.Println("**** OTHER: ", val.Kind())
		fmt.Println(val)
		fmt.Println("CAN SET: ", val.CanSet())

	}

	/*

		val := reflect.ValueOf(input)

		if val.Kind() == reflect.Map {
			//fmt.Println("MAP!!!!")
			for i, k := range val.MapKeys() {
				v := val.MapIndex(k)
				fmt.Println(i, k, v)
				fmt.Println(val.CanSet())
				walk(v.Interface())

			}
		} else {

			switch val.Kind() {

			case reflect.String:
				fmt.Println("*** FOUND STRING ***")
				fmt.Println(val)
				fmt.Println(val.CanSet())
				fmt.Println("********************")

			default:
				fmt.Println(val.Kind())
			}

		}
	*/
}

func mod(o []byte) []byte {
	str1 := string(o)
	var re = regexp.MustCompile(`(?m)\${([^}]*)}`)
	var substitution = "{{.Values.$1}}"
	str1 = re.ReplaceAllString(str1, substitution)
	return []byte(str1)
}

func genTemplate(objects kube, path string) {
	for x, y := range objects.Objects {

		//get the contents from the object
		content, err := yaml.Marshal(y)
		if err != nil {
			log.Fatal(err)
		}

		//convert the iteration into a string to be used in the filename
		no := strconv.Itoa(x)
		file, err := os.Create(path + "/templates/" + no + "-" + y.Kind + ".yaml")
		if err != nil {
			log.Fatal(err)
		}
		if _, err := file.Write(mod(content)); err != nil {
			log.Fatal(err)
		}
		if err := file.Close(); err != nil {
			log.Fatal(err)
		}
	}
}

func genChart(path string) {
	var c Chart
	c.ApiVersion = "v2"
	c.Name = "test"
	c.Version = "1.0.0"

	cg, err := yaml.Marshal(&c)
	if err != nil {
		log.Fatal(err)
	}

	chartFile, err := os.Create(path + "/Chart.yaml")
	if err != nil {
		log.Fatal(err)
	}

	if _, err := chartFile.Write(cg); err != nil {
		log.Fatal(err)
	}
	if err := chartFile.Close(); err != nil {
		log.Fatal(err)
	}
}

func genValues(parameters kube, path string) {
	m := make(map[interface{}]interface{})

	for _, y := range parameters.Parameters {
		m[y.Name] = y.Value
	}

	content, err := yaml.Marshal(m)
	if err != nil {
		log.Fatal(err)
	}

	file, err := os.Create(path + "/values.yaml")
	if err != nil {
		log.Fatal(err)
	}

	if _, err := file.Write(content); err != nil {
		log.Fatal(err)
	}
}

func Generate(path string, input []byte) {
	createFolderStruct(path)

	var data kube
	err := yaml.Unmarshal(input, &data)
	if err != nil {
		fmt.Println(err)
	}

	genTemplate(data, path)
	genValues(data, path)
	genChart(path)
}
<|endoftext|>


<commit_before>package migrations

import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"

func addDashboardSnapshotMigrations(mg *Migrator) {
	snapshotV4 := Table{
		Name: "dashboard_snapshot",
		Columns: []*Column{
			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
			{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "key", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "dashboard", Type: DB_Text, Nullable: false},
			{Name: "expires", Type: DB_DateTime, Nullable: false},
			{Name: "created", Type: DB_DateTime, Nullable: false},
			{Name: "updated", Type: DB_DateTime, Nullable: false},
		},
		Indices: []*Index{
			{Cols: []string{"key"}, Type: UniqueIndex},
		},
	}

	// add v4
	mg.AddMigration("create dashboard_snapshot table v4", NewAddTableMigration(snapshotV4))
	mg.AddMigration("drop table dashboard_snapshot_v4 #1", NewDropTableMigration("dashboard_snapshot"))

	snapshotV5 := Table{
		Name: "dashboard_snapshot",
		Columns: []*Column{
			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
			{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "key", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "delete_key", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "org_id", Type: DB_BigInt, Nullable: false},
			{Name: "user_id", Type: DB_BigInt, Nullable: false},
			{Name: "external", Type: DB_Bool, Nullable: false},
			{Name: "external_url", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "dashboard", Type: DB_Text, Nullable: false},
			{Name: "expires", Type: DB_DateTime, Nullable: false},
			{Name: "created", Type: DB_DateTime, Nullable: false},
			{Name: "updated", Type: DB_DateTime, Nullable: false},
		},
		Indices: []*Index{
			{Cols: []string{"key"}, Type: UniqueIndex},
			{Cols: []string{"delete_key"}, Type: UniqueIndex},
			{Cols: []string{"user_id"}},
		},
	}

	mg.AddMigration("create dashboard_snapshot table v5 #2", NewAddTableMigration(snapshotV5))
	addTableIndicesMigrations(mg, "v5", snapshotV5)

	// change column type of dashboard
	mg.AddMigration("alter dashboard_snapshot to mediumtext v2", new(RawSqlMigration).
		Sqlite("SELECT 0 WHERE 0;").
		Postgres("SELECT 0;").
		Mysql("ALTER TABLE dashboard_snapshot MODIFY dashboard MEDIUMTEXT;"))
}
<commit_msg>Added columns in dashboard_snapshot<commit_after>package migrations

import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"

func addDashboardSnapshotMigrations(mg *Migrator) {
	snapshotV4 := Table{
		Name: "dashboard_snapshot",
		Columns: []*Column{
			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
			{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "key", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "dashboard", Type: DB_Text, Nullable: false},
			{Name: "expires", Type: DB_DateTime, Nullable: false},
			{Name: "created", Type: DB_DateTime, Nullable: false},
			{Name: "updated", Type: DB_DateTime, Nullable: false},
		},
		Indices: []*Index{
			{Cols: []string{"key"}, Type: UniqueIndex},
		},
	}

	// add v4
	mg.AddMigration("create dashboard_snapshot table v4", NewAddTableMigration(snapshotV4))
	mg.AddMigration("drop table dashboard_snapshot_v4 #1", NewDropTableMigration("dashboard_snapshot"))

	snapshotV5 := Table{
		Name: "dashboard_snapshot",
		Columns: []*Column{
			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
			{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "key", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "delete_key", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "org_id", Type: DB_BigInt, Nullable: false},
			{Name: "user_id", Type: DB_BigInt, Nullable: false},
			{Name: "external", Type: DB_Bool, Nullable: false},
			{Name: "external_url", Type: DB_NVarchar, Length: 255, Nullable: false},
			{Name: "dashboard", Type: DB_Text, Nullable: false},
			{Name: "expires", Type: DB_DateTime, Nullable: false},
			{Name: "created", Type: DB_DateTime, Nullable: false},
			{Name: "updated", Type: DB_DateTime, Nullable: false},
		},
		Indices: []*Index{
			{Cols: []string{"key"}, Type: UniqueIndex},
			{Cols: []string{"delete_key"}, Type: UniqueIndex},
			{Cols: []string{"user_id"}},
		},
	}

	mg.AddMigration("create dashboard_snapshot table v5 #2", NewAddTableMigration(snapshotV5))
	addTableIndicesMigrations(mg, "v5", snapshotV5)

	// change column type of dashboard
	mg.AddMigration("alter dashboard_snapshot to mediumtext v2", new(RawSqlMigration).
		Sqlite("SELECT 0 WHERE 0;").
		Postgres("SELECT 0;").
		Mysql("ALTER TABLE dashboard_snapshot MODIFY dashboard MEDIUMTEXT;"))

	// add column to store creator of a dashboard snapshot
	mg.AddMigration("Add column created_by in dashboard_snapshot", NewAddColumnMigration(snapshotV5, &Column{
		Name: "created_by", Type: DB_BigInt, Nullable: true,
	}))

	// add column to store updater of a dashboard snapshot
	mg.AddMigration("Add column updated_by in dashboard_snapshot", NewAddColumnMigration(snapshotV5, &Column{
		Name: "updated_by", Type: DB_BigInt, Nullable: true,
	}))

}
<|endoftext|>


<commit_before>/*
// Copyright (c) 2016 Intel Corporation
//
// 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 qemu

import (
	//	"fmt"
	"strings"
	"testing"
)

func testAppend(structure interface{}, expected string, t *testing.T) {
	var params []string

	switch s := structure.(type) {
	case Machine:
		config := Config{
			Machine: s,
		}

		params = appendMachine([]string{}, config)

	case Device:
		config := Config{
			Devices: []Device{s},
		}

		params = appendDevices([]string{}, config)

	case Object:
		config := Config{
			Objects: []Object{s},
		}

		params = appendObjects([]string{}, config)

	case Knobs:
		config := Config{
			Knobs: s,
		}

		params = appendKnobs([]string{}, config)

	case Kernel:
		config := Config{
			Kernel: s,
		}

		params = appendKernel([]string{}, config)

	case Memory:
		config := Config{
			Memory: s,
		}

		params = appendMemory([]string{}, config)

	case SMP:
		config := Config{
			SMP: s,
		}

		params = appendCPUs([]string{}, config)
	}

	result := strings.Join(params, " ")
	if result != expected {
		t.Fatalf("Failed to append parameters [%s] != [%s]", result, expected)
	}
}

var machineString = "-machine pc-lite,accel=kvm,kernel_irqchip,nvdimm"

func TestAppendMachine(t *testing.T) {
	machine := Machine{
		Type:         "pc-lite",
		Acceleration: "kvm,kernel_irqchip,nvdimm",
	}

	testAppend(machine, machineString, t)
}

func TestAppendEmptyMachine(t *testing.T) {
	machine := Machine{}

	testAppend(machine, "", t)
}

var deviceNVDIMMString = "-device nvdimm,id=nv0,memdev=mem0"

func TestAppendDeviceNVDIMM(t *testing.T) {
	device := Device{
		Type:   "nvdimm",
		ID:     "nv0",
		MemDev: "mem0",
	}

	testAppend(device, deviceNVDIMMString, t)
}

var deviceFSString = "-device virtio-9p-pci,fsdev=workload9p,mount_tag=rootfs"

func TestAppendDeviceFS(t *testing.T) {
	device := Device{
		Type:     "virtio-9p-pci",
		FSDev:    "workload9p",
		MountTag: "rootfs",
	}

	testAppend(device, deviceFSString, t)
}

func TestAppendEmptyDevice(t *testing.T) {
	device := Device{}

	testAppend(device, "", t)
}

var objectMemoryString = "-object memory-backend-file,id=mem0,mem-path=/root,size=65536"

func TestAppendObjectMemory(t *testing.T) {
	object := Object{
		Type:    "memory-backend-file",
		ID:      "mem0",
		MemPath: "/root",
		Size:    1 << 16,
	}

	testAppend(object, objectMemoryString, t)
}

func TestAppendEmptyObject(t *testing.T) {
	device := Device{}

	testAppend(device, "", t)
}

var knobsString = "-no-user-config -nodefaults -nographic"

func TestAppendKnobsAllTrue(t *testing.T) {
	knobs := Knobs{
		NoUserConfig: true,
		NoDefaults:   true,
		NoGraphic:    true,
	}

	testAppend(knobs, knobsString, t)
}

func TestAppendKnobsAllFalse(t *testing.T) {
	knobs := Knobs{
		NoUserConfig: false,
		NoDefaults:   false,
		NoGraphic:    false,
	}

	testAppend(knobs, "", t)
}

var kernelString = "-kernel /opt/vmlinux.container -append root=/dev/pmem0p1 rootflags=dax,data=ordered,errors=remount-ro rw rootfstype=ext4 tsc=reliable"

func TestAppendKernel(t *testing.T) {
	kernel := Kernel{
		Path:   "/opt/vmlinux.container",
		Params: "root=/dev/pmem0p1 rootflags=dax,data=ordered,errors=remount-ro rw rootfstype=ext4 tsc=reliable",
	}

	testAppend(kernel, kernelString, t)
}

var memoryString = "-m 2G,slots=2,maxmem=3G"

func TestAppendMemory(t *testing.T) {
	memory := Memory{
		Size:   "2G",
		Slots:  2,
		MaxMem: "3G",
	}

	testAppend(memory, memoryString, t)
}

var cpusString = "-smp 2,cores=1,threads=2,sockets=2"

func TestAppendCPUs(t *testing.T) {
	smp := SMP{
		CPUs:    2,
		Sockets: 2,
		Cores:   1,
		Threads: 2,
	}

	testAppend(smp, cpusString, t)
}
<commit_msg>qemu: Add QMP socket unit tests<commit_after>/*
// Copyright (c) 2016 Intel Corporation
//
// 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 qemu

import (
	//	"fmt"
	"strings"
	"testing"
)

func testAppend(structure interface{}, expected string, t *testing.T) {
	var params []string

	switch s := structure.(type) {
	case Machine:
		config := Config{
			Machine: s,
		}

		params = appendMachine([]string{}, config)

	case Device:
		config := Config{
			Devices: []Device{s},
		}

		params = appendDevices([]string{}, config)

	case Object:
		config := Config{
			Objects: []Object{s},
		}

		params = appendObjects([]string{}, config)

	case Knobs:
		config := Config{
			Knobs: s,
		}

		params = appendKnobs([]string{}, config)

	case Kernel:
		config := Config{
			Kernel: s,
		}

		params = appendKernel([]string{}, config)

	case Memory:
		config := Config{
			Memory: s,
		}

		params = appendMemory([]string{}, config)

	case SMP:
		config := Config{
			SMP: s,
		}

		params = appendCPUs([]string{}, config)

	case QMPSocket:
		config := Config{
			QMPSocket: s,
		}

		params = appendQMPSocket([]string{}, config)
	}

	result := strings.Join(params, " ")
	if result != expected {
		t.Fatalf("Failed to append parameters [%s] != [%s]", result, expected)
	}
}

var machineString = "-machine pc-lite,accel=kvm,kernel_irqchip,nvdimm"

func TestAppendMachine(t *testing.T) {
	machine := Machine{
		Type:         "pc-lite",
		Acceleration: "kvm,kernel_irqchip,nvdimm",
	}

	testAppend(machine, machineString, t)
}

func TestAppendEmptyMachine(t *testing.T) {
	machine := Machine{}

	testAppend(machine, "", t)
}

var deviceNVDIMMString = "-device nvdimm,id=nv0,memdev=mem0"

func TestAppendDeviceNVDIMM(t *testing.T) {
	device := Device{
		Type:   "nvdimm",
		ID:     "nv0",
		MemDev: "mem0",
	}

	testAppend(device, deviceNVDIMMString, t)
}

var deviceFSString = "-device virtio-9p-pci,fsdev=workload9p,mount_tag=rootfs"

func TestAppendDeviceFS(t *testing.T) {
	device := Device{
		Type:     "virtio-9p-pci",
		FSDev:    "workload9p",
		MountTag: "rootfs",
	}

	testAppend(device, deviceFSString, t)
}

func TestAppendEmptyDevice(t *testing.T) {
	device := Device{}

	testAppend(device, "", t)
}

var objectMemoryString = "-object memory-backend-file,id=mem0,mem-path=/root,size=65536"

func TestAppendObjectMemory(t *testing.T) {
	object := Object{
		Type:    "memory-backend-file",
		ID:      "mem0",
		MemPath: "/root",
		Size:    1 << 16,
	}

	testAppend(object, objectMemoryString, t)
}

func TestAppendEmptyObject(t *testing.T) {
	device := Device{}

	testAppend(device, "", t)
}

var knobsString = "-no-user-config -nodefaults -nographic"

func TestAppendKnobsAllTrue(t *testing.T) {
	knobs := Knobs{
		NoUserConfig: true,
		NoDefaults:   true,
		NoGraphic:    true,
	}

	testAppend(knobs, knobsString, t)
}

func TestAppendKnobsAllFalse(t *testing.T) {
	knobs := Knobs{
		NoUserConfig: false,
		NoDefaults:   false,
		NoGraphic:    false,
	}

	testAppend(knobs, "", t)
}

var kernelString = "-kernel /opt/vmlinux.container -append root=/dev/pmem0p1 rootflags=dax,data=ordered,errors=remount-ro rw rootfstype=ext4 tsc=reliable"

func TestAppendKernel(t *testing.T) {
	kernel := Kernel{
		Path:   "/opt/vmlinux.container",
		Params: "root=/dev/pmem0p1 rootflags=dax,data=ordered,errors=remount-ro rw rootfstype=ext4 tsc=reliable",
	}

	testAppend(kernel, kernelString, t)
}

var memoryString = "-m 2G,slots=2,maxmem=3G"

func TestAppendMemory(t *testing.T) {
	memory := Memory{
		Size:   "2G",
		Slots:  2,
		MaxMem: "3G",
	}

	testAppend(memory, memoryString, t)
}

var cpusString = "-smp 2,cores=1,threads=2,sockets=2"

func TestAppendCPUs(t *testing.T) {
	smp := SMP{
		CPUs:    2,
		Sockets: 2,
		Cores:   1,
		Threads: 2,
	}

	testAppend(smp, cpusString, t)
}

var qmpSocketServerString = "-qmp unix:cc-qmp,server,nowait"
var qmpSocketString = "-qmp unix:cc-qmp"

func TestAppendQMPSocketServer(t *testing.T) {
	qmp := QMPSocket{
		Type:   "unix",
		Name:   "cc-qmp",
		Server: true,
		NoWait: true,
	}

	testAppend(qmp, qmpSocketServerString, t)
}

func TestAppendQMPSocket(t *testing.T) {
	qmp := QMPSocket{
		Type:   "unix",
		Name:   "cc-qmp",
		Server: false,
	}

	testAppend(qmp, qmpSocketString, t)
}
<|endoftext|>


<commit_before>/* Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 siesta

import (
	crand "crypto/rand"
	"math/rand"
	"net"
	"reflect"
	"testing"
	"runtime"
)

const TCPListenerAddress = "localhost:4455"

func assert(t *testing.T, actual interface{}, expected interface{}) {
	if !reflect.DeepEqual(actual, expected) {
		_, fn, line, _ := runtime.Caller(1)
		t.Errorf("Expected %v, actual %v\n@%s:%d", expected, actual, fn, line)
	}
}

func checkErr(t *testing.T, err error) {
	if err != nil {
		_, fn, line, _ := runtime.Caller(1)
		t.Errorf("%s\n @%s:%d", err, fn, line)
	}
}

func randomBytes(n int) []byte {
	b := make([]byte, n)
	crand.Read(b)
	return b
}

func randomString(n int) string {
	letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZйцукенгшщзхъфывапролджэжячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ0123456789!@#$%^&*()")

	b := make([]rune, n)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}
	return string(b)[:n]
}

func testRequest(t *testing.T, request Request, expected []byte) {
	sizing := NewSizingEncoder()
	request.Write(sizing)
	bytes := make([]byte, sizing.Size())
	encoder := NewBinaryEncoder(bytes)
	request.Write(encoder)

	assert(t, bytes, expected)
}

func decode(t *testing.T, response Response, bytes []byte) {
	decoder := NewBinaryDecoder(bytes)
	err := response.Read(decoder)
	checkErr(t, err)
}

func awaitForTCPRequestAndReturn(t *testing.T, bufferSize int, resultChannel chan []byte) {
	netName := "tcp"
	addr, _ := net.ResolveTCPAddr(netName, "localhost:4455")
	listener, err := net.ListenTCP(netName, addr)
	if err != nil {
		t.Errorf("Unable to start tcp request listener: %s", err)
	}

	buffer := make([]byte, bufferSize)
	conn, err := listener.AcceptTCP()
	if err != nil {
		t.Error(err)
	}
	_, err = conn.Read(buffer)
	if err != nil {
		t.Error(err)
	}

	resultChannel <- buffer
}
<commit_msg>changed port value<commit_after>/* Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 siesta

import (
	crand "crypto/rand"
	"math/rand"
	"net"
	"reflect"
	"testing"
	"runtime"
)

const TCPListenerAddress = "localhost:8093"

func assert(t *testing.T, actual interface{}, expected interface{}) {
	if !reflect.DeepEqual(actual, expected) {
		_, fn, line, _ := runtime.Caller(1)
		t.Errorf("Expected %v, actual %v\n@%s:%d", expected, actual, fn, line)
	}
}

func checkErr(t *testing.T, err error) {
	if err != nil {
		_, fn, line, _ := runtime.Caller(1)
		t.Errorf("%s\n @%s:%d", err, fn, line)
	}
}

func randomBytes(n int) []byte {
	b := make([]byte, n)
	crand.Read(b)
	return b
}

func randomString(n int) string {
	letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZйцукенгшщзхъфывапролджэжячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ0123456789!@#$%^&*()")

	b := make([]rune, n)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}
	return string(b)[:n]
}

func testRequest(t *testing.T, request Request, expected []byte) {
	sizing := NewSizingEncoder()
	request.Write(sizing)
	bytes := make([]byte, sizing.Size())
	encoder := NewBinaryEncoder(bytes)
	request.Write(encoder)

	assert(t, bytes, expected)
}

func decode(t *testing.T, response Response, bytes []byte) {
	decoder := NewBinaryDecoder(bytes)
	err := response.Read(decoder)
	checkErr(t, err)
}

func awaitForTCPRequestAndReturn(t *testing.T, bufferSize int, resultChannel chan []byte) {
	netName := "tcp"
	addr, _ := net.ResolveTCPAddr(netName, TCPListenerAddress)
	listener, err := net.ListenTCP(netName, addr)
	if err != nil {
		t.Errorf("Unable to start tcp request listener: %s", err)
	}

	buffer := make([]byte, bufferSize)
	conn, err := listener.AcceptTCP()
	if err != nil {
		t.Error(err)
	}
	_, err = conn.Read(buffer)
	if err != nil {
		t.Error(err)
	}

	resultChannel <- buffer
}
<|endoftext|>


<commit_before>package tau

import (
	"log"
	"testing"
	"time"
)

type TestTime struct {
	time.Time
	current time.Time
}

func (t TestTime) Since() Tau {
	return Tau(t.current.Sub(t.Time) / 1e9)
}

// newTestTime creates a deterministic TestTime for given value and current time.
func newTestTime(current, value string) TestTime {
	layout := "2006-01-02 15:04" // a simple time layout
	parse := func(s string) time.Time {
		t, err := time.Parse(layout, s)
		if err != nil {
			log.Fatalf("got err: %v\n", err)
		}
		return t

	}
	return TestTime{
		Time:    parse(value),
		current: parse(current),
	}
}

func TestTau(t *testing.T) {
	cases := []struct {
		in   Time
		want Tau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: Tau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:14"),
			want: Tau(999960),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:13"),
			want: Tau(1000020),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: Tau(1000000020),
		},
		{
			in:   newTestTime("2019-03-10 18:34", "1955-10-24 15:00"),
			want: Tau(2000000040),
		},
	}

	for i, tt := range cases {
		out := TauSince(tt.in)
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v) => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}

}

func TestMegaTau(t *testing.T) {
	cases := []struct {
		in   Time
		want MegaTau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: MegaTau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:14"),
			want: MegaTau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:13"),
			want: MegaTau(1),
		},
		{
			in:   newTestTime("2016-11-26 16:46", "1985-03-20 15:00"),
			want: MegaTau(999),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: MegaTau(1000),
		},
		{
			in:   newTestTime("2014-12-03 17:47", "1983-03-27 15:00"),
			want: MegaTau(1000),
		},
		{
			in:   newTestTime("2015-06-26 15:00", "1983-03-27 15:00"),
			want: MegaTau(1017),
		},
		{
			in:   newTestTime("2015-06-26 15:00", "1985-03-20 15:00"),
			want: MegaTau(955),
		},
		{
			// TODO(hkjn): This is the largest time span that can be
			// represented with time.Duration. Add more test cases once this
			// limitation is removed.
			in:   newTestTime("2277-06-25 07:26", "1985-03-20 15:00"),
			want: MegaTau(9222),
		},
	}
	for i, tt := range cases {
		out := TauSince(tt.in).Mega()
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v).Mega() => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}
}

func TestGigaTau(t *testing.T) {
	cases := []struct {
		in   Time
		want GigaTau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: GigaTau(0),
		},
		{
			in:   newTestTime("2016-11-26 16:46", "1985-03-20 15:00"),
			want: GigaTau(0),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: GigaTau(1),
		},
		{
			in:   newTestTime("2019-03-10 18:34", "1955-10-24 15:00"),
			want: GigaTau(2),
		},
		{
			in:   newTestTime("2277-06-25 07:26", "1985-03-20 15:00"),
			want: GigaTau(9),
		},
	}
	for i, tt := range cases {
		out := TauSince(tt.in).Giga()
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v).Giga() => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}
}
<commit_msg>Add some test cases<commit_after>package tau

import (
	"log"
	"testing"
	"time"
)

type TestTime struct {
	time.Time
	current time.Time
}

func (t TestTime) Since() Tau {
	return Tau(t.current.Sub(t.Time) / 1e9)
}

// newTestTime creates a deterministic TestTime for given value and current time.
func newTestTime(current, value string) TestTime {
	layout := "2006-01-02 15:04" // a simple time layout
	parse := func(s string) time.Time {
		t, err := time.Parse(layout, s)
		if err != nil {
			log.Fatalf("got err: %v\n", err)
		}
		return t

	}
	return TestTime{
		Time:    parse(value),
		current: parse(current),
	}
}

func TestTau(t *testing.T) {
	cases := []struct {
		in   Time
		want Tau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: Tau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:14"),
			want: Tau(999960),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:13"),
			want: Tau(1000020),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: Tau(1000000020),
		},
		{
			in:   newTestTime("2019-03-10 18:34", "1955-10-24 15:00"),
			want: Tau(2000000040),
		},
	}

	for i, tt := range cases {
		out := TauSince(tt.in)
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v) => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}

}

func TestMegaTau(t *testing.T) {
	cases := []struct {
		in   Time
		want MegaTau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: MegaTau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:14"),
			want: MegaTau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:13"),
			want: MegaTau(1),
		},
		{
			in:   newTestTime("2016-11-26 16:46", "1985-03-20 15:00"),
			want: MegaTau(999),
		},
		{
			in:   newTestTime("2015-05-09 09:00", "1985-03-20 15:00"),
			want: MegaTau(950),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: MegaTau(1000),
		},
		{
			in:   newTestTime("2018-06-30 12:00", "1985-03-20 15:00"),
			want: MegaTau(1050),
		},
		{
			in:   newTestTime("2014-12-03 17:47", "1983-03-27 15:00"),
			want: MegaTau(1000),
		},
		{
			in:   newTestTime("2015-06-26 15:00", "1983-03-27 15:00"),
			want: MegaTau(1017),
		},
		{
			in:   newTestTime("2015-06-26 15:00", "1985-03-20 15:00"),
			want: MegaTau(955),
		},
		{
			// TODO(hkjn): This is the largest time span that can be
			// represented with time.Duration. Add more test cases once this
			// limitation is removed.
			in:   newTestTime("2277-06-25 07:26", "1985-03-20 15:00"),
			want: MegaTau(9222),
		},
	}
	for i, tt := range cases {
		out := TauSince(tt.in).Mega()
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v).Mega() => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}
}

func TestGigaTau(t *testing.T) {
	cases := []struct {
		in   Time
		want GigaTau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: GigaTau(0),
		},
		{
			in:   newTestTime("2016-11-26 16:46", "1985-03-20 15:00"),
			want: GigaTau(0),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: GigaTau(1),
		},
		{
			in:   newTestTime("2019-03-10 18:34", "1955-10-24 15:00"),
			want: GigaTau(2),
		},
		{
			in:   newTestTime("2277-06-25 07:26", "1985-03-20 15:00"),
			want: GigaTau(9),
		},
	}
	for i, tt := range cases {
		out := TauSince(tt.in).Giga()
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v).Giga() => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}
}
<|endoftext|>


<commit_before>package cmds

import (
	"fmt"
	"testing"

	"github.com/pachyderm/pachyderm/src/client/pkg/require"
	"github.com/pachyderm/pachyderm/src/server/pfs/fuse"
	tu "github.com/pachyderm/pachyderm/src/server/pkg/testutil"
)

func TestCommit(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration tests in short mode")
	}
	require.NoError(t, tu.BashCmd(`
		pachctl create repo {{.repo}}

		# Create a commit and put some data in it
		commit1=$(pachctl start commit {{.repo}}@master)
		echo "file contents" | pachctl put file {{.repo}}@${commit1}:/file -f -
		pachctl finish commit {{.repo}}@${commit1}

		# Check that the commit above now appears in the output
		pachctl list commit {{.repo}} \
		  | match ${commit1}

		# Create a second commit and put some data in it
		commit2=$(pachctl start commit {{.repo}}@master)
		echo "file contents" | pachctl put file {{.repo}}@${commit2}:/file -f -
		pachctl finish commit {{.repo}}@${commit2}

		# Check that the commit above now appears in the output
		pachctl list commit {{.repo}} \
		  | match ${commit1} \
		  | match ${commit2}
		`,
		"repo", tu.UniqueString("TestCommit-repo"),
	).Run())
}

func TestPutFileSplit(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration tests in short mode")
	}
	require.NoError(t, tu.BashCmd(`
		pachctl create repo {{.repo}}

		pachctl put file {{.repo}}@master:/data --split=csv --header-records=1 <<EOF
		name,job
		alice,accountant
		bob,baker
		EOF

		pachctl get file "{{.repo}}@master:/data/*0" \
		  | match "name,job" \
			| match "alice,accountant" \
			| match -v "bob,baker"

		pachctl get file "{{.repo}}@master:/data/*1" \
		  | match "name,job" \
			| match -v "alice,accountant" \
			| match "bob,baker"

		pachctl get file "{{.repo}}@master:/data/*" \
		  | match "name,job" \
			| match "alice,accountant" \
			| match "bob,baker"
		`,
		"repo", tu.UniqueString("TestPutFileSplit-repo"),
	).Run())
}

func TestMountParsing(t *testing.T) {
	expected := map[string]*fuse.RepoOptions{
		"repo1": {
			Branch: "branch",
			Write:  true,
		},
		"repo2": {
			Branch: "master",
			Write:  true,
		},
		"repo3": {
			Branch: "master",
		},
	}
	opts, err := parseRepoOpts([]string{"repo1@branch+w", "repo2+w", "repo3"})
	require.NoError(t, err)
	require.Equal(t, 3, len(opts))
	fmt.Printf("%+v\n", opts)
	for repo, ro := range expected {
		require.Equal(t, ro, opts[repo])
	}
}
<commit_msg>Fixes TestPutFileSplit.<commit_after>package cmds

import (
	"fmt"
	"testing"

	"github.com/pachyderm/pachyderm/src/client/pkg/require"
	"github.com/pachyderm/pachyderm/src/server/pfs/fuse"
	tu "github.com/pachyderm/pachyderm/src/server/pkg/testutil"
)

func TestCommit(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration tests in short mode")
	}
	require.NoError(t, tu.BashCmd(`
		pachctl create repo {{.repo}}

		# Create a commit and put some data in it
		commit1=$(pachctl start commit {{.repo}}@master)
		echo "file contents" | pachctl put file {{.repo}}@${commit1}:/file -f -
		pachctl finish commit {{.repo}}@${commit1}

		# Check that the commit above now appears in the output
		pachctl list commit {{.repo}} \
		  | match ${commit1}

		# Create a second commit and put some data in it
		commit2=$(pachctl start commit {{.repo}}@master)
		echo "file contents" | pachctl put file {{.repo}}@${commit2}:/file -f -
		pachctl finish commit {{.repo}}@${commit2}

		# Check that the commit above now appears in the output
		pachctl list commit {{.repo}} \
		  | match ${commit1} \
		  | match ${commit2}
		`,
		"repo", tu.UniqueString("TestCommit-repo"),
	).Run())
}

func TestPutFileSplit(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration tests in short mode")
	}
	require.NoError(t, tu.BashCmd(`
		pachctl create repo {{.repo}}

		pachctl put file {{.repo}}@master:/data --split=csv --header-records=1 <<EOF
		name,job
		alice,accountant
		bob,baker
		EOF

		pachctl get file "{{.repo}}@master:/data/*0" \
		  | match "name,job"
		pachctl get file "{{.repo}}@master:/data/*0" \
		  | match "alice,accountant"
		pachctl get file "{{.repo}}@master:/data/*0" \
		  | match -v "bob,baker"

		pachctl get file "{{.repo}}@master:/data/*1" \
		  | match "name,job"
		pachctl get file "{{.repo}}@master:/data/*1" \
		  | match "bob,baker"
		pachctl get file "{{.repo}}@master:/data/*1" \
		  | match -v "alice,accountant"

		pachctl get file "{{.repo}}@master:/data/*" \
		  | match "name,job"
		pachctl get file "{{.repo}}@master:/data/*" \
		  | match "alice,accountant"
		pachctl get file "{{.repo}}@master:/data/*" \
		  | match "bob,baker"
		`,
		"repo", tu.UniqueString("TestPutFileSplit-repo"),
	).Run())
}

func TestMountParsing(t *testing.T) {
	expected := map[string]*fuse.RepoOptions{
		"repo1": {
			Branch: "branch",
			Write:  true,
		},
		"repo2": {
			Branch: "master",
			Write:  true,
		},
		"repo3": {
			Branch: "master",
		},
	}
	opts, err := parseRepoOpts([]string{"repo1@branch+w", "repo2+w", "repo3"})
	require.NoError(t, err)
	require.Equal(t, 3, len(opts))
	fmt.Printf("%+v\n", opts)
	for repo, ro := range expected {
		require.Equal(t, ro, opts[repo])
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 Cisco and/or its affiliates.
//
// 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 main

const Template = `
// Code generated by adapter-generator. DO NOT EDIT.

package adapter

import (
	"fmt"
	"github.com/ligato/cn-infra/datasync"
	. "github.com/ligato/cn-infra/kvscheduler/api"
	. "github.com/ligato/cn-infra/kvscheduler/value/protoval"

    {{- range $i, $path := .Imports }}
	"{{ $path }}"
	{{- end }}
)

////////// type-safe key-value pair with metadata //////////

type {{ .DescriptorName }}KVWithMetadata struct {
	Key      string
	Value    {{ .ValueT }}
	Metadata {{ .MetadataT }}
	Origin   ValueOrigin
}

////////// type-safe Descriptor interface //////////

type {{ .DescriptorName }}DescriptorAPI interface {
	GetName() string
	KeySelector(key string) bool
    NBKeyPrefixes() []string
    WithMetadata() (withMeta bool, customMapFactory MetadataMapFactory)
{{- if .IsProtoValue }}
	Build(key string, valueData {{ .ValueDataT }}) (value ProtoValue, err error)
{{- else }}
	Build(key string, valueData {{ .ValueDataT }}) (value {{ .ValueT }}, err error)
{{- end }}
	Add(key string, value {{ .ValueT }}) (metadata {{ .MetadataT }}, err error)
	Delete(key string, value {{ .ValueT }}, metadata {{ .MetadataT }}) error
	Modify(key string, oldValue, newValue {{ .ValueT }}, oldMetadata {{ .MetadataT }}) (newMetadata {{ .MetadataT }}, err error)
	ModifyHasToRecreate(key string, oldValue, newValue {{ .ValueT }}, metadata {{ .MetadataT }}) bool
	Update(key string, value {{ .ValueT }}, metadata {{ .MetadataT }}) error
	Dependencies(key string, value {{ .ValueT }}) []Dependency
	DerivedValues(key string, value {{ .ValueT }}) []KeyValuePair
	Dump(correlate []{{ .DescriptorName }}KVWithMetadata) ([]{{ .DescriptorName }}KVWithMetadata, error)
	DumpDependencies() []string
}

////////// Descriptor base implementation //////////

// {{ .DescriptorName }}DescriptorBase provides default(=empty) implementations
// for all the methods to extend from.
type {{ .DescriptorName }}DescriptorBase struct {
}

func (db *{{ .DescriptorName }}DescriptorBase) GetName() string {
	return "base"
}

func (db *{{ .DescriptorName }}DescriptorBase) KeySelector(key string) bool {
	return false
}

func (db *{{ .DescriptorName }}DescriptorBase) NBKeyPrefixes() []string {
	return nil
}

func (db *{{ .DescriptorName }}DescriptorBase) WithMetadata() (withMeta bool, customMapFactory MetadataMapFactory) {
	return false, nil
}

{{ if .IsProtoValue -}}
func (db *{{ .DescriptorName }}DescriptorBase) Build(key string, valueData {{ .ValueDataT }}) (value ProtoValue, err error) {
{{- if .FromDatasync }}
	// You can override specific methods of ProtoValue using embedding:
	//
	//	type MyProtoValue struct {
	//		ProtoValue
	//      typedMsg {{ .ValueDataT }}
	//	}
	//
	//	// ... (override some methods)
	//
	//  return &MyProtoValue{ProtoValue: NewProtoValue(valueData), typedMsg: valueData}	, nil
	return NewProtoValue(valueData), nil
{{- else }}
	return nil, nil
{{- end }}
}
{{- else }}
func (db *{{ .DescriptorName }}DescriptorBase) Build(key string, valueData {{ .ValueDataT }}) (value {{ .ValueT }}, err error) {
	return nil, nil
}
{{- end }}

func (db *{{ .DescriptorName }}DescriptorBase) Add(key string, value {{ .ValueT }}) (metadata {{ .MetadataT }}, err error) {
	fmt.Printf("Create for key=%s is not implemented\n", key)
	return nil, nil
}

func (db *{{ .DescriptorName }}DescriptorBase) Delete(key string, value {{ .ValueT }}, metadata {{ .MetadataT }}) error {
	fmt.Printf("Delete for key=%s is not implemented\n", key)
	return nil
}

func (db *{{ .DescriptorName }}DescriptorBase) Modify(key string, oldValue, newValue {{ .ValueT }}, oldMetadata {{ .MetadataT }}) (newMetadata {{ .MetadataT }}, err error) {
	fmt.Printf("Modify for key=%s is not implemented\n", key)
	return nil, nil
}

func (db *{{ .DescriptorName }}DescriptorBase) ModifyHasToRecreate(key string, oldValue, newValue {{ .ValueT }}, metadata {{ .MetadataT }}) bool {
	return false
}

func (db *{{ .DescriptorName }}DescriptorBase) Update(key string, value {{ .ValueT }}, metadata {{ .MetadataT }}) error {
	fmt.Printf("Modify for key=%s is not implemented\n", key)
	return nil
}

func (db *{{ .DescriptorName }}DescriptorBase) Dependencies(key string, value {{ .ValueT }}) []Dependency {
	return nil
}

func (db *{{ .DescriptorName }}DescriptorBase) DerivedValues(key string, value {{ .ValueT }}) []KeyValuePair {
	return nil
}

func (db *{{ .DescriptorName }}DescriptorBase) Dump(correlate []{{ .DescriptorName }}KVWithMetadata) ([]{{ .DescriptorName }}KVWithMetadata, error) {
	fmt.Println("Dump is not implemented")
	return nil, nil
}

func (db *{{ .DescriptorName }}DescriptorBase) DumpDependencies() []string {
	return nil
}

////////// Descriptor adapter //////////

type {{ .DescriptorName }}DescriptorAdapter struct {
	descriptor {{ .DescriptorName }}DescriptorAPI
}

func New{{ .DescriptorName }}Descriptor(impl {{ .DescriptorName }}DescriptorAPI) KVDescriptor {
	return &{{ .DescriptorName }}DescriptorAdapter{descriptor: impl}
}

func (da *{{ .DescriptorName }}DescriptorAdapter) GetName() string {
	return da.descriptor.GetName()
}

func (da *{{ .DescriptorName }}DescriptorAdapter) KeySelector(key string) bool {
	return da.descriptor.KeySelector(key)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) NBKeyPrefixes() []string {
	return da.descriptor.NBKeyPrefixes()
}

func (da *{{ .DescriptorName }}DescriptorAdapter) WithMetadata() (withMeta bool, customMapFactory MetadataMapFactory) {
	return da.descriptor.WithMetadata()
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Build(key string, valueData interface{}) (value Value, err error) {
	typedValueData, err := castValueData(key, valueData)
	if err != nil {
		return nil, err
	}
	return da.descriptor.Build(key, typedValueData)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Add(key string, value Value) (metadata Metadata, err error) {
	typedValue, err := castValue(key, value)
	if err != nil {
		return nil, err
	}
	return da.descriptor.Add(key, typedValue)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Modify(key string, oldValue, newValue Value, oldMetadata Metadata) (newMetadata Metadata, err error) {
	oldTypedValue, err := castValue(key, oldValue)
	if err != nil {
		return nil, err
	}
	newTypedValue, err := castValue(key, newValue)
	if err != nil {
		return nil, err
	}
	typedOldMetadata, err := castMetadata(key, oldMetadata)
	if err != nil {
		return nil, err
	}
	return da.descriptor.Modify(key, oldTypedValue, newTypedValue, typedOldMetadata)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Delete(key string, value Value, metadata Metadata) error {
	typedValue, err := castValue(key, value)
	if err != nil {
		return err
	}
	typedMetadata, err := castMetadata(key, metadata)
	if err != nil {
		return err
	}
	return da.descriptor.Delete(key, typedValue, typedMetadata)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) ModifyHasToRecreate(key string, oldValue, newValue Value, metadata Metadata) bool {
	oldTypedValue, err := castValue(key, oldValue)
	if err != nil {
		return true
	}
	newTypedValue, err := castValue(key, newValue)
	if err != nil {
		return true
	}
	typedMetadata, err := castMetadata(key, metadata)
	if err != nil {
		return true
	}
	return da.descriptor.ModifyHasToRecreate(key, oldTypedValue, newTypedValue, typedMetadata)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Update(key string, value Value, metadata Metadata) error {
	typedValue, err := castValue(key, value)
	if err != nil {
		return err
	}
	typedMetadata, err := castMetadata(key, metadata)
	if err != nil {
		return err
	}
	return da.descriptor.Update(key, typedValue, typedMetadata)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Dependencies(key string, value Value) []Dependency {
	typedValue, err := castValue(key, value)
	if err != nil {
		return nil
	}
	return da.descriptor.Dependencies(key, typedValue)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) DerivedValues(key string, value Value) []KeyValuePair {
	typedValue, err := castValue(key, value)
	if err != nil {
		return nil
	}
	return da.descriptor.DerivedValues(key, typedValue)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Dump(correlate []KVWithMetadata) ([]KVWithMetadata, error) {
	var correlateWithType []{{ .DescriptorName }}KVWithMetadata
	for _, kvpair := range correlate {
		typedValue, err := castValue(kvpair.Key, kvpair.Value)
		if err != nil {
			continue
		}
		typedMetadata, err := castMetadata(kvpair.Key, kvpair.Metadata)
		if err != nil {
			continue
		}
		correlateWithType = append(correlateWithType,
			{{ .DescriptorName }}KVWithMetadata{
				Key:      kvpair.Key,
				Value:    typedValue,
				Metadata: typedMetadata,
				Origin:   kvpair.Origin,
			})
	}

	typedDump, err := da.descriptor.Dump(correlateWithType)
	if err != nil {
		return nil, err
	}
	var dump []KVWithMetadata
	for _, typedKVWithMetadata := range typedDump {
		kvWithMetadata := KVWithMetadata{
			Key:      typedKVWithMetadata.Key,
			Metadata: typedKVWithMetadata.Metadata,
			Origin:   typedKVWithMetadata.Origin,
			}
		{{- if .IsProtoValue }}
		kvWithMetadata.Value = NewProtoValue(typedKVWithMetadata.Value)
		{{- else }}
		kvWithMetadata.Value = typedKVWithMetadata.Value
		{{- end }}
		dump = append(dump, kvWithMetadata)
	}
	return dump, err
}

func (da *{{ .DescriptorName }}DescriptorAdapter) DumpDependencies() []string {
	return da.descriptor.DumpDependencies()
}

////////// Helper methods //////////

func castValueData(key string, valueData interface{}) ({{ .ValueDataT }}, error) {
{{- if .FromDatasync }}
	changeValue, isChange := valueData.(datasync.ChangeValue)
	if !isChange {
		return nil, ErrInvalidValueDataType(key)
	}
	protoMessage := &{{ .ValueDataBaseT }}{}
	err := changeValue.GetValue(protoMessage)
	if err != nil {
		return nil, err
	}
	return protoMessage, nil
{{- else }}
	typedValueData, ok := valueData.({{ .ValueDataT }})
	if !ok {
		return nil, ErrInvalidValueDataType(key)
	}
	return typedValueData, nil
{{- end }}
}

func castValue(key string, value Value) ({{ .ValueT }}, error) {
{{- if .IsProtoValue }}
	protoValue, isProto := value.(ProtoValue)
	if !isProto {
		return nil, ErrInvalidValueType(key, value)
	}
	protoWithType, ok := protoValue.GetProtoMessage().({{ .ValueT }})
	if !ok {
		return nil, ErrInvalidValueType(key, value)
	}
	return protoWithType, nil
{{- else }}
	typedValue, ok := value.({{ .ValueT }})
	if !ok {
		return nil, ErrInvalidValueType(key, value)
	}
	return typedValue, nil
{{- end }}
}

func castMetadata(key string, metadata Metadata) ({{ .MetadataT }}, error) {
	if metadata == nil {
		return nil, nil
	}
	typedMetadata, ok := metadata.({{ .MetadataT }})
	if !ok {
		return nil, ErrInvalidMetadataType(key)
	}
	return typedMetadata, nil
}
`
<commit_msg>Fix indent in the descriptor adapter template.<commit_after>// Copyright (c) 2018 Cisco and/or its affiliates.
//
// 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 main

const Template = `
// Code generated by adapter-generator. DO NOT EDIT.

package adapter

import (
	"fmt"
	"github.com/ligato/cn-infra/datasync"
	. "github.com/ligato/cn-infra/kvscheduler/api"
	. "github.com/ligato/cn-infra/kvscheduler/value/protoval"

    {{- range $i, $path := .Imports }}
	"{{ $path }}"
	{{- end }}
)

////////// type-safe key-value pair with metadata //////////

type {{ .DescriptorName }}KVWithMetadata struct {
	Key      string
	Value    {{ .ValueT }}
	Metadata {{ .MetadataT }}
	Origin   ValueOrigin
}

////////// type-safe Descriptor interface //////////

type {{ .DescriptorName }}DescriptorAPI interface {
	GetName() string
	KeySelector(key string) bool
	NBKeyPrefixes() []string
	WithMetadata() (withMeta bool, customMapFactory MetadataMapFactory)
{{- if .IsProtoValue }}
	Build(key string, valueData {{ .ValueDataT }}) (value ProtoValue, err error)
{{- else }}
	Build(key string, valueData {{ .ValueDataT }}) (value {{ .ValueT }}, err error)
{{- end }}
	Add(key string, value {{ .ValueT }}) (metadata {{ .MetadataT }}, err error)
	Delete(key string, value {{ .ValueT }}, metadata {{ .MetadataT }}) error
	Modify(key string, oldValue, newValue {{ .ValueT }}, oldMetadata {{ .MetadataT }}) (newMetadata {{ .MetadataT }}, err error)
	ModifyHasToRecreate(key string, oldValue, newValue {{ .ValueT }}, metadata {{ .MetadataT }}) bool
	Update(key string, value {{ .ValueT }}, metadata {{ .MetadataT }}) error
	Dependencies(key string, value {{ .ValueT }}) []Dependency
	DerivedValues(key string, value {{ .ValueT }}) []KeyValuePair
	Dump(correlate []{{ .DescriptorName }}KVWithMetadata) ([]{{ .DescriptorName }}KVWithMetadata, error)
	DumpDependencies() []string
}

////////// Descriptor base implementation //////////

// {{ .DescriptorName }}DescriptorBase provides default(=empty) implementations
// for all the methods to extend from.
type {{ .DescriptorName }}DescriptorBase struct {
}

func (db *{{ .DescriptorName }}DescriptorBase) GetName() string {
	return "base"
}

func (db *{{ .DescriptorName }}DescriptorBase) KeySelector(key string) bool {
	return false
}

func (db *{{ .DescriptorName }}DescriptorBase) NBKeyPrefixes() []string {
	return nil
}

func (db *{{ .DescriptorName }}DescriptorBase) WithMetadata() (withMeta bool, customMapFactory MetadataMapFactory) {
	return false, nil
}

{{ if .IsProtoValue -}}
func (db *{{ .DescriptorName }}DescriptorBase) Build(key string, valueData {{ .ValueDataT }}) (value ProtoValue, err error) {
{{- if .FromDatasync }}
	// You can override specific methods of ProtoValue using embedding:
	//
	//	type MyProtoValue struct {
	//		ProtoValue
	//      typedMsg {{ .ValueDataT }}
	//	}
	//
	//	// ... (override some methods)
	//
	//  return &MyProtoValue{ProtoValue: NewProtoValue(valueData), typedMsg: valueData}	, nil
	return NewProtoValue(valueData), nil
{{- else }}
	return nil, nil
{{- end }}
}
{{- else }}
func (db *{{ .DescriptorName }}DescriptorBase) Build(key string, valueData {{ .ValueDataT }}) (value {{ .ValueT }}, err error) {
	return nil, nil
}
{{- end }}

func (db *{{ .DescriptorName }}DescriptorBase) Add(key string, value {{ .ValueT }}) (metadata {{ .MetadataT }}, err error) {
	fmt.Printf("Create for key=%s is not implemented\n", key)
	return nil, nil
}

func (db *{{ .DescriptorName }}DescriptorBase) Delete(key string, value {{ .ValueT }}, metadata {{ .MetadataT }}) error {
	fmt.Printf("Delete for key=%s is not implemented\n", key)
	return nil
}

func (db *{{ .DescriptorName }}DescriptorBase) Modify(key string, oldValue, newValue {{ .ValueT }}, oldMetadata {{ .MetadataT }}) (newMetadata {{ .MetadataT }}, err error) {
	fmt.Printf("Modify for key=%s is not implemented\n", key)
	return nil, nil
}

func (db *{{ .DescriptorName }}DescriptorBase) ModifyHasToRecreate(key string, oldValue, newValue {{ .ValueT }}, metadata {{ .MetadataT }}) bool {
	return false
}

func (db *{{ .DescriptorName }}DescriptorBase) Update(key string, value {{ .ValueT }}, metadata {{ .MetadataT }}) error {
	fmt.Printf("Modify for key=%s is not implemented\n", key)
	return nil
}

func (db *{{ .DescriptorName }}DescriptorBase) Dependencies(key string, value {{ .ValueT }}) []Dependency {
	return nil
}

func (db *{{ .DescriptorName }}DescriptorBase) DerivedValues(key string, value {{ .ValueT }}) []KeyValuePair {
	return nil
}

func (db *{{ .DescriptorName }}DescriptorBase) Dump(correlate []{{ .DescriptorName }}KVWithMetadata) ([]{{ .DescriptorName }}KVWithMetadata, error) {
	fmt.Println("Dump is not implemented")
	return nil, nil
}

func (db *{{ .DescriptorName }}DescriptorBase) DumpDependencies() []string {
	return nil
}

////////// Descriptor adapter //////////

type {{ .DescriptorName }}DescriptorAdapter struct {
	descriptor {{ .DescriptorName }}DescriptorAPI
}

func New{{ .DescriptorName }}Descriptor(impl {{ .DescriptorName }}DescriptorAPI) KVDescriptor {
	return &{{ .DescriptorName }}DescriptorAdapter{descriptor: impl}
}

func (da *{{ .DescriptorName }}DescriptorAdapter) GetName() string {
	return da.descriptor.GetName()
}

func (da *{{ .DescriptorName }}DescriptorAdapter) KeySelector(key string) bool {
	return da.descriptor.KeySelector(key)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) NBKeyPrefixes() []string {
	return da.descriptor.NBKeyPrefixes()
}

func (da *{{ .DescriptorName }}DescriptorAdapter) WithMetadata() (withMeta bool, customMapFactory MetadataMapFactory) {
	return da.descriptor.WithMetadata()
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Build(key string, valueData interface{}) (value Value, err error) {
	typedValueData, err := castValueData(key, valueData)
	if err != nil {
		return nil, err
	}
	return da.descriptor.Build(key, typedValueData)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Add(key string, value Value) (metadata Metadata, err error) {
	typedValue, err := castValue(key, value)
	if err != nil {
		return nil, err
	}
	return da.descriptor.Add(key, typedValue)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Modify(key string, oldValue, newValue Value, oldMetadata Metadata) (newMetadata Metadata, err error) {
	oldTypedValue, err := castValue(key, oldValue)
	if err != nil {
		return nil, err
	}
	newTypedValue, err := castValue(key, newValue)
	if err != nil {
		return nil, err
	}
	typedOldMetadata, err := castMetadata(key, oldMetadata)
	if err != nil {
		return nil, err
	}
	return da.descriptor.Modify(key, oldTypedValue, newTypedValue, typedOldMetadata)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Delete(key string, value Value, metadata Metadata) error {
	typedValue, err := castValue(key, value)
	if err != nil {
		return err
	}
	typedMetadata, err := castMetadata(key, metadata)
	if err != nil {
		return err
	}
	return da.descriptor.Delete(key, typedValue, typedMetadata)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) ModifyHasToRecreate(key string, oldValue, newValue Value, metadata Metadata) bool {
	oldTypedValue, err := castValue(key, oldValue)
	if err != nil {
		return true
	}
	newTypedValue, err := castValue(key, newValue)
	if err != nil {
		return true
	}
	typedMetadata, err := castMetadata(key, metadata)
	if err != nil {
		return true
	}
	return da.descriptor.ModifyHasToRecreate(key, oldTypedValue, newTypedValue, typedMetadata)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Update(key string, value Value, metadata Metadata) error {
	typedValue, err := castValue(key, value)
	if err != nil {
		return err
	}
	typedMetadata, err := castMetadata(key, metadata)
	if err != nil {
		return err
	}
	return da.descriptor.Update(key, typedValue, typedMetadata)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Dependencies(key string, value Value) []Dependency {
	typedValue, err := castValue(key, value)
	if err != nil {
		return nil
	}
	return da.descriptor.Dependencies(key, typedValue)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) DerivedValues(key string, value Value) []KeyValuePair {
	typedValue, err := castValue(key, value)
	if err != nil {
		return nil
	}
	return da.descriptor.DerivedValues(key, typedValue)
}

func (da *{{ .DescriptorName }}DescriptorAdapter) Dump(correlate []KVWithMetadata) ([]KVWithMetadata, error) {
	var correlateWithType []{{ .DescriptorName }}KVWithMetadata
	for _, kvpair := range correlate {
		typedValue, err := castValue(kvpair.Key, kvpair.Value)
		if err != nil {
			continue
		}
		typedMetadata, err := castMetadata(kvpair.Key, kvpair.Metadata)
		if err != nil {
			continue
		}
		correlateWithType = append(correlateWithType,
			{{ .DescriptorName }}KVWithMetadata{
				Key:      kvpair.Key,
				Value:    typedValue,
				Metadata: typedMetadata,
				Origin:   kvpair.Origin,
			})
	}

	typedDump, err := da.descriptor.Dump(correlateWithType)
	if err != nil {
		return nil, err
	}
	var dump []KVWithMetadata
	for _, typedKVWithMetadata := range typedDump {
		kvWithMetadata := KVWithMetadata{
			Key:      typedKVWithMetadata.Key,
			Metadata: typedKVWithMetadata.Metadata,
			Origin:   typedKVWithMetadata.Origin,
			}
		{{- if .IsProtoValue }}
		kvWithMetadata.Value = NewProtoValue(typedKVWithMetadata.Value)
		{{- else }}
		kvWithMetadata.Value = typedKVWithMetadata.Value
		{{- end }}
		dump = append(dump, kvWithMetadata)
	}
	return dump, err
}

func (da *{{ .DescriptorName }}DescriptorAdapter) DumpDependencies() []string {
	return da.descriptor.DumpDependencies()
}

////////// Helper methods //////////

func castValueData(key string, valueData interface{}) ({{ .ValueDataT }}, error) {
{{- if .FromDatasync }}
	changeValue, isChange := valueData.(datasync.ChangeValue)
	if !isChange {
		return nil, ErrInvalidValueDataType(key)
	}
	protoMessage := &{{ .ValueDataBaseT }}{}
	err := changeValue.GetValue(protoMessage)
	if err != nil {
		return nil, err
	}
	return protoMessage, nil
{{- else }}
	typedValueData, ok := valueData.({{ .ValueDataT }})
	if !ok {
		return nil, ErrInvalidValueDataType(key)
	}
	return typedValueData, nil
{{- end }}
}

func castValue(key string, value Value) ({{ .ValueT }}, error) {
{{- if .IsProtoValue }}
	protoValue, isProto := value.(ProtoValue)
	if !isProto {
		return nil, ErrInvalidValueType(key, value)
	}
	protoWithType, ok := protoValue.GetProtoMessage().({{ .ValueT }})
	if !ok {
		return nil, ErrInvalidValueType(key, value)
	}
	return protoWithType, nil
{{- else }}
	typedValue, ok := value.({{ .ValueT }})
	if !ok {
		return nil, ErrInvalidValueType(key, value)
	}
	return typedValue, nil
{{- end }}
}

func castMetadata(key string, metadata Metadata) ({{ .MetadataT }}, error) {
	if metadata == nil {
		return nil, nil
	}
	typedMetadata, ok := metadata.({{ .MetadataT }})
	if !ok {
		return nil, ErrInvalidMetadataType(key)
	}
	return typedMetadata, nil
}
`
<|endoftext|>


<commit_before>package git

type Repository struct {
	FullName    string
	Description string
	Master      string
	HTMLURL     string

	LatestMasterCommit *Commit
}
<commit_msg>Add Repository.Mirrored<commit_after>package git

type Repository struct {
	FullName    string
	Description string
	Master      string
	HTMLURL     string

	LatestMasterCommit *Commit
}

func (repo *Repository) Mirrored() bool {
	return repo.HTMLURL == ""
}
<|endoftext|>


<commit_before>package ov

import (
	"fmt"
	"github.com/HewlettPackard/oneview-golang/ov"
	"github.com/HewlettPackard/oneview-golang/utils"
	"github.com/docker/machine/libmachine/log"
	"github.com/stretchr/testify/assert"
	"os"
	"testing"
)

func TestCreateStorageVolume(t *testing.T) {
	var (
		d        *OVTest
		c        *ov.OVClient
		testName string
	)
	if os.Getenv("ONEVIEW_TEST_ACCEPTANCE") == "true" {
		d, c = getTestDriverA("test_storage_volume")
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}
		// find out if the test ethernet network already exist
		testName = d.Tc.GetTestData(d.Env, "Name").(string)

		testSVol, err := c.GetStorageVolumeByName(testName)
		assert.NoError(t, err, "CreateStorageVolume get the Storage Volume error -> %s", err)

		//Provisoning Parameters commented as this attribute not available from API500 and onwards
		//pMap := d.Tc.GetTestData(d.Env, "ProvisioningParameters").(map[string]interface{})

		//provParams := ov.ProvisioningParameters{StoragePoolUri: utils.NewNstring(pMap["storagePoolUri"].(string)), RequestedCapacity: pMap["requestedCapacity"].(string), ProvisionType: pMap["provisionType"].(string), Shareable: pMap["shareable"].(bool)}

		if testSVol.URI.IsNil() {
			testSVol = ov.StorageVolumeV3{
				Name:             testName,
				StorageSystemUri: utils.NewNstring(d.Tc.GetTestData(d.Env, "StorageSystemUri").(string)),
				Type:             d.Tc.GetTestData(d.Env, "Type").(string),
				//				ProvisioningParameters: provParams,
			}

			// not changed after this TODO: update to storage volume tests
			err := c.CreateStorageVolume(testSVol)
			assert.NoError(t, err, "CreateStorageVolume error -> %s", err)

			err = c.CreateStorageVolume(testSVol)
			assert.Error(t, err, "CreateStorageVolume should error because the Storage volume already exists, err-> %s", err)

		} else {
			log.Warnf("The storage volume already exist, so skipping CreateStorageVolume test for %s", testName)
		}

		// reload the test profile that we just created
		testSVol, err = c.GetStorageVolumeByName(testName)
		assert.NoError(t, err, "GetStorageVolumeByName error -> %s", err)
	}

}

func TestGetStorageVolumeByName(t *testing.T) {
	var (
		d        *OVTest
		c        *ov.OVClient
		testName string
	)
	if os.Getenv("ONEVIEW_TEST_ACCEPTANCE") == "true" {
		d, c = getTestDriverA("test_storage_volume")
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}
		testName = d.Tc.GetTestData(d.Env, "Name").(string)

		testSVol, err := c.GetStorageVolumeByName(testName)
		assert.NoError(t, err, "GetStorageVolumeByName thew an error -> %s", err)
		assert.Equal(t, testName, testSVol.Name)

		testSVol, err = c.GetStorageVolumeByName("bad")
		assert.NoError(t, err, "GetStorageVolumeByName with fake name -> %s", err)
		assert.Equal(t, "", testSVol.Name)

	} else {
		d, c = getTestDriverU("test_storage_volume")
		testName = d.Tc.GetTestData(d.Env, "Name").(string)
		data, err := c.GetStorageVolumeByName(testName)
		assert.Error(t, err, fmt.Sprintf("ALL ok, no error, caught as expected: %s,%+v\n", err, data))
	}
}

func TestGetStorageVolumes(t *testing.T) {
	var (
		c *ov.OVClient
	)
	if os.Getenv("ONEVIEW_TEST_ACCEPTANCE") == "true" {
		_, c = getTestDriverA("test_storage_volume")
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}
		sVols, err := c.GetStorageVolumes("", "")
		assert.NoError(t, err, "GetStorageVolumes threw error -> %s, %+v\n", err, sVols)

		sVols, err = c.GetStorageVolumes("", "name:asc")
		assert.NoError(t, err, "GetStorageVolumes name:asc error -> %s, %+v\n", err, sVols)

	} else {
		_, c = getTestDriverU("test_storage_volume")
		data, err := c.GetStorageVolumes("", "")
		assert.Error(t, err, fmt.Sprintf("ALL ok, no error, caught as expected: %s,%+v\n", err, data))
	}
}

func TestDeleteStorageVolumeNotFound(t *testing.T) {
	var (
		c        *ov.OVClient
		testName = "fake"
		testSVol ov.StorageVolumeV3
	)
	if os.Getenv("ONEVIEW_TEST_ACCEPTANCE") == "true" {
		_, c = getTestDriverA("test_storage_volume")
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}

		err := c.DeleteStorageVolume(testName)
		assert.NoError(t, err, "DeleteStorageVolume err-> %s", err)

		testSVol, err = c.GetStorageVolumeByName(testName)
		assert.NoError(t, err, "GetStorageVolumeByName with deleted storage volume -> %+v", err)
		assert.Equal(t, "", testSVol.Name, fmt.Sprintf("Problem getting storage volume name, %+v", testSVol))
	} else {
		_, c = getTestDriverU("test_storage_volume")
		err := c.DeleteStorageVolume(testName)
		assert.Error(t, err, fmt.Sprintf("All ok, no error, caught as expected: %s,%+v\n", err, testSVol))
	}
}

func TestDeleteStorageVolume(t *testing.T) {
	var (
		d        *OVTest
		c        *ov.OVClient
		testName string
		testSVol ov.StorageVolumeV3
	)
	if os.Getenv("ONEVIEW_TEST_ACCEPTANCE") == "true" {
		d, c = getTestDriverA("test_storage_volume")
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}
		testName = d.Tc.GetTestData(d.Env, "Name").(string)

		err := c.DeleteStorageVolume(testName)
		assert.NoError(t, err, "DeleteStorageVolume err-> %s", err)

		testSVol, err = c.GetStorageVolumeByName(testName)
		assert.NoError(t, err, "GetStorageVolumeByName with deleted storage volume -> %+v", err)
		assert.Equal(t, "", testSVol.Name, fmt.Sprintf("Problem getting storage volume name, %+v", testSVol))
	} else {
		_, c = getTestDriverU("test_storage_volume")
		err := c.DeleteStorageVolume("footest")
		assert.Error(t, err, fmt.Sprintf("ALL ok, no error, caught as expected: %s,%+v\n", err, testSVol))
	}
}
<commit_msg>reverting changes, updating tests<commit_after>package ov

import (
	"fmt"
	"github.com/HewlettPackard/oneview-golang/ov"
	"github.com/HewlettPackard/oneview-golang/utils"
	"github.com/docker/machine/libmachine/log"
	"github.com/stretchr/testify/assert"
	"os"
	"testing"
)

func TestCreateStorageVolume(t *testing.T) {
	var (
		d        *OVTest
		c        *ov.OVClient
		testName string
	)
	if os.Getenv("ONEVIEW_TEST_ACCEPTANCE") == "true" {
		d, c = getTestDriverA("test_storage_volume")
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}
		// find out if the test ethernet network already exist
		testName = d.Tc.GetTestData(d.Env, "Name").(string)

		testSVol, err := c.GetStorageVolumeByName(testName)
		assert.NoError(t, err, "CreateStorageVolume get the Storage Volume error -> %s", err)

		//Provisoning Parameters commented as this attribute not available from API500 and onwards
		//pMap := d.Tc.GetTestData(d.Env, "ProvisioningParameters").(map[string]interface{})

		//provParams := ov.ProvisioningParameters{StoragePoolUri: utils.NewNstring(pMap["storagePoolUri"].(string)), RequestedCapacity: pMap["requestedCapacity"].(string), ProvisionType: pMap["provisionType"].(string), Shareable: pMap["shareable"].(bool)}

		if testSVol.URI.IsNil() {
			testSVol = ov.StorageVolume{
				Name:             testName,
				StorageSystemUri: utils.NewNstring(d.Tc.GetTestData(d.Env, "StorageSystemUri").(string)),
				Type:             d.Tc.GetTestData(d.Env, "Type").(string),
				//				ProvisioningParameters: provParams,
			}

			// not changed after this TODO: update to storage volume tests
			err := c.CreateStorageVolume(testSVol)
			assert.NoError(t, err, "CreateStorageVolume error -> %s", err)

			err = c.CreateStorageVolume(testSVol)
			assert.Error(t, err, "CreateStorageVolume should error because the Storage volume already exists, err-> %s", err)

		} else {
			log.Warnf("The storage volume already exist, so skipping CreateStorageVolume test for %s", testName)
		}

		// reload the test profile that we just created
		testSVol, err = c.GetStorageVolumeByName(testName)
		assert.NoError(t, err, "GetStorageVolumeByName error -> %s", err)
	}

}

func TestGetStorageVolumeByName(t *testing.T) {
	var (
		d        *OVTest
		c        *ov.OVClient
		testName string
	)
	if os.Getenv("ONEVIEW_TEST_ACCEPTANCE") == "true" {
		d, c = getTestDriverA("test_storage_volume")
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}
		testName = d.Tc.GetTestData(d.Env, "Name").(string)

		testSVol, err := c.GetStorageVolumeByName(testName)
		assert.NoError(t, err, "GetStorageVolumeByName thew an error -> %s", err)
		assert.Equal(t, testName, testSVol.Name)

		testSVol, err = c.GetStorageVolumeByName("bad")
		assert.NoError(t, err, "GetStorageVolumeByName with fake name -> %s", err)
		assert.Equal(t, "", testSVol.Name)

	} else {
		d, c = getTestDriverU("test_storage_volume")
		testName = d.Tc.GetTestData(d.Env, "Name").(string)
		data, err := c.GetStorageVolumeByName(testName)
		assert.Error(t, err, fmt.Sprintf("ALL ok, no error, caught as expected: %s,%+v\n", err, data))
	}
}

func TestGetStorageVolumes(t *testing.T) {
	var (
		c *ov.OVClient
	)
	if os.Getenv("ONEVIEW_TEST_ACCEPTANCE") == "true" {
		_, c = getTestDriverA("test_storage_volume")
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}
		sVols, err := c.GetStorageVolumes("", "")
		assert.NoError(t, err, "GetStorageVolumes threw error -> %s, %+v\n", err, sVols)

		sVols, err = c.GetStorageVolumes("", "name:asc")
		assert.NoError(t, err, "GetStorageVolumes name:asc error -> %s, %+v\n", err, sVols)

	} else {
		_, c = getTestDriverU("test_storage_volume")
		data, err := c.GetStorageVolumes("", "")
		assert.Error(t, err, fmt.Sprintf("ALL ok, no error, caught as expected: %s,%+v\n", err, data))
	}
}

func TestDeleteStorageVolumeNotFound(t *testing.T) {
	var (
		c        *ov.OVClient
		testName = "fake"
		testSVol ov.StorageVolume
	)
	if os.Getenv("ONEVIEW_TEST_ACCEPTANCE") == "true" {
		_, c = getTestDriverA("test_storage_volume")
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}

		err := c.DeleteStorageVolume(testName)
		assert.NoError(t, err, "DeleteStorageVolume err-> %s", err)

		testSVol, err = c.GetStorageVolumeByName(testName)
		assert.NoError(t, err, "GetStorageVolumeByName with deleted storage volume -> %+v", err)
		assert.Equal(t, "", testSVol.Name, fmt.Sprintf("Problem getting storage volume name, %+v", testSVol))
	} else {
		_, c = getTestDriverU("test_storage_volume")
		err := c.DeleteStorageVolume(testName)
		assert.Error(t, err, fmt.Sprintf("All ok, no error, caught as expected: %s,%+v\n", err, testSVol))
	}
}

func TestDeleteStorageVolume(t *testing.T) {
	var (
		d        *OVTest
		c        *ov.OVClient
		testName string
		testSVol ov.StorageVolume
	)
	if os.Getenv("ONEVIEW_TEST_ACCEPTANCE") == "true" {
		d, c = getTestDriverA("test_storage_volume")
		if c == nil {
			t.Fatalf("Failed to execute getTestDriver() ")
		}
		testName = d.Tc.GetTestData(d.Env, "Name").(string)

		err := c.DeleteStorageVolume(testName)
		assert.NoError(t, err, "DeleteStorageVolume err-> %s", err)

		testSVol, err = c.GetStorageVolumeByName(testName)
		assert.NoError(t, err, "GetStorageVolumeByName with deleted storage volume -> %+v", err)
		assert.Equal(t, "", testSVol.Name, fmt.Sprintf("Problem getting storage volume name, %+v", testSVol))
	} else {
		_, c = getTestDriverU("test_storage_volume")
		err := c.DeleteStorageVolume("footest")
		assert.Error(t, err, fmt.Sprintf("ALL ok, no error, caught as expected: %s,%+v\n", err, testSVol))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"crypto/sha1"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"syscall"
	"text/template"
)

func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func groupByMulti(entries []*RuntimeContainer, key, sep string) map[string][]*RuntimeContainer {
	groups := make(map[string][]*RuntimeContainer)
	for _, v := range entries {
		value := deepGet(*v, key)
		if value != nil {
			items := strings.Split(value.(string), sep)
			for _, item := range items {
				groups[item] = append(groups[item], v)
			}

		}
	}
	return groups
}

// groupBy groups a list of *RuntimeContainers by the path property key
func groupBy(entries []*RuntimeContainer, key string) map[string][]*RuntimeContainer {
	groups := make(map[string][]*RuntimeContainer)
	for _, v := range entries {
		value := deepGet(*v, key)
		if value != nil {
			groups[value.(string)] = append(groups[value.(string)], v)
		}
	}
	return groups
}

// groupByKeys is the same as groupBy but only returns a list of keys
func groupByKeys(entries []*RuntimeContainer, key string) []string {
	groups := groupBy(entries, key)
	ret := []string{}
	for k, _ := range groups {
		ret = append(ret, k)
	}
	return ret
}

// selects entries based on key
func where(entries []*RuntimeContainer, key string, cmp string) []*RuntimeContainer {
	selection := []*RuntimeContainer{}
	for _, v := range entries {
		value := deepGet(*v, key)
		if value == cmp {
			selection = append(selection, v)
		}
	}
	return selection
}

// selects entries where a key exists
func whereExist(entries []*RuntimeContainer, key string) []*RuntimeContainer {
	selection := []*RuntimeContainer{}
	for _, v := range entries {
		value := deepGet(*v, key)
		if value != nil {
			selection = append(selection, v)
		}
	}
	return selection
}

// selects entries where a key does not exist
func whereNotExist(entries []*RuntimeContainer, key string) []*RuntimeContainer {
	selection := []*RuntimeContainer{}
        for _, v := range entries {
                value := deepGet(*v, key)
                if value == nil {
                        selection = append(selection, v)
                }
        }
        return selection
}

// selects entries based on key.  Assumes key is delimited and breaks it apart before comparing
func whereAny(entries []*RuntimeContainer, key, sep string, cmp []string) []*RuntimeContainer {
	selection := []*RuntimeContainer{}
	for _, v := range entries {
		value := deepGet(*v, key)
		if value != nil {
			items := strings.Split(value.(string), sep)
			if len(intersect(cmp, items)) > 0 {
				selection = append(selection, v)
			}
		}
	}
	return selection
}

// selects entries based on key.  Assumes key is delimited and breaks it apart before comparing
func whereAll(entries []*RuntimeContainer, key, sep string, cmp []string) []*RuntimeContainer {
	selection := []*RuntimeContainer{}
	req_count := len(cmp)
	for _, v := range entries {
		value := deepGet(*v, key)
		if value != nil {
			items := strings.Split(value.(string), sep)
			if len(intersect(cmp, items)) == req_count {
				selection = append(selection, v)
			}
		}
	}
	return selection
}

// hasPrefix returns whether a given string is a prefix of another string
func hasPrefix(prefix, s string) bool {
	return strings.HasPrefix(s, prefix)
}

// hasSuffix returns whether a given string is a suffix of another string
func hasSuffix(suffix, s string) bool {
	return strings.HasSuffix(s, suffix)
}

func keys(input interface{}) (interface{}, error) {
	if input == nil {
		return nil, nil
	}

	val := reflect.ValueOf(input)
	if val.Kind() != reflect.Map {
		return nil, fmt.Errorf("Cannot call keys on a non-map value: %v", input)
	}

	vk := val.MapKeys()
	k := make([]interface{}, val.Len())
	for i, _ := range k {
		k[i] = vk[i].Interface()
	}

	return k, nil
}

func intersect(l1, l2 []string) []string {
	m := make(map[string]bool)
	m2 := make(map[string]bool)
	for _, v := range l2 {
		m2[v] = true
	}
	for _, v := range l1 {
		if m2[v] {
			m[v] = true
		}
	}
	keys := make([]string, 0, len(m))
	for k := range m {
		keys = append(keys, k)
	}
	return keys
}

func contains(item map[string]string, key string) bool {
	if _, ok := item[key]; ok {
		return true
	}
	return false
}

func dict(values ...interface{}) (map[string]interface{}, error) {
	if len(values)%2 != 0 {
		return nil, errors.New("invalid dict call")
	}
	dict := make(map[string]interface{}, len(values)/2)
	for i := 0; i < len(values); i += 2 {
		key, ok := values[i].(string)
		if !ok {
			return nil, errors.New("dict keys must be strings")
		}
		dict[key] = values[i+1]
	}
	return dict, nil
}

func hashSha1(input string) string {
	h := sha1.New()
	io.WriteString(h, input)
	return fmt.Sprintf("%x", h.Sum(nil))
}

func marshalJson(input interface{}) (string, error) {
	var buf bytes.Buffer
	enc := json.NewEncoder(&buf)
	if err := enc.Encode(input); err != nil {
		return "", err
	}
	return strings.TrimSuffix(buf.String(), "\n"), nil
}

// arrayFirst returns first item in the array or nil if the
// input is nil or empty
func arrayFirst(input interface{}) interface{} {
	if input == nil {
		return nil
	}

	arr := reflect.ValueOf(input)

	if arr.Len() == 0 {
		return nil
	}

	return arr.Index(0).Interface()
}

// arrayLast returns last item in the array
func arrayLast(input interface{}) interface{} {
	arr := reflect.ValueOf(input)
	return arr.Index(arr.Len() - 1).Interface()
}

// arrayClosest find the longest matching substring in values
// that matches input
func arrayClosest(values []string, input string) string {
	best := ""
	for _, v := range values {
		if strings.Contains(input, v) && len(v) > len(best) {
			best = v
		}
	}
	return best
}

// dirList returns a list of files in the specified path
func dirList(path string) ([]string, error) {
	names := []string{}
	files, err := ioutil.ReadDir(path)
	if err != nil {
		return names, err
	}
	for _, f := range files {
		names = append(names, f.Name())
	}
	return names, nil
}

// coalesce returns the first non nil argument
func coalesce(input ...interface{}) interface{} {
	for _, v := range input {
		if v != nil {
			return v
		}
	}
	return nil
}

// trimPrefix returns whether a given string is a prefix of another string
func trimPrefix(prefix, s string) string {
	return strings.TrimPrefix(s, prefix)
}

// trimSuffix returns whether a given string is a suffix of another string
func trimSuffix(suffix, s string) string {
	return strings.TrimSuffix(s, suffix)
}

func generateFile(config Config, containers Context) bool {
	templatePath := config.Template
	tmpl, err := template.New(filepath.Base(templatePath)).Funcs(template.FuncMap{
		"closest":      arrayClosest,
		"coalesce":     coalesce,
		"contains":     contains,
		"dict":         dict,
		"dir":          dirList,
		"exists":       exists,
		"first":        arrayFirst,
		"groupBy":      groupBy,
		"groupByKeys":  groupByKeys,
		"groupByMulti": groupByMulti,
		"hasPrefix":    hasPrefix,
		"hasSuffix":    hasSuffix,
		"json":         marshalJson,
		"intersect":    intersect,
		"keys":         keys,
		"last":         arrayLast,
		"replace":      strings.Replace,
		"sha1":         hashSha1,
		"split":        strings.Split,
		"trimPrefix":   trimPrefix,
		"trimSuffix":   trimSuffix,
		"where":        where,
		"whereExist":	whereExist,
		"whereNotExist":	whereNotExist,
		"whereAny":     whereAny,
		"whereAll":     whereAll,
	}).ParseFiles(templatePath)
	if err != nil {
		log.Fatalf("unable to parse template: %s", err)
	}

	filteredContainers := Context{}
	if config.OnlyPublished {
		for _, container := range containers {
			if len(container.PublishedAddresses()) > 0 {
				filteredContainers = append(filteredContainers, container)
			}
		}
	} else if config.OnlyExposed {
		for _, container := range containers {
			if len(container.Addresses) > 0 {
				filteredContainers = append(filteredContainers, container)
			}
		}
	} else {
		filteredContainers = containers
	}

	dest := os.Stdout
	if config.Dest != "" {
		dest, err = ioutil.TempFile(filepath.Dir(config.Dest), "docker-gen")
		defer func() {
			dest.Close()
			os.Remove(dest.Name())
		}()
		if err != nil {
			log.Fatalf("unable to create temp file: %s\n", err)
		}
	}

	var buf bytes.Buffer
	multiwriter := io.MultiWriter(dest, &buf)
	err = tmpl.ExecuteTemplate(multiwriter, filepath.Base(templatePath), &filteredContainers)
	if err != nil {
		log.Fatalf("template error: %s\n", err)
	}

	if config.Dest != "" {

		contents := []byte{}
		if fi, err := os.Stat(config.Dest); err == nil {
			if err := dest.Chmod(fi.Mode()); err != nil {
				log.Fatalf("unable to chmod temp file: %s\n", err)
			}
			if err := dest.Chown(int(fi.Sys().(*syscall.Stat_t).Uid), int(fi.Sys().(*syscall.Stat_t).Gid)); err != nil {
				log.Fatalf("unable to chown temp file: %s\n", err)
			}
			contents, err = ioutil.ReadFile(config.Dest)
			if err != nil {
				log.Fatalf("unable to compare current file contents: %s: %s\n", config.Dest, err)
			}
		}

		if bytes.Compare(contents, buf.Bytes()) != 0 {
			err = os.Rename(dest.Name(), config.Dest)
			if err != nil {
				log.Fatalf("unable to create dest file %s: %s\n", config.Dest, err)
			}
			log.Printf("Generated '%s' from %d containers", config.Dest, len(filteredContainers))
			return true
		}
		return false
	}
	return true
}
<commit_msg>Run go fmt<commit_after>package main

import (
	"bytes"
	"crypto/sha1"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"syscall"
	"text/template"
)

func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func groupByMulti(entries []*RuntimeContainer, key, sep string) map[string][]*RuntimeContainer {
	groups := make(map[string][]*RuntimeContainer)
	for _, v := range entries {
		value := deepGet(*v, key)
		if value != nil {
			items := strings.Split(value.(string), sep)
			for _, item := range items {
				groups[item] = append(groups[item], v)
			}

		}
	}
	return groups
}

// groupBy groups a list of *RuntimeContainers by the path property key
func groupBy(entries []*RuntimeContainer, key string) map[string][]*RuntimeContainer {
	groups := make(map[string][]*RuntimeContainer)
	for _, v := range entries {
		value := deepGet(*v, key)
		if value != nil {
			groups[value.(string)] = append(groups[value.(string)], v)
		}
	}
	return groups
}

// groupByKeys is the same as groupBy but only returns a list of keys
func groupByKeys(entries []*RuntimeContainer, key string) []string {
	groups := groupBy(entries, key)
	ret := []string{}
	for k, _ := range groups {
		ret = append(ret, k)
	}
	return ret
}

// selects entries based on key
func where(entries []*RuntimeContainer, key string, cmp string) []*RuntimeContainer {
	selection := []*RuntimeContainer{}
	for _, v := range entries {
		value := deepGet(*v, key)
		if value == cmp {
			selection = append(selection, v)
		}
	}
	return selection
}

// selects entries where a key exists
func whereExist(entries []*RuntimeContainer, key string) []*RuntimeContainer {
	selection := []*RuntimeContainer{}
	for _, v := range entries {
		value := deepGet(*v, key)
		if value != nil {
			selection = append(selection, v)
		}
	}
	return selection
}

// selects entries where a key does not exist
func whereNotExist(entries []*RuntimeContainer, key string) []*RuntimeContainer {
	selection := []*RuntimeContainer{}
	for _, v := range entries {
		value := deepGet(*v, key)
		if value == nil {
			selection = append(selection, v)
		}
	}
	return selection
}

// selects entries based on key.  Assumes key is delimited and breaks it apart before comparing
func whereAny(entries []*RuntimeContainer, key, sep string, cmp []string) []*RuntimeContainer {
	selection := []*RuntimeContainer{}
	for _, v := range entries {
		value := deepGet(*v, key)
		if value != nil {
			items := strings.Split(value.(string), sep)
			if len(intersect(cmp, items)) > 0 {
				selection = append(selection, v)
			}
		}
	}
	return selection
}

// selects entries based on key.  Assumes key is delimited and breaks it apart before comparing
func whereAll(entries []*RuntimeContainer, key, sep string, cmp []string) []*RuntimeContainer {
	selection := []*RuntimeContainer{}
	req_count := len(cmp)
	for _, v := range entries {
		value := deepGet(*v, key)
		if value != nil {
			items := strings.Split(value.(string), sep)
			if len(intersect(cmp, items)) == req_count {
				selection = append(selection, v)
			}
		}
	}
	return selection
}

// hasPrefix returns whether a given string is a prefix of another string
func hasPrefix(prefix, s string) bool {
	return strings.HasPrefix(s, prefix)
}

// hasSuffix returns whether a given string is a suffix of another string
func hasSuffix(suffix, s string) bool {
	return strings.HasSuffix(s, suffix)
}

func keys(input interface{}) (interface{}, error) {
	if input == nil {
		return nil, nil
	}

	val := reflect.ValueOf(input)
	if val.Kind() != reflect.Map {
		return nil, fmt.Errorf("Cannot call keys on a non-map value: %v", input)
	}

	vk := val.MapKeys()
	k := make([]interface{}, val.Len())
	for i, _ := range k {
		k[i] = vk[i].Interface()
	}

	return k, nil
}

func intersect(l1, l2 []string) []string {
	m := make(map[string]bool)
	m2 := make(map[string]bool)
	for _, v := range l2 {
		m2[v] = true
	}
	for _, v := range l1 {
		if m2[v] {
			m[v] = true
		}
	}
	keys := make([]string, 0, len(m))
	for k := range m {
		keys = append(keys, k)
	}
	return keys
}

func contains(item map[string]string, key string) bool {
	if _, ok := item[key]; ok {
		return true
	}
	return false
}

func dict(values ...interface{}) (map[string]interface{}, error) {
	if len(values)%2 != 0 {
		return nil, errors.New("invalid dict call")
	}
	dict := make(map[string]interface{}, len(values)/2)
	for i := 0; i < len(values); i += 2 {
		key, ok := values[i].(string)
		if !ok {
			return nil, errors.New("dict keys must be strings")
		}
		dict[key] = values[i+1]
	}
	return dict, nil
}

func hashSha1(input string) string {
	h := sha1.New()
	io.WriteString(h, input)
	return fmt.Sprintf("%x", h.Sum(nil))
}

func marshalJson(input interface{}) (string, error) {
	var buf bytes.Buffer
	enc := json.NewEncoder(&buf)
	if err := enc.Encode(input); err != nil {
		return "", err
	}
	return strings.TrimSuffix(buf.String(), "\n"), nil
}

// arrayFirst returns first item in the array or nil if the
// input is nil or empty
func arrayFirst(input interface{}) interface{} {
	if input == nil {
		return nil
	}

	arr := reflect.ValueOf(input)

	if arr.Len() == 0 {
		return nil
	}

	return arr.Index(0).Interface()
}

// arrayLast returns last item in the array
func arrayLast(input interface{}) interface{} {
	arr := reflect.ValueOf(input)
	return arr.Index(arr.Len() - 1).Interface()
}

// arrayClosest find the longest matching substring in values
// that matches input
func arrayClosest(values []string, input string) string {
	best := ""
	for _, v := range values {
		if strings.Contains(input, v) && len(v) > len(best) {
			best = v
		}
	}
	return best
}

// dirList returns a list of files in the specified path
func dirList(path string) ([]string, error) {
	names := []string{}
	files, err := ioutil.ReadDir(path)
	if err != nil {
		return names, err
	}
	for _, f := range files {
		names = append(names, f.Name())
	}
	return names, nil
}

// coalesce returns the first non nil argument
func coalesce(input ...interface{}) interface{} {
	for _, v := range input {
		if v != nil {
			return v
		}
	}
	return nil
}

// trimPrefix returns whether a given string is a prefix of another string
func trimPrefix(prefix, s string) string {
	return strings.TrimPrefix(s, prefix)
}

// trimSuffix returns whether a given string is a suffix of another string
func trimSuffix(suffix, s string) string {
	return strings.TrimSuffix(s, suffix)
}

func generateFile(config Config, containers Context) bool {
	templatePath := config.Template
	tmpl, err := template.New(filepath.Base(templatePath)).Funcs(template.FuncMap{
		"closest":       arrayClosest,
		"coalesce":      coalesce,
		"contains":      contains,
		"dict":          dict,
		"dir":           dirList,
		"exists":        exists,
		"first":         arrayFirst,
		"groupBy":       groupBy,
		"groupByKeys":   groupByKeys,
		"groupByMulti":  groupByMulti,
		"hasPrefix":     hasPrefix,
		"hasSuffix":     hasSuffix,
		"json":          marshalJson,
		"intersect":     intersect,
		"keys":          keys,
		"last":          arrayLast,
		"replace":       strings.Replace,
		"sha1":          hashSha1,
		"split":         strings.Split,
		"trimPrefix":    trimPrefix,
		"trimSuffix":    trimSuffix,
		"where":         where,
		"whereExist":    whereExist,
		"whereNotExist": whereNotExist,
		"whereAny":      whereAny,
		"whereAll":      whereAll,
	}).ParseFiles(templatePath)
	if err != nil {
		log.Fatalf("unable to parse template: %s", err)
	}

	filteredContainers := Context{}
	if config.OnlyPublished {
		for _, container := range containers {
			if len(container.PublishedAddresses()) > 0 {
				filteredContainers = append(filteredContainers, container)
			}
		}
	} else if config.OnlyExposed {
		for _, container := range containers {
			if len(container.Addresses) > 0 {
				filteredContainers = append(filteredContainers, container)
			}
		}
	} else {
		filteredContainers = containers
	}

	dest := os.Stdout
	if config.Dest != "" {
		dest, err = ioutil.TempFile(filepath.Dir(config.Dest), "docker-gen")
		defer func() {
			dest.Close()
			os.Remove(dest.Name())
		}()
		if err != nil {
			log.Fatalf("unable to create temp file: %s\n", err)
		}
	}

	var buf bytes.Buffer
	multiwriter := io.MultiWriter(dest, &buf)
	err = tmpl.ExecuteTemplate(multiwriter, filepath.Base(templatePath), &filteredContainers)
	if err != nil {
		log.Fatalf("template error: %s\n", err)
	}

	if config.Dest != "" {

		contents := []byte{}
		if fi, err := os.Stat(config.Dest); err == nil {
			if err := dest.Chmod(fi.Mode()); err != nil {
				log.Fatalf("unable to chmod temp file: %s\n", err)
			}
			if err := dest.Chown(int(fi.Sys().(*syscall.Stat_t).Uid), int(fi.Sys().(*syscall.Stat_t).Gid)); err != nil {
				log.Fatalf("unable to chown temp file: %s\n", err)
			}
			contents, err = ioutil.ReadFile(config.Dest)
			if err != nil {
				log.Fatalf("unable to compare current file contents: %s: %s\n", config.Dest, err)
			}
		}

		if bytes.Compare(contents, buf.Bytes()) != 0 {
			err = os.Rename(dest.Name(), config.Dest)
			if err != nil {
				log.Fatalf("unable to create dest file %s: %s\n", config.Dest, err)
			}
			log.Printf("Generated '%s' from %d containers", config.Dest, len(filteredContainers))
			return true
		}
		return false
	}
	return true
}
<|endoftext|>


<commit_before>package resources

import (
	"bytes"
	"fmt"
	"io"
	"text/template"
)

var pkg *template.Template

func reader(input io.Reader) (string, error) {

	var (
		buff       bytes.Buffer
		err        error
		blockwidth int = 12
		curblock   int = 0
	)

	b := make([]byte, blockwidth)

	for n, err := input.Read(b); err == nil; n, err = input.Read(b) {
		for i := 0; i < n; i++ {
			fmt.Fprintf(&buff, "0x%02x,", b[i])
			curblock++
			if curblock < blockwidth {
				continue
			}
			buff.Write([]byte{'\n'})
			buff.Write([]byte{'\t', '\t'})
			curblock = 0
		}
	}

	return buff.String(), err
}

func init() {

	pkg = template.Must(template.New("file").Funcs(template.FuncMap{"reader": reader}).Parse(` File{
	  data: []byte{
	{{ reader . }}
  },
  fi: FileInfo {
	name:    "{{ .Stat.Name }}",
    size:    {{ .Stat.Size }},
	modTime: time.Unix({{ .Stat.ModTime.Unix }},{{ .Stat.ModTime.UnixNano }}),
    isDir:   {{ .Stat.IsDir }},
  },
}`))

	pkg = template.Must(pkg.New("pkg").Parse(`{{ if .Tag }} // +build {{ .Tag }} {{ end }}

//Generated by github.com/omeid/slurp/resources
package {{ .Pkg }}

import (
  "net/http"
  "time"
  "bytes"
  "os"
  "strings"
)

{{ if .Declare }}
var {{ .Var }} http.FileSystem
{{ end }}

// Helper functions for easier file access.
func Open(name string) (http.File, error) {
	return {{ .Var }}.Open(name)
}

// http.FileSystem implementation.
type FileSystem struct {
	files map[string]File
}

func (fs *FileSystem) Open(name string) (http.File, error) {
	file, ok := fs.files[name]
	if !ok {
		files := []os.FileInfo{}
		for path, file := range fs.files {
			if strings.HasPrefix(path, name) {
				s, _ := file.Stat()
				files = append(files, s)
			}
		}

		if len(files) < 0 {
			return nil, os.ErrNotExist
		}

		//We have a directory.
		return &File{
		  fi: FileInfo{
				isDir: true,
				files: files,
			}}, nil
	}
	file.Reader = bytes.NewReader(file.data)
	return &file, nil
}

type File struct {
	*bytes.Reader
	data []byte
	fi FileInfo
}

// A noop-closer.
func (f *File) Close() error {
	return nil
}

func (f *File) Readdir(count int) ([]os.FileInfo, error) {
  return nil, os.ErrNotExist
}

func (f *File) Stat() (os.FileInfo, error) {
  return &f.fi, nil
}

type FileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
	isDir   bool
	sys     interface{}

	files []os.FileInfo
}

func (f *FileInfo) Name() string {
	return f.name
}
func (f *FileInfo) Size() int64 {
	return f.size
}

func (f *FileInfo) Mode() os.FileMode {
	return f.mode
}

func (f *FileInfo) ModTime() time.Time {
	return f.modTime
}

func (f *FileInfo) IsDir() bool {
	return f.isDir
}

func (f *FileInfo) Readdir(count int) ([]os.FileInfo, error) {
	return f.files, nil
}

func (f *FileInfo) Sys() interface{} {
	return f.sys
}

func init() {
  {{ .Var }} = &FileSystem{
		files: map[string]File{
		  {{range $path, $file := .Files }} "/{{ $path }}": {{ template "file" $file }}, {{ end }}
		},
	  }
}
`))
}
<commit_msg>Better indentation.<commit_after>package resources

import (
	"bytes"
	"fmt"
	"io"
	"text/template"
)

var pkg *template.Template

func reader(input io.Reader) (string, error) {

	var (
		buff       bytes.Buffer
		err        error
		blockwidth int = 12
		curblock   int = 0
	)

	b := make([]byte, blockwidth)

	for n, err := input.Read(b); err == nil; n, err = input.Read(b) {
		for i := 0; i < n; i++ {
			fmt.Fprintf(&buff, "0x%02x,", b[i])
			curblock++
			if curblock < blockwidth {
				continue
			}
			buff.Write([]byte{'\n'})
			buff.Write([]byte{'\t', '\t'})
			curblock = 0
		}
	}

	return buff.String(), err
}

func init() {

	pkg = template.Must(template.New("file").Funcs(template.FuncMap{"reader": reader}).Parse(` File{
	  data: []byte{
	{{ reader . }}
  },
  fi: FileInfo {
	name:    "{{ .Stat.Name }}",
    size:    {{ .Stat.Size }},
	modTime: time.Unix({{ .Stat.ModTime.Unix }},{{ .Stat.ModTime.UnixNano }}),
    isDir:   {{ .Stat.IsDir }},
  },
}`))

	pkg = template.Must(pkg.New("pkg").Parse(`{{ if .Tag }}// +build {{ .Tag }}

{{ end }}//Generated by github.com/omeid/slurp/resources
package {{ .Pkg }}

import (
  "net/http"
  "time"
  "bytes"
  "os"
  "strings"
)

{{ if .Declare }}
var {{ .Var }} http.FileSystem
{{ end }}

// Helper functions for easier file access.
func Open(name string) (http.File, error) {
	return {{ .Var }}.Open(name)
}

// http.FileSystem implementation.
type FileSystem struct {
	files map[string]File
}

func (fs *FileSystem) Open(name string) (http.File, error) {
	file, ok := fs.files[name]
	if !ok {
		files := []os.FileInfo{}
		for path, file := range fs.files {
			if strings.HasPrefix(path, name) {
				s, _ := file.Stat()
				files = append(files, s)
			}
		}

		if len(files) < 0 {
			return nil, os.ErrNotExist
		}

		//We have a directory.
		return &File{
		  fi: FileInfo{
				isDir: true,
				files: files,
			}}, nil
	}
	file.Reader = bytes.NewReader(file.data)
	return &file, nil
}

type File struct {
	*bytes.Reader
	data []byte
	fi FileInfo
}

// A noop-closer.
func (f *File) Close() error {
	return nil
}

func (f *File) Readdir(count int) ([]os.FileInfo, error) {
  return nil, os.ErrNotExist
}

func (f *File) Stat() (os.FileInfo, error) {
  return &f.fi, nil
}

type FileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
	isDir   bool
	sys     interface{}

	files []os.FileInfo
}

func (f *FileInfo) Name() string {
	return f.name
}
func (f *FileInfo) Size() int64 {
	return f.size
}

func (f *FileInfo) Mode() os.FileMode {
	return f.mode
}

func (f *FileInfo) ModTime() time.Time {
	return f.modTime
}

func (f *FileInfo) IsDir() bool {
	return f.isDir
}

func (f *FileInfo) Readdir(count int) ([]os.FileInfo, error) {
	return f.files, nil
}

func (f *FileInfo) Sys() interface{} {
	return f.sys
}

func init() {
  {{ .Var }} = &FileSystem{
		files: map[string]File{
		  {{range $path, $file := .Files }} "/{{ $path }}": {{ template "file" $file }}, {{ end }}
		},
	  }
}
`))
}
<|endoftext|>