<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package main

import (
	"fmt"
	"github.com/szabba/md/src/newton"
	"github.com/szabba/md/src/vect"
	"math"
)

type SingleHooke struct {
	K float64
}

func (sh SingleHooke) Accel(bs []*newton.Body, i int) (a vect.Vector) {

	b := bs[i]

	return b.Xs[0].Scale(-sh.K / b.Mass())
}

type AnalyticSHM struct {
	K, M float64
	A    vect.Vector
}

func (ashm AnalyticSHM) XVAt(t float64) (x, v vect.Vector) {

	omega := math.Sqrt(ashm.K / ashm.M)

	x = ashm.A.Scale(math.Cos(omega * t))
	v = ashm.A.Negate().Scale(omega * math.Sin(omega*t))

	return
}

func (ashm AnalyticSHM) Force() newton.Force {

	return newton.Force(SingleHooke{K: ashm.K})
}

func (ashm AnalyticSHM) ForEuler() []*newton.Body {

	b := newton.NewBody(newton.Euler, ashm.M)

	b.SetNow(ashm.XVAt(0))

	return []*newton.Body{b}
}

func (ashm AnalyticSHM) ForVerlet(dt float64) []*newton.Body {

	b := newton.NewBody(newton.Verlet, ashm.M)
	b.Shift(ashm.XVAt(-dt))
	b.Shift(ashm.XVAt(0))

	bs := []*newton.Body{b}

	newton.Step(newton.Verlet, bs, ashm.Force(), dt)

	return bs
}

func (ashm AnalyticSHM) DataHeader() {

	//fmt.Printf("# ")
	fmt.Printf("t x v E Ek U ")
	fmt.Printf("x_e v_e E_e Ek_e U_e x_e_resid ")
	fmt.Printf("x_v v_v E_v Ek_v U_v x_v_resid ")
	fmt.Println()
}

func (ashm AnalyticSHM) Run(dt float64, steps int) {

	ashm.DataHeader()

	force := ashm.Force()

	eulerState := ashm.ForEuler()
	verletState := ashm.ForVerlet(dt)

	for t := 0.0; steps > 0; {

		fmt.Printf("%f ", t)

		x := ashm.Analytic(t)

		ashm.EulerFormat(eulerState, x)
		newton.Step(newton.Euler, eulerState, force, dt)

		ashm.VerletFormat(verletState, x)
		newton.Step(newton.Verlet, verletState, force, dt)

		fmt.Println()

		t += dt
		steps--
	}
}

func (ashm AnalyticSHM) Analytic(t float64) (x vect.Vector) {

	x, v := ashm.XVAt(t)

	kinetic := ashm.M * math.Pow(v.Norm(), 2) / 2
	potential := ashm.A.Norm() * math.Pow(x.Norm(), 2) / 2

	totalE := kinetic + potential

	fmt.Printf(
		"%f %f %f %f %f ",
		x.Dot(vect.UnitX), v.Dot(vect.UnitX), totalE, kinetic, potential,
	)

	return x
}

func (ashm AnalyticSHM) EulerFormat(bs []*newton.Body, x vect.Vector) {

	xE, vE := bs[0].Xs[0].Dot(vect.UnitX), bs[0].Vs[0].Dot(vect.UnitX)

	kinetic := ashm.M * math.Pow(vE, 2) / 2
	potential := ashm.K * math.Pow(xE, 2) / 2

	total := kinetic + potential

	residue := math.Abs(x.Dot(vect.UnitX) - xE)

	fmt.Printf(
		"%f %f %f %f %f %f ",
		xE, vE, total, kinetic, potential, residue,
	)
}

func (ashm AnalyticSHM) VerletFormat(bs []*newton.Body, x vect.Vector) {

	xV, vV := bs[0].Xs[1].Dot(vect.UnitX), bs[0].Vs[1].Dot(vect.UnitX)

	kinetic := ashm.M * math.Pow(vV, 2) / 2
	potential := ashm.K * math.Pow(xV, 2) / 2

	total := kinetic + potential

	residue := math.Abs(x.Dot(vect.UnitX) - xV)

	fmt.Printf(
		"%f %f %f %f %f %f ",
		xV, vV, total, kinetic, potential, residue,
	)
}
<commit_msg>Use newton.System for the Euler-based simulation in shm<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package main

import (
	"fmt"
	"github.com/szabba/md/src/newton"
	"github.com/szabba/md/src/vect"
	"math"
)

type SingleHooke struct {
	K float64
}

func (sh SingleHooke) Accel(bs []*newton.Body, i int) (a vect.Vector) {

	b := bs[i]

	return b.Xs[0].Scale(-sh.K / b.Mass())
}

type AnalyticSHM struct {
	K, M float64
	A    vect.Vector
}

func (ashm AnalyticSHM) XVAt(t float64) (x, v vect.Vector) {

	omega := math.Sqrt(ashm.K / ashm.M)

	x = ashm.A.Scale(math.Cos(omega * t))
	v = ashm.A.Negate().Scale(omega * math.Sin(omega*t))

	return
}

func (ashm AnalyticSHM) Force() newton.Force {

	return newton.Force(SingleHooke{K: ashm.K})
}

func (ashm AnalyticSHM) ForEuler() *newton.System {

	sys := newton.NewSystem(newton.Euler, 1)

	sys.SetForce(ashm.Force())

	b := sys.Body(0)

	b.SetMass(ashm.M)
	b.SetNow(ashm.XVAt(0))

	return sys
}

func (ashm AnalyticSHM) ForVerlet(dt float64) []*newton.Body {

	b := newton.NewBody(newton.Verlet)
	b.SetMass(ashm.M)
	b.Shift(ashm.XVAt(-dt))
	b.Shift(ashm.XVAt(0))

	bs := []*newton.Body{b}

	newton.Step(newton.Verlet, bs, ashm.Force(), dt)

	return bs
}

func (ashm AnalyticSHM) DataHeader() {

	//fmt.Printf("# ")
	fmt.Printf("t x v E Ek U ")
	fmt.Printf("x_e v_e E_e Ek_e U_e x_e_resid ")
	fmt.Printf("x_v v_v E_v Ek_v U_v x_v_resid ")
	fmt.Println()
}

func (ashm AnalyticSHM) Run(dt float64, steps int) {

	ashm.DataHeader()

	force := ashm.Force()

	eulerState := ashm.ForEuler()

	verletState := ashm.ForVerlet(dt)

	for t := 0.0; steps > 0; {

		fmt.Printf("%f ", t)

		x := ashm.Analytic(t)

		ashm.EulerFormat(eulerState, x)
		eulerState.Step(dt)

		ashm.VerletFormat(verletState, x)
		newton.Step(newton.Verlet, verletState, force, dt)

		fmt.Println()

		t += dt
		steps--
	}
}

func (ashm AnalyticSHM) Analytic(t float64) (x vect.Vector) {

	x, v := ashm.XVAt(t)

	kinetic := ashm.M * math.Pow(v.Norm(), 2) / 2
	potential := ashm.A.Norm() * math.Pow(x.Norm(), 2) / 2

	totalE := kinetic + potential

	fmt.Printf(
		"%f %f %f %f %f ",
		x.Dot(vect.UnitX), v.Dot(vect.UnitX), totalE, kinetic, potential,
	)

	return x
}

func (ashm AnalyticSHM) EulerFormat(sys *newton.System, x vect.Vector) {

	xE, vE := sys.Body(0).Now()

	xVal, vVal := xE.Dot(vect.UnitX), vE.Dot(vect.UnitX)

	kinetic := ashm.M * math.Pow(vVal, 2) / 2
	potential := ashm.K * math.Pow(xVal, 2) / 2

	total := kinetic + potential

	residue := math.Abs(x.Dot(vect.UnitX) - xVal)

	fmt.Printf(
		"%f %f %f %f %f %f ",
		xVal, vVal, total, kinetic, potential, residue,
	)
}

func (ashm AnalyticSHM) VerletFormat(bs []*newton.Body, x vect.Vector) {

	xV, vV := bs[0].Xs[1].Dot(vect.UnitX), bs[0].Vs[1].Dot(vect.UnitX)

	kinetic := ashm.M * math.Pow(vV, 2) / 2
	potential := ashm.K * math.Pow(xV, 2) / 2

	total := kinetic + potential

	residue := math.Abs(x.Dot(vect.UnitX) - xV)

	fmt.Printf(
		"%f %f %f %f %f %f ",
		xV, vV, total, kinetic, potential, residue,
	)
}
<|endoftext|>


<commit_before>package log_test

import (
	"os"
	"testing"

	"github.com/prasannavl/go-grab/log"
)

func TestPrint(t *testing.T) {
	rec := log.CreateMultiRecorder(
		&log.LeveledRecorder{
			MaxLevel: log.InfoLevel,
			Target: &log.StreamRecorder{
				Formatter: log.DefaultColorTextFormatterForHuman,
				Stream:    os.Stdout,
			},
		},
	)

	log.SetGlobal(rec)

	log.Info("Hello there 1")
	log.Warn("Hello there 2")
	log.Error("Hello there 3")
	log.Debug("Hello there 4")
	log.Trace("Hello there 5")

	log.Infof("%s", "Hey you X")
	log.Warnf("%s %q %v", "Hey", "you", "Y")

	l := log.WithContext("ctxName", "some val")
	l.Info("hello there!!")
	l.WithContext("ctx2", "another val").Info("Hey you")
	l.Infof("%s %v", "hello there", "again")
}
<commit_msg>fix: update tests to latest api<commit_after>package log_test

import (
	"os"
	"testing"

	"github.com/prasannavl/go-grab/log"
)

