<commit_before>package main

import (
	"fmt"
	"testing"
	"time"
)

const (
	LED      = 5  // Pin 29
	RELAY    = 13 // Pin 33
	CAP4700  = 19 // Pin 35: Also PCM capable
	CAP10000 = 6  // Pin 31
	SWITCH   = 26 // Pin 37
)

func GpioStr(g PiPin) string {
	switch g.Pin() {
	case LED:
		return "LED"
	case RELAY:
		return "RELAY"
	case CAP4700:
		return "CAP4700"
	case CAP10000:
		return "CAP10000"
	case SWITCH:
		return "SWITCH"
	default:
		return "UNKNOWN"
	}
	return ""
}

var Led PiPin        // Setup: GPIO -> <1k Resistor -> LED -> GND
var TestRelay *Relay // Setup GPIO -> 4.7k Resistor -> Relay Board
var Cap4700 PiPin    // Setup: +3.3v -> 4.7k Resistor -> GPIO -> 10uF capacitor -> GND
var Cap10000 PiPin   // Setup: +3.3v -> 10k Resistor -> GPIO -> 10uF capacitor -> GND
var Switch PiPin     // Setup: GPIO -> Button Switch -> GND

func ExpectedState(t *testing.T, gpio PiPin, exp GpioState) {
	if val := gpio.Read(); val != exp {
		t.Errorf("%s: Expected %s but found %s", GpioStr(gpio), exp, val)
	}
}

func TestInitilization(t *testing.T) {
	err := GpioInit()
	t.Run("Init Host", func(t *testing.T) {
		if err != nil {
			t.Errorf("Problem initializing gpio: %s", err.Error())
		}
	})

	// Initialized GPIOs
	Led = NewGpio(LED)
	Led.Output(Low)
	ExpectedState(t, Led, Low)
}

func TestBlinkLed(t *testing.T) {
	Info("Running %s", t.Name())
	for i := 0; i < 6; i++ {
		time.Sleep(time.Second / 5)
		Led.Output(High)
		ExpectedState(t, Led, High)
		time.Sleep(time.Second / 5)
		Led.Output(Low)
		ExpectedState(t, Led, Low)
	}
}

func doStop(button *Button, b *bool, t time.Time) {
	*b = false
	button.Stop()
	*b = true
	Info("doStop - Stopped after %d ms", time.Now().Sub(t)/time.Millisecond)
}

func runRelayTestOn(t *testing.T, relay *Relay) {
	relay.TurnOn()
	Info("Testing Relay On: %s is %s", relay.Name(), relay.Status())
	if !relay.isOn() {
		t.Errorf("Relay(%s) is %s", relay.Name(), relay.Status())
	}
}

func runRelayTestOff(t *testing.T, relay *Relay) {
	relay.TurnOff()
	Info("Testing Relay Off: %s is %s", relay.Name(), relay.Status())
	if relay.isOn() {
		t.Errorf("Relay(%s) is %s", relay.Name(), relay.Status())
	}
}

func runRelayTest(t *testing.T, r *Relay, sleep time.Duration) {
	t.Run(fmt.Sprintf("%s.Test", r.Name()), func(t *testing.T) {
		Info("Running %s", t.Name())
		runRelayTestOn(t, r)
		time.Sleep(sleep)
		runRelayTestOff(t, r)
	})
}

func TestRelays(t *testing.T) {
	Info("Running %s", t.Name())
	TestRelay = NewRelay(RELAY, "Relay", "Testing")
	runRelayTest(t, TestRelay, time.Second)
}

func discharge_us(t *GpioThermometer, e Edge, p Pull) time.Duration {
	t.mutex.Lock()
	defer t.mutex.Unlock()

	//Discharge the capacitor (low temps could make this really long)
	t.pin.Output(Low)
	time.Sleep(300 * time.Millisecond)

	// Start polling
	start := time.Now()
	t.pin.InputEdge(p, e)
	if !t.pin.WaitForEdge(time.Second / 2) {
		Trace("Thermometer %s, Rising read timed out", t.Name())
		return 0.0
	}
	stop := time.Now()
	t.pin.Output(Low)
	return stop.Sub(start)
}

func TestDischargeStrategies(t *testing.T) {
	Info("Running %s", t.Name())
	therm := NewGpioThermometer("Fixed 4.7kOhm ResistorTest", "TestManufacturer", CAP4700)
	pulls := []Pull{PullDown, PullUp, Float}
	edges := []Edge{RisingEdge, FallingEdge, BothEdges}
	expected := 4700 * therm.microfarads
	Info("Strategy: Pull, Edge, Expected, Average, Stddev, PctVar")
	for _, p := range pulls {
		for _, e := range edges {
			h := NewHistory(10)
			for i := 0; i < 10; i++ {
				dt := discharge_us(therm, e, p)
				//Info("DischargeTime %f us,  %f k-ohms", us(dt), therm.getOhms(dt))
				h.Push(us(dt))
			}
			Info("Strategy: %s, %s, %0.3f, %0.3f, %0.4f, %0.2f",
				p, e, expected, h.Average(), h.Stddev(), 100.0*h.Stddev()/h.Average())
		}
	}
}

func TestBestDischargeStrategy(t *testing.T) {
	Info("Running %s", t.Name())
	therm := NewGpioThermometer("Fixed 4.7kOhm ResistorTest", "TestManufacturer", CAP4700)
	expected := 4.700 * therm.microfarads
	Info("Strategy: Pull, Edge, Expected, Average, Stddev, PctVar")
	h := NewHistory(10)
	for i := 0; i < 10; i++ {
		dt1 := discharge_us(therm, RisingEdge, PullDown)
		dt2 := discharge_us(therm, FallingEdge, PullDown)
		dt := dt1 + dt2
		Info("DischargeTime dt1(%f ms),  dt2(%f ms), dt(%fms), %f k-ohms",
			ms(dt1), ms(dt2), ms(dt), therm.getOhms(dt))
		h.Push(ms(dt1 + dt2))
	}
	Info("Strategy: %0.3f, %0.3f, %0.4f, %0.2f",
		expected, h.Average(), h.Stddev(), 100.0*h.Stddev()/h.Average())
}

func TestThermometer(t *testing.T) {
	Info("Running %s", t.Name())
	therm := NewGpioThermometer("Fixed 4.7kOhm ResistorTest", "TestManufacturer", CAP4700)

	t.Run("Calibrate Cap4700", func(t *testing.T) {
		Info("Running %s", t.Name())
		c, err := therm.Calibrate(4700)
		if err != nil {
			t.Errorf("Failure to Calibrate successfully: %s", err.Error())
		}
		Debug("Setting calibration for %0.3f", c)
		therm.SetAdjustment(c)
	})
	t.Run("Temperature Cap4700", func(t *testing.T) {
		Info("Running %s", t.Name())
		err := therm.Update()
		if err != nil {
			t.Errorf("Thermometer update failed: %s", err.Error())
		}
		if therm.Temperature() > 44.1 || therm.Temperature() < 43.1 {
			t.Errorf("Thermometer value off: %0.1f, expected 43.6",
				therm.Temperature())
		}
	})

	therm = NewGpioThermometer("Fixed 10kOhm ResistorTest", "TestManufacturer", CAP10000)
	t.Run("Calibrate Cap10000", func(t *testing.T) {
		Info("Running %s", t.Name())
		c, err := therm.Calibrate(10000)
		if err != nil {
			t.Errorf("Failure to Calibrate successfully: %s", err.Error())
		}
		Debug("Setting calibration for %0.3f", c)
		therm.SetAdjustment(c)
	})
	t.Run("Temperature Cap4700", func(t *testing.T) {
		Info("Running %s", t.Name())
		err := therm.Update()
		if err != nil {
			t.Errorf("Thermometer update failed: %s", err.Error())
		}
		if therm.Temperature() > 25.4 || therm.Temperature() < 24.4 {
			t.Errorf("Thermometer value off: %0.1f, expected 24.9",
				therm.Temperature())
		}
	})
}

func TestPushButton(t *testing.T) {
	Info("Running %s", t.Name())
	wasRun := 0
	button := NewGpioButton(SWITCH, func() {
		wasRun++
		Led.Output(High)
		Info("Button Pushed %d!!!", wasRun)
	})

	Info("Starting button test, push it 3 times!")
	button.Start()
	time.Sleep(time.Second / 2) // let it start TODO Channel?
	for i := 0; i < 3; i++ {
		TestRelay.TurnOn()
		time.Sleep(time.Second / 3)
		TestRelay.TurnOff()
		Led.Output(Low)
		time.Sleep(2 * time.Second)
	}
	if wasRun < 3 {
		t.Errorf("Expected 3 button pushes")
	}
	Info("Stopping button job")
	exited := false
	go doStop(button, &exited, time.Now())
	time.Sleep(time.Second)
	if !exited {
		t.Errorf("Button loop should have stopped within time allotted")
	}
	Info("Button job stopped")
}
<commit_msg>test sync<commit_after>package main

import (
	"fmt"
	"testing"
	"time"
)

const (
	LED      = 5  // Pin 29
	RELAY    = 13 // Pin 33
	CAP4700  = 19 // Pin 35: Also PCM capable
	CAP10000 = 6  // Pin 31
	SWITCH   = 26 // Pin 37
)

func GpioStr(g PiPin) string {
	switch g.Pin() {
	case LED:
		return "LED"
	case RELAY:
		return "RELAY"
	case CAP4700:
		return "CAP4700"
	case CAP10000:
		return "CAP10000"
	case SWITCH:
		return "SWITCH"
	default:
		return "UNKNOWN"
	}
	return ""
}

var Led PiPin        // Setup: GPIO -> <1k Resistor -> LED -> GND
var TestRelay *Relay // Setup GPIO -> 4.7k Resistor -> Relay Board
var Cap4700 PiPin    // Setup: +3.3v -> 4.7k Resistor -> GPIO -> 10uF capacitor -> GND
var Cap10000 PiPin   // Setup: +3.3v -> 10k Resistor -> GPIO -> 10uF capacitor -> GND
var Switch PiPin     // Setup: GPIO -> Button Switch -> GND

var r10000 float64 = 9930.0
var r4700 float64 = 4600.0

func ExpectedState(t *testing.T, gpio PiPin, exp GpioState) {
	if val := gpio.Read(); val != exp {
		t.Errorf("%s: Expected %s but found %s", GpioStr(gpio), exp, val)
	}
}

func TestInitilization(t *testing.T) {
	err := GpioInit()
	t.Run("Init Host", func(t *testing.T) {
		if err != nil {
			t.Errorf("Problem initializing gpio: %s", err.Error())
		}
	})

	// Initialized GPIOs
	Led = NewGpio(LED)
	Led.Output(Low)
	ExpectedState(t, Led, Low)
}

func TestBlinkLed(t *testing.T) {
	Info("Running %s", t.Name())
	for i := 0; i < 6; i++ {
		time.Sleep(time.Second / 5)
		Led.Output(High)
		ExpectedState(t, Led, High)
		time.Sleep(time.Second / 5)
		Led.Output(Low)
		ExpectedState(t, Led, Low)
	}
}

func doStop(button *Button, b *bool, t time.Time) {
	*b = false
	button.Stop()
	*b = true
	Info("doStop - Stopped after %d ms", time.Now().Sub(t)/time.Millisecond)
}

func runRelayTestOn(t *testing.T, relay *Relay) {
	relay.TurnOn()
	Info("Testing Relay On: %s is %s", relay.Name(), relay.Status())
	if !relay.isOn() {
		t.Errorf("Relay(%s) is %s", relay.Name(), relay.Status())
	}
}

func runRelayTestOff(t *testing.T, relay *Relay) {
	relay.TurnOff()
	Info("Testing Relay Off: %s is %s", relay.Name(), relay.Status())
	if relay.isOn() {
		t.Errorf("Relay(%s) is %s", relay.Name(), relay.Status())
	}
}

func runRelayTest(t *testing.T, r *Relay, sleep time.Duration) {
	t.Run(fmt.Sprintf("%s.Test", r.Name()), func(t *testing.T) {
		Info("Running %s", t.Name())
		runRelayTestOn(t, r)
		time.Sleep(sleep)
		runRelayTestOff(t, r)
	})
}

func TestRelays(t *testing.T) {
	Info("Running %s", t.Name())
	TestRelay = NewRelay(RELAY, "Relay", "Testing")
	runRelayTest(t, TestRelay, time.Second)
}

func discharge_us(t *GpioThermometer, e Edge, p Pull) time.Duration {
	t.mutex.Lock()
	defer t.mutex.Unlock()

	//Discharge the capacitor (low temps could make this really long)
	t.pin.Output(Low)
	time.Sleep(300 * time.Millisecond)

	// Start polling
	start := time.Now()
	t.pin.InputEdge(p, e)
	if !t.pin.WaitForEdge(time.Second / 2) {
		Trace("Thermometer %s, Rising read timed out", t.Name())
		return 0.0
	}
	stop := time.Now()
	t.pin.Output(Low)
	return stop.Sub(start)
}

