<commit_before>package stackdriver

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"path"
	"regexp"
	"strings"
	"time"

	"golang.org/x/net/context/ctxhttp"

	"github.com/grafana/grafana/pkg/api/pluginproxy"
	"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
	"github.com/grafana/grafana/pkg/components/null"
	"github.com/grafana/grafana/pkg/log"
	"github.com/grafana/grafana/pkg/models"
	"github.com/grafana/grafana/pkg/plugins"
	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/tsdb"
	"github.com/opentracing/opentracing-go"
)

type StackdriverExecutor struct {
	HttpClient *http.Client
}

func NewStackdriverExecutor(datasource *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
	return &StackdriverExecutor{}, nil
}

var glog = log.New("tsdb.stackdriver")

func init() {
	tsdb.RegisterTsdbQueryEndpoint("stackdriver", NewStackdriverExecutor)
}

func (e *StackdriverExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) (*tsdb.Response, error) {
	result := &tsdb.Response{
		Results: make(map[string]*tsdb.QueryResult),
	}
	var target string

	startTime, err := tsdbQuery.TimeRange.ParseFrom()
	if err != nil {
		return nil, err
	}

	endTime, err := tsdbQuery.TimeRange.ParseTo()
	if err != nil {
		return nil, err
	}

	logger.Info("tsdbQuery", "req.URL.RawQuery", tsdbQuery.TimeRange.From)

	for _, query := range tsdbQuery.Queries {
		if fullTarget, err := query.Model.Get("targetFull").String(); err == nil {
			target = fixIntervalFormat(fullTarget)
		} else {
			target = fixIntervalFormat(query.Model.Get("target").MustString())
		}

		if setting.Env == setting.DEV {
			glog.Debug("Stackdriver request", "params")
		}

		req, err := e.createRequest(ctx, dsInfo)
		metricType := query.Model.Get("metricType").MustString()

		q := req.URL.Query()
		q.Add("interval.startTime", startTime.UTC().Format(time.RFC3339))
		q.Add("interval.endTime", endTime.UTC().Format(time.RFC3339))
		q.Add("aggregation.perSeriesAligner", "ALIGN_NONE")
		q.Add("filter", metricType)
		req.URL.RawQuery = q.Encode()
		logger.Info("tsdbQuery", "req.URL.RawQuery", req.URL.RawQuery)

		if err != nil {
			return nil, err
		}

		httpClient, err := dsInfo.GetHttpClient()
		if err != nil {
			return nil, err
		}

		span, ctx := opentracing.StartSpanFromContext(ctx, "stackdriver query")
		span.SetTag("target", target)
		span.SetTag("from", tsdbQuery.TimeRange.From)
		span.SetTag("until", tsdbQuery.TimeRange.To)
		span.SetTag("datasource_id", dsInfo.Id)
		span.SetTag("org_id", dsInfo.OrgId)

		defer span.Finish()

		opentracing.GlobalTracer().Inject(
			span.Context(),
			opentracing.HTTPHeaders,
			opentracing.HTTPHeadersCarrier(req.Header))

		res, err := ctxhttp.Do(ctx, httpClient, req)
		if err != nil {
			return nil, err
		}

		data, err := e.parseResponse(res)
		if err != nil {
			return nil, err
		}

		queryRes := tsdb.NewQueryResult()
		queryRes.RefId = query.RefId

		for _, series := range data.TimeSeries {
			points := make([]tsdb.TimePoint, 0)
			for _, point := range series.Points {
				points = append(points, tsdb.NewTimePoint(null.FloatFrom(point.Value.DoubleValue), float64((point.Interval.EndTime).Unix())*1000))
			}
			queryRes.Series = append(queryRes.Series, &tsdb.TimeSeries{
				Name:   series.Metric.Type,
				Points: points,
			})
		}
		result.Results[query.RefId] = queryRes
	}

	return result, nil
}

func (e *StackdriverExecutor) parseResponse(res *http.Response) (StackDriverResponse, error) {
	body, err := ioutil.ReadAll(res.Body)
	defer res.Body.Close()
	if err != nil {
		return StackDriverResponse{}, err
	}

	if res.StatusCode/100 != 2 {
		glog.Info("Request failed", "status", res.Status, "body", string(body))
		return StackDriverResponse{}, fmt.Errorf("Request failed status: %v", res.Status)
	}

	var data StackDriverResponse
	err = json.Unmarshal(body, &data)
	if err != nil {
		glog.Info("Failed to unmarshal graphite response", "error", err, "status", res.Status, "body", string(body))
		return StackDriverResponse{}, err
	}

	return data, nil
}

func (e *StackdriverExecutor) createRequest(ctx context.Context, dsInfo *models.DataSource) (*http.Request, error) {
	u, _ := url.Parse(dsInfo.Url)
	u.Path = path.Join(u.Path, "render")

	req, err := http.NewRequest(http.MethodGet, "https://monitoring.googleapis.com/", nil)
	if err != nil {
		glog.Info("Failed to create request", "error", err)
		return nil, fmt.Errorf("Failed to create request. error: %v", err)
	}

	req.Header.Set("Content-Type", "application/json")

	// find plugin
	plugin, ok := plugins.DataSources[dsInfo.Type]
	if !ok {
		return nil, errors.New("Unable to find datasource plugin Stackdriver")
	}
	proxyPass := fmt.Sprintf("stackdriver%s", "v3/projects/raintank-production/timeSeries")

	var stackdriverRoute *plugins.AppPluginRoute
	for _, route := range plugin.Routes {
		if route.Path == "stackdriver" {
			stackdriverRoute = route
			break
		}
	}

	pluginproxy.ApplyRoute(ctx, req, proxyPass, stackdriverRoute, dsInfo)

	return req, err
}

func formatTimeRange(input string) string {
	if input == "now" {
		return input
	}
	return strings.Replace(strings.Replace(strings.Replace(input, "now", "", -1), "m", "min", -1), "M", "mon", -1)
}

func fixIntervalFormat(target string) string {
	rMinute := regexp.MustCompile(`'(\d+)m'`)
	rMin := regexp.MustCompile("m")
	target = rMinute.ReplaceAllStringFunc(target, func(m string) string {
		return rMin.ReplaceAllString(m, "min")
	})
	rMonth := regexp.MustCompile(`'(\d+)M'`)
	rMon := regexp.MustCompile("M")
	target = rMonth.ReplaceAllStringFunc(target, func(M string) string {
		return rMon.ReplaceAllString(M, "mon")
	})
	return target
}
<commit_msg>Stackdriver: Break out parse response to its own func<commit_after>package stackdriver

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"path"
	"regexp"
	"strings"
	"time"

	"golang.org/x/net/context/ctxhttp"

	"github.com/grafana/grafana/pkg/api/pluginproxy"
	"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
	"github.com/grafana/grafana/pkg/components/null"
	"github.com/grafana/grafana/pkg/log"
	"github.com/grafana/grafana/pkg/models"
	"github.com/grafana/grafana/pkg/plugins"
	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/tsdb"
	"github.com/opentracing/opentracing-go"
)

type StackdriverExecutor struct {
	HttpClient *http.Client
}

func NewStackdriverExecutor(datasource *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
	return &StackdriverExecutor{}, nil
}

var glog = log.New("tsdb.stackdriver")

func init() {
	tsdb.RegisterTsdbQueryEndpoint("stackdriver", NewStackdriverExecutor)
}

func (e *StackdriverExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) (*tsdb.Response, error) {
	result := &tsdb.Response{
		Results: make(map[string]*tsdb.QueryResult),
	}
	var target string

	startTime, err := tsdbQuery.TimeRange.ParseFrom()
	if err != nil {
		return nil, err
	}

	endTime, err := tsdbQuery.TimeRange.ParseTo()
	if err != nil {
		return nil, err
	}

	logger.Info("tsdbQuery", "req.URL.RawQuery", tsdbQuery.TimeRange.From)

	for _, query := range tsdbQuery.Queries {
		if fullTarget, err := query.Model.Get("targetFull").String(); err == nil {
			target = fixIntervalFormat(fullTarget)
		} else {
			target = fixIntervalFormat(query.Model.Get("target").MustString())
		}

		if setting.Env == setting.DEV {
			glog.Debug("Stackdriver request", "params")
		}

		req, err := e.createRequest(ctx, dsInfo)
		metricType := query.Model.Get("metricType").MustString()

		q := req.URL.Query()
		q.Add("interval.startTime", startTime.UTC().Format(time.RFC3339))
		q.Add("interval.endTime", endTime.UTC().Format(time.RFC3339))
		q.Add("aggregation.perSeriesAligner", "ALIGN_NONE")
		q.Add("filter", metricType)
		req.URL.RawQuery = q.Encode()
		logger.Info("tsdbQuery", "req.URL.RawQuery", req.URL.RawQuery)

		if err != nil {
			return nil, err
		}

		httpClient, err := dsInfo.GetHttpClient()
		if err != nil {
			return nil, err
		}

		span, ctx := opentracing.StartSpanFromContext(ctx, "stackdriver query")
		span.SetTag("target", target)
		span.SetTag("from", tsdbQuery.TimeRange.From)
		span.SetTag("until", tsdbQuery.TimeRange.To)
		span.SetTag("datasource_id", dsInfo.Id)
		span.SetTag("org_id", dsInfo.OrgId)

		defer span.Finish()

		opentracing.GlobalTracer().Inject(
			span.Context(),
			opentracing.HTTPHeaders,
			opentracing.HTTPHeadersCarrier(req.Header))

		res, err := ctxhttp.Do(ctx, httpClient, req)
		if err != nil {
			return nil, err
		}

		data, err := e.unmarshalResponse(res)
		if err != nil {
			return nil, err
		}

		queryRes, err := e.parseResponse(data, query.RefId)
		result.Results[query.RefId] = queryRes
	}

	return result, nil
}

func (e *StackdriverExecutor) unmarshalResponse(res *http.Response) (StackDriverResponse, error) {
	body, err := ioutil.ReadAll(res.Body)
	defer res.Body.Close()
	if err != nil {
		return StackDriverResponse{}, err
	}

	if res.StatusCode/100 != 2 {
		glog.Info("Request failed", "status", res.Status, "body", string(body))
		return StackDriverResponse{}, fmt.Errorf("Request failed status: %v", res.Status)
	}

	var data StackDriverResponse
	err = json.Unmarshal(body, &data)
	if err != nil {
		glog.Info("Failed to unmarshal Stackdriver response", "error", err, "status", res.Status, "body", string(body))
		return StackDriverResponse{}, err
	}

	return data, nil
}

func (e *StackdriverExecutor) parseResponse(data StackDriverResponse, queryRefId string) (*tsdb.QueryResult, error) {
	queryRes := tsdb.NewQueryResult()
	queryRes.RefId = queryRefId

	for _, series := range data.TimeSeries {
		points := make([]tsdb.TimePoint, 0)
		for _, point := range series.Points {
			points = append(points, tsdb.NewTimePoint(null.FloatFrom(point.Value.DoubleValue), float64((point.Interval.EndTime).Unix())*1000))
		}
		queryRes.Series = append(queryRes.Series, &tsdb.TimeSeries{
			Name:   series.Metric.Type,
			Points: points,
		})
	}

	return queryRes, nil
}

func (e *StackdriverExecutor) createRequest(ctx context.Context, dsInfo *models.DataSource) (*http.Request, error) {
	u, _ := url.Parse(dsInfo.Url)
	u.Path = path.Join(u.Path, "render")

	req, err := http.NewRequest(http.MethodGet, "https://monitoring.googleapis.com/", nil)
	if err != nil {
		glog.Info("Failed to create request", "error", err)
		return nil, fmt.Errorf("Failed to create request. error: %v", err)
	}

	req.Header.Set("Content-Type", "application/json")

	// find plugin
	plugin, ok := plugins.DataSources[dsInfo.Type]
	if !ok {
		return nil, errors.New("Unable to find datasource plugin Stackdriver")
	}
	proxyPass := fmt.Sprintf("stackdriver%s", "v3/projects/raintank-production/timeSeries")

	var stackdriverRoute *plugins.AppPluginRoute
	for _, route := range plugin.Routes {
		if route.Path == "stackdriver" {
			stackdriverRoute = route
			break
		}
	}

	pluginproxy.ApplyRoute(ctx, req, proxyPass, stackdriverRoute, dsInfo)

	return req, err
}

func formatTimeRange(input string) string {
	if input == "now" {
		return input
	}
	return strings.Replace(strings.Replace(strings.Replace(input, "now", "", -1), "m", "min", -1), "M", "mon", -1)
}

func fixIntervalFormat(target string) string {
	rMinute := regexp.MustCompile(`'(\d+)m'`)
	rMin := regexp.MustCompile("m")
	target = rMinute.ReplaceAllStringFunc(target, func(m string) string {
		return rMin.ReplaceAllString(m, "min")
	})
	rMonth := regexp.MustCompile(`'(\d+)M'`)
	rMon := regexp.MustCompile("M")
	target = rMonth.ReplaceAllStringFunc(target, func(M string) string {
		return rMon.ReplaceAllString(M, "mon")
	})
	return target
}
<|endoftext|>


<commit_before>package virtwrap

import (
	"encoding/xml"
	"github.com/libvirt/libvirt-go"
	"k8s.io/client-go/pkg/api/meta"
	kubev1 "k8s.io/client-go/pkg/api/v1"
	metav1 "k8s.io/client-go/pkg/apis/meta/v1"
	"k8s.io/client-go/pkg/runtime/schema"
	"kubevirt.io/kubevirt/pkg/api/v1"
	"kubevirt.io/kubevirt/pkg/mapper"
	"kubevirt.io/kubevirt/pkg/precond"
)

type LifeCycle string