func TestPrint(t *testing.T) {
	rec := log.CreateMultiRecorder(
		&log.LeveledRecorder{
			MaxLevel: log.InfoLevel,
			Target: &log.StreamRecorder{
				Formatter: log.DefaultColorTextFormatterForHuman,
				Stream:    os.Stdout,
			},
		},
	)

	l := log.New(rec)
	log.SetGlobal(l)

	log.Info("Hello there 1")
	log.Warn("Hello there 2")
	log.Error("Hello there 3")
	log.Debug("Hello there 4")
	log.Trace("Hello there 5")

	log.Infof("%s", "Hey you X")
	log.Warnf("%s %q %v", "Hey", "you", "Y")

	l2 := log.WithContext("ctxName", "some val")
	l2.Info("hello there!!")
	l2.WithContext("ctx2", "another val").Info("Hey you")
	l2.Infof("%s %v", "hello there", "again")
}
<|endoftext|>


<commit_before>// +build !udp

package transport

import (
	"sync"
	"time"

	"github.com/emicklei/melrose/core"
	"github.com/rakyll/portmidi"
)

type listener struct {
	listening bool
	stream    *portmidi.Stream
	quit      chan bool
	noteOn    map[int]portmidi.Event

	mutex         *sync.RWMutex
	noteListeners []core.NoteListener
	keyListeners  map[int]core.NoteListener
}

func newListener(inputStream *portmidi.Stream) *listener {
	return &listener{
		stream:       inputStream,
		noteOn:       map[int]portmidi.Event{},
		keyListeners: map[int]core.NoteListener{},
		mutex:        new(sync.RWMutex),
	}
}

func (l *listener) OnKey(note core.Note, handler core.NoteListener) {
	nr := note.MIDI()
	// remove existing for the key
	old, ok := l.keyListeners[nr]
	if ok {
		l.Remove(old)
		delete(l.keyListeners, nr)
	}
	if handler == nil {
		return
	}
	// add to map and list
	l.keyListeners[nr] = handler
	l.Add(handler)
}

func (l *listener) Add(lis core.NoteListener) {
	l.mutex.Lock()
	defer l.mutex.Unlock()
	l.noteListeners = append(l.noteListeners, lis)
}

func (l *listener) Remove(lis core.NoteListener) {
	l.mutex.Lock()
	defer l.mutex.Unlock()
	without := []core.NoteListener{}
	for _, each := range l.noteListeners {
		if each != lis {
			without = append(without, each)
		}
	}
	l.noteListeners = without
}

func (l *listener) Start() {
	if l.listening {
		return
	}
	l.listening = true
	go l.listen()
}

func (l *listener) listen() {
	l.quit = make(chan bool)
	ch := l.stream.Listen()
	for {
		select {
		case <-l.quit:
			goto stop
		case e := <-ch:
			l.handle(e)
		}
	}
stop:
	close(l.quit)
	l.listening = false
}

func (l *listener) handle(event portmidi.Event) {
	l.mutex.RLock()
	defer l.mutex.RUnlock()
	nr := int(event.Data1)
	if (event.Status & noteOn) == noteOn {
		if _, ok := l.noteOn[nr]; ok {
			return
		}
		// replace with now in nanos
		event.Timestamp = portmidi.Timestamp(time.Now().UnixNano())
		l.noteOn[nr] = event
		onNote, _ := core.MIDItoNote(0.25, nr, int(event.Data2))
		for _, each := range l.noteListeners {
			each.NoteOn(onNote)
		}
	} else if (event.Status & noteOff) == noteOff {
		on, ok := l.noteOn[nr]
		if !ok {
			return
		}
		delete(l.noteOn, nr)
		// replace with now in nanos
		event.Timestamp = portmidi.Timestamp(time.Now().UnixNano())
		// compute delta
		ms := time.Duration(event.Timestamp-on.Timestamp) * time.Nanosecond
		frac := core.DurationToFraction(120.0, ms) // TODO
		offNote, _ := core.MIDItoNote(frac, nr, int(on.Data2))
		for _, each := range l.noteListeners {
			each.NoteOff(offNote)
		}
	}
}

func (l *listener) Stop() {
	// forget open notes
	l.noteOn = map[int]portmidi.Event{}
	if l.listening {
		l.quit <- true
	}
}
<commit_msg>handle aftertouch<commit_after>// +build !udp

package transport

import (
	"sync"
	"time"

	"github.com/emicklei/melrose/core"
	"github.com/emicklei/melrose/notify"
	"github.com/rakyll/portmidi"
)

type listener struct {
	listening bool
	stream    *portmidi.Stream
	quit      chan bool
	noteOn    map[int]portmidi.Event

	mutex         *sync.RWMutex
	noteListeners []core.NoteListener
	keyListeners  map[int]core.NoteListener
}

func newListener(inputStream *portmidi.Stream) *listener {
	return &listener{
		stream:       inputStream,
		noteOn:       map[int]portmidi.Event{},
		keyListeners: map[int]core.NoteListener{},
		mutex:        new(sync.RWMutex),
	}
}

func (l *listener) OnKey(note core.Note, handler core.NoteListener) {
	nr := note.MIDI()
	// remove existing for the key
	old, ok := l.keyListeners[nr]
	if ok {
		l.Remove(old)
		delete(l.keyListeners, nr)
	}
	if handler == nil {
		return
	}
	// add to map and list
	l.keyListeners[nr] = handler
	l.Add(handler)
}

func (l *listener) Add(lis core.NoteListener) {
	l.mutex.Lock()
	defer l.mutex.Unlock()
	l.noteListeners = append(l.noteListeners, lis)
}

func (l *listener) Remove(lis core.NoteListener) {
	l.mutex.Lock()
	defer l.mutex.Unlock()
	without := []core.NoteListener{}
	for _, each := range l.noteListeners {
		if each != lis {
			without = append(without, each)
		}
	}
	l.noteListeners = without
}

func (l *listener) Start() {
	if l.listening {
		return
	}
	l.listening = true
	go l.listen()
}

func (l *listener) listen() {
	l.quit = make(chan bool)
	ch := l.stream.Listen()
	for {
		select {
		case <-l.quit:
			goto stop
		case e := <-ch:
			l.handle(e)
		}
	}
stop:
	close(l.quit)
	l.listening = false
}

func (l *listener) handle(event portmidi.Event) {
	l.mutex.RLock()
	defer l.mutex.RUnlock()
	if core.IsDebug() {
		notify.Debugf("portmidi.handle %v", event)
	}
	nr := int(event.Data1)
	isNoteOn := (event.Status & noteOn) == noteOn
	velocity := int(event.Data2)
	if isNoteOn && velocity > 0 {
		if _, ok := l.noteOn[nr]; ok {
			return
		}
		// replace with now in nanos
		event.Timestamp = portmidi.Timestamp(time.Now().UnixNano())
		l.noteOn[nr] = event
		onNote, _ := core.MIDItoNote(0.25, nr, velocity)
		for _, each := range l.noteListeners {
			each.NoteOn(onNote)
		}
	}
	isNoteOff := (event.Status & noteOff) == noteOff
	// for devices that support aftertouch, a noteOn with velocity 0 is also handled as a noteOff
	if !isNoteOff {
		isNoteOff = isNoteOn && velocity == 0
	}
	if isNoteOff {
		on, ok := l.noteOn[nr]
		if !ok {
			return
		}
		delete(l.noteOn, nr)
		// replace with now in nanos
		event.Timestamp = portmidi.Timestamp(time.Now().UnixNano())
		// compute delta
		ms := time.Duration(event.Timestamp-on.Timestamp) * time.Nanosecond
		frac := core.DurationToFraction(120.0, ms) // TODO
		offNote, _ := core.MIDItoNote(frac, nr, velocity)
		for _, each := range l.noteListeners {
			each.NoteOff(offNote)
		}
	}
}

func (l *listener) Stop() {
	// forget open notes
	l.noteOn = map[int]portmidi.Event{}
	if l.listening {
		l.quit <- true
	}
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"net"
	"net/http"
	"net/http/httptest"
	"os/exec"
	"time"

	"github.com/go-check/check"

	checker "github.com/vdemeester/shakers"
)

// HTTPSSuite
type HTTPSSuite struct{ BaseSuite }

// TestWithSNIConfigHandshake involves a client sending a SNI hostname of
// "snitest.com", which happens to match the CN of 'snitest.com.crt'. The test
// verifies that traefik presents the correct certificate.
func (s *HTTPSSuite) TestWithSNIConfigHandshake(c *check.C) {
	cmd := exec.Command(traefikBinary, "--configFile=fixtures/https/https_sni.toml")
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer cmd.Process.Kill()

	time.Sleep(500 * time.Millisecond)

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
	}
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))

	defer conn.Close()
	err = conn.Handshake()
	c.Assert(err, checker.IsNil, check.Commentf("TLS handshake error"))

	cs := conn.ConnectionState()
	err = cs.PeerCertificates[0].VerifyHostname("snitest.com")
	c.Assert(err, checker.IsNil, check.Commentf("certificate did not match SNI servername"))
}

// TestWithSNIConfigRoute involves a client sending HTTPS requests with
// SNI hostnames of "snitest.org" and "snitest.com". The test verifies
// that traefik routes the requests to the expected backends.
func (s *HTTPSSuite) TestWithSNIConfigRoute(c *check.C) {
	cmd := exec.Command(traefikBinary, "--configFile=fixtures/https/https_sni.toml")
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer cmd.Process.Kill()

	backend1 := startTestServer("9010", 204)
	backend2 := startTestServer("9020", 205)
	defer backend1.Close()
	defer backend2.Close()

	time.Sleep(2000 * time.Millisecond)

	tr1 := &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
			ServerName:         "snitest.com",
		},
	}
	tr2 := &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
			ServerName:         "snitest.org",
		},
	}

	client := &http.Client{Transport: tr1}
	req, _ := http.NewRequest("GET", "https://127.0.0.1:4443/", nil)
	req.Host = "snitest.com"
	req.Header.Set("Host", "snitest.com")
	req.Header.Set("Accept", "*/*")
	resp, err := client.Do(req)
	c.Assert(err, checker.IsNil)
	// Expected a 204 (from backend1)
	c.Assert(resp.StatusCode, checker.Equals, 204)

	client = &http.Client{Transport: tr2}
	req, _ = http.NewRequest("GET", "https://127.0.0.1:4443/", nil)
	req.Host = "snitest.org"
	req.Header.Set("Host", "snitest.org")
	req.Header.Set("Accept", "*/*")
	resp, err = client.Do(req)
	c.Assert(err, checker.IsNil)
	// Expected a 205 (from backend2)
	c.Assert(resp.StatusCode, checker.Equals, 205)
}