func TestDischargeStrategies(t *testing.T) {
	Info("Running %s", t.Name())
	therm := NewGpioThermometer("Fixed 4.7kOhm ResistorTest", "TestManufacturer", CAP4700)
	pulls := []Pull{PullDown, PullUp, Float}
	edges := []Edge{RisingEdge, FallingEdge, BothEdges}
	expected := r4700 * therm.microfarads
	Info("Strategy: Pull, Edge, Expected, Average, Stddev, PctVar")
	for _, p := range pulls {
		for _, e := range edges {
			h := NewHistory(10)
			for i := 0; i < 10; i++ {
				dt := discharge_us(therm, e, p)
				//Info("DischargeTime %f us,  %f k-ohms", us(dt), therm.getOhms(dt))
				h.Push(us(dt))
			}
			Info("Strategy: %s, %s, %0.3f, %0.3f, %0.4f, %0.2f",
				p, e, expected, h.Average(), h.Stddev(), 100.0*h.Stddev()/h.Average())
		}
	}
}

func TestBestDischargeStrategy(t *testing.T) {
	Info("Running %s", t.Name())
	therm := NewGpioThermometer("Fixed 4.7kOhm ResistorTest", "TestManufacturer", CAP4700)
	expected := r4700 * therm.microfarads / 1000.0
	Info("Strategy: Pull, Edge, Expected, Average, Stddev, PctVar")
	h := NewHistory(10)
	for i := 0; i < 10; i++ {
		dt1 := discharge_us(therm, RisingEdge, PullDown)
		dt2 := discharge_us(therm, FallingEdge, PullDown)
		dt := dt1 + dt2
		Info("DischargeTime dt1(%f ms),  dt2(%f ms), dt(%fms), %f k-ohms",
			ms(dt1), ms(dt2), ms(dt), therm.getOhms(dt))
		h.Push(ms(dt1 + dt2))
	}
	Info("Strategy: %0.3f, %0.3f, %0.4f, %0.2f",
		expected, h.Average(), h.Stddev(), 100.0*h.Stddev()/h.Average())
}

func TestThermometer(t *testing.T) {
	Info("Running %s", t.Name())
	therm := NewGpioThermometer("Fixed 4.7kOhm ResistorTest", "TestManufacturer", CAP4700)

	t.Run("Calibrate Cap4700", func(t *testing.T) {
		Info("Running %s", t.Name())
		c, err := therm.Calibrate(r4700)
		if err != nil {
			t.Errorf("Failure to Calibrate successfully: %s", err.Error())
		}
		Debug("Setting calibration for %0.3f", c)
		therm.SetAdjustment(c)
	})
	t.Run("Temperature Cap4700", func(t *testing.T) {
		Info("Running %s", t.Name())
		err := therm.Update()
		if err != nil {
			t.Errorf("Thermometer update failed: %s", err.Error())
		}
		if therm.Temperature() > 44.1 || therm.Temperature() < 43.1 {
			t.Errorf("Thermometer value off: %0.1f, expected 43.6",
				therm.Temperature())
		}
	})

	therm = NewGpioThermometer("Fixed 10kOhm ResistorTest", "TestManufacturer", CAP10000)
	t.Run("Calibrate Cap10000", func(t *testing.T) {
		Info("Running %s", t.Name())
		c, err := therm.Calibrate(r10000)
		if err != nil {
			t.Errorf("Failure to Calibrate successfully: %s", err.Error())
		}
		Debug("Setting calibration for %0.3f", c)
		therm.SetAdjustment(c)
	})
	t.Run("Temperature Cap10000", func(t *testing.T) {
		Info("Running %s", t.Name())
		err := therm.Update()
		if err != nil {
			t.Errorf("Thermometer update failed: %s", err.Error())
		}
		if therm.Temperature() > 25.4 || therm.Temperature() < 24.4 {
			t.Errorf("Thermometer value off: %0.1f, expected 24.9",
				therm.Temperature())
		}
	})
}

func TestPushButton(t *testing.T) {
	Info("Running %s", t.Name())
	wasRun := 0
	button := NewGpioButton(SWITCH, func() {
		wasRun++
		Led.Output(High)
		Info("Button Pushed %d!!!", wasRun)
	})

	Info("Starting button test, push it 3 times!")
	button.Start()
	time.Sleep(time.Second / 2) // let it start TODO Channel?
	for i := 0; i < 3; i++ {
		TestRelay.TurnOn()
		time.Sleep(time.Second / 3)
		TestRelay.TurnOff()
		Led.Output(Low)
		time.Sleep(2 * time.Second)
	}
	if wasRun < 3 {
		t.Errorf("Expected 3 button pushes")
	}
	Info("Stopping button job")
	exited := false
	go doStop(button, &exited, time.Now())
	time.Sleep(time.Second)
	if !exited {
		t.Errorf("Button loop should have stopped within time allotted")
	}
	Info("Button job stopped")
}
<|endoftext|>


<commit_before>// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"os"
	"testing"

	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/ThomasRooney/gexpect"
	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/syndtr/gocapability/capability"
)

var capsTests = []struct {
	testName            string
	capIsolator         string
	capa                capability.Cap
	capInStage1Expected bool
	capInStage2Expected bool
	nonrootCapExpected  bool
}{
	{
		testName:            "Check we don't have CAP_NET_ADMIN without isolator",
		capIsolator:         "",
		capa:                capability.CAP_NET_ADMIN,
		capInStage1Expected: false,
		capInStage2Expected: false,
		nonrootCapExpected:  false,
	},
	{
		testName:            "Check we have CAP_MKNOD without isolator",
		capIsolator:         "",
		capa:                capability.CAP_MKNOD,
		capInStage1Expected: true,
		capInStage2Expected: true,
		nonrootCapExpected:  true,
	},
	{
		testName:            "Check we have CAP_NET_ADMIN with an isolator",
		capIsolator:         "CAP_NET_ADMIN,CAP_NET_BIND_SERVICE",
		capa:                capability.CAP_NET_ADMIN,
		capInStage1Expected: true,
		capInStage2Expected: true,
		nonrootCapExpected:  true,
	},
	{
		testName:            "Check we have CAP_NET_BIND_SERVICE with an isolator",
		capIsolator:         "CAP_NET_ADMIN,CAP_NET_BIND_SERVICE",
		capa:                capability.CAP_NET_BIND_SERVICE,
		capInStage1Expected: true,
		capInStage2Expected: true,
		nonrootCapExpected:  true,
	},
	{
		testName:            "Check we don't have CAP_NET_ADMIN with an isolator setting CAP_NET_BIND_SERVICE",
		capIsolator:         "CAP_NET_BIND_SERVICE",
		capa:                capability.CAP_NET_ADMIN,
		capInStage1Expected: false,
		capInStage2Expected: false,
		nonrootCapExpected:  false,
	},
}

func TestCaps(t *testing.T) {
	for i, tt := range capsTests {
		var stage1FileName = "rkt-inspect-print-caps-stage1.aci"
		var stage2FileName = "rkt-inspect-print-caps-stage2.aci"
		stage1Args := []string{"--exec=/inspect --print-caps-pid=1 --print-user"}
		stage2Args := []string{"--exec=/inspect --print-caps-pid=0 --print-user"}
		if tt.capIsolator != "" {
			stage1Args = append(stage1Args, "--capability="+tt.capIsolator)
			stage2Args = append(stage2Args, "--capability="+tt.capIsolator)
		}
		patchTestACI(stage1FileName, stage1Args...)
		patchTestACI(stage2FileName, stage2Args...)
		defer os.Remove(stage1FileName)
		defer os.Remove(stage2FileName)

		for _, stage := range []int{1, 2} {
			t.Logf("Running test #%v: %v [stage %v]", i, tt.testName, stage)

			cmd := fmt.Sprintf("../bin/rkt --debug --insecure-skip-verify run --set-env=CAPABILITY=%d ./rkt-inspect-print-caps-stage%d.aci", int(tt.capa), stage)
			t.Logf("Command: %v", cmd)
			child, err := gexpect.Spawn(cmd)
			if err != nil {
				t.Fatalf("Cannot exec rkt #%v: %v", i, err)
			}

			expectedLine := tt.capa.String()
			if (stage == 1 && tt.capInStage1Expected) || (stage == 2 && tt.capInStage2Expected) {
				expectedLine += "=enabled"
			} else {
				expectedLine += "=disabled"
			}
			err = child.Expect(expectedLine)
			if err != nil {
				t.Fatalf("Expected %q but not found", expectedLine)
			}

			err = child.Expect("User: uid=0 euid=0 gid=0 egid=0")
			if err != nil {
				t.Fatalf("Expected user 0 but not found")
			}

			err = child.Wait()
			if err != nil {
				t.Fatalf("rkt didn't terminate correctly: %v", err)
			}
		}
	}
}

func TestNonRootCaps(t *testing.T) {
	for i, tt := range capsTests {
		var fileName = "rkt-inspect-print-caps-nonroot.aci"
		var args []string
		args = []string{"--exec=/inspect --print-caps-pid=0 --print-user", "--user=9000", "--group=9000"}
		if tt.capIsolator != "" {
			args = append(args, "--capability="+tt.capIsolator)
		}
		patchTestACI(fileName, args...)
		defer os.Remove(fileName)

		t.Logf("Running test #%v: %v [non-root]", i, tt.testName)

		cmd := fmt.Sprintf("../bin/rkt --debug --insecure-skip-verify run --set-env=CAPABILITY=%d ./%s", int(tt.capa), fileName)
		t.Logf("Command: %v", cmd)
		child, err := gexpect.Spawn(cmd)
		if err != nil {
			t.Fatalf("Cannot exec rkt #%v: %v", i, err)
		}

		expectedLine := tt.capa.String()
		if tt.nonrootCapExpected {
			expectedLine += "=enabled"
		} else {
			expectedLine += "=disabled"
		}
		err = child.Expect(expectedLine)
		if err != nil {
			t.Fatalf("Expected %q but not found", expectedLine)
		}

		err = child.Expect("User: uid=9000 euid=9000 gid=9000 egid=9000")
		if err != nil {
			t.Fatalf("Expected user 9000 but not found")
		}

		err = child.Wait()
		if err != nil {
			t.Fatalf("rkt didn't terminate correctly: %v", err)
		}
	}
}
<commit_msg>functional tests: Port capabilities tests to rkt run context<commit_after>// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"os"
	"testing"

	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/ThomasRooney/gexpect"
	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/syndtr/gocapability/capability"
)

var capsTests = []struct {
	testName            string
	capIsolator         string
	capa                capability.Cap
	capInStage1Expected bool
	capInStage2Expected bool
	nonrootCapExpected  bool
}{
	{
		testName:            "Check we don't have CAP_NET_ADMIN without isolator",
		capIsolator:         "",
		capa:                capability.CAP_NET_ADMIN,
		capInStage1Expected: false,
		capInStage2Expected: false,
		nonrootCapExpected:  false,
	},
	{
		testName:            "Check we have CAP_MKNOD without isolator",
		capIsolator:         "",
		capa:                capability.CAP_MKNOD,
		capInStage1Expected: true,
		capInStage2Expected: true,
		nonrootCapExpected:  true,
	},
	{
		testName:            "Check we have CAP_NET_ADMIN with an isolator",
		capIsolator:         "CAP_NET_ADMIN,CAP_NET_BIND_SERVICE",
		capa:                capability.CAP_NET_ADMIN,
		capInStage1Expected: true,
		capInStage2Expected: true,
		nonrootCapExpected:  true,
	},
	{
		testName:            "Check we have CAP_NET_BIND_SERVICE with an isolator",
		capIsolator:         "CAP_NET_ADMIN,CAP_NET_BIND_SERVICE",
		capa:                capability.CAP_NET_BIND_SERVICE,
		capInStage1Expected: true,
		capInStage2Expected: true,
		nonrootCapExpected:  true,
	},
	{
		testName:            "Check we don't have CAP_NET_ADMIN with an isolator setting CAP_NET_BIND_SERVICE",
		capIsolator:         "CAP_NET_BIND_SERVICE",
		capa:                capability.CAP_NET_ADMIN,
		capInStage1Expected: false,
		capInStage2Expected: false,
		nonrootCapExpected:  false,
	},
}