func init() {
	// TODO the whole mapping registration can be done be an automatic process with reflection
	mapper.AddConversion(&Memory{}, &v1.Memory{})
	mapper.AddConversion(&OS{}, &v1.OS{})
	mapper.AddConversion(&Devices{}, &v1.Devices{})
	mapper.AddConversion(&Devices{}, &v1.Devices{})
	mapper.AddPtrConversion((**Clock)(nil), (**v1.Clock)(nil))
	mapper.AddPtrConversion((**SysInfo)(nil), (**v1.SysInfo)(nil))
	mapper.AddConversion(&Channel{}, &v1.Channel{})
	mapper.AddConversion(&Interface{}, &v1.Interface{})
	mapper.AddConversion(&Video{}, &v1.Video{})
	mapper.AddConversion(&Graphics{}, &v1.Graphics{})
	mapper.AddPtrConversion((**Ballooning)(nil), (**v1.Ballooning)(nil))
	mapper.AddConversion(&Disk{}, &v1.Disk{})
	mapper.AddConversion(&DiskSource{}, &v1.DiskSource{})
	mapper.AddConversion(&DiskTarget{}, &v1.DiskTarget{})
	mapper.AddPtrConversion((**DiskDriver)(nil), (**v1.DiskDriver)(nil))
	mapper.AddPtrConversion((**ReadOnly)(nil), (**v1.ReadOnly)(nil))
	mapper.AddPtrConversion((**Address)(nil), (**v1.Address)(nil))
	mapper.AddConversion(&InterfaceSource{}, &v1.InterfaceSource{})
	mapper.AddPtrConversion((**InterfaceTarget)(nil), (**v1.InterfaceTarget)(nil))
	mapper.AddPtrConversion((**Model)(nil), (**v1.Model)(nil))
	mapper.AddPtrConversion((**MAC)(nil), (**v1.MAC)(nil))
	mapper.AddPtrConversion((**BandWidth)(nil), (**v1.BandWidth)(nil))
	mapper.AddPtrConversion((**BootOrder)(nil), (**v1.BootOrder)(nil))
	mapper.AddPtrConversion((**LinkState)(nil), (**v1.LinkState)(nil))
	mapper.AddPtrConversion((**FilterRef)(nil), (**v1.FilterRef)(nil))
	mapper.AddPtrConversion((**Alias)(nil), (**v1.Alias)(nil))
	mapper.AddConversion(&OSType{}, &v1.OSType{})
	mapper.AddPtrConversion((**SMBios)(nil), (**v1.SMBios)(nil))
	mapper.AddConversion(&Boot{}, &v1.Boot{})
	mapper.AddPtrConversion((**BootMenu)(nil), (**v1.BootMenu)(nil))
	mapper.AddPtrConversion((**BIOS)(nil), (**v1.BIOS)(nil))
	mapper.AddConversion(&Entry{}, &v1.Entry{})
	mapper.AddConversion(&ChannelSource{}, &v1.ChannelSource{})
	mapper.AddPtrConversion((**ChannelTarget)(nil), (**v1.ChannelTarget)(nil))
	mapper.AddConversion(&VideoModel{}, &v1.VideoModel{})
	mapper.AddConversion(&Listen{}, &v1.Listen{})
}

const (
	NoState     LifeCycle = "NoState"
	Running     LifeCycle = "Running"
	Blocked     LifeCycle = "Blocked"
	Paused      LifeCycle = "Paused"
	Shutdown    LifeCycle = "Shutdown"
	Shutoff     LifeCycle = "Shutoff"
	Crashed     LifeCycle = "Crashed"
	PMSuspended LifeCycle = "PMSuspended"
)

var LifeCycleTranslationMap = map[libvirt.DomainState]LifeCycle{
	libvirt.DOMAIN_NOSTATE:     NoState,
	libvirt.DOMAIN_RUNNING:     Running,
	libvirt.DOMAIN_BLOCKED:     Blocked,
	libvirt.DOMAIN_PAUSED:      Paused,
	libvirt.DOMAIN_SHUTDOWN:    Shutdown,
	libvirt.DOMAIN_SHUTOFF:     Shutoff,
	libvirt.DOMAIN_CRASHED:     Crashed,
	libvirt.DOMAIN_PMSUSPENDED: PMSuspended,
}

type Domain struct {
	metav1.TypeMeta
	ObjectMeta kubev1.ObjectMeta
	Spec       DomainSpec
	Status     DomainStatus
}

type DomainStatus struct {
	Status LifeCycle
}

type DomainList struct {
	metav1.TypeMeta
	ListMeta metav1.ListMeta
	Items    []Domain
}

type DomainSpec struct {
	XMLName xml.Name `xml:"domain" json:"-"`
	Name    string   `xml:"name" json:"name"`
	UUID    string   `xml:"uuid,omitempty" json:"uuid,omitempty"`
	Memory  Memory   `xml:"memory" json:"memory"`
	Type    string   `xml:"type,attr" json:"type"`
	OS      OS       `xml:"os" json:"os"`
	SysInfo *SysInfo `xml:"sysinfo,omitempty" json:"sysInfo,omitempty"`
	Devices Devices  `xml:"devices" json:"devices"`
	Clock   *Clock   `xml:"clock,omitempty" json:"clock,omitempty"`
}

type Memory struct {
	Value uint   `xml:",chardata" json:"value"`
	Unit  string `xml:"unit,attr" json:"unit"`
}

type Devices struct {
	Emulator   string      `xml:"emulator" json:"emulator"`
	Interfaces []Interface `xml:"interface" json:"interfaces,omitempty"`
	Channels   []Channel   `xml:"channel" json:"channels,omitempty"`
	Video      []Video     `xml:"video" json:"video,omitempty"`
	Graphics   []Graphics  `xml:"graphics" json:"graphics,omitempty"`
	Ballooning *Ballooning `xml:"memballoon,omitempty" json:"memballoon,omitempty"`
	Disks      []Disk      `xml:"disk" json:"disks,omitempty"`
}

// BEGIN Disk -----------------------------

type Disk struct {
	Device     string      `xml:"device,attr" json:"device"`
	Snapshot   string      `xml:"snapshot,attr" json:"shapshot"`
	Type       string      `xml:"type,attr" json:"type"`
	DiskSource DiskSource  `xml:"source" json:"diskSource"`
	DiskTarget DiskTarget  `xml:"target" json:"diskTarget"`
	Serial     string      `xml:"serial,omitempty" json:"serial,omitempty"`
	Driver     *DiskDriver `xml:"driver,omitempty" json:"driver,omitempty"`
	ReadOnly   *ReadOnly   `xml:"readonly,omitempty" json:"readOnly,omitempty"`
}

type ReadOnly struct{}

type DiskSource struct {
	File          string `xml:"file,attr" json:"file"`
	StartupPolicy string `xml:"startupPolicy,attr,omitempty" json:"startupPolicy,omitempty"`
}

type DiskTarget struct {
	Bus    string `xml:"bus,attr" json:"bus"`
	Device string `xml:"dev,attr" json:"dev"`
}

type DiskDriver struct {
	Cache       string `xml:"cache,attr,omitempty" json:"cache,omitempty"`
	ErrorPolicy string `xml:"error_policy,attr,omitempty" json:"errorPolicy,omitempty"`
	IO          string `xml:"io,attr,omitempty" json:"io,omitempty"`
	Name        string `xml:"name,attr" json:"name"`
	Type        string `xml:"type,attr" json:"type"`
}

// END Disk -----------------------------

// BEGIN Inteface -----------------------------

type Interface struct {
	Address   *Address         `xml:"address,omitempty" json:"address,omitempty"`
	Type      string           `xml:"type,attr" json:"type"`
	Source    InterfaceSource  `xml:"source" json:"source"`
	Target    *InterfaceTarget `xml:"target,omitempty" json:"target,omitempty"`
	Model     *Model           `xml:"model,omitempty" json:"model,omitempty"`
	MAC       *MAC             `xml:"mac,omitempty" json:"mac,omitempty"`
	BandWidth *BandWidth       `xml:"bandwidth,omitempty" json:"bandwidth,omitempty"`
	BootOrder *BootOrder       `xml:"boot,omitempty" json:"boot,omitempty"`
	LinkState *LinkState       `xml:"link,omitempty" json:"link,omitempty"`
	FilterRef *FilterRef       `xml:"filterref,omitempty" json:"filterRef,omitempty"`
	Alias     *Alias           `xml:"alias,omitempty" json:"alias,omitempty"`
}

type LinkState struct {
	State string `xml:"state,attr" json:"state"`
}

type BandWidth struct {
}

type BootOrder struct {
	Order uint `xml:"order,attr" json:"order"`
}

type MAC struct {
	MAC string `xml:"address,attr" json:"address"`
}

type FilterRef struct {
	Filter string `xml:"filter,attr" json:"filter"`
}

type InterfaceSource struct {
	Network string `xml:"network,attr,omitempty" json:"network,omitempty"`
	Device  string `xml:"dev,attr,omitempty" json:"device,omitempty"`
	Bridge  string `xml:"bridge,attr,omitempty" json:"bridge,omitempty"`
}

type Model struct {
	Type string `xml:"type,attr" json:"type"`
}

type InterfaceTarget struct {
	Device string `xml:"dev,attr" json:"dev"`
}

type Alias struct {
	Name string `xml:"name,attr" json:"name"`
}

// END Inteface -----------------------------
//BEGIN OS --------------------

type OS struct {
	Type       OSType    `xml:"type" json:"type"`
	SMBios     *SMBios   `xml:"smbios,omitempty" json:"smBIOS,omitempty"`
	BootOrder  []Boot    `xml:"boot" json:"bootOrder"`
	BootMenu   *BootMenu `xml:"bootmenu,omitempty" json:"bootMenu,omitempty"`
	BIOS       *BIOS     `xml:"bios,omitempty" json:"bios,omitempty"`
	Kernel     string    `xml:"kernel,omitempty" json:"kernel,omitempty"`
	Initrd     string    `xml:"initrd,omitempty" json:"initrd,omitempty"`
	KernelArgs string    `xml:"cmdline,omitempty" json:"cmdline,omitempty"`
}

type OSType struct {
	OS      string `xml:",chardata" json:"os"`
	Arch    string `xml:"arch,attr,omitempty" json:"arch,omitempty"`
	Machine string `xml:"machine,attr,omitempty" json:"machine,omitempty"`
}

type SMBios struct {
	Mode string `xml:"mode,attr" json:"mode"`
}

type NVRam struct {
	NVRam    string `xml:",chardata,omitempty" json:"nvRam,omitempty"`
	Template string `xml:"template,attr,omitempty" json:"template,omitempty"`
}

type Boot struct {
	Dev string `xml:"dev,attr" json:"dev"`
}

type BootMenu struct {
	Enabled bool  `xml:"enabled,attr" json:"enabled,omitempty"`
	Timeout *uint `xml:"timeout,attr,omitempty" json:"timeout,omitempty"`
}

// TODO <loader readonly='yes' secure='no' type='rom'>/usr/lib/xen/boot/hvmloader</loader>
type BIOS struct {
}

// TODO <bios useserial='yes' rebootTimeout='0'/>
type Loader struct {
}

type SysInfo struct {
	Type      string  `xml:"type,attr" json:"type"`
	System    []Entry `xml:"system>entry" json:"system"`
	BIOS      []Entry `xml:"bios>entry" json:"bios"`
	BaseBoard []Entry `xml:"baseBoard>entry" json:"baseBoard"`
}

type Entry struct {
	Name  string `xml:"name" json:"name"`
	Value string `xml:",chardata" json:"value"`
}

//END OS --------------------

//BEGIN Clock --------------------

type Clock struct {
}

type Timer struct {
	Name       string `xml:"name,attr" json:"name"`
	TickPolicy string `xml:"tickpolicy,attr,omitempty" json:"tickPolicy,omitempty"`
	Present    string `xml:"present,attr,omitempty" json:"present,omitempty"`
}

//END Clock --------------------

//BEGIN Channel --------------------

type Channel struct {
	Type   string         `xml:"type,attr" json:"type"`
	Source ChannelSource  `xml:"source,omitempty" json:"source,omitempty"`
	Target *ChannelTarget `xml:"target,omitempty" json:"target,omitempty"`
}

type ChannelTarget struct {
	Name    string `xml:"name,attr,omitempty" json:"name,omitempty"`
	Type    string `xml:"type,attr" json:"type"`
	Address string `xml:"address,attr,omitempty" json:"address,omitempty"`
	Port    uint   `xml:"port,attr,omitempty" json:"port,omitempty"`
}

type ChannelSource struct {
	Mode string `xml:"mode,attr" json:"mode"`
	Path string `xml:"path,attr" json:"path"`
}

//END Channel --------------------

//BEGIN Video -------------------
/*
<graphics autoport="yes" defaultMode="secure" listen="0" passwd="*****" passwdValidTo="1970-01-01T00:00:01" port="-1" tlsPort="-1" type="spice" />
*/

type Video struct {
	Model VideoModel `xml:"model"`
}

type VideoModel struct {
	Type   string `xml:"type,attr" json:"type"`
	Heads  uint   `xml:"heads,attr,omitempty" json:"heads,omitempty"`
	Ram    uint   `xml:"ram,attr,omitempty" json:"ram,omitempty"`
	VRam   uint   `xml:"vram,attr,omitempty" json:"vram,omitempty"`
	VGAMem uint   `xml:"vgamem,attr,omitempty" vgamem:"vram,omitempty"`
}

type Graphics struct {
	AutoPort      string `xml:"autoPort,attr,omitempty" json:"autoPort,omitempty"`
	DefaultMode   string `xml:"defaultMode,attr,omitempty" json:"defaultMode,omitempty"`
	Listen        Listen `xml:"listen,omitempty" json:"listen,omitempty"`
	PasswdValidTo string `xml:"passwdValidTo,attr,omitempty" json:"passwdValidTo,omitempty"`
	Port          int32  `xml:"port,attr,omitempty" json:"port,omitempty"`
	TLSPort       int    `xml:"tlsPort,attr,omitempty" json:"tlsPort,omitempty"`
	Type          string `xml:"type,attr" json:"type"`
}

type Listen struct {
	Type    string `xml:"type,attr" json:"type"`
	Address string `xml:"address,attr,omitempty" json:"address,omitempty"`
	Network string `xml:"newtork,attr,omitempty" json:"network,omitempty"`
}