// TestWithClientCertificateAuthentication
// The client has to send a certificate signed by a CA trusted by the server
func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) {
	cmd := exec.Command(traefikBinary, "--configFile=fixtures/https/clientca/https_1ca1config.toml")
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer cmd.Process.Kill()

	time.Sleep(500 * time.Millisecond)

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	// Connection without client certificate should fail
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))

	// Connect with client certificate signed by ca1
	cert, err := tls.LoadX509KeyPair("fixtures/https/clientca/client1.crt", "fixtures/https/clientca/client1.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))

	conn.Close()

	// Connect with client signed by ca2 should fail
	tlsConfig = &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	cert, err = tls.LoadX509KeyPair("fixtures/https/clientca/client2.crt", "fixtures/https/clientca/client2.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))

}

// TestWithClientCertificateAuthentication
// Use two CA:s and test that clients with client signed by either of them can connect
func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipeCAs(c *check.C) {
	cmd := exec.Command(traefikBinary, "--configFile=fixtures/https/clientca/https_2ca1config.toml")
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer cmd.Process.Kill()

	time.Sleep(500 * time.Millisecond)

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	// Connection without client certificate should fail
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))

	// Connect with client signed by ca1
	cert, err := tls.LoadX509KeyPair("fixtures/https/clientca/client1.crt", "fixtures/https/clientca/client1.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))

	conn.Close()

	// Connect with client signed by ca2
	tlsConfig = &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	cert, err = tls.LoadX509KeyPair("fixtures/https/clientca/client2.crt", "fixtures/https/clientca/client2.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
	conn.Close()

	// Connect with client signed by ca3 should fail
	tlsConfig = &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	cert, err = tls.LoadX509KeyPair("fixtures/https/clientca/client3.crt", "fixtures/https/clientca/client3.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))
}

// TestWithClientCertificateAuthentication
// Use two CA:s in two different files and test that clients with client signed by either of them can connect
func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipeCAsMultipleFiles(c *check.C) {
	cmd := exec.Command(traefikBinary, "--configFile=fixtures/https/clientca/https_2ca2config.toml")
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer cmd.Process.Kill()

	time.Sleep(500 * time.Millisecond)

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	// Connection without client certificate should fail
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))

	// Connect with client signed by ca1
	cert, err := tls.LoadX509KeyPair("fixtures/https/clientca/client1.crt", "fixtures/https/clientca/client1.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))

	conn.Close()

	// Connect with client signed by ca2
	tlsConfig = &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	cert, err = tls.LoadX509KeyPair("fixtures/https/clientca/client2.crt", "fixtures/https/clientca/client2.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
	conn.Close()

	// Connect with client signed by ca3 should fail
	tlsConfig = &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	cert, err = tls.LoadX509KeyPair("fixtures/https/clientca/client3.crt", "fixtures/https/clientca/client3.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))
}

func startTestServer(port string, statusCode int) (ts *httptest.Server) {
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(statusCode)
	})
	listener, err := net.Listen("tcp", "127.0.0.1:"+port)
	if err != nil {
		panic(err)
	}

	ts = &httptest.Server{
		Listener: listener,
		Config:   &http.Server{Handler: handler},
	}
	ts.Start()
	return
}
<commit_msg>Check that we provide HTTP/2 <commit_after>package main

import (
	"crypto/tls"
	"net"
	"net/http"
	"net/http/httptest"
	"os/exec"
	"time"

	"github.com/go-check/check"

	checker "github.com/vdemeester/shakers"
)

// HTTPSSuite
type HTTPSSuite struct{ BaseSuite }

// TestWithSNIConfigHandshake involves a client sending a SNI hostname of
// "snitest.com", which happens to match the CN of 'snitest.com.crt'. The test
// verifies that traefik presents the correct certificate.
func (s *HTTPSSuite) TestWithSNIConfigHandshake(c *check.C) {
	cmd := exec.Command(traefikBinary, "--configFile=fixtures/https/https_sni.toml")
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer cmd.Process.Kill()

	time.Sleep(500 * time.Millisecond)

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		NextProtos:         []string{"h2", "http/1.1"},
	}
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))

	defer conn.Close()
	err = conn.Handshake()
	c.Assert(err, checker.IsNil, check.Commentf("TLS handshake error"))

	cs := conn.ConnectionState()
	err = cs.PeerCertificates[0].VerifyHostname("snitest.com")
	c.Assert(err, checker.IsNil, check.Commentf("certificate did not match SNI servername"))

	proto := conn.ConnectionState().NegotiatedProtocol
	c.Assert(proto, checker.Equals, "h2")
}

// TestWithSNIConfigRoute involves a client sending HTTPS requests with
// SNI hostnames of "snitest.org" and "snitest.com". The test verifies
// that traefik routes the requests to the expected backends.
func (s *HTTPSSuite) TestWithSNIConfigRoute(c *check.C) {
	cmd := exec.Command(traefikBinary, "--configFile=fixtures/https/https_sni.toml")
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer cmd.Process.Kill()

	backend1 := startTestServer("9010", 204)
	backend2 := startTestServer("9020", 205)
	defer backend1.Close()
	defer backend2.Close()

	time.Sleep(2000 * time.Millisecond)

	tr1 := &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
			ServerName:         "snitest.com",
		},
	}
	tr2 := &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
			ServerName:         "snitest.org",
		},
	}

	client := &http.Client{Transport: tr1}
	req, _ := http.NewRequest("GET", "https://127.0.0.1:4443/", nil)
	req.Host = "snitest.com"
	req.Header.Set("Host", "snitest.com")
	req.Header.Set("Accept", "*/*")
	resp, err := client.Do(req)
	c.Assert(err, checker.IsNil)
	// Expected a 204 (from backend1)
	c.Assert(resp.StatusCode, checker.Equals, 204)

	client = &http.Client{Transport: tr2}
	req, _ = http.NewRequest("GET", "https://127.0.0.1:4443/", nil)
	req.Host = "snitest.org"
	req.Header.Set("Host", "snitest.org")
	req.Header.Set("Accept", "*/*")
	resp, err = client.Do(req)
	c.Assert(err, checker.IsNil)
	// Expected a 205 (from backend2)
	c.Assert(resp.StatusCode, checker.Equals, 205)
}

// TestWithClientCertificateAuthentication
// The client has to send a certificate signed by a CA trusted by the server
func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) {
	cmd := exec.Command(traefikBinary, "--configFile=fixtures/https/clientca/https_1ca1config.toml")
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer cmd.Process.Kill()

	time.Sleep(500 * time.Millisecond)

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	// Connection without client certificate should fail
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))

	// Connect with client certificate signed by ca1
	cert, err := tls.LoadX509KeyPair("fixtures/https/clientca/client1.crt", "fixtures/https/clientca/client1.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))

	conn.Close()

	// Connect with client signed by ca2 should fail
	tlsConfig = &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	cert, err = tls.LoadX509KeyPair("fixtures/https/clientca/client2.crt", "fixtures/https/clientca/client2.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))

}

// TestWithClientCertificateAuthentication
// Use two CA:s and test that clients with client signed by either of them can connect
func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipeCAs(c *check.C) {
	cmd := exec.Command(traefikBinary, "--configFile=fixtures/https/clientca/https_2ca1config.toml")
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer cmd.Process.Kill()

	time.Sleep(500 * time.Millisecond)

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	// Connection without client certificate should fail
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))

	// Connect with client signed by ca1
	cert, err := tls.LoadX509KeyPair("fixtures/https/clientca/client1.crt", "fixtures/https/clientca/client1.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))

	conn.Close()

	// Connect with client signed by ca2
	tlsConfig = &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	cert, err = tls.LoadX509KeyPair("fixtures/https/clientca/client2.crt", "fixtures/https/clientca/client2.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
	conn.Close()

	// Connect with client signed by ca3 should fail
	tlsConfig = &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	cert, err = tls.LoadX509KeyPair("fixtures/https/clientca/client3.crt", "fixtures/https/clientca/client3.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))
}

// TestWithClientCertificateAuthentication
// Use two CA:s in two different files and test that clients with client signed by either of them can connect
func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipeCAsMultipleFiles(c *check.C) {
	cmd := exec.Command(traefikBinary, "--configFile=fixtures/https/clientca/https_2ca2config.toml")
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer cmd.Process.Kill()

	time.Sleep(500 * time.Millisecond)

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	// Connection without client certificate should fail
	conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))

	// Connect with client signed by ca1
	cert, err := tls.LoadX509KeyPair("fixtures/https/clientca/client1.crt", "fixtures/https/clientca/client1.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))

	conn.Close()

	// Connect with client signed by ca2
	tlsConfig = &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	cert, err = tls.LoadX509KeyPair("fixtures/https/clientca/client2.crt", "fixtures/https/clientca/client2.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
	conn.Close()

	// Connect with client signed by ca3 should fail
	tlsConfig = &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         "snitest.com",
		Certificates:       []tls.Certificate{},
	}
	cert, err = tls.LoadX509KeyPair("fixtures/https/clientca/client3.crt", "fixtures/https/clientca/client3.key")
	c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
	tlsConfig.Certificates = append(tlsConfig.Certificates, cert)

	conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
	c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))
}

