<commit_before>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package backups_test

import (
	gc "gopkg.in/check.v1"

	"github.com/juju/juju/api/backups"
	"github.com/juju/juju/apiserver/params"
)

type infoSuite struct {
	baseBackupsSuite
}

var _ = gc.Suite(&infoSuite{})

func (s *infoSuite) TestInfo(c *gc.C) {
	cleanup := backups.PatchClientFacadeCall(s.client,
		func(req string, paramsIn interface{}, resp interface{}) error {
			c.Check(req, gc.Equals, "Info")

			c.Assert(paramsIn, gc.FitsTypeOf, params.BackupsInfoArgs{})
			p := paramsIn.(params.BackupsInfoArgs)
			c.Check(p.ID, gc.Equals, "spam")

			if result, ok := resp.(*params.BackupsMetadataResult); ok {
				result.UpdateFromMetadata(s.meta)
			} else {
				c.Fatalf("wrong output structure")
			}
			return nil
		},
	)
	defer cleanup()

	result, err := s.client.Info("spam")
	c.Assert(err, gc.IsNil)

	s.checkMetadataResult(c, result, s.meta, "")
}
<commit_msg>Adjust to baseSuite.<commit_after>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package backups_test

import (
	gc "gopkg.in/check.v1"

	"github.com/juju/juju/api/backups"
	"github.com/juju/juju/apiserver/params"
)

type infoSuite struct {
	baseSuite
}

var _ = gc.Suite(&infoSuite{})

func (s *infoSuite) TestInfo(c *gc.C) {
	cleanup := backups.PatchClientFacadeCall(s.client,
		func(req string, paramsIn interface{}, resp interface{}) error {
			c.Check(req, gc.Equals, "Info")

			c.Assert(paramsIn, gc.FitsTypeOf, params.BackupsInfoArgs{})
			p := paramsIn.(params.BackupsInfoArgs)
			c.Check(p.ID, gc.Equals, "spam")

			if result, ok := resp.(*params.BackupsMetadataResult); ok {
				result.UpdateFromMetadata(s.Meta)
			} else {
				c.Fatalf("wrong output structure")
			}
			return nil
		},
	)
	defer cleanup()

	result, err := s.client.Info("spam")
	c.Assert(err, gc.IsNil)

	s.checkMetadataResult(c, result, s.Meta)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/guelfey/go.dbus"
	"os"
)

const intro = `
<node>
	<interface name="com.github.guelfey.Demo">
		<method name="Foo">
			<arg direction="out" type="s"/>
		</method>
	</interface>
</node>
`

type foo string

func (f foo) Foo() (string, *dbus.Error) {
	fmt.Println(f)
	return string(f), nil
}

func main() {
	conn, err := dbus.ConnectSessionBus()
	if err != nil {
		panic(err)
	}
	reply, err := conn.RequestName("com.github.guelfey.Demo",
		dbus.NameFlagDoNotQueue)
	if err != nil {
		panic(err)
	}
	if reply != dbus.RequestNameReplyPrimaryOwner {
		fmt.Fprintln(os.Stderr, "name already taken")
		os.Exit(1)
	}
	f := foo("Bar!")
	conn.Export(f, "/com/github/guelfey/Demo", "com.github.guelfey.Demo")
	conn.SetIntrospect("/com/github/guelfey/Demo", intro)
	fmt.Println("Listening on com.github.guelfey.Demo / /com/github/guelfey/Demo ...")
	select {}
}
<commit_msg>Fix server example to work with 04c6eba<commit_after>package main

import (
	"fmt"
	"github.com/guelfey/go.dbus"
	"github.com/guelfey/go.dbus/introspect"
	"os"
)

const intro = `
<node>
	<interface name="com.github.guelfey.Demo">
		<method name="Foo">
			<arg direction="out" type="s"/>
		</method>
	</interface>
	<interface name="org.freedesktop.DBus.Introspectable">
		<method name="Introspect">
			<arg direction="out" type="s"/>
		</method>
	</interface>
</node>
`

type foo string

func (f foo) Foo() (string, *dbus.Error) {
	fmt.Println(f)
	return string(f), nil
}

func main() {
	conn, err := dbus.ConnectSessionBus()
	if err != nil {
		panic(err)
	}
	reply, err := conn.RequestName("com.github.guelfey.Demo",
		dbus.NameFlagDoNotQueue)
	if err != nil {
		panic(err)
	}
	if reply != dbus.RequestNameReplyPrimaryOwner {
		fmt.Fprintln(os.Stderr, "name already taken")
		os.Exit(1)
	}
	f := foo("Bar!")
	conn.Export(f, "/com/github/guelfey/Demo", "com.github.guelfey.Demo")
	conn.Export(introspect.Introspectable(intro), "/com/github/guelfey/Demo",
		"org.freedesktop.DBus.Introspectable")
	fmt.Println("Listening on com.github.guelfey.Demo / /com/github/guelfey/Demo ...")
	select {}
}
<|endoftext|>


<commit_before>package configurer