func TestCaps(t *testing.T) {
	for i, tt := range capsTests {
		var stage1FileName = "rkt-inspect-print-caps-stage1.aci"
		var stage2FileName = "rkt-inspect-print-caps-stage2.aci"
		stage1Args := []string{"--exec=/inspect --print-caps-pid=1 --print-user"}
		stage2Args := []string{"--exec=/inspect --print-caps-pid=0 --print-user"}
		if tt.capIsolator != "" {
			stage1Args = append(stage1Args, "--capability="+tt.capIsolator)
			stage2Args = append(stage2Args, "--capability="+tt.capIsolator)
		}
		patchTestACI(stage1FileName, stage1Args...)
		patchTestACI(stage2FileName, stage2Args...)
		defer os.Remove(stage1FileName)
		defer os.Remove(stage2FileName)
		ctx := newRktRunCtx()
		defer ctx.cleanup()

		for _, stage := range []int{1, 2} {
			t.Logf("Running test #%v: %v [stage %v]", i, tt.testName, stage)

			cmd := fmt.Sprintf("%s --debug --insecure-skip-verify run --set-env=CAPABILITY=%d ./rkt-inspect-print-caps-stage%d.aci", ctx.cmd(), int(tt.capa), stage)
			t.Logf("Command: %v", cmd)
			child, err := gexpect.Spawn(cmd)
			if err != nil {
				t.Fatalf("Cannot exec rkt #%v: %v", i, err)
			}

			expectedLine := tt.capa.String()
			if (stage == 1 && tt.capInStage1Expected) || (stage == 2 && tt.capInStage2Expected) {
				expectedLine += "=enabled"
			} else {
				expectedLine += "=disabled"
			}
			err = child.Expect(expectedLine)
			if err != nil {
				t.Fatalf("Expected %q but not found", expectedLine)
			}

			err = child.Expect("User: uid=0 euid=0 gid=0 egid=0")
			if err != nil {
				t.Fatalf("Expected user 0 but not found")
			}

			err = child.Wait()
			if err != nil {
				t.Fatalf("rkt didn't terminate correctly: %v", err)
			}
		}
	}
}

func TestNonRootCaps(t *testing.T) {
	for i, tt := range capsTests {
		var fileName = "rkt-inspect-print-caps-nonroot.aci"
		var args []string
		args = []string{"--exec=/inspect --print-caps-pid=0 --print-user", "--user=9000", "--group=9000"}
		if tt.capIsolator != "" {
			args = append(args, "--capability="+tt.capIsolator)
		}
		patchTestACI(fileName, args...)
		defer os.Remove(fileName)

		t.Logf("Running test #%v: %v [non-root]", i, tt.testName)

		cmd := fmt.Sprintf("../bin/rkt --debug --insecure-skip-verify run --set-env=CAPABILITY=%d ./%s", int(tt.capa), fileName)
		t.Logf("Command: %v", cmd)
		child, err := gexpect.Spawn(cmd)
		if err != nil {
			t.Fatalf("Cannot exec rkt #%v: %v", i, err)
		}

		expectedLine := tt.capa.String()
		if tt.nonrootCapExpected {
			expectedLine += "=enabled"
		} else {
			expectedLine += "=disabled"
		}
		err = child.Expect(expectedLine)
		if err != nil {
			t.Fatalf("Expected %q but not found", expectedLine)
		}

		err = child.Expect("User: uid=9000 euid=9000 gid=9000 egid=9000")
		if err != nil {
			t.Fatalf("Expected user 9000 but not found")
		}

		err = child.Wait()
		if err != nil {
			t.Fatalf("rkt didn't terminate correctly: %v", err)
		}
	}
}
<|endoftext|>


<commit_before>package admin

import (
	"net/http"
	"encoding/json"
	"model"
	"appengine"
	"log"
	"io/ioutil"
)

func init() {
	http.HandleFunc("/admin/api/seasons/", seasonHandler)
}

func seasonHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		createSeason(w,r)
	}
	seasonList(w, r)
}

func createSeason(w http.ResponseWriter, r *http.Request) {
	body, e := ioutil.ReadAll(r.Body)
	if e != nil {
		log.Printf("Unexpected error read the body: %v", e)
	}
	c := appengine.NewContext(r)
	log.Println(string(body))
	// decoder := json.NewDecoder(r.Body)
	var s model.Season
	// err :=  decoder.Decode(&s)
	err := json.Unmarshal(body, &s)
	if err != nil {
		log.Printf("Unexpected error decoding json data: %v", err)
		panic(err)
	}
	err = model.SaveSeason(c, s)
	if err != nil {
		log.Printf("Unexpected error saving season: %v", err)
		panic(err)
	}
}

func seasonList(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	seasons := model.LoadAllSeasons(c)
	data, err := json.MarshalIndent(seasons, "", "\t")
	if err != nil {
		log.Printf("Unexpected error marshalling seasons: %v", err)
		panic(err)
	}
	w.Write(data)
}
<commit_msg>Removed old cruft code<commit_after>package admin

import (
	"net/http"
	"encoding/json"
	"model"
	"appengine"
	"log"
	// "io/ioutil"
)

func init() {
	http.HandleFunc("/admin/api/seasons/", seasonHandler)
}

func seasonHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		createSeason(w,r)
	}
	seasonList(w, r)
}

func createSeason(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	decoder := json.NewDecoder(r.Body)
	var s model.Season
	err :=  decoder.Decode(&s)
	if err != nil {
		log.Printf("Unexpected error decoding json data: %v", err)
		panic(err)
	}
	err = model.SaveSeason(c, s)
	if err != nil {
		log.Printf("Unexpected error saving season: %v", err)
		panic(err)
	}
}

func seasonList(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	seasons := model.LoadAllSeasons(c)
	data, err := json.MarshalIndent(seasons, "", "\t")
	if err != nil {
		log.Printf("Unexpected error marshalling seasons: %v", err)
		panic(err)
	}
	w.Write(data)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/google/go-github/github"
)

type Contribution struct {
	Date time.Time
	Num  int
}

const dateFormat string = "2006-01-02"

func (c *Contribution) UnmarshalJSON(data []byte) error {
	var i []interface{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return err
	}

	if v, ok := i[0].(string); ok {
		c.Date, err = time.Parse(dateFormat, v)
	}
	if err != nil {
		return err
	}

	if v, ok := i[1].(float64); ok {
		c.Num = int(v)
	}

	return nil
}

func getContributions(user github.User) []Contribution {
	login := github.Stringify(user.Login)
	url := "https://github.com/users/" + login[1:len(login)-1] + "/contributions"
	var contribData []Contribution

	resp, err := http.Get(url)
	defer resp.Body.Close()
	if err != nil {
		log.Fatal(err)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	if data == nil {
		log.Fatalln("No data returned.")
	}

	err = json.Unmarshal(data, &contribData)
	if err != nil {
		log.Fatal(err)
	}

	return contribData
}

func getOrgMembers(orgName string) []github.User {
	client := github.NewClient(nil)

	users, _, err := client.Organizations.ListMembers(orgName, nil)
	if err != nil {
		log.Fatal(err)
	}

	return users
}

func main() {
	flag.Parse()
	var i interface{} = flag.Arg(0)
	var users []github.User

	var v, ok = i.(string)
	if ok == false || v == "" {
		log.Fatalln("Usage: orgstreak <orgName>")
	} else {
		users = getOrgMembers(v)
	}

	orgContribs := make(map[time.Time]int)

	for _, user := range users {
		for _, contrib := range getContributions(user) {
			orgContribs[contrib.Date] += contrib.Num
		}
	}

	contribData := []interface{}{}
	for k, v := range orgContribs {
		contribData = append(contribData, []interface{}{k.Format(dateFormat), v})
	}
	j, err := json.Marshal(contribData)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", j)
}
<commit_msg>grab api responses asynchronously<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/google/go-github/github"
)

type Contribution struct {
	Date time.Time
	Num  int
}

const dateFormat string = "2006-01-02"

func (c *Contribution) UnmarshalJSON(data []byte) error {
	var i []interface{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return err
	}

	if v, ok := i[0].(string); ok {
		c.Date, err = time.Parse(dateFormat, v)
	}
	if err != nil {
		return err
	}

	if v, ok := i[1].(float64); ok {
		c.Num = int(v)
	}

	return nil
}

func getContributions(user github.User) []Contribution {
	login := github.Stringify(user.Login)
	url := "https://github.com/users/" + login[1:len(login)-1] + "/contributions"
	var contribData []Contribution

	resp, err := http.Get(url)
	defer resp.Body.Close()
	if err != nil {
		log.Fatal(err)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	if data == nil {
		log.Fatalln("No data returned.")
	}

	err = json.Unmarshal(data, &contribData)
	if err != nil {
		log.Fatal(err)
	}

	return contribData
}

func getOrgMembers(orgName string) []github.User {
	client := github.NewClient(nil)

	users, _, err := client.Organizations.ListMembers(orgName, nil)
	if err != nil {
		log.Fatal(err)
	}

	return users
}

func main() {
	flag.Parse()
	var i interface{} = flag.Arg(0)
	var users []github.User

	var v, ok = i.(string)
	if ok == false || v == "" {
		log.Fatalln("Usage: orgstreak <orgName>")
	} else {
		users = getOrgMembers(v)
	}

	orgContribs := make(map[time.Time]int)
	userContributions := make(chan []Contribution, len(users))

	for _, user := range users {
		go func(u github.User) {
			userContributions <- getContributions(u)
		}(user)
	}

	for y := 0; y < len(users); y++ {
		select {
		case userContribution := <-userContributions:
			for _, contrib := range userContribution {
				orgContribs[contrib.Date] += contrib.Num
			}
		}
	}

	contribData := []interface{}{}
	for k, v := range orgContribs {
		contribData = append(contribData, []interface{}{k.Format(dateFormat), v})
	}
	j, err := json.Marshal(contribData)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", j)
}
<|endoftext|>


<commit_before>// HTTP router
package violetear

import (
	"log"
	"net/http"
	"regexp"
	"strings"
)

type Violetear struct {
	// Routes to be matched
	routes *Trie

	// dynamicRoutes map of dynamic routes and regular expresions
	dynamicRoutes dynamicSet

	// logRequests yes or no
	logRequests bool

	// NotFound configurable http.Handler which is called when no matching
	// route is found. If it is not set, http.NotFound is used.
	NotFound http.Handler

	// NotAllowed configurable http.Handler which is called when method not
	// allowed.
	NotAllowed http.Handler

	// Function to handle panics recovered from http handlers.
	PanicHandler func(http.ResponseWriter, *http.Request)
}

var (
	split_path_rx = regexp.MustCompile(`[^/ ]+`)
)

// New returns a new initialized router.
func New(log ...bool) *Violetear {
	v := &Violetear{
		routes:        NewTrie(),
		dynamicRoutes: make(dynamicSet),
	}

	if len(log) > 0 {
		v.logRequests = true
	}
	return v
}

// Run violetear as an HTTP server.
// The addr string takes the same format as http.ListenAndServe.
func (v *Violetear) Run(addr string) {
	log.Printf("Violetear listening on %s", addr)
	log.Fatal(http.ListenAndServe(addr, v))
}

// HandleFunc add a route to the router (path, HandlerFunc, methods)
func (v *Violetear) HandleFunc(path string, handler http.HandlerFunc, http_methods ...string) {
	path_parts := v.splitPath(path)

	// search for dynamic routes
	for _, p := range path_parts {
		if strings.HasPrefix(p, ":") {
			if _, ok := v.dynamicRoutes[p]; !ok {
				log.Fatalf("[%s] not found, need to add it using AddRegex(\"%s\", `your regex`)", p, p)
			}
		}
	}

	// if no methods, accept ALL
	methods := "ALL"
	if len(http_methods) > 0 {
		methods = http_methods[0]
	}

	log.Printf("Adding path: %s, Handler: %T, Methods: %s", path, handler, methods)
	v.routes.Set(path_parts, handler, methods)
}

// AddRegex adds a ":named" regular expression to the dynamicRoutes
func (v *Violetear) AddRegex(name string, regex string) error {
	return v.dynamicRoutes.Set(name, regex)
}

// SetNotFound set the handler for 404
func (v *Violetear) SetNotFound(h http.HandlerFunc) {
	v.NotFound = http.HandlerFunc(h)
}

// SetNotAllowed set the handler for 405
func (v *Violetear) SetNotAllowed(h http.HandlerFunc) {
	v.NotAllowed = http.HandlerFunc(h)
}

// MethodNotAllowed default handler for 405
func (v *Violetear) MethodNotAllowed() http.HandlerFunc {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w,
			http.StatusText(http.StatusMethodNotAllowed),
			http.StatusMethodNotAllowed,
		)
	})
}