func startTestServer(port string, statusCode int) (ts *httptest.Server) {
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(statusCode)
	})
	listener, err := net.Listen("tcp", "127.0.0.1:"+port)
	if err != nil {
		panic(err)
	}

	ts = &httptest.Server{
		Listener: listener,
		Config:   &http.Server{Handler: handler},
	}
	ts.Start()
	return
}
<|endoftext|>


<commit_before>package main

// Google Code Jam 2016 Round 1C

import (
	"bytes"
	"fmt"
	"os"
	"runtime"
	"time"
)

var (
	pathIn = "/home/val/Téléchargements/"
	// pathIn   = "./"
	pathOut  = "./"
	letter   = "B"
	strategy = (*Case).solveSmall
	// strategy = (*Case).solveLarge
	// strategy   = (*Case).solveLargeAndCheck
	concurrent = false
	maxProc    = 4
)

// Put inputs here as global vars
var (
	B, M int
	mat  Matrix
	seen [2000000]bool
)

// Case data
type Case struct {
	caseNumber int
}

func (z *Case) readSingle() {
	check(!concurrent) // So we can use global vars
	B = readInt()
	M = readInt()
	seen = [2000000]bool{}
}

type Matrix [50][50]bool

func (m *Matrix) print() string {
	var buf bytes.Buffer
	for i := 0; i < B; i++ {
		for j := 0; j < B; j++ {
			c := "0"
			if m[i][j] {
				c = "1"
			}
			buf.WriteString(c)
		}
		if i < B-1 {
			buf.WriteString("\n")
		}
	}
	return buf.String()
}

func (m *Matrix) count() int {
	var c [50]int
	c[0] = 1
	for i := 0; i < B-1; i++ {
		for j := i; j < B; j++ {
			if m[i][j] {
				c[j] += c[i]
			}
		}
	}
	return c[B-1]
}

func (z *Case) solveSmall() interface{} {

	var rec func(int, int) string
	rec = func(i, j int) string {
		if i == B-1 {
			if mat.count() == M {
				return "POSSIBLE\n" + mat.print()
			}
			return ""
		}

		var ii, jj int
		if j == B-1 {
			ii, jj = i+1, i+2
		} else {
			ii, jj = i, j+1
		}
		a := rec(ii, jj)
		if a != "" {
			return a
		}

		mat[i][j] = true
		a = rec(ii, jj)
		if a != "" {
			return a
		}
		mat[i][j] = false
		return ""
	}
	answer := rec(0, 1)
	if answer == "" {
		return "IMPOSSIBLE"
	}
	return answer
}

func (z *Case) solveLarge() interface{} {
	return nil
}

// Global precomputed data (if needed)

func precompute() {
}

//
//
//
// NO NEED TO EDIT BELOW
//
//
//

func (z *Case) solveSingle() (answer interface{}) {
	defer func() {
		logf("------------ Case #%v: %v --------", z.caseNumber, answer)
	}()
	return strategy(z)
}

func (z *Case) solveLargeAndCheck() interface{} {
	// But make sure solveLarge is non-destructive!!
	sol1 := z.solveLarge()
	sol2 := z.solveSmall()
	if sol1 != sol2 {
		log("small = ", sol2, "; large = ", sol1)
		panic("Small and Large strategies must be equivalent")
	}
	return sol1
}

func solve() {
	if concurrent {
		runtime.GOMAXPROCS(maxProc)
	}

	top1 := time.Now() //.UnixNano()
	precompute()

	T := readInt()
	solutions := make([]chan interface{}, T)
	for i := range solutions {
		solutions[i] = make(chan interface{})
	}
	go func() {
		for i := range solutions {
			currentCase := &Case{caseNumber: 1 + i}
			currentCase.readSingle()
			if concurrent {
				go func(ch chan interface{}) {
					ch <- currentCase.solveSingle()
					close(ch)
				}(solutions[i])
			} else {
				solutions[i] <- currentCase.solveSingle()
				close(solutions[i])
			}
		}
	}()
	for i, ch := range solutions {
		solution := <-ch
		outf("Case #%v: %v\n", 1+i, solution)
	}
	duration := time.Since(top1)
	seconds := float64(duration) / 1000000000.0
	logf("Took %6.1fs \n", seconds)
}

func main() {
	if len(os.Args) < 2 {
		usage()
	}
	sample := os.Args[1]

	var fileIn = pathIn + letter + "-" + sample + ".in"
	var fileOut = pathOut + letter + "-" + sample + ".out"

	var err error
	input, err = os.Open(fileIn)
	if err != nil {
		panic(fmt.Sprintf("open %s: %v", fileIn, err))
	}
	output, err = os.Create(fileOut)
	if err != nil {
		panic(fmt.Sprintf("creating %s: %v", fileOut, err))
	}
	defer input.Close()
	defer output.Close()

	solve()
}

func usage() {
	logf("Usage: %v <sample> \n", os.Args[0])
	os.Exit(1)
}

var input *os.File
var output *os.File

func check(condition bool) {
	if !condition {
		panic("Failed!")
	}
}

func out(str string) {
	//	fmt.Print(str)
	fmt.Fprint(output, str)
}

func outf(pattern string, values ...interface{}) {
	str := fmt.Sprintf(pattern, values...)
	out(str)
}

func logf(str string, values ...interface{}) {
	fmt.Fprintf(os.Stderr, str, values...)
	fmt.Fprint(os.Stderr, "\n")
}

func log(values ...interface{}) {
	fmt.Fprintln(os.Stderr, values...)
}

func readInt() int {
	var i int
	fmt.Fscanf(input, "%d", &i)
	return i
}

func readString() string {
	var str string
	fmt.Fscanf(input, "%s", &str)
	return str
}

func readFloat() float64 {
	var x float64
	fmt.Fscanf(input, "%f", &x)
	return x
}
<commit_msg>GCJ 2016 round1C problem B: correct for small and large.<commit_after>package main

// Google Code Jam 2016 Round 1C

import (
	"bytes"
	"fmt"
	"os"
	"runtime"
	"time"
)

var (
	pathIn = "/home/valentin/Downloads/"
	// pathIn   = "./"
	pathOut = "./"
	letter  = "B"
	//strategy = (*Case).solveSmall
	strategy = (*Case).solveLarge
	// strategy   = (*Case).solveLargeAndCheck
	concurrent = false
	maxProc    = 4
)

// Put inputs here as global vars
var (
	B, M int
	mat  Matrix
	seen [2000000]bool
)

// Case data
type Case struct {
	caseNumber int
}

func (z *Case) readSingle() {
	check(!concurrent) // So we can use global vars
	B = readInt()
	M = readInt()
	seen = [2000000]bool{}
	mat = Matrix{}
}

type Matrix [50][50]bool

func (m *Matrix) print() string {
	var buf bytes.Buffer
	for i := 0; i < B; i++ {
		for j := 0; j < B; j++ {
			c := "0"
			if m[i][j] {
				c = "1"
			}
			buf.WriteString(c)
		}
		if i < B-1 {
			buf.WriteString("\n")
		}
	}
	return buf.String()
}

func (m *Matrix) count() int {
	var c [50]int
	c[0] = 1
	for i := 0; i < B-1; i++ {
		for j := i; j < B; j++ {
			if m[i][j] {
				c[j] += c[i]
			}
		}
	}
	return c[B-1]
}

func (z *Case) solveSmall() interface{} {

	var rec func(int, int) string
	rec = func(i, j int) string {
		if i == B-1 {
			if mat.count() == M {
				return "POSSIBLE\n" + mat.print()
			}
			return ""
		}

		var ii, jj int
		if j == B-1 {
			ii, jj = i+1, i+2
		} else {
			ii, jj = i, j+1
		}
		a := rec(ii, jj)
		if a != "" {
			return a
		}

		mat[i][j] = true
		a = rec(ii, jj)
		if a != "" {
			return a
		}
		mat[i][j] = false
		return ""
	}
	answer := rec(0, 1)
	if answer == "" {
		return "IMPOSSIBLE"
	}
	return answer
}

func (z *Case) solveLarge() interface{} {
	if M > pow(2, B-2) {
		return "IMPOSSIBLE"
	}

	for k := 0; k < B-1; k++ {
		mat[k][k+1] = true
	}
	// Now the "diagonal tangent" contains 1 path 1->2->...->B
	left := M - 1
	// Build full triangle : contains 2^X paths to "next building"
	p := 1
	j := 2
	for ; j < B && left >= p; j++ {
		for i := 0; i < j-1; i++ {
			mat[i][j] = true
		}
		left -= p
		p *= 2
	}
	// Build last, partial column
	if left > 0 {
		for i := j - 2; i >= 0; i-- {
			if left >= pow(2, i-1) {
				mat[i][j] = true
				left -= pow(2, i-1)
			} else {
			}
		}
	}
	check(left == 0)

	return "POSSIBLE\n" + mat.print()
}

func pow(a, b int) int {
	n := 1
	for i := 0; i < b; i++ {
		n *= a
	}
	return n
}

// Global precomputed data (if needed)

func precompute() {
}

//
//
//
// NO NEED TO EDIT BELOW
//
//
//

func (z *Case) solveSingle() (answer interface{}) {
	defer func() {
		logf("------------ Case #%v: %v --------", z.caseNumber, answer)
	}()
	return strategy(z)
}

func (z *Case) solveLargeAndCheck() interface{} {
	// But make sure solveLarge is non-destructive!!
	sol1 := z.solveLarge()
	sol2 := z.solveSmall()
	if sol1 != sol2 {
		log("small = ", sol2, "; large = ", sol1)
		panic("Small and Large strategies must be equivalent")
	}
	return sol1
}