type Address struct {
	Type     string `xml:"type,attr" json:"type"`
	Domain   string `xml:"domain,attr" json:"domain"`
	Bus      string `xml:"bus,attr" json:"bus"`
	Slot     string `xml:"slot,attr" json:"slot"`
	Function string `xml:"function,attr" json:"function"`
}

//END Video -------------------

type Ballooning struct {
	Model string `xml:"model,attr" json:"model"`
}

type RandomGenerator struct {
}

// TODO ballooning, rng, cpu ...

func NewMinimalVM(vmName string) *DomainSpec {
	precond.MustNotBeEmpty(vmName)
	domain := DomainSpec{OS: OS{Type: OSType{OS: "hvm"}}, Type: "qemu", Name: vmName}
	domain.Memory = Memory{Unit: "KiB", Value: 8192}
	domain.Devices = Devices{Emulator: "/usr/local/bin/qemu-x86_64"}
	domain.Devices.Interfaces = []Interface{
		{Type: "network", Source: InterfaceSource{Network: "default"}},
	}
	return &domain
}

// Required to satisfy Object interface
func (d *Domain) GetObjectKind() schema.ObjectKind {
	return &d.TypeMeta
}

// Required to satisfy ObjectMetaAccessor interface
func (d *Domain) GetObjectMeta() meta.Object {
	return &d.ObjectMeta
}

// Required to satisfy Object interface
func (dl *DomainList) GetObjectKind() schema.ObjectKind {
	return &dl.TypeMeta
}

// Required to satisfy ListMetaAccessor interface
func (dl *DomainList) GetListMeta() metav1.List {
	return &dl.ListMeta
}
<commit_msg>remove json tag from libvirt XML schema<commit_after>package virtwrap

import (
	"encoding/xml"
	"github.com/libvirt/libvirt-go"
	"k8s.io/client-go/pkg/api/meta"
	kubev1 "k8s.io/client-go/pkg/api/v1"
	metav1 "k8s.io/client-go/pkg/apis/meta/v1"
	"k8s.io/client-go/pkg/runtime/schema"
	"kubevirt.io/kubevirt/pkg/api/v1"
	"kubevirt.io/kubevirt/pkg/mapper"
	"kubevirt.io/kubevirt/pkg/precond"
)

type LifeCycle string

func init() {
	// TODO the whole mapping registration can be done be an automatic process with reflection
	mapper.AddConversion(&Memory{}, &v1.Memory{})
	mapper.AddConversion(&OS{}, &v1.OS{})
	mapper.AddConversion(&Devices{}, &v1.Devices{})
	mapper.AddConversion(&Devices{}, &v1.Devices{})
	mapper.AddPtrConversion((**Clock)(nil), (**v1.Clock)(nil))
	mapper.AddPtrConversion((**SysInfo)(nil), (**v1.SysInfo)(nil))
	mapper.AddConversion(&Channel{}, &v1.Channel{})
	mapper.AddConversion(&Interface{}, &v1.Interface{})
	mapper.AddConversion(&Video{}, &v1.Video{})
	mapper.AddConversion(&Graphics{}, &v1.Graphics{})
	mapper.AddPtrConversion((**Ballooning)(nil), (**v1.Ballooning)(nil))
	mapper.AddConversion(&Disk{}, &v1.Disk{})
	mapper.AddConversion(&DiskSource{}, &v1.DiskSource{})
	mapper.AddConversion(&DiskTarget{}, &v1.DiskTarget{})
	mapper.AddPtrConversion((**DiskDriver)(nil), (**v1.DiskDriver)(nil))
	mapper.AddPtrConversion((**ReadOnly)(nil), (**v1.ReadOnly)(nil))
	mapper.AddPtrConversion((**Address)(nil), (**v1.Address)(nil))
	mapper.AddConversion(&InterfaceSource{}, &v1.InterfaceSource{})
	mapper.AddPtrConversion((**InterfaceTarget)(nil), (**v1.InterfaceTarget)(nil))
	mapper.AddPtrConversion((**Model)(nil), (**v1.Model)(nil))
	mapper.AddPtrConversion((**MAC)(nil), (**v1.MAC)(nil))
	mapper.AddPtrConversion((**BandWidth)(nil), (**v1.BandWidth)(nil))
	mapper.AddPtrConversion((**BootOrder)(nil), (**v1.BootOrder)(nil))
	mapper.AddPtrConversion((**LinkState)(nil), (**v1.LinkState)(nil))
	mapper.AddPtrConversion((**FilterRef)(nil), (**v1.FilterRef)(nil))
	mapper.AddPtrConversion((**Alias)(nil), (**v1.Alias)(nil))
	mapper.AddConversion(&OSType{}, &v1.OSType{})
	mapper.AddPtrConversion((**SMBios)(nil), (**v1.SMBios)(nil))
	mapper.AddConversion(&Boot{}, &v1.Boot{})
	mapper.AddPtrConversion((**BootMenu)(nil), (**v1.BootMenu)(nil))
	mapper.AddPtrConversion((**BIOS)(nil), (**v1.BIOS)(nil))
	mapper.AddConversion(&Entry{}, &v1.Entry{})
	mapper.AddConversion(&ChannelSource{}, &v1.ChannelSource{})
	mapper.AddPtrConversion((**ChannelTarget)(nil), (**v1.ChannelTarget)(nil))
	mapper.AddConversion(&VideoModel{}, &v1.VideoModel{})
	mapper.AddConversion(&Listen{}, &v1.Listen{})
}

const (
	NoState     LifeCycle = "NoState"
	Running     LifeCycle = "Running"
	Blocked     LifeCycle = "Blocked"
	Paused      LifeCycle = "Paused"
	Shutdown    LifeCycle = "Shutdown"
	Shutoff     LifeCycle = "Shutoff"
	Crashed     LifeCycle = "Crashed"
	PMSuspended LifeCycle = "PMSuspended"
)

var LifeCycleTranslationMap = map[libvirt.DomainState]LifeCycle{
	libvirt.DOMAIN_NOSTATE:     NoState,
	libvirt.DOMAIN_RUNNING:     Running,
	libvirt.DOMAIN_BLOCKED:     Blocked,
	libvirt.DOMAIN_PAUSED:      Paused,
	libvirt.DOMAIN_SHUTDOWN:    Shutdown,
	libvirt.DOMAIN_SHUTOFF:     Shutoff,
	libvirt.DOMAIN_CRASHED:     Crashed,
	libvirt.DOMAIN_PMSUSPENDED: PMSuspended,
}

type Domain struct {
	metav1.TypeMeta
	ObjectMeta kubev1.ObjectMeta
	Spec       DomainSpec
	Status     DomainStatus
}

type DomainStatus struct {
	Status LifeCycle
}

type DomainList struct {
	metav1.TypeMeta
	ListMeta metav1.ListMeta
	Items    []Domain
}

type DomainSpec struct {
	XMLName xml.Name `xml:"domain"`
	Name    string   `xml:"name"`
	UUID    string   `xml:"uuid,omitempty"`
	Memory  Memory   `xml:"memory"`
	Type    string   `xml:"type,attr"`
	OS      OS       `xml:"os"`
	SysInfo *SysInfo `xml:"sysinfo,omitempty"`
	Devices Devices  `xml:"devices"`
	Clock   *Clock   `xml:"clock,omitempty"`
}

type Memory struct {
	Value uint   `xml:",chardata"`
	Unit  string `xml:"unit,attr"`
}

type Devices struct {
	Emulator   string      `xml:"emulator"`
	Interfaces []Interface `xml:"interface"`
	Channels   []Channel   `xml:"channel"`
	Video      []Video     `xml:"video"`
	Graphics   []Graphics  `xml:"graphics"`
	Ballooning *Ballooning `xml:"memballoon,omitempty"`
	Disks      []Disk      `xml:"disk"`
}

// BEGIN Disk -----------------------------

type Disk struct {
	Device     string      `xml:"device,attr"`
	Snapshot   string      `xml:"snapshot,attr"`
	Type       string      `xml:"type,attr"`
	DiskSource DiskSource  `xml:"source"`
	DiskTarget DiskTarget  `xml:"target"`
	Serial     string      `xml:"serial,omitempty"`
	Driver     *DiskDriver `xml:"driver,omitempty"`
	ReadOnly   *ReadOnly   `xml:"readonly,omitempty"`
}

type ReadOnly struct{}

type DiskSource struct {
	File          string `xml:"file,attr"`
	StartupPolicy string `xml:"startupPolicy,attr,omitempty"`
}

type DiskTarget struct {
	Bus    string `xml:"bus,attr"`
	Device string `xml:"dev,attr"`
}

type DiskDriver struct {
	Cache       string `xml:"cache,attr,omitempty"`
	ErrorPolicy string `xml:"error_policy,attr,omitempty"`
	IO          string `xml:"io,attr,omitempty"`
	Name        string `xml:"name,attr"`
	Type        string `xml:"type,attr"`
}

// END Disk -----------------------------

// BEGIN Inteface -----------------------------

type Interface struct {
	Address   *Address         `xml:"address,omitempty"`
	Type      string           `xml:"type,attr"`
	Source    InterfaceSource  `xml:"source"`
	Target    *InterfaceTarget `xml:"target,omitempty"`
	Model     *Model           `xml:"model,omitempty"`
	MAC       *MAC             `xml:"mac,omitempty"`
	BandWidth *BandWidth       `xml:"bandwidth,omitempty"`
	BootOrder *BootOrder       `xml:"boot,omitempty"`
	LinkState *LinkState       `xml:"link,omitempty"`
	FilterRef *FilterRef       `xml:"filterref,omitempty"`
	Alias     *Alias           `xml:"alias,omitempty"`
}

type LinkState struct {
	State string `xml:"state,attr"`
}

type BandWidth struct {
}

type BootOrder struct {
	Order uint `xml:"order,attr"`
}

type MAC struct {
	MAC string `xml:"address,attr"`
}

type FilterRef struct {
	Filter string `xml:"filter,attr"`
}

type InterfaceSource struct {
	Network string `xml:"network,attr,omitempty"`
	Device  string `xml:"dev,attr,omitempty"`
	Bridge  string `xml:"bridge,attr,omitempty"`
}

type Model struct {
	Type string `xml:"type,attr"`
}

type InterfaceTarget struct {
	Device string `xml:"dev,attr"`
}

type Alias struct {
	Name string `xml:"name,attr"`
}

// END Inteface -----------------------------
//BEGIN OS --------------------

type OS struct {
	Type       OSType    `xml:"type"`
	SMBios     *SMBios   `xml:"smbios,omitempty"`
	BootOrder  []Boot    `xml:"boot"`
	BootMenu   *BootMenu `xml:"bootmenu,omitempty"`
	BIOS       *BIOS     `xml:"bios,omitempty"`
	Kernel     string    `xml:"kernel,omitempty"`
	Initrd     string    `xml:"initrd,omitempty"`
	KernelArgs string    `xml:"cmdline,omitempty"`
}

type OSType struct {
	OS      string `xml:",chardata"`
	Arch    string `xml:"arch,attr,omitempty"`
	Machine string `xml:"machine,attr,omitempty"`
}

type SMBios struct {
	Mode string `xml:"mode,attr"`
}

type NVRam struct {
	NVRam    string `xml:",chardata,omitempty"`
	Template string `xml:"template,attr,omitempty"`
}

type Boot struct {
	Dev string `xml:"dev,attr"`
}

type BootMenu struct {
	Enabled bool  `xml:"enabled,attr"`
	Timeout *uint `xml:"timeout,attr,omitempty"`
}

// TODO <loader readonly='yes' secure='no' type='rom'>/usr/lib/xen/boot/hvmloader</loader>
type BIOS struct {
}

// TODO <bios useserial='yes' rebootTimeout='0'/>
type Loader struct {
}

type SysInfo struct {
	Type      string  `xml:"type,attr"`
	System    []Entry `xml:"system>entry"`
	BIOS      []Entry `xml:"bios>entry"`
	BaseBoard []Entry `xml:"baseBoard>entry"`
}

type Entry struct {
	Name  string `xml:"name"`
	Value string `xml:",chardata"`
}

//END OS --------------------

//BEGIN Clock --------------------

type Clock struct {
}

type Timer struct {
	Name       string `xml:"name,attr"`
	TickPolicy string `xml:"tickpolicy,attr,omitempty"`
	Present    string `xml:"present,attr,omitempty"`
}

//END Clock --------------------

//BEGIN Channel --------------------

type Channel struct {
	Type   string         `xml:"type,attr"`
	Source ChannelSource  `xml:"source,omitempty"`
	Target *ChannelTarget `xml:"target,omitempty"`
}

type ChannelTarget struct {
	Name    string `xml:"name,attr,omitempty"`
	Type    string `xml:"type,attr"`
	Address string `xml:"address,attr,omitempty"`
	Port    uint   `xml:"port,attr,omitempty"`
}

type ChannelSource struct {
	Mode string `xml:"mode,attr"`
	Path string `xml:"path,attr"`
}

//END Channel --------------------

//BEGIN Video -------------------
/*
<graphics autoport="yes" defaultMode="secure" listen="0" passwd="*****" passwdValidTo="1970-01-01T00:00:01" port="-1" tlsPort="-1" type="spice" />
*/

type Video struct {
	Model VideoModel `xml:"model"`
}

type VideoModel struct {
	Type   string `xml:"type,attr"`
	Heads  uint   `xml:"heads,attr,omitempty"`
	Ram    uint   `xml:"ram,attr,omitempty"`
	VRam   uint   `xml:"vram,attr,omitempty"`
	VGAMem uint   `xml:"vgamem,attr,omitempty" vgamem:"vram,omitempty"`
}

type Graphics struct {
	AutoPort      string `xml:"autoPort,attr,omitempty"`
	DefaultMode   string `xml:"defaultMode,attr,omitempty"`
	Listen        Listen `xml:"listen,omitempty"`
	PasswdValidTo string `xml:"passwdValidTo,attr,omitempty"`
	Port          int32  `xml:"port,attr,omitempty"`
	TLSPort       int    `xml:"tlsPort,attr,omitempty"`
	Type          string `xml:"type,attr"`
}