// ServerHTTP dispatches the handler registered in the matched path
func (v *Violetear) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	if v.logRequests {
		log.Println(req.Method, req.RequestURI)
	}

	node, path, leaf := v.routes.Get(v.splitPath(req.RequestURI))

	// checkMethod check if method is allowed or not
	checkMethod := func(node *Trie, method string) http.Handler {
		if h, ok := node.Handler[method]; ok {
			return h
		} else if h, ok := node.Handler["ALL"]; ok {
			return h
		}
		if v.NotAllowed != nil {
			return v.NotAllowed
		} else {
			return v.MethodNotAllowed()
		}
	}

	var match func(node *Trie, path []string, leaf bool) http.Handler

	// match find a handler for the request
	match = func(node *Trie, path []string, leaf bool) http.Handler {
		if len(node.Handler) > 0 && leaf {
			return checkMethod(node, req.Method)
		} else if node.HasRegex {
			for k, _ := range node.Node {
				if strings.HasPrefix(k, ":") {
					rx := v.dynamicRoutes[k]
					if rx.MatchString(path[0]) {
						path[0] = k
						if leaf {
							match(node, path, leaf)
						} else {
							return checkMethod(node.Node[k], req.Method)
						}
					}
				}
			}
		}
		if v.NotFound != nil {
			return v.NotFound
		}
		return http.NotFoundHandler()
	}

	//var handler http.Handler
	h := match(node, path, leaf)
	log.Printf("%T", h)
	res.Header().Set("X-app-epazote", "1.0")
	h.ServeHTTP(res, req)
}

// splitPath returns an slice of the path
func (v *Violetear) splitPath(p string) []string {
	path_parts := split_path_rx.FindAllString(p, -1)

	// root (empty slice)
	if len(path_parts) == 0 {
		path_parts = append(path_parts, "/")
	}

	return path_parts
}
<commit_msg>	modified:   violetear.go<commit_after>// HTTP router
package violetear

import (
	"log"
	"net/http"
	"regexp"
	"strings"
)

type Violetear struct {
	// Routes to be matched
	routes *Trie

	// dynamicRoutes map of dynamic routes and regular expresions
	dynamicRoutes dynamicSet

	// logRequests yes or no
	logRequests bool

	// NotFoundHandler configurable http.Handler which is called when no matching
	// route is found. If it is not set, http.NotFound is used.
	NotFoundHandler http.Handler

	// NotAllowedHandler configurable http.Handler which is called when method not allowed.
	NotAllowedHandler http.Handler

	// Function to handle panics recovered from http handlers.
	PanicHandler func(http.ResponseWriter, *http.Request)
}

var (
	split_path_rx = regexp.MustCompile(`[^/ ]+`)
)

// New returns a new initialized router.
func New(log ...bool) *Violetear {
	v := &Violetear{
		routes:        NewTrie(),
		dynamicRoutes: make(dynamicSet),
	}

	if len(log) > 0 {
		v.logRequests = true
	}
	return v
}

// Run violetear as an HTTP server.
// The addr string takes the same format as http.ListenAndServe.
func (v *Violetear) Run(addr string) {
	log.Printf("Violetear listening on %s", addr)
	log.Fatal(http.ListenAndServe(addr, v))
}

// HandleFunc add a route to the router (path, HandlerFunc, methods)
func (v *Violetear) HandleFunc(path string, handler http.HandlerFunc, http_methods ...string) {
	path_parts := v.splitPath(path)

	// search for dynamic routes
	for _, p := range path_parts {
		if strings.HasPrefix(p, ":") {
			if _, ok := v.dynamicRoutes[p]; !ok {
				log.Fatalf("[%s] not found, need to add it using AddRegex(\"%s\", `your regex`)", p, p)
			}
		}
	}

	// if no methods, accept ALL
	methods := "ALL"
	if len(http_methods) > 0 {
		methods = http_methods[0]
	}

	log.Printf("Adding path: %s, Handler: %T, Methods: %s", path, handler, methods)
	v.routes.Set(path_parts, handler, methods)
}

// AddRegex adds a ":named" regular expression to the dynamicRoutes
func (v *Violetear) AddRegex(name string, regex string) error {
	return v.dynamicRoutes.Set(name, regex)
}

// MethodNotAllowed default handler for 405
func (v *Violetear) MethodNotAllowed() http.HandlerFunc {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w,
			http.StatusText(http.StatusMethodNotAllowed),
			http.StatusMethodNotAllowed,
		)
	})
}

// ServerHTTP dispatches the handler registered in the matched path
func (v *Violetear) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	if v.logRequests {
		log.Println(req.Method, req.RequestURI)
	}

	node, path, leaf := v.routes.Get(v.splitPath(req.RequestURI))

	// checkMethod check if method is allowed or not
	checkMethod := func(node *Trie, method string) http.Handler {
		if h, ok := node.Handler[method]; ok {
			return h
		} else if h, ok := node.Handler["ALL"]; ok {
			return h
		}
		if v.NotAllowedHandler != nil {
			return v.NotAllowedHandler
		} else {
			return v.MethodNotAllowed()
		}
	}

	var match func(node *Trie, path []string, leaf bool) http.Handler

	// match find a handler for the request
	match = func(node *Trie, path []string, leaf bool) http.Handler {
		if len(node.Handler) > 0 && leaf {
			return checkMethod(node, req.Method)
		} else if node.HasRegex {
			for k, _ := range node.Node {
				if strings.HasPrefix(k, ":") {
					rx := v.dynamicRoutes[k]
					if rx.MatchString(path[0]) {
						path[0] = k
						if leaf {
							match(node, path, leaf)
						} else {
							return checkMethod(node.Node[k], req.Method)
						}
					}
				}
			}
		}
		if v.NotFoundHandler != nil {
			return v.NotFoundHandler
		}
		return http.NotFoundHandler()
	}

	//var handler http.Handler
	h := match(node, path, leaf)
	log.Printf("%T", h)
	res.Header().Set("X-app-epazote", "1.0")
	h.ServeHTTP(res, req)
}