func solve() {
	if concurrent {
		runtime.GOMAXPROCS(maxProc)
	}

	top1 := time.Now() //.UnixNano()
	precompute()

	T := readInt()
	solutions := make([]chan interface{}, T)
	for i := range solutions {
		solutions[i] = make(chan interface{})
	}
	go func() {
		for i := range solutions {
			currentCase := &Case{caseNumber: 1 + i}
			currentCase.readSingle()
			if concurrent {
				go func(ch chan interface{}) {
					ch <- currentCase.solveSingle()
					close(ch)
				}(solutions[i])
			} else {
				solutions[i] <- currentCase.solveSingle()
				close(solutions[i])
			}
		}
	}()
	for i, ch := range solutions {
		solution := <-ch
		outf("Case #%v: %v\n", 1+i, solution)
	}
	duration := time.Since(top1)
	seconds := float64(duration) / 1000000000.0
	logf("Took %6.1fs \n", seconds)
}

func main() {
	if len(os.Args) < 2 {
		usage()
	}
	sample := os.Args[1]

	var fileIn = pathIn + letter + "-" + sample + ".in"
	var fileOut = pathOut + letter + "-" + sample + ".out"

	var err error
	input, err = os.Open(fileIn)
	if err != nil {
		panic(fmt.Sprintf("open %s: %v", fileIn, err))
	}
	output, err = os.Create(fileOut)
	if err != nil {
		panic(fmt.Sprintf("creating %s: %v", fileOut, err))
	}
	defer input.Close()
	defer output.Close()

	solve()
}

func usage() {
	logf("Usage: %v <sample> \n", os.Args[0])
	os.Exit(1)
}

var input *os.File
var output *os.File

func check(condition bool) {
	if !condition {
		panic("Failed!")
	}
}

func out(str string) {
	//	fmt.Print(str)
	fmt.Fprint(output, str)
}

func outf(pattern string, values ...interface{}) {
	str := fmt.Sprintf(pattern, values...)
	out(str)
}

func logf(str string, values ...interface{}) {
	fmt.Fprintf(os.Stderr, str, values...)
	fmt.Fprint(os.Stderr, "\n")
}

func log(values ...interface{}) {
	fmt.Fprintln(os.Stderr, values...)
}

func readInt() int {
	var i int
	fmt.Fscanf(input, "%d", &i)
	return i
}

func readString() string {
	var str string
	fmt.Fscanf(input, "%s", &str)
	return str
}

func readFloat() float64 {
	var x float64
	fmt.Fscanf(input, "%f", &x)
	return x
}
<|endoftext|>


<commit_before>package openstack

import (
	"fmt"
	"log"
	"time"

	"github.com/gophercloud/gophercloud"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/policies"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceFWPolicyV1() *schema.Resource {
	return &schema.Resource{
		Create: resourceFWPolicyV1Create,
		Read:   resourceFWPolicyV1Read,
		Update: resourceFWPolicyV1Update,
		Delete: resourceFWPolicyV1Delete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"region": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				ForceNew:    true,
				DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""),
			},
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"description": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"audited": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"shared": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"tenant_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Computed: true,
			},
			"rules": &schema.Schema{
				Type:     schema.TypeList,
				Optional: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
			},
		},
	}
}

func resourceFWPolicyV1Create(d *schema.ResourceData, meta interface{}) error {

	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
	}

	v := d.Get("rules").([]interface{})

	log.Printf("[DEBUG] Rules found : %#v", v)
	log.Printf("[DEBUG] Rules count : %d", len(v))

	rules := make([]string, len(v))
	for i, v := range v {
		rules[i] = v.(string)
	}

	audited := d.Get("audited").(bool)
	shared := d.Get("shared").(bool)

	opts := policies.CreateOpts{
		Name:        d.Get("name").(string),
		Description: d.Get("description").(string),
		Audited:     &audited,
		Shared:      &shared,
		TenantID:    d.Get("tenant_id").(string),
		Rules:       rules,
	}

	log.Printf("[DEBUG] Create firewall policy: %#v", opts)

	policy, err := policies.Create(networkingClient, opts).Extract()
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Firewall policy created: %#v", policy)

	d.SetId(policy.ID)

	return resourceFWPolicyV1Read(d, meta)
}

func resourceFWPolicyV1Read(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG] Retrieve information about firewall policy: %s", d.Id())

	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
	}

	policy, err := policies.Get(networkingClient, d.Id()).Extract()
	if err != nil {
		return CheckDeleted(d, err, "FW policy")
	}

	log.Printf("[DEBUG] Read OpenStack Firewall Policy %s: %#v", d.Id(), policy)

	d.Set("name", policy.Name)
	d.Set("description", policy.Description)
	d.Set("shared", policy.Shared)
	d.Set("audited", policy.Audited)
	d.Set("tenant_id", policy.TenantID)
	d.Set("rules", policy.Rules)
	return nil
}

func resourceFWPolicyV1Update(d *schema.ResourceData, meta interface{}) error {

	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
	}

	opts := policies.UpdateOpts{}

	if d.HasChange("name") {
		opts.Name = d.Get("name").(string)
	}

	if d.HasChange("description") {
		opts.Description = d.Get("description").(string)
	}

	if d.HasChange("rules") {
		v := d.Get("rules").([]interface{})

		log.Printf("[DEBUG] Rules found : %#v", v)
		log.Printf("[DEBUG] Rules count : %d", len(v))

		rules := make([]string, len(v))
		for i, v := range v {
			rules[i] = v.(string)
		}
		opts.Rules = rules
	}

	log.Printf("[DEBUG] Updating firewall policy with id %s: %#v", d.Id(), opts)

	err = policies.Update(networkingClient, d.Id(), opts).Err
	if err != nil {
		return err
	}

	return resourceFWPolicyV1Read(d, meta)
}

func resourceFWPolicyV1Delete(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG] Destroy firewall policy: %s", d.Id())

	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
	}

	for i := 0; i < 15; i++ {

		err = policies.Delete(networkingClient, d.Id()).Err
		if err == nil {
			break
		}

		if _, ok := err.(gophercloud.ErrDefault404); ok {
			return nil
		}

		if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok {
			if errCode.Actual == 409 {
				// This error usually means that the policy is attached
				// to a firewall. At this point, the firewall is probably
				// being delete. So, we retry a few times.
				time.Sleep(time.Second * 2)
				continue
			}
		}

		return err
	}

	return nil
}
<commit_msg>provider/openstack: gophercloud migration: Allow Firewall v1 Policy to cleanly delete<commit_after>package openstack

import (
	"fmt"
	"log"
	"time"

	"github.com/gophercloud/gophercloud"
	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/policies"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceFWPolicyV1() *schema.Resource {
	return &schema.Resource{
		Create: resourceFWPolicyV1Create,
		Read:   resourceFWPolicyV1Read,
		Update: resourceFWPolicyV1Update,
		Delete: resourceFWPolicyV1Delete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"region": &schema.Schema{
				Type:        schema.TypeString,
				Required:    true,
				ForceNew:    true,
				DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""),
			},
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"description": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"audited": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"shared": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},
			"tenant_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Computed: true,
			},
			"rules": &schema.Schema{
				Type:     schema.TypeList,
				Optional: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
			},
		},
	}
}

func resourceFWPolicyV1Create(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
	}

	v := d.Get("rules").([]interface{})

	log.Printf("[DEBUG] Rules found : %#v", v)
	log.Printf("[DEBUG] Rules count : %d", len(v))

	rules := make([]string, len(v))
	for i, v := range v {
		rules[i] = v.(string)
	}

	audited := d.Get("audited").(bool)
	shared := d.Get("shared").(bool)

	opts := policies.CreateOpts{
		Name:        d.Get("name").(string),
		Description: d.Get("description").(string),
		Audited:     &audited,
		Shared:      &shared,
		TenantID:    d.Get("tenant_id").(string),
		Rules:       rules,
	}

	log.Printf("[DEBUG] Create firewall policy: %#v", opts)

	policy, err := policies.Create(networkingClient, opts).Extract()
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Firewall policy created: %#v", policy)

	d.SetId(policy.ID)

	return resourceFWPolicyV1Read(d, meta)
}

func resourceFWPolicyV1Read(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG] Retrieve information about firewall policy: %s", d.Id())

	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
	}

	policy, err := policies.Get(networkingClient, d.Id()).Extract()
	if err != nil {
		return CheckDeleted(d, err, "FW policy")
	}

	log.Printf("[DEBUG] Read OpenStack Firewall Policy %s: %#v", d.Id(), policy)

	d.Set("name", policy.Name)
	d.Set("description", policy.Description)
	d.Set("shared", policy.Shared)
	d.Set("audited", policy.Audited)
	d.Set("tenant_id", policy.TenantID)
	d.Set("rules", policy.Rules)
	return nil
}

func resourceFWPolicyV1Update(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
	}

	opts := policies.UpdateOpts{}

	if d.HasChange("name") {
		opts.Name = d.Get("name").(string)
	}

	if d.HasChange("description") {
		opts.Description = d.Get("description").(string)
	}

	if d.HasChange("rules") {
		v := d.Get("rules").([]interface{})

		log.Printf("[DEBUG] Rules found : %#v", v)
		log.Printf("[DEBUG] Rules count : %d", len(v))

		rules := make([]string, len(v))
		for i, v := range v {
			rules[i] = v.(string)
		}
		opts.Rules = rules
	}

	log.Printf("[DEBUG] Updating firewall policy with id %s: %#v", d.Id(), opts)

	err = policies.Update(networkingClient, d.Id(), opts).Err
	if err != nil {
		return err
	}

	return resourceFWPolicyV1Read(d, meta)
}