type Listen struct {
	Type    string `xml:"type,attr"`
	Address string `xml:"address,attr,omitempty"`
	Network string `xml:"newtork,attr,omitempty"`
}

type Address struct {
	Type     string `xml:"type,attr"`
	Domain   string `xml:"domain,attr"`
	Bus      string `xml:"bus,attr"`
	Slot     string `xml:"slot,attr"`
	Function string `xml:"function,attr"`
}

//END Video -------------------

type Ballooning struct {
	Model string `xml:"model,attr"`
}

type RandomGenerator struct {
}

// TODO ballooning, rng, cpu ...

func NewMinimalVM(vmName string) *DomainSpec {
	precond.MustNotBeEmpty(vmName)
	domain := DomainSpec{OS: OS{Type: OSType{OS: "hvm"}}, Type: "qemu", Name: vmName}
	domain.Memory = Memory{Unit: "KiB", Value: 8192}
	domain.Devices = Devices{Emulator: "/usr/local/bin/qemu-x86_64"}
	domain.Devices.Interfaces = []Interface{
		{Type: "network", Source: InterfaceSource{Network: "default"}},
	}
	return &domain
}

// Required to satisfy Object interface
func (d *Domain) GetObjectKind() schema.ObjectKind {
	return &d.TypeMeta
}

// Required to satisfy ObjectMetaAccessor interface
func (d *Domain) GetObjectMeta() meta.Object {
	return &d.ObjectMeta
}

// Required to satisfy Object interface
func (dl *DomainList) GetObjectKind() schema.ObjectKind {
	return &dl.TypeMeta
}

// Required to satisfy ListMetaAccessor interface
func (dl *DomainList) GetListMeta() metav1.List {
	return &dl.ListMeta
}
<|endoftext|>


<commit_before>package main

import "fmt"

const MINHEAT    = 10
const MEDIUMHEAT = 20
const MAXHEAT    = 30

type tile struct {
	xCoord int
	yCoord int

	heat			int //how hot a tile is before fire
	fireLevel int //strength of the fire

	wall bool
	door bool

	occupied bool
	personID int

	outOfBounds bool

	neighborNorth *tile
	neighborEast  *tile
	neighborSouth *tile
	neighborWest  *tile
}

//Initializes the fire
func SetFire(thisTile *tile) {
  thisTile.heat = MINHEAT
  thisTile.fireLevel = 1
}

func FireSpread(tileMap [][]tile) {
	for x:= 0; x < len(tileMap); x++{
		for y:= 0; y < len(tileMap[0]); y++{
			fireSpreadTile(&(tileMap[x][y]))
		}
	}

}

func fireSpreadTile(thisTile *tile){
	if thisTile.heat >= MINHEAT {
		thisTile.fireLevel = 1
	}
	if thisTile.heat >= MEDIUMHEAT {
		thisTile.fireLevel = 2
	}
	if thisTile.heat >= MAXHEAT {
		thisTile.fireLevel = 3
	}

	if thisTile.neighborNorth != nil && thisTile.fireLevel != 0 {
		(thisTile.neighborNorth.heat) += thisTile.fireLevel
	}
	if thisTile.neighborEast != nil && thisTile.fireLevel != 0 {
		(thisTile.neighborEast.heat)	+= thisTile.fireLevel
	}
	if thisTile.neighborWest != nil && thisTile.fireLevel != 0 {
		(thisTile.neighborWest.heat)	+= thisTile.fireLevel
	}
	if thisTile.neighborSouth != nil && thisTile.fireLevel != 0 {
		(thisTile.neighborSouth.heat) += thisTile.fireLevel
	}
}

func assignNeighbor(thisTile *tile, x int, y int, maxX int, maxY int, tileMap [][]tile) {
	if x > 0 {
		thisTile.neighborNorth = &tileMap[x-1][y]
	}

	if y > 0 {
		thisTile.neighborWest = &tileMap[x][y-1]
	}

	if x < maxX-1 {
		thisTile.neighborSouth = &tileMap[x+1][y]
	}

	if y < maxY-1 {
		thisTile.neighborEast = &tileMap[x][y+1]
	}
}

func makeNewTile(thisPoint int, x int, y int) tile{

	//makes a basic floor tile with no nothin on it
	//and also no neighbors
	newTile := tile{x, y, 0, 0, false, false, false, 0, false, nil, nil, nil, nil}

	if thisPoint == 0 {
		//make normal floor
		//helt normalt flour

		//append to tilemap
	} else if thisPoint == 1 {
		//wall
		newTile.wall = true
	} else if thisPoint == 2 {
		//door
		newTile.door = true
	} else if thisPoint == 3 {
		//out of bounds
		newTile.outOfBounds = true
	}

	return newTile
}

func TileConvert(inMap [][]int) [][]tile{
	mapXSize := len(inMap)
	mapYSize := len(inMap[0])

	//Initiates a slice of tile slices (2D tile slice)
	tileMap := make([][]tile, mapXSize)

	for x:= 0; x < mapXSize; x++{
		//initiates slice of tiles
		tileMap[x] = make([]tile, mapYSize)

		for y:= 0; y < mapYSize; y++{
			//constructs a new tile
			newTile := makeNewTile(inMap[x][y], x, y)

			//inserts tile into 2d slice
			tileMap[x][y] = newTile

		}
	}

	//Assigns 4 neighbors to each tile
	for x:= 0; x < mapXSize; x++{
		for y:= 0; y < mapYSize; y++{
			assignNeighbor(&(tileMap[x][y]), x, y, mapXSize, mapYSize, tileMap)
		}
	}

	return tileMap
}

func printTile(thisTile tile) {
	if thisTile.wall {
		fmt.Print("[vägg(")
	} else if thisTile.door {
		fmt.Print("[dörr(")
	} else if thisTile.outOfBounds {
		fmt.Print("[ute(")
	} else {
		fmt.Print("[golv(")
	}
  fmt.Print(thisTile.fireLevel)

  fmt.Print(" Heat: ")
  fmt.Print(thisTile.heat)
	fmt.Print(")] ")
}

func printTileMap(inMap [][]tile) {
	mapXSize := len(inMap)
	mapYSize := len(inMap[0])

	for x:= 0; x < mapXSize; x++{
		for y:= 0; y < mapYSize; y++{
			printTile(inMap[x][y])
		}
		fmt.Print("\n")
	}
}
func printNeighbors(atile tile) {
	if atile.neighborNorth != nil {
		fmt.Print("North: ")
		printTile(*(atile.neighborNorth))
		fmt.Print("\n")
	} else {
		fmt.Print("North: nil\n")
	}
	if atile.neighborWest != nil {
		fmt.Print("West: ")
		printTile(*(atile.neighborWest))
		fmt.Print("\n")
	} else {
		fmt.Print("West: nil\n")
	}
	if atile.neighborEast != nil {
		fmt.Print("East: ")
		printTile(*(atile.neighborEast))
		fmt.Print("\n")
	} else {
		fmt.Print("East: nil\n")
	}
	if atile.neighborSouth != nil {
		fmt.Print("South: ")
		printTile(*(atile.neighborSouth))
		fmt.Print("\n")
	} else {
		fmt.Print("South: nil\n")
	}
}

func main() {
/*	testMatrix := [][]int{
		{0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0},
		{1, 1, 0, 1, 1},
		{0, 0, 0, 3, 3}}

	amap := TileConvert(testMatrix)
	//tileConvert(testMatrix)
//	printTileMap(amap)
	fmt.Print("\n")
	printNeighbors(amap[0][0])

	//fire testing
	SetFire(&(amap[2][2]))
	printTileMap(amap)
//

    for i := 0; i < 100; i++{
			FireSpread(amap)
		//	if i%10 == 0{
        fmt.Println("\n")
				printTileMap(amap)
			//}
		}*/

	mainPath()

}
<commit_msg>changed queue and pathfinder to mainly work with pointers, also began to change some stuff in people, added hp etc<commit_after>package main

import "fmt"

const MINHEAT    = 10
const MEDIUMHEAT = 20
const MAXHEAT    = 30

type tile struct {
	xCoord int
	yCoord int

	heat			int //how hot a tile is before fire
	fireLevel int //strength of the fire

	wall bool
	door bool

	occupied bool
	personID int

	outOfBounds bool

	neighborNorth *tile
	neighborEast  *tile
	neighborSouth *tile
	neighborWest  *tile
}

//Initializes the fire
func SetFire(thisTile *tile) {
  thisTile.heat = MINHEAT
  thisTile.fireLevel = 1
}

func FireSpread(tileMap [][]tile) {
	for x:= 0; x < len(tileMap); x++{
		for y:= 0; y < len(tileMap[0]); y++{
			fireSpreadTile(&(tileMap[x][y]))
		}
	}

}

func fireSpreadTile(thisTile *tile){
	if thisTile.heat >= MINHEAT {
		thisTile.fireLevel = 1
	}
	if thisTile.heat >= MEDIUMHEAT {
		thisTile.fireLevel = 2
	}
	if thisTile.heat >= MAXHEAT {
		thisTile.fireLevel = 3
	}

	if thisTile.neighborNorth != nil && thisTile.fireLevel != 0 {
		(thisTile.neighborNorth.heat) += thisTile.fireLevel
	}
	if thisTile.neighborEast != nil && thisTile.fireLevel != 0 {
		(thisTile.neighborEast.heat)	+= thisTile.fireLevel
	}
	if thisTile.neighborWest != nil && thisTile.fireLevel != 0 {
		(thisTile.neighborWest.heat)	+= thisTile.fireLevel
	}
	if thisTile.neighborSouth != nil && thisTile.fireLevel != 0 {
		(thisTile.neighborSouth.heat) += thisTile.fireLevel
	}
}

func assignNeighbor(thisTile *tile, x int, y int, maxX int, maxY int, tileMap [][]tile) {
	if x > 0 {
		thisTile.neighborNorth = &tileMap[x-1][y]
	}

	if y > 0 {
		thisTile.neighborWest = &tileMap[x][y-1]
	}

	if x < maxX-1 {
		thisTile.neighborSouth = &tileMap[x+1][y]
	}

	if y < maxY-1 {
		thisTile.neighborEast = &tileMap[x][y+1]
	}
}

func makeNewTile(thisPoint int, x int, y int) tile{

	//makes a basic floor tile with no nothin on it
	//and also no neighbors
	newTile := tile{x, y, 0, 0, false, false, false, 0, false, nil, nil, nil, nil}

	if thisPoint == 0 {
		//make normal floor
		//helt normalt flour

		//append to tilemap
	} else if thisPoint == 1 {
		//wall
		newTile.wall = true
	} else if thisPoint == 2 {
		//door
		newTile.door = true
	} else if thisPoint == 3 {
		//out of bounds
		newTile.outOfBounds = true
	}

	return newTile
}

func TileConvert(inMap [][]int) [][]tile{
	mapXSize := len(inMap)
	mapYSize := len(inMap[0])

	//Initiates a slice of tile slices (2D tile slice)
	tileMap := make([][]tile, mapXSize)

	for x:= 0; x < mapXSize; x++{
		//initiates slice of tiles
		tileMap[x] = make([]tile, mapYSize)

		for y:= 0; y < mapYSize; y++{
			//constructs a new tile
			newTile := makeNewTile(inMap[x][y], x, y)

			//inserts tile into 2d slice
			tileMap[x][y] = newTile

		}
	}

	//Assigns 4 neighbors to each tile
	for x:= 0; x < mapXSize; x++{
		for y:= 0; y < mapYSize; y++{
			assignNeighbor(&(tileMap[x][y]), x, y, mapXSize, mapYSize, tileMap)
		}
	}

	return tileMap
}

func printTile(thisTile tile) {
	if thisTile.wall {
		fmt.Print("[vägg(")
	} else if thisTile.door {
		fmt.Print("[dörr(")
	} else if thisTile.outOfBounds {
		fmt.Print("[ute(")
	} else {
		fmt.Print("[golv(")
	}
  fmt.Print(thisTile.fireLevel)

  fmt.Print(" Heat: ")
  fmt.Print(thisTile.heat)
	fmt.Print(")] ")
}

func printTileMap(inMap [][]tile) {
	mapXSize := len(inMap)
	mapYSize := len(inMap[0])

	for x:= 0; x < mapXSize; x++{
		for y:= 0; y < mapYSize; y++{
			printTile(inMap[x][y])
		}
		fmt.Print("\n")
	}
}
func printNeighbors(atile tile) {
	if atile.neighborNorth != nil {
		fmt.Print("North: ")
		printTile(*(atile.neighborNorth))
		fmt.Print("\n")
	} else {
		fmt.Print("North: nil\n")
	}
	if atile.neighborWest != nil {
		fmt.Print("West: ")
		printTile(*(atile.neighborWest))
		fmt.Print("\n")
	} else {
		fmt.Print("West: nil\n")
	}
	if atile.neighborEast != nil {
		fmt.Print("East: ")
		printTile(*(atile.neighborEast))
		fmt.Print("\n")
	} else {
		fmt.Print("East: nil\n")
	}
	if atile.neighborSouth != nil {
		fmt.Print("South: ")
		printTile(*(atile.neighborSouth))
		fmt.Print("\n")
	} else {
		fmt.Print("South: nil\n")
	}
}

func main() {
/*	testMatrix := [][]int{
		{0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0},
		{1, 1, 0, 1, 1},
		{0, 0, 0, 3, 3}}

	amap := TileConvert(testMatrix)
	//tileConvert(testMatrix)
//	printTileMap(amap)
	fmt.Print("\n")
	printNeighbors(amap[0][0])

	//fire testing
	SetFire(&(amap[2][2]))
	printTileMap(amap)
//

    for i := 0; i < 100; i++{
			FireSpread(amap)
		//	if i%10 == 0{
        fmt.Println("\n")
				printTileMap(amap)
			//}
		}*/

	//mainPath()
	mainPeople()

}
<|endoftext|>


<commit_before>package v3

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"path"
	"strings"
	"time"

	"os/exec"

	"github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	"github.com/cloudfoundry-incubator/cf-test-helpers/runner"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"

	archive_helpers "github.com/pivotal-golang/archiver/extractor/test_helper"
)