import (
	"testing"

	"io/ioutil"

	"os"

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

// TestInit test the intialization phase of the interactive cli.
func TestInit(t *testing.T) {
	cli := CLI().(*interactiveCLI)
	cli.InitWithDefaultVaules(Defaults())
	assert.Equal(t, cli.defaultValues, cli.userValues)
	cli.userValues.file = "/tmp/throwaway.json"
	assert.NotEqual(t, cli.defaultValues, cli.userValues)
}

// TestObtain test the user data acquisition phase of the cli.
func TestObtain(t *testing.T) {
	cli := CLI().(*interactiveCLI)
	cli.InitWithDefaultVaules(Defaults())
	exfg := cli.Obtain()
	assert.NotNil(t, exfg)

}

// TestWrite test the configuration write phase of the cli.
func TestWrite(t *testing.T) {
	cli := CLI().(*interactiveCLI)
	extendedCfg := Defaults()
	tf, _ := ioutil.TempFile("", "test_fritzctl.json.")
	defer tf.Close()
	defer os.Remove(tf.Name())
	extendedCfg.file = tf.Name()
	cli.InitWithDefaultVaules(extendedCfg)
	err := cli.Write()
	assert.NoError(t, err)
}

// TestWriteWithIOError test the write phase of the cli with error.
func TestWriteWithIOError(t *testing.T) {
	cli := CLI().(*interactiveCLI)
	extendedCfg := Defaults()
	extendedCfg.file = "/root/a/b/c/no/such/file/or/directory/cfg.json"
	cli.InitWithDefaultVaules(extendedCfg)
	err := cli.Write()
	assert.Error(t, err)
}
<commit_msg>remove whitespace<commit_after>package configurer

import (
	"testing"

	"io/ioutil"

	"os"

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

// TestInit test the intialization phase of the interactive cli.
func TestInit(t *testing.T) {
	cli := CLI().(*interactiveCLI)
	cli.InitWithDefaultVaules(Defaults())
	assert.Equal(t, cli.defaultValues, cli.userValues)
	cli.userValues.file = "/tmp/throwaway.json"
	assert.NotEqual(t, cli.defaultValues, cli.userValues)
}

// TestObtain test the user data acquisition phase of the cli.
func TestObtain(t *testing.T) {
	cli := CLI().(*interactiveCLI)
	cli.InitWithDefaultVaules(Defaults())
	exfg := cli.Obtain()
	assert.NotNil(t, exfg)
}

// TestWrite test the configuration write phase of the cli.
func TestWrite(t *testing.T) {
	cli := CLI().(*interactiveCLI)
	extendedCfg := Defaults()
	tf, _ := ioutil.TempFile("", "test_fritzctl.json.")
	defer tf.Close()
	defer os.Remove(tf.Name())
	extendedCfg.file = tf.Name()
	cli.InitWithDefaultVaules(extendedCfg)
	err := cli.Write()
	assert.NoError(t, err)
}

// TestWriteWithIOError test the write phase of the cli with error.
func TestWriteWithIOError(t *testing.T) {
	cli := CLI().(*interactiveCLI)
	extendedCfg := Defaults()
	extendedCfg.file = "/root/a/b/c/no/such/file/or/directory/cfg.json"
	cli.InitWithDefaultVaules(extendedCfg)
	err := cli.Write()
	assert.Error(t, err)
}
<|endoftext|>


<commit_before>// Copyright 2010 GoDCCP Authors. All rights reserved.
// Use of this source code is governed by a
// license that can be found in the LICENSE file.

package ccid3

import (
	//"os"
	"math"
	//"github.com/petar/GoDCCP/dccp"
)

// rateCaclulator computers the allowed sending rate of the sender
type rateCalculator struct {
	x               uint32 // Current allowed sending rate, in bytes per second
	tld             int64  // Time Last Doubled (during slow start) or zero if unset; in ns since UTC zero
	recv_limit      uint32 // Receive limit, in bytes per second
	xRecvSet          // Data structure for x_recv_set (see RFC 5348)
}

const (
	X_MAX_INIT_WIN          = 4380           // Maximum size of initial window in bytes
	X_MAX_BACKOFF_INTERVAL  = 64e9           // Maximum backoff interval in ns (See RFC 5348, Section 4.3)
	X_RECV_MAX              = math.MaxInt32  // Maximum receive rate, in bytes per second
	X_RECV_SET_SIZE         = 3              // Size of x_recv_set
)

// Init resets the rate calculator for new use and returns the initial
// allowed sending rate (in bytes per second). The latter is the rate
// to be used before the first feedback packet is received and hence before
// an RTT estimate is available.
func (t *rateCalculator) Init(now int64, ss uint32) {
	// The allowed sending rate before the first feedback packet is received
	// is one packet per second.
	t.x = ss
	// tld = 0 indicates that the first feedback packet has yet not been received.
	t.tld = 0
	// Because X_recv_set is initialized with a single item, with value Infinity, recv_limit is
	// set to Infinity for the first two round-trip times of the connection.  As a result, the
	// sending rate is not limited by the receive rate during that period.  This avoids the
	// problem of the sending rate being limited by the value of X_recv from the first feedback
	// packet.
	t.recv_limit = X_RECV_MAX
	t.xRecvSet.Init()
}

// onFirstRead is called internally to handle the very first feedback packet received.
func (t *rateCalculator) onFirstRead(now int64, ss uint32, rtt int64) uint32 {
	t.tld = now
	t.x = initRate(ss, rtt)
	return t.x
}

// initRate returns the allowed initial sending rate in bytes per second.
func initRate(ss uint32, rtt int64) uint32 {
	if ss <= 0 || rtt <= 0 {
		panic("unknown SS or RTT")
	}
	win := minu32(4*ss, maxu32(2*ss, X_MAX_INIT_WIN)) // window = bytes per round trip (bpr)
	return uint32(max64((1e9*int64(win)) / rtt, 1))
}

// Sender calls OnRead each time a new feedback packet arrives.
// OnRead returns the new allowed sending in bytes per second.
// x_recv is given in bytes per second.
// lossRateInv equals zero if the loss rate is still unknown.
func (t *rateCalculator) OnRead(now int64, ss uint32, x_recv uint32, rtt int64, lossRateInv uint32, newLoss bool) uint32 {
	?? // The loss rate inv should never be < 1 after the first newLoss event
	?? // Fix for new UnknownLoss... value convention
	// lossSender: current rate, new loss reported, increase or decrease from prev event
	if t.tld <= 0 {
		return t.onFirstRead(now, ss, rtt)
	}
	if /* the entire interval covered by the feedback packet was a data-limited interval */ {
		if ?? /* the feedback packet reports a new loss event or an increase in the loss event rate p */ {
			t.xRecvSet.Halve()
			x_recv = (85 * x_recv) / 100
			t.xRecvSet.Maximize(now, x_recv)
			t.recv_limit = t.xRecvSet.Max()
		} else {
			t.xRecvSet.Maximize(now, x_recv)
			t.recv_limit = 2 * t.xRecvSet.Max()
		}
	} else {
		t.xRecvSet.Update(now, x_recv, rtt)
		t.recv_limit = 2 * t.xRecvSet.Max()
	}
	// Non-zero loss rate inverse indicates that we are in the post-slow start phase
	if lossRateInv > 0 {
		x_eq := t.thruEq(ss, rtt, lossRateInv)
		t.x = maxu32(
			minu32(x_eq, t.recv_limit),
			(1e9*ss) / X_MAX_BACKOFF_INTERVAL
		)
	} else if now - t.tld >= rtt {
		// Initial slow-start
		t.x = max(min(2*t.x, recv_limit), initRate(ss, rtt))
		t.tld = now
	}
	// TODO: Place oscillation reduction code here (see RFC 5348, Section 4.3)
	return t.x
}

// thruEq returns the allowed sending rate, in bytes per second, according to the TCP
// throughput equation, for the regime b=1 and t_RTO=4*RTT (See RFC 5348, Section 3.1).
func (t *rateCalculator) thruEq(ss uint32, rtt int64, lossRateInv uint32) uint32 {
	bps := (1e3*1e9*int64(ss)) / (rtt * thruEqQ(lossRateInv))
	return uint32(bps)
}

// thruEqDenom computes the quantity 1e3*(sqrt(2*p/3) + 12*sqrt(3*p/8)*p*(1+32*p^2)).
func thruEqQ(lossRateInv uint32) int64 {
	j := min(int(lossRateInv), len(qTable))
	return qTable[j-1].Q
}

// —————
// xRecvSet maintains a set of recently received Receive Rates (via ReceiveRateOption)
type xRecvSet struct {
	set [X_RECV_SET_SIZE]xRecvEntry  // Set of recent rates
}

type xRecvEntry struct {
	Rate uint32   // Receive rate; in bytes per second
	Time int64    // Entry timestamp or zero if unset; in ns since UTC zero
}

// Init resets the xRecvSet object for new use
func (t *xRecvSet) Init() {
	for i, _ := range t.set {
		t.set[i] = xRecvEntry{}
	}
}

// Halve halves all the rates in the set
func (t *xRecvSet) Halve() {
	for i, _ := range t.set {
		t.set[i].Rate /= 2
	}
}

// Max returns the highest rate in the set; in bytes per second
func (t *xRecvSet) Max() uint32 {
	var set bool
	var r uint32
	for _, e := range t.set {
		if e.Time <= 0 {
			continue
		}
		if e.Rate > r {
			r = e.Rate
			set = true
		}
	}
	if !set {
		return X_RECV_MAX
	}
	return r
}

// The procedure for maximizing X_recv_set keeps a single value, the
// largest value from X_recv_set and the new X_recv.
//
//   Maximize X_recv_set():
//     Add X_recv to X_recv_set;
//     Delete initial value Infinity from X_recv_set, if it is still a member.
//     Set the timestamp of the largest item to the current time;
//     Delete all other items.
//
func (t *xRecvSet) Maximize(now int64, x_recv_bps uint32) {
	for i, e := range t.set {
		if e.Time > 0 {
			x_recv_bps = maxu32(x_recv_bps, e.Rate)
		}
		t.set[i] = xRecvEntry{}
	}
	t.set[0].Time = now
	t.set[0].Rate = x_recv_bps
}

// The procedure for updating X_recv_set keeps a set of X_recv values
// with timestamps from the two most recent round-trip times.
//
//   Update X_recv_set():
//     Add X_recv to X_recv_set;
//     Delete from X_recv_set values older than two round-trip times.
//
func (t *xRecvSet) Update(now int64, x_recv_bps uint32, rtt int64) {
	// Remove entries older than two RTT
	for i, e := range t.set {
		if e.Time > 0 && now - e.Time > 2*rtt {
			t.set[i] = xRecvEntry{}
		}
	}
	// Find free cell or oldest entry
	var j int = -1
	var j_time int64 = now
	for i, e := range t.set {
		if e.Time <= 0 {
			j = i
			break
		}
		if e.Time <= j_time {
			j = i
			j_time = e.Time
		}
	}
	t.set[j].Rate = x_recv_bps
	t.set[j].Time = now
}
<commit_msg>integrated loss feedback in rate calculator<commit_after>// Copyright 2010 GoDCCP Authors. All rights reserved.
// Use of this source code is governed by a
// license that can be found in the LICENSE file.

package ccid3

import (
	//"os"
	"math"
	//"github.com/petar/GoDCCP/dccp"
)

// rateCaclulator computers the allowed sending rate of the sender
type rateCalculator struct {
	x         uint32 // Current allowed sending rate, in bytes per second
	tld       int64  // Time Last Doubled (during slow start) or zero if unset; in ns since UTC zero
	recvLimit uint32 // Receive limit, in bytes per second
	xRecvSet         // Data structure for x_recv_set (see RFC 5348)
}

const (
	X_MAX_INIT_WIN          = 4380           // Maximum size of initial window in bytes
	X_MAX_BACKOFF_INTERVAL  = 64e9           // Maximum backoff interval in ns (See RFC 5348, Section 4.3)
	X_RECV_MAX              = math.MaxInt32  // Maximum receive rate, in bytes per second
	X_RECV_SET_SIZE         = 3              // Size of x_recv_set
)

// Init resets the rate calculator for new use and returns the initial
// allowed sending rate (in bytes per second). The latter is the rate
// to be used before the first feedback packet is received and hence before
// an RTT estimate is available.
func (t *rateCalculator) Init(now int64, ss uint32) {
	// The allowed sending rate before the first feedback packet is received
	// is one packet per second.
	t.x = ss
	// tld = 0 indicates that the first feedback packet has yet not been received.
	t.tld = 0
	// Because X_recv_set is initialized with a single item, with value Infinity, recvLimit is
	// set to Infinity for the first two round-trip times of the connection.  As a result, the
	// sending rate is not limited by the receive rate during that period.  This avoids the
	// problem of the sending rate being limited by the value of X_recv from the first feedback
	// packet.
	t.recvLimit = X_RECV_MAX
	t.xRecvSet.Init()
}

// onFirstRead is called internally to handle the very first feedback packet received.
func (t *rateCalculator) onFirstRead(now int64, ss uint32, rtt int64) uint32 {
	t.tld = now
	t.x = initRate(ss, rtt)
	return t.x
}

// initRate returns the allowed initial sending rate in bytes per second.
func initRate(ss uint32, rtt int64) uint32 {
	if ss <= 0 || rtt <= 0 {
		panic("unknown SS or RTT")
	}
	win := minu32(4*ss, maxu32(2*ss, X_MAX_INIT_WIN)) // window = bytes per round trip (bpr)
	return uint32(max64((1e9*int64(win)) / rtt, 1))
}

// XFeedback contains computed feedback variables that are used by the rate calculator to update the
// allowed sending rate
type XFeedback struct {
	Now   int64   // Time now
	SS    uint32  // Segment size
	XRecv uint32  // Receive rate
	RTT   int64   // Round-trip time
	LossFeedback  // Loss-related feedback
}

// Sender calls OnRead each time a new feedback packet arrives.
// OnRead returns the new allowed sending in bytes per second.
// x_recv is given in bytes per second.
// lossRateInv equals zero if the loss rate is still unknown.
func (t *rateCalculator) OnRead(f XFeedback) uint32 {
	if f.LossFeedback.RateInv < 1 {
		panic("invalid loss rate inverse")
	}
	if t.tld <= 0 {
		return t.onFirstRead(f.Now, f.SS, f.RTT)
	}
	if /* the entire interval covered by the feedback packet was a data-limited interval */ {
		if f.LossFeedback.RateInc || f.LossFeedback.NewLossCount > 0 {
			t.xRecvSet.Halve()
			f.XRecv = (85 * f.XRecv) / 100
			t.xRecvSet.Maximize(f.Now, f.XRecv)
			t.recvLimit = t.xRecvSet.Max()
		} else {
			t.xRecvSet.Maximize(f.Now, f.XRecv)
			t.recvLimit = 2 * t.xRecvSet.Max()
		}
	} else {
		t.xRecvSet.Update(f.Now, f.XRecv, f.RTT)
		t.recvLimit = 2 * t.xRecvSet.Max()
	}
	// Are we in the post-slow start phase
	if f.LossFeedback.RateInv < UnknownLossEventRateInv {
		xEq := t.thruEq(f.SS, f.RTT, f.LossFeedback.RateInv)
		t.x = maxu32(
			minu32(xEq, t.recvLimit),
			(1e9 * f.SS) / X_MAX_BACKOFF_INTERVAL
		)
	} else if f.Now - t.tld >= f.RTT {
		// Initial slow-start
		t.x = max(min(2*t.x, recvLimit), initRate(f.SS, f.RTT))
		t.tld = f.Now
	}
	// TODO: Place oscillation reduction code here (see RFC 5348, Section 4.3)
	return t.x
}

// thruEq returns the allowed sending rate, in bytes per second, according to the TCP
// throughput equation, for the regime b=1 and t_RTO=4*RTT (See RFC 5348, Section 3.1).
func (t *rateCalculator) thruEq(ss uint32, rtt int64, lossRateInv uint32) uint32 {
	bps := (1e3*1e9*int64(ss)) / (rtt * thruEqQ(lossRateInv))
	return uint32(bps)
}

// thruEqDenom computes the quantity 1e3*(sqrt(2*p/3) + 12*sqrt(3*p/8)*p*(1+32*p^2)).
func thruEqQ(lossRateInv uint32) int64 {
	j := min(int(lossRateInv), len(qTable))
	return qTable[j-1].Q
}

// —————
// xRecvSet maintains a set of recently received Receive Rates (via ReceiveRateOption)
type xRecvSet struct {
	set [X_RECV_SET_SIZE]xRecvEntry  // Set of recent rates
}

type xRecvEntry struct {
	Rate uint32   // Receive rate; in bytes per second
	Time int64    // Entry timestamp or zero if unset; in ns since UTC zero
}

// Init resets the xRecvSet object for new use
func (t *xRecvSet) Init() {
	for i, _ := range t.set {
		t.set[i] = xRecvEntry{}
	}
}

// Halve halves all the rates in the set
func (t *xRecvSet) Halve() {
	for i, _ := range t.set {
		t.set[i].Rate /= 2
	}
}

// Max returns the highest rate in the set; in bytes per second
func (t *xRecvSet) Max() uint32 {
	var set bool
	var r uint32
	for _, e := range t.set {
		if e.Time <= 0 {
			continue
		}
		if e.Rate > r {
			r = e.Rate
			set = true
		}
	}
	if !set {
		return X_RECV_MAX
	}
	return r
}

// The procedure for maximizing X_recv_set keeps a single value, the
// largest value from X_recv_set and the new X_recv.
//
//   Maximize X_recv_set():
//     Add X_recv to X_recv_set;
//     Delete initial value Infinity from X_recv_set, if it is still a member.
//     Set the timestamp of the largest item to the current time;
//     Delete all other items.
//
func (t *xRecvSet) Maximize(now int64, xRecvBPS uint32) {
	for i, e := range t.set {
		if e.Time > 0 {
			xRecvBPS = maxu32(xRecvBPS, e.Rate)
		}
		t.set[i] = xRecvEntry{}
	}
	t.set[0].Time = now
	t.set[0].Rate = xRecvBPS
}

// The procedure for updating X_recv_set keeps a set of X_recv values
// with timestamps from the two most recent round-trip times.
//
//   Update X_recv_set():
//     Add X_recv to X_recv_set;
//     Delete from X_recv_set values older than two round-trip times.
//
func (t *xRecvSet) Update(now int64, xRecvBPS uint32, rtt int64) {
	// Remove entries older than two RTT
	for i, e := range t.set {
		if e.Time > 0 && now - e.Time > 2*rtt {
			t.set[i] = xRecvEntry{}
		}
	}
	// Find free cell or oldest entry
	var j int = -1
	var j_time int64 = now
	for i, e := range t.set {
		if e.Time <= 0 {
			j = i
			break
		}
		if e.Time <= j_time {
			j = i
			j_time = e.Time
		}
	}
	t.set[j].Rate = xRecvBPS
	t.set[j].Time = now
}
<|endoftext|>


<commit_before>package cargo

import (
	"fmt"
	"os/exec"
	"path/filepath"
	"strings"
)

type repository struct {
	remote  string
	org     string
	user    string
	repo    string
	version string
	dir     string
}

func newRepository(remote, org, user, repo, version, dir string) *repository {
	return &repository{
		remote:  remote,
		org:     org,
		user:    user,
		repo:    repo,
		version: version,
		dir:     dir,
	}
}

func (r repository) clone(schema string) error {
	cmd := exec.Command(
		"git",
		"clone",
		"--depth=1",
		"-b", r.version,
		r.cloneURL(schema),
	)
	cmd.Dir = r.dir
	return cmd.Run()
}

func (r repository) diffArchive(dest, typ string) error {
	// TODO use native zip, tar, gzip package.
	switch typ {
	case "tar.gz":
		return r.targz(r.diff(), dest+"."+typ)
	default:
		return nil
	}
}

func (r repository) targz(src []string, dest string) error {
	params := append(append([]string{}, "czf", dest), src...)
	cmd := exec.Command("tar", params...)
	cmd.Dir = r.pwd()
	return cmd.Run()
}

func (r repository) cleanWithDryRun() ([]byte, error) {
	cmd := exec.Command(
		"git",
		"clean",
		"--dry-run",
	)
	cmd.Dir = r.pwd()
	return cmd.Output()
}

func (r repository) diff() []string {
	out, _ := r.cleanWithDryRun()
	added := strings.Split(string(out), "\n")
	var files []string
	for _, a := range added {
		if a == "" || a == "Would remove Makefile" {
			continue
		}
		files = append(files, strings.TrimPrefix(a, "Would remove "))
	}
	return files
}

func (r repository) path() string {
	return filepath.Join(r.remote, r.owner(), r.repo)
}

func (r repository) pwd() string {
	return filepath.Join(r.dir, r.repo)
}

func (r repository) owner() string {
	var owner string
	if r.org != "" {
		owner = r.org + "/"
	}
	return owner + r.user
}

func (r repository) cloneURL(schema string) string {
	switch schema {
	case "https":
		return fmt.Sprintf("https://%s/%s/%s.git", r.remote, r.owner(), r.repo)
	default:
		return ""
	}
}
<commit_msg>Use params struct in repository struct.<commit_after>package cargo

import (
	"fmt"
	"os/exec"
	"path/filepath"
	"strings"
)

type repository struct {
	params *params
	dir    string
}

func newRepository(params *params, dir string) *repository {
	return &repository{
		params: params,
		dir:    dir,
	}
}

func (r repository) clone(schema string) error {
	cmd := exec.Command(
		"git",
		"clone",
		"--depth=1",
		"-b", r.params.version,
		r.cloneURL(schema),
	)
	cmd.Dir = r.dir
	return cmd.Run()
}

func (r repository) diffArchive(dest, typ string) error {
	// TODO use native zip, tar, gzip package.
	switch typ {
	case "tar.gz":
		return r.targz(r.diff(), dest+"."+typ)
	default:
		return nil
	}
}

func (r repository) targz(src []string, dest string) error {
	params := append(append([]string{}, "czf", dest), src...)
	cmd := exec.Command("tar", params...)
	cmd.Dir = r.pwd()
	return cmd.Run()
}

func (r repository) cleanWithDryRun() ([]byte, error) {
	cmd := exec.Command(
		"git",
		"clean",
		"--dry-run",
	)
	cmd.Dir = r.pwd()
	return cmd.Output()
}

func (r repository) diff() []string {
	out, _ := r.cleanWithDryRun()
	added := strings.Split(string(out), "\n")
	var files []string
	for _, a := range added {
		if a == "" || a == "Would remove Makefile" {
			continue
		}
		files = append(files, strings.TrimPrefix(a, "Would remove "))
	}
	return files
}

func (r repository) path() string {
	return filepath.Join(r.params.remote, r.params.owner(), r.params.repo)
}

func (r repository) pwd() string {
	return filepath.Join(r.dir, r.params.repo)
}

func (r repository) cloneURL(schema string) string {
	switch schema {
	case "https":
		return fmt.Sprintf("https://%s/%s/%s.git", r.params.remote, r.params.owner(), r.params.repo)
	default:
		return ""
	}
}
<|endoftext|>


<commit_before>package validators

import (
	"bytes"
	"fmt"
	"sort"
	"strings"

	"github.com/cihangir/gene/schema"
	"github.com/cihangir/gene/writers"
	"github.com/cihangir/stringext"
)

// Generate generates the validators for the the given schema
func Generate(s *schema.Schema) ([]byte, error) {
	validators := make([]string, 0)
	// schemaName := p.Title
	schemaFirstChar := stringext.Pointerize(s.Title)

	for k, property := range s.Properties {
		key := stringext.DepunctWithInitialUpper(k)
		switch property.Type {
		case "string":
			if property.MinLength != 0 {
				validator := fmt.Sprintf("govalidator.MinLength(%s.%s, %d)", schemaFirstChar, key, property.MinLength)
				validators = append(validators, validator)
			}

			if property.MaxLength != 0 {
				validator := fmt.Sprintf("govalidator.MaxLength(%s.%s, %d)", schemaFirstChar, key, property.MaxLength)
				validators = append(validators, validator)
			}

			if property.Pattern != "" {
				validator := fmt.Sprintf("govalidator.Pattern(%s.%s, \"%s\")", schemaFirstChar, key, property.Pattern)
				validators = append(validators, validator)
			}

			if len(property.Enum) > 0 {
				generatedEnums := make([]string, len(property.Enum))
				for i, enum := range property.Enum {
					k := stringext.DepunctWithInitialUpper(key)
					generatedEnums[i] = k + "." + stringext.DepunctWithInitialUpper(enum)
				}
				validator := fmt.Sprintf("govalidator.OneOf(%s.%s, []string{\n%s,\n})", schemaFirstChar, key, strings.Join(generatedEnums, ",\n"))
				validators = append(validators, validator)
			}

			// TODO impplement this one
			switch property.Format {
			case "date-time":
				// _, err := time.Parse(time.RFC3339, s)
				validator := fmt.Sprintf("govalidator.Date(%s.%s)", schemaFirstChar, key)
				validators = append(validators, validator)
			}

		case "integer", "number":

			// todo implement exclusive min/max

			if property.Minimum != 0 {
				validator := fmt.Sprintf("govalidator.Min(float64(%s.%s), %f)", schemaFirstChar, key, property.Minimum)
				validators = append(validators, validator)
			}

			if property.Maximum != 0 {
				validator := fmt.Sprintf("govalidator.Max(float64(%s.%s), %f)", schemaFirstChar, key, property.Maximum)
				validators = append(validators, validator)
			}

			// multipleOf:
			if property.MultipleOf != 0 {
				validator := fmt.Sprintf("govalidator.MultipleOf(float64(%s.%s), %f)", schemaFirstChar, key, property.MultipleOf)
				validators = append(validators, validator)
			}
		}
	}

	if len(validators) == 0 {
		return nil, nil
	}

	templ := `
// Validate validates the struct
func (%s *%s) Validate() error {
	return govalidator.NewMulti(%s).Validate()
}`

	sslice := sort.StringSlice(validators)
	sslice.Sort()

	res := fmt.Sprintf(
		templ,
		stringext.Pointerize(s.Title),
		s.Title,
		strings.Join(sslice, ",\n"),
	)

	return writers.Clear(*bytes.NewBufferString(res))
}
<commit_msg>Schema: use cihangir/schema instead of gene/schema<commit_after>package validators

import (
	"bytes"
	"fmt"
	"sort"
	"strings"

	"github.com/cihangir/gene/writers"
	"github.com/cihangir/schema"
	"github.com/cihangir/stringext"
)

// Generate generates the validators for the the given schema
func Generate(s *schema.Schema) ([]byte, error) {
	validators := make([]string, 0)
	// schemaName := p.Title
	schemaFirstChar := stringext.Pointerize(s.Title)

	for k, property := range s.Properties {
		key := stringext.DepunctWithInitialUpper(k)
		switch property.Type {
		case "string":
			if property.MinLength != 0 {
				validator := fmt.Sprintf("govalidator.MinLength(%s.%s, %d)", schemaFirstChar, key, property.MinLength)
				validators = append(validators, validator)
			}

			if property.MaxLength != 0 {
				validator := fmt.Sprintf("govalidator.MaxLength(%s.%s, %d)", schemaFirstChar, key, property.MaxLength)
				validators = append(validators, validator)
			}

			if property.Pattern != "" {
				validator := fmt.Sprintf("govalidator.Pattern(%s.%s, \"%s\")", schemaFirstChar, key, property.Pattern)
				validators = append(validators, validator)
			}

			if len(property.Enum) > 0 {
				generatedEnums := make([]string, len(property.Enum))
				for i, enum := range property.Enum {
					k := stringext.DepunctWithInitialUpper(key)
					generatedEnums[i] = k + "." + stringext.DepunctWithInitialUpper(enum)
				}
				validator := fmt.Sprintf("govalidator.OneOf(%s.%s, []string{\n%s,\n})", schemaFirstChar, key, strings.Join(generatedEnums, ",\n"))
				validators = append(validators, validator)
			}

			// TODO impplement this one
			switch property.Format {
			case "date-time":
				// _, err := time.Parse(time.RFC3339, s)
				validator := fmt.Sprintf("govalidator.Date(%s.%s)", schemaFirstChar, key)
				validators = append(validators, validator)
			}

		case "integer", "number":

			// todo implement exclusive min/max

			if property.Minimum != 0 {
				validator := fmt.Sprintf("govalidator.Min(float64(%s.%s), %f)", schemaFirstChar, key, property.Minimum)
				validators = append(validators, validator)
			}

			if property.Maximum != 0 {
				validator := fmt.Sprintf("govalidator.Max(float64(%s.%s), %f)", schemaFirstChar, key, property.Maximum)
				validators = append(validators, validator)
			}

			// multipleOf:
			if property.MultipleOf != 0 {
				validator := fmt.Sprintf("govalidator.MultipleOf(float64(%s.%s), %f)", schemaFirstChar, key, property.MultipleOf)
				validators = append(validators, validator)
			}
		}
	}

	if len(validators) == 0 {
		return nil, nil
	}

	templ := `
// Validate validates the struct
func (%s *%s) Validate() error {
	return govalidator.NewMulti(%s).Validate()
}`

	sslice := sort.StringSlice(validators)
	sslice.Sort()

	res := fmt.Sprintf(
		templ,
		stringext.Pointerize(s.Title),
		s.Title,
		strings.Join(sslice, ",\n"),
	)

	return writers.Clear(*bytes.NewBufferString(res))
}
<|endoftext|>


<commit_before>// Copyright © 2017 Julien Pivotto <roidelapluie@inuits.eu>
//
// 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 api

import (
	"encoding/json"
	"errors"
	"fmt"
	"time"
)

type Timesheet struct {
	ID           int    `json:"id"`
	Year         int    `json:"year"`
	Month        int    `json:"month"`
	DisplayLabel string `json:"display_label"`
	Status       string `json:"status"`
}

type TimesheetsList struct {
	Timesheets []Timesheet `json:"results"`
}

func (t *Timesheet) New(c Client) error {
	resp, err := c.PostRequest(fmt.Sprintf("%s/v1/my_timesheets/", c.Endpoint), t)
	if err != nil {
		return err
	}
	err = json.NewDecoder(resp.Body).Decode(t)
	if err != nil {
		return err
	}
	return nil
}

func (ts *TimesheetsList) apiURL() string {
	return "v1/my_timesheets"
}

func (ts *TimesheetsList) slug() string {
	return "timesheets"
}

func (ts *TimesheetsList) augment() error {
	return nil
}

// Get returns the timesheets from the server
func (t *Timesheet) Get(c Client) error {
	ts := &TimesheetsList{}
	resp, err := c.GetRequest(fmt.Sprintf("%s/v1/my_timesheets/?year=%d&month=%d", c.Endpoint, t.Year, t.Month))
	if err != nil {
		return err
	}
	err = json.NewDecoder(resp.Body).Decode(ts)
	if err != nil {
		return err
	}
	if len(ts.Timesheets) != 1 {
		return fmt.Errorf("Expected 1 timesheet, got %d", len(ts.Timesheets))
	}
	*t = ts.Timesheets[0]
	return nil
}

// GetByID returns the timesheet from the server by its id
func (t *Timesheet) GetByID(c Client) error {
	resp, err := c.GetRequest(fmt.Sprintf("%s/v1/my_timesheets/%d/", c.Endpoint, t.ID))
	if err != nil {
		return err
	}
	err = json.NewDecoder(resp.Body).Decode(t)
	if err != nil {
		return err
	}
	return nil
}

func (t *Timesheet) Release(c Client) error {
	if t.ID == 0 {
		return errors.New("No ID for this timesheet")
	}
	t.Status = "PENDING"
	resp, err := c.PatchRequest(fmt.Sprintf("%s/v1/my_timesheets/%d/", c.Endpoint, t.ID), t)
	if err != nil {
		return err
	}
	err = json.NewDecoder(resp.Body).Decode(t)
	if err != nil {
		return err
	}
	return nil
}

func (ts *TimesheetsList) PrettyPrint() {
	for _, t := range ts.Timesheets {
		t.PrettyPrint()
	}
}

func (t *Timesheet) Name() string {
	return fmt.Sprintf("%s %d", time.Month(t.Month), t.Year)
}

func (t *Timesheet) PrettyPrint() {
	fmt.Printf("%s [%s]\n", t.Name(), t.Status)
}
<commit_msg>Document timesheets methods<commit_after>// Copyright © 2017 Julien Pivotto <roidelapluie@inuits.eu>
//
// 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 api

import (
	"encoding/json"
	"errors"
	"fmt"
	"time"
)

// Timesheet represents a ninetofiver timesheet
type Timesheet struct {
	ID           int    `json:"id"`
	Year         int    `json:"year"`
	Month        int    `json:"month"`
	DisplayLabel string `json:"display_label"`
	Status       string `json:"status"`
}

// TimesheetsList represents a list of ninetofiver timesheet
type TimesheetsList struct {
	Timesheets []Timesheet `json:"results"`
}

// New creates a new timesheet on the server
func (t *Timesheet) New(c Client) error {
	resp, err := c.PostRequest(fmt.Sprintf("%s/v1/my_timesheets/", c.Endpoint), t)
	if err != nil {
		return err
	}
	err = json.NewDecoder(resp.Body).Decode(t)
	if err != nil {
		return err
	}
	return nil
}

func (ts *TimesheetsList) apiURL() string {
	return "v1/my_timesheets"
}

func (ts *TimesheetsList) slug() string {
	return "timesheets"
}

func (ts *TimesheetsList) augment() error {
	return nil
}

// Get returns the timesheets from the server
func (t *Timesheet) Get(c Client) error {
	ts := &TimesheetsList{}
	resp, err := c.GetRequest(fmt.Sprintf("%s/v1/my_timesheets/?year=%d&month=%d", c.Endpoint, t.Year, t.Month))
	if err != nil {
		return err
	}
	err = json.NewDecoder(resp.Body).Decode(ts)
	if err != nil {
		return err
	}
	if len(ts.Timesheets) != 1 {
		return fmt.Errorf("Expected 1 timesheet, got %d", len(ts.Timesheets))
	}
	*t = ts.Timesheets[0]
	return nil
}

// GetByID returns the timesheet from the server by its id
func (t *Timesheet) GetByID(c Client) error {
	resp, err := c.GetRequest(fmt.Sprintf("%s/v1/my_timesheets/%d/", c.Endpoint, t.ID))
	if err != nil {
		return err
	}
	err = json.NewDecoder(resp.Body).Decode(t)
	if err != nil {
		return err
	}
	return nil
}

// Release sends a request to ninetofiver to mark the timesheet as PENDING.
func (t *Timesheet) Release(c Client) error {
	if t.ID == 0 {
		return errors.New("No ID for this timesheet")
	}
	t.Status = "PENDING"
	resp, err := c.PatchRequest(fmt.Sprintf("%s/v1/my_timesheets/%d/", c.Endpoint, t.ID), t)
	if err != nil {
		return err
	}
	err = json.NewDecoder(resp.Body).Decode(t)
	if err != nil {
		return err
	}
	return nil
}

// PrettyPrint prints timesheets in a nice way to the console
func (ts *TimesheetsList) PrettyPrint() {
	for _, t := range ts.Timesheets {
		t.PrettyPrint()
	}
}

// Name returns the timesheet name (English month name + year)
func (t *Timesheet) Name() string {
	return fmt.Sprintf("%s %d", time.Month(t.Month), t.Year)
}

// PrettyPrint prints timesheet in a nice way to the console
func (t *Timesheet) PrettyPrint() {
	fmt.Printf("%s [%s]\n", t.Name(), t.Status)
}
<|endoftext|>


<commit_before>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package process

import (
	"github.com/juju/utils/set"
)

// Status values specific to workload processes.
const (
	StatusPending Status = iota
	StatusActive
	StatusFailed
	StatusStopped
)

// KnownStatuses defines the statuses supported by Juju.
var KnownStatuses = set.NewInts(
	StatusPending,
	StatusActive,
	StatusFailed,
	StatusStopped,
)

// Status represents the status of a worload process.
type Status string

// String implements fmt.Stringer.
func (s Status) String() string {
	switch status {
	case StatusPending:
		return "pending"
	case StatusActive:
		return "active"
	case StatusFailed:
		return "failed"
	case StatusStopped:
		return "stopped"
	}
	return "Unknown"
}
<commit_msg>Fix Status.<commit_after>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package process

// Status values specific to workload processes.
const (
	StatusPending Status = 1 << iota
	StatusActive
	StatusFailed
	StatusStopped
)

// KnownStatuses defines the statuses supported by Juju.
var KnownStatuses = []Status{
	StatusPending,
	StatusActive,
	StatusFailed,
	StatusStopped,
}

// Status represents the status of a worload process.
type Status int

// String implements fmt.Stringer.
func (s Status) String() string {
	switch s {
	case StatusPending:
		return "pending"
	case StatusActive:
		return "active"
	case StatusFailed:
		return "failed"
	case StatusStopped:
		return "stopped"
	}
	return "unknown"
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/csv"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"strconv"
	"strings"
)

func checkErr(e error) {
	if e != nil {
		fmt.Println("Error: ", e)
		os.Exit(1)
	}
}

// Removes non-directory elements of any []os.FileInfo
func onlyDirectories(inLs []os.FileInfo) (outLs []os.FileInfo) {
	for _, fd := range inLs {
		if fd.IsDir() {
			outLs = append(outLs, fd)
		}
	}
	return
}

// Strips the "-trial-X" suffix from a column name
func stripTrial(colName string) string {
	splitStrings := strings.Split(colName, "-")
	return strings.Join(splitStrings[:len(splitStrings)-2], "-")
}

// Returns the average of a slice of numbers. Input and output are strings.
func stringNumAverage(nums []string) string {
	sum := 0
	count := 0
	for _, numStr := range nums {
		if numStr != "" {
			num, err := strconv.Atoi(numStr)
			checkErr(err)
			sum += num
			count++
		}
	}
	if count == 0 {
		return ""
	}
	return strconv.Itoa(sum / count)
}

func max(nums []int) int {
	myMax := nums[0]
	for i := 1; i < len(nums); i++ {
		if nums[i] > myMax {
			myMax = nums[i]
		}
	}
	return myMax
}

// Copies previous row's data for any skipped trials.  Does not fill empty cells
// at the end of the table.
func fillEmptyCells(records [][]string) [][]string {
	// Determine where to stop filling data for each column.
	stoppingPoints := make([]int, len(records[0]))
	for row := len(records) - 1; row > 0; row-- {
		for col := 1; col < len(records[row]); col++ {
			if stoppingPoints[col] == 0 && records[row][col] != "" {
				stoppingPoints[col] = row
			}
		}
	}

	// Fill empty cells occurring before the stopping points
	finalStoppingPoint := max(stoppingPoints)
	for row := 1; row < finalStoppingPoint; row++ {
		for col := 1; col < len(records[row]); col++ {
			if row < stoppingPoints[col] && records[row][col] == "" {
				if row == 1 {
					records[row][col] = strconv.Itoa(0)
				} else {
					records[row][col] = records[row-1][col]
				}
			}
		}
	}
	return records
}

// Extend "records" matrix to have rows until time "desiredTime"
// Return: Extended version of record
func extendRecordsToTime(records [][]string, desiredTime int, recordCols int) [][]string {
	lenr := len(records)
	// records[1] stores cycle [1], as records[0] is column names
	for j := lenr; j < desiredTime+1; j++ {
		records = append(records, make([]string, recordCols))
		records[j][0] = strconv.Itoa(j)
	}
	return records
}

// Handles the CSV Reader for a single trial, and updates records[][] accordingly. Returns the updated records
func handleTrialCSV(trialReader *csv.Reader, records [][]string, colName string, totalCols int, trialNum int) [][]string {
	// Read whole CSV to an array
	trialRecords, err := trialReader.ReadAll()
	checkErr(err)
	// Add the name of this new column to records[0]
	records[0] = append(records[0], colName)

	finalTime, err := strconv.Atoi(trialRecords[len(trialRecords)-1][0])
	checkErr(err)
	//If this test went longer than all of the others, so far
	if len(records) < finalTime+1 {
		records = extendRecordsToTime(records, finalTime, totalCols)
	}
	for _, row := range trialRecords {
		// row[0] is time, on the x-axis; row[1] is value, on the y-axis
		time, err := strconv.Atoi(row[0])
		checkErr(err)
		records[time][trialNum+1] = row[1]
	}
	return records
}

func handleFEngine(fengine os.FileInfo, bmarkPath string, finalReportFName string) [][]string {
	// Create matrix, to eventually become a CSV
	records := [][]string{{"time"}}

	// Enter sub-directories
	fenginePath := path.Join(bmarkPath, fengine.Name())
	ls, err := ioutil.ReadDir(fenginePath)
	checkErr(err)
	trials := onlyDirectories(ls)

	totalCols := len(trials) + 1
	for j, trial := range trials {
		// Create fds
		trialCSV, err := os.Open(path.Join(fenginePath, trial.Name(), finalReportFName))
		checkErr(err)
		trialReader := csv.NewReader(trialCSV)

		records = handleTrialCSV(trialReader, records, fengine.Name()+"-"+trial.Name(), totalCols, j)
		trialCSV.Close()
	}

	fengineCSV, err := os.Create(path.Join(fenginePath, finalReportFName))
	checkErr(err)
	fengineWriter := csv.NewWriter(fengineCSV)
	fengineWriter.WriteAll(records)
	fengineCSV.Close()
	return records
}

func appendAllTrials(aggregateRecords [][]string, records [][]string) [][]string {
	records = extendRecordsToTime(records, len(aggregateRecords)-1, len(records[0]))
	aggregateRecords = extendRecordsToTime(aggregateRecords, len(records)-1, len(aggregateRecords[0]))
	for r, row := range records {
		aggregateRecords[r] = append(aggregateRecords[r], row[1:]...)
	}
	return aggregateRecords
}

func appendAverages(aggregateRecords [][]string, records [][]string) [][]string {
	records = extendRecordsToTime(records, len(aggregateRecords)-1, len(records[0]))
	aggregateRecords = extendRecordsToTime(aggregateRecords, len(records)-1, len(aggregateRecords[0]))

	// To calculate averages, we first need to interpolate missing data.
	records = fillEmptyCells(records)

	colName := stripTrial(records[0][1]) + "-avg"
	aggregateRecords[0] = append(aggregateRecords[0], colName)
	for i := 1; i < len(records); i++ {
		avg := stringNumAverage(records[i][1:])
		aggregateRecords[i] = append(aggregateRecords[i], avg)
	}
	return aggregateRecords
}

// Call handleFEngine() for each fengine, then compose all fengine data into a single CSV for comparison
func handleBmark(bmark os.FileInfo, recordsPath string, finalReportFName string) {
	bmarkRecords := [][]string{{"time"}}
	bmarkAvgRecords := [][]string{{"time"}}
	bmarkPath := path.Join(recordsPath, bmark.Name())
	ls, err := ioutil.ReadDir(bmarkPath)
	checkErr(err)
	fengines := onlyDirectories(ls)

	for _, fengine := range fengines {
		fengineRecords := handleFEngine(fengine, bmarkPath, finalReportFName)
		bmarkRecords = appendAllTrials(bmarkRecords, fengineRecords)
		bmarkAvgRecords = appendAverages(bmarkAvgRecords, fengineRecords)
	}
	bmCSV, err := os.Create(path.Join(bmarkPath, finalReportFName))
	checkErr(err)
	bmWriter := csv.NewWriter(bmCSV)
	bmWriter.WriteAll(bmarkRecords)
	bmCSV.Close()
	bmAvgCSV, err := os.Create(path.Join(bmarkPath, "avg-"+finalReportFName))
	checkErr(err)
	bmWriter = csv.NewWriter(bmAvgCSV)
	bmWriter.WriteAll(bmarkAvgRecords)
	bmAvgCSV.Close()
}

// Enters all report subdirectories, from benchmark to fengine to trial;
// composes individual CSVs (only two columns) into larger CSVs
func composeAllNamed(finalReportFName string) {
	reportsPath := "./reports"
	bmarks, err := ioutil.ReadDir(reportsPath)
	checkErr(err)
	for _, bmark := range bmarks {
		handleBmark(bmark, reportsPath, finalReportFName)
	}
}

func main() {
	composeAllNamed("coverage-graph.csv")
	composeAllNamed("corpus-size-graph.csv")
	composeAllNamed("corpus-elems-graph.csv")
	// createIFramesFor("setOfFrames.html")
	//
}
<commit_msg>Compute CSVs for trial maxes.<commit_after>package main

import (
	"encoding/csv"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"strconv"
	"strings"
)

func checkErr(e error) {
	if e != nil {
		fmt.Println("Error: ", e)
		os.Exit(1)
	}
}

// Removes non-directory elements of any []os.FileInfo
func onlyDirectories(inLs []os.FileInfo) (outLs []os.FileInfo) {
	for _, fd := range inLs {
		if fd.IsDir() {
			outLs = append(outLs, fd)
		}
	}
	return
}

// Strips the "-trial-X" suffix from a column name
func stripTrial(colName string) string {
	splitStrings := strings.Split(colName, "-")
	return strings.Join(splitStrings[:len(splitStrings)-2], "-")
}

// Returns the average of a slice of numbers. Input and output are strings.
func stringNumAverage(nums []string) string {
	sum := 0
	count := 0
	for _, numStr := range nums {
		if numStr != "" {
			num, err := strconv.Atoi(numStr)
			checkErr(err)
			sum += num
			count++
		}
	}
	if count == 0 {
		return ""
	}
	return strconv.Itoa(sum / count)
}

func max(nums []int) int {
	myMax := nums[0]
	for i := 1; i < len(nums); i++ {
		if nums[i] > myMax {
			myMax = nums[i]
		}
	}
	return myMax
}

// Returns the max of a slice of numbers. Input and output are strings.
func stringNumMax(nums []string) string {
	intNums := []int{}
	for _, numStr := range nums {
		if numStr != "" {
			num, err := strconv.Atoi(numStr)
			checkErr(err)
			intNums = append(intNums, num)
		}
	}
	if len(intNums) == 0 {
		return ""
	}
	return strconv.Itoa(max(intNums))
}

// Copies previous row's data for any skipped trials.  Does not fill empty cells
// at the end of the table.
func fillEmptyCells(records [][]string) [][]string {
	// Determine where to stop filling data for each column.
	stoppingPoints := make([]int, len(records[0]))
	for row := len(records) - 1; row > 0; row-- {
		for col := 1; col < len(records[row]); col++ {
			if stoppingPoints[col] == 0 && records[row][col] != "" {
				stoppingPoints[col] = row
			}
		}
	}

	// Fill empty cells occurring before the stopping points
	finalStoppingPoint := max(stoppingPoints)
	for row := 1; row < finalStoppingPoint; row++ {
		for col := 1; col < len(records[row]); col++ {
			if row < stoppingPoints[col] && records[row][col] == "" {
				if row == 1 {
					records[row][col] = strconv.Itoa(0)
				} else {
					records[row][col] = records[row-1][col]
				}
			}
		}
	}
	return records
}

// Extend "records" matrix to have rows until time "desiredTime"
// Return: Extended version of record
func extendRecordsToTime(records [][]string, desiredTime int, recordCols int) [][]string {
	lenr := len(records)
	// records[1] stores cycle [1], as records[0] is column names
	for j := lenr; j < desiredTime+1; j++ {
		records = append(records, make([]string, recordCols))
		records[j][0] = strconv.Itoa(j)
	}
	return records
}

// Handles the CSV Reader for a single trial, and updates records[][] accordingly. Returns the updated records
func handleTrialCSV(trialReader *csv.Reader, records [][]string, colName string, totalCols int, trialNum int) [][]string {
	// Read whole CSV to an array
	trialRecords, err := trialReader.ReadAll()
	checkErr(err)
	// Add the name of this new column to records[0]
	records[0] = append(records[0], colName)

	finalTime, err := strconv.Atoi(trialRecords[len(trialRecords)-1][0])
	checkErr(err)
	//If this test went longer than all of the others, so far
	if len(records) < finalTime+1 {
		records = extendRecordsToTime(records, finalTime, totalCols)
	}
	for _, row := range trialRecords {
		// row[0] is time, on the x-axis; row[1] is value, on the y-axis
		time, err := strconv.Atoi(row[0])
		checkErr(err)
		records[time][trialNum+1] = row[1]
	}
	return records
}

func handleFEngine(fengine os.FileInfo, bmarkPath string, finalReportFName string) [][]string {
	// Create matrix, to eventually become a CSV
	records := [][]string{{"time"}}

	// Enter sub-directories
	fenginePath := path.Join(bmarkPath, fengine.Name())
	ls, err := ioutil.ReadDir(fenginePath)
	checkErr(err)
	trials := onlyDirectories(ls)

	totalCols := len(trials) + 1
	for j, trial := range trials {
		// Create fds
		trialCSV, err := os.Open(path.Join(fenginePath, trial.Name(), finalReportFName))
		checkErr(err)
		trialReader := csv.NewReader(trialCSV)

		records = handleTrialCSV(trialReader, records, fengine.Name()+"-"+trial.Name(), totalCols, j)
		trialCSV.Close()
	}

	fengineCSV, err := os.Create(path.Join(fenginePath, finalReportFName))
	checkErr(err)
	fengineWriter := csv.NewWriter(fengineCSV)
	fengineWriter.WriteAll(records)
	fengineCSV.Close()
	return records
}

func appendAllTrials(aggregateRecords [][]string, records [][]string) [][]string {
	records = extendRecordsToTime(records, len(aggregateRecords)-1, len(records[0]))
	aggregateRecords = extendRecordsToTime(aggregateRecords, len(records)-1, len(aggregateRecords[0]))
	for r, row := range records {
		aggregateRecords[r] = append(aggregateRecords[r], row[1:]...)
	}
	return aggregateRecords
}

func appendAverages(aggregateRecords [][]string, records [][]string) [][]string {
	records = extendRecordsToTime(records, len(aggregateRecords)-1, len(records[0]))
	aggregateRecords = extendRecordsToTime(aggregateRecords, len(records)-1, len(aggregateRecords[0]))

	// To calculate averages, we first need to interpolate missing data.
	records = fillEmptyCells(records)

	colName := stripTrial(records[0][1]) + "-avg"
	aggregateRecords[0] = append(aggregateRecords[0], colName)
	for i := 1; i < len(records); i++ {
		avg := stringNumAverage(records[i][1:])
		aggregateRecords[i] = append(aggregateRecords[i], avg)
	}
	return aggregateRecords
}

func appendMaxes(aggregateRecords [][]string, records [][]string) [][]string {
	records = extendRecordsToTime(records, len(aggregateRecords)-1, len(records[0]))
	aggregateRecords = extendRecordsToTime(aggregateRecords, len(records)-1, len(aggregateRecords[0]))

	// To calculate maxes, we first need to interpolate missing data.
	records = fillEmptyCells(records)

	colName := stripTrial(records[0][1]) + "-max"
	aggregateRecords[0] = append(aggregateRecords[0], colName)
	for i := 1; i < len(records); i++ {
		max := stringNumMax(records[i][1:])
		aggregateRecords[i] = append(aggregateRecords[i], max)
	}
	return aggregateRecords
}

// Call handleFEngine() for each fengine, then compose all fengine data into a single CSV for comparison
func handleBmark(bmark os.FileInfo, recordsPath string, finalReportFName string) {
	bmarkRecords := [][]string{{"time"}}
	bmarkAvgRecords := [][]string{{"time"}}
	bmarkMaxRecords := [][]string{{"time"}}
	bmarkPath := path.Join(recordsPath, bmark.Name())
	ls, err := ioutil.ReadDir(bmarkPath)
	checkErr(err)
	fengines := onlyDirectories(ls)

	for _, fengine := range fengines {
		fengineRecords := handleFEngine(fengine, bmarkPath, finalReportFName)
		bmarkRecords = appendAllTrials(bmarkRecords, fengineRecords)
		bmarkAvgRecords = appendAverages(bmarkAvgRecords, fengineRecords)
		bmarkMaxRecords = appendMaxes(bmarkMaxRecords, fengineRecords)
	}
	bmCSV, err := os.Create(path.Join(bmarkPath, finalReportFName))
	checkErr(err)
	bmWriter := csv.NewWriter(bmCSV)
	bmWriter.WriteAll(bmarkRecords)
	bmCSV.Close()
	bmAvgCSV, err := os.Create(path.Join(bmarkPath, "avg-"+finalReportFName))
	checkErr(err)
	bmWriter = csv.NewWriter(bmAvgCSV)
	bmWriter.WriteAll(bmarkAvgRecords)
	bmAvgCSV.Close()
	bmMaxCSV, err := os.Create(path.Join(bmarkPath, "max-"+finalReportFName))
	checkErr(err)
	bmWriter = csv.NewWriter(bmMaxCSV)
	bmWriter.WriteAll(bmarkMaxRecords)
	bmMaxCSV.Close()
}

// Enters all report subdirectories, from benchmark to fengine to trial;
// composes individual CSVs (only two columns) into larger CSVs
func composeAllNamed(finalReportFName string) {
	reportsPath := "./reports"
	bmarks, err := ioutil.ReadDir(reportsPath)
	checkErr(err)
	for _, bmark := range bmarks {
		handleBmark(bmark, reportsPath, finalReportFName)
	}
}

func main() {
	composeAllNamed("coverage-graph.csv")
	composeAllNamed("corpus-size-graph.csv")
	composeAllNamed("corpus-elems-graph.csv")
	// createIFramesFor("setOfFrames.html")
	//
}
<|endoftext|>


<commit_before>package repository

import (
	"archive/tar"
	"crypto"
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"io"
	"log"
	"os"
)

// Repository is an encrypted bunch of stuff
type Repository struct {
	AesKey     []byte
	publicKey  *rsa.PublicKey
	privateKey *rsa.PrivateKey
	iv         []byte
	signature  []byte
}

// ReadRepository is a repository opened for reading
type ReadRepository struct {
	Repository
	tarReader    *tar.Reader
	cryptoReader *cipher.StreamReader
}

// WriteRepository is a repository opened for writing
type WriteRepository struct {
	Repository
	tarWriter    *tar.Writer
	cryptoWriter *cipher.StreamWriter
}

func (r *Repository) keylength() int {
	if r.publicKey != nil {
		return len(r.publicKey.N.Bytes())
	}

	if r.privateKey != nil {
		return len(r.privateKey.N.Bytes())
	}

	return 0
}

func (r *WriteRepository) writeHeader(repoFile io.Writer) error {
	keyBytes := make([]byte, r.keylength()/2)
	copy(keyBytes[0:32], r.AesKey)
	copy(keyBytes[32:48], r.iv)

	var err error

	log.Printf("%d bytes", len(r.publicKey.N.Bytes()))
	encryptedHeader, err := rsa.EncryptPKCS1v15(rand.Reader, r.publicKey, keyBytes)
	if err != nil {
		log.Printf("Repository#writeHeader - Failed to encrypt header: %v", err)
		return err
	}

	_, err = repoFile.Write(encryptedHeader)
	if err != nil {
		log.Printf("Repository#writeHeader - Failed to write encrypted header: %v", err)
		return err
	}

	return nil
}

func (r *WriteRepository) writeSignature(repoFile io.Writer) error {
	key := make([]byte, len(r.AesKey)+len(r.iv))
	copy(key[0:len(r.AesKey)], r.AesKey)
	copy(key[len(r.AesKey):], r.iv)

	var err error
	hash := sha256.Sum256(key)
	r.signature, err = rsa.SignPKCS1v15(rand.Reader, r.privateKey, crypto.SHA256, hash[:])
	if err != nil {
		log.Printf("Repository#writeHeader - Failed to sign header: %v", err)
		return err
	}

	_, err = repoFile.Write(r.signature)
	if err != nil {
		log.Printf("Repository#writeSignature - failed to write signature: %v", err)
		return err
	}

	return nil
}

// CreateRepository creates a new repository with the given filename
//
// AesKey contains the random AES encryption key
// RepoFile points to the open file
func CreateRepository(key *rsa.PublicKey, privateKey *rsa.PrivateKey, repoFile io.Writer) (*WriteRepository, error) {
	result := &WriteRepository{}
	result.publicKey = key
	result.privateKey = privateKey

	result.AesKey = make([]byte, 32)
	_, err := rand.Read(result.AesKey)
	if err != nil {
		log.Printf("Repository#CreateRepository - Unable to read random data while creating: %v", err)
		return nil, err
	}

	result.iv = make([]byte, 16)
	_, err = rand.Read(result.iv)
	if err != nil {
		log.Printf("Repository#CreateRepository - Unable to generate new initializtion vector: %v", err)
		return nil, err
	}

	block, err := aes.NewCipher(result.AesKey)
	if err != nil {
		log.Printf("Repository#CreateRepository - Unable to create a new cipher block: %v", err)
		return nil, err
	}

	if err = result.writeHeader(repoFile); err != nil {
		log.Printf("Repository#CreateRepository - Unable to create header: %v", err)
		return nil, err
	}

	if err = result.writeSignature(repoFile); err != nil {
		log.Printf("Repository#CreateRepository - Unable to write signature: %v", err)
	}

	stream := cipher.NewCTR(block, result.iv)
	result.cryptoWriter = &cipher.StreamWriter{
		S: stream,
		W: repoFile,
	}

	result.tarWriter = tar.NewWriter(result.cryptoWriter)

	return result, nil
}

func (r *ReadRepository) readHeader(repoFile io.Reader) error {
	encryptedHeader := make([]byte, r.keylength())
	if _, err := repoFile.Read(encryptedHeader); err != nil {
		log.Printf("Repository#readHeader - Unable to read header out of file: %v", err)
		return err
	}

	header, err := rsa.DecryptPKCS1v15(rand.Reader, r.privateKey, encryptedHeader)
	if err != nil {
		log.Printf("Repository#readHeader - Failed to decrypt header: %v", err)
		return err
	}

	r.AesKey = header[0:32]
	r.iv = header[32:48]

	return nil
}

func (r *ReadRepository) verifySignature(repoFile io.Reader) error {
	signature := make([]byte, r.keylength())
	if _, err := repoFile.Read(signature); err != nil {
		log.Printf("Repository#verifySignature - Unable to read signature block")
		return err
	}

	header := make([]byte, r.keylength())
	copy(header[0:32], r.AesKey)
	copy(header[32:], r.iv)

	sha := sha256.Sum256(header[0:48])
	err := rsa.VerifyPKCS1v15(r.publicKey, crypto.SHA256, sha[:], signature)
	if err != nil {
		log.Printf("Respository#readHeader - Failed to verify signature: %v", err)
		return err
	}

	r.signature = signature

	return nil
}

// OpenRepository opens a repository for reading
func OpenRepository(privateKey *rsa.PrivateKey, publicKey *rsa.PublicKey, repoFile io.Reader) (*ReadRepository, error) {
	result := &ReadRepository{}
	result.privateKey = privateKey
	result.publicKey = publicKey
	var err error

	if err = result.readHeader(repoFile); err != nil {
		log.Printf("Repository#OpenRepository - Failed to read the header for: %v", err)
		return nil, err
	}

	block, err := aes.NewCipher(result.AesKey)
	if err != nil {
		log.Printf("Repository#OpenRepository - Failed to create new block cipher for: %v", err)
		return nil, err
	}

	stream := cipher.NewCTR(block, result.iv)
	result.cryptoReader = &cipher.StreamReader{
		S: stream,
		R: repoFile,
	}

	result.tarReader = tar.NewReader(result.cryptoReader)
	return result, nil
}

// AddFile adds data from a file
func (r *WriteRepository) AddFile(filePath string) error {
	fileInfo, err := os.Stat(filePath)
	if err != nil {
		log.Printf("Repository#AddFile - Unable to stat file %s: %v", filePath, err)
		return err
	}

	header, err := tar.FileInfoHeader(fileInfo, filePath)
	if err != nil {
		log.Printf("Repository#AddFile - Unable create new info header for file %s: %v", filePath, err)
		return err
	}

	err = r.tarWriter.WriteHeader(header)
	if err != nil {
		log.Printf("Repository#AddFile - Unable to write header into file %s: %v", filePath, err)
		return err
	}

	infile, err := os.Open(filePath)
	if err != nil {
		log.Printf("Repository#AddFile - Unable to open input file %s: %v", filePath, err)
		return err
	}
	defer infile.Close()

	_, err = io.Copy(r.tarWriter, infile)
	if err != nil {
		log.Printf("Repository#AddFile - Failed to copy data from input file to tar writer %s: %v", filePath, err)
		return err
	}

	return nil
}

// ExtractFile extracts a file from the repository
func (r *ReadRepository) ExtractFile() error {
	header, err := r.tarReader.Next()
	if err == io.EOF {
		return err
	}
	if err != nil {
		log.Printf("Repository#ExtractFile - Failed to extract file from repository: %v", err)
		return err
	}

	file, err := os.OpenFile(header.Name, os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		log.Printf("Repository#ExtractFile - Failed to open file %s for writing: %v", header.Name, err)
		return err
	}

	_, err = io.Copy(file, r.tarReader)
	if err != nil {
		log.Printf("Repository#ExtractFile - Failed to extract data for file %s: %v", header.Name, err)
		return err
	}

	return nil
}

// Seal completes writing the data and closes the repository
func (r *WriteRepository) Seal() error {
	if err := r.tarWriter.Flush(); err != nil {
		log.Printf("Repository#Seal - Failed to flush the tar writer.")
	}

	return nil
}
<commit_msg>Rearranging file contents<commit_after>package repository

import (
	"archive/tar"
	"crypto"
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"io"
	"log"
	"os"
)

// Repository is an encrypted bunch of stuff
type Repository struct {
	AesKey     []byte
	publicKey  *rsa.PublicKey
	privateKey *rsa.PrivateKey
	iv         []byte
	signature  []byte
}

// ReadRepository is a repository opened for reading
type ReadRepository struct {
	Repository
	tarReader    *tar.Reader
	cryptoReader *cipher.StreamReader
}

// WriteRepository is a repository opened for writing
type WriteRepository struct {
	Repository
	tarWriter    *tar.Writer
	cryptoWriter *cipher.StreamWriter
}

func (r *Repository) keylength() int {
	if r.publicKey != nil {
		return len(r.publicKey.N.Bytes())
	}

	if r.privateKey != nil {
		return len(r.privateKey.N.Bytes())
	}

	return 0
}

func (r *WriteRepository) writeHeader(repoFile io.Writer) error {
	keyBytes := make([]byte, r.keylength()/2)
	copy(keyBytes[0:32], r.AesKey)
	copy(keyBytes[32:48], r.iv)

	var err error

	log.Printf("%d bytes", len(r.publicKey.N.Bytes()))
	encryptedHeader, err := rsa.EncryptPKCS1v15(rand.Reader, r.publicKey, keyBytes)
	if err != nil {
		log.Printf("Repository#writeHeader - Failed to encrypt header: %v", err)
		return err
	}

	_, err = repoFile.Write(encryptedHeader)
	if err != nil {
		log.Printf("Repository#writeHeader - Failed to write encrypted header: %v", err)
		return err
	}

	return nil
}

func (r *WriteRepository) writeSignature(repoFile io.Writer) error {
	key := make([]byte, len(r.AesKey)+len(r.iv))
	copy(key[0:len(r.AesKey)], r.AesKey)
	copy(key[len(r.AesKey):], r.iv)

	var err error
	hash := sha256.Sum256(key)
	r.signature, err = rsa.SignPKCS1v15(rand.Reader, r.privateKey, crypto.SHA256, hash[:])
	if err != nil {
		log.Printf("Repository#writeHeader - Failed to sign header: %v", err)
		return err
	}

	_, err = repoFile.Write(r.signature)
	if err != nil {
		log.Printf("Repository#writeSignature - failed to write signature: %v", err)
		return err
	}

	return nil
}

// Seal completes writing the data and closes the repository
func (r *WriteRepository) Seal() error {
	if err := r.tarWriter.Flush(); err != nil {
		log.Printf("Repository#Seal - Failed to flush the tar writer.")
	}

	return nil
}

// AddFile adds data from a file
func (r *WriteRepository) AddFile(filePath string) error {
	fileInfo, err := os.Stat(filePath)
	if err != nil {
		log.Printf("Repository#AddFile - Unable to stat file %s: %v", filePath, err)
		return err
	}

	header, err := tar.FileInfoHeader(fileInfo, filePath)
	if err != nil {
		log.Printf("Repository#AddFile - Unable create new info header for file %s: %v", filePath, err)
		return err
	}

	err = r.tarWriter.WriteHeader(header)
	if err != nil {
		log.Printf("Repository#AddFile - Unable to write header into file %s: %v", filePath, err)
		return err
	}

	infile, err := os.Open(filePath)
	if err != nil {
		log.Printf("Repository#AddFile - Unable to open input file %s: %v", filePath, err)
		return err
	}
	defer infile.Close()

	_, err = io.Copy(r.tarWriter, infile)
	if err != nil {
		log.Printf("Repository#AddFile - Failed to copy data from input file to tar writer %s: %v", filePath, err)
		return err
	}

	return nil
}

// CreateRepository creates a new repository with the given filename
//
// AesKey contains the random AES encryption key
// RepoFile points to the open file
func CreateRepository(key *rsa.PublicKey, privateKey *rsa.PrivateKey, repoFile io.Writer) (*WriteRepository, error) {
	result := &WriteRepository{}
	result.publicKey = key
	result.privateKey = privateKey

	result.AesKey = make([]byte, 32)
	_, err := rand.Read(result.AesKey)
	if err != nil {
		log.Printf("Repository#CreateRepository - Unable to read random data while creating: %v", err)
		return nil, err
	}

	result.iv = make([]byte, 16)
	_, err = rand.Read(result.iv)
	if err != nil {
		log.Printf("Repository#CreateRepository - Unable to generate new initializtion vector: %v", err)
		return nil, err
	}

	block, err := aes.NewCipher(result.AesKey)
	if err != nil {
		log.Printf("Repository#CreateRepository - Unable to create a new cipher block: %v", err)
		return nil, err
	}

	if err = result.writeHeader(repoFile); err != nil {
		log.Printf("Repository#CreateRepository - Unable to create header: %v", err)
		return nil, err
	}

	if err = result.writeSignature(repoFile); err != nil {
		log.Printf("Repository#CreateRepository - Unable to write signature: %v", err)
	}

	stream := cipher.NewCTR(block, result.iv)
	result.cryptoWriter = &cipher.StreamWriter{
		S: stream,
		W: repoFile,
	}

	result.tarWriter = tar.NewWriter(result.cryptoWriter)

	return result, nil
}

func (r *ReadRepository) readHeader(repoFile io.Reader) error {
	encryptedHeader := make([]byte, r.keylength())
	if _, err := repoFile.Read(encryptedHeader); err != nil {
		log.Printf("Repository#readHeader - Unable to read header out of file: %v", err)
		return err
	}

	header, err := rsa.DecryptPKCS1v15(rand.Reader, r.privateKey, encryptedHeader)
	if err != nil {
		log.Printf("Repository#readHeader - Failed to decrypt header: %v", err)
		return err
	}

	r.AesKey = header[0:32]
	r.iv = header[32:48]

	return nil
}

func (r *ReadRepository) verifySignature(repoFile io.Reader) error {
	signature := make([]byte, r.keylength())
	if _, err := repoFile.Read(signature); err != nil {
		log.Printf("Repository#verifySignature - Unable to read signature block")
		return err
	}

	header := make([]byte, r.keylength())
	copy(header[0:32], r.AesKey)
	copy(header[32:], r.iv)

	sha := sha256.Sum256(header[0:48])
	err := rsa.VerifyPKCS1v15(r.publicKey, crypto.SHA256, sha[:], signature)
	if err != nil {
		log.Printf("Respository#readHeader - Failed to verify signature: %v", err)
		return err
	}

	r.signature = signature

	return nil
}

// ExtractFile extracts a file from the repository
func (r *ReadRepository) ExtractFile() error {
	header, err := r.tarReader.Next()
	if err == io.EOF {
		return err
	}
	if err != nil {
		log.Printf("Repository#ExtractFile - Failed to extract file from repository: %v", err)
		return err
	}

	file, err := os.OpenFile(header.Name, os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		log.Printf("Repository#ExtractFile - Failed to open file %s for writing: %v", header.Name, err)
		return err
	}

	_, err = io.Copy(file, r.tarReader)
	if err != nil {
		log.Printf("Repository#ExtractFile - Failed to extract data for file %s: %v", header.Name, err)
		return err
	}

	return nil
}

// OpenRepository opens a repository for reading
func OpenRepository(privateKey *rsa.PrivateKey, publicKey *rsa.PublicKey, repoFile io.Reader) (*ReadRepository, error) {
	result := &ReadRepository{}
	result.privateKey = privateKey
	result.publicKey = publicKey
	var err error

	if err = result.readHeader(repoFile); err != nil {
		log.Printf("Repository#OpenRepository - Failed to read the header for: %v", err)
		return nil, err
	}

	block, err := aes.NewCipher(result.AesKey)
	if err != nil {
		log.Printf("Repository#OpenRepository - Failed to create new block cipher for: %v", err)
		return nil, err
	}

	stream := cipher.NewCTR(block, result.iv)
	result.cryptoReader = &cipher.StreamReader{
		S: stream,
		R: repoFile,
	}

	result.tarReader = tar.NewReader(result.cryptoReader)
	return result, nil
}
<|endoftext|>


<commit_before><commit_msg>+ p17<commit_after><|endoftext|>


<commit_before>// Copyright 2015 Matthew Collins
//
// 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 steven

import (
	"fmt"
	"io/ioutil"
	"math"
	"math/rand"
	"strings"

	realjson "encoding/json"

	"github.com/thinkofdeath/steven/console"
	"github.com/thinkofdeath/steven/encoding/json"

	"github.com/thinkofdeath/steven/render"
	"github.com/thinkofdeath/steven/resource"
	"github.com/thinkofdeath/steven/type/direction"
)

var (
	blockStateModels = map[pluginKey]*blockStateModel{}
)

type blockStateModel struct {
	variants map[string]blockVariants
}

type blockVariants []*processedModel

func findStateModel(plugin, name string) *blockStateModel {
	key := pluginKey{plugin, name}
	if bs, ok := blockStateModels[key]; ok {
		return bs
	}
	bs := loadStateModel(key)

	if bs == nil {
		blockStateModels[key] = nil
		return nil
	}

	blockStateModels[key] = bs
	return bs
}

func loadStateModel(key pluginKey) *blockStateModel {
	type jsType struct {
		Variants map[string]realjson.RawMessage
	}

	var data jsType
	err := loadJSON(key.Plugin, fmt.Sprintf("blockstates/%s.json", key.Name), &data)
	if err != nil {
		console.Text("Error loading state %s: %s", key.Name, err)
		return nil
	}
	bs := &blockStateModel{
		variants: map[string]blockVariants{},
	}
	variants := data.Variants
	for k, v := range variants {
		var models blockVariants
		switch v[0] {
		case '[':
			var list []realjson.RawMessage
			json.Unmarshal(v, &list)
			for _, vv := range list {
				mdl := parseBlockStateVariant(key.Plugin, vv)
				if mdl != nil {
					models = append(models, precomputeModel(mdl))
				}
			}
		default:
			mdl := parseBlockStateVariant(key.Plugin, v)
			if mdl != nil {
				models = append(models, precomputeModel(mdl))
			}
		}
		bs.variants[k] = models
	}
	return bs
}

func (bs *blockStateModel) variant(key string) blockVariants {
	return bs.variants[key]
}

func (bv blockVariants) selectModel(r *rand.Rand) *processedModel {
	totalW := 0
	for _, m := range bv {
		totalW += m.weight
	}
	i := r.Intn(totalW)
	offset := 0
	for _, m := range bv {
		if i <= offset+m.weight {
			return m
		}
		offset += m.weight
	}
	panic("should not be reached")
}

type builtInType int

const (
	builtInFalse = iota
	builtInGenerated
	builtInEntity
	builtInCompass
	builtInClock
)

type model struct {
	textureVars      map[string]string
	elements         []*modelElement
	ambientOcclusion bool
	aoSet            bool
	weight           int

	uvLock bool
	y, x   float64

	// Item specific features
	display map[string]modelDisplay
	builtIn builtInType
}

type modelDisplay struct {
	Rotation    *[3]float64
	Translation *[3]float64
	Scale       *[3]float64
}

func parseBlockStateVariant(plugin string, js realjson.RawMessage) *model {
	type jsType struct {
		Model  string
		X, Y   float64
		UVLock bool
		Weight *int
	}
	var data jsType
	err := json.Unmarshal(js, &data)
	if err != nil {
		console.Text("%s", err)
		return nil
	}
	var bdata jsModel
	err = loadJSON(plugin, "models/block/"+data.Model+".json", &bdata)
	if err != nil {
		return nil
	}
	bm := parseModel(plugin, &bdata)

	bm.y = data.Y
	bm.x = data.X
	bm.uvLock = data.UVLock
	if data.Weight != nil {
		bm.weight = *data.Weight
	} else {
		bm.weight = 1
	}
	return bm
}

type jsModel struct {
	Parent           string
	Textures         map[string]string
	AmbientOcclusion *bool
	Elements         []*jsBlockElement
	Display          map[string]modelDisplay
}

func parseModel(plugin string, data *jsModel) *model {
	var bm *model
	if data.Parent != "" && !strings.HasPrefix(data.Parent, "builtin/") {
		var pdata jsModel
		err := loadJSON(plugin, "models/"+data.Parent+".json", &pdata)
		if err != nil {
			console.Text("Error loading model %s: %s", data.Parent, err)
			return nil
		}
		bm = parseModel(plugin, &pdata)
	} else {
		bm = &model{
			textureVars: map[string]string{},
			display:     map[string]modelDisplay{},
		}
		if strings.HasPrefix(data.Parent, "builtin/") {
			switch data.Parent {
			case "builtin/generated":
				bm.builtIn = builtInGenerated
			case "builtin/entity":
				bm.builtIn = builtInEntity
			case "builtin/compass":
				bm.builtIn = builtInCompass
			case "builtin/clock":
				bm.builtIn = builtInClock
			}
		}
	}

	if data.Textures != nil {
		for k, v := range data.Textures {
			bm.textureVars[k] = v
		}
	}

	for _, e := range data.Elements {
		bm.elements = append(bm.elements, parseBlockElement(e))
	}

	if data.AmbientOcclusion != nil {
		bm.ambientOcclusion = *data.AmbientOcclusion
		bm.aoSet = true
	} else if !bm.aoSet {
		bm.ambientOcclusion = true
	}

	if data.Display != nil {
		for k, v := range data.Display {
			bm.display[k] = v
		}
	}

	return bm
}

type modelElement struct {
	from, to [3]float64
	shade    bool
	rotation *blockRotation

	faces [6]*blockFace
}

type blockRotation struct {
	origin  []float64
	axis    string
	angle   float64
	rescale bool
}

type blockFace struct {
	uv          [4]float64
	texture     string
	textureInfo *render.TextureInfo
	cullFace    direction.Type
	rotation    int
	tintIndex   int
}

type jsBlockElement struct {
	From, To [3]float64
	Shade    *bool
	Faces    map[string]*jsBlockFace
	Rotation *struct {
		Origin  *[3]float64
		Axis    string
		Angle   float64
		Rescale bool
	}
}

func parseBlockElement(data *jsBlockElement) *modelElement {
	be := &modelElement{}
	be.from, be.to = data.From, data.To

	be.shade = data.Shade == nil || *data.Shade

	if data.Faces != nil {
		for i, d := range direction.Values {
			if data, ok := data.Faces[d.String()]; ok {
				be.faces[i] = &blockFace{}
				be.faces[i].init(data)
				if math.IsNaN(be.faces[i].uv[0]) {
					be.faces[i].uv = [4]float64{0, 0, 16, 16}
					switch d {
					case direction.North, direction.South:
						be.faces[i].uv[0] = be.from[0]
						be.faces[i].uv[2] = be.to[0]
						be.faces[i].uv[1] = 16 - be.to[1]
						be.faces[i].uv[3] = 16 - be.from[1]
					case direction.West, direction.East:
						be.faces[i].uv[0] = be.from[2]
						be.faces[i].uv[2] = be.to[2]
						be.faces[i].uv[1] = 16 - be.to[1]
						be.faces[i].uv[3] = 16 - be.from[1]
					case direction.Down, direction.Up:
						be.faces[i].uv[0] = be.from[0]
						be.faces[i].uv[2] = be.to[0]
						be.faces[i].uv[1] = 16 - be.to[2]
						be.faces[i].uv[3] = 16 - be.from[2]
					}
				}
			}
		}
	}

	if data.Rotation != nil {
		r := &blockRotation{}
		be.rotation = r
		rot := data.Rotation

		r.origin = []float64{8, 8, 8}
		if rot.Origin != nil {
			r.origin = rot.Origin[:]
		}
		r.axis = rot.Axis
		r.angle = rot.Angle
		r.rescale = rot.Rescale
	}

	return be
}

type jsBlockFace struct {
	UV        *[4]float64
	Texture   string
	CullFace  string
	Rotation  int
	TintIndex *int
}

func (bf *blockFace) init(data *jsBlockFace) {
	if data.UV != nil {
		bf.uv = *data.UV
	} else {
		bf.uv = [4]float64{math.NaN(), 0, 0, 0}
	}
	bf.texture = data.Texture
	bf.cullFace = direction.FromString(data.CullFace)
	bf.rotation = data.Rotation
	bf.tintIndex = -1
	if data.TintIndex != nil {
		bf.tintIndex = *data.TintIndex
	}
}

func (bm *model) lookupTexture(name string) render.TextureInfo {
	if len(name) > 0 && name[0] == '#' {
		return bm.lookupTexture(bm.textureVars[name[1:]])
	}
	return render.GetTexture(name)
}

func loadJSON(plugin, name string, target interface{}) error {
	r, err := resource.Open(plugin, name)
	if err != nil {
		return err
	}
	defer r.Close()
	err = realjson.NewDecoder(r).Decode(target)
	if err != nil {
		// Take the slow path through our preprocessor.
		// Hopefully this can be removed in later minecraft versions.d, err := ioutil.ReadAll(r)
		r.Close()
		r, err = resource.Open(plugin, name)
		if err != nil {
			return err
		}

		d, err := ioutil.ReadAll(r)
		if err != nil {
			return err
		}
		return json.Unmarshal(d, target)
	}
	return err
}
<commit_msg>steven: don't crash on missing models<commit_after>// Copyright 2015 Matthew Collins
//
// 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 steven

import (
	"fmt"
	"io/ioutil"
	"math"
	"math/rand"
	"strings"

	realjson "encoding/json"

	"github.com/thinkofdeath/steven/console"
	"github.com/thinkofdeath/steven/encoding/json"

	"github.com/thinkofdeath/steven/render"
	"github.com/thinkofdeath/steven/resource"
	"github.com/thinkofdeath/steven/type/direction"
)

var (
	blockStateModels = map[pluginKey]*blockStateModel{}
)

type blockStateModel struct {
	variants map[string]blockVariants
}

type blockVariants []*processedModel

func findStateModel(plugin, name string) *blockStateModel {
	key := pluginKey{plugin, name}
	if bs, ok := blockStateModels[key]; ok {
		return bs
	}
	bs := loadStateModel(key)

	if bs == nil {
		blockStateModels[key] = nil
		return nil
	}

	blockStateModels[key] = bs
	return bs
}

func loadStateModel(key pluginKey) *blockStateModel {
	type jsType struct {
		Variants map[string]realjson.RawMessage
	}

	var data jsType
	err := loadJSON(key.Plugin, fmt.Sprintf("blockstates/%s.json", key.Name), &data)
	if err != nil {
		console.Text("Error loading state %s: %s", key.Name, err)
		return nil
	}
	bs := &blockStateModel{
		variants: map[string]blockVariants{},
	}
	variants := data.Variants
	for k, v := range variants {
		var models blockVariants
		switch v[0] {
		case '[':
			var list []realjson.RawMessage
			json.Unmarshal(v, &list)
			for _, vv := range list {
				mdl := parseBlockStateVariant(key.Plugin, vv)
				if mdl != nil {
					models = append(models, precomputeModel(mdl))
				}
			}
		default:
			mdl := parseBlockStateVariant(key.Plugin, v)
			if mdl != nil {
				models = append(models, precomputeModel(mdl))
			}
		}
		bs.variants[k] = models
	}
	return bs
}

func (bs *blockStateModel) variant(key string) blockVariants {
	return bs.variants[key]
}

func (bv blockVariants) selectModel(r *rand.Rand) *processedModel {
	totalW := 0
	for _, m := range bv {
		totalW += m.weight
	}
	i := r.Intn(totalW)
	offset := 0
	for _, m := range bv {
		if i <= offset+m.weight {
			return m
		}
		offset += m.weight
	}
	panic("should not be reached")
}

type builtInType int

const (
	builtInFalse = iota
	builtInGenerated
	builtInEntity
	builtInCompass
	builtInClock
)

type model struct {
	textureVars      map[string]string
	elements         []*modelElement
	ambientOcclusion bool
	aoSet            bool
	weight           int

	uvLock bool
	y, x   float64

	// Item specific features
	display map[string]modelDisplay
	builtIn builtInType
}

type modelDisplay struct {
	Rotation    *[3]float64
	Translation *[3]float64
	Scale       *[3]float64
}

func parseBlockStateVariant(plugin string, js realjson.RawMessage) *model {
	type jsType struct {
		Model  string
		X, Y   float64
		UVLock bool
		Weight *int
	}
	var data jsType
	err := json.Unmarshal(js, &data)
	if err != nil {
		console.Text("%s", err)
		return nil
	}
	var bdata jsModel
	err = loadJSON(plugin, "models/block/"+data.Model+".json", &bdata)
	if err != nil {
		return nil
	}
	bm := parseModel(plugin, &bdata)

	bm.y = data.Y
	bm.x = data.X
	bm.uvLock = data.UVLock
	if data.Weight != nil {
		bm.weight = *data.Weight
	} else {
		bm.weight = 1
	}
	return bm
}

type jsModel struct {
	Parent           string
	Textures         map[string]string
	AmbientOcclusion *bool
	Elements         []*jsBlockElement
	Display          map[string]modelDisplay
}

func parseModel(plugin string, data *jsModel) *model {
	var bm *model
	if data.Parent != "" && !strings.HasPrefix(data.Parent, "builtin/") {
		var pdata jsModel
		err := loadJSON(plugin, "models/"+data.Parent+".json", &pdata)
		if err != nil {
			console.Text("Error loading model %s: %s", data.Parent, err)
			loadJSON("steven", "models/block/missing_block.json", &pdata)
		}
		bm = parseModel(plugin, &pdata)
	} else {
		bm = &model{
			textureVars: map[string]string{},
			display:     map[string]modelDisplay{},
		}
		if strings.HasPrefix(data.Parent, "builtin/") {
			switch data.Parent {
			case "builtin/generated":
				bm.builtIn = builtInGenerated
			case "builtin/entity":
				bm.builtIn = builtInEntity
			case "builtin/compass":
				bm.builtIn = builtInCompass
			case "builtin/clock":
				bm.builtIn = builtInClock
			}
		}
	}

	if data.Textures != nil {
		for k, v := range data.Textures {
			bm.textureVars[k] = v
		}
	}

	for _, e := range data.Elements {
		bm.elements = append(bm.elements, parseBlockElement(e))
	}

	if data.AmbientOcclusion != nil {
		bm.ambientOcclusion = *data.AmbientOcclusion
		bm.aoSet = true
	} else if !bm.aoSet {
		bm.ambientOcclusion = true
	}

	if data.Display != nil {
		for k, v := range data.Display {
			bm.display[k] = v
		}
	}

	return bm
}

type modelElement struct {
	from, to [3]float64
	shade    bool
	rotation *blockRotation

	faces [6]*blockFace
}

type blockRotation struct {
	origin  []float64
	axis    string
	angle   float64
	rescale bool
}

type blockFace struct {
	uv          [4]float64
	texture     string
	textureInfo *render.TextureInfo
	cullFace    direction.Type
	rotation    int
	tintIndex   int
}

type jsBlockElement struct {
	From, To [3]float64
	Shade    *bool
	Faces    map[string]*jsBlockFace
	Rotation *struct {
		Origin  *[3]float64
		Axis    string
		Angle   float64
		Rescale bool
	}
}

func parseBlockElement(data *jsBlockElement) *modelElement {
	be := &modelElement{}
	be.from, be.to = data.From, data.To

	be.shade = data.Shade == nil || *data.Shade

	if data.Faces != nil {
		for i, d := range direction.Values {
			if data, ok := data.Faces[d.String()]; ok {
				be.faces[i] = &blockFace{}
				be.faces[i].init(data)
				if math.IsNaN(be.faces[i].uv[0]) {
					be.faces[i].uv = [4]float64{0, 0, 16, 16}
					switch d {
					case direction.North, direction.South:
						be.faces[i].uv[0] = be.from[0]
						be.faces[i].uv[2] = be.to[0]
						be.faces[i].uv[1] = 16 - be.to[1]
						be.faces[i].uv[3] = 16 - be.from[1]
					case direction.West, direction.East:
						be.faces[i].uv[0] = be.from[2]
						be.faces[i].uv[2] = be.to[2]
						be.faces[i].uv[1] = 16 - be.to[1]
						be.faces[i].uv[3] = 16 - be.from[1]
					case direction.Down, direction.Up:
						be.faces[i].uv[0] = be.from[0]
						be.faces[i].uv[2] = be.to[0]
						be.faces[i].uv[1] = 16 - be.to[2]
						be.faces[i].uv[3] = 16 - be.from[2]
					}
				}
			}
		}
	}

	if data.Rotation != nil {
		r := &blockRotation{}
		be.rotation = r
		rot := data.Rotation

		r.origin = []float64{8, 8, 8}
		if rot.Origin != nil {
			r.origin = rot.Origin[:]
		}
		r.axis = rot.Axis
		r.angle = rot.Angle
		r.rescale = rot.Rescale
	}

	return be
}

type jsBlockFace struct {
	UV        *[4]float64
	Texture   string
	CullFace  string
	Rotation  int
	TintIndex *int
}

func (bf *blockFace) init(data *jsBlockFace) {
	if data.UV != nil {
		bf.uv = *data.UV
	} else {
		bf.uv = [4]float64{math.NaN(), 0, 0, 0}
	}
	bf.texture = data.Texture
	bf.cullFace = direction.FromString(data.CullFace)
	bf.rotation = data.Rotation
	bf.tintIndex = -1
	if data.TintIndex != nil {
		bf.tintIndex = *data.TintIndex
	}
}

func (bm *model) lookupTexture(name string) render.TextureInfo {
	if len(name) > 0 && name[0] == '#' {
		return bm.lookupTexture(bm.textureVars[name[1:]])
	}
	return render.GetTexture(name)
}

func loadJSON(plugin, name string, target interface{}) error {
	r, err := resource.Open(plugin, name)
	if err != nil {
		return err
	}
	defer r.Close()
	err = realjson.NewDecoder(r).Decode(target)
	if err != nil {
		// Take the slow path through our preprocessor.
		// Hopefully this can be removed in later minecraft versions.d, err := ioutil.ReadAll(r)
		r.Close()
		r, err = resource.Open(plugin, name)
		if err != nil {
			return err
		}

		d, err := ioutil.ReadAll(r)
		if err != nil {
			return err
		}
		return json.Unmarshal(d, target)
	}
	return err
}
<|endoftext|>


<commit_before>package xlsx

import (
	"bytes"
	"encoding/xml"

	. "gopkg.in/check.v1"
)

type SheetSuite struct{}

var _ = Suite(&SheetSuite{})

// Test we can add a Row to a Sheet
func (s *SheetSuite) TestAddRow(c *C) {
	var f *File
	f = NewFile()
	sheet := f.AddSheet("MySheet")
	row := sheet.AddRow()
	c.Assert(row, NotNil)
	c.Assert(len(sheet.Rows), Equals, 1)
}

func (s *SheetSuite) TestMakeXLSXSheetFromRows(c *C) {
	file := NewFile()
	sheet := file.AddSheet("Sheet1")
	row := sheet.AddRow()
	cell := row.AddCell()
	cell.Value = "A cell!"
	refTable := NewSharedStringRefTable()
	styles := &xlsxStyles{}
	xSheet := sheet.makeXLSXSheet(refTable, styles)
	c.Assert(xSheet.Dimension.Ref, Equals, "A1:A1")
	c.Assert(xSheet.SheetData.Row, HasLen, 1)
	xRow := xSheet.SheetData.Row[0]
	c.Assert(xRow.R, Equals, 1)
	c.Assert(xRow.Spans, Equals, "")
	c.Assert(xRow.C, HasLen, 1)
	xC := xRow.C[0]
	c.Assert(xC.R, Equals, "A1")
	c.Assert(xC.S, Equals, 0)
	c.Assert(xC.T, Equals, "s") // Shared string type
	c.Assert(xC.V, Equals, "0") // reference to shared string
	xSST := refTable.makeXLSXSST()
	c.Assert(xSST.Count, Equals, 1)
	c.Assert(xSST.UniqueCount, Equals, 1)
	c.Assert(xSST.SI, HasLen, 1)
	xSI := xSST.SI[0]
	c.Assert(xSI.T, Equals, "A cell!")
}

// When we create the xlsxSheet we also populate the xlsxStyles struct
// with style information.
func (s *SheetSuite) TestMakeXLSXSheetAlsoPopulatesXLSXSTyles(c *C) {
	file := NewFile()
	sheet := file.AddSheet("Sheet1")
	row := sheet.AddRow()

	cell1 := row.AddCell()
	cell1.Value = "A cell!"
	style1 := *NewStyle()
	style1.Font = *NewFont(10, "Verdana")
	style1.Fill = *NewFill("solid", "FFFFFFFF", "00000000")
	style1.Border = *NewBorder("none", "thin", "none", "thin")
	cell1.SetStyle(style1)

	// We need a second style to check that Xfs are populated correctly.
	cell2 := row.AddCell()
	cell2.Value = "Another cell!"
	style2 := *NewStyle()
	style2.Font = *NewFont(10, "Verdana")
	style2.Fill = *NewFill("solid", "FFFFFFFF", "00000000")
	style2.Border = *NewBorder("none", "thin", "none", "thin")
	cell2.SetStyle(style2)

	refTable := NewSharedStringRefTable()
	styles := &xlsxStyles{}
	worksheet := sheet.makeXLSXSheet(refTable, styles)

	c.Assert(len(styles.Fonts), Equals, 2)
	c.Assert(styles.Fonts[0].Sz.Val, Equals, "10")
	c.Assert(styles.Fonts[0].Name.Val, Equals, "Verdana")

	c.Assert(len(styles.Fills), Equals, 2)
	c.Assert(styles.Fills[0].PatternFill.PatternType, Equals, "solid")
	c.Assert(styles.Fills[0].PatternFill.FgColor.RGB, Equals, "FFFFFFFF")
	c.Assert(styles.Fills[0].PatternFill.BgColor.RGB, Equals, "00000000")

	c.Assert(len(styles.Borders), Equals, 2)
	c.Assert(styles.Borders[0].Left.Style, Equals, "none")
	c.Assert(styles.Borders[0].Right.Style, Equals, "thin")
	c.Assert(styles.Borders[0].Top.Style, Equals, "none")
	c.Assert(styles.Borders[0].Bottom.Style, Equals, "thin")

	c.Assert(len(styles.CellStyleXfs), Equals, 2)
	// The 0th CellStyleXf could just be getting the zero values by default
	c.Assert(styles.CellStyleXfs[0].FontId, Equals, 0)
	c.Assert(styles.CellStyleXfs[0].FillId, Equals, 0)
	c.Assert(styles.CellStyleXfs[0].BorderId, Equals, 0)
	// The 1st element cannot get initialised this way by accident.
	c.Assert(styles.CellStyleXfs[1].FontId, Equals, 1)
	c.Assert(styles.CellStyleXfs[1].FillId, Equals, 1)
	c.Assert(styles.CellStyleXfs[1].BorderId, Equals, 1)

	c.Assert(len(styles.CellXfs), Equals, 2)
	c.Assert(styles.CellXfs[0].FontId, Equals, 0)
	c.Assert(styles.CellXfs[0].FillId, Equals, 0)
	c.Assert(styles.CellXfs[0].BorderId, Equals, 0)
	// As above, we need the 1st element to make the test fail
	// when it should.
	c.Assert(styles.CellXfs[1].FontId, Equals, 1)
	c.Assert(styles.CellXfs[1].FillId, Equals, 1)
	c.Assert(styles.CellXfs[1].BorderId, Equals, 1)

	// Finally we check that the cell points to the right CellXf /
	// CellStyleXf.
	c.Assert(worksheet.SheetData.Row[0].C[0].S, Equals, 0)
	c.Assert(worksheet.SheetData.Row[0].C[1].S, Equals, 1)
}

func (s *SheetSuite) TestMarshalSheet(c *C) {
	file := NewFile()
	sheet := file.AddSheet("Sheet1")
	row := sheet.AddRow()
	cell := row.AddCell()
	cell.Value = "A cell!"
	refTable := NewSharedStringRefTable()
	styles := &xlsxStyles{}
	xSheet := sheet.makeXLSXSheet(refTable, styles)

	output := bytes.NewBufferString(xml.Header)
	body, err := xml.MarshalIndent(xSheet, "  ", "  ")
	c.Assert(err, IsNil)
	c.Assert(body, NotNil)
	_, err = output.Write(body)
	c.Assert(err, IsNil)
	expectedXLSXSheet := `<?xml version="1.0" encoding="UTF-8"?>
  <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <dimension ref="A1:A1"></dimension>
    <cols>
      <col min="1" max="1"></col>
    </cols>
    <sheetData>
      <row r="1">
        <c r="A1" s="0" t="s">
          <v>0</v>
        </c>
      </row>
    </sheetData>
  </worksheet>`
	c.Assert(output.String(), Equals, expectedXLSXSheet)
}

func (s *SheetSuite) TestMarshalSheetWithMultipleCells(c *C) {
	file := NewFile()
	sheet := file.AddSheet("Sheet1")
	row := sheet.AddRow()
	cell := row.AddCell()
	cell.Value = "A cell (with value 1)!"
	cell = row.AddCell()
	cell.Value = "A cell (with value 2)!"
	refTable := NewSharedStringRefTable()
	xSheet := sheet.makeXLSXSheet(refTable)

	output := bytes.NewBufferString(xml.Header)
	body, err := xml.MarshalIndent(xSheet, "  ", "  ")
	c.Assert(err, IsNil)
	c.Assert(body, NotNil)
	_, err = output.Write(body)
	c.Assert(err, IsNil)
	expectedXLSXSheet := `<?xml version="1.0" encoding="UTF-8"?>
  <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <dimension ref="A1:B1"></dimension>
    <cols>
      <col min="1" max="1"></col>
      <col min="2" max="2"></col>
    </cols>
    <sheetData>
      <row r="1">
        <c r="A1" t="s">
          <v>0</v>
        </c>
        <c r="B1" t="s">
          <v>1</v>
        </c>
      </row>
    </sheetData>
  </worksheet>`
	c.Assert(output.String(), Equals, expectedXLSXSheet)
}
<commit_msg>Resolve failing tests from merge.<commit_after>package xlsx

import (
	"bytes"
	"encoding/xml"

	. "gopkg.in/check.v1"
)

type SheetSuite struct{}

var _ = Suite(&SheetSuite{})

// Test we can add a Row to a Sheet
func (s *SheetSuite) TestAddRow(c *C) {
	var f *File
	f = NewFile()
	sheet := f.AddSheet("MySheet")
	row := sheet.AddRow()
	c.Assert(row, NotNil)
	c.Assert(len(sheet.Rows), Equals, 1)
}

func (s *SheetSuite) TestMakeXLSXSheetFromRows(c *C) {
	file := NewFile()
	sheet := file.AddSheet("Sheet1")
	row := sheet.AddRow()
	cell := row.AddCell()
	cell.Value = "A cell!"
	refTable := NewSharedStringRefTable()
	styles := &xlsxStyles{}
	xSheet := sheet.makeXLSXSheet(refTable, styles)
	c.Assert(xSheet.Dimension.Ref, Equals, "A1:A1")
	c.Assert(xSheet.SheetData.Row, HasLen, 1)
	xRow := xSheet.SheetData.Row[0]
	c.Assert(xRow.R, Equals, 1)
	c.Assert(xRow.Spans, Equals, "")
	c.Assert(xRow.C, HasLen, 1)
	xC := xRow.C[0]
	c.Assert(xC.R, Equals, "A1")
	c.Assert(xC.S, Equals, 0)
	c.Assert(xC.T, Equals, "s") // Shared string type
	c.Assert(xC.V, Equals, "0") // reference to shared string
	xSST := refTable.makeXLSXSST()
	c.Assert(xSST.Count, Equals, 1)
	c.Assert(xSST.UniqueCount, Equals, 1)
	c.Assert(xSST.SI, HasLen, 1)
	xSI := xSST.SI[0]
	c.Assert(xSI.T, Equals, "A cell!")
}

// When we create the xlsxSheet we also populate the xlsxStyles struct
// with style information.
func (s *SheetSuite) TestMakeXLSXSheetAlsoPopulatesXLSXSTyles(c *C) {
	file := NewFile()
	sheet := file.AddSheet("Sheet1")
	row := sheet.AddRow()

	cell1 := row.AddCell()
	cell1.Value = "A cell!"
	style1 := *NewStyle()
	style1.Font = *NewFont(10, "Verdana")
	style1.Fill = *NewFill("solid", "FFFFFFFF", "00000000")
	style1.Border = *NewBorder("none", "thin", "none", "thin")
	cell1.SetStyle(style1)

	// We need a second style to check that Xfs are populated correctly.
	cell2 := row.AddCell()
	cell2.Value = "Another cell!"
	style2 := *NewStyle()
	style2.Font = *NewFont(10, "Verdana")
	style2.Fill = *NewFill("solid", "FFFFFFFF", "00000000")
	style2.Border = *NewBorder("none", "thin", "none", "thin")
	cell2.SetStyle(style2)

	refTable := NewSharedStringRefTable()
	styles := &xlsxStyles{}
	worksheet := sheet.makeXLSXSheet(refTable, styles)

	c.Assert(len(styles.Fonts), Equals, 2)
	c.Assert(styles.Fonts[0].Sz.Val, Equals, "10")
	c.Assert(styles.Fonts[0].Name.Val, Equals, "Verdana")

	c.Assert(len(styles.Fills), Equals, 2)
	c.Assert(styles.Fills[0].PatternFill.PatternType, Equals, "solid")
	c.Assert(styles.Fills[0].PatternFill.FgColor.RGB, Equals, "FFFFFFFF")
	c.Assert(styles.Fills[0].PatternFill.BgColor.RGB, Equals, "00000000")

	c.Assert(len(styles.Borders), Equals, 2)
	c.Assert(styles.Borders[0].Left.Style, Equals, "none")
	c.Assert(styles.Borders[0].Right.Style, Equals, "thin")
	c.Assert(styles.Borders[0].Top.Style, Equals, "none")
	c.Assert(styles.Borders[0].Bottom.Style, Equals, "thin")

	c.Assert(len(styles.CellStyleXfs), Equals, 2)
	// The 0th CellStyleXf could just be getting the zero values by default
	c.Assert(styles.CellStyleXfs[0].FontId, Equals, 0)
	c.Assert(styles.CellStyleXfs[0].FillId, Equals, 0)
	c.Assert(styles.CellStyleXfs[0].BorderId, Equals, 0)
	// The 1st element cannot get initialised this way by accident.
	c.Assert(styles.CellStyleXfs[1].FontId, Equals, 1)
	c.Assert(styles.CellStyleXfs[1].FillId, Equals, 1)
	c.Assert(styles.CellStyleXfs[1].BorderId, Equals, 1)

	c.Assert(len(styles.CellXfs), Equals, 2)
	c.Assert(styles.CellXfs[0].FontId, Equals, 0)
	c.Assert(styles.CellXfs[0].FillId, Equals, 0)
	c.Assert(styles.CellXfs[0].BorderId, Equals, 0)
	// As above, we need the 1st element to make the test fail
	// when it should.
	c.Assert(styles.CellXfs[1].FontId, Equals, 1)
	c.Assert(styles.CellXfs[1].FillId, Equals, 1)
	c.Assert(styles.CellXfs[1].BorderId, Equals, 1)

	// Finally we check that the cell points to the right CellXf /
	// CellStyleXf.
	c.Assert(worksheet.SheetData.Row[0].C[0].S, Equals, 0)
	c.Assert(worksheet.SheetData.Row[0].C[1].S, Equals, 1)
}

func (s *SheetSuite) TestMarshalSheet(c *C) {
	file := NewFile()
	sheet := file.AddSheet("Sheet1")
	row := sheet.AddRow()
	cell := row.AddCell()
	cell.Value = "A cell!"
	refTable := NewSharedStringRefTable()
	styles := &xlsxStyles{}
	xSheet := sheet.makeXLSXSheet(refTable, styles)

	output := bytes.NewBufferString(xml.Header)
	body, err := xml.MarshalIndent(xSheet, "  ", "  ")
	c.Assert(err, IsNil)
	c.Assert(body, NotNil)
	_, err = output.Write(body)
	c.Assert(err, IsNil)
	expectedXLSXSheet := `<?xml version="1.0" encoding="UTF-8"?>
  <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <dimension ref="A1:A1"></dimension>
    <cols>
      <col min="1" max="1"></col>
    </cols>
    <sheetData>
      <row r="1">
        <c r="A1" s="0" t="s">
          <v>0</v>
        </c>
      </row>
    </sheetData>
  </worksheet>`
	c.Assert(output.String(), Equals, expectedXLSXSheet)
}

func (s *SheetSuite) TestMarshalSheetWithMultipleCells(c *C) {
	file := NewFile()
	sheet := file.AddSheet("Sheet1")
	row := sheet.AddRow()
	cell := row.AddCell()
	cell.Value = "A cell (with value 1)!"
	cell = row.AddCell()
	cell.Value = "A cell (with value 2)!"
	refTable := NewSharedStringRefTable()
	styles := &xlsxStyles{}
	xSheet := sheet.makeXLSXSheet(refTable, styles)

	output := bytes.NewBufferString(xml.Header)
	body, err := xml.MarshalIndent(xSheet, "  ", "  ")
	c.Assert(err, IsNil)
	c.Assert(body, NotNil)
	_, err = output.Write(body)
	c.Assert(err, IsNil)
	expectedXLSXSheet := `<?xml version="1.0" encoding="UTF-8"?>
  <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <dimension ref="A1:B1"></dimension>
    <cols>
      <col min="1" max="1"></col>
      <col min="2" max="2"></col>
    </cols>
    <sheetData>
      <row r="1">
        <c r="A1" s="0" t="s">
          <v>0</v>
        </c>
        <c r="B1" s="1" t="s">
          <v>1</v>
        </c>
      </row>
    </sheetData>
  </worksheet>`
	c.Assert(output.String(), Equals, expectedXLSXSheet)
}
<|endoftext|>