func resourceFWPolicyV1Delete(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG] Destroy firewall policy: %s", d.Id())

	config := meta.(*Config)
	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
	if err != nil {
		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
	}

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"ACTIVE"},
		Target:     []string{"DELETED"},
		Refresh:    waitForFirewallPolicyDeletion(networkingClient, d.Id()),
		Timeout:    120 * time.Second,
		Delay:      0,
		MinTimeout: 2 * time.Second,
	}

	if _, err = stateConf.WaitForState(); err != nil {
		return err
	}

	return nil
}

func waitForFirewallPolicyDeletion(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		err := policies.Delete(networkingClient, id).Err
		if err == nil {
			return "", "DELETED", nil
		}

		if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok {
			if errCode.Actual == 409 {
				// This error usually means that the policy is attached
				// to a firewall. At this point, the firewall is probably
				// being delete. So, we retry a few times.
				return nil, "ACTIVE", nil
			}
		}

		return nil, "ACTIVE", err
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package fs

import (
	"errors"
	"fmt"
	"log"
	"os"
	"path"
	"time"

	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/syncutil"
	"github.com/jacobsa/gcsfuse/timeutil"
	"golang.org/x/net/context"
	"google.golang.org/cloud/storage"

	"bazil.org/fuse"
	fusefs "bazil.org/fuse/fs"
)

const dirSeparator = '/'

// Implementation detail, do not touch.
//
// How long we cache the most recent listing for a particular directory from
// GCS before regarding it as stale.
//
// Intended to paper over performance issues caused by quick follow-up calls;
// for example when the fuse VFS performs a readdir followed quickly by a
// lookup for each child. The drawback is that this increases the time before a
// write by a foreign machine within a recently-listed directory will be seen
// locally.
//
// TODO(jacobsa): Set this according to real-world performance issues when the
// kernel does e.g. ReadDir followed by LookUp. Can probably be set quite
// small.
//
// TODO(jacobsa): Can this be moved to a decorator implementation of gcs.Bucket
// instead of living here?
var ListingCacheTTL = 10 * time.Second

// Implementation detail, do not touch.
//
// How long we remember that we took some action on the contents of a directory
// (linking or unlinking), and pretend the action is reflected in the listing
// even if it is not.
//
// Intended to paper over the fact that GCS doesn't offer list-your-own-writes
// consistency: it may be an arbitrarily long time before you see the creation
// or deletion of an object in a subsequent listing, and even if you see it in
// one listing you may not in the next. The drawback is that modifications to
// recently-modified directories by foreign machines will not be reflected
// locally for awhile.
//
// TODO(jacobsa): Set this according to information about listing staleness
// distributions from the GCS team.
//
// TODO(jacobsa): Can this be moved to a decorator implementation of gcs.Bucket
// instead of living here?
var ChildActionMemoryTTL = 5 * time.Minute

// A "directory" in GCS, defined by an object name prefix.
//
// For example, if the bucket contains objects "foo/bar" and "foo/baz", this
// implicitly defines the directory "foo/". No matter what the contents of the
// bucket, there is an implicit root directory "".
type dir struct {
	/////////////////////////
	// Dependencies
	/////////////////////////

	logger *log.Logger
	clock  timeutil.Clock
	bucket gcs.Bucket

	/////////////////////////
	// Constant data
	/////////////////////////

	// INVARIANT: objectPrefix is "" (representing the root directory) or ends
	// with dirSeparator.
	objectPrefix string

	/////////////////////////
	// Mutable state
	/////////////////////////

	// TODO(jacobsa): Make sure to initialize this correctly.
	fixmemu syncutil.InvariantMutex

	// A cache of the most recent listing of the directory from GCS, expressed as
	// a map from (relative) names of children of this directory to nodes for
	// those children. May be nil if there is no most recent listing or if the
	// listing expired (see below).
	//
	// The time at which the listing completed is also stored. If clock.Now()
	// minus this time is more than ListingCacheTTL, the most recent listing
	// should not be used for any purpose.
	//
	// INVARIANT: All nodes are of type *dir or *file.
	mostRecentListing     map[string]fusefs.Node // GUARDED_BY(mu)
	mostRecentListingTime time.Time              // GUARDED_BY(mu)

	// A collection of children that have recently been added locally and the
	// time at which it happened. For a record R in this list with R's age less
	// than ChildActionMemoryTTL, any listing from the bucket should be augmented
	// by adding R, overwriting it if its name already exists. See
	// ChildActionMemoryTTL for more info.
	//
	// TODO(jacobsa): Make sure to test link followed by unlink, and unlink
	// followed by link.
	//
	// INVARIANT: All nodes are of type *dir or *file.
	childAdditions []childAddition // GUARDED_BY(mu)

	// A collection of children that have recently been removed locally and the
	// time at which it happened. For a record R in this list with R's age less
	// than ChildActionMemoryTTL, any listing from the bucket should be augmented
	// by removing any child with the name given by R. See ChildActionMemoryTTL
	// for more info.
	childRemovals []childRemoval // GUARDED_BY(mu)
}

// Make sure dir implements the interfaces we think it does.
var (
	_ fusefs.Node               = &dir{}
	_ fusefs.NodeCreater        = &dir{}
	_ fusefs.NodeMknoder        = &dir{}
	_ fusefs.NodeStringLookuper = &dir{}

	_ fusefs.Handle             = &dir{}
	_ fusefs.HandleReadDirAller = &dir{}
)

func newDir(
	logger *log.Logger,
	clock timeutil.Clock,
	bucket gcs.Bucket,
	objectPrefix string) *dir {
	return &dir{
		logger:       logger,
		clock:        clock,
		bucket:       bucket,
		objectPrefix: objectPrefix,
	}
}

// Initialize d.children from GCS if it has not already been populated or has
// expired.
//
// EXCLUSIVE_LOCKS_REQUIRED(d.mu)
func (d *dir) initChildren(ctx context.Context) error {
	// Have we already initialized the map and is it up to date?
	if d.children != nil && d.clock.Now().Before(d.childrenExpiry) {
		return nil
	}

	children := make(map[string]fusefs.Node)

	// List repeatedly until there is no more to list.
	query := &storage.Query{
		Delimiter: string(dirSeparator),
		Prefix:    d.objectPrefix,
	}

	for query != nil {
		// Grab one set of results.
		objects, err := d.bucket.ListObjects(ctx, query)
		if err != nil {
			return fmt.Errorf("bucket.ListObjects: %v", err)
		}

		// Extract objects as files.
		for _, o := range objects.Results {
			// Special case: the GCS storage browser's "New folder" button causes an
			// object with a trailing slash to be created. For example, if you make a
			// folder called "bar" within a folder called "foo", that creates an
			// object called "foo/bar/". (It seems like the redundant ones may be
			// removed eventually, but that's not relevant.)
			//
			// When we list the directory "foo/", we don't want to return the object
			// named "foo/" as if it were a file within the directory. So skip it.
			if o.Name == d.objectPrefix {
				continue
			}

			children[path.Base(o.Name)] =
				newFile(
					d.logger,
					d.bucket,
					o.Name,
					uint64(o.Size))
		}

		// Extract prefixes as directories.
		for _, p := range objects.Prefixes {
			children[path.Base(p)] = newDir(d.logger, d.clock, d.bucket, p)
		}

		// Move on to the next set of results.
		query = objects.Next
	}

	// Save the map.
	d.children = children
	d.childrenExpiry = d.clock.Now().Add(DirListingCacheTTL)

	return nil
}

func (d *dir) Attr() fuse.Attr {
	return fuse.Attr{
		// TODO(jacobsa): Expose ACLs from GCS?
		Mode: os.ModeDir | 0500,
	}
}

func (d *dir) ReadDirAll(ctx context.Context) (
	ents []fuse.Dirent, err error) {
	d.mu.Lock()
	defer d.mu.Unlock()

	d.logger.Printf("ReadDirAll: [%s]/%s", d.bucket.Name(), d.objectPrefix)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		return nil, fmt.Errorf("d.initChildren: %v", err)
	}

	// Read out the contents of the cache.
	for name, node := range d.children {
		ent := fuse.Dirent{
			Name: name,
		}

		if _, ok := node.(*dir); ok {
			ent.Type = fuse.DT_Dir
		} else {
			ent.Type = fuse.DT_File
		}

		ents = append(ents, ent)
	}

	return
}

func (d *dir) Lookup(ctx context.Context, name string) (fusefs.Node, error) {
	d.mu.Lock()
	defer d.mu.Unlock()

	d.logger.Printf("Lookup: ([%s]/%s) %s", d.bucket.Name(), d.objectPrefix, name)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		return nil, fmt.Errorf("d.initChildren: %v", err)
	}

	// Find the object within the map.
	if n, ok := d.children[name]; ok {
		return n, nil
	}

	return nil, fuse.ENOENT
}

func (d *dir) Create(
	ctx context.Context,
	req *fuse.CreateRequest,
	resp *fuse.CreateResponse) (
	fusefs.Node,
	fusefs.Handle,
	error) {
	// Tell fuse to use Mknod followed by Open, rather than re-implementing much
	// of Open here.
	return nil, nil, fuse.ENOSYS
}

func (d *dir) Mknod(
	ctx context.Context,
	req *fuse.MknodRequest) (fusefs.Node, error) {
	return nil, errors.New("TODO(jacobsa): Support Mknod.")
}
<commit_msg>Revised dir data structures.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package fs

import (
	"container/list"
	"errors"
	"fmt"
	"log"
	"os"
	"path"
	"time"

	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/syncutil"
	"github.com/jacobsa/gcsfuse/timeutil"
	"golang.org/x/net/context"
	"google.golang.org/cloud/storage"

	"bazil.org/fuse"
	fusefs "bazil.org/fuse/fs"
)

const dirSeparator = '/'