var _ = Describe("v3 staging", func() {
	var createBuildpack = func() string {
		tmpPath, err := ioutil.TempDir("", "env-group-staging")
		Expect(err).ToNot(HaveOccurred())

		buildpackArchivePath := path.Join(tmpPath, "buildpack.zip")

		archive_helpers.CreateZipArchive(buildpackArchivePath, []archive_helpers.ArchiveFile{
			{
				Name: "bin/compile",
				Body: `#!/usr/bin/env bash
sleep 5
echo "STAGED WITH CUSTOM BUILDPACK"
exit 1
`,
			},
			{
				Name: "bin/detect",
				Body: `#!/bin/bash
exit 1
`,
			},
			{
				Name: "bin/release",
				Body: `#!/usr/bin/env bash
exit 1
`,
			},
		})

		return buildpackArchivePath
	}

	var appName string
	var appGuid string
	var buildpackName string
	var buildpackGuid string
	var packageGuid string
	var spaceGuid string
	var token string

		BeforeEach(func() {
		appName = generator.RandomName()

		buildpackName = generator.RandomName()
		buildpackZip := createBuildpack()

		cf.AsUser(context.AdminUserContext(), func() {
				Expect(cf.Cf("create-buildpack", buildpackName, buildpackZip, "999").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			})

		session := cf.Cf("curl", fmt.Sprintf("/v2/spaces?q=name:%s", context.RegularUserContext().Space))
		bytes := session.Wait().Out.Contents()
		var space struct {
				Resources []struct {
				Metadata struct {
					Guid string `json:"guid"`
				} `json:"metadata"`
			} `json:"resources"`
			}
		json.Unmarshal(bytes, &space)
		spaceGuid = space.Resources[0].Metadata.Guid

		session = cf.Cf("curl", fmt.Sprintf("/v2/buildpacks?q=name:%s", buildpackName))
		bytes = session.Wait().Out.Contents()
		var buildpack struct {
				Resources []struct {
				Metadata struct {
					Guid string `json:"guid"`
				} `json:"metadata"`
			} `json:"resources"`
			}
		json.Unmarshal(bytes, &buildpack)
		buildpackGuid = buildpack.Resources[0].Metadata.Guid

		// CREATE APP
		session = cf.Cf("curl", "/v3/apps", "-X", "POST", "-d", fmt.Sprintf(`{"name":"%s", "space_guid":"%s"}`, appName, spaceGuid))
		bytes = session.Wait().Out.Contents()
		var app struct {
				Guid string `json:"guid"`
			}
		json.Unmarshal(bytes, &app)
		appGuid = app.Guid

		// CREATE PACKAGE
		packageCreateUrl := fmt.Sprintf("/v3/apps/%s/packages", appGuid)
		session = cf.Cf("curl", packageCreateUrl, "-X", "POST", "-d", fmt.Sprintf(`{"type":"bits"}`))
		bytes = session.Wait().Out.Contents()
		var pac struct {
				Guid string `json:"guid"`
			}
		json.Unmarshal(bytes, &pac)
		packageGuid = pac.Guid

		// UPLOAD PACKAGE
		bytes = runner.Run("bash", "-c", "cf oauth-token | tail -n +4").Wait(5).Out.Contents()
		token = strings.TrimSpace(string(bytes))
		uploadUrl := fmt.Sprintf("%s/v3/packages/%s/upload", config.ApiEndpoint, packageGuid)
		bytes, _ = exec.Command("curl", "-v", "-s", uploadUrl, "-F", `bits=@"/Users/pivotal/workspace/cf-release/src/acceptance-tests/dora.zip"`, "-H", fmt.Sprintf("Authorization: %s", token)).CombinedOutput()
		pkgUrl := fmt.Sprintf("/v3/packages/%s", packageGuid)
		Eventually(func() *Session {
				session = cf.Cf("curl", pkgUrl)
				Expect(session.Wait(DEFAULT_TIMEOUT)).To(Exit(0))
				return session
			}, 1 * time.Minute).Should(Say("READY"))
	})

	AfterEach(func() {
		cf.AsUser(context.AdminUserContext(), func() {
				Expect(cf.Cf("delete-buildpack", buildpackName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})
	})

	It("Stages with a user specified admin buildpack", func() {
		// STAGE PACKAGE
		stageUrl := fmt.Sprintf("/v3/packages/%s/droplets", packageGuid)
		session := cf.Cf("curl", stageUrl, "-X", "POST", "-d", fmt.Sprintf(`{"buildpack_guid":"%s"}`, buildpackGuid))
		bytes := session.Wait().Out.Contents()
		var droplet struct {
				Guid string `json:"guid"`
			}
		json.Unmarshal(bytes, &droplet)
		dropletGuid := droplet.Guid
		fmt.Println(string(bytes))

		logUrl := fmt.Sprintf("loggregator.%s/recent?app=%s", config.AppsDomain, dropletGuid)
		Eventually(func() *Session {
			session = runner.Curl(logUrl, "-H", fmt.Sprintf("Authorization: %s", token))
			Expect(session.Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			return session
		}, 1 * time.Minute, 10 * time.Second).Should(Say("STAGED WITH CUSTOM BUILDPACK"))
	})

	It("Stages with a user specified admin buildpack", func() {
		// STAGE PACKAGE
		stageUrl := fmt.Sprintf("/v3/packages/%s/droplets", packageGuid)
		session := cf.Cf("curl", stageUrl, "-X", "POST", "-d", `{"buildpack_git_url":"http://github.com/cloudfoundry/go-buildpack"}`)
		bytes := session.Wait().Out.Contents()
		var droplet struct {
				Guid string `json:"guid"`
			}
		json.Unmarshal(bytes, &droplet)
		dropletGuid := droplet.Guid
		fmt.Println(string(bytes))

		logUrl := fmt.Sprintf("loggregator.%s/recent?app=%s", config.AppsDomain, dropletGuid)
		Eventually(func() *Session {
				session = runner.Curl(logUrl, "-H", fmt.Sprintf("Authorization: %s", token))
				Expect(session.Wait(DEFAULT_TIMEOUT)).To(Exit(0))
				fmt.Println(string(session.Out.Contents()))
				return session
			}, 3 * time.Minute, 10 * time.Second).Should(Say("Cloning into"))
	})
})
<commit_msg>Gofmt<commit_after>package v3

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"path"
	"strings"
	"time"

	"os/exec"

	"github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	"github.com/cloudfoundry-incubator/cf-test-helpers/runner"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"

	archive_helpers "github.com/pivotal-golang/archiver/extractor/test_helper"
)

var _ = Describe("v3 staging", func() {
	var createBuildpack = func() string {
		tmpPath, err := ioutil.TempDir("", "env-group-staging")
		Expect(err).ToNot(HaveOccurred())

		buildpackArchivePath := path.Join(tmpPath, "buildpack.zip")

		archive_helpers.CreateZipArchive(buildpackArchivePath, []archive_helpers.ArchiveFile{
			{
				Name: "bin/compile",
				Body: `#!/usr/bin/env bash
sleep 5
echo "STAGED WITH CUSTOM BUILDPACK"
exit 1
`,
			},
			{
				Name: "bin/detect",
				Body: `#!/bin/bash
exit 1
`,
			},
			{
				Name: "bin/release",
				Body: `#!/usr/bin/env bash
exit 1
`,
			},
		})

		return buildpackArchivePath
	}

	var appName string
	var appGuid string
	var buildpackName string
	var buildpackGuid string
	var packageGuid string
	var spaceGuid string
	var token string

	BeforeEach(func() {
		appName = generator.RandomName()

		buildpackName = generator.RandomName()
		buildpackZip := createBuildpack()

		cf.AsUser(context.AdminUserContext(), func() {
			Expect(cf.Cf("create-buildpack", buildpackName, buildpackZip, "999").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})

		session := cf.Cf("curl", fmt.Sprintf("/v2/spaces?q=name:%s", context.RegularUserContext().Space))
		bytes := session.Wait().Out.Contents()
		var space struct {
			Resources []struct {
				Metadata struct {
					Guid string `json:"guid"`
				} `json:"metadata"`
			} `json:"resources"`
		}
		json.Unmarshal(bytes, &space)
		spaceGuid = space.Resources[0].Metadata.Guid

		session = cf.Cf("curl", fmt.Sprintf("/v2/buildpacks?q=name:%s", buildpackName))
		bytes = session.Wait().Out.Contents()
		var buildpack struct {
			Resources []struct {
				Metadata struct {
					Guid string `json:"guid"`
				} `json:"metadata"`
			} `json:"resources"`
		}
		json.Unmarshal(bytes, &buildpack)
		buildpackGuid = buildpack.Resources[0].Metadata.Guid

		// CREATE APP
		session = cf.Cf("curl", "/v3/apps", "-X", "POST", "-d", fmt.Sprintf(`{"name":"%s", "space_guid":"%s"}`, appName, spaceGuid))
		bytes = session.Wait().Out.Contents()
		var app struct {
			Guid string `json:"guid"`
		}
		json.Unmarshal(bytes, &app)
		appGuid = app.Guid

		// CREATE PACKAGE
		packageCreateUrl := fmt.Sprintf("/v3/apps/%s/packages", appGuid)
		session = cf.Cf("curl", packageCreateUrl, "-X", "POST", "-d", fmt.Sprintf(`{"type":"bits"}`))
		bytes = session.Wait().Out.Contents()
		var pac struct {
			Guid string `json:"guid"`
		}
		json.Unmarshal(bytes, &pac)
		packageGuid = pac.Guid

		// UPLOAD PACKAGE
		bytes = runner.Run("bash", "-c", "cf oauth-token | tail -n +4").Wait(5).Out.Contents()
		token = strings.TrimSpace(string(bytes))
		uploadUrl := fmt.Sprintf("%s/v3/packages/%s/upload", config.ApiEndpoint, packageGuid)
		bytes, _ = exec.Command("curl", "-v", "-s", uploadUrl, "-F", `bits=@"/Users/pivotal/workspace/cf-release/src/acceptance-tests/dora.zip"`, "-H", fmt.Sprintf("Authorization: %s", token)).CombinedOutput()
		pkgUrl := fmt.Sprintf("/v3/packages/%s", packageGuid)
		Eventually(func() *Session {
			session = cf.Cf("curl", pkgUrl)
			Expect(session.Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			return session
		}, 1*time.Minute).Should(Say("READY"))
	})

	AfterEach(func() {
		cf.AsUser(context.AdminUserContext(), func() {
			Expect(cf.Cf("delete-buildpack", buildpackName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})
	})

	It("Stages with a user specified admin buildpack", func() {
		// STAGE PACKAGE
		stageUrl := fmt.Sprintf("/v3/packages/%s/droplets", packageGuid)
		session := cf.Cf("curl", stageUrl, "-X", "POST", "-d", fmt.Sprintf(`{"buildpack_guid":"%s"}`, buildpackGuid))
		bytes := session.Wait().Out.Contents()
		var droplet struct {
			Guid string `json:"guid"`
		}
		json.Unmarshal(bytes, &droplet)
		dropletGuid := droplet.Guid
		fmt.Println(string(bytes))

		logUrl := fmt.Sprintf("loggregator.%s/recent?app=%s", config.AppsDomain, dropletGuid)
		Eventually(func() *Session {
			session = runner.Curl(logUrl, "-H", fmt.Sprintf("Authorization: %s", token))
			Expect(session.Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			return session
		}, 1*time.Minute, 10*time.Second).Should(Say("STAGED WITH CUSTOM BUILDPACK"))
	})

	It("Stages with a user specified admin buildpack", func() {
		// STAGE PACKAGE
		stageUrl := fmt.Sprintf("/v3/packages/%s/droplets", packageGuid)
		session := cf.Cf("curl", stageUrl, "-X", "POST", "-d", `{"buildpack_git_url":"http://github.com/cloudfoundry/go-buildpack"}`)
		bytes := session.Wait().Out.Contents()
		var droplet struct {
			Guid string `json:"guid"`
		}
		json.Unmarshal(bytes, &droplet)
		dropletGuid := droplet.Guid
		fmt.Println(string(bytes))

		logUrl := fmt.Sprintf("loggregator.%s/recent?app=%s", config.AppsDomain, dropletGuid)
		Eventually(func() *Session {
			session = runner.Curl(logUrl, "-H", fmt.Sprintf("Authorization: %s", token))
			Expect(session.Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			fmt.Println(string(session.Out.Contents()))
			return session
		}, 3*time.Minute, 10*time.Second).Should(Say("Cloning into"))
	})
})
<|endoftext|>


<commit_before>// Copyright (c) 2017 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 l3plugin

import (
	"bytes"
	"fmt"
	"net"
	"sort"

	"github.com/ligato/cn-infra/logging"
	"github.com/ligato/cn-infra/utils/addrs"
	"github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx"
	"github.com/ligato/vpp-agent/plugins/vpp/l3plugin/vppcalls"
	"github.com/ligato/vpp-agent/plugins/vpp/model/l3"
)

// SortedRoutes type is used to implement sort interface for slice of Route.
type SortedRoutes []*vppcalls.Route

// Return length of slice.
// Implements sort.Interface
func (arr SortedRoutes) Len() int {
	return len(arr)
}

// Swap swaps two items in slice identified by indices.
// Implements sort.Interface
func (arr SortedRoutes) Swap(i, j int) {
	arr[i], arr[j] = arr[j], arr[i]
}

// Less returns true if the item at index i in slice
// should be sorted before the element with index j.
// Implements sort.Interface
func (arr SortedRoutes) Less(i, j int) bool {
	return lessRoute(arr[i], arr[j])
}

func eqRoutes(a *vppcalls.Route, b *vppcalls.Route) bool {
	return a.Type == b.Type &&
		a.VrfID == b.VrfID &&
		bytes.Equal(a.DstAddr.IP, b.DstAddr.IP) &&
		bytes.Equal(a.DstAddr.Mask, b.DstAddr.Mask) &&
		bytes.Equal(a.NextHopAddr, b.NextHopAddr) &&
		a.ViaVrfId == b.ViaVrfId &&
		a.OutIface == b.OutIface &&
		a.Weight == b.Weight &&
		a.Preference == b.Preference
}

func lessRoute(a *vppcalls.Route, b *vppcalls.Route) bool {
	if a.Type != b.Type {
		return a.Type < b.Type
	}
	if a.VrfID != b.VrfID {
		return a.VrfID < b.VrfID
	}
	if !bytes.Equal(a.DstAddr.IP, b.DstAddr.IP) {
		return bytes.Compare(a.DstAddr.IP, b.DstAddr.IP) < 0
	}
	if !bytes.Equal(a.DstAddr.Mask, b.DstAddr.Mask) {
		return bytes.Compare(a.DstAddr.Mask, b.DstAddr.Mask) < 0
	}
	if !bytes.Equal(a.NextHopAddr, b.NextHopAddr) {
		return bytes.Compare(a.NextHopAddr, b.NextHopAddr) < 0
	}
	if a.ViaVrfId != b.ViaVrfId {
		return a.ViaVrfId < b.ViaVrfId
	}
	if a.OutIface != b.OutIface {
		return a.OutIface < b.OutIface
	}
	if a.Preference != b.Preference {
		return a.Preference < b.Preference
	}
	return a.Weight < b.Weight

}

// TransformRoute converts raw route data to Route object.
func TransformRoute(routeInput *l3.StaticRoutes_Route, swIndex uint32, log logging.Logger) (*vppcalls.Route, error) {
	if routeInput == nil {
		log.Infof("Route input is empty")
		return nil, nil
	}
	if routeInput.DstIpAddr == "" {
		if routeInput.Type != l3.StaticRoutes_Route_INTER_VRF {
			// no destination address is only allowed for inter-VRF routes
			log.Infof("Route does not contain destination address")
			return nil, nil
		}
	}
	parsedDestIP, isIpv6, err := addrs.ParseIPWithPrefix(routeInput.DstIpAddr)
	if err != nil {
		return nil, err
	}
	vrfID := routeInput.VrfId

	nextHopIP := net.ParseIP(routeInput.NextHopAddr)
	if isIpv6 {
		nextHopIP = nextHopIP.To16()
	} else {
		nextHopIP = nextHopIP.To4()
	}
	route := &vppcalls.Route{
		Type:        vppcalls.RouteType(routeInput.Type),
		VrfID:       vrfID,
		DstAddr:     *parsedDestIP,
		NextHopAddr: nextHopIP,
		ViaVrfId:    routeInput.ViaVrfId,
		OutIface:    swIndex,
		Weight:      routeInput.Weight,
		Preference:  routeInput.Preference,
	}
	return route, nil
}

func resolveInterfaceSwIndex(ifName string, index ifaceidx.SwIfIndex) (uint32, error) {
	ifIndex := vppcalls.NextHopOutgoingIfUnset
	if ifName != "" {
		var exists bool
		ifIndex, _, exists = index.LookupIdx(ifName)
		if !exists {
			return ifIndex, fmt.Errorf("route outgoing interface %v not found", ifName)
		}
	}
	return ifIndex, nil
}

func (plugin *RouteConfigurator) diffRoutes(new []*vppcalls.Route, old []*vppcalls.Route) (toBeDeleted []*vppcalls.Route, toBeAdded []*vppcalls.Route) {
	newSorted := SortedRoutes(new)
	oldSorted := SortedRoutes(old)
	sort.Sort(newSorted)
	sort.Sort(oldSorted)

	// Compare.
	i := 0
	j := 0
	for i < len(newSorted) && j < len(oldSorted) {
		if eqRoutes(newSorted[i], oldSorted[j]) {
			i++
			j++
		} else {
			if lessRoute(newSorted[i], oldSorted[j]) {
				toBeAdded = append(toBeAdded, newSorted[i])
				i++
			} else {
				toBeDeleted = append(toBeDeleted, oldSorted[j])
				j++
			}
		}
	}

	for ; i < len(newSorted); i++ {
		toBeAdded = append(toBeAdded, newSorted[i])
	}

	for ; j < len(oldSorted); j++ {
		toBeDeleted = append(toBeDeleted, oldSorted[j])
	}
	return
}
<commit_msg>Add recent vpp-agent changes<commit_after>// Copyright (c) 2017 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 l3plugin

import (
	"bytes"
	"fmt"
	"net"
	"sort"

	"github.com/ligato/cn-infra/logging"
	"github.com/ligato/cn-infra/utils/addrs"
	"github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx"
	"github.com/ligato/vpp-agent/plugins/vpp/l3plugin/vppcalls"
	"github.com/ligato/vpp-agent/plugins/vpp/model/l3"
)

// SortedRoutes type is used to implement sort interface for slice of Route.
type SortedRoutes []*vppcalls.Route

// Return length of slice.
// Implements sort.Interface
func (arr SortedRoutes) Len() int {
	return len(arr)
}

// Swap swaps two items in slice identified by indices.
// Implements sort.Interface
func (arr SortedRoutes) Swap(i, j int) {
	arr[i], arr[j] = arr[j], arr[i]
}

// Less returns true if the item at index i in slice
// should be sorted before the element with index j.
// Implements sort.Interface
func (arr SortedRoutes) Less(i, j int) bool {
	return lessRoute(arr[i], arr[j])
}

func eqRoutes(a *vppcalls.Route, b *vppcalls.Route) bool {
	return a.Type == b.Type &&
		a.VrfID == b.VrfID &&
		bytes.Equal(a.DstAddr.IP, b.DstAddr.IP) &&
		bytes.Equal(a.DstAddr.Mask, b.DstAddr.Mask) &&
		bytes.Equal(a.NextHopAddr, b.NextHopAddr) &&
		a.ViaVrfId == b.ViaVrfId &&
		a.OutIface == b.OutIface &&
		a.Weight == b.Weight &&
		a.Preference == b.Preference
}

func lessRoute(a *vppcalls.Route, b *vppcalls.Route) bool {
	if a.Type != b.Type {
		return a.Type < b.Type
	}
	if a.VrfID != b.VrfID {
		return a.VrfID < b.VrfID
	}
	if !bytes.Equal(a.DstAddr.IP, b.DstAddr.IP) {
		return bytes.Compare(a.DstAddr.IP, b.DstAddr.IP) < 0
	}
	if !bytes.Equal(a.DstAddr.Mask, b.DstAddr.Mask) {
		return bytes.Compare(a.DstAddr.Mask, b.DstAddr.Mask) < 0
	}
	if !bytes.Equal(a.NextHopAddr, b.NextHopAddr) {
		return bytes.Compare(a.NextHopAddr, b.NextHopAddr) < 0
	}
	if a.ViaVrfId != b.ViaVrfId {
		return a.ViaVrfId < b.ViaVrfId
	}
	if a.OutIface != b.OutIface {
		return a.OutIface < b.OutIface
	}
	if a.Preference != b.Preference {
		return a.Preference < b.Preference
	}
	return a.Weight < b.Weight

}

// TransformRoute converts raw route data to Route object.
func TransformRoute(routeInput *l3.StaticRoutes_Route, swIndex uint32, log logging.Logger) (*vppcalls.Route, error) {
	if routeInput == nil {
		log.Infof("Route input is empty")
		return nil, nil
	}
	if routeInput.DstIpAddr == "" {
		log.Infof("Route does not contain destination address")
		return nil, nil
	}
	parsedDestIP, isIpv6, err := addrs.ParseIPWithPrefix(routeInput.DstIpAddr)
	if err != nil {
		return nil, err
	}
	vrfID := routeInput.VrfId

	nextHopIP := net.ParseIP(routeInput.NextHopAddr)
	if isIpv6 {
		nextHopIP = nextHopIP.To16()
	} else {
		nextHopIP = nextHopIP.To4()
	}
	route := &vppcalls.Route{
		Type:        vppcalls.RouteType(routeInput.Type),
		VrfID:       vrfID,
		DstAddr:     *parsedDestIP,
		NextHopAddr: nextHopIP,
		ViaVrfId:    routeInput.ViaVrfId,
		OutIface:    swIndex,
		Weight:      routeInput.Weight,
		Preference:  routeInput.Preference,
	}
	return route, nil
}

func resolveInterfaceSwIndex(ifName string, index ifaceidx.SwIfIndex) (uint32, error) {
	ifIndex := vppcalls.NextHopOutgoingIfUnset
	if ifName != "" {
		var exists bool
		ifIndex, _, exists = index.LookupIdx(ifName)
		if !exists {
			return ifIndex, fmt.Errorf("route outgoing interface %v not found", ifName)
		}
	}
	return ifIndex, nil
}

func (plugin *RouteConfigurator) diffRoutes(new []*vppcalls.Route, old []*vppcalls.Route) (toBeDeleted []*vppcalls.Route, toBeAdded []*vppcalls.Route) {
	newSorted := SortedRoutes(new)
	oldSorted := SortedRoutes(old)
	sort.Sort(newSorted)
	sort.Sort(oldSorted)

	// Compare.
	i := 0
	j := 0
	for i < len(newSorted) && j < len(oldSorted) {
		if eqRoutes(newSorted[i], oldSorted[j]) {
			i++
			j++
		} else {
			if lessRoute(newSorted[i], oldSorted[j]) {
				toBeAdded = append(toBeAdded, newSorted[i])
				i++
			} else {
				toBeDeleted = append(toBeDeleted, oldSorted[j])
				j++
			}
		}
	}

	for ; i < len(newSorted); i++ {
		toBeAdded = append(toBeAdded, newSorted[i])
	}

	for ; j < len(oldSorted); j++ {
		toBeDeleted = append(toBeDeleted, oldSorted[j])
	}
	return
}
<|endoftext|>


<commit_before>package acceptance_test

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"os/exec"
	"strconv"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"github.com/onsi/say"
	"github.com/pivotal-cf-experimental/bletchley"
)

func run(args ...string) *gexec.Session {
	command := exec.Command(proctorCLIPath, args...)
	session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
	Expect(err).NotTo(HaveOccurred())
	return session
}

var _ = Describe("Proctor CLI", func() {
	It("should print some help info", func() {
		session := run("help")
		Eventually(session).Should(gexec.Exit(1))
		Expect(session.Err.Contents()).To(ContainSubstring("Create a fresh classroom environment"))
		Expect(session.Err.Contents()).To(ContainSubstring("Destroy an existing classroom"))
	})

	XContext("when the command is not recognized", func() {
		It("should exit status 1", func() {
			session := run("nonsense")
			Eventually(session).Should(gexec.Exit(1))
			// this fails because of a bug in onsi/say
			// we should probably switch over to something else
		})
	})
})

var _ = Describe("Interactions with AWS", func() {
	if os.Getenv("SKIP_AWS_TESTS") == "true" {
		say.Println(0, say.Yellow("WARNING: Skipping acceptance tests that use AWS"))
		return
	}

	It("should create and delete classrooms", func() {
		classroomName := fmt.Sprintf("test-%d", rand.Int31())
		instanceCount := 3
		session := run("create", "-name", classroomName, "-number", strconv.Itoa(instanceCount))
		Eventually(session.Out, 10).Should(gbytes.Say("Looking up latest AMI for"))
		Eventually(session.Out, 10).Should(gbytes.Say("ami-[a-z,0-9]"))
		Eventually(session.Out, 10).Should(gbytes.Say("Creating SSH Keypair"))
		Eventually(session.Out, 10).Should(gbytes.Say("Uploading private key"))
		Eventually(session, 20).Should(gexec.Exit(0))

		session = run("list", "-format", "json")
		Eventually(session, 10).Should(gexec.Exit(0))
		var classrooms []string
		Expect(json.Unmarshal(session.Out.Contents(), &classrooms)).To(Succeed())
		Expect(classrooms).To(ContainElement(classroomName))

		var info struct {
			Status string
			SSHKey string `json:"ssh_key"`
			Number int
			Hosts  map[string]string
		}
		session = run("describe", "-name", classroomName, "-format", "json")
		Eventually(session, 10).Should(gexec.Exit(0))
		Expect(json.Unmarshal(session.Out.Contents(), &info)).To(Succeed())
		Expect(info.Status).To(Equal("CREATE_IN_PROGRESS"))
		Expect(info.Number).To(Equal(instanceCount))

		resp, err := http.Get(info.SSHKey)
		Expect(err).NotTo(HaveOccurred())
		Expect(resp.StatusCode).To(Equal(http.StatusOK))
		Expect(resp.Header["Content-Type"]).To(Equal([]string{"application/x-pem-file"}))
		keyPEM, err := ioutil.ReadAll(resp.Body)
		Expect(err).NotTo(HaveOccurred())
		sshPrivateKey, err := bletchley.PEMToPrivateKey(keyPEM)
		Expect(err).NotTo(HaveOccurred())
		Expect(sshPrivateKey).NotTo(BeNil())

		Eventually(func() []byte {
			session = run("describe", "-name", classroomName, "-format", "plain")
			Eventually(session, 10).Should(gexec.Exit(0))
			return session.Out.Contents()
		}, 600).Should(ContainSubstring("status: CREATE_COMPLETE"))

		session = run("describe", "-name", classroomName)
		Eventually(session, 10).Should(gexec.Exit(0))
		Expect(json.Unmarshal(session.Out.Contents(), &info)).To(Succeed())
		Expect(info.Status).To(Equal("CREATE_COMPLETE"))
		Expect(info.Hosts).To(HaveLen(instanceCount))
		for _, state := range info.Hosts {
			Expect(state).To(Equal("running"))
		}

		Eventually(func() *gexec.Session {
			return run("run", "-name", classroomName, "-c", "echo hello")
		}, 120).Should(gexec.Exit(0))
		session = run("run", "-name", classroomName, "-c", "bosh status")
		Expect(session.Out.Contents()).To(ContainSubstring("/home/ubuntu/.bosh_config"))

		session = run("destroy", "-name", classroomName)
		Eventually(session, 20).Should(gexec.Exit(0))
		Expect(session.ExitCode()).To(Equal(0))
	})
})
<commit_msg>Fixup acceptance test timing constraints to not get throttled<commit_after>package acceptance_test

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"os/exec"
	"strconv"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"github.com/onsi/say"
	"github.com/pivotal-cf-experimental/bletchley"
)

func run(args ...string) *gexec.Session {
	command := exec.Command(proctorCLIPath, args...)
	session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
	Expect(err).NotTo(HaveOccurred())
	return session
}

var _ = Describe("Proctor CLI", func() {
	It("should print some help info", func() {
		session := run("help")
		Eventually(session).Should(gexec.Exit(1))
		Expect(session.Err.Contents()).To(ContainSubstring("Create a fresh classroom environment"))
		Expect(session.Err.Contents()).To(ContainSubstring("Destroy an existing classroom"))
	})

	XContext("when the command is not recognized", func() {
		It("should exit status 1", func() {
			session := run("nonsense")
			Eventually(session).Should(gexec.Exit(1))
			// this fails because of a bug in onsi/say
			// we should probably switch over to something else
		})
	})
})

var _ = Describe("Interactions with AWS", func() {
	if os.Getenv("SKIP_AWS_TESTS") == "true" {
		say.Println(0, say.Yellow("WARNING: Skipping acceptance tests that use AWS"))
		return
	}

	It("should create and delete classrooms", func() {
		classroomName := fmt.Sprintf("test-%d", rand.Int31())
		instanceCount := 3
		session := run("create", "-name", classroomName, "-number", strconv.Itoa(instanceCount))
		Eventually(session.Out, 10).Should(gbytes.Say("Looking up latest AMI for"))
		Eventually(session.Out, 10).Should(gbytes.Say("ami-[a-z,0-9]"))
		Eventually(session.Out, 10).Should(gbytes.Say("Creating SSH Keypair"))
		Eventually(session.Out, 10).Should(gbytes.Say("Uploading private key"))
		Eventually(session, 20).Should(gexec.Exit(0))

		session = run("list", "-format", "json")
		Eventually(session, 10).Should(gexec.Exit(0))
		var classrooms []string
		Expect(json.Unmarshal(session.Out.Contents(), &classrooms)).To(Succeed())
		Expect(classrooms).To(ContainElement(classroomName))

		var info struct {
			Status string
			SSHKey string `json:"ssh_key"`
			Number int
			Hosts  map[string]string
		}
		session = run("describe", "-name", classroomName, "-format", "json")
		Eventually(session, 10).Should(gexec.Exit(0))
		Expect(json.Unmarshal(session.Out.Contents(), &info)).To(Succeed())
		Expect(info.Status).To(Equal("CREATE_IN_PROGRESS"))
		Expect(info.Number).To(Equal(instanceCount))

		resp, err := http.Get(info.SSHKey)
		Expect(err).NotTo(HaveOccurred())
		Expect(resp.StatusCode).To(Equal(http.StatusOK))
		Expect(resp.Header["Content-Type"]).To(Equal([]string{"application/x-pem-file"}))
		keyPEM, err := ioutil.ReadAll(resp.Body)
		Expect(err).NotTo(HaveOccurred())
		sshPrivateKey, err := bletchley.PEMToPrivateKey(keyPEM)
		Expect(err).NotTo(HaveOccurred())
		Expect(sshPrivateKey).NotTo(BeNil())

		Eventually(func() []byte {
			session = run("describe", "-name", classroomName, "-format", "plain")
			Eventually(session, "10s").Should(gexec.Exit(0))
			return session.Out.Contents()
		}, "10m", "10s").Should(ContainSubstring("status: CREATE_COMPLETE"))

		session = run("describe", "-name", classroomName)
		Eventually(session, "10s").Should(gexec.Exit(0))
		Expect(json.Unmarshal(session.Out.Contents(), &info)).To(Succeed())
		Expect(info.Status).To(Equal("CREATE_COMPLETE"))
		Expect(info.Hosts).To(HaveLen(instanceCount))
		for _, state := range info.Hosts {
			Expect(state).To(Equal("running"))
		}

		Eventually(func() *gexec.Session {
			session := run("run", "-name", classroomName, "-c", "echo hello")
			Eventually(session, "120s").Should(gexec.Exit())
			return session
		}, "2m", "10s").Should(gexec.Exit(0))

		session = run("run", "-name", classroomName, "-c", "bosh status")
		Eventually(session, "120s").Should(gexec.Exit(0))
		Expect(session.Out.Contents()).To(ContainSubstring("/home/ubuntu/.bosh_config"))

		session = run("destroy", "-name", classroomName)
		Eventually(session, "20s").Should(gexec.Exit(0))
		Expect(session.ExitCode()).To(Equal(0))
	})
})
<|endoftext|>


<commit_before>// Find pairs in an integer array whose sum is equal to 10

package main

import (
	"fmt"
)

func main() {
	arr := []int{1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 6, 1, 7, 8, 2, 3, 4}
	sum := 10
	fmt.Println("Pair that adds up to", sum, "from the following array are:")
	fmt.Println(arr)
	fmt.Println(findpairs(arr, sum))
}

func findpairs(arr []int, sum int) [][]int {
	vmap := make(map[int]int, len(arr)) // init map with len(arr) for speed
	dups := make(map[int]int)
	pairs := [][]int{}

	// Add every value to the map. O(n)
	for i, val := range arr {
		vmap[val] = i
	}

	// Check if 'sum - a value = something in the map'. O(1)
	for a, chk := range arr {
		if b, ok := vmap[sum-chk]; ok {

			// Check if the index has already been found
			_, a_dup := dups[a]
			_, b_dup := dups[b]

			if !a_dup && !b_dup {
				pairs = append(pairs, [][]int{{arr[a], arr[b]}}...)
				dups[a] = 1
				dups[b] = 1
			}
		}
	}

	return pairs
}
<commit_msg>Added better examples to sum10<commit_after>// Find pairs in an integer array whose sum is equal to 10

package main

import (
	"fmt"
)

func main() {
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 7, 8, -2, 12, 4}
	sum := 10
	fmt.Println("Pair that adds up to", sum, "from the following array are:")
	fmt.Println(arr)
	fmt.Println(findpairs(arr, sum))
}

func findpairs(arr []int, sum int) [][]int {
	vmap := make(map[int]int, len(arr)) // init map with len(arr) for speed
	dups := make(map[int]int)
	pairs := [][]int{}

	// Add every value to the map. O(n)
	for i, val := range arr {
		vmap[val] = i
	}

	// Check if 'sum - a value = something in the map'. O(1)
	for a, chk := range arr {
		if b, ok := vmap[sum-chk]; ok {

			// Check if the index has already been found
			_, a_dup := dups[a]
			_, b_dup := dups[b]

			if !a_dup && !b_dup {
				pairs = append(pairs, [][]int{{arr[a], arr[b]}}...)
				dups[a] = 1
				dups[b] = 1
			}
		}
	}

	return pairs
}
<|endoftext|>


<commit_before>package soap

import (
	"encoding/xml"
	"regexp"
	"testing"

	. "github.com/smartystreets/goconvey/convey"
)

func TestEncodeRequestMatch(t *testing.T) {
	Convey("Given some TierRequest struct", t, func() {
		expectedRequest := &TierRequest{
			NsEnv:  "http://schemas.xmlsoap.org/soap/envelope/",
			NsType: "http://ws.loyalty.com/tp/ets/2008/04/01/collector/types",
			TierBodys: TierBody{
				GetCollectorProfiles: GetCollectorProfile{
					Contexts: CollectorContext{
						Channel:  "WEB",
						Source:   "WEB",
						Language: "en-CA"},
					Number: 5,
				}}}
		So(expectedRequest, ShouldHaveSameTypeAs, &TierRequest{})

		Convey("When the struct is marshaled to XML", func() {
			xmlstring, _ := xml.MarshalIndent(expectedRequest, "", "  ")
			xmlstring = []byte(xml.Header + string(xmlstring))
			So(xmlstring, ShouldHaveSameTypeAs, []byte("test"))

			Convey("The marshalled XML byte slice should match the one returned from the encodeRequest func", func() {
				realXML, _ := encodeRequest(5)
				So(realXML, ShouldResemble, xmlstring)
			})
		})
	})

}

func TestRegexMatch(t *testing.T) {
	Convey("Given a SOAP response", t, func() {
		fullReponse := `<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
      <GetCollectorProfileResponse
        xmlns="http://ws.loyalty.com/tp/ets/2008/04/01/collector/types"
        xmlns:ns2="http://ws.loyalty.com/tp/ets/2008/02/01/common"
        xmlns:ns3="http://ws.loyalty.com/tp/ets/2008/04/01/collector-common"
        xmlns:ns4="http://ws.loyalty.com/tp/ets/2008/04/01/collector"
        xmlns:ns5="http://ws.loyalty.com/tp/ets/2008/02/01/email"
        xmlns:ns6="http://ws.loyalty.com/tp/ets/2008/02/01/account"
        ETSServiceVersion="collector-2.12.17-20150306">
        <Collector
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          AMCashEligible="true"
          AMCashRegion="2"
          AccountStatus="A"
          AccountTier="B"
          AccountType="I"
          AddressType="H"
          CollectorNumber="50001366830"
          EnrollSourceCodeLevel1="PREA01"
          EnrollSourceCodeLevel2="TEST"
          LanguageCode="fr-CA"
          MailProfile="0"
          NumberOfCards="1"
          xsi:type="ns4:ConsumerCollectorType">
          <ns4:MosaikTier SegmentPrefix="BMPH" SegmentSuffix="3E" />
          <ns4:Person
            DateOfBirth="1983-02-22-05:00"
            FirstName="ANGELIQUE"
            Gender="F"
            LastName="LAURENT"
            Prefix="MS" Suffix=" ">
            <ns4:HomeAddress
              City="TORONTO"
              Country="CAN"
              PostalCode="M5G2L1"
              Province="ON"
              Status="0"
              StreetAddress1="600-438 UNIVERSITY AVE" />
            <ns4:HomePhone>4165522367</ns4:HomePhone>
            <ns4:BusinessPhone>4165522367</ns4:BusinessPhone>
          </ns4:Person>
        </Collector>
        <Balance Amount="97695" LastMaintenanceTime="2014-03-11T19:50:32-04:00" />
        <CashMilesBalance Amount="0" LastMaintenanceTime="1969-12-31T19:00:00-05:00" />
        <ContactDetails
          ChangedTime="2013-03-06T12:43:20.600-05:00"
          Channel="MOBAPP"
          CollectorNumber="50001366830"
          ContactType="EMAIL"
          EffectiveStartTime="2013-03-06T12:43:20.572-05:00"
          EnableOptions="true"
          Format="T"
          FromSecureSource="true"
          Source="MOBLOYAPP"
          Status="V"
          Value="hting@loyalty.com"
          Verified="false" />
      </GetCollectorProfileResponse>
    </soap:Body>
  </soap:Envelope>`
		So(fullReponse, ShouldHaveSameTypeAs, "text")

		Convey("Regular expression parsing output", func() {
			r, _ := regexp.Compile(`<Collector[\s\S]*?">`)
			mockResponse := r.FindString(fullReponse)
			So(fullReponse, ShouldContainSubstring, mockResponse)

			Convey("Function regexResponse should match parsed string", func() {
				actualResponse := regexResponse(fullReponse)
				So(actualResponse, ShouldEqual, mockResponse)
			})
		})
	})

}
<commit_msg>Few more soap tests<commit_after>package soap

import (
	"encoding/xml"
	"regexp"
	"testing"

	"github.com/sjug/am-go/structure"
	. "github.com/smartystreets/goconvey/convey"
)

func TestEncodeRequestMatch(t *testing.T) {
	Convey("Given some TierRequest struct", t, func() {
		expectedRequest := &TierRequest{
			NsEnv:  "http://schemas.xmlsoap.org/soap/envelope/",
			NsType: "http://ws.loyalty.com/tp/ets/2008/04/01/collector/types",
			TierBodys: TierBody{
				GetCollectorProfiles: GetCollectorProfile{
					Contexts: CollectorContext{
						Channel:  "WEB",
						Source:   "WEB",
						Language: "en-CA"},
					Number: 5,
				}}}
		So(expectedRequest, ShouldHaveSameTypeAs, &TierRequest{})

		Convey("When the struct is marshaled to XML", func() {
			xmlstring, _ := xml.MarshalIndent(expectedRequest, "", "  ")
			xmlstring = []byte(xml.Header + string(xmlstring))
			So(xmlstring, ShouldHaveSameTypeAs, []byte("test"))

			Convey("The marshalled XML byte slice should match the one returned from the encodeRequest func", func() {
				realXML, _ := encodeRequest(5)
				So(realXML, ShouldResemble, xmlstring)
			})
		})
	})

}

func TestRegexMatch(t *testing.T) {
	Convey("Given a SOAP response", t, func() {
		fullReponse := `<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
      <GetCollectorProfileResponse
        xmlns="http://ws.loyalty.com/tp/ets/2008/04/01/collector/types"
        xmlns:ns2="http://ws.loyalty.com/tp/ets/2008/02/01/common"
        xmlns:ns3="http://ws.loyalty.com/tp/ets/2008/04/01/collector-common"
        xmlns:ns4="http://ws.loyalty.com/tp/ets/2008/04/01/collector"
        xmlns:ns5="http://ws.loyalty.com/tp/ets/2008/02/01/email"
        xmlns:ns6="http://ws.loyalty.com/tp/ets/2008/02/01/account"
        ETSServiceVersion="collector-2.12.17-20150306">
        <Collector
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          AMCashEligible="true"
          AMCashRegion="2"
          AccountStatus="A"
          AccountTier="B"
          AccountType="I"
          AddressType="H"
          CollectorNumber="50001366830"
          EnrollSourceCodeLevel1="PREA01"
          EnrollSourceCodeLevel2="TEST"
          LanguageCode="fr-CA"
          MailProfile="0"
          NumberOfCards="1"
          xsi:type="ns4:ConsumerCollectorType">
          <ns4:MosaikTier SegmentPrefix="BMPH" SegmentSuffix="3E" />
          <ns4:Person
            DateOfBirth="1983-02-22-05:00"
            FirstName="ANGELIQUE"
            Gender="F"
            LastName="LAURENT"
            Prefix="MS" Suffix=" ">
            <ns4:HomeAddress
              City="TORONTO"
              Country="CAN"
              PostalCode="M5G2L1"
              Province="ON"
              Status="0"
              StreetAddress1="600-438 UNIVERSITY AVE" />
            <ns4:HomePhone>4165522367</ns4:HomePhone>
            <ns4:BusinessPhone>4165522367</ns4:BusinessPhone>
          </ns4:Person>
        </Collector>
        <Balance Amount="97695" LastMaintenanceTime="2014-03-11T19:50:32-04:00" />
        <CashMilesBalance Amount="0" LastMaintenanceTime="1969-12-31T19:00:00-05:00" />
        <ContactDetails
          ChangedTime="2013-03-06T12:43:20.600-05:00"
          Channel="MOBAPP"
          CollectorNumber="50001366830"
          ContactType="EMAIL"
          EffectiveStartTime="2013-03-06T12:43:20.572-05:00"
          EnableOptions="true"
          Format="T"
          FromSecureSource="true"
          Source="MOBLOYAPP"
          Status="V"
          Value="hting@loyalty.com"
          Verified="false" />
      </GetCollectorProfileResponse>
    </soap:Body>
  </soap:Envelope>`
		So(fullReponse, ShouldHaveSameTypeAs, "text")

		Convey("Regular expression parsing output", func() {
			r, _ := regexp.Compile(`<Collector[\s\S]*?">`)
			mockResponse := r.FindString(fullReponse)
			So(fullReponse, ShouldContainSubstring, mockResponse)

			Convey("Function regexResponse should match parsed string", func() {
				actualResponse := regexResponse(fullReponse)
				So(actualResponse, ShouldEqual, mockResponse)
			})
		})
	})

}

func TestParseXML(t *testing.T) {
	Convey("Given a collector response", t, func() {
		resp := `<Collector
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      AMCashEligible="true"
      AMCashRegion="2"
      AccountStatus="A"
      AccountTier="B"
      AccountType="I"
      AddressType="H"
      CollectorNumber="50001366830"
      EnrollSourceCodeLevel1="PREA01"
      EnrollSourceCodeLevel2="TEST"
      LanguageCode="fr-CA"
      MailProfile="0"
      NumberOfCards="1"
      xsi:type="ns4:ConsumerCollectorType">
      <ns4:MosaikTier SegmentPrefix="BMPH" SegmentSuffix="3E" />
      <ns4:Person
        DateOfBirth="1983-02-22-05:00"
        FirstName="ANGELIQUE"
        Gender="F"
        LastName="LAURENT"
        Prefix="MS" Suffix=" ">
        <ns4:HomeAddress
          City="TORONTO"
          Country="CAN"
          PostalCode="M5G2L1"
          Province="ON"
          Status="0"
          StreetAddress1="600-438 UNIVERSITY AVE" />
        <ns4:HomePhone>4165522367</ns4:HomePhone>
        <ns4:BusinessPhone>4165522367</ns4:BusinessPhone>
      </ns4:Person>
    </Collector>`
		So(resp, ShouldHaveSameTypeAs, "text")

		Convey("Response object should contain unmarshaled XML data", func() {
			var responseObject CollectorResponse
			xml.Unmarshal([]byte(resp), &responseObject)
			So(responseObject.Tier, ShouldNotBeBlank)

			Convey("Collector Tier object should match that returned by parseXML function", func() {
				mockCollectorTier := structure.CollectorTier{CollectorTier: responseObject.Tier}
				realCollectorTier, _ := parseXML(resp)
				So(realCollectorTier, ShouldResemble, &mockCollectorTier)
			})

		})
	})

}
<|endoftext|>


<commit_before>package resource

import (
	"os"

	"code.cloudfoundry.org/lager"
	"github.com/concourse/atc"
	"github.com/concourse/atc/creds"
	"github.com/concourse/atc/db"
	"github.com/concourse/atc/worker"
)

type resourceInstanceFetchSource struct {
	logger                 lager.Logger
	resourceInstance       ResourceInstance
	worker                 worker.Worker
	resourceTypes          creds.VersionedResourceTypes
	tags                   atc.Tags
	teamID                 int
	session                Session
	metadata               Metadata
	imageFetchingDelegate  worker.ImageFetchingDelegate
	dbResourceCacheFactory db.ResourceCacheFactory
}

func NewResourceInstanceFetchSource(
	logger lager.Logger,
	resourceInstance ResourceInstance,
	worker worker.Worker,
	resourceTypes creds.VersionedResourceTypes,
	tags atc.Tags,
	teamID int,
	session Session,
	metadata Metadata,
	imageFetchingDelegate worker.ImageFetchingDelegate,
	dbResourceCacheFactory db.ResourceCacheFactory,
) FetchSource {
	return &resourceInstanceFetchSource{
		logger:                 logger,
		resourceInstance:       resourceInstance,
		worker:                 worker,
		resourceTypes:          resourceTypes,
		tags:                   tags,
		teamID:                 teamID,
		session:                session,
		metadata:               metadata,
		imageFetchingDelegate:  imageFetchingDelegate,
		dbResourceCacheFactory: dbResourceCacheFactory,
	}
}

func (s *resourceInstanceFetchSource) LockName() (string, error) {
	return s.resourceInstance.LockName(s.worker.Name())
}

func (s *resourceInstanceFetchSource) Find() (VersionedSource, bool, error) {
	sLog := s.logger.Session("find")

	volume, found, err := s.resourceInstance.FindOn(s.logger, s.worker)
	if err != nil {
		sLog.Error("failed-to-find-initialized-on", err)
		return nil, false, err
	}

	if !found {
		return nil, false, nil
	}

	metadata, err := s.dbResourceCacheFactory.ResourceCacheMetadata(s.resourceInstance.ResourceCache())
	if err != nil {
		sLog.Error("failed-to-get-resource-cache-metadata", err)
		return nil, false, err
	}

	s.logger.Debug("found-initialized-versioned-source", lager.Data{"version": s.resourceInstance.Version(), "metadata": metadata.ToATCMetadata()})

	return NewGetVersionedSource(
		volume,
		s.resourceInstance.Version(),
		metadata.ToATCMetadata(),
	), true, nil
}

// Create runs under the lock but we need to make sure volume does not exist
// yet before creating it under the lock
func (s *resourceInstanceFetchSource) Create(signals <-chan os.Signal, ready chan<- struct{}) (VersionedSource, error) {
	sLog := s.logger.Session("create")

	versionedSource, found, err := s.Find()
	if err != nil {
		return nil, err
	}

	if found {
		return versionedSource, nil
	}

	mountPath := ResourcesDir("get")

	containerSpec := worker.ContainerSpec{
		ImageSpec: worker.ImageSpec{
			ResourceType: string(s.resourceInstance.ResourceType()),
		},
		Tags:   s.tags,
		TeamID: s.teamID,
		Env:    s.metadata.Env(),

		Outputs: map[string]string{
			"resource": mountPath,
		},
	}

	resourceFactory := NewResourceFactory(s.worker)
	resource, err := resourceFactory.NewResource(
		s.logger,
		nil,
		s.resourceInstance.ContainerOwner(),
		s.session.Metadata,
		containerSpec,
		s.resourceTypes,
		s.imageFetchingDelegate,
	)

	var volume worker.Volume
	for _, mount := range resource.Container().VolumeMounts() {
		if mount.MountPath == mountPath {
			volume = mount.Volume
			break
		}
	}

	versionedSource, err = resource.Get(
		volume,
		IOConfig{
			Stdout: s.imageFetchingDelegate.Stdout(),
			Stderr: s.imageFetchingDelegate.Stderr(),
		},
		s.resourceInstance.Source(),
		s.resourceInstance.Params(),
		s.resourceInstance.Version(),
		signals,
		ready,
	)
	if err != nil {
		if err == ErrAborted {
			sLog.Error("get-run-resource-aborted", err, lager.Data{"container": resource.Container().Handle()})
			return nil, ErrInterrupted
		}

		sLog.Error("failed-to-fetch-resource", err)
		return nil, err
	}

	err = volume.SetPrivileged(false)
	if err != nil {
		sLog.Error("failed-to-set-volume-unprivileged", err)
		return nil, err
	}

	err = volume.InitializeResourceCache(s.resourceInstance.ResourceCache())
	if err != nil {
		sLog.Error("failed-to-initialize-cache", err)
		return nil, err
	}

	err = s.dbResourceCacheFactory.UpdateResourceCacheMetadata(s.resourceInstance.ResourceCache(), versionedSource.Metadata())
	if err != nil {
		s.logger.Error("failed-to-update-resource-cache-metadata", err, lager.Data{"resource-cache": s.resourceInstance.ResourceCache()})
		return nil, err
	}

	return versionedSource, nil
}
<commit_msg>add missing err check<commit_after>package resource

import (
	"os"

	"code.cloudfoundry.org/lager"
	"github.com/concourse/atc"
	"github.com/concourse/atc/creds"
	"github.com/concourse/atc/db"
	"github.com/concourse/atc/worker"
)

type resourceInstanceFetchSource struct {
	logger                 lager.Logger
	resourceInstance       ResourceInstance
	worker                 worker.Worker
	resourceTypes          creds.VersionedResourceTypes
	tags                   atc.Tags
	teamID                 int
	session                Session
	metadata               Metadata
	imageFetchingDelegate  worker.ImageFetchingDelegate
	dbResourceCacheFactory db.ResourceCacheFactory
}

func NewResourceInstanceFetchSource(
	logger lager.Logger,
	resourceInstance ResourceInstance,
	worker worker.Worker,
	resourceTypes creds.VersionedResourceTypes,
	tags atc.Tags,
	teamID int,
	session Session,
	metadata Metadata,
	imageFetchingDelegate worker.ImageFetchingDelegate,
	dbResourceCacheFactory db.ResourceCacheFactory,
) FetchSource {
	return &resourceInstanceFetchSource{
		logger:                 logger,
		resourceInstance:       resourceInstance,
		worker:                 worker,
		resourceTypes:          resourceTypes,
		tags:                   tags,
		teamID:                 teamID,
		session:                session,
		metadata:               metadata,
		imageFetchingDelegate:  imageFetchingDelegate,
		dbResourceCacheFactory: dbResourceCacheFactory,
	}
}

func (s *resourceInstanceFetchSource) LockName() (string, error) {
	return s.resourceInstance.LockName(s.worker.Name())
}

func (s *resourceInstanceFetchSource) Find() (VersionedSource, bool, error) {
	sLog := s.logger.Session("find")

	volume, found, err := s.resourceInstance.FindOn(s.logger, s.worker)
	if err != nil {
		sLog.Error("failed-to-find-initialized-on", err)
		return nil, false, err
	}

	if !found {
		return nil, false, nil
	}

	metadata, err := s.dbResourceCacheFactory.ResourceCacheMetadata(s.resourceInstance.ResourceCache())
	if err != nil {
		sLog.Error("failed-to-get-resource-cache-metadata", err)
		return nil, false, err
	}

	s.logger.Debug("found-initialized-versioned-source", lager.Data{"version": s.resourceInstance.Version(), "metadata": metadata.ToATCMetadata()})

	return NewGetVersionedSource(
		volume,
		s.resourceInstance.Version(),
		metadata.ToATCMetadata(),
	), true, nil
}

// Create runs under the lock but we need to make sure volume does not exist
// yet before creating it under the lock
func (s *resourceInstanceFetchSource) Create(signals <-chan os.Signal, ready chan<- struct{}) (VersionedSource, error) {
	sLog := s.logger.Session("create")

	versionedSource, found, err := s.Find()
	if err != nil {
		return nil, err
	}

	if found {
		return versionedSource, nil
	}

	mountPath := ResourcesDir("get")

	containerSpec := worker.ContainerSpec{
		ImageSpec: worker.ImageSpec{
			ResourceType: string(s.resourceInstance.ResourceType()),
		},
		Tags:   s.tags,
		TeamID: s.teamID,
		Env:    s.metadata.Env(),

		Outputs: map[string]string{
			"resource": mountPath,
		},
	}

	resourceFactory := NewResourceFactory(s.worker)
	resource, err := resourceFactory.NewResource(
		s.logger,
		nil,
		s.resourceInstance.ContainerOwner(),
		s.session.Metadata,
		containerSpec,
		s.resourceTypes,
		s.imageFetchingDelegate,
	)
	if err != nil {
		sLog.Error("failed-to-construct-resource", err)
		return nil, err
	}

	var volume worker.Volume
	for _, mount := range resource.Container().VolumeMounts() {
		if mount.MountPath == mountPath {
			volume = mount.Volume
			break
		}
	}

	versionedSource, err = resource.Get(
		volume,
		IOConfig{
			Stdout: s.imageFetchingDelegate.Stdout(),
			Stderr: s.imageFetchingDelegate.Stderr(),
		},
		s.resourceInstance.Source(),
		s.resourceInstance.Params(),
		s.resourceInstance.Version(),
		signals,
		ready,
	)
	if err != nil {
		if err == ErrAborted {
			sLog.Error("get-run-resource-aborted", err, lager.Data{"container": resource.Container().Handle()})
			return nil, ErrInterrupted
		}

		sLog.Error("failed-to-fetch-resource", err)
		return nil, err
	}

	err = volume.SetPrivileged(false)
	if err != nil {
		sLog.Error("failed-to-set-volume-unprivileged", err)
		return nil, err
	}

	err = volume.InitializeResourceCache(s.resourceInstance.ResourceCache())
	if err != nil {
		sLog.Error("failed-to-initialize-cache", err)
		return nil, err
	}

	err = s.dbResourceCacheFactory.UpdateResourceCacheMetadata(s.resourceInstance.ResourceCache(), versionedSource.Metadata())
	if err != nil {
		s.logger.Error("failed-to-update-resource-cache-metadata", err, lager.Data{"resource-cache": s.resourceInstance.ResourceCache()})
		return nil, err
	}

	return versionedSource, nil
}
<|endoftext|>