// splitPath returns an slice of the path
func (v *Violetear) splitPath(p string) []string {
	path_parts := split_path_rx.FindAllString(p, -1)

	// root (empty slice)
	if len(path_parts) == 0 {
		path_parts = append(path_parts, "/")
	}

	return path_parts
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

package ovsdb

import (
	"errors"
	"reflect"
	"sync"
	"sync/atomic"
	"time"

	"github.com/socketplane/libovsdb"

	"github.com/skydive-project/skydive/logging"
)

type OvsClient struct {
	ovsdb     *libovsdb.OvsdbClient
	connected uint64
}

type OvsMonitorHandler interface {
	OnOvsBridgeAdd(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsBridgeDel(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsBridgeUpdate(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsInterfaceAdd(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsInterfaceDel(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsInterfaceUpdate(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsPortAdd(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsPortDel(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsPortUpdate(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
}

type OvsMonitor struct {
	sync.RWMutex
	Protocol        string
	Target          string
	OvsClient       *OvsClient
	MonitorHandlers []OvsMonitorHandler
	bridgeCache     map[string]string
	interfaceCache  map[string]string
	portCache       map[string]string
	columnsExcluded map[string]bool
	ticker          *time.Ticker
	done            chan struct{}
}

const ConnectionPollInterval time.Duration = 4 * time.Second

type Notifier struct {
	monitor *OvsMonitor
}

func (n Notifier) Update(context interface{}, tableUpdates libovsdb.TableUpdates) {
	n.monitor.updateHandler(&tableUpdates)
}

func (n Notifier) Locked([]interface{}) {
}

func (n Notifier) Stolen([]interface{}) {
}

func (n Notifier) Echo([]interface{}) {
}

func (n Notifier) Disconnected(c *libovsdb.OvsdbClient) {
	/* trigger re-connection */
	atomic.StoreUint64(&n.monitor.OvsClient.connected, 0)
}

func (o *OvsClient) Exec(operations ...libovsdb.Operation) ([]libovsdb.OperationResult, error) {
	if atomic.LoadUint64(&o.connected) == 0 {
		return nil, errors.New("OVSDB client is not connected")
	}

	result, err := o.ovsdb.Transact("Open_vSwitch", operations...)
	if err != nil {
		return nil, errors.New(
			"Replies number should be atleast equal to number of Operations ")
	}

	if len(result) < len(operations) {
		return nil, errors.New(
			"Replies number should be atleast equal to number of Operations ")
	}

	for i, o := range result {
		if o.Error != "" && i < len(operations) {
			return nil, errors.New(
				"Transaction Failed due to an error :" +
					o.Error + " details:" + o.Details)
		} else if o.Error != "" {
			return nil, errors.New(
				"Transaction Failed due to an error :" + o.Error)
		}
	}

	return result, nil
}

func (o *OvsMonitor) isConnected() bool {
	return atomic.LoadUint64(&o.OvsClient.connected) == 1
}

func (o *OvsMonitor) bridgeUpdated(bridgeUUID string, row *libovsdb.RowUpdate) {
	logging.GetLogger().Infof("Bridge \"%s(%s)\" updated",
		row.New.Fields["name"], bridgeUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsBridgeUpdate(o, bridgeUUID, row)
	}
}

func (o *OvsMonitor) bridgeAdded(bridgeUUID string, row *libovsdb.RowUpdate) {
	o.bridgeCache[bridgeUUID] = bridgeUUID

	logging.GetLogger().Infof("New bridge \"%s(%s)\" added",
		row.New.Fields["name"], bridgeUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsBridgeAdd(o, bridgeUUID, row)
	}
}

func (o *OvsMonitor) bridgeDeleted(bridgeUUID string, row *libovsdb.RowUpdate) {
	delete(o.bridgeCache, bridgeUUID)

	logging.GetLogger().Infof("Bridge \"%s(%s)\" got deleted",
		row.Old.Fields["name"], bridgeUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsBridgeDel(o, bridgeUUID, row)
	}
}

func (o *OvsMonitor) bridgeUpdateHandler(updates *libovsdb.TableUpdate) {
	empty := libovsdb.Row{}

	o.Lock()
	defer o.Unlock()

	for bridgeUUID, row := range updates.Rows {
		if !reflect.DeepEqual(row.New, empty) {
			if _, ok := o.bridgeCache[bridgeUUID]; ok {
				o.bridgeUpdated(bridgeUUID, &row)

			} else {
				o.bridgeAdded(bridgeUUID, &row)
			}
		} else {
			o.bridgeDeleted(bridgeUUID, &row)
		}
	}
}

func (o *OvsMonitor) interfaceUpdated(interfaceUUID string, row *libovsdb.RowUpdate) {
	logging.GetLogger().Infof("Interface \"%s(%s)\" updated",
		row.New.Fields["name"], interfaceUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsInterfaceUpdate(o, interfaceUUID, row)
	}
}

func (o *OvsMonitor) interfaceAdded(interfaceUUID string, row *libovsdb.RowUpdate) {
	o.interfaceCache[interfaceUUID] = interfaceUUID

	logging.GetLogger().Infof("New interface \"%s(%s)\" added",
		row.New.Fields["name"], interfaceUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsInterfaceAdd(o, interfaceUUID, row)
	}
}

func (o *OvsMonitor) interfaceDeleted(interfaceUUID string, row *libovsdb.RowUpdate) {
	delete(o.interfaceCache, interfaceUUID)

	logging.GetLogger().Infof("Interface \"%s(%s)\" got deleted",
		row.Old.Fields["name"], interfaceUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsInterfaceDel(o, interfaceUUID, row)
	}
}

func (o *OvsMonitor) interfaceUpdateHandler(updates *libovsdb.TableUpdate) {
	empty := libovsdb.Row{}

	o.Lock()
	defer o.Unlock()

	for interfaceUUID, row := range updates.Rows {
		if !reflect.DeepEqual(row.New, empty) {
			if _, ok := o.interfaceCache[interfaceUUID]; ok {
				o.interfaceUpdated(interfaceUUID, &row)
			} else {
				o.interfaceAdded(interfaceUUID, &row)
			}
		} else {
			o.interfaceDeleted(interfaceUUID, &row)
		}
	}
}

func (o *OvsMonitor) portUpdated(portUUID string, row *libovsdb.RowUpdate) {
	logging.GetLogger().Infof("Port \"%s(%s)\" updated",
		row.New.Fields["name"], portUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsPortUpdate(o, portUUID, row)
	}
}

func (o *OvsMonitor) portAdded(portUUID string, row *libovsdb.RowUpdate) {
	o.portCache[portUUID] = portUUID

	logging.GetLogger().Infof("New port \"%s(%s)\" added",
		row.New.Fields["name"], portUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsPortAdd(o, portUUID, row)
	}
}

func (o *OvsMonitor) portDeleted(portUUID string, row *libovsdb.RowUpdate) {
	delete(o.portCache, portUUID)

	logging.GetLogger().Infof("Port \"%s(%s)\" got deleted",
		row.Old.Fields["name"], portUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsPortDel(o, portUUID, row)
	}
}

func (o *OvsMonitor) portUpdateHandler(updates *libovsdb.TableUpdate) {
	empty := libovsdb.Row{}

	o.Lock()
	defer o.Unlock()

	for portUUID, row := range updates.Rows {
		if !reflect.DeepEqual(row.New, empty) {
			if _, ok := o.portCache[portUUID]; ok {
				o.portUpdated(portUUID, &row)
			} else {
				o.portAdded(portUUID, &row)
			}
		} else {
			o.portDeleted(portUUID, &row)
		}
	}
}

func (o *OvsMonitor) updateHandler(updates *libovsdb.TableUpdates) {
	for name, tableUpdate := range updates.Updates {
		switch name {
		case "Interface":
			o.interfaceUpdateHandler(&tableUpdate)
		case "Bridge":
			o.bridgeUpdateHandler(&tableUpdate)
		case "Port":
			o.portUpdateHandler(&tableUpdate)
		}
	}
}

func (o *OvsMonitor) setMonitorRequests(table string, r *map[string]libovsdb.MonitorRequest) error {
	schema, ok := o.OvsClient.ovsdb.Schema["Open_vSwitch"]
	if !ok {
		return errors.New("invalid Database Schema")
	}

	var columns []string
	for column := range schema.Tables[table].Columns {
		if _, found := o.columnsExcluded[column]; !found {
			columns = append(columns, column)
		}
	}

	requests := *r
	requests[table] = libovsdb.MonitorRequest{
		Columns: columns,
		Select: libovsdb.MonitorSelect{
			Initial: true,
			Insert:  true,
			Delete:  true,
			Modify:  true,
		},
	}

	return nil
}

func (o *OvsMonitor) AddMonitorHandler(handler OvsMonitorHandler) {
	o.Lock()
	defer o.Unlock()

	o.MonitorHandlers = append(o.MonitorHandlers, handler)
}

func (o *OvsMonitor) ExcludeColumn(column string) {
	o.columnsExcluded[column] = true
}

func (o *OvsMonitor) monitorOvsdb() error {
	ovsdb, err := libovsdb.ConnectUsingProtocol(o.Protocol, o.Target)
	if err != nil {
		return err
	}
	o.OvsClient.ovsdb = ovsdb
	atomic.StoreUint64(&o.OvsClient.connected, 1)

	notifier := Notifier{monitor: o}
	ovsdb.Register(notifier)

	requests := make(map[string]libovsdb.MonitorRequest)
	err = o.setMonitorRequests("Bridge", &requests)
	if err != nil {
		return err
	}

	err = o.setMonitorRequests("Interface", &requests)
	if err != nil {
		return err
	}

	err = o.setMonitorRequests("Port", &requests)
	if err != nil {
		return err
	}

	updates, err := ovsdb.Monitor("Open_vSwitch", "", requests)
	if err != nil {
		return err
	}

	o.updateHandler(updates)

	return nil
}

// startMonitoring() is a watchdog of OvsClient connection with ConnectionPollInterval
func (o *OvsMonitor) startMonitoring() error {
	o.ticker = time.NewTicker(ConnectionPollInterval)

	for {
		select {
		case <-o.ticker.C:
			if o.isConnected() {
				continue
			}
			if err := o.monitorOvsdb(); err != nil {
				logging.GetLogger().Errorf(": re-connect error %v, will try again", err)
			}
		case <-o.done:
			break
		}
	}
}

func (o *OvsMonitor) StartMonitoring() {
	o.monitorOvsdb()
	go o.startMonitoring()
}

func (o *OvsMonitor) StopMonitoring() {
	if o.OvsClient != nil {
		o.done <- struct{}{}
		if o.OvsClient.ovsdb != nil {
			o.OvsClient.ovsdb.Disconnect()
		}
	}
}

func NewOvsMonitor(protcol string, target string) *OvsMonitor {
	return &OvsMonitor{
		Protocol:        protcol,
		Target:          target,
		OvsClient:       &OvsClient{ovsdb: nil, connected: 0},
		bridgeCache:     make(map[string]string),
		interfaceCache:  make(map[string]string),
		portCache:       make(map[string]string),
		columnsExcluded: make(map[string]bool),
		ticker:          nil,
		done:            make(chan struct{}),
	}
}
<commit_msg>Ovs atomic disconnect<commit_after>/*
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

package ovsdb

import (
	"errors"
	"reflect"
	"sync"
	"sync/atomic"
	"time"

	"github.com/socketplane/libovsdb"

	"github.com/skydive-project/skydive/logging"
)

type OvsClient struct {
	ovsdb     *libovsdb.OvsdbClient
	connected uint64
}

type OvsMonitorHandler interface {
	OnOvsBridgeAdd(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsBridgeDel(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsBridgeUpdate(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsInterfaceAdd(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsInterfaceDel(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsInterfaceUpdate(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsPortAdd(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsPortDel(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
	OnOvsPortUpdate(monitor *OvsMonitor, uuid string, row *libovsdb.RowUpdate)
}

type OvsMonitor struct {
	sync.RWMutex
	Protocol        string
	Target          string
	OvsClient       *OvsClient
	MonitorHandlers []OvsMonitorHandler
	bridgeCache     map[string]string
	interfaceCache  map[string]string
	portCache       map[string]string
	columnsExcluded map[string]bool
	ticker          *time.Ticker
	done            chan struct{}
}

const ConnectionPollInterval time.Duration = 4 * time.Second

type Notifier struct {
	monitor *OvsMonitor
}

func (n Notifier) Update(context interface{}, tableUpdates libovsdb.TableUpdates) {
	n.monitor.updateHandler(&tableUpdates)
}

func (n Notifier) Locked([]interface{}) {
}

func (n Notifier) Stolen([]interface{}) {
}

func (n Notifier) Echo([]interface{}) {
}

func (n Notifier) Disconnected(c *libovsdb.OvsdbClient) {
	/* trigger re-connection */
	atomic.StoreUint64(&n.monitor.OvsClient.connected, 0)
}

func (o *OvsClient) Exec(operations ...libovsdb.Operation) ([]libovsdb.OperationResult, error) {
	if atomic.LoadUint64(&o.connected) == 0 {
		return nil, errors.New("OVSDB client is not connected")
	}

	result, err := o.ovsdb.Transact("Open_vSwitch", operations...)
	if err != nil {
		return nil, errors.New(
			"Replies number should be atleast equal to number of Operations ")
	}

	if len(result) < len(operations) {
		return nil, errors.New(
			"Replies number should be atleast equal to number of Operations ")
	}

	for i, o := range result {
		if o.Error != "" && i < len(operations) {
			return nil, errors.New(
				"Transaction Failed due to an error :" +
					o.Error + " details:" + o.Details)
		} else if o.Error != "" {
			return nil, errors.New(
				"Transaction Failed due to an error :" + o.Error)
		}
	}

	return result, nil
}

func (o *OvsMonitor) isConnected() bool {
	return atomic.LoadUint64(&o.OvsClient.connected) == 1
}

func (o *OvsMonitor) bridgeUpdated(bridgeUUID string, row *libovsdb.RowUpdate) {
	logging.GetLogger().Infof("Bridge \"%s(%s)\" updated",
		row.New.Fields["name"], bridgeUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsBridgeUpdate(o, bridgeUUID, row)
	}
}

func (o *OvsMonitor) bridgeAdded(bridgeUUID string, row *libovsdb.RowUpdate) {
	o.bridgeCache[bridgeUUID] = bridgeUUID

	logging.GetLogger().Infof("New bridge \"%s(%s)\" added",
		row.New.Fields["name"], bridgeUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsBridgeAdd(o, bridgeUUID, row)
	}
}

func (o *OvsMonitor) bridgeDeleted(bridgeUUID string, row *libovsdb.RowUpdate) {
	delete(o.bridgeCache, bridgeUUID)

	logging.GetLogger().Infof("Bridge \"%s(%s)\" got deleted",
		row.Old.Fields["name"], bridgeUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsBridgeDel(o, bridgeUUID, row)
	}
}

func (o *OvsMonitor) bridgeUpdateHandler(updates *libovsdb.TableUpdate) {
	empty := libovsdb.Row{}

	o.Lock()
	defer o.Unlock()

	for bridgeUUID, row := range updates.Rows {
		if !reflect.DeepEqual(row.New, empty) {
			if _, ok := o.bridgeCache[bridgeUUID]; ok {
				o.bridgeUpdated(bridgeUUID, &row)

			} else {
				o.bridgeAdded(bridgeUUID, &row)
			}
		} else {
			o.bridgeDeleted(bridgeUUID, &row)
		}
	}
}

func (o *OvsMonitor) interfaceUpdated(interfaceUUID string, row *libovsdb.RowUpdate) {
	logging.GetLogger().Infof("Interface \"%s(%s)\" updated",
		row.New.Fields["name"], interfaceUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsInterfaceUpdate(o, interfaceUUID, row)
	}
}

func (o *OvsMonitor) interfaceAdded(interfaceUUID string, row *libovsdb.RowUpdate) {
	o.interfaceCache[interfaceUUID] = interfaceUUID

	logging.GetLogger().Infof("New interface \"%s(%s)\" added",
		row.New.Fields["name"], interfaceUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsInterfaceAdd(o, interfaceUUID, row)
	}
}

func (o *OvsMonitor) interfaceDeleted(interfaceUUID string, row *libovsdb.RowUpdate) {
	delete(o.interfaceCache, interfaceUUID)

	logging.GetLogger().Infof("Interface \"%s(%s)\" got deleted",
		row.Old.Fields["name"], interfaceUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsInterfaceDel(o, interfaceUUID, row)
	}
}

func (o *OvsMonitor) interfaceUpdateHandler(updates *libovsdb.TableUpdate) {
	empty := libovsdb.Row{}

	o.Lock()
	defer o.Unlock()

	for interfaceUUID, row := range updates.Rows {
		if !reflect.DeepEqual(row.New, empty) {
			if _, ok := o.interfaceCache[interfaceUUID]; ok {
				o.interfaceUpdated(interfaceUUID, &row)
			} else {
				o.interfaceAdded(interfaceUUID, &row)
			}
		} else {
			o.interfaceDeleted(interfaceUUID, &row)
		}
	}
}

func (o *OvsMonitor) portUpdated(portUUID string, row *libovsdb.RowUpdate) {
	logging.GetLogger().Infof("Port \"%s(%s)\" updated",
		row.New.Fields["name"], portUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsPortUpdate(o, portUUID, row)
	}
}

func (o *OvsMonitor) portAdded(portUUID string, row *libovsdb.RowUpdate) {
	o.portCache[portUUID] = portUUID

	logging.GetLogger().Infof("New port \"%s(%s)\" added",
		row.New.Fields["name"], portUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsPortAdd(o, portUUID, row)
	}
}

func (o *OvsMonitor) portDeleted(portUUID string, row *libovsdb.RowUpdate) {
	delete(o.portCache, portUUID)

	logging.GetLogger().Infof("Port \"%s(%s)\" got deleted",
		row.Old.Fields["name"], portUUID)

	for _, handler := range o.MonitorHandlers {
		handler.OnOvsPortDel(o, portUUID, row)
	}
}

func (o *OvsMonitor) portUpdateHandler(updates *libovsdb.TableUpdate) {
	empty := libovsdb.Row{}

	o.Lock()
	defer o.Unlock()

	for portUUID, row := range updates.Rows {
		if !reflect.DeepEqual(row.New, empty) {
			if _, ok := o.portCache[portUUID]; ok {
				o.portUpdated(portUUID, &row)
			} else {
				o.portAdded(portUUID, &row)
			}
		} else {
			o.portDeleted(portUUID, &row)
		}
	}
}

func (o *OvsMonitor) updateHandler(updates *libovsdb.TableUpdates) {
	for name, tableUpdate := range updates.Updates {
		switch name {
		case "Interface":
			o.interfaceUpdateHandler(&tableUpdate)
		case "Bridge":
			o.bridgeUpdateHandler(&tableUpdate)
		case "Port":
			o.portUpdateHandler(&tableUpdate)
		}
	}
}

func (o *OvsMonitor) setMonitorRequests(table string, r *map[string]libovsdb.MonitorRequest) error {
	schema, ok := o.OvsClient.ovsdb.Schema["Open_vSwitch"]
	if !ok {
		return errors.New("invalid Database Schema")
	}

	var columns []string
	for column := range schema.Tables[table].Columns {
		if _, found := o.columnsExcluded[column]; !found {
			columns = append(columns, column)
		}
	}

	requests := *r
	requests[table] = libovsdb.MonitorRequest{
		Columns: columns,
		Select: libovsdb.MonitorSelect{
			Initial: true,
			Insert:  true,
			Delete:  true,
			Modify:  true,
		},
	}

	return nil
}

func (o *OvsMonitor) AddMonitorHandler(handler OvsMonitorHandler) {
	o.Lock()
	defer o.Unlock()

	o.MonitorHandlers = append(o.MonitorHandlers, handler)
}

func (o *OvsMonitor) ExcludeColumn(column string) {
	o.columnsExcluded[column] = true
}

func (o *OvsMonitor) monitorOvsdb() error {
	ovsdb, err := libovsdb.ConnectUsingProtocol(o.Protocol, o.Target)
	if err != nil {
		return err
	}
	o.OvsClient.ovsdb = ovsdb
	atomic.StoreUint64(&o.OvsClient.connected, 1)

	notifier := Notifier{monitor: o}
	ovsdb.Register(notifier)

	requests := make(map[string]libovsdb.MonitorRequest)
	err = o.setMonitorRequests("Bridge", &requests)
	if err != nil {
		return err
	}

	err = o.setMonitorRequests("Interface", &requests)
	if err != nil {
		return err
	}

	err = o.setMonitorRequests("Port", &requests)
	if err != nil {
		return err
	}

	updates, err := ovsdb.Monitor("Open_vSwitch", "", requests)
	if err != nil {
		return err
	}

	o.updateHandler(updates)

	return nil
}

// startMonitoring() is a watchdog of OvsClient connection with ConnectionPollInterval
func (o *OvsMonitor) startMonitoring() error {
	o.ticker = time.NewTicker(ConnectionPollInterval)

	for {
		select {
		case <-o.ticker.C:
			if o.isConnected() {
				continue
			}
			if err := o.monitorOvsdb(); err != nil {
				logging.GetLogger().Errorf(": re-connect error %v, will try again", err)
			}
		case <-o.done:
			break
		}
	}
}

func (o *OvsMonitor) StartMonitoring() {
	o.monitorOvsdb()
	go o.startMonitoring()
}

func (o *OvsMonitor) StopMonitoring() {
	if o.OvsClient != nil {
		o.done <- struct{}{}
		if o.isConnected() == true {
			o.OvsClient.ovsdb.Disconnect()
		}
	}
}

func NewOvsMonitor(protcol string, target string) *OvsMonitor {
	return &OvsMonitor{
		Protocol:        protcol,
		Target:          target,
		OvsClient:       &OvsClient{ovsdb: nil, connected: 0},
		bridgeCache:     make(map[string]string),
		interfaceCache:  make(map[string]string),
		portCache:       make(map[string]string),
		columnsExcluded: make(map[string]bool),
		ticker:          nil,
		done:            make(chan struct{}),
	}
}
<|endoftext|>


<commit_before>package clrs

type fibNode struct {
	key    int
	p      *fibNode
	child  *fibNode
	left   *fibNode
	right  *fibNode
	degree int
	mark   bool
}

type fibHeap struct {
	min *fibNode
	n   int
}

func makeFibHeap() *fibHeap {
	return new(fibHeap)
}

func fibHeapUnion(h1, h2 *fibHeap) *fibHeap {
	h := makeFibHeap()
	h.min = h1.min
	h.listConcatenate(h2)
	if h1.min == nil || h2.min != nil && h2.min.key < h1.min.key {
		h.min = h2.min
	}
	h.n = h1.n + h2.n
	return h
}

func (h *fibHeap) fibHeapInsert(x *fibNode) {
	x.degree = 0
	x.p = nil
	x.child = nil
	x.mark = false
	if h.min == nil {
		x.left = x
		x.right = x
		h.min = x
	} else {
		h.listInsert(h.min, x)
		if x.key < h.min.key {
			h.min = x
		}
	}
	h.n = h.n + 1
}

func (h *fibHeap) listInsert(root, x *fibNode) {
	x.right = root
	x.left = root.left
	x.left.right = x
	root.left = x
}

func (h *fibHeap) listConcatenate(h2 *fibHeap) {
	if h.min == nil {
		h.min = h2.min
	} else {
		h2.min.left.right = h.min
		h2.min.left, h.min.left = h.min.left, h2.min.left
		h2.min.left.right = h2.min
	}
}
<commit_msg>fibHeapExtractMin<commit_after>package clrs

import (
	"math"
)

type fibNode struct {
	key    int
	p      *fibNode
	child  *fibNode
	left   *fibNode
	right  *fibNode
	degree int
	mark   bool
}

type fibHeap struct {
	min *fibNode
	n   int
}

func makeFibHeap() *fibHeap {
	return new(fibHeap)
}

func fibHeapUnion(h1, h2 *fibHeap) *fibHeap {
	h := makeFibHeap()
	h.min = h1.min
	h.listConcatenate(h2)
	if h1.min == nil || h2.min != nil && h2.min.key < h1.min.key {
		h.min = h2.min
	}
	h.n = h1.n + h2.n
	return h
}

func (h *fibHeap) fibHeapInsert(x *fibNode) {
	x.degree = 0
	x.p = nil
	x.child = nil
	x.mark = false
	if h.min == nil {
		x.left = x
		x.right = x
		h.min = x
	} else {
		h.listInsert(h.min, x)
		if x.key < h.min.key {
			h.min = x
		}
	}
	h.n = h.n + 1
}

func (h *fibHeap) listInsert(root, x *fibNode) {
	x.right = root
	x.left = root.left
	x.left.right = x
	root.left = x
}

func (h *fibHeap) listDelete(x *fibNode) {
	x.right.left = x.left
	x.left.right = x.right
}

func (h *fibHeap) listConcatenate(h2 *fibHeap) {
	if h.min == nil {
		h.min = h2.min
	} else {
		h2.min.left.right = h.min
		h2.min.left, h.min.left = h.min.left, h2.min.left
		h2.min.left.right = h2.min
	}
}

func (h *fibHeap) fibHeapExtractMin() *fibNode {
	z := h.min
	if z != nil {
		for _, x := range h.children(z) {
			h.listInsert(z, x)
			x.p = nil
		}
		h.listDelete(z)
		if z == z.right {
			h.min = nil
		} else {
			h.min = z.right
			h.consolidate()
		}
		h.n = h.n - 1
	}
	return z
}

func (h *fibHeap) children(x *fibNode) []*fibNode {
	var cs []*fibNode
	for c := x; c != nil; c = c.right {
		if len(cs) > 0 && c == cs[0] {
			break
		}
		cs = append(cs, c)
	}
	return cs
}

func (h *fibHeap) d() int {
	return int(math.Log2(float64(h.n)))
}

func (h *fibHeap) consolidate() {
	hd := h.d()
	a := make([]*fibNode, hd+1)
	for _, w := range h.children(h.min) {
		x := w
		d := x.degree
		for a[d] != nil {
			y := a[d]
			if x.key > y.key {
				x, y = y, x
			}
			h.fibHeapLink(y, x)
			a[d] = nil
			d = d + 1
		}
		a[d] = x
	}
	h.min = nil
	for i := 0; i <= hd; i++ {
		if a[i] != nil {
			if h.min == nil {
				a[i].left = a[i]
				a[i].right = a[i]
				h.min = a[i]
			} else {
				h.listInsert(h.min, a[i])
				a[i].p = nil
				if a[i].key < h.min.key {
					h.min = a[i]
				}
			}
		}
	}
}

func (h *fibHeap) fibHeapLink(y, x *fibNode) {
	h.listDelete(y)
	if x.child == nil {
		y.left = y
		y.right = y
		x.child = y
	} else {
		h.listInsert(x.child, y)
	}
	y.p = x
	x.degree = x.degree + 1
	y.mark = false
}

func (h *fibHeap) fibHeapWalk() []*fibNode {
	var (
		nodes   []*fibNode
		child   func(x *fibNode)
		sibling func(x *fibNode)
	)
	child = func(x *fibNode) {
		if x.child != nil {
			sibling(x.child)
		}
	}
	sibling = func(x *fibNode) {
		start := -1
		for s := x; s != nil; s = s.right {
			if start != -1 && nodes[start] == s {
				break
			}
			child(s)
			nodes = append(nodes, s)
			if start == -1 {
				start = len(nodes) - 1
			}
		}
	}

	if h.min != nil {
		sibling(h.min)
	}
	return nodes
}
<|endoftext|>


<commit_before>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package vp8

// This file implements parsing the quantization factors.

// quant are DC/AC quantization factors.
type quant struct {
	y1 [2]uint16
	y2 [2]uint16
	uv [2]uint16
}

// clip clips x to the range [min, max] inclusive.
func clip(x, min, max int32) int32 {
	if x < min {
		return min
	}
	if x > max {
		return max
	}
	return x
}

// parseQuant parses the quantization factors, as specified in section 9.6.
func (d *Decoder) parseQuant() {
	baseQ0 := d.fp.readUint(uniformProb, 7)
	dqy1DC := d.fp.readOptionalInt(uniformProb, 4)
	const dqy1AC = 0
	dqy2DC := d.fp.readOptionalInt(uniformProb, 4)
	dqy2AC := d.fp.readOptionalInt(uniformProb, 4)
	dquvDC := d.fp.readOptionalInt(uniformProb, 4)
	dquvAC := d.fp.readOptionalInt(uniformProb, 4)
	for i := 0; i < nSegment; i++ {
		q := int32(baseQ0)
		if d.segmentHeader.useSegment {
			if d.segmentHeader.relativeDelta {
				q += int32(d.segmentHeader.quantizer[i])
			} else {
				q = int32(d.segmentHeader.quantizer[i])
			}
		}
		d.quant[i].y1[0] = dequantTableDC[clip(q+dqy1DC, 0, 127)]
		d.quant[i].y1[1] = dequantTableAC[clip(q+dqy1AC, 0, 127)]
		d.quant[i].y2[0] = dequantTableDC[clip(q+dqy2DC, 0, 127)] * 2
		d.quant[i].y2[1] = dequantTableAC[clip(q+dqy2AC, 0, 127)] * 155 / 100
		if d.quant[i].y2[1] < 8 {
			d.quant[i].y2[1] = 8
		}
		d.quant[i].uv[0] = dequantTableDC[clip(q+dquvDC, 0, 127)]
		d.quant[i].uv[1] = dequantTableAC[clip(q+dquvAC, 0, 127)]
	}
}

// The dequantization tables are specified in section 14.1.
var (
	dequantTableDC = [128]uint16{
		4, 5, 6, 7, 8, 9, 10, 10,
		11, 12, 13, 14, 15, 16, 17, 17,
		18, 19, 20, 20, 21, 21, 22, 22,
		23, 23, 24, 25, 25, 26, 27, 28,
		29, 30, 31, 32, 33, 34, 35, 36,
		37, 37, 38, 39, 40, 41, 42, 43,
		44, 45, 46, 46, 47, 48, 49, 50,
		51, 52, 53, 54, 55, 56, 57, 58,
		59, 60, 61, 62, 63, 64, 65, 66,
		67, 68, 69, 70, 71, 72, 73, 74,
		75, 76, 76, 77, 78, 79, 80, 81,
		82, 83, 84, 85, 86, 87, 88, 89,
		91, 93, 95, 96, 98, 100, 101, 102,
		104, 106, 108, 110, 112, 114, 116, 118,
		122, 124, 126, 128, 130, 132, 134, 136,
		138, 140, 143, 145, 148, 151, 154, 157,
	}
	dequantTableAC = [128]uint16{
		4, 5, 6, 7, 8, 9, 10, 11,
		12, 13, 14, 15, 16, 17, 18, 19,
		20, 21, 22, 23, 24, 25, 26, 27,
		28, 29, 30, 31, 32, 33, 34, 35,
		36, 37, 38, 39, 40, 41, 42, 43,
		44, 45, 46, 47, 48, 49, 50, 51,
		52, 53, 54, 55, 56, 57, 58, 60,
		62, 64, 66, 68, 70, 72, 74, 76,
		78, 80, 82, 84, 86, 88, 90, 92,
		94, 96, 98, 100, 102, 104, 106, 108,
		110, 112, 114, 116, 119, 122, 125, 128,
		131, 134, 137, 140, 143, 146, 149, 152,
		155, 158, 161, 164, 167, 170, 173, 177,
		181, 185, 189, 193, 197, 201, 205, 209,
		213, 217, 221, 225, 229, 234, 239, 245,
		249, 254, 259, 264, 269, 274, 279, 284,
	}
)
<commit_msg>go.image/vp8: clamp the UV DC quantization factor to 132.<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package vp8

// This file implements parsing the quantization factors.

// quant are DC/AC quantization factors.
type quant struct {
	y1 [2]uint16
	y2 [2]uint16
	uv [2]uint16
}

// clip clips x to the range [min, max] inclusive.
func clip(x, min, max int32) int32 {
	if x < min {
		return min
	}
	if x > max {
		return max
	}
	return x
}

// parseQuant parses the quantization factors, as specified in section 9.6.
func (d *Decoder) parseQuant() {
	baseQ0 := d.fp.readUint(uniformProb, 7)
	dqy1DC := d.fp.readOptionalInt(uniformProb, 4)
	const dqy1AC = 0
	dqy2DC := d.fp.readOptionalInt(uniformProb, 4)
	dqy2AC := d.fp.readOptionalInt(uniformProb, 4)
	dquvDC := d.fp.readOptionalInt(uniformProb, 4)
	dquvAC := d.fp.readOptionalInt(uniformProb, 4)
	for i := 0; i < nSegment; i++ {
		q := int32(baseQ0)
		if d.segmentHeader.useSegment {
			if d.segmentHeader.relativeDelta {
				q += int32(d.segmentHeader.quantizer[i])
			} else {
				q = int32(d.segmentHeader.quantizer[i])
			}
		}
		d.quant[i].y1[0] = dequantTableDC[clip(q+dqy1DC, 0, 127)]
		d.quant[i].y1[1] = dequantTableAC[clip(q+dqy1AC, 0, 127)]
		d.quant[i].y2[0] = dequantTableDC[clip(q+dqy2DC, 0, 127)] * 2
		d.quant[i].y2[1] = dequantTableAC[clip(q+dqy2AC, 0, 127)] * 155 / 100
		if d.quant[i].y2[1] < 8 {
			d.quant[i].y2[1] = 8
		}
		// The 117 is not a typo. The dequant_init function in the spec's Reference
		// Decoder Source Code (http://tools.ietf.org/html/rfc6386#section-9.6 Page 145)
		// says to clamp the LHS value at 132, which is equal to dequantTableDC[117].
		d.quant[i].uv[0] = dequantTableDC[clip(q+dquvDC, 0, 117)]
		d.quant[i].uv[1] = dequantTableAC[clip(q+dquvAC, 0, 127)]
	}
}

// The dequantization tables are specified in section 14.1.
var (
	dequantTableDC = [128]uint16{
		4, 5, 6, 7, 8, 9, 10, 10,
		11, 12, 13, 14, 15, 16, 17, 17,
		18, 19, 20, 20, 21, 21, 22, 22,
		23, 23, 24, 25, 25, 26, 27, 28,
		29, 30, 31, 32, 33, 34, 35, 36,
		37, 37, 38, 39, 40, 41, 42, 43,
		44, 45, 46, 46, 47, 48, 49, 50,
		51, 52, 53, 54, 55, 56, 57, 58,
		59, 60, 61, 62, 63, 64, 65, 66,
		67, 68, 69, 70, 71, 72, 73, 74,
		75, 76, 76, 77, 78, 79, 80, 81,
		82, 83, 84, 85, 86, 87, 88, 89,
		91, 93, 95, 96, 98, 100, 101, 102,
		104, 106, 108, 110, 112, 114, 116, 118,
		122, 124, 126, 128, 130, 132, 134, 136,
		138, 140, 143, 145, 148, 151, 154, 157,
	}
	dequantTableAC = [128]uint16{
		4, 5, 6, 7, 8, 9, 10, 11,
		12, 13, 14, 15, 16, 17, 18, 19,
		20, 21, 22, 23, 24, 25, 26, 27,
		28, 29, 30, 31, 32, 33, 34, 35,
		36, 37, 38, 39, 40, 41, 42, 43,
		44, 45, 46, 47, 48, 49, 50, 51,
		52, 53, 54, 55, 56, 57, 58, 60,
		62, 64, 66, 68, 70, 72, 74, 76,
		78, 80, 82, 84, 86, 88, 90, 92,
		94, 96, 98, 100, 102, 104, 106, 108,
		110, 112, 114, 116, 119, 122, 125, 128,
		131, 134, 137, 140, 143, 146, 149, 152,
		155, 158, 161, 164, 167, 170, 173, 177,
		181, 185, 189, 193, 197, 201, 205, 209,
		213, 217, 221, 225, 229, 234, 239, 245,
		249, 254, 259, 264, 269, 274, 279, 284,
	}
)
<|endoftext|>


<commit_before>// Copyright 2012 Marco Dinacci. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package amzpa provides functionality for using the
// Amazon Product Advertising service.

package amzpa

import (
	"encoding/xml"
)

type Image struct {
	XMLName xml.Name `xml:"MediumImage"`
	URL 	string
	Height 	uint16
	Width 	uint16
}

type Item struct {
	XMLName 	xml.Name `xml:"Item"`
	ASIN 		string
	URL 		string
	DetailPageURL string
	Author 		string `xml:"ItemAttributes>Author"`
	Price 		string `xml:"ItemAttributes>ListPrice>FormattedPrice"`
	PriceRaw 	string `xml:"ItemAttributes>ListPrice>Amount"`
	MediumImage Image
}

type Request struct {
	XMLName xml.Name `xml:"Request"`
	IsValid bool 	 `xml:"IsValid"`
	ItemLookupRequest ItemLookupRequest `xml:"ItemLookupRequest"`
}

type ItemLookupRequest struct {
	XMLName 	xml.Name `xml:"ItemLookupRequest"`
	// TODO not sure how to map this yet
}

type ItemLookupResponse struct {
	XMLName xml.Name `xml:"ItemLookupResponse"`
	Items 	[]Item 	 `xml:"Items>Item"`
	Request Request  `xml:"Items>Request"`
}

func unmarshal(contents []byte) (ItemLookupResponse, error) {
	itemLookupResponse := ItemLookupResponse{}
	err := xml.Unmarshal(contents, &itemLookupResponse)

	if err != nil {
		return ItemLookupResponse{}, err
	}

	return itemLookupResponse, err
}
<commit_msg>adding title<commit_after>// Copyright 2012 Marco Dinacci. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package amzpa provides functionality for using the
// Amazon Product Advertising service.

package amzpa

import (
	"encoding/xml"
)

type Image struct {
	XMLName xml.Name `xml:"MediumImage"`
	URL     string
	Height  uint16
	Width   uint16
}

type Item struct {
	XMLName       xml.Name `xml:"Item"`
	ASIN          string
	URL           string
	DetailPageURL string
	Author        string `xml:"ItemAttributes>Author"`
	Price         string `xml:"ItemAttributes>ListPrice>FormattedPrice"`
	PriceRaw      string `xml:"ItemAttributes>ListPrice>Amount"`
	Title         string `xml:"ItemAttributes>Title"`
	MediumImage   Image
}

type Request struct {
	XMLName           xml.Name          `xml:"Request"`
	IsValid           bool              `xml:"IsValid"`
	ItemLookupRequest ItemLookupRequest `xml:"ItemLookupRequest"`
}

type ItemLookupRequest struct {
	XMLName xml.Name `xml:"ItemLookupRequest"`
	// TODO not sure how to map this yet
}

type ItemLookupResponse struct {
	XMLName xml.Name `xml:"ItemLookupResponse"`
	Items   []Item   `xml:"Items>Item"`
	Request Request  `xml:"Items>Request"`
}

func unmarshal(contents []byte) (ItemLookupResponse, error) {
	itemLookupResponse := ItemLookupResponse{}
	err := xml.Unmarshal(contents, &itemLookupResponse)

	if err != nil {
		return ItemLookupResponse{}, err
	}

	return itemLookupResponse, err
}
<|endoftext|>


<commit_before>// Watch for transactions receiving to or sending from certain addresses.
// Receiving works, sending is probably messed up.
package main

import (
	"fmt"
	"sync"

	_ "github.com/decred/dcrd/chaincfg/chainhash"
	_ "github.com/decred/dcrd/dcrjson"
	"github.com/decred/dcrd/txscript"
	"github.com/decred/dcrrpcclient"
	"github.com/decred/dcrutil"
)

func handleReceivingTx(c *dcrrpcclient.Client, addrs map[string]struct{},
	recvTxChan <-chan *watchedAddrTx, wg *sync.WaitGroup,
	quit <-chan struct{}) {
	defer wg.Done()
	//out:
	for {
		//keepon:
		select {
		case addrTx, ok := <-recvTxChan:
			if !ok {
				log.Infof("Receive Tx watch channel closed")
				return
			}

			// Make like notifyForTxOuts and screen the transactions TxOuts for
			// addresses we are watching for.

			tx := addrTx.transaction
			var action string
			if addrTx.details != nil {
				action = fmt.Sprintf("mined into block %d.", addrTx.details.Height)
			} else {
				action = "inserted into mempool."
			}

			for _, txOut := range tx.MsgTx().TxOut {
				_, txAddrs, _, err := txscript.ExtractPkScriptAddrs(txOut.Version,
					txOut.PkScript, activeChain)
				if err != nil {
					log.Infof("ExtractPkScriptAddrs: %v", err.Error())
					continue
				}

				for _, txAddr := range txAddrs {
					addrstr := txAddr.EncodeAddress()
					if _, ok := addrs[addrstr]; ok {
						log.Infof("Transaction with watched address %v as outpoint (receiving), value %.6f, %v",
							addrstr, dcrutil.Amount(txOut.Value).ToCoin(),
							action)
						continue
					}
				}
			}

		case <-quit:
			mempoolLog.Debugf("Quitting OnRecvTx handler.")
			return
		}
	}

}

// Rather than watching for the sending address, which isn't known ahead of
// time, watch for a transaction with an input (source) whos previous outpoint
// is one of the watched addresses.
// But I am not sure we can do that here with the Tx and BlockDetails provided.
func handleSendingTx(c *dcrrpcclient.Client, addrs map[string]struct{},
	spendTxChan <-chan *watchedAddrTx, wg *sync.WaitGroup,
	quit <-chan struct{}) {
	defer wg.Done()
	//out:
	for {
		//keepon:
		select {
		case addrTx, ok := <-spendTxChan:
			if !ok {
				log.Infof("Send Tx watch channel closed")
				return
			}

			// Unfortunately, can't make like notifyForTxOuts because we are
			// not watching outpoints.  For the tx we are given, we need to
			// search through each TxIn's PreviousOutPoints, requesting the raw
			// transaction from each PreviousOutPoint's tx hash, and check each
			// TxOut in the result for each watched address.  Phew! There is
			// surely a better way, but I don't know it.

			tx := addrTx.transaction
			var action string
			if addrTx.details != nil {
				action = fmt.Sprintf("mined into block %d.", addrTx.details.Height)
			} else {
				action = "inserted into mempool."
			}

			for _, txIn := range tx.MsgTx().TxIn {
				prevOut := &txIn.PreviousOutPoint
				// uh, now what?
				// For each TxIn, we need to check the indicated vout index in the
				// txid of the previous outpoint.
				//txrr, err := c.GetRawTransactionVerbose(&prevOut.Hash)
				Tx, err := c.GetRawTransaction(&prevOut.Hash)
				if err != nil {
					log.Error("Unable to get raw transaction for", Tx)
				}

				// prevOut.Index should tell us which one, right?  Check all anyway.
				for _, txOut := range Tx.MsgTx().TxOut {
					_, txAddrs, _, err := txscript.ExtractPkScriptAddrs(
						txOut.Version, txOut.PkScript, activeChain)
					if err != nil {
						log.Infof("ExtractPkScriptAddrs: %v", err.Error())
						continue
					}

					for _, txAddr := range txAddrs {
						addrstr := txAddr.EncodeAddress()
						if _, ok := addrs[addrstr]; ok {
							log.Infof("Transaction with watched address %v as previous outpoint (spending), value %.6f, %v",
								addrstr, dcrutil.Amount(txOut.Value).ToCoin(), action)
							continue
						}
					}
				}

				// That's not what I'm doing here, but I'm looking anyway...
				// log.Debug(txscript.GetScriptClass(txscript.DefaultScriptVersion, txIn.SignatureScript))
				// log.Debug(txscript.GetPkScriptFromP2SHSigScript(txIn.SignatureScript))
				// sclass, txAddrs, nreqsigs, err := txscript.ExtractPkScriptAddrs(txscript.DefaultScriptVersion, txIn.SignatureScript, activeChain)
				// log.Debug(sclass, txAddrs, nreqsigs, err, action)

				// addresses := make([]string, len(txAddrs))
				// for i, addr := range txAddrs {
				// 	addresses[i] = addr.EncodeAddress()
				// }
				// log.Debug(addresses)
			}
		case <-quit:
			mempoolLog.Debugf("Quitting OnRedeemingTx handler.")
			return
		}
	}
}
<commit_msg>Fix potential nil pointer dereference.  Still need to figure out how to watch receiving transactions properly.<commit_after>// Watch for transactions receiving to or sending from certain addresses.
// Receiving works, sending is probably messed up.
package main

import (
	"fmt"
	"sync"

	_ "github.com/decred/dcrd/chaincfg/chainhash"
	_ "github.com/decred/dcrd/dcrjson"
	"github.com/decred/dcrd/txscript"
	"github.com/decred/dcrrpcclient"
	"github.com/decred/dcrutil"
)

func handleReceivingTx(c *dcrrpcclient.Client, addrs map[string]struct{},
	recvTxChan <-chan *watchedAddrTx, wg *sync.WaitGroup,
	quit <-chan struct{}) {
	defer wg.Done()
	//out:
	for {
		//keepon:
		select {
		case addrTx, ok := <-recvTxChan:
			if !ok {
				log.Infof("Receive Tx watch channel closed")
				return
			}

			// Make like notifyForTxOuts and screen the transactions TxOuts for
			// addresses we are watching for.

			tx := addrTx.transaction
			var action string
			if addrTx.details != nil {
				action = fmt.Sprintf("mined into block %d.", addrTx.details.Height)
			} else {
				action = "inserted into mempool."
			}

			for _, txOut := range tx.MsgTx().TxOut {
				_, txAddrs, _, err := txscript.ExtractPkScriptAddrs(txOut.Version,
					txOut.PkScript, activeChain)
				if err != nil {
					log.Infof("ExtractPkScriptAddrs: %v", err.Error())
					continue
				}

				for _, txAddr := range txAddrs {
					addrstr := txAddr.EncodeAddress()
					if _, ok := addrs[addrstr]; ok {
						log.Infof("Transaction with watched address %v as outpoint (receiving), value %.6f, %v",
							addrstr, dcrutil.Amount(txOut.Value).ToCoin(),
							action)
						continue
					}
				}
			}

		case <-quit:
			mempoolLog.Debugf("Quitting OnRecvTx handler.")
			return
		}
	}

}

// Rather than watching for the sending address, which isn't known ahead of
// time, watch for a transaction with an input (source) whos previous outpoint
// is one of the watched addresses.
// But I am not sure we can do that here with the Tx and BlockDetails provided.
func handleSendingTx(c *dcrrpcclient.Client, addrs map[string]struct{},
	spendTxChan <-chan *watchedAddrTx, wg *sync.WaitGroup,
	quit <-chan struct{}) {
	defer wg.Done()
	//out:
	for {
		//keepon:
		select {
		case addrTx, ok := <-spendTxChan:
			if !ok {
				log.Infof("Send Tx watch channel closed")
				return
			}

			// Unfortunately, can't make like notifyForTxOuts because we are
			// not watching outpoints.  For the tx we are given, we need to
			// search through each TxIn's PreviousOutPoints, requesting the raw
			// transaction from each PreviousOutPoint's tx hash, and check each
			// TxOut in the result for each watched address.  Phew! There is
			// surely a better way, but I don't know it.

			tx := addrTx.transaction
			var action string
			if addrTx.details != nil {
				action = fmt.Sprintf("mined into block %d.", addrTx.details.Height)
			} else {
				action = "inserted into mempool."
			}

			for _, txIn := range tx.MsgTx().TxIn {
				prevOut := &txIn.PreviousOutPoint
				// uh, now what?
				// For each TxIn, we need to check the indicated vout index in the
				// txid of the previous outpoint.
				//txrr, err := c.GetRawTransactionVerbose(&prevOut.Hash)
				Tx, err := c.GetRawTransaction(&prevOut.Hash)
				if err != nil {
					log.Error("Unable to get raw transaction for", Tx)
					continue
				}

				// prevOut.Index should tell us which one, right?  Check all anyway.
				wireMsg := Tx.MsgTx()
				if wireMsg == nil {
					log.Debug("No wire Msg? Hmm.")
					continue
				}
				for _, txOut := range wireMsg.TxOut {
					_, txAddrs, _, err := txscript.ExtractPkScriptAddrs(
						txOut.Version, txOut.PkScript, activeChain)
					if err != nil {
						log.Infof("ExtractPkScriptAddrs: %v", err.Error())
						continue
					}

					for _, txAddr := range txAddrs {
						addrstr := txAddr.EncodeAddress()
						if _, ok := addrs[addrstr]; ok {
							log.Infof("Transaction with watched address %v as previous outpoint (spending), value %.6f, %v",
								addrstr, dcrutil.Amount(txOut.Value).ToCoin(), action)
							continue
						}
					}
				}

				// That's not what I'm doing here, but I'm looking anyway...
				// log.Debug(txscript.GetScriptClass(txscript.DefaultScriptVersion, txIn.SignatureScript))
				// log.Debug(txscript.GetPkScriptFromP2SHSigScript(txIn.SignatureScript))
				// sclass, txAddrs, nreqsigs, err := txscript.ExtractPkScriptAddrs(txscript.DefaultScriptVersion, txIn.SignatureScript, activeChain)
				// log.Debug(sclass, txAddrs, nreqsigs, err, action)

				// addresses := make([]string, len(txAddrs))
				// for i, addr := range txAddrs {
				// 	addresses[i] = addr.EncodeAddress()
				// }
				// log.Debug(addresses)
			}
		case <-quit:
			mempoolLog.Debugf("Quitting OnRedeemingTx handler.")
			return
		}
	}
}
<|endoftext|>


<commit_before>/* access.go : Implement strided memory access to see the effects of cache
Author: James Fairbanks
Date: 2012-09-02
Liscence: BSD
*/

package main

import (
	"fmt"
	"github.com/jpfairbanks/timing"
	"math/rand"
)

//Dtype: the data type of the arrays
type Dtype int64

//Strider: a slice of type dtype with a fixed stride
type Strider struct {
	data   []Dtype
	stride int
}

//Walk: walk a strided array by the stride
func (s Strider) Walk() Dtype {
	var v Dtype
	iterations := s.stride
	for k := 0; k < iterations; k++ {
		for i := 0; i < len(s.data)-k; i += s.stride {
			v = s.data[i+k]
		}
	}
	return v
}

//main: time.Time the Walk
func main() {
	var n, s int
	n = 2 << 20
	fmt.Println(n)
	s = 1
	k := 18
	size := make([]int, k)
	tg := timing.New(k)

	size[0] = 1
	for i := 1; i < len(size); i++ {
		size[i] = 2 * size[i-1]
	}
	fmt.Println(size)
	sdr := Strider{make([]Dtype, n), s}
	for i := 0; i < len(sdr.data); i++ {
		sdr.data[i] = Dtype(i)
	}

	for i, k := range size {
		sdr.stride = k
		tg.Tic(i)
		for iter := 0; iter < 4; iter++ {
			sdr.Walk()
		}
		tg.Toc(i)
	}

	perm := rand.Perm(n)
	ptg := timing.New(1)
	ptg.Tic(0)
	var v Dtype
	for _, j := range perm {
		v = sdr.data[j]
	}
	ptg.Toc(0)
	fmt.Println(v)
	tg.Resolve()
	fmt.Println(tg.TupleString("\n"))
	ptg.Resolve()
	fmt.Println(ptg)
}
<commit_msg>update access to check that it traversed the array correctly<commit_after>/* access.go : Implement strided memory access to see the effects of cache
Author: James Fairbanks
Date: 2012-09-02
Liscence: BSD
*/

package main

import (
	"fmt"
	"github.com/jpfairbanks/timing"
	"math/rand"
)

//Dtype: the data type of the arrays
type Dtype int64

//Strider: a slice of type dtype with a fixed stride
type Strider struct {
	data   []Dtype
	stride int
}

//Walk: walk a strided array by the stride
func (s Strider) Walk() Dtype {
	var v Dtype
	iterations := s.stride
	for k := 0; k < iterations; k++ {
		for i := 0; i < len(s.data)-k; i += s.stride {
			v += s.data[i+k]
		}
	}
	return v
}

//main: time.Time the Walk
func main() {
	var n, s int
	n = 2 << 20
	fmt.Println(n)
	s = 1
	k := 18
	size := make([]int, k)
	tg := timing.New(k)

	size[0] = 1
	for i := 1; i < len(size); i++ {
		size[i] = 2 * size[i-1]
	}
	fmt.Println(size)
	sdr := Strider{make([]Dtype, n), s}
	for i := 0; i < len(sdr.data); i++ {
		sdr.data[i] = Dtype(i)
	}

	for i, k := range size {
		sdr.stride = k
		tg.Tic(i)
		var sum Dtype
		for iter := 0; iter < 1; iter++ {
			sum = sdr.Walk()
		}
		tg.Toc(i)
		if correctsum := (n * (n - 1)) / 2; correctsum != int(sum) {
			fmt.Println("we did not hit all the elements")
			fmt.Println(correctsum, sum)
		}
	}

	perm := rand.Perm(n)
	ptg := timing.New(1)
	ptg.Tic(0)
	var v Dtype
	for _, j := range perm {
		v = sdr.data[j]
	}

	ptg.Toc(0)
	fmt.Println(v)
	tg.Resolve()
	fmt.Println(tg.TupleString("\n"))
	ptg.Resolve()
	fmt.Println("Random Access: ", ptg)
}
<|endoftext|>


<commit_before>package web

import (
	"net/http"

	"github.com/gorilla/schema"

	"github.com/fallenhitokiri/leeroyci/database"
)

type userForm struct {
	Email     string `schema:"email"`
	FirstName string `schema:"first_name"`
	LastName  string `schema:"last_name"`
	Password  string `schema:"password"`

	URL     string `schema:"url"`
	Secret  string `schema:"secret"`
	SSLCert string `schema:"ssl_cert"`
	SSLKey  string `schema:"ssl_key"`

	Host         string `schema:"host"`
	Port         int    `schema:"port"`
	Sender       string `schema:"sender"`
	SMTPUser     string `schema:"smtp_user"`
	SMPTPassword string `schema:"smtp_password"`
}

func viewSetup(w http.ResponseWriter, r *http.Request) {
	template := "setup.html"
	ctx := make(responseContext)

	if r.Method == "POST" {
		err := r.ParseForm()

		if err != nil {
			ctx["error"] = err.Error()
			render(w, r, template, ctx)
			return
		}

		decoder := schema.NewDecoder()
		form := new(userForm)

		err = decoder.Decode(form, r.PostForm)

		if err != nil {
			ctx["error"] = err.Error()
			render(w, r, template, ctx)
			return
		}

		user, err := database.CreateUser(
			form.Email,
			form.FirstName,
			form.LastName,
			form.Password,
			true,
		)

		if err != nil {
			ctx["error"] = err.Error()
			render(w, r, template, ctx)
			return
		}

		database.AddConfig(
			form.Secret,
			form.URL,
			form.SSLCert,
			form.SSLKey,
		)

		database.AddMailServer(
			form.Host,
			form.Sender,
			form.SMTPUser,
			form.SMPTPassword,
			form.Port,
		)

		if user != nil {
			database.Configured = true
			http.Redirect(w, r, "/login", 302)
		}
	}

	render(w, r, template, ctx)
	return
}
<commit_msg>refactor setup view<commit_after>package web

import (
	"net/http"

	"github.com/gorilla/schema"

	"github.com/fallenhitokiri/leeroyci/database"
)

type configForm struct {
	Email     string `schema:"email"`
	FirstName string `schema:"first_name"`
	LastName  string `schema:"last_name"`
	Password  string `schema:"password"`

	URL     string `schema:"url"`
	Secret  string `schema:"secret"`
	SSLCert string `schema:"ssl_cert"`
	SSLKey  string `schema:"ssl_key"`

	Host         string `schema:"host"`
	Port         int    `schema:"port"`
	Sender       string `schema:"sender"`
	SMTPUser     string `schema:"smtp_user"`
	SMPTPassword string `schema:"smtp_password"`
}

func (c configForm) save(request *http.Request) (*database.User, error) {
	err := request.ParseForm()

	if err != nil {
		return nil, err
	}

	decoder := schema.NewDecoder()
	form := new(configForm)

	err = decoder.Decode(form, request.PostForm)

	if err != nil {
		return nil, err
	}

	user, err := database.CreateUser(
		form.Email,
		form.FirstName,
		form.LastName,
		form.Password,
		true,
	)

	if err != nil {
		return nil, err
	}

	database.AddConfig(
		form.Secret,
		form.URL,
		form.SSLCert,
		form.SSLKey,
	)

	database.AddMailServer(
		form.Host,
		form.Sender,
		form.SMTPUser,
		form.SMPTPassword,
		form.Port,
	)

	return user, nil
}

func viewSetup(w http.ResponseWriter, r *http.Request) {
	template := "setup.html"
	ctx := make(responseContext)

	if r.Method == "POST" {
		_, err := configForm{}.save(r)

		if err == nil {
			database.Configured = true
			http.Redirect(w, r, "/login", 302)
			return
		}

		ctx["error"] = err.Error()
	}

	render(w, r, template, ctx)
	return
}
<|endoftext|>