// Implementation detail, do not touch.
//
// How long we cache the most recent listing for a particular directory from
// GCS before regarding it as stale.
//
// Intended to paper over performance issues caused by quick follow-up calls;
// for example when the fuse VFS performs a readdir followed quickly by a
// lookup for each child. The drawback is that this increases the time before a
// write by a foreign machine within a recently-listed directory will be seen
// locally.
//
// TODO(jacobsa): Set this according to real-world performance issues when the
// kernel does e.g. ReadDir followed by LookUp. Can probably be set quite
// small.
//
// TODO(jacobsa): Can this be moved to a decorator implementation of gcs.Bucket
// instead of living here?
var ListingCacheTTL = 10 * time.Second

// Implementation detail, do not touch.
//
// How long we remember that we took some action on the contents of a directory
// (linking or unlinking), and pretend the action is reflected in the listing
// even if it is not.
//
// Intended to paper over the fact that GCS doesn't offer list-your-own-writes
// consistency: it may be an arbitrarily long time before you see the creation
// or deletion of an object in a subsequent listing, and even if you see it in
// one listing you may not in the next. The drawback is that modifications to
// recently-modified directories by foreign machines will not be reflected
// locally for awhile.
//
// TODO(jacobsa): Set this according to information about listing staleness
// distributions from the GCS team.
//
// TODO(jacobsa): Can this be moved to a decorator implementation of gcs.Bucket
// instead of living here?
var ChildActionMemoryTTL = 5 * time.Minute

// See the childAdditions field of dir.
type childAddition struct {
	time time.Time
	name string

	// INVARIANT: Of type *file or *dir.
	node fusefs.Node
}

// A "directory" in GCS, defined by an object name prefix.
//
// For example, if the bucket contains objects "foo/bar" and "foo/baz", this
// implicitly defines the directory "foo/". No matter what the contents of the
// bucket, there is an implicit root directory "".
type dir struct {
	/////////////////////////
	// Dependencies
	/////////////////////////

	logger *log.Logger
	clock  timeutil.Clock
	bucket gcs.Bucket

	/////////////////////////
	// Constant data
	/////////////////////////

	// INVARIANT: objectPrefix is "" (representing the root directory) or ends
	// with dirSeparator.
	objectPrefix string

	/////////////////////////
	// Mutable state
	/////////////////////////

	// TODO(jacobsa): Make sure to initialize this correctly.
	fixmemu syncutil.InvariantMutex

	// Our current best understanding of the contents of the directory in GCS,
	// formed by listing the bucket and then patching according to child addition
	// and removal records at the time, and patched since then by subsequent
	// additions and removals. May be nil if no listing has happened or the
	// listing expired (see below).
	//
	// The time after which this should be generated anew from a new listing is
	// also stored. This is set to the time at which the listing completed plus
	// ListingCacheTTL.
	//
	// INVARIANT: All nodes are of type *dir or *file.
	// INVARIANT: All nodes are indexed by names that agree with node contents.
	contents           map[string]fusefs.Node // GUARDED_BY(mu)
	contentsExpiration time.Time              // GUARDED_BY(mu)

	// A collection of children that have recently been added locally and the
	// time at which it happened, ordered by the sequence in which it happened.
	// For a record R in this list with R's age less than ChildActionMemoryTTL,
	// any listing from the bucket should be augmented by adding R, overwriting
	// it if its name already exists. See ChildActionMemoryTTL for more info.
	//
	// TODO(jacobsa): Make sure to test link followed by unlink, and unlink
	// followed by link.
	//
	// TODO(jacobsa): Make sure to test that these expire eventually, i.e. that
	// foreign overwrites and deletes are reflected eventually.
	//
	// INVARIANT: All elements are of type childAddition.
	// INVARIANT: Contains no duplicate names.
	// INVARIANT: If contents != nil, then for all A, contents[A.name] == A.node
	childAdditions list.List // GUARDED_BY(mu)

	// An index of childAdditions by name.
	//
	// INVARIANT: For all names N in the map, the indexed addition has name N.
	// INVARIANT: Contains exactly the set of names in childAdditions.
	childAdditionsIndex map[string]*list.Element

	// A collection of children that have recently been removed locally and the
	// time at which it happened, ordered by the sequence in which it happened.
	// For a record R in this list with R's age less than ChildActionMemoryTTL,
	// any listing from the bucket should be augmented by removing any child with
	// the name given by R. See ChildActionMemoryTTL for more info.
	//
	// TODO(jacobsa): Make sure to test that these expire eventually, i.e. that
	// foreign re-creates are reflected eventually.
	//
	// INVARIANT: All elements are of type childRemoval.
	// INVARIANT: Contains no duplicate names.
	// INVARIANT: Contains no overlap in names with childAdditions.
	// INVARIANT: For all R, contents does not contain R.name.
	childRemovals list.List // GUARDED_BY(mu)

	// An index of childRemovals by name.
	//
	// INVARIANT: For all names N in the map, the indexed removal has name N.
	// INVARIANT: Contains exactly the set of names in childRemovals.
	childRemovalsIndex map[string]*list.Element
}

// Make sure dir implements the interfaces we think it does.
var (
	_ fusefs.Node               = &dir{}
	_ fusefs.NodeCreater        = &dir{}
	_ fusefs.NodeMknoder        = &dir{}
	_ fusefs.NodeStringLookuper = &dir{}

	_ fusefs.Handle             = &dir{}
	_ fusefs.HandleReadDirAller = &dir{}
)

func newDir(
	logger *log.Logger,
	clock timeutil.Clock,
	bucket gcs.Bucket,
	objectPrefix string) *dir {
	return &dir{
		logger:       logger,
		clock:        clock,
		bucket:       bucket,
		objectPrefix: objectPrefix,
	}
}

// Initialize d.children from GCS if it has not already been populated or has
// expired.
//
// EXCLUSIVE_LOCKS_REQUIRED(d.mu)
func (d *dir) initChildren(ctx context.Context) error {
	// Have we already initialized the map and is it up to date?
	if d.children != nil && d.clock.Now().Before(d.childrenExpiry) {
		return nil
	}

	children := make(map[string]fusefs.Node)

	// List repeatedly until there is no more to list.
	query := &storage.Query{
		Delimiter: string(dirSeparator),
		Prefix:    d.objectPrefix,
	}

	for query != nil {
		// Grab one set of results.
		objects, err := d.bucket.ListObjects(ctx, query)
		if err != nil {
			return fmt.Errorf("bucket.ListObjects: %v", err)
		}

		// Extract objects as files.
		for _, o := range objects.Results {
			// Special case: the GCS storage browser's "New folder" button causes an
			// object with a trailing slash to be created. For example, if you make a
			// folder called "bar" within a folder called "foo", that creates an
			// object called "foo/bar/". (It seems like the redundant ones may be
			// removed eventually, but that's not relevant.)
			//
			// When we list the directory "foo/", we don't want to return the object
			// named "foo/" as if it were a file within the directory. So skip it.
			if o.Name == d.objectPrefix {
				continue
			}

			children[path.Base(o.Name)] =
				newFile(
					d.logger,
					d.bucket,
					o.Name,
					uint64(o.Size))
		}

		// Extract prefixes as directories.
		for _, p := range objects.Prefixes {
			children[path.Base(p)] = newDir(d.logger, d.clock, d.bucket, p)
		}

		// Move on to the next set of results.
		query = objects.Next
	}

	// Save the map.
	d.children = children
	d.childrenExpiry = d.clock.Now().Add(DirListingCacheTTL)

	return nil
}

func (d *dir) Attr() fuse.Attr {
	return fuse.Attr{
		// TODO(jacobsa): Expose ACLs from GCS?
		Mode: os.ModeDir | 0500,
	}
}

func (d *dir) ReadDirAll(ctx context.Context) (
	ents []fuse.Dirent, err error) {
	d.mu.Lock()
	defer d.mu.Unlock()

	d.logger.Printf("ReadDirAll: [%s]/%s", d.bucket.Name(), d.objectPrefix)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		return nil, fmt.Errorf("d.initChildren: %v", err)
	}

	// Read out the contents of the cache.
	for name, node := range d.children {
		ent := fuse.Dirent{
			Name: name,
		}

		if _, ok := node.(*dir); ok {
			ent.Type = fuse.DT_Dir
		} else {
			ent.Type = fuse.DT_File
		}

		ents = append(ents, ent)
	}

	return
}

func (d *dir) Lookup(ctx context.Context, name string) (fusefs.Node, error) {
	d.mu.Lock()
	defer d.mu.Unlock()

	d.logger.Printf("Lookup: ([%s]/%s) %s", d.bucket.Name(), d.objectPrefix, name)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		return nil, fmt.Errorf("d.initChildren: %v", err)
	}

	// Find the object within the map.
	if n, ok := d.children[name]; ok {
		return n, nil
	}

	return nil, fuse.ENOENT
}

func (d *dir) Create(
	ctx context.Context,
	req *fuse.CreateRequest,
	resp *fuse.CreateResponse) (
	fusefs.Node,
	fusefs.Handle,
	error) {
	// Tell fuse to use Mknod followed by Open, rather than re-implementing much
	// of Open here.
	return nil, nil, fuse.ENOSYS
}

func (d *dir) Mknod(
	ctx context.Context,
	req *fuse.MknodRequest) (fusefs.Node, error) {
	return nil, errors.New("TODO(jacobsa): Support Mknod.")
}
<|endoftext|>


<commit_before>package pearl

import (
	"crypto/rsa"
	"net"
	"time"

	"github.com/mmcloughlin/pearl/log"
	"github.com/mmcloughlin/pearl/meta"
	"github.com/mmcloughlin/pearl/torconfig"
	"github.com/mmcloughlin/pearl/torcrypto"
	"github.com/mmcloughlin/pearl/tordir"
	"github.com/mmcloughlin/pearl/torexitpolicy"
	"github.com/pkg/errors"
	"github.com/uber-go/tally"
)

// Router is a Tor router.
type Router struct {
	config      *torconfig.Config
	fingerprint []byte

	connections *ConnectionManager

	metrics *Metrics
	scope   tally.Scope
	logger  log.Logger
}

// TODO(mbm): determine which parts of Router struct are required for client and
// server. Perhaps a stripped down struct can be used for client-only.

// NewRouter constructs a router based on the given config.
func NewRouter(config *torconfig.Config, scope tally.Scope, logger log.Logger) (*Router, error) {
	fingerprint, err := torcrypto.Fingerprint(&config.Keys.Identity.PublicKey)
	if err != nil {
		return nil, errors.Wrap(err, "failed to compute fingerprint")
	}

	logger = log.ForComponent(logger, "router")
	return &Router{
		config:      config,
		fingerprint: fingerprint,
		connections: NewConnectionManager(),
		metrics:     NewMetrics(scope, logger),
		scope:       scope,
		logger:      logger,
	}, nil
}

// IdentityKey returns the identity key of the router.
func (r *Router) IdentityKey() *rsa.PrivateKey {
	return r.config.Keys.Identity
}

// Fingerprint returns the router fingerprint.
func (r *Router) Fingerprint() []byte {
	return r.fingerprint
}

// Serve starts a listener and enters a main loop handling connections.
func (r *Router) Serve() error {
	laddr := r.config.ORBindAddr()
	r.logger.With("laddr", laddr).Info("creating listener")
	ln, err := net.Listen("tcp", laddr)
	if err != nil {
		return errors.Wrap(err, "could not create listener")
	}

	for {
		conn, err := ln.Accept()
		if err != nil {
			return errors.Wrap(err, "error accepting connection")
		}

		c, err := NewServer(r, conn, r.logger)
		if err != nil {
			return errors.Wrap(err, "error building connection")
		}

		go func() {
			if err := c.Serve(); err != nil {
				log.Err(r.logger, err, "error serving connection")
			}
		}()
	}
}

func (r *Router) Connect(raddr string) (*Connection, error) {
	conn, err := net.Dial("tcp", raddr)
	if err != nil {
		return nil, errors.Wrap(err, "dial failed")
	}

	c, err := NewClient(r, conn, r.logger)
	if err != nil {
		return nil, errors.Wrap(err, "building connection failed")
	}

	// TODO(mbm): should we be calling this here?
	err = c.StartClient()
	if err != nil {
		return nil, errors.Wrap(err, "error starting client")
	}

	return c, nil
}

// Connection returns a connection to the indicated relay. Returns an existing
// connection, if it exists. Otherwise opens a connection and returns it.
func (r *Router) Connection(hint ConnectionHint) (*Connection, error) {
	fp, err := hint.Fingerprint()
	if err != nil {
		return nil, errors.Wrap(err, "missing fingerprint from connection hint")
	}

	if conn, ok := r.connections.Connection(fp); ok {
		return conn, nil
	}

	addrs, err := hint.Addresses()
	if err != nil {
		return nil, errors.Wrap(err, "no addresses provided")
	}

	for _, addr := range addrs {
		raddr := addr.String()
		conn, err := r.Connect(raddr)
		if err != nil {
			log.WithErr(r.logger, err).Warn("connection attempt failed")
			continue
		}
		return conn, nil
	}

	return nil, errors.New("all connection attempts failed")
}

// Descriptor returns a server descriptor for this router.
func (r *Router) Descriptor() (*tordir.ServerDescriptor, error) {
	s := tordir.NewServerDescriptor()

	if err := s.SetRouter(r.config.Nickname, r.config.IP, r.config.ORPort, 0); err != nil {
		return nil, err
	}
	if err := s.SetSigningKey(r.IdentityKey()); err != nil {
		return nil, err
	}
	if err := s.SetOnionKey(&r.config.Keys.Onion.PublicKey); err != nil {
		return nil, err
	}

	s.SetNtorOnionKey(r.config.Keys.Ntor)
	s.SetPlatform(r.config.Platform)
	s.SetContact(r.config.Contact)
	// TODO(mbm): publish real bandwidth values
	s.SetBandwidth(r.config.BandwidthAverage, r.config.BandwidthBurst, r.config.BandwidthAverage)
	s.SetPublishedTime(time.Now())
	s.SetExitPolicy(torexitpolicy.RejectAllPolicy)
	s.SetProtocols(meta.Protocols)

	return s, nil
}
<commit_msg>set uptime field in descriptor<commit_after>package pearl

import (
	"crypto/rsa"
	"net"
	"time"

	"github.com/mmcloughlin/pearl/log"
	"github.com/mmcloughlin/pearl/meta"
	"github.com/mmcloughlin/pearl/torconfig"
	"github.com/mmcloughlin/pearl/torcrypto"
	"github.com/mmcloughlin/pearl/tordir"
	"github.com/mmcloughlin/pearl/torexitpolicy"
	"github.com/pkg/errors"
	"github.com/uber-go/tally"
)

// Router is a Tor router.
type Router struct {
	config      *torconfig.Config
	startTime   time.Time
	fingerprint []byte

	connections *ConnectionManager

	metrics *Metrics
	scope   tally.Scope
	logger  log.Logger
}

// TODO(mbm): determine which parts of Router struct are required for client and
// server. Perhaps a stripped down struct can be used for client-only.

// NewRouter constructs a router based on the given config.
func NewRouter(config *torconfig.Config, scope tally.Scope, logger log.Logger) (*Router, error) {
	fingerprint, err := torcrypto.Fingerprint(&config.Keys.Identity.PublicKey)
	if err != nil {
		return nil, errors.Wrap(err, "failed to compute fingerprint")
	}

	logger = log.ForComponent(logger, "router")
	return &Router{
		config:      config,
		startTime:   time.Now(),
		fingerprint: fingerprint,
		connections: NewConnectionManager(),
		metrics:     NewMetrics(scope, logger),
		scope:       scope,
		logger:      logger,
	}, nil
}

// IdentityKey returns the identity key of the router.
func (r *Router) IdentityKey() *rsa.PrivateKey {
	return r.config.Keys.Identity
}

// Fingerprint returns the router fingerprint.
func (r *Router) Fingerprint() []byte {
	return r.fingerprint
}

// Serve starts a listener and enters a main loop handling connections.
func (r *Router) Serve() error {
	laddr := r.config.ORBindAddr()
	r.logger.With("laddr", laddr).Info("creating listener")
	ln, err := net.Listen("tcp", laddr)
	if err != nil {
		return errors.Wrap(err, "could not create listener")
	}

	for {
		conn, err := ln.Accept()
		if err != nil {
			return errors.Wrap(err, "error accepting connection")
		}

		c, err := NewServer(r, conn, r.logger)
		if err != nil {
			return errors.Wrap(err, "error building connection")
		}

		go func() {
			if err := c.Serve(); err != nil {
				log.Err(r.logger, err, "error serving connection")
			}
		}()
	}
}

func (r *Router) Connect(raddr string) (*Connection, error) {
	conn, err := net.Dial("tcp", raddr)
	if err != nil {
		return nil, errors.Wrap(err, "dial failed")
	}

	c, err := NewClient(r, conn, r.logger)
	if err != nil {
		return nil, errors.Wrap(err, "building connection failed")
	}

	// TODO(mbm): should we be calling this here?
	err = c.StartClient()
	if err != nil {
		return nil, errors.Wrap(err, "error starting client")
	}

	return c, nil
}

// Connection returns a connection to the indicated relay. Returns an existing
// connection, if it exists. Otherwise opens a connection and returns it.
func (r *Router) Connection(hint ConnectionHint) (*Connection, error) {
	fp, err := hint.Fingerprint()
	if err != nil {
		return nil, errors.Wrap(err, "missing fingerprint from connection hint")
	}

	if conn, ok := r.connections.Connection(fp); ok {
		return conn, nil
	}

	addrs, err := hint.Addresses()
	if err != nil {
		return nil, errors.Wrap(err, "no addresses provided")
	}

	for _, addr := range addrs {
		raddr := addr.String()
		conn, err := r.Connect(raddr)
		if err != nil {
			log.WithErr(r.logger, err).Warn("connection attempt failed")
			continue
		}
		return conn, nil
	}

	return nil, errors.New("all connection attempts failed")
}

// Descriptor returns a server descriptor for this router.
func (r *Router) Descriptor() (*tordir.ServerDescriptor, error) {
	s := tordir.NewServerDescriptor()

	if err := s.SetRouter(r.config.Nickname, r.config.IP, r.config.ORPort, 0); err != nil {
		return nil, err
	}
	if err := s.SetSigningKey(r.IdentityKey()); err != nil {
		return nil, err
	}
	if err := s.SetOnionKey(&r.config.Keys.Onion.PublicKey); err != nil {
		return nil, err
	}

	s.SetNtorOnionKey(r.config.Keys.Ntor)
	s.SetPlatform(r.config.Platform)
	s.SetContact(r.config.Contact)
	// TODO(mbm): publish real bandwidth values
	s.SetBandwidth(r.config.BandwidthAverage, r.config.BandwidthBurst, r.config.BandwidthAverage)
	s.SetPublishedTime(time.Now())
	s.SetUptime(time.Since(r.startTime))
	s.SetExitPolicy(torexitpolicy.RejectAllPolicy)
	s.SetProtocols(meta.Protocols)

	return s, nil
}
<|endoftext|>


<commit_before>package arn

// Spoiler represents a text that can spoil a future event.
type Spoiler struct {
	Text string `json:"text" editable:"true" type:"textarea"`
}
<commit_msg>Added string serializer for spoilers<commit_after>package arn

// Spoiler represents a text that can spoil a future event.
type Spoiler struct {
	Text string `json:"text" editable:"true" type:"textarea"`
}

// String returns the containing text.
func (spoiler *Spoiler) String() string {
	return spoiler.Text
}
<|endoftext|>